update payment and billing

This commit is contained in:
edmondlang
2022-08-07 17:11:26 +08:00
parent 9e756132ca
commit a2c7eddf7b
15 changed files with 308 additions and 26 deletions
@@ -50,10 +50,10 @@ class SuspendTransactionLogic extends AbstractControllerLogic
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$this->updatesTransactionStatus->execute($transaction, ApprovalStatus::SUSPENDED);
return $this->response([]);
$transaction = $this->updatesTransactionStatus->execute($transaction, ApprovalStatus::SUSPENDED);
return $this->resourceResponse(new TransactionResource($transaction));
}
@@ -0,0 +1,66 @@
<?php
namespace App\Classes\Modules\Transactions\ControllersLogic;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Transactions\Services\FetchesTransaction;
use App\Classes\Modules\Transactions\Services\ListsTransactions;
use App\Classes\Modules\Transactions\Services\UpdatesTransactionStatus;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Http\Resources\BookingResource;
use App\Http\Resources\TransactionResource;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UpdateTransactionStatusLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Update Transaction Status',
'message' => 'You have successfully updated the Transaction Status'
];
}
/** @var FetchesTransaction */
private $fetchesTransaction;
/** @var UpdatesTransactionStatus */
private $updatesTransactionStatus;
/**
* SuspendTransactionLogic constructor.
* @param FetchesTransaction $fetchesTransaction
* @param UpdatesTransactionStatus $updatesTransactionStatus
*/
public function __construct(FetchesTransaction $fetchesTransaction, UpdatesTransactionStatus $updatesTransactionStatus)
{
$this->fetchesTransaction = $fetchesTransaction;
$this->updatesTransactionStatus = $updatesTransactionStatus;
}
public function logic(Request $request) : JsonResponse
{
$approvalArray = [
'approve' => ApprovalStatus::APPROVED,
'expire' => ApprovalStatus::EXPIRED,
];
$approvalStatus = $approvalArray[$request->route('status')];
$transaction = $this->fetchesTransaction->execute(['id' => $request->route('id')]);
$transaction = $this->updatesTransactionStatus->execute($transaction, $approvalStatus);
return $this->resourceResponse(new TransactionResource($transaction));
}
}
@@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Transactions;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Classes\Modules\Transactions\ControllersLogic\UpdateTransactionStatusLogic;
class UpdateTransactionStatusController
{
/**
* @param Request $request
* @param SuspendTransactionLogic $logic
* @return JsonResponse
*/
public function update(Request $request, UpdateTransactionStatusLogic $logic) : JsonResponse {
return $logic->execute($request);
}
}
+2 -2
View File
@@ -21,11 +21,11 @@ class AddressResource extends JsonResource
$centerPostcodeConstantObject = SegmentConstant::where('reference', SegmentConstants::CENTER_POSTCODE)->get();
$centerPostcodeConstant = $centerPostcodeConstantObject->isEmpty() ? [] : (array)$centerPostcodeConstantObject->first()->value;
$postcodeArea = in_array($this->postcode, $centerPostcodeConstant) ? 'CENTER_POSTCODE' : null;
$postcodeArea = in_array((String)$this->postcode, $centerPostcodeConstant) ? 'CENTER_POSTCODE' : null;
$outstationPostcodeConstantObject = SegmentConstant::where('reference', SegmentConstants::OUTSTATION_POSTCODE)->get();
$outstationPostcodeConstant = $outstationPostcodeConstantObject->isEmpty() ? [] : (array)$outstationPostcodeConstantObject->first()->value;
in_array($this->postcode, $outstationPostcodeConstant) ? $postcodeArea = 'OUTSTATION_POSTCODE' : null;
in_array((String)$this->postcode, $outstationPostcodeConstant) ? $postcodeArea = 'OUTSTATION_POSTCODE' : null;
return [
'id' => $this->id,
+1 -1
View File
@@ -46,7 +46,7 @@ class OrderResource extends JsonResource
'received_packages' => PackingListResource::collection($this->packingLists()->where('type', PackingListType::WAREHOUSE_RECEIVE_LIST)->whereHas('packages')->get()),
];
}),
'invoices' => TransactionResource::collection($this->transactions),
'invoices' => TransactionResource::collection($this->transactions()->whereNotIn('transactions.status', [0, 1])->get()),
'remarks' => RemarkResource::collection($this->remarks),
'created_at' => $this->created_at->format('d-m-Y')
];
@@ -47,6 +47,7 @@ class TransactionResource extends JsonResource
->whereIn('status', [ApprovalStatus::APPROVED, ApprovalStatus::PENDING_VERIFICATION, ApprovalStatus::COMPLETED, ApprovalStatus::REJECTED])
->get()
),
'remarks' => RemarkResource::collection($this->remarks),
'expires_on' => Carbon::parse($this->expires_on)->format('d-m-Y h:s:i'),
'updated_at' => Carbon::parse($this->update_at)->format('d-m-Y')
];
+10 -1
View File
@@ -3,6 +3,7 @@
namespace App\Models;
use App\Classes\General\Interfaces\Documentable;
use App\Classes\General\Interfaces\Remarkable;
use App\Classes\General\Interfaces\Transactionable;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use App\Classes\ValueObjects\Constants\TransactionType;
@@ -13,7 +14,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Database\Eloquent\Relations\MorphTo;
class Transaction extends AbstractModel implements Documentable, Transactionable
class Transaction extends AbstractModel implements Documentable, Transactionable, Remarkable
{
protected $table = 'transactions';
@@ -122,4 +123,12 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
{
return $query->whereIn('status', [ApprovalStatus::COMPLETED]);
}
/**
* @return MorphMany
*/
public function remarks(): morphMany
{
return $this->morphMany(Remark::class, 'owner');
}
}
@@ -22,12 +22,11 @@
</div>
<div class="row">
<div class="col">
<!-- <div class="font-heading fs-10">{{item.title | truncate(20)}}</div> -->
<div class="font-heading fs-10">{{item.title}}</div>
<div class="font-heading fs-10 text-truncate">{{item.title}}</div>
</div>
</div>
</div>
<div class="col">
<div class="col-3">
<div class="row">
<div class="col-auto p-r-10">
<div class="font-heading all-caps fs-8 muted">Message</div>
@@ -35,8 +34,7 @@
</div>
<div class="row">
<div class="col">
<!-- <div class="font-heading fs-10">{{item.description | truncate(15)}}</div> -->
<div class="font-heading fs-10">{{item.description}}</div>
<div class="font-heading fs-10 text-truncate">{{item.description}}</div>
</div>
</div>
</div>
@@ -27,7 +27,24 @@
<div v-if="!item.shippng_transaction">n/a</div>
<div v-if="item.shippng_transaction">MYR {{ item.shippng_transaction.amount.toFixed(2) }}</div>
</div>
<div class="col-auto p-l-0 p-r-0" v-if="['Pending Payment', 'Paid Invoice'].includes(invoice_status)">
<div class="col" v-if="invoice_status == 'Suspended Invoice'">
<p class="no-margin fs-10 all-caps">Billing Question</p>
<div>{{ item.shippng_transaction.remarks[0].content }} </div>
</div>
<div class="col-auto p-l-0 p-r-0" v-if="['Suspended Invoice'].includes(invoice_status)">
<div class="btn bg-grey no-border muted requestModal" data-type="deleteDispute">
<i class="fa fa-close"></i>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="deleteDispute">
<delete-dispute-form-component :data="item" :section="section"></delete-dispute-form-component>
</modal-component>
</div>
<div class="col-auto p-l-0 p-r-0" v-if="['Suspended Invoice'].includes(invoice_status)">
<div class="btn bg-grey no-border muted">
<i class="fa fa-refresh"></i>
</div>
</div>
<div class="col-auto p-l-0 p-r-0" v-if="['Pending Payment', 'Paid Invoice', 'Suspended Invoice'].includes(invoice_status)">
<div v-if="item.shippng_transaction">
<div v-if="item.shippng_transaction.documents.length">
<div v-for="file in item.shippng_transaction.documents[0].files" v-bind:key="file.id" class="col-auto no-padding">
@@ -81,7 +98,7 @@
</div>
</div>
</div>
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="item.shippng_transaction && invoice_status == 'Pending Approval'">
<div class="row b-t b-grey p-t-10 m-l-5 m-r-5" v-show="expanded" v-if="item.shippng_transaction && ['Pending Approval', 'Suspended Invoice'].includes(invoice_status)">
<div class="col p-b-10">
<div class="row">
<div class="col p-l-20 p-r-20 p-t-10 p-b-10">
@@ -1,7 +1,7 @@
<template>
<div class="row m-b-15 m-l-5 m-r-10 parentContainer">
<div class="col bg-white rounded">
<div class="row">
<div class="row" :class="[{'b-danger': item.status == 5, 'b-a': item.status == 5}]">
<div class="col padding-20">
<div class="row align-items-center">
<div class="col">
@@ -11,16 +11,38 @@
<div class="col">
<p class="no-margin fs-10 all-caps">Status</p>
<div class="all-caps" v-if="item.status == 3">Payment Completed</div>
<div class="all-caps text-danger" v-else-if="item.status == 5">Suspended</div>
<div class="all-caps" v-else>Pending Payment</div>
</div>
<div class="col">
<p class="no-margin fs-10 all-caps">Amount</p>
<div>MYR {{ item.amount.toFixed(2) }}</div>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center">
<div class="col" v-if="item.remarks.length">
<p class="no-margin fs-10 all-caps">Billing Question</p>
<div>
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer">Billing Question?</span>
{{ item.remarks[0].content }}
<span class="btn requestModal no-border" v-if="item.remarks.length" data-type="editRemark">
<i class="fa fa-edit"></i>
</span>
<span class="btn requestModal no-border hide" v-if="item.remarks.length" data-type="deleteRemark">
<i class="fa fa-trash"></i>
</span>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" type="deleteRemark">
<delete-remark-form-component :section="section" :data="item.remarks[0]"></delete-remark-form-component>
</modal-component>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="editRemark">
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
</modal-component>
</div>
<div class="col-auto p-l-0 p-r-0 d-flex justify-content-center align-items-center">
<div v-if="!item.remarks.length">
<span class="d-inline-block m-r-15 text-primary bold text-underline pointer requestModal" data-type="billingRemark">Billing Question?</span>
</div>
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="billingRemark">
<customer-invoice-remark-form-component module_type="Transaction" :data="item" :section="section"></customer-invoice-remark-form-component>
</modal-component>
<div v-if="item.documents.length">
<div v-for="file in item.documents[0].files" v-bind:key="file.id" class="col-auto no-padding">
<document-file-viewer-component :file="file">
@@ -0,0 +1,77 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 50px; top: 0;" key="1" color="success" v-show="$store.getters.isLoading(section)"></loading-component>
<div class="row" v-show="!$store.getters.isLoading(section)">
<div class="col">
<div class="row m-b-20">
<div class="col">
<h6 class="all-caps m-b-5 bold no-margin">What is your billing question?</h6>
</div>
</div>
<div class="row m-b-5 animate__animated animate__fadeInUpBig animate__fast" v-if="error">
<div class="col">
<small class="bold fs-10 text-danger">{{error}}</small>
</div>
</div>
<div class="row m-b-10">
<div class="col">
<validation-wrapper-component :validator="$v.parameters.content">
<label>Billing Question</label>
<input type="text" class="form-control" v-model="parameters.content">
</validation-wrapper-component>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-default bg-master-lightest btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<div class="btn btn-sm btn-primary btn-block b-rad-none" @click="submitForm()">{{ data.remarks.length > 0 ? 'Edit' : 'Create' }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
props: {
data:{
type: Object,
required: true
},
module_type: {
type: String,
required: true
}
},
data(){
return {
parameters: {
content: this.data.remarks.length > 0 ? this.data.remarks[0].content : '',
model_type: this.module_type
}
}
},
validations: {
parameters: {
content: {
required: false
}
}
},
methods: {
submitForm() {
if (!this.data.remarks.length) {
this.submit(this.route('api.transaction.suspend', this.data.id), 'delete', this.section, false, true);
}
this.submit(this.data.remarks.length > 0 ? this.route('api.remark.update', this.data.remarks[0].id) : this.route('api.remark.create', this.data.id), this.data.remarks.length > 0 ? 'put' : 'post', this.section, true, true);
}
},
mixins: [ModalFormHandler]
}
</script>
@@ -0,0 +1,34 @@
<template>
<div class="row">
<div class="col">
<loading-component style="height: 300px; top: 0;" key="1" color="success" v-show="isLoading" ></loading-component>
<div class="row justify-content-center" v-show="!isLoading">
<div class="col">
<div class="row m-b-20">
<div class="col text-center">
<h3 class="all-caps">Are you Sure?</h3>
<div class="fs-11">Are you sure you want to delete this displute.</div>
</div>
</div>
<div class="row">
<div class="col p-r-5">
<div class="btn btn-sm btn-success btn-block b-rad-none" data-dismiss="modal">Cancel</div>
</div>
<div class="col p-l-5">
<!-- <div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.transaction.update', item.id, 'approve'), 'put', section, true, true)">Delete</div> -->
<div class="btn btn-sm btn-danger btn-block b-rad-none" @click="submit(route('api.transaction.update', item.shippng_transaction.id, 'approve'), 'put', section, true, true)">Delete</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import componentHandler from '../../../general/mixins/componentHandler';
import ModalFormHandler from '../../../general/mixins/modalFormHandler';
export default {
mixins: [componentHandler, ModalFormHandler]
}
</script>
@@ -59,8 +59,6 @@
</div>
</div>
<p>{{ data }}</p>
<div class="row m-t-15">
<div class="col">
<p class="m-b-0 small">Total</p>
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -3,7 +3,7 @@
<div class="row">
<div class="col">
<div class="row tabsContainer">
<div class="col-12 col-md-auto">
<div class="col-12 col-md-3">
<div class="row">
<div class="col">
<div class="row m-b-5">
@@ -171,7 +171,7 @@
</div>
</div>
</div>
<div class="col bg-master-lightest p-l-25 p-r-25 p-t-15 p-b-15">
<div class="col-9 bg-master-lightest p-l-25 p-r-25 p-t-15 p-b-15">
<div class="row tabsContainer tabContent" tab-name="profile">
<div class="col">
<div class="row">