Merge branch 'dev' into 8162-E2ETickets
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
81d7b9f04f
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "24.44.0",
|
"version": "24.50.0",
|
||||||
"description": "Salix frontend",
|
"description": "Salix frontend",
|
||||||
"productName": "Salix",
|
"productName": "Salix",
|
||||||
"author": "Verdnatura",
|
"author": "Verdnatura",
|
||||||
|
@ -64,4 +64,4 @@
|
||||||
"vite": "^5.1.4",
|
"vite": "^5.1.4",
|
||||||
"vitest": "^0.31.1"
|
"vitest": "^0.31.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,8 +9,6 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import FormModelPopup from './FormModelPopup.vue';
|
import FormModelPopup from './FormModelPopup.vue';
|
||||||
import { useState } from 'src/composables/useState';
|
import { useState } from 'src/composables/useState';
|
||||||
|
|
||||||
defineProps({ showEntityField: { type: Boolean, default: true } });
|
|
||||||
|
|
||||||
const emit = defineEmits(['onDataSaved']);
|
const emit = defineEmits(['onDataSaved']);
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const bicInputRef = ref(null);
|
const bicInputRef = ref(null);
|
||||||
|
@ -18,17 +16,16 @@ const state = useState();
|
||||||
|
|
||||||
const customer = computed(() => state.get('customer'));
|
const customer = computed(() => state.get('customer'));
|
||||||
|
|
||||||
|
const countriesFilter = {
|
||||||
|
fields: ['id', 'name', 'code'],
|
||||||
|
};
|
||||||
|
|
||||||
const bankEntityFormData = reactive({
|
const bankEntityFormData = reactive({
|
||||||
name: null,
|
name: null,
|
||||||
bic: null,
|
bic: null,
|
||||||
countryFk: customer.value?.countryFk,
|
countryFk: customer.value?.countryFk,
|
||||||
id: null,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const countriesFilter = {
|
|
||||||
fields: ['id', 'name', 'code'],
|
|
||||||
};
|
|
||||||
|
|
||||||
const countriesOptions = ref([]);
|
const countriesOptions = ref([]);
|
||||||
|
|
||||||
const onDataSaved = (...args) => {
|
const onDataSaved = (...args) => {
|
||||||
|
@ -44,7 +41,6 @@ onMounted(async () => {
|
||||||
<template>
|
<template>
|
||||||
<FetchData
|
<FetchData
|
||||||
url="Countries"
|
url="Countries"
|
||||||
:filter="countriesFilter"
|
|
||||||
auto-load
|
auto-load
|
||||||
@on-fetch="(data) => (countriesOptions = data)"
|
@on-fetch="(data) => (countriesOptions = data)"
|
||||||
/>
|
/>
|
||||||
|
@ -54,6 +50,7 @@ onMounted(async () => {
|
||||||
:title="t('title')"
|
:title="t('title')"
|
||||||
:subtitle="t('subtitle')"
|
:subtitle="t('subtitle')"
|
||||||
:form-initial-data="bankEntityFormData"
|
:form-initial-data="bankEntityFormData"
|
||||||
|
:filter="countriesFilter"
|
||||||
@on-data-saved="onDataSaved"
|
@on-data-saved="onDataSaved"
|
||||||
>
|
>
|
||||||
<template #form-inputs="{ data, validate }">
|
<template #form-inputs="{ data, validate }">
|
||||||
|
@ -85,7 +82,13 @@ onMounted(async () => {
|
||||||
:rules="validate('bankEntity.countryFk')"
|
:rules="validate('bankEntity.countryFk')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showEntityField" class="col">
|
<div
|
||||||
|
v-if="
|
||||||
|
countriesOptions.find((c) => c.id === data.countryFk)?.code ==
|
||||||
|
'ES'
|
||||||
|
"
|
||||||
|
class="col"
|
||||||
|
>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('id')"
|
:label="t('id')"
|
||||||
v-model="data.id"
|
v-model="data.id"
|
||||||
|
|
|
@ -1,155 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive, ref, computed } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
import FetchData from 'components/FetchData.vue';
|
|
||||||
import VnRow from 'components/ui/VnRow.vue';
|
|
||||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
|
||||||
import VnInput from 'src/components/common/VnInput.vue';
|
|
||||||
import FormModelPopup from './FormModelPopup.vue';
|
|
||||||
import VnInputDate from './common/VnInputDate.vue';
|
|
||||||
|
|
||||||
const emit = defineEmits(['onDataSaved']);
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const manualInvoiceFormData = reactive({
|
|
||||||
maxShipped: Date.vnNew(),
|
|
||||||
});
|
|
||||||
|
|
||||||
const formModelPopupRef = ref();
|
|
||||||
const invoiceOutSerialsOptions = ref([]);
|
|
||||||
const taxAreasOptions = ref([]);
|
|
||||||
const ticketsOptions = ref([]);
|
|
||||||
const clientsOptions = ref([]);
|
|
||||||
const isLoading = computed(() => formModelPopupRef.value?.isLoading);
|
|
||||||
|
|
||||||
const onDataSaved = async (formData, requestResponse) => {
|
|
||||||
emit('onDataSaved', formData, requestResponse);
|
|
||||||
if (requestResponse && requestResponse.id)
|
|
||||||
router.push({ name: 'InvoiceOutSummary', params: { id: requestResponse.id } });
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<FetchData
|
|
||||||
url="InvoiceOutSerials"
|
|
||||||
:filter="{ where: { code: { neq: 'R' } }, order: ['code'] }"
|
|
||||||
@on-fetch="(data) => (invoiceOutSerialsOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FetchData
|
|
||||||
url="TaxAreas"
|
|
||||||
:filter="{ order: ['code'] }"
|
|
||||||
@on-fetch="(data) => (taxAreasOptions = data)"
|
|
||||||
auto-load
|
|
||||||
/>
|
|
||||||
<FormModelPopup
|
|
||||||
ref="formModelPopupRef"
|
|
||||||
:title="t('Create manual invoice')"
|
|
||||||
url-create="InvoiceOuts/createManualInvoice"
|
|
||||||
model="invoiceOut"
|
|
||||||
:form-initial-data="manualInvoiceFormData"
|
|
||||||
@on-data-saved="onDataSaved"
|
|
||||||
>
|
|
||||||
<template #form-inputs="{ data }">
|
|
||||||
<span v-if="isLoading" class="text-primary invoicing-text">
|
|
||||||
<QIcon name="warning" class="fill-icon q-mr-sm" size="md" />
|
|
||||||
{{ t('Invoicing in progress...') }}
|
|
||||||
</span>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Ticket')"
|
|
||||||
:options="ticketsOptions"
|
|
||||||
hide-selected
|
|
||||||
option-label="id"
|
|
||||||
option-value="id"
|
|
||||||
v-model="data.ticketFk"
|
|
||||||
@update:model-value="data.clientFk = null"
|
|
||||||
url="Tickets"
|
|
||||||
:where="{ refFk: null }"
|
|
||||||
:fields="['id', 'nickname']"
|
|
||||||
:filter-options="{ order: 'shipped DESC' }"
|
|
||||||
>
|
|
||||||
<template #option="scope">
|
|
||||||
<QItem v-bind="scope.itemProps">
|
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
|
|
||||||
<QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
|
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
|
||||||
</template>
|
|
||||||
</VnSelect>
|
|
||||||
<span class="row items-center" style="max-width: max-content">{{
|
|
||||||
t('Or')
|
|
||||||
}}</span>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Client')"
|
|
||||||
:options="clientsOptions"
|
|
||||||
hide-selected
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
v-model="data.clientFk"
|
|
||||||
@update:model-value="data.ticketFk = null"
|
|
||||||
url="Clients"
|
|
||||||
:fields="['id', 'name']"
|
|
||||||
:filter-options="{ order: 'name ASC' }"
|
|
||||||
/>
|
|
||||||
<VnInputDate :label="t('Max date')" v-model="data.maxShipped" />
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Serial')"
|
|
||||||
:options="invoiceOutSerialsOptions"
|
|
||||||
hide-selected
|
|
||||||
option-label="description"
|
|
||||||
option-value="code"
|
|
||||||
v-model="data.serial"
|
|
||||||
/>
|
|
||||||
<VnSelect
|
|
||||||
:label="t('Area')"
|
|
||||||
:options="taxAreasOptions"
|
|
||||||
hide-selected
|
|
||||||
option-label="code"
|
|
||||||
option-value="code"
|
|
||||||
v-model="data.taxArea"
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
<VnRow>
|
|
||||||
<VnInput
|
|
||||||
:label="t('Reference')"
|
|
||||||
type="textarea"
|
|
||||||
v-model="data.reference"
|
|
||||||
fill-input
|
|
||||||
autogrow
|
|
||||||
/>
|
|
||||||
</VnRow>
|
|
||||||
</template>
|
|
||||||
</FormModelPopup>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.invoicing-text {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
color: $primary;
|
|
||||||
font-size: 24px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<i18n>
|
|
||||||
es:
|
|
||||||
Create manual invoice: Crear factura manual
|
|
||||||
Ticket: Ticket
|
|
||||||
Client: Cliente
|
|
||||||
Max date: Fecha límite
|
|
||||||
Serial: Serie
|
|
||||||
Area: Area
|
|
||||||
Reference: Referencia
|
|
||||||
Or: O
|
|
||||||
Invoicing in progress...: Facturación en progreso...
|
|
||||||
</i18n>
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<script setup>
|
||||||
|
defineProps({ row: { type: Object, required: true } });
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.isTaxDataChecked === 0"
|
||||||
|
name="vn:no036"
|
||||||
|
color="primary"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.hasTicketRequest" name="vn:buyrequest" color="primary" size="xs">
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.itemShortage" name="vn:unavailable" color="primary" size="xs">
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon
|
||||||
|
v-if="row.risk"
|
||||||
|
name="vn:risk"
|
||||||
|
:color="row.hasHighRisk ? 'negative' : 'primary'"
|
||||||
|
size="xs"
|
||||||
|
>
|
||||||
|
<QTooltip>
|
||||||
|
{{ $t('salesTicketsTable.risk') }}: {{ row.risk - row.credit }}
|
||||||
|
</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.hasComponentLack" name="vn:components" color="primary" size="xs">
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
<QIcon v-if="row.isTooLittle" name="vn:isTooLittle" color="primary" size="xs">
|
||||||
|
<QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
|
||||||
|
</QIcon>
|
||||||
|
</span>
|
||||||
|
</template>
|
|
@ -143,6 +143,10 @@ function alignRow() {
|
||||||
const showFilter = computed(
|
const showFilter = computed(
|
||||||
() => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
|
() => $props.column?.columnFilter !== false && $props.column.name != 'tableActions'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onTabPressed = async () => {
|
||||||
|
if (model.value) enterEvent['keyup.enter']();
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
|
@ -157,6 +161,7 @@ const showFilter = computed(
|
||||||
v-model="model"
|
v-model="model"
|
||||||
:components="components"
|
:components="components"
|
||||||
component-prop="columnFilter"
|
component-prop="columnFilter"
|
||||||
|
@keydown.tab="onTabPressed"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -162,9 +162,7 @@ onMounted(() => {
|
||||||
: $props.defaultMode;
|
: $props.defaultMode;
|
||||||
stateStore.rightDrawer = quasar.screen.gt.xs;
|
stateStore.rightDrawer = quasar.screen.gt.xs;
|
||||||
columnsVisibilitySkipped.value = [
|
columnsVisibilitySkipped.value = [
|
||||||
...splittedColumns.value.columns
|
...splittedColumns.value.columns.filter((c) => !c.visible).map((c) => c.name),
|
||||||
.filter((c) => c.visible == false)
|
|
||||||
.map((c) => c.name),
|
|
||||||
...['tableActions'],
|
...['tableActions'],
|
||||||
];
|
];
|
||||||
createForm.value = $props.create;
|
createForm.value = $props.create;
|
||||||
|
@ -237,7 +235,7 @@ function splitColumns(columns) {
|
||||||
if (col.create) splittedColumns.value.create.push(col);
|
if (col.create) splittedColumns.value.create.push(col);
|
||||||
if (col.cardVisible) splittedColumns.value.cardVisible.push(col);
|
if (col.cardVisible) splittedColumns.value.cardVisible.push(col);
|
||||||
if ($props.isEditable && col.disable == null) col.disable = false;
|
if ($props.isEditable && col.disable == null) col.disable = false;
|
||||||
if ($props.useModel && col.columnFilter != false)
|
if ($props.useModel && col.columnFilter !== false)
|
||||||
col.columnFilter = { inWhere: true, ...col.columnFilter };
|
col.columnFilter = { inWhere: true, ...col.columnFilter };
|
||||||
splittedColumns.value.columns.push(col);
|
splittedColumns.value.columns.push(col);
|
||||||
}
|
}
|
||||||
|
@ -326,6 +324,8 @@ function handleOnDataSaved(_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleScroll() {
|
function handleScroll() {
|
||||||
|
if ($props.crudModel.disableInfiniteScroll) return;
|
||||||
|
|
||||||
const tMiddle = tableRef.value.$el.querySelector('.q-table__middle');
|
const tMiddle = tableRef.value.$el.querySelector('.q-table__middle');
|
||||||
const { scrollHeight, scrollTop, clientHeight } = tMiddle;
|
const { scrollHeight, scrollTop, clientHeight } = tMiddle;
|
||||||
const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) <= 40;
|
const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) <= 40;
|
||||||
|
@ -394,7 +394,7 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
|
||||||
:name="col.orderBy ?? col.name"
|
:name="col.orderBy ?? col.name"
|
||||||
:data-key="$attrs['data-key']"
|
:data-key="$attrs['data-key']"
|
||||||
:search-url="searchUrl"
|
:search-url="searchUrl"
|
||||||
:vertical="true"
|
:vertical="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<slot
|
<slot
|
||||||
|
|
|
@ -101,7 +101,13 @@ const mixinRules = [
|
||||||
<QIcon
|
<QIcon
|
||||||
name="close"
|
name="close"
|
||||||
size="xs"
|
size="xs"
|
||||||
v-if="hover && value && !$attrs.disabled && $props.clearable"
|
v-if="
|
||||||
|
hover &&
|
||||||
|
value &&
|
||||||
|
!$attrs.disabled &&
|
||||||
|
!$attrs.readonly &&
|
||||||
|
$props.clearable
|
||||||
|
"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
value = null;
|
value = null;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, watch, computed, ref } from 'vue';
|
import { onMounted, watch, computed, ref, useAttrs } from 'vue';
|
||||||
import { date } from 'quasar';
|
import { date } from 'quasar';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useAttrs } from 'vue';
|
|
||||||
import VnDate from './VnDate.vue';
|
import VnDate from './VnDate.vue';
|
||||||
import { useRequired } from 'src/composables/useRequired';
|
import { useRequired } from 'src/composables/useRequired';
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,12 @@
|
||||||
const model = defineModel({ type: Boolean, required: true });
|
const model = defineModel({ type: Boolean, required: true });
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<QRadio v-model="model" v-bind="$attrs" dense :dark="true" class="q-mr-sm" />
|
<QRadio
|
||||||
|
v-model="model"
|
||||||
|
v-bind="$attrs"
|
||||||
|
dense
|
||||||
|
:dark="true"
|
||||||
|
class="q-mr-sm"
|
||||||
|
size="xs"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -138,8 +138,6 @@ onMounted(() => {
|
||||||
if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
|
if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
defineExpose({ opts: myOptions });
|
|
||||||
|
|
||||||
const arrayDataKey =
|
const arrayDataKey =
|
||||||
$props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
|
$props.dataKey ?? ($props.url?.length > 0 ? $props.url : $attrs.name ?? $attrs.label);
|
||||||
|
|
||||||
|
@ -202,7 +200,10 @@ async function fetchFilter(val) {
|
||||||
if (fields) fetchOptions.fields = fields;
|
if (fields) fetchOptions.fields = fields;
|
||||||
if (sortBy) fetchOptions.order = sortBy;
|
if (sortBy) fetchOptions.order = sortBy;
|
||||||
arrayData.reset(['skip', 'filter.skip', 'page']);
|
arrayData.reset(['skip', 'filter.skip', 'page']);
|
||||||
return (await arrayData.applyFilter({ filter: fetchOptions }))?.data;
|
|
||||||
|
const { data } = await arrayData.applyFilter({ filter: fetchOptions });
|
||||||
|
setOptions(data);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function filterHandler(val, update) {
|
async function filterHandler(val, update) {
|
||||||
|
@ -256,6 +257,30 @@ async function onScroll({ to, direction, from, index }) {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defineExpose({ opts: myOptions });
|
||||||
|
|
||||||
|
function handleKeyDown(event) {
|
||||||
|
if (event.key === 'Tab') {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const inputValue = vnSelectRef.value?.inputValue;
|
||||||
|
|
||||||
|
if (inputValue) {
|
||||||
|
const matchingOption = myOptions.value.find(
|
||||||
|
(option) =>
|
||||||
|
option[optionLabel.value].toLowerCase() === inputValue.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (matchingOption) {
|
||||||
|
emit('update:modelValue', matchingOption[optionValue.value]);
|
||||||
|
} else {
|
||||||
|
emit('update:modelValue', inputValue);
|
||||||
|
}
|
||||||
|
vnSelectRef.value?.hidePopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -266,6 +291,7 @@ async function onScroll({ to, direction, from, index }) {
|
||||||
:option-value="optionValue"
|
:option-value="optionValue"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
@filter="filterHandler"
|
@filter="filterHandler"
|
||||||
|
@keydown="handleKeyDown"
|
||||||
:emit-value="nullishToTrue($attrs['emit-value'])"
|
:emit-value="nullishToTrue($attrs['emit-value'])"
|
||||||
:map-options="nullishToTrue($attrs['map-options'])"
|
:map-options="nullishToTrue($attrs['map-options'])"
|
||||||
:use-input="nullishToTrue($attrs['use-input'])"
|
:use-input="nullishToTrue($attrs['use-input'])"
|
||||||
|
|
|
@ -37,7 +37,7 @@ const $props = defineProps({
|
||||||
},
|
},
|
||||||
hiddenTags: {
|
hiddenTags: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => ['filter', 'search', 'or', 'and'],
|
default: () => ['filter', 'or', 'and'],
|
||||||
},
|
},
|
||||||
customTags: {
|
customTags: {
|
||||||
type: Array,
|
type: Array,
|
||||||
|
@ -61,7 +61,6 @@ const emit = defineEmits([
|
||||||
'update:modelValue',
|
'update:modelValue',
|
||||||
'refresh',
|
'refresh',
|
||||||
'clear',
|
'clear',
|
||||||
'search',
|
|
||||||
'init',
|
'init',
|
||||||
'remove',
|
'remove',
|
||||||
'setUserParams',
|
'setUserParams',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="vn-row q-gutter-md q-mb-md">
|
<div class="vn-row q-gutter-md">
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -18,6 +18,9 @@
|
||||||
&:not(.wrap) {
|
&:not(.wrap) {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
&[fixed] {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -75,18 +75,10 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
limit: store.limit,
|
limit: store.limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
let exprFilter;
|
|
||||||
let userParams = { ...store.userParams };
|
let userParams = { ...store.userParams };
|
||||||
if (store?.exprBuilder) {
|
|
||||||
const where = buildFilter(userParams, (param, value) => {
|
|
||||||
const res = store.exprBuilder(param, value);
|
|
||||||
if (res) delete userParams[param];
|
|
||||||
return res;
|
|
||||||
});
|
|
||||||
exprFilter = where ? { where } : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign(filter, store.userFilter, exprFilter);
|
Object.assign(filter, store.userFilter);
|
||||||
|
|
||||||
let where;
|
let where;
|
||||||
if (filter?.where || store.filter?.where)
|
if (filter?.where || store.filter?.where)
|
||||||
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
where = Object.assign(filter?.where ?? {}, store.filter?.where ?? {});
|
||||||
|
@ -96,11 +88,28 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
||||||
|
|
||||||
Object.assign(params, userParams);
|
Object.assign(params, userParams);
|
||||||
params.filter.skip = store.skip;
|
params.filter.skip = store.skip;
|
||||||
if (store.order && store.order.length) params.filter.order = store.order;
|
if (store?.order && typeof store?.order == 'string') store.order = [store.order];
|
||||||
|
if (store.order?.length) params.filter.order = [...store.order];
|
||||||
else delete params.filter.order;
|
else delete params.filter.order;
|
||||||
|
|
||||||
|
store.currentFilter = JSON.parse(JSON.stringify(params));
|
||||||
|
delete store.currentFilter.filter.include;
|
||||||
|
store.currentFilter.filter = JSON.stringify(store.currentFilter.filter);
|
||||||
|
|
||||||
|
let exprFilter;
|
||||||
|
if (store?.exprBuilder) {
|
||||||
|
exprFilter = buildFilter(params, (param, value) => {
|
||||||
|
if (param == 'filter') return;
|
||||||
|
const res = store.exprBuilder(param, value);
|
||||||
|
if (res) delete params[param];
|
||||||
|
return res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.filter.where || exprFilter)
|
||||||
|
params.filter.where = { ...params.filter.where, ...exprFilter };
|
||||||
params.filter = JSON.stringify(params.filter);
|
params.filter = JSON.stringify(params.filter);
|
||||||
store.currentFilter = params;
|
|
||||||
store.isLoading = true;
|
store.isLoading = true;
|
||||||
const response = await axios.get(store.url, {
|
const response = await axios.get(store.url, {
|
||||||
signal: canceller.signal,
|
signal: canceller.signal,
|
||||||
|
|
|
@ -241,7 +241,7 @@ input::-webkit-inner-spin-button {
|
||||||
th,
|
th,
|
||||||
td {
|
td {
|
||||||
padding: 1px 10px 1px 10px;
|
padding: 1px 10px 1px 10px;
|
||||||
max-width: 100px;
|
max-width: 130px;
|
||||||
div span {
|
div span {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
|
@ -506,6 +506,7 @@ invoiceOut:
|
||||||
invoiceWithFutureDate: Exists an invoice with a future date
|
invoiceWithFutureDate: Exists an invoice with a future date
|
||||||
noTicketsToInvoice: There are not tickets to invoice
|
noTicketsToInvoice: There are not tickets to invoice
|
||||||
criticalInvoiceError: 'Critical invoicing error, process stopped'
|
criticalInvoiceError: 'Critical invoicing error, process stopped'
|
||||||
|
invalidSerialTypeForAll: The serial type must be global when invoicing all clients
|
||||||
table:
|
table:
|
||||||
addressId: Address id
|
addressId: Address id
|
||||||
streetAddress: Street
|
streetAddress: Street
|
||||||
|
@ -583,15 +584,15 @@ worker:
|
||||||
role: Role
|
role: Role
|
||||||
sipExtension: Extension
|
sipExtension: Extension
|
||||||
locker: Locker
|
locker: Locker
|
||||||
fiDueDate: Fecha de caducidad del DNI
|
fiDueDate: FI due date
|
||||||
sex: Sexo
|
sex: Sex
|
||||||
seniority: Antigüedad
|
seniority: Seniority
|
||||||
fi: DNI/NIE/NIF
|
fi: DNI/NIE/NIF
|
||||||
birth: Fecha de nacimiento
|
birth: Birth
|
||||||
isFreelance: Autónomo
|
isFreelance: Freelance
|
||||||
isSsDiscounted: Bonificación SS
|
isSsDiscounted: Bonificación SS
|
||||||
hasMachineryAuthorized: Autorizado para llevar maquinaria
|
hasMachineryAuthorized: Machinery authorized
|
||||||
isDisable: Trabajador desactivado
|
isDisable: Disable
|
||||||
notificationsManager:
|
notificationsManager:
|
||||||
activeNotifications: Active notifications
|
activeNotifications: Active notifications
|
||||||
availableNotifications: Available notifications
|
availableNotifications: Available notifications
|
||||||
|
@ -707,7 +708,7 @@ supplier:
|
||||||
supplierName: Supplier name
|
supplierName: Supplier name
|
||||||
basicData:
|
basicData:
|
||||||
workerFk: Responsible
|
workerFk: Responsible
|
||||||
isSerious: Verified
|
isReal: Verified
|
||||||
isActive: Active
|
isActive: Active
|
||||||
isPayMethodChecked: PayMethod checked
|
isPayMethodChecked: PayMethod checked
|
||||||
note: Notes
|
note: Notes
|
||||||
|
@ -857,6 +858,7 @@ components:
|
||||||
downloadFile: Download file
|
downloadFile: Download file
|
||||||
openCard: View
|
openCard: View
|
||||||
openSummary: Summary
|
openSummary: Summary
|
||||||
|
viewSummary: Summary
|
||||||
cardDescriptor:
|
cardDescriptor:
|
||||||
mainList: Main list
|
mainList: Main list
|
||||||
summary: Summary
|
summary: Summary
|
||||||
|
|
|
@ -509,6 +509,7 @@ invoiceOut:
|
||||||
invoiceWithFutureDate: Existe una factura con una fecha futura
|
invoiceWithFutureDate: Existe una factura con una fecha futura
|
||||||
noTicketsToInvoice: No existen tickets para facturar
|
noTicketsToInvoice: No existen tickets para facturar
|
||||||
criticalInvoiceError: Error crítico en la facturación proceso detenido
|
criticalInvoiceError: Error crítico en la facturación proceso detenido
|
||||||
|
invalidSerialTypeForAll: El tipo de serie debe ser global cuando se facturan todos los clientes
|
||||||
table:
|
table:
|
||||||
addressId: Id dirección
|
addressId: Id dirección
|
||||||
streetAddress: Dirección fiscal
|
streetAddress: Dirección fiscal
|
||||||
|
@ -579,9 +580,9 @@ worker:
|
||||||
newWorker: Nuevo trabajador
|
newWorker: Nuevo trabajador
|
||||||
summary:
|
summary:
|
||||||
boss: Jefe
|
boss: Jefe
|
||||||
phoneExtension: Extensión de teléfono
|
phoneExtension: Ext. de teléfono
|
||||||
entPhone: Teléfono de empresa
|
entPhone: Tel. de empresa
|
||||||
personalPhone: Teléfono personal
|
personalPhone: Tel. personal
|
||||||
noBoss: Sin jefe
|
noBoss: Sin jefe
|
||||||
userData: Datos de usuario
|
userData: Datos de usuario
|
||||||
userId: ID del usuario
|
userId: ID del usuario
|
||||||
|
@ -702,7 +703,7 @@ supplier:
|
||||||
supplierName: Nombre del proveedor
|
supplierName: Nombre del proveedor
|
||||||
basicData:
|
basicData:
|
||||||
workerFk: Responsable
|
workerFk: Responsable
|
||||||
isSerious: Verificado
|
isReal: Verificado
|
||||||
isActive: Activo
|
isActive: Activo
|
||||||
isPayMethodChecked: Método de pago validado
|
isPayMethodChecked: Método de pago validado
|
||||||
note: Notas
|
note: Notas
|
||||||
|
|
|
@ -130,7 +130,7 @@ function cancel() {
|
||||||
<template #body-cell-description="{ row, value }">
|
<template #body-cell-description="{ row, value }">
|
||||||
<QTd auto-width align="right" class="link">
|
<QTd auto-width align="right" class="link">
|
||||||
{{ value }}
|
{{ value }}
|
||||||
<ItemDescriptorProxy :id="row.itemFk"></ItemDescriptorProxy>
|
<ItemDescriptorProxy :id="row.itemFk" />
|
||||||
</QTd>
|
</QTd>
|
||||||
</template>
|
</template>
|
||||||
</QTable>
|
</QTable>
|
||||||
|
|
|
@ -25,7 +25,7 @@ const claimFilter = computed(() => {
|
||||||
include: {
|
include: {
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'nickname'],
|
fields: ['id', 'nickname', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -256,10 +256,10 @@ const showBalancePdf = ({ id }) => {
|
||||||
{{ toCurrency(balances[rowIndex]?.balance) }}
|
{{ toCurrency(balances[rowIndex]?.balance) }}
|
||||||
</template>
|
</template>
|
||||||
<template #column-description="{ row }">
|
<template #column-description="{ row }">
|
||||||
<div class="link" v-if="row.isInvoice">
|
<span class="link" v-if="row.isInvoice" @click.stop>
|
||||||
{{ t('bill', { ref: row.description }) }}
|
{{ t('bill', { ref: row.description }) }}
|
||||||
<InvoiceOutDescriptorProxy :id="row.description" />
|
<InvoiceOutDescriptorProxy :id="row.id" />
|
||||||
</div>
|
</span>
|
||||||
<span v-else class="q-pa-xs dotted rounded-borders" :title="row.description">
|
<span v-else class="q-pa-xs dotted rounded-borders" :title="row.description">
|
||||||
{{ row.description }}
|
{{ row.description }}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -320,7 +320,7 @@ const sumRisk = ({ clientRisks }) => {
|
||||||
:value="entity.recommendedCredit"
|
:value="entity.recommendedCredit"
|
||||||
/>
|
/>
|
||||||
</QCard>
|
</QCard>
|
||||||
<QCard class="vn-one">
|
<QCard class="vn-max">
|
||||||
<VnTitle :text="t('Latest tickets')" />
|
<VnTitle :text="t('Latest tickets')" />
|
||||||
<CustomerSummaryTable />
|
<CustomerSummaryTable />
|
||||||
</QCard>
|
</QCard>
|
||||||
|
|
|
@ -12,6 +12,7 @@ import VnImg from 'src/components/ui/VnImg.vue';
|
||||||
|
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const tableRef = ref();
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
|
@ -234,7 +235,6 @@ const columns = [
|
||||||
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)),
|
format: (row, dashIfEmpty) => dashIfEmpty(toDate(row.landing)),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const tableRef = ref();
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
stateStore.rightDrawer = true;
|
stateStore.rightDrawer = true;
|
||||||
|
|
|
@ -183,7 +183,7 @@ onMounted(async () => {
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
invoiceDate: Invoice date
|
invoiceDate: Invoice date
|
||||||
maxShipped: Max date
|
maxShipped: Max date ticket
|
||||||
allClients: All clients
|
allClients: All clients
|
||||||
oneClient: One client
|
oneClient: One client
|
||||||
company: Company
|
company: Company
|
||||||
|
@ -195,7 +195,7 @@ en:
|
||||||
|
|
||||||
es:
|
es:
|
||||||
invoiceDate: Fecha de factura
|
invoiceDate: Fecha de factura
|
||||||
maxShipped: Fecha límite
|
maxShipped: Fecha límite ticket
|
||||||
allClients: Todos los clientes
|
allClients: Todos los clientes
|
||||||
oneClient: Un solo cliente
|
oneClient: Un solo cliente
|
||||||
company: Empresa
|
company: Empresa
|
||||||
|
|
|
@ -6,15 +6,19 @@ import VnInputDate from 'src/components/common/VnInputDate.vue';
|
||||||
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
import VnSearchbar from 'src/components/ui/VnSearchbar.vue';
|
||||||
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
import VnSubToolbar from 'src/components/ui/VnSubToolbar.vue';
|
||||||
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
import { useSummaryDialog } from 'src/composables/useSummaryDialog';
|
||||||
import { usePrintService } from 'composables/usePrintService';
|
import { usePrintService } from 'src/composables/usePrintService';
|
||||||
import VnTable from 'components/VnTable/VnTable.vue';
|
import VnTable from 'src/components/VnTable/VnTable.vue';
|
||||||
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
|
import InvoiceOutSummary from './Card/InvoiceOutSummary.vue';
|
||||||
import { toCurrency, toDate } from 'src/filters/index';
|
import { toCurrency, toDate } from 'src/filters/index';
|
||||||
import { useStateStore } from 'stores/useStateStore';
|
import { useStateStore } from 'stores/useStateStore';
|
||||||
import { QBtn } from 'quasar';
|
import { QBtn } from 'quasar';
|
||||||
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
import axios from 'axios';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
import InvoiceOutFilter from './InvoiceOutFilter.vue';
|
||||||
|
import VnRow from 'src/components/ui/VnRow.vue';
|
||||||
|
import VnRadio from 'src/components/common/VnRadio.vue';
|
||||||
|
import VnInput from 'src/components/common/VnInput.vue';
|
||||||
|
import CustomerDescriptorProxy from '../Customer/Card/CustomerDescriptorProxy.vue';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const stateStore = useStateStore();
|
const stateStore = useStateStore();
|
||||||
|
@ -26,99 +30,86 @@ const selectedRows = ref([]);
|
||||||
const hasSelectedCards = computed(() => selectedRows.value.length > 0);
|
const hasSelectedCards = computed(() => selectedRows.value.length > 0);
|
||||||
const MODEL = 'InvoiceOuts';
|
const MODEL = 'InvoiceOuts';
|
||||||
const { openReport } = usePrintService();
|
const { openReport } = usePrintService();
|
||||||
|
const addressOptions = ref([]);
|
||||||
|
const selectedOption = ref('ticket');
|
||||||
|
async function fetchClientAddress(id) {
|
||||||
|
const { data } = await axios.get(
|
||||||
|
`Clients/${id}/addresses?filter[order]=isActive DESC`
|
||||||
|
);
|
||||||
|
addressOptions.value = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const exprBuilder = (_, value) => {
|
||||||
|
return {
|
||||||
|
or: [{ code: value }, { description: { like: `%${value}%` } }],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
align: 'center',
|
align: 'center',
|
||||||
name: 'id',
|
name: 'id',
|
||||||
label: t('invoiceOutList.tableVisibleColumns.id'),
|
label: t('invoiceOutList.tableVisibleColumns.id'),
|
||||||
chip: {
|
chip: { condition: () => true },
|
||||||
condition: () => true,
|
|
||||||
},
|
|
||||||
isId: true,
|
isId: true,
|
||||||
columnFilter: {
|
columnFilter: { name: 'search' },
|
||||||
name: 'search',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'ref',
|
name: 'ref',
|
||||||
label: t('invoiceOutList.tableVisibleColumns.ref'),
|
label: t('globals.reference'),
|
||||||
isTitle: true,
|
isTitle: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: { url: MODEL, optionLabel: 'ref', optionValue: 'id' },
|
||||||
url: MODEL,
|
columnField: { component: null },
|
||||||
optionLabel: 'ref',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'Issued',
|
name: 'issued',
|
||||||
label: t('invoiceOutList.tableVisibleColumns.issued'),
|
label: t('invoiceOut.summary.issued'),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
format: (row) => toDate(row.issued),
|
format: (row) => toDate(row.issued),
|
||||||
columnField: {
|
columnField: { component: null },
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'clientFk',
|
name: 'clientFk',
|
||||||
label: t('invoiceOutModule.customer'),
|
label: t('globals.client'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: { url: 'Clients', fields: ['id', 'name'] },
|
||||||
url: 'Clients',
|
columnField: { component: null },
|
||||||
fields: ['id', 'name'],
|
|
||||||
},
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'companyCode',
|
name: 'companyCode',
|
||||||
label: t('invoiceOutModule.company'),
|
label: t('globals.company'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: { url: 'Companies', optionLabel: 'code', optionValue: 'id' },
|
||||||
url: 'Companies',
|
columnField: { component: null },
|
||||||
optionLabel: 'code',
|
|
||||||
optionValue: 'id',
|
|
||||||
},
|
|
||||||
columnField: {
|
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
label: t('invoiceOutModule.amount'),
|
label: t('globals.amount'),
|
||||||
cardVisible: true,
|
cardVisible: true,
|
||||||
format: (row) => toCurrency(row.amount),
|
format: (row) => toCurrency(row.amount),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'created',
|
name: 'created',
|
||||||
label: t('invoiceOutList.tableVisibleColumns.created'),
|
label: t('globals.created'),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
columnField: {
|
columnField: { component: null },
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row) => toDate(row.created),
|
format: (row) => toDate(row.created),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
name: 'dued',
|
name: 'dued',
|
||||||
label: t('invoiceOutList.tableVisibleColumns.dueDate'),
|
label: t('invoiceOut.summary.dued'),
|
||||||
component: 'date',
|
component: 'date',
|
||||||
columnField: {
|
columnField: { component: null },
|
||||||
component: null,
|
|
||||||
},
|
|
||||||
format: (row) => toDate(row.dued),
|
format: (row) => toDate(row.dued),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -128,11 +119,12 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
title: t('components.smartCard.viewSummary'),
|
title: t('components.smartCard.viewSummary'),
|
||||||
icon: 'preview',
|
icon: 'preview',
|
||||||
|
isPrimary: true,
|
||||||
action: (row) => viewSummary(row.id, InvoiceOutSummary),
|
action: (row) => viewSummary(row.id, InvoiceOutSummary),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: t('DownloadPdf'),
|
title: t('globals.downloadPdf'),
|
||||||
icon: 'vn:ticket',
|
icon: 'cloud_download',
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
action: (row) => openPdf(row.id),
|
action: (row) => openPdf(row.id),
|
||||||
},
|
},
|
||||||
|
@ -181,7 +173,7 @@ watchEffect(selectedRows);
|
||||||
<template>
|
<template>
|
||||||
<VnSearchbar
|
<VnSearchbar
|
||||||
:info="t('youCanSearchByInvoiceReference')"
|
:info="t('youCanSearchByInvoiceReference')"
|
||||||
:label="t('searchInvoice')"
|
:label="t('Search invoice')"
|
||||||
data-key="invoiceOutList"
|
data-key="invoiceOutList"
|
||||||
/>
|
/>
|
||||||
<RightMenu>
|
<RightMenu>
|
||||||
|
@ -197,7 +189,7 @@ watchEffect(selectedRows);
|
||||||
@click="downloadPdf()"
|
@click="downloadPdf()"
|
||||||
:disable="!hasSelectedCards"
|
:disable="!hasSelectedCards"
|
||||||
>
|
>
|
||||||
<QTooltip>{{ t('globals.downloadPdf') }}</QTooltip>
|
<QTooltip>{{ t('downloadPdf') }}</QTooltip>
|
||||||
</QBtn>
|
</QBtn>
|
||||||
</template>
|
</template>
|
||||||
</VnSubToolbar>
|
</VnSubToolbar>
|
||||||
|
@ -207,11 +199,9 @@ watchEffect(selectedRows);
|
||||||
:url="`${MODEL}/filter`"
|
:url="`${MODEL}/filter`"
|
||||||
:create="{
|
:create="{
|
||||||
urlCreate: 'InvoiceOuts/createManualInvoice',
|
urlCreate: 'InvoiceOuts/createManualInvoice',
|
||||||
title: t('Create manual invoice'),
|
title: t('createManualInvoice'),
|
||||||
onDataSaved: ({ id }) => tableRef.redirect(id),
|
onDataSaved: ({ id }) => tableRef.redirect(id),
|
||||||
formInitialData: {
|
formInitialData: { active: true },
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
}"
|
}"
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
v-model:selected="selectedRows"
|
v-model:selected="selectedRows"
|
||||||
|
@ -231,74 +221,199 @@ watchEffect(selectedRows);
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
<template #more-create-dialog="{ data }">
|
<template #more-create-dialog="{ data }">
|
||||||
<div class="flex no-wrap flex-center">
|
<div class="row q-col-gutter-xs">
|
||||||
<VnSelect
|
<div class="col-12">
|
||||||
url="Tickets"
|
<div class="q-col-gutter-xs">
|
||||||
v-model="data.ticketFk"
|
<VnRow fixed>
|
||||||
:label="t('invoiceOutList.tableVisibleColumns.ticket')"
|
<VnRadio
|
||||||
option-label="id"
|
v-model="selectedOption"
|
||||||
option-value="id"
|
val="ticket"
|
||||||
>
|
:label="t('globals.ticket')"
|
||||||
<template #option="scope">
|
class="q-my-none q-mr-md"
|
||||||
<QItem v-bind="scope.itemProps">
|
/>
|
||||||
<QItemSection>
|
|
||||||
<QItemLabel> #{{ scope.opt?.id }} </QItemLabel>
|
<VnInput
|
||||||
<QItemLabel caption>{{ scope.opt?.nickname }}</QItemLabel>
|
v-show="selectedOption === 'ticket'"
|
||||||
</QItemSection>
|
v-model="data.ticketFk"
|
||||||
</QItem>
|
:label="t('globals.ticket')"
|
||||||
</template>
|
style="flex: 1"
|
||||||
</VnSelect>
|
/>
|
||||||
<span class="q-ml-md">O</span>
|
|
||||||
|
<div
|
||||||
|
class="row q-col-gutter-xs q-ml-none"
|
||||||
|
v-show="selectedOption !== 'ticket'"
|
||||||
|
>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelect
|
||||||
|
v-model="data.clientFk"
|
||||||
|
:label="t('globals.client')"
|
||||||
|
url="Clients"
|
||||||
|
:options="customerOptions"
|
||||||
|
option-label="name"
|
||||||
|
option-value="id"
|
||||||
|
@update:model-value="fetchClientAddress"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
#{{ scope.opt?.id }} -
|
||||||
|
{{ scope.opt?.name }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<VnSelect
|
||||||
|
v-model="data.addressFk"
|
||||||
|
:label="t('ticket.summary.consignee')"
|
||||||
|
:options="addressOptions"
|
||||||
|
option-label="nickname"
|
||||||
|
option-value="id"
|
||||||
|
v-if="
|
||||||
|
data.clientFk &&
|
||||||
|
selectedOption === 'consignatario'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel
|
||||||
|
:class="{
|
||||||
|
'color-vn-label':
|
||||||
|
!scope.opt?.isActive,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
`${
|
||||||
|
!scope.opt?.isActive
|
||||||
|
? t('inactive')
|
||||||
|
: ''
|
||||||
|
} `
|
||||||
|
}}
|
||||||
|
<span>{{
|
||||||
|
scope.opt?.nickname
|
||||||
|
}}</span>
|
||||||
|
<span
|
||||||
|
v-if="
|
||||||
|
scope.opt?.province ||
|
||||||
|
scope.opt?.city ||
|
||||||
|
scope.opt?.street
|
||||||
|
"
|
||||||
|
>
|
||||||
|
, {{ scope.opt?.street }},
|
||||||
|
{{ scope.opt?.city }},
|
||||||
|
{{
|
||||||
|
scope.opt?.province?.name
|
||||||
|
}}
|
||||||
|
-
|
||||||
|
{{
|
||||||
|
scope.opt?.agencyMode
|
||||||
|
?.name
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow fixed>
|
||||||
|
<VnRadio
|
||||||
|
v-model="selectedOption"
|
||||||
|
val="cliente"
|
||||||
|
:label="t('globals.client')"
|
||||||
|
class="q-my-none q-mr-md"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow fixed>
|
||||||
|
<VnRadio
|
||||||
|
v-model="selectedOption"
|
||||||
|
val="consignatario"
|
||||||
|
:label="t('ticket.summary.consignee')"
|
||||||
|
class="q-my-none q-mr-md"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="full-width">
|
||||||
|
<VnRow class="row q-col-gutter-xs">
|
||||||
|
<VnSelect
|
||||||
|
url="InvoiceOutSerials"
|
||||||
|
v-model="data.serial"
|
||||||
|
:label="t('invoiceIn.serial')"
|
||||||
|
:options="invoiceOutSerialsOptions"
|
||||||
|
option-label="description"
|
||||||
|
option-value="code"
|
||||||
|
option-filter
|
||||||
|
:expr-builder="exprBuilder"
|
||||||
|
>
|
||||||
|
<template #option="scope">
|
||||||
|
<QItem v-bind="scope.itemProps">
|
||||||
|
<QItemSection>
|
||||||
|
<QItemLabel>
|
||||||
|
{{ scope.opt?.code }} -
|
||||||
|
{{ scope.opt?.description }}
|
||||||
|
</QItemLabel>
|
||||||
|
</QItemSection>
|
||||||
|
</QItem>
|
||||||
|
</template>
|
||||||
|
</VnSelect>
|
||||||
|
<VnInputDate
|
||||||
|
:label="t('invoiceOut.summary.dued')"
|
||||||
|
v-model="data.maxShipped"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
<VnRow class="row q-col-gutter-xs">
|
||||||
|
<VnSelect
|
||||||
|
url="TaxAreas"
|
||||||
|
v-model="data.taxArea"
|
||||||
|
:label="t('invoiceOutList.tableVisibleColumns.taxArea')"
|
||||||
|
:options="taxAreasOptions"
|
||||||
|
option-label="code"
|
||||||
|
option-value="code"
|
||||||
|
/>
|
||||||
|
<VnInput
|
||||||
|
v-model="data.reference"
|
||||||
|
:label="t('globals.reference')"
|
||||||
|
/>
|
||||||
|
</VnRow>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<VnSelect
|
|
||||||
url="Clients"
|
|
||||||
v-model="data.clientFk"
|
|
||||||
:label="t('invoiceOutModule.customer')"
|
|
||||||
:options="customerOptions"
|
|
||||||
option-label="name"
|
|
||||||
option-value="id"
|
|
||||||
/>
|
|
||||||
<VnSelect
|
|
||||||
url="InvoiceOutSerials"
|
|
||||||
v-model="data.serial"
|
|
||||||
:label="t('invoiceOutList.tableVisibleColumns.invoiceOutSerial')"
|
|
||||||
:options="invoiceOutSerialsOptions"
|
|
||||||
option-label="description"
|
|
||||||
option-value="code"
|
|
||||||
/>
|
|
||||||
<VnInputDate
|
|
||||||
:label="t('invoiceOutList.tableVisibleColumns.dueDate')"
|
|
||||||
v-model="data.maxShipped"
|
|
||||||
/>
|
|
||||||
<VnSelect
|
|
||||||
url="TaxAreas"
|
|
||||||
v-model="data.taxArea"
|
|
||||||
:label="t('invoiceOutList.tableVisibleColumns.taxArea')"
|
|
||||||
:options="taxAreasOptions"
|
|
||||||
option-label="code"
|
|
||||||
option-value="code"
|
|
||||||
/>
|
|
||||||
<QInput
|
|
||||||
v-model="data.reference"
|
|
||||||
:label="t('invoiceOutList.tableVisibleColumns.ref')"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
</VnTable>
|
</VnTable>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#formModel .vn-row {
|
||||||
|
min-height: 45px;
|
||||||
|
|
||||||
|
.q-radio {
|
||||||
|
align-self: flex-end;
|
||||||
|
flex: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .q-input,
|
||||||
|
> .q-select {
|
||||||
|
flex: 0.75;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
en:
|
en:
|
||||||
searchInvoice: Search issued invoice
|
invoiceId: Invoice ID
|
||||||
fileDenied: Browser denied file download...
|
youCanSearchByInvoiceReference: You can search by invoice reference
|
||||||
fileAllowed: Successful download of CSV file
|
createManualInvoice: Create Manual Invoice
|
||||||
youCanSearchByInvoiceReference: You can search by invoice reference
|
inactive: (Inactive)
|
||||||
createInvoice: Make invoice
|
|
||||||
Create manual invoice: Create manual invoice
|
es:
|
||||||
es:
|
invoiceId: ID de factura
|
||||||
searchInvoice: Buscar factura emitida
|
youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
|
||||||
fileDenied: El navegador denegó la descarga de archivos...
|
createManualInvoice: Crear factura manual
|
||||||
fileAllowed: Descarga exitosa de archivo CSV
|
inactive: (Inactivo)
|
||||||
youCanSearchByInvoiceReference: Puedes buscar por referencia de la factura
|
|
||||||
createInvoice: Crear factura
|
|
||||||
Create manual invoice: Crear factura manual
|
|
||||||
</i18n>
|
</i18n>
|
||||||
|
|
|
@ -2,6 +2,7 @@ invoiceOutModule:
|
||||||
customer: Client
|
customer: Client
|
||||||
amount: Amount
|
amount: Amount
|
||||||
company: Company
|
company: Company
|
||||||
|
address: Address
|
||||||
invoiceOutList:
|
invoiceOutList:
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
id: ID
|
id: ID
|
||||||
|
@ -15,11 +16,11 @@ invoiceOutList:
|
||||||
DownloadPdf: Download PDF
|
DownloadPdf: Download PDF
|
||||||
InvoiceOutSummary: Summary
|
InvoiceOutSummary: Summary
|
||||||
negativeBases:
|
negativeBases:
|
||||||
country: Country
|
country: Country
|
||||||
clientId: Client ID
|
clientId: Client ID
|
||||||
base: Base
|
base: Base
|
||||||
ticketId: Ticket
|
ticketId: Ticket
|
||||||
active: Active
|
active: Active
|
||||||
hasToInvoice: Has to invoice
|
hasToInvoice: Has to invoice
|
||||||
verifiedData: Verified data
|
verifiedData: Verified data
|
||||||
commercial: Commercial
|
commercial: Commercial
|
||||||
|
|
|
@ -4,6 +4,7 @@ invoiceOutModule:
|
||||||
customer: Cliente
|
customer: Cliente
|
||||||
amount: Importe
|
amount: Importe
|
||||||
company: Empresa
|
company: Empresa
|
||||||
|
address: Consignatario
|
||||||
invoiceOutList:
|
invoiceOutList:
|
||||||
tableVisibleColumns:
|
tableVisibleColumns:
|
||||||
id: ID
|
id: ID
|
||||||
|
|
|
@ -440,7 +440,7 @@ function handleOnDataSave({ CrudModelRef }) {
|
||||||
selection: 'multiple',
|
selection: 'multiple',
|
||||||
}"
|
}"
|
||||||
:crud-model="{
|
:crud-model="{
|
||||||
paginate: false,
|
disableInfiniteScroll: true,
|
||||||
}"
|
}"
|
||||||
v-model:selected="rowsSelected"
|
v-model:selected="rowsSelected"
|
||||||
:row-click="saveOnRowChange"
|
:row-click="saveOnRowChange"
|
||||||
|
|
|
@ -27,7 +27,7 @@ function exprBuilder(param, value) {
|
||||||
|
|
||||||
const columns = computed(() => [
|
const columns = computed(() => [
|
||||||
{
|
{
|
||||||
label: t('salesOrdersTable.dateSend'),
|
label: t('globals.landed'),
|
||||||
name: 'dateSend',
|
name: 'dateSend',
|
||||||
field: 'dateSend',
|
field: 'dateSend',
|
||||||
align: 'left',
|
align: 'left',
|
||||||
|
|
|
@ -15,6 +15,7 @@ import { toCurrency, dateRange, dashIfEmpty } from 'src/filters';
|
||||||
import RightMenu from 'src/components/common/RightMenu.vue';
|
import RightMenu from 'src/components/common/RightMenu.vue';
|
||||||
import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
|
import MonitorTicketSearchbar from './MonitorTicketSearchbar.vue';
|
||||||
import MonitorTicketFilter from './MonitorTicketFilter.vue';
|
import MonitorTicketFilter from './MonitorTicketFilter.vue';
|
||||||
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
|
||||||
const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms
|
const DEFAULT_AUTO_REFRESH = 2 * 60 * 1000; // 2min in ms
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
@ -23,13 +24,18 @@ const tableRef = ref(null);
|
||||||
const provinceOpts = ref([]);
|
const provinceOpts = ref([]);
|
||||||
const stateOpts = ref([]);
|
const stateOpts = ref([]);
|
||||||
const zoneOpts = ref([]);
|
const zoneOpts = ref([]);
|
||||||
const visibleColumns = ref([]);
|
|
||||||
const { viewSummary } = useSummaryDialog();
|
const { viewSummary } = useSummaryDialog();
|
||||||
const from = Date.vnNew();
|
const from = Date.vnNew();
|
||||||
from.setHours(0, 0, 0, 0);
|
from.setHours(0, 0, 0, 0);
|
||||||
const to = new Date(from.getTime());
|
const to = new Date(from.getTime());
|
||||||
to.setDate(to.getDate() + 1);
|
to.setDate(to.getDate() + 1);
|
||||||
to.setHours(23, 59, 59, 999);
|
to.setHours(23, 59, 59, 999);
|
||||||
|
const stateColors = {
|
||||||
|
notice: 'info',
|
||||||
|
success: 'positive',
|
||||||
|
warning: 'warning',
|
||||||
|
alert: 'negative',
|
||||||
|
};
|
||||||
|
|
||||||
function exprBuilder(param, value) {
|
function exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
|
@ -224,7 +230,7 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
title: t('salesTicketsTable.goToLines'),
|
title: t('salesTicketsTable.goToLines'),
|
||||||
icon: 'vn:lines',
|
icon: 'vn:lines',
|
||||||
color: 'priamry',
|
color: 'primary',
|
||||||
action: (row) => openTab(row.id),
|
action: (row) => openTab(row.id),
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
attrs: {
|
attrs: {
|
||||||
|
@ -235,7 +241,7 @@ const columns = computed(() => [
|
||||||
{
|
{
|
||||||
title: t('salesTicketsTable.preview'),
|
title: t('salesTicketsTable.preview'),
|
||||||
icon: 'preview',
|
icon: 'preview',
|
||||||
color: 'priamry',
|
color: 'primary',
|
||||||
action: (row) => viewSummary(row.id, TicketSummary),
|
action: (row) => viewSummary(row.id, TicketSummary),
|
||||||
isPrimary: true,
|
isPrimary: true,
|
||||||
attrs: {
|
attrs: {
|
||||||
|
@ -253,10 +259,10 @@ const getBadgeAttrs = (date) => {
|
||||||
let timeTicket = new Date(date);
|
let timeTicket = new Date(date);
|
||||||
timeTicket.setHours(0, 0, 0, 0);
|
timeTicket.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
let comparation = today - timeTicket;
|
let timeDiff = today - timeTicket;
|
||||||
|
|
||||||
if (comparation == 0) return { color: 'warning', 'text-color': 'black' };
|
if (timeDiff == 0) return { color: 'warning', 'text-color': 'black' };
|
||||||
if (comparation < 0) return { color: 'success', 'text-color': 'black' };
|
if (timeDiff < 0) return { color: 'success', 'text-color': 'black' };
|
||||||
return { color: 'transparent', 'text-color': 'white' };
|
return { color: 'transparent', 'text-color': 'white' };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,13 +277,6 @@ const autoRefreshHandler = (value) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stateColors = {
|
|
||||||
notice: 'info',
|
|
||||||
success: 'positive',
|
|
||||||
warning: 'warning',
|
|
||||||
alert: 'negative',
|
|
||||||
};
|
|
||||||
|
|
||||||
const totalPriceColor = (ticket) => {
|
const totalPriceColor = (ticket) => {
|
||||||
const total = parseInt(ticket.totalWithVat);
|
const total = parseInt(ticket.totalWithVat);
|
||||||
if (total > 0 && total < 50) return 'warning';
|
if (total > 0 && total < 50) return 'warning';
|
||||||
|
@ -285,10 +284,10 @@ const totalPriceColor = (ticket) => {
|
||||||
|
|
||||||
const formatShippedDate = (date) => {
|
const formatShippedDate = (date) => {
|
||||||
if (!date) return '-';
|
if (!date) return '-';
|
||||||
const split1 = date.split('T');
|
const dateSplit = date.split('T');
|
||||||
const [year, month, day] = split1[0].split('-');
|
const [year, month, day] = dateSplit[0].split('-');
|
||||||
const _date = new Date(year, month - 1, day);
|
const newDate = new Date(year, month - 1, day);
|
||||||
return toDateFormat(_date);
|
return toDateFormat(newDate);
|
||||||
};
|
};
|
||||||
|
|
||||||
const openTab = (id) =>
|
const openTab = (id) =>
|
||||||
|
@ -336,7 +335,6 @@ const openTab = (id) =>
|
||||||
:expr-builder="exprBuilder"
|
:expr-builder="exprBuilder"
|
||||||
:offset="50"
|
:offset="50"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:visible-columns="visibleColumns"
|
|
||||||
:right-search="false"
|
:right-search="false"
|
||||||
default-mode="table"
|
default-mode="table"
|
||||||
auto-load
|
auto-load
|
||||||
|
@ -366,61 +364,7 @@ const openTab = (id) =>
|
||||||
</QCheckbox>
|
</QCheckbox>
|
||||||
</template>
|
</template>
|
||||||
<template #column-totalProblems="{ row }">
|
<template #column-totalProblems="{ row }">
|
||||||
<span>
|
<TicketProblems :row="row" />
|
||||||
<QIcon
|
|
||||||
v-if="row.isTaxDataChecked === 0"
|
|
||||||
name="vn:no036"
|
|
||||||
color="primary"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.noVerifiedData') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasTicketRequest"
|
|
||||||
name="vn:buyrequest"
|
|
||||||
color="primary"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.purchaseRequest') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.itemShortage"
|
|
||||||
name="vn:unavailable"
|
|
||||||
color="primary"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.notVisible') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon v-if="row.isFreezed" name="vn:frozen" color="primary" size="xs">
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.clientFrozen') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.risk"
|
|
||||||
name="vn:risk"
|
|
||||||
:color="row.hasHighRisk ? 'negative' : 'primary'"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip
|
|
||||||
>{{ $t('salesTicketsTable.risk') }}: {{ row.risk }}</QTooltip
|
|
||||||
>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasComponentLack"
|
|
||||||
name="vn:components"
|
|
||||||
color="primary"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.componentLack') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.isTooLittle"
|
|
||||||
name="vn:isTooLittle"
|
|
||||||
color="primary"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>{{ $t('salesTicketsTable.tooLittle') }}</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
<template #column-id="{ row }">
|
<template #column-id="{ row }">
|
||||||
<span class="link" @click.stop.prevent>
|
<span class="link" @click.stop.prevent>
|
||||||
|
@ -475,7 +419,7 @@ const openTab = (id) =>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
</template>
|
</template>
|
||||||
<template #column-zoneFk="{ row }">
|
<template #column-zoneFk="{ row }">
|
||||||
<div @click.stop.prevent :title="row.zoneName">
|
<div v-if="row.zoneFk" @click.stop.prevent :title="row.zoneName">
|
||||||
<span class="link">{{ row.zoneName }}</span>
|
<span class="link">{{ row.zoneName }}</span>
|
||||||
<ZoneDescriptorProxy :id="row.zoneFk" />
|
<ZoneDescriptorProxy :id="row.zoneFk" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -11,7 +11,6 @@ salesClientsTable:
|
||||||
client: Client
|
client: Client
|
||||||
salesOrdersTable:
|
salesOrdersTable:
|
||||||
delete: Delete
|
delete: Delete
|
||||||
dateSend: Send date
|
|
||||||
dateMake: Make date
|
dateMake: Make date
|
||||||
deleteConfirmMessage: All the selected elements will be deleted. Are you sure you want to continue?
|
deleteConfirmMessage: All the selected elements will be deleted. Are you sure you want to continue?
|
||||||
agency: Agency
|
agency: Agency
|
||||||
|
|
|
@ -11,7 +11,6 @@ salesClientsTable:
|
||||||
client: Cliente
|
client: Cliente
|
||||||
salesOrdersTable:
|
salesOrdersTable:
|
||||||
delete: Eliminar
|
delete: Eliminar
|
||||||
dateSend: Fecha de envío
|
|
||||||
dateMake: Fecha de realización
|
dateMake: Fecha de realización
|
||||||
deleteConfirmMessage: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
deleteConfirmMessage: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?
|
||||||
agency: Agencia
|
agency: Agencia
|
||||||
|
|
|
@ -166,6 +166,7 @@ onMounted(() => {
|
||||||
:expr-builder="exprBuilder"
|
:expr-builder="exprBuilder"
|
||||||
:custom-tags="['tagGroups', 'categoryFk']"
|
:custom-tags="['tagGroups', 'categoryFk']"
|
||||||
:redirect="false"
|
:redirect="false"
|
||||||
|
search-url="params"
|
||||||
>
|
>
|
||||||
<template #tags="{ tag, formatFn }">
|
<template #tags="{ tag, formatFn }">
|
||||||
<strong v-if="tag.label === 'typeFk'">
|
<strong v-if="tag.label === 'typeFk'">
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { onMounted, ref } from 'vue';
|
import { reactive, onMounted, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useState } from 'composables/useState';
|
import { useState } from 'composables/useState';
|
||||||
|
@ -9,7 +9,6 @@ import VnRow from 'components/ui/VnRow.vue';
|
||||||
import VnSelect from 'components/common/VnSelect.vue';
|
import VnSelect from 'components/common/VnSelect.vue';
|
||||||
import VnInputDate from 'components/common/VnInputDate.vue';
|
import VnInputDate from 'components/common/VnInputDate.vue';
|
||||||
import { useDialogPluginComponent } from 'quasar';
|
import { useDialogPluginComponent } from 'quasar';
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const state = useState();
|
const state = useState();
|
||||||
|
@ -58,10 +57,6 @@ const fetchAgencyList = async (landed, addressFk) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// const fetchOrderDetails = (order) => {
|
|
||||||
// fetchAddressList(order?.addressFk);
|
|
||||||
// fetchAgencyList(order?.landed, order?.addressFk);
|
|
||||||
// };
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
clientFk: {
|
clientFk: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -73,39 +68,6 @@ const initialFormState = reactive({
|
||||||
addressId: null,
|
addressId: null,
|
||||||
clientFk: $props.clientFk,
|
clientFk: $props.clientFk,
|
||||||
});
|
});
|
||||||
// const orderMapper = (order) => {
|
|
||||||
// return {
|
|
||||||
// addressId: order.addressFk,
|
|
||||||
// agencyModeId: order.agencyModeFk,
|
|
||||||
// landed: new Date(order.landed).toISOString(),
|
|
||||||
// };
|
|
||||||
// };
|
|
||||||
// const orderFilter = {
|
|
||||||
// include: [
|
|
||||||
// { relation: 'agencyMode', scope: { fields: ['name'] } },
|
|
||||||
// {
|
|
||||||
// relation: 'address',
|
|
||||||
// scope: { fields: ['nickname'] },
|
|
||||||
// },
|
|
||||||
// { relation: 'rows', scope: { fields: ['id'] } },
|
|
||||||
// {
|
|
||||||
// relation: 'client',
|
|
||||||
// scope: {
|
|
||||||
// fields: [
|
|
||||||
// 'salesPersonFk',
|
|
||||||
// 'name',
|
|
||||||
// 'isActive',
|
|
||||||
// 'isFreezed',
|
|
||||||
// 'isTaxDataChecked',
|
|
||||||
// ],
|
|
||||||
// include: {
|
|
||||||
// relation: 'salesPersonUser',
|
|
||||||
// scope: { fields: ['id', 'name'] },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
|
|
||||||
const onClientChange = async (clientId = $props.clientFk) => {
|
const onClientChange = async (clientId = $props.clientFk) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -111,6 +111,7 @@ const columns = computed(() => [
|
||||||
component: 'select',
|
component: 'select',
|
||||||
attrs: {
|
attrs: {
|
||||||
url: 'Items',
|
url: 'Items',
|
||||||
|
sortBy: 'name ASC ',
|
||||||
fields: ['id', 'name', 'subName'],
|
fields: ['id', 'name', 'subName'],
|
||||||
},
|
},
|
||||||
columnField: {
|
columnField: {
|
||||||
|
|
|
@ -126,7 +126,6 @@ const setWireTransfer = async () => {
|
||||||
(_, requestResponse) =>
|
(_, requestResponse) =>
|
||||||
onBankEntityCreated(requestResponse, row)
|
onBankEntityCreated(requestResponse, row)
|
||||||
"
|
"
|
||||||
:show-entity-field="false"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #option="scope">
|
<template #option="scope">
|
||||||
|
|
|
@ -76,8 +76,8 @@ const companySizes = [
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
v-model="data.isSerious"
|
v-model="data.isReal"
|
||||||
:label="t('supplier.basicData.isSerious')"
|
:label="t('supplier.basicData.isReal')"
|
||||||
/>
|
/>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
v-model="data.isActive"
|
v-model="data.isActive"
|
||||||
|
|
|
@ -38,7 +38,7 @@ const filter = {
|
||||||
'payDemFk',
|
'payDemFk',
|
||||||
'payDay',
|
'payDay',
|
||||||
'isActive',
|
'isActive',
|
||||||
'isSerious',
|
'isReal',
|
||||||
'isTrucker',
|
'isTrucker',
|
||||||
'account',
|
'account',
|
||||||
],
|
],
|
||||||
|
@ -137,7 +137,7 @@ const getEntryQueryParams = (supplier) => {
|
||||||
<QTooltip>{{ t('Inactive supplier') }}</QTooltip>
|
<QTooltip>{{ t('Inactive supplier') }}</QTooltip>
|
||||||
</QIcon>
|
</QIcon>
|
||||||
<QIcon
|
<QIcon
|
||||||
v-if="!supplier.isSerious"
|
v-if="!supplier.isReal"
|
||||||
name="vn:supplierfalse"
|
name="vn:supplierfalse"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="xs"
|
size="xs"
|
||||||
|
|
|
@ -83,7 +83,7 @@ const getUrl = (section) => `#/supplier/${entityId.value}/${section}`;
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
:label="t('supplier.summary.verified')"
|
:label="t('supplier.summary.verified')"
|
||||||
v-model="supplier.isSerious"
|
v-model="supplier.isReal"
|
||||||
:disable="true"
|
:disable="true"
|
||||||
/>
|
/>
|
||||||
<QCheckbox
|
<QCheckbox
|
||||||
|
|
|
@ -239,7 +239,7 @@ function makeInvoiceDialog() {
|
||||||
}
|
}
|
||||||
async function makeInvoice() {
|
async function makeInvoice() {
|
||||||
const params = {
|
const params = {
|
||||||
ticketsIds: [parseInt(ticketId)],
|
ticketsIds: [parseInt(ticketId.value)],
|
||||||
};
|
};
|
||||||
await axios.post(`Tickets/invoiceTicketsAndPdf`, params);
|
await axios.post(`Tickets/invoiceTicketsAndPdf`, params);
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ async function transferClient(client) {
|
||||||
|
|
||||||
async function addTurn(day) {
|
async function addTurn(day) {
|
||||||
const params = {
|
const params = {
|
||||||
ticketFk: parseInt(ticketId),
|
ticketFk: parseInt(ticketId.value),
|
||||||
weekDay: day,
|
weekDay: day,
|
||||||
agencyModeFk: ticket.value.agencyModeFk,
|
agencyModeFk: ticket.value.agencyModeFk,
|
||||||
};
|
};
|
||||||
|
@ -280,7 +280,7 @@ async function addTurn(day) {
|
||||||
|
|
||||||
async function createRefund(withWarehouse) {
|
async function createRefund(withWarehouse) {
|
||||||
const params = {
|
const params = {
|
||||||
ticketsIds: [parseInt(ticketId)],
|
ticketsIds: [parseInt(ticketId.value)],
|
||||||
withWarehouse: withWarehouse,
|
withWarehouse: withWarehouse,
|
||||||
negative: true,
|
negative: true,
|
||||||
};
|
};
|
||||||
|
@ -368,7 +368,7 @@ async function uploadDocuware(force) {
|
||||||
|
|
||||||
const { data } = await axios.post(`Docuwares/upload`, {
|
const { data } = await axios.post(`Docuwares/upload`, {
|
||||||
fileCabinet: 'deliveryNote',
|
fileCabinet: 'deliveryNote',
|
||||||
ticketIds: [parseInt(ticketId)],
|
ticketIds: [parseInt(ticketId.value)],
|
||||||
});
|
});
|
||||||
|
|
||||||
if (data) notify({ message: t('PDF sent!'), type: 'positive' });
|
if (data) notify({ message: t('PDF sent!'), type: 'positive' });
|
||||||
|
|
|
@ -94,25 +94,32 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('ticketList.id'),
|
label: t('globals.id'),
|
||||||
name: 'itemFk',
|
name: 'itemFk',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('basicData.quantity'),
|
label: t('globals.quantity'),
|
||||||
name: 'quantity',
|
name: 'quantity',
|
||||||
format: (row) => toCurrency(row.quantity),
|
format: (row) => toCurrency(row.quantity),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('basicData.item'),
|
label: t('globals.item'),
|
||||||
name: 'item',
|
name: 'item',
|
||||||
format: (row) => row?.item?.name,
|
format: (row) => row?.item?.name,
|
||||||
columnClass: 'expand',
|
columnClass: 'expand',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('basicData.price'),
|
label: t('globals.size'),
|
||||||
|
name: 'size',
|
||||||
|
format: (row) => row?.item?.size,
|
||||||
|
columnClass: 'expand',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
align: 'left',
|
||||||
|
label: t('globals.price'),
|
||||||
name: 'price',
|
name: 'price',
|
||||||
format: (row) => toCurrency(row.price),
|
format: (row) => toCurrency(row.price),
|
||||||
},
|
},
|
||||||
|
@ -124,7 +131,7 @@ const columns = computed(() => [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
align: 'left',
|
align: 'left',
|
||||||
label: t('ticketList.amount'),
|
label: t('globals.amount'),
|
||||||
name: 'amount',
|
name: 'amount',
|
||||||
format: (row) => parseInt(row.amount * row.quantity),
|
format: (row) => parseInt(row.amount * row.quantity),
|
||||||
},
|
},
|
||||||
|
@ -685,7 +692,7 @@ watch(
|
||||||
}"
|
}"
|
||||||
:create-as-dialog="false"
|
:create-as-dialog="false"
|
||||||
:crud-model="{
|
:crud-model="{
|
||||||
paginate: false,
|
disableInfiniteScroll: true,
|
||||||
}"
|
}"
|
||||||
:default-remove="false"
|
:default-remove="false"
|
||||||
:default-reset="false"
|
:default-reset="false"
|
||||||
|
|
|
@ -215,7 +215,7 @@ const requestComponentUpdate = async (ticket, isWithoutNegatives) => {
|
||||||
|
|
||||||
if (!newLanded) {
|
if (!newLanded) {
|
||||||
notify(t('advanceTickets.noDeliveryZone'), 'negative');
|
notify(t('advanceTickets.noDeliveryZone'), 'negative');
|
||||||
return;
|
throw new Error(t('advanceTickets.noDeliveryZone'));
|
||||||
}
|
}
|
||||||
|
|
||||||
ticket.landed = newLanded.landed;
|
ticket.landed = newLanded.landed;
|
||||||
|
@ -299,10 +299,10 @@ const splitTickets = async () => {
|
||||||
const { query, params } = await requestComponentUpdate(ticket, true);
|
const { query, params } = await requestComponentUpdate(ticket, true);
|
||||||
await axios.post(query, params);
|
await axios.post(query, params);
|
||||||
progressAdd(ticket.futureId);
|
progressAdd(ticket.futureId);
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
splitErrors.value.push({
|
splitErrors.value.push({
|
||||||
id: ticket.futureId,
|
id: ticket.futureId,
|
||||||
reason: error.response?.data?.error?.message,
|
reason: e.message || e.response?.data?.error?.message,
|
||||||
});
|
});
|
||||||
progressAdd(ticket.futureId);
|
progressAdd(ticket.futureId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import CustomerDescriptorProxy from 'src/pages/Customer/Card/CustomerDescriptorP
|
||||||
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
import ZoneDescriptorProxy from 'src/pages/Zone/Card/ZoneDescriptorProxy.vue';
|
||||||
import { toTimeFormat } from 'src/filters/date';
|
import { toTimeFormat } from 'src/filters/date';
|
||||||
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
import InvoiceOutDescriptorProxy from 'src/pages/InvoiceOut/Card/InvoiceOutDescriptorProxy.vue';
|
||||||
|
import TicketProblems from 'src/components/TicketProblems.vue';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
@ -492,66 +493,7 @@ function setReference(data) {
|
||||||
data-cy="ticketListTable"
|
data-cy="ticketListTable"
|
||||||
>
|
>
|
||||||
<template #column-statusIcons="{ row }">
|
<template #column-statusIcons="{ row }">
|
||||||
<div class="q-gutter-x-xs">
|
<TicketProblems :row="row" />
|
||||||
<QIcon
|
|
||||||
v-if="row.isTaxDataChecked === 0"
|
|
||||||
color="primary"
|
|
||||||
name="vn:no036"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('No verified data') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasTicketRequest"
|
|
||||||
color="primary"
|
|
||||||
name="vn:buyrequest"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Purchase request') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.itemShortage"
|
|
||||||
color="primary"
|
|
||||||
name="vn:unavailable"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Not visible') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon v-if="row.isFreezed" color="primary" name="vn:frozen" size="xs">
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Client frozen') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon v-if="row.risk" color="primary" name="vn:risk" size="xs">
|
|
||||||
<QTooltip> {{ t('Risk') }}: {{ row.risk }} </QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasComponentLack"
|
|
||||||
color="primary"
|
|
||||||
name="vn:components"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Component lack') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
<QIcon
|
|
||||||
v-if="row.hasRounding"
|
|
||||||
color="primary"
|
|
||||||
name="sync_problem"
|
|
||||||
size="xs"
|
|
||||||
>
|
|
||||||
<QTooltip>
|
|
||||||
{{ t('Rounding') }}
|
|
||||||
</QTooltip>
|
|
||||||
</QIcon>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<template #column-salesPersonFk="{ row }">
|
<template #column-salesPersonFk="{ row }">
|
||||||
<span class="link" @click.stop>
|
<span class="link" @click.stop>
|
||||||
|
|
|
@ -138,6 +138,7 @@ ticketSale:
|
||||||
ok: Ok
|
ok: Ok
|
||||||
more: Más
|
more: Más
|
||||||
address: Consignatario
|
address: Consignatario
|
||||||
|
size: Medida
|
||||||
ticketComponents:
|
ticketComponents:
|
||||||
serie: Serie
|
serie: Serie
|
||||||
components: Componentes
|
components: Componentes
|
||||||
|
|
|
@ -15,7 +15,7 @@ const filter = {
|
||||||
include: {
|
include: {
|
||||||
relation: 'user',
|
relation: 'user',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'nickname'],
|
fields: ['id', 'nickname', 'name'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -75,10 +75,10 @@ onBeforeMount(async () => {
|
||||||
<VnLinkPhone :phone-number="worker.phone" />
|
<VnLinkPhone :phone-number="worker.phone" />
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
<VnLv :value="worker.client?.phone">
|
<VnLv :value="advancedSummary?.client?.phone">
|
||||||
<template #label>
|
<template #label>
|
||||||
{{ t('worker.summary.personalPhone') }}
|
{{ t('worker.summary.personalPhone') }}
|
||||||
<VnLinkPhone :phone-number="worker.client?.phone" />
|
<VnLinkPhone :phone-number="advancedSummary?.client?.phone" />
|
||||||
</template>
|
</template>
|
||||||
</VnLv>
|
</VnLv>
|
||||||
</QCard>
|
</QCard>
|
||||||
|
@ -86,12 +86,12 @@ onBeforeMount(async () => {
|
||||||
<VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" />
|
<VnTitle :url="basicDataUrl" :text="t('globals.summary.basicData')" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('worker.summary.fiDueDate')"
|
:label="t('worker.summary.fiDueDate')"
|
||||||
:value="toDate(worker.fiDueDate)"
|
:value="toDate(advancedSummary.fiDueDate)"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('worker.summary.sex')" :value="worker.sex" />
|
<VnLv :label="t('worker.summary.sex')" :value="worker.sex" />
|
||||||
<VnLv
|
<VnLv
|
||||||
:label="t('worker.summary.seniority')"
|
:label="t('worker.summary.seniority')"
|
||||||
:value="toDate(worker.seniority)"
|
:value="toDate(advancedSummary.seniority)"
|
||||||
/>
|
/>
|
||||||
<VnLv :label="t('worker.summary.fi')" :value="advancedSummary.fi" />
|
<VnLv :label="t('worker.summary.fi')" :value="advancedSummary.fi" />
|
||||||
<VnLv
|
<VnLv
|
||||||
|
|
|
@ -306,7 +306,7 @@ async function autofillBic(worker) {
|
||||||
</VnRow>
|
</VnRow>
|
||||||
<VnRow>
|
<VnRow>
|
||||||
<VnInput
|
<VnInput
|
||||||
:label="t('worker.create.street')"
|
:label="t('globals.street')"
|
||||||
:model-value="uppercaseStreetModel(data).get()"
|
:model-value="uppercaseStreetModel(data).get()"
|
||||||
@update:model-value="uppercaseStreetModel(data).set"
|
@update:model-value="uppercaseStreetModel(data).set"
|
||||||
:disable="data.isFreelance"
|
:disable="data.isFreelance"
|
||||||
|
|
|
@ -113,7 +113,7 @@ export default {
|
||||||
name: 'SupplierAccounts',
|
name: 'SupplierAccounts',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'accounts',
|
title: 'accounts',
|
||||||
icon: 'vn:account',
|
icon: 'vn:credit',
|
||||||
},
|
},
|
||||||
component: () =>
|
component: () =>
|
||||||
import('src/pages/Supplier/Card/SupplierAccounts.vue'),
|
import('src/pages/Supplier/Card/SupplierAccounts.vue'),
|
||||||
|
|
|
@ -162,6 +162,15 @@ export const useInvoiceOutGlobalStore = defineStore({
|
||||||
);
|
);
|
||||||
throw new Error('Invalid Serial Type');
|
throw new Error('Invalid Serial Type');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clientsToInvoice === 'all' && params.serialType !== 'global') {
|
||||||
|
notify(
|
||||||
|
'invoiceOut.globalInvoices.errors.invalidSerialTypeForAll',
|
||||||
|
'negative'
|
||||||
|
);
|
||||||
|
throw new Error('For "all" clients, the serialType must be "global"');
|
||||||
|
}
|
||||||
|
|
||||||
if (!params.companyFk) {
|
if (!params.companyFk) {
|
||||||
notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
|
notify('invoiceOut.globalInvoices.errors.chooseValidCompany', 'negative');
|
||||||
throw new Error('Invalid company');
|
throw new Error('Invalid company');
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
videos/*
|
reports/*
|
||||||
screenshots/*
|
screenshots/*
|
||||||
|
|
|
@ -28,7 +28,7 @@ describe('Logout', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('when token not exists', () => {
|
it('when token not exists', () => {
|
||||||
cy.get('.q-list > [href="#/item"]').click();
|
cy.get('.q-list').first().should('be.visible').click();
|
||||||
cy.checkNotification('Authorization Required');
|
cy.checkNotification('Authorization Required');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,6 +5,7 @@ describe('VnSearchBar', () => {
|
||||||
const idGap = '.q-item > .q-item__label';
|
const idGap = '.q-item > .q-item__label';
|
||||||
const vnTableRow = '.q-virtual-scroll__content';
|
const vnTableRow = '.q-virtual-scroll__content';
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
cy.viewport(1280, 720);
|
||||||
cy.login('developer');
|
cy.login('developer');
|
||||||
cy.visit('#/customer/list');
|
cy.visit('#/customer/list');
|
||||||
});
|
});
|
||||||
|
|
|
@ -106,7 +106,6 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => {
|
||||||
case 'select':
|
case 'select':
|
||||||
cy.wrap(el).type(val);
|
cy.wrap(el).type(val);
|
||||||
cy.get('.q-menu .q-item').contains(val).click();
|
cy.get('.q-menu .q-item').contains(val).click();
|
||||||
cy.get('body').click();
|
|
||||||
break;
|
break;
|
||||||
case 'date':
|
case 'date':
|
||||||
cy.wrap(el).type(val.split('-').join(''));
|
cy.wrap(el).type(val.split('-').join(''));
|
||||||
|
|
Loading…
Reference in New Issue