web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Answered

Create project invoice proposal with lines from sales order through X++ code

(0) ShareShare
ReportReport
Posted on by 55

Hi,

I'm new in Dynamics 365 for Finance and Operations.

I have to create a project invoice proposal that uses lines from a specified sales order by x code.

I try to create them with the code below, I notice that the created invoice proposal includes transactions from Fee, Expense, On-account, etc. But I wat It to include only transactions from my sales order, how could I do this?

Here is my code:

public void run(ProjInvoiceProjId _projInvoiceProjId = projInvoiceProjId, ProjId _projId = projId)
{
    ProjInvoiceProjId   _ProjectContractId = _projInvoiceProjId;
    ProjProposalJour    projProposalJour;               //table which will store journal records after creating invoice proposal
    ProjInvoiceChoose   m_oProjInvoiceChooseNormal;     //Class for creating invoice proposal
    ProjFormLetter      projFormLetter;                 //Class for posting invoice proposal
    ProjProposalItem    projProposalItem;

    
    ProjInvoiceProposalInsertLines          proposalInsertLines;
    ProjInvoiceProposalCreateLines          proposalCreateLines;
    ProjInvoiceProposalCreateLinesBase      proposalCreateLinesBase;
    ProjInvoiceProposalCreateLinesParams    proposalCreateLinesParams;

    
    ttsbegin;
    
    //creation of invoice proposal
    m_oProjInvoiceChooseNormal = ProjInvoiceChoose::psaNew_InvoiceChoose(_ProjectContractId,_projId,dateNull(),dateNull(),true, SalesUpdate::All);
    m_oProjInvoiceChooseNormal.parmSalesTable(salesTable);
    m_oProjInvoiceChooseNormal.parmSalesLine(salesLine);
    m_oProjInvoiceChooseNormal.parmQuerySalesLine(true);
    m_oProjInvoiceChooseNormal.run();
    
    

    while select forupdate projProposalJour where projProposalJour.ProjInvoiceProjId == _ProjectContractId
    {
        //for approving invoice proposals
        projProposalJour.LineProperty = ProjLinePropertyCode::Canceled;
        projProposalJour.update();
        
        //for posting invoice proposals
        projFormLetter = projFormLetter::construct(DocumentStatus::ProjectInvoice);
        projFormLetter.createParmLine(projProposalJour);
        projFormLetter.run();

        //to get latest record
        projProposalJour = projProposalJour::find(projProposalJour.ProposalId);

        info(strFmt("Invoice ProposalId: %1 \t InvoiceId: %2",
            projProposalJour.ProposalId, projProposalJour.ProjInvoiceId));
    }

    ttscommit;
}

