Merge branch 'dillon/34.8-jenkins-vapor' into vapor/production

This commit is contained in:
Dillon Ngo
2024-10-26 04:25:28 +08:00
7 changed files with 426 additions and 2 deletions
@@ -0,0 +1,104 @@
<?php
namespace App\Classes\Modules\Exports\Services;
use App\Classes\ValueObjects\Constants\TransactionType;
use App\Models\Booking;
use App\Models\Company;
use App\Models\Transaction;
use App\Models\Wallet;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class ExportsV2Transactions implements FromQuery, WithHeadingRow, WithMapping, ShouldAutoSize
{
use Exportable;
protected $startDate;
protected $endDate;
public function __construct($startDate = null, $endDate = null) {
$this->startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(1);
$this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now();
}
/**
* @return \Illuminate\Support\Collection|mixed
*/
public function query()
{
return Transaction::whereBetween('created_at', [$this->startDate, $this->endDate]) //Limit, 'expensive' query;
->whereIn('type', [TransactionType::PAYMENT, TransactionType::BILL])
->where('owner_type', '!=', Wallet::class);
}
/**
* @param $transaction
* @return array
*/
public function map($transaction): array
{
$transactionTypes = [
0 => 'PAYMENT_ATTEMPT',
1 => 'PAYMENT',
2 => 'INVOICE',
3 => 'BILL',
4 => 'PROFORMA',
5 => 'TOP_UP',
6 => 'REFUND',
7 => 'PURCHASE_ORDER',
8 => 'SUPPLIER_DELIVER',
9 => 'CREDIT_NOTE',
10 => 'WITHDRAW',
11 => 'DEBIT_NOTE',
12 => 'TRANSFER_FEE'
];
$transactionStatus = [
0 => 'PENDING_SUBMISSION',
1 => 'PENDING_VERIFICATION',
2 => 'APPROVED',
3 => 'COMPLETED',
4 => 'REJECTED',
5 => 'SUSPENDED',
6 => 'EXPIRED'
];
$booking = $transaction->owner;
if(!($booking instanceof Booking)){
$booking = $booking->owner;
}
$company = $booking->company;
if(!$company instanceof Company) dd($transaction);
return [
$company->reference,
$booking ? $booking->marking : '',
$transaction->bill_no,
$transaction->owner_id,
$transaction->owner_type,
$transactionTypes[$transaction->type],
$transaction->issuerCompany->name,
$transaction->reciver,
$transaction->currency->short_code,
$transaction->amount,
$transaction->original_currency->short_code,
$transaction->original_amount,
$transaction->currency_rate,
$transaction->tax,
$transaction->service_charge,
isset($transactionStatus[$transaction->status]) ? $transactionStatus[$transaction->status] : 'Unknown Status',
\PhpOffice\PhpSpreadsheet\Shared\Date::dateTimeToExcel($transaction->created_at),
\PhpOffice\PhpSpreadsheet\Shared\Date::dateTimeToExcel($transaction->updated_at),
];
}
}
@@ -6,6 +6,7 @@ namespace App\Http\Controllers\Exports;
use App\Classes\Modules\Exports\Services\ExportCurrencyVendorOrder;
use App\Classes\Modules\Exports\Services\ExportsCustomers;
use App\Classes\Modules\Exports\Services\ExportsTransactions;
use App\Classes\Modules\Exports\Services\ExportsV2Transactions;
use App\Classes\Modules\Exports\Services\ExportsBookingTransactions;
use App\Classes\Modules\Exports\Services\ExportsLeadsTransactions;
use App\Classes\Modules\Exports\Services\ExportsNullDebtors;
@@ -23,6 +24,7 @@ use App\Classes\Modules\Exports\Services\ExportsImportedReceiptMappeds;
use App\Classes\Modules\Exports\Services\ExportsWhiteFormTransactions;
use Illuminate\Support\Facades\Storage;
use App\Classes\General\AWSS3Helper;
use Illuminate\Support\Carbon;
class ExportCustomersToExcelController
{
@@ -72,6 +74,39 @@ class ExportCustomersToExcelController
}
}
public function v2transactions(Request $request){
$validated = $request->validate([
'startDate' => 'nullable|date_format:d-m-Y',
'endDate' => 'nullable|date_format:d-m-Y|after_or_equal:startDate',
]);
$startDate = null;
$endDate = null;
if (isset($validated['startDate']) && $validated['startDate']) {
$startDate = Carbon::createFromFormat('d-m-Y', $validated['startDate'])->startOfDay();
} else {
$startDate = Carbon::now()->subMonths(1)->startOfDay();
}
if (isset($validated['endDate']) && $validated['endDate']) {
$endDate = Carbon::createFromFormat('d-m-Y', $validated['endDate'])->endOfDay();
} else {
$endDate = Carbon::now()->endOfDay();
}
$exportsTransactions = new ExportsV2Transactions($startDate, $endDate);
$exportFileName = 'transactions.csv';
$filesystemDriver = Storage::getDefaultDriver();
if ($filesystemDriver === 's3') {
return response(['src' => AWSS3Helper::S3Exportable($exportFileName, $exportsTransactions)]);
} else {
return $exportsTransactions->download($exportFileName, Excel::CSV, ['Content-Type' => 'text/csv']);
}
}
public function nullDebtor(ExportsNullDebtors $exportsNullDebtors, Request $request){
$exportFileName = 'nullDebtor.xls';
$filesystemDriver = Storage::getDefaultDriver();
@@ -0,0 +1,110 @@
<template>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body no-padding-top">
<div id="accordionDownloadTransactionReport">
<div id="heading">
<button class="btn btn-link w-100 text-center no-padding" data-toggle="collapse" data-target="#collapseDownloadTransactionReport" aria-expanded="true" aria-controls="collapseDownloadTransactionReport">
<i class="fa fa-chevron-down"></i>
</button>
<div id="collapseDownloadTransactionReport" class="collapse" aria-labelledby="heading" data-parent="#accordionDownloadTransactionReport">
<div class="card-body">
<div class="row">
<div class="col-6">
<label>Start Date</label>
<date-picker-limit-range-component v-model="startDate" @input="onStartDateChange" :maxDays="maxDays"></date-picker-limit-range-component>
</div>
<div class="col-6">
<label>End Date</label>
<date-picker-limit-range-component v-model="endDate" ref="endDatePicker"></date-picker-limit-range-component>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div>
<span>transactions.csv</span>
<p class="text-muted mb-0">(default: last 1 month)</p>
</div>
<open-link-in-new-tab-component custom-class="btn btn-primary" :url="downloadUrl">
<i class="fa fa-download"></i> Download
</open-link-in-new-tab-component>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.no-padding-top {
padding-top: 0 !important;
}
</style>
<script>
export default {
data() {
return {
maxDays: 21,
startDate: '',
endDate: '',
isValidRange: false,
};
},
computed: {
downloadUrl() {
let url = this.generateLink();
return url;
}
},
methods: {
onStartDateChange(date) {
if (date) {
if (this.$refs.endDatePicker) {
const startDate = new Date(date.split('-').reverse().join('-'));
const adjustedEndDate = new Date(startDate);
// adjustedEndDate.setDate(startDate.getDate() + this.maxDays);
this.$refs.endDatePicker.setStartDate(adjustedEndDate);
}
// this.endDate = '';
this.isValidRange = false;
}
},
formatDate(date) {
if (date) {
const [day, month, year] = date.split('-');
return `${day}-${month}-${year}`;
}
return '';
},
validateDateRange() {
if (this.startDate && this.endDate) {
const start = new Date(this.startDate.split('-').reverse().join('-'));
const end = new Date(this.endDate.split('-').reverse().join('-'));
const difference = Math.floor((end - start) / (1000 * 60 * 60 * 24));
this.isValidRange = difference >= 0 && difference <= 14;
return this.isValidRange;
}
return false;
},
generateLink() {
if (this.validateDateRange()) {
const formattedStartDate = this.formatDate(this.startDate);
const formattedEndDate = this.formatDate(this.endDate);
return `${route('transactions.v2.export')}?startDate=${formattedStartDate}&endDate=${formattedEndDate}`;
}
return `${route('transactions.v2.export')}`;
}
}
};
</script>
@@ -0,0 +1,118 @@
<template>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body no-padding-top">
<div id="accordionShowWhiteForm">
<div id="heading">
<button class="btn btn-link w-100 text-center no-padding" data-toggle="collapse" data-target="#collapseShowWhiteForm" aria-expanded="true" aria-controls="collapseShowWhiteForm">
<i class="fa fa-chevron-down"></i>
</button>
<div id="collapseShowWhiteForm" class="collapse" aria-labelledby="heading" data-parent="#accordionShowWhiteForm">
<div class="card-body">
<div class="row">
<div class="col-6">
<label>Start Date</label>
<date-picker-limit-range-component v-model="startDate" @input="onStartDateChange" :maxDays="maxDays"></date-picker-limit-range-component>
</div>
<div class="col-6">
<label>End Date</label>
<date-picker-limit-range-component v-model="endDate" ref="endDatePicker"></date-picker-limit-range-component>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div>
<span>show-white-form-transactions-in-date-range</span>
<p class="text-muted mb-0">(default: last 2 weeks)</p>
</div>
<button class="btn btn-primary" @click="openLink">
<i class="fa fa-link"></i> Open Link
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.no-padding-top {
padding-top: 0 !important;
}
</style>
<script>
export default {
data() {
return {
maxDays: 14,
startDate: '',
endDate: '',
isValidRange: false,
};
},
created() {
this.startDate = this.getDefaultStartDate();
this.endDate = this.getDefaultEndDate();
},
methods: {
getDefaultStartDate() {
console.log('maxDays: ', this.maxDays);
const today = new Date();
const newStartDate = new Date(today);
newStartDate.setDate(today.getDate() - this.maxDays);
return this.formatDate(newStartDate);
},
getDefaultEndDate() {
const today = new Date();
return this.formatDate(today);
},
onStartDateChange(date) {
if (date) {
if (this.$refs.endDatePicker) {
const startDate = new Date(date.split('-').reverse().join('-'));
const adjustedEndDate = new Date(startDate);
// adjustedEndDate.setDate(startDate.getDate() + this.maxDays);
this.$refs.endDatePicker.setStartDate(adjustedEndDate);
}
// this.endDate = '';
this.isValidRange = false;
}
},
formatDate(date) {
if (date) {
const day = String(date.getDate()).padStart(2, '0');
const month = String(date.getMonth() + 1).padStart(2, '0');
const year = date.getFullYear();
return `${day}-${month}-${year}`;
}
return '';
},
validateDateRange() {
if (this.startDate && this.endDate) {
const start = new Date(this.startDate.split('-').reverse().join('-'));
const end = new Date(this.endDate.split('-').reverse().join('-'));
const difference = Math.floor((end - start) / (1000 * 60 * 60 * 24));
this.isValidRange = difference >= 0 && difference <= 14;
return this.isValidRange;
}
return false;
},
openLink() {
if (this.validateDateRange()) {
const formattedStartDate = this.formatDate(new Date(this.startDate.split('-').reverse().join('-')));
const formattedEndDate = this.formatDate(new Date(this.endDate.split('-').reverse().join('-')));
const url = `https://exchange.cief-malaysia.com/show-white-form-transactions-in-date-range/${formattedStartDate}/${formattedEndDate}`;
window.open(url, '_blank');
}
}
}
};
</script>
@@ -0,0 +1,47 @@
<template>
<input class="form-control">
</template>
<script>
export default {
props: {
value: {
required: false
},
maxDays: {
type: Number,
default: 14
},
},
mounted() {
let vm = this;
$(this.$el).datepicker({
format: 'dd-mm-yyyy',
autoclose: true,
clearBtn: true,
todayHighlight: true
}).val(this.value).trigger("change").on('changeDate', function () {
vm.$emit('input', this.value);
});
},
watch: {
value: function (value) {
$(this.$el).val(value).trigger('change');
}
},
methods: {
setStartDate(date) {
const startDate = date instanceof Date ? date : new Date(date);
const maxEndDate = new Date(startDate);
maxEndDate.setDate(startDate.getDate() + (this.maxDays - 1));
$(this.$el).datepicker('setStartDate', startDate);
$(this.$el).datepicker('setEndDate', maxEndDate);
// Ensure the visual highlighting
$(this.$el).datepicker('update', startDate);
}
}
}
</script>
@@ -21,7 +21,8 @@
</div>
<div class="col-md-6">
<div class="card mb-3">
<download-transactions-report-component></download-transactions-report-component>
<!-- <div class="card mb-3">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
<span>transactions.csv</span>
@@ -31,7 +32,7 @@
<i class="fa fa-download"></i> Download
</open-link-in-new-tab-component>
</div>
</div>
</div> -->
</div>
</div>
<div class="row">
@@ -60,6 +61,14 @@
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<show-white-form-transactions-component></show-white-form-transactions-component>
</div>
<div class="col-md-6">
</div>
</div>
</div>
<!-- Group 2: XXX Downloads -->
+1
View File
@@ -291,6 +291,7 @@ Route::get('billplz/bills/{bill_no}', function($bill_no){
Route::get('/export/customers/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@export')->name('customers.export');
Route::get('/export/transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@transactions')->name('transactions.export');
Route::get('/export/transactions/v2/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@v2transactions')->name('transactions.v2.export');
Route::get('/export/null-debtor/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@nullDebtor')->name('newDebtor.export');
Route::get('/export/payment-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@paymentTransactions')->name('paymentTransactions.export');
Route::get('/export/white-form-transactions/f614e339d7058904a831aad742e24d55', 'Exports\ExportCustomersToExcelController@whiteFormTransactions')->name('whiteFormTransactions.export');