0
0
Fork 0

refactor: refs #7553 modified ticket sale to create a row in the table

This commit is contained in:
Jon Elias 2024-09-11 10:16:42 +02:00
parent 8e35737c8e
commit ff7bcfb00a
2 changed files with 122 additions and 83 deletions

View File

@ -53,6 +53,10 @@ const $props = defineProps({
type: Boolean, type: Boolean,
default: true, default: true,
}, },
bottom: {
type: Object,
default: null,
},
cardClass: { cardClass: {
type: String, type: String,
default: 'flex-one', default: 'flex-one',
@ -522,7 +526,24 @@ function handleOnDataSaved(_, res) {
</QTd> </QTd>
</template> </template>
<template #bottom v-if="bottom"> <template #bottom v-if="bottom">
<slot name="bottom-table" /> <slot name="bottom-table">
<QIcon
@click="
() =>
createAsDialog
? (showForm = !showForm)
: handleOnDataSaved(create)
"
class="fill-icon-on-hover"
color="primary"
name="add_circle"
size="sm"
shortcut="+"
/>
<QTooltip>
{{ createForm.title }}
</QTooltip>
</slot>
</template> </template>
<template #item="{ row, colsMap }"> <template #item="{ row, colsMap }">
<component <component

View File

@ -22,7 +22,6 @@ import { useVnConfirm } from 'composables/useVnConfirm';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import axios from 'axios'; import axios from 'axios';
import VnTable from 'src/components/VnTable/VnTable.vue'; import VnTable from 'src/components/VnTable/VnTable.vue';
import FormModelPopup from 'src/components/FormModelPopup.vue';
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -51,8 +50,6 @@ const transfer = ref({
sales: [], sales: [],
}); });
const tableRef = ref([]); const tableRef = ref([]);
const formModelPopupRef = ref();
const showForm = ref(false);
watch( watch(
() => route.params.id, () => route.params.id,
@ -219,6 +216,7 @@ const addSale = async (sale) => {
sale.item = newSale.item; sale.item = newSale.item;
notify('globals.dataSaved', 'positive'); notify('globals.dataSaved', 'positive');
window.location.reload();
} catch (err) { } catch (err) {
console.error('Error adding sale', err); console.error('Error adding sale', err);
} }
@ -427,18 +425,70 @@ onMounted(async () => {
stateStore.rightDrawer = true; stateStore.rightDrawer = true;
getConfig(); getConfig();
getSales(); getSales();
getItems();
}); });
onUnmounted(() => (stateStore.rightDrawer = false)); onUnmounted(() => (stateStore.rightDrawer = false));
async function save(item) { const items = ref([]);
const { data } = await axios.post(`Tickets/${route.params.id}/addSale`, { const newRow = ref({});
id: route.params.id,
barcode: item.itemFk, async function getItems() {
quantity: parseInt(item.quantity), const { data } = await axios.get(`Items/withName`);
}); items.value = data;
if (data) window.location.reload();
} }
const updateItem = (row) => {
const selectedItem = items.value.find((item) => item.id === row.itemFk);
if (selectedItem) {
row.item = selectedItem;
row.itemFk = selectedItem.id;
row.price = selectedItem.price;
row.discount = 0;
row.quantity = 0;
row.amount = row.price * row.quantity;
}
endNewRow(selectedItem);
};
function handleOnDataSave({ CrudModelRef }) {
const { copy } = addRow(CrudModelRef.formData);
CrudModelRef.insert(copy);
}
const addRow = (original = null) => {
let copy = null;
if (!original) {
copy = { isNew: true };
} else {
copy = {
itemFk: original.itemFk,
item: original.item,
quantity: original.quantity,
price: original.price,
discount: original.discount,
amount: original.amount,
isNew: true,
};
}
newRow.value = copy;
return { original, copy };
};
const endNewRow = (row) => {
if (row.itemFk && row.quantity) {
row.isNew = false;
}
};
watch(
() => newRow.value.itemFk,
(newItemFk) => {
if (newItemFk) {
updateItem(newRow.value);
}
}
);
</script> </script>
<template> <template>
@ -566,6 +616,16 @@ async function save(item) {
:column-search="false" :column-search="false"
:disable-option="{ card: true }" :disable-option="{ card: true }"
auto-load auto-load
:create="{
onDataSaved: handleOnDataSave,
}"
:create-as-dialog="false"
:crud-model="{
paginate: false,
}"
:default-remove="false"
:default-reset="false"
:default-save="false"
> >
<template #column-statusIcons="{ row }"> <template #column-statusIcons="{ row }">
<router-link <router-link
@ -626,7 +686,26 @@ async function save(item) {
</QBadge> </QBadge>
</template> </template>
<template #column-itemFk="{ row }"> <template #column-itemFk="{ row }">
<span class="link" @click.stop> <VnSelect
v-if="row.isNew"
url="Items"
:options="items"
option-label="name"
option-value="id"
v-model="row.itemFk"
@update:model-value="updateItem(row)"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel>
{{ scope.opt?.id }} - {{ scope.opt?.name }}</QItemLabel
>
</QItemSection>
</QItem>
</template>
</VnSelect>
<span v-else class="link" @click.stop>
{{ row?.itemFk }} {{ row?.itemFk }}
<ItemDescriptorProxy :id="row?.itemFk" /> <ItemDescriptorProxy :id="row?.itemFk" />
</span> </span>
@ -638,34 +717,22 @@ async function save(item) {
{{ row?.item?.subName.toUpperCase() }} {{ row?.item?.subName.toUpperCase() }}
</div> </div>
</div> </div>
<FetchedTags :item="row?.item" :max-length="6" /> <FetchedTags :item="row" :max-length="6" />
<QPopupProxy v-if="row.id && isTicketEditable"> <QPopupProxy v-if="row.id && isTicketEditable">
<VnInput v-model="row.concept" @change="updateConcept(row)" /> <VnInput v-model="row.concept" @change="updateConcept(row)" />
</QPopupProxy> </QPopupProxy>
<VnSelect
v-else
:options="itemsWithNameOptions"
hide-selected
option-label="name"
option-value="id"
@update:model-value="changeQuantity(row)"
v-model="row.itemFk"
>
<template #option="scope">
<QItem v-bind="scope.itemProps">
<QItemSection>
<QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
<QItemLabel caption>{{ scope.opt?.name }}</QItemLabel>
</QItemSection>
</QItem>
</template>
</VnSelect>
</template> </template>
<template #column-quantity="{ row }"> <template #column-quantity="{ row }">
<VnInput <VnInput
v-if="isTicketEditable" v-if="row.isNew"
v-model.number="row.quantity"
type="number"
@blur="changeQuantity(row)"
@focus="edit.oldQuantity = row.quantity"
/>
<VnInput
v-else-if="isTicketEditable"
v-model.number="row.quantity" v-model.number="row.quantity"
@keyup.enter="changeQuantity(row)"
@blur="changeQuantity(row)" @blur="changeQuantity(row)"
@focus="edit.oldQuantity = row.quantity" @focus="edit.oldQuantity = row.quantity"
/> />
@ -713,58 +780,9 @@ async function save(item) {
<template #column-amount="{ row }"> <template #column-amount="{ row }">
{{ toCurrency(row.quantity * row.price) }} {{ toCurrency(row.quantity * row.price) }}
</template> </template>
<template #bottom-table v-if="isTicketEditable">
<QIcon
@click="showForm = !showForm"
class="fill-icon-on-hover"
color="primary"
name="add_circle"
size="sm"
>
<QTooltip>
{{ t('Add item') }}
</QTooltip>
</QIcon>
<QDialog v-model="showForm" transition-show="scale" transition-hide="scale">
<FormModelPopup
ref="formModelPopupRef"
:url-create="`Tickets/${route.params.id}/addSale`"
:title="t('New item')"
:form-initial-data="{
price: 0,
discount: 0,
visible: 0,
available: 0,
packaging: null,
}"
:save-fn="save"
>
<template #form-inputs="{ data }">
<VnSelect
url="Items/withName"
:option-filter="{
order: 'id DESC',
}"
:fields="['id', 'name']"
:label="t('Items')"
option-label="name"
option-value="id"
:options="itemsWithNameOptions"
hide-selected
v-model="data.itemFk"
/>
<VnInput
v-model="data.quantity"
:label="t('Quantity')"
type="number"
/>
</template>
</FormModelPopup>
</QDialog>
</template>
</VnTable> </VnTable>
<QPageSticky :offset="[20, 20]"> <QPageSticky :offset="[20, 20]" style="z-index: 2">
<QBtn @click="newOrderFromTicket()" color="primary" fab icon="add" /> <QBtn @click="newOrderFromTicket()" color="primary" fab icon="add" />
<QTooltip class="text-no-wrap"> <QTooltip class="text-no-wrap">
{{ t('Add item to basket') }} {{ t('Add item to basket') }}