Monday, November 4, 2024

Copy Markup charges while posting purchase invoice using X++

 Copy Markup charges while posting purchase invoice using X++


Class:

Important: Code logic is just for Reference. 

New class => Duplicate of class MarkupCopy & Named as SAN_MarkupCopy

/// <summary>

/// Duplicate Copy class of MarkupCopy

/// Due to extension limited capabilities on internal and private implementation from STD OOB


Helper class: To call logic 

/// <summary>

/// Helper class to centralized logic to copy charges from and to table buffer for purchase

/// </summary>

class SAN_GeneratePurchaseMarkupChargesHelper

{

    public static void createPurchaseHeaderMarkupCharge(

                        Common          _fromTable, 

                        Common          _toTable,

                        PurchTable      _purchTable )

    {

        MarkupCopy                          markupCopy;

        MarkupCopyFromPurchOrderParameters  copyFromPurchOrderToSubTableParameters;


        markupCopy = MarkupCopy::construct();

        copyFromPurchOrderToSubTableParameters =

            MarkupCopyFromPurchOrderParameters::createCopyFromPurchOrderParameters(

                _fromTable,

                _toTable,

                '',

                _purchTable.CurrencyCode,

                SourceDocumentLineAccountingStatus::Draft,

                _purchTable,

                false);

        markupCopy.copyFromPurchOrder(copyFromPurchOrderToSubTableParameters);

    }


  public static void createPurchaseLinesMarkupCharge(

                        PurchLine          _purchLine,

                        VendInvoiceInfoLine          _vendInvoiceInfoLine,

                        PurchTable                  _purchTable,

                        VendInvoiceInfoTable    _vendInvoiceInfoTable)

    {

        ttsbegin;

        SAN_MarkupCopy markupCopy;


        markupCopy = SAN_MarkupCopy::construct();

        MarkupCopyFromPurchOrderParameters copyFromPurchOrderToLineParameters;

        

        copyFromPurchOrderToLineParameters =

                    MarkupCopyFromPurchOrderParameters::createCopyFromPurchOrderParameters(

                        _purchLine,

                        _vendInvoiceInfoLine,

                        '',

                        '',

                        SourceDocumentLineAccountingStatus::Draft,

                        null,

                        false);

        SysDaBinaryExpression       sysDaBinaryExpressionSource, sysDaBinaryExpressionDest;

        sysDaBinaryExpressionDest =  new SysDaEqualsExpression(

                new SysDaFieldExpression(_vendInvoiceInfoLine, fieldStr(VendInvoiceInfoLine, ParmId)), new SysDaValueExpression(_vendInvoiceInfoTable.ParmId))

            .and(new SysDaEqualsExpression(

                new SysDaFieldExpression(_vendInvoiceInfoLine, fieldStr(VendInvoiceInfoLine, TableRefId)), new SysDaValueExpression(_vendInvoiceInfoTable.TableRefId)));


        sysDaBinaryExpressionSource =  new SysDaEqualsExpression(

                new SysDaFieldExpression(_purchLine, fieldStr(PurchLine, RecId)), new SysDaFieldExpression(_vendInvoiceInfoLine, fieldStr(VendInvoiceInfoLine, PurchLineRecId)));


        copyFromPurchOrderToLineParameters.parmBufferToWhereClause(sysDaBinaryExpressionDest);

        copyFromPurchOrderToLineParameters.parmBufferFromWhereClause(sysDaBinaryExpressionSource);

        copyFromPurchOrderToLineParameters.parmDocumentStatusToExclude(DocumentStatus::Invoice);



        MarkupTransTmp markUpTransTmp = markupCopy.copyForAllDocumentLinesUsingTempMarkupTrans(copyFromPurchOrderToLineParameters);

        SAN_GeneratePurchaseMarkupChargesHelper::copyMarkupFromPurchOrderOptimizedCleanup(_vendInvoiceInfoTable, markUpTransTmp);


        ttscommit;

    }


    private static void copyMarkupFromPurchOrderOptimizedCleanup(VendInvoiceInfoTable _vendInvoiceInfoTable, MarkupTransTmp _markUpTransTmpCopy)

