Merge branch 'dillon/90-e-invoice-f' into vapor/development

This commit is contained in:
Dillon Ngo
2025-07-23 21:19:43 +08:00
6 changed files with 209 additions and 7 deletions
@@ -0,0 +1,82 @@
<?php
namespace App\Classes\Modules\Imports\ControllersLogic;
use App\Classes\Exceptions\MalformedRequestException;
use App\Classes\General\Abstracts\AbstractControllerLogic;
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
use App\Classes\ValueObjects\Constants\ApprovalStatus;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
class ImportExcelLogic extends AbstractControllerLogic
{
/**
* @return array
*/
protected function notification():array {
return [
'title' => 'Import Excel',
'message' => 'You have successfully imported and updated booking details'
];
}
/**
* @param Request $request
* @return JsonResponse
* @throws MalformedRequestException
*/
public function logic(Request $request) : JsonResponse
{
$files = $request->file('files');
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
foreach ($object->getFiles() as $file){
$collection = Excel::toCollection(null, json_decode($file)->file_info->original->file, null, null, true);
$rows = $collection->first()->skip(1);
foreach ($rows as $index => $details) {
$docNo = $details[0] ?? null;
$docDate = $details[1] ?? null;
$debtorCode = $details[2] ?? null;
$ref = $details[3] ?? null;
$shipInfo = $details[4] ?? null;
$accNo = $details[5] ?? null;
$detailDescription = $details[6] ?? null;
$furtherDescription = $details[7] ?? null;
$classification = $details[8] ?? null;
$deptNo = $details[9] ?? null;
$qty = $details[10] ?? null;
$unitPrice = $details[11] ?? null;
$submitEinvoice = $details[12] ?? null;
$consolidatedEinvoice = $details[13] ?? null;
$eInvoiceValidationLink = $details[14] ?? null; // Safe access for the new column
Log::info("Row {$index} Details:", [
'DocNo' => $docNo,
'DocDate' => $docDate,
'DebtorCode' => $debtorCode,
'Ref' => $ref,
'ShipInfo' => $shipInfo,
'AccNo' => $accNo,
'DetailDescription' => $detailDescription,
'FurtherDescription' => $furtherDescription,
'Classification' => $classification,
'DeptNo' => $deptNo,
'Qty' => $qty,
'UnitPrice' => $unitPrice,
'SubmitEinvoice' => $submitEinvoice,
'ConsolidatedEinvoice' => $consolidatedEinvoice,
'EInvoiceValidationLink' => $eInvoiceValidationLink,
]);
}
}
return $this->response([]);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers\Imports;
use App\Classes\Modules\Imports\ControllersLogic\ImportExcelLogic;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ImportController extends Controller
{
public function salesInvoices(Request $request, ImportExcelLogic $logic): JsonResponse
{
return $logic->execute($request);
}
}
@@ -3,7 +3,7 @@
<div class="col">
<div class="row">
<div class="col">
<div class="row m-l-0 m-r-0">
<div class="row m-l-0 m-r-0 parentContainer">
<div class="col-12 col-md mb-2 mb-md-0 p-l-3 p-r-3 p-md-0">
<validation-wrapper-component :validator="$v.parameters.startDate">
<label class="all-caps">Start Date</label>
@@ -22,14 +22,24 @@
<select-component :options="options()" v-model="parameters.reportType"></select-component>
</validation-wrapper-component>
</div>
<div class="col-12 col-md-auto p-l-3 p-r-3 p-md-0">
<div class="btn btn-lg btn-primary fs-11 w-100 h-100 d-flex justify-content-center align-items-center" :class="{ disabled: isDownloading }" @click="handleClick">
<div class="col-12 col-md-auto p-l-3 p-r-3">
<div class="btn btn-lg btn-primary fs-11 w-100 h-100 d-flex justify-content-center align-items-center" :class="{ disabled: isDownloading }" @click="handleExportClick">
<span>
Export
</span>
<span v-if="isDownloading" class="spinner"></span>
</div>
</div>
<div class="col-12 col-md-auto p-l-3 p-r-3 p-md-0">
<div class="btn btn-lg btn-primary fs-11 w-100 h-100 d-flex justify-content-center align-items-center requestModal pointer" data-type="uploadDocumentModel">
<span>
Import
</span>
</div>
</div>
<modal-component type="uploadDocumentModel">
<upload-component :section="section"></upload-component>
</modal-component>
</div>
</div>
</div>
@@ -85,13 +95,13 @@ export default {
'Customers Report',
];
},
handleClick(){
handleExportClick(){
if (!this.validate()) return;
const reportType = this.parameters.reportType;
const routesMap = {
'Sales Invoice Report': route('api.export.transactions.sales-invoices'),
'Sales Invoice Report': route('api.export.bookings.sales-invoices'),
'Customers Report': route('api.export.companies.customers-data'),
};
@@ -4,7 +4,7 @@
<div class="row">
<div class="col-8 p-l-0">
<small class="all-caps muted fs-10">Export Report (New)</small>
<download-component section="exportDataSection"></download-component>
<download-upload-component section="exportDataSection"></download-upload-component>
</div>
</div>
<div class="row">
@@ -0,0 +1,88 @@
<template>
<div class="row" @keyup.enter="submitForm">
<div class="col">
<loading-component style="height: 200px; 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-10">
<div class="col">
<div class="font-heading fs-16 all-caps bold m-b-15">Document Upload</div>
</div>
</div>
<error-message-component class="m-b-20" :error="error"></error-message-component>
<div class="row">
<div class="col">
<file-input-component :validator="$v.files" v-model="files">
<template slot="label">
<div class="font-heading fs-11 text-primary all-caps">.xls file ONLY</div>
</template>
<template slot="tips">
<div class="row">
<div class="col">
<div class="row m-b-10">
<div class="col">
<div class="font-heading fs-11 text-warning m-b-10">Please double check the Report Type selected before proceed upload.</div>
</div>
</div>
</div>
</div>
</template>
</file-input-component>
</div>
</div>
<div class="row m-t-20">
<div class="col">
<div class="row">
<div class="col-auto">
<button type="button" class="btn btn-sm bg-master-lighter p-t-10 p-b-10 p-r-35 p-l-35 btn-default b-rad-none" data-dismiss="modal">Cancel</button>
</div>
<div class="col text-right">
<button type="button" class="btn btn-sm p-t-10 p-b-10 p-r-35 p-l-35 btn-success b-rad-none" @click="submitForm">Upload</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ModalFromHandler from '../../../general/mixins/modalFormHandler'
import { required } from "vuelidate/lib/validators";
export default {
props: {
// id: {
// required: true,
// type: Number
// }
},
data(){
return {
files: [],
parameters: {}
}
},
validations: {
files: {
required
}
},
methods: {
submitForm(){
this.parameters = {
files: this.files,
// booking_id: this.id,
// company_id: this.data.booking.company.id,
// payment_id: this.data.id,
};
this.submit(this.route('api.import.sales-invoices'), 'post', this.section, true, true);
}
},
mixins: [ModalFromHandler]
}
</script>
+6 -1
View File
@@ -1,14 +1,19 @@
<?php
use App\Http\Controllers\Exports\ExportController;
use App\Http\Controllers\Imports\ImportController;
use Illuminate\Support\Facades\Route;
Route::group(['prefix' => 'export', 'as' => 'export.', 'namespace' => 'Exports'], function () {
Route::group(['prefix' => 'transactions', 'as' => 'transactions.'], function () {
Route::group(['prefix' => 'bookings', 'as' => 'bookings.'], function () {
Route::get('/sales-invoices', [ExportController::class, 'salesInvoices'])->name('sales-invoices');
});
Route::group(['prefix' => 'companies', 'as' => 'companies.'], function () {
Route::get('/customers-data', [ExportController::class, 'companies'])->name('customers-data');
});
});
Route::group(['prefix' => 'import', 'as' => 'import.', 'namespace' => 'Imports'], function () {
Route::post('/import', [ImportController::class, 'salesInvoices'])->name('sales-invoices');
});