1519 lines
46 KiB
PHP
1519 lines
46 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Cart class - manages shopping cart functionality
|
|
*/
|
|
class Cart extends ObjectModel
|
|
{
|
|
/** @var int|null */
|
|
public $id;
|
|
|
|
/** @var int */
|
|
public $id_shop_group;
|
|
|
|
/** @var int */
|
|
public $id_shop;
|
|
|
|
/** @var int|null */
|
|
public $id_address_delivery;
|
|
|
|
/** @var int|null */
|
|
public $id_address_invoice;
|
|
|
|
/** @var int */
|
|
public $id_currency;
|
|
|
|
/** @var int */
|
|
public $id_customer;
|
|
|
|
/** @var int */
|
|
public $id_guest;
|
|
|
|
/** @var int */
|
|
public $id_lang;
|
|
|
|
/** @var bool */
|
|
public $recyclable = false;
|
|
|
|
/** @var bool */
|
|
public $gift = false;
|
|
|
|
/** @var string */
|
|
public $gift_message;
|
|
|
|
/** @var bool */
|
|
public $mobile_theme = false;
|
|
|
|
/** @var string */
|
|
public $date_add;
|
|
|
|
/** @var string */
|
|
public $secure_key;
|
|
|
|
/** @var int */
|
|
public $id_carrier = 0;
|
|
|
|
/** @var string */
|
|
public $date_upd;
|
|
|
|
/** @var bool */
|
|
public $checkedTos = false;
|
|
|
|
/** @var string */
|
|
public $delivery_option;
|
|
|
|
/** @var bool */
|
|
public $allow_seperated_package = false;
|
|
|
|
// Static cache properties
|
|
protected static $_nbProducts = [];
|
|
protected static $_isVirtualCart = [];
|
|
protected static $_totalWeight = [];
|
|
protected static $_carriers = null;
|
|
protected static $_taxes_rate = null;
|
|
protected static $_attributesLists = [];
|
|
|
|
/** @var Customer|null */
|
|
protected static $_customer = null;
|
|
|
|
// Cache properties
|
|
protected static $cacheDeliveryOption = [];
|
|
protected static $cacheNbPackages = [];
|
|
protected static $cachePackageList = [];
|
|
protected static $cacheDeliveryOptionList = [];
|
|
|
|
// Constants
|
|
public const ONLY_PRODUCTS = 1;
|
|
public const ONLY_DISCOUNTS = 2;
|
|
public const BOTH = 3;
|
|
public const BOTH_WITHOUT_SHIPPING = 4;
|
|
public const ONLY_SHIPPING = 5;
|
|
public const ONLY_WRAPPING = 6;
|
|
public const ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING = 8;
|
|
|
|
/**
|
|
* @see ObjectModel::$definition
|
|
*/
|
|
public static $definition = [
|
|
'table' => 'cart',
|
|
'primary' => 'id_cart',
|
|
'fields' => [
|
|
'id_shop_group' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_shop' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_address_delivery' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_address_invoice' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_carrier' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_currency' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
|
|
'id_customer' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_guest' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
|
'id_lang' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true],
|
|
'recyclable' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
|
'gift' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
|
'gift_message' => ['type' => self::TYPE_STRING, 'validate' => 'isCleanHtml'],
|
|
'mobile_theme' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
|
'delivery_option' => ['type' => self::TYPE_STRING],
|
|
'secure_key' => ['type' => self::TYPE_STRING, 'size' => 32],
|
|
'allow_seperated_package' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
|
|
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
|
'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
|
],
|
|
];
|
|
|
|
/**
|
|
* Reset static cache
|
|
*/
|
|
public static function resetStaticCache()
|
|
{
|
|
self::$_nbProducts = [];
|
|
self::$_isVirtualCart = [];
|
|
self::$_totalWeight = [];
|
|
self::$_carriers = null;
|
|
self::$_taxes_rate = null;
|
|
self::$_attributesLists = [];
|
|
self::$_customer = null;
|
|
self::$cacheDeliveryOption = [];
|
|
self::$cacheNbPackages = [];
|
|
self::$cachePackageList = [];
|
|
self::$cacheDeliveryOptionList = [];
|
|
}
|
|
|
|
/**
|
|
* Get number of products in cart
|
|
*
|
|
* @return int
|
|
*/
|
|
public function nbProducts()
|
|
{
|
|
if (!$this->id) {
|
|
return 0;
|
|
}
|
|
|
|
return self::getNbProducts($this->id);
|
|
}
|
|
|
|
/**
|
|
* Get number of products in cart by ID
|
|
*
|
|
* @param int $id
|
|
* @return int
|
|
*/
|
|
public static function getNbProducts($id)
|
|
{
|
|
if (isset(self::$_nbProducts[$id]) && self::$_nbProducts[$id] !== null) {
|
|
return self::$_nbProducts[$id];
|
|
}
|
|
|
|
self::$_nbProducts[$id] = (int) Db::getInstance()->getValue(
|
|
'SELECT SUM(`quantity`)
|
|
FROM `' . _DB_PREFIX_ . 'cart_product`
|
|
WHERE `id_cart` = ' . (int) $id
|
|
);
|
|
|
|
return self::$_nbProducts[$id];
|
|
}
|
|
|
|
/**
|
|
* Add a CartRule to the Cart
|
|
*
|
|
* @param int $id_cart_rule
|
|
* @param bool $useOrderPrices
|
|
* @return bool
|
|
*/
|
|
public function addCartRule($id_cart_rule, bool $useOrderPrices = false)
|
|
{
|
|
$cartRule = new CartRule($id_cart_rule, Context::getContext()->language->id);
|
|
|
|
if (!Validate::isLoadedObject($cartRule)) {
|
|
return false;
|
|
}
|
|
|
|
if (Db::getInstance()->getValue('SELECT id_cart_rule FROM ' . _DB_PREFIX_ . 'cart_cart_rule WHERE id_cart_rule = ' . (int) $id_cart_rule . ' AND id_cart = ' . (int) $this->id)) {
|
|
return false;
|
|
}
|
|
|
|
if (!Db::getInstance()->insert('cart_cart_rule', [
|
|
'id_cart_rule' => (int) $id_cart_rule,
|
|
'id_cart' => (int) $this->id,
|
|
])) {
|
|
return false;
|
|
}
|
|
|
|
Cache::clean('Cart::getCartRules_' . $this->id . '-' . CartRule::FILTER_ACTION_ALL);
|
|
Cache::clean('Cart::getCartRules_' . $this->id . '-' . CartRule::FILTER_ACTION_SHIPPING);
|
|
Cache::clean('Cart::getCartRules_' . $this->id . '-' . CartRule::FILTER_ACTION_REDUCTION);
|
|
Cache::clean('Cart::getCartRules_' . $this->id . '-' . CartRule::FILTER_ACTION_GIFT);
|
|
|
|
if ((int) $cartRule->gift_product) {
|
|
$this->updateQty(
|
|
1,
|
|
$cartRule->gift_product,
|
|
$cartRule->gift_product_attribute,
|
|
false,
|
|
'up',
|
|
0,
|
|
null,
|
|
false,
|
|
false,
|
|
true,
|
|
$useOrderPrices
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get product quantity in cart
|
|
*
|
|
* @param int $idProduct
|
|
* @param int $idProductAttribute
|
|
* @param int $idCustomization
|
|
* @param int $idAddressDelivery
|
|
* @return array
|
|
*/
|
|
public function getProductQuantity($idProduct, $idProductAttribute = 0, $idCustomization = 0, $idAddressDelivery = 0)
|
|
{
|
|
$sql = 'SELECT SUM(cp.`quantity`) as quantity
|
|
FROM `' . _DB_PREFIX_ . 'cart_product` cp
|
|
WHERE cp.`id_product` = ' . (int) $idProduct . '
|
|
AND cp.`id_product_attribute` = ' . (int) $idProductAttribute . '
|
|
AND cp.`id_customization` = ' . (int) $idCustomization . '
|
|
AND cp.`id_cart` = ' . (int) $this->id;
|
|
|
|
if ($idAddressDelivery) {
|
|
$sql .= ' AND cp.`id_address_delivery` = ' . (int) $idAddressDelivery;
|
|
}
|
|
|
|
$result = Db::getInstance()->getRow($sql);
|
|
|
|
return [
|
|
'quantity' => (int) $result['quantity'],
|
|
'deep_quantity' => (int) $result['quantity']
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Update product quantity
|
|
*
|
|
* @param int $quantity
|
|
* @param int $id_product
|
|
* @param int|null $id_product_attribute
|
|
* @param int|false $id_customization
|
|
* @param string $operator
|
|
* @param int $id_address_delivery
|
|
* @param Shop|null $shop
|
|
* @param bool $auto_add_cart_rule
|
|
* @param bool $skipAvailabilityCheckOutOfStock
|
|
* @param bool $preserveGiftRemoval
|
|
* @param bool $useOrderPrices
|
|
* @return bool|int
|
|
*/
|
|
public function updateQty(
|
|
$quantity,
|
|
$id_product,
|
|
$id_product_attribute = null,
|
|
$id_customization = false,
|
|
$operator = 'up',
|
|
$id_address_delivery = 0,
|
|
?Shop $shop = null,
|
|
$auto_add_cart_rule = true,
|
|
$skipAvailabilityCheckOutOfStock = false,
|
|
bool $preserveGiftRemoval = true,
|
|
bool $useOrderPrices = false
|
|
) {
|
|
if (!$shop) {
|
|
$shop = Context::getContext()->shop;
|
|
}
|
|
|
|
$quantity = (int) $quantity;
|
|
$id_product = (int) $id_product;
|
|
$id_product_attribute = (int) $id_product_attribute;
|
|
$id_customization = (int) $id_customization;
|
|
|
|
$product = new Product($id_product, false, (int) Configuration::get('PS_LANG_DEFAULT'), $shop->id);
|
|
|
|
if (!Validate::isLoadedObject($product)) {
|
|
return false;
|
|
}
|
|
|
|
if ($id_product_attribute) {
|
|
$combination = new Combination((int) $id_product_attribute);
|
|
if ($combination->id_product != $id_product) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$currentQuantity = $this->getProductQuantity($id_product, $id_product_attribute, $id_customization, $id_address_delivery);
|
|
$currentQuantity = (int) $currentQuantity['quantity'];
|
|
|
|
if ($operator == 'up') {
|
|
$newQuantity = $currentQuantity + $quantity;
|
|
} elseif ($operator == 'down') {
|
|
$newQuantity = $currentQuantity - $quantity;
|
|
} else {
|
|
$newQuantity = $quantity;
|
|
}
|
|
|
|
if ($newQuantity <= 0) {
|
|
return $this->deleteProduct($id_product, $id_product_attribute, $id_customization, $id_address_delivery, $preserveGiftRemoval, $useOrderPrices);
|
|
}
|
|
|
|
// Check if product exists in cart
|
|
$sql = 'SELECT `id_cart_product` FROM `' . _DB_PREFIX_ . 'cart_product`
|
|
WHERE `id_cart` = ' . (int) $this->id . '
|
|
AND `id_product` = ' . (int) $id_product . '
|
|
AND `id_product_attribute` = ' . (int) $id_product_attribute . '
|
|
AND `id_customization` = ' . (int) $id_customization;
|
|
|
|
if ($id_address_delivery) {
|
|
$sql .= ' AND `id_address_delivery` = ' . (int) $id_address_delivery;
|
|
}
|
|
|
|
$result = Db::getInstance()->getRow($sql);
|
|
|
|
if ($result) {
|
|
// Update existing product
|
|
$sql = 'UPDATE `' . _DB_PREFIX_ . 'cart_product`
|
|
SET `quantity` = ' . (int) $newQuantity . '
|
|
WHERE `id_cart_product` = ' . (int) $result['id_cart_product'];
|
|
} else {
|
|
// Add new product
|
|
$sql = 'INSERT INTO `' . _DB_PREFIX_ . 'cart_product`
|
|
(`id_cart`, `id_product`, `id_product_attribute`, `id_customization`, `id_address_delivery`, `quantity`)
|
|
VALUES (' . (int) $this->id . ', ' . (int) $id_product . ', ' . (int) $id_product_attribute . ', ' . (int) $id_customization . ', ' . (int) $id_address_delivery . ', ' . (int) $newQuantity . ')';
|
|
}
|
|
|
|
if (!Db::getInstance()->execute($sql)) {
|
|
return false;
|
|
}
|
|
|
|
// Clear cache
|
|
self::$_nbProducts[$this->id] = null;
|
|
self::$_totalWeight[$this->id] = null;
|
|
|
|
return $newQuantity;
|
|
}
|
|
|
|
/**
|
|
* Delete product from cart
|
|
*
|
|
* @param int $id_product
|
|
* @param int $id_product_attribute
|
|
* @param int $id_customization
|
|
* @param int $id_address_delivery
|
|
* @param bool $preserveGiftsRemoval
|
|
* @param bool $useOrderPrices
|
|
* @return bool
|
|
*/
|
|
public function deleteProduct(
|
|
$id_product,
|
|
$id_product_attribute = 0,
|
|
$id_customization = 0,
|
|
$id_address_delivery = 0,
|
|
bool $preserveGiftsRemoval = true,
|
|
bool $useOrderPrices = false
|
|
) {
|
|
$sql = 'DELETE FROM `' . _DB_PREFIX_ . 'cart_product`
|
|
WHERE `id_cart` = ' . (int) $this->id . '
|
|
AND `id_product` = ' . (int) $id_product . '
|
|
AND `id_product_attribute` = ' . (int) $id_product_attribute . '
|
|
AND `id_customization` = ' . (int) $id_customization;
|
|
|
|
if ($id_address_delivery) {
|
|
$sql .= ' AND `id_address_delivery` = ' . (int) $id_address_delivery;
|
|
}
|
|
|
|
if (!Db::getInstance()->execute($sql)) {
|
|
return false;
|
|
}
|
|
|
|
// Clear cache
|
|
self::$_nbProducts[$this->id] = null;
|
|
self::$_totalWeight[$this->id] = null;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Get order total
|
|
*
|
|
* @param bool $withTaxes
|
|
* @param int $type
|
|
* @param array|null $products
|
|
* @param int|null $id_carrier
|
|
* @param bool $use_cache
|
|
* @param bool $keepOrderPrices
|
|
* @return float
|
|
*/
|
|
public function getOrderTotal(
|
|
$withTaxes = true,
|
|
$type = self::BOTH,
|
|
$products = null,
|
|
$id_carrier = null,
|
|
$use_cache = false,
|
|
bool $keepOrderPrices = false
|
|
) {
|
|
$total = 0;
|
|
|
|
if ($type == self::ONLY_PRODUCTS || $type == self::BOTH || $type == self::BOTH_WITHOUT_SHIPPING) {
|
|
$products = $this->getProducts($use_cache, false, null, true, $keepOrderPrices);
|
|
|
|
foreach ($products as $product) {
|
|
$price = $product['price_with_reduction'];
|
|
if (!$withTaxes) {
|
|
$price = $product['price_with_reduction_without_tax'];
|
|
}
|
|
$total += $price * $product['cart_quantity'];
|
|
}
|
|
}
|
|
|
|
if ($type == self::ONLY_DISCOUNTS || $type == self::BOTH) {
|
|
$discounts = $this->getDiscounts();
|
|
foreach ($discounts as $discount) {
|
|
$total -= $discount['value_real'];
|
|
}
|
|
}
|
|
|
|
if ($type == self::ONLY_SHIPPING || $type == self::BOTH) {
|
|
if ($id_carrier) {
|
|
$total += $this->getCarrierCost($id_carrier, $withTaxes);
|
|
}
|
|
}
|
|
|
|
if ($type == self::ONLY_WRAPPING || $type == self::BOTH) {
|
|
if ($this->gift) {
|
|
$total += $this->getGiftWrappingPrice($withTaxes);
|
|
}
|
|
}
|
|
|
|
return Tools::ps_round($total, 2);
|
|
}
|
|
|
|
/**
|
|
* Get total weight
|
|
*
|
|
* @param array|null $products
|
|
* @return float
|
|
*/
|
|
public function getTotalWeight($products = null)
|
|
{
|
|
if (!$this->id) {
|
|
return 0;
|
|
}
|
|
|
|
if (isset(self::$_totalWeight[$this->id])) {
|
|
return self::$_totalWeight[$this->id];
|
|
}
|
|
|
|
if ($products === null) {
|
|
$products = $this->getProducts();
|
|
}
|
|
|
|
$weight = 0;
|
|
foreach ($products as $product) {
|
|
$weight += $product['weight'] * $product['cart_quantity'];
|
|
}
|
|
|
|
self::$_totalWeight[$this->id] = $weight;
|
|
return $weight;
|
|
}
|
|
|
|
/**
|
|
* Check if cart is virtual (only virtual products)
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isVirtualCart()
|
|
{
|
|
if (!$this->id) {
|
|
return true;
|
|
}
|
|
|
|
if (isset(self::$_isVirtualCart[$this->id])) {
|
|
return self::$_isVirtualCart[$this->id];
|
|
}
|
|
|
|
$sql = 'SELECT COUNT(*)
|
|
FROM `' . _DB_PREFIX_ . 'cart_product` cp
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON cp.`id_product` = p.`id_product`
|
|
WHERE cp.`id_cart` = ' . (int) $this->id . '
|
|
AND p.`is_virtual` = 0';
|
|
|
|
$result = Db::getInstance()->getValue($sql);
|
|
$isVirtual = ($result == 0);
|
|
|
|
self::$_isVirtualCart[$this->id] = $isVirtual;
|
|
return $isVirtual;
|
|
}
|
|
|
|
/**
|
|
* Check if cart has products
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasProducts()
|
|
{
|
|
if (!$this->id) {
|
|
return false;
|
|
}
|
|
|
|
return (bool) Db::getInstance()->getValue(
|
|
'SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'cart_product` WHERE `id_cart` = ' . (int) $this->id
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Check if cart has real products
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function hasRealProducts()
|
|
{
|
|
if (!$this->id) {
|
|
return false;
|
|
}
|
|
|
|
$sql = 'SELECT COUNT(*)
|
|
FROM `' . _DB_PREFIX_ . 'cart_product` cp
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON cp.`id_product` = p.`id_product`
|
|
WHERE cp.`id_cart` = ' . (int) $this->id . '
|
|
AND p.`is_virtual` = 0';
|
|
|
|
return (bool) Db::getInstance()->getValue($sql);
|
|
}
|
|
|
|
/**
|
|
* Get carrier cost
|
|
*
|
|
* @param int $id_carrier
|
|
* @param bool $useTax
|
|
* @param Country|null $default_country
|
|
* @param string|null $delivery_option
|
|
* @return float
|
|
*/
|
|
public function getCarrierCost($id_carrier, $useTax = true, ?Country $default_country = null, $delivery_option = null)
|
|
{
|
|
// Simplified carrier cost calculation
|
|
$carrier = new Carrier($id_carrier);
|
|
if (!Validate::isLoadedObject($carrier)) {
|
|
return 0;
|
|
}
|
|
|
|
$cost = $carrier->getDeliveryPriceByWeight($this->getTotalWeight());
|
|
|
|
if ($useTax) {
|
|
$tax = new Tax($carrier->getIdTaxRulesGroup());
|
|
if (Validate::isLoadedObject($tax)) {
|
|
$cost += $cost * ($tax->rate / 100);
|
|
}
|
|
}
|
|
|
|
return Tools::ps_round($cost, 2);
|
|
}
|
|
|
|
/**
|
|
* Get gift wrapping price
|
|
*
|
|
* @param bool $with_taxes
|
|
* @param int|null $id_address
|
|
* @return float
|
|
*/
|
|
public function getGiftWrappingPrice($with_taxes = true, $id_address = null)
|
|
{
|
|
$wrapping_fees = (float) Configuration::get('PS_GIFT_WRAPPING_PRICE');
|
|
|
|
if ($with_taxes) {
|
|
$tax = new Tax(Configuration::get('PS_GIFT_WRAPPING_TAX_RULES_GROUP'));
|
|
if (Validate::isLoadedObject($tax)) {
|
|
$wrapping_fees += $wrapping_fees * ($tax->rate / 100);
|
|
}
|
|
}
|
|
|
|
return Tools::ps_round($wrapping_fees, 2);
|
|
}
|
|
|
|
/**
|
|
* Get last none ordered cart
|
|
*
|
|
* @param int $id_customer
|
|
* @return int|false
|
|
*/
|
|
public static function lastNoneOrderedCart($id_customer)
|
|
{
|
|
$sql = 'SELECT c.`id_cart`
|
|
FROM `' . _DB_PREFIX_ . 'cart` c
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON c.`id_cart` = o.`id_cart`
|
|
WHERE c.`id_customer` = ' . (int) $id_customer . '
|
|
AND o.`id_cart` IS NULL
|
|
ORDER BY c.`date_add` DESC';
|
|
|
|
return Db::getInstance()->getValue($sql);
|
|
}
|
|
|
|
/**
|
|
* Get customer carts
|
|
*
|
|
* @param int $id_customer
|
|
* @param bool $with_order
|
|
* @return array
|
|
*/
|
|
public static function getCustomerCarts($id_customer, $with_order = true)
|
|
{
|
|
$sql = 'SELECT c.*
|
|
FROM `' . _DB_PREFIX_ . 'cart` c';
|
|
|
|
if ($with_order) {
|
|
$sql .= ' LEFT JOIN `' . _DB_PREFIX_ . 'orders` o ON c.`id_cart` = o.`id_cart`
|
|
WHERE c.`id_customer` = ' . (int) $id_customer . '
|
|
AND o.`id_cart` IS NULL';
|
|
} else {
|
|
$sql .= ' WHERE c.`id_customer` = ' . (int) $id_customer;
|
|
}
|
|
|
|
$sql .= ' ORDER BY c.`date_add` DESC';
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
/**
|
|
* Check quantities
|
|
*
|
|
* @param bool $returnProductOnFailure
|
|
* @return bool|array
|
|
*/
|
|
public function checkQuantities($returnProductOnFailure = false)
|
|
{
|
|
$products = $this->getProducts();
|
|
$errors = [];
|
|
|
|
foreach ($products as $product) {
|
|
if (!$product['active'] || !$product['available_for_order']) {
|
|
$errors[] = $product;
|
|
continue;
|
|
}
|
|
|
|
if ($product['quantity'] < $product['cart_quantity']) {
|
|
$errors[] = $product;
|
|
}
|
|
}
|
|
|
|
if ($returnProductOnFailure) {
|
|
return $errors;
|
|
}
|
|
|
|
return empty($errors);
|
|
}
|
|
|
|
/**
|
|
* Get products
|
|
*
|
|
* @param bool $refresh
|
|
* @param bool $id_product
|
|
* @param int|null $id_country
|
|
* @param bool $fullInfos
|
|
* @param bool $keepOrderPrices
|
|
* @return array
|
|
*/
|
|
public function getProducts($refresh = false, $id_product = false, $id_country = null, $fullInfos = true, bool $keepOrderPrices = false)
|
|
{
|
|
if (!$this->id) {
|
|
return [];
|
|
}
|
|
|
|
$sql = 'SELECT cp.*, p.*, pl.*, i.`id_image`, cl.`name` as category_default
|
|
FROM `' . _DB_PREFIX_ . 'cart_product` cp
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'product` p ON cp.`id_product` = p.`id_product`
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON p.`id_product` = pl.`id_product` AND pl.`id_lang` = ' . (int) $this->id_lang . '
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'image` i ON p.`id_product` = i.`id_product` AND i.`cover` = 1
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'category_lang` cl ON p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = ' . (int) $this->id_lang . '
|
|
WHERE cp.`id_cart` = ' . (int) $this->id;
|
|
|
|
if ($id_product) {
|
|
$sql .= ' AND cp.`id_product` = ' . (int) $id_product;
|
|
}
|
|
|
|
$sql .= ' ORDER BY cp.`date_add` ASC';
|
|
|
|
$products = Db::getInstance()->executeS($sql);
|
|
|
|
if (!$products) {
|
|
return [];
|
|
}
|
|
|
|
foreach ($products as &$product) {
|
|
$product['price_with_reduction'] = $product['price'];
|
|
$product['price_with_reduction_without_tax'] = $product['price'];
|
|
$product['total'] = $product['price'] * $product['cart_quantity'];
|
|
$product['total_wt'] = $product['price'] * $product['cart_quantity'];
|
|
}
|
|
|
|
return $products;
|
|
}
|
|
|
|
/**
|
|
* Get discounts
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getDiscounts()
|
|
{
|
|
$sql = 'SELECT cr.*, crl.`name`
|
|
FROM `' . _DB_PREFIX_ . 'cart_cart_rule` ccr
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule` cr ON ccr.`id_cart_rule` = cr.`id_cart_rule`
|
|
LEFT JOIN `' . _DB_PREFIX_ . 'cart_rule_lang` crl ON cr.`id_cart_rule` = crl.`id_cart_rule` AND crl.`id_lang` = ' . (int) $this->id_lang . '
|
|
WHERE ccr.`id_cart` = ' . (int) $this->id . '
|
|
AND cr.`active` = 1';
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
// Erweiterte Cart-Funktionen
|
|
public function setTaxCalculationMethod()
|
|
{
|
|
$this->_taxCalculationMethod = Configuration::get('PS_TAX');
|
|
}
|
|
|
|
public function updateAddressId($id_address, $id_address_new)
|
|
{
|
|
$sql = 'UPDATE ' . _DB_PREFIX_ . 'cart_product
|
|
SET id_address_delivery = ' . (int) $id_address_new . '
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_address_delivery = ' . (int) $id_address;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function updateDeliveryAddressId($currentAddressId, $newAddressId)
|
|
{
|
|
$sql = 'UPDATE ' . _DB_PREFIX_ . 'cart_product
|
|
SET id_address_delivery = ' . (int) $newAddressId . '
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_address_delivery = ' . (int) $currentAddressId;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function getCartRules($filter = CartRule::FILTER_ACTION_ALL, $autoAdd = true, $useOrderPrices = false)
|
|
{
|
|
$sql = 'SELECT cr.*, crl.*
|
|
FROM ' . _DB_PREFIX_ . 'cart_cart_rule ccr
|
|
LEFT JOIN ' . _DB_PREFIX_ . 'cart_rule cr ON (ccr.id_cart_rule = cr.id_cart_rule)
|
|
LEFT JOIN ' . _DB_PREFIX_ . 'cart_rule_lang crl ON (cr.id_cart_rule = crl.id_cart_rule AND crl.id_lang = ' . (int) Context::getContext()->language->id . ')
|
|
WHERE ccr.id_cart = ' . (int) $this->id;
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
public function getOrderedCartRulesIds($filter = CartRule::FILTER_ACTION_ALL)
|
|
{
|
|
$sql = 'SELECT id_cart_rule FROM ' . _DB_PREFIX_ . 'cart_cart_rule
|
|
WHERE id_cart = ' . (int) $this->id;
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
public function getDiscountsCustomer($id_cart_rule)
|
|
{
|
|
$sql = 'SELECT * FROM ' . _DB_PREFIX_ . 'cart_cart_rule
|
|
WHERE id_cart_rule = ' . (int) $id_cart_rule . '
|
|
AND id_cart = ' . (int) $this->id;
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
public function getLastProduct()
|
|
{
|
|
$sql = 'SELECT cp.*, p.*, pl.*
|
|
FROM ' . _DB_PREFIX_ . 'cart_product cp
|
|
LEFT JOIN ' . _DB_PREFIX_ . 'product p ON (cp.id_product = p.id_product)
|
|
LEFT JOIN ' . _DB_PREFIX_ . 'product_lang pl ON (p.id_product = pl.id_product AND pl.id_lang = ' . (int) Context::getContext()->language->id . ')
|
|
WHERE cp.id_cart = ' . (int) $this->id . '
|
|
ORDER BY cp.date_add DESC
|
|
LIMIT 1';
|
|
|
|
return Db::getInstance()->getRow($sql);
|
|
}
|
|
|
|
public function removeCartRule($id_cart_rule, $useOrderPrices = false)
|
|
{
|
|
$sql = 'DELETE FROM ' . _DB_PREFIX_ . 'cart_cart_rule
|
|
WHERE id_cart_rule = ' . (int) $id_cart_rule . '
|
|
AND id_cart = ' . (int) $this->id;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function orderExists()
|
|
{
|
|
$sql = 'SELECT id_order FROM ' . _DB_PREFIX_ . 'orders
|
|
WHERE id_cart = ' . (int) $this->id;
|
|
|
|
return (bool) Db::getInstance()->getValue($sql);
|
|
}
|
|
|
|
public function _addCustomization($id_product, $id_product_attribute, $index, $type, $value, $quantity, $returnId = false)
|
|
{
|
|
$customization = [
|
|
'id_product' => (int) $id_product,
|
|
'id_product_attribute' => (int) $id_product_attribute,
|
|
'id_cart' => (int) $this->id,
|
|
'quantity' => (int) $quantity,
|
|
'type' => (int) $type,
|
|
'index' => (int) $index,
|
|
];
|
|
|
|
if ($type == Product::CUSTOMIZE_TEXTFIELD) {
|
|
$customization['value'] = pSQL($value);
|
|
} elseif ($type == Product::CUSTOMIZE_FILE) {
|
|
$customization['value'] = pSQL($value);
|
|
}
|
|
|
|
$id_customization = Db::getInstance()->insert('customization', $customization);
|
|
|
|
if ($returnId) {
|
|
return $id_customization;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getTotalCart($id_cart, $use_tax_display = false, $type = Cart::BOTH)
|
|
{
|
|
$cart = new Cart($id_cart);
|
|
return $cart->getOrderTotal($use_tax_display, $type);
|
|
}
|
|
|
|
public function getOrderTotalUsingTaxCalculationMethod($id_cart)
|
|
{
|
|
$cart = new Cart($id_cart);
|
|
return $cart->getOrderTotal(true, Cart::BOTH);
|
|
}
|
|
|
|
public function newCalculator($products, $cartRules, $id_carrier, $computePrecision = null, $keepOrderPrices = false)
|
|
{
|
|
// Calculator-Implementierung
|
|
return new Calculator($products, $cartRules, $id_carrier, $computePrecision, $keepOrderPrices);
|
|
}
|
|
|
|
public function getDiscountSubtotalWithoutGifts($withTaxes = true)
|
|
{
|
|
$products = $this->getProducts();
|
|
$subtotal = 0;
|
|
|
|
foreach ($products as $product) {
|
|
if (!$product['is_gift']) {
|
|
$subtotal += $product['total_price'];
|
|
}
|
|
}
|
|
|
|
return $subtotal;
|
|
}
|
|
|
|
public function countProductLines($products)
|
|
{
|
|
return count($products);
|
|
}
|
|
|
|
public function getDeliveryAddressId($products = null)
|
|
{
|
|
if (!$products) {
|
|
$products = $this->getProducts();
|
|
}
|
|
|
|
if (count($products) == 0) {
|
|
return 0;
|
|
}
|
|
|
|
return (int) $products[0]['id_address_delivery'];
|
|
}
|
|
|
|
public function getTotalCalculationCartRules($type, $withShipping)
|
|
{
|
|
$cartRules = $this->getCartRules();
|
|
$total = 0;
|
|
|
|
foreach ($cartRules as $cartRule) {
|
|
if ($cartRule['free_shipping'] && $withShipping) {
|
|
$total += $this->getCarrierCost($this->id_carrier);
|
|
} else {
|
|
$total += $cartRule['value_real'];
|
|
}
|
|
}
|
|
|
|
return $total;
|
|
}
|
|
|
|
public function findTaxRulesGroupId($withTaxes, $product, $virtualContext)
|
|
{
|
|
if ($withTaxes) {
|
|
return $product['id_tax_rules_group'];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public function getProductAddressId($product = null)
|
|
{
|
|
if (!$product) {
|
|
$products = $this->getProducts();
|
|
if (count($products) == 0) {
|
|
return 0;
|
|
}
|
|
$product = $products[0];
|
|
}
|
|
|
|
return (int) $product['id_address_delivery'];
|
|
}
|
|
|
|
public function getTaxAddressId()
|
|
{
|
|
return $this->getProductAddressId();
|
|
}
|
|
|
|
public function calculateWrappingFees($withTaxes, $type)
|
|
{
|
|
if ($this->gift) {
|
|
$wrapping_fees = Configuration::get('PS_GIFT_WRAPPING_PRICE');
|
|
if ($withTaxes) {
|
|
$wrapping_fees *= (1 + (Configuration::get('PS_GIFT_WRAPPING_TAX_RATE') / 100));
|
|
}
|
|
return $wrapping_fees;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
public function getNbOfPackages()
|
|
{
|
|
$products = $this->getProducts();
|
|
$package_list = [];
|
|
|
|
foreach ($products as $product) {
|
|
$package_list[$product['id_address_delivery']][] = $product;
|
|
}
|
|
|
|
return count($package_list);
|
|
}
|
|
|
|
public function getPackageList($flush = false)
|
|
{
|
|
$products = $this->getProducts();
|
|
$package_list = [];
|
|
|
|
foreach ($products as $product) {
|
|
$package_list[$product['id_address_delivery']][] = $product;
|
|
}
|
|
|
|
return $package_list;
|
|
}
|
|
|
|
public function getPackageIdWarehouse($package, $id_carrier = null)
|
|
{
|
|
$warehouse_list = [];
|
|
|
|
foreach ($package as $product) {
|
|
$warehouse_list[] = $product['id_warehouse'];
|
|
}
|
|
|
|
return array_unique($warehouse_list);
|
|
}
|
|
|
|
public function getDeliveryOptionList($default_country = null, $flush = false)
|
|
{
|
|
$delivery_option_list = [];
|
|
|
|
if (!$default_country) {
|
|
$default_country = Context::getContext()->country;
|
|
}
|
|
|
|
$carriers = Carrier::getCarriers(Context::getContext()->language->id, true, false, false, null, Carrier::ALL_CARRIERS);
|
|
|
|
foreach ($carriers as $carrier) {
|
|
$delivery_option_list[$carrier['id_carrier']] = [
|
|
'id_carrier' => $carrier['id_carrier'],
|
|
'name' => $carrier['name'],
|
|
'delay' => $carrier['delay'],
|
|
'price' => $this->getCarrierCost($carrier['id_carrier']),
|
|
];
|
|
}
|
|
|
|
return $delivery_option_list;
|
|
}
|
|
|
|
public static function sortDeliveryOptionList($option1, $option2)
|
|
{
|
|
if ($option1['price'] == $option2['price']) {
|
|
return 0;
|
|
}
|
|
|
|
return ($option1['price'] < $option2['price']) ? -1 : 1;
|
|
}
|
|
|
|
public function carrierIsSelected($id_carrier, $id_address)
|
|
{
|
|
return $this->id_carrier == $id_carrier;
|
|
}
|
|
|
|
public function simulateCarrierSelectedOutput($use_cache = true)
|
|
{
|
|
$delivery_option = $this->getDeliveryOption();
|
|
$delivery_option_list = $this->getDeliveryOptionList();
|
|
|
|
foreach ($delivery_option_list as $id_carrier => $option) {
|
|
if (isset($delivery_option[$id_carrier])) {
|
|
return $delivery_option[$id_carrier];
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function intifier($string, $delimiter = ',')
|
|
{
|
|
$array = explode($delimiter, $string);
|
|
$array = array_map('intval', $array);
|
|
|
|
return $array;
|
|
}
|
|
|
|
public static function desintifier($int, $delimiter = ',')
|
|
{
|
|
if (is_array($int)) {
|
|
return implode($delimiter, $int);
|
|
}
|
|
|
|
return $int;
|
|
}
|
|
|
|
public function isMultiAddressDelivery()
|
|
{
|
|
$products = $this->getProducts();
|
|
$addresses = [];
|
|
|
|
foreach ($products as $product) {
|
|
$addresses[] = $product['id_address_delivery'];
|
|
}
|
|
|
|
return count(array_unique($addresses)) > 1;
|
|
}
|
|
|
|
public function getAddressCollection()
|
|
{
|
|
$addresses = [];
|
|
$products = $this->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
$addresses[] = new Address($product['id_address_delivery']);
|
|
}
|
|
|
|
return $addresses;
|
|
}
|
|
|
|
public function setDeliveryOption($delivery_option = null)
|
|
{
|
|
if (!$delivery_option) {
|
|
$delivery_option = $this->getDeliveryOption();
|
|
}
|
|
|
|
$this->delivery_option = serialize($delivery_option);
|
|
$this->id_carrier = $this->getIdCarrierFromDeliveryOption($delivery_option);
|
|
|
|
return $this->update();
|
|
}
|
|
|
|
protected function getIdCarrierFromDeliveryOption($delivery_option)
|
|
{
|
|
if (is_array($delivery_option)) {
|
|
foreach ($delivery_option as $id_carrier) {
|
|
return (int) $id_carrier;
|
|
}
|
|
}
|
|
|
|
return (int) $delivery_option;
|
|
}
|
|
|
|
public function getDeliveryOption($default_country = null, $dontAutoSelectOptions = false, $use_cache = true)
|
|
{
|
|
if (!$default_country) {
|
|
$default_country = Context::getContext()->country;
|
|
}
|
|
|
|
$delivery_option_list = $this->getDeliveryOptionList($default_country);
|
|
|
|
if ($dontAutoSelectOptions) {
|
|
return $delivery_option_list;
|
|
}
|
|
|
|
// Auto-select first option
|
|
foreach ($delivery_option_list as $id_carrier => $option) {
|
|
return [$id_carrier => $option];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
public function getTotalShippingCost($delivery_option = null, $use_tax = true, $default_country = null)
|
|
{
|
|
if (!$delivery_option) {
|
|
$delivery_option = $this->getDeliveryOption();
|
|
}
|
|
|
|
$total_shipping = 0;
|
|
|
|
foreach ($delivery_option as $id_carrier => $option) {
|
|
$total_shipping += $this->getCarrierCost($id_carrier, $use_tax, $default_country);
|
|
}
|
|
|
|
return $total_shipping;
|
|
}
|
|
|
|
public function getPackageShippingCost($id_carrier = null, $use_tax = true, $default_country = null, $product_list = null, $id_zone = null, $keepOrderPrices = false)
|
|
{
|
|
if (!$id_carrier) {
|
|
$id_carrier = $this->id_carrier;
|
|
}
|
|
|
|
return $this->getPackageShippingCostValue($id_carrier, $use_tax, $default_country, $product_list, $id_zone, $keepOrderPrices);
|
|
}
|
|
|
|
protected function getPackageShippingCostValue($id_carrier = null, $use_tax = true, $default_country = null, $product_list = null, $id_zone = null, $keepOrderPrices = false)
|
|
{
|
|
if (!$id_carrier) {
|
|
$id_carrier = $this->id_carrier;
|
|
}
|
|
|
|
if (!$product_list) {
|
|
$product_list = $this->getProducts();
|
|
}
|
|
|
|
if (!$default_country) {
|
|
$default_country = Context::getContext()->country;
|
|
}
|
|
|
|
$carrier = new Carrier($id_carrier);
|
|
$shipping_cost = $carrier->getShippingCost($this->getTotalWeight($product_list), $default_country);
|
|
|
|
if ($use_tax) {
|
|
$shipping_cost *= (1 + ($carrier->getTaxesRate($default_country) / 100));
|
|
}
|
|
|
|
return $shipping_cost;
|
|
}
|
|
|
|
protected function getPackageShippingCostFromModule($carrier, $shipping_cost, $products)
|
|
{
|
|
// Module-spezifische Versandkosten
|
|
return $shipping_cost;
|
|
}
|
|
|
|
protected function updateProductWeight($productId)
|
|
{
|
|
$product = new Product($productId);
|
|
$weight = $product->weight;
|
|
|
|
$sql = 'UPDATE ' . _DB_PREFIX_ . 'cart_product
|
|
SET weight = ' . (float) $weight . '
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_product = ' . (int) $productId;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function getSummaryDetails($id_lang = null, $refresh = false)
|
|
{
|
|
if (!$id_lang) {
|
|
$id_lang = Context::getContext()->language->id;
|
|
}
|
|
|
|
$summary = [
|
|
'products' => $this->getProducts(),
|
|
'total_products' => $this->getOrderTotal(false, Cart::ONLY_PRODUCTS),
|
|
'total_discounts' => $this->getOrderTotal(false, Cart::ONLY_DISCOUNTS),
|
|
'total_wrapping' => $this->getOrderTotal(false, Cart::ONLY_WRAPPING),
|
|
'total_shipping' => $this->getOrderTotal(true, Cart::ONLY_SHIPPING),
|
|
'total_price' => $this->getOrderTotal(true, Cart::BOTH),
|
|
'total_tax' => $this->getOrderTotal(true, Cart::BOTH) - $this->getOrderTotal(false, Cart::BOTH),
|
|
];
|
|
|
|
return $summary;
|
|
}
|
|
|
|
public function getRawSummaryDetails($id_lang, $refresh = false)
|
|
{
|
|
return $this->getSummaryDetails($id_lang, $refresh);
|
|
}
|
|
|
|
public function checkProductsAccess()
|
|
{
|
|
$products = $this->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
if (!$product['active']) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static function getCartByOrderId($id_order)
|
|
{
|
|
$sql = 'SELECT id_cart FROM ' . _DB_PREFIX_ . 'orders
|
|
WHERE id_order = ' . (int) $id_order;
|
|
|
|
return Db::getInstance()->getValue($sql);
|
|
}
|
|
|
|
public static function getCartIdByOrderId($id_order)
|
|
{
|
|
return self::getCartByOrderId($id_order);
|
|
}
|
|
|
|
public function addTextFieldToProduct($id_product, $index, $type, $text_value, $returnCustomizationId = false)
|
|
{
|
|
return $this->_addCustomization($id_product, 0, $index, $type, $text_value, 1, $returnCustomizationId);
|
|
}
|
|
|
|
public function addPictureToProduct($id_product, $index, $type, $file, $returnCustomizationId = false)
|
|
{
|
|
return $this->_addCustomization($id_product, 0, $index, $type, $file, 1, $returnCustomizationId);
|
|
}
|
|
|
|
public function deleteCustomizationToProduct($id_product, $index)
|
|
{
|
|
$sql = 'DELETE FROM ' . _DB_PREFIX_ . 'customization
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_product = ' . (int) $id_product . '
|
|
AND `index` = ' . (int) $index;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function getProductCustomization($id_product, $type = null, $not_in_cart = false)
|
|
{
|
|
$sql = 'SELECT * FROM ' . _DB_PREFIX_ . 'customization
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_product = ' . (int) $id_product;
|
|
|
|
if ($type !== null) {
|
|
$sql .= ' AND type = ' . (int) $type;
|
|
}
|
|
|
|
if ($not_in_cart) {
|
|
$sql .= ' AND id_customization NOT IN (SELECT id_customization FROM ' . _DB_PREFIX_ . 'cart_product WHERE id_cart = ' . (int) $this->id . ')';
|
|
}
|
|
|
|
return Db::getInstance()->executeS($sql);
|
|
}
|
|
|
|
public function duplicate()
|
|
{
|
|
$cart = new Cart();
|
|
$cart->id_shop_group = $this->id_shop_group;
|
|
$cart->id_shop = $this->id_shop;
|
|
$cart->id_address_delivery = $this->id_address_delivery;
|
|
$cart->id_address_invoice = $this->id_address_invoice;
|
|
$cart->id_currency = $this->id_currency;
|
|
$cart->id_customer = $this->id_customer;
|
|
$cart->id_guest = $this->id_guest;
|
|
$cart->id_lang = $this->id_lang;
|
|
$cart->recyclable = $this->recyclable;
|
|
$cart->gift = $this->gift;
|
|
$cart->gift_message = $this->gift_message;
|
|
$cart->mobile_theme = $this->mobile_theme;
|
|
$cart->secure_key = $this->secure_key;
|
|
$cart->id_carrier = $this->id_carrier;
|
|
$cart->delivery_option = $this->delivery_option;
|
|
$cart->allow_seperated_package = $this->allow_seperated_package;
|
|
|
|
if ($cart->add()) {
|
|
$products = $this->getProducts();
|
|
foreach ($products as $product) {
|
|
$cart->updateQty($product['quantity'], $product['id_product'], $product['id_product_attribute']);
|
|
}
|
|
|
|
return $cart;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function getWsCartRows()
|
|
{
|
|
$products = $this->getProducts();
|
|
$cart_rows = [];
|
|
|
|
foreach ($products as $product) {
|
|
$cart_rows[] = [
|
|
'id_product' => $product['id_product'],
|
|
'id_product_attribute' => $product['id_product_attribute'],
|
|
'id_address_delivery' => $product['id_address_delivery'],
|
|
'id_customization' => $product['id_customization'],
|
|
'quantity' => $product['quantity'],
|
|
];
|
|
}
|
|
|
|
return $cart_rows;
|
|
}
|
|
|
|
public function setWsCartRows($values)
|
|
{
|
|
// Bestehende Produkte löschen
|
|
Db::getInstance()->delete('cart_product', 'id_cart = ' . (int) $this->id);
|
|
|
|
// Neue Produkte hinzufügen
|
|
foreach ($values as $value) {
|
|
$data = [
|
|
'id_cart' => (int) $this->id,
|
|
'id_product' => (int) $value['id_product'],
|
|
'id_product_attribute' => (int) $value['id_product_attribute'],
|
|
'id_address_delivery' => (int) $value['id_address_delivery'],
|
|
'id_customization' => (int) $value['id_customization'],
|
|
'quantity' => (int) $value['quantity'],
|
|
];
|
|
Db::getInstance()->insert('cart_product', $data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function setProductAddressDelivery($id_product, $id_product_attribute, $old_id_address_delivery, $new_id_address_delivery)
|
|
{
|
|
$sql = 'UPDATE ' . _DB_PREFIX_ . 'cart_product
|
|
SET id_address_delivery = ' . (int) $new_id_address_delivery . '
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_product = ' . (int) $id_product . '
|
|
AND id_product_attribute = ' . (int) $id_product_attribute . '
|
|
AND id_address_delivery = ' . (int) $old_id_address_delivery;
|
|
|
|
return Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function setProductCustomizedDatas(&$product, $customized_datas)
|
|
{
|
|
$product['customizedDatas'] = $customized_datas;
|
|
}
|
|
|
|
public function duplicateProduct($id_product, $id_product_attribute, $id_address_delivery, $new_id_address_delivery, $quantity = 1, $keep_quantity = false)
|
|
{
|
|
$data = [
|
|
'id_cart' => (int) $this->id,
|
|
'id_product' => (int) $id_product,
|
|
'id_product_attribute' => (int) $id_product_attribute,
|
|
'id_address_delivery' => (int) $new_id_address_delivery,
|
|
'quantity' => (int) $quantity,
|
|
];
|
|
|
|
return Db::getInstance()->insert('cart_product', $data);
|
|
}
|
|
|
|
public function setNoMultishipping()
|
|
{
|
|
$this->allow_seperated_package = false;
|
|
return $this->update();
|
|
}
|
|
|
|
public function autosetProductAddress()
|
|
{
|
|
$products = $this->getProducts();
|
|
if (count($products) == 0) {
|
|
return;
|
|
}
|
|
|
|
$id_address_delivery = $products[0]['id_address_delivery'];
|
|
$sql = 'UPDATE ' . _DB_PREFIX_ . 'cart_product
|
|
SET id_address_delivery = ' . (int) $id_address_delivery . '
|
|
WHERE id_cart = ' . (int) $this->id;
|
|
|
|
Db::getInstance()->execute($sql);
|
|
}
|
|
|
|
public function deleteAssociations()
|
|
{
|
|
return Db::getInstance()->delete('cart_product', 'id_cart = ' . (int) $this->id);
|
|
}
|
|
|
|
public function isCarrierInRange($id_carrier, $id_zone)
|
|
{
|
|
$carrier = new Carrier($id_carrier);
|
|
return $carrier->getZone($id_zone);
|
|
}
|
|
|
|
public static function isGuestCartByCartId($id_cart)
|
|
{
|
|
$sql = 'SELECT id_guest FROM ' . _DB_PREFIX_ . 'cart
|
|
WHERE id_cart = ' . (int) $id_cart;
|
|
|
|
return (bool) Db::getInstance()->getValue($sql);
|
|
}
|
|
|
|
public function checkAllProductsAreStillAvailableInThisState()
|
|
{
|
|
$products = $this->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
if (!$product['active']) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function isAllProductsInStock($ignoreVirtual = false)
|
|
{
|
|
$products = $this->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
if ($ignoreVirtual && $product['is_virtual']) {
|
|
continue;
|
|
}
|
|
|
|
if ($product['quantity'] > $product['stock_quantity']) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function checkAllProductsHaveMinimalQuantities()
|
|
{
|
|
$products = $this->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
if ($product['quantity'] < $product['minimal_quantity']) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
protected function splitGiftsProductsQuantity()
|
|
{
|
|
$this->shouldSplitGiftProductsQuantity = true;
|
|
}
|
|
|
|
protected function mergeGiftsProductsQuantity()
|
|
{
|
|
$this->shouldSplitGiftProductsQuantity = false;
|
|
}
|
|
|
|
protected function excludeGiftsDiscountFromTotal()
|
|
{
|
|
$this->shouldExcludeGiftsDiscount = true;
|
|
}
|
|
|
|
protected function includeGiftsDiscountInTotal()
|
|
{
|
|
$this->shouldExcludeGiftsDiscount = false;
|
|
}
|
|
|
|
public function getProductsWithSeparatedGifts()
|
|
{
|
|
$products = $this->getProducts();
|
|
$gifts = [];
|
|
$regular_products = [];
|
|
|
|
foreach ($products as $product) {
|
|
if ($product['is_gift']) {
|
|
$gifts[] = $product;
|
|
} else {
|
|
$regular_products[] = $product;
|
|
}
|
|
}
|
|
|
|
return [
|
|
'gifts' => $gifts,
|
|
'regular_products' => $regular_products,
|
|
];
|
|
}
|
|
|
|
public function getTaxCountry()
|
|
{
|
|
$address = new Address($this->getTaxAddressId());
|
|
return new Country($address->id_country);
|
|
}
|
|
|
|
public function alterSummaryForDisplay($summary, $refresh = false)
|
|
{
|
|
// Summary für Anzeige anpassen
|
|
return $summary;
|
|
}
|
|
|
|
public function getCartTotalPrice()
|
|
{
|
|
return $this->getOrderTotal(true, Cart::BOTH);
|
|
}
|
|
|
|
public function getProductQuantityInAllVariants($idProduct)
|
|
{
|
|
$sql = 'SELECT SUM(quantity) as total_quantity FROM ' . _DB_PREFIX_ . 'cart_product
|
|
WHERE id_cart = ' . (int) $this->id . '
|
|
AND id_product = ' . (int) $idProduct;
|
|
|
|
$result = Db::getInstance()->getRow($sql);
|
|
return isset($result['total_quantity']) ? (int) $result['total_quantity'] : 0;
|
|
}
|
|
}
|