Current File : /var/www/vinorea/modules/sendinblue/services/OrderService.php |
<?php
/**
* 2007-2025 Sendinblue
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* 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 contact@sendinblue.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author Sendinblue <contact@sendinblue.com>
* @copyright 2007-2025 Sendinblue
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of Sendinblue
*/
namespace Sendinblue\Services;
if (!defined('_PS_VERSION_')) {
exit;
}
class OrderService
{
private $idShop;
private $psVersion;
public function __construct()
{
$this->idShop = \ContextCore::getContext()->shop->id;
$this->psVersion = version_compare(_PS_VERSION_, '1.7.7') <= 0 ? 'old' : 'new';
}
public function getTotalOrderCount()
{
$query = $this->buildOrderCountQuery();
try {
$result = \DbCore::getInstance()->getValue($query);
return (int) $result;
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3);
return 0;
}
}
public function getOrders($limit, $offset)
{
$baseQuery = $this->buildBaseQuery();
$query = sprintf('%s LIMIT %d, %d', $baseQuery, $offset, $limit);
try {
$orders = \DbCore::getInstance()->executeS($query);
if (empty($orders)) {
return ['orders' => []];
}
return ['orders' => array_map([$this, 'processOrder'], $orders)];
} catch (\Exception $e) {
\PrestaShopLogger::addLog($e->getMessage(), 3);
return ['orders' => []];
}
}
private function buildOrderCountQuery()
{
return sprintf(
'SELECT COUNT(*) AS `count` FROM `%sorders` WHERE `id_shop` = %d',
_DB_PREFIX_,
$this->idShop
);
}
private function buildBaseQuery()
{
$refundedField = $this->getRefundedField();
$orderDetailJoin = $this->getOrderDetailJoin();
$productFields = $this->getJsonOrConcatSQL(\Db::getInstance()->getVersion());
return sprintf(
"SELECT
o.`id_order`, o.`reference`, o.`total_paid_tax_incl` AS total_paid,
o.`date_add`, o.`date_upd`, o.`current_state`, %s,
c.`firstname`, c.`lastname`, c.`email`,
CONCAT(a.`address1`, ' ', a.`address2`) AS address,
a.`city`, a.`postcode`, a.`phone`,
co.`iso_code` AS countryCode, s.`name` AS region,
b.`name` AS order_status, o.`payment` AS paymentMethod,
o.`conversion_rate` AS conversion_rate,
GROUP_CONCAT(DISTINCT cr_lang.`name` SEPARATOR ', ') AS distinct_coupons,
GROUP_CONCAT(
$productFields
) AS products_json
FROM `%sorders` o
LEFT JOIN `%scustomer` c ON o.`id_customer` = c.`id_customer`
LEFT JOIN `%saddress` a ON o.`id_address_invoice` = a.`id_address`
LEFT JOIN `%sorder_state_lang` b ON b.`id_order_state` = o.`current_state` AND b.`id_lang` = 1
LEFT JOIN `%scountry` co ON co.`id_country` = a.`id_country`
LEFT JOIN `%sstate` s ON s.`id_state` = a.`id_state`
LEFT JOIN `%sorder_cart_rule` ocr ON ocr.`id_order` = o.`id_order`
LEFT JOIN `%scart_rule_lang` cr_lang ON ocr.`id_cart_rule` = cr_lang.`id_cart_rule` AND cr_lang.`id_lang` = 1
LEFT JOIN `%sorder_detail` od ON od.`id_order` = o.`id_order`
$orderDetailJoin
LEFT JOIN `%sproduct` p ON p.`id_product` = od.`product_id`
LEFT JOIN `%sproduct_lang` p_lang ON p.`id_product` = p_lang.`id_product` AND p_lang.`id_lang` = 1 AND p_lang.`id_shop` = %d
WHERE o.`id_shop` = %d AND o.`current_state` != 0
GROUP BY o.`id_order`",
$refundedField,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
_DB_PREFIX_,
$this->idShop,
$this->idShop
);
}
private function getRefundedField()
{
if ($this->psVersion === 'old') {
return 'SUM(osd.`amount_tax_incl`) as refunded';
}
return 'SUM(od.`total_refunded_tax_incl`) as refunded';
}
private function getOrderDetailJoin()
{
if ($this->psVersion === 'old') {
return sprintf('LEFT JOIN `%sorder_slip_detail` osd ON (od.`id_order_detail` = osd.`id_order_detail`)', _DB_PREFIX_);
}
return '';
}
private function getJsonOrConcatSQL($dbVersion)
{
$functionName = 'JSON_OBJECT';
if (stripos($dbVersion, 'MariaDB') !== false && version_compare($dbVersion, '10.2.3', '<')) {
$functionName = 'CONCAT';
}
return "$functionName(
'id_product', od.`product_id`,
'id_variant', od.`product_attribute_id`,
'name', p_lang.`name`,
'price', od.`product_price`,
'quantity', od.`product_quantity`
)";
}
private function processOrder($order)
{
$conversionRate = $order['conversion_rate'];
$order['date_add'] = gmdate('Y-m-d\TH:i:s', strtotime($order['date_add']));
$order['date_upd'] = gmdate('Y-m-d\TH:i:s', strtotime($order['date_upd']));
// Prepare billing info
$order['billing'] = $this->prepareBillingInfo($order);
// Process products
$order['products'] = $this->processProducts($order['products_json'], $conversionRate);
unset($order['products_json']);
// Process coupons
$order['coupons'] = !empty($order['distinct_coupons']) ? explode(', ', $order['distinct_coupons']) : [];
unset($order['distinct_coupons']);
// Adjust total paid
$order['total_paid'] = $this->adjustTotalPaid($order['total_paid'], $order['refunded'], $conversionRate, $order['current_state']);
unset($order['refunded']);
// Remove redundant fields from the root level
unset($order['address'], $order['city'], $order['countryCode'], $order['paymentMethod'], $order['phone'], $order['postcode'], $order['region']);
return $order;
}
private function prepareBillingInfo($order)
{
return [
'address' => $order['address'],
'city' => $order['city'],
'postCode' => $order['postcode'],
'phone' => $order['phone'],
'countryCode' => $order['countryCode'],
'paymentMethod' => $order['paymentMethod'],
'region' => $order['region'],
];
}
private function processProducts($productsJson, $conversionRate)
{
$products = json_decode('[' . $productsJson . ']', true);
if (!empty($products)) {
foreach ($products as &$product) {
$product['price'] = round($product['price'] / $conversionRate, 2);
}
}
return $products ?: [];
}
private function adjustTotalPaid($totalPaid, $refunded, $conversionRate, $currentState)
{
return ($currentState == 8 || $currentState == 7 || $currentState == 6)
? '0'
: (string)round(($totalPaid - $refunded) / $conversionRate, 2);
}
}