Files
kupshop/class/class.PriceLevel.php
2025-08-02 16:30:27 +02:00

213 lines
5.9 KiB
PHP

<?php
use Query\Operator;
/**
* Class representing PriceLevel.
*
* @author Joe
*/
#[AllowDynamicProperties]
class PriceLevel
{
use DatabaseCommunication;
/**
* Pro Level ID.
*
* @var int
*/
public $id = -1;
/**
* Product texts.
*
* @var string
*/
public $name;
public $discount = 0;
public $discount_discount;
public $unit;
public $sections;
public $products;
public $producers;
public $ranges;
public $descr;
public $combine;
public $add = true;
/**
* Constructor.
*
* @param int $id
*/
public function __construct($id = -1)
{
$this->id = $id;
}
/**
* Fetches data from database, price level ID specified in $id.
*
* @param int $id
*
* @return $this
*/
public function createFromDB($id)
{
$this->id = $id;
$row = sqlFetchAssoc($this->selectSQL('price_levels', ['id' => $id]));
if ($row) {
foreach ($row as $key => $value) {
$this->$key = $value;
}
}
if (!empty($this->combine)) {
$this->add = $this->combine != 'N';
}
// ------------------------------------------------------------------
// prohleda, jestli k dane cenove hladine jsou urceny slevy k sekcim
$this->sections = sqlFetchAll($this->selectSQL('price_levels_sections', ['id_price_level' => $id]), 'id_section');
// ------------------------------------------------------------------
// prohleda, jestli k dane cenove hladine jsou urceny slevy k produktum
$this->products = sqlFetchAll($this->selectSQL('price_levels_products', ['id_price_level' => $id]), 'id_product');
// ------------------------------------------------------------------
// prohleda, jestli k dane cenove hladine jsou urceny slevy k vyrobcum
$this->producers = sqlFetchAll($this->selectSQL('price_levels_producers', ['id_price_level' => $id]), 'id_producer');
$this->ranges = $this->getRanges();
wpj_debug(['discount_discount', $this]);
return $this;
}
public function getDiscount($IDp = null, $IDcat = null, $IDprod = -1, &$product = null)
{
if ($product && !toDecimal($product['discount'])->isZero() && !is_null($this->discount_discount)) {
return [
'discount' => $this->discount_discount,
'unit' => $this->unit,
'add' => $this->add,
];
}
// urceni slevy podle slevy k produktu
if ($IDp && isset($this->products[$IDp])) {
return $this->products[$IDp] + ['add' => $this->add];
}
// urceni slevy podle slevy k sekci
if ($this->sections) {
// pokud neni urcena sekce - dohledat sekci k produktu
if ($IDp && is_null($IDcat)) {
$IDcat = $product['priceLevelSections'] ?? null;
if (is_null($IDcat)) {
$IDcat = $this->selectSQL('products_in_sections', ['id_product' => $IDp], ['id_section'])->fetchAll();
$IDcat = array_column($IDcat, 'id_section');
}
}
if ($IDcat) {
$product['priceLevelSections'] = $IDcat;
$discount = null;
foreach ($IDcat as $cat) {
if (isset($this->sections[$cat])) {
$this->products[$IDp] = $this->mergeDiscounts($discount, $this->sections[$cat]);
}
}
if (isset($this->products[$IDp])) {
return $this->products[$IDp] + ['add' => $this->add];
}
}
}
// urceni slevy podle vyrobce
if ($this->producers) {
// urceni slevy podle vyrobce - dohledat vyrobce k produktu
// default $IDprod = -1 (ne null), protoze product->producer muze byt null
// $IDprod = null znamena ze vyrobce = null a nemusime to fetchovat
// $IDprod = -1 znamena ze nebyl vyrobce jeste nafetchovany
if ($IDp && ($IDprod == -1)) {
$IDprod = $this->selectSQL('products', ['id' => $IDp], ['producer'])->fetchColumn();
}
if ($IDprod && isset($this->producers[$IDprod])) {
return $this->producers[$IDprod] + ['add' => $this->add];
}
}
// globalni sleva
return [
'discount' => $this->discount,
'unit' => $this->unit,
'add' => $this->add,
];
}
protected function getRanges()
{
if ($this->ranges) {
return $this->ranges;
}
return sqlQueryBuilder()
->select('*')
->from('price_levels_ranges')
->where(Operator::equals(['id_price_level' => $this->id]))
->orderBy('range_from')
->execute()
->fetchAll();
}
/**
* @return bool or $range
*/
public function getRangeByPrice(Decimal $price)
{
if (isset($this->ranges)) {
foreach ($this->ranges as $range) {
if ($price->lowerThan(toDecimal($range['range_to'])) && !$price->lowerThan(toDecimal($range['range_from']))) {
return $range;
}
}
}
return false;
}
public function mergeDiscounts(&$target, $from)
{
if (empty($target)) {
return $from;
}
if ($from['discount'] > $target['discount'] && $from['unit'] == $target['unit']) {
return $from;
}
if ($from['unit'] == 'perc' && $target['unit'] == 'price') {
return $from;
}
return $target;
}
public function getName(): string
{
return $this->name;
}
public function getId(): int
{
return $this->id;
}
}