Optimización de la Asignación de Cargos De Producto en Microsoft Dynamics 365 Business Central

Este código AL optimiza la asignación proporcional de cargos en Microsoft Dynamics 365 Business Central, mejorando la precisión y eficiencia operativa en la gestión de documentos de venta.

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!

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *