Files
api/services/nginx/app/objects/user_price_overrides_o.php
T

237 lines
9.5 KiB
PHP

<?php
namespace objects;
use classes\db;
use classes\object_property;
use classes\price_overrides_schema_bootstrap;
use classes\system_search_cache;
use traits\db_object_t;
class user_price_overrides_o extends db
{
use db_object_t;
public int $user_id;
public object_property $is_category;
public object_property $product_or_category_id;
public object_property $percentage;
public object_property $fixed_price;
public function structure(): void
{
$this->setTable('price_overrides');
price_overrides_schema_bootstrap::ensureColumns();
}
public function objectChanged(): void
{
// No need to invalidate the cache, since the user_price_overrides object is not cached
}
public function getObjectProperties(): void
{
$this->is_category = new object_property($this->table, $this->id, 'is_category', 'bool', true);
$this->product_or_category_id = new object_property($this->table, $this->id, 'product_or_category_id', 'int', true);
$this->percentage = new object_property($this->table, $this->id, 'percentage', 'int', true);
$this->fixed_price = new object_property($this->table, $this->id, 'fixed_price', 'int', false, null);
}
public function setUser($user_id): user_price_overrides_o
{
$this->user_id = $user_id;
return $this;
}
/**
* Set a price override for the user
* @param bool $is_category
* @param int|string $product_or_category_id
* @param int $percentage
* @param int|null $fixed_price
* @return $this
*/
public function setPrice(bool $is_category, int|string $product_or_category_id, int $percentage, ?int $fixed_price = null): user_price_overrides_o
{
global $db;
// If the user is not set, return the object
if (!isset($this->user_id)) {
return $this;
}
if ($is_category) {
$fixed_price = null;
}
// Check if the record already exists
$this->removePriceIfExist($is_category, $product_or_category_id);
// If neither a discount nor a fixed product price is set, remove the record.
if ($percentage === 0 && $fixed_price === null) {
return $this;
}
// Create a new record in the database
$product_or_category_id = $db->escape_string((string)$product_or_category_id);
$fixed_price_sql = $fixed_price === null ? 'NULL' : (string)max(0, (int)$fixed_price);
$sql = "INSERT INTO $this->table (user_id, is_category, product_or_category_id, percentage, fixed_price) VALUES (" . (int)$this->user_id . ", " . (int)$is_category . ", '$product_or_category_id', " . (int)$percentage . ", $fixed_price_sql)";
$db->query($sql);
$this->markSearchDirty();
return $this;
}
private function removePriceIfExist(bool $is_category, int|string $product_or_category_id): void
{
global $db;
$product_or_category_id = $db->escape_string((string)$product_or_category_id);
$sql = "DELETE FROM $this->table WHERE user_id = " . (int)$this->user_id . " AND is_category = " . (int)$is_category . " AND product_or_category_id = '$product_or_category_id'";
$db->query($sql);
$this->markSearchDirty();
}
/**
* Get the price override (PERCENTAGE) for the user
* @param bool $is_category
* @param int|string $product_or_category_id
* @return int
*/
public function getPrice(bool $is_category, int|string $product_or_category_id): int
{
global /** @var db $db */
$db;
$sql = "SELECT * FROM $this->table WHERE user_id = " . $this->user_id . " AND is_category = " . (int)$is_category . " AND product_or_category_id = ";
// If the is_category is false, the product_or_category_id is a product_id
if (!$is_category) {
$product_or_category_id = (int)$product_or_category_id;
$sql .= $product_or_category_id;
} else {
// If the is_category is true, the product_or_category_id is a category_id
$product_or_category_id = $db->escape_string($product_or_category_id);
$sql .= "'$product_or_category_id'";
}
// Get the price override from the database
$result = $db->query($sql);
$percentage = 0;
if ($result->num_rows > 0) {
// Return the percentage
$percentage = $result->fetch_assoc()['percentage'];
}
// If the object is a product, check if the category has a discount set
if (!$is_category) {
$product = (new products_o())->getProductById($product_or_category_id);
if ($product->apply_category_discount->value()) {
// Get the economic user discount
$economic_user_global_discount = (new users_o())->getUserById($this->user_id)->getEconomicCustomerDiscountPercentage();
// Get the category discount
$sql = "SELECT * FROM $this->table WHERE user_id = " . $this->user_id . " AND is_category = 1 AND product_or_category_id = '" . $product->category->value() . "'";
$result = $db->query($sql);
if ($result->num_rows > 0) {
$category_discount = $result->fetch_assoc()['percentage'];
// If the category discount is higher than the product discount, return the category discount
if ((int)$category_discount > (int)$percentage && (int)$category_discount > (int)$economic_user_global_discount) {
return $category_discount;
}
}
// If the economic user discount is higher than the product discount, return the economic user discount
if ((int)$economic_user_global_discount > (int)$percentage) {
return $economic_user_global_discount;
}
}
}
return $percentage;
}
public function getFixedPrice(bool $is_category, int|string $product_or_category_id): ?int
{
if ($is_category || !isset($this->user_id)) {
return null;
}
$row = $this->getDirectPriceRow(false, (int)$product_or_category_id);
if ($row === null || $row['fixed_price'] === null) {
return null;
}
return (int)$row['fixed_price'];
}
public function getDirectPriceRow(bool $is_category, int|string $product_or_category_id): ?array
{
global $db;
if (!isset($this->user_id)) {
return null;
}
$product_or_category_id = $db->escape_string((string)$product_or_category_id);
$sql = "SELECT * FROM $this->table WHERE user_id = " . (int)$this->user_id . " AND is_category = " . (int)$is_category . " AND product_or_category_id = '$product_or_category_id' LIMIT 1";
$result = $db->query($sql);
if (!$result || $result->num_rows < 1) {
return null;
}
$row = $result->fetch_assoc();
$row['id'] = (int)$row['id'];
$row['user_id'] = (int)$row['user_id'];
$row['is_category'] = (bool)$row['is_category'];
$row['product_or_category_id'] = $is_category
? (string)$row['product_or_category_id']
: (int)$row['product_or_category_id'];
$row['percentage'] = (int)$row['percentage'];
$row['fixed_price'] = array_key_exists('fixed_price', $row) && $row['fixed_price'] !== null
? (int)$row['fixed_price']
: null;
return $row;
}
/**
* Get all the price overrides for the user
* @return array
*/
public function getAllPrices(): array
{
global $db;
// Get the customers global discount
$economic_user_global_discount = (new users_o())->getUserById($this->user_id)->getEconomicCustomerDiscountPercentage();
// Get all the price overrides for the user
$sql = "SELECT * FROM $this->table WHERE user_id = " . $this->user_id;
$result = $db->query($sql);
$prices = [];
if ($result->num_rows > 0) {
while ($row = $result->fetch_assoc()) {
// Parse the row
$row['id'] = (int)$row['id'];
$row['user_id'] = (int)$row['user_id'];
$row['is_category'] = (bool)$row['is_category'];
$row['product_or_category_id'] = (int)$row['product_or_category_id'];
$row['percentage'] = (int)$row['percentage'];
$row['fixed_price'] = array_key_exists('fixed_price', $row) && $row['fixed_price'] !== null ? (int)$row['fixed_price'] : null;
$row['created_at'] = (string)$row['created_at'];
$row['updated_at'] = (string)$row['updated_at'];
// Add the row to the list
$prices[] = $row;
}
}
// If the user has a global discount, add it to the list
if ($economic_user_global_discount > 0) {
$prices[] = [
'id' => (int)999999,
'user_id' => (int)$this->user_id,
'is_category' => true,
'product_or_category_id' => "global",
'percentage' => (int)$economic_user_global_discount,
'fixed_price' => null,
'created_at' => "2021-01-01 00:00:00",
'updated_at' => "2021-01-01 00:00:00"
];
}
return $prices;
}
private function markSearchDirty(): void
{
try {
system_search_cache::markDirtyTable($this->table);
} catch (\Throwable) {
}
}
}