Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix-front into 6695-docker_push_3
This commit is contained in:
commit
28613c1e96
3095
CHANGELOG.md
3095
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "25.08.0",
|
"version": "25.10.0",
|
||||||
"description": "Salix frontend",
|
"description": "Salix frontend",
|
||||||
"productName": "Salix",
|
"productName": "Salix",
|
||||||
"author": "Verdnatura",
|
"author": "Verdnatura",
|
||||||
|
|
|
@ -106,7 +106,7 @@ const isLoading = ref(false);
|
||||||
const isResetting = ref(false);
|
const isResetting = ref(false);
|
||||||
const hasChanges = ref(!$props.observeFormChanges);
|
const hasChanges = ref(!$props.observeFormChanges);
|
||||||
const originalData = computed(() => state.get(modelValue));
|
const originalData = computed(() => state.get(modelValue));
|
||||||
const formData = ref({});
|
const formData = ref();
|
||||||
const defaultButtons = computed(() => ({
|
const defaultButtons = computed(() => ({
|
||||||
save: {
|
save: {
|
||||||
dataCy: 'saveDefaultBtn',
|
dataCy: 'saveDefaultBtn',
|
||||||
|
@ -134,7 +134,8 @@ onMounted(async () => {
|
||||||
|
|
||||||
if (!$props.formInitialData) {
|
if (!$props.formInitialData) {
|
||||||
if ($props.autoLoad && $props.url) await fetch();
|
if ($props.autoLoad && $props.url) await fetch();
|
||||||
else if (arrayData.store.data) updateAndEmit('onFetch', arrayData.store.data);
|
else if (arrayData.store.data)
|
||||||
|
updateAndEmit('onFetch', { val: arrayData.store.data });
|
||||||
}
|
}
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
watch(
|
watch(
|
||||||
|
@ -154,7 +155,7 @@ onMounted(async () => {
|
||||||
if (!$props.url)
|
if (!$props.url)
|
||||||
watch(
|
watch(
|
||||||
() => arrayData.store.data,
|
() => arrayData.store.data,
|
||||||
(val) => updateAndEmit('onFetch', val),
|
(val) => updateAndEmit('onFetch', { val }),
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -200,7 +201,7 @@ async function fetch() {
|
||||||
});
|
});
|
||||||
if (Array.isArray(data)) data = data[0] ?? {};
|
if (Array.isArray(data)) data = data[0] ?? {};
|
||||||
|
|
||||||
updateAndEmit('onFetch', data);
|
updateAndEmit('onFetch', { val: data });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state.set(modelValue, {});
|
state.set(modelValue, {});
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -228,7 +229,11 @@ async function save(prevent = false) {
|
||||||
|
|
||||||
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
||||||
|
|
||||||
updateAndEmit('onDataSaved', formData.value, response?.data);
|
updateAndEmit('onDataSaved', {
|
||||||
|
val: formData.value,
|
||||||
|
res: response?.data,
|
||||||
|
old: originalData.value,
|
||||||
|
});
|
||||||
if ($props.reload) await arrayData.fetch({});
|
if ($props.reload) await arrayData.fetch({});
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -242,8 +247,7 @@ async function saveAndGo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
formData.value = JSON.parse(JSON.stringify(originalData.value));
|
updateAndEmit('onFetch', { val: originalData.value });
|
||||||
updateAndEmit('onFetch', originalData.value);
|
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
isResetting.value = true;
|
isResetting.value = true;
|
||||||
|
@ -265,11 +269,11 @@ function filter(value, update, filterOptions) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAndEmit(evt, val, res) {
|
function updateAndEmit(evt, { val, res, old } = { val: null, res: null, old: null }) {
|
||||||
state.set(modelValue, val);
|
state.set(modelValue, val);
|
||||||
if (!$props.url) arrayData.store.data = val;
|
if (!$props.url) arrayData.store.data = val;
|
||||||
|
|
||||||
emit(evt, state.get(modelValue), res);
|
emit(evt, state.get(modelValue), res, old);
|
||||||
}
|
}
|
||||||
|
|
||||||
function trimData(data) {
|
function trimData(data) {
|
||||||
|
|
|
@ -1,8 +1,22 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { toCurrency } from 'src/filters';
|
||||||
|
|
||||||
defineProps({ row: { type: Object, required: true } });
|
defineProps({ row: { type: Object, required: true } });
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<span class="q-gutter-x-xs">
|
<span class="q-gutter-x-xs">
|
||||||
|
<router-link
|
||||||
|
v-if="row.claim?.claimFk"
|
||||||
|
:to="{ name: 'ClaimBasicData', params: { id: row.claim?.claimFk } }"
|
||||||
|
class="link"
|
||||||
|
>
|
||||||
|
<QIcon name="vn:claims" size="xs">
|
||||||
|
<QTooltip>
|
||||||
|
{{ t('ticketSale.claim') }}:
|
||||||
|
{{ row.claim?.claimFk }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</router-link>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="row?.risk"
|
v-if="row?.risk"
|
||||||
name="vn:risk"
|
name="vn:risk"
|
||||||
|
@ -10,7 +24,8 @@ defineProps({ row: { type: Object, required: true } });
|
||||||
size="xs"
|
size="xs"
|
||||||
>
|
>
|
||||||
<QTooltip>
|
<QTooltip>
|
||||||
{{ $t('salesTicketsTable.risk') }}: {{ row.risk - row.credit }}
|
{{ $t('salesTicketsTable.risk') }}:
|
||||||
|
{{ toCurrency(row.risk - row.credit) }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
|
@ -53,7 +68,7 @@ defineProps({ row: { type: Object, required: true } });
|
||||||
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="!row?.isTaxDataChecked === 0"
|
v-if="row?.isTaxDataChecked !== 0"
|
||||||
name="vn:no036"
|
name="vn:no036"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
|
@ -757,7 +757,7 @@ function cardClick(_, row) {
|
||||||
flat
|
flat
|
||||||
dense
|
dense
|
||||||
:class="
|
:class="
|
||||||
btn.isPrimary ? 'text-primary-light' : 'color-vn-text '
|
btn.isPrimary ? 'text-primary-light' : 'color-vn-label'
|
||||||
"
|
"
|
||||||
:style="`visibility: ${
|
:style="`visibility: ${
|
||||||
((btn.show && btn.show(row)) ?? true)
|
((btn.show && btn.show(row)) ?? true)
|
||||||
|
@ -783,7 +783,7 @@ function cardClick(_, row) {
|
||||||
<QCardSection
|
<QCardSection
|
||||||
vertical
|
vertical
|
||||||
class="no-margin no-padding"
|
class="no-margin no-padding"
|
||||||
:class="colsMap.tableActions ? 'w-80' : 'fit'"
|
:class="colsMap.tableActions ? '' : 'fit'"
|
||||||
>
|
>
|
||||||
<!-- Chips -->
|
<!-- Chips -->
|
||||||
<QCardSection
|
<QCardSection
|
||||||
|
@ -814,7 +814,7 @@ function cardClick(_, row) {
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<!-- Fields -->
|
<!-- Fields -->
|
||||||
<QCardSection
|
<QCardSection
|
||||||
class="q-pl-sm q-pr-lg q-py-xs"
|
class="q-pl-sm q-py-xs"
|
||||||
:class="$props.cardClass"
|
:class="$props.cardClass"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
@ -861,13 +861,14 @@ function cardClick(_, row) {
|
||||||
:key="index"
|
:key="index"
|
||||||
:title="btn.title"
|
:title="btn.title"
|
||||||
:icon="btn.icon"
|
:icon="btn.icon"
|
||||||
|
data-cy="cardBtn"
|
||||||
class="q-pa-xs"
|
class="q-pa-xs"
|
||||||
flat
|
|
||||||
:class="
|
:class="
|
||||||
btn.isPrimary
|
btn.isPrimary
|
||||||
? 'text-primary-light'
|
? 'text-primary-light'
|
||||||
: 'color-vn-text '
|
: 'color-vn-label'
|
||||||
"
|
"
|
||||||
|
flat
|
||||||
@click="btn.action(row)"
|
@click="btn.action(row)"
|
||||||
/>
|
/>
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
|
@ -1120,6 +1121,7 @@ es:
|
||||||
.vn-label-value {
|
.vn-label-value {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
color: var(--vn-text-color);
|
color: var(--vn-text-color);
|
||||||
.value {
|
.value {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
@ -57,6 +57,7 @@ describe('FormModel', () => {
|
||||||
vm.state.set(model, formInitialData);
|
vm.state.set(model, formInitialData);
|
||||||
expect(vm.hasChanges).toBe(false);
|
expect(vm.hasChanges).toBe(false);
|
||||||
|
|
||||||
|
await vm.$nextTick();
|
||||||
vm.formData.mockKey = 'newVal';
|
vm.formData.mockKey = 'newVal';
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
expect(vm.hasChanges).toBe(true);
|
expect(vm.hasChanges).toBe(true);
|
||||||
|
@ -94,8 +95,12 @@ describe('FormModel', () => {
|
||||||
it('should call axios.patch with the right data', async () => {
|
it('should call axios.patch with the right data', async () => {
|
||||||
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
const spy = vi.spyOn(axios, 'patch').mockResolvedValue({ data: {} });
|
||||||
const { vm } = mount({ propsData: { url, model } });
|
const { vm } = mount({ propsData: { url, model } });
|
||||||
vm.formData.mockKey = 'newVal';
|
|
||||||
|
vm.formData = {};
|
||||||
await vm.$nextTick();
|
await vm.$nextTick();
|
||||||
|
vm.formData = { mockKey: 'newVal' };
|
||||||
|
await vm.$nextTick();
|
||||||
|
|
||||||
await vm.save();
|
await vm.save();
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
vm.formData.mockKey = 'mockVal';
|
vm.formData.mockKey = 'mockVal';
|
||||||
|
|
|
@ -39,6 +39,13 @@ onBeforeMount(async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeRouteUpdate(async (to, from) => {
|
onBeforeRouteUpdate(async (to, from) => {
|
||||||
|
if (hasRouteParam(to.params)) {
|
||||||
|
const { matched } = router.currentRoute.value;
|
||||||
|
const { name } = matched.at(-3);
|
||||||
|
if (name) {
|
||||||
|
router.push({ name, params: to.params });
|
||||||
|
}
|
||||||
|
}
|
||||||
const id = to.params.id;
|
const id = to.params.id;
|
||||||
if (id !== from.params.id) await fetch(id, true);
|
if (id !== from.params.id) await fetch(id, true);
|
||||||
});
|
});
|
||||||
|
@ -50,6 +57,9 @@ async function fetch(id, append = false) {
|
||||||
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
else arrayData.store.url = props.url.replace(regex, `/${id}`);
|
||||||
await arrayData.fetch({ append, updateRouter: false });
|
await arrayData.fetch({ append, updateRouter: false });
|
||||||
}
|
}
|
||||||
|
function hasRouteParam(params, valueToCheck = ':addressId') {
|
||||||
|
return Object.values(params).includes(valueToCheck);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
<Teleport to="#left-panel" v-if="stateStore.isHeaderMounted()">
|
||||||
|
|
|
@ -85,6 +85,7 @@ const handleModelValue = (data) => {
|
||||||
:tooltip="t('Create new location')"
|
:tooltip="t('Create new location')"
|
||||||
:rules="mixinRules"
|
:rules="mixinRules"
|
||||||
:lazy-rules="true"
|
:lazy-rules="true"
|
||||||
|
required
|
||||||
>
|
>
|
||||||
<template #form>
|
<template #form>
|
||||||
<CreateNewPostcode
|
<CreateNewPostcode
|
||||||
|
|
|
@ -53,3 +53,8 @@ const manaCode = ref(props.manaCode);
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<i18n>
|
||||||
|
es:
|
||||||
|
Promotion mana: Maná promoción
|
||||||
|
Claim mana: Maná reclamación
|
||||||
|
</i18n>
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
import { describe, it, expect, vi } from 'vitest';
|
||||||
|
import { useRequired } from '../useRequired';
|
||||||
|
|
||||||
|
vi.mock('../useValidator', () => ({
|
||||||
|
useValidator: () => ({
|
||||||
|
validations: () => ({
|
||||||
|
required: vi.fn((isRequired, val) => {
|
||||||
|
if (!isRequired) return true;
|
||||||
|
return val !== null && val !== undefined && val !== '';
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('useRequired', () => {
|
||||||
|
it('should detect required when attr is boolean true', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect required when attr is boolean false', () => {
|
||||||
|
const attrs = { required: false };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect required when attr exists without value', () => {
|
||||||
|
const attrs = { required: '' };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when required attr does not exist', () => {
|
||||||
|
const attrs = { someOtherAttr: 'value' };
|
||||||
|
const { isRequired } = useRequired(attrs);
|
||||||
|
expect(isRequired).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('requiredFieldRule', () => {
|
||||||
|
it('should validate required field with value', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('some value')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should validate required field with empty value', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('')).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass validation when field is not required', () => {
|
||||||
|
const attrs = { required: false };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule('')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle null and undefined values', () => {
|
||||||
|
const attrs = { required: true };
|
||||||
|
const { requiredFieldRule } = useRequired(attrs);
|
||||||
|
expect(requiredFieldRule(null)).toBe(false);
|
||||||
|
expect(requiredFieldRule(undefined)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -11,7 +11,7 @@ export async function useCau(res, message) {
|
||||||
const { config, headers, request, status, statusText, data } = res || {};
|
const { config, headers, request, status, statusText, data } = res || {};
|
||||||
const { params, url, method, signal, headers: confHeaders } = config || {};
|
const { params, url, method, signal, headers: confHeaders } = config || {};
|
||||||
const { message: resMessage, code, name } = data?.error || {};
|
const { message: resMessage, code, name } = data?.error || {};
|
||||||
delete confHeaders.Authorization;
|
delete confHeaders?.Authorization;
|
||||||
|
|
||||||
const additionalData = {
|
const additionalData = {
|
||||||
path: location.hash,
|
path: location.hash,
|
||||||
|
|
|
@ -2,14 +2,10 @@ import { useValidator } from 'src/composables/useValidator';
|
||||||
|
|
||||||
export function useRequired($attrs) {
|
export function useRequired($attrs) {
|
||||||
const { validations } = useValidator();
|
const { validations } = useValidator();
|
||||||
const hasRequired = Object.keys($attrs).includes('required');
|
const isRequired =
|
||||||
let isRequired = false;
|
typeof $attrs['required'] === 'boolean'
|
||||||
if (hasRequired) {
|
? $attrs['required']
|
||||||
const required = $attrs['required'];
|
: Object.keys($attrs).includes('required');
|
||||||
if (typeof required === 'boolean') {
|
|
||||||
isRequired = required;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const requiredFieldRule = (val) => validations().required(isRequired, val);
|
const requiredFieldRule = (val) => validations().required(isRequired, val);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -830,6 +830,8 @@ travel:
|
||||||
CloneTravelAndEntries: Clone travel and his entries
|
CloneTravelAndEntries: Clone travel and his entries
|
||||||
deleteTravel: Delete travel
|
deleteTravel: Delete travel
|
||||||
AddEntry: Add entry
|
AddEntry: Add entry
|
||||||
|
availabled: Availabled
|
||||||
|
availabledHour: Availabled hour
|
||||||
thermographs: Thermographs
|
thermographs: Thermographs
|
||||||
hb: HB
|
hb: HB
|
||||||
basicData:
|
basicData:
|
||||||
|
|
|
@ -839,6 +839,7 @@ supplier:
|
||||||
verified: Verificado
|
verified: Verificado
|
||||||
isActive: Está activo
|
isActive: Está activo
|
||||||
billingData: Forma de pago
|
billingData: Forma de pago
|
||||||
|
financialData: Datos financieros
|
||||||
payDeadline: Plazo de pago
|
payDeadline: Plazo de pago
|
||||||
payDay: Día de pago
|
payDay: Día de pago
|
||||||
account: Cuenta
|
account: Cuenta
|
||||||
|
@ -916,6 +917,8 @@ travel:
|
||||||
deleteTravel: Eliminar envío
|
deleteTravel: Eliminar envío
|
||||||
AddEntry: Añadir entrada
|
AddEntry: Añadir entrada
|
||||||
thermographs: Termógrafos
|
thermographs: Termógrafos
|
||||||
|
availabled: F. Disponible
|
||||||
|
availabledHour: Hora Disponible
|
||||||
hb: HB
|
hb: HB
|
||||||
basicData:
|
basicData:
|
||||||
daysInForward: Desplazamiento automatico (redada)
|
daysInForward: Desplazamiento automatico (redada)
|
||||||
|
|
|
@ -232,7 +232,6 @@ const updateDateParams = (value, params) => {
|
||||||
:include="'category'"
|
:include="'category'"
|
||||||
:sortBy="'name ASC'"
|
:sortBy="'name ASC'"
|
||||||
dense
|
dense
|
||||||
@update:model-value="(data) => updateDateParams(data, params)"
|
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -254,7 +253,6 @@ const updateDateParams = (value, params) => {
|
||||||
:fields="['id', 'name']"
|
:fields="['id', 'name']"
|
||||||
:sortBy="'name ASC'"
|
:sortBy="'name ASC'"
|
||||||
dense
|
dense
|
||||||
@update:model-value="(data) => updateDateParams(data, params)"
|
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="params.campaign"
|
v-model="params.campaign"
|
||||||
|
@ -303,12 +301,14 @@ en:
|
||||||
valentinesDay: Valentine's Day
|
valentinesDay: Valentine's Day
|
||||||
mothersDay: Mother's Day
|
mothersDay: Mother's Day
|
||||||
allSaints: All Saints' Day
|
allSaints: All Saints' Day
|
||||||
|
frenchMothersDay: Mother's Day in France
|
||||||
es:
|
es:
|
||||||
Enter a new search: Introduce una nueva búsqueda
|
Enter a new search: Introduce una nueva búsqueda
|
||||||
Group by items: Agrupar por artículos
|
Group by items: Agrupar por artículos
|
||||||
valentinesDay: Día de San Valentín
|
valentinesDay: Día de San Valentín
|
||||||
mothersDay: Día de la Madre
|
mothersDay: Día de la Madre
|
||||||
allSaints: Día de Todos los Santos
|
allSaints: Día de Todos los Santos
|
||||||
|
frenchMothersDay: (Francia) Día de la Madre
|
||||||
Campaign consumption: Consumo campaña
|
Campaign consumption: Consumo campaña
|
||||||
Campaign: Campaña
|
Campaign: Campaña
|
||||||
From: Desde
|
From: Desde
|
||||||
|
|
|
@ -2,7 +2,10 @@
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import { useQuasar } from 'quasar';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'components/FormModel.vue';
|
import FormModel from 'components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
@ -11,9 +14,12 @@ import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnLocation from 'src/components/common/VnLocation.vue';
|
import VnLocation from 'src/components/common/VnLocation.vue';
|
||||||
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
import VnCheckbox from 'src/components/common/VnCheckbox.vue';
|
||||||
import { getDifferences, getUpdatedValues } from 'src/filters';
|
import { getDifferences, getUpdatedValues } from 'src/filters';
|
||||||
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
|
|
||||||
|
const quasar = useQuasar();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const { notify } = useNotify();
|
||||||
|
|
||||||
const typesTaxes = ref([]);
|
const typesTaxes = ref([]);
|
||||||
const typesTransactions = ref([]);
|
const typesTransactions = ref([]);
|
||||||
|
@ -31,6 +37,31 @@ function onBeforeSave(formData, originalData) {
|
||||||
formData,
|
formData,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function checkEtChanges(data, _, originalData) {
|
||||||
|
const equalizatedHasChanged = originalData.isEqualizated != data.isEqualizated;
|
||||||
|
const hasToInvoiceByAddress =
|
||||||
|
originalData.hasToInvoiceByAddress || data.hasToInvoiceByAddress;
|
||||||
|
if (equalizatedHasChanged && hasToInvoiceByAddress) {
|
||||||
|
quasar.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t('You changed the equalization tax'),
|
||||||
|
message: t('Do you want to spread the change?'),
|
||||||
|
promise: () => acceptPropagate(data),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else if (equalizatedHasChanged) {
|
||||||
|
await acceptPropagate(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function acceptPropagate({ isEqualizated }) {
|
||||||
|
await axios.patch(`Clients/${route.params.id}/addressesPropagateRe`, {
|
||||||
|
isEqualizated,
|
||||||
|
});
|
||||||
|
notify(t('Equivalent tax spreaded'), 'warning');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -45,6 +76,8 @@ function onBeforeSave(formData, originalData) {
|
||||||
auto-load
|
auto-load
|
||||||
model="Customer"
|
model="Customer"
|
||||||
:mapper="onBeforeSave"
|
:mapper="onBeforeSave"
|
||||||
|
observe-form-changes
|
||||||
|
@on-data-saved="checkEtChanges"
|
||||||
>
|
>
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -180,6 +213,9 @@ es:
|
||||||
whenActivatingIt: Al activarlo, no informar el código del país en el campo nif
|
whenActivatingIt: Al activarlo, no informar el código del país en el campo nif
|
||||||
inOrderToInvoice: Para facturar no se consulta este campo, sino el RE de consignatario. Al modificar este campo si no esta marcada la casilla Facturar por consignatario, se propagará automaticamente el cambio a todos lo consignatarios, en caso contrario preguntará al usuario si quiere o no propagar
|
inOrderToInvoice: Para facturar no se consulta este campo, sino el RE de consignatario. Al modificar este campo si no esta marcada la casilla Facturar por consignatario, se propagará automaticamente el cambio a todos lo consignatarios, en caso contrario preguntará al usuario si quiere o no propagar
|
||||||
Daily invoice: Facturación diaria
|
Daily invoice: Facturación diaria
|
||||||
|
Equivalent tax spreaded: Recargo de equivalencia propagado
|
||||||
|
You changed the equalization tax: Has cambiado el recargo de equivalencia
|
||||||
|
Do you want to spread the change?: ¿Deseas propagar el cambio a sus consignatarios?
|
||||||
en:
|
en:
|
||||||
onlyLetters: Only letters, numbers and spaces can be used
|
onlyLetters: Only letters, numbers and spaces can be used
|
||||||
whenActivatingIt: When activating it, do not enter the country code in the ID field
|
whenActivatingIt: When activating it, do not enter the country code in the ID field
|
||||||
|
|
|
@ -270,7 +270,7 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
<VnTitle
|
<VnTitle
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
|
:url="`${grafanaUrl}/d/40buzE4Vk/comportamiento-pagos-clientes?orgId=1&var-clientFk=${entityId}`"
|
||||||
:text="t('customer.summary.payMethodFk')"
|
:text="t('customer.summary.financialData')"
|
||||||
icon="vn:grafana"
|
icon="vn:grafana"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
|
|
|
@ -98,7 +98,6 @@ function onAgentCreated({ id, fiscalName }, data) {
|
||||||
:rules="validate('Worker.postcode')"
|
:rules="validate('Worker.postcode')"
|
||||||
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
:acls="[{ model: 'Town', props: '*', accessType: 'WRITE' }]"
|
||||||
v-model="data.location"
|
v-model="data.location"
|
||||||
:required="true"
|
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -96,11 +96,11 @@ const updateObservations = async (payload) => {
|
||||||
await axios.post('AddressObservations/crud', payload);
|
await axios.post('AddressObservations/crud', payload);
|
||||||
notes.value = [];
|
notes.value = [];
|
||||||
deletes.value = [];
|
deletes.value = [];
|
||||||
toCustomerAddress();
|
|
||||||
};
|
};
|
||||||
async function updateAll({ data, payload }) {
|
async function updateAll({ data, payload }) {
|
||||||
await updateObservations(payload);
|
await updateObservations(payload);
|
||||||
await updateAddress(data);
|
await updateAddress(data);
|
||||||
|
toCustomerAddress();
|
||||||
}
|
}
|
||||||
function getPayload() {
|
function getPayload() {
|
||||||
return {
|
return {
|
||||||
|
@ -137,15 +137,12 @@ async function handleDialog(data) {
|
||||||
.onOk(async () => {
|
.onOk(async () => {
|
||||||
await updateAddressTicket();
|
await updateAddressTicket();
|
||||||
await updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
})
|
})
|
||||||
.onCancel(async () => {
|
.onCancel(async () => {
|
||||||
await updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
updateAll(body);
|
await updateAll(body);
|
||||||
toCustomerAddress();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +233,7 @@ function handleLocation(data, location) {
|
||||||
postcode: data.postalCode,
|
postcode: data.postalCode,
|
||||||
city: data.city,
|
city: data.city,
|
||||||
province: data.province,
|
province: data.province,
|
||||||
country: data.province.country,
|
country: data.province?.country,
|
||||||
}"
|
}"
|
||||||
@update:model-value="(location) => handleLocation(data, location)"
|
@update:model-value="(location) => handleLocation(data, location)"
|
||||||
></VnLocation>
|
></VnLocation>
|
||||||
|
|
|
@ -125,7 +125,7 @@ const ticketsColumns = ref([
|
||||||
:value="toDate(invoiceOut.issued)"
|
:value="toDate(invoiceOut.issued)"
|
||||||
/>
|
/>
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('invoiceOut.summary.dued')"
|
:label="t('invoiceOut.summary.expirationDate')"
|
||||||
:value="toDate(invoiceOut.dued)"
|
:value="toDate(invoiceOut.dued)"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('globals.created')" :value="toDate(invoiceOut.created)" />
|
<VnLv :label="t('globals.created')" :value="toDate(invoiceOut.created)" />
|
||||||
|
|
|
@ -19,6 +19,7 @@ invoiceOut:
|
||||||
summary:
|
summary:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
dued: Due
|
dued: Due
|
||||||
|
expirationDate: Expiration date
|
||||||
booked: Booked
|
booked: Booked
|
||||||
taxBreakdown: Tax breakdown
|
taxBreakdown: Tax breakdown
|
||||||
taxableBase: Taxable base
|
taxableBase: Taxable base
|
||||||
|
|
|
@ -19,6 +19,7 @@ invoiceOut:
|
||||||
summary:
|
summary:
|
||||||
issued: Fecha
|
issued: Fecha
|
||||||
dued: Fecha límite
|
dued: Fecha límite
|
||||||
|
expirationDate: Fecha vencimiento
|
||||||
booked: Contabilizada
|
booked: Contabilizada
|
||||||
taxBreakdown: Desglose impositivo
|
taxBreakdown: Desglose impositivo
|
||||||
taxableBase: Base imp.
|
taxableBase: Base imp.
|
||||||
|
|
|
@ -6,6 +6,8 @@ import VnLv from 'components/ui/VnLv.vue';
|
||||||
import { dashIfEmpty, toDate } from 'src/filters';
|
import { dashIfEmpty, toDate } from 'src/filters';
|
||||||
import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
|
import RouteDescriptorMenu from 'pages/Route/Card/RouteDescriptorMenu.vue';
|
||||||
import filter from './RouteFilter.js';
|
import filter from './RouteFilter.js';
|
||||||
|
import useCardDescription from 'src/composables/useCardDescription';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
|
@ -16,7 +18,6 @@ const $props = defineProps({
|
||||||
});
|
});
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
|
||||||
const zone = ref();
|
const zone = ref();
|
||||||
const zoneId = ref();
|
const zoneId = ref();
|
||||||
const entityId = computed(() => {
|
const entityId = computed(() => {
|
||||||
|
@ -50,9 +51,9 @@ onMounted(async () => {
|
||||||
width="lg-width"
|
width="lg-width"
|
||||||
>
|
>
|
||||||
<template #body="{ entity }">
|
<template #body="{ entity }">
|
||||||
<VnLv :label="t('Date')" :value="toDate(entity?.dated)" />
|
<VnLv :label="$t('Date')" :value="toDate(entity?.dated)" />
|
||||||
<VnLv :label="t('Agency')" :value="entity?.agencyMode?.name" />
|
<VnLv :label="$t('Agency')" :value="entity?.agencyMode?.name" />
|
||||||
<VnLv :label="t('Zone')" :value="zone" />
|
<VnLv :label="$t('Zone')" :value="zone" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="$t('Volume')"
|
:label="$t('Volume')"
|
||||||
:value="`${dashIfEmpty(entity?.m3)} / ${dashIfEmpty(
|
:value="`${dashIfEmpty(entity?.m3)} / ${dashIfEmpty(
|
||||||
|
|
|
@ -14,7 +14,6 @@ export default {
|
||||||
'started',
|
'started',
|
||||||
'finished',
|
'finished',
|
||||||
'cost',
|
'cost',
|
||||||
'zoneFk',
|
|
||||||
'isOk',
|
'isOk',
|
||||||
],
|
],
|
||||||
include: [
|
include: [
|
||||||
|
@ -23,7 +22,6 @@ export default {
|
||||||
relation: 'vehicle',
|
relation: 'vehicle',
|
||||||
scope: { fields: ['id', 'm3'] },
|
scope: { fields: ['id', 'm3'] },
|
||||||
},
|
},
|
||||||
{ relation: 'zone', scope: { fields: ['id', 'name'] } },
|
|
||||||
{
|
{
|
||||||
relation: 'worker',
|
relation: 'worker',
|
||||||
scope: {
|
scope: {
|
||||||
|
|
|
@ -28,52 +28,6 @@ const defaultInitialData = {
|
||||||
isOk: false,
|
isOk: false,
|
||||||
};
|
};
|
||||||
const maxDistance = ref();
|
const maxDistance = ref();
|
||||||
|
|
||||||
const routeFilter = {
|
|
||||||
fields: [
|
|
||||||
'id',
|
|
||||||
'workerFk',
|
|
||||||
'agencyModeFk',
|
|
||||||
'dated',
|
|
||||||
'm3',
|
|
||||||
'warehouseFk',
|
|
||||||
'description',
|
|
||||||
'vehicleFk',
|
|
||||||
'kmStart',
|
|
||||||
'kmEnd',
|
|
||||||
'started',
|
|
||||||
'finished',
|
|
||||||
'cost',
|
|
||||||
'isOk',
|
|
||||||
],
|
|
||||||
include: [
|
|
||||||
{ relation: 'agencyMode', scope: { fields: ['id', 'name'] } },
|
|
||||||
{
|
|
||||||
relation: 'vehicle',
|
|
||||||
scope: { fields: ['id', 'm3'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'ticket',
|
|
||||||
scope: {
|
|
||||||
fields: ['id', 'name', 'zoneFk'],
|
|
||||||
include: { relation: 'zone', scope: { fields: ['id', 'name'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'worker',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: {
|
|
||||||
relation: 'user',
|
|
||||||
scope: {
|
|
||||||
fields: ['id'],
|
|
||||||
include: { relation: 'emailUser', scope: { fields: ['email'] } },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const onSave = (data, response) => {
|
const onSave = (data, response) => {
|
||||||
if (isNew) {
|
if (isNew) {
|
||||||
axios.post(`Routes/${response?.id}/updateWorkCenter`);
|
axios.post(`Routes/${response?.id}/updateWorkCenter`);
|
||||||
|
|
|
@ -47,7 +47,10 @@ const cancel = () => {
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
<div class="header">Mana: {{ toCurrency(mana) }}</div>
|
||||||
<div class="q-pa-md">
|
<div class="q-pa-md">
|
||||||
<slot />
|
<slot :popup="QPopupProxyRef" />
|
||||||
|
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
||||||
|
<VnUsesMana :mana-code="manaCode" />
|
||||||
|
</div>
|
||||||
<div v-if="newPrice" class="column items-center q-mt-lg">
|
<div v-if="newPrice" class="column items-center q-mt-lg">
|
||||||
<span class="text-primary">{{ t('New price') }}</span>
|
<span class="text-primary">{{ t('New price') }}</span>
|
||||||
<span class="text-subtitle1">
|
<span class="text-subtitle1">
|
||||||
|
@ -56,9 +59,6 @@ const cancel = () => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
|
||||||
<VnUsesMana :mana-code="manaCode" />
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<QBtn
|
<QBtn
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
|
@ -133,7 +133,7 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('globals.amount'),
|
label: t('globals.amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
format: (row) => parseInt(row.amount * row.quantity),
|
format: (row) => toCurrency(getSaleTotal(row)),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -331,8 +331,7 @@ const updateDiscount = async (sales, newDiscount = null) => {
|
||||||
};
|
};
|
||||||
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
for (let sale of sales) sale.discount = _newDiscount;
|
tableRef.value.reload();
|
||||||
edit.value = { ...DEFAULT_EDIT };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNewPrice = computed(() => {
|
const getNewPrice = computed(() => {
|
||||||
|
@ -789,21 +788,24 @@ watch(
|
||||||
:mana-code="manaCode"
|
:mana-code="manaCode"
|
||||||
@save="changeDiscount(row)"
|
@save="changeDiscount(row)"
|
||||||
>
|
>
|
||||||
<VnInput
|
<template #default="{ popup }">
|
||||||
v-model.number="edit.discount"
|
<VnInput
|
||||||
:label="t('ticketSale.discount')"
|
autofocus
|
||||||
type="number"
|
@keyup.enter="
|
||||||
/>
|
() => {
|
||||||
<div v-if="usesMana" class="column q-gutter-y-sm q-mt-sm">
|
changeDiscount(row);
|
||||||
<VnUsesMana :mana-code="manaCode" />
|
popup.hide();
|
||||||
</div>
|
}
|
||||||
|
"
|
||||||
|
v-model.number="edit.discount"
|
||||||
|
:label="t('ticketSale.discount')"
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
</TicketEditManaProxy>
|
</TicketEditManaProxy>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
<span v-else>{{ toPercentage(row.discount / 100) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-amount="{ row }">
|
|
||||||
{{ toCurrency(row.quantity * row.price) }}
|
|
||||||
</template>
|
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
|
||||||
<QPageSticky :offset="[20, 20]" style="z-index: 2">
|
<QPageSticky :offset="[20, 20]" style="z-index: 2">
|
||||||
|
|
|
@ -16,6 +16,7 @@ import useNotify from 'src/composables/useNotify.js';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
import { toDateTimeFormat } from 'src/filters/date.js';
|
import { toDateTimeFormat } from 'src/filters/date.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
|
||||||
const state = useState();
|
const state = useState();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -286,71 +287,7 @@ watch(
|
||||||
</span>
|
</span>
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<TicketProblems :row />
|
||||||
v-if="row.isTaxDataChecked === 0"
|
|
||||||
color="primary"
|
|
||||||
name="vn:no036"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.noVerified') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasTicketRequest"
|
|
||||||
color="primary"
|
|
||||||
name="vn:buyrequest"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.purchaseRequest') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.itemShortage"
|
|
||||||
color="primary"
|
|
||||||
name="vn:unavailable"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('ticketSale.noVisible') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.isFreezed"
|
|
||||||
color="primary"
|
|
||||||
name="vn:frozen"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.clientFrozen') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.risk') }}: {{ row.risk }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasComponentLack"
|
|
||||||
color="primary"
|
|
||||||
name="vn:components"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.componentLack') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasRounding"
|
|
||||||
color="primary"
|
|
||||||
name="sync_problem"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('futureTickets.rounding') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #column-id="{ row }">
|
<template #column-id="{ row }">
|
||||||
|
|
|
@ -9,6 +9,7 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import VnInputTime from 'components/common/VnInputTime.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -53,7 +54,16 @@ const warehousesOptionsIn = ref([]);
|
||||||
<VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
|
<VnInputDate v-model="data.shipped" :label="t('globals.shipped')" />
|
||||||
<VnInputDate v-model="data.landed" :label="t('globals.landed')" />
|
<VnInputDate v-model="data.landed" :label="t('globals.landed')" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
<VnRow>
|
||||||
|
<VnInputDate
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
/>
|
||||||
|
<VnInputTime
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabledHour')"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('globals.warehouseOut')"
|
:label="t('globals.warehouseOut')"
|
||||||
|
@ -101,10 +111,3 @@ const warehousesOptionsIn = ref([]);
|
||||||
</template>
|
</template>
|
||||||
</FormModel>
|
</FormModel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
raidDays: El travel se desplaza automáticamente cada día para estar desde hoy al número de días indicado. Si se deja vacio no se moverá
|
|
||||||
en:
|
|
||||||
raidDays: The travel adjusts itself daily to match the number of days set, starting from today. If left blank, it won’t move
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ export default {
|
||||||
'agencyModeFk',
|
'agencyModeFk',
|
||||||
'isRaid',
|
'isRaid',
|
||||||
'daysInForward',
|
'daysInForward',
|
||||||
|
'availabled',
|
||||||
],
|
],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,6 +10,8 @@ import EntryDescriptorProxy from 'src/pages/Entry/Card/EntryDescriptorProxy.vue'
|
||||||
import FetchData from 'src/components/FetchData.vue';
|
import FetchData from 'src/components/FetchData.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
import { toDate, toCurrency, toCelsius } from 'src/filters';
|
import { toDate, toCurrency, toCelsius } from 'src/filters';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date.js';
|
||||||
|
import { dashIfEmpty } from 'src/filters';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
import TravelDescriptorMenuItems from './TravelDescriptorMenuItems.vue';
|
||||||
|
|
||||||
|
@ -333,6 +335,12 @@ const getLink = (param) => `#/travel/${entityId.value}/${param}`;
|
||||||
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
<VnLv :label="t('globals.reference')" :value="travel.ref" />
|
||||||
<VnLv label="m³" :value="travel.m3" />
|
<VnLv label="m³" :value="travel.m3" />
|
||||||
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
<VnLv :label="t('globals.totalEntries')" :value="travel.totalEntries" />
|
||||||
|
<VnLv
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
:value="
|
||||||
|
dashIfEmpty(toDateTimeFormat(travel.availabled))
|
||||||
|
"
|
||||||
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="full-width">
|
<QCard class="full-width">
|
||||||
<VnTitle :text="t('travel.summary.entries')" />
|
<VnTitle :text="t('travel.summary.entries')" />
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { onMounted, ref, computed, watch } from 'vue';
|
import { onMounted, ref, computed, watch } from 'vue';
|
||||||
import { QBtn } from 'quasar';
|
import { QBtn } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
import SupplierDescriptorProxy from 'src/pages/Supplier/Card/SupplierDescriptorProxy.vue';
|
||||||
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
import TravelDescriptorProxy from 'src/pages/Travel/Card/TravelDescriptorProxy.vue';
|
||||||
|
@ -22,6 +23,8 @@ import VnPopup from 'src/components/common/VnPopup.vue';
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const { openReport } = usePrintService();
|
const { openReport } = usePrintService();
|
||||||
|
const route = useRoute();
|
||||||
|
const tableParams = ref();
|
||||||
|
|
||||||
const shippedFrom = ref(Date.vnNew());
|
const shippedFrom = ref(Date.vnNew());
|
||||||
const landedTo = ref(Date.vnNew());
|
const landedTo = ref(Date.vnNew());
|
||||||
|
@ -143,7 +146,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('globals.pageTitles.supplier'),
|
label: t('extraCommunity.cargoShip'),
|
||||||
field: 'cargoSupplierNickname',
|
field: 'cargoSupplierNickname',
|
||||||
name: 'cargoSupplierNickname',
|
name: 'cargoSupplierNickname',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -171,7 +174,7 @@ const columns = computed(() => [
|
||||||
? value.reduce((sum, entry) => {
|
? value.reduce((sum, entry) => {
|
||||||
return sum + (entry.invoiceAmount || 0);
|
return sum + (entry.invoiceAmount || 0);
|
||||||
}, 0)
|
}, 0)
|
||||||
: 0
|
: 0,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -200,7 +203,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('kg'),
|
label: t('extraCommunity.kg'),
|
||||||
field: 'kg',
|
field: 'kg',
|
||||||
name: 'kg',
|
name: 'kg',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -208,7 +211,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('physicKg'),
|
label: t('extraCommunity.physicKg'),
|
||||||
field: 'loadedKg',
|
field: 'loadedKg',
|
||||||
name: 'loadedKg',
|
name: 'loadedKg',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -232,7 +235,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('shipped'),
|
label: t('extraCommunity.shipped'),
|
||||||
field: 'shipped',
|
field: 'shipped',
|
||||||
name: 'shipped',
|
name: 'shipped',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -249,7 +252,7 @@ const columns = computed(() => [
|
||||||
sortable: true,
|
sortable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('landed'),
|
label: t('extraCommunity.landed'),
|
||||||
field: 'landed',
|
field: 'landed',
|
||||||
name: 'landed',
|
name: 'landed',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -258,7 +261,7 @@ const columns = computed(() => [
|
||||||
format: (value) => toDate(value),
|
format: (value) => toDate(value),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('notes'),
|
label: t('extraCommunity.notes'),
|
||||||
field: '',
|
field: '',
|
||||||
name: 'notes',
|
name: 'notes',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -284,7 +287,7 @@ watch(
|
||||||
if (!arrayData.store.data) return;
|
if (!arrayData.store.data) return;
|
||||||
onStoreDataChange();
|
onStoreDataChange();
|
||||||
},
|
},
|
||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
const openReportPdf = () => {
|
const openReportPdf = () => {
|
||||||
|
@ -451,13 +454,24 @@ const getColor = (percentage) => {
|
||||||
for (const { value, className } of travelKgPercentages.value)
|
for (const { value, className } of travelKgPercentages.value)
|
||||||
if (percentage > value) return className;
|
if (percentage > value) return className;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const filteredEntries = (entries) => {
|
||||||
|
if (!tableParams?.value?.entrySupplierFk) return entries;
|
||||||
|
return entries?.filter(
|
||||||
|
(entry) => entry.supplierFk === tableParams?.value?.entrySupplierFk,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(route, () => {
|
||||||
|
tableParams.value = JSON.parse(route.query.table);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
data-key="ExtraCommunity"
|
data-key="ExtraCommunity"
|
||||||
:limit="20"
|
:limit="20"
|
||||||
:label="t('searchExtraCommunity')"
|
:label="t('extraCommunity.searchExtraCommunity')"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<RightMenu>
|
||||||
<template #right-panel>
|
<template #right-panel>
|
||||||
|
@ -521,7 +535,7 @@ const getColor = (percentage) => {
|
||||||
? tableColumnComponents[col.name].event(
|
? tableColumnComponents[col.name].event(
|
||||||
rows[props.rowIndex][col.field],
|
rows[props.rowIndex][col.field],
|
||||||
col.field,
|
col.field,
|
||||||
props.rowIndex
|
props.rowIndex,
|
||||||
)
|
)
|
||||||
: {}
|
: {}
|
||||||
"
|
"
|
||||||
|
@ -546,7 +560,7 @@ const getColor = (percentage) => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
link: ['id', 'cargoSupplierNickname'].includes(
|
link: ['id', 'cargoSupplierNickname'].includes(
|
||||||
col.name
|
col.name,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
|
@ -564,9 +578,8 @@ const getColor = (percentage) => {
|
||||||
</component>
|
</component>
|
||||||
</QTd>
|
</QTd>
|
||||||
</QTr>
|
</QTr>
|
||||||
|
|
||||||
<QTr
|
<QTr
|
||||||
v-for="(entry, index) in props.row.entries"
|
v-for="(entry, index) in filteredEntries(props.row.entries)"
|
||||||
:key="index"
|
:key="index"
|
||||||
:props="props"
|
:props="props"
|
||||||
class="bg-vn-secondary-row cursor-pointer"
|
class="bg-vn-secondary-row cursor-pointer"
|
||||||
|
@ -598,7 +611,7 @@ const getColor = (percentage) => {
|
||||||
name="warning"
|
name="warning"
|
||||||
color="negative"
|
color="negative"
|
||||||
size="md"
|
size="md"
|
||||||
:title="t('requiresInspection')"
|
:title="t('extraCommunity.requiresInspection')"
|
||||||
>
|
>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</QTd>
|
</QTd>
|
||||||
|
@ -709,24 +722,3 @@ const getColor = (percentage) => {
|
||||||
width: max-content;
|
width: max-content;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
searchExtraCommunity: Search for extra community shipping
|
|
||||||
kg: BI. KG
|
|
||||||
physicKg: Phy. KG
|
|
||||||
shipped: W. shipped
|
|
||||||
landed: W. landed
|
|
||||||
requiresInspection: Requires inspection
|
|
||||||
BIP: Boder Inspection Point
|
|
||||||
notes: Notes
|
|
||||||
es:
|
|
||||||
searchExtraCommunity: Buscar por envío extra comunitario
|
|
||||||
kg: KG Bloq.
|
|
||||||
physicKg: KG físico
|
|
||||||
shipped: F. envío
|
|
||||||
landed: F. llegada
|
|
||||||
notes: Notas
|
|
||||||
Open as PDF: Abrir como PDF
|
|
||||||
requiresInspection: Requiere inspección
|
|
||||||
BIP: Punto de Inspección Fronteriza
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ warehouses();
|
||||||
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
<VnFilterPanel :data-key="props.dataKey" :search-button="true">
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
<div class="q-gutter-x-xs">
|
<div class="q-gutter-x-xs">
|
||||||
<strong>{{ t(`params.${tag.label}`) }}: </strong>
|
<strong>{{ t(`extraCommunity.filter.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -92,7 +92,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('params.reference')"
|
:label="t('extraCommunity.filter.reference')"
|
||||||
v-model="params.reference"
|
v-model="params.reference"
|
||||||
is-outlined
|
is-outlined
|
||||||
/>
|
/>
|
||||||
|
@ -103,7 +103,7 @@ warehouses();
|
||||||
<QInput
|
<QInput
|
||||||
v-model="params.totalEntries"
|
v-model="params.totalEntries"
|
||||||
type="number"
|
type="number"
|
||||||
:label="t('params.totalEntries')"
|
:label="t('extraCommunity.filter.totalEntries')"
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
@ -133,10 +133,10 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.agencyModeFk')"
|
:label="t('extraCommunity.filter.agencyModeFk')"
|
||||||
v-model="params.agencyModeFk"
|
v-model="params.agencyModeFk"
|
||||||
:options="agenciesOptions"
|
:options="agenciesOptions"
|
||||||
option-value="agencyFk"
|
option-value="id"
|
||||||
option-label="name"
|
option-label="name"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
|
@ -148,7 +148,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('params.shippedFrom')"
|
:label="t('extraCommunity.filter.shippedFrom')"
|
||||||
v-model="params.shippedFrom"
|
v-model="params.shippedFrom"
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@ -158,7 +158,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('params.landedTo')"
|
:label="t('extraCommunity.filter.landedTo')"
|
||||||
v-model="params.landedTo"
|
v-model="params.landedTo"
|
||||||
@update:model-value="searchFn()"
|
@update:model-value="searchFn()"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@ -168,7 +168,7 @@ warehouses();
|
||||||
<QItem v-if="warehousesByContinent[params.continent]">
|
<QItem v-if="warehousesByContinent[params.continent]">
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseOutFk')"
|
:label="t('extraCommunity.filter.warehouseOutFk')"
|
||||||
v-model="params.warehouseOutFk"
|
v-model="params.warehouseOutFk"
|
||||||
:options="warehousesByContinent[params.continent]"
|
:options="warehousesByContinent[params.continent]"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -183,7 +183,7 @@ warehouses();
|
||||||
<QItem v-else>
|
<QItem v-else>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseOutFk')"
|
:label="t('extraCommunity.filter.warehouseOutFk')"
|
||||||
v-model="params.warehouseOutFk"
|
v-model="params.warehouseOutFk"
|
||||||
:options="warehousesOptions"
|
:options="warehousesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -198,7 +198,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.warehouseInFk')"
|
:label="t('extraCommunity.filter.warehouseInFk')"
|
||||||
v-model="params.warehouseInFk"
|
v-model="params.warehouseInFk"
|
||||||
:options="warehousesOptions"
|
:options="warehousesOptions"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
|
@ -213,6 +213,7 @@ warehouses();
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelectSupplier
|
<VnSelectSupplier
|
||||||
|
:label="t('extraCommunity.cargoShip')"
|
||||||
v-model="params.cargoSupplierFk"
|
v-model="params.cargoSupplierFk"
|
||||||
hide-selected
|
hide-selected
|
||||||
dense
|
dense
|
||||||
|
@ -221,10 +222,21 @@ warehouses();
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection>
|
||||||
|
<VnSelectSupplier
|
||||||
|
v-model="params.entrySupplierFk"
|
||||||
|
hide-selected
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('params.continent')"
|
:label="t('extraCommunity.filter.continent')"
|
||||||
v-model="params.continent"
|
v-model="params.continent"
|
||||||
:options="continentsOptions"
|
:options="continentsOptions"
|
||||||
option-value="code"
|
option-value="code"
|
||||||
|
@ -240,30 +252,3 @@ warehouses();
|
||||||
</template>
|
</template>
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
id: Id
|
|
||||||
reference: Reference
|
|
||||||
totalEntries: Total entries
|
|
||||||
agencyModeFk: Agency
|
|
||||||
warehouseInFk: Warehouse In
|
|
||||||
warehouseOutFk: Warehouse Out
|
|
||||||
shippedFrom: Shipped from
|
|
||||||
landedTo: Landed to
|
|
||||||
cargoSupplierFk: Supplier
|
|
||||||
continent: Continent out
|
|
||||||
es:
|
|
||||||
params:
|
|
||||||
id: Id
|
|
||||||
reference: Referencia
|
|
||||||
totalEntries: Ent. totales
|
|
||||||
agencyModeFk: Agencia
|
|
||||||
warehouseInFk: Alm. entrada
|
|
||||||
warehouseOutFk: Alm. salida
|
|
||||||
shippedFrom: Llegada desde
|
|
||||||
landedTo: Llegada hasta
|
|
||||||
cargoSupplierFk: Proveedor
|
|
||||||
continent: Cont. Salida
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -10,6 +10,9 @@ import { getDateQBadgeColor } from 'src/composables/getDateQBadgeColor.js';
|
||||||
import TravelFilter from './TravelFilter.vue';
|
import TravelFilter from './TravelFilter.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
import VnSection from 'src/components/common/VnSection.vue';
|
import VnSection from 'src/components/common/VnSection.vue';
|
||||||
|
import VnInputTime from 'src/components/common/VnInputTime.vue';
|
||||||
|
import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
|
import { toDateTimeFormat } from 'src/filters/date';
|
||||||
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -167,6 +170,17 @@ const columns = computed(() => [
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
create: true,
|
create: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
name: 'availabled',
|
||||||
|
label: t('travel.summary.availabled'),
|
||||||
|
component: 'input',
|
||||||
|
columnClass: 'expand',
|
||||||
|
columnField: {
|
||||||
|
component: null,
|
||||||
|
},
|
||||||
|
format: (row, dashIfEmpty) => dashIfEmpty(toDateTimeFormat(row.availabled)),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
label: '',
|
label: '',
|
||||||
|
@ -269,6 +283,16 @@ const columns = computed(() => [
|
||||||
:class="{ 'is-active': row.isReceived }"
|
:class="{ 'is-active': row.isReceived }"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
<template #more-create-dialog="{ data }">
|
||||||
|
<VnInputDate
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabled')"
|
||||||
|
/>
|
||||||
|
<VnInputTime
|
||||||
|
v-model="data.availabled"
|
||||||
|
:label="t('travel.summary.availabledHour')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
<template #moreFilterPanel="{ params }">
|
<template #moreFilterPanel="{ params }">
|
||||||
<VnInputNumber
|
<VnInputNumber
|
||||||
:label="t('params.scopeDays')"
|
:label="t('params.scopeDays')"
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
extraCommunity:
|
||||||
|
cargoShip: Cargo ship
|
||||||
|
searchExtraCommunity: Search for extra community shipping
|
||||||
|
kg: BI. KG
|
||||||
|
physicKg: Phy. KG
|
||||||
|
shipped: W. shipped
|
||||||
|
landed: W. landed
|
||||||
|
requiresInspection: Requires inspection
|
||||||
|
BIP: Boder Inspection Point
|
||||||
|
notes: Notes
|
||||||
|
filter:
|
||||||
|
id: Id
|
||||||
|
reference: Reference
|
||||||
|
totalEntries: Total entries
|
||||||
|
agencyModeFk: Agency
|
||||||
|
warehouseInFk: Warehouse In
|
||||||
|
warehouseOutFk: Warehouse Out
|
||||||
|
shippedFrom: Shipped from
|
||||||
|
landedTo: Landed to
|
||||||
|
cargoSupplierFk: Cargo supplier
|
||||||
|
continent: Continent out
|
||||||
|
entrySupplierFk: Supplier
|
|
@ -0,0 +1,23 @@
|
||||||
|
extraCommunity:
|
||||||
|
cargoShip: Carguera
|
||||||
|
searchExtraCommunity: Buscar por envío extra comunitario
|
||||||
|
kg: KG Bloq.
|
||||||
|
physicKg: KG físico
|
||||||
|
shipped: F. envío
|
||||||
|
landed: F. llegada
|
||||||
|
notes: Notas
|
||||||
|
Open as PDF: Abrir como PDF
|
||||||
|
requiresInspection: Requiere inspección
|
||||||
|
BIP: Punto de Inspección Fronteriza
|
||||||
|
filter:
|
||||||
|
id: Id
|
||||||
|
reference: Referencia
|
||||||
|
totalEntries: Ent. totales
|
||||||
|
agencyModeFk: Agencia
|
||||||
|
warehouseInFk: Alm. entrada
|
||||||
|
warehouseOutFk: Alm. salida
|
||||||
|
shippedFrom: Llegada desde
|
||||||
|
landedTo: Llegada hasta
|
||||||
|
cargoSupplierFk: Carguera
|
||||||
|
continent: Cont. Salida
|
||||||
|
entrySupplierFk: Proveedor
|
|
@ -53,7 +53,7 @@ const showChangePasswordDialog = () => {
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem
|
<QItem
|
||||||
v-if="!worker.user.emailVerified && user.id == worker.id"
|
v-if="!worker.user.emailVerified && user.id != worker.id"
|
||||||
v-ripple
|
v-ripple
|
||||||
clickable
|
clickable
|
||||||
@click="showChangePasswordDialog"
|
@click="showChangePasswordDialog"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { computed, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import FetchData from 'components/FetchData.vue';
|
import FetchData from 'components/FetchData.vue';
|
||||||
import FormModel from 'src/components/FormModel.vue';
|
import FormModel from 'src/components/FormModel.vue';
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
import VnRow from 'components/ui/VnRow.vue';
|
||||||
|
@ -9,33 +9,23 @@ import VnInputTime from 'src/components/common/VnInputTime.vue';
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const agencyFilter = {
|
|
||||||
fields: ['id', 'name'],
|
|
||||||
order: 'name ASC',
|
|
||||||
limit: 30,
|
|
||||||
};
|
|
||||||
const agencyOptions = ref([]);
|
|
||||||
const validAddresses = ref([]);
|
const validAddresses = ref([]);
|
||||||
|
const addresses = ref([]);
|
||||||
|
|
||||||
const filterWhere = computed(() => ({
|
const setFilteredAddresses = (data) => {
|
||||||
id: { inq: validAddresses.value.map((item) => item.addressFk) },
|
const validIds = new Set(validAddresses.value.map((item) => item.addressFk));
|
||||||
}));
|
addresses.value = data.filter((address) => validIds.has(address.id));
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
|
||||||
:filter="agencyFilter"
|
|
||||||
@on-fetch="(data) => (agencyOptions = data)"
|
|
||||||
auto-load
|
|
||||||
url="AgencyModes/isActive"
|
|
||||||
/>
|
|
||||||
<FetchData
|
<FetchData
|
||||||
url="RoadmapAddresses"
|
url="RoadmapAddresses"
|
||||||
auto-load
|
auto-load
|
||||||
@on-fetch="(data) => (validAddresses = data)"
|
@on-fetch="(data) => (validAddresses = data)"
|
||||||
/>
|
/>
|
||||||
<FormModel :url="`Zones/${$route.params.id}`" auto-load data-key="Zone">
|
<FetchData url="Addresses" auto-load @on-fetch="setFilteredAddresses" />
|
||||||
|
<FormModel auto-load model="zone">
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -45,7 +35,6 @@ const filterWhere = computed(() => ({
|
||||||
v-model="data.name"
|
v-model="data.name"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
v-model="data.agencyModeFk"
|
v-model="data.agencyModeFk"
|
||||||
|
@ -128,7 +117,7 @@ const filterWhere = computed(() => ({
|
||||||
v-model="data.addressFk"
|
v-model="data.addressFk"
|
||||||
option-value="id"
|
option-value="id"
|
||||||
option-label="nickname"
|
option-label="nickname"
|
||||||
url="Addresses"
|
:options="addresses"
|
||||||
:fields="['id', 'nickname']"
|
:fields="['id', 'nickname']"
|
||||||
sort-by="id"
|
sort-by="id"
|
||||||
hide-selected
|
hide-selected
|
||||||
|
|
|
@ -3,11 +3,46 @@ describe('Client consignee', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/1110/address', {
|
cy.visit('#/customer/1107/address');
|
||||||
timeout: 5000,
|
cy.domContentLoad();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('Should load layout', () => {
|
it('Should load layout', () => {
|
||||||
cy.get('.q-card').should('be.visible');
|
cy.get('.q-card').should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('check as equalizated', function () {
|
||||||
|
cy.get('.q-card__section > .address-card').then(($el) => {
|
||||||
|
let addressCards_before = $el.length;
|
||||||
|
|
||||||
|
cy.get('.q-page-sticky > div > .q-btn').click();
|
||||||
|
const addressName = 'test';
|
||||||
|
cy.dataCy('Consignee_input').type(addressName);
|
||||||
|
cy.dataCy('Location_select').click();
|
||||||
|
cy.get('[role="listbox"] .q-item:nth-child(1)').click();
|
||||||
|
cy.dataCy('Street address_input').type('TEST ADDRESS');
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard').click();
|
||||||
|
cy.location('href').should('contain', '#/customer/1107/address');
|
||||||
|
cy.get('.q-card__section > .address-card').should(
|
||||||
|
'have.length',
|
||||||
|
addressCards_before + 1,
|
||||||
|
);
|
||||||
|
cy.get('.q-card__section > .address-card')
|
||||||
|
.eq(addressCards_before)
|
||||||
|
.should('be.visible')
|
||||||
|
.get('.text-weight-bold')
|
||||||
|
.eq(addressCards_before - 1)
|
||||||
|
.should('contain', addressName)
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get(
|
||||||
|
'.q-card > :nth-child(1) > :nth-child(2) > .q-checkbox > .q-checkbox__inner',
|
||||||
|
)
|
||||||
|
.should('have.class', 'q-checkbox__inner--falsy')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
|
||||||
|
cy.get(
|
||||||
|
':nth-child(2) > :nth-child(2) > .flex > .q-mr-lg > .q-checkbox__inner',
|
||||||
|
).should('have.class', 'q-checkbox__inner--truthy');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,9 +3,8 @@ describe('Client fiscal data', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/1107/fiscal-data', {
|
cy.visit('#/customer/1107/fiscal-data');
|
||||||
timeout: 5000,
|
cy.domContentLoad();
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it('Should change required value when change customer', () => {
|
it('Should change required value when change customer', () => {
|
||||||
cy.get('.q-card').should('be.visible');
|
cy.get('.q-card').should('be.visible');
|
||||||
|
@ -15,4 +14,25 @@ describe('Client fiscal data', () => {
|
||||||
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
|
cy.get('.q-item > .q-item__label').should('have.text', ' #1');
|
||||||
cy.dataCy('sageTaxTypeFk').filter('input').should('have.attr', 'required');
|
cy.dataCy('sageTaxTypeFk').filter('input').should('have.attr', 'required');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('check as equalizated', () => {
|
||||||
|
cy.get(
|
||||||
|
':nth-child(1) > .q-checkbox > .q-checkbox__inner > .q-checkbox__bg',
|
||||||
|
).click();
|
||||||
|
cy.get('.q-btn-group > .q-btn--standard > .q-btn__content').click();
|
||||||
|
|
||||||
|
cy.get('.q-card > :nth-child(1) > span').should(
|
||||||
|
'contain',
|
||||||
|
'You changed the equalization tax',
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.get('.q-card > :nth-child(2) > span').should(
|
||||||
|
'have.text',
|
||||||
|
'Do you want to spread the change?',
|
||||||
|
);
|
||||||
|
cy.get('[data-cy="VnConfirm_confirm"] > .q-btn__content > .block').click();
|
||||||
|
cy.get(
|
||||||
|
'.bg-warning > .q-notification__wrapper > .q-notification__content > .q-notification__message',
|
||||||
|
).should('have.text', 'Equivalent tax spreaded');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,11 +8,9 @@ describe('EntryMy when is supplier', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open buyLabel when is supplier', () => {
|
it('should open buyLabel when is supplier', () => {
|
||||||
cy.get(
|
cy.dataCy('cardBtn').eq(2).click();
|
||||||
'[to="/null/3"] > .q-card > :nth-child(2) > .q-btn > .q-btn__content > .q-icon'
|
|
||||||
).click();
|
|
||||||
cy.dataCy('printLabelsBtn').click();
|
cy.dataCy('printLabelsBtn').click();
|
||||||
cy.window().its('open').should('be.called');
|
cy.window().its('open').should('be.called');
|
||||||
});
|
});
|
||||||
|
|
|
@ -36,7 +36,7 @@ describe('InvoiceInVat', () => {
|
||||||
cy.get(dialogInputs).eq(0).type(randomInt);
|
cy.get(dialogInputs).eq(0).type(randomInt);
|
||||||
cy.get(dialogInputs).eq(1).type('This is a dummy expense');
|
cy.get(dialogInputs).eq(1).type('This is a dummy expense');
|
||||||
|
|
||||||
cy.get('button[type="submit"]').click();
|
cy.get('[data-cy="FormModelPopup_save"]').click();
|
||||||
cy.get('.q-notification__message').should('have.text', 'Data created');
|
cy.get('.q-notification__message').should('have.text', 'Data created');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue