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 STAKZ for the budget billing request (default: 'G'), (2) that EABP.OPBEL is the document number of the budget billing request in DFKKOP, and (3) that DFKKOP.VTREF carries 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 pruefen

Note: 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

QuestionAnswer
Delta anchorPostingDate 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.
MappingDocumentNumber → 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 receivableWhen 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 dueThe Bilendo document type ABSCHLAG is configured in the dunning strategy so that nothing happens before due_date.