243 lines
10 KiB
JavaScript
243 lines
10 KiB
JavaScript
Vue.component('preorder-logistics', {
|
|
template: `
|
|
<tt-card>
|
|
<div class="card mb-3">
|
|
<div class="card-body filter-panel">
|
|
<h4 class="header-title mb-2">Filter</h4>
|
|
<div class="row g-2 align-items-end">
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-select label="Kampagne" :options="campaigns" v-model="filters.preordercampaign_id" sm multiple/>
|
|
</div>
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-select label="FCP" :options="fcps" v-model="filters.fcp" sm multiple searchable/>
|
|
</div>
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-select label="Versandstatus" :options="sentStatusOptions" v-model="filters.sent" sm/>
|
|
</div>
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-input label="Bestellcode" v-model="filters.ucode" sm/>
|
|
</div>
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-input label="OAID" v-model="filters.oaid" sm/>
|
|
</div>
|
|
<div class="col-lg-2 col-md-4">
|
|
<tt-date-picker label="Versanddatum" v-model="filters.sent_date" sm :time-picker="false"/>
|
|
</div>
|
|
</div>
|
|
<div class="row g-2 mt-1 align-items-end">
|
|
<div class="col-lg-4 col-md-6">
|
|
<tt-input label="Anschlussadresse" v-model="filters.address" sm/>
|
|
</div>
|
|
<div class="col-lg-4 col-md-6">
|
|
<tt-input label="Kunde" v-model="filters.kunde" sm/>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-2">
|
|
<div class="col filter-actions">
|
|
<tt-button text="Filter anwenden" @click="applyFilters" icon="fas fa-filter"
|
|
additional-class="btn-primary"/>
|
|
<tt-button text="Filter zurücksetzen" @click="resetFilters" icon="fas fa-undo"
|
|
additional-class="btn-secondary"/>
|
|
<tt-button text="Alle drucken" @click="printAll" icon="fas fa-print" additional-class="btn-success"
|
|
:loading="isPrinting"/>
|
|
<tt-button text="CSV Export" @click="exportCsv(false)" icon="fas fa-file-csv"
|
|
additional-class="btn-success" :loading="isExporting"/>
|
|
<tt-button text="CSV Export & als versendet markieren" @click="exportCsv(true)" icon="fas fa-file-csv"
|
|
additional-class="btn-success" :loading="isExportingAndMarking"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<tt-table
|
|
:fetch-url="window.TT_CONFIG.BASE_PATH + '/Preorderlogistics/getPreorders'"
|
|
:config="tableConfig"
|
|
ref="table"
|
|
ssr
|
|
>
|
|
<template v-slot:actions="{ row }">
|
|
<tt-button @click="printSlip(row)" sm additional-class="btn-success" icon="fas fa-print" text="Drucken"/>
|
|
</template>
|
|
|
|
<template v-slot:sent="{ row }">
|
|
<div class="sent-checkbox-wrapper">
|
|
<tt-switch :value="row.sent" :key ="'switch-' + row.id" @input="saveSent(row.id, $event)"></tt-switch>
|
|
<i v-if="row.sent" class="fas fa-check text-success ml-2"></i>
|
|
</div>
|
|
</template>
|
|
|
|
<template v-slot:shipping_address="{ row }">
|
|
<div v-html="row.display_address"></div>
|
|
</template>
|
|
</tt-table>
|
|
</tt-card>
|
|
`,
|
|
data() {
|
|
return {
|
|
window: window,
|
|
loading: false,
|
|
isPrinting: false,
|
|
isExporting: false,
|
|
isExportingAndMarking: false,
|
|
lastFcpInfoTime: null,
|
|
campaigns: [{value: '', text: 'Alle'}],
|
|
fcps: [],
|
|
sentStatusOptions: [
|
|
{value: 'no', text: 'Noch nicht versendet'},
|
|
{value: 'yes', text: 'Versendet'},
|
|
{value: 'all', text: 'Alle'}
|
|
],
|
|
filters: {
|
|
preordercampaign_id: '',
|
|
ucode: '',
|
|
oaid: '',
|
|
sent: 'no',
|
|
address: '',
|
|
kunde: '',
|
|
fcp: [],
|
|
sent_date: null
|
|
},
|
|
tableConfig: {
|
|
key: 'preorderlogistics',
|
|
tableHeader: 'Bestellungen',
|
|
headers: [
|
|
{key: 'actions', text: '', sortable: false, filter: false},
|
|
{key: 'sent', text: 'Versandt', sortable: false, filter: false},
|
|
{key: 'status_code', text: 'Status', sortable: false, filter: false},
|
|
{key: 'shipping_address', text: 'Versandadresse', sortable: false, filter: false},
|
|
{key: 'oaid', text: 'OAID', sortable: false, filter: false},
|
|
{key: 'ucode', text: 'Bestellcode', sortable: false, filter: false},
|
|
]
|
|
}
|
|
}
|
|
},
|
|
async mounted() {
|
|
this.campaigns.push(...window.TT_CONFIG.CRUD_CONFIG.CAMPAIGNS);
|
|
if (this.campaigns.length === 2) { // 'Alle' + one campaign
|
|
this.filters.preordercampaign_id = this.campaigns[1].value;
|
|
}
|
|
await this.fetchFcps();
|
|
},
|
|
watch: {
|
|
'filters.preordercampaign_id': 'fetchFcps'
|
|
},
|
|
methods: {
|
|
async fetchFcps() {
|
|
if (!this.filters.preordercampaign_id) {
|
|
this.fcps = [];
|
|
this.filters.fcp = [];
|
|
return;
|
|
}
|
|
|
|
if (Array.isArray(this.filters.preordercampaign_id) && this.filters.preordercampaign_id.length !== 1) {
|
|
this.fcps = [];
|
|
this.filters.fcp = [];
|
|
const now = new Date().getTime();
|
|
if (!this.lastFcpInfoTime || now - this.lastFcpInfoTime > 7000) {
|
|
this.lastFcpInfoTime = now;
|
|
} else {
|
|
return;
|
|
}
|
|
|
|
window.notify('info', 'Bitte wählen Sie genau eine Kampagne aus, um die FCPs zu laden.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await axios.get(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/getFCPsForCampaign`, {
|
|
params: {campaign_id: this.filters.preordercampaign_id}
|
|
});
|
|
this.fcps = response.data;
|
|
} catch (e) {
|
|
console.error("Could not fetch FCPs", e);
|
|
this.fcps = [];
|
|
}
|
|
},
|
|
applyFilters() {
|
|
this.$refs.table.filters = {...this.filters};
|
|
this.$refs.table.refreshTable();
|
|
},
|
|
resetFilters() {
|
|
this.filters = {
|
|
preordercampaign_id: '', ucode: '', oaid: '', sent: 'no', address: '', kunde: '', fcp: [], sent_date: null
|
|
};
|
|
this.applyFilters();
|
|
},
|
|
async saveSent(id, sent) {
|
|
try {
|
|
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/saveSentAction`, {
|
|
id,
|
|
sent
|
|
});
|
|
if (response.data.success) {
|
|
window.notify('success', 'Status gespeichert.');
|
|
this.$refs.table.refreshTable();
|
|
} else {
|
|
window.notify('error', 'Fehler beim Speichern.');
|
|
}
|
|
} catch (e) {
|
|
console.error("Error saving sent status:", e);
|
|
window.notify('error', 'Ein Fehler ist aufgetreten.');
|
|
this.$refs.table.refreshTable();
|
|
}
|
|
},
|
|
printSlip(row) {
|
|
const w = window.open(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/print?id=${row.id}`, "_blank", "popup=yes");
|
|
w.addEventListener('load', () => w.print());
|
|
},
|
|
async printAll() {
|
|
this.isPrinting = true;
|
|
try {
|
|
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/printAllAction`, {
|
|
filters: this.filters
|
|
}, {responseType: 'text'});
|
|
|
|
const printWindow = window.open("", "_blank");
|
|
printWindow.document.write(response.data);
|
|
printWindow.document.close();
|
|
setTimeout(() => {
|
|
printWindow.focus();
|
|
printWindow.print();
|
|
}, 500);
|
|
|
|
} catch (e) {
|
|
console.error("Error printing all slips:", e);
|
|
window.notify('error', 'Fehler beim Drucken.');
|
|
} finally {
|
|
this.isPrinting = false;
|
|
}
|
|
},
|
|
async exportCsv(markAsSent) {
|
|
const action = markAsSent ? 'csvExportAndMarkAsSentAction' : 'csvExportAction';
|
|
if (markAsSent) this.isExportingAndMarking = true; else this.isExporting = true;
|
|
|
|
try {
|
|
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/Preorderlogistics/${action}`, {
|
|
filters: this.filters
|
|
}, {responseType: 'blob'});
|
|
|
|
const url = window.URL.createObjectURL(new Blob([response.data]));
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.setAttribute('download', markAsSent ? 'export-versand-markiert.csv' : 'export-versand.csv');
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
window.URL.revokeObjectURL(url);
|
|
|
|
if (markAsSent) {
|
|
window.notify('success', 'CSV exportiert und Einträge als versendet markiert.');
|
|
this.$refs.table.refreshTable();
|
|
} else {
|
|
window.notify('success', 'CSV erfolgreich exportiert.');
|
|
}
|
|
|
|
} catch (e) {
|
|
console.error("Error exporting CSV:", e);
|
|
window.notify('error', 'Fehler beim CSV-Export.');
|
|
} finally {
|
|
if (markAsSent) this.isExportingAndMarking = false; else this.isExporting = false;
|
|
}
|
|
}
|
|
}
|
|
}); |