Skip to content

Commit 4d31c5f

Browse files
authored
Merge pull request #1103 from sumitwebkul/gli-2054
Updated: Validations of order status changes while changing order status using bulk action
2 parents 9a08b5a + e7e8b02 commit 4d31c5f

File tree

2 files changed

+141
-130
lines changed

2 files changed

+141
-130
lines changed

classes/order/Order.php

+129
Original file line numberDiff line numberDiff line change
@@ -2688,4 +2688,133 @@ public function setWsTransactionId($transactionId)
26882688
{
26892689
$this->transaction_id = $transactionId;
26902690
}
2691+
2692+
/**
2693+
* Validate and change order status
2694+
* @return array of status, errors, has_mail_error(if order status is changes but mail error occurs while sending mail)
2695+
*/
2696+
public function ChangeOrderStatus()
2697+
{
2698+
$result = array();
2699+
$result['status'] = false;
2700+
$result['has_mail_error'] = false;
2701+
$result['errors'] = array();
2702+
$objNewOrderState = new OrderState(Tools::getValue('id_order_state'));
2703+
if (!Validate::isLoadedObject($objNewOrderState)) {
2704+
$result['errors'][] = Tools::displayError('The new order status is invalid.');
2705+
} else {
2706+
$objHotelBooking = new HotelBookingDetail();
2707+
$objCurrentOrderState = $this->getCurrentOrderState();
2708+
2709+
if ($objCurrentOrderState->id == Configuration::get('PS_OS_REFUND')) {
2710+
$result['errors'][] = Tools::displayError('Order status can not be changed once order status is set to Refunded.');
2711+
} elseif ($objCurrentOrderState->id == Configuration::get('PS_OS_CANCELED')) {
2712+
$result['errors'][] = Tools::displayError('Order status can not be changed once order status is set to Cancelled.');
2713+
} elseif (in_array($objNewOrderState->id, array (Configuration::get('PS_OS_OVERBOOKING_PAID'), Configuration::get('PS_OS_OVERBOOKING_UNPAID'), Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')))) {
2714+
if (!$objHotelBooking->getOverbookedRooms($this->id)) {
2715+
$result['errors'][] = Tools::displayError('Order status can not be changed to any overbooking status as there are no overbooked rooms in the order.');
2716+
}
2717+
} elseif ($objNewOrderState->id == Configuration::get('PS_OS_REFUND')
2718+
&& !$this->hasCompletelyRefunded(Order::ORDER_COMPLETE_REFUND_FLAG)
2719+
) {
2720+
$result['errors'][] = Tools::displayError('Order status can not be set to Refunded until all bookings in the order are completely refunded.');
2721+
} elseif ($objNewOrderState->id == Configuration::get('PS_OS_CANCELED')
2722+
&& !$this->hasCompletelyRefunded(Order::ORDER_COMPLETE_CANCELLATION_FLAG)
2723+
) {
2724+
$result['errors'][] = Tools::displayError('Order status can not be set to Cancelled until all bookings in the order are cancelled.');
2725+
} elseif ($objCurrentOrderState->id == Configuration::get('PS_OS_ERROR') && !($objNewOrderState->id == Configuration::get('PS_OS_ERROR'))) {
2726+
// All rooms must be available before changing status from Payment Error to Other status in which rooms are getting blocked again
2727+
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
2728+
foreach ($orderBookings as $orderBooking) {
2729+
// If booking is refunded then no need to check inventory
2730+
if ((OrderReturn::getOrdersReturnDetail($this->id, 0, $orderBooking['id']) && $orderBooking['is_refunded'])
2731+
|| ($orderBooking['is_cancelled'] && $orderBooking['is_refunded'])
2732+
) {
2733+
continue;
2734+
} else {
2735+
// if inventory is available for that booking
2736+
$bookingParams = array(
2737+
'date_from' => $orderBooking['date_from'],
2738+
'date_to' => $orderBooking['date_to'],
2739+
'hotel_id' => $orderBooking['id_hotel'],
2740+
'id_room_type' => $orderBooking['id_product'],
2741+
'only_search_data' => 1
2742+
);
2743+
2744+
$objHotelBookingDetail = new HotelBookingDetail($orderBooking['id']);
2745+
if ($searchRoomsInfo = $objHotelBooking->getBookingData($bookingParams)) {
2746+
if (isset($searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'])
2747+
&& $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']
2748+
) {
2749+
$availableRoomsInfo = $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'];
2750+
if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) {
2751+
// Check If room is still there in the available rooms list
2752+
if (!in_array($orderBooking['id_room'], $roomIdsAvailable)) {
2753+
$result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
2754+
2755+
break;
2756+
} else {
2757+
$objHotelBookingDetail->is_refunded = 0;
2758+
$objHotelBookingDetail->save();
2759+
}
2760+
} else {
2761+
$result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
2762+
break;
2763+
}
2764+
}
2765+
} else {
2766+
$result['errors'][] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
2767+
2768+
break;
2769+
}
2770+
}
2771+
}
2772+
}
2773+
} elseif ($objCurrentOrderState->id == $objNewOrderState->id) {
2774+
$result['errors'][] = Tools::displayError('The order has already been assigned this status.');
2775+
}
2776+
}
2777+
2778+
if (!count($result['errors'])) {
2779+
// Create new OrderHistory
2780+
$context = Context::getContext();
2781+
$history = new OrderHistory();
2782+
$history->id_order = $this->id;
2783+
$history->id_employee = (int)$context->employee->id;
2784+
2785+
$useExistingsPayment = false;
2786+
if (!$this->hasInvoice()) {
2787+
$useExistingsPayment = true;
2788+
}
2789+
$history->changeIdOrderState((int)$objNewOrderState->id, $this, $useExistingsPayment);
2790+
2791+
// Save all changes
2792+
$templateVars = array();
2793+
if ($history->add(true)) {
2794+
if (!$history->sendEmail($this, $templateVars)) {
2795+
// if an error occurred while sending an email the set has_mail_error to true
2796+
$result['has_mail_error'] = true;
2797+
$result['errors'][] = Tools::displayError('We were unable to send an email to the customer while changing order status.');
2798+
}
2799+
2800+
// synchronizes quantities if needed..
2801+
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
2802+
foreach ($this->getProducts() as $product) {
2803+
if (StockAvailable::dependsOnStock($product['product_id'])) {
2804+
StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
2805+
}
2806+
}
2807+
}
2808+
} else {
2809+
$result['errors'][] = Tools::displayError('An error occurred while changing order status.');
2810+
}
2811+
}
2812+
2813+
// if no errors then return status true
2814+
if (!count($result['errors'])) {
2815+
$result['status'] = true;
2816+
}
2817+
2818+
return $result;
2819+
}
26912820
}

