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, ...
Suggested Answer

ProjFormLetter_Invoice_Extension

(0) ShareShare
ReportReport
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);
        }
        
    }
}

I have the same question (0)
  • Martin Dráb Profile Picture
    237,965 Most Valuable Professional on at

    Couldn't you get them from formletterOutputContract?

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

  • Suggested answer
    nmaenpaa Profile Picture
    101,160 Moderator on at

    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.

  • hefug Profile Picture
    12 on at

    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.

  • nmaenpaa Profile Picture
    101,160 Moderator on at

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

  • Martin Dráb Profile Picture
    237,965 Most Valuable Professional on at

    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())
    		{
    			...
    		}
    	}	
    }

  • hefug Profile Picture
    12 on at

    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
    237,965 Most Valuable Professional on at

    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);
    		}
    	}
    }

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 503 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

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

#3
BillurSamdancioglu Profile Picture

BillurSamdancioglu 278 Most Valuable Professional

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans