Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ public function recalculateCost(array $params = []): array
$options['manual_delivery_cost'] = $params['manual_delivery_cost'];
}

$recalculator = new ManagerOrderCostRecalculator($this->modx, $ms3);
$recalculator = $this->modx->services->get('ms3_manager_order_cost_recalculator');
$result = $recalculator->recalculate($order, $options);

if (empty($result['success'])) {
Expand Down
55 changes: 8 additions & 47 deletions core/components/minishop3/src/Controllers/Delivery/Delivery.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use MiniShop3\MiniShop3;
use MiniShop3\Model\msDelivery;
use MiniShop3\Model\msOrder;
use MiniShop3\Utils\PriceAdjustment;
use MiniShop3\Services\Order\OrderCostEngine;
use MODX\Revolution\modX;

/**
Expand Down Expand Up @@ -77,8 +77,6 @@ public function __construct(MiniShop3 $ms3, array $config = [])
*/
public function getCost(msOrder $order, msDelivery $delivery, float $cost): float
{
$deliveryCost = 0;

// Get cart data for weight calculation
$cart = [
'total_weight' => 0,
Expand All @@ -98,51 +96,14 @@ public function getCost(msOrder $order, msDelivery $delivery, float $cost): floa
}
}

// Check free delivery threshold first
// Use $cost parameter (cart cost passed from calculator) for threshold check
$freeDeliveryAmount = (float)$delivery->get('free_delivery_amount');

if ($freeDeliveryAmount > 0 && $cost >= $freeDeliveryAmount) {
return 0;
}

// Cost by weight
$weightPrice = (float)$delivery->get('weight_price');
$cartWeight = (float)($cart['total_weight'] ?? 0);

if ($weightPrice < 0) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
"[Delivery] Invalid weight_price for delivery #{$delivery->get('id')}: {$weightPrice}. Must be >= 0."
);
$weightPrice = 0;
}

$deliveryCost += $weightPrice * $cartWeight;

// Base delivery cost
$addPrice = $delivery->get('price');

if (empty($addPrice)) {
return $deliveryCost;
}

if (PriceAdjustment::isPercent($addPrice)) {
$percent = PriceAdjustment::getPercent($addPrice);
if (!PriceAdjustment::isAllowedPercent($percent)) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
sprintf(
'[Delivery] Invalid percent value for delivery #%s: %s%%. Must be between -100%% and 100%%.',
$delivery->get('id'),
$percent
)
);
return $deliveryCost;
}
}
$cartWeight = (float) ($cart['total_weight'] ?? 0);

return $deliveryCost + PriceAdjustment::calculate($cost, $addPrice);
return OrderCostEngine::calculateDefaultDeliveryCost(
$this->modx,
$delivery,
$cost,
$cartWeight
);
}

/**
Expand Down
27 changes: 4 additions & 23 deletions core/components/minishop3/src/Controllers/Payment/Payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use MiniShop3\MiniShop3;
use MiniShop3\Model\msOrder;
use MiniShop3\Model\msPayment;
use MiniShop3\Utils\PriceAdjustment;
use MiniShop3\Services\Order\OrderCostEngine;
use MODX\Revolution\modX;

/**
Expand Down Expand Up @@ -137,33 +137,14 @@ abstract public function receive(msOrder $order): array;
*
* @param msOrder $order Order (can be used for fee calculation)
* @param msPayment $payment Payment method with fee settings
* @param float $cost Current order cost
* @param float $cost Commission base before surcharge: cart lines + delivery (#372), not cart alone
* @return float Cost including fee
*/
public function getCost(msOrder $order, msPayment $payment, float $cost): float
{
$addPrice = $payment->get('price');
$surcharge = OrderCostEngine::calculatePaymentSurcharge($this->modx, $payment, $cost);

if (empty($addPrice)) {
return $cost;
}

if (PriceAdjustment::isPercent($addPrice)) {
$percent = PriceAdjustment::getPercent($addPrice);
if (!PriceAdjustment::isAllowedPercent($percent)) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
sprintf(
'[Payment] Invalid percent value for payment #%s: %s%%. Must be between -100%% and 100%%.',
$payment->get('id'),
$percent
)
);
return $cost;
}
}

