Wednesday, June 6, 2018

Create Production Picking List Journal through code in D365:

The below class will create the production picking list journal header and lines through code based on the proposal and consumption quantity.

Let us assume for an item - Item001. The BOM proposal quantity = 5 and consumption quantity = 3 then the below code will create picking list journal for the production order - Item001- 3(qty).

In case the Production order has BOM lines more than 1 item then it will create for all the items.

//Create new picking list journal when difference between proposal and consumption on production order.
class ProdPickingListJourBOM
{
    ProdJournalTable            prodJournalTable;
    ProdJournalBOM              prodJournalBOM;
    ProdBOMConsumpProposal      consumpProposal;
    BOMAutoConsump              bomAutoConsump;
    ProdBOM                     consumptionProdBOM;
    NoYes                       consumpAsProposal;
    NoYes                       proposalAsConsump;

    NoYes                       drawNegative;
    NoYes                       skipAccError;
    NoYes                       endUpdate;

    OprNum                      oprNumFrom;
    OprNum                      oprNumTo;

    InventQty                   qtyCalc;
    BOMQty                      qtyConsumption;

    boolean                     isStart;
    boolean                     isFinish;// Reported as finished
    ProdId                      prodId;
    ProdJournalNameId           journalNameId;
    boolean                     createNoYes = false;
    ProdJournalTable            prodJournalOrig;