I have the same question (0)
  • Verified answer
    Gunjan Bhattachayya Profile Picture
    35,423 on at

    Hi Chris,

    Have you tried setting all the other transaction types to false? That should help you exclude the other transaction types.

    m_oProjInvoiceChooseNormal.parmQuerySalesLine(true);
    m_oProjInvoiceChooseNormal.parmQueryOnAccTrans(false);
    m_oProjInvoiceChooseNormal.parmQueryRetentionTrans(false);
    m_oProjInvoiceChooseNormal.parmQueryRevenueTrans(false);
    m_oProjInvoiceChooseNormal.parmQuerySubscriptionTrans(false);
    m_oProjInvoiceChooseNormal.parmQueryAdvanceTrans(false);
    m_oProjInvoiceChooseNormal.parmQueryCostTrans(false);
    m_oProjInvoiceChooseNormal.parmQueryEmplTrans(false);

  • chrisrojas Profile Picture
    55 on at

    I tried It and It worked, thanks a lot Gunjan!

  • chrisrojas Profile Picture
    55 on at

    Hi Gunjan,

    I have a question, the code works fine but the created proposal takes lines from various sales orders related to the project, how could I make it take the lines just from a specific sales order?

    This is my current code:

    public static void createInvoiceProposal(ProjInvoiceProjId _projInvoiceProjId, ProjId _projId, SalesId _salesId)
        {
            ProjInvoiceProjId       _ProjectContractId = _projInvoiceProjId;
            ProjProposalJour        projProposalJour;               //table which will store journal records after creating invoice proposal
            projProposalJour        proposalJour;
            ProjInvoiceChoose       m_oProjInvoiceChooseNormal;     //Class for creating invoice proposal
            ProjFormLetter          projFormLetter;                 //Class for posting invoice proposal
            ProjProposalItem        projProposalItem;
            ProjProposalId          proposalId;
            SalesLine               salesLine;
    
            select salesLine where salesLine.SalesId == _salesId && salesLine.SalesType == SalesType::Sales;
    
            ttsbegin;
            
            m_oProjInvoiceChooseNormal = ProjInvoiceChoose::psaNew_InvoiceChoose(_ProjectContractId,_projId,dateNull(),maxDate(),true, SalesUpdate::All);
            m_oProjInvoiceChooseNormal.parmQuerySalesLine(true);
            m_oProjInvoiceChooseNormal.parmQueryOnAccTrans(false);
            m_oProjInvoiceChooseNormal.parmQueryRetentionTrans(false);
            m_oProjInvoiceChooseNormal.parmQueryRevenueTrans(false);
            m_oProjInvoiceChooseNormal.parmQuerySubscriptionTrans(false);
            m_oProjInvoiceChooseNormal.parmQueryAdvanceTrans(false);
            m_oProjInvoiceChooseNormal.parmQueryCostTrans(false);
            m_oProjInvoiceChooseNormal.parmQueryEmplTrans(false);
            m_oProjInvoiceChooseNormal.parmSalesLine(salesLine);
            //create proposal
            m_oProjInvoiceChooseNormal.run();
    
            while select forupdate projProposalJour where projProposalJour.ProjInvoiceProjId == _ProjectContractId
                && projProposalJour.LineProperty == ProjLinePropertyCode::Open
            {
                //for approving invoice proposals
                projProposalJour.LineProperty = ProjLinePropertyCode::Approved;
                projProposalJour.update();
    
                //for posting invoice proposals
                try
                {
                    projFormLetter = projFormLetter::construct(DocumentStatus::ProjectInvoice);
                    projFormLetter.createParmLine(projProposalJour);
                    projFormLetter.run();
                }
                catch
                {
                    throw;
                }
            }
            ttscommit;
        }

  • Gunjan Bhattachayya Profile Picture
    35,423 on at

    Hi Chris,

    You will need to change your code if you want to do that. The standard feature does not have a parameter for Sales order so you can't pass that as a parameter. I did something similar a few years back and I did it something like this -

    ProjInvoiceProposalCreateLinesParams    proposalCreateLinesParams = ProjInvoiceProposalCreateLinesParams::construct();
    ProjInvoiceProposalCreateLines          proposalCreateLines;
    ProjInvoiceProposalInsertLines          projInvoiceProposalInsertLines;
    List                                    proposalIdList;
    ListEnumerator                          proposalIdEnumerator;
    ProjProposalId                          proposalId;
    
    PSATmpProjProposalTrans                 tmpProjProposalTrans, tmpProjProposalTransPreBill;        
    
    proposalCreateLinesParams.parmEndDate(invoiceDate);
    
    
    proposalCreateLinesParams.parmInvoiceDate(invoiceDate);
    proposalCreateLinesParams.parmInvoiceTypeSelection(ProjInvoiceTypeSelection::Both);
    proposalCreateLinesParams.parmIsQueryCostTrans(false);
    proposalCreateLinesParams.parmIsQueryEmplTrans(false);
    proposalCreateLinesParams.parmIsQueryItemTrans(false);
    proposalCreateLinesParams.parmIsQueryOnAccTrans(includeOnAcc);
    proposalCreateLinesParams.parmIsQueryRevenueTrans(includeFee);
    proposalCreateLinesParams.parmIsQuerySalesLine(includeSO);        
    
    proposalCreateLinesParams.parmProjInvoiceProjId(this.parmProjInvoiceProjId());
    proposalCreateLinesParams.parmSalesUpdate(SalesUpdate::All);        
    
    proposalCreateLines = ProjInvoiceProposalCreateLines::newStandard(proposalCreateLinesParams.pack());
    proposalCreateLines.parmProposalCreateLinesParams().parmInvoiceDate(invoiceDate);
    proposalCreateLines.run();
    
    mpProjProposalTrans = proposalCreateLines.getProposalTransDisplay();
    this.cleanProjInvoiceProposalTmp(tmpProjProposalTrans);
    
    tmpProjProposalTrans = proposalCreateLines.parmProposalTransCreate();
    this.cleanProjInvoiceProposalTmp(tmpProjProposalTrans);    
    proposalCreateLines.parmProposalTransCreate(tmpProjProposalTrans);
    
    tmpProjProposalTransPreBill = proposalCreateLines.getProposalTransDisplayDeduction();
    this.cleanProjInvoiceProposalTmp(tmpProjProposalTransPreBill);
    
    projInvoiceProposalInsertLines = new ProjInvoiceProposalInsertLines(proposalCreateLines, false);
    projInvoiceProposalInsertLines.parmShowMessages(false);
    projInvoiceProposalInsertLines.parmInvoiceType(ProjInvoiceType::Invoice);
    projInvoiceProposalInsertLines.runOperation();
    
    

    I was using the method - cleanProjInvoiceProposalTmp to clean some other records. But you may try writing your code to delete records in tmpProjProposalTrans that don't belong to the specific sales order based on RefRecIdTrans and RefTableId fields (which correspond to SalesLine RecId and Table Id fields) .

  • generate credit note on project invoice by code in d365fo Profile Picture
    on at

    have any preposition to cancel this project invoice and create a creditnote

  • Sophs@4Sight Profile Picture
    223 on at

    Hi chrisrojas

    Were you able to solve this problem?  I have the same requirement and have not been able to get it working.

    Can you please advise.

    Kind regards

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 544 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 450 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 250 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans