Merge branch 'dev' into 7937-claimAgile
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
62fe649e89
|
@ -34,6 +34,17 @@ export default defineConfig({
|
||||||
const plugin = await import('cypress-mochawesome-reporter/plugin');
|
const plugin = await import('cypress-mochawesome-reporter/plugin');
|
||||||
plugin.default(on);
|
plugin.default(on);
|
||||||
|
|
||||||
|
const fs = await import('fs');
|
||||||
|
on('task', {
|
||||||
|
deleteFile(filePath) {
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
viewportWidth: 1280,
|
viewportWidth: 1280,
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -30,22 +30,5 @@ export default {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
form.addEventListener('keyup', function (evt) {
|
|
||||||
if (evt.key === 'Enter' && !that.$attrs['prevent-submit']) {
|
|
||||||
const input = evt.target;
|
|
||||||
if (input.type == 'textarea' && evt.shiftKey) {
|
|
||||||
evt.preventDefault();
|
|
||||||
let { selectionStart, selectionEnd } = input;
|
|
||||||
input.value =
|
|
||||||
input.value.substring(0, selectionStart) +
|
|
||||||
'\n' +
|
|
||||||
input.value.substring(selectionEnd);
|
|
||||||
selectionStart = selectionEnd = selectionStart + 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
evt.preventDefault();
|
|
||||||
that.onSubmit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { onMounted, onUnmounted, computed, ref, watch, nextTick } from 'vue';
|
import { onMounted, onUnmounted, computed, ref, watch, nextTick, useAttrs } from 'vue';
|
||||||
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
@ -22,6 +22,7 @@ const { validate } = useValidator();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const myForm = ref(null);
|
const myForm = ref(null);
|
||||||
|
const attrs = useAttrs();
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -106,14 +107,14 @@ 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',
|
||||||
color: 'primary',
|
color: 'primary',
|
||||||
icon: 'save',
|
icon: 'save',
|
||||||
label: 'globals.save',
|
label: 'globals.save',
|
||||||
click: () => myForm.value.onSubmit(false),
|
click: async () => await save(),
|
||||||
type: 'submit',
|
type: 'submit',
|
||||||
},
|
},
|
||||||
reset: {
|
reset: {
|
||||||
|
@ -208,8 +209,7 @@ async function fetch() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function save(prevent = false) {
|
async function save() {
|
||||||
if (prevent) return;
|
|
||||||
if ($props.observeFormChanges && !hasChanges.value)
|
if ($props.observeFormChanges && !hasChanges.value)
|
||||||
return notify('globals.noChanges', 'negative');
|
return notify('globals.noChanges', 'negative');
|
||||||
|
|
||||||
|
@ -247,6 +247,7 @@ async function saveAndGo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function reset() {
|
function reset() {
|
||||||
|
formData.value = JSON.parse(JSON.stringify(originalData.value));
|
||||||
updateAndEmit('onFetch', { val: originalData.value });
|
updateAndEmit('onFetch', { val: originalData.value });
|
||||||
if ($props.observeFormChanges) {
|
if ($props.observeFormChanges) {
|
||||||
hasChanges.value = false;
|
hasChanges.value = false;
|
||||||
|
@ -284,6 +285,22 @@ function trimData(data) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onKeyup(evt) {
|
||||||
|
if (evt.key === 'Enter' && !('prevent-submit' in attrs)) {
|
||||||
|
const input = evt.target;
|
||||||
|
if (input.type == 'textarea' && evt.shiftKey) {
|
||||||
|
let { selectionStart, selectionEnd } = input;
|
||||||
|
input.value =
|
||||||
|
input.value.substring(0, selectionStart) +
|
||||||
|
'\n' +
|
||||||
|
input.value.substring(selectionEnd);
|
||||||
|
selectionStart = selectionEnd = selectionStart + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
save,
|
save,
|
||||||
isLoading,
|
isLoading,
|
||||||
|
@ -298,12 +315,12 @@ defineExpose({
|
||||||
<QForm
|
<QForm
|
||||||
ref="myForm"
|
ref="myForm"
|
||||||
v-if="formData"
|
v-if="formData"
|
||||||
@submit="save(!!$event)"
|
@submit.prevent
|
||||||
|
@keyup.prevent="onKeyup"
|
||||||
@reset="reset"
|
@reset="reset"
|
||||||
class="q-pa-md"
|
class="q-pa-md"
|
||||||
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
:style="maxWidth ? 'max-width: ' + maxWidth : ''"
|
||||||
id="formModel"
|
id="formModel"
|
||||||
:prevent-submit="$attrs['prevent-submit']"
|
|
||||||
>
|
>
|
||||||
<QCard>
|
<QCard>
|
||||||
<slot
|
<slot
|
||||||
|
|
|
@ -27,10 +27,15 @@ const formModelRef = ref(null);
|
||||||
const closeButton = ref(null);
|
const closeButton = ref(null);
|
||||||
const isSaveAndContinue = ref(false);
|
const isSaveAndContinue = ref(false);
|
||||||
const onDataSaved = (formData, requestResponse) => {
|
const onDataSaved = (formData, requestResponse) => {
|
||||||
if (closeButton.value && isSaveAndContinue) closeButton.value.click();
|
if (closeButton.value && !isSaveAndContinue.value) closeButton.value.click();
|
||||||
emit('onDataSaved', formData, requestResponse);
|
emit('onDataSaved', formData, requestResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onClick = async (saveAndContinue) => {
|
||||||
|
isSaveAndContinue.value = saveAndContinue;
|
||||||
|
await formModelRef.value.save();
|
||||||
|
};
|
||||||
|
|
||||||
const isLoading = computed(() => formModelRef.value?.isLoading);
|
const isLoading = computed(() => formModelRef.value?.isLoading);
|
||||||
const reset = computed(() => formModelRef.value?.reset);
|
const reset = computed(() => formModelRef.value?.reset);
|
||||||
|
|
||||||
|
@ -78,10 +83,7 @@ defineExpose({
|
||||||
:flat="showSaveAndContinueBtn"
|
:flat="showSaveAndContinueBtn"
|
||||||
:label="t('globals.save')"
|
:label="t('globals.save')"
|
||||||
:title="t('globals.save')"
|
:title="t('globals.save')"
|
||||||
@click="
|
@click="onClick(false)"
|
||||||
formModelRef.save();
|
|
||||||
isSaveAndContinue = false;
|
|
||||||
"
|
|
||||||
color="primary"
|
color="primary"
|
||||||
class="q-ml-sm"
|
class="q-ml-sm"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading"
|
||||||
|
@ -99,10 +101,7 @@ defineExpose({
|
||||||
:loading="isLoading"
|
:loading="isLoading"
|
||||||
data-cy="FormModelPopup_isSaveAndContinue"
|
data-cy="FormModelPopup_isSaveAndContinue"
|
||||||
z-max
|
z-max
|
||||||
@click="
|
@click="onClick(true)"
|
||||||
isSaveAndContinue = true;
|
|
||||||
formModelRef.save();
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -5,6 +5,18 @@ 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"
|
||||||
|
@ -56,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"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { markRaw, computed } from 'vue';
|
import { markRaw, computed } from 'vue';
|
||||||
import { QIcon, QCheckbox, QToggle } from 'quasar';
|
import { QIcon, QToggle } from 'quasar';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty } from 'src/filters';
|
||||||
|
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
|
|
|
@ -10,14 +10,15 @@ import {
|
||||||
render,
|
render,
|
||||||
inject,
|
inject,
|
||||||
useAttrs,
|
useAttrs,
|
||||||
|
nextTick,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { useArrayData } from 'src/composables/useArrayData';
|
import { useArrayData } from 'src/composables/useArrayData';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar, date } from 'quasar';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { useFilterParams } from 'src/composables/useFilterParams';
|
import { useFilterParams } from 'src/composables/useFilterParams';
|
||||||
import { dashIfEmpty } from 'src/filters';
|
import { dashIfEmpty, toDate } from 'src/filters';
|
||||||
|
|
||||||
import CrudModel from 'src/components/CrudModel.vue';
|
import CrudModel from 'src/components/CrudModel.vue';
|
||||||
import FormModelPopup from 'components/FormModelPopup.vue';
|
import FormModelPopup from 'components/FormModelPopup.vue';
|
||||||
|
@ -164,7 +165,6 @@ const app = inject('app');
|
||||||
const editingRow = ref(null);
|
const editingRow = ref(null);
|
||||||
const editingField = ref(null);
|
const editingField = ref(null);
|
||||||
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
const isTableMode = computed(() => mode.value == TABLE_MODE);
|
||||||
const showRightIcon = computed(() => $props.rightSearch || $props.rightSearchIcon);
|
|
||||||
const selectRegex = /select/;
|
const selectRegex = /select/;
|
||||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||||
const tableModes = [
|
const tableModes = [
|
||||||
|
@ -345,7 +345,7 @@ const clickHandler = async (event) => {
|
||||||
if (isDateElement || isTimeElement || isQselectDropDown) return;
|
if (isDateElement || isTimeElement || isQselectDropDown) return;
|
||||||
|
|
||||||
if (clickedElement === null) {
|
if (clickedElement === null) {
|
||||||
destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const rowIndex = clickedElement.getAttribute('data-row-index');
|
const rowIndex = clickedElement.getAttribute('data-row-index');
|
||||||
|
@ -355,7 +355,7 @@ const clickHandler = async (event) => {
|
||||||
if (editingRow.value !== null && editingField.value !== null) {
|
if (editingRow.value !== null && editingField.value !== null) {
|
||||||
if (editingRow.value == rowIndex && editingField.value == colField) return;
|
if (editingRow.value == rowIndex && editingField.value == colField) return;
|
||||||
|
|
||||||
destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEditableColumn(column)) {
|
if (isEditableColumn(column)) {
|
||||||
|
@ -365,7 +365,7 @@ const clickHandler = async (event) => {
|
||||||
|
|
||||||
async function handleTabKey(event, rowIndex, colField) {
|
async function handleTabKey(event, rowIndex, colField) {
|
||||||
if (editingRow.value == rowIndex && editingField.value == colField)
|
if (editingRow.value == rowIndex && editingField.value == colField)
|
||||||
destroyInput(editingRow.value, editingField.value);
|
await destroyInput(editingRow.value, editingField.value);
|
||||||
|
|
||||||
const direction = event.shiftKey ? -1 : 1;
|
const direction = event.shiftKey ? -1 : 1;
|
||||||
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
|
||||||
|
@ -425,7 +425,8 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
|
||||||
},
|
},
|
||||||
keyup: async (event) => {
|
keyup: async (event) => {
|
||||||
if (event.key === 'Enter') handleBlur(rowId, field, clickedElement);
|
if (event.key === 'Enter')
|
||||||
|
await destroyInput(rowIndex, field, clickedElement);
|
||||||
},
|
},
|
||||||
keydown: async (event) => {
|
keydown: async (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
|
@ -434,7 +435,7 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
destroyInput(rowId, field, clickedElement);
|
await destroyInput(rowId, field, clickedElement);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -456,12 +457,13 @@ async function renderInput(rowId, field, clickedElement) {
|
||||||
node.el?.querySelector('span > div > div').focus();
|
node.el?.querySelector('span > div > div').focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroyInput(rowIndex, field, clickedElement) {
|
async function destroyInput(rowIndex, field, clickedElement) {
|
||||||
if (!clickedElement)
|
if (!clickedElement)
|
||||||
clickedElement = document.querySelector(
|
clickedElement = document.querySelector(
|
||||||
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
|
||||||
);
|
);
|
||||||
if (clickedElement) {
|
if (clickedElement) {
|
||||||
|
await nextTick();
|
||||||
render(null, clickedElement);
|
render(null, clickedElement);
|
||||||
Array.from(clickedElement.childNodes).forEach((child) => {
|
Array.from(clickedElement.childNodes).forEach((child) => {
|
||||||
child.style.visibility = 'visible';
|
child.style.visibility = 'visible';
|
||||||
|
@ -473,10 +475,6 @@ function destroyInput(rowIndex, field, clickedElement) {
|
||||||
editingField.value = null;
|
editingField.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBlur(rowIndex, field, clickedElement) {
|
|
||||||
destroyInput(rowIndex, field, clickedElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleTabNavigation(rowIndex, colName, direction) {
|
async function handleTabNavigation(rowIndex, colName, direction) {
|
||||||
const columns = $props.columns;
|
const columns = $props.columns;
|
||||||
const totalColumns = columns.length;
|
const totalColumns = columns.length;
|
||||||
|
@ -527,11 +525,36 @@ function formatColumnValue(col, row, dashIfEmpty) {
|
||||||
} else {
|
} else {
|
||||||
return col.format(row, dashIfEmpty);
|
return col.format(row, dashIfEmpty);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (col?.component === 'date') return dashIfEmpty(toDate(row[col?.name]));
|
||||||
|
|
||||||
|
if (col?.component === 'time')
|
||||||
|
return row[col?.name] >= 5
|
||||||
|
? dashIfEmpty(date.formatDate(new Date(row[col?.name]), 'HH:mm'))
|
||||||
|
: row[col?.name];
|
||||||
|
|
||||||
|
if (selectRegex.test(col?.component) && $props.isEditable) {
|
||||||
|
const { find, url } = col.attrs;
|
||||||
|
const urlRelation = url?.charAt(0)?.toLocaleLowerCase() + url?.slice(1, -1);
|
||||||
|
|
||||||
|
if (col?.attrs.options) {
|
||||||
|
const find = col?.attrs.options.find((option) => option.id === row[col.name]);
|
||||||
|
if (!col.attrs?.optionLabel || !find) return dashIfEmpty(row[col?.name]);
|
||||||
|
return dashIfEmpty(find[col.attrs?.optionLabel ?? 'name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof row[urlRelation] == 'object') {
|
||||||
|
if (typeof find == 'object')
|
||||||
|
return dashIfEmpty(row[urlRelation][find?.label ?? 'name']);
|
||||||
|
|
||||||
|
return dashIfEmpty(row[urlRelation][col?.attrs.optionLabel ?? 'name']);
|
||||||
|
}
|
||||||
|
if (typeof row[urlRelation] == 'string') return dashIfEmpty(row[urlRelation]);
|
||||||
} else {
|
} else {
|
||||||
return dashIfEmpty(row[col?.name]);
|
return dashIfEmpty(row[col?.name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const checkbox = ref(null);
|
|
||||||
function cardClick(_, row) {
|
function cardClick(_, row) {
|
||||||
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
if ($props.redirect) router.push({ path: `/${$props.redirect}/${row.id}` });
|
||||||
}
|
}
|
||||||
|
@ -618,14 +641,6 @@ function cardClick(_, row) {
|
||||||
dense
|
dense
|
||||||
:options="tableModes.filter((mode) => !mode.disable)"
|
:options="tableModes.filter((mode) => !mode.disable)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<QBtn
|
|
||||||
v-if="showRightIcon"
|
|
||||||
icon="filter_alt"
|
|
||||||
class="bg-vn-section-color q-ml-sm"
|
|
||||||
dense
|
|
||||||
@click="stateStore.toggleRightDrawer()"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
<template #header-cell="{ col }">
|
<template #header-cell="{ col }">
|
||||||
<QTh
|
<QTh
|
||||||
|
@ -730,7 +745,11 @@ function cardClick(_, row) {
|
||||||
<span
|
<span
|
||||||
v-else
|
v-else
|
||||||
:class="hasEditableFormat(col)"
|
:class="hasEditableFormat(col)"
|
||||||
:style="col?.style ? col.style(row) : null"
|
:style="
|
||||||
|
typeof col?.style == 'function'
|
||||||
|
? col.style(row)
|
||||||
|
: col?.style
|
||||||
|
"
|
||||||
style="bottom: 0"
|
style="bottom: 0"
|
||||||
>
|
>
|
||||||
{{ formatColumnValue(col, row, dashIfEmpty) }}
|
{{ formatColumnValue(col, row, dashIfEmpty) }}
|
||||||
|
@ -783,7 +802,7 @@ function cardClick(_, row) {
|
||||||
<QCardSection
|
<QCardSection
|
||||||
vertical
|
vertical
|
||||||
class="no-margin no-padding"
|
class="no-margin no-padding"
|
||||||
:class="colsMap.tableActions ? '' : 'fit'"
|
:class="colsMap.tableActions ? 'w-80' : 'fit'"
|
||||||
>
|
>
|
||||||
<!-- Chips -->
|
<!-- Chips -->
|
||||||
<QCardSection
|
<QCardSection
|
||||||
|
@ -822,11 +841,11 @@ function cardClick(_, row) {
|
||||||
col, index
|
col, index
|
||||||
) of splittedColumns.cardVisible"
|
) of splittedColumns.cardVisible"
|
||||||
:key="col.name"
|
:key="col.name"
|
||||||
|
class="fields"
|
||||||
>
|
>
|
||||||
<VnLv :label="col.label + ':'">
|
<VnLv :label="col.label + ':'">
|
||||||
<template #value>
|
<template #value>
|
||||||
<span
|
<span
|
||||||
class="q-pl-xs"
|
|
||||||
@click="stopEventPropagation($event)"
|
@click="stopEventPropagation($event)"
|
||||||
>
|
>
|
||||||
<slot
|
<slot
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -107,6 +107,7 @@ const manageDate = (date) => {
|
||||||
@click="isPopupOpen = !isPopupOpen"
|
@click="isPopupOpen = !isPopupOpen"
|
||||||
@keydown="isPopupOpen = false"
|
@keydown="isPopupOpen = false"
|
||||||
hide-bottom-space
|
hide-bottom-space
|
||||||
|
:data-cy="$attrs.dataCy ?? $attrs.label + '_inputDate'"
|
||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<QIcon
|
<QIcon
|
||||||
|
|
|
@ -193,8 +193,10 @@ const toModule = computed(() =>
|
||||||
</div>
|
</div>
|
||||||
</QItemLabel>
|
</QItemLabel>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemLabel class="subtitle" caption>
|
<QItemLabel class="subtitle">
|
||||||
#{{ getValueFromPath(subtitle) ?? entity.id }}
|
#{{ getValueFromPath(subtitle) ?? entity.id }}
|
||||||
|
</QItemLabel>
|
||||||
|
|
||||||
<QBtn
|
<QBtn
|
||||||
round
|
round
|
||||||
flat
|
flat
|
||||||
|
@ -208,7 +210,7 @@ const toModule = computed(() =>
|
||||||
{{ t('globals.copyId') }}
|
{{ t('globals.copyId') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</QItemLabel>
|
<!-- </QItemLabel> -->
|
||||||
</QItem>
|
</QItem>
|
||||||
</QList>
|
</QList>
|
||||||
<div class="list-box q-mt-xs">
|
<div class="list-box q-mt-xs">
|
||||||
|
|
|
@ -7,6 +7,7 @@ export function getColAlign(col) {
|
||||||
case 'number':
|
case 'number':
|
||||||
align = 'right';
|
align = 'right';
|
||||||
break;
|
break;
|
||||||
|
case 'time':
|
||||||
case 'date':
|
case 'date':
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
align = 'center';
|
align = 'center';
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -335,3 +335,7 @@ input::-webkit-inner-spin-button {
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
box-shadow: 0 4px 6px #00000000;
|
box-shadow: 0 4px 6px #00000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.containerShrinked {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ globals:
|
||||||
rowRemoved: Row removed
|
rowRemoved: Row removed
|
||||||
pleaseWait: Please wait...
|
pleaseWait: Please wait...
|
||||||
noPinnedModules: You don't have any pinned modules
|
noPinnedModules: You don't have any pinned modules
|
||||||
|
enterToConfirm: Press Enter to confirm
|
||||||
summary:
|
summary:
|
||||||
basicData: Basic data
|
basicData: Basic data
|
||||||
daysOnward: Days onward
|
daysOnward: Days onward
|
||||||
|
|
|
@ -51,6 +51,7 @@ globals:
|
||||||
pleaseWait: Por favor espera...
|
pleaseWait: Por favor espera...
|
||||||
noPinnedModules: No has fijado ningún módulo
|
noPinnedModules: No has fijado ningún módulo
|
||||||
split: Split
|
split: Split
|
||||||
|
enterToConfirm: Pulsa Enter para confirmar
|
||||||
summary:
|
summary:
|
||||||
basicData: Datos básicos
|
basicData: Datos básicos
|
||||||
daysOnward: Días adelante
|
daysOnward: Días adelante
|
||||||
|
|
|
@ -233,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>
|
||||||
|
|
|
@ -114,7 +114,7 @@ function onBeforeSave(data) {
|
||||||
if (isCash.value && shouldSendEmail.value && !data.email)
|
if (isCash.value && shouldSendEmail.value && !data.email)
|
||||||
return notify(t('There is no assigned email for this client'), 'negative');
|
return notify(t('There is no assigned email for this client'), 'negative');
|
||||||
|
|
||||||
data.bankFk = data.bankFk.id;
|
data.bankFk = data.bankFk?.id;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ async function getAmountPaid() {
|
||||||
:url-create="urlCreate"
|
:url-create="urlCreate"
|
||||||
:mapper="onBeforeSave"
|
:mapper="onBeforeSave"
|
||||||
@on-data-saved="onDataSaved"
|
@on-data-saved="onDataSaved"
|
||||||
:prevent-submit="true"
|
prevent-submit
|
||||||
>
|
>
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
<span ref="closeButton" class="row justify-end close-icon" v-close-popup>
|
||||||
|
|
|
@ -103,7 +103,7 @@ const refundInvoice = async (withWarehouse) => {
|
||||||
t('refundInvoiceSuccessMessage', {
|
t('refundInvoiceSuccessMessage', {
|
||||||
refundTicket: data[0].id,
|
refundTicket: data[0].id,
|
||||||
}),
|
}),
|
||||||
'positive'
|
'positive',
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +124,13 @@ const showRefundInvoiceForm = () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const showExportationLetter = () => {
|
||||||
|
openReport(`InvoiceOuts/${$props.invoiceOutData.ref}/exportation-pdf`, {
|
||||||
|
recipientId: $props.invoiceOutData.client.id,
|
||||||
|
refFk: $props.invoiceOutData.ref,
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -172,7 +179,7 @@ const showRefundInvoiceForm = () => {
|
||||||
t('Confirm deletion'),
|
t('Confirm deletion'),
|
||||||
t('Are you sure you want to delete this invoice?'),
|
t('Are you sure you want to delete this invoice?'),
|
||||||
deleteInvoice,
|
deleteInvoice,
|
||||||
redirectToInvoiceOutList
|
redirectToInvoiceOutList,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -185,7 +192,7 @@ const showRefundInvoiceForm = () => {
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
'',
|
'',
|
||||||
t('Are you sure you want to book this invoice?'),
|
t('Are you sure you want to book this invoice?'),
|
||||||
bookInvoice
|
bookInvoice,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -198,7 +205,7 @@ const showRefundInvoiceForm = () => {
|
||||||
openConfirmationModal(
|
openConfirmationModal(
|
||||||
t('Generate PDF invoice document'),
|
t('Generate PDF invoice document'),
|
||||||
t('Are you sure you want to generate/regenerate the PDF invoice?'),
|
t('Are you sure you want to generate/regenerate the PDF invoice?'),
|
||||||
generateInvoicePdf
|
generateInvoicePdf,
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
@ -226,6 +233,14 @@ const showRefundInvoiceForm = () => {
|
||||||
{{ t('Create a single ticket with all the content of the current invoice') }}
|
{{ t('Create a single ticket with all the content of the current invoice') }}
|
||||||
</QTooltip>
|
</QTooltip>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
<QItem
|
||||||
|
v-if="$props.invoiceOutData.serial === 'E'"
|
||||||
|
v-ripple
|
||||||
|
clickable
|
||||||
|
@click="showExportationLetter()"
|
||||||
|
>
|
||||||
|
<QItemSection>{{ t('Show CITES letter') }}</QItemSection>
|
||||||
|
</QItem>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -255,7 +270,7 @@ es:
|
||||||
Create a single ticket with all the content of the current invoice: Crear un ticket único con todo el contenido de la factura actual
|
Create a single ticket with all the content of the current invoice: Crear un ticket único con todo el contenido de la factura actual
|
||||||
refundInvoiceSuccessMessage: Se ha creado el siguiente ticket de abono {refundTicket}
|
refundInvoiceSuccessMessage: Se ha creado el siguiente ticket de abono {refundTicket}
|
||||||
The email can't be empty: El email no puede estar vacío
|
The email can't be empty: El email no puede estar vacío
|
||||||
|
Show CITES letter: Ver carta CITES
|
||||||
en:
|
en:
|
||||||
refundInvoiceSuccessMessage: The following refund ticket have been created {refundTicket}
|
refundInvoiceSuccessMessage: The following refund ticket have been created {refundTicket}
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -22,7 +22,7 @@ const states = ref();
|
||||||
<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(`invoiceOut.params.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -84,15 +84,6 @@ const states = ref();
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
|
||||||
<QItemSection>
|
|
||||||
<VnInputDate
|
|
||||||
v-model="params.issued"
|
|
||||||
:label="t('Issued')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
|
@ -110,37 +101,3 @@ const states = ref();
|
||||||
</template>
|
</template>
|
||||||
</VnFilterPanel>
|
</VnFilterPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
|
||||||
en:
|
|
||||||
params:
|
|
||||||
search: Contains
|
|
||||||
clientFk: Customer
|
|
||||||
fi: FI
|
|
||||||
amount: Amount
|
|
||||||
min: Min
|
|
||||||
max: Max
|
|
||||||
hasPdf: Has PDF
|
|
||||||
issued: Issued
|
|
||||||
created: Created
|
|
||||||
dued: Dued
|
|
||||||
es:
|
|
||||||
params:
|
|
||||||
search: Contiene
|
|
||||||
clientFk: Cliente
|
|
||||||
fi: CIF
|
|
||||||
amount: Importe
|
|
||||||
min: Min
|
|
||||||
max: Max
|
|
||||||
hasPdf: Tiene PDF
|
|
||||||
issued: Emitida
|
|
||||||
created: Creada
|
|
||||||
dued: Vencida
|
|
||||||
Customer ID: ID cliente
|
|
||||||
FI: CIF
|
|
||||||
Amount: Importe
|
|
||||||
Has PDF: Tiene PDF
|
|
||||||
Issued: Fecha emisión
|
|
||||||
Created: Fecha creación
|
|
||||||
Dued: Fecha vencimiento
|
|
||||||
</i18n>
|
|
||||||
|
|
|
@ -71,14 +71,6 @@ const columns = computed(() => [
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
align: 'left',
|
|
||||||
name: 'issued',
|
|
||||||
label: t('invoiceOut.summary.issued'),
|
|
||||||
component: 'date',
|
|
||||||
format: (row) => toDate(row.issued),
|
|
||||||
columnField: { component: null },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'clientFk',
|
name: 'clientFk',
|
||||||
|
|
|
@ -10,6 +10,8 @@ import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vu
|
||||||
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
|
import TicketDescriptorProxy from '../Ticket/Card/TicketDescriptorProxy.vue';
|
||||||
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
import WorkerDescriptorProxy from '../Worker/Card/WorkerDescriptorProxy.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
|
import InvoiceOutNegativeBasesFilter from './InvoiceOutNegativeBasesFilter.vue';
|
||||||
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
@ -97,16 +99,19 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'isActive',
|
name: 'isActive',
|
||||||
label: t('invoiceOut.negativeBases.active'),
|
label: t('invoiceOut.negativeBases.active'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasToInvoice',
|
name: 'hasToInvoice',
|
||||||
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
label: t('invoiceOut.negativeBases.hasToInvoice'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'hasVerifiedData',
|
name: 'isTaxDataChecked',
|
||||||
label: t('invoiceOut.negativeBases.verifiedData'),
|
label: t('invoiceOut.negativeBases.verifiedData'),
|
||||||
|
component: 'checkbox',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -142,7 +147,7 @@ const downloadCSV = async () => {
|
||||||
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
await invoiceOutGlobalStore.getNegativeBasesCsv(
|
||||||
userParams.from,
|
userParams.from,
|
||||||
userParams.to,
|
userParams.to,
|
||||||
filterParams
|
filterParams,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -154,6 +159,11 @@ const downloadCSV = async () => {
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
|
<RightMenu>
|
||||||
|
<template #right-panel>
|
||||||
|
<InvoiceOutNegativeBasesFilter data-key="negativeFilter" />
|
||||||
|
</template>
|
||||||
|
</RightMenu>
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="negativeFilter"
|
data-key="negativeFilter"
|
||||||
|
@ -174,6 +184,7 @@ const downloadCSV = async () => {
|
||||||
auto-load
|
auto-load
|
||||||
:is-editable="false"
|
:is-editable="false"
|
||||||
:use-model="true"
|
:use-model="true"
|
||||||
|
:right-search="false"
|
||||||
>
|
>
|
||||||
<template #column-clientId="{ row }">
|
<template #column-clientId="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
|
||||||
import VnFilterPanel from 'src/components/ui/VnFilterPanel.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 VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
import VnInputNumber from 'src/components/common/VnInputNumber.vue';
|
||||||
|
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||||
|
import VnSelectWorker from 'src/components/common/VnSelectWorker.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -24,11 +25,11 @@ const props = defineProps({
|
||||||
>
|
>
|
||||||
<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(`invoiceOut.params.${tag.label}`) }}: </strong>
|
||||||
<span>{{ formatFn(tag.value) }}</span>
|
<span>{{ formatFn(tag.value) }}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #body="{ params }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
|
@ -49,38 +50,70 @@ const props = defineProps({
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
v-model="params.company"
|
url="Companies"
|
||||||
:label="t('globals.company')"
|
:label="t('globals.company')"
|
||||||
is-outlined
|
v-model="params.company"
|
||||||
/>
|
option-label="code"
|
||||||
|
option-value="code"
|
||||||
|
dense
|
||||||
|
outlined
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.code }}
|
||||||
|
</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{ `#${scope.opt?.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
|
url="Countries"
|
||||||
|
:label="t('globals.params.countryFk')"
|
||||||
v-model="params.country"
|
v-model="params.country"
|
||||||
:label="t('globals.country')"
|
option-label="name"
|
||||||
is-outlined
|
option-value="name"
|
||||||
/>
|
outlined
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.name }}
|
||||||
|
</QItemLabel>
|
||||||
|
<QItemLabel caption>
|
||||||
|
{{ `#${scope.opt?.id}` }}
|
||||||
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
</template>
|
||||||
<QItem>
|
</VnSelect>
|
||||||
<QItemSection>
|
|
||||||
<VnInput
|
|
||||||
v-model="params.clientId"
|
|
||||||
:label="t('invoiceOut.negativeBases.clientId')"
|
|
||||||
is-outlined
|
|
||||||
/>
|
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelect
|
||||||
v-model="params.clientSocialName"
|
url="Clients"
|
||||||
:label="t('globals.client')"
|
:label="t('globals.client')"
|
||||||
is-outlined
|
v-model="params.clientId"
|
||||||
|
outlined
|
||||||
|
dense
|
||||||
|
rounded
|
||||||
|
@update:model-value="searchFn()"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
@ -90,15 +123,18 @@ const props = defineProps({
|
||||||
v-model="params.amount"
|
v-model="params.amount"
|
||||||
:label="t('globals.amount')"
|
:label="t('globals.amount')"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
:positive="false"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput
|
<VnSelectWorker
|
||||||
v-model="params.comercialName"
|
|
||||||
:label="t('invoiceOut.negativeBases.comercial')"
|
:label="t('invoiceOut.negativeBases.comercial')"
|
||||||
|
v-model="params.workerName"
|
||||||
|
option-value="name"
|
||||||
is-outlined
|
is-outlined
|
||||||
|
@update:model-value="searchFn()"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
|
|
|
@ -4,7 +4,7 @@ invoiceOut:
|
||||||
params:
|
params:
|
||||||
company: Company
|
company: Company
|
||||||
country: Country
|
country: Country
|
||||||
clientId: Client ID
|
clientId: Client
|
||||||
clientSocialName: Client
|
clientSocialName: Client
|
||||||
taxableBase: Base
|
taxableBase: Base
|
||||||
ticketFk: Ticket
|
ticketFk: Ticket
|
||||||
|
@ -12,6 +12,18 @@ invoiceOut:
|
||||||
hasToInvoice: Has to invoice
|
hasToInvoice: Has to invoice
|
||||||
hasVerifiedData: Verified data
|
hasVerifiedData: Verified data
|
||||||
workerName: Worker
|
workerName: Worker
|
||||||
|
isTaxDataChecked: Verified data
|
||||||
|
amount: Amount
|
||||||
|
clientFk: Client
|
||||||
|
companyFk: Company
|
||||||
|
created: Created
|
||||||
|
dued: Dued
|
||||||
|
customsAgentFk: Custom Agent
|
||||||
|
ref: Reference
|
||||||
|
fi: FI
|
||||||
|
min: Min
|
||||||
|
max: Max
|
||||||
|
hasPdf: Has PDF
|
||||||
card:
|
card:
|
||||||
issued: Issued
|
issued: Issued
|
||||||
customerCard: Customer card
|
customerCard: Customer card
|
||||||
|
@ -53,7 +65,7 @@ invoiceOut:
|
||||||
active: Active
|
active: Active
|
||||||
hasToInvoice: Has to Invoice
|
hasToInvoice: Has to Invoice
|
||||||
verifiedData: Verified Data
|
verifiedData: Verified Data
|
||||||
comercial: Commercial
|
comercial: Sales person
|
||||||
errors:
|
errors:
|
||||||
downloadCsvFailed: CSV download failed
|
downloadCsvFailed: CSV download failed
|
||||||
invoiceOutModule:
|
invoiceOutModule:
|
||||||
|
|
|
@ -4,7 +4,7 @@ invoiceOut:
|
||||||
params:
|
params:
|
||||||
company: Empresa
|
company: Empresa
|
||||||
country: País
|
country: País
|
||||||
clientId: ID del cliente
|
clientId: Cliente
|
||||||
clientSocialName: Cliente
|
clientSocialName: Cliente
|
||||||
taxableBase: Base
|
taxableBase: Base
|
||||||
ticketFk: Ticket
|
ticketFk: Ticket
|
||||||
|
@ -12,6 +12,18 @@ invoiceOut:
|
||||||
hasToInvoice: Debe facturar
|
hasToInvoice: Debe facturar
|
||||||
hasVerifiedData: Datos verificados
|
hasVerifiedData: Datos verificados
|
||||||
workerName: Comercial
|
workerName: Comercial
|
||||||
|
isTaxDataChecked: Datos comprobados
|
||||||
|
amount: Importe
|
||||||
|
clientFk: Cliente
|
||||||
|
companyFk: Empresa
|
||||||
|
created: Creada
|
||||||
|
dued: Vencida
|
||||||
|
customsAgentFk: Agente aduanas
|
||||||
|
ref: Referencia
|
||||||
|
fi: CIF
|
||||||
|
min: Min
|
||||||
|
max: Max
|
||||||
|
hasPdf: Tiene PDF
|
||||||
card:
|
card:
|
||||||
issued: Fecha emisión
|
issued: Fecha emisión
|
||||||
customerCard: Ficha del cliente
|
customerCard: Ficha del cliente
|
||||||
|
|
|
@ -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`);
|
||||||
|
|
|
@ -280,7 +280,7 @@ const openTicketsDialog = (id) => {
|
||||||
</QCardSection>
|
</QCardSection>
|
||||||
<QCardSection class="q-pt-none">
|
<QCardSection class="q-pt-none">
|
||||||
<VnInputDate
|
<VnInputDate
|
||||||
:label="t('route.Stating date')"
|
:label="t('route.Starting date')"
|
||||||
v-model="startingDate"
|
v-model="startingDate"
|
||||||
autofocus
|
autofocus
|
||||||
/>
|
/>
|
||||||
|
@ -335,6 +335,7 @@ const openTicketsDialog = (id) => {
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="vn:clone"
|
icon="vn:clone"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
flat
|
||||||
class="q-mr-sm"
|
class="q-mr-sm"
|
||||||
:disable="!selectedRows?.length"
|
:disable="!selectedRows?.length"
|
||||||
@click="confirmationDialog = true"
|
@click="confirmationDialog = true"
|
||||||
|
@ -344,6 +345,7 @@ const openTicketsDialog = (id) => {
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="cloud_download"
|
icon="cloud_download"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
flat
|
||||||
class="q-mr-sm"
|
class="q-mr-sm"
|
||||||
:disable="!selectedRows?.length"
|
:disable="!selectedRows?.length"
|
||||||
@click="showRouteReport"
|
@click="showRouteReport"
|
||||||
|
@ -353,6 +355,7 @@ const openTicketsDialog = (id) => {
|
||||||
<QBtn
|
<QBtn
|
||||||
icon="check"
|
icon="check"
|
||||||
color="primary"
|
color="primary"
|
||||||
|
flat
|
||||||
class="q-mr-sm"
|
class="q-mr-sm"
|
||||||
:disable="!selectedRows?.length"
|
:disable="!selectedRows?.length"
|
||||||
@click="markAsServed()"
|
@click="markAsServed()"
|
||||||
|
|
|
@ -21,6 +21,10 @@ const $props = defineProps({
|
||||||
type: String,
|
type: String,
|
||||||
default: 'mana',
|
default: 'mana',
|
||||||
},
|
},
|
||||||
|
sale: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['save', 'cancel']);
|
const emit = defineEmits(['save', 'cancel']);
|
||||||
|
@ -29,8 +33,8 @@ const { t } = useI18n();
|
||||||
const QPopupProxyRef = ref(null);
|
const QPopupProxyRef = ref(null);
|
||||||
const manaCode = ref($props.manaCode);
|
const manaCode = ref($props.manaCode);
|
||||||
|
|
||||||
const save = () => {
|
const save = (sale = $props.sale) => {
|
||||||
emit('save');
|
emit('save', sale);
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,10 +42,11 @@ const cancel = () => {
|
||||||
emit('cancel');
|
emit('cancel');
|
||||||
QPopupProxyRef.value.hide();
|
QPopupProxyRef.value.hide();
|
||||||
};
|
};
|
||||||
|
defineExpose({ save });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPopupProxy ref="QPopupProxyRef">
|
<QPopupProxy ref="QPopupProxyRef" data-cy="ticketEditManaProxy">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<QSpinner v-if="!mana" color="primary" size="md" />
|
<QSpinner v-if="!mana" color="primary" size="md" />
|
||||||
<div v-else>
|
<div v-else>
|
||||||
|
|
|
@ -22,7 +22,6 @@ import { useVnConfirm } from 'composables/useVnConfirm';
|
||||||
import useNotify from 'src/composables/useNotify.js';
|
import useNotify from 'src/composables/useNotify.js';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VnTable from 'src/components/VnTable/VnTable.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import VnUsesMana from 'src/components/ui/VnUsesMana.vue';
|
|
||||||
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
import VnConfirm from 'src/components/ui/VnConfirm.vue';
|
||||||
import TicketProblems from 'src/components/TicketProblems.vue';
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
|
@ -33,6 +32,7 @@ const { t } = useI18n();
|
||||||
const { notify } = useNotify();
|
const { notify } = useNotify();
|
||||||
const { openConfirmationModal } = useVnConfirm();
|
const { openConfirmationModal } = useVnConfirm();
|
||||||
const editPriceProxyRef = ref(null);
|
const editPriceProxyRef = ref(null);
|
||||||
|
const editManaProxyRef = ref(null);
|
||||||
const stateBtnDropdownRef = ref(null);
|
const stateBtnDropdownRef = ref(null);
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
const arrayData = useArrayData('Ticket');
|
const arrayData = useArrayData('Ticket');
|
||||||
|
@ -53,7 +53,6 @@ const transfer = ref({
|
||||||
sales: [],
|
sales: [],
|
||||||
});
|
});
|
||||||
const tableRef = ref([]);
|
const tableRef = ref([]);
|
||||||
const canProceed = ref();
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => route.params.id,
|
() => route.params.id,
|
||||||
|
@ -133,7 +132,6 @@ const columns = computed(() => [
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('globals.amount'),
|
label: t('globals.amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
format: (row) => toCurrency(getSaleTotal(row)),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -183,8 +181,6 @@ const resetChanges = async () => {
|
||||||
};
|
};
|
||||||
const rowToUpdate = ref(null);
|
const rowToUpdate = ref(null);
|
||||||
const changeQuantity = async (sale) => {
|
const changeQuantity = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
if (
|
if (
|
||||||
!sale.itemFk ||
|
!sale.itemFk ||
|
||||||
sale.quantity == null ||
|
sale.quantity == null ||
|
||||||
|
@ -193,11 +189,21 @@ const changeQuantity = async (sale) => {
|
||||||
return;
|
return;
|
||||||
if (!sale.id) return addSale(sale);
|
if (!sale.id) return addSale(sale);
|
||||||
|
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateQuantity(sale));
|
||||||
|
} else await updateQuantity(sale);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateQuantity = async (sale) => {
|
||||||
try {
|
try {
|
||||||
|
let { quantity, id } = sale;
|
||||||
if (!rowToUpdate.value) return;
|
if (!rowToUpdate.value) return;
|
||||||
rowToUpdate.value = null;
|
rowToUpdate.value = null;
|
||||||
sale.isNew = false;
|
sale.isNew = false;
|
||||||
await updateQuantity(sale);
|
const params = { quantity: quantity };
|
||||||
|
await axios.post(`Sales/${id}/updateQuantity`, params);
|
||||||
|
notify('globals.dataSaved', 'positive');
|
||||||
|
tableRef.value.reload();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
const { quantity } = tableRef.value.CrudModelRef.originalData.find(
|
||||||
(s) => s.id === sale.id,
|
(s) => s.id === sale.id,
|
||||||
|
@ -207,12 +213,6 @@ const changeQuantity = async (sale) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateQuantity = async ({ quantity, id }) => {
|
|
||||||
const params = { quantity: quantity };
|
|
||||||
await axios.post(`Sales/${id}/updateQuantity`, params);
|
|
||||||
notify('globals.dataSaved', 'positive');
|
|
||||||
};
|
|
||||||
|
|
||||||
const addSale = async (sale) => {
|
const addSale = async (sale) => {
|
||||||
const params = {
|
const params = {
|
||||||
barcode: sale.itemFk,
|
barcode: sale.itemFk,
|
||||||
|
@ -237,13 +237,17 @@ const addSale = async (sale) => {
|
||||||
sale.isNew = false;
|
sale.isNew = false;
|
||||||
arrayData.fetch({});
|
arrayData.fetch({});
|
||||||
};
|
};
|
||||||
|
const changeConcept = async (sale) => {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateConcept(sale));
|
||||||
|
} else await updateConcept(sale);
|
||||||
|
};
|
||||||
|
|
||||||
const updateConcept = async (sale) => {
|
const updateConcept = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const data = { newConcept: sale.concept };
|
const data = { newConcept: sale.concept };
|
||||||
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
await axios.post(`Sales/${sale.id}/updateConcept`, data);
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
|
tableRef.value.reload();
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_EDIT = {
|
const DEFAULT_EDIT = {
|
||||||
|
@ -295,33 +299,43 @@ const onOpenEditDiscountPopover = async (sale) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const changePrice = async (sale) => {
|
||||||
const updatePrice = async (sale) => {
|
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const newPrice = edit.value.price;
|
const newPrice = edit.value.price;
|
||||||
if (newPrice != null && newPrice != sale.price) {
|
if (newPrice != null && newPrice != sale.price) {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updatePrice(sale, newPrice));
|
||||||
|
} else updatePrice(sale, newPrice);
|
||||||
|
}
|
||||||
|
await getMana();
|
||||||
|
};
|
||||||
|
const updatePrice = async (sale, newPrice) => {
|
||||||
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
await axios.post(`Sales/${sale.id}/updatePrice`, { newPrice });
|
||||||
sale.price = newPrice;
|
sale.price = newPrice;
|
||||||
edit.value = { ...DEFAULT_EDIT };
|
edit.value = { ...DEFAULT_EDIT };
|
||||||
notify('globals.dataSaved', 'positive');
|
notify('globals.dataSaved', 'positive');
|
||||||
}
|
tableRef.value.reload();
|
||||||
|
|
||||||
await getMana();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeDiscount = async (sale) => {
|
const changeDiscount = async (sale) => {
|
||||||
canProceed.value = await isSalePrepared(sale);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const newDiscount = edit.value.discount;
|
const newDiscount = edit.value.discount;
|
||||||
if (newDiscount != null && newDiscount != sale.discount) updateDiscount([sale]);
|
if (newDiscount != null && newDiscount != sale.discount) {
|
||||||
|
if (await isSalePrepared(sale))
|
||||||
|
await confirmUpdate(() => updateDiscount([sale], newDiscount));
|
||||||
|
else await updateDiscount([sale], newDiscount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateDiscounts = async (sales, newDiscount = null) => {
|
||||||
|
const salesTracking = await fetchSalesTracking();
|
||||||
|
|
||||||
|
const someSaleIsPrepared = salesTracking.some((sale) =>
|
||||||
|
matchSale(salesTracking, sale),
|
||||||
|
);
|
||||||
|
if (someSaleIsPrepared) await confirmUpdate(() => updateDiscount(sales, newDiscount));
|
||||||
|
else updateDiscount(sales, newDiscount);
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDiscount = async (sales, newDiscount = null) => {
|
const updateDiscount = async (sales, newDiscount = null) => {
|
||||||
for (const sale of sales) {
|
|
||||||
const canProceed = await isSalePrepared(sale);
|
|
||||||
if (!canProceed) return;
|
|
||||||
}
|
|
||||||
const saleIds = sales.map((sale) => sale.id);
|
const saleIds = sales.map((sale) => sale.id);
|
||||||
const _newDiscount = newDiscount || edit.value.discount;
|
const _newDiscount = newDiscount || edit.value.discount;
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -424,9 +438,13 @@ onMounted(async () => {
|
||||||
const items = ref([]);
|
const items = ref([]);
|
||||||
const newRow = ref({});
|
const newRow = ref({});
|
||||||
|
|
||||||
|
const changeItem = async (sale) => {
|
||||||
|
if (await isSalePrepared(sale)) {
|
||||||
|
await confirmUpdate(() => updateItem(sale));
|
||||||
|
} else await updateItem(sale);
|
||||||
|
};
|
||||||
|
|
||||||
const updateItem = async (row) => {
|
const updateItem = async (row) => {
|
||||||
canProceed.value = await isSalePrepared(row);
|
|
||||||
if (!canProceed.value) return;
|
|
||||||
const selectedItem = items.value.find((item) => item.id === row.itemFk);
|
const selectedItem = items.value.find((item) => item.id === row.itemFk);
|
||||||
if (selectedItem) {
|
if (selectedItem) {
|
||||||
row.item = selectedItem;
|
row.item = selectedItem;
|
||||||
|
@ -470,7 +488,18 @@ const endNewRow = (row) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async function isSalePrepared(item) {
|
async function confirmUpdate(cb) {
|
||||||
|
await quasar
|
||||||
|
.dialog({
|
||||||
|
component: VnConfirm,
|
||||||
|
componentProps: {
|
||||||
|
title: t('Item prepared'),
|
||||||
|
message: t('This item is already prepared. Do you want to continue?'),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.onOk(cb);
|
||||||
|
}
|
||||||
|
async function fetchSalesTracking() {
|
||||||
const filter = {
|
const filter = {
|
||||||
params: {
|
params: {
|
||||||
where: { ticketFk: route.params.id },
|
where: { ticketFk: route.params.id },
|
||||||
|
@ -482,48 +511,37 @@ async function isSalePrepared(item) {
|
||||||
filter: JSON.stringify(filter),
|
filter: JSON.stringify(filter),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
return data;
|
||||||
const matchingSale = data.find((sale) => sale.itemFk === item.itemFk);
|
|
||||||
if (!matchingSale) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
matchingSale.hasSaleGroupDetail ||
|
|
||||||
matchingSale.isControled ||
|
|
||||||
matchingSale.isPrepared ||
|
|
||||||
matchingSale.isPrevious ||
|
|
||||||
matchingSale.isPreviousSelected
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
quasar
|
|
||||||
.dialog({
|
|
||||||
component: VnConfirm,
|
|
||||||
componentProps: {
|
|
||||||
title: t('Item prepared'),
|
|
||||||
message: t(
|
|
||||||
'This item is already prepared. Do you want to continue?',
|
|
||||||
),
|
|
||||||
data: item,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.onOk(() => resolve(true))
|
|
||||||
.onCancel(() => reject(new Error('cancelled')));
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
tableRef.value.reload();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function isSalePrepared(sale) {
|
||||||
|
const data = await fetchSalesTracking();
|
||||||
|
return matchSale(data, sale);
|
||||||
|
}
|
||||||
|
function matchSale(data, sale) {
|
||||||
|
const matchingSale = data.find(({ itemFk }) => itemFk === sale.itemFk);
|
||||||
|
|
||||||
|
if (!matchingSale) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isPrepared(matchingSale);
|
||||||
|
}
|
||||||
|
function isPrepared(sale) {
|
||||||
|
const flagsToCheck = [
|
||||||
|
'hasSaleGroupDetail',
|
||||||
|
'isControled',
|
||||||
|
'isPrepared',
|
||||||
|
'isPrevious',
|
||||||
|
'isPreviousSelected',
|
||||||
|
];
|
||||||
|
return flagsToCheck.some((flag) => sale[flag] === 1);
|
||||||
|
}
|
||||||
watch(
|
watch(
|
||||||
() => newRow.value.itemFk,
|
() => newRow.value.itemFk,
|
||||||
(newItemFk) => {
|
(newItemFk) => {
|
||||||
if (newItemFk) {
|
if (newItemFk) {
|
||||||
updateItem(newRow.value);
|
changeItem(newRow.value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -584,7 +602,7 @@ watch(
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
:ticket-config="ticketConfig"
|
:ticket-config="ticketConfig"
|
||||||
@get-mana="getMana()"
|
@get-mana="getMana()"
|
||||||
@update-discounts="updateDiscount"
|
@update-discounts="updateDiscounts"
|
||||||
@refresh-table="resetChanges"
|
@refresh-table="resetChanges"
|
||||||
/>
|
/>
|
||||||
<QBtn
|
<QBtn
|
||||||
|
@ -715,7 +733,7 @@ watch(
|
||||||
option-value="id"
|
option-value="id"
|
||||||
v-model="row.itemFk"
|
v-model="row.itemFk"
|
||||||
:use-like="false"
|
:use-like="false"
|
||||||
@update:model-value="updateItem(row)"
|
@update:model-value="changeItem(row)"
|
||||||
>
|
>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
<QItem v-bind="scope.itemProps">
|
<QItem v-bind="scope.itemProps">
|
||||||
|
@ -741,16 +759,21 @@ watch(
|
||||||
</div>
|
</div>
|
||||||
<FetchedTags :item="row" :max-length="6" />
|
<FetchedTags :item="row" :max-length="6" />
|
||||||
<QPopupProxy v-if="row.id && isTicketEditable">
|
<QPopupProxy v-if="row.id && isTicketEditable">
|
||||||
<VnInput v-model="row.concept" @change="updateConcept(row)" />
|
<VnInput
|
||||||
|
v-model="row.concept"
|
||||||
|
@keyup.enter.stop="changeConcept(row)"
|
||||||
|
:hint="t('globals.enterToConfirm')"
|
||||||
|
/>
|
||||||
</QPopupProxy>
|
</QPopupProxy>
|
||||||
</template>
|
</template>
|
||||||
<template #column-quantity="{ row }">
|
<template #column-quantity="{ row }">
|
||||||
<VnInput
|
<VnInput
|
||||||
|
data-cy="ticketSaleQuantityInput"
|
||||||
v-if="row.isNew || isTicketEditable"
|
v-if="row.isNew || isTicketEditable"
|
||||||
type="number"
|
type="number"
|
||||||
v-model.number="row.quantity"
|
v-model.number="row.quantity"
|
||||||
@blur="changeQuantity(row)"
|
@blur="changeQuantity(row)"
|
||||||
@keyup.enter="changeQuantity(row)"
|
@keyup.enter.stop="changeQuantity(row)"
|
||||||
@update:model-value="() => (rowToUpdate = row)"
|
@update:model-value="() => (rowToUpdate = row)"
|
||||||
@focus="edit.oldQuantity = row.quantity"
|
@focus="edit.oldQuantity = row.quantity"
|
||||||
/>
|
/>
|
||||||
|
@ -764,10 +787,12 @@ watch(
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
ref="editPriceProxyRef"
|
ref="editPriceProxyRef"
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
@save="updatePrice(row)"
|
@save="changePrice"
|
||||||
>
|
>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@keyup.enter.stop="() => editManaProxyRef.save(row)"
|
||||||
v-model.number="edit.price"
|
v-model.number="edit.price"
|
||||||
:label="t('basicData.price')"
|
:label="t('basicData.price')"
|
||||||
type="number"
|
type="number"
|
||||||
|
@ -781,31 +806,30 @@ watch(
|
||||||
<QBtn flat class="link" dense @click="onOpenEditDiscountPopover(row)">
|
<QBtn flat class="link" dense @click="onOpenEditDiscountPopover(row)">
|
||||||
{{ toPercentage(row.discount / 100) }}
|
{{ toPercentage(row.discount / 100) }}
|
||||||
</QBtn>
|
</QBtn>
|
||||||
|
|
||||||
<TicketEditManaProxy
|
<TicketEditManaProxy
|
||||||
|
ref="editManaProxyRef"
|
||||||
:mana="mana"
|
:mana="mana"
|
||||||
|
:sale="row"
|
||||||
:new-price="getNewPrice"
|
:new-price="getNewPrice"
|
||||||
:uses-mana="usesMana"
|
:uses-mana="usesMana"
|
||||||
:mana-code="manaCode"
|
:mana-code="manaCode"
|
||||||
@save="changeDiscount(row)"
|
@save="changeDiscount"
|
||||||
>
|
>
|
||||||
<template #default="{ popup }">
|
|
||||||
<VnInput
|
<VnInput
|
||||||
autofocus
|
autofocus
|
||||||
@keyup.enter="
|
@keyup.enter.stop="() => editManaProxyRef.save(row)"
|
||||||
() => {
|
|
||||||
changeDiscount(row);
|
|
||||||
popup.hide();
|
|
||||||
}
|
|
||||||
"
|
|
||||||
v-model.number="edit.discount"
|
v-model.number="edit.discount"
|
||||||
:label="t('ticketSale.discount')"
|
:label="t('ticketSale.discount')"
|
||||||
type="number"
|
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(getSaleTotal(row)) }}
|
||||||
|
</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 }">
|
||||||
|
|
|
@ -209,7 +209,7 @@ const onThermographCreated = async (data) => {
|
||||||
}"
|
}"
|
||||||
sort-by="thermographFk ASC"
|
sort-by="thermographFk ASC"
|
||||||
option-label="thermographFk"
|
option-label="thermographFk"
|
||||||
option-filter-value="id"
|
option-filter-value="thermographFk"
|
||||||
:disable="viewAction === 'edit'"
|
:disable="viewAction === 'edit'"
|
||||||
:tooltip="t('New thermograph')"
|
:tooltip="t('New thermograph')"
|
||||||
:roles-allowed-to-create="['logistic']"
|
:roles-allowed-to-create="['logistic']"
|
||||||
|
|
|
@ -119,7 +119,7 @@ const columns = computed(() => [
|
||||||
:url="`Workers/${entityId}/trainingCourse`"
|
:url="`Workers/${entityId}/trainingCourse`"
|
||||||
:url-create="`Workers/${entityId}/trainingCourse`"
|
:url-create="`Workers/${entityId}/trainingCourse`"
|
||||||
save-url="TrainingCourses/crud"
|
save-url="TrainingCourses/crud"
|
||||||
:filter="courseFilter"
|
:user-filter="courseFilter"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'trainingCourses',
|
urlCreate: 'trainingCourses',
|
||||||
title: t('Create training course'),
|
title: t('Create training course'),
|
||||||
|
|
|
@ -8,6 +8,17 @@ const { t } = useI18n();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const entityId = computed(() => route.params.id);
|
const entityId = computed(() => route.params.id);
|
||||||
|
|
||||||
|
const centerFilter = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'center',
|
||||||
|
scope: {
|
||||||
|
fields: ['id', 'name'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -33,7 +44,7 @@ const columns = [
|
||||||
create: true,
|
create: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'medicalCenters',
|
url: 'centers',
|
||||||
fields: ['id', 'name'],
|
fields: ['id', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -84,6 +95,7 @@ const columns = [
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="WorkerMedical"
|
data-key="WorkerMedical"
|
||||||
:url="`Workers/${entityId}/medicalReview`"
|
:url="`Workers/${entityId}/medicalReview`"
|
||||||
|
:user-filter="centerFilter"
|
||||||
save-url="MedicalReviews/crud"
|
save-url="MedicalReviews/crud"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'medicalReviews',
|
urlCreate: 'medicalReviews',
|
||||||
|
|
|
@ -176,6 +176,7 @@ const deleteRelative = async (id) => {
|
||||||
:label="t('isDescendant')"
|
:label="t('isDescendant')"
|
||||||
v-model="row.isDescendant"
|
v-model="row.isDescendant"
|
||||||
class="q-gutter-xs q-mb-xs"
|
class="q-gutter-xs q-mb-xs"
|
||||||
|
data-cy="Descendant/Ascendant"
|
||||||
/>
|
/>
|
||||||
<VnSelect
|
<VnSelect
|
||||||
:label="t('disabilityGrades')"
|
:label="t('disabilityGrades')"
|
||||||
|
|
|
@ -25,7 +25,7 @@ const setFilteredAddresses = (data) => {
|
||||||
@on-fetch="(data) => (validAddresses = data)"
|
@on-fetch="(data) => (validAddresses = data)"
|
||||||
/>
|
/>
|
||||||
<FetchData url="Addresses" auto-load @on-fetch="setFilteredAddresses" />
|
<FetchData url="Addresses" auto-load @on-fetch="setFilteredAddresses" />
|
||||||
<FormModel auto-load model="zone">
|
<FormModel auto-load model="Zone">
|
||||||
<template #form="{ data, validate }">
|
<template #form="{ data, validate }">
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -33,6 +33,7 @@ const setFilteredAddresses = (data) => {
|
||||||
:label="t('Name')"
|
:label="t('Name')"
|
||||||
clearable
|
clearable
|
||||||
v-model="data.name"
|
v-model="data.name"
|
||||||
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -83,7 +84,7 @@ const setFilteredAddresses = (data) => {
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
/>
|
/>
|
||||||
<VnInputTime v-model="data.hour" :label="t('Closing')" />
|
<VnInputTime v-model="data.hour" :label="t('Closing')" :required="true" />
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
||||||
<VnRow>
|
<VnRow>
|
||||||
|
@ -92,7 +93,7 @@ const setFilteredAddresses = (data) => {
|
||||||
:label="t('Price')"
|
:label="t('Price')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
required="true"
|
:required="true"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
<VnInput
|
<VnInput
|
||||||
|
@ -100,7 +101,7 @@ const setFilteredAddresses = (data) => {
|
||||||
:label="t('Price optimum')"
|
:label="t('Price optimum')"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
required="true"
|
:required="true"
|
||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</VnRow>
|
</VnRow>
|
||||||
|
|
|
@ -38,7 +38,12 @@ const agencies = ref([]);
|
||||||
<template #body="{ params, searchFn }">
|
<template #body="{ params, searchFn }">
|
||||||
<QItem>
|
<QItem>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<VnInput :label="t('list.name')" v-model="params.name" is-outlined />
|
<VnInput
|
||||||
|
:label="t('list.name')"
|
||||||
|
v-model="params.name"
|
||||||
|
is-outlined
|
||||||
|
data-cy="zoneFilterPanelNameInput"
|
||||||
|
/>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
</QItem>
|
</QItem>
|
||||||
<QItem>
|
<QItem>
|
||||||
|
@ -53,6 +58,7 @@ const agencies = ref([]);
|
||||||
dense
|
dense
|
||||||
outlined
|
outlined
|
||||||
rounded
|
rounded
|
||||||
|
data-cy="zoneFilterPanelAgencySelect"
|
||||||
>
|
>
|
||||||
</VnSelect>
|
</VnSelect>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
|
|
|
@ -65,7 +65,6 @@ const tableFilter = {
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'id',
|
name: 'id',
|
||||||
label: t('list.id'),
|
label: t('list.id'),
|
||||||
chip: {
|
chip: {
|
||||||
|
@ -75,6 +74,8 @@ const columns = computed(() => [
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
|
columnClass: 'shrink-column',
|
||||||
|
component: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
@ -106,7 +107,6 @@ const columns = computed(() => [
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(row?.agencyMode?.name),
|
format: (row, dashIfEmpty) => dashIfEmpty(row?.agencyMode?.name),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
|
||||||
name: 'price',
|
name: 'price',
|
||||||
label: t('list.price'),
|
label: t('list.price'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -114,9 +114,11 @@ const columns = computed(() => [
|
||||||
columnFilter: {
|
columnFilter: {
|
||||||
inWhere: true,
|
inWhere: true,
|
||||||
},
|
},
|
||||||
|
columnClass: 'shrink-column',
|
||||||
|
component: 'number',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'center',
|
||||||
name: 'hour',
|
name: 'hour',
|
||||||
label: t('list.close'),
|
label: t('list.close'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
|
@ -129,6 +131,7 @@ const columns = computed(() => [
|
||||||
label: t('list.addressFk'),
|
label: t('list.addressFk'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
columnFilter: false,
|
columnFilter: false,
|
||||||
|
columnClass: 'expand',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'right',
|
align: 'right',
|
||||||
|
@ -177,6 +180,8 @@ function formatRow(row) {
|
||||||
<ZoneFilterPanel data-key="ZonesList" />
|
<ZoneFilterPanel data-key="ZonesList" />
|
||||||
</template>
|
</template>
|
||||||
</RightMenu>
|
</RightMenu>
|
||||||
|
<div class="table-container">
|
||||||
|
<div class="column items-center">
|
||||||
<VnTable
|
<VnTable
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
data-key="ZonesList"
|
data-key="ZonesList"
|
||||||
|
@ -191,6 +196,8 @@ function formatRow(row) {
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
redirect="zone"
|
redirect="zone"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
|
table-height="85vh"
|
||||||
|
order="id ASC"
|
||||||
>
|
>
|
||||||
<template #column-addressFk="{ row }">
|
<template #column-addressFk="{ row }">
|
||||||
{{ dashIfEmpty(formatRow(row)) }}
|
{{ dashIfEmpty(formatRow(row)) }}
|
||||||
|
@ -238,6 +245,8 @@ function formatRow(row) {
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
@ -245,3 +254,20 @@ es:
|
||||||
Search zone: Buscar zona
|
Search zone: Buscar zona
|
||||||
You can search zones by id or name: Puedes buscar zonas por id o nombre
|
You can search zones by id or name: Puedes buscar zonas por id o nombre
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.column {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.shrink-column) {
|
||||||
|
width: 8%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -56,7 +56,7 @@ onMounted(() => weekdayStore.initStore());
|
||||||
<ZoneSearchbar />
|
<ZoneSearchbar />
|
||||||
<VnSubToolbar />
|
<VnSubToolbar />
|
||||||
<QPage class="column items-center q-pa-md">
|
<QPage class="column items-center q-pa-md">
|
||||||
<QCard class="full-width q-pa-md">
|
<QCard class="containerShrinked q-pa-md">
|
||||||
<div
|
<div
|
||||||
v-for="(detail, index) in details"
|
v-for="(detail, index) in details"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|
|
@ -44,6 +44,8 @@ summary:
|
||||||
filterPanel:
|
filterPanel:
|
||||||
name: Name
|
name: Name
|
||||||
agencyModeFk: Agency
|
agencyModeFk: Agency
|
||||||
|
id: ID
|
||||||
|
price: Price
|
||||||
deliveryPanel:
|
deliveryPanel:
|
||||||
pickup: Pick up
|
pickup: Pick up
|
||||||
delivery: Delivery
|
delivery: Delivery
|
||||||
|
|
|
@ -45,6 +45,8 @@ summary:
|
||||||
filterPanel:
|
filterPanel:
|
||||||
name: Nombre
|
name: Nombre
|
||||||
agencyModeFk: Agencia
|
agencyModeFk: Agencia
|
||||||
|
id: ID
|
||||||
|
price: Precio
|
||||||
deliveryPanel:
|
deliveryPanel:
|
||||||
pickup: Recogida
|
pickup: Recogida
|
||||||
delivery: Entrega
|
delivery: Entrega
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
describe('Route extended list', () => {
|
||||||
|
const getSelector = (colField) => `tr:last-child > [data-col-field="${colField}"]`;
|
||||||
|
|
||||||
|
const selectors = {
|
||||||
|
worker: getSelector('workerFk'),
|
||||||
|
agency: getSelector('agencyModeFk'),
|
||||||
|
vehicle: getSelector('vehicleFk'),
|
||||||
|
date: getSelector('dated'),
|
||||||
|
description: getSelector('description'),
|
||||||
|
served: getSelector('isOk'),
|
||||||
|
lastRowSelectCheckBox: 'tbody > tr:last-child > :nth-child(1) .q-checkbox__inner',
|
||||||
|
removeBtn: '[title="Remove"]',
|
||||||
|
resetBtn: '[title="Reset"]',
|
||||||
|
confirmBtn: 'VnConfirm_confirm',
|
||||||
|
saveBtn: 'crudModelDefaultSaveBtn',
|
||||||
|
saveFormBtn: 'FormModelPopup_save',
|
||||||
|
cloneBtn: '#st-actions > .q-btn-group > :nth-child(1)',
|
||||||
|
downloadBtn: '#st-actions > .q-btn-group > :nth-child(2)',
|
||||||
|
markServedBtn: '#st-actions > .q-btn-group > :nth-child(3)',
|
||||||
|
searchbar: 'searchbar',
|
||||||
|
firstTicketsRowSelectCheckBox:
|
||||||
|
'.q-card > :nth-child(2) > .q-table__container > .q-table__middle > .q-table > tbody > :nth-child(1) > .q-table--col-auto-width > .q-checkbox > .q-checkbox__inner > .q-checkbox__bg > .q-checkbox__svg',
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkboxState = {
|
||||||
|
check: 'check',
|
||||||
|
uncheck: 'close',
|
||||||
|
};
|
||||||
|
const url = '/#/route/extended-list';
|
||||||
|
const dataCreated = 'Data created';
|
||||||
|
const dataSaved = 'Data saved';
|
||||||
|
|
||||||
|
const originalFields = [
|
||||||
|
{ selector: selectors.worker, type: 'select', value: 'logistic' },
|
||||||
|
{ selector: selectors.agency, type: 'select', value: 'Super-Man delivery' },
|
||||||
|
{ selector: selectors.vehicle, type: 'select', value: '3333-IMK' },
|
||||||
|
{ selector: selectors.date, type: 'date', value: '01/02/2024' },
|
||||||
|
{ selector: selectors.description, type: 'input', value: 'Test route' },
|
||||||
|
{ selector: selectors.served, type: 'checkbox', value: checkboxState.uncheck },
|
||||||
|
];
|
||||||
|
|
||||||
|
const updateFields = [
|
||||||
|
{ selector: selectors.worker, type: 'select', value: 'salesperson' },
|
||||||
|
{ selector: selectors.agency, type: 'select', value: 'inhouse pickup' },
|
||||||
|
{ selector: selectors.vehicle, type: 'select', value: '1111-IMK' },
|
||||||
|
{ selector: selectors.date, type: 'date', value: '01/01/2001' },
|
||||||
|
{ selector: selectors.description, type: 'input', value: 'Description updated' },
|
||||||
|
{ selector: selectors.served, type: 'checkbox', value: checkboxState.check },
|
||||||
|
];
|
||||||
|
|
||||||
|
function fillField(selector, type, value) {
|
||||||
|
switch (type) {
|
||||||
|
case 'select':
|
||||||
|
cy.get(selector).should('be.visible').click();
|
||||||
|
cy.dataCy('null_select').clear().type(value);
|
||||||
|
cy.get('.q-item').contains(value).click();
|
||||||
|
break;
|
||||||
|
case 'input':
|
||||||
|
cy.get(selector).should('be.visible').click();
|
||||||
|
cy.dataCy('null_input').clear().type(`${value}{enter}`);
|
||||||
|
break;
|
||||||
|
case 'date':
|
||||||
|
cy.get(selector).should('be.visible').click();
|
||||||
|
cy.dataCy('null_inputDate').clear().type(`${value}{enter}`);
|
||||||
|
break;
|
||||||
|
case 'checkbox':
|
||||||
|
cy.get(selector).should('be.visible').click().click();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(url);
|
||||||
|
cy.typeSearchbar('{enter}');
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => {
|
||||||
|
cy.visit(url);
|
||||||
|
cy.typeSearchbar('{enter}');
|
||||||
|
cy.get(selectors.lastRowSelectCheckBox).click();
|
||||||
|
|
||||||
|
cy.get(selectors.removeBtn).click();
|
||||||
|
cy.dataCy(selectors.confirmBtn).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should list routes', () => {
|
||||||
|
cy.get('.q-table')
|
||||||
|
.children()
|
||||||
|
.should('be.visible')
|
||||||
|
.should('have.length.greaterThan', 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should create new route', () => {
|
||||||
|
cy.addBtnClick();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
Worker: { val: 'logistic', type: 'select' },
|
||||||
|
Agency: { val: 'Super-Man delivery', type: 'select' },
|
||||||
|
Vehicle: { val: '3333-IMK', type: 'select' },
|
||||||
|
Date: { val: '02-01-2024', type: 'date' },
|
||||||
|
From: { val: '01-01-2024', type: 'date' },
|
||||||
|
To: { val: '10-01-2024', type: 'date' },
|
||||||
|
'Km start': { val: 1000 },
|
||||||
|
'Km end': { val: 1200 },
|
||||||
|
Description: { val: 'Test route' },
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.fillInForm(data);
|
||||||
|
|
||||||
|
cy.dataCy(selectors.saveFormBtn).click();
|
||||||
|
cy.checkNotification(dataCreated);
|
||||||
|
cy.url().should('include', '/summary');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should reset changed values when click reset button', () => {
|
||||||
|
updateFields.forEach(({ selector, type, value }) => {
|
||||||
|
fillField(selector, type, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('[title="Reset"]').click();
|
||||||
|
|
||||||
|
originalFields.forEach(({ selector, value }) => {
|
||||||
|
cy.validateContent(selector, value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should clone selected route', () => {
|
||||||
|
cy.get(selectors.lastRowSelectCheckBox).click();
|
||||||
|
cy.get(selectors.cloneBtn).click();
|
||||||
|
cy.dataCy('route.Starting date_inputDate').type('10-05-2001{enter}');
|
||||||
|
cy.get('.q-card__actions > .q-btn--standard > .q-btn__content').click();
|
||||||
|
cy.validateContent(selectors.date, '05/10/2001');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should download selected route', () => {
|
||||||
|
const downloadsFolder = Cypress.config('downloadsFolder');
|
||||||
|
cy.get(selectors.lastRowSelectCheckBox).click();
|
||||||
|
cy.get(selectors.downloadBtn).click();
|
||||||
|
cy.wait(5000);
|
||||||
|
|
||||||
|
const fileName = 'download.zip';
|
||||||
|
cy.readFile(`${downloadsFolder}/${fileName}`).should('exist');
|
||||||
|
|
||||||
|
cy.task('deleteFile', `${downloadsFolder}/${fileName}`).then((deleted) => {
|
||||||
|
expect(deleted).to.be.true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should mark as served the selected route', () => {
|
||||||
|
cy.get(selectors.lastRowSelectCheckBox).click();
|
||||||
|
cy.get(selectors.markServedBtn).click();
|
||||||
|
|
||||||
|
cy.typeSearchbar('{enter}');
|
||||||
|
cy.validateContent(selectors.served, checkboxState.check);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should delete the selected route', () => {
|
||||||
|
cy.get(selectors.lastRowSelectCheckBox).click();
|
||||||
|
|
||||||
|
cy.get(selectors.removeBtn).click();
|
||||||
|
cy.dataCy(selectors.confirmBtn).click();
|
||||||
|
|
||||||
|
cy.checkNotification(dataSaved);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should save changes in route', () => {
|
||||||
|
updateFields.forEach(({ selector, type, value }) => {
|
||||||
|
fillField(selector, type, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.dataCy(selectors.saveBtn).should('not.be.disabled').click();
|
||||||
|
cy.checkNotification(dataSaved);
|
||||||
|
|
||||||
|
cy.typeSearchbar('{enter}');
|
||||||
|
|
||||||
|
updateFields.forEach(({ selector, value }) => {
|
||||||
|
cy.validateContent(selector, value);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should add ticket to route', () => {
|
||||||
|
cy.dataCy('tableAction-0').last().click();
|
||||||
|
cy.get(selectors.firstTicketsRowSelectCheckBox).click();
|
||||||
|
cy.get('.q-card__actions > .q-btn--standard > .q-btn__content').click();
|
||||||
|
cy.checkNotification(dataSaved);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should open summary pop-up when click summuary icon', () => {
|
||||||
|
cy.dataCy('tableAction-1').last().click();
|
||||||
|
cy.get('.summaryHeader > :nth-child(2').should('contain', updateFields[4].value);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should redirect to the summary from the route summary pop-up', () => {
|
||||||
|
cy.dataCy('tableAction-1').last().click();
|
||||||
|
cy.get('.header > .q-icon').should('be.visible').click();
|
||||||
|
cy.url().should('include', '/summary');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should redirect to the summary when click go to summary icon', () => {
|
||||||
|
cy.dataCy('tableAction-2').last().click();
|
||||||
|
cy.url().should('include', '/summary');
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
/// <reference types="cypress" />
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
describe('TicketSale', () => {
|
describe('TicketSale', () => {
|
||||||
|
describe('Free ticket #31', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.viewport(1920, 1080);
|
cy.viewport(1920, 1080);
|
||||||
|
@ -119,4 +120,89 @@ describe('TicketSale', () => {
|
||||||
cy.get(firstRow).find('.q-btn:last').click();
|
cy.get(firstRow).find('.q-btn:last').click();
|
||||||
cy.url().should('match', /\/ticket\/31\/log/);
|
cy.url().should('match', /\/ticket\/31\/log/);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
describe('Ticket prepared #23', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.viewport(1920, 1080);
|
||||||
|
cy.visit('/#/ticket/23/sale');
|
||||||
|
});
|
||||||
|
|
||||||
|
const firstRow = 'tbody > :nth-child(1)';
|
||||||
|
|
||||||
|
const selectFirstRow = () => {
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(firstRow).find('.q-checkbox__inner').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
it('update price', () => {
|
||||||
|
const price = Number((Math.random() * 99 + 1).toFixed(2));
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(':nth-child(10) > .q-btn').click();
|
||||||
|
cy.waitForElement('[data-cy="ticketEditManaProxy"]');
|
||||||
|
cy.dataCy('ticketEditManaProxy').should('exist');
|
||||||
|
cy.waitForElement('[data-cy="Price_input"]');
|
||||||
|
cy.dataCy('Price_input').clear();
|
||||||
|
cy.dataCy('Price_input').type(price);
|
||||||
|
cy.dataCy('saveManaBtn').click();
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(10) > .q-btn > .q-btn__content').should(
|
||||||
|
'have.text',
|
||||||
|
`€${price}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('update dicount', () => {
|
||||||
|
const discount = Math.floor(Math.random() * 100) + 1;
|
||||||
|
selectFirstRow();
|
||||||
|
cy.get(':nth-child(11) > .q-btn').click();
|
||||||
|
cy.waitForElement('[data-cy="ticketEditManaProxy"]');
|
||||||
|
cy.dataCy('ticketEditManaProxy').should('exist');
|
||||||
|
cy.waitForElement('[data-cy="Disc_input"]');
|
||||||
|
cy.dataCy('Disc_input').clear();
|
||||||
|
cy.dataCy('Disc_input').type(discount);
|
||||||
|
cy.dataCy('saveManaBtn').click();
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(11) > .q-btn > .q-btn__content').should(
|
||||||
|
'have.text',
|
||||||
|
`${discount}.00%`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('change concept', () => {
|
||||||
|
const quantity = Math.floor(Math.random() * 100) + 1;
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.get(':nth-child(8) > .row').click();
|
||||||
|
cy.get(
|
||||||
|
'.q-menu > [data-v-ca3f07a4=""] > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > [data-cy="undefined_input"]',
|
||||||
|
)
|
||||||
|
.type(quantity)
|
||||||
|
.type('{enter}');
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get(':nth-child(8) >.row').should('contain.text', `${quantity}`);
|
||||||
|
});
|
||||||
|
it('changequantity ', () => {
|
||||||
|
const quantity = Math.floor(Math.random() * 100) + 1;
|
||||||
|
cy.waitForElement(firstRow);
|
||||||
|
cy.dataCy('ticketSaleQuantityInput').clear();
|
||||||
|
cy.dataCy('ticketSaleQuantityInput').type(quantity).trigger('tab');
|
||||||
|
cy.get('.q-page > :nth-child(6)').click();
|
||||||
|
|
||||||
|
handleVnConfirm();
|
||||||
|
|
||||||
|
cy.get('[data-cy="ticketSaleQuantityInput"]')
|
||||||
|
.find('[data-cy="undefined_input"]')
|
||||||
|
.should('have.value', `${quantity}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function handleVnConfirm() {
|
||||||
|
cy.get('[data-cy="VnConfirm_confirm"] > .q-btn__content > .block').click();
|
||||||
|
cy.waitForElement('.q-notification__message');
|
||||||
|
|
||||||
|
cy.get('.q-notification__message').should('be.visible');
|
||||||
|
cy.checkNotification('Data saved');
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ describe('WagonTypeCreate', () => {
|
||||||
|
|
||||||
it('should create a new wagon type and then delete it', () => {
|
it('should create a new wagon type and then delete it', () => {
|
||||||
cy.get('.q-page-sticky > div > .q-btn').click();
|
cy.get('.q-page-sticky > div > .q-btn').click();
|
||||||
cy.get('input').first().type('Example for testing');
|
cy.dataCy('Name_input').type('Example for testing');
|
||||||
cy.get('[data-cy="FormModelPopup_save"]').click();
|
cy.get('[data-cy="FormModelPopup_save"]').click();
|
||||||
cy.get('[title="Remove"] > .q-btn__content > .q-icon').first().click();
|
cy.get('[title="Remove"] > .q-btn__content > .q-icon').first().click();
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,9 +2,24 @@ describe('WorkerCreate', () => {
|
||||||
const externalRadio = '.q-radio:nth-child(2)';
|
const externalRadio = '.q-radio:nth-child(2)';
|
||||||
const developerBossId = 120;
|
const developerBossId = 120;
|
||||||
const payMethodCross =
|
const payMethodCross =
|
||||||
'.grid-create .full-width > :nth-child(9) .q-select .q-field__append:not(.q-anchor--skip)';
|
':nth-child(9) > .q-select > .q-field__inner > .q-field__control > :nth-child(2)';
|
||||||
const saveBtn = '.q-mt-lg > .q-btn--standard';
|
const saveBtn = '.q-mt-lg > .q-btn--standard';
|
||||||
|
|
||||||
|
const internalWithOutPay = {
|
||||||
|
Fi: { val: '78457139E' },
|
||||||
|
'Web user': { val: 'manolo' },
|
||||||
|
Name: { val: 'Manolo' },
|
||||||
|
'Last name': { val: 'Hurtado' },
|
||||||
|
'Personal email': { val: 'manolo@mydomain.com' },
|
||||||
|
Company: { val: 'VNL', type: 'select' },
|
||||||
|
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
||||||
|
Location: { val: 1, type: 'select' },
|
||||||
|
Phone: { val: '123456789' },
|
||||||
|
'Worker code': { val: 'DWW' },
|
||||||
|
Boss: { val: developerBossId, type: 'select' },
|
||||||
|
Birth: { val: '11-12-2022', type: 'date' },
|
||||||
|
};
|
||||||
|
|
||||||
const internal = {
|
const internal = {
|
||||||
Fi: { val: '78457139E' },
|
Fi: { val: '78457139E' },
|
||||||
'Web user': { val: 'manolo' },
|
'Web user': { val: 'manolo' },
|
||||||
|
@ -14,6 +29,7 @@ describe('WorkerCreate', () => {
|
||||||
Company: { val: 'VNL', type: 'select' },
|
Company: { val: 'VNL', type: 'select' },
|
||||||
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
Street: { val: 'S/ DEFAULTWORKERSTREET' },
|
||||||
Location: { val: 1, type: 'select' },
|
Location: { val: 1, type: 'select' },
|
||||||
|
'Pay method': { val: 1, type: 'select' },
|
||||||
Phone: { val: '123456789' },
|
Phone: { val: '123456789' },
|
||||||
'Worker code': { val: 'DWW' },
|
'Worker code': { val: 'DWW' },
|
||||||
Boss: { val: developerBossId, type: 'select' },
|
Boss: { val: developerBossId, type: 'select' },
|
||||||
|
@ -37,17 +53,14 @@ describe('WorkerCreate', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error if a pay method has not been selected', () => {
|
it('should throw an error if a pay method has not been selected', () => {
|
||||||
cy.fillInForm(internal);
|
cy.fillInForm(internalWithOutPay);
|
||||||
cy.get(payMethodCross).click();
|
cy.get(payMethodCross).click();
|
||||||
cy.get(saveBtn).click();
|
cy.get(saveBtn).click();
|
||||||
cy.checkNotification('Payment method is required');
|
cy.checkNotification('Payment method is required');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create an internal', () => {
|
it('should create an internal', () => {
|
||||||
cy.fillInForm({
|
cy.fillInForm(internal);
|
||||||
...internal,
|
|
||||||
'Pay method': { val: 'PayMethod one', type: 'select' },
|
|
||||||
});
|
|
||||||
cy.get(saveBtn).click();
|
cy.get(saveBtn).click();
|
||||||
cy.checkNotification('Data created');
|
cy.checkNotification('Data created');
|
||||||
});
|
});
|
||||||
|
|
|
@ -18,7 +18,7 @@ describe('WorkerNotificationsManager', () => {
|
||||||
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
||||||
cy.get(firstAvailableNotification).click();
|
cy.get(firstAvailableNotification).click();
|
||||||
cy.checkNotification(
|
cy.checkNotification(
|
||||||
'The notification subscription of this worker cant be modified'
|
'The notification subscription of this worker cant be modified',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ describe('WorkerPit', () => {
|
||||||
const spousePensionInput = '[data-cy="Spouse Pension_input"]';
|
const spousePensionInput = '[data-cy="Spouse Pension_input"]';
|
||||||
const spousePension = '120';
|
const spousePension = '120';
|
||||||
const addRelative = '[data-cy="addRelative"]';
|
const addRelative = '[data-cy="addRelative"]';
|
||||||
const isDescendantSelect = '[data-cy="Descendant/Ascendant_select"]';
|
const isDescendantSelect = '[data-cy="Descendant/Ascendant"]';
|
||||||
|
const Descendant = 'Descendiente';
|
||||||
const birthedInput = '[data-cy="Birth Year_input"]';
|
const birthedInput = '[data-cy="Birth Year_input"]';
|
||||||
const birthed = '2002';
|
const birthed = '2002';
|
||||||
const adoptionYearInput = '[data-cy="Adoption Year_input"]';
|
const adoptionYearInput = '[data-cy="Adoption Year_input"]';
|
||||||
|
@ -28,11 +29,8 @@ describe('WorkerPit', () => {
|
||||||
cy.get(spouseNifInput).type(spouseNif);
|
cy.get(spouseNifInput).type(spouseNif);
|
||||||
cy.get(spousePensionInput).type(spousePension);
|
cy.get(spousePensionInput).type(spousePension);
|
||||||
cy.get(savePIT).click();
|
cy.get(savePIT).click();
|
||||||
});
|
|
||||||
|
|
||||||
it('complete relative', () => {
|
|
||||||
cy.get(addRelative).click();
|
cy.get(addRelative).click();
|
||||||
cy.get(isDescendantSelect).type('{downArrow}{downArrow}{enter}');
|
cy.get(isDescendantSelect).type(Descendant);
|
||||||
cy.get(birthedInput).type(birthed);
|
cy.get(birthedInput).type(birthed);
|
||||||
cy.get(adoptionYearInput).type(adoptionYear);
|
cy.get(adoptionYearInput).type(adoptionYear);
|
||||||
cy.get(saveRelative).click();
|
cy.get(saveRelative).click();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
describe('ZoneList', () => {
|
describe('ZoneList', () => {
|
||||||
|
const agency = 'inhouse pickup';
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
|
@ -6,11 +7,15 @@ describe('ZoneList', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should filter by agency', () => {
|
it('should filter by agency', () => {
|
||||||
cy.get('input[aria-label="Agency"]').type('{downArrow}{enter}');
|
cy.dataCy('zoneFilterPanelNameInput').type('{downArrow}{enter}');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should open the zone summary', () => {
|
it('should open the zone summary', () => {
|
||||||
cy.get('input[aria-label="Name"]').type('zone refund');
|
cy.dataCy('zoneFilterPanelAgencySelect').type(agency);
|
||||||
cy.get('.q-scrollarea__content > .q-btn--standard > .q-btn__content').click();
|
cy.get('.q-menu .q-item').contains(agency).click();
|
||||||
|
cy.get(':nth-child(1) > [data-col-field="agencyModeFk"]').should(
|
||||||
|
'include.text',
|
||||||
|
agency,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue