mirror of
https://gitlab.com/CIEFWorldwideSdnBhd/exchange-2.0.git
synced 2026-08-29 09:24:07 +00:00
add /export/all-customers-info-for-lark-system
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\Modules\Exports\Services;
|
||||
|
||||
use App\Models\Company;
|
||||
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 App\Classes\General\Eloquent\ApplyFiltersToQuery;
|
||||
|
||||
class ExportsAllCustomersInfoForLarkSystem implements FromQuery, WithMapping, WithHeadings, ShouldAutoSize
|
||||
{
|
||||
use Exportable;
|
||||
|
||||
public function __construct() {}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'Marking',
|
||||
'Name',
|
||||
'Phone Number',
|
||||
'Email',
|
||||
'Registration Date',
|
||||
'Last Order Date',
|
||||
'Custom Segments',
|
||||
];
|
||||
}
|
||||
|
||||
public function query()
|
||||
{
|
||||
return (new ApplyFiltersToQuery())->execute(
|
||||
Company::query()->with([
|
||||
'employees',
|
||||
'segments',
|
||||
'contacts'
|
||||
]),
|
||||
['business_type' => 2]
|
||||
);
|
||||
}
|
||||
|
||||
public function map($company): array
|
||||
{
|
||||
$employeeEmail = '';
|
||||
if ($company->employees->first()) {
|
||||
$employeeEmail = $company->employees->first()->email;
|
||||
}
|
||||
|
||||
$contactPhone = '';
|
||||
if ($company->contacts->first()) {
|
||||
$contactPhone = $company->contacts->first()->phone;
|
||||
}
|
||||
|
||||
$segments = '';
|
||||
if ($company->segments->first()) {
|
||||
$segments = $company->segments->pluck('name')->implode(', ');
|
||||
}
|
||||
|
||||
return [
|
||||
$company->reference,
|
||||
$company->name,
|
||||
$contactPhone,
|
||||
$employeeEmail,
|
||||
$company->created_at ? $company->created_at->toDateString() : '',
|
||||
$company->updated_at ? $company->updated_at->toDateString() : '',
|
||||
$segments,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -24,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 App\Classes\Modules\Exports\Services\ExportsAllCustomersInfoForLarkSystem;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class ExportCustomersToExcelController
|
||||
@@ -241,5 +242,25 @@ class ExportCustomersToExcelController
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
public function exportAllCustomersInfoForLarkSystem(Request $request)
|
||||
{
|
||||
$password = $request->input('password');
|
||||
if ($password !== 'all_customers_data') {
|
||||
return response()->json(['error' => 'Invalid password'], 403);
|
||||
}
|
||||
|
||||
$exportsAllCustomersInfoForLarkSystem = new ExportsAllCustomersInfoForLarkSystem($request);
|
||||
$exportFileName = 'all_customers_info_for_lark_system.xls';
|
||||
|
||||
$filesystemDriver = Storage::getDefaultDriver();
|
||||
if ($filesystemDriver === 's3') {
|
||||
return response(['src' => AWSS3Helper::S3Exportable($exportFileName, $exportsAllCustomersInfoForLarkSystem)]);
|
||||
} else {
|
||||
$response = $exportsAllCustomersInfoForLarkSystem->download($exportFileName, Excel::XLS, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
|
||||
ob_end_clean();
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<span>
|
||||
<a :class="[customClass, { 'link-disabled': isDownloading }]" @click.prevent="showPasswordModal">
|
||||
<slot></slot>
|
||||
<span v-if="isDownloading" class="spinner"></span>
|
||||
</a>
|
||||
|
||||
<modal-component styleType="fill-in" type="passwordPrompt" @close="closeModal">
|
||||
<div class="row bg-white p-t-45 p-b-45 p-l-45 p-r-45">
|
||||
<div class="col">
|
||||
<h4 class="m-b-20 text-center">Enter Password</h4>
|
||||
<div class="form-group">
|
||||
<input type="password" class="form-control" v-model="password" placeholder="Enter password" @keyup.enter="handleDownload">
|
||||
</div>
|
||||
<div class="text-danger m-b-10" v-if="error">{{ error }}</div>
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-default btn-block" @click="closeModal">Cancel</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-primary btn-block" @click="handleDownload" :disabled="isDownloading">
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</modal-component>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
customClass: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDownloading: false,
|
||||
password: '',
|
||||
error: '',
|
||||
modalVisible: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showPasswordModal() {
|
||||
this.password = '';
|
||||
this.error = '';
|
||||
this.$nextTick(() => {
|
||||
$('.modalContainer[data-type="passwordPrompt"]').modal('show');
|
||||
});
|
||||
},
|
||||
closeModal() {
|
||||
$('.modalContainer[data-type="passwordPrompt"]').modal('hide');
|
||||
},
|
||||
async handleDownload() {
|
||||
if (!this.password) {
|
||||
this.error = 'Please enter a password';
|
||||
return;
|
||||
}
|
||||
|
||||
this.isDownloading = true;
|
||||
this.error = '';
|
||||
|
||||
try {
|
||||
const response = await fetch(this.url + '?password=' + this.password, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + this.$store.getters.getAccessToken,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status === 403) {
|
||||
this.error = 'Invalid password';
|
||||
this.isDownloading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.status === 200) {
|
||||
// Check if response is JSON
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
const data = await response.json();
|
||||
if (data.src) {
|
||||
// If JSON contains a file URL, trigger download
|
||||
window.location.href = data.src;
|
||||
this.closeModal();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle direct file download
|
||||
const contentDisposition = response.headers.get('Content-Disposition');
|
||||
const filename = contentDisposition ? contentDisposition.split('filename=')[1] : 'downloaded_file';
|
||||
|
||||
const blob = await response.blob();
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = blobUrl;
|
||||
a.download = filename;
|
||||
a.style.display = 'none';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(blobUrl);
|
||||
this.closeModal();
|
||||
} else {
|
||||
this.error = 'Download failed';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Network error:', error);
|
||||
this.error = 'Network error occurred';
|
||||
} finally {
|
||||
this.isDownloading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.spinner {
|
||||
border: 2px solid rgba(0, 0, 0, 0.1);
|
||||
border-left-color: #000;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
animation: spin 1s linear infinite;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: translate(-50%, -50%) rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: translate(-50%, -50%) rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.link-disabled {
|
||||
pointer-events: none;
|
||||
opacity: 0.6;
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
@@ -69,6 +69,20 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="card mb-3">
|
||||
<div class="card-body d-flex justify-content-between align-items-center">
|
||||
<span>all_customers_info_for_lark_system.xls</span>
|
||||
<password-protected-download-component custom-class="btn btn-primary" :url="route('exportAllCustomersInfoForLarkSystem.export')">
|
||||
<i class="fa fa-download"></i> Download
|
||||
</password-protected-download-component>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Group 2: XXX Downloads -->
|
||||
|
||||
@@ -326,6 +326,7 @@ Route::get('/export/analytic/booking', 'Exports\ExportAnalyticToExcelController@
|
||||
Route::get('/export/analytic/bills', 'Exports\ExportAnalyticToExcelController@billingData')->name('billingData.export');;
|
||||
Route::get('/export/customers/leads', 'Exports\ExportCustomersToExcelController@leadsData')->name('leads.export');
|
||||
route::get('/export/excel/{id}', 'Exports\ExportCustomersToExcelController@exportCurrencyVendorOrder')->name('group.excel');
|
||||
Route::get('/export/all-customers-info-for-lark-system', 'Exports\ExportCustomersToExcelController@exportAllCustomersInfoForLarkSystem')->name('exportAllCustomersInfoForLarkSystem.export');
|
||||
|
||||
Route::get('/products', function (\App\Classes\Modules\Exports\Services\ExportsProducts $exportsProducts) {
|
||||
$bookings = Booking::where(function($query){
|
||||
|
||||
Reference in New Issue
Block a user