*/ private array $config; /** * Constructor. * * @param array $config Settings (tax_in_profit, payment_fee_*, shipping_alloc, other_cost_*). */ public function __construct( array $config ) { $this->config = wp_parse_args( $config, array( 'tax_in_profit' => false, 'payment_fee_percent' => 0.0, 'payment_fee_fixed' => 0.0, 'shipping_alloc' => 'value', 'other_cost_percent' => 0.0, 'other_cost_fixed' => 0.0, ) ); } /** * Whether tax should be subtracted as a cost. */ public function tax_is_cost(): bool { return (bool) $this->config['tax_in_profit']; } /** * Whether shipping cost should be allocated to lines. */ public function allocates_shipping(): bool { return 'value' === $this->config['shipping_alloc']; } /** * The total payment-gateway fee for an order. * * @param float $order_total Order grand total (what the customer paid). */ public function order_payment_fee( float $order_total ): float { $pct = (float) $this->config['payment_fee_percent']; $fixed = (float) $this->config['payment_fee_fixed']; return ( $order_total * $pct / 100 ) + $fixed; } /** * The total "other" configurable cost for an order. * * @param float $order_revenue Order revenue (net, excl tax). */ public function order_other_cost( float $order_revenue ): float { $pct = (float) $this->config['other_cost_percent']; $fixed = (float) $this->config['other_cost_fixed']; return ( $order_revenue * $pct / 100 ) + $fixed; } /** * Allocate an order-level amount to a line by its revenue share. * * @param float $amount Order-level amount to spread. * @param float $line_revenue This line's revenue. * @param float $total_revenue Sum of all lines' revenue. */ public function allocate_by_share( float $amount, float $line_revenue, float $total_revenue ): float { if ( $total_revenue <= 0.0 ) { return 0.0; } return $amount * ( $line_revenue / $total_revenue ); } /** * Compute profit for a line from its resolved cost buckets. * * @param array{revenue:float,cost_total:float,tax:float,shipping_alloc:float,payment_fee:float,other_cost:float} $line Line buckets. * @return array{profit:float,margin:float} */ public function line_profit( array $line ): array { $revenue = (float) ( $line['revenue'] ?? 0.0 ); $profit = $revenue - (float) ( $line['cost_total'] ?? 0.0 ) - (float) ( $line['shipping_alloc'] ?? 0.0 ) - (float) ( $line['payment_fee'] ?? 0.0 ) - (float) ( $line['other_cost'] ?? 0.0 ); if ( $this->tax_is_cost() ) { $profit -= (float) ( $line['tax'] ?? 0.0 ); } $margin = $revenue > 0.0 ? ( $profit / $revenue ) : 0.0; return array( 'profit' => $profit, 'margin' => $margin, ); } }