mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-25 07:23:59 +00:00
fix billing page
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');
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Classes\General\Abstracts\AbstractControllerLogic;
|
||||
|
||||
class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
class DownloadBookingDocumentLogic
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -42,25 +42,21 @@ class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return JsonResponse
|
||||
* @throws \App\Classes\Exceptions\AccessForbiddenException
|
||||
* @throws \App\Classes\Exceptions\RequestValidationException
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function logic(Request $request): JsonResponse
|
||||
public function execute(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
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::disk('documents')->path('zip/'.$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('updated_at', '>=', Carbon::parse($request->input('startDate')))
|
||||
->whereDate('updated_at', '<=', Carbon::parse($request->input('endDate')))->get();
|
||||
|
||||
if (!count($bookings)) throw new MalformedRequestException('No available file to download');
|
||||
|
||||
@@ -71,23 +67,7 @@ class DownloadBookingDocumentLogic extends AbstractControllerLogic
|
||||
|
||||
$zip->close();
|
||||
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
ob_start();
|
||||
header($_SERVER['SERVER_PROTOCOL'] . ' 200 OK');
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Transfer-Encoding: Binary");
|
||||
header("Content-Length: " . filesize($attachment));
|
||||
header('Pragma: no-cache');
|
||||
header("Content-Disposition: attachment; filename=\"" . basename($attachment) . "\"");
|
||||
ob_flush();
|
||||
ob_clean();
|
||||
|
||||
readfile($attachment);
|
||||
File::delete($attachment);
|
||||
|
||||
exit;
|
||||
return Storage::download($attachment);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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')
|
||||
];
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<loading-component style="height: 50px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row m-l-0 m-r-0 bg-master-light padding-10" v-show="!isLoading">
|
||||
<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">
|
||||
@@ -44,13 +43,13 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md mb-2 mb-md-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.frequency">
|
||||
<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.monetary">
|
||||
<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>
|
||||
@@ -73,32 +72,36 @@ import {VMoney} from 'v-money'
|
||||
export default {
|
||||
data(){
|
||||
return {
|
||||
section: 'customerSectionComponent',
|
||||
isLoading: false,
|
||||
search: false,
|
||||
parameters: {
|
||||
startDate: '2021-01-01',
|
||||
endDate: '2022-01-01',
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
type: 'INVOICE',
|
||||
},
|
||||
selectedDocumentStatus: false,
|
||||
documents: ['INVOICE', 'PURCHASE_ORDER', 'DELIVERY_ORDER', 'SUPPLIER_DELIVERY_ORDER'],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitSearch(){
|
||||
this.submit(this.route('api.booking.download'), 'post', this.section, false, false)
|
||||
},
|
||||
updateDocumentType(documentType) {
|
||||
this.parameters.type = documentType;
|
||||
this.selectedDocumentStatus = !this.selectedDocumentStatus
|
||||
selectedDocumentStatus: false
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
recency: {},
|
||||
frequency: {},
|
||||
monetary: {},
|
||||
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]
|
||||
|
||||
@@ -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>
|
||||
@@ -95,30 +95,30 @@
|
||||
<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="invoice">
|
||||
<list-component key="2" section="invoiceSection" :endpoint="route('api.booking.download')" :options="{type: 'INVOICE'}">
|
||||
<list-component key="2" section="invoiceSection" :endpoint="route('api.document.list')" :options="{'per_page': 30, 'with_owner': true, 'document_type_in': ['INVOICE']}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<company-component :data="data"></company-component>
|
||||
<billing-document-component :data="data"></billing-document-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent m-l-0 m-r-0 hide" tab-name="purchase-order">
|
||||
<list-component key="2" section="purchaseOrderSection" :endpoint="route('api.booking.download')" :options="{type: 'PURCHASE_ORDER'}">
|
||||
<list-component key="2" section="purchaseOrderSection" :endpoint="route('api.document.list')" :options="{'per_page': 30, 'with_owner': true, 'document_type_in': ['PURCHASE_ORDER']}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<company-component :data="data"></company-component>
|
||||
<billing-document-component :data="data"></billing-document-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent m-l-0 m-r-0 hide" tab-name="delivery-order">
|
||||
<list-component key="2" section="deliveryOrderSection" :endpoint="route('api.booking.download')" :options="{type: 'DELIVERY_ORDER'}">
|
||||
<list-component key="2" section="deliveryOrderSection" :endpoint="route('api.document.list')" :options="{'per_page': 30, 'with_owner': true, 'document_type_in': ['DELIVER_ORDER']}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<company-component :data="data"></company-component>
|
||||
<billing-document-component :data="data"></billing-document-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
<div class="row tabsContainer tabContent m-l-0 m-r-0 hide" tab-name="supplier-delivery-order">
|
||||
<list-component key="2" section="SupplierDeliveryOrderSection" :endpoint="route('api.booking.download')" :options="{type: 'SUPPLIER_DELIVERY_ORDER'}">
|
||||
<list-component key="2" section="SupplierDeliveryOrderSection" :endpoint="route('api.document.list')" :options="{'per_page': 30, 'with_owner': true, 'document_type_in': ['SUPPLIER_DELIVER_ORDER']}">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<company-component :data="data"></company-component>
|
||||
<billing-document-component :data="data"></billing-document-component>
|
||||
</template>
|
||||
</list-component>
|
||||
</div>
|
||||
|
||||
@@ -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');
|
||||
|
||||
});
|
||||
@@ -132,6 +132,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