controllers/admin/AdminOrdersController.php

+12-130
Original file line numberDiff line numberDiff line change
@@ -1040,28 +1040,13 @@ public function processBulkUpdateOrderStatus()
10401040
if (!Validate::isLoadedObject($order)) {
10411041
$this->errors[] = sprintf(Tools::displayError('Order #%d cannot be loaded'), $id_order);
10421042
} else {
1043-
$current_order_state = $order->getCurrentOrderState();
1044-
if ($current_order_state->id == $order_state->id) {
1045-
$this->errors[] = $this->displayWarning(sprintf('Order #%d has already been assigned this status.', $id_order));
1046-
} else {
1047-
$history = new OrderHistory();
1048-
$history->id_order = $order->id;
1049-
$history->id_employee = (int)$this->context->employee->id;
1050-
1051-
$use_existings_payment = !$order->hasInvoice();
1052-
$history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment);
1053-
1054-
$carrier = new Carrier($order->id_carrier, $order->id_lang);
1055-
$templateVars = array();
1056-
1057-
if ($history->addWithemail(true, $templateVars)) {
1058-
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
1059-
foreach ($order->getProducts() as $product) {
1060-
if (StockAvailable::dependsOnStock($product['product_id'])) {
1061-
StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
1062-
}
1063-
}
1064-
}
1043+
$result = $order->changeOrderStatus();
1044+
if (!$result['status']) {
1045+
if (isset($result['has_mail_error']) && $result['has_mail_error']) {
1046+
$this->errors[] = sprintf(
1047+
Tools::displayError('Unable to send email to the customer while changing order status for order #%d.'),
1048+
$id_order
1049+
);
10651050
} else {
10661051
$this->errors[] = sprintf(Tools::displayError('Cannot change status for order #%d.'), $id_order);
10671052
}
@@ -1070,6 +1055,7 @@ public function processBulkUpdateOrderStatus()
10701055
}
10711056
}
10721057
}
1058+
10731059
if (!count($this->errors)) {
10741060
Tools::redirectAdmin(self::$currentIndex.'&conf=4&token='.$this->token);
10751061
}
@@ -1275,115 +1261,11 @@ public function postProcess()
12751261
/* Change order status, add a new entry in order history and send an e-mail to the customer if needed */
12761262
elseif (Tools::isSubmit('submitState') && isset($order)) {
12771263
if ($this->tabAccess['edit'] === '1') {
1278-
$order_state = new OrderState(Tools::getValue('id_order_state'));
1279-
1280-
if (!Validate::isLoadedObject($order_state)) {
1281-
$this->errors[] = Tools::displayError('The new order status is invalid.');
1264+
$result = $order->changeOrderStatus();
1265+
if ($result['status']) {
1266+
Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&conf=5&vieworder&token='.$this->token);
12821267
} else {
1283-
$current_order_state = $order->getCurrentOrderState();
1284-
1285-
if ($current_order_state->id == Configuration::get('PS_OS_REFUND')) {
1286-
$this->errors[] = Tools::displayError('Order status can not be changed once order status is set to Refunded.');
1287-
} elseif ($current_order_state->id == Configuration::get('PS_OS_CANCELED')) {
1288-
$this->errors[] = Tools::displayError('Order status can not be changed once order status is set to Cancelled.');
1289-
} elseif (in_array($order_state->id, array (Configuration::get('PS_OS_OVERBOOKING_PAID'), Configuration::get('PS_OS_OVERBOOKING_UNPAID'), Configuration::get('PS_OS_OVERBOOKING_PARTIAL_PAID')))) {
1290-
$objHotelBooking = new HotelBookingDetail();
1291-
if (!$objHotelBooking->getOverbookedRooms($order->id)) {
1292-
$this->errors[] = Tools::displayError('Order status can not be changed to any overbooking status as there are no overbooked rooms in the order.');
1293-
}
1294-
} elseif ($order_state->id == Configuration::get('PS_OS_REFUND')
1295-
&& !$order->hasCompletelyRefunded(Order::ORDER_COMPLETE_REFUND_FLAG)
1296-
) {
1297-
$this->errors[] = Tools::displayError('Order status can not be set to Refunded until all bookings in the order are completely refunded.');
1298-
} elseif ($order_state->id == Configuration::get('PS_OS_CANCELED')
1299-
&& !$order->hasCompletelyRefunded(Order::ORDER_COMPLETE_CANCELLATION_FLAG)
1300-
) {
1301-
$this->errors[] = Tools::displayError('Order status can not be set to Cancelled until all bookings in the order are cancelled.');
1302-
} elseif ($current_order_state->id == Configuration::get('PS_OS_ERROR') && !($order_state->id == Configuration::get('PS_OS_ERROR'))) {
1303-
// All rooms must be available before changing status from Payment Error to Other status in which rooms are getting blocked again
1304-
$objHotelBooking = new HotelBookingDetail();
1305-
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($order->id)) {
1306-
foreach ($orderBookings as $orderBooking) {
1307-
// If booking is refunded then no need to check inventory
1308-
if ((OrderReturn::getOrdersReturnDetail($order->id, 0, $orderBooking['id']) && $orderBooking['is_refunded'])
1309-
|| ($orderBooking['is_cancelled'] && $orderBooking['is_refunded'])
1310-
) {
1311-
continue;
1312-
} else {
1313-
// if inventory is available for that booking
1314-
$bookingParams = array(
1315-
'date_from' => $orderBooking['date_from'],
1316-
'date_to' => $orderBooking['date_to'],
1317-
'hotel_id' => $orderBooking['id_hotel'],
1318-
'id_room_type' => $orderBooking['id_product'],
1319-
'only_search_data' => 1
1320-
);
1321-
1322-
$objHotelBookingDetail = new HotelBookingDetail($orderBooking['id']);
1323-
if ($searchRoomsInfo = $objHotelBooking->getBookingData($bookingParams)) {
1324-
if (isset($searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'])
1325-
&& $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available']
1326-
) {
1327-
$availableRoomsInfo = $searchRoomsInfo['rm_data'][$orderBooking['id_product']]['data']['available'];
1328-
if ($roomIdsAvailable = array_column($availableRoomsInfo, 'id_room')) {
1329-
// Check If room is still there in the available rooms list
1330-
if (!in_array($orderBooking['id_room'], $roomIdsAvailable)) {
1331-
$this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
1332-
1333-
break;
1334-
} else {
1335-
$objHotelBookingDetail->is_refunded = 0;
1336-
$objHotelBookingDetail->save();
1337-
}
1338-
} else {
1339-
$this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
1340-
break;
1341-
}
1342-
}
1343-
} else {
1344-
$this->errors[] = Tools::displayError('You can not change the order status as some rooms are not available now in this order. You can reallocate/swap rooms with other rooms to make rooms available and then change the order status.');
1345-
1346-
break;
1347-
}
1348-
}
1349-
}
1350-
}
1351-
} elseif ($current_order_state->id == $order_state->id) {
1352-
$this->errors[] = Tools::displayError('The order has already been assigned this status.');
1353-
}
1354-
1355-
// If no errors then we change the order status
1356-
if (!count($this->errors)) {
1357-
// Create new OrderHistory
1358-
$history = new OrderHistory();
1359-
$history->id_order = $order->id;
1360-
$history->id_employee = (int)$this->context->employee->id;
1361-
1362-
$use_existings_payment = false;
1363-
if (!$order->hasInvoice()) {
1364-
$use_existings_payment = true;
1365-
}
1366-
$history->changeIdOrderState((int)$order_state->id, $order, $use_existings_payment);
1367-
1368-
$carrier = new Carrier($order->id_carrier, $order->id_lang);
1369-
$templateVars = array();
1370-
1371-
// Save all changes
1372-
if ($history->addWithemail(true, $templateVars)) {
1373-
// synchronizes quantities if needed..
1374-
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT')) {
1375-
foreach ($order->getProducts() as $product) {
1376-
if (StockAvailable::dependsOnStock($product['product_id'])) {
1377-
StockAvailable::synchronize($product['product_id'], (int)$product['id_shop']);
1378-
}
1379-
}
1380-
}
1381-
1382-
Tools::redirectAdmin(self::$currentIndex.'&id_order='.(int)$order->id.'&conf=5&vieworder&token='.$this->token);
1383-
}
1384-
1385-
$this->errors[] = Tools::displayError('An error occurred while changing order status, or we were unable to send an email to the customer.');
1386-
}
1268+
$this->errors = array_merge($this->errors, $result['errors']);
13871269
}
13881270
} else {
13891271
$this->errors[] = Tools::displayError('You do not have permission to edit this.');

0 commit comments

Comments
 (0)