Add booking synchronization and API integration
Implemented methods for booking synchronization, including fetching, parsing, and updating bookings from a remote API. Added caching mechanisms and data validation for customer names, department names, and booking details. Integrated new API trait and remote booking class to improve scalability and enable automated tests for booking modules.
This commit is contained in:
+8
-1
@@ -56,6 +56,10 @@ class redis implements redis_i
|
||||
*/
|
||||
public function cache_economic_customer_name(int $customer_number, string $customer_name): self
|
||||
{
|
||||
// If the customer name is empty, or null, set it to 'IS_EMPTY_OR_NULL'
|
||||
if (empty($customer_name)) {
|
||||
$customer_name = 'IS_EMPTY_OR_NULL';
|
||||
}
|
||||
// Cache the economic customer name
|
||||
$this->set('economic_customer_name_' . $customer_number, $customer_name);
|
||||
return $this;
|
||||
@@ -114,7 +118,10 @@ class redis implements redis_i
|
||||
*/
|
||||
public function cache_department_name(int $department_id, string $department_name): self
|
||||
{
|
||||
// Cache the department name
|
||||
// Cache the department name (If it is not empty or null)
|
||||
if (!empty($department_name)) {
|
||||
$department_name = 'IS_EMPTY_OR_NULL';
|
||||
}
|
||||
$this->set('department_name_' . $department_id, $department_name);
|
||||
return $this;
|
||||
}
|
||||
|
||||
+6
-3
@@ -31,7 +31,7 @@ class slack implements notification_i
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function get_department_webhook(int $department_id): string
|
||||
private function get_department_webhook(int $department_id): string|null
|
||||
{
|
||||
// Check if the department webhook is cached
|
||||
$webhook = redis->get_department_webhook($department_id);
|
||||
@@ -41,8 +41,11 @@ class slack implements notification_i
|
||||
$department->id = $department_id;
|
||||
$department->getObjectProperties();
|
||||
$webhook = $department->slack_webhook->value();
|
||||
// Cache the department webhook
|
||||
redis->cache_department_webhook($department_id, $webhook);
|
||||
// Cache the department webhook (If it is not empty or null)
|
||||
if (!empty($webhook)) {
|
||||
redis->cache_department_webhook($department_id, $webhook);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return redis->get_department_webhook($department_id);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace classes;
|
||||
|
||||
use interfaces\wordpress_bookings_remote_i;
|
||||
use traits\wordpress_api_object_t;
|
||||
|
||||
class wordpress_bookings_remote implements wordpress_bookings_remote_i
|
||||
{
|
||||
use wordpress_api_object_t;
|
||||
|
||||
protected array $booking_cache = [];
|
||||
protected wash_certificate_store $wash_certificate_store;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// Run wordpress_api_object_t constructor
|
||||
$this->wordpress_api_object_t_construct();
|
||||
$this->wash_certificate_store = new wash_certificate_store();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_all_wash_ids(): array
|
||||
{
|
||||
// Get all the wash IDs
|
||||
return $this->request('get_all_wash_ids');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_all_bookings(): array
|
||||
{
|
||||
// Get all the bookings
|
||||
return $this->request('get_all_wash_bookings');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_last_wash_id(): int
|
||||
{
|
||||
// Get the last wash ID
|
||||
$result = $this->request('get_last_wash_id');
|
||||
return $result["success"] ? (int)$result["data"]["last_wash_id"] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function parse_bookings(array $bookings): array
|
||||
{
|
||||
// Parse all the bookings
|
||||
$parsed_bookings = [];
|
||||
foreach ( $bookings as $booking ) {
|
||||
$parsed_booking = $this->parse_booking($booking);
|
||||
if ($parsed_booking !== null) {
|
||||
// Check if the booking has a wash certificate
|
||||
$parsed_bookings[] = $parsed_booking;
|
||||
}
|
||||
}
|
||||
return $parsed_bookings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function parse_booking(array|int $booking): array|null
|
||||
{
|
||||
// Check if the booking is an integer, and get the booking by the ID
|
||||
if (is_int($booking)) {
|
||||
$booking = $this->get_booking($booking);
|
||||
}
|
||||
|
||||
// Check if the success is false
|
||||
if (isset($booking["success"])) {
|
||||
if (!$booking["success"]) {
|
||||
return null;
|
||||
} else {
|
||||
$booking = $booking["data"]["booking"];
|
||||
}
|
||||
} else if (isset($booking["id"])) {
|
||||
// Check if the booking property is set
|
||||
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->booking_cache[$booking["id"]] = [
|
||||
"id" => (int)$booking["id"],
|
||||
"customer_number" => (int)$booking["customer_number"],
|
||||
"wash_type" => (string)$booking["wash_type"],
|
||||
"contact_email" => (string)$booking["contact_email"],
|
||||
"reference_number" => (string)$booking["reference_number"],
|
||||
"regNrTraekker" => (string)$booking["regNrTraekker"],
|
||||
"regNrTrailer" => (string)$booking["regNrTrailer"],
|
||||
"washCertificateEmail" => (string)$booking["washCertificateEmail"],
|
||||
"date" => (string)$booking["date"],
|
||||
"department" => (string)$booking["department"],
|
||||
"pickup_bool" => (boolean)$booking["pickup_bool"] ? 'true' : 'false',
|
||||
"notes" => (string)$booking["notes"],
|
||||
"washCertificateStatus" => (string)$booking["washCertificateStatus"],
|
||||
"washCertificateUrl" => (string)$booking["washCertificateUrl"],
|
||||
"status" => (string)$booking["status"]
|
||||
];
|
||||
|
||||
// If the status is pending, check if the booking has a wash certificate
|
||||
if ($this->booking_cache[$booking["id"]]["status"] === 'pending') {
|
||||
$this->booking_cache[$booking["id"]]["status"] = $this->check_booking_has_wash_certificate($booking) ? 'completed' : 'pending';
|
||||
}
|
||||
return $this->booking_cache[$booking["id"]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_booking(int $id): array
|
||||
{
|
||||
// Get the booking by the ID
|
||||
return $this->request('get_wash_booking', ['wash_id' => $id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function check_booking_has_wash_certificate(array $booking): bool
|
||||
{
|
||||
// Check if the booking has a wash certificate
|
||||
return $this->wash_certificate_store->washCertificateExists($booking['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function check_booking_has_expected_keys(array $booking, array $expected_keys): bool
|
||||
{
|
||||
// Check if the booking has the expected keys
|
||||
return count(array_intersect($expected_keys, array_keys($booking))) === count($expected_keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function get_booking_cache(): array
|
||||
{
|
||||
// Get the booking cache
|
||||
return $this->booking_cache;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,6 @@ if (php_sapi_name() !== 'cli') {
|
||||
exit;
|
||||
}
|
||||
$args = $argv;
|
||||
echo "This is the CLI script";
|
||||
echo "\n";
|
||||
echo "Arguments: ";
|
||||
print_r($args);
|
||||
|
||||
// If the first argument is 'run', switch to the second argument
|
||||
if ($args[1] === 'run') {
|
||||
@@ -28,6 +24,13 @@ if ($args[1] === 'run') {
|
||||
echo "Running the slack test script";
|
||||
require_once 'tests/slackModule/SlackModuleTest.php';
|
||||
break;
|
||||
case 'bookingSync-test':
|
||||
echo "Running the bookingSync test script";
|
||||
require_once 'tests/bookingModule/bookingSyncTest.php';
|
||||
break;
|
||||
case 'bookingSync':
|
||||
require_once 'cron/SyncBookings.php';
|
||||
break;
|
||||
default:
|
||||
echo "Invalid script name";
|
||||
break;
|
||||
|
||||
@@ -31,8 +31,5 @@ $htaccess = "
|
||||
// Write the .htaccess file (This is not really ideal, but it works for now. This is because the .htaccess file is changed by cPanel, and it's not going to be kept there anyway.)
|
||||
file_put_contents(__DIR__ . '/.htaccess', $htaccess);
|
||||
|
||||
// Get the current time
|
||||
$now = time();
|
||||
|
||||
// Log the time of the cron job
|
||||
file_put_contents(__DIR__ . '/cron.log', date('Y-m-d H:i:s', $now) . ' - Cron job executed in ' . (time() - $now) . ' seconds ( ' . (microtime(true) - $now) . 'ms )' . PHP_EOL, FILE_APPEND);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* This script is used to sync bookings from the remote API to the local database.
|
||||
* It is run as a cron job.
|
||||
*
|
||||
* index.php run bookingSync
|
||||
*/
|
||||
|
||||
// prevent direct access
|
||||
|
||||
use objects\bookings_o;
|
||||
|
||||
if (!defined('WD')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// Sync the bookings
|
||||
$bookings_o = new bookings_o();
|
||||
$bookings_o->syncBookings();
|
||||
@@ -40,6 +40,7 @@ require_once 'classes/ratelimit.php';
|
||||
require_once 'classes/wash_certificate_store.php';
|
||||
require_once 'classes/redis.php';
|
||||
require_once 'classes/slack.php';
|
||||
require_once 'classes/wordpress_bookings_remote.php';
|
||||
|
||||
/**
|
||||
* Modules
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace interfaces;
|
||||
|
||||
interface wordpress_bookings_remote_i
|
||||
{
|
||||
/**
|
||||
* Get booking by ID from the remote API
|
||||
* @param int $id
|
||||
* @return array
|
||||
*/
|
||||
public function get_booking(int $id): array;
|
||||
|
||||
/**
|
||||
* Parse booking data, and return it as an array
|
||||
* @param array|int $booking
|
||||
* @return array|null The parsed booking data, or null if the booking was not found
|
||||
*/
|
||||
public function parse_booking(array|int $booking): array|null;
|
||||
|
||||
/**
|
||||
* Get all wash IDs from the remote API
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_wash_ids(): array;
|
||||
|
||||
/**
|
||||
* Get all bookings from the remote API
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_bookings(): array;
|
||||
|
||||
/**
|
||||
* Get the last wash ID from the remote API
|
||||
* @return int
|
||||
*/
|
||||
public function get_last_wash_id(): int;
|
||||
|
||||
/**
|
||||
* Parse multiple bookings
|
||||
* @param array $bookings
|
||||
* @return array
|
||||
*/
|
||||
public function parse_bookings(array $bookings): array;
|
||||
|
||||
/**
|
||||
* Check if a booking has the expected keys
|
||||
* @param array $booking
|
||||
* @param array $expected_keys
|
||||
* @return bool
|
||||
*/
|
||||
public function check_booking_has_expected_keys(array $booking, array $expected_keys): bool;
|
||||
|
||||
/**
|
||||
* Check if a booking has a wash certificate
|
||||
* @param array $booking
|
||||
*/
|
||||
public function check_booking_has_wash_certificate(array $booking): bool;
|
||||
|
||||
/**
|
||||
* Get the booking cache
|
||||
* @return array
|
||||
*/
|
||||
public function get_booking_cache(): array;
|
||||
}
|
||||
+143
-75
@@ -6,6 +6,7 @@ use classes\db;
|
||||
use classes\object_property;
|
||||
use classes\response;
|
||||
use classes\slack;
|
||||
use classes\wordpress_bookings_remote;
|
||||
use traits\db_object_t;
|
||||
|
||||
class bookings_o extends db
|
||||
@@ -27,11 +28,153 @@ class bookings_o extends db
|
||||
public object_property $washCertificateUrl;
|
||||
public object_property $status;
|
||||
|
||||
private static function isCancelled(int $id): bool
|
||||
{
|
||||
global $db;
|
||||
// Check if the booking has been cancelled
|
||||
$sql = "SELECT status FROM bookings WHERE id = $id";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
return $row['status'] === 'cancelled';
|
||||
}
|
||||
|
||||
public function structure(): void
|
||||
{
|
||||
$this->setTable('bookings');
|
||||
}
|
||||
|
||||
public function getCustomerBookingsPaginated(int $customer_number, int $page = 1, int $limit = 10, array $order = ['id' => 'DESC'], string $search = null, array $filters = null): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
// Add the customer number to the filters
|
||||
$filters['customer_number'] = $customer_number;
|
||||
// List the objects with pagination
|
||||
$array = $this->listObjectsWithPagination($page, $limit, $search, $filters, $order);
|
||||
// Get the total number of objects
|
||||
$total = $this->getTotalObjects($search, $filters);
|
||||
$response->paginate($page, $limit, $total);
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getDepartmentBookingsUnfulfilledCount(int $department_id): int
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
// Check if the count is cached
|
||||
if (redis->get_department_booking_count($department_id)) {
|
||||
$response->add_meta('cached', true);
|
||||
return redis->get_department_booking_count($department_id);
|
||||
}
|
||||
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE department = $department_id AND status = 'pending'";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
// Cache the count
|
||||
redis->cache_department_booking_count($department_id, $row['count']);
|
||||
return $row['count'];
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
// Set the status to cancelled
|
||||
$this->status->set('cancelled');
|
||||
// Remove the cache
|
||||
redis->clear_department_booking_count($this->department->value());
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
|
||||
$this->wash_type = new object_property($this->table, $this->id, 'wash_type', 'string', true);
|
||||
$this->contact_email = new object_property($this->table, $this->id, 'contact_email', 'string', true);
|
||||
$this->reference_number = new object_property($this->table, $this->id, 'reference_number', 'string', true);
|
||||
$this->regNrTraekker = new object_property($this->table, $this->id, 'regNrTraekker', 'string', true);
|
||||
$this->regNrTrailer = new object_property($this->table, $this->id, 'regNrTrailer', 'string', true);
|
||||
$this->washCertificateEmail = new object_property($this->table, $this->id, 'washCertificateEmail', 'string', true);
|
||||
$this->date = new object_property($this->table, $this->id, 'date', 'string', true);
|
||||
$this->department = new object_property($this->table, $this->id, 'department', 'string', true);
|
||||
$this->pickup_bool = new object_property($this->table, $this->id, 'pickup_bool', 'int', true);
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
|
||||
$this->washCertificateStatus = new object_property($this->table, $this->id, 'washCertificateStatus', 'string', true);
|
||||
$this->washCertificateUrl = new object_property($this->table, $this->id, 'washCertificateUrl', 'string', true);
|
||||
$this->status = new object_property($this->table, $this->id, 'status', 'string', true);
|
||||
}
|
||||
|
||||
public function parseBookings(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
// Parse the customer numbers
|
||||
$bookings = $this->parseCustomerNumbers($listObjectsWithPaginationIfSet);
|
||||
return $bookings;
|
||||
}
|
||||
|
||||
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
// Parse the customer numbers
|
||||
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
|
||||
$listObjectsWithPaginationIfSet[$key]['customer_name'] = redis->get_economic_customer_name($value['customer_number']) ?? (new users_o())->getCustomerName($value['customer_number']);
|
||||
}
|
||||
return $listObjectsWithPaginationIfSet;
|
||||
|
||||
}
|
||||
|
||||
public function syncBookings(): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
$wordpress_bookings_remote = new wordpress_bookings_remote();
|
||||
// Get all the bookings from the remote API
|
||||
$bookings = $wordpress_bookings_remote->get_all_bookings()['data']['all_wash_bookings'];
|
||||
// Parse the bookings
|
||||
$parsed_bookings = $wordpress_bookings_remote->parse_bookings($bookings);
|
||||
// Remove the cancelled bookings from the $parsed_bookings array
|
||||
$cancelled_bookings = $this->getAllCancelledBookings();
|
||||
foreach ( $cancelled_bookings as $cancelled_booking ) {
|
||||
// Remove the cancelled booking from the parsed bookings
|
||||
foreach ( $parsed_bookings as $key => $parsed_booking ) {
|
||||
if ((int)$parsed_booking['id'] === (int)$cancelled_booking['id']) {
|
||||
unset($parsed_bookings[$key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sync the bookings
|
||||
foreach ( $parsed_bookings as $booking ) {
|
||||
// Add or update the booking
|
||||
$this->addOrUpdate(
|
||||
$booking['id'],
|
||||
$booking['customer_number'],
|
||||
$booking['wash_type'],
|
||||
$booking['contact_email'],
|
||||
$booking['reference_number'],
|
||||
$booking['regNrTraekker'],
|
||||
$booking['regNrTrailer'],
|
||||
$booking['washCertificateEmail'],
|
||||
$booking['date'],
|
||||
$booking['department'],
|
||||
$booking['pickup_bool'] === 'true' ? 1 : 0,
|
||||
$booking['notes'],
|
||||
$booking['washCertificateStatus'],
|
||||
$booking['washCertificateUrl'],
|
||||
$booking['status']
|
||||
);
|
||||
}
|
||||
return [
|
||||
"bookings" => count($bookings),
|
||||
"cancelled" => count($cancelled_bookings),
|
||||
"parsed" => count($parsed_bookings),
|
||||
];
|
||||
}
|
||||
|
||||
public function getAllCancelledBookings(): array
|
||||
{
|
||||
global $db;
|
||||
// Get all the cancelled bookings
|
||||
$sql = "SELECT * FROM $this->table WHERE status = 'cancelled'";
|
||||
$result = $db->query($sql);
|
||||
return $db->fetch_all($result);
|
||||
}
|
||||
|
||||
public function addOrUpdate($id, $customer_number, $wash_type, $contact_email, $reference_number, $regNrTraekker, $regNrTrailer, $washCertificateEmail, $date, $department, $pickup_bool, $notes, $washCertificateStatus, $washCertificateUrl, $status): void
|
||||
{
|
||||
global $db;
|
||||
@@ -127,79 +270,4 @@ class bookings_o extends db
|
||||
$this->id = $db->insert_id();
|
||||
}
|
||||
|
||||
public function getCustomerBookingsPaginated(int $customer_number, int $page = 1, int $limit = 10, array $order = ['id' => 'DESC'], string $search = null, array $filters = null): array
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
// Add the customer number to the filters
|
||||
$filters['customer_number'] = $customer_number;
|
||||
// List the objects with pagination
|
||||
$array = $this->listObjectsWithPagination($page, $limit, $search, $filters, $order);
|
||||
// Get the total number of objects
|
||||
$total = $this->getTotalObjects($search, $filters);
|
||||
$response->paginate($page, $limit, $total);
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getDepartmentBookingsUnfulfilledCount(int $department_id): int
|
||||
{
|
||||
global /** @var response $response */
|
||||
$db, $response;
|
||||
// Check if the count is cached
|
||||
if (redis->get_department_booking_count($department_id)) {
|
||||
$response->add_meta('cached', true);
|
||||
return redis->get_department_booking_count($department_id);
|
||||
}
|
||||
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE department = $department_id AND status = 'pending'";
|
||||
$result = $db->query($sql);
|
||||
$row = $db->fetch_assoc($result);
|
||||
// Cache the count
|
||||
redis->cache_department_booking_count($department_id, $row['count']);
|
||||
return $row['count'];
|
||||
}
|
||||
|
||||
public function delete(int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->getObjectProperties();
|
||||
// Set the status to cancelled
|
||||
$this->status->set('cancelled');
|
||||
// Remove the cache
|
||||
redis->clear_department_booking_count($this->department->value());
|
||||
}
|
||||
|
||||
public function getObjectProperties(): void
|
||||
{
|
||||
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
|
||||
$this->wash_type = new object_property($this->table, $this->id, 'wash_type', 'string', true);
|
||||
$this->contact_email = new object_property($this->table, $this->id, 'contact_email', 'string', true);
|
||||
$this->reference_number = new object_property($this->table, $this->id, 'reference_number', 'string', true);
|
||||
$this->regNrTraekker = new object_property($this->table, $this->id, 'regNrTraekker', 'string', true);
|
||||
$this->regNrTrailer = new object_property($this->table, $this->id, 'regNrTrailer', 'string', true);
|
||||
$this->washCertificateEmail = new object_property($this->table, $this->id, 'washCertificateEmail', 'string', true);
|
||||
$this->date = new object_property($this->table, $this->id, 'date', 'string', true);
|
||||
$this->department = new object_property($this->table, $this->id, 'department', 'string', true);
|
||||
$this->pickup_bool = new object_property($this->table, $this->id, 'pickup_bool', 'int', true);
|
||||
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
|
||||
$this->washCertificateStatus = new object_property($this->table, $this->id, 'washCertificateStatus', 'string', true);
|
||||
$this->washCertificateUrl = new object_property($this->table, $this->id, 'washCertificateUrl', 'string', true);
|
||||
$this->status = new object_property($this->table, $this->id, 'status', 'string', true);
|
||||
}
|
||||
|
||||
public function parseBookings(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
// Parse the customer numbers
|
||||
$bookings = $this->parseCustomerNumbers($listObjectsWithPaginationIfSet);
|
||||
return $bookings;
|
||||
}
|
||||
|
||||
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
|
||||
{
|
||||
// Parse the customer numbers
|
||||
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
|
||||
$listObjectsWithPaginationIfSet[$key]['customer_name'] = redis->get_economic_customer_name($value['customer_number']) ?? (new users_o())->getCustomerName($value['customer_number']);
|
||||
}
|
||||
return $listObjectsWithPaginationIfSet;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -155,13 +155,19 @@ class departments_o extends db
|
||||
$name = redis->get_department_name($department);
|
||||
// If the department name is not cached, get it from the database
|
||||
if ($name === null) {
|
||||
$sql = "SELECT name FROM $this->table WHERE id = $department";
|
||||
$result = $db->query($sql);
|
||||
$result = $db->fetch_assoc($result);
|
||||
$name = $result['name'];
|
||||
// Cache the department name
|
||||
redis->cache_department_name($department, $name);
|
||||
try {
|
||||
$this->id = $department;
|
||||
$this->getObjectProperties();
|
||||
$name = $this->name->value();
|
||||
// Cache the department name (If it is not empty or null)
|
||||
if (!empty($name)) {
|
||||
redis->cache_department_name($department, $name);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$name = 'Unable to get department name: ' . $department;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
return redis->get_department_name($department);
|
||||
return redis->get_department_name($department) ?? 'Unable to get department name: ' . $department;
|
||||
}
|
||||
}
|
||||
+16
-15
@@ -195,6 +195,7 @@ class users_o extends db
|
||||
$array = [
|
||||
'id' => (int)$this->id,
|
||||
'customer_number' => (int)$this->customer_number->value(),
|
||||
'customer_name' => $this->getCustomerName($this->customer_number->value()),
|
||||
'display_name' => $this->display_name->value(),
|
||||
'group_id' => (int)$this->group_id->value(),
|
||||
'created_at' => $this->created_at->value(),
|
||||
@@ -219,6 +220,20 @@ class users_o extends db
|
||||
return $array;
|
||||
}
|
||||
|
||||
public function getCustomerName(int $customer_number): string|null
|
||||
{
|
||||
// Check if the customer name is cached
|
||||
if (redis->get_economic_customer_name($customer_number) !== null) {
|
||||
return redis->get_economic_customer_name($customer_number);
|
||||
}
|
||||
// Get the customer name from the external source
|
||||
$economic = new economicCustomers();
|
||||
$customer_name = $economic->getCustomerName($customer_number);
|
||||
// Cache the customer name
|
||||
redis->cache_economic_customer_name($customer_number, $customer_name ?? '');
|
||||
return $customer_name;
|
||||
}
|
||||
|
||||
public function getNotes(): array
|
||||
{
|
||||
global $db;
|
||||
@@ -634,7 +649,7 @@ class users_o extends db
|
||||
return true;
|
||||
}
|
||||
// Get the record from the database
|
||||
$sql = "SELECT * FROM bookings WHERE id = $id AND user_id = " . $this->id;
|
||||
$sql = "SELECT * FROM bookings WHERE id = $id AND customer_number = " . $this->customer_number->value();
|
||||
$result = $db->query($sql);
|
||||
if ($result->num_rows > 0) {
|
||||
return true;
|
||||
@@ -654,18 +669,4 @@ class users_o extends db
|
||||
}
|
||||
return $listObjectsWithPaginationIfSet;
|
||||
}
|
||||
|
||||
public function getCustomerName(int $customer_number): string|null
|
||||
{
|
||||
// Check if the customer name is cached
|
||||
if (redis->get_economic_customer_name($customer_number)) {
|
||||
return redis->get_economic_customer_name($customer_number);
|
||||
}
|
||||
// Get the customer name from the external source
|
||||
$economic = new economicCustomers();
|
||||
$customer_name = $economic->getCustomerName($customer_number);
|
||||
// Cache the customer name
|
||||
redis->cache_economic_customer_name($customer_number, $customer_name ?? '');
|
||||
return $customer_name;
|
||||
}
|
||||
}
|
||||
@@ -59,8 +59,9 @@ class bookingsRoute
|
||||
// Log the incident
|
||||
(new logs_o())->add('bookings', 'global', 1, $user->id, 'LIST_OWN_BOOKINGS', 'Successfully listed own bookings');
|
||||
// Return the list of departments
|
||||
$bookings_o = new bookings_o();
|
||||
$response->success(
|
||||
(new bookings_o())->getCustomerBookingsPaginated(
|
||||
$bookings_o->parseBookings($bookings_o->getCustomerBookingsPaginated(
|
||||
$user->customer_number->value(),
|
||||
($this->fromRequest('page') ?? 1),
|
||||
($this->fromRequest('limit') ?? 10),
|
||||
@@ -68,7 +69,7 @@ class bookingsRoute
|
||||
$this->fromRequest('search') === null ? '' : $this->fromRequest('search'),
|
||||
$this->fromRequest('filters') === null ? [] :
|
||||
$response->parseFilters($this->fromRequest('filters')) ?? []
|
||||
)
|
||||
))
|
||||
);
|
||||
} else {
|
||||
// Log the incident
|
||||
@@ -230,5 +231,26 @@ class bookingsRoute
|
||||
["message" => "Booking deleted"]
|
||||
);
|
||||
});
|
||||
|
||||
$this->post('/superuser/bookings/sync/all', function () {
|
||||
// Require the user to be logged in
|
||||
global /** @var response $response */
|
||||
$response;
|
||||
$this->requirePermission('sync_all_bookings');
|
||||
// Get the user object
|
||||
$user = (new authentication())->get_user();
|
||||
// Check if the request was successful
|
||||
if (!$user->exists()) {
|
||||
$response->error('User not found', 400);
|
||||
}
|
||||
// Log the incident
|
||||
(new logs_o())->add('bookings', 'global', 1, $user->id, 'SYNC_ALL_BOOKINGS', 'Successfully synced all bookings');
|
||||
// Sync all bookings
|
||||
(new bookings_o())->syncBookings();
|
||||
// Return success
|
||||
$response->success(
|
||||
["message" => "All bookings synced"]
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
// prevent direct access
|
||||
use classes\wordpress_bookings_remote;
|
||||
|
||||
if (!defined('WD')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
function warn($message): void
|
||||
{
|
||||
echo "\n\033[33m$message\033[0m\n";
|
||||
}
|
||||
|
||||
// Test if we can fetch a booking.
|
||||
$booking_id = 155;
|
||||
|
||||
$wordpress_bookings_remote = new wordpress_bookings_remote();
|
||||
|
||||
// Get the last wash ID from the remote API.
|
||||
$last_wash_id = $wordpress_bookings_remote->get_last_wash_id();
|
||||
|
||||
if (empty($last_wash_id)) {
|
||||
warn("Failed to fetch the last wash ID");
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\nLast wash ID fetched successfully from the remote API\n";
|
||||
echo "\nLast wash ID: $last_wash_id\n";
|
||||
|
||||
// Get all wash IDs from the remote API.
|
||||
$wash_ids = $wordpress_bookings_remote->get_all_wash_ids()['data']['all_wash_ids'];
|
||||
|
||||
if (empty($wash_ids)) {
|
||||
warn("Failed to fetch wash IDs");
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\nWash IDs fetched successfully from the remote API\n";
|
||||
echo "\nWash IDs: (count: " . count($wash_ids) . ")\n";
|
||||
|
||||
// Parse all bookings from the remote API.
|
||||
$bookings = $wordpress_bookings_remote->parse_bookings($wordpress_bookings_remote->get_all_bookings());
|
||||
|
||||
if (empty($bookings)) {
|
||||
warn("Failed to fetch bookings");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all bookings from the remote API.
|
||||
$bookings = $wordpress_bookings_remote->get_all_bookings();
|
||||
|
||||
if (empty($bookings)) {
|
||||
warn("Failed to fetch bookings");
|
||||
return;
|
||||
}
|
||||
|
||||
echo "\nBookings fetched successfully from the remote API\n";
|
||||
echo "\nBookings: (count: " . count($bookings['data']['all_wash_bookings']) . ")\n";
|
||||
|
||||
$booking = $wordpress_bookings_remote->parse_booking($booking_id);
|
||||
$bookings_o = new \objects\bookings_o();
|
||||
if (empty($booking)) {
|
||||
warn("Failed to fetch booking with ID $booking_id");
|
||||
} else {
|
||||
// Test if the booking has the expected keys.
|
||||
$expected_keys = [
|
||||
'id',
|
||||
'customer_number',
|
||||
'wash_type',
|
||||
'contact_email',
|
||||
'reference_number',
|
||||
'regNrTraekker',
|
||||
'regNrTrailer',
|
||||
'washCertificateEmail',
|
||||
'date',
|
||||
'department',
|
||||
'pickup_bool',
|
||||
'notes',
|
||||
'washCertificateStatus',
|
||||
'washCertificateUrl',
|
||||
'status',
|
||||
];
|
||||
|
||||
foreach ( $expected_keys as $key ) {
|
||||
if (!array_key_exists($key, $booking)) {
|
||||
warn("Booking with ID $booking_id is missing key $key");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
echo "\nBooking with ID $booking_id fetched successfully\n";
|
||||
|
||||
// Check if the booking wash certificate exists.
|
||||
$wash_certificate_store = new \classes\wash_certificate_store();
|
||||
|
||||
if (!$wash_certificate_store->washCertificateExists($booking['id'])) {
|
||||
warn("Booking with ID $booking_id does not have a wash certificate");
|
||||
} else {
|
||||
echo "\nBooking with ID $booking_id has a wash certificate\n";
|
||||
$booking['washCertificateUrl'] = 'Protected URL';
|
||||
$booking['washCertificateStatus'] = 'completed';
|
||||
// Print the booking data.
|
||||
echo "\nBooking data:\n";
|
||||
print_r($booking);
|
||||
|
||||
|
||||
// Save the booking data to database.
|
||||
$bookings_o->addOrUpdate(
|
||||
$booking['id'],
|
||||
$booking['customer_number'],
|
||||
$booking['wash_type'],
|
||||
$booking['contact_email'],
|
||||
$booking['reference_number'],
|
||||
$booking['regNrTraekker'],
|
||||
$booking['regNrTrailer'],
|
||||
$booking['washCertificateEmail'],
|
||||
$booking['date'],
|
||||
$booking['department'],
|
||||
$booking['pickup_bool'] === 'true' ? 1 : 0,
|
||||
$booking['notes'],
|
||||
$booking['washCertificateStatus'],
|
||||
$booking['washCertificateUrl'],
|
||||
$booking['status']
|
||||
);
|
||||
|
||||
echo "\nBooking data saved to database\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo "\nSyncing bookings to the remote API... This may take a while\n";
|
||||
|
||||
// Sync all bookings to the remote API.
|
||||
$start = microtime(true);
|
||||
$sync = $bookings_o->syncBookings();
|
||||
$end = microtime(true);
|
||||
|
||||
echo "\nBookings synced to the remote API\n";
|
||||
echo "\nTime taken: " . ($end - $start) . " seconds\n";
|
||||
echo "\nTime per booking: " . (($end - $start) / count($bookings['data']['all_wash_bookings'])) . " seconds\n";
|
||||
echo "\nSync: \n";
|
||||
print_r($sync);
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace traits;
|
||||
|
||||
trait wordpress_api_object_t
|
||||
{
|
||||
protected string $API_URL; // The URL of the WordPress API
|
||||
protected string $API_KEY; // The key of the WordPress API
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->wordpress_api_object_t_construct();
|
||||
}
|
||||
|
||||
public function wordpress_api_object_t_construct(): void
|
||||
{
|
||||
global $EMAIL_WASH_CERTIFICATE_TOKEN, $WORDPRESS_API_URL;
|
||||
// Make sure the WordPress API configuration is set
|
||||
if (!isset($EMAIL_WASH_CERTIFICATE_TOKEN) || !isset($WORDPRESS_API_URL)) {
|
||||
throw new \Exception('WordPress API configuration is not set');
|
||||
}
|
||||
// Apply the WordPress API configuration
|
||||
$this->API_KEY = $EMAIL_WASH_CERTIFICATE_TOKEN;
|
||||
$this->API_URL = $WORDPRESS_API_URL;
|
||||
}
|
||||
|
||||
public function debug(): void
|
||||
{
|
||||
echo 'API URL: ' . $this->API_URL . '<br>';
|
||||
echo 'API KEY: ' . $this->API_KEY . '<br>';
|
||||
}
|
||||
|
||||
public function request($invoke = 'example', $data = []): array
|
||||
{
|
||||
// Add the auth_key to the data
|
||||
$data['auth_key'] = $this->API_KEY;
|
||||
$data['invoke'] = $invoke;
|
||||
$data['action'] = 'twc_api_endpoints';
|
||||
// Send a post request to the API
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $this->API_URL);
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
$response = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
// Check if the response is an error
|
||||
if ($response === false) {
|
||||
return ['error' => 'Curl error: ' . curl_error($ch)];
|
||||
}
|
||||
// If the response is not JSON, return it as is
|
||||
if ($response[0] !== '{') {
|
||||
return ['response' => $response];
|
||||
}
|
||||
return json_decode($response, true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user