Delta Pre-Invoice Generation

Delta Pre-Invoice Generation

The New Delta Pre-Invoice Generation feature ensures that your invoicing process is accurate and up-to-date by comparing the latest invoiced amounts with new amounts and creating delta pre-invoice items for any differences. This feature handles various aspects of invoicing, including timesheet activities, flexible payment plans, packages, and invoice contacts, making your invoicing more efficient and reliable

How it works

When delta invoicing is activated, the generation of pre-invoices is based on comparing the latest invoiced amounts with the new amounts, which include the changes. When you generate a new pre-invoice, the system will fetch the latest invoiced items and compare them with the new campaign amounts to identify any differences. The system will create delta pre-invoice items for any differences found between the latest invoiced amounts and the new amounts.

Delta pre-invoices are generated and invoice items are created when the delta optimization version is activated or after the Delta Preinvoice generation when the campaign item is adjusted.

The delta changes are made in the pre-invoice of their respective period or, if the period is closed for invoicing, the adjustments are made in the next open period.

How to call Delta Preinvoice generation

Legal Entities are now mapped with Delta pre-invoice generation

When the delta invoicing is enabled on the Admin settings the new delta pre-invoice generation is called during the following processes:

  • New PreInvoice generation button on the Media Campaign

  • Pre-Invoice wizard (Lightening)

  • Scheduled Pre-Invoice Batch Job

  • the global invocable method that calls the batch job → GenerateInvoiceBatch.doGenerateInvoice (can be called from everywhere, custom apex code and flows)

  • The end campaign item feature for items based on actuals (triggered by the media campaign trigger)

  • The end campaign item feature for items based on linear distribution (triggered by the end campaign item feature)

  • The FlowInvocableProcess for flow executions (“CreateInvoicesBatchJob")

  • The optimizer activation triggered Process Builder flow → ProcessCompleteEventOptimizingVersion.flow - this action can be disabled since PreInvoice generation is triggered with optimizing version activation

  • Invoice Wizard (Lightening) - The pre-invoice update stage is included

  • Invoice Wizard (To be deprecated) - The pre-invoice update stage is included

Financial Changes

Only financial changes are considered by the pre-invoice generation and the following items are compared to evaluate if it is a financial change or not.

  • Invoice Item Amount Comparison:

    • comparison of invoice item amounts already invoiced with those that would be calculated by the next pre-invoice generation, for each specified payment interval (total, yearly, half-yearly, quarterly, monthly, weekly).

    • This comparison is done at the invoice item level, considering amounts B3, B2, B1, N1, N2, and N3

  • Invoicing Based on Linear Distribution vs. Actual Delivery

    • There are two types of invoicing: based on the linear distribution and based on actual delivery data (utilizing actual delivery from Revenue Schedules).

    • For linear distribution, amounts are calculated based on the runtime of the campaign item across payment intervals.

    • For actual delivery, amounts are calculated based on delivery data in the Revenue Schedule, for billing categories such as CPM, CPC, vCPM, CPCV, and Budget

      • Weekly payment interval is using Revenue Schedules Daily and has to be enabled through the admin settings

New Delta Pre-Invoice generation will delete and not create any 0 amount pre-invoice items when the campaign items are fully invoiced. This is also relevant for already invoiced campaign items, where only the runtime is switched.

New Invoice and invoice item fields

A new invoice item fields have been created to improve the handling of the Delta Invoicing:

Delta Change Reason

API Name: DeltaChangeReason__c

During the optimization, the reason for the change for every single Campaign item can be added and it is mapped to the invoice item to use it in the Invoice PDF to show the reason for the change.

Referenced Invoice Number

API Name: ReferencedInvoiceNumber__c

This field stores the original invoice number which was adjusted and will be shown on the Invoice PDF as a reference.

Position Reference

API Name: PositionReference__c

This is a reference to the previous version of the invoice item related to this campaign item

Invoice Item Creation Type

API Name: CreationType__c.

A new picklist field has been created to identify an invoice item creation type. This field is preset automatically and should not be changed by the user.

Following are the picklist values:

  • None - This creation type is the same as the related invoice. Nothing will change when it comes to displaying this item

  • Flexible Payment Plan - Invoice items created based on the Flexible Payment Plan

  • Technical Reversal - This is the negative clone of the previous version

  • Delta Adjustment - This is a new version of the Invoice item after the change. This item would display the new Delta fields

  • Cancelation - This is a new version of the Invoice item after the cancelation.

The Cancelation creation type is a new picklist value on this field. It should be added to the Invoice item object after installation

The following new fields for delta invoicing are created which will calculate the outstanding amount based on changes done for Campaigns and what was already invoiced.

Invoice API Name

Invoice Field Label

Invoice Item API Name + Logic

Invoice API Name

Invoice Field Label

Invoice Item API Name + Logic

GrossAmountB3Outstanding__c

Outstanding Gross Amount B3

GrossAmountB3delta__c

Additional Condition:
NonMedia__c is not set

GrossAmountB2Outstanding__c

Outstanding Gross Amount B2

GrossAmountB2delta__c

Additional Condition:
NonMedia__c is false

GrossAmountB1Outstanding__c

Outstanding Gross Amount B1

GrossAmountB1delta__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet1Outstanding__c

Outstanding Invoiced Amount N1

InvoicedAmountNet1delta__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet2Outstanding__c

Outstanding Invoiced Amount N2

InvoicedAmountNet2delta__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet3Outstanding__c

Outstanding Invoiced Amount N3

InvoicedAmountNet3delta__c

Additional Condition:
NonMedia__c is false

NonMediaAmountOutstanding__c

Outstanding Non-Media Amount

InvoicedAmountNet3delta__c

Additional Condition:
NonMedia__c is true

DstAmountOutstanding__c

Outstanding DST Amount

DstAmountdelta__c

Additional Condition:
DstRelevant__c == true && DstExempt__c is false

NonTaxableAmountDstOutstanding__c

Outstanding Nontaxable Amount (DST)

Based on TaxableAmountType__c:
InvoicedAmountNet2delta__c
or
InvoicedAmountNet3delta__c

Additional Condition:
DstRelevant__c is false || DstExempt__c is true

TaxableAmountDstOutstanding__c

Outstanding Taxable Amount (DST)

Based on TaxableAmountType__c:
InvoicedAmountNet2delta__c
or
InvoicedAmountNet3delta__c

Additional Condition:
DstRelevant__c is true && DstExempt__c is false

VATAmount1Outstanding__c

Outstanding VAT Amount (Type 1 (A))

VATAmountdelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '1'

VATAmount1BOutstanding__c

Outstanding VAT Amount (Type 1 (B))

VATAmountBdelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '1'

VATAmount2Outstanding__c

Outstanding VAT Amount (Type 2 (A))

VATAmountdelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

VATAmount2BOutstanding__c

Outstanding VAT Amount (Type 2 (B))

VATAmountBdelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

TaxableAmountVatType1Outstanding__c

Outstanding Taxable Amount (VAT Type 1)

Based on TaxableAmountType__c:
InvoicedAmountNet2Delta__c + DstAmountDelta__c
or
InvoicedAmountNet3Delta__c + DstAmountDelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '1'

TaxableAmountVatType2Outstanding__c

Outstanding Taxable Amount (VAT Type 2)

Based on TaxableAmountType__c:
InvoicedAmountNet2Delta__c + DstAmountDelta__c
or
InvoicedAmountNet3Delta__c + DstAmountDelta__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

NonTaxableAmountTotalOutstanding__c

Outstanding Nontaxable Amount (VAT Total)

Based on TaxableAmountType__c:
InvoicedAmountNet2delta__c + DstAmountDelta__c
or
InvoicedAmountNet3delta__c + DstAmountDelta__c

Additional Condition:
VATExempt__c is true or TaxableAmountType__c not supported or VATType__c not supported

QR code feature users should map the correct amount to the ESR reference.

The following invoice fields will calculate the outstanding + the already paid amount:

Invoice Field API Name

Invoice Field Label

Invoice Item API Name + Logic

Invoice Field API Name

Invoice Field Label

Invoice Item API Name + Logic

GrossAmountB3__c

Gross Amount B3

GrossAmountB3__c

Additional Condition:
NonMedia__c is false

GrossAmountB2__c

Gross Amount B2

GrossAmountB2__c

Additional Condition:
NonMedia__c is false

GrossAmountB1__c

Gross Amount B1

GrossAmountB1__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet1__c

Invoiced Amount N1

InvoicedAmountNet1__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet2__c

Invoiced Amount N2

InvoicedAmountNet2__c

Additional Condition:
NonMedia__c is false

InvoicedAmountNet3__c

Invoiced Amount N3

InvoicedAmountNet3__c

Additional Condition:
NonMedia__c is false

NonMediaAmount__c

Non-Media Amount

InvoicedAmountNet3__c

Additional Condition:
NonMedia__c is true

DstAmount__c

DST Amount

DstAmount__c

Additional Condition:
DstRelevant__c is true && DstExempt__c is false

NonTaxableAmountDst__c

Nontaxable Amount (DST)

Based on TaxableAmountType__c:
InvoicedAmountNet2__c
or
InvoicedAmountNet3__c

Additional Condition:
DstRelevant__c is false || DstExempt__c is true

TaxableAmountDst__c

Taxable Amount (DST)

Based on TaxableAmountType__c:
InvoicedAmountNet2__c
or
InvoicedAmountNet3__c

Additional Condition:
DstRelevant__c is true && DstExempt__c is false

VATAmount1__c

VAT Amount (Type 1 (A))

VATAmount__c

Additional Condition:
VATExempt__c is false && VATType__c = '1'

VATAmount1B__c

VAT Amount (Type 1 (B))

VATAmountB__c

Additional Condition:
VATExempt__c is false && VATType__c = '1'

VATAmount2__c

VAT Amount (Type 2 (A))

VATAmount__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

VATAmount2B__c

VAT Amount (Type 2 (B))

VATAmountB__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

TaxableAmountVatType1__c

Taxable Amount (VAT Type 1)

Based on TaxableAmountType__c:
InvoicedAmountNet2__c + DstAmount__c
or
InvoicedAmountNet3__c + DstAmount__c

Additional Condition:
VATExempt__c is false && VATType__c is '1'

TaxableAmountVatType2__c

Taxable Amount (VAT Type 2)

Based on TaxableAmountType__c:
InvoicedAmountNet2__c + DstAmount__c
or
InvoicedAmountNet3__c + DstAmount__c

Additional Condition:
VATExempt__c is false && VATType__c is '2'

NonTaxableAmountTotal__c

Nontaxable Amount (VAT Total)

Based on TaxableAmountType__c:
InvoicedAmountNet2__c + DstAmount__c
or
InvoicedAmountNet3__c + DstAmount__c

Additional Condition:
VATExempt__c == true or TaxableAmountType__c not supported or VATType__c not supported

The general amount calculation is described here: https://advendio.atlassian.net/wiki/spaces/SO/pages/128161786

Following Invoice Formula fields are created for Delta.

Formula

Delta API Name

Formula

Delta API Name

TaxableAmountVatType1Outstanding__c + TaxableAmountVatType2Outstanding__c+TaxableAmountVatType3Outstanding__c + TaxableAmountVatType4Outstanding__c

TaxableAmountTotalOutstanding__c

VATAmount1Outstanding__c + VATAmount1BOutstanding__c+VATAmount2Outstanding__c + VATAmount2BOutstanding__c+VATAmount3Outstanding__c + VATAmount4Outstanding__c

VatTotalOutstanding__c

TaxableAmountTotalOutstanding__c + VatTotalOutstanding__c + NonTaxableAmountTotalOutstanding__c

InvoicedAmountTotalOutstanding__c

 

 

Following Invoice Formula fields are not created for Delta, however, they can be created as custom fields if needed.

Formula

Delta API Name

Delta Label

Normal Formula API Name (can be taken as reference)

Formula

Delta API Name

Delta Label

Normal Formula API Name (can be taken as reference)

NonTaxableAmountDstDelta__c + TaxableAmountDstOutstanding__c + DstAmountOutstanding__c

InvoicedAmountDstOutstanding__c

Outstanding Invoiced Amount Gross (DST)

InvoicedAmountDst__c

VATAmount1Outstanding__c + VATAmount1BOutstanding__c

VatTotalType1Outstanding__c

Outstanding VAT Total (Type 1)

VatTotalType1__c

VATAmount2Outstanding__c + VATAmount2BOutstanding__c

VatTotalType2Outstanding__c

Outstanding VAT Total (Type 2)

VatTotalType2__c

TaxableAmountVatType1Outstanding__c + TaxableAmountVatType2Outstanding__c

TaxableAmountTotalOutstanding__c

Outstanding Taxable Amount (VAT Total)

TaxableAmountTotal__c

VatTotalType1Outstanding__c + VatTotalType2Outstanding__c

VatTotalOutstanding__c

Outstanding VAT Total

VatTotal__c

TaxableAmountTotalOutstanding__c + VatTotalOutstanding__c + NonTaxableAmountTotalOutstanding__c

InvoicedAmountTotalOutstanding__c

Outstanding Invoiced Amount Gross (Total)

InvoicedAmountTotal__c

ROUND(InvoicedAmountTotalOutstanding__c * Early_Payment_Discount__c,2)

EarlyPaymentDiscountAbsOutstanding__c

Outstanding Early Payment Discount abs.

EarlyPaymentDiscountAbs__c

InvoicedAmountTotaOutstanding__c - EarlyPaymentDiscountAbsOutstanding__c

InvoicedAmountGrossInclEpdOutstanding__c

Outstanding Invoiced Amount Gross (incl. EPD)

InvoicedAmountGrossInclEpd__c

Assigning Accounting Periods

Each legal entity has associated accounting periods, typically structured on a monthly basis. In the updated feature, accounting periods play a crucial role in assigning and calculating invoice dates for pre-invoices.

The Delta Pre-Invoice Generation process ensures that all pre-invoices have an assigned accounting period. If the invoice date matches an open accounting period, that period will be assigned to the pre-invoice. If no matching accounting period is found, the system will search for the next open accounting period.

Supposing accounting periods are not yet created when the pre-invoices are generated. In that case, the accounting period field will remain empty and will be updated during the next pre-invoice generation once the accounting periods are created.

If there is an open accounting period before the latest closed accounting period (ordered by until date), we will ignore those open accounting periods. No accounting period will be assigned to related pre invoices until new period is open after the latest closed.

Example: Open matching accounting period in the past, with NO gap between latest closed and earliest next open

Campaign Item runs in June 2024 Accounting Period July 2024 is closed but Accounting Period June 2024 is still open (somehow) The next (open) Accounting Period is in August 2024 Start Delta Pre-Invoice Generation -> Pre-Invoice with Accounting Period August 2024 assigned will be created

If there is a gap between the latest closed accounting period and the next open accounting period, no invoice item related to a closed accounting period will be assigned.

Pre-Invoice Items that match a certain open Accounting Period in the future will still be assigned to that Accounting Period, even if gaps in between Accounting Periods exist.

“Invoice Merging Exception”

When the accounting periods are already there and the current accounting period is closed the invoice items of the current month will merge into the pre-invoice of the next open period as a separate line item. This is true for all cases except, when the payment of the Media Campaign is due at the “end of the interval” the invoice items of the closed month do not get merge into the pre-invoice of the next open period instead it generates two separate invoice in the same period.

In order to close the accounting period all Pre-invoice within this accounting period should be invoiced or deleted, otherwise the validation will throw an error.

Change Accounting Period of created Pre-Invoice to September 2024 (keep Invoice Date July 1st) Close Accounting Period July 2024 Run Delta Pre-Invoice Generation -> pre-invoice Invoice Date changed to August 1st and Accounting Period did not change (September 2024)! -> pre-invoice item related to CI #1 was update (LastModifiedDate)

Example 2: Invoice Date (Manual) of Pre-Invoice was set to a future month

Create Campaign Item #1 Runtime July Run Delta Pre-Invoice Generation -> one pre-invoice and one pre-invoice item got created -> pre-invoice with Invoice Date July 1st and Accounting Period July 2024 was created -> pre-invoice item related to CI #1 was created Set Invoice Date (Manual) of created Pre-Invoice to August 10th -> Invoice Date changed to August 10th Run Delta Pre-Invoice Generation -> pre-invoice was update (LastModifiedDate), Invoice Date (August 10th) and Accounting Period (July 2024) did not change! -> pre-invoice item related to CI #1 was update (LastModifiedDate)

Example 3: Invoice Date of Pre-Invoice was changed manually or by some process

Create Campaign Item #1 Runtime July Run Delta Pre-Invoice Generation -> one pre-invoice and one pre-invoice item got created -> pre-invoice with Invoice Date July 1st and Accounting Period July 2024 was created -> pre-invoice item related to CI #1 was created Change Invoice Date of created Pre-Invoice to July 15th Run Delta Pre-Invoice Generation -> pre-invoice Invoice Date was updated (back) to (July 1st) and Accounting Period (July 2024) did not change! -> pre-invoice item related to CI #1 was update (LastModifiedDate)

 

  • Important the payment start after Billingperiod will be treated as before / during Billingperiod for the invoice date calculation for case where the initial matching accounting period is closed, this makes sure that the pre-invoice items related to the past get quicker invoiced rather than waiting for a later date only because the after Billingperiod in combination with the dates from the earliest open accounting period from the future. See the example below:

Have following accounting periods created for the following cases:

  • July 2024 (closed)

  • August 2024 (closed)

  • September 2024 (closed)

  • October 2024 (open)

All Media Campaigns are set up with…

  • Payment Interval: "monthly"

  • Payment Start: "after Billingperiod"

  • Payment Due To: "due to beginning of interval"

Create Campaign Item #1 Runtime July -> September Run Delta Pre-Invoice Generation -> pre-invoice #1 is created with Invoice Date 1st October and Accounting Period October 2024 -> pre-invoice item related to CI #1 July created -> pre-invoice item related to CI #1 August created -> pre-invoice item related to CI #1 September created

Setting the Invoice date

The invoice date for a pre-invoice is calculated using three key fields: payment interval, payment due, and payment start. The system then checks if this invoice date matches the start and end dates of the relevant accounting period.

Invoice date will always be consistent with the assigned accounting period. If there is no matching accounting period, the Invoice Date will be always the first day of the next open accounting period.