    {

        MarkupTrans markupTransOtherInvoices;

        VendInvoiceInfoLine vendInvoiceInfoLine;

        MarkupTransMapping markUpTransMapping;

        

        // Find if there is a MarkupTrans that is not marked Keep and it is already connected to another invoice

        // we will only call delete if there exists one

        select firstonly RecId from _markUpTransTmpCopy

        join vendInvoiceInfoLine

            where vendInvoiceInfoLine.ParmId == _vendInvoiceInfoTable.ParmId

                && vendInvoiceInfoLine.TableRefId == _vendInvoiceInfoTable.TableRefId

                && _markUpTransTmpCopy.TransTableId == vendInvoiceInfoLine.TableId

                && _markUpTransTmpCopy.TransRecId == vendInvoiceInfoLine.RecId

                && _markUpTransTmpCopy.SourceDocumentLine == 0

                && !_markUpTransTmpCopy.Keep

        join markupTransOtherInvoices

            where markupTransOtherInvoices.OrigTableId == _markUpTransTmpCopy.OrigTableId

                && markupTransOtherInvoices.OrigRecId == _markUpTransTmpCopy.OrigRecId

                && markupTransOtherInvoices.TransTableId == _markUpTransTmpCopy.TransTableId

                && markupTransOtherInvoices.TransRecId != _markUpTransTmpCopy.TransRecId;


        if (_markUpTransTmpCopy.RecId != 0)

        {

            vendInvoiceInfoLine.clear();

            markupTransOtherInvoices.clear();


            delete_from _markUpTransTmpCopy

            exists join vendInvoiceInfoLine

                where vendInvoiceInfoLine.ParmId == _vendInvoiceInfoTable.ParmId

                    && vendInvoiceInfoLine.TableRefId == _vendInvoiceInfoTable.TableRefId

                    && _markUpTransTmpCopy.TransTableId == vendInvoiceInfoLine.TableId

                    && _markUpTransTmpCopy.TransRecId == vendInvoiceInfoLine.RecId

                    && _markUpTransTmpCopy.SourceDocumentLine == 0

                    && !_markUpTransTmpCopy.Keep

            join markupTransOtherInvoices

                where markupTransOtherInvoices.OrigTableId == _markUpTransTmpCopy.OrigTableId

                    && markupTransOtherInvoices.OrigRecId == _markUpTransTmpCopy.OrigRecId

                    && markupTransOtherInvoices.TransTableId == _markUpTransTmpCopy.TransTableId

                    && markupTransOtherInvoices.TransRecId != _markUpTransTmpCopy.TransRecId;

        

            //Perform cascading delete action for <c>MarkupTransMapping</c> table

            markUpTransMapping.clear();


            markUpTransMapping.skipDataMethods(true);

            markUpTransMapping.skipDeleteActions(true);

            markUpTransMapping.skipEvents(true);


            delete_from markUpTransMapping

            notexists join _markUpTransTmpCopy

                where _markUpTransTmpCopy.TransRecId == markUpTransMapping.MarkupTransTransRecId &&

                    _markUpTransTmpCopy.TransTableId == markUpTransMapping.MarkupTransTransTableId &&

                    _markUpTransTmpCopy.LineNum == markUpTransMapping.MarkupTransLineNum;

        }


        // Create a SourceDocumentLine record for each new charge

        RecId sourceDocumentHeader = _vendInvoiceInfoTable.SourceDocumentHeader;

        int SourceRelationType = tableNum(MarkupTrans);

        EnumName TypeEnumName = enumStr(SourceDocumentLine_VendorInvoice);

        EnumValue TypeEnumValue = SourceDocumentLine_VendorInvoice::VendorInvoiceChargeLine;

        SourceDocumentLineAccountingStatus AccountingStatus = SourceDocumentLineAccountingStatus::Draft;

        AccountingDate ExchangeRateDate = _vendInvoiceInfoTable.updateDate();


        vendInvoiceInfoLine.clear();

        

        SourceDocumentLine sourceDocumentLine;

        

        sourceDocumentLine.skipDataMethods(true);

        sourceDocumentLine.skipEvents(true);

        sourceDocumentLine.skipTempTableForInsertRecordSet(true);


        insert_recordset sourceDocumentLine

        (

            ParentSourceDocumentLine,

            SourceDocumentHeader,

            AccountingStatus,

            ExchangeRateDate,

            SourceRelationType,

            TypeEnumName,

            TypeEnumValue,

            SourceImplementationRecId

        )

        select

            SourceDocumentLine,

            sourceDocumentHeader,

            AccountingStatus,

            ExchangeRateDate,

            SourceRelationType,

            TypeEnumName,

            TypeEnumValue

        from vendInvoiceInfoLine

            where vendInvoiceInfoLine.ParmId == _vendInvoiceInfoTable.ParmId

                && vendInvoiceInfoLine.TableRefId == _vendInvoiceInfoTable.TableRefId

        join RecId from _markUpTransTmpCopy

            where _markUpTransTmpCopy.TransTableId == vendInvoiceInfoLine.TableId

                && _markUpTransTmpCopy.TransRecId == vendInvoiceInfoLine.RecId

                && _markUpTransTmpCopy.SourceDocumentLine == 0;


        sourceDocumentLine.skipTempTableForInsertRecordSet(false);


        vendInvoiceInfoLine.clear();

        sourceDocumentLine.clear();


        update_recordset _markUpTransTmpCopy setting

            SourceDocumentLine = sourceDocumentLine.RecId

            where _markUpTransTmpCopy.SourceDocumentLine == 0

        join vendInvoiceInfoLine

            where vendInvoiceInfoLine.ParmId == _vendInvoiceInfoTable.ParmId

                && vendInvoiceInfoLine.TableRefId == _vendInvoiceInfoTable.TableRefId

                && vendInvoiceInfoLine.TableId == _markUpTransTmpCopy.TransTableId

                && vendInvoiceInfoLine.RecId == _markUpTransTmpCopy.TransRecId

        join sourceDocumentLine

            where sourceDocumentLine.SourceDocumentHeader == sourceDocumentHeader &&

                sourceDocumentLine.ParentSourceDocumentLine == vendInvoiceInfoLine.SourceDocumentLine &&

                sourceDocumentLine.SourceImplementationRecId == _markUpTransTmpCopy.RecId;


        SAN_GeneratePurchaseMarkupChargesHelper::insertMarkupTransRecordFromMarkupTransTmp(_markUpTransTmpCopy);


        //dispose buffers

        vendInvoiceInfoLine.dispose();

        _markUpTransTmpCopy.dispose();

        markupTransOtherInvoices.dispose();

        markUpTransMapping.dispose();

        sourceDocumentLine.dispose();

    }


