Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved: Order Status changes, Refund issues resolved and order and cancellation process improved #908

Merged
merged 10 commits into from
Mar 15, 2024
Merged
4 changes: 3 additions & 1 deletion admin/themes/default/sass/controllers/_order.sass
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@
max-height: 55px
max-width: 55px


.room_status_info_form
.room_status
white-space: normal
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@
* International Registered Trademark & Property of PrestaShop SA
*}

<tr class="product-line-row" data-id_room="{$data.id_room}" data-id_product="{$data.id_product}" data-id_hotel="{$data.id_hotel}" data-date_from="{$data.date_from}" data-date_to="{$data.date_to}" data-product_price="{$data.unit_amt_tax_incl}" data-id_order_detail="{$data.id_order_detail}">
<tr class="product-line-row" data-id_htl_booking="{$data.id|escape:'html':'UTF-8'}" data-id_room="{$data.id_room}" data-id_product="{$data.id_product}" data-id_hotel="{$data.id_hotel}" data-date_from="{$data.date_from}" data-date_to="{$data.date_to}" data-product_price="{$data.unit_amt_tax_incl}" data-id_order_detail="{$data.id_order_detail}">
{if $refund_allowed}
<td class="standard_refund_fields" style="display:none">
<input type="checkbox" name="id_htl_booking[]" value="{$data.id|escape:'html':'UTF-8'}" {if isset($refundReqBookings) && ($data.id|in_array:$refundReqBookings)}disabled{/if}/>
<input type="checkbox" name="id_htl_booking[]" value="{$data.id|escape:'html':'UTF-8'}" {if (isset($refundReqBookings) && ($data.id|in_array:$refundReqBookings)) || $data.is_refunded}disabled{/if}/>
</td>
{/if}
<td class="text-center">
Expand Down Expand Up @@ -261,7 +261,7 @@
<li>
<a href="#" data-toggle="modal" data-target="#mySwappigModal" data-id_order="{$order->id}" data-room_num='{$data.room_num}' data-date_from='{$data.date_from}' data-date_to='{$data.date_to}' data-id_room='{$data.id_room}' data-cust_name='{$data.alloted_cust_name}' data-cust_email='{$data.alloted_cust_email}' data-avail_rm_swap='{$data.avail_rooms_to_swap|@json_encode}' data-avail_rm_realloc='{$data.avail_rooms_to_realloc|@json_encode}'>
<i class="icon-refresh"></i>
{l s='Reallocate Room'}
{l s='Reallocate/Swap Room'}
</a>
</li>
<li>
Expand All @@ -283,4 +283,4 @@
</button>
</td>
{/if}
</tr>
</tr>
183 changes: 98 additions & 85 deletions admin/themes/default/template/controllers/orders/helpers/view/view.tpl

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions classes/Cart.php
Original file line number Diff line number Diff line change
Expand Up @@ -2387,7 +2387,6 @@ public function getPackageList($flush = false)
$array[$selectedProduct['id_hotel']] = array(
'quantity' => $selectedProduct['quantity'],
'id_hotel' => $selectedProduct['id_hotel'],
'unit_price_tax_incl' => $selectedProduct['unit_price_tax_incl'],
'total_price_tax_excl' => $selectedProduct['total_price_tax_excl'],
'total_price_tax_incl' => $selectedProduct['total_price_tax_incl'],
);
Expand All @@ -2397,7 +2396,8 @@ public function getPackageList($flush = false)
$product['cart_quantity'] = $selectedProduct['quantity'];
$product['total'] = $selectedProduct['total_price_tax_excl'];
$product['total_wt'] = $selectedProduct['total_price_tax_incl'];
$product['price_wt'] = $selectedProduct['unit_price_tax_incl'];
$product['price_wt'] = $selectedProduct['total_price_tax_incl'] / $product['cart_quantity'];
$product['price'] = $selectedProduct['total_price_tax_excl'] / $product['cart_quantity'];
$product['id_hotel'] = $selectedProduct['id_hotel'];
$orderPackage[$id_address][$selectedProduct['id_hotel']]['product_list'][] = $product;
if (!isset($orderPackage[$id_address][$selectedProduct['id_hotel']]['id_hotel'])) {
Expand Down Expand Up @@ -2431,6 +2431,7 @@ public function getPackageList($flush = false)
$unitPriceWt = $objHotelServiceProductCartDetail->getHotelProductUnitPrice($this->id, $product['id_product'], $hotelProduct['id_hotel'], true);
$serviceProduct['total'] = $unitPrice * $hotelProduct['quantity'];
$serviceProduct['total_wt'] = $unitPriceWt * $hotelProduct['quantity'];
$serviceProduct['price'] = $unitPrice;
$serviceProduct['price_wt'] = $unitPriceWt;
// if (!empty($hotelProducts['products'])) {
// foreach($hotelProducts['products'] as $hotelProduct) {
Expand Down
8 changes: 3 additions & 5 deletions classes/PaymentModule.php
Original file line number Diff line number Diff line change
Expand Up @@ -1008,11 +1008,9 @@ public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_
// Set the order status
$new_history = new OrderHistory();
$new_history->id_order = (int)$order->id;
if ($order_status->logable && $order->is_advance_payment && $order->advance_paid_amount < $order->total_paid_tax_incl) {
$new_history->changeIdOrderState((int)Configuration::get('PS_OS_PARTIAL_PAYMENT_ACCEPTED'), $order, true);
} else {
$new_history->changeIdOrderState((int)$id_order_state, $order, true);
}

$new_history->changeIdOrderState((int)$id_order_state, $order, true);

$new_history->addWithemail(true, $extra_vars);

// Switch to back order if needed
Expand Down
80 changes: 43 additions & 37 deletions classes/order/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class OrderCore extends ObjectModel
const ORDER_PAYMENT_TYPE_FULL = 1;
const ORDER_PAYMENT_TYPE_ADVANCE = 2;

const ORDER_COMPLETE_REFUND_FLAG = 1;
const ORDER_COMPLETE_CANCELLATION_FLAG = 2;
const ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG = 3;

/** @var int Delivery address id */
public $id_address_delivery;

Expand Down Expand Up @@ -2602,56 +2606,58 @@ public static function getAllOrdersByCartId($id_cart)
return Db::getInstance()->executeS('SELECT * FROM '._DB_PREFIX_.'orders WHERE id_cart = '.(int)$id_cart);
}

