Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/ameliabooking/ameliabooking.php
+++ b/ameliabooking/ameliabooking.php
@@ -3,7 +3,7 @@
Plugin Name: Amelia
Plugin URI: https://wpamelia.com/
Description: Amelia is a simple yet powerful automated booking specialist, working 24/7 to make sure your customers can make appointments and events even while you sleep!
-Version: 2.1.2
+Version: 2.3
Author: Melograno Ventures
Author URI: https://melograno.io/
Text Domain: ameliabooking
@@ -35,6 +35,8 @@
use AmeliaBookingInfrastructureWPUserRolesUserRoles;
use AmeliaBookingInfrastructureWPWPMenuSubmenu;
use AmeliaBookingInfrastructureWPWPMenuSubmenuPageHandler;
+use AmeliaBookingInfrastructureWPCompatibilityLiteSpeedCacheCompatibility;
+use AmeliaBookingInfrastructureWPWPMenuAdminBarMenu;
use Exception;
use SlimApp;
use AmeliaBookingInfrastructureLicence;
@@ -54,13 +56,13 @@
// Const for uploads path
if (!defined('AMELIA_UPLOADS_PATH')) {
$uploadDir = wp_upload_dir();
- define('AMELIA_UPLOADS_PATH', $uploadDir['basedir']);
+ define('AMELIA_UPLOADS_PATH', !empty($uploadDir['basedir']) ? $uploadDir['basedir'] : '');
}
// Const for uploads url
if (!defined('AMELIA_UPLOADS_URL')) {
$uploadUrl = wp_upload_dir();
- define('AMELIA_UPLOADS_URL', set_url_scheme($uploadUrl['baseurl']));
+ define('AMELIA_UPLOADS_URL', !empty($uploadUrl['baseurl']) ? set_url_scheme($uploadUrl['baseurl']) : '');
}
// Const for uploads url
@@ -109,7 +111,7 @@
// Const for Amelia version
if (!defined('AMELIA_VERSION')) {
- define('AMELIA_VERSION', '2.1.2');
+ define('AMELIA_VERSION', '2.3');
}
// Const for site URL
@@ -214,6 +216,9 @@
{
$settingsService = new SettingsService(new SettingsStorage());
+ // Initialize LiteSpeed Cache compatibility
+ LiteSpeedCacheCompatibility::init();
+
self::weglotConflict($settingsService, true);
load_plugin_textdomain(AMELIA_DOMAIN, false, plugin_basename(__DIR__) . '/languages/' . AMELIA_LOCALE . '/');
@@ -257,6 +262,14 @@
$ameliaRole = UserRoles::getUserAmeliaRole(wp_get_current_user());
+ // Register Gutenberg blocks for rendering on frontend (works for all users, logged in or not)
+ AmeliaStepBookingGutenbergBlock::init();
+ AmeliaCatalogBookingGutenbergBlock::init();
+ AmeliaBookingGutenbergBlock::init();
+ AmeliaCatalogGutenbergBlock::init();
+ AmeliaEventsGutenbergBlock::init();
+ AmeliaEventsListBookingGutenbergBlock::init();
+
// Init menu if user is logged in with amelia role
if (in_array($ameliaRole, ['admin', 'manager', 'provider', 'customer'])) {
if ($ameliaRole === 'admin') {
@@ -266,15 +279,6 @@
// Add TinyMCE button for shortcode generator
ButtonService::renderButton();
- // Add Gutenberg Block for shortcode generator
- AmeliaStepBookingGutenbergBlock::init();
- AmeliaCatalogBookingGutenbergBlock::init();
- AmeliaBookingGutenbergBlock::init();
- AmeliaCatalogGutenbergBlock::init();
- AmeliaEventsGutenbergBlock::init();
- AmeliaEventsListBookingGutenbergBlock::init();
-
-
add_filter('block_categories_all', array('AmeliaBookingPlugin', 'addAmeliaBlockCategory'), 10, 2);
add_filter('learn-press/frontend-default-scripts', array('AmeliaBookingPlugin', 'learnPressConflict'));
}
@@ -415,6 +419,16 @@
$wpMenu->addOptionsPages();
}
+ public static function initAdminBar()
+ {
+ $settingsService = new SettingsService(new SettingsStorage());
+
+ add_action('admin_bar_menu', function ($wpAdminBar) use ($settingsService) {
+ $adminBarMenu = new AdminBarMenu($settingsService);
+ $adminBarMenu->addAdminBarMenu($wpAdminBar);
+ }, 100);
+ }
+
public static function adminInit()
{
$settingsService = new SettingsService(new SettingsStorage());
@@ -605,7 +619,18 @@
];
if (LicenceLicence::getLicence() === LicenceConstants::LITE) {
- $links[] = '<a href="https://wpamelia.com/pricing/?utm_source=wp_org&utm_medium=wp_org&utm_content=plugin_row&utm_campaign=wp_org" style="color: #5951F6; font-weight: bold;" target="_blank">Get Amelia Pro</a>';
+ $deactivate = [];
+ if (isset($links['deactivate'])) {
+ $deactivate = ['deactivate' => $links['deactivate']];
+ unset($links['deactivate']);
+ }
+
+ return array_merge(
+ $primaryLinks,
+ $links,
+ ['<a href="https://wpamelia.com/pricing/?utm_source=wp_org&utm_medium=wp_org&utm_content=plugin_row&utm_campaign=wp_org" style="color: #5951F6; font-weight: bold;" target="_blank">Get Amelia Pro</a>'],
+ $deactivate
+ );
}
return array_merge($primaryLinks, $links);
@@ -667,6 +692,9 @@
/** Init the plugin */
add_action('plugins_loaded', array('AmeliaBookingPlugin', 'init'));
+add_action('init', array('AmeliaBookingInfrastructureWPWPMenuAdminBarMenu', 'enqueueScripts'));
+add_action('init', array('AmeliaBookingPlugin', 'initAdminBar'));
+
add_action('admin_init', array('AmeliaBookingPlugin', 'adminInit'));
add_action('admin_menu', array('AmeliaBookingPlugin', 'initMenu'));
--- a/ameliabooking/extensions/divi_5_amelia/server/AmeliaEventsListModule.php
+++ b/ameliabooking/extensions/divi_5_amelia/server/AmeliaEventsListModule.php
@@ -63,6 +63,25 @@
$shortcode .= ' event=' . implode(',', $event);
}
+ $event_to_show = $attrs['event_to_show']['innerContent']['desktop']['value'] ?? 'all';
+ if (count($event) === 0 && $event_to_show !== 'all') {
+ if ($event_to_show === 'custom') {
+ $start_date = $attrs['start_date']['innerContent']['desktop']['value'] ?? '';
+ $end_date = $attrs['end_date']['innerContent']['desktop']['value'] ?? '';
+
+ $has_valid_start = $start_date && preg_match('/^d{4}-d{2}-d{2}$/', $start_date);
+ $has_valid_end = $end_date && preg_match('/^d{4}-d{2}-d{2}$/', $end_date);
+
+ if (!$has_valid_start || !$has_valid_end) {
+ return '';
+ }
+
+ $shortcode .= ' range="' . esc_attr($start_date) . ' - ' . esc_attr($end_date) . '"';
+ } else {
+ $shortcode .= ' range="' . esc_attr($event_to_show) . '"';
+ }
+ }
+
$tag = $attrs['tags']['innerContent']['desktop']['value'] ?? [];
if ($tag && count($tag) > 0) {
$shortcode .= ' tag="' . implode(',', array_map(function ($t) {
--- a/ameliabooking/extensions/divi_amelia/includes/modules/EventsList/EventsList.php
+++ b/ameliabooking/extensions/divi_amelia/includes/modules/EventsList/EventsList.php
@@ -71,6 +71,42 @@
'toggle_slug' => 'main_content',
'option_category' => 'basic_option',
),
+ 'event_to_show' => array(
+ 'label' => esc_html__(BackendStrings::get('event_time_scope'), 'divi-divi_amelia'),
+ 'type' => 'select',
+ 'options' => array(
+ 'all' => BackendStrings::get('all_events'),
+ 'future' => BackendStrings::get('future_events'),
+ 'past' => BackendStrings::get('past_events'),
+ 'custom' => BackendStrings::get('custom_range'),
+ ),
+ 'default' => 'all',
+ 'toggle_slug' => 'main_content',
+ 'option_category' => 'basic_option',
+ 'show_if' => array(
+ 'booking_params' => 'on',
+ ),
+ ),
+ 'start_date' => array(
+ 'label' => esc_html__(BackendStrings::get('red_start_date'), 'divi-divi_amelia'),
+ 'type' => 'amelia_date_picker',
+ 'toggle_slug' => 'main_content',
+ 'option_category' => 'basic_option',
+ 'show_if' => array(
+ 'booking_params' => 'on',
+ 'event_to_show' => 'custom',
+ ),
+ ),
+ 'end_date' => array(
+ 'label' => esc_html__(BackendStrings::get('red_end_date'), 'divi-divi_amelia'),
+ 'type' => 'amelia_date_picker',
+ 'toggle_slug' => 'main_content',
+ 'option_category' => 'basic_option',
+ 'show_if' => array(
+ 'booking_params' => 'on',
+ 'event_to_show' => 'custom',
+ ),
+ ),
'events' => array(
'label' => esc_html__(BackendStrings::get('select_event'), 'divi-divi_amelia'),
'type' => 'amelia_multi_select',
@@ -184,6 +220,26 @@
}
if ($preselect === 'on') {
$event = $this->checkValues($this->props['events']);
+
+ // Add event_to_show range logic (only if no specific event is selected)
+ if (empty($event) && !empty($this->props['event_to_show']) && $this->props['event_to_show'] !== 'all') {
+ if ($this->props['event_to_show'] === 'custom') {
+ $startDate = !empty($this->props['start_date']) ? $this->props['start_date'] : '';
+ $endDate = !empty($this->props['end_date']) ? $this->props['end_date'] : '';
+
+ $has_valid_start = $startDate && preg_match('/^d{4}-d{2}-d{2}$/', $startDate);
+ $has_valid_end = $endDate && preg_match('/^d{4}-d{2}-d{2}$/', $endDate);
+
+ if (!$has_valid_start || !$has_valid_end) {
+ return '';
+ }
+
+ $shortcode .= ' range="' . $startDate . ' - ' . $endDate . '"';
+ } else {
+ $shortcode .= ' range="' . $this->props['event_to_show'] . '"';
+ }
+ }
+
$tag = $this->props['tags'];
if ($event && count($event) > 0) {
$shortcode .= ' event=' . implode(',', $event);
--- a/ameliabooking/src/Application/Commands/Bookable/Category/GetCategoryDeleteEffectCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Bookable/Category/GetCategoryDeleteEffectCommandHandler.php
@@ -10,9 +10,9 @@
use AmeliaBookingApplicationCommandsCommandResult;
use AmeliaBookingApplicationCommandsCommandHandler;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
+use AmeliaBookingInfrastructureRepositoryBookableServicePackageRepository;
use AmeliaBookingInfrastructureRepositoryBookableServiceServiceRepository;
use AmeliaBookingDomainCollectionCollection;
-use InteropContainerExceptionContainerException;
use SlimExceptionContainerValueNotFoundException;
/**
@@ -29,7 +29,6 @@
* @throws ContainerValueNotFoundException
* @throws AccessDeniedException
* @throws QueryExecutionException
- * @throws ContainerException
* @throws InvalidArgumentException
*/
public function handle(GetCategoryDeleteEffectCommand $command)
@@ -46,6 +45,9 @@
/** @var ServiceRepository $serviceRepository */
$serviceRepository = $this->getContainer()->get('domain.bookable.service.repository');
+ /** @var PackageRepository $packageRepository */
+ $packageRepository = $this->container->get('domain.bookable.package.repository');
+
/** @var Collection $services */
$services = $serviceRepository->getByCriteria(['categories' => [$command->getArg('id')]]);
@@ -73,11 +75,18 @@
}
}
+ /** @var Collection $packages */
+ $packages = $services->length() ? $packageRepository->getByCriteria(['services' => $services->keys()]) : new Collection();
+
+ if ($packages->length()) {
+ $messageKey = 'red_category_failed_to_be_deleted';
+ }
+
$result->setResult(CommandResult::RESULT_SUCCESS);
$result->setMessage('Successfully retrieved message.');
$result->setData(
[
- 'valid' => !($categoryServiceIds && ($appointmentsCount['futureAppointments'] || $appointmentsCount['packageAppointments'])),
+ 'valid' => !($categoryServiceIds && ($appointmentsCount['futureAppointments'] || $appointmentsCount['packageAppointments'])),
'messageKey' => $messageKey,
'messageData' => $messageData,
]
--- a/ameliabooking/src/Application/Commands/Bookable/Service/DeleteServiceCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Bookable/Service/DeleteServiceCommandHandler.php
@@ -11,12 +11,13 @@
use AmeliaBookingApplicationCommandsCommandResult;
use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
use AmeliaBookingApplicationServicesBookableBookableApplicationService;
+use AmeliaBookingDomainCollectionCollection;
use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
use AmeliaBookingDomainEntityBookableServiceService;
use AmeliaBookingDomainEntityEntities;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
+use AmeliaBookingInfrastructureRepositoryBookableServicePackageRepository;
use AmeliaBookingInfrastructureRepositoryBookableServiceServiceRepository;
-use InteropContainerExceptionContainerException;
use SlimExceptionContainerValueNotFoundException;
/**
@@ -34,7 +35,6 @@
* @throws InvalidArgumentException
* @throws QueryExecutionException
* @throws AccessDeniedException
- * @throws ContainerException
*/
public function handle(DeleteServiceCommand $command)
{
@@ -51,15 +51,21 @@
$appointmentsCount = $bookableApplicationService->getAppointmentsCountForServices([$command->getArg('id')]);
- /** @var ServiceRepository $serviceRepository */
- $serviceRepository = $this->container->get('domain.bookable.service.repository');
+ if ($appointmentsCount['futureAppointments']) {
+ $result->setResult(CommandResult::RESULT_CONFLICT);
+ $result->setMessage('Could not delete service.');
+ $result->setData([]);
- /** @var Service $service */
- $service = $serviceRepository->getByCriteria(
- ['services' => [$command->getArg('id')]]
- )->getItem($command->getArg('id'));
+ return $result;
+ }
- if ($appointmentsCount['futureAppointments']) {
+ /** @var PackageRepository $packageRepository */
+ $packageRepository = $this->container->get('domain.bookable.package.repository');
+
+ /** @var Collection $packages */
+ $packages = $packageRepository->getByCriteria(['services' => [$command->getArg('id')]]);
+
+ if ($packages->length()) {
$result->setResult(CommandResult::RESULT_CONFLICT);
$result->setMessage('Could not delete service.');
$result->setData([]);
@@ -67,6 +73,14 @@
return $result;
}
+ /** @var ServiceRepository $serviceRepository */
+ $serviceRepository = $this->container->get('domain.bookable.service.repository');
+
+ /** @var Service $service */
+ $service = $serviceRepository->getByCriteria(
+ ['services' => [$command->getArg('id')]]
+ )->getItem($command->getArg('id'));
+
$serviceRepository->beginTransaction();
do_action('amelia_before_service_deleted', $service->toArray());
--- a/ameliabooking/src/Application/Commands/Bookable/Service/GetServiceDeleteEffectCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Bookable/Service/GetServiceDeleteEffectCommandHandler.php
@@ -4,12 +4,13 @@
use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
use AmeliaBookingApplicationServicesBookableBookableApplicationService;
+use AmeliaBookingDomainCollectionCollection;
use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
use AmeliaBookingDomainEntityEntities;
use AmeliaBookingApplicationCommandsCommandResult;
use AmeliaBookingApplicationCommandsCommandHandler;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
-use InteropContainerExceptionContainerException;
+use AmeliaBookingInfrastructureRepositoryBookableServicePackageRepository;
use SlimExceptionContainerValueNotFoundException;
/**
@@ -26,7 +27,6 @@
* @throws ContainerValueNotFoundException
* @throws AccessDeniedException
* @throws QueryExecutionException
- * @throws ContainerException
* @throws InvalidArgumentException
*/
public function handle(GetServiceDeleteEffectCommand $command)
@@ -37,6 +37,9 @@
$result = new CommandResult();
+ /** @var PackageRepository $packageRepository */
+ $packageRepository = $this->container->get('domain.bookable.package.repository');
+
/** @var BookableApplicationService $bookableAS */
$bookableAS = $this->getContainer()->get('application.bookable.service');
@@ -55,11 +58,18 @@
$messageData = ['count' => $appointmentsCount['pastAppointments']];
}
+ /** @var Collection $packages */
+ $packages = $packageRepository->getByCriteria(['services' => [$command->getArg('id')]]);
+
+ if ($packages->length()) {
+ $messageKey = 'red_service_failed_to_be_deleted';
+ }
+
$result->setResult(CommandResult::RESULT_SUCCESS);
$result->setMessage('Successfully retrieved message.');
$result->setData(
[
- 'valid' => $appointmentsCount['futureAppointments'] ? false : true,
+ 'valid' => !$appointmentsCount['futureAppointments'] && !$packages->length(),
'messageKey' => $messageKey,
'messageData' => $messageData,
]
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/AddAppointmentCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/AddAppointmentCommandHandler.php
@@ -16,6 +16,7 @@
use AmeliaBookingDomainEntityBookableServiceService;
use AmeliaBookingDomainEntityBookingAppointmentAppointment;
use AmeliaBookingDomainEntityBookingAppointmentCustomerBooking;
+use AmeliaBookingDomainEntityCouponCoupon;
use AmeliaBookingDomainEntityEntities;
use AmeliaBookingDomainEntityPaymentPayment;
use AmeliaBookingDomainEntityUserAbstractUser;
@@ -27,6 +28,7 @@
use AmeliaBookingInfrastructureCommonExceptionsNotFoundException;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
use AmeliaBookingInfrastructureRepositoryBookingAppointmentAppointmentRepository;
+use AmeliaBookingInfrastructureRepositoryCouponCouponRepository;
use Exception;
use InteropContainerExceptionContainerException;
use SlimExceptionContainerValueNotFoundException;
@@ -124,10 +126,24 @@
$maxDuration = 0;
- foreach ($appointmentData['bookings'] as $booking) {
+ foreach ($appointmentData['bookings'] as $key => $booking) {
if ($booking['duration'] > $maxDuration && ($booking['status'] === BookingStatus::APPROVED || BookingStatus::PENDING)) {
$maxDuration = $booking['duration'];
}
+
+ $couponId = !empty($booking['coupon']['id'])
+ ? $booking['coupon']['id']
+ : (!empty($booking['couponId']) ? $booking['couponId'] : null);
+
+ if ($couponId) {
+ /** @var CouponRepository $couponRepository */
+ $couponRepository = $this->getContainer()->get('domain.coupon.repository');
+
+ /** @var Coupon $coupon */
+ $coupon = $couponRepository->getById($couponId);
+
+ $appointmentData['bookings'][$key]['coupon'] = $coupon ? $coupon->toArray() : null;
+ }
}
if ($maxDuration) {
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/ApproveBookingRemotelyCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/ApproveBookingRemotelyCommandHandler.php
@@ -94,10 +94,7 @@
$booking->setToken(new Token($token['token']));
- if (
- $booking->getStatus()->getValue() !== BookingStatus::WAITING &&
- !$customerAS->isCustomerBooking($booking, $user, $command->getField('token'))
- ) {
+ if (!$customerAS->isCustomerBooking($booking, $user, $command->getField('token'))) {
throw new AccessDeniedException('You are not allowed to update booking status');
}
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/GetAppointmentBookingsCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/GetAppointmentBookingsCommandHandler.php
@@ -212,7 +212,9 @@
$customersNoShowCountIds[] = $booking->getCustomerId()->getValue();
}
- $bookedSpots += $booking->getPersons()->getValue();
+ if (in_array($booking->getStatus()->getValue(), ['approved', 'pending'], true)) {
+ $bookedSpots += $booking->getPersons()->getValue();
+ }
$bookings[] = [
'id' => $booking->getId()->getValue(),
@@ -227,6 +229,8 @@
),
'status' => $paymentAS->getFullStatus($booking->toArray(), 'appointment'),
],
+ 'created' => $booking->getCreated() ?
+ $booking->getCreated()->getValue()->format('Y-m-d') : null,
];
$isPackageAppointment = !empty($booking->getPackageCustomerService());
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/GetPackageAppointmentsCommand.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/GetPackageAppointmentsCommand.php
@@ -1,14 +0,0 @@
-<?php
-
-namespace AmeliaBookingApplicationCommandsBookingAppointment;
-
-use AmeliaBookingApplicationCommandsCommand;
-
-/**
- * Class GetPackageAppointmentsCommand
- *
- * @package AmeliaBookingApplicationCommandsBookingAppointment
- */
-class GetPackageAppointmentsCommand extends Command
-{
-}
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/GetPackageAppointmentsCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/GetPackageAppointmentsCommandHandler.php
@@ -1,282 +0,0 @@
-<?php
-
-namespace AmeliaBookingApplicationCommandsBookingAppointment;
-
-use AmeliaBookingApplicationCommandsCommandHandler;
-use AmeliaBookingApplicationCommandsCommandResult;
-use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
-use AmeliaBookingApplicationServicesBookableAbstractPackageApplicationService;
-use AmeliaBookingApplicationServicesBookingAppointmentApplicationService;
-use AmeliaBookingApplicationServicesBookingBookingApplicationService;
-use AmeliaBookingDomainCollectionCollection;
-use AmeliaBookingDomainCommonExceptionsAuthorizationException;
-use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
-use AmeliaBookingDomainEntityBookableServiceService;
-use AmeliaBookingDomainEntityBookingAppointmentAppointment;
-use AmeliaBookingDomainEntityBookingAppointmentCustomerBooking;
-use AmeliaBookingDomainEntityEntities;
-use AmeliaBookingDomainEntityUserAbstractUser;
-use AmeliaBookingDomainServicesDateTimeDateTimeService;
-use AmeliaBookingDomainServicesSettingsSettingsService;
-use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
-use AmeliaBookingInfrastructureRepositoryBookableServicePackageCustomerRepository;
-use AmeliaBookingInfrastructureRepositoryBookableServiceServiceRepository;
-use AmeliaBookingInfrastructureRepositoryBookingAppointmentCustomerBookingRepository;
-
-/**
- * Class GetPackageAppointmentsCommandHandler
- *
- * @package AmeliaBookingApplicationCommandsBookingAppointment
- */
-class GetPackageAppointmentsCommandHandler extends CommandHandler
-{
- /**
- * @param GetPackageAppointmentsCommand $command
- *
- * @return CommandResult
- *
- * @throws InvalidArgumentException
- * @throws QueryExecutionException
- * @throws AccessDeniedException
- */
- public function handle(GetPackageAppointmentsCommand $command)
- {
- $result = new CommandResult();
-
- /** @var ServiceRepository $serviceRepository */
- $serviceRepository = $this->container->get('domain.bookable.service.repository');
-
- /** @var PackageCustomerRepository $packageCustomerRepository */
- $packageCustomerRepository = $this->container->get('domain.bookable.packageCustomer.repository');
-
- /** @var AbstractPackageApplicationService $packageAS */
- $packageAS = $this->container->get('application.bookable.package');
-
- /** @var SettingsService $settingsDS */
- $settingsDS = $this->container->get('domain.settings.service');
-
- /** @var BookingApplicationService $bookingAS */
- $bookingAS = $this->container->get('application.booking.booking.service');
-
- /** @var AppointmentApplicationService $appointmentAS */
- $appointmentAS = $this->container->get('application.booking.appointment.service');
-
- try {
- /** @var AbstractUser $user */
- $user = $command->getUserApplicationService()->authorization(null, $command->getCabinetType());
- } catch (AuthorizationException $e) {
- $result->setResult(CommandResult::RESULT_ERROR);
- $result->setData(
- [
- 'reauthorize' => true
- ]
- );
-
- return $result;
- }
-
- $params = $command->getField('params');
-
- if ($user && $user->getType() === Entities::PROVIDER) {
- $params['providers'] = [$user->getId()->getValue()];
- }
-
- if ($user && $user->getType() === Entities::CUSTOMER) {
- $params['customers'] = [$user->getId()->getValue()];
- }
-
- if (!empty($params['dates'])) {
- !empty($params['dates'][0]) ? $params['dates'][0] .= ' 00:00:00' : null;
- !empty($params['dates'][1]) ? $params['dates'][1] .= ' 23:59:59' : null;
- }
-
- $availablePackageBookings = [];
-
- $packageCustomerIds = [];
-
- $noResultsManagePackagesFilters = false;
-
- $totalPackagePurchases = 0;
-
- $customers = isset($params['customerId']) ? [$params['customerId']] : [];
-
- if (!empty($params['packageStatus']) || !empty($params['page']) || !empty($params['bookingsCount'])) {
- $packageCustomerIds = $packageCustomerRepository->getFilteredIds(
- [
- 'dates' => !empty($params['dates']) ? $params['dates'] : [],
- 'packages' => !empty($params['packageId']) ? [$params['packageId']] : [],
- 'page' => !empty($params['page']) ? $params['page'] : null,
- 'status' => !empty($params['packageStatus']) ? $params['packageStatus'] : null,
- 'customers' => $customers,
- ],
- $settingsDS->getSetting('general', 'itemsPerPage')
- );
-
- $noResultsManagePackagesFilters = !$packageCustomerIds;
-
- $totalPackagePurchases = sizeof($packageCustomerRepository->getFilteredIds(
- [
- 'packageCustomerIds' => $packageCustomerIds ?: [],
- 'purchased' => !empty($params['dates']) ? $params['dates'] : [],
- 'packages' => !empty($params['packageId']) ? [$params['packageId']] : [],
- 'packageStatus' => !empty($params['packageStatus']) ? $params['packageStatus'] : null,
- 'customers' => $customers
- ]
- ));
- }
-
- /**
- * @var Collection $appointments
- */
- $appointments = new Collection();
-
- if (isset($params['customerId'])) {
- unset($params['customerId']);
- }
-
- $customersNoShowCountIds = [];
-
- $noShowTagEnabled = $settingsDS->isFeatureEnabled('noShowTag');
-
- if (!$noResultsManagePackagesFilters) {
- $availablePackageBookings = $packageAS->getPackageAvailability(
- $appointments,
- [
- 'packageCustomerIds' => !empty($packageCustomerIds) ? $packageCustomerIds : [],
- 'purchased' => !empty($params['dates']) ? $params['dates'] : [],
- 'customers' => $customers,
- 'packageId' => !empty($params['packageId']) ? (int)$params['packageId'] : null,
- 'managePackagePage' => true
- ]
- );
-
- if ($noShowTagEnabled && !!$availablePackageBookings) {
- $customersNoShowCountIds[] = $availablePackageBookings[0]['customerId'];
- }
- }
-
- /** @var Collection $services */
- $services = $serviceRepository->getAllArrayIndexedById();
-
- $packageAS->setPackageBookingsForAppointments($appointments);
-
- $occupiedTimes = [];
-
- $currentDateTime = DateTimeService::getNowDateTimeObject();
-
- $groupedAppointments = [];
-
- /** @var Appointment $appointment */
- foreach ($appointments->getItems() as $appointment) {
- /** @var Service $service */
- $service = $services->getItem($appointment->getServiceId()->getValue());
-
- $bookingsCount = 0;
-
- /** @var CustomerBooking $booking */
- foreach ($appointment->getBookings()->getItems() as $booking) {
- // fix for wrongly saved JSON
- if (
- $booking->getCustomFields() &&
- json_decode($booking->getCustomFields()->getValue(), true) === null
- ) {
- $booking->setCustomFields(null);
- }
-
- if ($bookingAS->isBookingApprovedOrPending($booking->getStatus()->getValue())) {
- $bookingsCount++;
- }
-
- if ($noShowTagEnabled && !in_array($booking->getCustomerId()->getValue(), $customersNoShowCountIds)) {
- $customersNoShowCountIds[] = $booking->getCustomerId()->getValue();
- }
- }
-
- $appointmentAS->calculateAndSetAppointmentEnd($appointment, $service);
-
- $minimumCancelTimeInSeconds = $settingsDS
- ->getEntitySettings($service->getSettings())
- ->getGeneralSettings()
- ->getMinimumTimeRequirementPriorToCanceling();
-
- $minimumCancelTime = DateTimeService::getCustomDateTimeObject(
- $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s')
- )->modify("-{$minimumCancelTimeInSeconds} seconds");
-
- $date = $appointment->getBookingStart()->getValue()->format('Y-m-d');
-
- $cancelable = $currentDateTime <= $minimumCancelTime;
-
- $minimumRescheduleTimeInSeconds = $settingsDS
- ->getEntitySettings($service->getSettings())
- ->getGeneralSettings()
- ->getMinimumTimeRequirementPriorToRescheduling();
-
- $minimumRescheduleTime = DateTimeService::getCustomDateTimeObject(
- $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s')
- )->modify("-{$minimumRescheduleTimeInSeconds} seconds");
-
- $reschedulable = $currentDateTime <= $minimumRescheduleTime;
-
- $groupedAppointments[$date]['date'] = $date;
-
- $groupedAppointments[$date]['appointments'][] = array_merge(
- $appointment->toArray(),
- [
- 'cancelable' => $cancelable,
- 'reschedulable' => $reschedulable,
- 'past' => $currentDateTime >= $appointment->getBookingStart()->getValue()
- ]
- );
- }
-
- $emptyBookedPackages = null;
-
- if (
- !empty($params['packageId']) &&
- empty($params['services']) &&
- empty($params['providers']) &&
- empty($params['locations']) &&
- !$noResultsManagePackagesFilters
- ) {
- /** @var AbstractPackageApplicationService $packageApplicationService */
- $packageApplicationService = $this->container->get('application.bookable.package');
-
- /** @var Collection $emptyBookedPackages */
- $emptyBookedPackages = $packageApplicationService->getEmptyPackages(
- [
- 'packageCustomerIds' => !empty($packageCustomerIds) ? $packageCustomerIds : [],
- 'packages' => [$params['packageId']],
- 'purchased' => !empty($params['dates']) ? $params['dates'] : [],
- 'customers' => $customers
- ]
- );
- }
-
- $customersNoShowCount = [];
-
- if ($noShowTagEnabled && $customersNoShowCountIds) {
- /** @var CustomerBookingRepository $bookingRepository */
- $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
-
- $customersNoShowCount = $bookingRepository->countByNoShowStatus($customersNoShowCountIds);
- }
-
-
- $result->setResult(CommandResult::RESULT_SUCCESS);
- $result->setMessage('Successfully retrieved appointments');
- $result->setData(
- [
- Entities::APPOINTMENTS =>
- !empty($params['asArray']) && filter_var($params['asArray'], FILTER_VALIDATE_BOOLEAN) ? $appointments->toArray() : $groupedAppointments,
- 'availablePackageBookings' => $availablePackageBookings,
- 'emptyPackageBookings' => !empty($emptyBookedPackages) ? $emptyBookedPackages->toArray() : [],
- 'occupied' => $occupiedTimes,
- 'totalPackagePurchases' => $totalPackagePurchases,
- 'customersNoShowCount' => $customersNoShowCount
- ]
- );
-
- return $result;
- }
-}
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/ReassignBookingCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/ReassignBookingCommandHandler.php
@@ -616,6 +616,8 @@
$oldAppointment->getStatus()->getValue()
);
+ $newAppointment->setInternalNotes(new Description(''));
+
$newAppointmentId = $appointmentRepository->add($newAppointment);
$newAppointment->setId(new Id($newAppointmentId));
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentCommandHandler.php
@@ -13,7 +13,6 @@
use AmeliaBookingApplicationServicesPaymentPaymentApplicationService;
use AmeliaBookingApplicationServicesReservationAppointmentReservationService;
use AmeliaBookingApplicationServicesUserUserApplicationService;
-use AmeliaBookingApplicationServicesZoomAbstractZoomApplicationService;
use AmeliaBookingDomainCollectionCollection;
use AmeliaBookingDomainCommonExceptionsAuthorizationException;
use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
@@ -35,6 +34,7 @@
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
use AmeliaBookingInfrastructureRepositoryBookingAppointmentAppointmentRepository;
use AmeliaBookingInfrastructureRepositoryBookingAppointmentCustomerBookingRepository;
+use AmeliaBookingInfrastructureRepositoryPaymentPaymentRepository;
use AmeliaBookingInfrastructureRepositoryUserProviderRepository;
use AmeliaBookingInfrastructureRepositoryUserUserRepository;
use AmeliaBookingInfrastructureWPTranslationsFrontendStrings;
@@ -87,8 +87,6 @@
$bookableAS = $this->container->get('application.bookable.service');
/** @var AbstractCustomFieldApplicationService $customFieldService */
$customFieldService = $this->container->get('application.customField.service');
- /** @var AbstractZoomApplicationService $zoomService */
- $zoomService = $this->container->get('application.zoom.service');
/** @var UserApplicationService $userAS */
$userAS = $this->getContainer()->get('application.user.service');
/** @var SettingsService $settingsDS */
@@ -125,30 +123,6 @@
throw new AccessDeniedException('You are not allowed to update appointment');
}
- if (!empty($params['noteOnly'])) {
- $appointmentId = (int)$command->getField('id');
-
- $note = $command->getField('internalNotes');
-
- $oldAppointment = $appointmentRepo->getById($appointmentId);
-
- $appointmentRepo->updateFieldById($appointmentId, $note, 'internalNotes');
-
- $result->setResult(CommandResult::RESULT_SUCCESS);
- $result->setMessage('Successfully updated appointment note');
- $result->setData([
- Entities::APPOINTMENT => array_merge($oldAppointment ? $oldAppointment->toArray() : [], ['internalNotes' => $note]),
- 'appointmentStatusChanged' => false,
- 'appointmentRescheduled' => false,
- 'bookingsWithChangedStatus' => [],
- 'appointmentEmployeeChanged' => false,
- 'appointmentZoomUserChanged' => false,
- 'bookingAdded' => false
- ]);
-
- return $result;
- }
-
$this->checkMandatoryFields($command);
$appointmentData = $command->getFields();
@@ -428,6 +402,43 @@
$appointment->setChangedStatus(new BooleanValueObject(true));
}
+ /** @var PaymentRepository $paymentRepository */
+ $paymentRepository = $this->container->get('domain.payment.repository');
+
+ $bookingIds = [];
+
+ /** @var CustomerBooking $booking */
+ foreach ($appointment->getBookings()->getItems() as $booking) {
+ if ($booking->getId() && $booking->getId()->getValue()) {
+ $bookingIds[] = $booking->getId()->getValue();
+ }
+ }
+
+ if ($bookingIds) {
+ /** @var Collection $payments */
+ $payments = $paymentRepository->getByCriteria(['bookingIds' => $bookingIds]);
+
+ /** @var CustomerBooking $booking */
+ foreach ($appointment->getBookings()->getItems() as $booking) {
+ if ($booking->getId() && $booking->getId()->getValue() && !$booking->getPayments()->length()) {
+ $bookingPayments = new Collection();
+
+ foreach ($payments->getItems() as $payment) {
+ if (
+ $payment->getCustomerBookingId() &&
+ $payment->getCustomerBookingId()->getValue() === $booking->getId()->getValue()
+ ) {
+ $bookingPayments->addItem($payment, $payment->getId()->getValue());
+ }
+ }
+
+ if ($bookingPayments->length()) {
+ $booking->setPayments($bookingPayments);
+ }
+ }
+ }
+ }
+
$appointmentArray = $appointment->toArray();
$oldAppointmentArray = $oldAppointment->toArray();
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentNoteCommand.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentNoteCommand.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace AmeliaBookingApplicationCommandsBookingAppointment;
+
+use AmeliaBookingApplicationCommandsCommand;
+
+/**
+ * Class UpdateAppointmentNoteCommand
+ *
+ * @package AmeliaBookingApplicationCommandsBookingAppointment
+ */
+class UpdateAppointmentNoteCommand extends Command
+{
+}
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentNoteCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentNoteCommandHandler.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace AmeliaBookingApplicationCommandsBookingAppointment;
+
+use AmeliaBookingApplicationCommandsCommandHandler;
+use AmeliaBookingApplicationCommandsCommandResult;
+use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
+use AmeliaBookingApplicationServicesUserUserApplicationService;
+use AmeliaBookingDomainCommonExceptionsAuthorizationException;
+use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
+use AmeliaBookingDomainEntityEntities;
+use AmeliaBookingDomainEntityUserAbstractUser;
+use AmeliaBookingDomainServicesSettingsSettingsService;
+use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
+use AmeliaBookingInfrastructureRepositoryBookingAppointmentAppointmentRepository;
+
+/**
+ * Class UpdateAppointmentNoteCommandHandler
+ *
+ * @package AmeliaBookingApplicationCommandsBookingAppointment
+ */
+class UpdateAppointmentNoteCommandHandler extends CommandHandler
+{
+ /**
+ * @param UpdateAppointmentNoteCommand $command
+ *
+ * @return CommandResult
+ * @throws AccessDeniedException
+ * @throws AuthorizationException
+ * @throws InvalidArgumentException
+ * @throws QueryExecutionException
+ */
+ public function handle(UpdateAppointmentNoteCommand $command)
+ {
+ $result = new CommandResult();
+
+ /** @var UserApplicationService $userAS */
+ $userAS = $this->getContainer()->get('application.user.service');
+ /** @var SettingsService $settingsDS */
+ $settingsDS = $this->container->get('domain.settings.service');
+ /** @var AppointmentRepository $appointmentRepo */
+ $appointmentRepo = $this->container->get('domain.booking.appointment.repository');
+
+ try {
+ /** @var AbstractUser $user */
+ $user = $command->getUserApplicationService()->authorization(
+ $command->getPage() === 'cabinet' ? $command->getToken() : null,
+ $command->getCabinetType()
+ );
+ } catch (AuthorizationException $e) {
+ $result->setResult(CommandResult::RESULT_ERROR);
+ $result->setData(['reauthorize' => true]);
+
+ return $result;
+ }
+
+ if ($userAS->isCustomer($user)) {
+ throw new AccessDeniedException('You are not allowed to update appointment');
+ }
+
+ if ($userAS->isProvider($user) && !$settingsDS->getSetting('roles', 'allowWriteAppointments')) {
+ throw new AccessDeniedException('You are not allowed to update appointment');
+ }
+
+ $appointmentId = (int)$command->getArg('id');
+ $note = $command->getField('internalNotes');
+ $oldAppointment = $appointmentRepo->getById($appointmentId);
+
+ if ($oldAppointment === null) {
+ $result->setResult(CommandResult::RESULT_ERROR);
+ $result->setMessage('Appointment not found');
+ return $result;
+ }
+
+ $appointmentRepo->updateFieldById($appointmentId, $note, 'internalNotes');
+
+ $result->setResult(CommandResult::RESULT_SUCCESS);
+ $result->setMessage('Successfully updated appointment note');
+ $result->setData([
+ Entities::APPOINTMENT => array_merge(
+ $oldAppointment->toArray(),
+ ['internalNotes' => $note]
+ ),
+ ]);
+
+ return $result;
+ }
+}
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentStatusCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentStatusCommandHandler.php
@@ -150,6 +150,8 @@
$appointment->getProviderId()->getValue()
);
+ $appointment->setService($service);
+
if (
$requestedStatus === BookingStatus::APPROVED &&
(
--- a/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentTimeCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Appointment/UpdateAppointmentTimeCommandHandler.php
@@ -31,7 +31,6 @@
use AmeliaBookingInfrastructureRepositoryBookingAppointmentCustomerBookingRepository;
use AmeliaBookingInfrastructureRepositoryUserUserRepository;
use AmeliaBookingInfrastructureWPTranslationsFrontendStrings;
-use InteropContainerExceptionContainerException;
/**
* Class UpdateAppointmentTimeCommandHandler
@@ -56,7 +55,6 @@
* @throws InvalidArgumentException
* @throws QueryExecutionException
* @throws NotFoundException
- * @throws ContainerException
*/
public function handle(UpdateAppointmentTimeCommand $command)
{
@@ -129,26 +127,28 @@
}
}
- $minimumRescheduleTimeInSeconds = $settingsDS
- ->getEntitySettings($service->getSettings())
- ->getGeneralSettings()
- ->getMinimumTimeRequirementPriorToRescheduling();
-
- try {
- $reservationService->inspectMinimumCancellationTime(
- $appointment->getBookingStart()->getValue(),
- $minimumRescheduleTimeInSeconds
- );
- } catch (BookingCancellationException $e) {
- $result->setResult(CommandResult::RESULT_ERROR);
- $result->setMessage('You are not allowed to update booking');
- $result->setData(
- [
- 'rescheduleBookingUnavailable' => true
- ]
- );
+ if ($userAS->isCustomer($user)) {
+ $minimumRescheduleTimeInSeconds = $settingsDS
+ ->getEntitySettings($service->getSettings())
+ ->getGeneralSettings()
+ ->getMinimumTimeRequirementPriorToRescheduling();
+
+ try {
+ $reservationService->inspectMinimumCancellationTime(
+ $appointment->getBookingStart()->getValue(),
+ $minimumRescheduleTimeInSeconds
+ );
+ } catch (BookingCancellationException $e) {
+ $result->setResult(CommandResult::RESULT_ERROR);
+ $result->setMessage('You are not allowed to update booking');
+ $result->setData(
+ [
+ 'rescheduleBookingUnavailable' => true
+ ]
+ );
- return $result;
+ return $result;
+ }
}
$bookingStart = $command->getField('bookingStart');
@@ -231,6 +231,14 @@
$appointment->setRescheduled(new BooleanValueObject(true));
+ $appointment->setInitialBookingStart(
+ new DateTimeValue($initialBookingStart)
+ );
+
+ $appointment->setInitialBookingEnd(
+ new DateTimeValue($initialBookingEnd)
+ );
+
$bookingAS->bookingRescheduled(
$appointment->getId()->getValue(),
Entities::APPOINTMENT,
@@ -252,11 +260,7 @@
$result->setMessage('Successfully updated appointment time');
$result->setData(
[
- Entities::APPOINTMENT => $appointment->toArray(),
- 'initialAppointmentDateTime' => [
- 'bookingStart' => $initialBookingStart->format('Y-m-d H:i:s'),
- 'bookingEnd' => $initialBookingEnd->format('Y-m-d H:i:s'),
- ],
+ Entities::APPOINTMENT => $appointment->toArray(),
]
);
--- a/ameliabooking/src/Application/Commands/Booking/Event/DeleteEventBookingCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Event/DeleteEventBookingCommandHandler.php
@@ -124,6 +124,8 @@
do_action('amelia_before_event_booking_deleted', $customerBooking->toArray(), $event ? $event->toArray() : null);
if (!$eventApplicationService->deleteEventBooking($customerBooking)) {
+ $customerBookingRepository->rollback();
+
$result->setResult(CommandResult::RESULT_ERROR);
$result->setMessage('Could not delete booking');
--- a/ameliabooking/src/Application/Commands/Booking/Event/DeleteEventsCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Event/DeleteEventsCommandHandler.php
@@ -6,12 +6,13 @@
use AmeliaBookingApplicationCommandsCommandResult;
use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
use AmeliaBookingApplicationServicesBookingEventApplicationService;
-use AmeliaBookingDomainCollectionCollection;
use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
use AmeliaBookingDomainEntityEntities;
+use AmeliaBookingInfrastructureCommonExceptionsNotFoundException;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
use AmeliaBookingInfrastructureRepositoryBookingEventEventRepository;
use AmeliaBookingInfrastructureWPEventListenersBookingEventEventStatusUpdatedEventHandler;
+use MicrosoftGraphExceptionGraphException;
/**
* Class DeleteEventsCommandHandler
@@ -24,11 +25,11 @@
* @param DeleteEventsCommand $command
*
* @return CommandResult
- * @throws SlimExceptionContainerValueNotFoundException
* @throws AccessDeniedException
* @throws InvalidArgumentException
* @throws QueryExecutionException
- * @throws InteropContainerExceptionContainerException
+ * @throws NotFoundException
+ * @throws GraphException
*/
public function handle(DeleteEventsCommand $command)
{
@@ -59,12 +60,11 @@
]
);
- do_action('amelia_before_events_deleted', $events ? $events->toArray() : null);
+ do_action('amelia_before_events_deleted', $events->toArray());
$eventRepository->beginTransaction();
try {
- /** @var Collection $updatedEvents */
$updatedEvents = $eventApplicationService->updateStatus(
$events,
'rejected',
--- a/ameliabooking/src/Application/Commands/Booking/Event/GetEventBookingCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Event/GetEventBookingCommandHandler.php
@@ -197,6 +197,12 @@
'location' =>
$event->getCustomLocation() ?
['name' => $event->getCustomLocation()->getValue()] : ($event->getLocationId() ? $event->getLocation()->toArray() : null),
+ 'periods' => array_map(function ($period) {
+ return [
+ 'periodStart' => $period['periodStart'],
+ 'periodEnd' => $period['periodEnd']
+ ];
+ }, $event->getPeriods()->toArray()),
]
);
--- a/ameliabooking/src/Application/Commands/Booking/Event/GetEventBookingsCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Event/GetEventBookingsCommandHandler.php
@@ -6,9 +6,11 @@
use AmeliaBookingApplicationCommandsCommandResult;
use AmeliaBookingApplicationCommonExceptionsAccessDeniedException;
use AmeliaBookingApplicationServicesBookingEventApplicationService;
+use AmeliaBookingApplicationServicesCustomFieldAbstractCustomFieldApplicationService;
use AmeliaBookingApplicationServicesPaymentPaymentApplicationService;
use AmeliaBookingApplicationServicesUserProviderApplicationService;
use AmeliaBookingApplicationServicesUserUserApplicationService;
+use AmeliaBookingDomainCollectionCollection;
use AmeliaBookingDomainCommonExceptionsAuthorizationException;
use AmeliaBookingDomainCommonExceptionsInvalidArgumentException;
use AmeliaBookingDomainEntityBookingAppointmentCustomerBooking;
@@ -18,6 +20,7 @@
use AmeliaBookingDomainEntityEntities;
use AmeliaBookingDomainEntityUserAbstractUser;
use AmeliaBookingDomainEntityUserProvider;
+use AmeliaBookingDomainFactoryBookingAppointmentCustomerBookingFactory;
use AmeliaBookingDomainFactoryBookingEventEventFactory;
use AmeliaBookingDomainServicesDateTimeDateTimeService;
use AmeliaBookingDomainServicesSettingsSettingsService;
@@ -25,6 +28,7 @@
use AmeliaBookingDomainValueObjectsStringBookingStatus;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
use AmeliaBookingInfrastructureRepositoryBookingAppointmentCustomerBookingRepository;
+use AmeliaBookingInfrastructureRepositoryCustomFieldCustomFieldRepository;
use Exception;
/**
@@ -58,8 +62,12 @@
$eventApplicationService = $this->container->get('application.booking.event.service');
/** @var CustomerBookingRepository $bookingRepository */
$bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
+ /** @var CustomFieldRepository $customFieldRepository */
+ $customFieldRepository = $this->container->get('domain.customField.repository');
/** @var ProviderApplicationService $providerAS */
$providerAS = $this->container->get('application.user.provider.service');
+ /** @var AbstractCustomFieldApplicationService $customFieldService */
+ $customFieldService = $this->container->get('application.customField.service');
$params = $command->getField('params');
@@ -217,6 +225,7 @@
$bookings = $bookingRepository->getEventBookingsByIds(
$bookingIds,
array_merge(
+ !empty($params['sort']) ? ['sort' => $params['sort']] : [],
!empty($params['dates']) ? ['dates' => $params['dates']] : [],
[
'fetchBookingsPayments' => true,
@@ -229,6 +238,9 @@
);
+ /** @var Collection $customFieldsCollection */
+ $customFieldsCollection = $customFieldRepository->getAll([], false);
+
$customersNoShowCountIds = [];
$noShowTagEnabled = $settingsDS->isFeatureEnabled('noShowTag');
@@ -236,6 +248,8 @@
$eventBookings = [];
foreach ($bookings as &$booking) {
+ $customFields = [];
+
ksort($booking['payments']);
if ($noShowTagEnabled) {
@@ -281,6 +295,7 @@
$wcTax = 0;
$wcDiscount = 0;
+ $paid = 0;
foreach ($booking['payments'] as $payment) {
$paymentAS->addWcFields($payment);
@@ -288,8 +303,16 @@
$wcTax += !empty($payment['wcItemTaxValue']) ? $payment['wcItemTaxValue'] : 0;
$wcDiscount += !empty($payment['wcItemCouponValue']) ? $payment['wcItemCouponValue'] : 0;
+
+ $paid = $paid + $payment['amount'];
}
+ $customFields = $customFieldService->reformatCustomField(
+ CustomerBookingFactory::create($booking),
+ $customFields,
+ $customFieldsCollection
+ );
+
$eventBooking = [
'id' => $booking['id'],
'bookedSpots' => $persons,
@@ -329,10 +352,13 @@
'payment' => [
'status' => $paymentAS->getFullStatus($booking, BookableType::EVENT),
'total' => $paymentAS->calculateAppointmentPrice($booking, BookableType::EVENT) + $wcTax - $wcDiscount,
+ 'paid' => $paid,
],
+ 'customFields' => $customFields,
'payments' => array_values($booking['payments']),
'qrCodes' => !empty($booking['qrCodes']) ? $booking['qrCodes'] : null,
'cancelable' => $eventApplicationService->isCancelable(EventFactory::create($booking['event']), $user),
+ 'created' => !empty($booking['created']) ? explode(' ', $booking['created'])[0] : null,
];
if ($isCabinetPage) {
--- a/ameliabooking/src/Application/Commands/Booking/Event/GetEventCommandHandler.php
+++ b/ameliabooking/src/Application/Commands/Booking/Event/GetEventCommandHandler.php
@@ -21,7 +21,6 @@
use AmeliaBookingDomainEntityBookingEventEventTicket;
use AmeliaBookingDomainEntityEntities;
use AmeliaBookingDomainEntityUserAbstractUser;
-use AmeliaBookingDomainEntityUserProvider;
use AmeliaBookingDomainValueObjectsNumberIntegerIntegerValue;
use AmeliaBookingDomainValueObjectsStringBookingStatus;
use AmeliaBookingInfrastructureCommonExceptionsQueryExecutionException;
@@ -90,6 +89,9 @@
/** @var CustomFieldRepository $customFieldRepository */
$customFieldRepository = $this->container->get('domain.customField.repository');
+ $fetchBookings =
+ empty($command->getFields()['params']['bookings']) ||
+ filter_var($command->getFields()['params']['bookings'], FILTER_VALIDATE_BOOLEAN);
/** @var Event $event */
$event = $eventApplicationService->getEventById(
@@ -100,13 +102,14 @@
'fetchEventsTags' => empty($command->getFields()['params']['drawer']),
'fetchEventsProviders' => empty($command->getFields()['params']['drawer']),
'fetchEventsImages' => true,
- 'fetchBookings' => true,
- 'fetchBookingsTickets' => true,
- 'fetchBookingsUsers' => true,
- 'fetchBookingsPayments' => true,
- 'fetchBookingsCoupons' => true,
+ 'fetchBookings' => $fetchBookings,
+ 'fetchBookingsTickets' => $fetchBookings,
+ 'fetchBookingsUsers' => $fetchBookings,
+ 'fetchBookingsPayments' => $fetchBookings,
+ 'fetchBookingsCoupons' => $fetchBookings,
'fetchEventsOrganizer' => true,
'fetchEventsLocation' => true,
+ 'fetchOccupancy' => !$fetchBookings,
]
);
@@ -173,6 +176,15 @@
$bookingsPrice = 0;
$paidPrice = 0;
+ $customersIds = [];
+
+ /** @var CustomerBooking $booking */
+ foreach ($event->getBookings()->getItems() as $booking) {
+ $customersIds[] = $booking->getCustomerId()->getValue();
+ }
+
+ $customersNoShowCount = $customersIds ? $bookingRepository->countByNoShowStatus($customersIds) : [];
+
/** @var CustomerBooking $booking */
foreach ($event->getBookings()->getItems() as $booking) {
$customFields = [];
@@ -211,11 +223,6 @@
}
$paidPrice += $bookingPaidPrice;
- $noShowCount = $bookingRepository->countByNoShowStatus([$booking->getCustomerId()->getValue()]);
- if ($noShowCount && !empty($noShowCount[$booking->getCustomerId()->getValue()])) {
- $noShowCount = $noShowCount[$booking->getCu