Implement department-specific customer pricing functionality

This commit is contained in:
Jeppe Bundgaard
2026-07-07 17:27:56 +02:00
parent c24428e4c7
commit 172a21c517
21 changed files with 1687 additions and 33 deletions
+59 -7
View File
@@ -936,9 +936,18 @@ class users_o extends db
* @param bool $is_category If the object is a category
* @return int|null The discount percentage
*/
public function getCustomPrice(int $object_id, bool $is_category = false): int|null
public function getCustomPrice(int $object_id, bool $is_category = false, ?int $department_id = null): int|null
{
self::requireSelected();
if ($department_id !== null && (new departments_o())->isCustomPricingOnly((int)$department_id)) {
$row = (new department_customer_price_overrides_o())->getDirectPriceRow(
(int)$department_id,
(int)$this->id,
$is_category,
$object_id
);
return $row === null ? 0 : (int)$row['percentage'];
}
// Get the custom price for the product
$discount = $this->price_overrides->setUser($this->id)->getPrice($is_category, $object_id);
// If the is_category is false, check if there is a custom price for the category that the product belongs to
@@ -962,9 +971,12 @@ class users_o extends db
* - Category discount (If the product allows category inheritance of discounts)
* - Product discount (If the product has a custom price)
*/
public function getProductDiscountPercentage(int $product_id): int|null
public function getProductDiscountPercentage(int $product_id, ?int $department_id = null): int|null
{
self::requireSelected();
if ($department_id !== null && (new departments_o())->isCustomPricingOnly((int)$department_id)) {
return $this->getDepartmentScopedProductDiscountPercentage($product_id, (int)$department_id);
}
// Get the product by ID
$product = (new products_o())->select((int)$product_id);
$doesProductAllowCategoryDiscount = (bool)$product->apply_category_discount->value();
@@ -981,24 +993,36 @@ class users_o extends db
return $discount_percentage === null ? 0 : (int)$discount_percentage;
}
public function getProductFixedPrice(int $product_id): ?int
public function getProductFixedPrice(int $product_id, ?int $department_id = null): ?int
{
self::requireSelected();
if ($department_id !== null && (new departments_o())->isCustomPricingOnly((int)$department_id)) {
$row = (new department_customer_price_overrides_o())->getDirectPriceRow(
(int)$department_id,
(int)$this->id,
false,
(int)$product_id
);
if ($row === null || $row['fixed_price'] === null) {
return null;
}
return (int)$row['fixed_price'];
}
return $this->price_overrides->setUser($this->id)->getFixedPrice(false, $product_id);
}
public function applyProductCustomerPricing(int $product_id, int $base_price, bool $use_final_price_discount_calculation = true): int
public function applyProductCustomerPricing(int $product_id, int $base_price, bool $use_final_price_discount_calculation = true, ?int $department_id = null): int
{
self::requireSelected();
$fixed_price = $this->getProductFixedPrice($product_id);
$fixed_price = $this->getProductFixedPrice($product_id, $department_id);
if ($fixed_price !== null) {
return $fixed_price;
}
$discount_percentage = $use_final_price_discount_calculation
? (int)$this->getProductDiscountPercentage($product_id)
: (int)$this->getCustomPrice($product_id, false);
? (int)$this->getProductDiscountPercentage($product_id, $department_id)
: (int)$this->getCustomPrice($product_id, false, $department_id);
if ($discount_percentage <= 0) {
return $base_price;
}
@@ -1006,6 +1030,34 @@ class users_o extends db
return (int)round($base_price * (1 - ($discount_percentage / 100)));
}
private function getDepartmentScopedProductDiscountPercentage(int $product_id, int $department_id): int
{
self::requireSelected();
$overrides = new department_customer_price_overrides_o();
$product = (new products_o())->select((int)$product_id);
$discounts = [];
$productRow = $overrides->getDirectPriceRow($department_id, (int)$this->id, false, (int)$product_id);
if ($productRow !== null) {
$discounts[] = (int)$productRow['percentage'];
}
if ((bool)$product->apply_category_discount->value()) {
$categoryRow = $overrides->getDirectPriceRow($department_id, (int)$this->id, true, (string)$product->category->value());
if ($categoryRow !== null) {
$discounts[] = (int)$categoryRow['percentage'];
}
$globalRow = $overrides->getDirectPriceRow($department_id, (int)$this->id, true, 'global');
if ($globalRow !== null) {
$discounts[] = (int)$globalRow['percentage'];
}
}
return max([0, ...$discounts]);
}
/**