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 { toDate, toCurrency, toPercentage } from 'src/filters';
|
||||
import VnDiscount from 'components/common/vnDiscount.vue';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const route = useRoute();
|
||||
|
@ -90,13 +91,18 @@ const columns = computed(() => [
|
|||
name: 'discount',
|
||||
label: t('Discount'),
|
||||
field: ({ sale }) => sale.discount,
|
||||
format: (value) => toPercentage(value),
|
||||
format: (value) => toPercentage(value / 100),
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
name: '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),
|
||||
sortable: true,
|
||||
},
|
||||
|
@ -106,6 +112,7 @@ const columns = computed(() => [
|
|||
},
|
||||
]);
|
||||
|
||||
const selected = ref([]);
|
||||
const mana = ref(0);
|
||||
async function fetchMana() {
|
||||
const ticketId = claim.value.ticketFk;
|
||||
|
@ -118,7 +125,25 @@ async function updateQuantity({ 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) {
|
||||
quasar
|
||||
|
@ -141,9 +166,6 @@ async function remove({ id }) {
|
|||
message: t('globals.rowRemoved'),
|
||||
});
|
||||
}
|
||||
|
||||
const manaTitle = computed(() => `${t('Mana')} ${toCurrency(mana.value)}`);
|
||||
const totalClaimed = 0;
|
||||
</script>
|
||||
<template>
|
||||
<q-page-sticky position="top" :offset="[0, 0]" expand>
|
||||
|
@ -184,6 +206,8 @@ const totalClaimed = 0;
|
|||
:dense="$q.screen.lt.md"
|
||||
:pagination="{ rowsPerPage: 0 }"
|
||||
row-key="id"
|
||||
selection="multiple"
|
||||
v-model:selected="selected"
|
||||
hide-pagination
|
||||
>
|
||||
<template #body-cell-claimed="{ row, value }">
|
||||
|
@ -209,16 +233,32 @@ const totalClaimed = 0;
|
|||
</q-td>
|
||||
</template>
|
||||
|
||||
<template #body-cell-discount="{ row, value }">
|
||||
<template #body-cell-discount="{ row, value, rowIndex }">
|
||||
<q-td auto-width align="right" class="dimmed">
|
||||
{{ 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-slot="scope"
|
||||
:title="manaTitle"
|
||||
title="Update discount"
|
||||
buttons
|
||||
>
|
||||
<q-banner
|
||||
class="bg-primary text-center q-mb-md"
|
||||
rounded
|
||||
dense
|
||||
>
|
||||
{{ t('Mana') }} {{ toCurrency(mana) }}
|
||||
</q-banner>
|
||||
<q-input
|
||||
v-model="scope.value"
|
||||
type="number"
|
||||
|
@ -227,7 +267,8 @@ const totalClaimed = 0;
|
|||
@keyup.enter="scope.set"
|
||||
@focus="($event) => $event.target.select()"
|
||||
/>
|
||||
</q-popup-edit>
|
||||
<span>New amount:</span>
|
||||
</q-popup-edit> -->
|
||||
</q-td>
|
||||
</template>
|
||||
<template #body-cell-actions="{ row, rowIndex }">
|
||||
|
@ -295,5 +336,5 @@ es:
|
|||
Amount: Total
|
||||
Amount Claimed: Cantidad reclamada
|
||||
Delete claimed sale: Eliminar venta reclamada
|
||||
Mana: Maná
|
||||
Discount updated: Descuento actualizado
|
||||
</i18n>
|
||||
|
|
Loading…
Reference in New Issue