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

This commit is contained in:
Dillon Ngo
2024-10-30 12:25:25 +08:00
7 changed files with 208 additions and 9 deletions
@@ -4,6 +4,7 @@ namespace App\Classes\Modules\Exports\Services;
use App\Classes\Modules\Exports\Sheets\ContainersSheet;
use App\Classes\Modules\Exports\Sheets\PackingListsSheet;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;;
@@ -11,6 +12,14 @@ class ExportsParcel implements WithMultipleSheets
{
use Exportable;
protected $startDate;
protected $endDate;
public function __construct($startDate = null, $endDate = null) {
$this->startDate = $startDate;
$this->endDate = $endDate;
}
/**
* @return array
@@ -19,10 +28,10 @@ class ExportsParcel implements WithMultipleSheets
{
$sheets = [];
$sheets[] = new ContainersSheet();
$sheets[] = new PackingListsSheet();
$sheets[] = new ContainersSheet($this->startDate, $this->endDate);
$sheets[] = new PackingListsSheet($this->startDate, $this->endDate);
return $sheets;
}
}
}
@@ -23,9 +23,16 @@ use Maatwebsite\Excel\Concerns\ShouldAutoSize;
class ContainersSheet implements WithHeadings, WithHeadingRow, WithMapping, ShouldAutoSize, FromQuery, WithTitle
{
use Exportable;
protected $startDate;
protected $endDate;
public function __construct($startDate = null, $endDate = null) {
$this->startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(3);
$this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now();
}
public function headings(): array
{
return [
@@ -47,7 +54,7 @@ class ContainersSheet implements WithHeadings, WithHeadingRow, WithMapping, Shou
public function query()
{
return Container::query()
->whereBetween('created_at', [Carbon::now()->subMonths(3), Carbon::now()]); //Limit, 'expensive' query
->whereBetween('created_at', [$this->startDate, $this->endDate]); //Limit, 'expensive' query
}
/**
@@ -30,6 +30,14 @@ class PackingListsSheet implements WithHeadings, WithHeadingRow, WithMapping, Sh
use Exportable;
protected $startDate;
protected $endDate;
public function __construct($startDate = null, $endDate = null) {
$this->startDate = $startDate ? Carbon::parse($startDate)->startOfDay() : Carbon::now()->subMonths(3);
$this->endDate = $endDate ? Carbon::parse($endDate)->endOfDay() : Carbon::now();
}
public function headings(): array
{
return [
@@ -55,7 +63,7 @@ class PackingListsSheet implements WithHeadings, WithHeadingRow, WithMapping, Sh
{
$packingLists = PackingList::where('status', '=', 2)
->whereIn('type', [PackingListType::WAREHOUSE_RECEIVE_LIST, PackingListType::SHIPPING_PACKING_LIST])
->whereBetween('created_at', [Carbon::now()->subMonths(3), Carbon::now()]) //Limit, 'expensive' query
->whereBetween('created_at', [$this->startDate, $this->endDate]) //Limit, 'expensive' query
->get();
return $packingLists->filter(function ($packingList) {
@@ -13,6 +13,7 @@ use App\Classes\Modules\Exports\Services\ExportsAgingList;
use Illuminate\Support\Facades\Storage;
use App\Classes\General\AWSS3Helper;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
class ExportArrivedParcelController extends Controller
{
@@ -45,7 +46,24 @@ class ExportArrivedParcelController extends Controller
}
public function summary(Request $request) {
$exportsParcelsSummary = new ExportsParcel();
$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();
}
if (isset($validated['endDate']) && $validated['endDate']) {
$endDate = Carbon::createFromFormat('d-m-Y', $validated['endDate'])->endOfDay();
}
$exportsParcelsSummary = new ExportsParcel($startDate, $endDate);
$exportFileName = 'parcel-summary.xls';
$filesystemDriver = Storage::getDefaultDriver();
if($filesystemDriver === 's3'){
@@ -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>
@@ -0,0 +1,109 @@
<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" :maxDays="maxDays"></date-picker-limit-range-component>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-between align-items-center">
<div>
<span>parcel-summary.xls</span>
<p class="text-muted mb-0">(default: last 3 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: 30,
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);
this.$refs.endDatePicker.setStartDate(adjustedEndDate);
}
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 <= this.maxDays;
return this.isValidRange;
}
return false;
},
generateLink() {
console.log('validateDateRange(): ', this.validateDateRange());
if (this.validateDateRange()) {
const formattedStartDate = this.formatDate(this.startDate);
const formattedEndDate = this.formatDate(this.endDate);
return `${route('packing_list.arrived_parcel.parcel-summary')}?startDate=${formattedStartDate}&endDate=${formattedEndDate}`;
}
return `${route('packing_list.arrived_parcel.parcel-summary')}`;
}
}
};
</script>
@@ -43,7 +43,8 @@
</div>
</div>
<div class="col-md-6">
<div class="card mb-3">
<download-parcel-summary-component></download-parcel-summary-component>
<!-- <div class="card mb-3">
<div class="card-body d-flex justify-content-between align-items-center">
<div>
<span>parcel-summary.xls</span>
@@ -53,7 +54,7 @@
<i class="fa fa-download"></i> Download
</open-link-in-new-tab-component>
</div>
</div>
</div> -->
</div>
</div>