Update Model Quote and Adjustment in API
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m24s
All checks were successful
CI/CD Pipeline / Build and Deploy with Docker Compose (push) Successful in 5m24s
This commit is contained in:
parent
5c2489b168
commit
6476cfd701
@ -1,5 +1,6 @@
|
||||
using Domain.Entities;
|
||||
using Domain.Generics;
|
||||
using Models.Helpers;
|
||||
using Models.Interfaces;
|
||||
using System.Reflection;
|
||||
using Transversal.Services;
|
||||
@ -20,7 +21,7 @@ namespace PhronCare.Core.Services.Sales
|
||||
private readonly IPhSFormSeriesRepository _formSeriesRepository = formSeriesRepository;
|
||||
#endregion
|
||||
|
||||
#region Métodos
|
||||
#region Presupuestos
|
||||
public async Task<PagedResult<EQuoteHeader>> GetAllQuotesAsync(int page = 1, int pageSize = 50)
|
||||
{
|
||||
return await _quoteHeaderRepository.GetAllAsync(page, pageSize);
|
||||
@ -33,12 +34,23 @@ namespace PhronCare.Core.Services.Sales
|
||||
|
||||
public async Task<IEnumerable<EQuoteHeader>> GetQuotesByCustomerAsync(int customerId)
|
||||
{
|
||||
var quotes = await _quoteHeaderRepository.GetByCustomerIdAsync(customerId);
|
||||
return quotes;
|
||||
return await _quoteHeaderRepository.GetByCustomerIdAsync(customerId);
|
||||
}
|
||||
public async Task<PagedResult<EQuoteHeader>> SearchQuotesAsync(int? customerId, string? quoteNumber, int? professionalId, int? institutionId, int? patientId, DateTime? issueDateFrom, DateTime? issueDateTo, string? status, int page = 1, int pageSize = 50)
|
||||
|
||||
public async Task<PagedResult<EQuoteHeader>> SearchQuotesAsync(
|
||||
int? customerId,
|
||||
string? quoteNumber,
|
||||
int? professionalId,
|
||||
int? institutionId,
|
||||
int? patientId,
|
||||
DateTime? issueDateFrom,
|
||||
DateTime? issueDateTo,
|
||||
string? status,
|
||||
int page = 1,
|
||||
int pageSize = 50)
|
||||
{
|
||||
return await _quoteHeaderRepository.SearchAsync(customerId,
|
||||
return await _quoteHeaderRepository.SearchAsync(
|
||||
customerId,
|
||||
quoteNumber,
|
||||
professionalId,
|
||||
institutionId,
|
||||
@ -54,14 +66,12 @@ namespace PhronCare.Core.Services.Sales
|
||||
{
|
||||
// Obtener el próximo número de documento
|
||||
var nextNumber = await _formSeriesRepository.GetNextInternalNumberAsync(formSeriesId);
|
||||
|
||||
// Asignar el número al presupuesto
|
||||
quote.Quotenumber = nextNumber.ToString();
|
||||
|
||||
// Crear el presupuesto
|
||||
// Crear encabezado
|
||||
var newQuote = await _quoteHeaderRepository.AddAsync(quote);
|
||||
|
||||
// Crear los detalles asociados
|
||||
// Crear detalles asociados
|
||||
if (quote.PhSQuoteDetails != null)
|
||||
{
|
||||
foreach (var detail in quote.PhSQuoteDetails)
|
||||
@ -71,7 +81,7 @@ namespace PhronCare.Core.Services.Sales
|
||||
}
|
||||
}
|
||||
|
||||
// Crear los roles asociados
|
||||
// Crear roles asociados
|
||||
if (quote.PhSQuoteRoles != null)
|
||||
{
|
||||
foreach (var role in quote.PhSQuoteRoles)
|
||||
@ -93,12 +103,35 @@ namespace PhronCare.Core.Services.Sales
|
||||
{
|
||||
await _quoteHeaderRepository.DeleteAsync(id);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Ajustes
|
||||
public async Task<IEnumerable<EQuoteAdjustment>> GetAdjustmentsByQuoteIdAsync(int quoteId)
|
||||
{
|
||||
return await _quoteHeaderRepository.GetAdjustmentsByQuoteIdAsync(quoteId);
|
||||
}
|
||||
|
||||
public async Task<EQuoteAdjustment> AddAdjustmentAsync(EQuoteAdjustment adjustment)
|
||||
{
|
||||
return await _quoteHeaderRepository.AddAdjustmentAsync(adjustment);
|
||||
}
|
||||
|
||||
public async Task UpdateAdjustmentAsync(EQuoteAdjustment adjustment)
|
||||
{
|
||||
await _quoteHeaderRepository.UpdateAdjustmentAsync(adjustment);
|
||||
}
|
||||
|
||||
public async Task DeleteAdjustmentAsync(int adjustmentId)
|
||||
{
|
||||
await _quoteHeaderRepository.DeleteAdjustmentAsync(adjustmentId);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Exportación
|
||||
public async Task<byte[]> ExportFilteredQuotesToExcelAsync(QuoteSearchParams searchParams)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Buscar los presupuestos con los filtros indicados
|
||||
var searchResult = await SearchQuotesAsync(
|
||||
searchParams.CustomerId,
|
||||
searchParams.QuoteNumber,
|
||||
@ -109,36 +142,28 @@ namespace PhronCare.Core.Services.Sales
|
||||
searchParams.IssueDateTo,
|
||||
searchParams.Status,
|
||||
searchParams.Page,
|
||||
searchParams.PageSize
|
||||
);
|
||||
searchParams.PageSize);
|
||||
|
||||
// Verificar si hay resultados
|
||||
if (searchResult?.Items == null || !searchResult.Items.Any())
|
||||
{
|
||||
throw new Exception("No se encontraron presupuestos para exportar.");
|
||||
}
|
||||
|
||||
// Instanciar exportador
|
||||
var stream = new XLSXExportBase();
|
||||
|
||||
// Armar los datos a exportar
|
||||
var quotesData = searchResult.Items.Select(q => new
|
||||
{
|
||||
NúmeroPresupuesto = q.Quotenumber,
|
||||
Estado = q.Status,
|
||||
FechaEmisión = q.Issuedate.ToString("yyyy-MM-dd"),
|
||||
FechaTentativa = q.Estimateddate?.ToString("yyyy-MM-dd"),
|
||||
ImporteEstimado = q.Estimatedamount,
|
||||
ImporteAprobado = q.Approvedamount,
|
||||
Profesional = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == "PhS_Professionals")?.Entitytype,
|
||||
Institución = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == "PhS_Institutions")?.Entitytype,
|
||||
Paciente = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == "PhS_Patients")?.Entitytype
|
||||
Profesional = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Professional)?.Entitytype,
|
||||
Institución = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Institution)?.Entitytype,
|
||||
Paciente = q.PhSQuoteRoles.FirstOrDefault(r => r.Entitytype == PhSEntityTypes.Patient)?.Entitytype
|
||||
}).ToList();
|
||||
|
||||
// Generar archivo Excel
|
||||
var excelFile = stream.ExportExcel(quotesData);
|
||||
|
||||
return excelFile;
|
||||
return stream.ExportExcel(quotesData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
42
Domain/Entities/EQuoteAdjustment.cs
Normal file
42
Domain/Entities/EQuoteAdjustment.cs
Normal file
@ -0,0 +1,42 @@
|
||||
namespace Domain.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// Tabla de ajustes aplicados a presupuestos comerciales
|
||||
/// </summary>
|
||||
public class EQuoteAdjustment
|
||||
{
|
||||
/// <summary>
|
||||
/// ID interno del ajuste aplicado al presupuesto
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// FK al presupuesto (PhS_QuoteHeaders)
|
||||
/// </summary>
|
||||
public int QuoteheaderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Código del motivo de ajuste (FK a PhS_AdjustmentReasons)
|
||||
/// </summary>
|
||||
public string ReasonCode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Importe del ajuste realizado (positivo o nulo)
|
||||
/// </summary>
|
||||
public decimal? Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descripción adicional del ajuste
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de registro del ajuste
|
||||
/// </summary>
|
||||
public DateTime Createdat { get; set; }
|
||||
|
||||
//public virtual PhSQuoteHeader Quoteheader { get; set; } = null!;
|
||||
|
||||
//public virtual PhSAdjustmentReason ReasonCodeNavigation { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@
|
||||
/// <summary>
|
||||
/// Tabla de cabeceras de presupuestos
|
||||
/// </summary>
|
||||
///
|
||||
public class EQuoteHeader
|
||||
{
|
||||
/// <summary>
|
||||
@ -15,6 +16,11 @@
|
||||
/// </summary>
|
||||
public Guid TicketId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Número visible del presupuesto
|
||||
/// </summary>
|
||||
public string Quotenumber { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Cliente asociado
|
||||
/// </summary>
|
||||
@ -30,11 +36,6 @@
|
||||
/// </summary>
|
||||
public int PeopleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Estado: E (Emitido), A (Aprobado), AC (Aprobado para cirugia), etc.
|
||||
/// </summary>
|
||||
public string Status { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de emisión
|
||||
/// </summary>
|
||||
@ -51,9 +52,24 @@
|
||||
public DateTime? Estimateddate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Importe estimado total
|
||||
/// Código de moneda pactada (ISO 4217). Ej: ARS, USD
|
||||
/// </summary>
|
||||
public decimal? Estimatedamount { get; set; }
|
||||
public string Currency { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo de cambio pactado para conversión a pesos argentinos
|
||||
/// </summary>
|
||||
public decimal? Exchangerate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total del presupuesto expresado en moneda extranjera
|
||||
/// </summary>
|
||||
public decimal? TotalForeign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total final del presupuesto expresado en moneda local, considerando ajustes o acuerdos comerciales
|
||||
/// </summary>
|
||||
public decimal? Total { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Importe aprobado
|
||||
@ -61,9 +77,19 @@
|
||||
public decimal? Approvedamount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Número visible del presupuesto
|
||||
/// Estado: E (Emitido), A (Aprobado), AC (Aprobado para cirugia), etc.
|
||||
/// </summary>
|
||||
public string Quotenumber { get; set; } = null!;
|
||||
public string Status { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la cirugía se realizará fuera de la ciudad/localidad habitual (“out of town”)
|
||||
/// </summary>
|
||||
public bool OutOfTown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instrucción dirigida al área de logística para detallar qué debe prepararse o despacharse (ej: “CMF 1.5 + INSTRUMENTAL”)
|
||||
/// </summary>
|
||||
public string? DispatchInstruction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cantidad de impresiones
|
||||
@ -85,9 +111,98 @@
|
||||
/// </summary>
|
||||
public DateTime? Modifiedat { get; set; }
|
||||
|
||||
public virtual ICollection<EQuoteAdjustment> PhSQuoteAdjustments { get; set; } = new List<EQuoteAdjustment>();
|
||||
|
||||
public virtual ICollection<EQuoteDetail> PhSQuoteDetails { get; set; } = new List<EQuoteDetail>();
|
||||
|
||||
public virtual ICollection<EQuoteRole> PhSQuoteRoles { get; set; } = new List<EQuoteRole>();
|
||||
}
|
||||
|
||||
}
|
||||
//public class EQuoteHeader
|
||||
//{
|
||||
// /// <summary>
|
||||
// /// ID interno
|
||||
// /// </summary>
|
||||
// public int Id { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Relación con Tickets
|
||||
// /// </summary>
|
||||
// public Guid TicketId { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Cliente asociado
|
||||
// /// </summary>
|
||||
// public int CustomerId { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Unidad de negocio
|
||||
// /// </summary>
|
||||
// public int BusinessunitId { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Identificador único del vendedor
|
||||
// /// </summary>
|
||||
// public int PeopleId { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Estado: E (Emitido), A (Aprobado), AC (Aprobado para cirugia), etc.
|
||||
// /// </summary>
|
||||
// public string Status { get; set; } = null!;
|
||||
|
||||
// /// <summary>
|
||||
// /// Fecha de emisión
|
||||
// /// </summary>
|
||||
// public DateTime Issuedate { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Fecha de aprobación
|
||||
// /// </summary>
|
||||
// public DateOnly? Approvaldate { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Fecha tentativa (de cirugía por ej.)
|
||||
// /// </summary>
|
||||
// public DateTime? Estimateddate { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Importe estimado total
|
||||
// /// </summary>
|
||||
// public decimal? Estimatedamount { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Importe aprobado
|
||||
// /// </summary>
|
||||
// public decimal? Approvedamount { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Número visible del presupuesto
|
||||
// /// </summary>
|
||||
// public string Quotenumber { get; set; } = null!;
|
||||
|
||||
// /// <summary>
|
||||
// /// Cantidad de impresiones
|
||||
// /// </summary>
|
||||
// public int Printcount { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Observaciones internas
|
||||
// /// </summary>
|
||||
// public string? Observations { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Fecha de creación
|
||||
// /// </summary>
|
||||
// public DateTime Createdat { get; set; }
|
||||
|
||||
// /// <summary>
|
||||
// /// Fecha de modificación
|
||||
// /// </summary>
|
||||
// public DateTime? Modifiedat { get; set; }
|
||||
|
||||
// public virtual ICollection<EQuoteDetail> PhSQuoteDetails { get; set; } = new List<EQuoteDetail>();
|
||||
|
||||
// public virtual ICollection<EQuoteRole> PhSQuoteRoles { get; set; } = new List<EQuoteRole>();
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\maski\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\maski\.nuget\packages\" />
|
||||
|
||||
9
Models/Helpers/PhSEntityTypes.cs
Normal file
9
Models/Helpers/PhSEntityTypes.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace Models.Helpers
|
||||
{
|
||||
public static class PhSEntityTypes
|
||||
{
|
||||
public const string Professional = "PhS_Professionals";
|
||||
public const string Institution = "PhS_Institutions";
|
||||
public const string Patient = "PhS_Patients";
|
||||
}
|
||||
}
|
||||
@ -6,11 +6,20 @@ namespace Models.Interfaces
|
||||
public interface IPhSQuoteHeaderRepository
|
||||
{
|
||||
Task<PagedResult<EQuoteHeader>> GetAllAsync(int page = 1, int pageSize = 50);
|
||||
Task<IEnumerable<EQuoteHeader>> GetByCustomerIdAsync(int customerId);
|
||||
Task<EQuoteHeader?> GetByIdAsync(int id);
|
||||
Task<PagedResult<EQuoteHeader>> SearchAsync(int? customerId, string? quoteNumber, int? professionalId, int? institutionId, int? patientId, DateTime? issueDateFrom, DateTime? issueDateTo, string? status, int page = 1, int pageSize = 50);
|
||||
Task<IEnumerable<EQuoteHeader>> GetByCustomerIdAsync(int customerId);
|
||||
Task<PagedResult<EQuoteHeader>> SearchAsync(int? customerId, string? quoteNumber, int? professionalId,
|
||||
int? institutionId, int? patientId, DateTime? issueDateFrom, DateTime? issueDateTo, string? status,
|
||||
int page = 1, int pageSize = 50);
|
||||
|
||||
Task<EQuoteHeader> AddAsync(EQuoteHeader quoteHeader);
|
||||
Task UpdateAsync(EQuoteHeader quoteHeader);
|
||||
Task DeleteAsync(int id);
|
||||
|
||||
// Ajustes
|
||||
Task<IEnumerable<EQuoteAdjustment>> GetAdjustmentsByQuoteIdAsync(int quoteId);
|
||||
Task<EQuoteAdjustment> AddAdjustmentAsync(EQuoteAdjustment adjustment);
|
||||
Task UpdateAdjustmentAsync(EQuoteAdjustment adjustment);
|
||||
Task DeleteAdjustmentAsync(int adjustmentId);
|
||||
}
|
||||
}
|
||||
|
||||
17
Models/Models/PhSAdjustmentReason.cs
Normal file
17
Models/Models/PhSAdjustmentReason.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Models.Models;
|
||||
|
||||
public partial class PhSAdjustmentReason
|
||||
{
|
||||
public string Code { get; set; } = null!;
|
||||
|
||||
public string Description { get; set; } = null!;
|
||||
|
||||
public bool Active { get; set; }
|
||||
|
||||
public DateTime Createdat { get; set; }
|
||||
|
||||
public virtual ICollection<PhSQuoteAdjustment> PhSQuoteAdjustments { get; set; } = new List<PhSQuoteAdjustment>();
|
||||
}
|
||||
44
Models/Models/PhSQuoteAdjustment.cs
Normal file
44
Models/Models/PhSQuoteAdjustment.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Models.Models;
|
||||
|
||||
/// <summary>
|
||||
/// Tabla de ajustes aplicados a presupuestos comerciales
|
||||
/// </summary>
|
||||
public partial class PhSQuoteAdjustment
|
||||
{
|
||||
/// <summary>
|
||||
/// ID interno del ajuste aplicado al presupuesto
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// FK al presupuesto (PhS_QuoteHeaders)
|
||||
/// </summary>
|
||||
public int QuoteheaderId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Código del motivo de ajuste (FK a PhS_AdjustmentReasons)
|
||||
/// </summary>
|
||||
public string ReasonCode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Importe del ajuste realizado (positivo o nulo)
|
||||
/// </summary>
|
||||
public decimal? Amount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Descripción adicional del ajuste
|
||||
/// </summary>
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de registro del ajuste
|
||||
/// </summary>
|
||||
public DateTime Createdat { get; set; }
|
||||
|
||||
public virtual PhSQuoteHeader Quoteheader { get; set; } = null!;
|
||||
|
||||
public virtual PhSAdjustmentReason ReasonCodeNavigation { get; set; } = null!;
|
||||
}
|
||||
@ -18,6 +18,11 @@ public partial class PhSQuoteHeader
|
||||
/// </summary>
|
||||
public Guid TicketId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Número visible del presupuesto
|
||||
/// </summary>
|
||||
public string Quotenumber { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Cliente asociado
|
||||
/// </summary>
|
||||
@ -33,11 +38,6 @@ public partial class PhSQuoteHeader
|
||||
/// </summary>
|
||||
public int PeopleId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Estado: E (Emitido), A (Aprobado), AC (Aprobado para cirugia), etc.
|
||||
/// </summary>
|
||||
public string Status { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de emisión
|
||||
/// </summary>
|
||||
@ -54,9 +54,24 @@ public partial class PhSQuoteHeader
|
||||
public DateTime? Estimateddate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Importe estimado total
|
||||
/// Código de moneda pactada (ISO 4217). Ej: ARS, USD
|
||||
/// </summary>
|
||||
public decimal? Estimatedamount { get; set; }
|
||||
public string Currency { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Tipo de cambio pactado para conversión a pesos argentinos
|
||||
/// </summary>
|
||||
public decimal? Exchangerate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total del presupuesto expresado en moneda extranjera
|
||||
/// </summary>
|
||||
public decimal? TotalForeign { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Total final del presupuesto expresado en moneda local, considerando ajustes o acuerdos comerciales
|
||||
/// </summary>
|
||||
public decimal? Total { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Importe aprobado
|
||||
@ -64,9 +79,19 @@ public partial class PhSQuoteHeader
|
||||
public decimal? Approvedamount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Número visible del presupuesto
|
||||
/// Estado: E (Emitido), A (Aprobado), AC (Aprobado para cirugia), etc.
|
||||
/// </summary>
|
||||
public string Quotenumber { get; set; } = null!;
|
||||
public string Status { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Indica si la cirugía se realizará fuera de la ciudad/localidad habitual (“out of town”)
|
||||
/// </summary>
|
||||
public bool OutOfTown { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Instrucción dirigida al área de logística para detallar qué debe prepararse o despacharse (ej: “CMF 1.5 + INSTRUMENTAL”)
|
||||
/// </summary>
|
||||
public string? DispatchInstruction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Cantidad de impresiones
|
||||
@ -88,6 +113,8 @@ public partial class PhSQuoteHeader
|
||||
/// </summary>
|
||||
public DateTime? Modifiedat { get; set; }
|
||||
|
||||
public virtual ICollection<PhSQuoteAdjustment> PhSQuoteAdjustments { get; set; } = new List<PhSQuoteAdjustment>();
|
||||
|
||||
public virtual ICollection<PhSQuoteDetail> PhSQuoteDetails { get; set; } = new List<PhSQuoteDetail>();
|
||||
|
||||
public virtual ICollection<PhSQuoteRole> PhSQuoteRoles { get; set; } = new List<PhSQuoteRole>();
|
||||
|
||||
@ -23,6 +23,8 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
|
||||
public virtual DbSet<PhSAccountType> PhSAccountTypes { get; set; }
|
||||
|
||||
public virtual DbSet<PhSAdjustmentReason> PhSAdjustmentReasons { get; set; }
|
||||
|
||||
public virtual DbSet<PhSBusinessUnit> PhSBusinessUnits { get; set; }
|
||||
|
||||
public virtual DbSet<PhSCustomer> PhSCustomers { get; set; }
|
||||
@ -55,6 +57,8 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
|
||||
public virtual DbSet<PhSProfessionalSpecialty> PhSProfessionalSpecialties { get; set; }
|
||||
|
||||
public virtual DbSet<PhSQuoteAdjustment> PhSQuoteAdjustments { get; set; }
|
||||
|
||||
public virtual DbSet<PhSQuoteDetail> PhSQuoteDetails { get; set; }
|
||||
|
||||
public virtual DbSet<PhSQuoteHeader> PhSQuoteHeaders { get; set; }
|
||||
@ -62,8 +66,15 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
public virtual DbSet<PhSQuoteRole> PhSQuoteRoles { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
|
||||
=> optionsBuilder.UseSqlServer("data source=srv01.saludlab.com.ar,39458;initial catalog=phronCare_OperationsHub;User ID=sa;Password=HS|s[~xxQzTo/n>9jO;encrypt=False;trustServerCertificate=True;MultipleActiveResultSets=True");
|
||||
#region VERSION DOCKER
|
||||
{
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
// Dejarlo vacío para usar la configuración externa desde Program.cs o Startup.cs
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
// => optionsBuilder.UseSqlServer("data source=srv01.saludlab.com.ar,39458;initial catalog=phronCare_OperationsHub;User ID=sa;Password=HS|s[~xxQzTo/n>9jO;encrypt=False;trustServerCertificate=True;MultipleActiveResultSets=True");
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
@ -152,6 +163,28 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
.HasColumnName("name");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhSAdjustmentReason>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Code).HasName("PK__PhS_Adju__357D4CF809676D8C");
|
||||
|
||||
entity.ToTable("PhS_AdjustmentReasons");
|
||||
|
||||
entity.Property(e => e.Code)
|
||||
.HasMaxLength(50)
|
||||
.IsUnicode(false)
|
||||
.HasColumnName("code");
|
||||
entity.Property(e => e.Active)
|
||||
.HasDefaultValue(true)
|
||||
.HasColumnName("active");
|
||||
entity.Property(e => e.Createdat)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("createdat");
|
||||
entity.Property(e => e.Description)
|
||||
.HasMaxLength(100)
|
||||
.HasColumnName("description");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhSBusinessUnit>(entity =>
|
||||
{
|
||||
entity.ToTable("PhS_BusinessUnits");
|
||||
@ -695,6 +728,48 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
.HasColumnName("name");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhSQuoteAdjustment>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__PhS_Quot__3213E83FFBF7D244");
|
||||
|
||||
entity.ToTable("PhS_QuoteAdjustments", tb => tb.HasComment("Tabla de ajustes aplicados a presupuestos comerciales"));
|
||||
|
||||
entity.Property(e => e.Id)
|
||||
.HasComment("ID interno del ajuste aplicado al presupuesto")
|
||||
.HasColumnName("id");
|
||||
entity.Property(e => e.Amount)
|
||||
.HasComment("Importe del ajuste realizado (positivo o nulo)")
|
||||
.HasColumnType("decimal(18, 2)")
|
||||
.HasColumnName("amount");
|
||||
entity.Property(e => e.Createdat)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("Fecha de registro del ajuste")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("createdat");
|
||||
entity.Property(e => e.Description)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("Descripción adicional del ajuste")
|
||||
.HasColumnName("description");
|
||||
entity.Property(e => e.QuoteheaderId)
|
||||
.HasComment("FK al presupuesto (PhS_QuoteHeaders)")
|
||||
.HasColumnName("quoteheader_id");
|
||||
entity.Property(e => e.ReasonCode)
|
||||
.HasMaxLength(50)
|
||||
.IsUnicode(false)
|
||||
.HasComment("Código del motivo de ajuste (FK a PhS_AdjustmentReasons)")
|
||||
.HasColumnName("reason_code");
|
||||
|
||||
entity.HasOne(d => d.Quoteheader).WithMany(p => p.PhSQuoteAdjustments)
|
||||
.HasForeignKey(d => d.QuoteheaderId)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_QuoteAdjustments_Header");
|
||||
|
||||
entity.HasOne(d => d.ReasonCodeNavigation).WithMany(p => p.PhSQuoteAdjustments)
|
||||
.HasForeignKey(d => d.ReasonCode)
|
||||
.OnDelete(DeleteBehavior.ClientSetNull)
|
||||
.HasConstraintName("FK_QuoteAdjustments_Reason");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhSQuoteDetail>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__PhS_Quot__3213E83F94207114");
|
||||
@ -773,17 +848,27 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
.HasComment("Fecha de creación")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("createdat");
|
||||
entity.Property(e => e.Currency)
|
||||
.HasMaxLength(3)
|
||||
.IsUnicode(false)
|
||||
.HasDefaultValue("ARS")
|
||||
.HasComment("Código de moneda pactada (ISO 4217). Ej: ARS, USD")
|
||||
.HasColumnName("currency");
|
||||
entity.Property(e => e.CustomerId)
|
||||
.HasComment("Cliente asociado")
|
||||
.HasColumnName("customer_id");
|
||||
entity.Property(e => e.Estimatedamount)
|
||||
.HasComment("Importe estimado total")
|
||||
.HasColumnType("decimal(18, 2)")
|
||||
.HasColumnName("estimatedamount");
|
||||
entity.Property(e => e.DispatchInstruction)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("Instrucción dirigida al área de logística para detallar qué debe prepararse o despacharse (ej: “CMF 1.5 + INSTRUMENTAL”)")
|
||||
.HasColumnName("dispatch_instruction");
|
||||
entity.Property(e => e.Estimateddate)
|
||||
.HasComment("Fecha tentativa (de cirugía por ej.)")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("estimateddate");
|
||||
entity.Property(e => e.Exchangerate)
|
||||
.HasComment("Tipo de cambio pactado para conversión a pesos argentinos")
|
||||
.HasColumnType("decimal(18, 6)")
|
||||
.HasColumnName("exchangerate");
|
||||
entity.Property(e => e.Issuedate)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasComment("Fecha de emisión")
|
||||
@ -796,6 +881,9 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
entity.Property(e => e.Observations)
|
||||
.HasComment("Observaciones internas")
|
||||
.HasColumnName("observations");
|
||||
entity.Property(e => e.OutOfTown)
|
||||
.HasComment("Indica si la cirugía se realizará fuera de la ciudad/localidad habitual (“out of town”)")
|
||||
.HasColumnName("out_of_town");
|
||||
entity.Property(e => e.PeopleId)
|
||||
.HasDefaultValue(1)
|
||||
.HasComment("Identificador único del vendedor")
|
||||
@ -818,6 +906,14 @@ public partial class PhronCareOperationsHubContext : DbContext
|
||||
entity.Property(e => e.TicketId)
|
||||
.HasComment("Relación con Tickets")
|
||||
.HasColumnName("ticket_id");
|
||||
entity.Property(e => e.Total)
|
||||
.HasComment("Total final del presupuesto expresado en moneda local, considerando ajustes o acuerdos comerciales")
|
||||
.HasColumnType("decimal(18, 2)")
|
||||
.HasColumnName("total");
|
||||
entity.Property(e => e.TotalForeign)
|
||||
.HasComment("Total del presupuesto expresado en moneda extranjera")
|
||||
.HasColumnType("decimal(18, 2)")
|
||||
.HasColumnName("total_foreign");
|
||||
});
|
||||
|
||||
modelBuilder.Entity<PhSQuoteRole>(entity =>
|
||||
|
||||
@ -9,16 +9,14 @@ namespace PhronCare.Core.Data.Repositories.Sales
|
||||
{
|
||||
public class PhSQuoteHeaderRepository(PhronCareOperationsHubContext context) : IPhSQuoteHeaderRepository
|
||||
{
|
||||
#region Declaraciones
|
||||
private readonly PhronCareOperationsHubContext _context = context;
|
||||
#endregion
|
||||
#region Métodos
|
||||
public async Task<PagedResult<EQuoteHeader>> GetAllAsync(int page = 1, int pageSize = 50)
|
||||
{
|
||||
var query = _context.PhSQuoteHeaders
|
||||
.Include(q => q.PhSQuoteDetails)
|
||||
.Include(q => q.PhSQuoteRoles)
|
||||
.AsQueryable();
|
||||
.Include(q => q.PhSQuoteAdjustments)
|
||||
.AsNoTracking();
|
||||
|
||||
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
||||
|
||||
@ -35,6 +33,7 @@ namespace PhronCare.Core.Data.Repositories.Sales
|
||||
var entity = await _context.PhSQuoteHeaders
|
||||
.Include(q => q.PhSQuoteDetails)
|
||||
.Include(q => q.PhSQuoteRoles)
|
||||
.Include(q => q.PhSQuoteAdjustments)
|
||||
.FirstOrDefaultAsync(q => q.Id == id);
|
||||
|
||||
return entity != null ? EntityMapper.MapEntity<PhSQuoteHeader, EQuoteHeader>(entity) : null;
|
||||
@ -45,61 +44,46 @@ namespace PhronCare.Core.Data.Repositories.Sales
|
||||
.Where(q => q.CustomerId == customerId)
|
||||
.Include(q => q.PhSQuoteDetails)
|
||||
.Include(q => q.PhSQuoteRoles)
|
||||
.Include(q => q.PhSQuoteAdjustments)
|
||||
.ToListAsync();
|
||||
|
||||
return entities.Select(EntityMapper.MapEntity<PhSQuoteHeader, EQuoteHeader>);
|
||||
}
|
||||
public async Task<PagedResult<EQuoteHeader>> SearchAsync(int? customerId,
|
||||
string? quoteNumber, int? professionalId, int? institutionId, int? patientId,
|
||||
DateTime? issueDateFrom, DateTime? issueDateTo,
|
||||
string? status, int page = 1, int pageSize = 50)
|
||||
DateTime? issueDateFrom, DateTime? issueDateTo, string? status,
|
||||
int page = 1, int pageSize = 50)
|
||||
{
|
||||
var query = _context.PhSQuoteHeaders
|
||||
.Include(q => q.PhSQuoteDetails)
|
||||
.Include(q => q.PhSQuoteRoles)
|
||||
.Include(q => q.PhSQuoteAdjustments)
|
||||
.AsQueryable();
|
||||
|
||||
if (customerId.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.CustomerId == customerId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(quoteNumber))
|
||||
{
|
||||
query = query.Where(q => q.Quotenumber.Contains(quoteNumber));
|
||||
}
|
||||
|
||||
if (professionalId.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == "PhS_Professionals" && r.EntityId == professionalId));
|
||||
}
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == PhSEntityTypes.Professional && r.EntityId == professionalId));
|
||||
|
||||
if (institutionId.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == "PhS_Institutions" && r.EntityId == institutionId));
|
||||
}
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == PhSEntityTypes.Institution && r.EntityId == institutionId));
|
||||
|
||||
if (patientId.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == "PhS_Patients" && r.EntityId == patientId));
|
||||
}
|
||||
query = query.Where(q => q.PhSQuoteRoles.Any(r => r.Entitytype == PhSEntityTypes.Patient && r.EntityId == patientId));
|
||||
|
||||
if (issueDateFrom.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.Issuedate >= issueDateFrom.Value);
|
||||
}
|
||||
|
||||
if (issueDateTo.HasValue)
|
||||
{
|
||||
query = query.Where(q => q.Issuedate <= issueDateTo.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(status))
|
||||
{
|
||||
query = query.Where(q => q.Status == status);
|
||||
}
|
||||
|
||||
// Paginación final
|
||||
var pagedEntities = await query.ToPagedResultAsync(page, pageSize);
|
||||
|
||||
return new PagedResult<EQuoteHeader>
|
||||
@ -132,6 +116,39 @@ namespace PhronCare.Core.Data.Repositories.Sales
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
// ----------------------------
|
||||
// Métodos para Ajustes
|
||||
// ----------------------------
|
||||
public async Task<IEnumerable<EQuoteAdjustment>> GetAdjustmentsByQuoteIdAsync(int quoteId)
|
||||
{
|
||||
var adjustments = await _context.PhSQuoteAdjustments
|
||||
.Where(a => a.QuoteheaderId == quoteId)
|
||||
.ToListAsync();
|
||||
|
||||
return adjustments.Select(EntityMapper.MapEntity<PhSQuoteAdjustment, EQuoteAdjustment>);
|
||||
}
|
||||
public async Task<EQuoteAdjustment> AddAdjustmentAsync(EQuoteAdjustment adjustment)
|
||||
{
|
||||
var dbEntity = EntityMapper.MapEntity<EQuoteAdjustment, PhSQuoteAdjustment>(adjustment);
|
||||
_context.PhSQuoteAdjustments.Add(dbEntity);
|
||||
await _context.SaveChangesAsync();
|
||||
return EntityMapper.MapEntity<PhSQuoteAdjustment, EQuoteAdjustment>(dbEntity);
|
||||
}
|
||||
public async Task UpdateAdjustmentAsync(EQuoteAdjustment adjustment)
|
||||
{
|
||||
var dbEntity = EntityMapper.MapEntity<EQuoteAdjustment, PhSQuoteAdjustment>(adjustment);
|
||||
_context.PhSQuoteAdjustments.Update(dbEntity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
public async Task DeleteAdjustmentAsync(int adjustmentId)
|
||||
{
|
||||
var entity = await _context.PhSQuoteAdjustments.FindAsync(adjustmentId);
|
||||
if (entity != null)
|
||||
{
|
||||
_context.PhSQuoteAdjustments.Remove(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\maski\.nuget\packages\;C:\Program Files (x86)\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\maski\.nuget\packages\" />
|
||||
|
||||
@ -42,19 +42,16 @@
|
||||
SuccessIcon="fa fa-thumbs-up"
|
||||
ErrorIcon="fa fa-ban" />
|
||||
@code {
|
||||
private bool state=false;
|
||||
private string MinimizeMenuCss => navMenuService.Minimized ? "width:82px" : string.Empty;
|
||||
|
||||
protected void ToggleMinNavMenu(bool status)
|
||||
{
|
||||
navMenuService.Minimized = status;
|
||||
}
|
||||
private bool state=false;
|
||||
|
||||
private void OnChangeToggleSwitchState(bool value)
|
||||
{
|
||||
state = value;
|
||||
}
|
||||
|
||||
private string GetMode()
|
||||
{
|
||||
if (state )
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user