Skip to content

Commit

Permalink
feat: new checkout with delivery options works
Browse files Browse the repository at this point in the history
  • Loading branch information
PoulainMaxime committed Nov 27, 2024
1 parent 5c3380e commit e4a20e7
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 5 deletions.
4 changes: 4 additions & 0 deletions classes/checkout/DeliveryOptionsFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
*/
use PrestaShop\PrestaShop\Adapter\Presenter\Object\ObjectPresenter;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
use PrestaShop\PrestaShop\Core\Checkout\DeliveryOptionsBuilder;
use Symfony\Contracts\Translation\TranslatorInterface;

class DeliveryOptionsFinderCore
Expand Down Expand Up @@ -72,7 +73,10 @@ public function getSelectedDeliveryOption()

public function getDeliveryOptions()
{
return (new DeliveryOptionsBuilder($this->context, $this->priceFormatter, $this->translator))->getDeliveryOptions();

$delivery_option_list = $this->context->cart->getDeliveryOptionList();

Check failure on line 78 in classes/checkout/DeliveryOptionsFinder.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.2)

Unreachable statement - code above always terminates.

Check failure on line 78 in classes/checkout/DeliveryOptionsFinder.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.1)

Unreachable statement - code above always terminates.

Check failure on line 78 in classes/checkout/DeliveryOptionsFinder.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis (8.3)

Unreachable statement - code above always terminates.

$include_taxes = !Product::getTaxCalculationMethod((int) $this->context->cart->id_customer) && (int) Configuration::get('PS_TAX');
$display_taxes_label = (Configuration::get('PS_TAX') && $this->context->country->display_tax_label && !Configuration::get('AEUC_LABEL_TAX_INC_EXC'));

