Added new WarehouseOrder Module
This commit is contained in:
@@ -1,70 +1,169 @@
|
||||
// noinspection JSUnusedLocalSymbols
|
||||
Vue.component('warehouse-order-modal', {
|
||||
props: {
|
||||
id: {type: [String, Number], required: true},
|
||||
mode: {type: String, default: 'sign'}
|
||||
},
|
||||
template: `
|
||||
<tt-modal :show="true"
|
||||
@submit="submit"
|
||||
:delete="id !== 'create'"
|
||||
:title="id === 'create' ? 'Bestellung erstellen' : \`Bestellung #\${id} bearbeiten\`"
|
||||
@update:show="$emit('close')">
|
||||
<div style="width: 99%">
|
||||
<h4 class="text-center">Bestelldetails</h4>
|
||||
<tt-select label="Bearbeiter (XINON)"
|
||||
:options="window.TT_CONFIG.CRUD_CONFIG.columns.find(column => column.key === 'createBy')?.modal.items"
|
||||
sm
|
||||
row
|
||||
v-model="order.editor"/>
|
||||
|
||||
<hr>
|
||||
<h4 class="text-center">Positionen</h4>
|
||||
<tt-positions-manager
|
||||
ref="positionsManager"
|
||||
v-model="order.positions"
|
||||
:config="positionsConfig"
|
||||
@updateField-article="fetchDistributors"
|
||||
@updateField-distributorId="fetchDistributorData"
|
||||
/>
|
||||
|
||||
<hr>
|
||||
<h4 class="text-center">Lieferadresse</h4>
|
||||
<div style="display: grid; grid-gap: 10px; grid-template-columns: 2fr 2fr 1fr 1fr 2fr;">
|
||||
<tt-input label="Name" v-model="order.delAddrName" sm/>
|
||||
<tt-input label="Straße" v-model="order.delAddrLine" sm/>
|
||||
<tt-input label="PLZ" v-model="order.delAddrPLZ" sm/>
|
||||
<tt-input label="Ort" v-model="order.delAddrCity" sm/>
|
||||
<tt-input label="E-Mail" v-model="order.delAddrEMail" sm/>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<tt-textarea label="Notiz" v-model="order.note" sm row/>
|
||||
</div>
|
||||
</tt-modal>
|
||||
`,
|
||||
|
||||
data() {
|
||||
return {
|
||||
window: window,
|
||||
positionsConfig: {
|
||||
customOrdering: 'distributorId',
|
||||
fields: {
|
||||
article: {
|
||||
type: 'autocomplete',
|
||||
label: 'Artikel',
|
||||
apiUrl: '/WarehouseArticle/autoComplete',
|
||||
customFieldReference: 'WarehouseArticle',
|
||||
},
|
||||
distributorId: {type: 'select', label: 'Lieferant', options: [], customFieldReference: 'WarehouseDistributor'},
|
||||
distributorArticleNumber: {type: 'input', label: 'Lieferant Art-Nr.'},
|
||||
amount: {type: 'input', label: 'Menge', inputType: 'number'},
|
||||
buyPrice: {type: 'input', label: 'Einkaufspreis', inputType: 'number'},
|
||||
verwendung: {type: 'input', label: 'Verwendung'},
|
||||
},
|
||||
validateForm: (formData) => {
|
||||
const fields = [
|
||||
{key: 'amount', message: 'Bitte füllen Sie die Menge aus'},
|
||||
{key: 'distributorId', message: 'Bitte füllen Sie den Lieferanten aus'},
|
||||
{key: 'article', message: 'Bitte füllen Sie den Artikel aus'},
|
||||
{key: 'buyPrice', message: 'Bitte füllen Sie den Einkaufspreis aus'}
|
||||
];
|
||||
|
||||
for (const field of fields) {
|
||||
if (!formData[field.key]) {
|
||||
window.notify('error', field.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
order: {
|
||||
delAddrName: 'XINON GmbH',
|
||||
delAddrLine: 'Fladnitz im Raabtal 150',
|
||||
delAddrPLZ: '8322',
|
||||
delAddrCity: 'Studenzen',
|
||||
delAddrEMail: 'einkauf@xinon.at',
|
||||
note: '',
|
||||
editor: window.TT_CONFIG['USER_ID'],
|
||||
positions: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
if (this.id !== 'create') {
|
||||
const response = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getById`, {params: {id: this.id}});
|
||||
response.data.positions = JSON.parse(response.data.positions);
|
||||
this.order = response.data;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async submit() {
|
||||
if (this.order.positions.length === 0) return window.notify('error', 'Bitte fügen Sie mindestens eine Position hinzu.');
|
||||
|
||||
if (this.id === 'create') {
|
||||
const distributorIds = [...new Set(this.order.positions.map(position => position.distributorId))];
|
||||
|
||||
for (const distributorId of distributorIds) {
|
||||
const response = await axios.post(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/create`, {
|
||||
...this.order,
|
||||
distributorId,
|
||||
positions: this.order.positions.filter(position => position.distributorId === distributorId)
|
||||
}
|
||||
);
|
||||
if (response.data.success) window.notify('success', response.data.message ?? 'Bestellung erfolgreich erstellt');
|
||||
else window.notify('error',
|
||||
response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
|
||||
}
|
||||
} else {
|
||||
const response = await axios.post(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/update`, this.order);
|
||||
if (response.data.success) window.notify('success', response.data.message ?? 'Bestellung erfolgreich aktualisiert');
|
||||
else window.notify('error',
|
||||
response.data.errors ? Object.values(response.data.errors).join('<br>') : response.data.message || 'Ein Fehler ist aufgetreten');
|
||||
}
|
||||
this.$emit('close');
|
||||
|
||||
},
|
||||
async fetchDistributors(article) {
|
||||
const url = `${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getArticleDistributorData`;
|
||||
const params = typeof article === 'string' ? {allDistributor: true} : {articleId: article};
|
||||
|
||||
const response = await axios.get(url, {params});
|
||||
this.positionsConfig.fields.distributorId.options = response.data.map(distributor => ({
|
||||
value: distributor.id,
|
||||
text: distributor.name,
|
||||
externalArticleNumber: distributor.externalArticleNumber || null,
|
||||
purchasePrice: distributor.purchasePrice || null,
|
||||
}));
|
||||
},
|
||||
async fetchDistributorData(distributorId) {
|
||||
if (distributorId && typeof this.$refs.positionsManager.formData.article === 'number') {
|
||||
const distributor = this.positionsConfig.fields.distributorId.options.find(distributor => parseInt(distributor.value) ===
|
||||
parseInt(distributorId));
|
||||
this.$refs.positionsManager.updateField('distributorArticleNumber', distributor.externalArticleNumber);
|
||||
this.$refs.positionsManager.updateField('buyPrice', distributor.purchasePrice);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Vue.component('warehouse-order', {
|
||||
//language=Vue
|
||||
template: `
|
||||
<tt-card>
|
||||
<tt-table-crud @openHistory="historyModal = true; historyModalId = $event.id"
|
||||
ref="table">
|
||||
|
||||
<template v-slot:create="{ row }">
|
||||
{{ window.moment(row.create * 1000).format('DD.MM.YYYY HH:mm:ss') }}
|
||||
</template>
|
||||
|
||||
<template v-slot:sum="{ row }">
|
||||
<div style="text-align: right">{{ row.sum.toFixed(2) }} €</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:expandedRow="{ row }">
|
||||
<div class="lazy-loading" :data-row-id="row.id">
|
||||
<tt-loader v-if="orderLazyLoad[row.id] === true"/>
|
||||
<div v-else>
|
||||
<ul class="list-group">
|
||||
<li class="list-group-item" v-for="item in orderLazyLoad[row.id]">
|
||||
{{ item.quantity }}x {{ item.articleName }} - {{ item.price.toFixed(2) }} €
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<warehouse-order-modal v-if="orderModalId" :id="orderModalId" @close="orderModalId = null;$refs.table.$refs.table.refreshTable()"/>
|
||||
<button @click="orderModalId = 'create'" class="btn btn-primary">Bestellung erstellen</button>
|
||||
<tt-table-crud emit-edit @edit="orderModalId = $event.id" ref="table">
|
||||
<template v-slot:expandedRow="{ row }"><span>Work in Progress</span></template>
|
||||
</tt-table-crud>
|
||||
<warehouse-history-modal :show.sync="historyModal" :id="historyModalId"/>
|
||||
</tt-card>
|
||||
`, data() {
|
||||
return {
|
||||
window: window, historyModal: false, historyModalId: null, observer: null, orderLazyLoad: {},
|
||||
}
|
||||
}, mounted() {
|
||||
this.observer = new MutationObserver((mutations) => {
|
||||
const lazyLoadingElements = document.querySelectorAll('.lazy-loading');
|
||||
console.log(lazyLoadingElements);
|
||||
|
||||
// check row id and check if it is already defined in orderLazyLoad else alert('loading')
|
||||
// if it is defined do nothing
|
||||
|
||||
for (const element of lazyLoadingElements) {
|
||||
if (element.dataset.rowId in this.orderLazyLoad) {
|
||||
continue;
|
||||
}
|
||||
this.loadOrder(element.dataset.rowId);
|
||||
}
|
||||
|
||||
})
|
||||
this.observer.observe(document.querySelector('.tt-table-container'), {childList: true, subtree: true,});
|
||||
}, methods: {
|
||||
async loadOrder(rowId) {
|
||||
this.orderLazyLoad[rowId] = true;
|
||||
// use BASE_PATH . /WarehouseOrder/getOrderItems?id= + rowId
|
||||
const response = await axios.post(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseOrder/getOrderItems?id=${rowId}`);
|
||||
console.log(response.data);
|
||||
this.orderLazyLoad[rowId] = response.data;
|
||||
|
||||
// force re-render of the table
|
||||
this.$refs.table.$forceUpdate();
|
||||
|
||||
window: window,
|
||||
orderModalId: null,
|
||||
|
||||
}
|
||||
}, beforeDestroy() {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user