Skip to main content

Notifications

Finance | Project Operations, Human Resources, ...
Suggested answer

ProjFormLetter_Invoice_Extension

Posted on by 12

I am newbie in D365 development, but has experience in Ax2012 development, My problem is the "new way of thinking" in D365.

I have an extension on projFormLetter_invoice and I need to do something with ProjInvoiceJour, when the invoice is posted.

I am posting two og more proposals at the same time so I need all the projInvoiceJour records.

I have created a COC on run() like this, but my code (this.doSomething(invoiceJour)) does only run on projInvoiceJour for the last projProposalJour that I have selected to post. Because of the code projProposalJour = this.parmProjProposalJour().

How can i get all projProposalJour records or all projInvoiceJour records?

public void run()
{
    ProjProposalJour projProposalJour;
    ProjInvoiceJour  invoiceJour;
    ;

    next run();
    projProposalJour = this.parmProjProposalJour();
    
    while select invoiceJour
    where invoiceJour.ProposalId == projProposalJour.ProposalId
    {
        if(MyParameters::find().AutoSettlementOnCreditNote == NoYes::Yes
        && invoiceJour.isCreditNote_CZ() == true)
        {
            this.doSomething(invoiceJour);
        }
        
    }
}

  • Martin Dráb Profile Picture
    Martin Dráb 230,149 Most Valuable Professional on at
    RE: ProjFormLetter_Invoice_Extension

    Note that you could improve performance a lot.

    You shouldn't use nested while selects unless necessary. Using a join will ne much more efficient.

    You fetch all fields from parmTable, but you need only ProposalId (and you won't need any if you use a join).

    You can also change the query to find credit notes only, therefore you don't have to fetch normal invoices from database.

    And you fetch all the data for no reason if AutoSettlementOnCreditNote is No. You should check that at the beginning.

    public void run()
    {
    	next run();
    	
    	this.xyzAutoSettleCreditNotes();
    }
    
    private void xyzAutoSettleCreditNotes()
    {
    	if (MyParameters::find().AutoSettlementOnCreditNote)
    	{
    		ProjInvoiceJour         invoiceJour; 
    		ProjInvoiceParmTable	parmTable;
    	
    		while select invoiceJour
    			where invoiceJour.InvoiceAmount < 0 
    			exists join parmTable
    				where parmTable.ProposalId == invoiceJour.ProposalId
    				   && parmTable.ParmId == this.parmId()
    		{
    			this.doSomething(invoiceJour);
    		}
    	}
    }

  • hefug Profile Picture
    hefug 12 on at
    RE: ProjFormLetter_Invoice_Extension

    Thanks for helping me guys.

    I solved it like this using this.ParmId() and ProjInvoiceParmTable

    public void run()
        {
            ProjProposalJour        projProposalJour;
            ProjInvoiceJour         invoiceJour; 
            ProjInvoiceParmTable    parmTable;
            ParmId                  parmId;
            ;
    
            next run();
            parmId = this.parmId();
    
            while select parmTable
                where parmTable.ParmId == parmId
            {            
                while select invoiceJour
                    where invoiceJour.ProposalId == parmTable.ProposalId
                {
                    if(MyParameters::find().AutoSettlementOnCreditNote == NoYes::Yes
                    && invoiceJour.isCreditNote_CZ() == true)
                    {
                        this.doSomething(invoiceJour);
                    }
                }
            }
        }

  • Martin Dráb Profile Picture
    Martin Dráb 230,149 Most Valuable Professional on at
    RE: ProjFormLetter_Invoice_Extension

    Sorry, I didn't realize that the output contract in ProjFormLetter isn't put to formletterOutputContract (as it is in PurchFormLetter, for example).

    I would get it from in formletterService.getOutputContract() in readFormletterServiceOutputs():

    [ExtensionOf(classStr(ProjFormLetter_Invoice))]
    class MyProjFormLetter_Invoice_Extension
    {
    	Set outJournalsAll;
    
    	protected void readFormletterServiceOutputs(FormletterService formletterService)
    	{
    		next readFormletterServiceOutputs(formletterService);
    		
            outJournalsAll = Set::create(formletterService.getOutputContract().parmAllJournalsPacked());
    	}
    	
    	public void run()
    	{
    		next run();
    		
    		if (outJournalsAll && !outJournalsAll.empty())
    		{
    			...
    		}
    	}	
    }

  • nmaenpaa Profile Picture
    nmaenpaa 101,156 on at
    RE: ProjFormLetter_Invoice_Extension

    Have you initialized a variable called formLetterOutputContract, or does it exist in the scope of the standard class? 

  • hefug Profile Picture
    hefug 12 on at
    RE: ProjFormLetter_Invoice_Extension

    Any ideas where to put the code (set::create(formletterOutputContract.parmAllJournalsPacked()))?

    I tired to put it in run(), after next run(); 

    I am getting the error: The qualifier 'FormLetterOutputContract' is not valid in this context. Use a variable of this tye instead.

  • Suggested answer
    nmaenpaa Profile Picture
    nmaenpaa 101,156 on at
    RE: ProjFormLetter_Invoice_Extension

    Hi,

    I'm not sure if D365 has any impact on this solution. If you need all selected ProjPropsalJours, you need to find a place in the code where all the selected ProjProposalJours are available. Do you already have an idea how you would implement your code in AX2012? If yes, could you please share it, so we can suggest how to do it in D365.

    I'm not so familiar with project invoice proposals. But if each proposal ends up as a separate invoice, then your current code would eventually call the "doSomething" for all created invoices. No matter if you selected 1 or 20 proposals, the ProjFormLetter_Invoice class would run once for each invoice, therefore also your "doSomething" method would run once for each created invoice. But like I said, I'm not sure if it really works like this.

    Also, please remember that you should use your prefix in the extension class naming. Instead of ProjFormLetter_Invoice_Extension, you should call it MYProjFormLetter_Invoice_Extension, where "MY" is your prefix.

  • Martin Dráb Profile Picture
    Martin Dráb 230,149 Most Valuable Professional on at
    RE: ProjFormLetter_Invoice_Extension

    Couldn't you get them from formletterOutputContract?

    Set journals = Set::create(formletterOutputContract.parmAllJournalsPacked());

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

December Spotlight Star - Muhammad Affan

Congratulations to a top community star!

Top 10 leaders for November!

Congratulations to our November super stars!

Community AMA December 12th

Join us as we continue to demystify the Dynamics 365 Contact Center

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,240 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,149 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans