Files
api/services/nginx/app/routes/productsRoute.php
T
Jeppe Bundgaard 32de29127a Fix product price typecasting and improve product parsing in productsRoute
- Corrected typecasting for product prices to ensure consistent integer values.
- Enhanced product parsing logic for better modularity and data handling in `productsRoute`.
2025-11-18 11:06:33 +01:00

398 lines
19 KiB
PHP

<?php
namespace routes;
use classes\authentication;
use objects\categories_o;
use objects\department_categories_o;
use objects\departments_o;
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');
try {
$customerObject = (new users_o())->getUserByCustomerNumber((int)$customerId);
if ($customerObject->exists()) {
return $customerObject;
}
} catch (\Exception $e) {
// Log the incident
(new logs_o())->add('products', 'global', 3, 0, 'GET_CUSTOMER_FAILED', 'Failed to get customer with id ' . $customerId . '. Error: ' . $e->getMessage());
// Return null
return null;
}
}
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'] = (int)$product['price'];
}
return $options;
}
public function run(): void
{
$this->get('/products', function () {
function parseProduct($product): array
{
return [
'id' => (int)$product['id'],
'name' => (string)$product['name'],
'description' => (string)$product['description'],
'price' => (int)$product['price'],
'subscription_allowed' => (boolean)$product['subscription_allowed'],
'category' => (int)$product['category'],
'piktogram' => (string)$product['piktogram'],
'economic_product_id' => (int)$product['economic_product_id'],
'apply_category_discount' => (boolean)$product['apply_category_discount'],
'requires_note' => (boolean)$product['requires_note'],
'created_at' => (string)$product['created_at'],
'updated_at' => (string)$product['updated_at'],
'addons' => (new product_options_o())->getProductOptions($product['id']),
'is_wash' => (bool)$product['is_wash'],
'display_in_booking_form' => (bool)$product['display_in_booking_form'],
'order_priority' => (int)$product['order_priority'],
];
}
// Require the user to be logged in
global $response;
$this->requirePermission('list_products');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// 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);
// If the category is "6" exterior washes, include category "1" and "3"
if ($category === 6) {
$additionalProducts = (new products_o())->listObjectsByCategory(1);
$products = array_merge($products, $additionalProducts);
$additionalProducts = (new products_o())->listObjectsByCategory(3);
$products = array_merge($products, $additionalProducts);
}
} 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 parseProduct($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))
//);
$result = array_map(function ($product) use ($customer, $departmentId) {
$productArray = parseProduct($product);
// Get the price of the product with the department pricing and customer discounts applied
$productArray = parseProduct(self::parseProductsPrice([$productArray], $customer, $departmentId)[0]);
// Get the options for the product
$productArray['addons'] = self::parseOptionsPrice($productArray['addons'], $customer, $departmentId);
// Return the product with the updated price
return $productArray;
}, $products);
// If the productId is set, return a single object instead of an array
$response->success($productId && count($result) > 0 ? $result[0] : $result);
}
// 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'));
// Return the product
$response->success(
parseProduct(
(new products_o())->select((int)self::getParameter('id'))->asArray()
)
);
}
// Check if the category is set in the request
$data = $_GET ?? [];
// Check if the category is set
if (isset($data['category'])) {
// Log the incident
(new logs_o())->add('products', 'global', 1, $user->id, 'LIST_PRODUCTS', 'Successfully listed products in category ' . $data['category']);
// Return the list of products
$products = (new products_o())->listObjectsByCategory($data['category']);
// Check if the department_id is set
if (isset($data['department_id'])) {
// Apply the departments unique pricing
$products = (new products_o())->applyDepartmentPricing((array)$products, (int)$data['department_id']);
}
$response->success(
array_map(function ($product) {
return parseProduct($product);
}, $products)
);
}
// Log the incident
(new logs_o())->add('products', 'global', 1, $user->id, 'LIST_PRODUCTS', 'Successfully listed products');
// Check if the department_id is set
if (isset($data['department_id'])) {
// Get all product ids contained in a category attached to the department
$departmentSpecificProducts = (new departments_o())->select((int)$data['department_id'])->getAllProductInDepartmentCategories();
// Get the product ids as an array
$departmentSpecificProductIds = array_map(function ($product) {
return $product->id;
}, $departmentSpecificProducts);
// Return the list of products
$response->success(
(new products_o())->applyDepartmentPricing((array)(new products_o())->listObjectsWithPaginationIfSet(
function ($product) use ($departmentSpecificProductIds) {
// Only include products that are in the department specific product ids
return parseProduct($product);
},
(new products_o())->forceRestrictFilters([
'id' => $departmentSpecificProductIds
])
), (int)$data['department_id'])
);
}
// Return the list of products
$response->success(
(new products_o())->listObjectsWithPaginationIfSet(function ($product) {
return parseProduct($product);
})
);
} else {
// Log the incident
(new logs_o())->add('products', 'global', 1, 0, 'LIST_PRODUCTS', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'list_products' => 'List all products'
]
);
$this->post('/products', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('add_product');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Get the request data
$name = $response->getRequestParameter('name');
$description = $response->getRequestParameter('description') ?? null;
$price = $response->getRequestParameter('price');
$category = $response->getRequestParameter('category') ?? null;
$piktogram = $response->getRequestParameter('piktogram') ?? null;
$economicProductId = $response->getRequestParameter('economicProductId') ?? null;
// Check if the required fields are set
self::requireParameters(
[
'name',
'price'
]
);
// Add the product
(new products_o())->add(
(string)$name,
(string)$description ?? '',
(int)$price,
(int)$category ?? '',
(int)$piktogram ?? null,
(int)$economicProductId ?? null
);
// Log the incident
(new logs_o())->add('products', 'global', 1, $user->id, 'ADD_PRODUCT', 'Product name: ' . $name);
// Return a success message
$response->success(['message' => 'Product added successfully']);
} else {
// Log the incident
(new logs_o())->add('products', 'global', 1, 0, 'ADD_PRODUCT', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'add_product' => 'Add a product'
]
);
$this->put('/products', function () {
// Require the user to be logged in
global $response;
$this->requirePermission('edit_product');
// Get the user object
$user = (new authentication())->get_user();
// Check if the request was successful
if ($user) {
// Check if the required fields are set
self::requireParameters(['id']);
$id = $response->getRequestParameter('id');
$product = (new products_o())->select((int)$id);
// Check if the product exists
if (!$product->exists()) {
$response->error('Product not found', 404);
}
// Update the fields that are set
if (self::isParametersSet(['name'])) {
$product->name->set($response->getRequestParameter('name'));
}
if (self::isParametersSet(['description'])) {
$product->description->set($response->getRequestParameter('description') ?? '');
}
if (self::isParametersSet(['price'])) {
$product->price->set($response->getRequestParameter('price'));
}
if (self::isParametersSet(['subscription_allowed'])) {
$product->subscription_allowed->set($response->getRequestParameter('subscription_allowed') ? 1 : 0);
}
if (self::isParametersSet(['category'])) {
$product->category->set($response->getRequestParameter('category') ?? '');
}
if (self::isParametersSet(['piktogram'])) {
$product->piktogram->set($response->getRequestParameter('piktogram') ?? '');
}
if (self::isParametersSet(['economic_product_id'])) {
$product->economic_product_id->set($response->getRequestParameter('economic_product_id') ?? '');
}
if (self::isParametersSet(['apply_category_discount'])) {
$product->apply_category_discount->set($response->getRequestParameter('apply_category_discount') ? 1 : 0);
}
if (self::isParametersSet(['requires_note'])) {
$product->requires_note->set($response->getRequestParameter('requires_note') ? 1 : 0);
}
if (self::isParametersSet(['is_wash'])) {
$product->is_wash->set($response->getRequestParameter('is_wash') ? 1 : 0);
}
if (self::isParametersSet(['display_in_booking_form'])) {
$product->display_in_booking_form->set($response->getRequestParameter('display_in_booking_form') ? 1 : 0);
}
if (self::isParametersSet(['order_priority'])) {
$product->order_priority->set((int)$response->getRequestParameter('order_priority') ?? '');
}
(new logs_o())->add('products', 'global', 1, $user->id, 'EDIT_PRODUCT', 'Product id: ' . $id);
// Return a success message
$response->success(['message' => 'Product edited successfully']);
} else {
// Log the incident
(new logs_o())->add('products', 'global', 1, 0, 'EDIT_PRODUCT', 'No user found, or invalid session');
// Return an error
$response->error('Invalid session', 400);
}
},
[
'edit_product' => 'Edit a product'
]
);
}
}