feat(sales): agregar servicio core de lectura para Delivery Note #18
36
Core/Interfaces/IDeliveryNoteDom.cs
Normal file
36
Core/Interfaces/IDeliveryNoteDom.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using Domain.Entities;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Servicio de dominio para la gestión de consultas de Delivery Note (Remito Ventas).
|
||||||
|
/// Encapsula el acceso a datos y expone operaciones de lectura para la capa superior.
|
||||||
|
/// </summary>
|
||||||
|
public interface IDeliveryNoteDom
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Obtiene un Delivery Note por su identificador único.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">Identificador interno del Delivery Note.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// La entidad <see cref="EDeliveryNote"/> si existe; en caso contrario, null.
|
||||||
|
/// </returns>
|
||||||
|
Task<EDeliveryNote?> GetByIdAsync(int id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Obtiene un Delivery Note a partir de su número de documento.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deliveryNoteNumber">Número del Delivery Note (ej: DN-00000001).</param>
|
||||||
|
/// <returns>
|
||||||
|
/// La entidad <see cref="EDeliveryNote"/> si existe; en caso contrario, null.
|
||||||
|
/// </returns>
|
||||||
|
Task<EDeliveryNote?> GetByDeliveryNoteNumberAsync(string deliveryNoteNumber);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Obtiene todos los Delivery Notes asociados a un presupuesto (Quote).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="quoteId">Identificador del presupuesto relacionado.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Colección de <see cref="EDeliveryNote"/> asociadas al presupuesto.
|
||||||
|
/// Puede estar vacía si no existen registros.
|
||||||
|
/// </returns>
|
||||||
|
Task<IEnumerable<EDeliveryNote>> GetByQuoteIdAsync(int quoteId);
|
||||||
|
}
|
||||||
35
Core/Services/DeliveryNoteService.cs
Normal file
35
Core/Services/DeliveryNoteService.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using Core.Interfaces;
|
||||||
|
using Domain.Entities;
|
||||||
|
using Models.Interfaces;
|
||||||
|
|
||||||
|
namespace Core.Services
|
||||||
|
{
|
||||||
|
public class DeliveryNoteService(IPhSDeliveryNoteRepository deliveryNoteRepository) : IDeliveryNoteDom
|
||||||
|
{
|
||||||
|
private readonly IPhSDeliveryNoteRepository _deliveryNoteRepository = deliveryNoteRepository;
|
||||||
|
|
||||||
|
public Task<EDeliveryNote?> GetByIdAsync(int id)
|
||||||
|
{
|
||||||
|
if (id <= 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(id), "El identificador del remito es inválido.");
|
||||||
|
|
||||||
|
return _deliveryNoteRepository.GetByIdAsync(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<EDeliveryNote?> GetByDeliveryNoteNumberAsync(string deliveryNoteNumber)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(deliveryNoteNumber))
|
||||||
|
throw new ArgumentException("El número de remito es obligatorio.", nameof(deliveryNoteNumber));
|
||||||
|
|
||||||
|
return _deliveryNoteRepository.GetByDeliveryNoteNumberAsync(deliveryNoteNumber.Trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<IEnumerable<EDeliveryNote>> GetByQuoteIdAsync(int quoteId)
|
||||||
|
{
|
||||||
|
if (quoteId <= 0)
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(quoteId), "El identificador del presupuesto es inválido.");
|
||||||
|
|
||||||
|
return _deliveryNoteRepository.GetByQuoteIdAsync(quoteId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,44 +0,0 @@
|
|||||||
USE [phronCare_OperationsHub]
|
|
||||||
GO
|
|
||||||
|
|
||||||
SET ANSI_NULLS ON
|
|
||||||
GO
|
|
||||||
SET QUOTED_IDENTIFIER ON
|
|
||||||
GO
|
|
||||||
|
|
||||||
-- =============================================
|
|
||||||
-- Procedure: PhLSM_Expedition_CheckStockItemConflicts
|
|
||||||
-- Module: Logistics / Stock (PhLSM)
|
|
||||||
-- Purpose: Detect serialized stock items already assigned
|
|
||||||
-- to active expeditions.
|
|
||||||
-- Author: Leandro Rojas
|
|
||||||
-- Created: 2026-03-05
|
|
||||||
-- =============================================
|
|
||||||
|
|
||||||
ALTER PROCEDURE [dbo].[PhLSM_Expedition_CheckStockItemConflicts]
|
|
||||||
(
|
|
||||||
@StockItemIds dbo.PhLSM_StockItemIdList READONLY,
|
|
||||||
@IgnoreExpeditionId INT = NULL
|
|
||||||
)
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
SET NOCOUNT ON;
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
d.stockitem_id AS StockitemId,
|
|
||||||
h.id AS ExpeditionId,
|
|
||||||
h.expeditionnumber AS Expeditionnumber,
|
|
||||||
h.status AS Status
|
|
||||||
FROM dbo.PhLSM_ExpeditionDetails d
|
|
||||||
INNER JOIN @StockItemIds ids
|
|
||||||
ON ids.stockitem_id = d.stockitem_id
|
|
||||||
INNER JOIN dbo.PhLSM_ExpeditionHeaders h
|
|
||||||
ON h.id = d.expedition_id
|
|
||||||
INNER JOIN dbo.PhLSM_StockItem si
|
|
||||||
ON si.id = d.stockitem_id
|
|
||||||
WHERE h.status NOT IN (5,6) -- 5=Cerrada, 6=Anulada
|
|
||||||
AND (@IgnoreExpeditionId IS NULL OR h.id <> @IgnoreExpeditionId)
|
|
||||||
AND si.serial IS NOT NULL
|
|
||||||
AND LTRIM(RTRIM(si.serial)) <> '';
|
|
||||||
END
|
|
||||||
GO
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
CREATE TYPE dbo.PhLSM_StockItemIdList AS TABLE
|
|
||||||
(
|
|
||||||
stockitem_id INT NOT NULL
|
|
||||||
);
|
|
||||||
GO
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
USE [phronCare_OperationsHub]
|
|
||||||
GO
|
|
||||||
|
|
||||||
SET ANSI_NULLS ON
|
|
||||||
GO
|
|
||||||
SET QUOTED_IDENTIFIER ON
|
|
||||||
GO
|
|
||||||
|
|
||||||
-- =============================================
|
|
||||||
-- Procedure: PhLSM_Stock_GetAvailabilityByStockItemIds
|
|
||||||
-- Module: Logistics / Stock (PhLSM)
|
|
||||||
-- Purpose: Returns quantity and availability data
|
|
||||||
-- for the requested stock items.
|
|
||||||
-- Author: Leandro Rojas
|
|
||||||
-- Created: 2026-03-09
|
|
||||||
-- =============================================
|
|
||||||
|
|
||||||
CREATE OR ALTER PROCEDURE [dbo].[PhLSM_Stock_GetAvailabilityByStockItemIds]
|
|
||||||
(
|
|
||||||
@StockItemIds dbo.PhLSM_StockItemIdList READONLY
|
|
||||||
)
|
|
||||||
AS
|
|
||||||
BEGIN
|
|
||||||
SET NOCOUNT ON;
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
si.id AS StockitemId,
|
|
||||||
si.quantity AS Quantity,
|
|
||||||
ISNULL(si.reserved_quantity, 0) AS ReservedQuantity,
|
|
||||||
si.quantity - ISNULL(si.reserved_quantity, 0) AS AvailableQuantity,
|
|
||||||
si.serial AS Serial
|
|
||||||
FROM dbo.PhLSM_StockItem si
|
|
||||||
INNER JOIN @StockItemIds ids
|
|
||||||
ON ids.stockitem_id = si.id;
|
|
||||||
END
|
|
||||||
GO
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
/* =========================================================
|
|
||||||
VERIFICACIÓN STORY #9
|
|
||||||
Expedición -> EnTransito + reservas de stock
|
|
||||||
========================================================= */
|
|
||||||
|
|
||||||
SET NOCOUNT ON;
|
|
||||||
|
|
||||||
DECLARE @ExpeditionNumber VARCHAR(50) = 'X-00000054'; -- cambiar
|
|
||||||
|
|
||||||
DECLARE @ExpeditionId INT;
|
|
||||||
|
|
||||||
SELECT @ExpeditionId = id
|
|
||||||
FROM dbo.PhLSM_ExpeditionHeaders
|
|
||||||
WHERE expeditionnumber = @ExpeditionNumber;
|
|
||||||
|
|
||||||
IF @ExpeditionId IS NULL
|
|
||||||
BEGIN
|
|
||||||
RAISERROR('Expedición no encontrada',16,1);
|
|
||||||
RETURN;
|
|
||||||
END
|
|
||||||
|
|
||||||
PRINT 'ExpeditionId: ' + CAST(@ExpeditionId AS VARCHAR);
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 1. CABECERA
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== CABECERA =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
id,
|
|
||||||
expeditionnumber,
|
|
||||||
issuedate,
|
|
||||||
status,
|
|
||||||
observations
|
|
||||||
FROM dbo.PhLSM_ExpeditionHeaders
|
|
||||||
WHERE id = @ExpeditionId;
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 2. DETALLES
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== DETALLES =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
d.id,
|
|
||||||
d.expedition_id,
|
|
||||||
d.product_id,
|
|
||||||
d.stockitem_id,
|
|
||||||
d.quantity,
|
|
||||||
d.batch,
|
|
||||||
d.serial,
|
|
||||||
d.expiration
|
|
||||||
FROM dbo.PhLSM_ExpeditionDetails d
|
|
||||||
WHERE d.expedition_id = @ExpeditionId
|
|
||||||
ORDER BY d.id;
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 3. RESERVAS CREADAS
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== RESERVAS =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
r.id,
|
|
||||||
r.source_type,
|
|
||||||
r.source_id,
|
|
||||||
r.stockitem_id,
|
|
||||||
r.reserved_quantity,
|
|
||||||
r.status,
|
|
||||||
r.createdat
|
|
||||||
FROM dbo.PhLSM_StockReservation r
|
|
||||||
WHERE r.source_type = 1
|
|
||||||
AND r.source_id = @ExpeditionId
|
|
||||||
ORDER BY r.id;
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 4. STOCK ITEMS AFECTADOS
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== STOCK ITEMS =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
si.id,
|
|
||||||
si.product_id,
|
|
||||||
si.location_id,
|
|
||||||
si.quantity,
|
|
||||||
si.reserved_quantity,
|
|
||||||
(si.quantity - si.reserved_quantity) AS available
|
|
||||||
FROM dbo.PhLSM_StockItem si
|
|
||||||
WHERE si.id IN
|
|
||||||
(
|
|
||||||
SELECT stockitem_id
|
|
||||||
FROM dbo.PhLSM_ExpeditionDetails
|
|
||||||
WHERE expedition_id = @ExpeditionId
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 5. VALIDACIÓN DETALLE VS RESERVA
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== VALIDACION =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
d.id AS detail_id,
|
|
||||||
d.stockitem_id,
|
|
||||||
d.quantity AS requested,
|
|
||||||
r.reserved_quantity,
|
|
||||||
CASE
|
|
||||||
WHEN r.id IS NULL THEN 'FALTA RESERVA'
|
|
||||||
WHEN r.reserved_quantity <> d.quantity THEN 'CANTIDAD DISTINTA'
|
|
||||||
ELSE 'OK'
|
|
||||||
END AS resultado
|
|
||||||
FROM dbo.PhLSM_ExpeditionDetails d
|
|
||||||
LEFT JOIN dbo.PhLSM_StockReservation r
|
|
||||||
ON r.source_id = d.expedition_id
|
|
||||||
AND r.stockitem_id = d.stockitem_id
|
|
||||||
AND r.source_type = 1
|
|
||||||
AND r.status = 1
|
|
||||||
WHERE d.expedition_id = @ExpeditionId;
|
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
-- 6. CHEQUEO DE DUPLICADOS
|
|
||||||
-------------------------------------------------------------
|
|
||||||
PRINT '===== DUPLICADOS =====';
|
|
||||||
|
|
||||||
SELECT
|
|
||||||
stockitem_id,
|
|
||||||
COUNT(*) AS cantidad
|
|
||||||
FROM dbo.PhLSM_StockReservation
|
|
||||||
WHERE source_type = 1
|
|
||||||
AND source_id = @ExpeditionId
|
|
||||||
AND status = 1
|
|
||||||
GROUP BY stockitem_id
|
|
||||||
HAVING COUNT(*) > 1;
|
|
||||||
@ -43,26 +43,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.5 Documents", "1.5 Docume
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Documents", "Documents\Documents.csproj", "{0EFF27D3-C585-49F3-BBB5-A5E99C52207B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Documents", "Documents\Documents.csproj", "{0EFF27D3-C585-49F3-BBB5-A5E99C52207B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Database", "2.Database", "{E93C8350-6A6C-40F1-99C0-14CF7459EA8B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Migrations", "Migrations", "{5826BD19-0018-4F9C-B405-9BAB997CC8C7}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Types", "Types", "{3C3276F6-7320-4AB8-9C1E-1893E4646FD4}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
PhLSM_StockItemIdList.sql = PhLSM_StockItemIdList.sql
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Procedures", "Procedures", "{E4F7BA13-B838-42D5-AADD-481DD76DDD5E}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
PhLSM_Expedition_CheckStockItemConflicts.sql = PhLSM_Expedition_CheckStockItemConflicts.sql
|
|
||||||
PhLSM_Stock_GetAvailabilityByStockItemIds.sql = PhLSM_Stock_GetAvailabilityByStockItemIds.sql
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Verifications", "Verifications", "{85918AF0-7D8E-41B6-9157-BD2ADF05BD64}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
Story 9 - Stock Reservation.sql = Story 9 - Stock Reservation.sql
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@ -124,10 +104,6 @@ Global
|
|||||||
{34FC5538-4779-41F5-8355-7866B1395A4F} = {13328F60-28A6-446D-9935-23866F3F3D9D}
|
{34FC5538-4779-41F5-8355-7866B1395A4F} = {13328F60-28A6-446D-9935-23866F3F3D9D}
|
||||||
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5}
|
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {74280C0B-F2CC-4A3E-86D6-05530F9766D5}
|
||||||
{0EFF27D3-C585-49F3-BBB5-A5E99C52207B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
{0EFF27D3-C585-49F3-BBB5-A5E99C52207B} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||||
{5826BD19-0018-4F9C-B405-9BAB997CC8C7} = {E93C8350-6A6C-40F1-99C0-14CF7459EA8B}
|
|
||||||
{3C3276F6-7320-4AB8-9C1E-1893E4646FD4} = {E93C8350-6A6C-40F1-99C0-14CF7459EA8B}
|
|
||||||
{E4F7BA13-B838-42D5-AADD-481DD76DDD5E} = {E93C8350-6A6C-40F1-99C0-14CF7459EA8B}
|
|
||||||
{85918AF0-7D8E-41B6-9157-BD2ADF05BD64} = {E93C8350-6A6C-40F1-99C0-14CF7459EA8B}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {92DE3FEB-7D7E-4C78-BE8C-34931CA1DAED}
|
SolutionGuid = {92DE3FEB-7D7E-4C78-BE8C-34931CA1DAED}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user