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
20 changes: 13 additions & 7 deletions src/classes/BusinessLogicServices/SystemInfoService.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,19 @@ private function getCurrencies($systemId = null)
return array();
}

$currency = new \Currency(\Configuration::get(
'PS_CURRENCY_DEFAULT',
null,
null,
$systemId
));
$currencies = \Currency::getCurrenciesByIdShop((int) $systemId);
$isoCodes = array();

return array($currency->iso_code);
foreach ($currencies as $currency) {
if (empty($currency['active']) || !empty($currency['deleted'])) {
continue;
}

if (!empty($currency['iso_code'])) {
$isoCodes[] = $currency['iso_code'];
}
}

return array_values(array_unique($isoCodes));
}
}
64 changes: 62 additions & 2 deletions src/classes/ShippingServices/PackageCostCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Packlink\BusinessLogic\ShippingMethod\ShippingMethodService;
use Packlink\PrestaShop\Classes\Bootstrap;
use Packlink\PrestaShop\Classes\Utility\CachingUtility;
use Packlink\PrestaShop\Classes\Utility\ShippingCostCurrencyConverter;

/**
* Class PackageCostCalculator.
Expand Down Expand Up @@ -62,13 +63,18 @@ public static function getPackageCost(Cart $cart, array $products, $carrierId)
if (self::displayBackupCarrier($cart, $calculatedCosts, $carrierReferenceId)) {
$allCosts = self::getCostsForAllShippingMethods($cart, $shippingProducts);
if (!empty($allCosts)) {
$allCosts = self::convertCostsToCartCurrency($allCosts, $cart);

return self::applyShopCostCalculationSettings(min(array_values($allCosts)), $cart);
}
}

if ($calculatedCosts !== false) {
return isset($calculatedCosts[$methodId])
? self::applyShopCostCalculationSettings($calculatedCosts[$methodId], $cart) : false;
? self::applyShopCostCalculationSettings(
self::convertCostToCartCurrency($calculatedCosts[$methodId], $cart, $methodId),
$cart
) : false;
}

$warehouse = CachingUtility::getDefaultWarehouse();
Expand Down Expand Up @@ -98,7 +104,10 @@ public static function getPackageCost(Cart $cart, array $products, $carrierId)
CachingUtility::setCosts($calculatedCosts);

return isset($calculatedCosts[$methodId])
? self::applyShopCostCalculationSettings($calculatedCosts[$methodId], $cart) : false;
? self::applyShopCostCalculationSettings(
self::convertCostToCartCurrency($calculatedCosts[$methodId], $cart, $methodId),
$cart
) : false;
}

/**
Expand Down Expand Up @@ -234,6 +243,57 @@ private static function getCartTotal(Cart $cart)
return CachingUtility::getCartTotal();
}

/**
* Converts shipping costs from service currency to cart currency.
*
* @param array $costs Shipping costs keyed by shipping method ID.
* @param \Cart $cart
*
* @return array
*
* @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException
* @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException
*/
private static function convertCostsToCartCurrency(array $costs, Cart $cart)
{
$convertedCosts = array();

foreach ($costs as $methodId => $cost) {
$convertedCosts[$methodId] = self::convertCostToCartCurrency($cost, $cart, $methodId);
}

return $convertedCosts;
}

/**
* Converts a single shipping cost from service currency to cart currency.
*
* @param float $cost
* @param \Cart $cart
* @param int|string $methodId
*
* @return float
*
* @throws \Logeecom\Infrastructure\ORM\Exceptions\QueryFilterInvalidParamException
* @throws \Logeecom\Infrastructure\ORM\Exceptions\RepositoryNotRegisteredException
*/
private static function convertCostToCartCurrency($cost, Cart $cart, $methodId)
{
/** @var \Packlink\BusinessLogic\ShippingMethod\ShippingMethodService $shippingMethodService */
$shippingMethodService = ServiceRegister::getService(ShippingMethodService::CLASS_NAME);
$shippingMethod = $shippingMethodService->getShippingMethod($methodId);

if ($shippingMethod === null) {
return $cost;
}

return ShippingCostCurrencyConverter::convertToCartCurrency(
$cost,
$shippingMethod->getCurrency(),
(int) $cart->id_currency
);
}

/**
* Checks shipping cost settings and handling costs and applies settings to the given cost.
*
Expand Down
79 changes: 79 additions & 0 deletions src/classes/Utility/ShippingCostCurrencyConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace Packlink\PrestaShop\Classes\Utility;

/**
* Class ShippingCostCurrencyConverter
*
* @package Packlink\PrestaShop\Classes\Utility
*/
class ShippingCostCurrencyConverter
{
/**
* Converts shipping cost from service/API currency to cart currency.
*
* Uses PrestaShop conversion rates (same logic as Tools::convertPriceFull).
*
* @param float $amount Amount in service currency.
* @param string $fromCurrencyIso ISO code of the service/API currency.
* @param int $cartCurrencyId PrestaShop cart currency ID.
*
* @return float Converted amount in cart currency.
*/
public static function convertToCartCurrency($amount, $fromCurrencyIso, $cartCurrencyId)
{
if (empty($fromCurrencyIso) || (int) $cartCurrencyId <= 0) {
return $amount;
}

$cartCurrency = new \Currency((int) $cartCurrencyId);
if (!\Validate::isLoadedObject($cartCurrency)) {
return $amount;
}

if (strtoupper($fromCurrencyIso) === strtoupper($cartCurrency->iso_code)) {
return $amount;
}

$fromCurrencyId = (int) \Currency::getIdByIsoCode($fromCurrencyIso);
if ($fromCurrencyId <= 0) {
return $amount;
}

$fromCurrency = new \Currency($fromCurrencyId);

return self::convertPrice($amount, $fromCurrency, $cartCurrency);
}

/**
* Converts price between two currencies using shop conversion rates.
*
* @param float $amount
* @param \Currency $currencyFrom
* @param \Currency $currencyTo
*
* @return float
*/
private static function convertPrice($amount, \Currency $currencyFrom, \Currency $currencyTo)
{
if ((int) $currencyFrom->id === (int) $currencyTo->id) {
return $amount;
}

$defaultCurrencyId = (int) \Configuration::get('PS_CURRENCY_DEFAULT');

if ((int) $currencyFrom->id === $defaultCurrencyId) {
$amount *= (float) $currencyTo->conversion_rate;
} else {
$conversionRate = (float) $currencyFrom->conversion_rate;
if ($conversionRate <= 0) {
$conversionRate = 1;
}

$amount = $amount / $conversionRate;
$amount *= (float) $currencyTo->conversion_rate;
}

return (float) \Tools::ps_round($amount, _PS_PRICE_DISPLAY_PRECISION_);
}
}