Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: PFUN-16763

...

  • Tiered rebate – based on quantities or amounts purchased.
  • Stepped rebate – tiered rebate where the rebate is calculated separately for each tier.
  • Growth rebate – based on a specified increase in purchases.
  • Fixed rebate – not dependent on the purchased amounts.

See also the 97673724 Rebate Variants section below for detailed explanation of the rebate types.

...

TypeElement NameDisplay ModeFormat Type

LibraryNever

RetainGlobalNever

CustomerGroupNever

ProductGroupNever

SalesTargetNever

ActualsQueryNever

ActualSalesNever

TotalSalesRebateQuoteConfiguratorQuotingMoney (EUR)

ASFFactorNever

SalesForecastQuoteConfiguratorQuotingMoney (EUR)

RebateForecastQuoteConfiguratorQuotingMoney (EUR)

RebateRecordsNever

...

Code Block
languagegroovy
titleSalesTarget
def tieredVal = api.multiTierEntry("Revenue Target", "€","%")
if (api.isSyntaxCheckisInputGenerationExecution()) return
// 5% --> 0.05 conversion
if (tieredVal != null){
  tieredVal = tieredVal.multiplyValues(0.01)
}
api.log("sales target", tieredVal.inspect())
api.global.target = tieredVal
return tieredVal

...

Code Block
languagegroovy
titleActualsQuery
if (api.isSyntaxCheckisInputGenerationExecution()) return
def line = api.currentItem()
if (line != null){		// is null on syntaxinput checkgeneration/formula save
  def customerGroup = api.getElement("CustomerGroup")
  def productGroup = api.getElement("ProductGroup")

  // actuals for the period specified in the rebate line item
  def timeFilter = api.filter("InvoiceDate", line?.startDate, line?.endDate)
  if (timeFilter != null){
  	api.datamartQuery("TX", "Transaction DM", customerGroup, productGroup, timeFilter, "InvoicePrice\$")
  }
}

...

Code Block
languagegroovy
titleActualSales
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.datamartLookup("TX", "InvoicePrice\$")
api.log("actual", sales.inspect())

api.global.actual = sales as BigDecimal
return api.global.actual

...

Code Block
languagegroovy
titleTotalSalesRebate
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual
if (sales<0) sales=0

