Add support for dynamic pricing in productsRoute

- Introduced methods to apply customer-specific discounts and department-based pricing to products and addons.
- Enhanced `productsRoute` to handle optional parameters (`customer_id`, `department_id`, `category`, `id`) for tailored pricing and filtering.
- Updated response generation to include adjusted prices for both products and options based on customer and department context.
- Added helper methods to streamline parameter validation and parsing in `productsRoute`.
- Extended `products_o` to support discount application logic for customer pricing.
This commit is contained in:
Jeppe Bundgaard
2025-09-17 09:59:05 +02:00
parent b87950654b
commit 102605f15b
2 changed files with 164 additions and 1 deletions
+142 -1
View File
@@ -6,12 +6,112 @@ use classes\authentication;
use objects\logs_o;
use objects\product_options_o;
use objects\products_o;
use objects\users_o;
use traits\route_t;
class productsRoute
{
use route_t;
/**
* Get the customer object if the customer_id parameter is provided (In the request 'customer_id')
* @return users_o|null
*/
private function getCustomerIfProvided(): ?users_o
{
global $response;
if (self::isParametersSet(['customer_id'])) {
$customerId = (int)self::getParameter('customer_id');
return (new users_o())->getUserByCustomerNumber((int)$customerId);
}
return null;
}
/**
* Get the department id if the department_id parameter is provided (In the request 'department_id')
* @return int|null
*/
private function getDepartmentIdIfProvided(): ?int
{
global $response;
if (self::isParametersSet(['department_id'])) {
return (int)self::getParameter('department_id');
}
return null;
}
/**
* Get the category (ID) if the category parameter is provided (In the request 'category')
* @return int|null
*/
private function getCategoryIfProvided(): ?int
{
global $response;
if (self::isParametersSet(['category'])) {
return (int)self::getParameter('category');
}
return null;
}
/**
* Get the product id if the id parameter is provided (In the request 'id')
* @return int|null
*/
private function getProductIdIfProvided(): ?int
{
global $response;
if (self::isParametersSet(['id'])) {
return (int)self::getParameter('id');
}
return null;
}
/**
* Parse the products price in the (optional) department pricing, with the (optional) customer discounts applied
* @param array $products
* @param users_o|null $customer
* @param int|null $departmentId
* @return array
*/
private function parseProductsPrice(array $products, ?users_o $customer, ?int $departmentId): array
{
// Check if the departmentId is set
if ($departmentId) {
// Apply the departments unique pricing
$products = (new products_o())->applyDepartmentPricing($products, $departmentId);
}
// Check if the customer is set
if ($customer) {
// Apply the customers unique discounts
$products = (new products_o())->applyCustomerDiscounts($products, $customer);
}
return $products;
}
/**
* Parse the addons/options price in the (optional) department pricing, with the (optional) customer discounts applied
* @param array $options
* @param users_o|null $customer
* @param int|null $departmentId
* @return array
*/
private function parseOptionsPrice(array $options, ?users_o $customer, ?int $departmentId): array
{
foreach ($options as $key => $option) {
// Get the options product
$product = $option['product'];
// Apply the department pricing and customer discounts to the product
$product = self::parseProductsPrice([$product], $customer, $departmentId)[0];
// Update the option with the new product
$options[$key]['product'] = $product;
// Set the price of the option to the price of the product
$options[$key]['price'] = $product['price'];
}
return $options;
}
public function run(): void
{
$this->get('/products', function () {
@@ -42,7 +142,48 @@ class productsRoute
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the id is set in the request
// Define the variables
$customer = self::getCustomerIfProvided(); // This is only used if the customer_id parameter is provided
$departmentId = self::getDepartmentIdIfProvided(); // This is only used if the department_id parameter is provided
$category = self::getCategoryIfProvided(); // This is only used if the category parameter is provided (ID of the category)
$productId = self::getProductIdIfProvided(); // This is only used if the id parameter is provided (ID of the product)
// Check if the "final_price" parameter is set, and true.
if (self::isParametersSet(['final_price']) && self::getParameter('final_price') === 'true') {
// Determine the products to return
if ($category) {
// Get products in the category
$products = (new products_o())->listObjectsByCategory($category);
} elseif ($productId) {
// Get the specific product
$product = (new products_o())->select($productId);
if ($product->exists()) {
$products = [$product->asArray()];
} else {
$products = [];
}
} else {
// Get all products
$products = (array)(new products_o())->listObjectsWithPaginationIfSet(
function ($product) {
return $product;
}
);
}
// Return all products, with the department pricing and customer discounts applied
//$response->success(
// array_map(function ($product) {
// return parseProduct($product);
// }, self::parseProductsPrice($products, $customer, $departmentId))
//);
$response->success(array_map(function ($product) use ($customer, $departmentId) {
$productArray = parseProduct($product);
// Get the options for the product
$productArray['addons'] = self::parseOptionsPrice($productArray['addons'], $customer, $departmentId);
// Return the product with the updated price
return $productArray;
}, $products));
}
// Check if the id is set in the request (to get a specific product)
if (self::isParametersSet(['id'])) {
// Log the incident
(new logs_o())->add('products', 'global', 1, $user->id, 'LIST_PRODUCTS', 'Successfully listed product with id ' . $response->getRequestParameter('id'));