Expand Down
2 changes: 1 addition & 1 deletion classes/order/OrderDetail.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ class OrderDetailCore extends ObjectModel
'id_order' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'id_order_invoice' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
'id_warehouse' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'id_order_carrier' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'id_order_carrier' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
'id_shop' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
'product_id' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
'product_attribute_id' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
Expand Down
5 changes: 1 addition & 4 deletions install-dev/data/db_structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,7 @@ CREATE TABLE IF NOT EXISTS `PREFIX_order_invoice_tax` (
/* order detail (every product inside an order) */
CREATE TABLE `PREFIX_order_detail` (
`id_order_detail` int(10) unsigned NOT NULL auto_increment,
`id_order_carrier` int(10) unsigned DEFAULT 0,
`id_order` int(10) unsigned NOT NULL,
`id_order_invoice` int(11) DEFAULT NULL,
`id_warehouse` int(10) unsigned DEFAULT '0',
Expand Down Expand Up @@ -3031,7 +3032,3 @@ CREATE TABLE `PREFIX_access` (
KEY `IDX_564352A15FCA037F` (`id_profile`),
KEY `IDX_564352A18C6DE0E5` (`id_authorization_role`)
) ENGINE=ENGINE_TYPE DEFAULT CHARSET=utf8mb4 COLLATION;

ALTER TABLE `PREFIX_order_carrier` ADD `id_order_invoice` INT(10) UNSIGNED DEFAULT NULL AFTER `id_order`;

ALTER TABLE `PREFIX_order_detail` ADD `id_order_carrier` INT(10) UNSIGNED DEFAULT NULL AFTER `id_order`;
52 changes: 52 additions & 0 deletions src/Core/Checkout/DeliveryOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

namespace PrestaShop\PrestaShop\Core\Checkout;

use Product;

class DeliveryOption {
/**
* @var array
*/
private $combination = [];

public function addCombination($combination)
{
$this->combination[] = $combination;
}

public function getCombination()
{
return $this->combination;
}

public function getCombinationByCarrier()
{
$result = [];
foreach ($this->combination as $combination) {
$result[$combination['id_carrier']]['products'][] = $combination['product'];
$result[$combination['id_carrier']]['carrierName'] = $combination['display_name'];
}

return $result;
}
}
187 changes: 187 additions & 0 deletions src/Core/Checkout/DeliveryOptionsBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php

/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <[email protected]>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/

namespace PrestaShop\PrestaShop\Core\Checkout;

use PrestaShop\PrestaShop\Core\Checkout\DeliveryOption;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
use Symfony\Contracts\Translation\TranslatorInterface;
use Context;
use Configuration;
use Country;
use Product;
use Carrier;

class DeliveryOptionsBuilder
{
/**
* @var Context
*/
private $context;

/**
* @var PriceFormatter
*/
private $priceFormatter;

/**
* @var TranslatorInterface
*/
private $translator;

/**
* @var array
*/
private $deliveryOptions = [];

public function __construct(Context $context, PriceFormatter $priceFormatter, TranslatorInterface $translator)
{
$this->context = $context;
$this->priceFormatter = $priceFormatter;
$this->translator = $translator;
}

public function getSelectedCarriers() {}

public function getDeliveryOptions()
{
$this->findAllCombinations($this->context->cart->getProducts(), 0, null);
$this->calculateShippingCost();

return $this->deliveryOptions;
}

public function findAllCombinations(array $products, int $currentPosition, $deliveryOption)
{
$carriersFromCurrentPosition = (new Product($products[$currentPosition]['id_product']))->getCarriers();
$nextPosition = isset($products[$currentPosition + 1]) ? $currentPosition + 1 : -1;

foreach($carriersFromCurrentPosition as $carrier) {
if ($deliveryOption === null) {
$deliveryOption = new DeliveryOption();
}

$cpyDeliveryOption = clone($deliveryOption);

$cpyDeliveryOption->addCombination([
'product' => $products[$currentPosition],
'id_carrier' => $carrier['id_carrier'],
'display_name' => $carrier['name']
]);

if ($nextPosition !== -1) {
$this->findAllCombinations($products, $nextPosition, $cpyDeliveryOption);
} else {
$this->deliveryOptions[]['productsGroupedByCarrier'] = $cpyDeliveryOption->getCombinationByCarrier();
}
}
}

private function calculateShippingCost()
{
$includeTaxes = !Product::getTaxCalculationMethod((int) $this->context->cart->id_customer) && (int) Configuration::get('PS_TAX');
$displayTaxesLabel = (Configuration::get('PS_TAX') && $this->context->country->display_tax_label && !Configuration::get('AEUC_LABEL_TAX_INC_EXC'));
$priceWithoutTax = 0;
$priceWithTax = 0;

// TODO: maybe split this to distinct function
foreach($this->deliveryOptions as $key => $deliveryOption) {
$this->deliveryOptions[$key]['details']['price_without_tax'] = 0;
$this->deliveryOptions[$key]['details']['price_with_tax'] = 0;

foreach($deliveryOption['productsGroupedByCarrier'] as $carrierId => $products) {
$priceWithoutTax += $this->context->cart->getPackageShippingCost($carrierId, false, new Country($this->context->language->id), $products['products']);
$priceWithTax += $this->context->cart->getPackageShippingCost($carrierId, true, new Country($this->context->language->id), $products['products']);
$this->deliveryOptions[$key]['details']['price_without_tax'] = $priceWithoutTax;
$this->deliveryOptions[$key]['details']['price_with_tax'] = $priceWithTax;

if ($this->isFreeShipping($carrierId)) {
$this->deliveryOptions[$key]['details']['price'] = $this->translator->trans(
'Free',
[],
'Shop.Theme.Checkout'
);
} else {
if ($includeTaxes) {
$this->deliveryOptions[$key]['details']['price'] = $this->priceFormatter->format($priceWithTax);
if ($displayTaxesLabel) {
$this->deliveryOptions[$key]['details']['price'] = $this->translator->trans(
'%price% tax incl.',
['%price%' => $this->deliveryOptions[$key]['details']['price']],
'Shop.Theme.Checkout'
);
}
} else {
$this->deliveryOptions[$key]['details']['price'] = $this->priceFormatter->format($priceWithoutTax);
if ($displayTaxesLabel) {
$this->deliveryOptions[$key]['details']['price'] = $this->translator->trans(
'%price% tax excl.',
['%price%' => $this->deliveryOptions[$key]['details']['price']],
'Shop.Theme.Checkout'
);
}
}
}
$this->deliveryOptions[$key]['details']['carrier_name'] = $this->getCarrierName($key)['carrierName'];
$this->deliveryOptions[$key]['details']['ids_carriers'] = $this->getCarrierName($key)['idsCarriers'];

}
$priceWithoutTax = 0;
$priceWithTax = 0;
}
}

private function isFreeShipping(int $carrierId)
{
$free_shipping = false;
$carrier = new Carrier($carrierId);

if ($carrier->is_free) {
$free_shipping = true;
} else {
foreach ($this->context->cart->getCartRules() as $rule) {
if ($rule['free_shipping'] && !$rule['carrier_restriction']) {
$free_shipping = true;

break;
}
}
}

return $free_shipping;
}

private function getCarrierName($index)
{
$details = [];

foreach($this->deliveryOptions[$index]['productsGroupedByCarrier'] as $carrierId => $products) {
$carrier = new Carrier($carrierId);
$details['carrierName'][] = $carrier->name;
$details['idsCarriers'][] = $carrierId;
}

$details['carrierName'] = implode(' + ', $details['carrierName']);
$details['idsCarriers'] = implode(',', $details['idsCarriers']);

return $details;
}
}
Loading

0 comments on commit e4a20e7

Please sign in to comment.