update refund ui and logic

This commit is contained in:
edmondlang
2024-02-16 14:59:11 +08:00
parent ddcad4969e
commit f083434390
13 changed files with 208 additions and 146 deletions
@@ -19,6 +19,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Classes\Modules\Currencies\DataTransferObjects\CurrencyConversionObject;
use App\Http\Resources\TransactionResource;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use App\Classes\Modules\Transactions\Processors\CreateCashBackTransactionProcessor;
use App\Classes\Modules\Vouchers\Processors\Voucherify\BookingToVoucherifyProcessor;
@@ -77,6 +78,9 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
/** @var BookingToVoucherifyProcessor */
private $bookingToVoucherifyProcessor;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/**
* CreateBookingPaymentLogic constructor.
* @param FetchesBookingQuotation $fetchBookingQuotation
@@ -90,8 +94,9 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
* @param CreateCashBackTransactionProcessor $createCashBackTransactionProcessor
* @param RecalculatesWalletBalance $recalculatesWalletBalance
* @param BookingToVoucherifyProcessor $bookingToVoucherifyProcessor
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
*/
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor)
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingOutstanding $calculatesBookingOutstanding, CreatesBillplzBill $createsBillplzBill, UpdatesWalletBalance $updatesWalletBalance, UpdatesTransactionStatus $updatesTransactionStatus, CreateCashBackTransactionProcessor $createCashBackTransactionProcessor, RecalculatesWalletBalance $recalculatesWalletBalance, BookingToVoucherifyProcessor $bookingToVoucherifyProcessor, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
{
$this->fetchBookingQuotation = $fetchBookingQuotation;
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
@@ -104,6 +109,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$this->createCashBackTransactionProcessor = $createCashBackTransactionProcessor;
$this->recalculatesWalletBalance = $recalculatesWalletBalance;
$this->bookingToVoucherifyProcessor = $bookingToVoucherifyProcessor;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
}
/**
@@ -119,7 +125,7 @@ class CreateBookingPaymentLogic extends AbstractControllerLogic
$conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]);
$outstanding = $this->calculatesBookingOutstanding->execute($booking);
$outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '. $outstanding .'.');
@@ -15,7 +15,6 @@ use App\Classes\Modules\Transactions\Services\CreatesTransaction;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Bookings\Services\FetchesBookingQuotation;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionObject;
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
use App\Classes\Modules\Transactions\DataTransferObjects\TransactionRefundCalculationObject;
@@ -49,9 +48,6 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
/** @var CreatesTransaction */
private $createsTransaction;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/**
* CreateBookingPaymentLogic constructor.
* @param FetchesBookingQuotation $fetchBookingQuotation
@@ -59,16 +55,14 @@ class CreateBookingRefundLogic extends AbstractControllerLogic
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
* @param CreatesTransaction $createsTransaction
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
*/
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, GeneratesTransactionBillNumber $generatesTransactionBillNumber, CreatesTransaction $createsTransaction)
{
$this->fetchBookingQuotation = $fetchBookingQuotation;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
$this->createsTransaction = $createsTransaction;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
}
/**
@@ -18,7 +18,7 @@ class FetchBookingLogic extends AbstractControllerLogic
*/
protected function notification():array {
return [
'title' => 'Retrieved Address',
'title' => 'Retrieved Booking',
'message' => 'You have successfully retrieved a Address'
];
}
@@ -14,6 +14,7 @@ use App\Classes\ValueObjects\Constants\PaymentMethodType;
use App\Models\Booking;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
{
@@ -40,6 +41,9 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
/** @var CalculatesBookingOutstanding */
private $calculatesBookingOutstanding;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/**
* FetchBookingPaymentQuotationLogic constructor.
* @param FetchesBookingQuotation $fetchBookingQuotation
@@ -47,12 +51,13 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
* @param FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit
* @param CalculatesBookingOutstanding $calculatesBookingOutstanding
*/
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, GeneratesBookingQuotation $generatesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesBookingOutstanding $calculatesBookingOutstanding)
public function __construct(FetchesBookingQuotation $fetchBookingQuotation, GeneratesBookingQuotation $generatesBookingQuotation, FetchesCompanyPaymentAttemptLimit $fetchesCompanyPaymentAttemptLimit, CalculatesBookingOutstanding $calculatesBookingOutstanding, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
{
$this->fetchBookingQuotation = $fetchBookingQuotation;
$this->generatesBookingQuotation = $generatesBookingQuotation;
$this->fetchesCompanyPaymentAttemptLimit = $fetchesCompanyPaymentAttemptLimit;
$this->calculatesBookingOutstanding = $calculatesBookingOutstanding;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
}
/**
@@ -66,7 +71,7 @@ class FetchBookingPaymentQuotationLogic extends AbstractControllerLogic
$conversionObject = new CurrencyConversionObject(floatval(str_replace(',', '', $request->input('amount'))), $booking->convertible_currency_id, $booking->service_id, $booking->fix_currency_id === 1 ? 0:1, PaymentMethodType::PAYMENT_METHODS[$request->input('payment_method')]);
$outstanding = $this->calculatesBookingOutstanding->execute($booking);
$outstanding = $this->calculatesBookingOutstanding->execute($booking) + $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
if($conversionObject->getAmount() > round($outstanding, 2)) throw new MalformedRequestException('Your payment must not be greater than '.$booking->fixedCurrency->short_code.' '. number_format((float)$outstanding, 2, '.', ','));
//Voucherify
@@ -2,19 +2,30 @@
namespace App\Classes\Modules\Bookings\Services;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use Carbon\Carbon;
class CalculatesBookingRefundAmount
{
public function execute(Booking $booking, int $type, ?string $payment_reference = null): float
{
$refundAmounts = $booking->transactions()->payments()->get()->map(function ($payment) use ($type) {
return $this->calculateRefundAmount($payment, $type);
});
public function execute(Booking $booking, int $type, ?string $payment_reference = NULL){
return $type === 1 ?
$booking->transactions()->refunds($payment_reference)
->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total') : $booking->transactions()->refunds($payment_reference)->sum('original_amount');
$totalRefundAmount = $refundAmounts->sum();
return $totalRefundAmount;
}
}
private function calculateRefundAmount($payment, int $type): float
{
$refundTransactions = $payment->transactions()->refunds()->whereIn('status', [ApprovalStatus::APPROVED]);
if ($type === 1) {
return $refundTransactions->selectRaw('sum(amount - service_charge - tax) as sub_total')->get()->sum('sub_total');
}
return $refundTransactions->sum('original_amount');
}
}
@@ -13,6 +13,8 @@ use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Wallets\Processors\CreditWalletProcessor;
use App\Classes\Modules\Bookings\Services\CalculatesBookingPayableAmount;
use App\Classes\Modules\Bookings\Services\CalculatesBookingRefundAmount;
class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
@@ -43,6 +45,12 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
/** @var CreditWalletProcessor */
private $creditWalletProcessor;
/** @var CalculatesBookingPayableAmount */
private $calculatesBookingPayableAmount;
/** @var CalculatesBookingRefundAmount */
private $calculatesBookingRefundAmount;
/**
* CreatePaymentVerificationDocumentLogic constructor.
* @param FetchesCompany $fetchesCompany
@@ -50,14 +58,18 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
* @param UpdatesTransactionStatus $updatesTransactionStatus
* @param DeletesDocument $deletesDocument
* @param CreditWalletProcessor $creditWalletProcessor
* @param CalculatesBookingPayableAmount $calculatesBookingPayableAmount
* @param CalculatesBookingRefundAmount $calculatesBookingRefundAmount
*/
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor)
public function __construct(FetchesCompany $fetchesCompany, FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus, DeletesDocument $deletesDocument, CreditWalletProcessor $creditWalletProcessor, CalculatesBookingPayableAmount $calculatesBookingPayableAmount, CalculatesBookingRefundAmount $calculatesBookingRefundAmount)
{
$this->fetchesCompany = $fetchesCompany;
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
$this->deletesDocument = $deletesDocument;
$this->creditWalletProcessor = $creditWalletProcessor;
$this->calculatesBookingPayableAmount = $calculatesBookingPayableAmount;
$this->calculatesBookingRefundAmount = $calculatesBookingRefundAmount;
}
/**
@@ -69,7 +81,7 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
{
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$transaction = $this->updatesTransactionStatus->execute($transaction, $request->input('status'));
$transaction = $this->updatesTransactionStatus->execute($transaction, $request->route('status'));
$booking = $transaction->owner->owner;
@@ -81,7 +93,10 @@ class UpdateRefundTransactionStatusLogic extends AbstractControllerLogic
$this->creditWalletProcessor->execute($booking->company, $transaction->type, $transaction->amount, $reference);
}
$paidAmount = $this->calculatesBookingPayableAmount->execute($booking, $booking->fix_currency_id) - $this->calculatesBookingRefundAmount->execute($booking, $booking->fix_currency_id);
if (!$paidAmount > 0) {
$this->updatesTransactionStatus->execute($paymentTransaction, ApprovalStatus::REFUNDED);
}
return $this->response([]);
}
+2 -2
View File
@@ -34,7 +34,7 @@ class BookingResource extends JsonResource
'amount' => $this->fix_amount,
'floating_amount' => floatval((App()->make(CalculatesBookingFloatingAmount::class))->execute($this->resource, $this->fix_currency_id)),
'paid_amount' => floatval((App()->make(CalculatesBookingPayableAmount::class))->execute($this->resource, $this->fix_currency_id)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) - floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'outstanding_amount' => floatval((App()->make(CalculatesBookingOutstanding::class))->execute($this->resource)) + floatval((App()->make(CalculatesBookingRefundAmount::class))->execute($this->resource, $this->fix_currency_id)),
'fixed_currency' => new CurrencyResource($this->fixedCurrency),
'convertible_currency' => new CurrencyResource($this->convertibleCurrency),
'conversion_currency' => new CurrencyResource($this->conversionCurrency),
@@ -60,7 +60,7 @@ class BookingResource extends JsonResource
'expired_payment_attempts' => TransactionResource::collection($this->transactions()->payments()->where('status', ApprovalStatus::PENDING_SUBMISSION)->whereDate('expires_on', '>=', Carbon::now())->where('expires_on', '>', Carbon::now()->toTimeString())->get()),
'payment_history' => TransactionResource::collection($this->transactions()->where(function($query){
$query->where(function($query){
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED]);
$query->payments()->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED, ApprovalStatus::REFUNDED]);
})->orWhere(function($query){
$query->where(function($query){
$query->where('type', TransactionType::REFUND)->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::REJECTED, ApprovalStatus::COMPLETED]);
@@ -45,6 +45,7 @@ class TransactionResource extends JsonResource
'transaction_refunds' => TransactionResource::collection($this->when((int) $this->type === TransactionType::PAYMENT, $this->transactions()->refunds()->get())),
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:i:s A'),
'updated_at' => Carbon::parse($this->updated_at)->format('d-m-Y h:i:s A'),
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A'),
'interval' => [
'value' => $days->gt(Carbon::now()) ? '+' : '-',
'duration' => $days->diff(Carbon::now())->format('%d'),
@@ -4,12 +4,12 @@
<div class="row" v-if="!item.transaction_bill">
<div class="col">
<div class="row">
<div class="col p-t-10 p-b-10 p-r-0 pointer" @click="clickExpand()" :class="[{'bg-master-lighter': item.status === 1 && item.type !== 6}, {'bg-white': item.status !== 1 && item.status !== 4}, {'bg-warning-lighter': item.type === 6}]">
<div class="col p-t-10 p-b-10 p-r-0 pointer" @click="clickExpand()" :class="[{'bg-master-lighter': item.status === 1 && item.type !== 6}, {'bg-white': item.status !== 1 && item.status !== 4}, {'bg-warning-lighter': item.status === 7}, {'bg-warning-lighter': item.type === 6}]">
<div class="row m-b-5">
<div class="col-auto">
<div class="font-heading fs-8 muted all-caps">Status</div>
<div class="font-heading fs-10 bold" v-if="item.type === 1" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4}]">
{{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}}
<div class="font-heading fs-10 bold" v-if="item.type === 1" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4 && item.status !== 7}, {'text-danger': item.status == 7}]">
{{ item.status === 7 ? 'Refunded' : (item.status === 1 ? 'Processing Payment' : 'Transferred')}}
</div>
<div class="font-heading fs-10 bold" v-if="item.type === 6" :class="[{'text-danger': item.status === 1 || item.status === 4}, {'text-success': item.status !== 1 && item.status !== 4}]">
{{ item.status === 1 ? 'Pending Verification' : item.status === 4 ? 'Rejected' : 'Processing Payment'}}
@@ -39,7 +39,7 @@
</div>
</div>
</div>
<div class="col-auto" v-if="item.status !== 3" :class="[{'bg-master-light': item.status === 1 && item.type !== 6}, {'bg-master-lighter': item.status === 2}, {'bg-warning-light': item.type === 6}]">
<div class="col-auto" v-if="item.status !== 3" :class="[{'bg-master-light': item.status === 1 && item.type !== 6}, {'bg-master-lighter': item.status === 2}, {'bg-warning-lighter': item.status === 7}, {'bg-warning-light': item.type === 6}]">
<div class="row align-items-center h-100" v-if="item.status !== 1 || item.payment_method !== 5">
<div class="col">
<i class="fa" :class="[{'fa-cloud-download': item.status === 1 || item.status === 2}, {'fa-ban': item.status === 4}, {'muted': item.status === 1 || item.status === 2}, {'text-danger': item.status === 4}]"></i>
@@ -147,13 +147,13 @@
<div class="font-heading all-caps fs-10">Refunded Amount</div>
</div>
<div class="col-auto text-right">
<div class="font-heading fs-12">{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
<div class="font-heading fs-10">{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
<div class="row align-items-end m-b-10 bold text-danger" v-if="totalRefunds != 0">
<div class="col"></div>
<div class="col-auto text-right">
<div class="font-heading fs-12">{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
<div class="font-heading fs-10">{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
<div class="row align-items-end bold m-b-10 text-primary">
@@ -292,7 +292,7 @@
</div>
</div>
<div class="row m-t-10" v-show="[2, 3].includes(item.status) && (totalRequestedRefund + totalRefunds) < data.booking.amount">
<div class="col" v-if="!item.transaction_bill">
<div class="col" v-if="!item.transaction_bill && $store.getters.isAdmin">
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border requestModal" data-type="transferSummary">Request Refund</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="transferSummary" size="large">
<refund-confirmation-component :data="data" :section="section" :totalRefunds="totalRequestedRefund + totalRefunds"></refund-confirmation-component>
@@ -301,42 +301,83 @@
</div>
<div class="row m-t-10" v-if="data.transaction_refunds.length > 0">
<div class="col">
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border" @click="clickExpandRefundTransactions">Show Refund Transactions</button>
<button class="btn btn-xs all-caps b-rad-none bg-master-lighter btn-block no-border pointer" @click="clickExpandRefundTransactions">
<div class="row justify-content-between">
<div class="col-auto">
<i class="fa" :class="[{'fa-angle-up': expandRefundTransactions}, {'fa-angle-down': !expandRefundTransactions}]"></i>
</div>
<div class="col">
Show Refund Transactions
</div>
<div class="col-auto">
<i class="fa" :class="[{'fa-angle-up': expandRefundTransactions}, {'fa-angle-down': !expandRefundTransactions}]"></i>
</div>
</div>
</button>
</div>
</div>
</div>
</div>
<div class="row" v-if="data.transaction_refunds.length > 0 && expandRefundTransactions">
<div class="col bg-white padding-15">
<div v-for="(refund, index) in data.transaction_refunds">
<div class="row align-items-end m-b-10 bold">
<div class="col">
<div class="font-heading all-caps fs-10">{{ index + 1 }}. Refund updated on</div>
<div class="b-b b-grey m-b-5" v-for="(refund, index) in data.transaction_refunds">
<div class="row m-b-10">
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">Created At</div>
<div class="font-heading fs-10">
{{ refund.created_at }}
</div>
</div>
<div class="col-auto">
<div class="font-heading fs-10 muted all-caps">Status</div>
<div class="font-heading fs-10">
<div class="font-heading fs-10 bold" :class="[{'text-warning': refund.status === 1}, {'text-success': refund.status === 2}, {'text-danger': refund.status === 4}]">{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}</div>
</div>
</div>
<div class="col text-right">
<div class="font-heading fs-10 muted all-caps">Amount</div>
<div class="font-heading fs-10">
<div class="font-heading fs-10">{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
<div class="col-auto text-right">
<div class="font-heading fs-10">{{ refund.updated_at }}</div>
<div class="font-heading fs-10 muted all-caps">Amount</div>
<div class="font-heading fs-14 text-success bold">
<div class="font-heading fs-10">{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
</div>
<div class="row align-items-end m-b-10 bold">
<div class="row m-b-15 text-right parentContainer" v-if="$store.getters.isAdmin && refund.status === 1">
<div class="col">
<div class="font-heading all-caps fs-10">&nbsp;&nbsp;&nbsp; Refund status</div>
</div>
<div class="col-auto text-right">
<div class="font-heading fs-10" :class="[{'text-warning': refund.status === 1}, {'text-success': refund.status === 2}, {'text-danger': refund.status === 4}]">{{ refund.status === 1 ? 'Pending Verification' : refund.status === 2 ? 'Approved' : 'Rejected'}}</div>
</div>
</div>
<div class="row align-items-end m-b-10 bold text-danger">
<div class="col">
<div class="font-heading all-caps fs-10">&nbsp;&nbsp;&nbsp; Requested Refund Amount</div>
</div>
<div class="col-auto text-right">
<div class="font-heading fs-10">{{refund.original_currency.short_code}} {{(Math.round((refund.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
</div>
</div>
<div class="row align-items-end m-b-10 bold text-danger">
<div class="col"></div>
<div class="col-auto text-right">
<div class="font-heading fs-10">{{refund.currency.short_code}} {{(Math.round((refund.amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
<button class="btn btn-xs btn-outline-danger b-rad-none m-r-5 requestModal" data-type="rejectRefund">
<i class="fa fa-times fa-fw"></i>
</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="rejectRefund">
<general-confirmation-form-component
contentText="Are you sure you want to reject this refund?"
modalType="delete"
class="text-center"
:apiRoute="route('api.transaction.refund.status.update', refund.id, 4)"
apiMethod="put"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
<button class="btn btn-xs btn-outline-primary b-rad-none m-r-5 requestModal" data-type="approveRefund">
<i class="fa fa-check fa-fw"></i>
</button>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="approveRefund">
<general-confirmation-form-component
contentText="Are you sure you want to approve this refund?"
modalType="confirm"
class="text-center"
:apiRoute="route('api.transaction.refund.status.update', refund.id, 2)"
apiMethod="put"
:section="section"
>
</general-confirmation-form-component>
</modal-component>
</div>
</div>
</div>
@@ -3,64 +3,42 @@
<div class="col bg-white padding-25">
<div class="row p-b-10">
<div class="col">
<div class="row m-b-5">
<div class="col">
<div class="font-heading all-caps bold fs-10">Request Refund</div>
<div class="font-heading all-caps bold fs-10">Request Refund</div>
</div>
</div>
<div class="row m-b-10">
<div class="col-7">
<div class="font-heading all-caps fs-10 m-b-5">Refund Type:</div>
<div class="row p-l-15">
<div v-for="(method, index) in refundMethods" :key="index"
class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey pointer"
:class="{ 'bg-complete text-white': method.name === refundMethod.name }"
@click="updateRefundType(method)">
{{ method.name }}
</div>
</div>
</div>
</div>
<div class="row">
<div class="row m-r-0 m-b-10" v-if="refundMethod.name === 'Partially Refund'">
<div class="col">
<div class="row">
<validation-wrapper-component :validator="$v.refundAmount">
<label>Amount</label>
<input class="form-control" name="amount" v-model="refundAmount"
:disabled="refundMethod.name === 'Fully Refund'" v-money="moneyV2">
</validation-wrapper-component>
</div>
<div class="col-auto b-r b-t b-b b-grey">
<div class="row h-100 align-items-center">
<div class="col">
<div class="row m-b-10">
<div class="col">
<div class="row parentContainer">
<div class="col">
<div class="row" >
<div class="col-7 p-r-0">
<div class="row m-b-10">
<div class="col">
<div class="font-heading all-caps fs-10 m-b-5">Refund Type: </div>
<div class="row p-l-15">
<div class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey pointer" :class="[{'bg-complete': refundMethod.name === 'Fully Refund'}, {'text-white': refundMethod.name === 'Fully Refund'}]" @click="updateRefundType({name: 'Fully Refund'})">
Full Refund
</div>
<div class="col p-t-20 p-b-20 bg-master-lightest text-center b-grey pointer" :class="[{'bg-complete': refundMethod.name === 'Partially Refund'}, {'text-white': refundMethod.name === 'Partially Refund'}]" @click="updateRefundType({name: 'Partially Refund'})">
Partial Refund
</div>
</div>
</div>
</div>
<div class="row m-r-0 m-b-10" v-if="refundMethod.name === 'Partially Refund'">
<div class="col p-r-0">
<validation-wrapper-component :validator="$v.refundAmount">
<label>Amount</label>
<input class="form-control" name="amount" v-model="refundAmount" :disabled="refundMethod.name == 'Fully Refund'" v-money="moneyV2">
</validation-wrapper-component>
</div>
<div class="col-auto b-r b-t b-b b-grey">
<div class="row h-100 align-items-center">
<div class="col">
<div class="font-heading fs-10 muted">{{data.booking.fixed_currency.short_code}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="font-heading fs-10 muted">{{ data.booking.fixed_currency.short_code }}</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-auto">
<button class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12" data-dismiss="modal">Cancel</button>
<button class="btn btn-lg btn-default bg-master-lightest b-rad-none all-caps fs-12"
data-dismiss="modal">Cancel</button>
</div>
<div class="col text-right">
<button class="btn btn-lg btn-success b-rad-none all-caps fs-12" @click="submitForm()">Confirm & Proceed</button>
@@ -71,47 +49,54 @@
</template>
<script>
import FormHandler from '../../../general/mixins/formHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
import { required, maxValue } from "vuelidate/lib/validators";
export default {
props: {
totalRefunds:{
type: Number,
default: 0,
import FormHandler from '../../../general/mixins/formHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
import { maxValue } from "vuelidate/lib/validators";
export default {
props: {
totalRefunds: {
type: Number,
default: 0,
}
},
data() {
return {
refundMethod: { name: 'Fully Refund', status: false },
refundMethods: [
{ name: 'Fully Refund', label: 'Full Refund' },
// { name: 'Partially Refund', label: 'Partial Refund' }
]
}
},
validations() {
return {
refundAmount: {
maxValue: maxValue(this.refundMaxValue)
}
}
},
computed: {
refundAmount() {
return (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2);
},
data(){
return {
refundAmount: (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2),
refundMethod: {
name: 'Partially Refund',
status: false
},
refundMaxValue: (Math.round((this.data.booking.amount - this.totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2),
refundMaxValue() {
return this.refundAmount;
},
},
methods: {
submitForm() {
this.parameters.amount = this.refundAmount;
this.submit(this.route('api.booking.refund.create', this.data.booking.id, this.data.id), 'post', this.section, true, true)
},
updateRefundType(refund) {
this.refundMethod = { ...refund, status: !this.refundMethod.status };
if (this.refundMethod.name === 'Fully Refund') {
this.refundAmount = this.refundMaxValue;
}
console.log(this.refundAmount);
},
validations() {
return {
refundAmount: {
// required,
maxValue: maxValue(this.refundMaxValue)
}
}
},
methods: {
submitForm(){
this.parameters.amount = this.refundAmount;
this.submit(this.route('api.booking.refund.create', this.data.booking.id, this.data.id), 'post', this.section, true, true)
},
updateRefundType(refund){
this.refundMethod = {
name: refund.name,
status: !this.refundMethod.status
}
this.refundMethod.name === 'Fully Refund' ? this.refundAmount = this.refundMaxValue : '';
},
},
mixins: [FormHandler, ModalFormHandler]
}
</script>
},
mixins: [FormHandler, ModalFormHandler]
}
</script>
@@ -115,7 +115,7 @@
approveRefund(status){
this.isLoading = true;
this.parameters.status = status;
this.submit(this.route('api.transaction.refund.status.update', this.data.id), 'put', 'listRefundTransactionSection', true, true);
this.submit(this.route('api.transaction.refund.status.update', this.data.id, status), 'put', 'listRefundTransactionSection', true, true);
},
},
mixins: [componentHandler, staticFormHandler]
@@ -240,7 +240,11 @@
},
watch: {
'data': function () {
this.products = this.data.purchase_order.details
if (this.data && this.data.purchase_order && this.data.purchase_order.details) {
this.products = this.data.purchase_order.details;
} else {
this.products = [];
}
}
},
methods: {
+1 -1
View File
@@ -11,7 +11,7 @@ Route::group(['prefix' => 'transactions', 'namespace' => 'Transactions', 'as' =>
route::post('{id}/bill/verification', 'CreatePaymentProofDocumentController@verify')->name('bill.verification');
route::post('{id}/bill/pay', 'CreatePaymentProofDocumentController@pay')->name('bill.pay');
Route::put('/{id}/bill/{status}', 'UpdatePaymentTransactionStatusController@update')->where('status', 'pending|complete')->name('bill.status');
Route::put('/{id}/refund/status/update', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update');
Route::put('/{id}/refund/status/update/{status}', 'UpdateRefundTransactionStatusController@update')->name('refund.status.update');
route::delete('{id}/bill/delete', 'DeletePaymentProofDocumentController@delete')->name('bill.delete');