salix-front/src/pages/Travel/Card/TravelSummary.vue

422 lines
14 KiB
Vue

<script setup>
import { ref, computed } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import CardSummary from 'components/ui/CardSummary.vue';
import VnLv from 'src/components/ui/VnLv.vue';
import VnTitle from 'src/components/common/VnTitle.vue';
import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue';
import FetchData from 'src/components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue';
import { toDate, toCurrency, toCelsius } from 'src/filters';
import { toDateTimeFormat } from 'src/filters/date.js';
import { dashIfEmpty } from 'src/filters';
import axios from 'axios';
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
const $props = defineProps({
id: {
type: Number,
required: false,
default: null,
},
});
const route = useRoute();
const { t } = useI18n();
const entityId = computed(() => $props.id || route.params.id);
const summaryRef = ref();
const travel = ref();
const entries = ref([]);
const thermographs = ref([]);
const warehouses = ref([]);
const entriesTableColumns = computed(() => {
return [
{
label: t('globals.confirmed'),
field: 'isConfirmed',
name: 'isConfirmed',
align: 'left',
showValue: false,
},
{
label: t('travel.summary.entryId'),
field: 'id',
name: 'id',
align: 'left',
showValue: false,
},
{
label: t('globals.pageTitles.supplier'),
field: 'supplierName',
name: 'supplierName',
align: 'left',
showValue: true,
},
{
label: t('globals.reference'),
field: 'reference',
name: 'reference',
align: 'left',
showValue: true,
},
{
label: t('travel.summary.hb'),
field: 'hb',
name: 'hb',
align: 'left',
showValue: true,
},
{
label: t('travel.summary.freight'),
field: 'freightValue',
name: 'freightValue',
align: 'left',
format: (val) => {
return toCurrency(val);
},
showValue: true,
},
{
label: t('travel.summary.package'),
field: 'packageValue',
name: 'packageValue',
align: 'left',
format: (val) => {
return toCurrency(val);
},
showValue: true,
},
{ label: 'CC', field: 'cc', name: 'cc', align: 'left', showValue: true },
{
label: 'Pallet',
field: 'pallet',
name: 'pallet',
align: 'left',
showValue: true,
},
{ label: 'm³', field: 'm3', name: 'm3', align: 'left', showValue: true },
{
label: t('entry.basicData.initialTemperature'),
field: 'initialTemperature',
name: 'initialTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: t('entry.basicData.finalTemperature'),
field: 'finalTemperature',
name: 'finalTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: '',
field: 'observation',
name: 'observation',
align: 'left',
toolTip: 'Observation three',
showValue: false,
},
];
});
const thermographsTableColumns = computed(() => {
return [
{
label: t('globals.code'),
field: 'thermographFk',
name: 'thermographFk',
align: 'left',
},
{
label: t('travel.thermographs.temperature'),
field: 'temperatureFk',
name: 'temperatureFk',
align: 'left',
},
{
label: t('travel.thermographs.carrier'),
field: (row) => row.agencyMode?.name,
name: 'agencyModeFk',
align: 'left',
},
{
label: t('globals.maxTemperature'),
field: 'maxTemperature',
name: 'maxTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: t('globals.minTemperature'),
field: 'minTemperature',
name: 'minTemperature',
align: 'left',
format: (val) => toCelsius(val),
},
{
label: t('globals.state'),
field: 'result',
name: 'result',
align: 'left',
},
{
label: t('travel.thermographs.destination'),
field: 'warehouseFk',
name: 'destination',
align: 'left',
format: (val) =>
warehouses.value.find((warehouse) => warehouse.id === val)?.name,
},
{
label: t('globals.created'),
field: 'created',
name: 'created',
align: 'left',
format: (val) => toDate(val),
},
];
});
const entriesTableRows = computed(() => {
if (!entries.value && !entries.value.length > 0) return [];
return entries.value;
});
const entriesTotals = computed(() => {
const totals = {
hb: 0,
freightValue: 0,
packageValue: 0,
cc: 0,
pallet: 0,
m3: 0,
};
entriesTableRows.value.forEach((row) => {
for (const key in totals) {
totals[key] += row[key] || 0;
}
});
return {
hb: totals.hb.toFixed(2),
freight: toCurrency(totals.freightValue),
packageValue: toCurrency(totals.packageValue),
cc: totals.cc.toFixed(2),
pallet: totals.pallet.toFixed(2),
m3: totals.m3.toFixed(2),
};
});
const getTravelEntries = async (id) => {
const { data } = await axios.get(`Travels/${id}/getEntries`);
entries.value = data;
};
const getTravelThermographs = async (id) => {
const filter = {
include: [
{
relation: 'agencyMode',
scope: {
fields: ['id', 'name'],
},
},
{
relation: 'warehouse',
scope: {
fields: ['id', 'name'],
},
},
],
where: { travelFk: id },
};
const { data } = await axios.get('TravelThermographs', {
params: { filter },
});
thermographs.value = data;
};
async function setTravelData(travelData) {
if (travelData) {
travel.value = travelData;
await getTravelEntries(travel.value.id);
await getTravelThermographs(travel.value.id);
}
}
const getLink = (param) => `#/travel/${entityId.value}/${param}`;
</script>
<template>
<FetchData
url="Warehouses"
:filter="{ fields: ['id', 'name'] }"
order="name"
@on-fetch="(data) => (warehouses = data)"
auto-load
/>
<CardSummary
ref="summaryRef"
:url="`Travels/${entityId}/getTravel`"
@on-fetch="(data) => setTravelData(data)"
data-key="TravelSummary"
>
<template #header>
<span>{{ travel.id }} - {{ travel.ref }}</span>
</template>
<template #menu="{ entity }">
<TravelDescriptorMenuItems :travel="entity" />
</template>
<template #body>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<VnTitle
:url="getLink('basic-data')"
:text="t('globals.pageTitles.basicData')"
/>
</QCardSection>
<VnLv :label="t('globals.shipped')" :value="toDate(travel.shipped)" />
<VnLv
:label="t('globals.warehouseOut')"
:value="travel.warehouseOut?.name"
/>
<VnRow>
<QCheckbox
:label="t('travel.basicData.isRaid')"
v-model="travel.isRaid"
:disable="true"
/>
</VnRow>
<VnRow>
<QCheckbox
:label="t('travel.summary.delivered')"
v-model="travel.isDelivered"
:disable="true"
/>
</VnRow>
</QCard>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<VnTitle
:url="getLink('basic-data')"
:text="t('globals.pageTitles.basicData')"
/>
</QCardSection>
<VnLv :label="t('globals.landed')" :value="toDate(travel.landed)" />
<VnLv
:label="t('globals.warehouseIn')"
:value="travel.warehouseIn?.name"
/>
<VnLv
:label="t('travel.basicData.daysInForward')"
:value="travel?.daysInForward"
/>
<QCheckbox
:label="t('travel.summary.received')"
v-model="travel.isReceived"
:disable="true"
/>
</QCard>
<QCard class="vn-one">
<QCardSection class="q-pa-none">
<VnTitle
:url="getLink('basic-data')"
:text="t('globals.pageTitles.basicData')"
/>
</QCardSection>
<VnLv :label="t('globals.agency')" :value="travel.agency?.name" />
<VnLv :label="t('globals.reference')" :value="travel.ref" />
<VnLv label="" :value="travel.m3" />
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
<VnLv
:label="t('travel.summary.availabled')"
:value="
dashIfEmpty(toDateTimeFormat(travel.availabled))
"
/>
</QCard>
<QCard class="full-width">
<VnTitle :text="t('travel.summary.entries')" />
<QTable
:rows="entriesTableRows"
:columns="entriesTableColumns"
row-key="id"
class="full-width q-mt-md"
>
<template #header="props">
<QTr :props="props" class="bg">
<QTh v-for="col in props.cols" :key="col.name" :props="props">
{{ t(col.label) }}
</QTh>
</QTr>
</template>
<template #body-cell-isConfirmed="{ col, row }">
<QTd>
<QCheckbox
v-if="col.name === 'isConfirmed'"
:true-value="1"
:false-value="0"
v-model="row[col.name]"
:disable="true"
/>
</QTd>
</template>
<template #body-cell-id="{ col, value }">
<QTd>
<QBtn v-if="col.name === 'id'" flat class="link">
{{ value }}
<EntryDescriptorProxy :id="value" />
</QBtn>
</QTd>
</template>
<template #body-cell-observation="{ value }">
<QTd>
<QIcon name="insert_drive_file" color="primary" size="24px">
<QTooltip>{{ value }}</QTooltip>
</QIcon>
</QTd>
</template>
<template #bottom-row>
<QTd></QTd>
<QTd></QTd>
<QTd></QTd>
<QTd></QTd>
<QTd class="text-bold">{{ entriesTotals.hb }}</QTd>
<QTd class="text-bold">{{ entriesTotals.freight }}</QTd>
<QTd class="text-bold">{{ entriesTotals.packageValue }}</QTd>
<QTd class="text-bold">{{ entriesTotals.cc }}</QTd>
<QTd class="text-bold">{{ entriesTotals.pallet }}</QTd>
<QTd class="text-bold">{{ entriesTotals.m3 }}</QTd>
</template>
</QTable>
</QCard>
<QCard class="full-width" v-if="thermographs.length > 0">
<RouterLink
class="header header-link"
:to="{
name: 'TravelThermographsIndex',
params: { id: travel.id },
}"
>
{{ t('travel.summary.thermographs') }}
<QIcon name="open_in_new" />
</RouterLink>
<QTable
:rows="thermographs"
:columns="thermographsTableColumns"
row-key="id"
class="full-width q-mt-md"
/>
</QCard>
</template>
</CardSummary>
</template>