diff --git a/src/pages/Ticket/Card/TicketSplit.vue b/src/pages/Ticket/Card/TicketSplit.vue index e79057266..66ba3e9a6 100644 --- a/src/pages/Ticket/Card/TicketSplit.vue +++ b/src/pages/Ticket/Card/TicketSplit.vue @@ -2,7 +2,7 @@ import { ref } from 'vue'; import VnInputDate from 'src/components/common/VnInputDate.vue'; -import split from './components/split'; +import { splitTicket } from './components/split'; const emit = defineEmits(['ticketTransfered']); const $props = defineProps({ @@ -12,6 +12,8 @@ const $props = defineProps({ }, }); +const { split } = splitTicket(); + const splitDate = ref(Date.vnNew()); const splitSelectedRows = async () => { diff --git a/src/pages/Ticket/Card/components/split.js b/src/pages/Ticket/Card/components/split.js index feef6dbb1..7d3cd9ed8 100644 --- a/src/pages/Ticket/Card/components/split.js +++ b/src/pages/Ticket/Card/components/split.js @@ -1,25 +1,24 @@ import axios from 'axios'; -import notifyResults from 'src/utils/notifyResults'; import { showResultsAsTable } from 'src/composables/showResultsTable'; import HandleSplitDialog from 'src/pages/Ticket/Negative/components/HandleSplitDialog.vue'; -export default async function (data, date) { - const reducedData = data.reduce((acc, item) => { - const existing = acc.find(({ ticketFk }) => ticketFk === item.id); - if (existing) { - existing.sales.push(item.saleFk); - } else { - acc.push({ ticketFk: item.id, sales: [item.saleFk], date }); - } - return acc; - }, []); - - const promises = reducedData.map((params) => axios.post(`Tickets/split`, params)); +export function splitTicket() { const { openTable } = showResultsAsTable(); - const results = await Promise.allSettled(promises); - openTable(HandleSplitDialog, result, 'ticketFk', 'changeState'); + async function split(data, date) { + const reducedData = data.reduce((acc, item) => { + const existing = acc.find(({ ticketFk }) => ticketFk === item.ticketFk); + if (existing) { + existing.sales.push(item.saleFk); + } else { + acc.push({ ticketFk: item.ticketFk, sales: [item.saleFk], landed: date }); + } + return acc; + }, []); - notifyResults(results, 'ticketFk'); + const promises = reducedData.map((params) => axios.post(`Tickets/split`, params)); - return results; + const result = await Promise.allSettled(promises); + openTable(HandleSplitDialog, result, 'ticket', 'split'); + } + return { split }; } diff --git a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue index bcba4caf0..1d8967ac0 100644 --- a/src/pages/Ticket/Negative/components/ChangeItemDialog.vue +++ b/src/pages/Ticket/Negative/components/ChangeItemDialog.vue @@ -1,18 +1,12 @@ <script setup> import { ref } from 'vue'; import axios from 'axios'; -import { useQuasar } from 'quasar'; -import { useI18n } from 'vue-i18n'; import VnSelect from 'src/components/common/VnSelect.vue'; -import notifyResults from 'src/utils/notifyResults'; import { showResultsAsTable } from 'src/composables/showResultsTable'; -import VnConfirm from 'src/components/ui/VnConfirm.vue'; import HandleSplitDialog from './HandleSplitDialog.vue'; const { openTable } = showResultsAsTable(); const emit = defineEmits(['update-item']); -const quasar = useQuasar(); -const { t } = useI18n(); const showChangeItemDialog = ref(false); const newItem = ref(null); @@ -37,7 +31,6 @@ const updateItem = async () => { const result = await Promise.allSettled(rowsToUpdate); openTable(HandleSplitDialog, result, 'ticketFk', 'changeItem'); - // notifyResults(result, 'saleFk'); emit('update-item', newItem.value); } catch (err) { console.error('Error updating item:', err); diff --git a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue index 62a4b775a..520f9b63c 100644 --- a/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue +++ b/src/pages/Ticket/Negative/components/ChangeQuantityDialog.vue @@ -2,7 +2,6 @@ import { ref } from 'vue'; import axios from 'axios'; import VnInput from 'src/components/common/VnInput.vue'; -// import notifyResults from 'src/utils/notifyResults'; import { showResultsAsTable } from 'src/composables/showResultsTable'; import HandleSplitDialog from './HandleSplitDialog.vue'; const { openTable } = showResultsAsTable(); @@ -16,24 +15,17 @@ const $props = defineProps({ }); const emit = defineEmits(['update-quantity']); const updateQuantity = async () => { - try { - showChangeQuantityDialog.value = true; - const rowsToUpdate = $props.selectedRows.map(({ saleFk }) => - axios.post(`Sales/${saleFk}/updateQuantity`, { - saleFk, - quantity: +newQuantity.value, - }), - ); + showChangeQuantityDialog.value = true; + const rowsToUpdate = $props.selectedRows.map(({ saleFk }) => + axios.post(`Sales/${saleFk}/updateQuantity`, { + saleFk, + quantity: +newQuantity.value, + }), + ); - const result = await Promise.allSettled(rowsToUpdate); - openTable(HandleSplitDialog, result, 'ticketFk', 'changeQuantity'); - - // notifyResults(result, 'saleFk'); - - emit('update-quantity', newQuantity.value); - } catch (err) { - return err; - } + const result = await Promise.allSettled(rowsToUpdate); + openTable(HandleSplitDialog, result, 'ticketFk', 'changeQuantity'); + emit('update-quantity', newQuantity.value); }; </script> diff --git a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue index 8bf9bc730..ec9b9fcd1 100644 --- a/src/pages/Ticket/Negative/components/ChangeStateDialog.vue +++ b/src/pages/Ticket/Negative/components/ChangeStateDialog.vue @@ -5,7 +5,6 @@ import VnSelect from 'src/components/common/VnSelect.vue'; import FetchData from 'components/FetchData.vue'; import { showResultsAsTable } from 'src/composables/showResultsTable'; import HandleSplitDialog from './HandleSplitDialog.vue'; -// import notifyResults from 'src/utils/notifyResults'; const { openTable } = showResultsAsTable(); const emit = defineEmits(['update-state']); @@ -19,7 +18,6 @@ const $props = defineProps({ }, }); const updateState = async () => { - try { showChangeStateDialog.value = true; const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) => axios.post(`Tickets/state`, { @@ -27,15 +25,11 @@ const updateState = async () => { code: newState.value, }), ); + const result = await Promise.allSettled(rowsToUpdate); + openTable(HandleSplitDialog, result, 'ticketFk', 'changeState'); - - // notifyResults(result, 'ticketFk'); - emit('update-state', newState.value); - } catch (err) { - return err; - } }; </script> diff --git a/src/pages/Ticket/Negative/components/HandleSplitDialog.vue b/src/pages/Ticket/Negative/components/HandleSplitDialog.vue index 9aabc21e4..574ad8d76 100644 --- a/src/pages/Ticket/Negative/components/HandleSplitDialog.vue +++ b/src/pages/Ticket/Negative/components/HandleSplitDialog.vue @@ -6,7 +6,6 @@ import FetchData from 'components/FetchData.vue'; import ItemDescriptorProxy from 'src/pages/Item/Card/ItemDescriptorProxy.vue'; const { t } = useI18n(); -const newState = ref(null); const $props = defineProps({ results: { type: Array, @@ -25,10 +24,8 @@ const $props = defineProps({ default: '', }, }); -console.error($props.tag, 'results', $props.results); const results = ref($props.results); - -// const rowsSelected = ref([]); +const states = ref([]); const columns = computed(() => [ { @@ -44,30 +41,18 @@ const columns = computed(() => [ sortable: true, align: 'center', }, - // { - // name: 'newTicket', - // label: t('negative.split.newTicket'), - // field: ({ newTicket }) => newTicket, - // sortable: true, - // }, { name: 'statusText', label: t('negative.split.message'), sortable: true, align: 'center', }, - // { - // name: 'actions', - // align: 'center', - // label: t('negative.split.actions'), - // // style: 'padding-left: 100px', - // // headerStyle: 'padding-left: 100px', - // }, ]); -function handleMessage(value) { - const actions = { - changeState: {}, - }; +function getState(value) { + return states.value.find((state) => state.id === value)?.name; +} +function getTicketRejected(row) { + return JSON.parse(row.reason.config.data)?.ticketFk; } function getIcon(value) { const icons = { @@ -86,19 +71,17 @@ function getIcon(value) { }; return icons[value]; } - -const states = ref([]); </script> <template> - <QDialog ref="dialogRef" @hide="onDialogHide"> + <QDialog ref="dialogRef" @hide="onDialogHide" data-cy="handleSplitDialog"> <FetchData v-if="$props.action === 'changeState'" url="States" @on-fetch="(data) => (states = data)" auto-load /> - <QCard class="q-pa-sm"> + <QCard class="q-pa-sm" style="width: 60vw; max-width: 80vw"> <QCardSection class="row items-center q-pb-none"> <QAvatar :icon="icon" @@ -107,12 +90,13 @@ const states = ref([]); size="xl" v-if="icon" /> - <span class="text-h6 text-grey">{{ t($props.title) }}</span> + <span class="text-h6 text-grey" + >{{ t($props.title) }} ({{ $props.action }}) + </span> <QSpace /> <QBtn icon="close" flat round dense v-close-popup /> </QCardSection> <QCardSection class="row items-center justify-center column items-stretch"> - {{ results }} <QTable :rows="results" :columns="columns" @@ -124,9 +108,7 @@ const states = ref([]); auto-load > <template #header="props"> - <!-- {{ props }} --> <QTr :props="props"> - <!-- <QTh></QTh> --> <QTh v-for="col in props.cols" :key="col.name" :props="props"> {{ t(col.label) }} </QTh> @@ -146,18 +128,21 @@ const states = ref([]); <template #body-cell-value="{ row }"> <QTd align="center"> <div class="link" @click.stop> - <span v-if="row.status === 'fulfilled'"> - *{{ row.value.data[$props.tag] }} - <TicketDescriptorProxy - :id="row.value.data[$props.tag]" - > - </TicketDescriptorProxy> - </span> + <div v-if="row.status === 'fulfilled'"> + <span v-if="$props.action !== 'changeItem'"> + {{ row.value.data[$props.tag] }} + <TicketDescriptorProxy + :id="row.value.data[$props.tag]" + > + </TicketDescriptorProxy> + </span> + <span v-else> + {{ JSON.parse(row.value.config.data).ticketFk }} + </span> + </div> <span v-else> - {{ JSON.parse(row.reason.config.data)?.ticketFk - }}<TicketDescriptorProxy - :id="JSON.parse(row.reason.config.data)?.ticketFk" - > + {{ getTicketRejected(row) + }}<TicketDescriptorProxy :id="getTicketRejected(row)"> </TicketDescriptorProxy ></span> </div> @@ -167,18 +152,11 @@ const states = ref([]); <QTd align="center"> <div v-if="row.status === 'fulfilled'"> <div v-if="$props.action === 'changeState'"> - {{ - states.find( - (state) => - state.id === row.value.data.stateFk, - )?.name - }} + {{ getState(row.value.data.stateFk) }} </div> <div v-if="$props.action === 'split'"> - <span class="link" @click.stop> - {{ value }} - <TicketDescriptorProxy :id="value"> - </TicketDescriptorProxy> + <span> + {{ row.value.data.status }} </span> </div> <div v-if="$props.action === 'changeItem'"> @@ -197,43 +175,6 @@ const states = ref([]); </template> </QTable> </QCardSection> - <QCardActions align="right"> - <QBtn - :label="t('globals.cancel')" - color="primary" - flat - v-close-popup - /> </QCardActions - ></QCard> + </QCard> </QDialog> </template> - -<style lang="scss" scoped> -.splitRow { - border: 1px solid #ec8916; - border-width: 1px 0 1px 0; -} -.list { - max-height: 100%; - padding: 15px; - width: 100%; -} - -.grid-style-transition { - transition: - transform 0.28s, - background-color 0.28s; -} - -#true { - background-color: $positive; -} - -#false { - background-color: $negative; -} - -div.q-dialog__inner > div { - max-width: fit-content !important; -} -</style> diff --git a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js index 2a20e202a..71cee0d68 100644 --- a/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js +++ b/test/cypress/integration/ticket/negative/TicketLackDetail.spec.js @@ -1,8 +1,8 @@ /// <reference types="cypress" /> +const firstRow = 'tr.cursor-pointer > :nth-child(1)'; describe('Ticket Lack detail', () => { beforeEach(() => { cy.viewport(1280, 720); - cy.login('developer'); cy.intercept('GET', /\/api\/Tickets\/itemLack\/88.*$/).as('getItemLack'); cy.visit('/#/ticket/negative/88'); @@ -16,23 +16,22 @@ describe('Ticket Lack detail', () => { cy.domContentLoad(); cy.waitForElement('.q-table'); }); - describe.skip('Table detail', () => { + describe('Table detail', () => { it('should open descriptors', () => { cy.get('.q-table').should('be.visible'); - cy.get('[data-col-field="nickname"]').click(); - cy.dataCy('customerDescriptorProxy').should('be.visible'); - cy.get('.q-item > .q-item__label').should('have.text', ' #1 content_copy'); + cy.get('[data-col-field="zoneName"]').click(); cy.dataCy('zoneDescriptorProxy').should('be.visible'); - cy.get('.q-item > .q-item__label').should('have.text', ' #1 content_copy'); + cy.get('.q-item > .q-item__label').should('have.text', ' #1'); cy.get('[data-col-field="ticketFk"]').click(); cy.dataCy('ticketDescriptorProxy').should('be.visible'); - cy.get('.q-item > .q-item__label').should( - 'have.text', - ' #1000000 content_copy', - ); + cy.get('.q-item > .q-item__label').should('have.text', ' #1000000'); + cy.get('[data-col-field="nickname"] > .no-padding > .link').click(); + cy.waitForElement('[data-cy="customerDescriptorProxy"]'); + cy.dataCy('customerDescriptorProxy').should('be.visible'); + cy.get('.q-item > .q-item__label').should('have.text', ' #1'); }); - it.only('should display only one row in the lack list', () => { + it('should display only one row in the lack list', () => { cy.get('[data-cy="changeItem"]').should('be.disabled'); cy.get('[data-cy="changeState"]').should('be.disabled'); cy.get('[data-cy="changeQuantity"]').should('be.disabled'); @@ -47,94 +46,130 @@ describe('Ticket Lack detail', () => { }); }); - describe.only('Item proposal', () => { + describe('Split', () => { beforeEach(() => { - cy.get('tr.cursor-pointer > :nth-child(1)').click(); + cy.get(firstRow).click(); + cy.get('[data-cy="transferLines"]').click(); + }); + it('Split', () => { + cy.get('[data-cy="ticketTransferPopup"] > .flex > .q-btn').click(); + cy.get('.q-notification').should('be.visible'); + cy.get('.q-notification').find('.q-btn').click(); + cy.get('.q-notification').should('not.be.visible'); + + cy.get('[data-cy="handleSplitDialog"]').should('be.visible'); + cy.get('[data-cy="handleSplitDialog"]').find( + 'tbody > tr > :nth-child(1) > .q-icon', + ); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div') + .should('have.class', 'link'); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div.link > div > span') + .should('have.text', '1000000 '); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(3) > div') + .should('have.text', 'noSplit'); + }); + }); + describe('Change Item', () => { + beforeEach(() => { + cy.get(firstRow).click(); + cy.get('[data-cy="changeItem"]').click(); + }); + it('Change failed', () => { + cy.get('[data-cy="New item_select"]').click(); + cy.get('.q-item').contains('Palito rojo').click(); + cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + cy.waitForElement('.q-notification'); + cy.get('.q-notification').should('be.visible'); + cy.get('.q-notification').find('.q-btn').click(); + + cy.get('[data-cy="handleSplitDialog"]').should('be.visible'); + cy.get('[data-cy="handleSplitDialog"]').find( + 'tbody > tr > :nth-child(1) > .q-icon', + ); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div') + .should('have.class', 'link'); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div.link > span') + .should('have.text', '1000000'); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(3) > div') + .should('have.text', 'price retrieval failed'); + }); + }); + describe('Change state', () => { + beforeEach(() => { + cy.get(firstRow).click(); + cy.get('[data-cy="changeState"]').click(); + }); + it('Change success', () => { + cy.get('[data-cy="New state_select"]').click(); + cy.get('.q-item').contains('OK').click(); + cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + + cy.waitForElement('.q-notification'); + cy.get('.q-notification').should('be.visible'); + cy.get('.q-notification').find('.q-btn').click(); + + cy.get('[data-cy="handleSplitDialog"]').should('be.visible'); + cy.get('[data-cy="handleSplitDialog"]').find( + 'tbody > tr > :nth-child(1) > .q-icon', + ); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div') + .should('have.class', 'link'); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div.link > div > span') + .should('have.text', '1000000 '); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(3) > div') + .should('have.text', 'OK'); + }); + }); + describe('change quantity', () => { + beforeEach(() => { + cy.get(firstRow).click(); + + cy.get('[data-cy="changeQuantity"]').click(); + }); + + it('Change success', () => { + cy.get('[data-cy="New quantity_input"]').type(10); + cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + cy.waitForElement('.q-notification'); + cy.get('.q-notification').should('be.visible'); + cy.get('.q-notification').find('.q-btn').click(); + + cy.get('[data-cy="handleSplitDialog"]').should('be.visible'); + cy.get('[data-cy="handleSplitDialog"]').find( + 'tbody > tr > :nth-child(1) > .q-icon', + ); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div') + .should('have.class', 'link'); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(2) > div.link > div > span') + .should('have.text', '1000000 '); + cy.get('[data-cy="handleSplitDialog"]') + .find('tbody > tr > :nth-child(3) > div') + .should('have.text', '10'); + }); + }); + describe('Item proposal', () => { + beforeEach(() => { + cy.get(firstRow).click(); - // cy.intercept('GET', /\/api\/Items\/getSimilar\?.*$/, { - // statusCode: 200, - // body: [ - // { - // id: 1, - // longName: 'Ranged weapon longbow 50cm', - // subName: 'Stark Industries', - // tag5: 'Color', - // value5: 'Brown', - // match5: 0, - // match6: 0, - // match7: 0, - // match8: 1, - // tag6: 'Categoria', - // value6: '+1 precission', - // tag7: 'Tallos', - // value7: '1', - // tag8: null, - // value8: null, - // available: 20, - // calc_id: 6, - // counter: 0, - // minQuantity: 1, - // visible: null, - // price2: 1, - // }, - // { - // id: 2, - // longName: 'Ranged weapon longbow 100cm', - // subName: 'Stark Industries', - // tag5: 'Color', - // value5: 'Brown', - // match5: 0, - // match6: 1, - // match7: 0, - // match8: 1, - // tag6: 'Categoria', - // value6: '+1 precission', - // tag7: 'Tallos', - // value7: '1', - // tag8: null, - // value8: null, - // available: 50, - // calc_id: 6, - // counter: 1, - // minQuantity: 5, - // visible: null, - // price2: 10, - // }, - // { - // id: 3, - // longName: 'Ranged weapon longbow 200cm', - // subName: 'Stark Industries', - // tag5: 'Color', - // value5: 'Brown', - // match5: 1, - // match6: 1, - // match7: 1, - // match8: 1, - // tag6: 'Categoria', - // value6: '+1 precission', - // tag7: 'Tallos', - // value7: '1', - // tag8: null, - // value8: null, - // available: 185, - // calc_id: 6, - // counter: 10, - // minQuantity: 10, - // visible: null, - // price2: 100, - // }, - // ], - // }).as('getItemGetSimilar'); cy.get('[data-cy="itemProposal"]').click(); - // cy.wait('@getItemGetSimilar'); }); describe('Replace item if', () => { it('Quantity is less than available', () => { cy.get(':nth-child(1) > .text-right > .q-btn').click(); }); - /* ==== Test Created with Cypress Studio ==== */ - it.only('item proposal cells', function () { + it('item proposal cells', () => { cy.get( ':nth-child(1) > .q-table--col-auto-width > .q-btn > .q-btn__content > .q-icon', ).should('not.be.visible'); @@ -152,16 +187,6 @@ describe('Ticket Lack detail', () => { ':nth-child(2) > [data-col-field="tag6"] > .no-padding > .match', ).should('have.class', 'match'); cy.get(':nth-child(2) > [data-col-field="tag7"]').click(); - cy.get( - ':nth-child(2) > .q-table--col-auto-width > .q-btn > .q-btn__content > .q-icon', - ).should('be.visible'); - cy.get(':nth-child(2) > .q-table--col-auto-width > .q-btn') - .should('be.enabled') - .click(); - // cy.get('.q-notification__message').should( - // 'have.text', - // 'Operación (1) 43 completada con éxito.', - // ); }); }); });