j.a.estevan

Si no eres parte de la solución, eres parte del problema

HOWTO: Facturación selectiva de líneas en Dynamics AX

En Microsoft Dynamics AX, como en la gran mayoría de ERP’s, se pueden facturar líneas de forma parcial y agruparlas según diferentes criterios. El usuario puede elegir el número de líneas que desee:

PurchFormLetter | 1

y facturarlas completamente o en parte, dejando el resto pendiente de facturar o no, agrupandolas en facturas por clientes, por dirección, etc.:

PurchFormLetter | 2

Incluso para cada línea se pueden cambiar en ese momento las condiciones a facturar:

PurchFormLetter | 3

Todo esto es facil e intuitivo desde los formularios propios de Microsoft Dynamics AX, pero se vuelve mas complicado a la hora de simularlo desde código X++. Facturar pedidos completos es muy facil pero según se quiere granular mas la facturación y tener mas control o modificar detalles concretos de cada línea el código resulta mas complicado.

Este es un ejemplo que puede servir como base de código para facturar líneas una a una, indicar el número y fecha de la factura que las englobará todas y modificar gran parte de las opciones que son personalizables (básicamente, las que se muestran en el formulario capturado mas arriba):

static void JAEE_PurchFormLetter(Args _args)
{
    Num                 _invoiceNum;    // Núm. factura
    TransDate           _invoiceDate;   // Fecha factura

    PurchFormLetter     purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
    PurchParmUpdate     purchParmUpdate;
    PurchParmTable      purchParmTable;
    PurchParmLine       purchParmLine;

    TradeLineRefId      tableRefId;
    PurchTable          purchTable;
    PurchLine           purchLine;
    ;

    ttsbegin;

    purchTable = PurchTable::find('PO-100104'); // Primer pedido

    // Inizializar purchFormLetter con el primer pedido
    purchFormLetter.parmCallerTable(purchTable);
    purchFormLetter.callInitParmPurchTable(purchTable);
    purchFormLetter.proforma(false);                                // Proforma: NO (Registrar: SI)
    purchFormLetter.enableUpdateNowField(true);                     // Actualizar ahora: SI
    purchFormLetter.printFormLetter(false);                         // Imprimir: NO
    purchFormLetter.transDate(_invoiceDate);                        // Fecha de factura

    // Inizializar purchParmUpdate con el primer pedido
    purchParmUpdate.clear();
    purchParmUpdate.initValue();
    purchParmUpdate.ParmId              = purchFormLetter.parmId();
    purchParmUpdate.SumBy               = AccountOrder::Account;    // Agrupar por cliente
    purchParmUpdate.SumNum              = _invoiceNum;              // Núm. Factura
    purchParmUpdate.SpecQty             = PurchUpdate::All;         // Actualizar: Todo
    purchParmUpdate.DocumentStatus      = DocumentStatus::Invoice;  // Tipo documento: Factura
    purchParmUpdate.Proforma            = NoYes::No;                // Proforma: NO
    purchParmUpdate.SumIncludePending   = NoYes::No;                // Incluir pendiente: NO
    if (purchParmUpdate.validateWrite())
        purchParmUpdate.insert();
    else
        throw Exception::Error;

    purchFormLetter.purchParmUpdate(purchParmUpdate);
    purchFormLetter.parmParmTableNum(purchParmUpdate.SumNum);

    // Tabla temporal, se crea un registro de cabecera del primer pedido (sólo uno)
    purchParmTable.clear();
    purchParmTable.TableRefId = FormLetter::getTableRef();
    purchFormLetter.createParmTable(purchParmTable, purchTable);
    if (purchParmTable.validateWrite())
        purchParmTable.insert();
    else
        throw Exception::Error;

    tableRefId  = purchParmTable.TableRefId;

    // BEGIN - LINEAS
    //       - Repetir para cada línea que se quiera facturar y para cada una y
    //       - asignar las variabies purchTable y purchLine según proceda
    purchParmLine.clear();
    purchParmLine.initValue();

    // Ajustar cantidades según necesidades
   
    // Catnidades de compra
    [purchParmLine.ReceiveNow,
     purchParmLine.RemainBefore,
     purchParmLine.RemainAfter] = purchFormLetter.qtyPurch(purchLine, naReal());

    // Cantidades de inventario
    [purchParmLine.InventNow,
     purchParmLine.RemainBeforeInvent,
     purchParmLine.RemainAfterInvent] = purchFormLetter.qtyInvent(purchLine, naReal());

    if (purchParmLine.ReceiveNow)
    {
        purchParmLine.ParmId = purchParmUpdate.ParmId;
        purchParmLine.initFromPurchLine(purchLine);
        purchParmLine.setLineAmount();
        purchParmLine.TableRefId = tableRefId;

        if (purchParmLine.validateWrite())
            purchParmLine.insert();
        else
            throw Exception::Error;
    }
    // END - LINEAS

    // Registrar!
    purchFormLetter.reArrangeNow(false); // No organizar
    purchFormLetter.run();

    ttscommit;
}

Este código hace usa de las clase PurchFormLetter para compras, pero también es adaptable a las clases SalesFormLetter para facturación de ventas.

Descarga

05-09-2011 | hay 6 comentarios