Bitta Commission reference

Developer events

Public capture and integration events, finding tables and the estimate API that let a companion app add attributes, supply costs, adjust netting and price open orders.

updated: applies-to: 1.2.0.0

Bitta Commission 1.2 opens new extension points for companion apps and partners: public capture events with typed attributes, public integration events, public temporary tables and a public estimate API. A companion app can add its own values to each captured sales line, supply a commission cost, adjust credit memo netting, add findings to reports and readiness checks, describe rate sources, and price an open order the same way posting would. Company-specific logic stays in your own extension, and the commission engine and its controls stay in Bitta Commission.

This page is for AL developers and partners. The API pages, API queries and the events and codeunits that existed before 1.2 are listed in API reference.

Before you start

  • Build a per-tenant or AppSource extension that depends on Bitta Commission 1.2.0.0 and uses its own object range and affix.
  • Use only objects with Access = Public. Internal objects and procedures can change without notice. The public procedures and events carry a V1 suffix.
  • Subscribers to the events on this page cannot commit. A commit in a subscriber raises an error.

Add values to captured sales lines

Codeunit "BAA Comm Capture Events" (73570591) raises an event for every posted sales line while Bitta Commission builds its source evidence, before the line is hashed and accepted:

OnAfterBuildSalesInvoiceLineV1(SalesInvoiceHeader: Record "Sales Invoice Header"; SalesInvoiceLine: Record "Sales Invoice Line"; var CaptureLine: Record "BAA Comm Capture Line" temporary; var CaptureAttribute: Record "BAA Comm Capture Attribute" temporary)
OnAfterBuildSalesCrMemoLineV1(SalesCrMemoHeader: Record "Sales Cr.Memo Header"; SalesCrMemoLine: Record "Sales Cr.Memo Line"; var CaptureLine: Record "BAA Comm Capture Line" temporary; var CaptureAttribute: Record "BAA Comm Capture Attribute" temporary)
OnAfterBuildOpenSalesLineV1(SalesHeader: Record "Sales Header"; SalesLine: Record "Sales Line"; var CaptureLine: Record "BAA Comm Capture Line" temporary; var CaptureAttribute: Record "BAA Comm Capture Attribute" temporary)

On a credit memo line, quantities and amounts on CaptureLine carry the commission sign, which is negative. The third event is raised for each line of an open quote, order or invoice when Bitta Commission estimates it, for example on Commission Line Estimates or in the Open-Order Commission Estimate report. Nothing is written then. Subscribe with the same logic as for posted lines, so the estimate matches what posting will capture.

Add attributes with the public procedures of the same codeunit. Each takes the CaptureAttribute buffer, an attribute code (Code[50]) and a typed value:

Procedure Value
AddCodeAttributeV1 Code[100]. A blank value adds nothing.
AddTextAttributeV1 Text[250]. A blank value adds nothing.
AddDecimalAttributeV1 Decimal. Zero is stored as a value.
AddBooleanAttributeV1 Boolean. No is stored as a value.
AddDateAttributeV1 Date. A blank date adds nothing.

A procedure replaces an existing attribute with the same code, and a blank attribute code adds nothing. The attributes are stored on the source fact. Credit rule conditions read them as Custom Attribute or through an attribute path such as SRC:ATTRIBUTE:BRAND, a Deduct From Base rule can take its percentage from a decimal attribute (Deduction Attribute Code), and a Set Rate rule can take its rate from one (Rate Attribute Code). See Crediting and splits.

The public temporary table "BAA Comm Capture Line" gives read-only context: source fact type, Document Type Code (a token that is never translated: INVOICE or CREDIT-MEMO for posted lines; QUOTE, ORDER, INVOICE, CREDIT-MEMO, BLANKET-ORDER or RETURN-ORDER for open documents), document number (Code[35]), line number, posting date, sell-to and bill-to customer, line type, account number, variant, quantity and base quantity, net amount, currency, order number, reason and return reason codes, dimension set and salesperson. You can set two fields:

  • Supplied Unit Cost: a unit cost in local currency per base unit of measure. Measures whose cost basis is Supplied Cost use it. See Commission costs.
  • Supplied Cost Source: where the cost came from, for example the name of a cost list. It is stored on the source fact as evidence.

WARNING

Read only posted or dated data in these subscribers, never current master data that can change later. The attributes and the supplied cost are part of the line's snapshot hash, so a later capture of the same line with different values is reported as a conflict instead of silently changing commission.

Integration events

Codeunit "BAA Comm Integration Events" (73570593) publishes five events:

Event Raised when What you can do
OnBeforeCalculateCreditMemoNettingV1 Before a credit memo applied to an invoice reduces the invoice's commission under the netting basis Customer Ledger Application. Raised once per earning and application. Set ExcludeFromNetting to keep the commission unchanged, or set CommissionableReductionLCY and Handled to replace the standard reduction. ReasonCode is stored as evidence.
OnResolveZeroCommissionReasonV1 When a posted document earned no commission. Supply a more specific reason code and text, shown on Commission Document Outcomes.
OnCollectExceptionFindingsV1 When the Commission Exception Report collects findings for a date range. Add your own findings, limited to the data the current user may see.
OnCollectSeasonReadinessFindingsV1 When Commission Season Readiness runs. Add findings. A finding with the severity code ERROR makes the season not ready.
OnDescribeRateSourceV1 When a statement line, the Commission FactBox on posted sales documents or Why This Rate? describes where an earning's rate came from. Replace the rate source text, for example with an agreement name.