    public void create(ProdJournalTable _prodJournalTable)
    {
        #OCCRetryCount
        prodJournalOrig = _prodJournalTable;
        try
        {
            ttsbegin;

            this.initialValues();

            if (! this.validate())
            {
                throw error("@SYS18447");
            }

            this.check();

            if(createNoYes)
            {
                this.createHeader();
            }

            ttscommit;

        }
        catch (Exception::Deadlock)
        {
            retry;
        }
        catch (Exception::UpdateConflict)
        {
            if (appl.ttsLevel() == 0)
            {
                if (xSession::currentRetryCount() >= #RetryNum)
                {
                    throw Exception::UpdateConflictNotRecovered;
                }
                else
                {
                    retry;
                }
            }
            else
            {
                throw Exception::UpdateConflict;
            }
        }
    }

    void initialValues()
    {
        oprNumTo            =   0;
        bomAutoConsump      =    BOMAutoConsump::Never;
        consumpProposal     =    ProdBOMConsumpProposal::RemainQty;
        consumpAsProposal   =    NoYes::Yes;
        oprNumFrom          =    0;
        qtyCalc             =    0;
        endUpdate           =   NoYes::No;
        prodId              = prodJournalOrig.ProdId;
        journalNameId       = prodJournalOrig.JournalNameId;
    }

    boolean validate()
    {
        boolean ok = true;

        if (!prodId)
        {
            ok = checkFailed("@SYS26122");
        }

        if (!ProdTable::checkExist(prodId))
        {
            ok = false;
        }

        if (! ProdTable::find(prodId).status().isBefore(ProdStatus::Completed))
        {
            ok = checkFailed(strfmt("@SYS22041",ProdTable::find(prodId).ProdStatus));
        }
     
        if (!journalNameId)
        {
            ok = checkFailed("@SYS26138");
        }

        if (!ProdJournalName::checkExist(journalNameId))
        {
            ok = false;
        }

        if (consumpProposal == ProdBOMConsumpProposal::Reversed)
        {
            ok = ok && ProdJournalBOM::checkNotMissingPosting(prodId);
        }

        ok = ok && this.checkCreateLinesProdBOM();

        return ok;
    }

    boolean check()
    {
        ProdBOM prodBOM;
        ProdJournalBOM      prodJournalBomOrig;
        BOMCalcData         bomCalcData     = BOMCalcData::newProdTable(qtyCalc,ProdTable::find(prodJournalOrig.ProdId));

        while select forupdate prodBOM
            index hint NumIdx
            join prodJournalBomOrig
            where   prodBOM.ProdId == prodJournalOrig.ProdId
                && prodJournalBomOrig.JournalId     == prodJournalOrig.JournalId
                && prodJournalBomOrig.InventTransId == prodBOM.InventTransId
            {
                ProdBOMCalc         prodBOMCalc     = ProdBOMCalc::newBOMCalcData(bomCalcData, prodBOM, consumpProposal, bomAutoConsump, !prodBOM.ConstantReleased, skipAccError, isStart, isFinish);

              if (prodBOMCalc.bomConsump() || prodBOMCalc.bomProposal() || prodBOMCalc.inventConsump() || prodBOMCalc.inventProposal()
                || ((endUpdate
                        &&  bomAutoConsump != BOMAutoConsump::FlushingPrincip || prodBOM.ProdFlushingPrincip != ProdFlushingPrincipBOM::Manual)
                        &&  prodBOM.BackorderStatus == ProdBackStatus::Release))
                {
                    createNoYes = true;
                    break;
                }
            }

        return createNoYes;
    }

    boolean checkCreateLinesProdBOM()
    {
        boolean     ret                     = true;
        ProdBOM     prodBOM;
        //
        ProdTable   prodTable               = ProdTable::find(prodId);
        boolean     isProjMethodConsumed    = prodTable.isProjMethodConsumed();
        boolean     calculatingWIP_RU       = prodTable.calculatingWIP_RU();
        //

        //
        if (isProjMethodConsumed || calculatingWIP_RU)
        //
        {
            while select prodBOM
                index hint NumIdx
                where prodBOM.ProdId == prodId
                    &&  prodBOM.OprNum >= oprNumFrom
                    &&  (prodBOM.OprNum <= oprNumTo    || !oprNumTo)
            {
                //
                setprefix(strfmt("@SYS24300", prodBOM.ItemId));

                if (isProjMethodConsumed)
                {
                    //
                    ret = ret && prodBOM.validateProject();
                    //
                }

                if (calculatingWIP_RU)
                {
                    ret = ret && prodBOM.checkBOMQty_RU(true);
                }
                //
            }
        }

        return ret;
    }

    public ProdJournalTable createHeader()
    {
        ProdTable           prodTable = prodTable::find(prodJournalOrig.ProdId);

        prodJournalTable.clear();
        prodJournalTable.initValue();
        prodJournalTable.JournalType    = ProdJournalType::Picklist;
        prodJournalTable.JournalNameId  = prodJournalOrig.JournalNameId;
        prodJournalTable.Description    = prodJournalOrig.Description;
        prodJournalTable.ProdId         = prodTable.ProdId;
        prodJournalTable.VoucherDraw    = JournalVoucherDraw::Post;
        prodJournalTable.VoucherSeqRecId = NumberSequenceTable::find(ProdParameters::numRefProdJournalVoucherId().NumberSequenceId).RecId;
        if (!prodJournalTable.JournalId)
        {
            prodJournalTable.DrawNegative = drawNegative;
        }
        prodJournalTable.AutoCreateDiff = NoYes::Yes;
        prodJournalTable.insert();

        this.createLines();
     
        prodJournalTable.selectForUpdate(true);
        prodJournalTable.NumOfLines = ProdJournalBOM::lastLineNum(prodJournalTable.JournalId);
        prodJournalTable.update();

        return prodJournalTable;
     
    }

    public void createLines()
    {
        ProdBOM             prodBOM;
        ProdJournalBOM      prodJournalBomOrig;
        BOMCalcData         bomCalcData    = BOMCalcData::newProdTable(qtyCalc,ProdTable::find(prodJournalOrig.ProdId));
     
        setPrefix("@SYS28536");

        if (!oprNumTo)
        {
            oprNumTo         = oprNumFrom;
        }

        while select forupdate prodBOM
            index hint NumIdx
            join prodJournalBomOrig
            where   prodBOM.ProdId == prodJournalOrig.ProdId
                && prodJournalBomOrig.JournalId == prodJournalOrig.JournalId
                && prodJournalBomOrig.InventTransId == prodBOM.InventTransId
                &&  prodBOM.OprNum >= oprNumFrom
                &&  (prodBOM.OprNum <= oprNumTo    || !oprNumTo)
        {
            ProdBOMCalc prodBOMCalc = ProdBOMCalc::newBOMCalcData(bomCalcData, prodBOM, consumpProposal, bomAutoConsump, !prodBOM.ConstantReleased, skipAccError, isStart, isFinish);

            this.createSingleLineProdBOM(prodBOM,
                                            prodBOMCalc.bomConsump(),
                                            prodBOMCalc.bomProposal(),
                                            prodBOMCalc.inventConsump(),
                                            prodBOMCalc.inventProposal(),
                                            prodBOMCalc.pdsCWInventConsump(),
                                            prodBOMCalc.pdsCWInventProposal());
        }
    }

    public void createSingleLineProdBOM(
        ProdBOM     _prodBOM,
        UnitQty     _bomConsump,
        UnitQty     _bomProposal,
        UnitQty     _inventConsump,
        UnitQty     _inventProposal,
        UnitQty     _pdsCWInventConsump,
        UnitQty     _pdsCWInventProposal)
    {

        if (_bomConsump || _bomProposal || _inventConsump || _inventProposal
                || ((endUpdate
                        &&  bomAutoConsump != BOMAutoConsump::FlushingPrincip || _prodBOM.ProdFlushingPrincip != ProdFlushingPrincipBOM::Manual)
                        &&  _prodBOM.BackorderStatus == ProdBackStatus::Release))
        {

            prodJournalBOM.clear();
            prodJournalBOM.initValue();

            prodJournalBOM.JournalId        = prodJournalTable.JournalId;

            prodJournalBOM.initFromProdBOM(_prodBOM);

            prodJournalBOM.EndConsump     = endUpdate;

            //
            if (TaxParameters::isExciseEnable_IN())
            {
                TransTaxInformation transTaxInformation_Current;
                TransTaxInformation transTaxInformation_Origin;

                transTaxInformation_Current = TransTaxInformationHelper_IN::findOrCreateTransTaxInformation(prodJournalBOM.TableId, prodJournalBOM.RecId, true);
                transTaxInformation_Origin  = TransTaxInformationHelper_IN::findOrCreateTransTaxInformation(_prodBOM.prodTable().TableId, _prodBOM.prodTable().RecId);

                transTaxInformation_Current.CompanyLocation = transTaxInformation_Origin.CompanyLocation;
                transTaxInformation_Current.TaxInformation  = transTaxInformation_Origin.TaxInformation;
                TransTaxInformationHelper_IN::initFromTaxInformation(transTaxInformation_Current);
                transTaxInformation_Current.ExciseType = ExciseType_IN::Manufacturer;
                ttsbegin;
                transTaxInformation_Current.doUpdate();
                ttscommit;
            }
            //

            prodJournalBOM.bomConsump      = _bomConsump;
            prodJournalBOM.bomProposal     = _bomProposal;
            prodJournalBOM.InventConsump   = _inventConsump;
            prodJournalBOM.InventProposal  = _inventProposal;

            prodJournalBOM.PdsCWInventConsump = _pdsCWInventConsump;
            prodJournalBOM.PdsCWInventProposal= _pdsCWInventProposal;

             
            if (consumpAsProposal)
            {
                prodJournalBOM.bomConsump           = prodJournalBOM.bomProposal;
                prodJournalBOM.InventConsump        = prodJournalBOM.InventProposal;
                prodJournalBOM.PdsCWInventConsump   = prodJournalBOM.PdsCWInventProposal;
            }

            if (proposalAsConsump)
            {
                prodJournalBOM.bomProposal          = prodJournalBOM.bomConsump;
                prodJournalBOM.InventProposal       = prodJournalBOM.InventConsump;
                prodJournalBOM.PdsCWInventProposal  = prodJournalBOM.PdsCWInventConsump;
            }
            prodJournalBOM.insert();
        }
    }

}

No comments: