Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/old/app/code/Chronopost/Chronorelais/Model/Carrier/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //home/corals/old/app/code/Chronopost/Chronorelais/Model/Carrier/AbstractChronopost.php
<?php
/**
 * Chronopost
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category  Chronopost
 * @package   Chronopost_Chronorelais
 * @copyright Copyright (c) 2021 Chronopost
 */
declare(strict_types=1);

namespace Chronopost\Chronorelais\Model\Carrier;

use Chronopost\Chronorelais\Helper\Contract;
use Chronopost\Chronorelais\Helper\Data;
use Chronopost\Chronorelais\Helper\Webservice as HelperWebservice;
use Exception;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Serialize\SerializerInterface;
use Magento\Quote\Model\Quote\Address\RateRequest;
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
use Magento\Quote\Model\Quote\Address\RateResult\Method;
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
use Magento\Shipping\Model\Carrier\AbstractCarrier;
use Magento\Shipping\Model\Carrier\CarrierInterface;
use Magento\Shipping\Model\Rate\Result;
use Magento\Shipping\Model\Rate\ResultFactory;
use Magento\Shipping\Model\Tracking\Result\StatusFactory;
use Magento\Shipping\Model\Tracking\ResultFactory as TrackingResultFactory;
use Psr\Log\LoggerInterface;

/**
 * Class AbstractChronopost
 *
 * @package Chronopost\Chronorelais\Model\Carrier
 * @SuppressWarnings("CouplingBetweenObjects")
 * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
 */
abstract class AbstractChronopost extends AbstractCarrier implements CarrierInterface
{
    const CHECK_RELAI_WS = false;
    const CHECK_CONTRACT = false;
    const OPTION_BAL_ENABLE = false;
    const DELIVER_ON_SATURDAY = false;

    protected $debugData = [];

    /**
     * @var HelperWebservice
     */
    protected $helperWebservice;

    /**
     * @var $helperData
     */
    protected $helperData;

    /**
     * @var ResultFactory
     */
    protected $rateResultFactory;

    /**
     * @var MethodFactory
     */
    protected $rateMethodFactory;

    /**
     * @var TrackingResultFactory
     */
    protected $trackFactory;

    /**
     * @var StatusFactory
     */
    protected $trackStatusFactory;

    /**
     * @var SerializerInterface
     */
    private $jsonSerializer;

    /**
     * @var CheckoutSession
     */
    protected $checkoutSession;

    /**
     * @var Contract
     */
    private $helperContract;

    /**
     * Chronopost constructor.
     *
     * @param ScopeConfigInterface  $scopeConfig
     * @param ErrorFactory          $rateErrorFactory
     * @param LoggerInterface       $logger
     * @param ResultFactory         $rateResultFactory
     * @param MethodFactory         $rateMethodFactory
     * @param HelperWebservice      $helperWebservice
     * @param TrackingResultFactory $trackFactory
     * @param StatusFactory         $trackStatusFactory
     * @param Data                  $helperData
     * @param Contract              $helperContract
     * @param SerializerInterface   $jsonSerializer
     * @param CheckoutSession       $checkoutSession
     * @param array                 $data
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig,
        ErrorFactory $rateErrorFactory,
        LoggerInterface $logger,
        ResultFactory $rateResultFactory,
        MethodFactory $rateMethodFactory,
        HelperWebservice $helperWebservice,
        TrackingResultFactory $trackFactory,
        StatusFactory $trackStatusFactory,
        Data $helperData,
        Contract $helperContract,
        SerializerInterface $jsonSerializer,
        CheckoutSession $checkoutSession,
        array $data = []
    ) {
        $this->rateResultFactory = $rateResultFactory;
        $this->rateMethodFactory = $rateMethodFactory;
        $this->helperWebservice = $helperWebservice;
        $this->trackFactory = $trackFactory;
        $this->trackStatusFactory = $trackStatusFactory;
        $this->helperData = $helperData;
        $this->helperContract = $helperContract;
        $this->jsonSerializer = $jsonSerializer;
        $this->checkoutSession = $checkoutSession;
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
    }

    /**
     * Check if carrier has shipping tracking option available
     *
     * @return bool
     */
    public function isTrackingAvailable()
    {
        return true;
    }

    /**
     * Get tracking informations
     *
     * @param $tracking
     *
     * @return mixed
     */
    public function getTrackingInfo($tracking)
    {
        $tracking_url = $this->helperData->getConfig('chronorelais/shipping/tracking_view_url');
        $tracking_url = str_replace('{tracking_number}', $tracking, $tracking_url);

        $status = $this->trackStatusFactory->create();
        $status->setCarrier($this->_code);
        $status->setCarrierTitle($this->getConfigData('title'));
        $status->setTracking($tracking);
        $status->setPopup(1);
        $status->setUrl($tracking_url);

        return $status;
    }

    /**
     * Get chronopost product code
     *
     * @param $shippingMethod
     *
     * @return string
     */
    public function getChronoProductCode($shippingMethod): string
    {
        return $this->helperData->getChronoProductCode($shippingMethod);
    }

    /**
     * Get chronopost product code str
     *
     * @param string $shippingMethod
     *
     * @return string
     */
    public function getChronoProductCodeStr(string $shippingMethod)
    {
        return $this->helperData->getChronoProductCodeStr($shippingMethod);
    }

    /**
     * Get chronopost product code to shipment
     *
     * @param string      $shippingMethod
     * @param string|null $offer
     *
     * @return string
     */
    public function getChronoProductCodeToShipment(string $shippingMethod, $offer = null)
    {
        if (static::OPTION_BAL_ENABLE) {
            return $this->helperData->getChronoProductCode($shippingMethod, true, $offer);
        }

        return $this->helperData->getChronoProductCode($shippingMethod, false, $offer);
    }

    /**
     * Get chronopost product code (str) to shipment
     *
     * @param string $shippingMethod
     *
     * @return string
     */
    public function getChronoProductCodeToShipmentStr(string $shippingMethod)
    {
        if (static::OPTION_BAL_ENABLE) {
            return $this->helperData->getChronoProductCodeStr($shippingMethod, true);
        }

        return $this->helperData->getChronoProductCodeStr($shippingMethod);
    }

    /**
     * Check if option is enable
     *
     * @return bool
     */
    public function optionBalEnable()
    {
        return static::OPTION_BAL_ENABLE && $this->helperData->getConfigOptionBAL();
    }

    /**
     * @return bool
     */
    public function canDeliverOnSaturday()
    {
        return static::DELIVER_ON_SATURDAY === true;
    }

    /**
     * @return array
     */
    public function getAllowedMethods()
    {
        return [$this->_code => $this->getConfigData('name')];
    }

    /**
     * Check if chronopost method
     *
     * @return bool
     */
    public function getIsChronoMethod()
    {
        return true;
    }

    /**
     * Collect rates
     *
     * @param RateRequest $request
     *
     * @return bool|Result
     * @throws NoSuchEntityException
     */
    public function collectRates(RateRequest $request)
    {
        if (!$this->getConfigFlag('active')) {
            return false;
        }

        $this->debugData = [];
        $this->debugData['request'] = [];
        $this->debugData['error'] = [];
        $this->debugData['request']['code'] = $this->_code;

        /** @var Result $result */
        $result = $this->rateResultFactory->create();

        if (!$this->validateMethod($request)) {
            $this->_debug($this->debugData);

            return false;
        }

        $cartWeight = $this->checkCartWeight($request);
        $this->debugData['request']['cart_weight'] = $cartWeight;
        if ($cartWeight === false) {

            $this->_debug($this->debugData);

            return false;
        }

        $shippingPrice = $this->getShippingPrice($request, $cartWeight);
        $this->debugData['request']['shipping_price'] = $shippingPrice;
        if ($shippingPrice === false) {
            $this->_debug($this->debugData);

            return false;
        }

        // Application fees
        $applicationFee = $this->getConfigData('application_fee');
        if ($applicationFee) {
            $this->debugData['request']['application_fee'] = $applicationFee;
            $shippingPrice += $applicationFee;
        }

        // Processing fee
        $handlingFee = $this->getConfigData('handling_fee');
        if ($handlingFee) {
            $this->debugData['request']['handling_fee'] = $handlingFee;
            $shippingPrice += $handlingFee;
        }

        $shippingPrice = $this->additionalPrice($shippingPrice);
        $this->debugData['request']['shipping_price_total'] = $shippingPrice;

        // Freeshipping
        $freeShippingEnable = $this->getConfigData('free_shipping_enable');
        $freeShippingSubtotal = $this->getConfigData('free_shipping_subtotal');
        $cartTotal = $request->getBaseSubtotalInclTax();

        $this->debugData['request']['free_shipping_enable'] = (int)$freeShippingEnable;
        $this->debugData['request']['free_shipping_subtotal'] = (int)$freeShippingSubtotal;

        if ($freeShippingEnable && $freeShippingSubtotal <= $cartTotal) {
            $shippingPrice = 0;
        }

        /** @var Method $method */
        $method = $this->rateMethodFactory->create();
        $method->setCarrier($this->_code);
        $method->setCarrierTitle($this->getConfigData('title'));
        $method->setMethod($this->_code);
        $method->setMethodTitle($this->getMethodTitle());
        $method->setDescription($this->getConfigData('description'));
        $method->setPrice($shippingPrice);
        $method->setCost($shippingPrice);
        $result->append($method);

        $this->_debug($this->debugData);

        return $result;
    }

    /**
     * Checks if all product weights are below the weight limit
     *
     * @param RateRequest $request
     *
     * @return bool|float
     * @throws NoSuchEntityException
     */
    protected function checkCartWeight(RateRequest $request)
    {
        $cartWeight = 0;
        $weightLimit = $this->getConfigData('weight_limit');
        $weightUnit = $this->helperData->getChronoWeightUnit();

        if ($request->getAllItems()) {
            foreach ($request->getAllItems() as $item) {
                if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
                    continue;
                }

                $itemWeight = $item->getWeight();
                if ($weightUnit === 'g') {
                    $itemWeight /= 1000; // conversion g => kg
                }

                if ($itemWeight > $weightLimit) {
                    $this->debugData['error'][] = __('Weight of products greater than the maximum weight');

                    return false;
                }

                $cartWeight += $itemWeight * $item->getQty();
            }
        }

        return (float)$cartWeight;
    }

    /**
     * Additional conditions to show shipping method, each shipping method model might have their own validateMethod
     * function
     *
     * @param RateRequest $request
     *
     * @return bool
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     */
    public function validateMethod(RateRequest $request)
    {
        if ($request->getDestPostcode() === null) {
            $this->_debug($this->debugData);

            return false;
        }

        if ($this->_code === Data::CHRONO_FRESH_CODE && $request->getDestPostcode() >= 20000 &&
            $request->getDestPostcode() < 21000) {
            return false;
        }

        $shippingMethodIsEnabled = $this->helperData->shippingMethodIsEnabled($this->_code);
        if ($shippingMethodIsEnabled === false) {
            $this->_debug($this->debugData);

            return false;
        }

        // Test if the webservice is available
        if (static::CHECK_RELAI_WS) {
            $webservice = $this->helperWebservice->getPointsRelaisByCp($request->getDestPostcode());
            if ($webservice === false) {
                $this->debugData['error'][] = __('The webservice does not respond');

                return false;
            }
        }

        return $this->helperWebservice->getMethodIsAllowed(static::PRODUCT_CODE, $this->_code, $request);
    }

    /**
     * Get shipping price
     *
     * @param RateRequest $request
     * @param float       $cartWeight
     *
     * @return bool|float
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @throws NoSuchEntityException
     */
    protected function getShippingPrice(RateRequest $request, float $cartWeight)
    {
        $saturdaySupplement = $this->getSaturdaySupplement();
        $corsicaSupplement = (float)$this->helperData->getConfig('chronorelais/tarification/corsica_supplement');

        // Price recovery via WS
        $quickcostEnable = $this->getConfigData('quickcost');
        if ($quickcostEnable) {
            $this->debugData['request']['quickcost'] = 1;
            $quickCostValues = $this->getQuickCostValue($request, $cartWeight);
            if ($quickCostValues && $quickCostValues->return->errorCode === 0) {
                $quickcostValue = (float)$quickCostValues->return->amountTTC;

                // Add margin to quickcost
                if ($quickcostValue !== false) {
                    $this->debugData['request']['quickcost_value'] = $quickcostValue;
                    $quickcostValueWithMargin = $this->addMarginToQuickcost($quickcostValue);

                    return $quickcostValueWithMargin + $saturdaySupplement;
                }
            }
        }

        // Recovery of the price via the price list entered by the customer in BO
        $config = trim((string)$this->getConfigData('config'));
        if ($config) {
            try {
                $fees = $this->getFeesConfig($config, $request->getDestCountryId(), $request->getDestPostcode());
                $gridPrices = $this->parseJsonConfig($fees);
                if ($request->getDestCountryId() === 'FR' && $request->getDestPostcode() >= 20000 &&
                    $request->getDestPostcode() < 21000) {
                    foreach ($gridPrices as $key => $gridPrice) {
                        $gridPrices[$key] = $gridPrice + $corsicaSupplement;
                    }
                }

                $shippingPrice = $this->getPriceFromGrid($gridPrices, $cartWeight);
                if ($shippingPrice !== null) {
                    return $shippingPrice + $saturdaySupplement;
                }
            } catch (\Exception $exception) {
                return false;
            }
        }

        $this->debugData['error'][] = __('No price found');

        return false;
    }

    /**
     * Get quick cost value
     *
     * @param RateRequest $request
     * @param float       $cartWeight
     *
     * @return bool|Object
     * @throws NoSuchEntityException
     */
    protected function getQuickCostValue(RateRequest $request, float $cartWeight)
    {
        $accountNumber = '';
        $accountPassword = '';
        $contract = $this->helperContract->getCarrierContract($this->_code);
        if ($contract !== null) {
            $accountNumber = $contract['number'];
            $accountPassword = $contract['pass'];
        }

        $offer = null;
        if ($this->_code === Data::CHRONO_FRESH_CODE) {
            $offer = $this->helperData->getDefaultChronofreshOffer();
        }

        $productCode = $this->helperData->getChronoProductCode($this->_code, false, $offer);
        $origin_postcode = $this->helperData->getConfig('chronorelais/shipperinformation/zipcode');

        $arrCode = $request->getDestPostcode();
        if ($this->_code === Data::CHRONO_EXPRESS_CODE || $this->_code === Data::CHRONO_CLASSIC_CODE) {
            $arrCode = $request->getDestCountryId();
        }

        $weightUnit = $this->helperData->getChronoWeightUnit();
        if ($weightUnit === 'g') {
            $cartWeight = $this->helperData->getConvertedWeight($cartWeight);
        }

        $wsParams = [
            'accountNumber' => $accountNumber,
            'password'      => $accountPassword,
            'depCode'       => $origin_postcode,
            'arrCode'       => $arrCode,
            'weight'        => $cartWeight,
            'productCode'   => $productCode,
            'type'          => 'M'
        ];

        $this->debugData['request']['quickcost_params'] = $wsParams;
        $quickcostUrl = $this->getConfigData('quickcost_url');
        $quickCostValues = $this->helperWebservice->getQuickcost($wsParams, $quickcostUrl);

        // Manage double code for chronofresh sec
        if ($productCode === Chronofresh::PRODUCT_CODE_SEC && $quickCostValues->return->errorCode === 5) {
            $wsParams['productCode'] = Chronofresh::PRODUCT_CODE_SEC_OLD;
            $quickCostValues = $this->helperWebservice->getQuickcost($wsParams, $quickcostUrl);
        }

        return $quickCostValues;
    }

    /**
     * Add margin to quick cost
     *
     * @param float $quickcostValue
     *
     * @return float|int
     */
    public function addMarginToQuickcost(float $quickcostValue)
    {
        $quickcostMarge = $this->getConfigData('quickcost_marge');
        $quickcostMargeType = $this->getConfigData('quickcost_marge_type');

        if ($quickcostMarge) {
            if ($quickcostMargeType === 'amount') {
                $quickcostValue += $quickcostMarge;
                $this->debugData['request']['quickcost_marge'] = $quickcostMarge;
            } elseif ($quickcostMargeType == 'prcent') {
                $quickcostValue += $quickcostValue * $quickcostMarge / 100;
                $this->debugData['request']['quickcost_marge'] = $quickcostMarge . '%';
            }
        }

        return $quickcostValue;
    }

    /**
     * Get fees config
     *
     * @param string      $config
     * @param null|string $countryId
     * @param null|string $postcode
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     *
     * @return null|string
     * @throws Exception
     */
    protected function getFeesConfig($config, $countryId = null, $postcode = null)
    {
        if (!$countryId) {
            throw new \Exception((string)__('Country id is required'));
        }

        $fees = null;
        $configArray = $this->jsonSerializer->unserialize($config);
        foreach ($configArray as $item) {
            if (!isset($item['fees'])) {
                continue;
            }

            if (isset($item['destination'])) {
                $countries = explode(';', $item['destination']);
                foreach ($countries as $country) {
                    if (preg_match('/(.*)-\((.+)\)/', $country, $matches)) { // Example: FR-(12*,62400)
                        if ($matches[1] === $countryId) {
                            $fees = $item['fees'];
                        }

                        $postcodesConfig = explode(',', $matches[2]);
                        foreach ($postcodesConfig as $postcodeConfig) {
                            if (preg_match('/(.+)\*/', $postcodeConfig, $matches2)) { // Example: 12*
                                if (strpos($postcode, $matches2[1]) !== false) {
                                    $fees = null;
                                }
                            } elseif ($postcode == $postcodeConfig) { // 62400
                                $fees = null;
                            }
                        }
                    } elseif ($country === $countryId) { // Example: FR
                        $fees = $item['fees'];
                        break 2;
                    }
                }
            } else {
                $fees = $item['fees'];
            }
        }

        if (!$fees) {
            throw new \Exception('Config of fees is invalid !');
        }

        return $fees;
    }

    /**
     * Convert the weight / price grid to an array
     *
     * @param string $fees
     *
     * @return array
     */
    protected function parseJsonConfig($fees)
    {
        $array = [];

        $string = str_replace(['{', '}'], '', $fees);
        $string = explode(',', $string);
        foreach ($string as $value) {
            $value = explode(':', $value);
            if (isset($value[0], $value[1]) && $value[0] && $value[1]) {
                $array[trim($value[0])] = trim($value[1]);
            }
        }

        return $array;
    }

    /**
     * Returns price in relation to weight. If basket weight > max weight entered: no price so no delivery method
     *
     * @param array $gridPrices
     * @param float $cartWeight
     *
     * @return float|null
     */
    protected function getPriceFromGrid(array $gridPrices, float $cartWeight)
    {
        $maxWeight = (float)key(array_slice($gridPrices, -1, 1, true));
        if ($cartWeight > $maxWeight) {
            $this->debugData['error'][] = __('No price found in the grid. The weight of the basket is greater ' .
                'than the maximum weight of the grid');

            return null;
        }

        $currentPrice = null;
        foreach ($gridPrices as $weight => $price) {
            if ($cartWeight <= $weight) {
                $currentPrice = (float)$price;
                break;
            }
        }

        return $currentPrice;
    }

    /**
     * Method overloaded in other modes if additional price is needed
     *
     * @param $price
     *
     * @return mixed
     */
    public function additionalPrice($price)
    {
        return $price;
    }

    /**
     * Get method title
     *
     * @return false|string
     */
    public function getMethodTitle()
    {
        return $this->getConfigData('name');
    }

    /**
     * Get Saturday supplement
     *
     * @return float
     */
    private function getSaturdaySupplement()
    {
        if ($this->checkoutSession->getData('chronopost_saturday_option') === '1') {
            return $this->helperData->getSaturdayShippingAmount();
        }

        return (float)'0';
    }
}

Spamworldpro Mini