    private static void insertMarkupTransRecordFromMarkupTransTmp(MarkupTransTmp _markUpTransTmpCopy)

    {

        SysDaInsertObject insertObj = SAN_GeneratePurchaseMarkupChargesHelper::buildMarkupTransInsertObject();

        SysDaQueryObject  queryObj  = SAN_GeneratePurchaseMarkupChargesHelper::buildMarkupTransTmpQueryObject(_markUpTransTmpCopy);

            

        SAN_GeneratePurchaseMarkupChargesHelper::insertRecords(queryObj, insertObj);

    }


    private static SysDaInsertObject buildMarkupTransInsertObject()

    {

        //insert_recordset markupTransDestination (

        //    BankLCImportChargeAllocation_SA, CalculatedAmount, CalculatedAmountMST_W, CurrencyCode, etc.)


        MarkupTrans markupTransDestination;


        markupTransDestination.skipEvents(true);

        markupTransDestination.skipDataMethods(true);

        markupTransDestination.skipTempTableForInsertRecordSet(true);


        SysDaInsertObject   markupTransInsertObject = new SysDaInsertObject(markupTransDestination);


        SAN_GeneratePurchaseMarkupChargesHelper::addMarkupTransFields(markupTransInsertObject.fields());


        return markupTransInsertObject;

    }


    private static SysDaQueryObject buildMarkupTransTmpQueryObject(MarkupTransTmp _markupTransTmpSource)

    {

        //select BankLCImportChargeAllocation_SA, CalculatedAmount, CalculatedAmountMST_W, CurrencyCode, etc. from markupTransTmpSource


        SysDaQueryObject markupTransTmpQueryObject = new SysDaQueryObject(_markupTransTmpSource);

        SAN_GeneratePurchaseMarkupChargesHelper::addMarkupTransFields(markupTransTmpQueryObject.projection());

        

        return markupTransTmpQueryObject;

    }


    private static void addMarkupTransFields(SysDaSelection _selectionObject)

