8315-devToTest #1094
|
@ -329,6 +329,7 @@ globals:
|
|||
email: Email
|
||||
SSN: SSN
|
||||
fi: FI
|
||||
packing: ITP
|
||||
myTeam: My team
|
||||
departmentFk: Department
|
||||
countryFk: Country
|
||||
|
|
|
@ -335,6 +335,7 @@ globals:
|
|||
SSN: NSS
|
||||
fi: NIF
|
||||
myTeam: Mi equipo
|
||||
packing: ITP
|
||||
countryFk: País
|
||||
changePass: Cambiar contraseña
|
||||
deleteConfirmTitle: Eliminar los elementos seleccionados
|
||||
|
|
|
@ -134,6 +134,7 @@ const getLocale = (label) => {
|
|||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
|
@ -209,6 +210,34 @@ const getLocale = (label) => {
|
|||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
outlined
|
||||
dense
|
||||
rounded
|
||||
:label="t('globals.params.departmentFk')"
|
||||
v-model="params.department"
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
url="Departments"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<VnSelect
|
||||
outlined
|
||||
dense
|
||||
rounded
|
||||
:label="t('globals.params.packing')"
|
||||
v-model="params.packing"
|
||||
url="ItemPackingTypes"
|
||||
option-label="code"
|
||||
option-value="code"
|
||||
/>
|
||||
</QItemSection>
|
||||
</QItem>
|
||||
<QItem>
|
||||
<QItemSection>
|
||||
<QCheckbox
|
||||
|
@ -258,7 +287,7 @@ en:
|
|||
ON_PREVIOUS: On previous
|
||||
PACKED: Packed
|
||||
No one: No one
|
||||
|
||||
|
||||
es:
|
||||
params:
|
||||
orderFk: Id cesta
|
||||
|
|
|
@ -24,6 +24,9 @@ const tableRef = ref(null);
|
|||
const provinceOpts = ref([]);
|
||||
const stateOpts = ref([]);
|
||||
const zoneOpts = ref([]);
|
||||
const DepartmentOpts = ref([]);
|
||||
const ItemPackingTypeOpts = ref([]);
|
||||
const visibleColumns = ref([]);
|
||||
const { viewSummary } = useSummaryDialog();
|
||||
|
||||
const [from, to] = dateRange(Date.vnNew());
|
||||
|
@ -51,6 +54,8 @@ function exprBuilder(param, value) {
|
|||
case 'nickname':
|
||||
return { [`t.nickname`]: { like: `%${value}%` } };
|
||||
case 'zoneFk':
|
||||
case 'department':
|
||||
return { 'd.name': value };
|
||||
case 'totalWithVat':
|
||||
return { [`t.${param}`]: value };
|
||||
}
|
||||
|
@ -137,6 +142,7 @@ const columns = computed(() => [
|
|||
align: 'left',
|
||||
format: (row) => row.practicalHour,
|
||||
columnFilter: false,
|
||||
dense: true,
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.preparation'),
|
||||
|
@ -190,6 +196,7 @@ const columns = computed(() => [
|
|||
'false-value': 0,
|
||||
'true-value': 1,
|
||||
},
|
||||
component: false,
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.zone'),
|
||||
|
@ -206,6 +213,12 @@ const columns = computed(() => [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.payMethod'),
|
||||
name: 'payMethod',
|
||||
align: 'left',
|
||||
columnFilter: false,
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.total'),
|
||||
name: 'totalWithVat',
|
||||
|
@ -219,6 +232,36 @@ const columns = computed(() => [
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.department'),
|
||||
name: 'department',
|
||||
align: 'left',
|
||||
columnFilter: {
|
||||
component: 'select',
|
||||
url: 'Departments',
|
||||
attrs: {
|
||||
options: DepartmentOpts.value,
|
||||
optionValue: 'name',
|
||||
optionLabel: 'name',
|
||||
dense: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
label: t('salesTicketsTable.packing'),
|
||||
name: 'packing',
|
||||
align: 'left',
|
||||
columnFilter: {
|
||||
component: 'select',
|
||||
url: 'ItemPackingTypes',
|
||||
attrs: {
|
||||
options: ItemPackingTypeOpts.value,
|
||||
'option-value': 'code',
|
||||
'option-label': 'code',
|
||||
dense: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
align: 'right',
|
||||
name: 'tableActions',
|
||||
|
@ -318,6 +361,24 @@ const openTab = (id) =>
|
|||
auto-load
|
||||
@on-fetch="(data) => (zoneOpts = data)"
|
||||
/>
|
||||
<FetchData
|
||||
url="ItemPackingTypes"
|
||||
:filter="{
|
||||
fields: ['code'],
|
||||
order: 'code ASC',
|
||||
}"
|
||||
auto-load
|
||||
@on-fetch="(data) => (ItemPackingTypeOpts = data)"
|
||||
/>
|
||||
<FetchData
|
||||
url="Departments"
|
||||
:filter="{
|
||||
fields: ['id', 'name'],
|
||||
order: 'id ASC',
|
||||
}"
|
||||
auto-load
|
||||
@on-fetch="(data) => (DepartmentOpts = data)"
|
||||
/>
|
||||
<MonitorTicketSearchbar />
|
||||
<RightMenu>
|
||||
<template #right-panel>
|
||||
|
@ -337,7 +398,7 @@ const openTab = (id) =>
|
|||
auto-load
|
||||
:row-click="({ id }) => openTab(id)"
|
||||
:disable-option="{ card: true }"
|
||||
:user-params="{ from, to, scopeDays: 0 }"
|
||||
:user-params="{ from, to, scopeDays: 0, packing }"
|
||||
>
|
||||
<template #top-left>
|
||||
<QBtn
|
||||
|
|
|
@ -26,8 +26,8 @@ salesTicketsTable:
|
|||
componentLack: Component lack
|
||||
tooLittle: Ticket too little
|
||||
identifier: Identifier
|
||||
theoretical: Theoretical
|
||||
practical: Practical
|
||||
theoretical: H.Theor
|
||||
practical: H.Prac
|
||||
province: Province
|
||||
state: State
|
||||
isFragile: Is fragile
|
||||
|
@ -35,7 +35,10 @@ salesTicketsTable:
|
|||
goToLines: Go to lines
|
||||
preview: Preview
|
||||
total: Total
|
||||
preparation: Preparation
|
||||
preparation: H.Prep
|
||||
payMethod: Pay method
|
||||
department: Department
|
||||
packing: ITP
|
||||
searchBar:
|
||||
label: Search tickets
|
||||
info: Search tickets by id or alias
|
||||
|
|
|
@ -26,8 +26,8 @@ salesTicketsTable:
|
|||
componentLack: Faltan componentes
|
||||
tooLittle: Ticket demasiado pequeño
|
||||
identifier: Identificador
|
||||
theoretical: Teórica
|
||||
practical: Práctica
|
||||
theoretical: H.Teór
|
||||
practical: H.Prác
|
||||
province: Provincia
|
||||
state: Estado
|
||||
isFragile: Es frágil
|
||||
|
@ -35,7 +35,10 @@ salesTicketsTable:
|
|||
goToLines: Ir a líneas
|
||||
preview: Vista previa
|
||||
total: Total
|
||||
preparation: Preparación
|
||||
preparation: H.Prep
|
||||
payMethod: Método de pago
|
||||
department: Departamento
|
||||
packing: ITP
|
||||
searchBar:
|
||||
label: Buscar tickets
|
||||
info: Buscar tickets por identificador o alias
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { computed, ref, toRefs } from 'vue';
|
||||
import { computed, onMounted, ref, toRefs, watch } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
@ -24,6 +24,15 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
restoreTicket();
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.ticket,
|
||||
() => restoreTicket
|
||||
);
|
||||
|
||||
const { push, currentRoute } = useRouter();
|
||||
const { dialog, notify } = useQuasar();
|
||||
const { t } = useI18n();
|
||||
|
@ -42,6 +51,7 @@ const hasPdf = ref();
|
|||
const weight = ref();
|
||||
const hasDocuwareFile = ref();
|
||||
const quasar = useQuasar();
|
||||
const canRestoreTicket = ref(false);
|
||||
const actions = {
|
||||
clone: async () => {
|
||||
const opts = { message: t('Ticket cloned'), type: 'positive' };
|
||||
|
@ -373,6 +383,54 @@ async function uploadDocuware(force) {
|
|||
|
||||
if (data) notify({ message: t('PDF sent!'), type: 'positive' });
|
||||
}
|
||||
|
||||
const restoreTicket = async () => {
|
||||
const filter = {
|
||||
fields: ['id', 'originFk', 'creationDate', 'newInstance'],
|
||||
where: {
|
||||
originFk: ticketId.value,
|
||||
newInstance: { like: '%"isDeleted":true%' },
|
||||
},
|
||||
order: 'creationDate DESC',
|
||||
limit: 1,
|
||||
};
|
||||
const params = { filter: JSON.stringify(filter) };
|
||||
|
||||
const { data } = await axios.get(`TicketLogs`, { params });
|
||||
|
||||
if (data && data.length) {
|
||||
const now = Date.vnNew();
|
||||
const maxDate = new Date(data[0].creationDate);
|
||||
maxDate.setHours(maxDate.getHours() + 1);
|
||||
if (now <= maxDate) {
|
||||
return (canRestoreTicket.value = true);
|
||||
}
|
||||
return (canRestoreTicket.value = false);
|
||||
}
|
||||
return (canRestoreTicket.value = false);
|
||||
};
|
||||
|
||||
async function openRestoreConfirmation(force) {
|
||||
if (!force)
|
||||
return quasar
|
||||
.dialog({
|
||||
component: VnConfirm,
|
||||
componentProps: {
|
||||
title: t('Are you sure you want to restore the ticket?'),
|
||||
message: t('You are going to restore this ticket'),
|
||||
},
|
||||
})
|
||||
.onOk(async () => {
|
||||
ticketToRestore();
|
||||
});
|
||||
}
|
||||
|
||||
async function ticketToRestore() {
|
||||
const { data } = await axios.post(`Tickets/${ticketId.value}/restore`);
|
||||
if (data) {
|
||||
notify({ message: t('Ticket restored'), type: 'positive' });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<FetchData
|
||||
|
@ -560,6 +618,12 @@ async function uploadDocuware(force) {
|
|||
</QItemSection>
|
||||
<QItemSection>{{ t('Show Proforma') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem v-if="canRestoreTicket" @click="openRestoreConfirmation()" v-ripple clickable>
|
||||
<QItemSection avatar>
|
||||
<QIcon name="restore" />
|
||||
</QItemSection>
|
||||
<QItemSection>{{ t('Restore ticket') }}</QItemSection>
|
||||
</QItem>
|
||||
<QItem
|
||||
v-if="isEditable"
|
||||
@click="showChangeTimeDialog = !showChangeTimeDialog"
|
||||
|
@ -746,4 +810,8 @@ es:
|
|||
You are going to delete this ticket: Vas a eliminar este ticket
|
||||
as PDF signed: como PDF firmado
|
||||
Are you sure you want to replace this delivery note?: ¿Seguro que quieres reemplazar este albarán?
|
||||
Restore ticket: Restaurar ticket
|
||||
Are you sure you want to restore the ticket?: ¿Seguro que quieres restaurar el ticket?
|
||||
You are going to restore this ticket: Vas a restaurar este ticket
|
||||
Ticket restored: Ticket restaurado
|
||||
</i18n>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
describe('ZoneBasicData', () => {
|
||||
const notification = '.q-notification__message';
|
||||
const priceBasicData = '[data-cy="Price_input"]';
|
||||
|
||||
beforeEach(() => {
|
||||
cy.viewport(1280, 720);
|
||||
|
@ -13,9 +14,15 @@ describe('ZoneBasicData', () => {
|
|||
cy.get(notification).should('contains.text', "can't be blank");
|
||||
});
|
||||
|
||||
it('should throw an error if the price is empty', () => {
|
||||
cy.get(priceBasicData).clear();
|
||||
cy.get('.q-btn-group > .q-btn--standard').click();
|
||||
cy.get(notification).should('contains.text', 'cannot be blank');
|
||||
});
|
||||
|
||||
it("should edit the basicData's zone", () => {
|
||||
cy.get('.q-card > :nth-child(1)').type(' modified');
|
||||
cy.get('.q-btn-group > .q-btn--standard').click();
|
||||
cy.get(notification).should('contains.text', 'Data saved');
|
||||
cy.checkNotification('Data saved');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue