feat: refs #7984 add currency in ticket basic-data
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Alex Moreno 2025-01-20 14:07:05 +01:00
parent f3f0c0e88c
commit 3c6a4c1e16
9 changed files with 155 additions and 101 deletions

View File

@ -6,7 +6,7 @@ import { ref } from 'vue';
import { watch } from 'vue';
const model = defineModel({
type: [String, Number, Object],
type: Number,
default: null,
});
@ -16,8 +16,12 @@ const clientId = defineModel('clientId', {
});
const currencyList = ref([]);
const emit = defineEmits(['newValue']);
onMounted(async () => {
currencyList.value = (await axios.get('Currencies')).data;
emitCurrency(model.value);
});
watch(
@ -30,6 +34,14 @@ watch(
model.value = data.defaultCurrencyFk;
}
);
function emitCurrency(id) {
if (!id) return;
emit(
'newValue',
currencyList.value?.find((c) => c.id == id)
);
}
</script>
<template>
@ -40,5 +52,6 @@ watch(
:options="currencyList"
option-label="name"
option-caption="code"
@update:model-value="(id) => emitCurrency(id)"
/>
</template>

View File

@ -27,26 +27,28 @@ const $props = defineProps({
description: 'find currency code in array data model',
},
});
const arrayData = $props.arrayDataModel && useArrayData($props.arrayDataModel);
const foreignValue = computed(() => $props.model?.[$props.foreignField]);
const localValue = computed(() => $props.model?.[$props.localField]);
const currency = computed(() => $props.currencyCode ?? currencyCodeModel.value);
const currency = computed(
() => $props.currencyCode ?? arrayData.store.data?.currency?.code
);
const toCurrencyLabel = computed(() =>
toCurrency(foreignValue.value ?? localValue.value, currency.value)
);
const currencyCodeModel = ref();
onMounted(() => {
if ($props.arrayDataModel) {
const arrayData = useArrayData($props.arrayDataModel);
currencyCodeModel.value = arrayData.store.data?.currency?.code;
}
});
// onMounted(() => {
// if ($props.arrayDataModel) {
// currencyCodeModel.value = arrayData.store.data?.currency?.code;
// }
// });
</script>
<template>
<span :title="toCurrencyLabel">
<span v-if="foreignValue">{{ toCurrency(localValue) }} /</span>
{{ toCurrencyLabel }}
<span :title="toCurrencyLabel" v-if="currency && localValue">
<span v-if="foreignValue">{{ toCurrencyLabel }} /</span>
{{ toCurrency(localValue) }}
</span>
<span v-else>-</span>
</template>

View File

@ -22,7 +22,7 @@ export function useVnConfirm() {
{ customHTML: () => h(component, props) }
),
}).onOk(async () => {
if (successFn) successFn();
if (successFn) await successFn();
});
};

View File

@ -16,7 +16,7 @@ import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
const { t } = useI18n();
const route = useRoute();
const state = useState();
const ORDER_MODEL = 'order';
const ORDER_MODEL = 'Order';
const isNew = Boolean(!route.params.id);
const clientList = ref([]);
@ -56,33 +56,6 @@ const fetchOrderDetails = (order) => {
fetchAgencyList(order?.landed, order?.addressFk);
};
const orderFilter = {
include: [
{ relation: 'agencyMode', scope: { fields: ['name'] } },
{
relation: 'address',
scope: { fields: ['nickname'] },
},
{ relation: 'rows', scope: { fields: ['id'] } },
{
relation: 'client',
scope: {
fields: [
'salesPersonFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
relation: 'salesPersonUser',
scope: { fields: ['id', 'name'] },
},
},
},
],
};
const onClientChange = async (clientId) => {
const { data } = await axios.get(`Clients/${clientId}`);
await fetchAddressList(data.defaultAddressFk);
@ -93,12 +66,9 @@ const onClientChange = async (clientId) => {
<VnSubToolbar v-if="isNew" />
<div class="q-pa-md">
<FormModel
:url="`Orders/${route.params.id}`"
:url-update="`Orders/${route.params.id}/updateBasicData`"
:model="ORDER_MODEL"
:filter="orderFilter"
@on-fetch="fetchOrderDetails"
auto-load
>
<template #form="{ data }">
<VnRow>

View File

@ -9,9 +9,33 @@ import OrderDescriptor from 'pages/Order/Card/OrderDescriptor.vue';
base-url="Orders"
:descriptor="OrderDescriptor"
:user-filter="{
include: {
relation: 'currency',
},
include: [
{ relation: 'agencyMode', scope: { fields: ['name'] } },
{
relation: 'address',
scope: { fields: ['nickname'] },
},
{ relation: 'rows', scope: { fields: ['id'] } },
{
relation: 'client',
scope: {
fields: [
'salesPersonFk',
'name',
'isActive',
'isFreezed',
'isTaxDataChecked',
],
include: {
relation: 'salesPersonUser',
scope: { fields: ['id', 'name'] },
},
},
},
{
relation: 'currency',
},
],
}"
/>
</template>

View File

@ -9,6 +9,7 @@ import FetchData from 'components/FetchData.vue';
import { useStateStore } from 'stores/useStateStore';
import { toCurrency } from 'filters/index';
import { useRole } from 'src/composables/useRole';
import VnCurrency from 'src/components/ui/VnCurrency.vue';
const haveNegatives = defineModel('haveNegatives', { type: Boolean, required: true });
const formData = defineModel({ type: Object, required: true });
@ -18,7 +19,7 @@ const { t } = useI18n();
const { hasAny } = useRole();
const ticketUpdateActions = ref(null);
const rows = computed(() => formData.value?.sale?.items || []);
const rows = computed(() => formData.value?.ticket?.sales || []);
const columns = computed(() => [
{
@ -83,20 +84,6 @@ const loadDefaultTicketAction = () => {
formData.value.option = isSalesAssistant ? 'mana' : 'renewPrices';
};
const totalPrice = computed(() => {
return rows.value.reduce((acc, item) => acc + item.price * item.quantity, 0);
});
const totalNewPrice = computed(() => {
return rows.value.reduce(
(acc, item) => acc + item.component.newPrice * item.quantity,
0
);
});
const totalDifference = computed(() => {
return rows.value.reduce((acc, item) => acc + item.component?.difference || 0, 0);
});
const showMovableColumn = computed(() => (haveDifferences.value > 0 ? ['movable'] : []));
const haveDifferences = computed(() => formData.value.sale?.haveDifferences);
async function ticketHaveNegatives() {
@ -141,17 +128,34 @@ onMounted(async () => {
<QCardSection class="column items-left" horizontal>
<span>
{{ t('basicData.price') }}:
{{ toCurrency(totalPrice) }}
<VnCurrency
:model="formData?.ticket"
local-field="totalUnitPrice"
foreign-field="totalForeignUnitPrice"
:currency-code="formData.currency.code"
/>
</span>
</QCardSection>
<QCardSection class="column items-left" horizontal>
<span>
{{ t('basicData.newPrice') }}: {{ toCurrency(totalNewPrice) }}
{{ t('basicData.newPrice') }}:
<VnCurrency
:model="formData?.ticket"
local-field="totalNewPrice"
foreign-field="totalForeignNewPrice"
:currency-code="formData.currency.code"
/>
</span>
</QCardSection>
<QCardSection class="column items-left" horizontal>
<span>
{{ t('basicData.difference') }}: {{ toCurrency(totalDifference) }}
{{ t('basicData.difference') }}:
<VnCurrency
:model="formData?.ticket"
local-field="totalDifference"
foreign-field="totalForeignDifference"
:currency-code="formData.currency.code"
/>
</span>
</QCardSection>
</QCard>
@ -244,5 +248,33 @@ onMounted(async () => {
/>
</QTd>
</template>
<template #body-cell-price="{ row }">
<QTd class="number">
<VnCurrency
:model="row.component"
:currency-code="formData.currency.code"
/>
</QTd>
</template>
<template #body-cell-newPrice="{ row }">
<QTd class="number">
<VnCurrency
:model="row.component"
:currency-code="formData.currency.code"
local-field="newPrice"
foreign-field="newForeignPrice"
/>
</QTd>
</template>
<template #body-cell-difference="{ row }">
<QTd class="number">
<VnCurrency
:model="row.component"
:currency-code="formData.currency.code"
local-field="difference"
foreign-field="foreignDifference"
/>
</QTd>
</template>
</QTable>
</template>

View File

@ -15,6 +15,7 @@ import useNotify from 'src/composables/useNotify.js';
import { useAcl } from 'src/composables/useAcl';
import { useValidator } from 'src/composables/useValidator';
import { toTimeFormat } from 'filters/date.js';
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
const formData = defineModel({
type: Object,
@ -357,7 +358,7 @@ async function getZone(options) {
:rules="validate('basicData.alias')"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md no-wrap">
<VnRow>
<VnSelect
:label="t('ticketList.company')"
v-model="formData.companyFk"
@ -369,6 +370,12 @@ async function getZone(options) {
:required="true"
:rules="validate('ticketList.company')"
/>
<VnSelectCurrency
v-model="formData.currencyFk"
@new-value="(value) => (formData.currency = value)"
/>
</VnRow>
<VnRow class="row q-gutter-md q-mb-md no-wrap">
<VnSelect
:label="t('basicData.agency')"
v-model="agencyModeId"

View File

@ -77,12 +77,13 @@ const getPriceDifference = async () => {
zoneId: formData.value.zoneFk,
warehouseId: formData.value.warehouseFk,
shipped: formData.value.shipped,
currencyId: formData.value.currencyFk,
};
const { data } = await axios.post(
`tickets/${formData.value.id}/priceDifference`,
params
);
formData.value.sale = data;
formData.value.ticket = data;
};
const submit = async () => {
@ -102,6 +103,7 @@ const submit = async () => {
option: formData.value.option,
isWithoutNegatives: formData.value.withoutNegatives,
withWarningAccept: formData.value.withWarningAccept,
currencyFk: formData.value.currencyFk,
keepPrice: false,
};
@ -119,7 +121,7 @@ const submit = async () => {
const submitWithNegatives = async () => {
formData.value.withWarningAccept = true;
submit();
await submit();
};
const onNextStep = async () => {
@ -136,7 +138,7 @@ const onNextStep = async () => {
t('basicData.negativesConfirmMessage'),
submitWithNegatives
);
else submit();
else await submit();
}
};

View File

@ -22,6 +22,8 @@ import { toTimeFormat } from 'src/filters/date';
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
import TicketProblems from 'src/components/TicketProblems.vue';
import VnSection from 'src/components/common/VnSection.vue';
import VnSelectCompany from 'src/components/common/VnSelectCompany.vue';
import VnSelectCurrency from 'src/components/common/VnSelectCurrency.vue';
const route = useRoute();
const router = useRouter();
@ -636,43 +638,45 @@ function setReference(data) {
</VnSelect>
</VnRow>
<VnRow>
<div class="col">
<VnInputDate
placeholder="dd-mm-aaa"
:label="t('globals.landed')"
v-model="data.landed"
@update:model-value="() => fetchAvailableAgencies(data)"
/>
</div>
<VnInputDate
placeholder="dd-mm-aaa"
:label="t('globals.landed')"
v-model="data.landed"
@update:model-value="() => fetchAvailableAgencies(data)"
/>
</VnRow>
<VnRow>
<div class="col">
<VnSelect
url="Warehouses"
:sort-by="['name']"
:label="t('globals.warehouse')"
v-model="data.warehouseId"
:options="warehousesOptions"
option-value="id"
option-label="name"
hide-selected
required
@update:model-value="() => fetchAvailableAgencies(data)"
/>
</div>
<VnSelect
url="Warehouses"
:sort-by="['name']"
:label="t('globals.warehouse')"
v-model="data.warehouseId"
:options="warehousesOptions"
option-value="id"
option-label="name"
hide-selected
required
@update:model-value="() => fetchAvailableAgencies(data)"
/>
</VnRow>
<VnRow>
<div class="col">
<VnSelect
:label="t('globals.agency')"
v-model="data.agencyModeId"
:options="agenciesOptions"
option-value="agencyModeFk"
option-label="agencyMode"
hide-selected
/>
</div>
<VnSelect
:label="t('globals.agency')"
v-model="data.agencyModeId"
:options="agenciesOptions"
option-value="agencyModeFk"
option-label="agencyMode"
hide-selected
/>
</VnRow>
<VnSelectCompany
v-model="data.companyId"
v-model:client-id="data.clientId"
/>
<VnSelectCurrency
v-model="data.currencyId"
v-model:client-id="data.clientId"
/>
</template>
</VnTable>
</template>