Some checks failed
Telegram Mini App Shop Builder / Compute version metadata (push) Has been cancelled
Telegram Mini App Shop Builder / Run Frontend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run Backend tests (push) Has been cancelled
Telegram Mini App Shop Builder / Run PHP_CodeSniffer (push) Has been cancelled
Telegram Mini App Shop Builder / Build module. (push) Has been cancelled
Telegram Mini App Shop Builder / release (push) Has been cancelled
315 lines
13 KiB
PHP
Executable File
315 lines
13 KiB
PHP
Executable File
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use Cart\Cart;
|
|
use Cart\Currency;
|
|
use Acme\ECommerceFramework\ECommerce\Decorators\OcRegistryDecorator;
|
|
|
|
class CartService
|
|
{
|
|
private OcRegistryDecorator $oc;
|
|
private Cart $cart;
|
|
private Currency $currency;
|
|
|
|
public function __construct(OcRegistryDecorator $registry, Cart $cart, Currency $currency)
|
|
{
|
|
$this->oc = $registry;
|
|
$this->cart = $cart;
|
|
$this->currency = $currency;
|
|
}
|
|
|
|
public function getCart(): array
|
|
{
|
|
$this->oc->load->language('checkout/cart');
|
|
|
|
if ($this->oc->cart->hasProducts()) {
|
|
if (
|
|
! $this->oc->cart->hasStock()
|
|
&& (
|
|
! $this->oc->config->get('config_stock_checkout')
|
|
|| $this->oc->config->get('config_stock_warning')
|
|
)
|
|
) {
|
|
$data['error_warning'] = $this->oc->language->get('error_stock');
|
|
} elseif (isset($this->oc->session->data['error'])) {
|
|
$data['error_warning'] = $this->oc->session->data['error'];
|
|
|
|
unset($this->oc->session->data['error']);
|
|
} else {
|
|
$data['error_warning'] = '';
|
|
}
|
|
|
|
if ($this->oc->config->get('config_customer_price') && ! $this->oc->customer->isLogged()) {
|
|
$data['attention'] = sprintf(
|
|
$this->oc->language->get('text_login'),
|
|
$this->oc->url->link('account/login'),
|
|
$this->oc->url->link('account/register')
|
|
);
|
|
} else {
|
|
$data['attention'] = '';
|
|
}
|
|
|
|
if (isset($this->oc->session->data['success'])) {
|
|
$data['success'] = $this->oc->session->data['success'];
|
|
|
|
unset($this->oc->session->data['success']);
|
|
} else {
|
|
$data['success'] = '';
|
|
}
|
|
|
|
if ($this->oc->config->get('config_cart_weight')) {
|
|
$data['weight'] = $this->oc->weight->format(
|
|
$this->oc->cart->getWeight(),
|
|
$this->oc->config->get('config_weight_class_id'),
|
|
$this->oc->language->get('decimal_point'),
|
|
$this->oc->language->get('thousand_point')
|
|
);
|
|
} else {
|
|
$data['weight'] = '';
|
|
}
|
|
|
|
$this->oc->load->model('tool/image');
|
|
$this->oc->load->model('tool/upload');
|
|
|
|
$data['products'] = array();
|
|
|
|
$products = $this->oc->cart->getProducts();
|
|
|
|
foreach ($products as $product) {
|
|
$product_total = 0;
|
|
|
|
foreach ($products as $product_2) {
|
|
if ($product_2['product_id'] == $product['product_id']) {
|
|
$product_total += $product_2['quantity'];
|
|
}
|
|
}
|
|
|
|
if ($product['minimum'] > $product_total) {
|
|
$data['error_warning'] = sprintf(
|
|
$this->oc->language->get('error_minimum'),
|
|
$product['name'],
|
|
$product['minimum']
|
|
);
|
|
}
|
|
|
|
if ($product['image']) {
|
|
$image = $this->oc->model_tool_image->resize(
|
|
$product['image'],
|
|
$this->oc->config->get('theme_' . $this->oc->config->get('config_theme') . '_image_cart_width'),
|
|
$this->oc->config->get('theme_' . $this->oc->config->get('config_theme') . '_image_cart_height')
|
|
);
|
|
} else {
|
|
$image = '';
|
|
}
|
|
|
|
$option_data = array();
|
|
|
|
foreach ($product['option'] as $option) {
|
|
if ($option['type'] != 'file') {
|
|
$value = $option['value'];
|
|
} else {
|
|
$upload_info = $this->oc->model_tool_upload->getUploadByCode($option['value']);
|
|
|
|
if ($upload_info) {
|
|
$value = $upload_info['name'];
|
|
} else {
|
|
$value = '';
|
|
}
|
|
}
|
|
|
|
$option_data[] = [
|
|
'product_option_id' => (int) $option['product_option_id'],
|
|
'product_option_value_id' => (int) $option['product_option_value_id'],
|
|
'name' => $option['name'],
|
|
'value' => (strlen($value) > 20 ? substr($value, 0, 20) . '..' : $value),
|
|
'type' => $option['type'],
|
|
];
|
|
}
|
|
|
|
$priceNumeric = 0;
|
|
$totalNumeric = 0;
|
|
|
|
// Display prices
|
|
if ($this->oc->customer->isLogged() || ! $this->oc->config->get('config_customer_price')) {
|
|
$unit_price = $this->oc->tax->calculate(
|
|
$product['price'],
|
|
$product['tax_class_id'],
|
|
$this->oc->config->get('config_tax')
|
|
);
|
|
|
|
$priceNumeric = $unit_price;
|
|
$totalNumeric = $unit_price * $product['quantity'];
|
|
|
|
$price = $this->currency->format($unit_price, $this->oc->session->data['currency']);
|
|
$total = $this->currency->format($totalNumeric, $this->oc->session->data['currency']);
|
|
} else {
|
|
$price = false;
|
|
$total = false;
|
|
}
|
|
|
|
$recurring = '';
|
|
|
|
if ($product['recurring']) {
|
|
$frequencies = array(
|
|
'day' => $this->oc->language->get('text_day'),
|
|
'week' => $this->oc->language->get('text_week'),
|
|
'semi_month' => $this->oc->language->get('text_semi_month'),
|
|
'month' => $this->oc->language->get('text_month'),
|
|
'year' => $this->oc->language->get('text_year')
|
|
);
|
|
|
|
if ($product['recurring']['trial']) {
|
|
$recurring = sprintf(
|
|
$this->oc->language->get('text_trial_description'),
|
|
$this->currency->format(
|
|
$this->oc->tax->calculate(
|
|
$product['recurring']['trial_price'] * $product['quantity'],
|
|
$product['tax_class_id'],
|
|
$this->oc->config->get('config_tax')
|
|
),
|
|
$this->oc->session->data['currency']
|
|
),
|
|
$product['recurring']['trial_cycle'],
|
|
$frequencies[$product['recurring']['trial_frequency']],
|
|
$product['recurring']['trial_duration']
|
|
) . ' ';
|
|
}
|
|
|
|
if ($product['recurring']['duration']) {
|
|
$recurring .= sprintf(
|
|
$this->oc->language->get('text_payment_description'),
|
|
$this->currency->format(
|
|
$this->oc->tax->calculate(
|
|
$product['recurring']['price'] * $product['quantity'],
|
|
$product['tax_class_id'],
|
|
$this->oc->config->get('config_tax')
|
|
),
|
|
$this->oc->session->data['currency']
|
|
),
|
|
$product['recurring']['cycle'],
|
|
$frequencies[$product['recurring']['frequency']],
|
|
$product['recurring']['duration']
|
|
);
|
|
} else {
|
|
$recurring .= sprintf(
|
|
$this->oc->language->get('text_payment_cancel'),
|
|
$this->currency->format(
|
|
$this->oc->tax->calculate(
|
|
$product['recurring']['price'] * $product['quantity'],
|
|
$product['tax_class_id'],
|
|
$this->oc->config->get('config_tax')
|
|
),
|
|
$this->oc->session->data['currency']
|
|
),
|
|
$product['recurring']['cycle'],
|
|
$frequencies[$product['recurring']['frequency']],
|
|
$product['recurring']['duration']
|
|
);
|
|
}
|
|
}
|
|
|
|
$data['products'][] = array(
|
|
'product_id' => (int) $product['product_id'],
|
|
'cart_id' => (int) $product['cart_id'],
|
|
'thumb' => $image,
|
|
'name' => $product['name'],
|
|
'model' => $product['model'],
|
|
'option' => $option_data,
|
|
'recurring' => $recurring,
|
|
'quantity' => (int) $product['quantity'],
|
|
'stock' => $product['stock'] ? true : ! (! $this->oc->config->get(
|
|
'config_stock_checkout'
|
|
) || $this->oc->config->get('config_stock_warning')),
|
|
'reward' => ($product['reward'] ? sprintf(
|
|
$this->oc->language->get('text_points'),
|
|
$product['reward']
|
|
) : ''),
|
|
'price' => $price,
|
|
'total' => $total,
|
|
'href' => $this->oc->url->link('product/product', 'product_id=' . $product['product_id']),
|
|
|
|
'price_numeric' => $priceNumeric,
|
|
'total_numeric' => $totalNumeric,
|
|
'reward_numeric' => $product['reward'] ?? 0,
|
|
);
|
|
}
|
|
|
|
// Totals
|
|
$this->oc->load->model('setting/extension');
|
|
|
|
$totals = array();
|
|
$taxes = $this->oc->cart->getTaxes();
|
|
$total = 0;
|
|
|
|
// Because __call can not keep var references so we put them into an array.
|
|
$total_data = array(
|
|
'totals' => &$totals,
|
|
'taxes' => &$taxes,
|
|
'total' => &$total
|
|
);
|
|
|
|
$sort_order = array();
|
|
|
|
$results = $this->oc->model_setting_extension->getExtensions('total');
|
|
|
|
foreach ($results as $key => $value) {
|
|
$sort_order[$key] = $this->oc->config->get('total_' . $value['code'] . '_sort_order');
|
|
}
|
|
|
|
array_multisort($sort_order, SORT_ASC, $results);
|
|
|
|
foreach ($results as $result) {
|
|
if ($this->oc->config->get('total_' . $result['code'] . '_status')) {
|
|
$this->oc->load->model('extension/total/' . $result['code']);
|
|
|
|
// We have to put the totals in an array so that they pass by reference.
|
|
$this->oc->{'model_extension_total_' . $result['code']}->getTotal($total_data);
|
|
}
|
|
}
|
|
|
|
$sort_order = array();
|
|
|
|
foreach ($totals as $key => $value) {
|
|
$sort_order[$key] = $value['sort_order'];
|
|
}
|
|
|
|
array_multisort($sort_order, SORT_ASC, $totals);
|
|
|
|
$data['totals'] = array();
|
|
|
|
foreach ($totals as $total) {
|
|
$data['totals'][] = [
|
|
'code' => $total['code'],
|
|
'title' => $total['title'],
|
|
'value' => $total['value'],
|
|
'sort_order' => $total['sort_order'],
|
|
'text' => $this->currency->format($total['value'], $this->oc->session->data['currency']),
|
|
];
|
|
}
|
|
|
|
$lastTotal = $totals[count($totals) - 1] ?? false;
|
|
$data['total'] = $lastTotal ? $lastTotal['value'] : 0;
|
|
$data['total_text'] = $lastTotal
|
|
? $this->currency->format($lastTotal['value'], $this->oc->session->data['currency'])
|
|
: 0;
|
|
$data['total_products_count'] = $this->oc->cart->countProducts();
|
|
} else {
|
|
$data['text_error'] = $this->oc->language->get('text_empty');
|
|
$data['totals'] = [];
|
|
$data['total'] = 0;
|
|
$data['total_text'] = '';
|
|
$data['products'] = [];
|
|
$data['total_products_count'] = 0;
|
|
unset($this->oc->session->data['success']);
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
public function flush(): void
|
|
{
|
|
$this->cart->clear();
|
|
}
|
|
}
|