mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
add refund transaction under booking payment history, update on admin currency order dashboard to show the correct amount after refunded
This commit is contained in:
+24
-1
@@ -3,6 +3,7 @@
|
||||
|
||||
namespace App\Classes\Modules\Transactions\ControllersLogic;
|
||||
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\Modules\Transactions\Processors\CreateSupplierTransactionProcessor;
|
||||
use App\Classes\Modules\Transactions\Services\GeneratesTransactionBillNumber;
|
||||
use App\Models\Document;
|
||||
@@ -18,6 +19,7 @@ use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
use App\Classes\Modules\Companies\Services\FetchesCompany;
|
||||
use App\Classes\Modules\Documents\Services\CreatesDocument;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
|
||||
|
||||
class CreateSupplierTransactionLogic extends AbstractControllerLogic
|
||||
{
|
||||
@@ -48,6 +50,9 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
|
||||
/** @var GeneratesTransactionBillNumber */
|
||||
private $generatesTransactionBillNumber;
|
||||
|
||||
/** @var FetchesTransaction */
|
||||
private $fetchesTransaction;
|
||||
|
||||
|
||||
/**
|
||||
* CreateSupplierTransactionLogic constructor.
|
||||
@@ -56,14 +61,16 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
|
||||
* @param CreatesDocument $createsDocument
|
||||
* @param CreatesFiles $createsFile
|
||||
* @param GeneratesTransactionBillNumber $generatesTransactionBillNumber
|
||||
* @param FetchesTransaction $fetchesTransaction
|
||||
*/
|
||||
public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber)
|
||||
public function __construct(FetchesCompany $fetchesCompany, CreateSupplierTransactionProcessor $createSupplierTransactionProcessor, CreatesDocument $createsDocument, CreatesFiles $createsFile, GeneratesTransactionBillNumber $generatesTransactionBillNumber, FetchesTransaction $fetchesTransaction)
|
||||
{
|
||||
$this->fetchesCompany = $fetchesCompany;
|
||||
$this->createSupplierTransactionProcessor = $createSupplierTransactionProcessor;
|
||||
$this->createsDocument = $createsDocument;
|
||||
$this->createsFile = $createsFile;
|
||||
$this->generatesTransactionBillNumber = $generatesTransactionBillNumber;
|
||||
$this->fetchesTransaction = $fetchesTransaction;
|
||||
}
|
||||
|
||||
public function logic(Request $request) : JsonResponse
|
||||
@@ -75,6 +82,22 @@ class CreateSupplierTransactionLogic extends AbstractControllerLogic
|
||||
|
||||
$payments = $request->input('payments');
|
||||
|
||||
foreach($payments as $payment){
|
||||
$payment = $this->fetchesTransaction->execute(['id' => $payment['id']]);
|
||||
|
||||
$pendingRefundRequest = $payment->transactions()->refunds()->where('status', ApprovalStatus::PENDING_VERIFICATION)->first();
|
||||
|
||||
if ($pendingRefundRequest) {
|
||||
throw new MalformedRequestException('Unable to create supplier order for pending refund request payment');
|
||||
}
|
||||
|
||||
$totalRefund = $payment->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->sum('original_amount');
|
||||
|
||||
if ($payment->original_amount - $totalRefund <= 0) {
|
||||
throw new MalformedRequestException('Unable to create supplier order for fully refunded payment');
|
||||
}
|
||||
}
|
||||
|
||||
$this->createSupplierTransactionProcessor->execute($supplier, $rate, $payments);
|
||||
|
||||
if(!count($this->createSupplierTransactionProcessor->getBills())) return $this->response([]);
|
||||
|
||||
@@ -81,15 +81,19 @@ class CreateSupplierTransactionProcessor
|
||||
|
||||
if($payment->status !== ApprovalStatus::APPROVED) continue;
|
||||
|
||||
$totalRefund = $payment->transactions()->refunds()->where('status', ApprovalStatus::APPROVED)->sum('original_amount');
|
||||
|
||||
$original_amount_after_refund = $payment->original_amount - $totalRefund;
|
||||
|
||||
$this->updatesTransactionStatus->execute($payment, ApprovalStatus::COMPLETED);
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute('SPLR-');
|
||||
$constant = SegmentConstant::where('reference', SegmentConstants::SERVICE_CHARGE)->where('detail->id', $supplier->id)->first();
|
||||
|
||||
$serviceCharge = $this->calculatesTransactionServiceCharge->execute($payment->original_amount, $rate, $constant);
|
||||
$serviceCharge = $this->calculatesTransactionServiceCharge->execute($original_amount_after_refund, $rate, $constant);
|
||||
|
||||
$object = new TransactionObject($billNumber, TransactionType::BILL, $supplier->id, 1,
|
||||
$supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH,
|
||||
$payment->original_amount * (1 / $rate), $payment->original_amount, 1, $payment->original_currency_id,
|
||||
$original_amount_after_refund * (1 / $rate), $original_amount_after_refund, 1, $payment->original_currency_id,
|
||||
$rate, 0, $serviceCharge, null, ApprovalStatus::PENDING_SUBMISSION);
|
||||
|
||||
/** @var Transaction $billTransaction */
|
||||
@@ -101,7 +105,7 @@ class CreateSupplierTransactionProcessor
|
||||
$transferFee = $this->calculatesTransactionTransferFee->execute($billTransaction->original_amount, $constant);
|
||||
$object = new TransactionObject($transferFeeNumber, TransactionType::TRANSFER_FEE, 1, $supplier->id,
|
||||
$supplier->banks()->where('default', true)->first()->id, PaymentMethodType::CASH,
|
||||
$payment->original_amount, $payment->original_amount, $payment->original_currency_id, $payment->original_currency_id,
|
||||
$original_amount_after_refund, $original_amount_after_refund, $payment->original_currency_id, $payment->original_currency_id,
|
||||
1, 0, $transferFee, null, ApprovalStatus::PENDING_VERIFICATION);
|
||||
|
||||
$this->pushTransferFee($this->createsTransaction->execute($billTransaction, $object));
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="col-auto p-l-0" v-if="totalRefunds !== 0">
|
||||
<div class="font-heading fs-8 muted all-caps">Refunded Amount</div>
|
||||
<div class="font-heading fs-10 bold text-danger">
|
||||
{{item.original_currency.short_code}} {{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
{{item.currency.short_code}} {{(Math.round((totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -136,6 +136,12 @@
|
||||
<div class="font-heading fs-10">{{item.original_currency.short_code}} {{(Math.round((totalRequestedRefund + 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="totalRequestedRefund != 0">
|
||||
<div class="col"></div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-10">{{item.currency.short_code}} {{(Math.round((totalRequestedConvertRefund + 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 class="font-heading all-caps fs-10">Refunded Amount</div>
|
||||
@@ -144,6 +150,12 @@
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
<div class="row align-items-end bold m-b-10 text-primary">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10">Rate</div>
|
||||
@@ -187,6 +199,14 @@
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((item.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-success" v-if="totalRefunds != 0">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10">Your Payment After Refund</div>
|
||||
</div>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-12">MYR {{(Math.round((item.amount - totalConvertRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10 m-b-5">Your Payment Proof</div>
|
||||
@@ -279,6 +299,47 @@
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10" v-if="totalRefunds !== 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="totalRefunds != 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>
|
||||
<div class="col-auto text-right">
|
||||
<div class="font-heading fs-10">{{ refund.updated_at }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row align-items-end m-b-10 bold">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-10"> 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"> 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -291,6 +352,7 @@
|
||||
data(){
|
||||
return {
|
||||
expandPaymentDetails: false,
|
||||
expandRefundTransactions: false,
|
||||
amount: (Math.round(1000 * 100) / 100).toFixed(2),
|
||||
parameters: {
|
||||
amount: (Math.round(1000 * 100) / 100).toFixed(2),
|
||||
@@ -313,12 +375,12 @@
|
||||
let vm = this;
|
||||
var TotalRequestedRefund = 0;
|
||||
this.data.transaction_refunds.forEach(function(refunds) {
|
||||
TotalRequestedRefund += refunds.status === 1 ? refunds.original_amount : 0;
|
||||
TotalRequestedRefund += refunds.status === 1 ? refunds.amount : 0;
|
||||
});
|
||||
if (vm.data.booking.fixed_currency.id != 1 && this.data.transaction_refunds[0]) {
|
||||
TotalRequestedRefund = (TotalRequestedRefund * this.data.transaction_refunds[0].currency_rate);
|
||||
}
|
||||
return ((Math.round((TotalRequestedRefund + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
|
||||
// if (vm.data.booking.fixed_currency.id != 1 && this.data.transaction_refunds[0]) {
|
||||
// TotalRequestedRefund = (TotalRequestedRefund * this.data.transaction_refunds[0].currency_rate);
|
||||
// }
|
||||
return TotalRequestedRefund;
|
||||
},
|
||||
totalRefunds() {
|
||||
var TotalRequestedRefund = 0;
|
||||
@@ -326,11 +388,22 @@
|
||||
TotalRequestedRefund += refunds.status === 2 ? refunds.original_amount : 0;
|
||||
});
|
||||
return TotalRequestedRefund;
|
||||
},
|
||||
totalConvertRefunds() {
|
||||
var TotalRequestedRefund = 0;
|
||||
this.data.transaction_refunds.forEach(function(refunds) {
|
||||
TotalRequestedRefund += refunds.status === 2 ? refunds.amount : 0;
|
||||
});
|
||||
return TotalRequestedRefund;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clickExpand(){
|
||||
this.expandPaymentDetails = !this.expandPaymentDetails;
|
||||
this.expandRefundTransactions = false;
|
||||
},
|
||||
clickExpandRefundTransactions(){
|
||||
this.expandRefundTransactions = !this.expandRefundTransactions;
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
|
||||
+21
-2
@@ -56,6 +56,16 @@
|
||||
<span class="flag-icon" :class="'flag-icon-'+item.original_currency.country.short_code.toLowerCase()"></span> {{item.original_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right" v-if="totalRefunds !== 0">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Refunded Amount</div>
|
||||
<div class="font-heading fs-14 text-danger bold">
|
||||
{{(Math.round((totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
@@ -95,7 +105,7 @@
|
||||
<div class="col text-right">
|
||||
<div class="font-heading fs-10 muted all-caps">Amount</div>
|
||||
<div class="font-heading fs-14 text-success bold">
|
||||
{{(Math.round((item.original_amount + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
{{(Math.round((item.original_amount - totalRefunds + Number.EPSILON) * 100) / 100).toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,11 +134,20 @@
|
||||
active: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalRefunds() {
|
||||
var TotalRequestedRefund = 0;
|
||||
this.data.transaction_refunds.forEach(function(refunds) {
|
||||
TotalRequestedRefund += refunds.status === 2 ? refunds.original_amount : 0;
|
||||
});
|
||||
return TotalRequestedRefund;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
activate(){
|
||||
this.active = !this.active;
|
||||
this.$emit('input', this.item)
|
||||
}
|
||||
},
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
|
||||
@@ -115,7 +115,12 @@
|
||||
computed: {
|
||||
total(){
|
||||
return this.payments.reduce(function (total, currentValue) {
|
||||
return total + currentValue.original_amount;
|
||||
return total + currentValue.original_amount - currentValue.transaction_refunds.reduce(function (totalRefund, refundTransaction) {
|
||||
if (refundTransaction.status === 2) {
|
||||
return totalRefund + refundTransaction.original_amount;
|
||||
}
|
||||
return totalRefund;
|
||||
}, 0);
|
||||
}, 0);
|
||||
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user