forked from verdnatura/salix-front
Merge branch 'dev' into 6486-salixColors
This commit is contained in:
commit
c18a974ff8
|
@ -1,5 +1,6 @@
|
|||
FROM node:stretch-slim
|
||||
RUN npm install -g @quasar/cli
|
||||
RUN corepack enable pnpm
|
||||
RUN pnpm install -g @quasar/cli
|
||||
WORKDIR /app
|
||||
COPY dist/spa ./
|
||||
CMD ["quasar", "serve", "./", "--history", "--hostname", "0.0.0.0"]
|
||||
|
|
|
@ -62,7 +62,7 @@ pipeline {
|
|||
NODE_ENV = ""
|
||||
}
|
||||
steps {
|
||||
sh 'npm install --prefer-offline'
|
||||
sh 'pnpm install --prefer-offline'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
|
@ -73,7 +73,7 @@ pipeline {
|
|||
NODE_ENV = ""
|
||||
}
|
||||
steps {
|
||||
sh 'npm run test:unit:ci'
|
||||
sh 'pnpm run test:unit:ci'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
|
|
17
package.json
17
package.json
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"name": "salix-front",
|
||||
"version": "24.10.0",
|
||||
"version": "24.12.0",
|
||||
"description": "Salix frontend",
|
||||
"productName": "Salix",
|
||||
"author": "Verdnatura",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@8.15.1",
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .js,.vue ./",
|
||||
"format": "prettier --write \"**/*.{js,vue,scss,html,md,json}\" --ignore-path .gitignore",
|
||||
|
@ -16,12 +17,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@quasar/cli": "^2.3.0",
|
||||
"@quasar/extras": "^1.16.4",
|
||||
"@quasar/extras": "^1.16.9",
|
||||
"axios": "^1.4.0",
|
||||
"chromium": "^3.0.3",
|
||||
"croppie": "^2.6.5",
|
||||
"pinia": "^2.1.3",
|
||||
"quasar": "^2.12.0",
|
||||
"quasar": "^2.14.5",
|
||||
"validator": "^13.9.0",
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.2.2",
|
||||
|
@ -30,9 +31,9 @@
|
|||
"devDependencies": {
|
||||
"@intlify/unplugin-vue-i18n": "^0.8.1",
|
||||
"@pinia/testing": "^0.1.2",
|
||||
"@quasar/app-vite": "^1.4.3",
|
||||
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.3.0",
|
||||
"@vue/test-utils": "^2.3.2",
|
||||
"@quasar/app-vite": "^1.7.3",
|
||||
"@quasar/quasar-app-extension-testing-unit-vitest": "^0.4.0",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"cypress": "^12.13.0",
|
||||
"eslint": "^8.41.0",
|
||||
|
@ -50,8 +51,8 @@
|
|||
"bun": ">= 1.0.25"
|
||||
},
|
||||
"overrides": {
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"vite": "^4.3.5",
|
||||
"@vitejs/plugin-vue": "^5.0.4",
|
||||
"vite": "^5.1.4",
|
||||
"vitest": "^0.31.1"
|
||||
}
|
||||
}
|
||||
|
|
737
pnpm-lock.yaml
737
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -81,7 +81,7 @@ onMounted(async () => {
|
|||
});
|
||||
|
||||
// Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla
|
||||
state.set($props.model, $props.formInitialData ?? {});
|
||||
state.set($props.model, $props.formInitialData);
|
||||
if ($props.autoLoad && !$props.formInitialData) {
|
||||
await fetch();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useCapitalize } from 'src/composables/useCapitalize';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: { type: String, default: '' },
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const amount = computed({
|
||||
get() {
|
||||
return props.modelValue;
|
||||
},
|
||||
set(val) {
|
||||
emit('update:modelValue', val);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<VnInput
|
||||
v-model="amount"
|
||||
type="number"
|
||||
step="any"
|
||||
:label="useCapitalize(t('amount'))"
|
||||
/>
|
||||
</template>
|
||||
<i18n>
|
||||
es:
|
||||
amount: importe
|
||||
</i18n>
|
|
@ -111,7 +111,7 @@ function addDefaultData(data) {
|
|||
<FormModelPopup
|
||||
:title="formInitialData ? t('globals.edit') : t('globals.create')"
|
||||
model="dms"
|
||||
:form-initial-data="formInitialData"
|
||||
:form-initial-data="formInitialData ?? {}"
|
||||
:save-fn="save"
|
||||
>
|
||||
<template #form-inputs>
|
||||
|
|
|
@ -13,12 +13,49 @@ defineProps({
|
|||
<template>
|
||||
<div class="fetchedTags">
|
||||
<div class="wrap">
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value5 }">{{ $props.item.value5 }}</div>
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value6 }">{{ $props.item.value6 }}</div>
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value7 }">{{ $props.item.value7 }}</div>
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value8 }">{{ $props.item.value8 }}</div>
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value9 }">{{ $props.item.value9 }}</div>
|
||||
<div class="inline-tag" :class="{ empty: !$props.item.value10 }">{{ $props.item.value10 }}</div>
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.value5 }"
|
||||
:title="$props.item.tag5 + ': ' + $props.item.value5"
|
||||
>
|
||||
{{ $props.item.value5 }}
|
||||
</div>
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.tag6 }"
|
||||
:title="$props.item.tag6 + ': ' + $props.item.value6"
|
||||
>
|
||||
{{ $props.item.value6 }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.value7 }"
|
||||
:title="$props.item.tag7 + ': ' + $props.item.value7"
|
||||
>
|
||||
{{ $props.item.value7 }}
|
||||
</div>
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.value8 }"
|
||||
:title="$props.item.tag8 + ': ' + $props.item.value8"
|
||||
>
|
||||
{{ $props.item.value8 }}
|
||||
</div>
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.value9 }"
|
||||
:title="$props.item.tag9 + ': ' + $props.item.value9"
|
||||
>
|
||||
{{ $props.item.value9 }}
|
||||
</div>
|
||||
<div
|
||||
class="inline-tag"
|
||||
:class="{ empty: !$props.item.value10 }"
|
||||
:title="$props.item.tag10 + ': ' + $props.item.value10"
|
||||
>
|
||||
{{ $props.item.value10 }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
<template>
|
||||
<div id="row" class="q-gutter-md">
|
||||
<div id="row" class="q-gutter-md q-mb-md">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss" scopped>
|
||||
#row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
display: flex;
|
||||
> * {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
#row {
|
||||
grid-template-columns: 1fr;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -12,10 +12,6 @@ const props = defineProps({
|
|||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
function isValidNumber(value) {
|
||||
return /^(\d|\d+(\.|,)?\d+)$/.test(value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -51,28 +47,9 @@ function isValidNumber(value) {
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('Amount')"
|
||||
v-model="params.amount"
|
||||
is-outlined
|
||||
@update:model-value="
|
||||
(value) => {
|
||||
if (value.includes(','))
|
||||
params.amount = params.amount.replace(',', '.');
|
||||
}
|
||||
"
|
||||
:rules="[
|
||||
(val) => isValidNumber(val) || !val || 'Please type a number',
|
||||
]"
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="euro" size="sm" />
|
||||
</template>
|
||||
</VnInput>
|
||||
<VnCurrency v-model="params.amount" is-outlined />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInputDate v-model="params.from" :label="t('From')" is-outlined />
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRoute, useRouter } from 'vue-router';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
|
@ -20,13 +20,9 @@ const router = useRouter();
|
|||
|
||||
const formInitialData = reactive({ isDefaultAddress: false });
|
||||
|
||||
const townsFetchDataRef = ref(null);
|
||||
const postcodeFetchDataRef = ref(null);
|
||||
const urlCreate = ref('');
|
||||
|
||||
const postcodesOptions = ref([]);
|
||||
const citiesLocationOptions = ref([]);
|
||||
const provincesLocationOptions = ref([]);
|
||||
const agencyModes = ref([]);
|
||||
const incoterms = ref([]);
|
||||
const customsAgents = ref([]);
|
||||
|
@ -36,14 +32,6 @@ onBeforeMount(() => {
|
|||
getCustomsAgents();
|
||||
});
|
||||
|
||||
const onPostcodeCreated = async ({ code, provinceFk, townFk }, formData) => {
|
||||
await postcodeFetchDataRef.value.fetch();
|
||||
await townsFetchDataRef.value.fetch();
|
||||
formData.postalCode = code;
|
||||
formData.provinceFk = provinceFk;
|
||||
formData.city = citiesLocationOptions.value.find((town) => town.id === townFk).name;
|
||||
};
|
||||
|
||||
const getCustomsAgents = async () => {
|
||||
const { data } = await axios.get('CustomsAgents');
|
||||
customsAgents.value = data;
|
||||
|
@ -61,26 +49,16 @@ const toCustomerConsignees = () => {
|
|||
},
|
||||
});
|
||||
};
|
||||
function handleLocation(data, location) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||
data.postalCode = code;
|
||||
data.city = town;
|
||||
data.provinceFk = provinceFk;
|
||||
data.countryFk = countryFk;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
@on-fetch="(data) => (postcodesOptions = data)"
|
||||
auto-load
|
||||
ref="postcodeFetchDataRef"
|
||||
url="Postcodes/location"
|
||||
/>
|
||||
<FetchData
|
||||
@on-fetch="(data) => (citiesLocationOptions = data)"
|
||||
auto-load
|
||||
ref="townsFetchDataRef"
|
||||
url="Towns/location"
|
||||
/>
|
||||
<FetchData
|
||||
@on-fetch="(data) => (provincesLocationOptions = data)"
|
||||
auto-load
|
||||
url="Provinces/location"
|
||||
/>
|
||||
<fetch-data
|
||||
@on-fetch="(data) => (agencyModes = data)"
|
||||
auto-load
|
||||
|
@ -113,83 +91,17 @@ const toCustomerConsignees = () => {
|
|||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectDialog
|
||||
:label="t('Postcode')"
|
||||
:options="postcodesOptions"
|
||||
:roles-allowed-to-create="['deliveryAssistant']"
|
||||
<VnLocation
|
||||
:rules="validate('Worker.postcode')"
|
||||
hide-selected
|
||||
option-label="code"
|
||||
option-value="code"
|
||||
v-model="data.postalCode"
|
||||
>
|
||||
<template #form>
|
||||
<CustomerCreateNewPostcode
|
||||
@on-data-saved="onPostcodeCreated($event, data)"
|
||||
/>
|
||||
</template>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection v-if="scope.opt">
|
||||
<QItemLabel>{{ scope.opt.code }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt.code }} -
|
||||
{{ scope.opt.town.name }}
|
||||
({{ scope.opt.town.province.name }},
|
||||
{{ scope.opt.town.province.country.country }})
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectDialog>
|
||||
</div>
|
||||
<div class="col">
|
||||
<!-- ciudades -->
|
||||
<VnSelectFilter
|
||||
:label="t('City')"
|
||||
:options="citiesLocationOptions"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
v-model="data.city"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{
|
||||
`${scope.opt.name}, ${scope.opt.province.name} (${scope.opt.province.country.country})`
|
||||
}}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
:roles-allowed-to-create="['deliveryAssistant']"
|
||||
:options="postcodesOptions"
|
||||
v-model="data.location"
|
||||
@update:model-value="(location) => handleLocation(data, location)"
|
||||
></VnLocation>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Province')"
|
||||
:options="provincesLocationOptions"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="data.provinceFk"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{
|
||||
`${scope.opt.name} (${scope.opt.country.country})`
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Agency')"
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import { useRoute } from 'vue-router';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||
import FetchData from 'components/FetchData.vue';
|
||||
import FormModel from 'components/FormModel.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
|
@ -17,13 +17,8 @@ import CustomsNewCustomsAgent from 'src/pages/Customer/components/CustomerNewCus
|
|||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
||||
const townsFetchDataRef = ref(null);
|
||||
const postcodeFetchDataRef = ref(null);
|
||||
const urlUpdate = ref('');
|
||||
|
||||
const postcodesOptions = ref([]);
|
||||
const citiesLocationOptions = ref([]);
|
||||
const provincesLocationOptions = ref([]);
|
||||
const agencyModes = ref([]);
|
||||
const incoterms = ref([]);
|
||||
const customsAgents = ref([]);
|
||||
|
@ -34,14 +29,6 @@ onBeforeMount(() => {
|
|||
urlUpdate.value = `Clients/${route.params.id}/updateAddress/${route.params.consigneeId}`;
|
||||
});
|
||||
|
||||
const onPostcodeCreated = async ({ code, provinceFk, townFk }, formData) => {
|
||||
await postcodeFetchDataRef.value.fetch();
|
||||
await townsFetchDataRef.value.fetch();
|
||||
formData.postalCode = code;
|
||||
formData.provinceFk = provinceFk;
|
||||
formData.city = citiesLocationOptions.value.find((town) => town.id === townFk).name;
|
||||
};
|
||||
|
||||
const getData = async (observations) => {
|
||||
observationTypes.value = observations;
|
||||
|
||||
|
@ -97,26 +84,16 @@ const onDataSaved = () => {
|
|||
};
|
||||
axios.post('AddressObservations/crud', payload);
|
||||
};
|
||||
function handleLocation(data, location) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||
data.postalCode = code;
|
||||
data.city = town;
|
||||
data.provinceFk = provinceFk;
|
||||
data.countryFk = countryFk;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
ref="postcodeFetchDataRef"
|
||||
@on-fetch="(data) => (postcodesOptions = data)"
|
||||
auto-load
|
||||
url="Postcodes/location"
|
||||
/>
|
||||
<FetchData
|
||||
ref="townsFetchDataRef"
|
||||
@on-fetch="(data) => (citiesLocationOptions = data)"
|
||||
auto-load
|
||||
url="Towns/location"
|
||||
/>
|
||||
<FetchData
|
||||
@on-fetch="(data) => (provincesLocationOptions = data)"
|
||||
auto-load
|
||||
url="Provinces/location"
|
||||
/>
|
||||
<fetch-data
|
||||
@on-fetch="(data) => (agencyModes = data)"
|
||||
auto-load
|
||||
|
@ -168,83 +145,17 @@ const onDataSaved = () => {
|
|||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectDialog
|
||||
:label="t('Postcode')"
|
||||
:options="postcodesOptions"
|
||||
:roles-allowed-to-create="['deliveryAssistant']"
|
||||
<VnLocation
|
||||
:rules="validate('Worker.postcode')"
|
||||
hide-selected
|
||||
option-label="code"
|
||||
option-value="code"
|
||||
v-model="data.postalCode"
|
||||
>
|
||||
<template #form>
|
||||
<CustomerCreateNewPostcode
|
||||
@on-data-saved="onPostcodeCreated($event, data)"
|
||||
/>
|
||||
</template>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection v-if="scope.opt">
|
||||
<QItemLabel>{{ scope.opt.code }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{ scope.opt.code }} -
|
||||
{{ scope.opt.town.name }}
|
||||
({{ scope.opt.town.province.name }},
|
||||
{{ scope.opt.town.province.country.country }})
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectDialog>
|
||||
</div>
|
||||
<div class="col">
|
||||
<!-- ciudades -->
|
||||
<VnSelectFilter
|
||||
:label="t('City')"
|
||||
:options="citiesLocationOptions"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
v-model="data.city"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{ scope.opt.name }}</QItemLabel>
|
||||
<QItemLabel caption>
|
||||
{{
|
||||
`${scope.opt.name}, ${scope.opt.province.name} (${scope.opt.province.country.country})`
|
||||
}}
|
||||
</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
:roles-allowed-to-create="['deliveryAssistant']"
|
||||
:options="postcodesOptions"
|
||||
v-model="data.location"
|
||||
@update:model-value="(location) => handleLocation(data, location)"
|
||||
></VnLocation>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Province')"
|
||||
:options="provincesLocationOptions"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="data.provinceFk"
|
||||
>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection>
|
||||
<QItemLabel>{{
|
||||
`${scope.opt.name} (${scope.opt.country.country})`
|
||||
}}</QItemLabel>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectFilter>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('Agency')"
|
||||
|
|
|
@ -50,25 +50,23 @@ onMounted(() => {
|
|||
:key="index"
|
||||
class="row q-gutter-md q-mb-md"
|
||||
>
|
||||
<div class="col-3">
|
||||
<VnSelectFilter
|
||||
:label="t('entry.notes.observationType')"
|
||||
v-model="row.observationTypeFk"
|
||||
:options="entryObservationsOptions"
|
||||
:disable="!!row.id"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
hide-selected
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnInput
|
||||
:label="t('globals.description')"
|
||||
v-model="row.description"
|
||||
:rules="validate('EntryObservation.description')"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-1 row justify-center items-center">
|
||||
<VnSelectFilter
|
||||
:label="t('entry.notes.observationType')"
|
||||
v-model="row.observationTypeFk"
|
||||
:options="entryObservationsOptions"
|
||||
:disable="!!row.id"
|
||||
option-label="description"
|
||||
option-value="id"
|
||||
hide-selected
|
||||
/>
|
||||
|
||||
<VnInput
|
||||
:label="t('globals.description')"
|
||||
v-model="row.description"
|
||||
:rules="validate('EntryObservation.description')"
|
||||
/>
|
||||
|
||||
<div class="row justify-center items-center">
|
||||
<QIcon
|
||||
name="delete"
|
||||
size="sm"
|
||||
|
@ -82,19 +80,17 @@ onMounted(() => {
|
|||
</QIcon>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow>
|
||||
<QIcon
|
||||
name="add"
|
||||
size="sm"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
@click="entryObservationsRef.insert()"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Add note') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</VnRow>
|
||||
<QIcon
|
||||
name="add"
|
||||
size="sm"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
@click="entryObservationsRef.insert()"
|
||||
>
|
||||
<QTooltip>
|
||||
{{ t('Add note') }}
|
||||
</QTooltip>
|
||||
</QIcon>
|
||||
</QCard>
|
||||
</template>
|
||||
</CrudModel>
|
||||
|
|
|
@ -39,30 +39,47 @@ onMounted(async () => {
|
|||
const tableColumnComponents = {
|
||||
quantity: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
},
|
||||
stickers: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
packagingFk: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
weight: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
packing: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
grouping: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
buyingValue: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
amount: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
pvp: {
|
||||
component: () => 'span',
|
||||
props: () => {},
|
||||
event: () => {},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -162,125 +179,82 @@ const fetchEntryBuys = async () => {
|
|||
{{ t('globals.summary.basicData') }}
|
||||
<QIcon name="open_in_new" />
|
||||
</a>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.commission')"
|
||||
:value="entry.commission"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.currency')"
|
||||
:value="entry.currency.name"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.company')"
|
||||
:value="entry.company.code"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.reference')"
|
||||
:value="entry.reference"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.invoiceNumber')"
|
||||
:value="entry.invoiceNumber"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.ordered')"
|
||||
:value="entry.isOrdered"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.confirmed')"
|
||||
:value="entry.isConfirmed"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.booked')"
|
||||
:value="entry.isBooked"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv :label="t('entry.summary.raid')" :value="entry.isRaid" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.excludedFromAvailable')"
|
||||
:value="entry.isExcludedFromAvailable"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnLv :label="t('entry.summary.commission')" :value="entry.commission" />
|
||||
|
||||
<VnLv :label="t('entry.summary.currency')" :value="entry.currency.name" />
|
||||
|
||||
<VnLv :label="t('entry.summary.company')" :value="entry.company.code" />
|
||||
|
||||
<VnLv :label="t('entry.summary.reference')" :value="entry.reference" />
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.invoiceNumber')"
|
||||
:value="entry.invoiceNumber"
|
||||
/>
|
||||
|
||||
<VnLv :label="t('entry.summary.ordered')" :value="entry.isOrdered" />
|
||||
|
||||
<VnLv :label="t('entry.summary.confirmed')" :value="entry.isConfirmed" />
|
||||
|
||||
<VnLv :label="t('entry.summary.booked')" :value="entry.isBooked" />
|
||||
|
||||
<VnLv :label="t('entry.summary.raid')" :value="entry.isRaid" />
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.excludedFromAvailable')"
|
||||
:value="entry.isExcludedFromAvailable"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard class="vn-one">
|
||||
<a class="header header-link" :href="entryUrl">
|
||||
{{ t('Travel data') }}
|
||||
<QIcon name="open_in_new" />
|
||||
</a>
|
||||
<VnRow>
|
||||
<div class="col">
|
||||
<VnLv :label="t('entry.summary.travelReference')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entry.travel.ref }}
|
||||
<TravelDescriptorProxy :id="entry.travel.id" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelAgency')"
|
||||
:value="entry.travel.agency.name"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelShipped')"
|
||||
:value="toDate(entry.travel.shipped)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelWarehouseOut')"
|
||||
:value="entry.travel.warehouseOut.name"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelDelivered')"
|
||||
:value="entry.travel.isDelivered"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelLanded')"
|
||||
:value="toDate(entry.travel.landed)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelWarehouseIn')"
|
||||
:value="entry.travel.warehouseIn.name"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelReceived')"
|
||||
:value="entry.travel.isReceived"
|
||||
/>
|
||||
</div>
|
||||
</VnRow>
|
||||
|
||||
<VnLv :label="t('entry.summary.travelReference')">
|
||||
<template #value>
|
||||
<span class="link">
|
||||
{{ entry.travel.ref }}
|
||||
<TravelDescriptorProxy :id="entry.travel.id" />
|
||||
</span>
|
||||
</template>
|
||||
</VnLv>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelAgency')"
|
||||
:value="entry.travel.agency.name"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelShipped')"
|
||||
:value="toDate(entry.travel.shipped)"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelWarehouseOut')"
|
||||
:value="entry.travel.warehouseOut.name"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelDelivered')"
|
||||
:value="entry.travel.isDelivered"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelLanded')"
|
||||
:value="toDate(entry.travel.landed)"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelWarehouseIn')"
|
||||
:value="entry.travel.warehouseIn.name"
|
||||
/>
|
||||
|
||||
<VnLv
|
||||
:label="t('entry.summary.travelReceived')"
|
||||
:value="entry.travel.isReceived"
|
||||
/>
|
||||
</QCard>
|
||||
<QCard class="vn-two" style="min-width: 100%">
|
||||
<a class="header header-link">
|
||||
|
@ -298,7 +272,10 @@ const fetchEntryBuys = async () => {
|
|||
<QTr no-hover>
|
||||
<QTd v-for="col in cols" :key="col.name">
|
||||
<component
|
||||
:is="tableColumnComponents[col.name].component()"
|
||||
:is="tableColumnComponents[col.name].component(props)"
|
||||
v-bind="tableColumnComponents[col.name].props(props)"
|
||||
@click="tableColumnComponents[col.name].event(props)"
|
||||
class="col-content"
|
||||
>
|
||||
<template
|
||||
v-if="
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useArrayData } from 'src/composables/useArrayData';
|
|||
import CrudModel from 'src/components/CrudModel.vue';
|
||||
import FetchData from 'src/components/FetchData.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -158,7 +159,12 @@ async function insert() {
|
|||
</template>
|
||||
<template #body-cell-amount="{ row }">
|
||||
<QTd>
|
||||
<QInput v-model="row.amount" clearable clear-icon="close" />
|
||||
<VnCurrency
|
||||
v-model="row.amount"
|
||||
:is-outlined="false"
|
||||
clearable
|
||||
clear-icon="close"
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-foreignvalue="{ row }">
|
||||
|
|
|
@ -9,6 +9,7 @@ import { toCurrency } from 'src/filters';
|
|||
import FetchData from 'src/components/FetchData.vue';
|
||||
import VnSelectFilter from 'src/components/common/VnSelectFilter.vue';
|
||||
import CrudModel from 'src/components/CrudModel.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
|
@ -225,7 +226,7 @@ async function addExpense() {
|
|||
</template>
|
||||
<template #body-cell-taxablebase="{ row }">
|
||||
<QTd>
|
||||
<QInput
|
||||
<VnCurrency
|
||||
:class="{
|
||||
'no-pointer-events': isNotEuro(invoiceIn.currency.code),
|
||||
}"
|
||||
|
@ -234,11 +235,7 @@ async function addExpense() {
|
|||
clear-icon="close"
|
||||
v-model="row.taxableBase"
|
||||
clearable
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="euro" size="xs" flat />
|
||||
</template>
|
||||
</QInput>
|
||||
/>
|
||||
</QTd>
|
||||
</template>
|
||||
<template #body-cell-sageiva="{ row, col }">
|
||||
|
@ -328,7 +325,7 @@ async function addExpense() {
|
|||
</VnSelectFilter>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QInput
|
||||
<VnCurrency
|
||||
:label="t('Taxable base')"
|
||||
:class="{
|
||||
'no-pointer-events': isNotEuro(
|
||||
|
@ -340,11 +337,7 @@ async function addExpense() {
|
|||
clear-icon="close"
|
||||
v-model="props.row.taxableBase"
|
||||
clearable
|
||||
>
|
||||
<template #append>
|
||||
<QIcon name="euro" size="xs" flat />
|
||||
</template>
|
||||
</QInput>
|
||||
/>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<VnSelectFilter
|
||||
|
|
|
@ -8,6 +8,7 @@ import FetchData from 'components/FetchData.vue';
|
|||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import { useCapitalize } from 'src/composables/useCapitalize';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -137,16 +138,7 @@ const suppliersRef = ref();
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
:label="t('Amount')"
|
||||
v-model="params.amount"
|
||||
is-outlined
|
||||
lazy-rules
|
||||
>
|
||||
<template #prepend>
|
||||
<QIcon name="euro" size="sm"></QIcon>
|
||||
</template>
|
||||
</VnInput>
|
||||
<VnCurrency v-model="params.amount" is-outlined />
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem class="q-mb-md">
|
||||
|
|
|
@ -6,6 +6,7 @@ import FetchData from 'components/FetchData.vue';
|
|||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -57,7 +58,11 @@ function setWorkers(data) {
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput :label="t('Amount')" v-model="params.amount" is-outlined />
|
||||
<VnCurrency
|
||||
:label="t('Amount')"
|
||||
v-model="params.amount"
|
||||
is-outlined
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n';
|
|||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||
import VnCurrency from 'src/components/common/VnCurrency.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const props = defineProps({
|
||||
|
@ -84,7 +85,7 @@ const props = defineProps({
|
|||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnInput
|
||||
<VnCurrency
|
||||
v-model="params.amount"
|
||||
:label="t('invoiceOut.negativeBases.amount')"
|
||||
is-outlined
|
||||
|
|
|
@ -10,6 +10,7 @@ import VnInput from 'src/components/common/VnInput.vue';
|
|||
import VnSelectDialog from 'src/components/common/VnSelectDialog.vue';
|
||||
import VnRow from 'components/ui/VnRow.vue';
|
||||
import CustomerCreateNewPostcode from 'src/components/CreateNewPostcodeForm.vue';
|
||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
|
@ -55,27 +56,16 @@ onMounted(() => {
|
|||
updateAddressForm(addressData);
|
||||
}
|
||||
});
|
||||
function handleLocation(data, location) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||
data.postalCode = code;
|
||||
data.city = town;
|
||||
data.provinceFk = provinceFk;
|
||||
data.countryFk = countryFk;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FetchData
|
||||
ref="postcodeFetchDataRef"
|
||||
url="Postcodes/location"
|
||||
@on-fetch="(data) => (postcodesOptions = data)"
|
||||
auto-load
|
||||
/>
|
||||
<FetchData
|
||||
ref="provincesFetchDataRef"
|
||||
@on-fetch="(data) => (provincesOptions = data)"
|
||||
auto-load
|
||||
url="Provinces"
|
||||
/>
|
||||
<FetchData
|
||||
ref="townsFetchDataRef"
|
||||
@on-fetch="(data) => (townsLocationOptions = data)"
|
||||
auto-load
|
||||
url="Towns/location"
|
||||
/>
|
||||
<QPage>
|
||||
<FormModel
|
||||
model="supplierAddresses"
|
||||
|
@ -104,59 +94,15 @@ onMounted(() => {
|
|||
</VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
<div class="col">
|
||||
<VnSelectDialog
|
||||
v-model="data.postalCode"
|
||||
:label="t('supplier.addresses.postcode')"
|
||||
:rules="validate('supplierAddress.postcode')"
|
||||
<VnLocation
|
||||
:rules="validate('Worker.postcode')"
|
||||
:roles-allowed-to-create="['deliveryAssistant']"
|
||||
:options="postcodesOptions"
|
||||
option-label="code"
|
||||
option-value="code"
|
||||
hide-selected
|
||||
>
|
||||
<template #form>
|
||||
<CustomerCreateNewPostcode
|
||||
@on-data-saved="onPostcodeCreated($event)"
|
||||
/>
|
||||
</template>
|
||||
<template #option="scope">
|
||||
<QItem v-bind="scope.itemProps">
|
||||
<QItemSection v-if="scope.opt">
|
||||
<QItemLabel>{{ scope.opt.code }}</QItemLabel>
|
||||
<QItemLabel caption
|
||||
>{{ scope.opt.code }} -
|
||||
{{ scope.opt.town.name }} ({{
|
||||
scope.opt.town.province.name
|
||||
}},
|
||||
{{
|
||||
scope.opt.town.province.country.country
|
||||
}})</QItemLabel
|
||||
>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
</template>
|
||||
</VnSelectDialog>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('supplier.addresses.city')"
|
||||
:options="townsLocationOptions"
|
||||
v-model="data.city"
|
||||
hide-selected
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<VnSelectFilter
|
||||
:label="t('supplier.addresses.province')"
|
||||
:options="provincesOptions"
|
||||
hide-selected
|
||||
map-options
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
v-model="data.provinceFk"
|
||||
/>
|
||||
v-model="data.location"
|
||||
@update:model-value="
|
||||
(location) => handleLocation(data, location)
|
||||
"
|
||||
></VnLocation>
|
||||
</div>
|
||||
</VnRow>
|
||||
<VnRow class="row q-gutter-md q-mb-md">
|
||||
|
|
|
@ -21,7 +21,7 @@ const postcodesOptions = ref([]);
|
|||
|
||||
function handleLocation(data, location) {
|
||||
const { town, code, provinceFk, countryFk } = location ?? {};
|
||||
data.postcode = code;
|
||||
data.postCode = code;
|
||||
data.city = town;
|
||||
data.provinceFk = provinceFk;
|
||||
data.countryFk = countryFk;
|
||||
|
|
|
@ -78,7 +78,7 @@ const filter = {
|
|||
<VnLv :label="t('worker.card.name')" :value="worker.user.nickname" />
|
||||
<VnLv
|
||||
:label="t('worker.list.department')"
|
||||
:value="worker.department.department.name"
|
||||
:value="worker.department?.department?.name"
|
||||
/>
|
||||
<VnLv :label="t('worker.list.email')" :value="worker.user.email" copy />
|
||||
<VnLv :label="t('worker.summary.boss')" link>
|
||||
|
@ -102,10 +102,10 @@ const filter = {
|
|||
<VnLinkPhone :phone-number="worker.phone" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :value="worker.client.phone">
|
||||
<VnLv :value="worker.client?.phone">
|
||||
<template #label>
|
||||
{{ t('worker.summary.personalPhone') }}
|
||||
<VnLinkPhone :phone-number="worker.client.phone" />
|
||||
<VnLinkPhone :phone-number="worker.client?.phone" />
|
||||
</template>
|
||||
</VnLv>
|
||||
<VnLv :label="t('worker.summary.locker')" :value="worker.locker" />
|
||||
|
|
|
@ -5,11 +5,12 @@ describe('InvoiceInList', () => {
|
|||
':nth-child(1) > :nth-child(1) > .justify-between > .flex > .q-chip > .q-chip__content';
|
||||
const firstDetailBtn = '.q-card:nth-child(1) .q-btn:nth-child(2)';
|
||||
const summaryHeaders = '.summaryBody .header';
|
||||
const screen = '.q-page-container > .q-drawer-container > .fullscreen';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1920, 1080);
|
||||
cy.login('developer');
|
||||
cy.visit(`/#/invoice-in/list`);
|
||||
cy.get(screen).click();
|
||||
});
|
||||
|
||||
it('should redirect on clicking a invoice', () => {
|
||||
|
|
Loading…
Reference in New Issue