mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-29 17:34:02 +00:00
Merge branch 'master' of gitlab.com:CIEFWorldwideSdnBhd/exchange-2.0 into development
This commit is contained in:
@@ -16,6 +16,8 @@ class CreatedAfterOrEqual implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('created_at', '>=', Carbon::parse($value));
|
||||
$table = $builder->getModel()->getTable();
|
||||
$startDate = Carbon::createFromFormat('d-m-Y', $value)->startOfDay();
|
||||
return $builder->where("{$table}.created_at", '>=', $startDate);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ class CreatedBeforeOrEqual implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('created_at', '<=', Carbon::parse($value));
|
||||
$table = $builder->getModel()->getTable();
|
||||
$endDate = Carbon::createFromFormat('d-m-Y', $value)->endOfDay();
|
||||
return $builder->where("{$table}.created_at", '<=', $endDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ class OwnerId implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('owner_id', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->where("{$table}.owner_id", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,8 @@ class OwnerType implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->where('owner_type', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->where("{$table}.owner_type", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,8 @@ class StatusIn implements Filter
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->whereIn('status', $value);
|
||||
$table = $builder->getModel()->getTable();
|
||||
return $builder->whereIn("{$table}.status", $value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\General\Eloquent\Filters;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use App\Models\Booking;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class WithBookingMarkingLike implements Filter
|
||||
{
|
||||
|
||||
/**
|
||||
* @param Builder $builder
|
||||
* @param $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function apply(Builder $builder, $value)
|
||||
{
|
||||
return $builder->join('transactions as t2', 't2.payment_reference', '=', 'transactions.bill_no')
|
||||
->join('bookings', function ($join) use ($value) {
|
||||
$join->on('bookings.id', '=', 't2.owner_id')
|
||||
->where('bookings.marking', 'LIKE', '%'.$value.'%');
|
||||
})
|
||||
->addSelect(['transactions.*','t2.owner_id as bookingId', 'bookings.marking as bookingMarking']);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ class GeneratesBookingMarking
|
||||
*/
|
||||
public function execute(): int {
|
||||
|
||||
$marking = mt_rand(20000, 99999);
|
||||
$marking = mt_rand(100000, 999999);
|
||||
return !$this->bookingMarkingExists->execute($marking) ? $marking : self::execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Companies\ControllersLogic;
|
||||
|
||||
|
||||
use App\Classes\ValueObjects\Constants\TransactionType;
|
||||
use ZipArchive;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Classes\Exceptions\MalformedRequestException;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\ValueObjects\Constants\DocumentType;
|
||||
use App\Models\Company;
|
||||
|
||||
class BulkDownloadCustomerInvoicesLogic
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return void
|
||||
* @throws MalformedRequestException
|
||||
*/
|
||||
public function execute(Request $request)
|
||||
{
|
||||
$company = Company::where('reference', $request->input('marking'))->first();
|
||||
|
||||
$startDate = $request->input('startDate');
|
||||
$endDate = $request->input('endDate');
|
||||
if ($company) {
|
||||
$invoicebookings = $company->bookings()->whereDate('created_at', '>=', $startDate)
|
||||
->whereDate('created_at', '<=', $endDate)
|
||||
->whereHas('transactions', function ($query) {
|
||||
$query->where('transactions.type', TransactionType::INVOICE)
|
||||
->whereIn('transactions.status', [ApprovalStatus::APPROVED, ApprovalStatus::COMPLETED]);
|
||||
})->orderBy('created_at')->get();
|
||||
|
||||
|
||||
if (count($invoicebookings) > 0) {
|
||||
$zip_file = "invoices_{$startDate}_to_{$endDate}_{$company->reference}.zip";
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zip_file, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE)) {
|
||||
foreach($invoicebookings as $booking) {
|
||||
$invoice_file = $booking->documents()->where('document_type', DocumentType::INVOICE)->whereNull('deleted_at')->first()->files()->first();
|
||||
$zip->addFile(Storage::disk('documents')->path($invoice_file->file->file_info->original->file), 'invoice-' . $booking->created_at->format('d_m_Y') . '_' . $booking->marking . '.pdf');
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
while (ob_get_level()) {
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return response()->download($zip_file);
|
||||
}
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'Failed',
|
||||
'message' => 'No invoices found for this customer in the given date range.',
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
return response()->json([
|
||||
'status' => 'Failed',
|
||||
'message' => 'Customer not found.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,8 @@ class GeneratesTransactionBillNumber
|
||||
|
||||
$attempt = 0;
|
||||
while ($attempt < 10) { // Retry up to 10 times
|
||||
$billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . microtime(true);
|
||||
// $billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . intval(microtime(true));
|
||||
$billNumber = $prefix . $date->format('Y') . $date->format('m') . '-' . mt_rand(1000000, 9999999);
|
||||
if (!$this->checksIfTransactionBillNumberExists->execute($billNumber)) {
|
||||
return $billNumber;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Companies;
|
||||
|
||||
use App\Classes\Modules\Companies\ControllersLogic\BulkDownloadCustomerInvoicesLogic;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class BulkDownloadCustomerInvoicesController
|
||||
{
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param BulkDownloadCustomerInvoicesLogic $logic
|
||||
* @return void
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function download(Request $request, BulkDownloadCustomerInvoicesLogic $logic) {
|
||||
return $logic->execute($request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-5" @keyup.enter="submitSearch">
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.marking">
|
||||
<label class="all-caps">Marking</label>
|
||||
<!-- <input type="text" class="form-control" v-model="parameters.marking" :class="[{ 'not-allowed': hasMarkingParameter }]" :disabled="hasMarkingParameter"> -->
|
||||
<input type="text" class="form-control" v-model="parameters.marking" :class="[{ 'not-allowed': hasMarking }]" :disabled="hasMarking">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col 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>
|
||||
<loading-component style="height: 100px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div class="row align-items-center justify-content-center bg-white p-t-50 p-b-50 p-l-15 p-r-15 margin-15"
|
||||
v-if="!isLoading && returnData">
|
||||
<div class="col-10">
|
||||
<div class="row align-items-center justify-content-center hint-text">
|
||||
<div class="col-4 hint-text"><img src="/images/not-found-illustration.png"
|
||||
class="w-100 hint-text" /></div>
|
||||
</div>
|
||||
<div class="row text-center">
|
||||
<div class="col">
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
<p class="all-caps no-margin fs-11" style="letter-spacing: 2px;">{{ returnData.message
|
||||
}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { required } from "vuelidate/lib/validators";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
key: 1,
|
||||
returnData: null,
|
||||
isLoading: false,
|
||||
hasMarking: false,
|
||||
parameters: {
|
||||
marking: null,
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
marking: { required },
|
||||
startDate: { required },
|
||||
endDate: { required },
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
if (urlSearchParams.has('marking')) {
|
||||
this.parameters.marking = urlSearchParams.get('marking');
|
||||
}
|
||||
this.hasMarkingParameter();
|
||||
},
|
||||
methods: {
|
||||
submitSearch() {
|
||||
this.isLoading = true;
|
||||
this.submit(this.route('api.customers.invoices'), 'post', this.section, false, false);
|
||||
},
|
||||
errorHandler(error) {
|
||||
this.isLoading = false;
|
||||
console.log(error);
|
||||
},
|
||||
successHandler(response) {
|
||||
this.isLoading = false;
|
||||
this.returnData = response;
|
||||
},
|
||||
hasMarkingParameter() {
|
||||
const urlSearchParams = new URLSearchParams(window.location.search);
|
||||
this.hasMarking = urlSearchParams.has('marking');
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,6 +1,29 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row m-b-5" @keyup.enter="submitSearch">
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.reference_no">
|
||||
<label class="all-caps">Booking Reference</label>
|
||||
<input type="text" class="form-control" v-model="parameters.reference_no">
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.startDate">
|
||||
<label class="all-caps">Start Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.startDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col p-r-0">
|
||||
<validation-wrapper-component :validator="$v.parameters.endDate">
|
||||
<label class="all-caps">End Date</label>
|
||||
<date-picker-component v-model.lazy="parameters.endDate"></date-picker-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
<div class="col 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()">Search</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row padding-10">
|
||||
@@ -11,7 +34,7 @@
|
||||
<div class="col-2 fs-10 text-right">Balance</div>
|
||||
</div>
|
||||
|
||||
<list-component :key="key" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="{status_in: [2, 3], owner_type: 'App\\Models\\Wallet', owner_id: wallet_id, per_page: showingTransactionCount}">
|
||||
<list-component :key="key" section="topUp" :endpoint="route('api.transaction.wallet.list')" :options="options">
|
||||
<template slot="list" slot-scope="{data}">
|
||||
<customer-wallet-transaction-component :data="data" :deciamls="deciamls"></customer-wallet-transaction-component>
|
||||
</template>
|
||||
@@ -39,12 +62,50 @@ export default {
|
||||
data(){
|
||||
return {
|
||||
key: 1,
|
||||
parameters: {
|
||||
reference_no: null,
|
||||
startDate: null,
|
||||
endDate: null,
|
||||
},
|
||||
options: {
|
||||
status_in: [2, 3],
|
||||
owner_type: 'App\\Models\\Wallet',
|
||||
owner_id: this.wallet_id,
|
||||
per_page: this.showingTransactionCount
|
||||
}
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
parameters: {
|
||||
reference_no: { },
|
||||
startDate: { },
|
||||
endDate: { },
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showingTransactionCount() {
|
||||
this.options.per_page = this.showingTransactionCount;
|
||||
this.key ++;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submitSearch() {
|
||||
delete this.options.with_booking_marking_like;
|
||||
delete this.options.created_after_or_equal;
|
||||
delete this.options.created_before_or_equal;
|
||||
|
||||
if (this.parameters.reference_no) {
|
||||
this.options.with_booking_marking_like = this.parameters.reference_no
|
||||
}
|
||||
if (this.parameters.startDate) {
|
||||
this.options.created_after_or_equal = this.parameters.startDate
|
||||
}
|
||||
if (this.parameters.endDate) {
|
||||
this.options.created_before_or_equal = this.parameters.endDate
|
||||
}
|
||||
|
||||
this.key ++;
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
+27
-27
@@ -1,36 +1,37 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
|
||||
<div class="col no-padding">
|
||||
<h6>Wallet Transaction History</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<span class="btn btn-md fs-11 bg-primary text-white fs-12 bold m-r-5" :class="[{'bg-primary-darker': showingPreciseAmount}]" @click="showingPreciseAmount=!showingPreciseAmount">{{ showingPreciseAmount ? 'Showing Precise Wallet Transaction' : 'Show Precise Wallet Transaction'}}</span>
|
||||
<a v-if="company" :href="route('wallet.details-export', company.reference, showingPreciseAmount)" target="_blank" class="btn btn-md btn-primary fs-11"><i class="fa fa-download m-r-5"></i>{{ showingPreciseAmount ? 'Download Precise Transaction' : 'Download Transaction'}}</a>
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
<div v-if="!isLoading">
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="row p-b-5 b-b b-grey m-b-10 m-l-0 m-r-0">
|
||||
<div class="col no-padding">
|
||||
<h6>Wallet Transaction History</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<validation-wrapper-component selectable :validator="$v.showingTransactionCount">
|
||||
<label>Showing Rows</label>
|
||||
<select-component :options="[5, 10, 20, 30, 50]" v-model="showingTransactionCount"></select-component>
|
||||
</validation-wrapper-component>
|
||||
<div class="row m-t-10 m-b-10">
|
||||
<div class="col">
|
||||
<div class="d-flex align-items-center h-100">
|
||||
<span class="btn btn-md fs-11 bg-primary text-white fs-12 m-r-5" :class="[{'bg-primary-darker': showingPreciseAmount}]" @click="showingPreciseAmount=!showingPreciseAmount">{{ showingPreciseAmount ? 'Showing Precise Wallet Transaction' : 'Show Precise Wallet Transaction'}}</span>
|
||||
<a v-if="company" :href="route('wallet.details-export', company.reference, showingPreciseAmount)" target="_blank" class="btn btn-md btn-primary fs-11"><i class="fa fa-download m-r-5"></i>{{ showingPreciseAmount ? 'Download Precise Transaction' : 'Download Transaction'}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<validation-wrapper-component selectable :validator="$v.showingTransactionCount">
|
||||
<label>Showing Rows</label>
|
||||
<select-component :options="[5, 10, 20, 30, 50]" v-model="showingTransactionCount"></select-component>
|
||||
</validation-wrapper-component>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="!showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="2" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
<div v-show="showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="5" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
</div>
|
||||
<div v-show="!showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="2" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
<div v-show="showingPreciseAmount">
|
||||
<customer-transaction-component :deciamls="5" :wallet_id="wallet_id" :showingTransactionCount="showingTransactionCount"></customer-transaction-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 m-l-15">
|
||||
<div v-if="!isLoading">
|
||||
<div class="col-3 m-l-15">
|
||||
<wallet-component :data="company" :creditable=true></wallet-component>
|
||||
<div class="row m-t-20">
|
||||
<div class="col">
|
||||
@@ -68,7 +69,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<loading-component style="height: 200px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<div class="col-auto">
|
||||
<div class="btn btn-xs p-l-15 p-r-20 b-rad-none font-heading btn-rounded bg-white" @click="reload = true"><i class="fa fa-plus fs-8 m-r-5"></i> Reload</div>
|
||||
</div>
|
||||
<div class="col-auto p-l-0" v-if="!mini">
|
||||
<div class="col-auto p-l-0" v-if="!mini && data.wallet">
|
||||
<a class="text-white fs-10" :href="route('wallet.details', data.reference)" target="_blank">Transaction History<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -52,9 +52,18 @@
|
||||
<wallet-top-up-form-component :data="data" :amount="(!data.wallet ? amount : (Math.round((((amount - data.wallet.amount) < '0.00' ? '0.00' : (amount - data.wallet.amount)) + Number.EPSILON) * 100) / 100).toFixed(2))" :creditable="creditable"></wallet-top-up-form-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-20" v-if="$store.getters.isAdmin">
|
||||
<div class="row m-t-10" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<a :href="route('account.statment', data.reference)">View Account Statement<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
<div class="row m-t-10" v-if="$store.getters.isSuperAdmin">
|
||||
<div class="col">
|
||||
<a :href="route('account.statment', data.reference)">View Account Statement<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row m-t-10">
|
||||
<div class="col">
|
||||
<a :href="downloadInvoiceUrl()">Download All Invoices<i class="fa fa-angle-right p-l-5"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,6 +88,11 @@
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
downloadInvoiceUrl(){
|
||||
return this.route('customers.invoices') + '?marking=' + this.data.reference;
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
reload: false,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
@extends('layouts.base_portal')
|
||||
@section('inner_content')
|
||||
<div class="row" v-if="$store.getters.isAdmin">
|
||||
<div class="col">
|
||||
<bulk-download-invoice-component section="BulkDownloadInvoiceComponent"></bulk-download-invoice-component>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -32,6 +32,7 @@ Route::group(['middleware' => 'api', 'prefix' => 'v1', 'as' => 'api.'], function
|
||||
Route::post('/import/upload-honey-trap', 'Imports\ImportHoneyTrapController@import')->name('honey_trap.upload');
|
||||
Route::post('/import/upload-import-invoices', 'Imports\ImportStatementInvoiceController@import')->name('import_invoices.upload');
|
||||
Route::post('/import/upload-import-receipt', 'Imports\ImportStatementReceiptsController@import')->name('import_receipts.upload');
|
||||
Route::post('/customers/invoices', 'Companies\BulkDownloadCustomerInvoicesController@download')->name('customers.invoices');
|
||||
|
||||
require __DIR__ . '/company.php';
|
||||
|
||||
|
||||
@@ -145,6 +145,10 @@ Route::get('/purchase_orders', function () {
|
||||
return view('pages.purchase_orders');
|
||||
})->name('purchase_orders');
|
||||
|
||||
Route::get('/customers/invoices', function () {
|
||||
return view('pages.customer_invoices_bulk_download');
|
||||
})->name('customers.invoices');
|
||||
|
||||
Route::get('/support', function () {
|
||||
return view('pages.customer_support', [
|
||||
'marking' => null,
|
||||
|
||||
Reference in New Issue
Block a user