mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-19 04:23:55 +00:00
code for statement import invoice mapping
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||
use Maatwebsite\Excel\Concerns\Exportable;
|
||||
use Maatwebsite\Excel\Concerns\WithMapping;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadingRow;
|
||||
|
||||
class ExportsImportedInvoiceMappeds implements FromQuery, WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
private $dateTime;
|
||||
private $count;
|
||||
private $counter = 1;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->dateTime = $request->input('date').' '.$request->input('time');
|
||||
$this->count = 0;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'No',
|
||||
'Doc No',
|
||||
'Date',
|
||||
'Debtor Code',
|
||||
'Debtor Name',
|
||||
'Shipping Info',
|
||||
'Net Total',
|
||||
'Cancelled',
|
||||
'Mapped Status',
|
||||
'Mapped Reference No'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection|mixed
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
return TransactionMappingLog::where('imported_date', $this->dateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Transaction $transaction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function map($transaction): array
|
||||
{
|
||||
// dd($transaction);
|
||||
$this->count += 1;
|
||||
$data = $transaction->data;
|
||||
return [
|
||||
$this->count,
|
||||
Arr::get($data,'doc_no'),
|
||||
Arr::get($data,'date'),
|
||||
Arr::get($data,'debtor_code'),
|
||||
Arr::get($data,'debtor_name'),
|
||||
Arr::get($data,'shipping_info'),
|
||||
Arr::get($data,'net_total'),
|
||||
Arr::get($data,'cancelled'),
|
||||
Arr::get($data,'mapped_status'),
|
||||
Arr::get($data,'mapped_result_reference'),
|
||||
];
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Maatwebsite\Excel\Excel;
|
||||
use App\Classes\Modules\Exports\Services\ExportsImportedInvoiceMappeds;
|
||||
use App\Models\TransactionMappingLog;
|
||||
|
||||
class ExportCustomersToExcelController
|
||||
{
|
||||
@@ -75,4 +77,10 @@ class ExportCustomersToExcelController
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function importedInvoiceMapped(ExportsImportedInvoiceMappeds $exportsImportedInvoiceMappeds, Request $request) {
|
||||
$response = $exportsImportedInvoiceMappeds->download('InvoiceMapped.xls', Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
@@ -2,33 +2,47 @@
|
||||
|
||||
namespace App\Http\Controllers\Imports;
|
||||
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Models\Segment;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use DateTime;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Models\Company;
|
||||
use App\Models\Segment;
|
||||
use App\Models\Transaction;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\SeasonalSegment;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use App\Models\TransactionMappingLog;
|
||||
use App\Classes\ValueObjects\Constants\HttpStatus;
|
||||
use App\Classes\ValueObjects\Constants\ApprovalStatus;
|
||||
use App\Classes\Modules\Imports\Services\GenericImport;
|
||||
use App\Classes\ValueObjects\Response\ApiResponseObject;
|
||||
use App\Classes\Modules\Accounting\Processors\ChecksBillNumber;
|
||||
use App\Classes\Modules\Segments\Services\CreatesSeasonalSegment;
|
||||
use App\Classes\Modules\Companies\Processors\AssignSegmentProcessor;
|
||||
use App\Models\Company;
|
||||
use App\Models\SeasonalSegment;
|
||||
use App\Models\Transaction;
|
||||
use App\Classes\Modules\Documents\DataTransferObjects\DocumentObject;
|
||||
use App\Classes\Modules\Segments\DataTransferObjects\SeasonalSegmentObject;
|
||||
|
||||
class ImportStatementInvoiceController
|
||||
{
|
||||
private $responseTitle;
|
||||
private $responseMessage;
|
||||
|
||||
public function __construct() {
|
||||
$this->responseTitle = 'Import Invoice Mapping';
|
||||
$this->responseMessage = 'You have successfully imported invoice mapping';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array
|
||||
* @throws \App\Classes\Exceptions\MalformedRequestException
|
||||
*/
|
||||
public function import(Request $request)
|
||||
public function import(Request $request) : JsonResponse
|
||||
{
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
$importDate = date('Y-m-d H:i:s');
|
||||
$object = new DocumentObject('', $request->input('files'), '', ApprovalStatus::APPROVED, 'imports');
|
||||
$file = json_decode($object->getFiles()[0])->file_info->original->file;
|
||||
|
||||
@@ -37,26 +51,37 @@ class ImportStatementInvoiceController
|
||||
$excelRows = $import->rows;
|
||||
$excelRows = $excelRows->toArray();
|
||||
|
||||
$data = [];
|
||||
foreach ($excelRows as $row) {
|
||||
dd($row);
|
||||
// $row['debtor_code']
|
||||
|
||||
// attempt 1 - try map by amount and date
|
||||
// $transactionDate = $this->changeExcelDate($row['date']);
|
||||
// $transaction = Transaction::where('original_amount', $row['total'])->whereDate('created_at', $transactionDate)->get();
|
||||
// if ($transaction) {
|
||||
// // check company
|
||||
// // $company = Company::where('debtor', $row['debtor_code'])->first();
|
||||
// // dd($company);
|
||||
// // try to verify is it the correct transaction
|
||||
// }
|
||||
$row['mapped_result_reference'] = null;
|
||||
$row['mapped_status'] = 'failed';
|
||||
$row['date'] = $this->changeExcelDate($row['date']);
|
||||
|
||||
// Shipping Info
|
||||
// TOPUP -> map with transaction.bill_no
|
||||
if (str_starts_with($row['shipping_info'], 'TOPUP')) {
|
||||
// find in exchange first, if cannont then find in izyim
|
||||
// (App()->make(ChecksBillNumber::class))->execute($bill_no, 'exchange');
|
||||
foreach (['exchange','izyim'] as $system) {
|
||||
$returnReference = $this->mappingTopUp($row, $system);
|
||||
if ($returnReference) {
|
||||
$row['mapped_result_reference'] = $returnReference;
|
||||
$row['mapped_status'] = 'success';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$returnReference = $this->mappingExchange($row);
|
||||
if ($returnReference) {
|
||||
$row['mapped_result_reference'] = $returnReference;
|
||||
$row['mapped_status'] = 'success';
|
||||
}
|
||||
}
|
||||
|
||||
TransactionMappingLog::create([
|
||||
'imported_date'=>$importDate,
|
||||
'data'=>$row,
|
||||
]);
|
||||
array_push($data, $row);
|
||||
|
||||
|
||||
// if 5 digits -> exchange booking reference
|
||||
// find transation
|
||||
@@ -88,6 +113,51 @@ class ImportStatementInvoiceController
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $this->response(['data'=>$data,'importedDate'=>$importDate]);
|
||||
}
|
||||
|
||||
public function response(?array $data = []) : JsonResponse {
|
||||
return (new ApiResponseObject($this->responseTitle,
|
||||
$this->responseMessage,
|
||||
HttpStatus::OK_WITH_MESSAGE, $data))->handler();
|
||||
}
|
||||
|
||||
private function mappingTopUp(Array $row, String $system) {
|
||||
try {
|
||||
if ($data = (App()->make(ChecksBillNumber::class))->execute($row['shipping_info'], $system)) {
|
||||
if ($system == 'izyim' && isset($data['owner_reference'])) return $data['owner_reference'];
|
||||
|
||||
if ($system == 'exchange') return $this->updateTransactionOwnerReference($data, $row['doc_no']);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function mappingExchange(Array $row) {
|
||||
$date = $row['date'];
|
||||
$transactions = Transaction::where('original_amount', $row['net_total'])->whereRaw("DATE(created_at) = '$date'")
|
||||
->whereHas('receiverCompany', function($q) use($row) {
|
||||
$q->where('debtor',$row['debtor_code']);
|
||||
})
|
||||
->get();
|
||||
|
||||
if ($transactions && $transactions->count() == 1) {
|
||||
foreach ($transactions as $key => $transaction) {
|
||||
return $this->updateTransactionOwnerReference($transaction, $row['doc_no']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateTransactionOwnerReference($transaction, String $docNo) {
|
||||
$transactionOwner = $transaction->transaction_owner;
|
||||
if ($transactionOwner) {
|
||||
$transactionOwner->update(['invoice_reference'=>$docNo]);
|
||||
return $transactionOwner->owner_reference;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function changeExcelDate($date)
|
||||
|
||||
@@ -21,6 +21,11 @@ class StatementTransactionOwner extends Model
|
||||
'receipt_reference',
|
||||
'status',
|
||||
];
|
||||
|
||||
public function owner(): morphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function transaction(): BelongsTo
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Staudenmeir\EloquentHasManyDeep\HasTableAlias;
|
||||
use App\Models\StatementTransactionOwner;
|
||||
|
||||
|
||||
class Transaction extends AbstractModel implements Documentable, Transactionable, Voucherifiable
|
||||
@@ -53,6 +54,14 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $this->MorphOne(Transaction::class, 'owner')->where('type', TransactionType::CREDIT_NOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
|
||||
*/
|
||||
public function transaction_owner()
|
||||
{
|
||||
return $this->MorphOne(StatementTransactionOwner::class, 'owner','owner_type','owner_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
@@ -69,6 +78,16 @@ class Transaction extends AbstractModel implements Documentable, Transactionable
|
||||
return $this->BelongsTo( Company::class, 'issuer', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user that owns the Transaction
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function receiverCompany(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class, 'receiver', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BelongsTo
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TransactionMappingLog extends Model
|
||||
{
|
||||
protected $fillable = ['imported_by','data','imported_date'];
|
||||
|
||||
protected $casts = [
|
||||
'data' => 'array',
|
||||
];
|
||||
|
||||
public static function boot() {
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($model) {
|
||||
$model->imported_by = auth()->user()->id;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTransactionMappingLogsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('transaction_mapping_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->bigInteger('imported_by')->unsigned();
|
||||
$table->foreign('imported_by')->references('id')->on('users');
|
||||
$table->dateTime('imported_date')->nullable();
|
||||
$table->text('data')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('transaction_mapping_logs');
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<div class="row h-100 parentContainer">
|
||||
<div class="col-12" style="min-height: 20px;">
|
||||
<loading-component style="height: 20px; top: 0;" key="1" color="success" v-show="isLoading"></loading-component>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Imported Invoice Mapped</h3>
|
||||
<div class="text-right">
|
||||
<button class="btn btn-xs btn-outline-success b-rad-none m-r-5" @click="downloadInvoiceMapped">
|
||||
Download Invoices Mapped
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.card-header -->
|
||||
<div class="card-body table-responsive p-0">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Doc No</th>
|
||||
<th>Date</th>
|
||||
<th>Debtor Code</th>
|
||||
<th>Debtor Name</th>
|
||||
<th>Shipping Info</th>
|
||||
<th>Net Total</th>
|
||||
<th>Cancelled</th>
|
||||
<th>Mapped Status</th>
|
||||
<th>Mapped Reference No</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody v-show="!isLoading">
|
||||
<tr v-for="(item, index) in $store.getters.getListData(section)">
|
||||
<td>{{index+1}}</td>
|
||||
<td>{{item.doc_no }}</td>
|
||||
<td>{{item.date}}</td>
|
||||
<td>{{item.debtor_code }}}</td>
|
||||
<td>{{item.debtor_name}}</td>
|
||||
<td>{{item.shipping_info}}</td>
|
||||
<td>{{item.net_total}}</td>
|
||||
<td>{{item.cancelled}}</td>
|
||||
<td>{{item.mapped_status}}</td>
|
||||
<td>{{item.mapped_result_reference}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- /.card-body -->
|
||||
<div class="card-footer">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<pagination-component :section="section" class="mb-5" ref="pagination"></pagination-component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
files: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
section: 'importInvoiceMapping',
|
||||
isLoading: false,
|
||||
importedDate: null,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pendingQueue() {
|
||||
return this.$store.getters.isInCompleteQueue(this.section);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
pendingQueue(inComplete, oldValue){
|
||||
if(inComplete){
|
||||
this.importInvoice();
|
||||
}
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.$store.dispatch('updateListQueue', {'name': this.section});
|
||||
},
|
||||
methods: {
|
||||
importInvoice(){
|
||||
this.isLoading = true;
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
|
||||
this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false);
|
||||
},
|
||||
|
||||
successHandler(response){
|
||||
this.$store.dispatch('completeList', {'name': this.section, 'data': response.payload.data});
|
||||
this.importedDate = response.payload.importedDate;
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
||||
downloadInvoiceMapped() {
|
||||
var arrDateTime = this.importedDate.split(" ");
|
||||
|
||||
window.open(this.route('importedInvoiceMapped.export')+'?date='+arrDateTime[0]+'&time='+arrDateTime[1], '_blank');
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
+11
-6
@@ -99,7 +99,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" v-if="stage === 4">
|
||||
<div class="row parentContainer" v-if="stage === 4">
|
||||
<div class="col">
|
||||
<div class="row text-center m-t-50 m-b-50 p-t-50 p-b-50" v-show="exportStage === 0">
|
||||
<div class="col">
|
||||
@@ -123,7 +123,7 @@
|
||||
</file-input-component>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20" @click="importInvoice">Import Invoices</div>
|
||||
<div class="btn btn-lg btn-primary m-t-20 requestModal" data-type="ModalImportInvoice" @click="importInvoice">Import Invoices</div>
|
||||
<!-- todo-new: delete later --><br><div class="btn btn-lg btn-primary m-t-20" @click="exportStage++">Nest Step</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
@@ -131,6 +131,13 @@
|
||||
<a href="https://docs.google.com/presentation/d/1XwKcdBCpHQSCQmsgnUHsypcqk5kdc8uZMqkjW9JXiw4/edit?usp=sharing" target="_blank">Learn How to do this step?</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<modal-component class="animate__animated animate__fast animate__fadeIn" styleType="fill-in" type="ModalImportInvoice">
|
||||
<imported-invoice-mapped-component v-if="mappedTrue" :files="files"></imported-invoice-mapped-component>
|
||||
</modal-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row text-center m-t-50 m-b-50 p-t-50 p-b-50" v-show="exportStage === 2">
|
||||
@@ -191,6 +198,7 @@ export default {
|
||||
files: [],
|
||||
parameters: {},
|
||||
section: 'bankTransactionSection',
|
||||
mappedTrue: false,
|
||||
}
|
||||
},
|
||||
validations: {
|
||||
@@ -200,10 +208,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
importInvoice(){
|
||||
this.parameters = {
|
||||
files: this.files
|
||||
};
|
||||
this.submit(this.route('api.import_invoices.upload'), 'post', this.section, true, false);
|
||||
this.mappedTrue = true;
|
||||
},
|
||||
importReceipts(){
|
||||
this.parameters = {
|
||||
|
||||
@@ -261,6 +261,7 @@ Route::get('/export/payment-transactions/f614e339d7058904a831aad742e24d55', 'Exp
|
||||
Route::get('/export/wallet-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@walletTransactions')->name('walletTransactions.export');
|
||||
Route::get('/export/booking-transactions', 'Exports\ExportCustomersToExcelController@bookingTransactions')->name('export.transactions.booking');
|
||||
Route::get('/export/invoice-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@invoiceTransactions')->name('invoiceTransactions.export');
|
||||
Route::get('/export/imported-invoice-mapped', 'Exports\ExportCustomersToExcelController@importedInvoiceMapped')->name('importedInvoiceMapped.export');
|
||||
|
||||
Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) {
|
||||
$bookings = Booking::where(function($query){
|
||||
|
||||
Reference in New Issue
Block a user