The DsPart
class constructors have been expanded and split to support the new part pricing system (introduced in 16.5).
New constructors now accept basePrice
and optionPriceSum
separately.
Old constructors that use list price remain available but are marked for future deprecation.
constructor(Snapper, DsPData, double listPrice, …)
constructor(Snapper, DsPData, str articleCode, str description, double listPrice, …)
constructor(Snapper, DsPData, double basePrice, Double optionPriceSum, …)
constructor(Snapper, DsPData, str articleCode, str description, double basePrice, Double optionPriceSum, …)
cm.core.part.Part
compile-time section for more migration tipsThe following functions were introduced or modified to support the transition to the new part pricing system.
Find more documentation on the new pricing system in the compile-time section for cm.core.part.Part
.
Added: public Double generateOptionPriceSum() {} Removed: public double basePrice() {} Removed: public void performPriceConversions(ProjectInformation projectInfo) {}
Old:
New:
pData.optionPriceSum(specOptions, this)
generateOptionPriceSum()
in your extended Part class.invalidateOptionPriceSum()
) when option state changes to trigger regeneration.The basePrice
method was expanded to support the new pricing framework by adding parameters and delegating to the superclass when new pricing is enabled.
Old: public double basePrice() {} New: public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
Old:
public double basePrice()
PartSpecial
(replace or append)_data.basePrice
New:
public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
useNewPricing
is enabled → delegates directly to super()_data.basePrice
with PartSpecial
adjustments)ProdPart
).As of 16.5, a new interface for lead time has been added to core Part
and overridden in DsPart
. It's value is displayed in the new LeadTimeColumn
implemented in cm/core/init/leadTimeColumn.cm
.
In cm/abstract/dataSymbol/parts.cm /** * Get lead time string. * Ex. 20 days, 3 weeks, etc. */ public str leadTime() { DsProductType product = pData.product(); if (!product) return super(); int days; for (ref in product.leadTimeProgramRefs()) { DsLeadTimeProgramType ltp = pData.leadTimeProgram(ref); if (!ltp) continue; days = max(days, ltp.days); } return days > 0 ? spnn(days, ' ', days == 1 ? $day : $days) : ""; }
The abstract ProdPart
interface for generateOptAdjustmentSifRows
has been changed to accept PartOptionItem
s instead of SpecOption
s.
As a result, the empty override of this function in DsPart
has been removed entirely.
Old: public void generateOptAdjustmentSifRows(SpecOption opt, str[] lines) {}
The abstract ProdPart
interface for optSpecialKey
has been changed to accept PartOptionItem
s instead of SpecOption
s.
Old: public str optSpecialKey(SpecOption opt) {} New: public str optSpecialKey(PartOptionItem opt) {}
When collecting PartInfoTree
s on DsPart
s, the specOptions
sequence is no longer filtered by DsSpecOption
s. All options
within the specOptions
sequence will have a tree constructed.
public PartInfoTree[] infoTrees() { PartInfoTree[] items(); PartInfoTree[] parents(); Old: for (DsSpecOption tp in specOptions, index=i) { New: for (tp in specOptions, index=i) { ... } return items; }
With the addition of the new part attribute description/notes system, DsPart
s now
need to be differentiable/split by their attribute values.
The following change has been made in flattenableKey
to account for this:
public str flattenableKey() { StrBuf buf(uniqueKey()); ... New: buf << annotationFlattenableKey(); return buf.retireToS(); }
The basePrice
method was expanded to support the new pricing framework by adding parameters and delegating to the superclass when new pricing is enabled.
Old: public double basePrice() {} New: public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true) {}
Old:
public double basePrice()
item.price()
PartSpecial
(replace or append)New:
public double basePrice(bool includeChildren=false, Space space=null, bool translatePrice=true)
useNewPricing
is enabled → delegates directly to super()item.price()
with PartSpecial
adjustments)The following functions were added to support base price for DsFreeformItem
s.
Added: extend public str currentCurrencyKey(str key) {} Added: extend public double basePrice() {} Added: extend public double basePrice=(double value) {}
The handling of currency-based pricing was refactored to make currentCurrencyKey
more flexible.
Old:
currentCurrencyKey()
directly constructed a key using cDsFPriceKey
and the current currency symbolNew:
currentCurrencyKey()
now delegates to a new overload:
currentCurrencyKey(str key)
→ builds a unique freeform key from the given key and currency symbol.Explicit support for base price has been added to DsFreeformItem
.
Old:
New:
basePrice
field accessors:
basePrice()
→ retrieves the base price using cDsFBasePriceKey
basePrice=(double value)
→ sets the base price.The following functions were introduced or modified to support the transition to the new part pricing system.
Find more documentation on the new pricing system in the compile-time section for cm.core.part.Part
.
Added: extend public bool useNewPartPricing() {} Added: extend public Double optionPriceSum(SpecOption[] opts, Part part=null) {} Added: extend public DsPart createPart(Snapper snapper, PartsEnv env, double basePrice, Double optionPriceSum) {} Changed: extend public void getParts(Snapper snapper, PartsEnv env) {}
Indicates whether the new part pricing system should be used when generating Parts. An opt-in feature flag to the new pricing system.
getParts
, and createPart
.Calculates the total option prices from a collection of SpecOption
s. Optionally takes a Part
parameter to allow for special pricing scenarios.
The createPart
method was split into two overloads to support the new pricing framework.
The new overload takes basePrice
and optionPriceSum
, while the old single-parameter version (using list price) has been marked for deprecation.
Old:
createPart(Snapper snapper, PartsEnv env, double price)
useNewPartPricing
is falseNew:
createPart(Snapper snapper, PartsEnv env, double basePrice, Double optionPriceSum)
basePrice
and optional optionPriceSum
useNewPartPricing
is truebasePrice
and optionPriceSum
The getParts
method was updated to integrate the new pricing model.
Old:
price(options)
createPart(..., price)
Old: extend public void getParts(Snapper snapper, PartsEnv env) { ... if (usePartsCache and cachedParts.any) { ... } else if (prd) { ... double price = price(options); ... DsPart dpart = createPart(snapper, env, price); ... } }
New:
bool newPricing = useNewPartPricing();
basePrice()
, and new createPart
uses new signatureprice(options)
, and createPart
uses legacy signatureinvalidateOptionPriceSum()
to reset option-based pricing.New: extend public void getParts(Snapper snapper, PartsEnv env) { ... if (usePartsCache and cachedParts.any) { for (c in cachedParts) { Part cpy = c.copy; ... cpy.invalidateOptionPriceSum(); } } else if (prd) { ... bool newPricing = useNewPartPricing(); double price = newPricing ? basePrice() : price(options); ... DsPart dpart = newPricing ? createPart(snapper, env, price, null) : createPart(snapper, env, price); ... } }
useNewPartPricing()
is disabled.With the addition of the new part attribute description/notes system, DsPData
now exports
these values during SIF exports in generateConfiguraSifRows(..)
:
final package str[] generateConfiguraSifRows(DsPart part, Space space) { ... //Attributes New: part.generateSifAnnotationRows(env.lines); return res; }
The logic for initializing a pricelistRef
was simplified by replacing an early return with direct initialization when the reference is empty.
Old:
pricelistRef
was already set, the method returned immediately and did nothing.Old: extend public void initPricelist() { if (pricelistRef.any()) return; str code = currentCurrencySymbol(); pricelistRef = code; Date currentDate(date()); dataCatalog.pricelists.put(pricelistRef, PricelistType(pricelistRef, pricelistRef, currentDate)); }
New:
pricelistRef
is empty, it is set to the current currency symbol.pricelistRef
entry in dataCatalog.pricelists
New: extend public void initPricelist() { if (pricelistRef.empty()) pricelistRef = currentCurrencySymbol(); Date currentDate(date()); dataCatalog.pricelists.put(pricelistRef, PricelistType(pricelistRef, pricelistRef, currentDate)); }
The createPart
API was extended to support a new pricing model with separate basePrice
and optionPriceSum
parameters.
The original listPrice
version remains for backward compatibility but is now marked for deprecation.
Old:
createPart
method signature:
public DsPart createPart(Snapper snapper, PartsEnv env, double price)
getParts
when useNewPartPricing
is false New:
createPart
method signature:
public DsPart createPart(Snapper snapper, PartsEnv env, double basePrice, Double optionPriceSum)
getParts
when useNewPartPricing
is truelistPrice
to passing basePrice
and optionPriceSum
The getParts
method was updated to support the new pricing model which is documented in the compile-time section for cm.core.part.Part
.
Instead of always creating parts with a single price, it now conditionally uses basePrice
when the new pricing system is enabled.
Old:
DsPart dpart = createPart(snapper, env, freeformItem.price());
Old: public void getParts(Snapper snapper, PartsEnv env) { ... if (usePartsCache and cachedParts.any) { ... } else { DsPart dpart = createPart(snapper, env, freeformItem.price()); ... } }
New:
useNewPartPricing()
:
basePrice
(and optionPriceSum = null
).New: public void getParts(Snapper snapper, PartsEnv env) { ... if (usePartsCache and cachedParts.any) { ... } else { DsPart dpart; if (useNewPartPricing()) { dpart = createPart(snapper, env, freeformItem.basePrice(), null); } else { dpart = createPart(snapper, env, freeformItem.price()); } ... } }
basePrice
or price
, depending on configuration.The constructor for parts created from DsFreeformPData
was updated to support the new pricing model.
It now conditionally passes basePrice
and optionPriceSum
to the superclass instead of always relying on listPrice
.
Old:
super(snapper, fpData, fpData.freeformItem.price(), qty);
New:
useNewPartPricing()
:
basePrice
and optionPriceSum=null
.listPrice
as before.listPrice
or basePrice
depending on pricing model configuration.The following functions were introduced or modified to support the transition to the new part pricing system.
Find more documentation on the new pricing system in the compile-time section for cm.core.part.Part
.
Added: extend public bool useNewPartPricing(DsPDataProxyEnv dsEnv) {} Added: extend public Double optionPriceSum(DsPDataProxyEnv dsEnv, SpecOption[] opts, Part part=null) {} Added: extend public DsPart createPart(DsPDataProxyEnv dsEnv, PartsEnv env, double basePrice, Double optionPriceSum) {}
Allows proxy-aware code to check whether the new pricing system is enabled.
A new overload of optionPriceSum
was introduced to support execution through a DsPDataProxy
, enabling proxy-aware option pricing calculations.
blockDataProxy
to prevent recursive proxy calls.dsEnv.data.optionPriceSum(opts, part)
.blockDataProxy
is decremented in a finally block for safety.DsPDataProxyEnv
).optionPriceSum(SpecOption[], Part)
method.DsPDataProxy
is available to ensure correct delegation.The createPart
method was split into two overloads to support the new pricing framework.
The new overload takes basePrice
and optionPriceSum
, while the old single-parameter version (using list price) has been marked for deprecation.
Old:
createPart(DsPDataProxyEnv dsEnv, PartsEnv env, double price)
useNewPartPricing
is falseNew:
createPart(DsPDataProxyEnv dsEnv, PartsEnv env, double basePrice, Double optionPriceSum)
useNewPartPricing
is truecreatePart
behavior in the new pricing system.