Merge pull request 'fix: solve problem when discount is 0' (!1586) from hotfix_ticketSale_updateDiscountTo0 into master
gitea/salix-front/pipeline/head This commit looks good Details

Reviewed-on: #1586
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
Reviewed-by: Jon Elias <jon@verdnatura.es>
This commit is contained in:
Javier Segarra 2025-03-12 11:58:26 +00:00
commit 32fde59fba
4 changed files with 175 additions and 147 deletions

View File

@ -28,6 +28,17 @@ defineProps({ row: { type: Object, required: true } });
{{ t('ticketSale.reserved') }}
</QTooltip>
</QIcon>
<QIcon
v-if="row?.isDeleted"
color="primary"
name="vn:deletedTicket"
size="xs"
data-cy="ticketDeletedIcon"
>
<QTooltip>
{{ t('Ticket deleted') }}
</QTooltip>
</QIcon>
<QIcon
v-if="row?.hasRisk"
name="vn:risk"

View File

@ -95,7 +95,7 @@ function ticketFilter(ticket) {
</template>
<template #icons="{ entity }">
<QCardActions class="q-gutter-x-xs">
<TicketProblems :row="{ ...entity?.client, ...problems }" />
<TicketProblems :row="{ ...entity?.client, ...problems, ...entity }" />
</QCardActions>
</template>
<template #actions="{ entity }">

View File

@ -174,22 +174,28 @@ const getSaleTotal = (sale) => {
return price - discount;
};
const getRowUpdateInputEvents = (sale) => ({
'keyup.enter': () => {
changeQuantity(sale);
},
blur: () => {
changeQuantity(sale);
},
});
const getRowUpdateInputEvents = (sale) => {
return {
'keyup.enter': (evt) => {
console.error(evt);
changeQuantity(sale);
},
blur: (evt) => {
console.error(evt);
changeQuantity(sale);
},
};
};
const resetChanges = async () => {
arrayData.fetch({ append: false });
tableRef.value.reload();
selectedRows.value = [];
};
const changeQuantity = async (sale) => {
if (!sale.itemFk || sale.quantity == null || sale?.originalQuantity === sale.quantity)
return;
else sale.originalQuantity = sale.quantity;
if (!sale.id) return addSale(sale);
if (await isSalePrepared(sale)) {
@ -235,7 +241,7 @@ const addSale = async (sale) => {
notify('globals.dataSaved', 'positive');
sale.isNew = false;
arrayData.fetch({});
resetChanges();
};
const changeConcept = async (sale) => {
if (await isSalePrepared(sale)) {
@ -310,7 +316,7 @@ const changeDiscount = async (sale) => {
}
};
const updateDiscounts = async (sales, newDiscount = null) => {
const updateDiscounts = async (sales, newDiscount) => {
const salesTracking = await fetchSalesTracking();
const someSaleIsPrepared = salesTracking.some((sale) =>
@ -320,12 +326,11 @@ const updateDiscounts = async (sales, newDiscount = null) => {
else updateDiscount(sales, newDiscount);
};
const updateDiscount = async (sales, newDiscount = null) => {
const saleIds = sales.map((sale) => sale.id);
const _newDiscount = newDiscount || edit.value.discount;
const updateDiscount = async (sales, newDiscount = 0) => {
const salesIds = sales.map(({ id }) => id);
const params = {
salesIds: saleIds,
newDiscount: _newDiscount,
salesIds,
newDiscount,
manaCode: manaCode.value,
};
await axios.post(`Tickets/${route.params.id}/updateDiscount`, params);
@ -474,7 +479,7 @@ const endNewRow = (row) => {
};
async function confirmUpdate(cb) {
await quasar
quasar
.dialog({
component: VnConfirm,
componentProps: {
@ -664,6 +669,7 @@ watch(
selection: 'multiple',
}"
:right-search="false"
:search-url="false"
:column-search="false"
:disable-option="{ card: true }"
auto-load
@ -692,7 +698,7 @@ watch(
</template>
<template #column-image="{ row }">
<div class="image-wrapper">
<VnImg :id="parseInt(row?.item?.id)" class="rounded" />
<VnImg v-if="row.item" :id="parseInt(row?.item?.id)" class="rounded" />
</div>
</template>
<template #column-visible="{ row }">
@ -740,7 +746,7 @@ watch(
{{ row?.item?.subName.toUpperCase() }}
</div>
</div>
<FetchedTags :item="row.item" :max-length="6" />
<FetchedTags v-if="row.item" :item="row.item" :max-length="6" />
<QPopupProxy v-if="row.id && isTicketEditable">
<VnInput
v-model="row.concept"

View File

@ -1,139 +1,14 @@
/// <reference types="cypress" />
const firstRow = 'tbody > :nth-child(1)';
describe('TicketSale', () => {
describe.skip('Free ticket #31', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit('/#/ticket/31/sale');
});
const firstRow = 'tbody > :nth-child(1)';
const selectFirstRow = () => {
cy.waitForElement(firstRow);
cy.get(firstRow).find('.q-checkbox__inner').click();
};
it('it should add item to basket', () => {
cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen');
});
cy.dataCy('ticketSaleAddToBasketBtn').should('exist');
cy.dataCy('ticketSaleAddToBasketBtn').click();
cy.get('@windowOpen').should('be.calledWithMatch', /\/order\/\d+\/catalog/);
});
it('should send SMS', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="sendShortageSMSItem"]');
cy.dataCy('sendShortageSMSItem').should('exist');
cy.dataCy('sendShortageSMSItem').click();
cy.dataCy('vnSmsDialog').should('exist');
cy.dataCy('sendSmsBtn').click();
cy.checkNotification('SMS sent');
});
it('should recalculate price when "Recalculate price" is clicked', () => {
cy.intercept('POST', '**/recalculatePrice').as('recalculatePrice');
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="recalculatePriceItem"]');
cy.dataCy('recalculatePriceItem').should('exist');
cy.dataCy('recalculatePriceItem').click();
cy.wait('@recalculatePrice').its('response.statusCode').should('eq', 200);
cy.checkNotification('Data saved');
});
it('should update discount when "Update discount" is clicked', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="updateDiscountItem"]');
cy.dataCy('updateDiscountItem').should('exist');
cy.dataCy('updateDiscountItem').click();
cy.waitForElement('[data-cy="ticketSaleDiscountInput"]');
cy.dataCy('ticketSaleDiscountInput').find('input').focus();
cy.dataCy('ticketSaleDiscountInput').find('input').type('10');
cy.dataCy('saveManaBtn').click();
cy.waitForElement('.q-notification__message');
cy.checkNotification('Data saved');
});
it('adds claim', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('createClaimItem').click();
cy.dataCy('VnConfirm_confirm').click();
cy.url().should('contain', 'claim/');
// Delete created claim to avoid cluttering the database
cy.dataCy('descriptor-more-opts').click();
cy.dataCy('deleteClaim').click();
cy.dataCy('VnConfirm_confirm').click();
cy.checkNotification('Data deleted');
});
it('marks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="markAsReservedItem"]');
cy.dataCy('markAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('exist');
});
it('unmarks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
cy.dataCy('unmarkAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('not.exist');
});
it('refunds row with warehouse', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('ticketSaleRefundItem').click();
cy.dataCy('ticketSaleRefundWithWarehouse').click();
cy.checkNotification('The following refund ticket have been created');
});
it('refunds row without warehouse', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('ticketSaleRefundItem').click();
cy.dataCy('ticketSaleRefundWithoutWarehouse').click();
cy.checkNotification('The following refund ticket have been created');
});
it('transfer sale to a new ticket', () => {
cy.visit('/#/ticket/32/sale');
cy.get('.q-item > .q-item__label').should('have.text', ' #32');
selectFirstRow();
cy.dataCy('ticketSaleTransferBtn').click();
cy.dataCy('ticketTransferPopup').should('exist');
cy.dataCy('ticketTransferNewTicketBtn').click();
cy.get('.q-item > .q-item__label').should('not.have.text', ' #32');
});
it('should redirect to ticket logs', () => {
cy.get(firstRow).find('.q-btn:last').click();
cy.url().should('match', /\/ticket\/31\/log/);
});
});
describe.skip('Ticket prepared #23', () => {
describe('Ticket #23', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit('/#/ticket/23/sale');
});
const firstRow = 'tbody > :nth-child(1)';
const selectFirstRow = () => {
cy.waitForElement(firstRow);
cy.get(firstRow).find('.q-checkbox__inner').click();
};
it('update price', () => {
const price = Number((Math.random() * 99 + 1).toFixed(2));
cy.waitForElement(firstRow);
@ -196,8 +71,144 @@ describe('TicketSale', () => {
.should('have.value', `${quantity}`);
});
});
});
describe('Ticket to add claim #24', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit('/#/ticket/24/sale');
});
it('adds claim', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('createClaimItem').click();
cy.dataCy('VnConfirm_confirm').click();
cy.url().should('contain', 'claim/');
// Delete created claim to avoid cluttering the database
cy.dataCy('descriptor-more-opts').click();
cy.dataCy('deleteClaim').click();
cy.dataCy('VnConfirm_confirm').click();
});
});
describe('Free ticket #31', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit('/#/ticket/31/sale');
});
it('it should add item to basket', () => {
cy.window().then((win) => {
cy.stub(win, 'open').as('windowOpen');
});
cy.dataCy('ticketSaleAddToBasketBtn').should('exist');
cy.dataCy('ticketSaleAddToBasketBtn').click();
cy.get('@windowOpen').should('be.calledWithMatch', /\/order\/\d+\/catalog/);
});
it('should send SMS', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="sendShortageSMSItem"]');
cy.dataCy('sendShortageSMSItem').should('exist');
cy.dataCy('sendShortageSMSItem').click();
cy.dataCy('vnSmsDialog').should('exist');
cy.dataCy('sendSmsBtn').click();
cy.checkNotification('SMS sent');
});
it('should recalculate price when "Recalculate price" is clicked', () => {
cy.intercept('POST', '**/recalculatePrice').as('recalculatePrice');
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="recalculatePriceItem"]');
cy.dataCy('recalculatePriceItem').should('exist');
cy.dataCy('recalculatePriceItem').click();
cy.wait('@recalculatePrice').its('response.statusCode').should('eq', 200);
cy.checkNotification('Data saved');
cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled');
});
it('should update discount when "Update discount" is clicked', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="updateDiscountItem"]');
cy.dataCy('updateDiscountItem').should('exist');
cy.dataCy('updateDiscountItem').click();
cy.waitForElement('[data-cy="ticketSaleDiscountInput"]');
cy.dataCy('ticketSaleDiscountInput').find('input').focus();
cy.dataCy('ticketSaleDiscountInput').find('input').type('10');
cy.dataCy('saveManaBtn').click();
cy.waitForElement('.q-notification__message');
cy.checkNotification('Data saved');
cy.dataCy('ticketSaleMoreActionsDropdown').should('be.disabled');
});
it('adds claim', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('createClaimItem').click();
cy.dataCy('VnConfirm_confirm').click();
cy.checkNotification('Future ticket date not allowed');
});
it('marks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="markAsReservedItem"]');
cy.dataCy('markAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('exist');
});
it('unmarks row as reserved', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.waitForElement('[data-cy="unmarkAsReservedItem"]');
cy.dataCy('unmarkAsReservedItem').click();
cy.dataCy('ticketSaleReservedIcon').should('not.exist');
});
it('refunds row with warehouse', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('ticketSaleRefundItem').click();
cy.dataCy('ticketSaleRefundWithWarehouse').click();
cy.checkNotification('The following refund ticket have been created');
});
it('refunds row without warehouse', () => {
selectFirstRow();
cy.dataCy('ticketSaleMoreActionsDropdown').click();
cy.dataCy('ticketSaleRefundItem').click();
cy.dataCy('ticketSaleRefundWithoutWarehouse').click();
cy.checkNotification('The following refund ticket have been created');
});
it('should redirect to ticket logs', () => {
cy.get(firstRow).find('.q-btn:last').click();
cy.url().should('match', /\/ticket\/31\/log/);
});
});
describe('Ticket to transfer #32', () => {
beforeEach(() => {
cy.login('developer');
cy.viewport(1920, 1080);
cy.visit('/#/ticket/32/sale');
});
it('transfer sale to a new ticket', () => {
cy.get('.q-item > .q-item__label').should('have.text', ' #32');
selectFirstRow();
cy.dataCy('ticketSaleTransferBtn').click();
cy.dataCy('ticketTransferPopup').should('exist');
cy.dataCy('ticketTransferNewTicketBtn').click();
cy.get('.q-item > .q-item__label').should('not.have.text', ' #32');
});
});
});
function selectFirstRow() {
cy.waitForElement(firstRow);
cy.get(firstRow).find('.q-checkbox__inner').click();
}
function handleVnConfirm() {
cy.get('[data-cy="VnConfirm_confirm"]').click();
cy.waitForElement('.q-notification__message');