GET */ $this->get('/collected-invoices', function () { global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES', 'User accessed the list of collected order invoices'); $collected_order_invoices = new collected_order_invoices_o(); // Check if the request contains an ID if (self::isParametersSet(['id'])) { self::requireType((int)self::getParameter('id'), self::type_int()); $collected_order_invoices->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); $response->success($collected_order_invoices->asArray()); } // Define the users $users = new users_o(); // Define the collected order invoices $tmp_collected_order_invoices = new collected_order_invoices_o(); // Return the list of collected order invoices $response->success($collected_order_invoices->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($tmp_collected_order_invoices, $users) { // Select the orders for each collected order invoice $tmp_collected_order_invoices->select((int)$collected_order_invoice['id']); return $this->getOrderInvoiceDetails($collected_order_invoice, $users, $tmp_collected_order_invoices); }, )); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES', 'User tried to access the list of collected order invoices without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices' => 'List ALL collected order invoices. This is a superuser-only route.' ] ); /** Collected order invoices > Ready to invoice > GET */ $this->get('/collected-invoices/ready-to-invoice', function () { global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_READY_TO_INVOICE', 'User accessed the list of collected order invoices ready to invoice'); $collected_order_invoices = new collected_order_invoices_o(); // Define the users $users = new users_o(); // Define the collected order invoices $tmp_collected_order_invoices = new collected_order_invoices_o(); // Return the list of collected order invoices $response->success($collected_order_invoices->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($tmp_collected_order_invoices, $users) { // Select the orders for each collected order invoice $tmp_collected_order_invoices->select((int)$collected_order_invoice['id']); return $this->getOrderInvoiceDetails($collected_order_invoice, $users, $tmp_collected_order_invoices); }, $collected_order_invoices->forceRestrictFilters( [ // This makes sure that the user can only see orders from the departments they explicitly have access to 'customer_number' => $collected_order_invoices->listCustomersWithIndividualOrderInvoicing(), ] ) )); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_READY_TO_INVOICE', 'User tried to access the list of collected order invoices ready to invoice without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices' => 'List ALL collected order invoices. This is a superuser-only route.' ] ); /** Collected order invoices > POST */ $this->post('/collected-invoices', function () { global $response; self::requirePermission('add_collected_invoice'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE', 'User added a collected order invoice'); // Require the customer number, and validate its type and length self::requireParameters(['customer_number']); self::requireType((int)self::getParameter('customer_number'), self::type_int()); self::requireMinLength('customer_number', 1); self::requireMaxLength('customer_number', 10); // Require the customer number to be above 0 self::requireMinValue((int)self::getParameter('customer_number'), 1); // Validate the customer number against the database $customer = (new users_o())->select((int)self::getParameter('customer_number')); $customer->requireSelected(); // Define the variables $name = null; $notes = null; $processor = null; $closed_at = null; // Check if the name is set if (self::isParametersSet(['name'])) { self::requireType((string)self::getParameter('name'), self::type_string()); self::requireMinLength('name', 1); self::requireMaxLength('name', 255); $name = (string)self::getParameter('name'); } // Check if the notes are set if (self::isParametersSet(['notes'])) { self::requireType((string)self::getParameter('notes'), self::type_string()); $notes = (string)self::getParameter('notes'); } // Check if the processor is set if (self::isParametersSet(['processor'])) { self::requireType((int)self::getParameter('processor'), self::type_int()); $processor = (int)self::getParameter('processor'); } // Check if the closed_at is set if (self::isParametersSet(['closed_at'])) { // Check if the closed date is set, and validate its type if (!!self::getParameter('closed_at')) { self::requireType((string)self::getParameter('closed_at'), self::type_string()); $closed_at = (string)self::getParameter('closed_at'); // Check if the closed date is valid if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $closed_at)) { $response->error('Invalid closed date format', 400); } // Set the time to 00:00:01z $closed_at = date('Y-m-d H:i:s', strtotime($closed_at . ' 00:00:01')); } } // Add the collected order invoice $collected_order_invoices = new collected_order_invoices_o(); $collected_order_invoices->add( $customer->id, $name, $notes, $processor, $closed_at ?: null, ); $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE', 'User tried to add a collected order invoice without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice' => 'Add a collected order invoice. This is a superuser-only route.' ] ); /** Collected order invoices > Split > POST */ $this->post('/collected-invoices/split', function () { global $response; self::requirePermission('split_collected_invoice'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'SPLIT_COLLECTED_INVOICE', 'User split a collected order invoice'); // Require the ID, and validate its type and length self::requireParameters(['id']); self::requireType((int)self::getParameter('id'), self::type_int()); self::requireMinValue((int)self::getParameter('id'), 1); // Require the ID to be above 0 self::requireMinValue((int)self::getParameter('id'), 1); // Validate the ID against the database $collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); // Split the collected order invoice $collected_order_invoices->split(); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'SPLIT_COLLECTED_INVOICE', 'User tried to split a collected order invoice without a valid session'); $response->error('Invalid session', 400); } }, [ 'split_collected_invoice' => 'Split a collected order invoice. This is a superuser-only route.' ] ); /** Collected order invoices > E-Conomic > POST */ $this->post('/collected-invoices/economic', function () { global $response; self::requirePermission('add_collected_invoice_economic'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_ECONOMIC', 'User added a collected order invoice to E-Conomic'); // Require the ID, and validate its type and length self::requireParameters(['id']); self::requireType((int)self::getParameter('id'), self::type_int()); self::requireMinLength('id', 1); self::requireMaxLength('id', 10); // Require the ID to be above 0 self::requireMinValue((int)self::getParameter('id'), 1); // Validate the ID against the database $collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); // Check if the collected order invoice has an external ID if ($collected_order_invoices->external_id->value() === null) { // Add fixed price to the collected order invoice $customer_fixed_pricing_o = new customer_fixed_pricing_o(); if ($customer_fixed_pricing_o->doesUserHaveFixedPricing((int)$collected_order_invoices->customer_number->value())) { $customer_fixed_pricing_price = $customer_fixed_pricing_o->selectByCustomerNumber((int)$collected_order_invoices->customer_number->value()); $customer_fixed_pricing_price = (int)$customer_fixed_pricing_price->price->value(); $collected_order_invoices->overridePricesFixed((int)$customer_fixed_pricing_price); } else { // Apply vehicle subscriptions if the customer does not have fixed pricing $collected_order_invoices->addVehicleSubscriptionsTransaction(); } // Add the collected order invoice to E-Conomic $collected_order_invoices->addToEconomic(); $response->success($collected_order_invoices->asArray()); } // Check if the invoice has been booked if ($collected_order_invoices->booked_invoice_id->value() !== null) { $response->error('Invoice has already been booked', 400); } // Check if the invoice draft exists in E-Conomic if ($collected_order_invoices->isDraftExisting()) { $response->error('Invoice draft already exists in E-Conomic', 400); } // Add fixed price to the collected order invoice $customer_fixed_pricing_o = new customer_fixed_pricing_o(); if ($customer_fixed_pricing_o->doesUserHaveFixedPricing((int)$collected_order_invoices->customer_number->value())) { $customer_fixed_pricing_price = $customer_fixed_pricing_o->selectByCustomerNumber((int)$collected_order_invoices->customer_number->value()); $customer_fixed_pricing_price = (int)$customer_fixed_pricing_price->price->value(); $collected_order_invoices->overridePricesFixed((int)$customer_fixed_pricing_price); } else { // Apply vehicle subscriptions if the customer does not have fixed pricing $collected_order_invoices->addVehicleSubscriptionsTransaction(); } // Create the invoice in E-Conomic $collected_order_invoices->addToEconomic(true); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_ECONOMIC', 'User tried to add a collected order invoice to E-Conomic without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice_economic' => 'Add a collected order invoice to E-Conomic. This is a superuser-only route.' ] ); /** Collected order invoices > Stripe > BOOK > POST */ $this->post('/collected-invoices/stripe/book', function () { global $response; self::requirePermission('add_collected_invoice_stripe'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_STRIPE', 'User added a collected order invoice to Stripe'); // Require the ID, and validate its type and length self::requireParameters(['id']); self::requireType((int)self::getParameter('id'), self::type_int()); self::requireMinLength('id', 1); self::requireMaxLength('id', 10); // Require the ID to be above 0 self::requireMinValue((int)self::getParameter('id'), 1); // Validate the ID against the database $collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); // Require the external ID to be set if ($collected_order_invoices->external_id->value() === null) { $response->error('Transaction has not been created in Stripe', 400); } // Require the booked invoice ID to be not set if ($collected_order_invoices->booked_invoice_id->value() !== null) { $response->error('Invoice has already been booked', 400); } // Add the collected order invoice to Stripe $collected_order_invoices->addToEconomic(true); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_STRIPE', 'User tried to add a collected order invoice to Stripe without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice_stripe' => 'Add a collected order invoice to Stripe. This is a superuser-only route.' ] ); /** Collected order invoices > Vehicle subscriptions > POST */ $this->post('/collected-invoices/vehicle-subscriptions', function () { global $response; self::requirePermission('add_collected_invoice_vehicle_subscriptions'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions'); // Require the ID, and validate its type and length self::requireParameters(['id']); self::requireType((int)self::getParameter('id'), self::type_int()); self::requireMinLength('id', 1); self::requireMaxLength('id', 10); // Require the ID to be above 0 self::requireMinValue((int)self::getParameter('id'), 1); // Validate the ID against the database $collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); // Add the collected order invoice to E-Conomic $collected_order_invoices->addVehicleSubscriptionsTransaction(); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User tried to add a collected order invoice for vehicle subscriptions without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice_vehicle_subscriptions' => 'Add a collected order invoice for vehicle subscriptions. This is a superuser-only route.' ] ); /** Collected order invoices > Vehicle subscriptions > POST */ $this->post('/collected-invoices/fixed-price', function () { global $response; self::requirePermission('add_collected_invoice_fixed_price'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_FIXED_PRICE', 'User added a collected order invoice fixed price modifications'); // Require the ID, and validate its type and length self::requireParameters(['id']); self::requireType((int)self::getParameter('id'), self::type_int()); self::requireMinLength('id', 1); self::requireMaxLength('id', 10); // Require the ID to be above 0 self::requireMinValue((int)self::getParameter('id'), 1); // Validate the ID against the database $collected_order_invoices = (new collected_order_invoices_o())->select((int)self::getParameter('id')); $collected_order_invoices->requireSelected(); // Check if the customer has a fixed price $customer = new users_o(); $customer->getUserByCustomerNumber((int)$collected_order_invoices->customer_number->value()); $customer_fixed_pricing_o = new customer_fixed_pricing_o(); if (!$customer_fixed_pricing_o->doesUserHaveFixedPricing((int)$customer->customer_number->value())) { $response->error('Customer does not have fixed pricing', 400); } $customer_fixed_pricing_price = $customer_fixed_pricing_o->selectByCustomerNumber((int)$customer->customer_number->value()); $customer_fixed_pricing_price = (int)$customer_fixed_pricing_price->price->value(); echo 'Fixed price: ' . $customer_fixed_pricing_price; // Add the collected order invoice to E-Conomic $collected_order_invoices->overridePricesFixed((int)$customer_fixed_pricing_price); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_FIXED_PRICE', 'User tried to add a collected order invoice fixed price modifications without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice_fixed_price' => 'Add a collected order invoice fixed price modifications. This is a superuser-only route.' ] ); /** Collected order invoices > Vehicle subscriptions > POST */ $this->post('/collected-invoices/vehicle-subscriptions/custom', function () { global $response; self::requirePermission('add_collected_invoice_vehicle_subscriptions'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User added a collected order invoice for vehicle subscriptions'); // Require the ID, and validate its type and length self::requireParameters(['customer_number', 'month', 'year']); self::requireType((int)self::getParameter('customer_number'), self::type_int()); self::requireMinLength('customer_number', 1); self::requireMaxLength('customer_number', 10); self::requireMinValue((int)self::getParameter('customer_number'), 1); $customer = (new users_o())->getUserByCustomerNumber((int)self::getParameter('customer_number')); $customer->requireSelected(); // Require the month to be between 1 and 12 self::requireType((int)self::getParameter('month'), self::type_int()); self::requireMinLength('month', 1); self::requireMaxLength('month', 2); self::requireMinValue((int)self::getParameter('month'), 1); self::requireMaxValue((int)self::getParameter('month'), 12); // Require the year to be in the past 2 years self::requireType((int)self::getParameter('year'), self::type_int()); self::requireMinLength('year', 1); self::requireMaxLength('year', 4); self::requireMinValue((int)self::getParameter('year'), date('Y') - 2); self::requireMaxValue((int)self::getParameter('year'), date('Y')); // Create the collected order invoice $collected_order_invoices = new collected_order_invoices_o(); $collected_order_invoices->add( (int)self::getParameter('customer_number'), ); // Require the collected order invoice to be selected $collected_order_invoices->requireSelected(); // Get the month and year from the request $month = (int)self::getParameter('month'); $year = (int)self::getParameter('year'); // Add a leading zero to the month if it's less than 10 $month_with_prefix_if_applicable = str_pad($month, 2, '0', STR_PAD_LEFT); // Add a leading zero to the year if it's less than 4 digits $year_with_prefix_if_applicable = str_pad($year, 4, '0', STR_PAD_LEFT); // Generate the timestamp for the selected month and year, with the first day, and first second $timestamp_selected = mktime(0, 0, 1, $month_with_prefix_if_applicable, 1, $year_with_prefix_if_applicable); // MySQL requires the date to be in the format YYYY-MM-DD HH:MM:SS $timestamp_selected = date('Y-m-d H:i:s', $timestamp_selected); // Set the date to the first second of the date specified $collected_order_invoices->created_at->set($timestamp_selected); // Add the collected order invoice to E-Conomic $collected_order_invoices->addVehicleSubscriptionsTransaction(); // Close the collected order invoice $collected_order_invoices->closed_at->set($timestamp_selected); // Update the collected order invoice $collected_order_invoices->objectChanged(); // Return the collected order invoice $response->success($collected_order_invoices->asArray()); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'ADD_COLLECTED_INVOICE_VEHICLE_SUBSCRIPTIONS', 'User tried to add a collected order invoice for vehicle subscriptions without a valid session'); $response->error('Invalid session', 400); } }, [ 'add_collected_invoice_vehicle_subscriptions' => 'Add a collected order invoice for vehicle subscriptions. This is a superuser-only route.' ] ); /** Collected order invoices > Open > GET Customers */ $this->get('/collected-invoices/customers', function () { global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS', 'User accessed the list of collected order invoices customers'); // Define the users $users_o = new users_o(); $tmp_customer_numbers = $users_o->getCustomerNumbersWithAttributes([ 'invoiceAllOrdersIndividually' ]); // Filter out the customers that do not have any open invoices $customer_numbers = []; //print_r($tmp_customer_numbers); foreach ( $tmp_customer_numbers as $customer_number ) { // This is the customers open invoices, this might contain invoices that's empty, or only contains deleted orders. $tmp_customer_open_invoice_ids = []; // This is the net amount of the total transactions for the customer $tmp_total_net_amount = 0; // This is the number of invoices, that's not empty. $tmp_customer_active_invoice_ids = []; $collected_order_invoices = new collected_order_invoices_o(); $customer_open_invoices = $collected_order_invoices->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($tmp_total_net_amount, $users_o, $collected_order_invoices) { // Select the orders for each collected order invoice $collected_order_invoices->select((int)$collected_order_invoice['id']); // Return the details return $this->getOrderInvoiceDetails($collected_order_invoice, $users_o, $collected_order_invoices); }, $collected_order_invoices->forceRestrictFilters([ 'customer_number' => $customer_number, 'closed_at' => 'null', ]) ); //print_r($customer_open_invoices); // Check if the customer has any open invoices if (count($customer_open_invoices) > 0) { $tmp_customer_orders = 0; // Get the total net amount of the open invoices foreach ( $customer_open_invoices as $customer_open_invoice ) { // Check if the invoice is empty if (count($customer_open_invoice['orders']) === 0) { continue; } // Add the invoice collected order invoice ID to the list (if it's not already in the list) if (!in_array($customer_open_invoice['id'], $tmp_customer_open_invoice_ids)) { $tmp_customer_active_invoice_ids[] = $customer_open_invoice['id']; } // Update the total net amount, and the number of orders $tmp_customer_open_invoice_ids[] = $customer_open_invoice['id']; $tmp_total_net_amount += $customer_open_invoice['total_net_amount']; $tmp_customer_orders += count($customer_open_invoice['orders']); } // If the open invoices are not empty, add the customer to the list if (empty($tmp_customer_orders)) { continue; } $tmp_user = (new users_o())->getUserByCustomerNumber($customer_number); $customer_numbers[] = array( 'customer_number' => $customer_number, 'customer_name' => $users_o->getCustomerName($customer_number), 'user_id' => $tmp_user->id, 'open_invoices' => $customer_open_invoices, 'active_invoices' => $tmp_customer_active_invoice_ids, 'orders' => $tmp_customer_orders, 'total_net_amount' => $tmp_total_net_amount, ); } } // Return the list of customers $response->success($customer_numbers); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS', 'User tried to access the list of collected order invoices customers without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices_customers' => 'List ALL collected order invoices customers. This is a superuser-only route.' ] ); $this->get('/collected-invoices/customers/invoicePerOrder', function () { global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_ORDER', 'User accessed the list of collected order invoices customers with invoice per order'); // Define the users $users_o = new users_o(); $users_o->setView('customers_invoice_count_per_order'); $result = $users_o ->setSearchableFields([ 'customer_number', 'customer_name', 'active_invoices', 'closed_invoices', ]) ->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($users_o) { return [ 'customer_number' => (int)$collected_order_invoice['customer_number'], 'display_name' => (string)$users_o->getCustomerName((int)$collected_order_invoice['customer_number']), 'active_invoices' => (int)$collected_order_invoice['active_invoices'], 'closed_invoices' => (int)$collected_order_invoice['closed_invoices'], ]; }, $users_o->forceRestrictFilters( [ //'active_invoices' => 'NOT ZERO', ] ) ); // Return the list of customers $response->success($result); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_ORDER', 'User tried to access the list of collected order invoices customers with invoice per order without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices_customers_invoice_per_order' => 'List ALL collected order invoices customers with invoice per order. This is a superuser-only route.' ] ); $this->get('/collected-invoices/customers/invoicePerMonth', function () { global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_MONTH', 'User accessed the list of collected order invoices customers with invoice per month'); // Define the users $users_o = new users_o(); $users_o->setView('customers_invoice_count_per_month'); $result = $users_o ->setSearchableFields([ 'customer_number', 'customer_name', 'active_invoices', 'closed_invoices', ]) ->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($users_o) { return [ 'customer_number' => (int)$collected_order_invoice['customer_number'], 'display_name' => (string)$users_o->getCustomerName((int)$collected_order_invoice['customer_number']), 'active_invoices' => (int)$collected_order_invoice['active_invoices'], 'closed_invoices' => (int)$collected_order_invoice['closed_invoices'], ]; }, $users_o->forceRestrictFilters( [ //'active_invoices' => 'NOT ZERO', ] ) ); // Return the list of customers $response->success($result); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_PER_MONTH', 'User tried to access the list of collected order invoices customers with invoice per month without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices_customers_invoice_per_month' => 'List ALL collected order invoices customers with invoice per month. This is a superuser-only route.' ] ); $this->post('/collected-invoices/customers/invoiceTotals', function () { // This is a superuser-only route global $response; self::requirePermission('list_collected_invoices'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_TOTALS', 'User accessed the list of collected order invoices customers with invoice totals'); // Require the customer_numbers parameter self::requireParameters(['customer_numbers']); // Print the customer_numbers parameter $customer_numbers = self::getParameter('customer_numbers'); // validate the customer_numbers parameter if (!is_array($customer_numbers)) { $response->error('customer_numbers must be an array', 400); } // Validate the customer_numbers parameter foreach ( $customer_numbers as $customer_number ) { self::requireType((int)$customer_number, self::type_int()); if (!is_numeric($customer_number)) { $response->error('customer_numbers must be an array of integers', 400); } if (!$customer_number || $customer_number < 1) { $response->error('customer_numbers must be an array of integers greater than 0', 400); } } // Now we can safely use the customer_numbers parameter // Define the result array $result = []; // Loop through the customer_numbers array, and get the invoice totals for each customer foreach ( $customer_numbers as $customer_number ) { // Define the invoices array $tmp_invoices = [ 'closed_invoices' => [], 'open_invoices' => [], ]; // Define the total net amount $tmp_total_net_amount = [ 'closed_invoices' => 0, 'open_invoices' => 0, ]; // Define the collected order invoices $collected_order_invoices = new collected_order_invoices_o(); // Get the collected order invoices for the customer $collected_order_invoices->setView('invoices_with_completed_orders'); $tmp_invoice_collections = $collected_order_invoices->listObjectsWithPaginationIfSet( function ($collected_order_invoice) use ($tmp_invoices, $customer_number, $collected_order_invoices) { // Select the orders for each collected order invoice $collected_order_invoices->select((int)$collected_order_invoice['id']); // Get the details for the collected order invoice return $this->getOrderInvoiceDetails($collected_order_invoice, new users_o(), $collected_order_invoices); }, $collected_order_invoices->forceRestrictFilters([ 'customer_number' => $customer_number, ]) ); // Loop through the collected order invoices, and get the total net amount foreach ( $tmp_invoice_collections as $tmp_invoice_collection ) { // Update the total net amount if ($tmp_invoice_collection['closed_at'] !== null) { $tmp_total_net_amount['closed_invoices'] += $tmp_invoice_collection['total_net_amount']; // Add the closed invoice to the closed invoices array $tmp_invoices['closed_invoices'][] = $tmp_invoice_collection; } else { $tmp_total_net_amount['open_invoices'] += $tmp_invoice_collection['total_net_amount']; // Add the open invoice to the open invoices array $tmp_invoices['open_invoices'][] = $tmp_invoice_collection; } } $tmp_user = (new users_o())->getUserByCustomerNumber($customer_number); // Add the customer to the result array $result[$customer_number] = [ 'customer_number' => (int)$customer_number, 'customer_name' => (string)$tmp_user->display_name->value(), 'user_id' => (int)$tmp_user->id, 'invoices' => $tmp_invoices, 'total_net_amount' => $tmp_total_net_amount, ]; } // Return the list of customers $response->success($result); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_CUSTOMERS_INVOICE_TOTALS', 'User tried to access the list of collected order invoices customers with invoice totals without a valid session'); $response->error('Invalid session', 400); } }); $this->get('/collected-invoices/economic/overview', function () { global $response; self::requirePermission('list_collected_invoices_economic_overview'); $user = (new authentication())->get_user(); if ($user) { // Get the economic module $economic = new economic(); // Get the collected order invoices $collected_order_invoices = new collected_order_invoices_o(); /** * Get the total invoices using E-conomic as the processor, with the given restrictions * @param $collected_order_invoices collected_order_invoices_o * @param $restrictions array * @param $view string The MySQL view to use for the query * @param $page int The page number to return * @param $limit int The number of results to return per page * @return int */ function getTotalInvoices(collected_order_invoices_o $collected_order_invoices, array $restrictions = [], string $view = 'invoices_with_completed_orders', int $page = 1, int $limit = 100000): int { // Add the economic processor to the restrictions $restrictions['processor'] = 1; // E-conomic return count( $collected_order_invoices->getTotalInvoices( $collected_order_invoices, $restrictions, $view, $page, $limit, 1 ) ); } (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'LIST_COLLECTED_INVOICES_ECONOMIC_OVERVIEW', 'User accessed the list of collected order invoices economic overview'); // Define the result array $result = [ 'total' => getTotalInvoices($collected_order_invoices), 'paid' => 0, 'unpaid' => 0, 'overdue' => 0, 'booked' => getTotalInvoices( $collected_order_invoices, [ 'booked_invoice_id' => 'NOT NULL', 'external_id' => 'NOT NULL', ], 'invoices_with_completed_orders' ), 'draft' => getTotalInvoices( $collected_order_invoices, [ 'booked_invoice_id' => null, 'error_message' => null, 'external_id' => 'NOT NULL', ], 'invoices_with_completed_orders' ), 'sent' => 0, 'error' => getTotalInvoices( $collected_order_invoices, [ 'booked_invoice_id' => null, 'external_id' => 'NOT NULL', 'error_message' => 'NOT NULL', ], 'invoices_with_completed_orders' ), ]; // Return the list of customers $response->success($result); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'LIST_COLLECTED_INVOICES_ECONOMIC_OVERVIEW', 'User tried to access the list of collected order invoices economic overview without a valid session'); $response->error('Invalid session', 400); } }, [ 'list_collected_invoices_economic_overview' => 'List ALL collected order invoices overview. This is a superuser-only route.' ] ); $this->post('/collected-invoices/economic/run/check-drafts', function () { global $response; self::requirePermission('module_economic_run_check_drafts'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_DRAFTS', 'User ran the check drafts'); // Get the economic module $economic = new economic(); try { // Run the check drafts $economic->getTasks()->runCheckDrafts(); } catch (Exception $e) { // If the task fails, log the error and return an error response (new logs_o())->add('orderInvoices', 'global', 0, 0, 'RUN_CHECK_DRAFTS', 'User tried to run the check drafts, but it failed: ' . $e->getMessage()); $response->error('Failed to run the check drafts: ' . $e->getMessage(), 500); } // Return the result $response->success('Check drafts completed successfully'); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'RUN_CHECK_DRAFTS', 'User tried to run the check drafts without a valid session'); $response->error('Invalid session', 400); } }, [ 'module_economic_run_check_drafts' => 'Run the check drafts. This is a superuser-only route.' ] ); $this->post('/collected-invoices/economic/run/check-errors', function () { global $response; self::requirePermission('module_economic_run_check_errors'); $user = (new authentication())->get_user(); if ($user) { (new logs_o())->add('orderInvoices', 'global', 1, $user->id, 'RUN_CHECK_ERRORS', 'User ran the check errors'); // Get the economic module $economic = new economic(); try { // Run the check errors $economic->getTasks()->runCheckErrors(); } catch (Exception $e) { // If the task fails, log the error and return an error response (new logs_o())->add('orderInvoices', 'global', 0, 0, 'RUN_CHECK_ERRORS', 'User tried to run the check errors, but it failed: ' . $e->getMessage()); $response->error('Failed to run the check errors: ' . $e->getMessage(), 500); } // Return the result $response->success('Check errors completed successfully'); } else { (new logs_o())->add('orderInvoices', 'global', 0, 0, 'RUN_CHECK_ERRORS', 'User tried to run the check errors without a valid session'); $response->error('Invalid session', 400); } }, [ 'module_economic_run_check_errors' => 'Run the check errors. This is a superuser-only route.' ] ); } /** * @param $collected_order_invoice * @param users_o $users * @param collected_order_invoices_o $tmp_collected_order_invoices * @return array * @throws Exception */ function getOrderInvoiceDetails($collected_order_invoice, users_o $users, collected_order_invoices_o $tmp_collected_order_invoices): array { return [ 'id' => (int)$collected_order_invoice['id'], 'name' => (string)$collected_order_invoice['name'], 'notes' => (string)$collected_order_invoice['notes'], 'customer_number' => (int)$collected_order_invoice['customer_number'], 'customer_name' => (string)$users->getCustomerName((int)$collected_order_invoice['customer_number']), 'processor' => $collected_order_invoice['processor'] ? (int)$collected_order_invoice['processor'] : null, 'external_id' => (string)$collected_order_invoice['external_id'], 'closed_at' => $collected_order_invoice['closed_at'] ? (string)$collected_order_invoice['closed_at'] : null, 'updated_at' => (string)$collected_order_invoice['updated_at'], 'created_at' => (string)$collected_order_invoice['created_at'], 'orders' => $tmp_collected_order_invoices->getOrders(), 'total_net_amount' => (float)$tmp_collected_order_invoices->getTotalAmount(), ]; } }