Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Question

We mark nearly all items as "dirty" since we need all products from one product family calculated first before setting a family price for all of them. But the first and second pass calculate different fields. Yet I need the results from the first pass in the second pass. My question is: is there a way not to calculate those again but refer to their results from the first pass without using api.global?

This topic Multi-pass Calculation of a Price List or LPG does not fully cover this case.

Answer

It's not so pretty, but we've used this:

Code Block
languagegroovy
Boolean isSecondPass(){
  return ((String)api.currentContext()).contains("update")
}
Object getFirstPassResult(String elementName){
  api.currentItem().calculationResults.find { it.resultName == elementName }.result
}
if(isSecondPass()){
  return getFirstPassResult("ThisElementName")
}

Doesn't api.currentItem do the trick? I got the understanding that results from the 1st pass are persisted.

  • Why you didn't use api.getIterationNumber() == 1 to check for the second pass?

  • Note that if you need multiple fields from the results and depending on how many elements are in the results, then a conversion to a Map should be considered as mentioned in Best Practices: Accessing Inputs and Outputs in Header and Workflow Logics.

The results from the 1st pass are persisted to a PGI. A PGI item access is the best way when accessing another SKU from the first pass.

api.currentItem() stores only elements which are marked as output (so this means max 100 elements). We use a lookup from PGI:

Code Block
languagegroovy
def getCurrentCalculationResultsPGI(sku) {
  def PGI = api.find("PGI", 0, 1, null, Filter.equal("sku", sku))
  if (PGI) {
    def results = PGI[0].allCalculationResults
    return getCalculationResults(results)
  }
  return [:]
}
def getCalculationResults(calculationResults) {
  if (calculationResults) {
    return calculationResults.collectEntries{ [(it.resultName) : it.result] }
  }
  return [:]
}

Note: Use collectEntries only when it is needed – it has serious performance impact. It is handy to use when you can load only some attributes which ideally have fixed attribute allocation.