return $cost + PriceAdjustment::calculate($cost, $addPrice);
return OrderCostEngine::calculatePaymentTotal($cost, $surcharge);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions core/components/minishop3/src/ServiceRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class ServiceRegistry
'class' => \MiniShop3\Services\Order\OrderCostCalculator::class,
'interface' => null,
],
'ms3_manager_order_cost_recalculator' => [
'class' => \MiniShop3\Services\Order\ManagerOrderCostRecalculator::class,
'interface' => null,
],
'ms3_order_field_manager' => [
'class' => \MiniShop3\Services\Order\OrderFieldManager::class,
'interface' => null,
Expand Down Expand Up @@ -453,6 +457,7 @@ protected function registerService(string $serviceKey, array $config): bool
$servicesWithModxAndMs3 = [
'ms3_order_draft_manager',
'ms3_order_cost_calculator',
'ms3_manager_order_cost_recalculator',
'ms3_order_user_resolver',
'ms3_order_log',
'ms3_cart_item_manager',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use MiniShop3\Controllers\Delivery\DefaultDelivery;
use MiniShop3\Controllers\Payment\DefaultPayment;
use MiniShop3\MiniShop3;
use MiniShop3\Utils\PriceAdjustment;
use MiniShop3\Model\msDelivery;
use MiniShop3\Model\msOrder;
use MiniShop3\Model\msOrderLog;
Expand All @@ -17,6 +16,9 @@
* Explicit manager-side recomputation of order totals from persisted msOrderProducts
* and configured delivery/payment methods (without mutating unrelated order fields).
*
* Manager adapter: modes (auto/manual/force_provider), warnings, order log — no msOn* cost events.
* Default-handler formulas delegate to {@see OrderCostEngine} (shared with web checkout).
*
* External delivery/payment provider classes are not invoked in {@see self::MODE_AUTO};
* callers should use manual delivery cost or {@see self::MODE_FORCE_PROVIDER}.
*
Expand Down Expand Up @@ -87,7 +89,7 @@ public function recalculate(msOrder $order, array $options = []): array

$deliveryCost = $deliveryResult['delivery_cost'];

$paymentBase = round($cartCost + $deliveryCost, 6);
$paymentBase = OrderCostEngine::paymentCommissionBase($cartCost, $deliveryCost);
$paymentResult = $this->resolvePaymentFee($order, $paymentBase, $mode, $options);
if (!$paymentResult['success']) {
return $paymentResult;
Expand All @@ -99,7 +101,8 @@ public function recalculate(msOrder $order, array $options = []): array

/** @var OrderService $orderService */
$orderService = $this->modx->services->get('ms3_order_service');
$cost = round($orderService->clampComputedTotal($order, $cartCost, $deliveryCost, $paymentFee), 6);
$breakdown = OrderCostEngine::composeBreakdown($order, $orderService, $cartCost, $deliveryCost, $paymentFee);
$cost = $breakdown['cost'];

$before = [
'cart_cost' => (float)$order->get('cart_cost'),
Expand Down Expand Up @@ -221,7 +224,12 @@ protected function resolveDeliveryCost(
if ($this->isSimpleDelivery($msDelivery)) {
return [
'success' => true,
'delivery_cost' => $this->calculateDefaultDeliveryCost($msDelivery, $cartCost, $orderWeight),
'delivery_cost' => OrderCostEngine::calculateDefaultDeliveryCost(
$this->modx,
$msDelivery,
$cartCost,
$orderWeight
),
'warnings' => $warnings,
];
}
Expand Down Expand Up @@ -300,7 +308,7 @@ protected function resolvePaymentFee(msOrder $order, float $paymentBase, string
if ($this->isSimplePayment($msPayment)) {
return [
'success' => true,
'payment_fee' => $this->calculateDefaultPaymentCommission($msPayment, $paymentBase),
'payment_fee' => OrderCostEngine::calculatePaymentSurcharge($this->modx, $msPayment, $paymentBase),
'warnings' => $warnings,
];
}
Expand All @@ -314,81 +322,6 @@ protected function resolvePaymentFee(msOrder $order, float $paymentBase, string
];
}

protected function calculateDefaultDeliveryCost(msDelivery $delivery, float $cartCost, float $orderWeight): float
{
$freeDeliveryAmount = (float)$delivery->get('free_delivery_amount');

if ($freeDeliveryAmount > 0 && $cartCost >= $freeDeliveryAmount) {
return 0.0;
}

$deliveryCost = 0.0;
$weightPrice = (float)$delivery->get('weight_price');
if ($weightPrice < 0) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
'[ManagerOrderCostRecalculator] Invalid weight_price for delivery #' . $delivery->get(
'id'
) . ': ' . $weightPrice,
);
$weightPrice = 0;
}

$deliveryCost += $weightPrice * $orderWeight;

$addPrice = $delivery->get('price');
if (empty($addPrice)) {
return round($deliveryCost, 6);
}

if (PriceAdjustment::isPercent($addPrice)) {
$percent = PriceAdjustment::getPercent($addPrice);
if (!PriceAdjustment::isAllowedPercent($percent)) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
sprintf(
'[ManagerOrderCostRecalculator] Invalid percent for delivery #%s: %s%%. Must be between -100%% and 100%%.',
$delivery->get('id'),
$percent
)
);

return round($deliveryCost, 6);
}
}

return round($deliveryCost + PriceAdjustment::calculate($cartCost, $addPrice), 6);
}

/**
* Surcharge only (excluding base), aligned with {@see \MiniShop3\Controllers\Payment\Payment::getCost()}.
*/
protected function calculateDefaultPaymentCommission(msPayment $payment, float $baseCost): float
{
$addPrice = $payment->get('price');
if (empty($addPrice)) {
return 0.0;
}

if (PriceAdjustment::isPercent($addPrice)) {
$percent = PriceAdjustment::getPercent($addPrice);
if (!PriceAdjustment::isAllowedPercent($percent)) {
$this->modx->log(
modX::LOG_LEVEL_ERROR,
sprintf(
'[ManagerOrderCostRecalculator] Invalid percent for payment #%s: %s%%. Must be between -100%% and 100%%.',
$payment->get('id'),
$percent
)
);

return 0.0;
}
}

return round(PriceAdjustment::calculate($baseCost, $addPrice), 6);
}

protected function isSimpleDelivery(msDelivery $delivery): bool
{
return $this->isDefaultShippingPaymentHandlerClass((string) $delivery->get('class'), DefaultDelivery::class);
Expand Down
Loading