Thursday 10 February 2022

Adobe Forms – Subtotals on each page

The goal is to generate in a PDF document a subtotal on each page in case the document has multiple pages. The PDF Form is designed using Adobe LiveCycle Designer (transaction SFP).

Adobe Forms, SAP ABAP Exam Prep, SAP ABAP Exam, SAP ABAP, SAP ABAP Skills, SAP ABAP Jobs, SAP ABAP Preparation

Scenario’s


1. There is only one page, no subtotals needed.
2. There are more than page, subtotals are needed.

Pages with only items contain a “Previous page subtotal” and a “Bottom page subtotal”.

i. The End block is pushed to the next page to keep the lines of the End Block together, so the last page does not contain items. The “Previous page subtotal” is not needed on the last page, because the last page does not contain items.

ii. The End block is not pushed to the next page, the last page also contains items, so the last page does contain “Previous page subtotal”.

Items


The form contains a table called “ITEMS” which contain the sales order items. Each line contains the field “TOTAL_AMOUNT”, which is the Nett total amount of the line. The subtotals have to be calculated based on this field.

Masterpages


The layout of the first page differs from the next pages, so there are 2 master pages. A “First page” and a “Next page”. The First page contains only a “Bottom page subtotal”. The Next page contains a “Previous page subtotal” and a “Bottom page subtotal”.

The “Bottom page subtotal” is sum of the “Previous page subtotal” plus the Total amounts of the Sales order items of the current page.

Subtotal Sub forms and Amount calculation


“Bottom page subtotal Sub form” on First and Next page – showing/hiding subtotal

The “Bottom page subtotal Sub form” contains all the layout elements of the subtotal like the Label, the Text field and some graphical lines. So when this sub form is hidden, than all these elements are hidden. Therefor the code below is placed in the calculation method of the “Bottom page subtotal Sub form”.

The Sub form is only shown when the “EndBlock” is not shown on the page, because the End block contains the total.

//Get current page
var CurrentPage = xfa.layout.absPage(this);

//Get current page - content page - fields
var FieldList = xfa.layout.pageContent(CurrentPage, "subform",false);
var FieldListLength = FieldList.length; 
        
//Check page contains EndBlock
var FieldListIndex = 0;
var Item;
var FoundInd = false;;
        
for (FieldListIndex; FieldListIndex < FieldListLength; FieldListIndex++) {
  Item = FieldList.item(FieldListIndex);
  if (Item.name === "EndBlock") {            
    FoundInd = true;
  }
}

//Hide subform if EndBlock found
if (FoundInd === true) {
  this.presence = "hidden";
}

“Bottom page subtotal amount” on First page – calculation

The “Bottom page subtotal” on the first page does need to read the “Previous page subtotal”, because there is no Previous page.

So it searches for all “field” elements and than sums all “TOTAL_AMOUNT” fields. To overcome rounding issues all amounts are first multiplied by 100 and after that divided by 100.

//Get current page
var currentPage = xfa.layout.absPage(this);
var currentPage_Index = currentPage.toString();

//Sum TOTAL_AMOUNT fields
var oFields = xfa.layout.pageContent(currentPage, "field"); 
var nNodesLength = oFields.length; 
var oTotalAmountFloat = Number(0);

for (var nNodeCount = 0; nNodeCount < nNodesLength; nNodeCount++) {
  if (oFields.item(nNodeCount).name == "TOTAL_AMOUNT") {            
    oTotalAmountFloat = ((oTotalAmountFloat * 100) + 
      (Number(oFields.item(nNodeCount).rawValue) * 100))/100;
  } 
}

this.rawValue = Number(oTotalAmountFloat);

“Previous page subtotal Sub form” on Next page – showing and hiding the subtotal

The “Previous page subtotal Sub form” is only needed when the current page contains Sales order items. This is check by the name of the “TOTAL_AMOUNT”.

//Get current page
var CurrentPage = xfa.layout.absPage(this);

//Get current page - content page - fields
var FieldList = xfa.layout.pageContent(CurrentPage, "field",false);
var FieldListLength = FieldList.length; 
        
//Check for a Sales order item line
var FieldListIndex = 0;
var Item;
var FoundInd = false;;
        
for (FieldListIndex; FieldListIndex < FieldListLength; FieldListIndex++) {
  Item = FieldList.item(FieldListIndex);
  if (Item.name === "TOTAL_AMOUNT") {            
    FoundInd = true;
  }
}

//If no Sales order item line, than hide Previous page subtotal
if (FoundInd === false) {
  this.presence = "hidden";
}

“Previous page subtotal amount” on next page – calculation

The “Previous page subtotal” shows the “Bottom page subtotal” of the previous page. So the code first gets the “Previous page” and than the “Bottom page subtotal”.

The third parameter of method pageContent has value “true” to get the elements of the Master page instead of the Content page.

//Get previous page
var CurrentPage = xfa.layout.absPage(this);
var CurrentPage_Index = Number( CurrentPage.toString() );
var PreviousPage_Index = CurrentPage_Index - 1;

//Get Bottom page subtotal
var FieldList = xfa.layout.pageContent( PreviousPage_Index, "field", true);
var FieldListLength = FieldList.length; 

for (var FieldListCount = 0; FieldListCount < FieldListLength; FieldListCount++) {
  if (FieldList.item(FieldListCount).name == "PageSubtotalAmount") { 
    this.rawValue = FieldList.item(FieldListCount).rawValue;
  }        
}

“Bottom page subtotal next page” – calculation

First the “Previous page subtotal amount” on the current page is determined. Method pageContent has as third parameter the value “true” to get the elements of the Master page instead of the Content page.

After that the TOTAL_AMOUNT of the current page is summed. Method pageContent has as third parameter the value “false” to get the elements of the Content page.

//Get current page
var CurrentPage = xfa.layout.absPage(this);
        
//Get current page - master page - fields
var FieldList = xfa.layout.pageContent(CurrentPage, "field",true);
var FieldListLength = FieldList.length; 
        
//Get Previous page subtotal
var FieldListCount = 0;
var PreviousPageSubtotal = 0;        
for (FieldListCount; FieldListCount < FieldListLength; FieldListCount++) {
  if (FieldList.item(FieldListCount).name == "PreviousPageSubtotalAmount") { 
    PreviousPageSubtotal = +FieldList.item(FieldListCount).rawValue;
  }
}
        
//Calculate current page total
var TotalAmount = PreviousPageSubtotal * 100;
var FieldListIndex2 = 0;
var Item;
        
//Get current page - content page - fields
FieldList = xfa.layout.pageContent(CurrentPage, "field",false);
FieldListLength = FieldList.length; 
        
//Sum total amounts (X 100 to overcome decimal problems)
for (FieldListIndex2; FieldListIndex2 < FieldListLength; FieldListIndex2++) {
  Item = FieldList.item(FieldListIndex2);
  if (Item.className === "field" && Item.name === "TOTAL_AMOUNT") {            
    TotalAmount += Item.rawValue * 100;
  }
}
this.rawValue = TotalAmount / 100;

Source: sap.com

No comments:

Post a Comment