mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-26 16:04:05 +00:00
Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into development
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class WithOwner implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->with('owner');
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ namespace App\Classes\Modules\Billplzs\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use phpDocumentor\Reflection\Types\Boolean;
|
||||
|
||||
class CreatesBillplzBill
|
||||
{
|
||||
@@ -20,7 +19,7 @@ class CreatesBillplzBill
|
||||
* @return null|object
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null, ?Boolean $wallet = null) {
|
||||
public function execute(string $name, string $email, string $description, float $amount, string $billNumber, ?string $bankCode = null, ?bool $wallet = null) {
|
||||
try{
|
||||
// config('billplz.maybank')
|
||||
$response = Http::withBasicAuth(config('billplz.api_key').':', '')->post(config('billplz.base_url').'/api/v3/bills', [
|
||||
|
||||
@@ -3,64 +3,39 @@
|
||||
namespace App\Classes\Modules\Bookings\ControllersLogic;
|
||||
|
||||
|
||||
use Illuminate\Support\Facades\File;
|
||||
use ZipArchive;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
|
||||
class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
class DownloadBookingDocumentLogic
|
||||
{
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function notification(): array
|
||||
{
|
||||
return [
|
||||
'title' => 'Download Booking Document',
|
||||
'message' => 'You have successfully retrieved a Booking Document'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* DownloadBookingDocumentLogic constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request): JsonResponse
|
||||
public function execute(Request $request)
|
||||
{
|
||||
|
||||
Auth::login(User::findOrFail(1));
|
||||
$zip_file = 'do_' . Carbon::yesterday()->format('Y_m_d') . '.zip';
|
||||
$attachment = storage_path() . '/' . $zip_file;
|
||||
$zip_file = $request->input('type').'.zip';
|
||||
$attachment = storage_path().'/app/documents/collections/' . $zip_file;
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($attachment, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
|
||||
|
||||
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)->whereDate('updated_at', '>=', $request->input('startDate'))->whereDate('updated_at', '<=', $request->input('endDate'))
|
||||
->whereHas('transactions', function ($query) {
|
||||
return $query->where('type', TransactionType::PAYMENT)->whereHas('transactions', function ($query) {
|
||||
return $query->where('issuer', 2);
|
||||
});
|
||||
})->get();
|
||||
$bookings = Booking::where('status', ApprovalStatus::COMPLETED)
|
||||
->whereDate('created_at', '>=', Carbon::parse($request->input('startDate')))
|
||||
->whereDate('created_at', '<=', Carbon::parse($request->input('endDate')))->get();
|
||||
|
||||
if (!count($bookings)) throw new MalformedRequestException('No available file to download');
|
||||
|
||||
@@ -70,7 +45,6 @@ class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
@@ -86,9 +60,14 @@ class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
|
||||
readfile($attachment);
|
||||
File::delete($attachment);
|
||||
|
||||
|
||||
exit;
|
||||
|
||||
// header('Content-Type: application/zip');
|
||||
// header('Content-Length: ' . filesize($attachment));
|
||||
// readfile($attachment);
|
||||
// unlink($attachment);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,13 +102,13 @@ class CreditWalletLogic extends AbstractControllerLogic
|
||||
$wallet = $company->wallets()->first();
|
||||
|
||||
$billNumber = $this->generatesTransactionBillNumber->execute($type === 2 ? 'DEBIT-NOTE-' : 'CREDIT-NOTE-');
|
||||
|
||||
$transaction_object = new TransactionObject($billNumber, $type === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->company->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
|
||||
|
||||
$transaction_object = new TransactionObject($billNumber, $type === 2 ? TransactionType::DEBIT_NOTE : TransactionType::CREDIT_NOTE, 1, $wallet->owner->id, 1, PaymentMethodType::CASH, $amount, $amount, 1, 1, 1, 0, 0, null, ApprovalStatus::APPROVED, [], $reference);
|
||||
$transaction = $this->createsTransaction->execute($wallet, $transaction_object);
|
||||
|
||||
$updateWalletAmount = $type === 2 ? ($wallet->amount - $transaction->amount) : ($wallet->amount + $transaction->amount);
|
||||
|
||||
$walletObject = new WalletObject($wallet->company->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
$walletObject = new WalletObject($wallet->owner->id, $wallet->currency_id, $wallet->code, $updateWalletAmount);
|
||||
|
||||
$wallet = $this->updatesWallet->execute($wallet, $walletObject);
|
||||
|
||||
|
||||
@@ -11,9 +11,10 @@ class DownloadBookingDocumentController
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param DownloadBookingDocumentLogic $logic
|
||||
* @return JsonResponse
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function download(Request $request, DownloadBookingDocumentLogic $logic): JsonResponse {
|
||||
public function download(Request $request, DownloadBookingDocumentLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
|
||||
namespace App\Http\Controllers\Transactions;
|
||||
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\ListWalletTransactionsLogic;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Classes\Modules\Transactions\ControllersLogic\ListTransactionsLogic;
|
||||
|
||||
|
||||
class ListWalletTransactionsController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param ListTransactionsLogic $logic
|
||||
* @param ListWalletTransactionsLogic $logic
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function list(Request $request, ListTransactionsLogic $logic) : JsonResponse {
|
||||
public function list(Request $request, ListWalletTransactionsLogic $logic) : JsonResponse {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use App\Models\Booking;
|
||||
use App\Models\Company;
|
||||
use App\Models\Document;
|
||||
use Carbon\Carbon;
|
||||
@@ -23,7 +24,7 @@ class DocumentResource extends JsonResource
|
||||
'reference' => $this->reference,
|
||||
'status' => (int) $this->status,
|
||||
'document_type' => $this->document_type,
|
||||
'owner' => new CompanyResource($this->whenLoaded('owner')),
|
||||
'owner' => $this->relationLoaded('owner') ? ($this->owner instanceof Booking ? new BookingResource($this->owner) : new CompanyResource($this->owner)) : null,
|
||||
'files' => FileResource::collection($this->files),
|
||||
'created_at' => Carbon::parse($this->created_at)->format('d-m-Y h:i:s A')
|
||||
];
|
||||
|
||||
@@ -17,6 +17,7 @@ class TransactionResource extends JsonResource
|
||||
public function toArray($request)
|
||||
{
|
||||
$booking = (int)$this->type === TransactionType::BILL ? $this->owner->owner : $this->booking;
|
||||
$days = Carbon::parse($this->created_at)->addDays($booking->service_id === 1 ? 1 : 2);
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
@@ -41,8 +42,8 @@ class TransactionResource extends JsonResource
|
||||
'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'),
|
||||
'interval' => [
|
||||
'value' => (Carbon::parse($this->created_at)->addDays(3)->gt(Carbon::now()) ) ? '+' : '-' ,
|
||||
'duration' => Carbon::parse($this->created_at)->addDays(3)->diff(Carbon::now())->format('%d'),
|
||||
'value' => $days->gt(Carbon::now()) ? '+' : '-',
|
||||
'duration' => $days->diff(Carbon::now())->format('%d'),
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
+4
@@ -1184,4 +1184,8 @@
|
||||
border: 1px solid #d9d9d9;
|
||||
border-top: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.top-0 {
|
||||
top: 0;
|
||||
}
|
||||
@@ -439,6 +439,10 @@ hr{
|
||||
background: -webkit-linear-gradient(top, rgba(0,0,0,0) 0%, rgba(0,0,0,0.8) 75%);
|
||||
background: linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,0.8) 75%);
|
||||
}
|
||||
.gradient-white {
|
||||
background: -webkit-linear-gradient(top, rgba(255,255,255, 0.5) 0%, rgba(255,255,255, 0.9) 75%);
|
||||
background: linear-gradient(to bottom, rgba(255,255,255, 0.5) 0%, rgba(255,255,255, 0.9) 75%);
|
||||
}
|
||||
|
||||
/* Other Colors
|
||||
------------------------------------
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-l-0 m-r-0 bg-master-light padding-10">
|
||||
<div class="col-12 col-md mb-2 mb-md-0 pointer">
|
||||
<div class="row h-100">
|
||||
<div class="col">
|
||||
<div class="bg-white bg-hover-complete h-100 btn btn-xs btn-outline-none btn-block text-left b-rad-none p-t-0 p-b-0 p-l-15 p-r-15" @click="selectedDocumentStatus = !selectedDocumentStatus">
|
||||
<div class="row h-100">
|
||||
<div class="col fs-9 d-flex align-items-center flex-column" style="padding-top: 7px; padding-bottom: 4px;">
|
||||
<label class="all-caps w-100 m-b-0" style="font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 500;">Document Type</label>
|
||||
<span class="w-100 fs-14">{{parameters.type}}</span>
|
||||
</div>
|
||||
<div class="col-auto b-l b-grey">
|
||||
<div class="row h-100 align-items-center">
|
||||
<div class="col">
|
||||
<i class="fa" :class="[{'fa-angle-down': !selectedDocumentStatus}, {'fa-angle-up': selectedDocumentStatus}]"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative w-100">
|
||||
<div class="absolute w-100 b-l b-b b-r b-grey" :class="[{'hide': !selectedDocumentStatus}]" style="top: 100%; right: 0; z-index: 1;">
|
||||
<div class="row text-left no-margin bg-white">
|
||||
<div class="col no-padding">
|
||||
<div class="row no-margin" v-for="document in documents" :key="document">
|
||||
<div class="col b-grey p-t-10 p-b-10 pointer hover-t-10 p-b-10 b-a" @click="updateDocumentType(document)">
|
||||
<div class="row align-items-center justify-content-center">
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10">{{document}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md mb-2 mb-md-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-12 col-md mb-2 mb-md-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component :parameters="parameters" v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col-12 col-md-auto d-flex justify-content-center align-items-center">
|
||||
<button type="button" class="btn btn-lg btn-primary fs-11 w-100" @click="submitSearch()">Download</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from "../../../general/mixins/componentHandler";
|
||||
import { required, minValue} from "vuelidate/lib/validators";
|
||||
import {VMoney} from 'v-money'
|
||||
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
parameters: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
type: 'INVOICE',
|
||||
},
|
||||
documents: ['INVOICE', 'PURCHASE_ORDER', 'DELIVERY_ORDER', 'SUPPLIER_DELIVERY_ORDER'],
|
||||
selectedDocumentStatus: false
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
startDate: {
|
||||
required
|
||||
},
|
||||
endDate: {
|
||||
required
|
||||
},
|
||||
type: {
|
||||
required
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitSearch(){
|
||||
if(!this.validate()){ return; }
|
||||
window.open(route('documents.download')+'?type='+this.parameters.type+'&startDate='+this.parameters.startDate+'&endDate='+this.parameters.endDate, '_blank');
|
||||
},
|
||||
updateDocumentType(documentType) {
|
||||
this.parameters.type = documentType;
|
||||
this.selectedDocumentStatus = !this.selectedDocumentStatus
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row align-items-center m-b-15 parentContainer position-relative">
|
||||
<div class="col-auto">
|
||||
<div class="row">
|
||||
<div class="col-auto p-r-10 all-caps">
|
||||
<div class="font-heading all-caps bold">{{item.owner.marking}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps muted fs-11">{{item.owner.created_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<div class="font-heading fs-10 muted all-caps">Marking</div>
|
||||
<div class="font-heading">
|
||||
<a :href="route('customer.profile', item.owner.company.reference)">{{this.item.owner.company.reference}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div class="font-heading fs-10 muted all-caps">Document Type</div>
|
||||
<div class="font-heading">
|
||||
<span v-if="item.document_type === 'INVOICE'">Invoice</span>
|
||||
<span v-if="item.document_type === 'PURCHASE_ORDER'">Purchase Order</span>
|
||||
<span v-if="item.document_type === 'DELIVER_ORDER'">Delivery Order</span>
|
||||
<span v-if="item.document_type === 'SUPPLIER_DELIVER_ORDER'">Supplier Delivery Order</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto d-none d-lg-block">
|
||||
<div class="font-heading fs-10 muted all-caps">Currency</div>
|
||||
<div class="font-heading bold">
|
||||
<span class="flag-icon" :class="'flag-icon-'+item.owner.convertible_currency.country.short_code.toLowerCase()"></span> {{item.owner.convertible_currency.short_code}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="font-heading fs-10 muted all-caps">Payable Amount</div>
|
||||
<div class="font-heading text-success bold">{{item.owner.amount}} {{item.owner.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<document-file-viewer-component :file="item.files[0]">
|
||||
<template slot="button">
|
||||
<button class="btn btn-success">Download</button>
|
||||
</template>
|
||||
</document-file-viewer-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import componentHandler from '../../../general/mixins/componentHandler';
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler]
|
||||
}
|
||||
</script>
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="font-heading fs-10 muted all-caps">Payable Amount</div>
|
||||
<div class="font-heading text-success bold">{{this.item.amount}} {{this.item.fixed_currency.short_code}}</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isCustomer">
|
||||
<div class="col-auto hide" v-if="$store.getters.isCustomer">
|
||||
<div class="font-heading fs-10 muted all-caps">status</div>
|
||||
<div class="font-heading all-caps text-master btn-rounded p-l-10 p-r-10 lh-15 mt-1" :class="[{'bg-warning': item.status !== 3}, {'bg-success': item.status === 3} ]">
|
||||
{{item.status === 3 ? 'Complete' : 'In Progress'}}
|
||||
|
||||
@@ -28,6 +28,12 @@
|
||||
{{item.booking.company.reference}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto" v-if="$store.getters.isAdmin">
|
||||
<div class="font-heading fs-10 muted all-caps">Supplier</div>
|
||||
<div class="font-heading fs-10">
|
||||
{{item.issuer_name}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" v-if="item.status === 3">
|
||||
<div v-for="file in item.documents.files" v-bind:key="file.id" class="col-auto no-padding m-l-5">
|
||||
<document-file-viewer-component :file="file">
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{{item.payment_method === 5 || item.payment_method === 4 ? item.updated_at : item.documents.created_at}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col text-right hide">
|
||||
<div class="col text-right">
|
||||
<div class="font-heading fs-10 muted all-caps">timer</div>
|
||||
<div class="font-heading fs-12 bold" :class="[{'text-success': item.interval.value === '+'}, {'text-danger': item.interval.value === '-'}]">
|
||||
{{item.interval.value}}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
<div class="col">
|
||||
<div class="row p-t-5 p-b-20">
|
||||
<div class="col">
|
||||
<div class="row m-b-20" v-if="data.services.length > 1">
|
||||
<div class="row" v-if="data.services.length > 1">
|
||||
<div class="col">
|
||||
<div class="row m-l-0 m-r-0 m-b-5">
|
||||
<div class="col-auto p-l-0">
|
||||
@@ -41,8 +41,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row no-margin h-100" v-if="data.services.length <= 3">
|
||||
<div class="col no-padding m-b-10" :class="[{'p-l-5': index != 0}, {'p-r-5': index+1 != data.services.length}]" v-for="(service, index) in data.services" v-bind:key="service.id" >
|
||||
<div class="btn btn-md b-rad-none p-t-5 p-b-5 w-100 h-100 d-flex align-items-center justify-content-center" :class="[{'btn-success': serviceType.id === service.id}, {'bg-master-lighter': serviceType.id != service.id}]" @click="updateServiceType(service)">{{service.name}}</div>
|
||||
<div class="col no-padding m-b-10" :class="[{'p-l-5': index !== 0}, {'p-r-5': index+1 !== data.services.length}]" v-for="(service, index) in data.services" v-bind:key="service.id" >
|
||||
<div class="btn btn-xs b-rad-none padding-25 btn-block" :class="[{'btn-success': serviceType.id === service.id}, {'bg-master-lighter': serviceType.id !== service.id}]" @click="updateServiceType(service)">
|
||||
{{service.name}}
|
||||
<span class="absolute" style="right: -15px;top: -15px;width: 40px;" v-if="index !==0">
|
||||
<img src="/images/new-icon.png" class="w-100">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="data.services.length > 3">
|
||||
@@ -86,6 +91,12 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-b-20">
|
||||
<div class="col">
|
||||
<p class="no-margin" v-if="serviceType.id === 1">Recipient will receive the transfer on the <span class="text-success bold">next working day</span>. Check out on another three-day transfer option to get a better rate!</p>
|
||||
<p class="no-margin" v-if="serviceType.id === 3">Enjoy a <span class="bold text-underline">better rate</span> with this option! The recipient will receive the transfer after <span class="text-success bold">three working days</span>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-l-0 m-r-0 m-b-5">
|
||||
@@ -102,8 +113,8 @@
|
||||
</div>
|
||||
<div class="row m-b-10">
|
||||
<div class="col">
|
||||
<div class="btn btn-xs b-rad-none p-l-25 p-r-25 p-t-5 p-b-5" :class="[{'btn-success': paymentType === 1}, {'btn-default': paymentType !== 1}, {'bg-master-lighter': paymentType !== 1}]" @click="paymentType = 1">Full Payment</div>
|
||||
<div class="btn btn-xs b-rad-none p-l-25 p-r-25 m-r-5 p-t-5 p-b-5" :class="[{'btn-success': paymentType === 0}, {'btn-default': paymentType !== 0}, {'bg-master-lighter': paymentType !== 0}]" @click="paymentType = 0">Deposit</div>
|
||||
<div class="btn btn-xs b-rad-none p-l-25 p-r-25 p-t-5 p-b-5" :class="[{'btn-complete': paymentType === 1}, {'btn-default': paymentType !== 1}, {'bg-master-lighter': paymentType !== 1}]" @click="paymentType = 1">Full Payment</div>
|
||||
<div class="btn btn-xs b-rad-none p-l-25 p-r-25 m-r-5 p-t-5 p-b-5" :class="[{'btn-complete': paymentType === 0}, {'btn-default': paymentType !== 0}, {'bg-master-lighter': paymentType !== 0}]" @click="paymentType = 0">Deposit</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="paymentType === 0">
|
||||
|
||||
@@ -235,7 +235,9 @@
|
||||
style=" fill:#000000;"><defs><linearGradient x1="47.41556" y1="114.21875" x2="47.41556" y2="136.68625" gradientUnits="userSpaceOnUse" id="color-1_DGsE9caX0XGr_gr1"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="86" y1="21.78488" x2="86" y2="154.10125" gradientUnits="userSpaceOnUse" id="color-2_DGsE9caX0XGr_gr2"><stop offset="0" stop-color="#009add"></stop><stop offset="1" stop-color="#00baa4"></stop></linearGradient><linearGradient x1="111.53125" y1="27.50388" x2="111.53125" y2="49.92569" gradientUnits="userSpaceOnUse" id="color-3_DGsE9caX0XGr_gr3"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient><linearGradient x1="63.15625" y1="54.32244" x2="63.15625" y2="64.45969" gradientUnits="userSpaceOnUse" id="color-4_DGsE9caX0XGr_gr4"><stop offset="0" stop-color="#4ec9ff"></stop><stop offset="1" stop-color="#2bffe6"></stop></linearGradient></defs><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M0,172v-172h172v172z" fill="none"></path><g id="Layer_2"><path d="M55.9,134.375h-15.5875c-1.6125,0 -2.6875,-1.075 -2.6875,-2.6875v-15.5875c0,-1.075 1.34375,-1.88125 2.41875,-1.075l16.93125,16.93125c0.80625,1.075 0,2.41875 -1.075,2.41875z" fill="url(#color-1_DGsE9caX0XGr_gr1)"></path><path d="M150.5,96.75v-37.625c0,-5.9125 -4.8375,-10.75 -10.75,-10.75h-7.525c1.34375,-2.95625 2.15,-6.18125 2.15,-9.40625c0,-12.63125 -10.2125,-22.84375 -22.84375,-22.84375c-12.63125,0 -22.84375,10.2125 -22.84375,22.84375c0,3.225 0.80625,6.45 2.15,9.40625h-12.9c-4.03125,-3.225 -9.1375,-5.375 -14.78125,-5.375c-5.64375,0 -10.75,2.15 -14.78125,5.375h-21.5c-2.95625,0 -5.64375,1.34375 -7.79375,3.225c-1.88125,2.15 -2.95625,4.8375 -2.95625,7.525v0v83.3125c0,7.525 5.9125,13.4375 13.4375,13.4375h107.5c7.525,0 13.4375,-5.9125 13.4375,-13.4375v-18.8125c2.95625,0 5.375,-2.41875 5.375,-5.375v-16.125c0,-2.95625 -2.41875,-5.375 -5.375,-5.375zM111.53125,21.5c9.675,0 17.46875,7.79375 17.46875,17.46875c0,9.675 -7.79375,17.46875 -17.46875,17.46875c-9.675,0 -17.46875,-7.79375 -17.46875,-17.46875c0,-9.675 7.79375,-17.46875 17.46875,-17.46875zM111.53125,61.8125c6.9875,0 13.16875,-3.225 17.46875,-8.0625h10.75c2.95625,0 5.375,2.41875 5.375,5.375v8.0625c-2.15,-1.6125 -5.10625,-2.6875 -8.0625,-2.6875h-51.0625c-0.26875,-4.03125 -1.34375,-7.525 -3.49375,-10.75h11.55625c4.3,4.8375 10.48125,8.0625 17.46875,8.0625zM80.625,64.5h-34.9375c0.80625,-9.1375 8.33125,-16.125 17.46875,-16.125c9.1375,0 16.6625,6.9875 17.46875,16.125zM23.1125,55.3625c0.80625,-1.075 2.15,-1.6125 3.7625,-1.6125h16.93125c-1.88125,3.225 -3.225,6.71875 -3.49375,10.75h-13.16875c-2.95625,0 -5.375,-2.15 -5.64375,-5.10625c0,-1.34375 0.5375,-2.95625 1.6125,-4.03125zM145.125,142.4375c0,4.56875 -3.49375,8.0625 -8.0625,8.0625h-107.5c-4.56875,0 -8.0625,-3.49375 -8.0625,-8.0625v-74.175c1.6125,1.075 3.7625,1.6125 5.9125,1.6125h13.16875h42.73125h53.75c4.56875,0 8.0625,3.49375 8.0625,8.0625v18.8125h-5.375v-13.4375c0,-4.56875 -3.49375,-8.0625 -8.0625,-8.0625h-96.75c-4.56875,0 -8.0625,3.49375 -8.0625,8.0625v53.75c0,4.56875 3.49375,8.0625 8.0625,8.0625h96.75c4.56875,0 8.0625,-3.49375 8.0625,-8.0625v-13.4375h5.375zM120.9375,96.75c-7.525,0 -13.4375,5.9125 -13.4375,13.4375c0,7.525 5.9125,13.4375 13.4375,13.4375h13.4375v13.4375c0,1.6125 -1.075,2.6875 -2.6875,2.6875h-96.75c-1.6125,0 -2.6875,-1.075 -2.6875,-2.6875v-53.75c0,-1.6125 1.075,-2.6875 2.6875,-2.6875h96.75c1.6125,0 2.6875,1.075 2.6875,2.6875v13.4375zM129,110.1875c0,4.56875 -3.49375,8.0625 -8.0625,8.0625c-4.56875,0 -8.0625,-3.49375 -8.0625,-8.0625c0,-4.56875 3.49375,-8.0625 8.0625,-8.0625c4.56875,0 8.0625,3.49375 8.0625,8.0625zM131.6875,118.25c1.6125,-2.15 2.6875,-5.10625 2.6875,-8.0625c0,-2.95625 -1.075,-5.9125 -2.6875,-8.0625h18.8125v16.125z" fill="url(#color-2_DGsE9caX0XGr_gr2)"></path><circle cx="41.5" cy="14.5" transform="scale(2.6875,2.6875)" r="4.5" fill="url(#color-3_DGsE9caX0XGr_gr3)"></circle><path d="M74.98125,64.5c-0.80625,-5.9125 -5.64375,-10.75 -11.825,-10.75c-6.18125,0 -11.2875,4.8375 -11.825,10.75z" fill="url(#color-4_DGsE9caX0XGr_gr4)"></path></g></g></svg>
|
||||
</div>
|
||||
<p class="no-margin bold all-caps">Wallet Credit</p>
|
||||
<p class="no-margin bold text-primary fs-10">(Better Rate)</p>
|
||||
</div>
|
||||
<span class="absolute" style="right: 5px;top: 5px;width: 25px;"><img src="/images/hot.png" class="w-100"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,69 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row padding-15">
|
||||
<div class="col bg-white padding-15">
|
||||
<div class="bold d-flex align-items-center m-b-10">
|
||||
<span class="rounded badge-success m-r-10 padding-5 p-l-15 p-r-15">New</span> March 1, 2020
|
||||
<div class="row m-b-20 parentContainer" v-if="data.id === 9">
|
||||
<div class="col-auto">
|
||||
<img src="/images/first_topup_badge.png" class="pointer requestModal" data-type="badgeModal" style="width: 50px;">
|
||||
</div>
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="badgeModal" size="extra-large">
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<div class="row m-b-50">
|
||||
<div class="col bg-white padding-15">
|
||||
<h5 class="text-center text-success bold">Congratulation! You've earned and achievement</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-8">
|
||||
<img src="/images/first_topup_badge.png" class="animate__animated animate__infinite animate__tada w-100">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</modal-component>
|
||||
</div>
|
||||
<div class="row m-l-0 m-r-0 m-b-15">
|
||||
<div class="col bg-white padding-15">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="bold d-flex align-items-center m-b-10">
|
||||
<span class="rounded badge-success m-r-10 padding-5 p-l-15 p-r-15">New</span> March 1, 2020
|
||||
</div>
|
||||
<h5 class="bold fs-18">Try out our wallet to get a better rate now.</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<img class="m-b-10 w-100" src="/images/10107.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" :class="[{'h-25': !expanded}, {'overflow-hidden': !expanded}]">
|
||||
<div class="col position-relative">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<p>Transferring your payments by using the wallet just got a lot easier.</p>
|
||||
<div class="row">
|
||||
<div class="col" v-if="expanded">
|
||||
<p class="no-margin">This release you can:</p>
|
||||
<p class="no-margin">1. Top up once, pay for multiple transfers</p>
|
||||
<p class="no-margin">2. Get your refund back to your wallet</p>
|
||||
<p class="no-margin">3. Get a better exchange rate.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row position-absolute top-0 w-100 gradient-white p-t-15 p-b-15" v-if="!expanded">
|
||||
<div class="col">
|
||||
<div class="m-b-0 m-t-5 d-flex justify-content-center cursor" @click="expanded = !expanded">Show more <i class="fa fa-angle-down fs-20 bold m-l-10"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="expanded">
|
||||
<div class="col">
|
||||
<div class="m-b-0 m-t-5 d-flex justify-content-center cursor" @click="expanded = !expanded">Show less <i class="fa fa-angle-up fs-20 bold m-l-10"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="bold fs-18">Try out our wallet to get a better rate now.</h5>
|
||||
<img class="m-b-10" src="http://localhost/others/cief/exchange-2.0/public/images/temp_reload_annnouncement.jpg" />
|
||||
<p>Transfering your payments by using the wallet just got a lot easier.</p>
|
||||
<p>This release can:</p>
|
||||
<p>1. Top up once, upload ONE bankslip and you get to pay multiple transactions</p>
|
||||
<p>2. Get your refund back to your wallet and easier for you to make the next payment (if applicable)</p>
|
||||
<p>3. Get a better exchange rate.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="!reload">
|
||||
@@ -70,6 +121,7 @@
|
||||
data(){
|
||||
return {
|
||||
reload: false,
|
||||
expanded: false
|
||||
}
|
||||
},
|
||||
mixins: [componentHandler],
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="font-heading all-caps fs-11">{{data.created_at}}</div>
|
||||
<div class="font-heading all-caps fs-11">{{data.updated_at}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
<div class="btn btn-block btn-sm b-rad-none p-t-10 p-b-10 lh-15" @click="parameters.amount = '50000.00'" :class="[{'btn-complete': parseInt(parameters.amount.replace(/\,/g,'')) === 50000}, {'btn-default': parseInt(parameters.amount.replace(/\,/g,'')) !== 50000}]">MYR<br>50,000</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-15 justify-content-center parentContainer" v-if="parseInt(parameters.amount.replace(/\,/g,'')) > 0" >
|
||||
<div class="row m-t-15 justify-content-center parentContainer" v-if="parseFloat(parameters.amount.replace(/\,/g,'')) > 0" >
|
||||
<div class="col-10">
|
||||
<div class="btn btn-sm btn-complete btn-block b-rad-none requestModal" data-type="paymentSummary">Reload Credit</div>
|
||||
</div>
|
||||
@@ -108,7 +108,7 @@
|
||||
amount: '0.00',
|
||||
transaction_type: 0,
|
||||
reference: ''
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
created(){
|
||||
@@ -119,7 +119,7 @@
|
||||
parameters: {
|
||||
amount: {
|
||||
required,
|
||||
minValue: 10.000,
|
||||
minValue: minValue(this.minValue),
|
||||
},
|
||||
reference: {
|
||||
required: requiredIf(function () { return this.parameters.transaction_type !== 0 })
|
||||
@@ -127,6 +127,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
minValue()
|
||||
{
|
||||
return this.transaction_type === 0 ? 10.0000 : 0;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
successHandler(response){
|
||||
if (this.parameters.transaction_type === 0) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -82,28 +82,28 @@
|
||||
<div class="row no-margin">
|
||||
<div class="col bg-white padding-25">
|
||||
<div class="row tabsContainer tabContent m-l-0 m-r-0" tab-name="top-up">
|
||||
<list-component key="2" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="{type: 5, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<list-component key="2" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="{type: 5, status: 2, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<wallet-transaction-component :data="data"></wallet-transaction-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide m-l-0 m-r-0 hide" tab-name="payments">
|
||||
<list-component key="2" section="payments" :endpoint="route('api.transaction.wallet.list')" :options="{type: 1, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<list-component key="2" section="payments" :endpoint="route('api.transaction.wallet.list')" :options="{type: 1, status: 2, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<wallet-transaction-component :data="data"></wallet-transaction-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide m-l-0 m-r-0 hide" tab-name="credit-note">
|
||||
<list-component key="2" section="creditNote" :endpoint="route('api.transaction.wallet.list')" :options="{type: 9, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<list-component key="2" section="creditNote" :endpoint="route('api.transaction.wallet.list')" :options="{type: 9, status: 2, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<wallet-transaction-component :data="data"></wallet-transaction-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent hide m-l-0 m-r-0 hide" tab-name="debit-note">
|
||||
<list-component key="2" section="debitNote" :endpoint="route('api.transaction.wallet.list')" :options="{type: 11, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<list-component key="2" section="debitNote" :endpoint="route('api.transaction.wallet.list')" :options="{type: 11, status: 2, owner_type: 'App\\Models\\Wallet', per_page: 30}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<wallet-transaction-component :data="data"></wallet-transaction-component>
|
||||
</template>
|
||||
|
||||
@@ -25,7 +25,12 @@
|
||||
</div>
|
||||
<div class="col-auto p-r-20" v-if="$store.getters.isAdmin">
|
||||
<a href="{{route('payments')}}">
|
||||
<div class="text-white all-caps fs-12">Payments & Billing</div>
|
||||
<div class="text-white all-caps fs-12">Payments</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto p-r-20" v-if="$store.getters.isAdmin">
|
||||
<a href="{{route('billings')}}">
|
||||
<div class="text-white all-caps fs-12">Billings</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-auto p-r-20" v-if="$store.getters.isAdmin">
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -32,6 +32,4 @@ Route::group(['prefix' => 'booking', 'as' => 'booking.', 'namespace' => 'Booking
|
||||
|
||||
Route::post('{id}/proforma/create', 'CreateProformaInvoiceTransaction@create')->name('proforma.create');
|
||||
|
||||
Route::get('/document/download', 'DownloadBookingDocumentController@download')->name('download');
|
||||
|
||||
});
|
||||
+26
-19
@@ -6,6 +6,7 @@ use App\Classes\Modules\Documents\Services\CreatesFiles;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Company;
|
||||
use App\Models\Transaction;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -62,6 +63,10 @@ Route::get('/payments', function () {
|
||||
return view('pages.payments');
|
||||
})->name('payments');
|
||||
|
||||
Route::get('/billings', function () {
|
||||
return view('pages.billings');
|
||||
})->name('billings');
|
||||
|
||||
Route::get('/currency_orders', function () {
|
||||
return view('pages.currency_orders');
|
||||
})->name('currency_orders');
|
||||
@@ -92,25 +97,25 @@ Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsP
|
||||
})->name('products.random');
|
||||
|
||||
Route::get('/fix_bills', function () {
|
||||
ini_set('max_execution_time', '10000');
|
||||
Auth()->login(User::find(1));
|
||||
Transaction::where('type', TransactionType::SUPPLIER_DELIVER)->whereIn('issuer', [2165])->chunk(50, function($dos){
|
||||
foreach ($dos as $do){
|
||||
$do->booking->documents()->where('document_type', DocumentType::SUPPLIER_DELIVER_ORDER)->delete();
|
||||
$supplier = [];
|
||||
$po = $do->booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
$supplier_order_pdf = LaravelMpdf::loadView('pages.pdfs.supplier_deliver_order', ['supplier_deliver_order_transaction' => $do, 'po_order_transaction' => $po, 'supplier' => $supplier]);
|
||||
$document_object = new DocumentObject(
|
||||
DocumentType::SUPPLIER_DELIVER_ORDER,
|
||||
[chunk_split('data:application/pdf;base64,'.base64_encode($supplier_order_pdf->output()))],
|
||||
'',
|
||||
ApprovalStatus::COMPLETED,
|
||||
'supplier_delivery_orders'
|
||||
);
|
||||
$document = (App()->make(CreatesDocument::class))->execute($do->booking, $document_object);
|
||||
(App()->make(CreatesFiles::class))->execute($document, $document_object);
|
||||
}
|
||||
});
|
||||
// ini_set('max_execution_time', '1000000');
|
||||
// Auth()->login(User::find(1));
|
||||
// Transaction::where('type', TransactionType::INVOICE)->chunk(200, function($invoices){
|
||||
// foreach ($invoices as $invoice){
|
||||
// $invoice->booking->documents()->where('document_type', DocumentType::INVOICE)->delete();
|
||||
// $po = $invoice->booking->transactions()->where('type', TransactionType::PURCHASE_ORDER)->first();
|
||||
// $supplier = Company::find($invoice->receiver);
|
||||
// $invoice_pdf = LaravelMpdf::loadView('pages.pdfs.invoice', ['invoice_transaction' => $invoice, 'po_order_transaction' => $po, 'supplier' => $supplier]);
|
||||
// $document_object = new DocumentObject(
|
||||
// DocumentType::INVOICE,
|
||||
// [chunk_split('data:application/pdf;base64,'.base64_encode($invoice_pdf->output()))],
|
||||
// '',
|
||||
// ApprovalStatus::COMPLETED,
|
||||
// 'invoices'
|
||||
// );
|
||||
// $document = (App()->make(CreatesDocument::class))->execute($invoice->booking, $document_object);
|
||||
// (App()->make(CreatesFiles::class))->execute($document, $document_object);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
})->name('products.random');
|
||||
@@ -128,6 +133,8 @@ Route::get('/bookings/billplz', function () {
|
||||
return view('pages.billplz_redirect');
|
||||
})->name('bookings.billplz');
|
||||
|
||||
Route::get('/document/download', 'Bookings\DownloadBookingDocumentController@download')->name('documents.download');
|
||||
|
||||
Route::get('billplz/bills/{bill_no}', function($bill_no){
|
||||
return redirect(env('BILLPLZ_BASE_URL').'/bills/'.$bill_no);
|
||||
})->name('billplz.bill');
|
||||
|
||||
Reference in New Issue
Block a user