0
0
Fork 0

feat(claim): added claim lines section

This commit is contained in:
Joan Sanchez 2023-03-21 14:54:28 +01:00
parent b077622fe7
commit 6e935cb91f
3 changed files with 281 additions and 3 deletions

View File

@ -72,9 +72,9 @@ function stateColor(code) {
<q-item-section v-if="entity.claimState">
<q-item-label caption>{{ t('claim.card.state') }}</q-item-label>
<q-item-label>
<q-chip :color="stateColor(entity.claimState.code)" dense>
<q-badge :color="stateColor(entity.claimState.code)" dense>
{{ entity.claimState.description }}
</q-chip>
</q-badge>
</q-item-label>
</q-item-section>
</q-item>

View File

@ -0,0 +1,269 @@
<script setup>
import axios from 'axios';
import { ref, computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import { useRoute } from 'vue-router';
import { useArrayData } from 'src/composables/useArrayData';
import { useStateStore } from 'stores/useStateStore';
import Paginate from 'src/components/PaginateData.vue';
import FetchData from 'components/FetchData.vue';
import VnConfirm from 'src/components/ui/VnConfirm.vue';
import { toDate, toCurrency, toPercentage } from 'src/filters';
const quasar = useQuasar();
const route = useRoute();
const { t } = useI18n();
const stateStore = useStateStore();
const arrayData = useArrayData('ClaimLines');
const store = arrayData.store;
const filter = {
include: {
relation: 'sale',
scope: {
fields: ['concept', 'ticketFk', 'price', 'quantity', 'discount', 'itemFk'],
include: {
relation: 'ticket',
},
},
},
};
const amount = ref(0);
const amountClaimed = ref(0);
async function onFetch(rows) {
amount.value = rows.reduce(
(acumulator, { sale }) => acumulator + sale.price * sale.quantity,
0
);
amountClaimed.value = rows.reduce(
(acumulator, line) => acumulator + line.sale.price * line.quantity,
0
);
}
const columns = computed(() => [
{
name: 'dated',
label: t('Delivered'),
field: ({ sale: { ticket } }) => toDate(ticket.landed),
sortable: true,
},
{
name: 'quantity',
label: t('Quantity'),
field: ({ sale }) => sale.quantity,
sortable: true,
},
{
name: 'claimed',
label: t('Claimed'),
field: (row) => row.quantity,
sortable: true,
},
{
name: 'description',
label: t('Description'),
field: ({ sale }) => sale.concept,
},
{
name: 'price',
label: t('Price'),
field: ({ sale }) => sale.price,
format: (value) => toCurrency(value),
sortable: true,
},
{
name: 'discount',
label: t('Discount'),
field: ({ sale }) => sale.discount,
format: (value) => toPercentage(value),
sortable: true,
},
{
name: 'total',
label: t('Total'),
field: ({ sale }) => sale.price * sale.quantity,
format: (value) => toCurrency(value),
sortable: true,
},
{
name: 'actions',
label: t('Actions'),
},
]);
async function updateQuantity({ id, quantity }) {
if (!id) return;
await axios.patch(`ClaimBeginnings/${id}`, { quantity });
}
async function updateDiscount({ id, discount }) {}
async function confirmRemove(id, index) {
quasar
.dialog({
component: VnConfirm,
componentProps: {
title: t('Delete claimed sale'),
data: { id },
promise: remove,
},
})
.onOk(() => store.data.splice(index, 1));
}
async function remove({ id }) {
if (!id) return;
await axios.delete(`ClaimBeginnings/${id}`);
quasar.notify({
type: 'positive',
message: t('globals.rowRemoved'),
});
}
</script>
<template>
<q-page-sticky position="top" :offset="[0, 0]" expand>
<q-toolbar class="bg-dark text-white">
<q-toolbar-title class="row q-gutter-md">
<div>
{{ t('Amount') }}
<q-chip>{{ toCurrency(amount) }}</q-chip>
</div>
<q-separator dark vertical />
<div>
{{ t('Amount Claimed') }}
<q-chip color="positive">{{ toCurrency(amountClaimed) }}</q-chip>
</div>
</q-toolbar-title>
</q-toolbar>
</q-page-sticky>
<div class="column items-center">
<div class="list">
<paginate
data-key="ClaimLines"
:url="`Claims/${route.params.id}/lines`"
:filter="filter"
@on-fetch="onFetch"
auto-load
>
<template #body="{ rows }">
<q-table
:columns="columns"
:rows="rows"
:dense="$q.screen.lt.md"
:pagination="{ rowsPerPage: 0 }"
row-key="id"
hide-pagination
>
<template #body-cell-claimed="{ row, value }">
<q-td auto-width align="right" class="dimmed">
<span>{{ value }}</span>
<q-popup-edit
v-model="row.quantity"
v-slot="scope"
title="Claimed quantity"
buttons
@update:model-value="updateQuantity(row)"
>
<q-input
v-model="scope.value"
dense
autofocus
@keyup.enter="scope.set"
@focus="($event) => $event.target.select()"
/>
</q-popup-edit>
</q-td>
</template>
<template #body-cell-discount="{ row, value }">
<q-td auto-width align="right" class="dimmed">
{{ value }}
<q-popup-edit
v-model="row.sale.discount"
v-slot="scope"
title="Discount"
buttons
>
<q-input
v-model="scope.value"
dense
autofocus
@keyup.enter="scope.set"
@focus="($event) => $event.target.select()"
/>
</q-popup-edit>
</q-td>
</template>
<template #body-cell-actions="{ row, rowIndex }">
<q-td auto-width class="text-center">
<q-btn
icon="vn:deleteline"
color="primary"
flat
round
dense
@click="confirmRemove(row.id, rowIndex)"
>
<q-tooltip>Delete claimed sale</q-tooltip>
</q-btn>
</q-td>
</template>
</q-table>
</template>
</paginate>
</div>
</div>
<Teleport
v-if="stateStore.isHeaderMounted() && !quasar.platform.is.mobile"
to="#actions-prepend"
>
<div class="row q-gutter-x-sm">
<q-btn @click="addRow()" icon="add" color="primary" dense rounded>
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
</q-btn>
<q-separator vertical />
</div>
</Teleport>
<q-page-sticky
v-if="quasar.platform.is.mobile"
position="bottom"
:offset="[0, 0]"
expand
>
<q-toolbar class="bg-primary text-white q-pa-none">
<q-tabs class="full-width" align="justify" inline-label narrow-indicator>
<q-tab @click="addRow()" icon="add_circle" :label="t('globals.add')" />
</q-tabs>
</q-toolbar>
</q-page-sticky>
</template>
<style lang="scss" scoped>
.list {
padding-top: 50px;
width: 100%;
}
</style>
<i18n>
es:
Delivered: Entregado
Quantity: Cantidad
Claimed: Reclamada
Description: Descripción
Price: Precio
Discount: Descuento
Actions: Acciones
Amount: Total
Amount Claimed: Cantidad reclamada
Delete claimed sale: Eliminar venta reclamada
</i18n>

View File

@ -11,7 +11,7 @@ export default {
redirect: { name: 'ClaimMain' },
menus: {
main: ['ClaimList', 'ClaimRmaList'],
card: ['ClaimBasicData', 'ClaimRma', 'ClaimPhotos', 'ClaimLog'],
card: ['ClaimBasicData', 'ClaimLines', 'ClaimRma', 'ClaimPhotos', 'ClaimLog'],
},
children: [
{
@ -85,6 +85,15 @@ export default {
},
component: () => import('src/pages/Claim/Card/ClaimPhoto.vue'),
},
{
name: 'ClaimLines',
path: 'lines',
meta: {
title: 'lines',
icon: 'history',
},
component: () => import('src/pages/Claim/Card/ClaimLines.vue'),
},
{
name: 'ClaimLog',
path: 'log',