CDS View Installment Plan
Copy template: the future installment payments as an OData service, so they appear as open items in Bilendo.
Why a Custom View
In FI-CA, the installments of a budget billing plan are stored as statistical items (budget billing request, DFKKOP.STAKZ). The standard FI-CA document API does return them, but the mapping excludes them as "not a receivable." There is no released API for the Utilities package that links the installments to the plan, cycle, and period. The view below provides exactly this perspective, with one row per installment, and is released as an OData V4 service that the data handler reads in the same way as the six standard services.
Three assumptions must be verified in the customer's QA system before the view is transported: (1) the value of
STAKZfor the budget billing request (default:'G'), (2) thatEABP.OPBELis the document number of the budget billing request inDFKKOP, and (3) thatDFKKOP.VTREFcarries the utility contract.
1 · Interface View
@AbapCatalog.viewEnhancementCategory: [#NONE]
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Bilendo: Abschlagsraten (Budget Billing Instalments)'
@Metadata.ignorePropagatedAnnotations: true
@ObjectModel.usageType: {
serviceQuality: #X,
sizeCategory: #L,
dataClass: #TRANSACTIONAL
}
define view entity ZI_BILENDO_BBP_INSTALLMENT
as select from dfkkop as Item
inner join eabp as Plan on Plan.opbel = Item.opbel
{
key Item.opbel as DocumentNumber,
key Item.opupw as RepetitionItemNumber,
key Item.opupk as ItemNumber,
key Item.opupz as SubItemNumber,
Item.bukrs as CompanyCode,
Item.gpart as BusinessPartner,
Item.vkont as ContractAccount,
Item.vtref as Contract,
Item.spart as Division,
Plan.abszyk as BudgetBillingCycle,
Plan.begperiode as PeriodStartDate,
Plan.endperiode as PeriodEndDate,
Plan.ercHzbelnr as BillingDocument,
Item.faedn as DueDate,
Item.budat as PostingDate,
Item.bldat as DocumentDate,
@Semantics.amount.currencyCode: 'Currency'
Item.betrw as Amount,
@Semantics.currencyCode: true
Item.waers as Currency,
Item.hvorg as MainTransaction,
Item.tvorg as SubTransaction,
Item.stakz as StatisticalItemCode,
Item.augst as ClearingStatus,
Item.augdt as ClearingDate,
Item.augbl as ClearingDocument,
Item.augrd as ClearingReason,
Item.mansp as DunningLockReason,
Item.studt as DeferralDate,
cast( 'ABSCHLAG' as abap.char( 8 ) ) as ExternalDocumentType
}
where
Item.stakz = 'G' // Abschlagsanforderung (statistischer Posten) — Wert im QA-System pruefenNote: Plan.ercHzbelnr is called ERCHZBELNR in the table (the billing document on which the plan is based). Use the spelling from the system's ABAP Dictionary. If the table is available in your release as a released view I_..., the view should be based on that; for on-premise systems, direct access to DFKKOP/EABP is the norm.
2 · Consumption View
@EndUserText.label: 'Bilendo: Abschlagsraten (API)'
@AccessControl.authorizationCheck: #CHECK
@Metadata.allowExtensions: true
@ObjectModel.semanticKey: [ 'DocumentNumber', 'RepetitionItemNumber', 'ItemNumber', 'SubItemNumber' ]
define view entity ZC_BILENDO_BBP_INSTALLMENT
as select from ZI_BILENDO_BBP_INSTALLMENT
{
key DocumentNumber,
key RepetitionItemNumber,
key ItemNumber,
key SubItemNumber,
CompanyCode,
BusinessPartner,
ContractAccount,
Contract,
Division,
BudgetBillingCycle,
PeriodStartDate,
PeriodEndDate,
BillingDocument,
DueDate,
PostingDate,
DocumentDate,
@Semantics.amount.currencyCode: 'Currency'
Amount,
Currency,
MainTransaction,
SubTransaction,
StatisticalItemCode,
ClearingStatus,
ClearingDate,
ClearingDocument,
ClearingReason,
DunningLockReason,
DeferralDate,
ExternalDocumentType
}3 · Service Definition and Service Binding
@EndUserText.label: 'Bilendo: Abschlagsraten'
define service ZSD_BILENDO_BBP_INSTALLMENT {
expose ZC_BILENDO_BBP_INSTALLMENT as BudgetBillingInstalment;
}Create the service binding in ADT: ZAPI_BILENDO_BBP_INSTALLMENT_O4, binding type OData V4 – Web API, service definition ZSD_BILENDO_BBP_INSTALLMENT; then Publish. The service path is then /sap/opu/odata4/sap/zapi_bilendo_bbp_installment_o4/srvd_a2x/sap/zsd_bilendo_bbp_installment/0001/. An API Management proxy is placed in front of it, just like for the standard services.
4 · Access Control (DCL)
@EndUserText.label: 'Bilendo: Abschlagsraten - Buchungskreis'
@MappingRole: true
define role ZI_BILENDO_BBP_INSTALLMENT {
grant select on ZI_BILENDO_BBP_INSTALLMENT
where ( CompanyCode ) = aspect pfcg_auth( F_BKPF_BUK, BUKRS, ACTVT = '03' );
}5 · How the Data Handler Reads the View
| Question | Answer |
|---|---|
| Delta anchor | PostingDate for new installments; ClearingDate for installments that have come due and been converted into a real item. DFKKOP has no change timestamp — the same rule as for the FI-CA document. |
| Mapping | DocumentNumber → receipt_number · ItemNumber chain → external_position · Contract → erp_reference · ContractAccount → imported_customer_number · DueDate → due_date · Amount/Currency · ExternalDocumentType → external_doctype = ABSCHLAG · Division → external_sales_unit |
| Transition to the real receivable | When the installment is posted as due, a non-statistical item with its own document number is created. The plan item arrives with delete_indicator (ClearingStatus set), and the real item arrives as new. Correlation: contract account + due date + amount. |
| Not subject to dunning until due | The Bilendo document type ABSCHLAG is configured in the dunning strategy so that nothing happens before due_date. |