The signatures:

OnBeforeCalculateCreditMemoNettingV1(InvoiceCustLedgEntry: Record "Cust. Ledger Entry"; CrMemoCustLedgEntry: Record "Cust. Ledger Entry"; DetailedCustLedgEntry: Record "Detailed Cust. Ledg. Entry"; EarningEntryId: Guid; ParticipantId: Guid; ComponentId: Guid; AppliedAmountLCY: Decimal; CommissionableBaseLCY: Decimal; var CommissionableReductionLCY: Decimal; var ExcludeFromNetting: Boolean; var ReasonCode: Code[30]; var Handled: Boolean)
OnResolveZeroCommissionReasonV1(DocumentType: Code[30]; DocumentNo: Code[35]; var ReasonCode: Code[30]; var ReasonText: Text[250])
OnCollectExceptionFindingsV1(DateFrom: Date; DateTo: Date; var TempFinding: Record "BAA Comm Integration Finding" temporary)
OnCollectSeasonReadinessFindingsV1(AsOfDate: Date; var TempFinding: Record "BAA Comm Integration Finding" temporary)
OnDescribeRateSourceV1(EarningEntryId: Guid; SourceDocumentNo: Code[35]; SourceDocumentLineNo: Integer; var RateSourceText: Text[100])

In the netting event, all amounts are in local currency. DetailedCustLedgEntry is the detailed customer ledger entry of the application, so a subscriber can tell partial applications and components apart. AppliedAmountLCY is the amount of this application, and CommissionableBaseLCY is the net amount of the invoice lines that earned this participant's commission on this component. When you set Handled, the earning is netted by CommissionableReductionLCY divided by CommissionableBaseLCY of its commission, at most all of it. The subscriber must answer the same way for the same arguments every time. See Credit memo netting.

DocumentNo and SourceDocumentNo pass the full captured document number (Code[35]).

Findings

Findings use the public temporary table "BAA Comm Integration Finding": Entry No., Area Code, Severity Code, Finding Code, Summary Text, Reference Table No., Reference Text, Salesperson Code, Amount, Age Days, Action Code, Reference System ID, Participant No., Currency Code and Occurred On. The field lengths match the internal findings, so nothing you write is truncated.

TempFinding arrives with the findings of Bitta Commission itself. They are read-only: changes to them are ignored and only the rows you add are kept. Give each new row a new Entry No., for example the last entry number plus one.

Estimate an open sales document

Codeunit "BAA Comm Estimate API" (73570760) has three public procedures:

EstimateSalesDocumentV1(SalesHeader: Record "Sales Header"; var EstimateLine: Record "BAA Comm Estimate Line" temporary)
TotalForComponentV1(var EstimateLine: Record "BAA Comm Estimate Line" temporary; ParticipantId: Guid; ComponentId: Guid): Decimal
TotalForComponentByCodeV1(var EstimateLine: Record "BAA Comm Estimate Line" temporary; SalespersonCode: Code[20]; ComponentCode: Code[20]): Decimal

EstimateSalesDocumentV1 works on quotes, orders and invoices and writes nothing. It reads the open lines the same way posted capture reads posted lines: the line commission salesperson, Doc. Rate Override %, ship-to, line and invoice discounts, source code and the line margin. Each line is estimated for the salesperson posted crediting would credit, that is the line salesperson, otherwise the document salesperson. It returns one row per document line and component of that salesperson's live plans:

  • Line Rate components are priced line by line with the same credit rules, deductions, pools, margin bands, rate tables and cost basis as posting.
  • Components priced on a cumulative base, such as tiers, quotas and period-close models, are listed but not priced, with a note. Priced shows which rows are priced.
  • The as-of date (As Of Date) is the posting date, otherwise the document date or order date, otherwise the work date.
  • Each row carries Participant ID, Plan Version ID and Component ID, the rate, rate source, pool key and pool margin, Cost Missing, No-Match Reason (No Rate Match or Missing Cost), Estimated Commission (LCY) and the amount in the participant's currency.

TotalForComponentV1 returns the estimated commission in local currency of one participant on one component, counting only priced rows. TotalForComponentByCodeV1 does the same for a salesperson and a component code; component codes repeat across plans, so prefer the ID variant when a salesperson's plans share a code. Neither changes the filters you set on EstimateLine.

A companion app can use the estimate rows, for example Cost Missing and No-Match Reason, to warn or block before an order is released. Bitta Commission itself does not block release. The posted calculation stays authoritative. See Estimated commission.

Other changes for integrators

  • Power BI: two new read-only API queries, commissionCreditFacts and commissionAttainmentFacts. See Power BI.
  • Plan change packages now also carry component options (such as the band basis and the Line Rate pool attribute path), accelerator bands, the rate column attribute path and the measure cost basis, and Compare Versions shows them. See Commission plans.

What's next

See the API pages, API queries and the staging endpoint: API reference.

// next step

Ready to try Bitta Commission?