diff --git a/db/changes/232201/00-ticket_warehouse.sql b/db/changes/232201/00-ticket_warehouse.sql new file mode 100644 index 000000000..b5255ee3f --- /dev/null +++ b/db/changes/232201/00-ticket_warehouse.sql @@ -0,0 +1 @@ +ALTER TABLE `vn`.`ticket` MODIFY COLUMN warehouseFk smallint(6) unsigned DEFAULT NULL NULL; diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index dcd9211f9..fff0a2f15 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -595,6 +595,8 @@ export default { moreMenuUpdateDiscount: 'vn-item[name="discount"]', moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]', moreMenuRefund: 'vn-item[name="refund"]', + refundWithWarehouse: 'vn-item[name="refundWithWarehouse"]', + refundWithoutWarehouse: 'vn-item[name="refundWithoutWarehouse"]', moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index a87e00543..6264073f6 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -220,14 +220,25 @@ describe('Ticket Edit sale path', () => { it('should log in as salesAssistant and navigate to ticket sales', async() => { await page.loginAndModule('salesAssistant', 'ticket'); - await page.accessToSearchResult('16'); + await page.accessToSearchResult('17'); await page.accessToSection('ticket.card.sale'); }); - it('should select the third sale and create a refund', async() => { + it('should select the first sale and create a refund with warehouse', async() => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuRefund); + await page.waitToClick(selectors.ticketSales.refundWithWarehouse); + await page.waitForSnackbar(); + await page.waitForState('ticket.card.sale'); + }); + + it('should select the first sale and create a refund without warehouse', async() => { + await page.accessToSearchResult('18'); + await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); + await page.waitToClick(selectors.ticketSales.moreMenu); + await page.waitToClick(selectors.ticketSales.moreMenuRefund); + await page.waitToClick(selectors.ticketSales.refundWithoutWarehouse); await page.waitForSnackbar(); await page.waitForState('ticket.card.sale'); }); @@ -246,7 +257,6 @@ describe('Ticket Edit sale path', () => { it('should select the third sale and create a claim of it', async() => { await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); diff --git a/modules/invoiceOut/back/methods/invoiceOut/refund.js b/modules/invoiceOut/back/methods/invoiceOut/refund.js index ad480dc7d..c722d9806 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/refund.js +++ b/modules/invoiceOut/back/methods/invoiceOut/refund.js @@ -2,11 +2,19 @@ module.exports = Self => { Self.remoteMethod('refund', { description: 'Create refund tickets with sales and services if provided', accessType: 'WRITE', - accepts: [{ - arg: 'ref', - type: 'string', - description: 'The invoice reference' - }], + accepts: [ + { + arg: 'ref', + type: 'string', + description: 'The invoice reference', + required: true + }, + { + arg: 'withWarehouse', + type: 'boolean', + required: true + } + ], returns: { type: ['number'], root: true @@ -17,7 +25,7 @@ module.exports = Self => { } }); - Self.refund = async(ref, options) => { + Self.refund = async(ref, withWarehouse, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -35,7 +43,7 @@ module.exports = Self => { const tickets = await models.Ticket.find(filter, myOptions); const ticketsIds = tickets.map(ticket => ticket.id); - const refundedTickets = await models.Ticket.refund(ticketsIds, myOptions); + const refundedTickets = await models.Ticket.refund(ticketsIds, withWarehouse, myOptions); if (tx) await tx.commit(); diff --git a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js index 35f2b4023..3d0ea6809 100644 --- a/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js +++ b/modules/invoiceOut/back/methods/invoiceOut/specs/refund.spec.js @@ -3,6 +3,7 @@ const LoopBackContext = require('loopback-context'); describe('InvoiceOut refund()', () => { const userId = 5; + const withWarehouse = true; const activeCtx = { accessToken: {userId: userId}, }; @@ -15,7 +16,7 @@ describe('InvoiceOut refund()', () => { const options = {transaction: tx}; try { - const result = await models.InvoiceOut.refund('T1111111', options); + const result = await models.InvoiceOut.refund('T1111111', withWarehouse, options); expect(result).toBeDefined(); diff --git a/modules/invoiceOut/front/descriptor-menu/index.html b/modules/invoiceOut/front/descriptor-menu/index.html index 389fcf81b..106f8e3cc 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.html +++ b/modules/invoiceOut/front/descriptor-menu/index.html @@ -76,14 +76,27 @@ translate> Show CITES letter - - Refund + Refund... + + + + with warehouse + + + without warehouse + + + @@ -97,12 +110,7 @@ on-accept="$ctrl.bookInvoiceOut()" question="Are you sure you want to book this invoice?"> - - - @@ -148,4 +156,4 @@ - \ No newline at end of file + diff --git a/modules/invoiceOut/front/descriptor-menu/index.js b/modules/invoiceOut/front/descriptor-menu/index.js index 57ea653a8..38c3c9434 100644 --- a/modules/invoiceOut/front/descriptor-menu/index.js +++ b/modules/invoiceOut/front/descriptor-menu/index.js @@ -114,9 +114,9 @@ class Controller extends Section { }); } - refundInvoiceOut() { + refundInvoiceOut(withWarehouse) { const query = 'InvoiceOuts/refund'; - const params = {ref: this.invoiceOut.ref}; + const params = {ref: this.invoiceOut.ref, withWarehouse: withWarehouse}; this.$http.post(query, params).then(res => { const refundTicket = res.data; this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { diff --git a/modules/invoiceOut/front/descriptor-menu/locale/es.yml b/modules/invoiceOut/front/descriptor-menu/locale/es.yml index df0ba57cf..393efd58c 100644 --- a/modules/invoiceOut/front/descriptor-menu/locale/es.yml +++ b/modules/invoiceOut/front/descriptor-menu/locale/es.yml @@ -13,10 +13,11 @@ InvoiceOut deleted: Factura eliminada Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura? Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura? InvoiceOut booked: Factura asentada -Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? +Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura? Are you sure you want to refund this invoice?: Estas seguro de querer abonar esta factura? Create a single ticket with all the content of the current invoice: Crear un ticket unico con todo el contenido de la factura actual Regenerate PDF invoice: Regenerar PDF factura The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado The email can't be empty: El correo no puede estar vacío The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}" +Refund...: Abono... diff --git a/modules/ticket/back/methods/sale/refund.js b/modules/ticket/back/methods/sale/refund.js index 18ccee976..e84232752 100644 --- a/modules/ticket/back/methods/sale/refund.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -11,6 +11,11 @@ module.exports = Self => { { arg: 'servicesIds', type: ['number'] + }, + { + arg: 'withWarehouse', + type: 'boolean', + required: true } ], returns: { @@ -23,7 +28,7 @@ module.exports = Self => { } }); - Self.refund = async(salesIds, servicesIds, options) => { + Self.refund = async(salesIds, servicesIds, withWarehouse, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -65,7 +70,7 @@ module.exports = Self => { const now = Date.vnNew(); const [firstTicketId] = ticketsIds; - const refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, myOptions); + const refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions); for (const sale of sales) { const createdSale = await models.Sale.create({ @@ -113,7 +118,7 @@ module.exports = Self => { } }; - async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, myOptions) { + async function createTicketRefund(ticketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions) { const models = Self.app.models; const filter = {include: {relation: 'address'}}; @@ -125,7 +130,7 @@ module.exports = Self => { addressFk: ticket.address().id, agencyModeFk: refundAgencyMode.id, nickname: ticket.address().nickname, - warehouseFk: ticket.warehouseFk, + warehouseFk: withWarehouse ? ticket.warehouseFk : null, companyFk: ticket.companyFk, landed: now, zoneFk: refoundZoneId diff --git a/modules/ticket/back/methods/sale/specs/refund.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js index 83b3755e2..b870a36f7 100644 --- a/modules/ticket/back/methods/sale/specs/refund.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -6,8 +6,8 @@ describe('Sale refund()', () => { const activeCtx = { accessToken: {userId: userId}, }; - const servicesIds = [3]; + const withWarehouse = true; beforeEach(() => { spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({ @@ -22,7 +22,7 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; - const refundedTicket = await models.Sale.refund(salesIds, servicesIds, options); + const refundedTicket = await models.Sale.refund(salesIds, servicesIds, withWarehouse, options); expect(refundedTicket).toBeDefined(); @@ -40,7 +40,7 @@ describe('Sale refund()', () => { try { const options = {transaction: tx}; - const ticket = await models.Sale.refund(salesIds, servicesIds, options); + const ticket = await models.Sale.refund(salesIds, servicesIds, withWarehouse, options); const refundedTicket = await models.Ticket.findOne({ where: { diff --git a/modules/ticket/back/methods/ticket/refund.js b/modules/ticket/back/methods/ticket/refund.js index 91f48cfd6..fe17b7101 100644 --- a/modules/ticket/back/methods/ticket/refund.js +++ b/modules/ticket/back/methods/ticket/refund.js @@ -7,6 +7,11 @@ module.exports = Self => { arg: 'ticketsIds', type: ['number'], required: true + }, + { + arg: 'withWarehouse', + type: 'boolean', + required: true } ], returns: { @@ -19,7 +24,7 @@ module.exports = Self => { } }); - Self.refund = async(ticketsIds, options) => { + Self.refund = async(ticketsIds, withWarehouse, options) => { const models = Self.app.models; const myOptions = {}; let tx; @@ -41,7 +46,7 @@ module.exports = Self => { const services = await models.TicketService.find(filter, myOptions); const servicesIds = services.map(service => service.id); - const refundedTickets = await models.Sale.refund(salesIds, servicesIds, myOptions); + const refundedTickets = await models.Sale.refund(salesIds, servicesIds, withWarehouse, myOptions); if (tx) await tx.commit(); diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index c2ebc3e3a..afa5db41a 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -141,12 +141,27 @@ translate> Recalculate components - - Refund all + Refund all... + + + + with warehouse + + + without warehouse + + + @@ -319,14 +334,6 @@ message="Recalculate components"> - - - - this.vnApp.showSuccess(this.$t('Data saved!'))); } - async refund() { - const params = {ticketsIds: [this.id]}; + refund(withWarehouse) { + const params = {ticketsIds: [this.id], withWarehouse: withWarehouse}; const query = 'Tickets/refund'; - return this.$http.post(query, params).then(res => { - const refundTicket = res.data; - this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { - ticketId: refundTicket.id - })); - this.$state.go('ticket.card.sale', {id: refundTicket.id}); - }); + return this.$http.post(query, params) + .then(res => { + const refundTicket = res.data; + this.vnApp.showSuccess(this.$t('The following refund ticket have been created', { + ticketId: refundTicket.id + })); + this.$state.go('ticket.card.sale', {id: refundTicket.id}); + }); } onSmsSend(sms) { diff --git a/modules/ticket/front/descriptor-menu/locale/es.yml b/modules/ticket/front/descriptor-menu/locale/es.yml index b51637524..3830523cf 100644 --- a/modules/ticket/front/descriptor-menu/locale/es.yml +++ b/modules/ticket/front/descriptor-menu/locale/es.yml @@ -10,7 +10,9 @@ Send CSV: Enviar CSV Send CSV Delivery Note: Enviar albarán en CSV Send PDF Delivery Note: Enviar albarán en PDF Show Proforma: Ver proforma -Refund all: Abonar todo +Refund all...: Abonar todo... +with warehouse: con almacén +without warehouse: sin almacén Invoice sent: Factura enviada The following refund ticket have been created: "Se ha creado siguiente ticket de abono: {{ticketId}}" Transfer client: Transferir cliente @@ -18,3 +20,4 @@ SMS Notify changes: SMS Notificar cambios PDF sent!: ¡PDF enviado! Already exist signed delivery note: Ya existe albarán de entrega firmado Are you sure you want to replace this delivery note?: ¿Seguro que quieres reemplazar este albarán de entrega? +Create a single ticket with all the content of the current ticket: Crea un ticket único con todo el contenido del ticket actual diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 7d14a4fa3..f50ef10a5 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -529,11 +529,28 @@ ng-if="$ctrl.isEditable && $ctrl.hasReserves()"> Unmark as reserved - - Refund - + + Refund... + + + + with warehouse + + + without warehouse + + + + diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 72dfb0329..88a59e605 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -520,13 +520,12 @@ class Controller extends Section { }); } - createRefund() { + createRefund(withWarehouse) { const sales = this.selectedValidSales(); if (!sales) return; const salesIds = sales.map(sale => sale.id); - - const params = {salesIds: salesIds}; + const params = {salesIds: salesIds, withWarehouse: withWarehouse}; const query = 'Sales/refund'; this.$http.post(query, params).then(res => { const refundTicket = res.data; diff --git a/modules/ticket/front/sale/locale/es.yml b/modules/ticket/front/sale/locale/es.yml index 6eb558a56..0b1fd84ea 100644 --- a/modules/ticket/front/sale/locale/es.yml +++ b/modules/ticket/front/sale/locale/es.yml @@ -36,10 +36,10 @@ Warehouse: Almacen Agency: Agencia Shipped: F. envio Packaging: Encajado -Refund: Abono +Refund...: Abono... Promotion mana: Maná promoción Claim mana: Maná reclamación History: Historial Do you want to continue?: ¿Desea continuar? Claim out of time: Reclamación fuera de plazo -Do you want to create a claim?: ¿Quieres crear una reclamación? \ No newline at end of file +Do you want to create a claim?: ¿Quieres crear una reclamación?