// Order is considered as refunded if all bookings are requested for refund and all are with refunded status
// $refundFlag [ORDER_RETURN_STATE_FLAG_REFUNDED || ORDER_RETURN_STATE_FLAG_DENIED]
public function hasCompletelyRefunded($refundFlag = 0)
/**
* Function to check if order has been completely refunded
* @param integer action: can have 3 values as below
* Order::ORDER_COMPLETE_REFUND_FLAG for complete refunded and
* Order::ORDER_COMPLETE_CANCELLATION_FLAG for completely cancelled and
* Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG for all rooms are either cancelled or requested for refunded
* @return boolean: true if order has been completely refunded as per requested parameters or false
*/
public function hasCompletelyRefunded($action = 0)
{
$objHotelBooking = new HotelBookingdetail();
if ($refundBookings = OrderReturn::getOrdersReturnDetail($this->id)) {
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
if (count($refundBookings) == count($orderBookings)) {
if ($refundFlag) {
foreach ($refundBookings as $refundRow) {
if (Validate::isLoadedObject(
$objReturnState = new OrderReturnState($refundRow['state']
))) {
if ($refundFlag == OrderReturnState::ORDER_RETURN_STATE_FLAG_REFUNDED
&& !$objReturnState->refunded
) {
return false;
}
if ($refundFlag == OrderReturnState::ORDER_RETURN_STATE_FLAG_DENIED
&& !$objReturnState->denied
) {
return false;
}
}
if ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
// If action is Order::ORDER_COMPLETE_REFUND_FLAG (for refunded) then we will check
// that all rooms must be refunded and at least one booking is not cancelled
if ($action == Order::ORDER_COMPLETE_REFUND_FLAG) {
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_refunded'));
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
foreach ($orderBookings as $booking) {
if ($booking['is_cancelled'] == 0) {
return true;
}
}
}
// If action is Order::ORDER_COMPLETE_CANCELLATION_FLAG (for cancelled) then we will check that all rooms must be cancelled
} elseif ($action == Order::ORDER_COMPLETE_CANCELLATION_FLAG) {
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_cancelled'));
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
return true;
}
}
} elseif ($orderBookings = $objHotelBooking->getOrderCurrentDataByOrderId($this->id)) {
if (count(array_unique(array_column($orderBookings, 'is_cancelled'))) === 1
&& array_unique(array_column($orderBookings, 'is_cancelled'))[0] != 0
) {
// If action is Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG (for cancelled and refund requests) then we will check that all rooms are either cancelled or requested for refund
} elseif ($action == Order::ORDER_COMPLETE_CANCELLATION_OR_REFUND_REQUEST_FLAG) {
foreach ($orderBookings as $booking) {
if (!$booking['is_refunded']) {
if (!OrderReturn::getOrdersReturnDetail($this->id, 0, $booking['id'])) {
return false;
}
}
}
return true;
// Default process to check if order is fully refunded or cancelled or not
} else {
// if is_refunded is 1 means booking either is cancelled or refunded. So check all bookings must have is_refunded = 1
$uniqueRefundedBookings = array_unique(array_column($orderBookings, 'is_refunded'));
if (count($uniqueRefundedBookings) == 1 && $uniqueRefundedBookings[0] == 1) {
return true;
}
}
}

return false;
}

// Order is considered as denied if all bookings are requested for refund and all are with denied status
public function orderRefundHasBeenDenied()
{
if (OrderReturn::getOrdersReturn($this->id_customer, $this->id)) {

}

return false;
}

public function getWsBookings()
{
return Db::getInstance()->executeS(
Expand Down
30 changes: 25 additions & 5 deletions classes/order/OrderHistory.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,6 @@ public function changeIdOrderState($new_order_state, $id_order, $use_existing_pa

// set orders as paid
if ($new_os->paid == 1) {
$invoices = $order->getInvoicesCollection();
if ($order->total_paid != 0) {
// if order is created by API then create a direct object instead of creating an object from module
if ($order->module == 'wsorder') {
Expand All @@ -323,22 +322,43 @@ public function changeIdOrderState($new_order_state, $id_order, $use_existing_pa
}
}

foreach ($invoices as $invoice) {
/** @var OrderInvoice $invoice */
$rest_paid = $invoice->getRestPaid();
// if order has invoices then create payment entry for all the invoices
if ($invoices = $order->getInvoicesCollection()->getResults()) {
foreach ($invoices as $invoice) {
/** @var OrderInvoice $invoice */
$rest_paid = $invoice->getRestPaid();
if ($rest_paid > 0) {
if ($order->total_paid != 0) {
$payment_method = $payment_method->displayName;
} else {
$payment_method = null;
}
$order->addOrderPayment(
$rest_paid,
$payment_method,
null,
null,
null,
$invoice
);
}
}
} else {
$rest_paid = $order->total_paid_tax_incl - $order->total_paid_real;
if ($rest_paid > 0) {
if ($order->total_paid != 0) {
$payment_method = $payment_method->displayName;
} else {
$payment_method = null;
}

$order->addOrderPayment(
$rest_paid,
$payment_method,
null,
null,
null,
$invoice
null
);
}
}
Expand Down
3 changes: 2 additions & 1 deletion classes/order/OrderReturn.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ public function checkEnoughProduct($order_detail_list, $product_qty_list, $custo
public function hasBeenCompleted()
{
if (Validate::isLoadedObject($objReturnState = new OrderReturnState($this->state))) {
if ($objReturnState->denied || $objReturnState->refunded) {
// refund process will be considered as completed when the state is "Refunded"
if ($objReturnState->refunded) {
return true;
}
}
Expand Down
Loading