forked from verdnatura/salix-front
Added discount component
This commit is contained in:
parent
e44da1c999
commit
a52cb0fb46
|
@ -0,0 +1,139 @@
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, onUnmounted, ref, computed } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { toCurrency } from 'filters/index';
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
quantity: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
price: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
discount: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
mana: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
promise: {
|
||||||
|
type: Function,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['onUpdate']);
|
||||||
|
|
||||||
|
const discount = ref(0);
|
||||||
|
let canceller;
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (props.discount) {
|
||||||
|
discount.value = props.discount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const total = computed(() => {
|
||||||
|
const amount = props.price * props.quantity;
|
||||||
|
const appliedDiscount = (discount.value * amount) / 100;
|
||||||
|
|
||||||
|
return amount - appliedDiscount;
|
||||||
|
});
|
||||||
|
|
||||||
|
const newAmount = computed(() => `${t('New amount')}: ${toCurrency(total.value)}`);
|
||||||
|
|
||||||
|
const isLoading = ref(false);
|
||||||
|
async function save({ set }) {
|
||||||
|
isLoading.value = true;
|
||||||
|
const response = {
|
||||||
|
...props.data,
|
||||||
|
...{
|
||||||
|
discount: parseInt(discount.value),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (props.promise) {
|
||||||
|
canceller = new AbortController();
|
||||||
|
Object.assign(response, { canceller });
|
||||||
|
|
||||||
|
await props.promise(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (set) set();
|
||||||
|
emit('onUpdate', response);
|
||||||
|
isLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cancel({ cancel }) {
|
||||||
|
if (canceller) {
|
||||||
|
canceller.abort();
|
||||||
|
canceller = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
discount.value = props.discount;
|
||||||
|
if (isLoading.value === true) isLoading.value = false;
|
||||||
|
if (cancel) cancel();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<q-popup-edit
|
||||||
|
v-model="discount"
|
||||||
|
v-slot="scope"
|
||||||
|
:title="t('Update discount')"
|
||||||
|
@cancel="cancel"
|
||||||
|
>
|
||||||
|
<q-banner class="bg-primary text-center q-mb-md" rounded dense>
|
||||||
|
{{ t('Mana') }} {{ toCurrency(props.mana) }}
|
||||||
|
</q-banner>
|
||||||
|
<q-input
|
||||||
|
v-model="scope.value"
|
||||||
|
type="number"
|
||||||
|
dense
|
||||||
|
autofocus
|
||||||
|
@keyup.enter="save(scope)"
|
||||||
|
@update:model-value="discount = scope.value"
|
||||||
|
@focus="($event) => $event.target.select()"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
:disable="isLoading"
|
||||||
|
:hint="newAmount"
|
||||||
|
:rules="[
|
||||||
|
(value) => value.length > 0 || t('Enter a value'),
|
||||||
|
(value) => (value >= 0 && value <= 100) || t('Invalid discount amount'),
|
||||||
|
]"
|
||||||
|
/>
|
||||||
|
<q-card-actions class="q-px-none q-mt-sm" align="right">
|
||||||
|
<q-btn :label="t('Cancel')" color="primary" flat @click="cancel(scope)" />
|
||||||
|
<q-btn
|
||||||
|
:label="t('Update')"
|
||||||
|
color="primary"
|
||||||
|
:loading="isLoading"
|
||||||
|
unelevated
|
||||||
|
@click="save(scope)"
|
||||||
|
/>
|
||||||
|
</q-card-actions>
|
||||||
|
</q-popup-edit>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
New amount: Nuevo importe
|
||||||
|
Update discount: Actualizar descuento
|
||||||
|
Mana: Maná
|
||||||
|
Enter a value: Introduce un valor
|
||||||
|
Invalid discount amount: Cantidad de descuento incorrecta
|
||||||
|
Cancel: Cancelar
|
||||||
|
Update: Actualizar
|
||||||
|
</i18n>
|
|
@ -11,6 +11,7 @@ import FetchData from 'components/FetchData.vue';
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
import { toDate, toCurrency, toPercentage } from 'src/filters';
|
import { toDate, toCurrency, toPercentage } from 'src/filters';
|
||||||
|
import VnDiscount from 'components/common/vnDiscount.vue';
|
||||||
|
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -90,13 +91,18 @@ const columns = computed(() => [
|
||||||
name: 'discount',
|
name: 'discount',
|
||||||
label: t('Discount'),
|
label: t('Discount'),
|
||||||
field: ({ sale }) => sale.discount,
|
field: ({ sale }) => sale.discount,
|
||||||
format: (value) => toPercentage(value),
|
format: (value) => toPercentage(value / 100),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'total',
|
name: 'total',
|
||||||
label: t('Total'),
|
label: t('Total'),
|
||||||
field: ({ sale }) => sale.price * sale.quantity,
|
field: ({ sale }) => {
|
||||||
|
const amount = sale.price * sale.quantity;
|
||||||
|
const appliedDiscount = (sale.discount * amount) / 100;
|
||||||
|
|
||||||
|
return amount - appliedDiscount;
|
||||||
|
},
|
||||||
format: (value) => toCurrency(value),
|
format: (value) => toCurrency(value),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
|
@ -106,6 +112,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const selected = ref([]);
|
||||||
const mana = ref(0);
|
const mana = ref(0);
|
||||||
async function fetchMana() {
|
async function fetchMana() {
|
||||||
const ticketId = claim.value.ticketFk;
|
const ticketId = claim.value.ticketFk;
|
||||||
|
@ -118,7 +125,25 @@ async function updateQuantity({ id, quantity }) {
|
||||||
await axios.patch(`ClaimBeginnings/${id}`, { quantity });
|
await axios.patch(`ClaimBeginnings/${id}`, { quantity });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateDiscount({ id, discount }) {}
|
async function updateDiscount({ saleFk, discount, canceller }) {
|
||||||
|
const body = { salesIds: [saleFk], newDiscount: discount };
|
||||||
|
const claimId = claim.value.ticketFk;
|
||||||
|
const query = `Tickets/${claimId}/updateDiscount`;
|
||||||
|
|
||||||
|
await axios.post(query, body, {
|
||||||
|
signal: canceller.signal,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUpdateDiscount(response) {
|
||||||
|
const row = store.data[response.rowIndex];
|
||||||
|
row.sale.discount = response.discount;
|
||||||
|
//store.data[response.rowIndex].sale.discount = response.discount;
|
||||||
|
quasar.notify({
|
||||||
|
message: t('Discount updated'),
|
||||||
|
type: 'positive',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function confirmRemove(id, index) {
|
async function confirmRemove(id, index) {
|
||||||
quasar
|
quasar
|
||||||
|
@ -141,9 +166,6 @@ async function remove({ id }) {
|
||||||
message: t('globals.rowRemoved'),
|
message: t('globals.rowRemoved'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const manaTitle = computed(() => `${t('Mana')} ${toCurrency(mana.value)}`);
|
|
||||||
const totalClaimed = 0;
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<q-page-sticky position="top" :offset="[0, 0]" expand>
|
<q-page-sticky position="top" :offset="[0, 0]" expand>
|
||||||
|
@ -184,6 +206,8 @@ const totalClaimed = 0;
|
||||||
:dense="$q.screen.lt.md"
|
:dense="$q.screen.lt.md"
|
||||||
:pagination="{ rowsPerPage: 0 }"
|
:pagination="{ rowsPerPage: 0 }"
|
||||||
row-key="id"
|
row-key="id"
|
||||||
|
selection="multiple"
|
||||||
|
v-model:selected="selected"
|
||||||
hide-pagination
|
hide-pagination
|
||||||
>
|
>
|
||||||
<template #body-cell-claimed="{ row, value }">
|
<template #body-cell-claimed="{ row, value }">
|
||||||
|
@ -209,16 +233,32 @@ const totalClaimed = 0;
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #body-cell-discount="{ row, value }">
|
<template #body-cell-discount="{ row, value, rowIndex }">
|
||||||
<q-td auto-width align="right" class="dimmed">
|
<q-td auto-width align="right" class="dimmed">
|
||||||
{{ value }}
|
{{ value }}
|
||||||
|
<VnDiscount
|
||||||
|
:quantity="row.quantity"
|
||||||
|
:price="row.sale.price"
|
||||||
|
:discount="row.sale.discount"
|
||||||
|
:mana="mana"
|
||||||
|
:promise="updateDiscount"
|
||||||
|
:data="{ saleFk: row.sale.id, rowIndex: rowIndex }"
|
||||||
|
@on-update="onUpdateDiscount"
|
||||||
|
/>
|
||||||
|
|
||||||
<q-popup-edit
|
<!-- <q-popup-edit
|
||||||
v-model="row.sale.discount"
|
v-model="row.sale.discount"
|
||||||
v-slot="scope"
|
v-slot="scope"
|
||||||
:title="manaTitle"
|
title="Update discount"
|
||||||
buttons
|
buttons
|
||||||
>
|
>
|
||||||
|
<q-banner
|
||||||
|
class="bg-primary text-center q-mb-md"
|
||||||
|
rounded
|
||||||
|
dense
|
||||||
|
>
|
||||||
|
{{ t('Mana') }} {{ toCurrency(mana) }}
|
||||||
|
</q-banner>
|
||||||
<q-input
|
<q-input
|
||||||
v-model="scope.value"
|
v-model="scope.value"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -227,7 +267,8 @@ const totalClaimed = 0;
|
||||||
@keyup.enter="scope.set"
|
@keyup.enter="scope.set"
|
||||||
@focus="($event) => $event.target.select()"
|
@focus="($event) => $event.target.select()"
|
||||||
/>
|
/>
|
||||||
</q-popup-edit>
|
<span>New amount:</span>
|
||||||
|
</q-popup-edit> -->
|
||||||
</q-td>
|
</q-td>
|
||||||
</template>
|
</template>
|
||||||
<template #body-cell-actions="{ row, rowIndex }">
|
<template #body-cell-actions="{ row, rowIndex }">
|
||||||
|
@ -295,5 +336,5 @@ es:
|
||||||
Amount: Total
|
Amount: Total
|
||||||
Amount Claimed: Cantidad reclamada
|
Amount Claimed: Cantidad reclamada
|
||||||
Delete claimed sale: Eliminar venta reclamada
|
Delete claimed sale: Eliminar venta reclamada
|
||||||
Mana: Maná
|
Discount updated: Descuento actualizado
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
Loading…
Reference in New Issue