Creating a Custom Post-Process
A guide to building a custom post-process equation from one of three templates - flat fee, percentage of process price, or geometry-based - plus shared rules for all post-process equations.
Overview
Most post-processes can be built from one of three templates. Choose the one that matches how your cost scales, then modify the numbers.
Template 1 - Flat fee
Use when: the post-process costs roughly the same regardless of part size (e.g. inspection, marking, labelling, packaging).
// Level 2 equation
const FLAT_FEE = variable('Post-process cost', 8.00)
const unitPrice = variable('unitPrice', round(FLAT_FEE, 2))
done(unitPrice)That's it. The operator can override the fee per order if needed.
Template 2 - Percentage of process price
Use when: the post-process adds a proportional cost relative to the part's base price (e.g. premium finishing, quality inspection tier).
// Level 2 equation
const PERCENTAGE = variable('Percentage price increase', 0.15) // 15%
const unitPrice = variable('unitPrice', round(processPricing.price * PERCENTAGE, 2))
done(unitPrice)processPricing.price is the unit price returned by the Level 1 equation for this part.
Template 3 - Geometry-based
Use when: cost depends on part size. Choose the right geometry metric:
| Cost driver | Use | Example |
|---|---|---|
| Surface treated | specification.area | Painting, plating, coating, blasting |
| Material consumed | specification.volume or shrinkWrapVolume | Resin coating, impregnation |
| Part weight | (volume / 1000) × density | Plating by gram, dyeing by mass |
// Level 2 equation — area-based example
const { area } = specification
const ratePerMm2 = variable('Rate per mm²', 0.002)
const MIN_CHARGE = variable('Minimum charge', 5.00)
const calculated = round(area * ratePerMm2, 2)
const unitPrice = variable('unitPrice', Math.max(MIN_CHARGE, calculated))
done(unitPrice)Using Level 1 data in Level 2
If your post-process cost depends on something the Level 1 equation calculated (machine time, support volume, machine type), expose it via variable() at Level 1 and read it at Level 2:
// Level 1 (at the end, before done()):
const machineTimeHours = variable('machineTime', round(calculatedTime, 2))
done(unitPrice, machineTimeHours)
// Level 2:
const printTime = processPricing.variables['machineTime'] // hours
const RATE = variable('Rate per hour', 3.00)
const unitPrice = variable('unitPrice', round(printTime * RATE, 2))
done(unitPrice)Rules for all post-process equations
- Always end with
done(unitPrice)- do not forget this - Always wrap the final price in
variable('unitPrice', ...)- this is the operator's escape hatch - Use
reviewRequiredwhen the post-process isn't available for this geometry, colour, or material:
const SUPPORTED_COLORS = ['Black', 'White', 'Grey']
const reviewRequired = !SUPPORTED_COLORS.includes(specification.color ?? '')
const unitPrice = variable('unitPrice', calculatedCost)
done(unitPrice, 0, reviewRequired)- Never multiply by
requisition.quantity- Phasio does this automatically. Return the unit price for one part.
Last updated on
Thread Inserts
How to price heat-set thread inserts in Phasio using a Level 2 equation that reads an operator-entered count exposed as a Level 1 variable.
Level 3 - Order Level Pricing
How to price at the order level - running once per order to apply minimum fees, volume discounts, post-processing minimums, and shipping costs across the whole cart.