2025-09-05 16:31:58 -03:00
|
|
|
|
@page "/expeditions"
|
|
|
|
|
|
@using Domain.Dtos
|
|
|
|
|
|
@using Domain.Dtos.Stock
|
|
|
|
|
|
@using Domain.Generics
|
|
|
|
|
|
@using System.Text.Json
|
2026-03-14 21:23:06 -03:00
|
|
|
|
@using phronCare.UIBlazor.Shared.Modals
|
2025-09-05 16:31:58 -03:00
|
|
|
|
@using phronCare.UIBlazor.Services.Stock.Expeditions
|
2025-09-09 23:54:11 -03:00
|
|
|
|
@inject IExpeditionService expeditionService
|
2025-09-05 16:31:58 -03:00
|
|
|
|
|
|
|
|
|
|
@inject NavigationManager Nav
|
|
|
|
|
|
@inject IToastService Toast
|
2026-03-14 21:23:06 -03:00
|
|
|
|
@inject IModalService Modal
|
2025-09-05 16:31:58 -03:00
|
|
|
|
|
|
|
|
|
|
<div class="card shadow-sm mb-3" style="zoom: 0.8;">
|
|
|
|
|
|
<div class="card-header py-2">
|
|
|
|
|
|
<div class="d-flex justify-content-center align-items-center">
|
|
|
|
|
|
<h3 class="card-title m-0">Consulta de Expediciones</h3>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="card-body">
|
|
|
|
|
|
<EditForm Model="@filters" OnValidSubmit="@Search">
|
|
|
|
|
|
<div class="row g-2 align-items-end">
|
|
|
|
|
|
<!-- En monitores grandes queda todo en una fila (col-xxl-2 = 6 columnas por fila) -->
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="number" class="form-label mb-1">Número</label>
|
|
|
|
|
|
<InputText id="number" class="form-control form-control-sm" @bind-Value="filters.Number" />
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="status" class="form-label mb-1">Estado</label>
|
|
|
|
|
|
<InputSelect id="status" class="form-select form-select-sm" @bind-Value="filters.Status">
|
2025-09-05 16:31:58 -03:00
|
|
|
|
<option value="">(Todos)</option>
|
|
|
|
|
|
<option value="Emitida">Emitida</option>
|
|
|
|
|
|
<option value="EnTransito">En tránsito</option>
|
|
|
|
|
|
<option value="EnDestino">En destino</option>
|
|
|
|
|
|
<option value="Retorno">Retorno</option>
|
|
|
|
|
|
<option value="Cerrada">Cerrada</option>
|
|
|
|
|
|
<option value="Anulada">Anulada</option>
|
|
|
|
|
|
</InputSelect>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="from" class="form-label mb-1">Fecha desde</label>
|
|
|
|
|
|
<InputDate id="from" class="form-control form-control-sm" @bind-Value="filters.From" />
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="to" class="form-label mb-1">Fecha hasta</label>
|
|
|
|
|
|
<InputDate id="to" class="form-control form-control-sm" @bind-Value="filters.To" />
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="location" class="form-label mb-1">Ubicación</label>
|
|
|
|
|
|
<InputNumber id="location" class="form-control form-control-sm" @bind-Value="filters.LocationId" />
|
2025-09-05 16:31:58 -03:00
|
|
|
|
@* TODO: reemplazar por BlazoredTypeahead cuando conectes lookup de ubicaciones *@
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xxl-2">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<label for="pageg" class="form-label mb-1">Tam. página</label>
|
|
|
|
|
|
<InputSelect id="pageg"class="form-select form-select-sm" @bind-Value="pageSize" @onchange="@(e => ChangePageSize(e.Value?.ToString()))">
|
2025-09-05 16:31:58 -03:00
|
|
|
|
<option value="10">10</option>
|
|
|
|
|
|
<option value="20">20</option>
|
|
|
|
|
|
<option value="50">50</option>
|
|
|
|
|
|
</InputSelect>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="d-flex justify-content-end gap-2 mt-3">
|
|
|
|
|
|
<button class="btn btn-primary rounded-pill">
|
|
|
|
|
|
<i class="fas fa-search me-1"></i> Buscar
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn btn-success rounded-pill" @onclick="Create">
|
|
|
|
|
|
<i class="fas fa-plus me-1"></i> Nuevo
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn btn-secondary rounded-pill" @onclick="Clear">
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<i class="fas fa-eraser me-1"></i> Limpiar
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</button>
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<button class="btn btn-success rounded-pill" @onclick="ExportarExcel">
|
|
|
|
|
|
<i class="fas fa-file-excel me-1"></i> Excel
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</EditForm>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="card shadow-sm" style="zoom:0.8;">
|
|
|
|
|
|
<div class="table-responsive">
|
|
|
|
|
|
<table class="table table-sm align-middle mb-0">
|
|
|
|
|
|
<thead class="table-light">
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<th style="width:160px">Nº</th>
|
|
|
|
|
|
<th style="width:120px">Fecha</th>
|
|
|
|
|
|
<th style="width:140px">Estado</th>
|
|
|
|
|
|
<th style="width:200px">Referencia Ext.</th>
|
|
|
|
|
|
<th style="width:220px">Paciente</th>
|
|
|
|
|
|
<th style="width:220px">Médico</th>
|
|
|
|
|
|
<th style="width:220px">Hospital</th>
|
|
|
|
|
|
<th>Observaciones</th>
|
|
|
|
|
|
<th style="width:180px" class="text-end">Acciones</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
@if (result?.Items?.Any() == true)
|
|
|
|
|
|
{
|
|
|
|
|
|
@foreach (var e in result!.Items!)
|
|
|
|
|
|
{
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<td class="fw-semibold">@e.Expeditionnumber</td>
|
|
|
|
|
|
<td>@e.Issuedate.ToString("yyyy-MM-dd")</td>
|
|
|
|
|
|
<td>@e.Status</td>
|
|
|
|
|
|
<td>@e.ExternalReference</td>
|
|
|
|
|
|
<td class="text-truncate" style="max-width: 220px">@GetPatient(e.ExtrainfoJson)</td>
|
|
|
|
|
|
<td class="text-truncate" style="max-width: 220px">@GetProfessional(e.ExtrainfoJson)</td>
|
|
|
|
|
|
<td class="text-truncate" style="max-width: 220px">@GetInstitution(e.ExtrainfoJson)</td>
|
|
|
|
|
|
<td class="text-truncate" style="max-width: 420px">@e.Observations</td>
|
|
|
|
|
|
<td class="text-end">
|
|
|
|
|
|
<div class="btn-group btn-group-sm">
|
2026-03-14 21:23:06 -03:00
|
|
|
|
<button class="btn btn-outline-primary rounded-pill" title="PDF" @onclick="() => ViewPdf(e.Id, e.Expeditionnumber)">
|
|
|
|
|
|
<i class="fas fa-file-pdf"></i>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn btn-outline-secondary rounded-pill" title="Ver" @onclick="() => OpenDetailAsync(e)">
|
|
|
|
|
|
<i class="fas fa-eye"></i>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
|
|
@if (CanMarkInTransit(e))
|
|
|
|
|
|
{
|
|
|
|
|
|
<button class="btn btn-outline-warning rounded-pill"
|
|
|
|
|
|
title="Pasar a En tránsito"
|
|
|
|
|
|
@onclick="() => ConfirmMarkInTransitAsync(e)">
|
|
|
|
|
|
<i class="fas fa-truck"></i>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
}
|
2025-09-05 16:31:58 -03:00
|
|
|
|
</div>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-11 22:41:46 -03:00
|
|
|
|
else if (IsLoading)
|
|
|
|
|
|
{
|
|
|
|
|
|
<tr><td colspan="9" class="text-center text-muted py-4">Cargando...</td></tr>
|
|
|
|
|
|
}
|
2025-09-05 16:31:58 -03:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-09-11 22:41:46 -03:00
|
|
|
|
<tr><td colspan="9" class="text-center text-muted py-4">Sin resultados</td></tr>
|
2025-09-05 16:31:58 -03:00
|
|
|
|
}
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Paginación debajo -->
|
|
|
|
|
|
<div class="d-flex justify-content-between align-items-center px-3 py-2 border-top">
|
|
|
|
|
|
<div class="small text-muted">
|
|
|
|
|
|
@if (result is not null && result.TotalItems > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
var from = ((page - 1) * pageSize) + 1;
|
|
|
|
|
|
var to = Math.Min(page * pageSize, result.TotalItems);
|
|
|
|
|
|
<text>Mostrando @from–@to de @result.TotalItems</text>
|
|
|
|
|
|
}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="btn-group">
|
|
|
|
|
|
<button class="btn btn-outline-secondary btn-sm rounded-pill"
|
|
|
|
|
|
disabled="@(page<=1)" @onclick="PrevPage">
|
|
|
|
|
|
<i class="fas fa-chevron-left me-1"></i> Anterior
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button class="btn btn-outline-secondary btn-sm rounded-pill"
|
|
|
|
|
|
disabled="@(result is null || page>=TotalPages)" @onclick="NextPage">
|
|
|
|
|
|
Siguiente <i class="fas fa-chevron-right ms-1"></i>
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Drawer de detalle -->
|
|
|
|
|
|
<ExpeditionDetailDrawer Expedition="@selected"
|
|
|
|
|
|
Visible="@drawerOpen"
|
|
|
|
|
|
VisibleChanged="@(v => drawerOpen = v)"
|
|
|
|
|
|
ExportPdfRequested="OnExportPdfRequested"
|
|
|
|
|
|
Loading="@loadingDetail" />
|
|
|
|
|
|
|
|
|
|
|
|
@code {
|
2025-09-09 23:54:11 -03:00
|
|
|
|
private LSProductSearchParams SearchParams = new() { Page = 1, PageSize = 10 };
|
|
|
|
|
|
|
2025-09-11 22:41:46 -03:00
|
|
|
|
private Filters filters = new();
|
|
|
|
|
|
private PagedResult<ExpeditionDto>? result;
|
|
|
|
|
|
private bool IsLoading;
|
|
|
|
|
|
|
|
|
|
|
|
private int page = 1;
|
|
|
|
|
|
private int pageSize = 10;
|
|
|
|
|
|
private int TotalPages => result is null ? 1 : (int)Math.Ceiling((double)result.TotalItems / result.PageSize);
|
2025-09-05 16:31:58 -03:00
|
|
|
|
|
|
|
|
|
|
private ExpeditionDto? selected;
|
|
|
|
|
|
private bool drawerOpen;
|
|
|
|
|
|
private bool loadingDetail;
|
|
|
|
|
|
|
|
|
|
|
|
private async Task OpenDetailAsync(ExpeditionDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Abro el drawer con lo que ya tengo (encabezado)
|
2026-03-14 21:23:06 -03:00
|
|
|
|
loadingDetail = true;
|
2025-09-05 16:31:58 -03:00
|
|
|
|
drawerOpen = true;
|
|
|
|
|
|
selected = dto;
|
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
|
|
|
|
|
|
|
// Traigo el DTO completo (incluye Items)
|
|
|
|
|
|
var full = await expeditionService.GetDtoByIdAsync(dto.Id);
|
|
|
|
|
|
if (full is not null)
|
|
|
|
|
|
{
|
|
|
|
|
|
selected = full; // ahora sí con Items
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Toast.ShowError("No se pudo cargar el detalle de la expedición.");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// opcional: si querés mostrar un spinner en el drawer mientras carga
|
|
|
|
|
|
loadingDetail = false;
|
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task Search()
|
|
|
|
|
|
{
|
2025-09-11 22:41:46 -03:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
IsLoading = true;
|
|
|
|
|
|
result = await expeditionService.SearchAsync(
|
|
|
|
|
|
expeditionNumber: filters.Number,
|
|
|
|
|
|
status: filters.Status,
|
|
|
|
|
|
issueDateFrom: filters.From,
|
|
|
|
|
|
issueDateTo: filters.To,
|
|
|
|
|
|
locationId: filters.LocationId,
|
|
|
|
|
|
page: page,
|
|
|
|
|
|
pageSize: pageSize);
|
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Toast.ShowError(ex.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
IsLoading = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-05 16:31:58 -03:00
|
|
|
|
|
|
|
|
|
|
private void Clear()
|
|
|
|
|
|
{
|
|
|
|
|
|
filters = new();
|
|
|
|
|
|
page = 1;
|
|
|
|
|
|
result = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Create()
|
|
|
|
|
|
{
|
|
|
|
|
|
Nav.NavigateTo("/expeditions/create");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-09 23:54:11 -03:00
|
|
|
|
private async Task ExportarExcel()
|
|
|
|
|
|
{
|
|
|
|
|
|
SearchParams.Page = 1;
|
|
|
|
|
|
SearchParams.PageSize = int.MaxValue; // Exportar todos los resultados
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await expeditionService.ExportFilteredAsync(SearchParams);
|
|
|
|
|
|
Toast.ShowSuccess("Exportación completada.");
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Toast.ShowError($"Error: {ex.Message}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// private async Task ExportCurrent()
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // Opcional: /api/lsm/expeditions/export?{filtros}
|
|
|
|
|
|
// Toast.ShowInfo("Export en preparación.");
|
|
|
|
|
|
// }
|
2025-09-05 16:31:58 -03:00
|
|
|
|
|
|
|
|
|
|
private async Task ViewPdf(int id, string number)
|
|
|
|
|
|
{
|
|
|
|
|
|
await expeditionService.ExportPdfAsync(id, number);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OpenDetail(ExpeditionDto dto)
|
|
|
|
|
|
{
|
|
|
|
|
|
selected = dto;
|
|
|
|
|
|
drawerOpen = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task OnExportPdfRequested((int Id, string Number) payload)
|
|
|
|
|
|
{
|
|
|
|
|
|
await expeditionService.ExportPdfAsync(payload.Id, payload.Number);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task PrevPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (page <= 1) return;
|
|
|
|
|
|
page--;
|
|
|
|
|
|
await Search();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task NextPage()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (result is null || page >= TotalPages) return;
|
|
|
|
|
|
page++;
|
|
|
|
|
|
await Search();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void ChangePageSize(string? value)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (int.TryParse(value, out var newSize) && newSize > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
pageSize = newSize;
|
|
|
|
|
|
page = 1;
|
|
|
|
|
|
_ = Search();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class Filters
|
|
|
|
|
|
{
|
|
|
|
|
|
public string? Number { get; set; }
|
|
|
|
|
|
public string? Status { get; set; }
|
|
|
|
|
|
public DateTime? From { get; set; }
|
|
|
|
|
|
public DateTime? To { get; set; }
|
|
|
|
|
|
public int? LocationId { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
private static string? GetProfessional(string? json) => TryGetString(json, "Professional");
|
|
|
|
|
|
private static string? GetInstitution(string? json) => TryGetString(json, "Institution");
|
|
|
|
|
|
private static string? GetPatient(string? json) => TryGetString(json, "Patient");
|
|
|
|
|
|
private static string? GetSurgeryDateShort(string? json)
|
|
|
|
|
|
=> TryGetDate(json, "SurgeryDate")?.ToString("dd/MM/yyyy");
|
|
|
|
|
|
|
|
|
|
|
|
private static string? TryGetString(string? json, string propName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(json)) return null;
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
using var doc = JsonDocument.Parse(json);
|
|
|
|
|
|
var root = doc.RootElement;
|
|
|
|
|
|
if (root.ValueKind != JsonValueKind.Object) return null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var p in root.EnumerateObject())
|
|
|
|
|
|
if (string.Equals(p.Name, propName, StringComparison.OrdinalIgnoreCase)
|
|
|
|
|
|
&& p.Value.ValueKind == JsonValueKind.String)
|
|
|
|
|
|
return p.Value.GetString();
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch { return null; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static DateTime? TryGetDate(string? json, string propName)
|
|
|
|
|
|
{
|
|
|
|
|
|
var s = TryGetString(json, propName);
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(s)) return null;
|
|
|
|
|
|
if (DateTime.TryParse(s, out var dt)) return dt;
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2026-03-14 21:23:06 -03:00
|
|
|
|
// private bool CanMarkInTransit(ExpeditionDto expedition)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (expedition == null)
|
|
|
|
|
|
// return false;
|
|
|
|
|
|
|
|
|
|
|
|
// if (!string.IsNullOrWhiteSpace(expedition.StatusLabel))
|
|
|
|
|
|
// return string.Equals(expedition.StatusLabel, "Emitida", StringComparison.OrdinalIgnoreCase);
|
|
|
|
|
|
|
|
|
|
|
|
// return expedition.Status == 1;
|
|
|
|
|
|
// }
|
|
|
|
|
|
private bool CanMarkInTransit(ExpeditionDto expedition)
|
|
|
|
|
|
{
|
|
|
|
|
|
return expedition is not null && expedition.Status == 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
private async Task ConfirmMarkInTransitAsync(ExpeditionDto expedition)
|
|
|
|
|
|
{
|
|
|
|
|
|
var parameters = new ModalParameters();
|
|
|
|
|
|
parameters.Add(nameof(ConfirmModal.Title), "Confirmar cambio de estado");
|
|
|
|
|
|
parameters.Add(nameof(ConfirmModal.Message),
|
|
|
|
|
|
$"La expedición '{expedition.Expeditionnumber}' pasará a estado 'En tránsito'. ¿Desea continuar?");
|
|
|
|
|
|
|
|
|
|
|
|
var modal = Modal.Show<ConfirmModal>("Confirmar", parameters);
|
|
|
|
|
|
var resultModal = await modal.Result;
|
|
|
|
|
|
|
|
|
|
|
|
if (resultModal.Cancelled)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await expeditionService.MarkInTransitAsync(expedition.Id);
|
|
|
|
|
|
|
|
|
|
|
|
Toast.ShowSuccess($"La expedición '{expedition.Expeditionnumber}' pasó a 'En tránsito' correctamente.");
|
|
|
|
|
|
|
|
|
|
|
|
await Search();
|
|
|
|
|
|
|
|
|
|
|
|
if (selected is not null && selected.Id == expedition.Id)
|
|
|
|
|
|
{
|
|
|
|
|
|
selected = await expeditionService.GetDtoByIdAsync(expedition.Id);
|
|
|
|
|
|
StateHasChanged();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
Toast.ShowError(string.IsNullOrWhiteSpace(ex.Message)
|
|
|
|
|
|
? "No se pudo pasar la expedición a 'En tránsito'."
|
|
|
|
|
|
: ex.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-05 16:31:58 -03:00
|
|
|
|
}
|