def rebate = Library.calcDiscount(sales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateForecast
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual * api.getElement("ASFFactor")
if (sales<0) sales=0

def rebate = Library.calcDiscount(sales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateRecords
if (api.isSyntaxCheckisInputGenerationExecution()) return
rebateRecords.add()

...

TypeElement NameDisplay ModeFormat Type

LibraryNever

RetainGlobalNever

CustomerGroupNever

ProductGroupNever

SalesTargetNever

ActualsQueryNever

ActualSalesNever

TotalSalesRebateQuoteConfiguratorQuotingMoney (EUR)

ASFFactorNever

SalesForecastQuoteConfiguratorQuotingMoney (EUR)

RebateForecastQuoteConfiguratorQuotingMoney (EUR)

RebateRecordsNever

...

Code Block
languagegroovy
titleLibrary
//Stepped discount calculation function: revenue falls in a specific tier, %discount of each tier up to this tier is applied to the part of the revenue.
if (api.isSyntaxCheckisInputGenerationExecution()) return

// target values are % values (i.e. 5% is represented by 5 rather than 0.05)
def calcSteppedDiscount(actual, tieredTarget){
  api.log("calcSteppedDiscount: actual", actual.inspect())
  api.log("calcSteppedDiscount: target", tieredTarget.inspect())

  def cumulativeDiscount = 0.0
  if (actual != null && tieredTarget != null){
    if (tieredTarget.size()>0){
      def unusedActual = actual
      for (i = tieredTarget.size()-1; i>=0; i--){  
      	def tier = tieredTarget.get(i)
      	def target = tier.target as BigDecimal
      	def value = tier.value as BigDecimal
      	api.log("Tier" +i + " target", target.inspect())
      	api.log("Tier" +i + " value", value.inspect())
        
      	if (target != null){
          if (unusedActual > target){
          	if (value == null) value=0

          	def discountable = unusedActual - target
          	def discount = discountable * value
            api.log("Discountable", discountable)
            api.log("Discount", discount)
            
            cumulativeDiscount += (discountable * value)
            api.log("  Cumulative discount", cumulativeDiscount)
            unusedActual = target
          }
        }
      }
    }
  }
  return cumulativeDiscount
}

...

Code Block
languagegroovy
titleSalesTarget
def tieredVal = api.multiTierEntry("Revenue Target", "€","%")
if (api.isSyntaxCheckisInputGenerationExecution()) return
// 5% --> 0.05 conversion
if (tieredVal != null){
  tieredVal = tieredVal.multiplyValues(0.01)
}
api.log("sales target", tieredVal.inspect())
api.global.target = tieredVal
return tieredVal

...

Code Block
languagegroovy
titleActualsQuery
if (api.isSyntaxCheckisInputGenerationExecution()) return
def line = api.currentItem()
if (line != null){		// is null on syntaxinput checkgeneration/formula save
  def customerGroup = api.getElement("CustomerGroup")
  def productGroup = api.getElement("ProductGroup")

  // actuals for the period specified in the rebate line item
  def timeFilter = api.filter("InvoiceDate", line?.startDate, line?.endDate)
  if (timeFilter != null){
  	api.datamartQuery("TX", "Transaction DM", customerGroup, productGroup, timeFilter, "InvoicePrice\$")
  }
}

...

Code Block
languagegroovy
titleActualSales
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.datamartLookup("TX", "InvoicePrice\$")
api.log("actual", sales.inspect())

api.global.actual = sales as BigDecimal
return api.global.actual

...

Code Block
languagegroovy
titleTotalSalesRebate
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual
if (sales<0) sales=0

def rebate = Library.calcSteppedDiscount(sales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateForecast
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual * api.getElement("ASFFactor")
if (sales<0) sales=0

def rebate = Library.calcDiscount(sales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateRecords
if (api.isSyntaxCheckisInputGenerationExecution()) return
rebateRecords.add()

...

TypeElement NameDisplay ModeFormat Type

LibraryNever

RetainGlobalNever

CustomerGroupNever

ProductGroupNever

GrowthTargetNever

ActualsQueryNever

ActualSalesNever

PreviousYearSalesNever

GrowthRebateQuoteConfiguratorQuotingMoney (EUR)

ASFFactorNever

SalesForecastQuoteConfiguratorQuotingMoney (EUR)

RebateForecastQuoteConfiguratorQuotingMoney (EUR)

RebateRecordsNever

...

Code Block
languagegroovy
titleGrowthTarget
def tieredVal = api.multiTierEntry("Growth Target", "%","%")
if (api.isSyntaxCheckisInputGenerationExecution()) return
//rebate % conversion
if (tieredVal != null){
  tieredVal = tieredVal.multiplyValues(0.01)
}
api.log("growth target", tieredVal.inspect())
api.global.target = tieredVal
return tieredVal

...

Code Block
languagegroovy
titleActualsQuery
if (api.isSyntaxCheckisInputGenerationExecution()) return
def line = api.currentItem()
if (line != null){		// is null on syntaxinput checkgeneration/formula save
  def customerGroup = api.getElement("CustomerGroup")
  def productGroup = api.getElement("ProductGroup")

  // actuals for the period specified in the rebate line item
  def timeFilter = api.filter("InvoiceDate", line?.startDate, line?.endDate)
  if (timeFilter != null){
  	api.datamartQuery("TX", "Transaction DM", customerGroup, productGroup, timeFilter, "InvoicePrice\$")
  }

  // previous year (copy and paste for other past periods)
  def cal = api.datamartCalendar()
  
  def startDate = line?.startDate?.toString()		// is a string
  def endDate = line.endDate.toString()		// is a string
  
  if (startDate != null){
	startDate = cal.add(startDate, -1, "YEAR");
  }
  if (endDate != null){
    endDate = cal.add(endDate, -1, "YEAR");
  }  
  timeFilter = api.filter("InvoiceDate", startDate, endDate)
  if (timeFilter != null){
    api.datamartQuery("TX-1yr", "Transaction DM", customerGroup, productGroup, timeFilter, "InvoicePrice\$")
  }
}

...

Code Block
languagegroovy
titleActualSales
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.datamartLookup("TX", "InvoicePrice\$")
api.log("actual", sales.inspect())

api.global.actual = sales as BigDecimal
return api.global.actual

...

Code Block
languagegroovy
titlePrevYearSales
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.datamartLookup("TX-1yr", "InvoicePrice\$")
api.log("actual", sales.inspect())

api.global.actualPrevYear = sales as BigDecimal
return api.global.actualPrevYear

...

Code Block
languagegroovy
titleGrowthRebate
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual
def lastYearsSales = api.global.actualPrevYear

if (sales<0) sales=0
if (lastYearsSales<0) lastYearsSales=0

def rebate = Library.growthBonus(sales, lastYearsSales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateForecast
if (api.isSyntaxCheckisInputGenerationExecution()) return
def sales = api.global.actual * api.getElement("ASFFactor")
if (sales<0) sales=0

def rebate = Library.calcDiscount(sales, api.global.target)
api.global.rebate = rebate as BigDecimal
return api.global.rebate

...

Code Block
languagegroovy
titleRebateRecords
if (api.isSyntaxCheckisInputGenerationExecution()) return
rebateRecords.add()

...

TypeElement NameDisplay ModeFormat Type

CustomerGroupNever

ProductGroupNever

FixedRebateQuoteConfiguratorQuotingMoney (EUR)

RebateRecordsNever

...

Code Block
languagegroovy
titleRebateRecords
if (api.isSyntaxCheckisInputGenerationExecution()) return
rebateRecords.add()

...