Leandro Hernan Rojas 8623488221
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m24s
Update ADD Patients y Institutions Models in API
2025-04-20 19:58:17 -03:00

425 lines
18 KiB
Plaintext

@page "/sales/customerform"
@page "/sales/customerform/{CustomerId:int}"
@using System.ComponentModel.DataAnnotations
@using phronCare.UIBlazor.Pages.Shared.Modals
@using phronCare.UIBlazor.Services.Sales
@inject IModalService Modal
@inject IToastService toastService
@inject HttpClient _httpClient
@inject NavigationManager Navigation
@inject AuthenticationStateProvider authenticationStateProvider
@inject AccountTypeService accountTypeService
@inject TaxConditionService taxConditionService
<div class="card" style="zoom:80%">
<div class="card-header d-flex justify-content-center align-items-center">
<h3 class="card-title m-0">Información del cliente</h3>
</div>
<div class="card-body">
<EditForm Model="@customer" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="row">
<div class="col-md-6">
<label for="Name">Nombre / Razón Social:</label>
<InputText id="Name" @bind-Value="customer.Name" class="form-control" />
</div>
<div class="col-md-6">
<label for="BusinessName">Sucursal / Nombre Comercial:</label>
<InputText id="BusinessName" @bind-Value="customer.BusinessName" class="form-control" />
</div>
</div>
<div class="row">
<div class="col-md-6">
<label for="AccounttypesId">Tipo de Cuenta:</label>
<InputSelect id="AccounttypesId" @bind-Value="customer.AccounttypesId" class="form-control">
<option value="">-- Seleccionar --</option>
@foreach (var type in accountTypes)
{
<option value="@type.Id">@type.Name</option>
}
</InputSelect>
</div>
<div class="col-md-6">
<label for="TaxConditionId">Condición Fiscal:</label>
<InputSelect id="TaxConditionId" @bind-Value="customer.TaxConditionId" class="form-control">
<option value="">-- Seleccionar --</option>
@foreach (var tax in taxConditions)
{
<option value="@tax.Id">@tax.Description</option>
}
</InputSelect>
</div>
</div>
<div class="row">
<div class="col-md-4 d-flex align-items-center justify-content-start mt-4">
<div class="form-check form-switch">
<InputCheckbox id="HasCreditAccount" @bind-Value="customer.HasCreditAccount" class="form-check-input" />
<label class="form-check-label ms-2" for="HasCreditAccount">¿Cuenta Corriente?</label>
</div>
</div>
<div class="col-md-4">
<label for="CreditLimit">Límite de Crédito:</label>
<InputNumber id="CreditLimit" @bind-Value="customer.CreditLimit" class="form-control" />
</div>
<div class="col-md-4 d-flex align-items-center justify-content-start mt-4">
<div class="form-check form-switch">
<InputCheckbox id="Active" @bind-Value="customer.Active" class="form-check-input" />
<label class="form-check-label ms-2" for="Active">Activo</label>
</div>
</div>
</div>
<hr />
<h5>Documentos</h5>
<div class="row align-items-end">
<div class="col-sm-4">
<label for="TipoDocumento">Tipo:</label>
<InputSelect id="TipoDocumento" class="form-control" @bind-Value="documentFormModel.DocumenttypesId">
<option value="">-- Seleccionar --</option>
@foreach (var tipo in documentTypes)
{
<option value="@tipo.Id">@tipo.Name</option>
}
</InputSelect>
</div>
<div class="col-sm-4">
<label for="NumeroDocumento">Número:</label>
<InputText id="NumeroDocumento" class="form-control" @bind-Value="documentFormModel.DocumentNumber" />
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-sm btn-success" @onclick="AddCustomerDocument">Agregar documento</button>
</div>
</div>
<br />
@if (customer.PhSCustomerDocuments?.Any() == true)
{
<table class="table table-sm table-bordered">
<thead>
<tr>
<th>Tipo</th>
<th>Número</th>
<th style="width:50px;"></th>
</tr>
</thead>
<tbody>
@foreach (var doc in customer.PhSCustomerDocuments)
{
<tr>
<td>@documentTypes.FirstOrDefault(t => t.Id == doc.DocumenttypesId)?.Name</td>
<td>@doc.DocumentNumber</td>
<td>
<button type="button" class="btn btn-sm btn-danger" @onclick="() => RemoveCustomerDocument(doc)">🗑</button>
</td>
</tr>
}
</tbody>
</table>
}
<hr />
<h5>Direcciones</h5>
@if (customer.PhSCustomerAddresses.Any())
{
<table class="table table-bordered">
<thead>
<tr>
<th>Sucursal</th>
<th>Dirección</th>
<th>Ciudad</th>
<th>Provincia</th>
<th>País</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var address in customer.PhSCustomerAddresses.Select((value, index) => new { value, index }))
{
<tr>
<td>@address.value.BusinessName</td>
<td>@address.value.Streetaddress1</td>
<td>@address.value.City</td>
<td>@address.value.Stateprovince</td>
<td>@address.value.Country</td>
<td>
<button type="button" class="btn btn-sm btn-primary me-1" @onclick="() => EditAddress(address.index)">Editar</button>
<button type="button" class="btn btn-sm btn-danger" @onclick="() => RemoveAddress(address.index)">Eliminar</button>
</td>
</tr>
}
</tbody>
</table>
}
<div class="row align-items-end">
<div class="row mb-3">
<div class="col-md-6">
<input class="form-control" placeholder="Nombre de sucursal" @bind="editingAddress.BusinessName" />
</div>
<div class="col-md-6">
<input class="form-control" placeholder="Dirección línea 1" @bind="editingAddress.Streetaddress1" />
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<input class="form-control" placeholder="Dirección línea 2" @bind="editingAddress.Streetaddress2" />
</div>
<div class="col-md-6">
<input class="form-control" placeholder="Ciudad" @bind="editingAddress.City" />
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<select class="form-control" value="@editingAddress.Country" @onchange="OnCountryChanged">
<option value="">Seleccionar país</option>
@foreach (var country in countries)
{
<option value="@country">@country</option>
}
</select>
</div>
<div class="col-md-6">
@if (editingAddress.Country == "Argentina" && provincesByCountry.TryGetValue("Argentina", out var provincias))
{
<select class="form-control" @bind="editingAddress.Stateprovince">
<option value="">Seleccionar provincia</option>
@foreach (var provincia in provincias)
{
<option value="@provincia">@provincia</option>
}
</select>
}
else
{
<input class="form-control" placeholder="Estado/Provincia" @bind="editingAddress.Stateprovince" />
}
</div>
</div>
<div class="row mb-3">
<div class="col-md-4">
<input class="form-control" placeholder="Código Postal" @bind="editingAddress.Postalcode" />
</div>
<div class="col-md-4">
<input class="form-control" placeholder="Teléfono" @bind="editingAddress.Phonenumber" />
</div>
<div class="col-md-4">
<input class="form-control" placeholder="Email" @bind="editingAddress.Email" />
</div>
</div>
<div class="row mb-3 row align-items-end align-items-center">
<div class="col-sm-8">
<textarea class="form-control" placeholder="Notas" @bind="editingAddress.Notes"></textarea>
</div>
<div class="col-sm-2">
<button type="button" class="btn btn-sm btn-success" @onclick="AddOrUpdateAddress">
@((editingIndex == -1) ? "Agregar dirección" : "Actualizar dirección")
</button>
</div>
</div>
</div>
<div class="mb-3">
@if (editingIndex != -1)
{
<button type="button" class="btn btn-sm btn-secondary ms-2" @onclick="CancelAddressEdit">Cancelar</button>
}
</div>
</EditForm>
</div>
<div class="card-footer">
<div class="d-flex justify-content-end align-items-center py-3">
<button class="btn btn-primary me-2" type="button" @onclick="HandleValidSubmit" disabled="@isSaving">
@(isSaving ? "Guardando..." : "Guardar Cliente") </button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancelar</button>
</div>
</div>
</div>
@code {
[Parameter]
public int? CustomerId { get; set; }
private ECustomer customer { get; set; } = new();
private List<EAccountType> accountTypes = new();
private List<ETaxCondition> taxConditions = new();
private List<EDocumentType> documentTypes = new();
private ECustomerDocument documentFormModel = new();
private bool isSaving = false;
private string returnUrl = "/sales/customers";
private List<string> countries = new() {
"Argentina", "Brasil", "Chile", "Uruguay", "Paraguay", "Estados Unidos", "Canadá",
"México", "Alemania", "Reino Unido", "Francia", "Italia", "España"
};
private Dictionary<string, List<string>> provincesByCountry = new()
{
{
"Argentina", new List<string>
{
"Buenos Aires", "CABA", "Catamarca", "Chaco", "Chubut", "Córdoba", "Corrientes",
"Entre Ríos", "Formosa", "Jujuy", "La Pampa", "La Rioja", "Mendoza", "Misiones",
"Neuquén", "Río Negro", "Salta", "San Juan", "San Luis", "Santa Cruz",
"Santa Fe", "Santiago del Estero", "Tierra del Fuego", "Tucumán"
}
}
};
private ECustomerAddress editingAddress = new();
private int editingIndex = -1;
private void OnCountryChanged(ChangeEventArgs e)
{
var selectedCountry = e.Value?.ToString();
editingAddress.Country = selectedCountry;
editingAddress.Stateprovince = string.Empty; // Resetear la provincia si cambia el país
}
private void AddOrUpdateAddress()
{
var context = new ValidationContext(editingAddress, null, null);
var results = new List<ValidationResult>();
if (!Validator.TryValidateObject(editingAddress, context, results, true))
{
// Mostrar errores en un toast o en pantalla
foreach (var error in results)
{
toastService.ShowError(error.ErrorMessage);
}
return;
}
if (editingIndex == -1)
{
// Agregar nueva dirección
customer.PhSCustomerAddresses.Add(editingAddress);
}
else
{
// Actualizar dirección existente
var existing = customer.PhSCustomerAddresses.ElementAt(editingIndex);
existing.BusinessName = editingAddress.BusinessName;
existing.Streetaddress1 = editingAddress.Streetaddress1;
existing.Streetaddress2 = editingAddress.Streetaddress2;
existing.City = editingAddress.City;
existing.Stateprovince = editingAddress.Stateprovince;
existing.Postalcode = editingAddress.Postalcode;
existing.Country = editingAddress.Country;
existing.Latitude = editingAddress.Latitude;
existing.Longitude = editingAddress.Longitude;
existing.Phonenumber = editingAddress.Phonenumber;
existing.Email = editingAddress.Email;
existing.Notes = editingAddress.Notes;
}
ResetAddressForm();
}
private void EditAddress(int index)
{
var addr = customer.PhSCustomerAddresses.ElementAt(index);
editingAddress = new ECustomerAddress
{
Id = addr.Id, // Incluí el Id como mencionamos antes, para no perder referencia
BusinessName = addr.BusinessName,
Streetaddress1 = addr.Streetaddress1,
Streetaddress2 = addr.Streetaddress2,
City = addr.City,
Stateprovince = addr.Stateprovince,
Postalcode = addr.Postalcode,
Country = addr.Country,
Latitude = addr.Latitude,
Longitude = addr.Longitude,
Phonenumber = addr.Phonenumber,
Email = addr.Email,
Notes = addr.Notes
};
editingIndex = index;
}
private void RemoveAddress(int index)
{
var itemToRemove = customer.PhSCustomerAddresses.ElementAt(index);
customer.PhSCustomerAddresses.Remove(itemToRemove);
ResetAddressForm();
}
private void CancelAddressEdit()
{
ResetAddressForm();
}
private void ResetAddressForm()
{
editingAddress = new();
editingIndex = -1;
}
protected override async Task OnInitializedAsync()
{
await LoadAccountTypes();
await LoadTaxConditions();
await LoadDocumentTypes();
if (CustomerId.HasValue)
{
// Cargar datos del cliente existente desde la API
customer = await _httpClient.GetFromJsonAsync<ECustomer>($"/api/Customer/{CustomerId.Value}") ?? new();
}
}
private async Task LoadAccountTypes()
{
accountTypes = await accountTypeService.GetAllAsync();
}
private async Task LoadTaxConditions()
{
taxConditions = await taxConditionService.GetAllAsync();
}
private async Task LoadDocumentTypes()
{
var result = await _httpClient.GetFromJsonAsync<List<EDocumentType>>("/api/DocumentType/GetAll");
documentTypes = result ?? new();
}
private void AddCustomerDocument()
{
if (!string.IsNullOrWhiteSpace(documentFormModel.DocumentNumber))
{
customer.PhSCustomerDocuments.Add(documentFormModel);
documentFormModel = new();
}
}
private void RemoveCustomerDocument(ECustomerDocument document)
{
customer.PhSCustomerDocuments.Remove(document);
}
private void RemoveCustomerAddress(ECustomerAddress address)
{
customer.PhSCustomerAddresses.Remove(address);
}
private async Task HandleValidSubmit()
{
var parameters = new ModalParameters();
parameters.Add("Message", "¿Desea guardar los cambios del cliente?");
var modal = Modal.Show<ConfirmModal>("Confirmacion", parameters);
var result = await modal.Result;
if (result.Cancelled)
return;
try
{
HttpResponseMessage response;
if (CustomerId.HasValue)
{
response = await _httpClient.PutAsJsonAsync("/api/Customer/Update", customer);
}
else
{
response = await _httpClient.PostAsJsonAsync("/api/Customer/Create", customer);
}
if (response.IsSuccessStatusCode)
{
toastService.ShowSuccess("Cliente guardado exitosamente");
Navigation.NavigateTo(returnUrl);
}
else
{
var error = await response.Content.ReadAsStringAsync();
toastService.ShowError($"Error: {error}");
}
}
catch (Exception ex)
{
toastService.ShowError($"Error: {ex.Message}");
}
}
private void Cancel()
{
Navigation.NavigateTo(returnUrl);
}
}