    {

        _selectionObject

            .add(fieldStr(MarkupTrans, BankLCImportChargeAllocation_SA))

            .add(fieldStr(MarkupTrans, CalculatedAmount))

            .add(fieldStr(MarkupTrans, CalculatedAmountMST_W))

            .add(fieldStr(MarkupTrans, CurrencyCode))

            .add(fieldStr(MarkupTrans, CustomsAssessableValue_IN))

            .add(fieldStr(MarkupTrans, CustVendPosted_RU))

            .add(fieldStr(MarkupTrans, ExchRate_RU))

            .add(fieldStr(MarkupTrans, ExchRateSecond_RU))

            .add(fieldStr(MarkupTrans, FromAmount))

            .add(fieldStr(MarkupTrans, IsAutoCharge))

            .add(fieldStr(MarkupTrans, IsTieredCharge))

            .add(fieldStr(MarkupTrans, ItemPosted_RU))

            .add(fieldStr(MarkupTrans, Keep))

            .add(fieldStr(MarkupTrans, LineNum))

            .add(fieldStr(MarkupTrans, MarkupAllocateAfter_IN))

            .add(fieldStr(MarkupTrans, MarkupCategory))

            .add(fieldStr(MarkupTrans, MarkupClassification_BR))

            .add(fieldStr(MarkupTrans, MarkupCode))

            .add(fieldStr(MarkupTrans, MCRBrokerContractFee))

            .add(fieldStr(MarkupTrans, MCRCouponMarkup))

            .add(fieldStr(MarkupTrans, MCRInstallmentEligible))

            .add(fieldStr(MarkupTrans, MCRMarkupTransCreatedBy))

            .add(fieldStr(MarkupTrans, MCRMiscChargeOverride))

            .add(fieldStr(MarkupTrans, MCROriginalMiscChargeValue))

            .add(fieldStr(MarkupTrans, MCRReasonCode))

            .add(fieldStr(MarkupTrans, MCRRetailInfoCodeId))

            .add(fieldStr(MarkupTrans, MCRSavedRecId))

            .add(fieldStr(MarkupTrans, MCRSavedTableId))

            .add(fieldStr(MarkupTrans, ModuleCategory))

            .add(fieldStr(MarkupTrans, ModuleType))

            .add(fieldStr(MarkupTrans, NotionalCharges_IN))

            .add(fieldStr(MarkupTrans, NotionalPct_IN))

            .add(fieldStr(MarkupTrans, TaxAmount))

            .add(fieldStr(MarkupTrans, TaxAmountExcise_RU))

            .add(fieldStr(MarkupTrans, TaxAmountExciseMST_RU))

            .add(fieldStr(MarkupTrans, TaxAmountMst_W))

            .add(fieldStr(MarkupTrans, TaxAmountVAT_RU))

            .add(fieldStr(MarkupTrans, TaxAmountVATMST_RU))

            .add(fieldStr(MarkupTrans, TaxAutoGenerated))

            .add(fieldStr(MarkupTrans, TaxGroup))

            .add(fieldStr(MarkupTrans, TaxItemGroup))

            .add(fieldStr(MarkupTrans, TaxValueVAT_RU))

            .add(fieldStr(MarkupTrans, TaxVATType_RU))

            .add(fieldStr(MarkupTrans, TaxWriteCode))

            .add(fieldStr(MarkupTrans, ToAmount))

            .add(fieldStr(MarkupTrans, Txt))

            .add(fieldStr(MarkupTrans, Value))

            .add(fieldStr(MarkupTrans, VATDocumentType_RU))

            .add(fieldStr(MarkupTrans, SATProductCode_MX))

            .add(fieldStr(MarkupTrans, SATUnitCode_MX))

            .add(fieldStr(MarkupTrans, WithholdingTypeCode_MX))

            .add(fieldStr(MarkupTrans, MarkupAutoTableRecId))

            .add(fieldStr(MarkupTrans, RetailShippingPromotionDiscount))

            .add(fieldStr(MarkupTrans, IsAdvancedLineProrated))

            .add(fieldStr(MarkupTrans, IsOverriddenProratedLine))

            .add(fieldStr(MarkupTrans, MarkupAutoLineRecId))

            .add(fieldStr(MarkupTrans, IsOverriddenLine))

            .add(fieldStr(MarkupTrans, PreviousValue))

            .add(fieldStr(MarkupTrans, OverrideSalesTax))

            .add(fieldStr(MarkupTrans, TransTableId))

            .add(fieldStr(MarkupTrans, TransRecId))

            .add(fieldStr(MarkupTrans, OrigTableId))

            .add(fieldStr(MarkupTrans, OrigRecId))

            .add(fieldStr(MarkupTrans, SpecificUnitSymbol))

            .add(fieldStr(MarkupTrans, SourceDocumentLine));


        if (LedgerParameters::find().EnableWHTOnCharges == NoYes::Yes)

        {

            _selectionObject

                .add(fieldStr(MarkupTrans, TaxWithholdGroup))

                .add(fieldStr(MarkupTrans, TaxWithholdItemGroup));

        }

    }


    private static void insertRecords(SysDaQueryObject _queryObject, SysDaInsertObject _insertObject)

    {

        _insertObject.query(_queryObject);

        SysDaInsertStatement insertStatement = new SysDaInsertStatement();


        insertStatement.executeQuery(_insertObject);

    }


}

No comments:

Post a Comment

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...