En la gestión de ventas y distribución dentro de una empresa, la asignación precisa de cargos a las líneas de venta es fundamental para mantener una contabilidad correcta y un control eficiente de los costos. Imaginemos un escenario en el que una empresa necesita distribuir cargos adicionales, como costos de envío o descuentos, entre varias líneas de un pedido de ventas. Hacer esto manualmente no solo es tedioso, sino que también es propenso a errores.
Para los desarrolladores que trabajamos con Microsoft Dynamics 365 Business Central, optimizar la asignación de cargos a las líneas de venta puede ser crucial para mejorar la eficiencia y precisión en la gestión de documentos de venta. A continuación, voy a desglosar un fragmento de código en AL que facilita este proceso.
Sin más dilación ¡Vamos manos a la obra! 🚀
Asignación Proporcional a Todas las Líneas
Esta primera función asigna proporcionalmente un cargo a todas las líneas de una venta.
procedure AssignProportionallyToAllLines(ChargeSalesLine: Record "Sales Line"; var SalesLine: Record "Sales Line"; TotalQty: Decimal; TotalAmount: Decimal)
var
Qty: Decimal;
Amt: Decimal;
AmountCharge: Decimal;
NextLineNo: Integer;
begin
NextLineNo := -10000;
AmountCharge := ChargeSalesLine."Line Amount";
if SalesLine.FindSet() then
repeat
NextLineNo += 10000;
FromOneLineToOneLine(ChargeSalesLine, SalesLine, NextLineNo);
Qty := SalesLine.Amount / TotalAmount;
Amt := AmountCharge / Qty;
ModifyAssignedItemCharge(ChargeSalesLine, SalesLine."Line No.", Qty, Amt);
until SalesLine.Next() = 0;
end;
En esta función, AssignProportionallyToAllLines
, comenzamos inicializando NextLineNo
con un valor negativo, lo cual es útil para identificar las líneas asignadas de forma única durante el proceso de asignación. AmountCharge
se establece con el importe de la línea de cargo.
Luego, se utiliza un bucle repeat
para recorrer cada línea de venta. Dentro del bucle, se incrementa NextLineNo
para garantizar un número de línea único, y llamamos a la función FromOneLineToOneLine
para asignar el cargo a la línea actual. La cantidad proporcional (Qty
) y el importe proporcional (Amt
) se calculan en base al importe total y a la cantidad. Finalmente, se usa la función ModifyAssignedItemCharge
para modificar la línea de cargo asignada.
Asignación de Cargo a una Línea
El siguiente procedimiento asigna un cargo específico a una línea de documento de venta.
procedure FromOneLineToOneLine(ChargeSalesLine: Record "Sales Line"; SalesLine: Record "Sales Line"; NextLineNo: Integer)
var
ItemChargeAssignmentSales: Record "Item Charge Assignment (Sales)";
ItemChargeAssgntSales: Codeunit "Item Charge Assgnt. (Sales)";
SalesAppliestoDocumentType: enum "Sales Applies-to Document Type";
begin
ItemChargeAssignmentSales.Reset();
ItemChargeAssignmentSales.SetRange("Document Type", ChargeSalesLine."Document Type");
ItemChargeAssignmentSales.SetRange("Document No.", ChargeSalesLine."Document No.");
ItemChargeAssignmentSales.SetRange("Document Line No.", ChargeSalesLine."Line No.");
ItemChargeAssignmentSales.SetRange("Item Charge No.", ChargeSalesLine."No.");
ItemChargeAssignmentSales.SetRange("Applies-to Doc. Line No.", SalesLine."Line No.");
if ItemChargeAssignmentSales.IsEmpty() then begin
ItemChargeAssignmentSales.Init();
ItemChargeAssignmentSales."Document Type" := ChargeSalesLine."Document Type";
ItemChargeAssignmentSales."Document No." := ChargeSalesLine."Document No.";
ItemChargeAssignmentSales."Document Line No." := ChargeSalesLine."Line No.";
ItemChargeAssignmentSales."Item Charge No." := ChargeSalesLine."No.";
if ChargeSalesLine.Quantity <> 0 then
ItemChargeAssignmentSales."Unit Cost" :=
Round(ChargeSalesLine."Line Amount" / ChargeSalesLine.Quantity, 0.01);
case SalesLine."Document Type" of
"Sales Document Type"::Quote:
SalesAppliestoDocumentType := SalesAppliestoDocumentType::Quote;
"Sales Document Type"::Order:
SalesAppliestoDocumentType := SalesAppliestoDocumentType::Order;
"Sales Document Type"::Invoice:
SalesAppliestoDocumentType := SalesAppliestoDocumentType::Invoice;
"Sales Document Type"::"Blanket Order":
SalesAppliestoDocumentType := SalesAppliestoDocumentType::"Blanket Order";
"Sales Document Type"::"Credit Memo":
SalesAppliestoDocumentType := SalesAppliestoDocumentType::"Credit Memo";
"Sales Document Type"::"Return Order":
SalesAppliestoDocumentType := SalesAppliestoDocumentType::"Return Order";
end;
ItemChargeAssgntSales.InsertItemChargeAssignment(ItemChargeAssignmentSales, SalesAppliestoDocumentType, ChargeSalesLine."Document No.", SalesLine."Line No.", SalesLine."No.", SalesLine.Description, NextLineNo);
end;
ModifyAssignedItemCharge(ChargeSalesLine, SalesLine."Line No.", ChargeSalesLine.Quantity, ChargeSalesLine."Line Amount");
end;
La función FromOneLineToOneLine
se encarga de asignar un cargo específico a una línea de documento de venta. Primero, resetea el registro ItemChargeAssignmentSales
y establece los filtros necesarios para seleccionar la línea específica del documento de venta correspondiente al cargo.
Si no existe una asignación previa para la línea, inicializa el registro y asigna los valores necesarios. Esto incluye la inicialización del tipo de documento, número de documento, número de línea del documento, número del cargo del artículo, y el costo unitario si la cantidad no es cero. También se determina el tipo de documento aplicable (cotización, pedido, factura, etc.) y se inserta la asignación de cargo utilizando ItemChargeAssgntSales.InsertItemChargeAssignment
. Finalmente, se llama a ModifyAssignedItemCharge
para ajustar los valores del cargo en la línea.
Modificación de Cargos Asignados
Finalmente, la función ModifyAssignedItemCharge
modifica los cargos asignados basándose en los valores calculados.
local procedure ModifyAssignedItemCharge(ChargeSalesLine: Record "Sales Line"; SalesLineLineNo: Integer; Qty: Decimal; Amount: Decimal)
var
ItemChargeAssignmentSales: Record "Item Charge Assignment (Sales)";
begin
ItemChargeAssignmentSales.Reset();
ItemChargeAssignmentSales.SetRange("Document Type", ChargeSalesLine."Document Type");
ItemChargeAssignmentSales.SetRange("Document No.", ChargeSalesLine."Document No.");
ItemChargeAssignmentSales.SetRange("Document Line No.", ChargeSalesLine."Line No.");
ItemChargeAssignmentSales.SetRange("Item Charge No.", ChargeSalesLine."No.");
ItemChargeAssignmentSales.SetRange("Applies-to Doc. Line No.", SalesLineLineNo);
if ItemChargeAssignmentSales.FindFirst() then begin
if Qty <> 0 then begin
ItemChargeAssignmentSales."Qty. to Assign" := Qty;
ItemChargeAssignmentSales."Qty. to Handle" := Qty;
end;
if Amount <> 0 then begin
ItemChargeAssignmentSales."Amount to Assign" := Amount;
ItemChargeAssignmentSales."Amount to Handle" := Amount;
end;
ItemChargeAssignmentSales.Modify(true);
end;
end;
En la función ModifyAssignedItemCharge
, se resetea el registro ItemChargeAssignmentSales
y se establecen los filtros necesarios para encontrar la asignación de cargo específica. Si se encuentra la primera coincidencia, se procede a actualizar los valores del cargo. Si la cantidad (Qty
) no es cero, se asigna la cantidad correspondiente para manejar y asignar. De manera similar, si el importe (Amount
) no es cero, se asigna el importe correspondiente para manejar y asignar. Finalmente, se modifica el registro para aplicar los cambios.
Beneficios y Aplicaciones Prácticas
Este enfoque de asignación de cargos ofrece varios beneficios:
- Precisión Mejorada: Al distribuir proporcionalmente los cargos basados en el importe total y la cantidad, se asegura una asignación más precisa y justa.
- Eficiencia Operativa: La automatización de la asignación reduce el tiempo y esfuerzo manual requerido, permitiendo a los usuarios centrarse en tareas de mayor valor.
- Flexibilidad: Las empresas pueden ajustar y extender estas funciones para adaptarlas a sus necesidades específicas, mejorando la personalización y la adecuación del sistema a su operativa diaria.
Conclusión
Este código AL optimiza la asignación de cargos en Microsoft Dynamics 365 Business Central. No solo mejora la precisión en la asignación de cargos, sino que también incrementa la eficiencia operativa. Implementar estas prácticas en tus proyectos de Business Central puede resultar en una gestión más efectiva y precisa de los documentos de venta.
Si quieres ver el código completo está en GitHub.
Espero que esta explicación te haya sido de utilidad y te anime a explorar más sobre cómo optimizar tus procesos en Business Central. ¡Hasta la próxima!