Merge pull request '#7710 - clone with ticket packaging' (!2878) from 7710-cloneWithTicketPackaging into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #2878 Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
commit
638a43d3e6
|
@ -0,0 +1,24 @@
|
|||
DELETE FROM `salix`.`ACL`
|
||||
WHERE `model` = 'Ticket'
|
||||
AND `property` = 'refund'
|
||||
AND `accessType` = 'WRITE'
|
||||
AND `permission` = 'ALLOW'
|
||||
AND `principalType` = 'ROLE'
|
||||
AND `principalId` = 'salesAssistant';
|
||||
|
||||
UPDATE `salix`.`ACL`
|
||||
SET `property` = 'cloneAll'
|
||||
WHERE `model` = 'Ticket'
|
||||
AND `property` = 'refund'
|
||||
AND `accessType` = 'WRITE'
|
||||
AND `permission` = 'ALLOW'
|
||||
AND `principalType` = 'ROLE'
|
||||
AND `principalId` IN ('invoicing', 'claimManager', 'logistic');
|
||||
|
||||
DELETE FROM `salix`.`ACL`
|
||||
WHERE `model` = 'Ticket'
|
||||
AND `property` = 'clone'
|
||||
AND `accessType` = 'WRITE'
|
||||
AND `permission` = 'ALLOW'
|
||||
AND `principalType` = 'ROLE'
|
||||
AND `principalId` = 'administrative';
|
|
@ -43,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(ctx, ticketsIds, withWarehouse, myOptions);
|
||||
const refundedTickets = await models.Ticket.cloneAll(ctx, ticketsIds, withWarehouse, true, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
|
|
|
@ -82,20 +82,12 @@ module.exports = Self => {
|
|||
myOptions.transaction = tx;
|
||||
}
|
||||
try {
|
||||
const filterRef = {where: {refFk: refFk}};
|
||||
const tickets = await models.Ticket.find(filterRef, myOptions);
|
||||
const tickets = await models.Ticket.find({where: {refFk}}, myOptions);
|
||||
const ticketsIds = tickets.map(ticket => ticket.id);
|
||||
const refundTickets = await models.Ticket.refund(ctx, ticketsIds, null, myOptions);
|
||||
const refundTickets = await models.Ticket.cloneAll(ctx, ticketsIds, false, true, myOptions);
|
||||
|
||||
const filterTicket = {where: {ticketFk: {inq: ticketsIds}}};
|
||||
const clonedTickets = await models.Ticket.cloneAll(ctx, ticketsIds, false, false, myOptions);
|
||||
|
||||
const services = await models.TicketService.find(filterTicket, myOptions);
|
||||
const servicesIds = services.map(service => service.id);
|
||||
|
||||
const sales = await models.Sale.find(filterTicket, myOptions);
|
||||
const salesIds = sales.map(sale => sale.id);
|
||||
|
||||
const clonedTickets = await models.Sale.clone(ctx, salesIds, servicesIds, null, false, myOptions);
|
||||
const clonedTicketIds = [];
|
||||
|
||||
for (const clonedTicket of clonedTickets) {
|
||||
|
|
|
@ -88,28 +88,7 @@
|
|||
translate>
|
||||
Show CITES letter
|
||||
</vn-item>
|
||||
<vn-item class="dropdown"
|
||||
vn-click-stop="refundMenu.show($event, 'left')"
|
||||
vn-tooltip="Create a refund ticket for each ticket on the current invoice"
|
||||
vn-acl="invoicing, claimManager, salesAssistant"
|
||||
vn-acl-action="remove"
|
||||
translate>
|
||||
Refund...
|
||||
<vn-menu vn-id="refundMenu">
|
||||
<vn-list>
|
||||
<vn-item
|
||||
ng-click="$ctrl.refundInvoiceOut(true)"
|
||||
translate>
|
||||
with warehouse
|
||||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="$ctrl.refundInvoiceOut(false)"
|
||||
translate>
|
||||
without warehouse
|
||||
</vn-item>
|
||||
</vn-list>
|
||||
</vn-menu>
|
||||
</vn-item>
|
||||
|
||||
</vn-list>
|
||||
</vn-menu>
|
||||
<vn-confirm
|
||||
|
|
|
@ -135,21 +135,6 @@ class Controller extends Section {
|
|||
});
|
||||
}
|
||||
|
||||
refundInvoiceOut(withWarehouse) {
|
||||
const query = 'InvoiceOuts/refund';
|
||||
const params = {ref: this.invoiceOut.ref, withWarehouse: withWarehouse};
|
||||
this.$http.post(query, params).then(res => {
|
||||
const tickets = res.data;
|
||||
const refundTickets = tickets.map(ticket => ticket.id);
|
||||
|
||||
this.vnApp.showSuccess(this.$t('The following refund tickets have been created', {
|
||||
ticketId: refundTickets.join(',')
|
||||
}));
|
||||
if (refundTickets.length == 1)
|
||||
this.$state.go('ticket.card.sale', {id: refundTickets[0]});
|
||||
});
|
||||
}
|
||||
|
||||
transferInvoice() {
|
||||
const params = {
|
||||
id: this.invoiceOut.id,
|
||||
|
|
|
@ -105,17 +105,4 @@ describe('vnInvoiceOutDescriptorMenu', () => {
|
|||
expect(controller.vnApp.showMessage).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('refundInvoiceOut()', () => {
|
||||
it('should make a query and show a success message', () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
const params = {ref: controller.invoiceOut.ref};
|
||||
|
||||
$httpBackend.expectPOST(`InvoiceOuts/refund`, params).respond([{id: 1}, {id: 2}]);
|
||||
controller.refundInvoiceOut();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,40 +1,25 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('clone', {
|
||||
description: 'Clone sales and services provided',
|
||||
description: 'Clone sales, services, and ticket packaging provided',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'salesIds',
|
||||
type: ['number'],
|
||||
}, {
|
||||
arg: 'servicesIds',
|
||||
type: ['number']
|
||||
}, {
|
||||
arg: 'withWarehouse',
|
||||
type: 'boolean',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'negative',
|
||||
type: 'boolean'
|
||||
}
|
||||
{arg: 'salesIds', type: ['number']},
|
||||
{arg: 'servicesIds', type: ['number']},
|
||||
{arg: 'ticketPackagingIds', type: ['number']},
|
||||
{arg: 'withWarehouse', type: 'boolean', required: true},
|
||||
{arg: 'negative', type: 'boolean'}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/clone`,
|
||||
verb: 'POST'
|
||||
}
|
||||
returns: {type: ['object'], root: true},
|
||||
http: {path: `/clone`, verb: 'POST'}
|
||||
});
|
||||
Self.clone = async(ctx, salesIds, servicesIds, withWarehouse, negative, options) => {
|
||||
|
||||
Self.clone = async(ctx, salesIds, servicesIds, ticketPackagingIds, withWarehouse, negative, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
const newTickets = [];
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
if (typeof options === 'object') Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
|
@ -44,8 +29,9 @@ module.exports = Self => {
|
|||
try {
|
||||
let sales;
|
||||
let services;
|
||||
let ticketPackaging;
|
||||
|
||||
if (salesIds && salesIds.length) {
|
||||
if (salesIds?.length) {
|
||||
sales = await models.Sale.find({
|
||||
where: {id: {inq: salesIds}},
|
||||
include: {
|
||||
|
@ -57,12 +43,18 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
}
|
||||
|
||||
if (servicesIds && servicesIds.length) {
|
||||
if (servicesIds?.length) {
|
||||
services = await models.TicketService.find({
|
||||
where: {id: {inq: servicesIds}}
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
if (ticketPackagingIds?.length) {
|
||||
ticketPackaging = await models.TicketPackaging.find({
|
||||
where: {id: {inq: ticketPackagingIds}}
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
let ticketsIds = sales ?
|
||||
[...new Set(sales.map(sale => sale.ticketFk))] :
|
||||
[...new Set(services.map(service => service.ticketFk))];
|
||||
|
@ -74,12 +66,12 @@ module.exports = Self => {
|
|||
ctx,
|
||||
ticketId,
|
||||
withWarehouse,
|
||||
negative,
|
||||
myOptions
|
||||
);
|
||||
newTickets.push(newTicket);
|
||||
mappedTickets.set(ticketId, newTicket.id);
|
||||
}
|
||||
|
||||
if (sales) {
|
||||
for (const sale of sales) {
|
||||
const newTicketId = mappedTickets.get(sale.ticketFk);
|
||||
|
@ -107,7 +99,7 @@ module.exports = Self => {
|
|||
|
||||
await models.TicketService.create({
|
||||
description: service.description,
|
||||
quantity: negative ? - service.quantity : service.quantity,
|
||||
quantity: negative ? -service.quantity : service.quantity,
|
||||
price: service.price,
|
||||
taxClassFk: service.taxClassFk,
|
||||
ticketFk: newTicketId,
|
||||
|
@ -116,6 +108,18 @@ module.exports = Self => {
|
|||
}
|
||||
}
|
||||
|
||||
if (ticketPackaging) {
|
||||
for (const packaging of ticketPackaging) {
|
||||
const newTicketId = mappedTickets.get(packaging.ticketFk);
|
||||
|
||||
await models.TicketPackaging.create({
|
||||
ticketFk: newTicketId,
|
||||
packagingFk: packaging.packagingFk,
|
||||
quantity: negative ? -packaging.quantity : packaging.quantity
|
||||
}, myOptions);
|
||||
}
|
||||
}
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return newTickets;
|
||||
|
@ -124,13 +128,7 @@ module.exports = Self => {
|
|||
throw e;
|
||||
}
|
||||
|
||||
async function createTicket(
|
||||
ctx,
|
||||
ticketId,
|
||||
withWarehouse,
|
||||
negative,
|
||||
myOptions
|
||||
) {
|
||||
async function createTicket(ctx, ticketId, withWarehouse, myOptions) {
|
||||
const models = Self.app.models;
|
||||
const now = Date.vnNew();
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('Ticket cloning - clone function', () => {
|
|||
const servicesIds = [];
|
||||
const withWarehouse = true;
|
||||
const negative = false;
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, withWarehouse, negative, options);
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, null, withWarehouse, negative, options);
|
||||
|
||||
expect(newTickets).toBeDefined();
|
||||
expect(newTickets.length).toBeGreaterThan(0);
|
||||
|
@ -30,7 +30,7 @@ describe('Ticket cloning - clone function', () => {
|
|||
const negative = true;
|
||||
const salesIds = [7, 8];
|
||||
const servicesIds = [];
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, false, negative, options);
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, null, false, negative, options);
|
||||
|
||||
for (const ticket of newTickets) {
|
||||
const sales = await models.Sale.find({where: {ticketFk: ticket.id}}, options);
|
||||
|
@ -43,7 +43,7 @@ describe('Ticket cloning - clone function', () => {
|
|||
it('should create new components and services for cloned tickets', async() => {
|
||||
const servicesIds = [2];
|
||||
const salesIds = [5];
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, false, false, options);
|
||||
const newTickets = await models.Sale.clone(ctx, salesIds, servicesIds, null, false, false, options);
|
||||
|
||||
for (const ticket of newTickets) {
|
||||
const sale = await models.Sale.findOne({where: {ticketFk: ticket.id}}, options);
|
||||
|
@ -58,7 +58,7 @@ describe('Ticket cloning - clone function', () => {
|
|||
it('should create a ticket without sales', async() => {
|
||||
const servicesIds = [4];
|
||||
|
||||
const tickets = await models.Sale.clone(ctx, null, servicesIds, false, false, options);
|
||||
const tickets = await models.Sale.clone(ctx, null, servicesIds, null, false, false, options);
|
||||
const refundedTicket = await getTicketRefund(tickets[0].id, options);
|
||||
|
||||
expect(refundedTicket).toBeDefined();
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('clone', {
|
||||
description: 'clone a ticket and return the new ticket id',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'shipped',
|
||||
type: 'date',
|
||||
}, {
|
||||
arg: 'withWarehouse',
|
||||
type: 'boolean',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: 'number',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/clone`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.clone = async(ctx, id, shipped, withWarehouse, options) => {
|
||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const [, [{clonedTicketId}]] = await Self.rawSql(`
|
||||
CALL vn.ticket_cloneAll(?, ?, ?, @clonedTicketId);
|
||||
SELECT @clonedTicketId clonedTicketId;`,
|
||||
[id, shipped, withWarehouse], myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
return clonedTicketId;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,77 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('cloneAll', {
|
||||
description: 'Clone tickets, sales, services and packages',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'ticketsIds',
|
||||
type: ['number'],
|
||||
required: true,
|
||||
description: 'IDs of the tickets to clone'
|
||||
},
|
||||
{
|
||||
arg: 'withWarehouse',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
description: 'true: keep original warehouse; false: set to null'
|
||||
},
|
||||
{
|
||||
arg: 'negative',
|
||||
type: 'boolean',
|
||||
required: true,
|
||||
description: 'true: invert quantities; false: keep as is.'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true,
|
||||
description: 'The cloned tickets with associated data'
|
||||
},
|
||||
http: {
|
||||
path: `/cloneAll`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.cloneAll = async(ctx, ticketsIds, withWarehouse, negative, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = typeof options == 'object' ? {...options} : {};
|
||||
let tx;
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const filter = {where: {ticketFk: {inq: ticketsIds}}};
|
||||
|
||||
const [sales, services, ticketPackaging] = await Promise.all([
|
||||
models.Sale.find(filter, myOptions),
|
||||
models.TicketService.find(filter, myOptions),
|
||||
models.TicketPackaging.find(filter, myOptions)
|
||||
]);
|
||||
|
||||
const salesIds = sales.map(({id}) => id);
|
||||
const servicesIds = services.map(({id}) => id);
|
||||
const ticketPackagingIds = ticketPackaging.map(({id}) => id);
|
||||
|
||||
const clonedTickets = await models.Sale.clone(
|
||||
ctx,
|
||||
salesIds,
|
||||
servicesIds,
|
||||
ticketPackagingIds,
|
||||
withWarehouse,
|
||||
negative,
|
||||
myOptions
|
||||
);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return clonedTickets;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -1,58 +0,0 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('refund', {
|
||||
description: 'Create refund tickets with all their sales and services',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'ticketsIds',
|
||||
type: ['number'],
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'withWarehouse',
|
||||
type: 'boolean',
|
||||
required: true
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/refund`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.refund = async(ctx, ticketsIds, withWarehouse, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
try {
|
||||
const filter = {where: {ticketFk: {inq: ticketsIds}}};
|
||||
const sales = await models.Sale.find(filter, myOptions);
|
||||
const salesIds = sales.map(sale => sale.id);
|
||||
|
||||
const services = await models.TicketService.find(filter, myOptions);
|
||||
const servicesIds = services.map(service => service.id);
|
||||
|
||||
const refundedTickets = await models.Sale.clone(ctx, salesIds, servicesIds, withWarehouse, true, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return refundedTickets;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -1,43 +0,0 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('Ticket cloning - clone function', () => {
|
||||
const ctx = beforeAll.getCtx();
|
||||
let options;
|
||||
let tx;
|
||||
const ticketId = 1;
|
||||
const shipped = Date.vnNew();
|
||||
|
||||
beforeEach(async() => {
|
||||
options = {transaction: tx};
|
||||
tx = await models.Ticket.beginTransaction({});
|
||||
options.transaction = tx;
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should clone a new ticket without warehouse', async() => {
|
||||
const originalTicket = await models.Ticket.findById(ticketId, null, options);
|
||||
|
||||
const newTicketId = await models.Ticket.clone(ctx, ticketId, shipped, false, options);
|
||||
const newTicket = await models.Ticket.findById(newTicketId, null, options);
|
||||
|
||||
expect(newTicket.clientFk).toEqual(originalTicket.clientFk);
|
||||
expect(newTicket.companyFk).toEqual(originalTicket.companyFk);
|
||||
expect(newTicket.addressFk).toEqual(originalTicket.addressFk);
|
||||
expect(newTicket.warehouseFk).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should clone a new ticket with warehouse', async() => {
|
||||
const originalTicket = await models.Ticket.findById(ticketId, null, options);
|
||||
|
||||
const newTicketId = await models.Ticket.clone(ctx, ticketId, shipped, true, options);
|
||||
const newTicket = await models.Ticket.findById(newTicketId, null, options);
|
||||
|
||||
expect(newTicket.clientFk).toEqual(originalTicket.clientFk);
|
||||
expect(newTicket.companyFk).toEqual(originalTicket.companyFk);
|
||||
expect(newTicket.addressFk).toEqual(originalTicket.addressFk);
|
||||
expect(newTicket.warehouseFk).toEqual(originalTicket.warehouseFk);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('Ticket cloning - cloneAll function', () => {
|
||||
const activeCtx = {
|
||||
accessToken: {userId: 1},
|
||||
http: {
|
||||
req: {
|
||||
headers: {origin: 'http://localhost'}
|
||||
}
|
||||
}
|
||||
};
|
||||
const ctx = {req: activeCtx};
|
||||
let options;
|
||||
let tx;
|
||||
const ticketIds = [1, 2];
|
||||
const withWarehouse = true;
|
||||
const negative = false;
|
||||
|
||||
beforeEach(async() => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({active: ctx.req});
|
||||
tx = await models.Ticket.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
if (tx)
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should clone all provided tickets with their associated sales, services, and packages', async() => {
|
||||
const originalTickets = await models.Ticket.find({where: {id: {inq: ticketIds}}}, options);
|
||||
const originalSales = await models.Sale.find({where: {ticketFk: {inq: ticketIds}}}, options);
|
||||
const originalServices = await models.TicketService.find({where: {ticketFk: {inq: ticketIds}}}, options);
|
||||
const originalTicketPackaging =
|
||||
await models.TicketPackaging.find({where: {ticketFk: {inq: ticketIds}}}, options);
|
||||
|
||||
// Pass the ctx correctly to the cloneAll function
|
||||
const clonedTickets = await models.Ticket.cloneAll(ctx, ticketIds, withWarehouse, negative, options);
|
||||
|
||||
expect(clonedTickets.length).toEqual(originalTickets.length);
|
||||
|
||||
const clonedSales = await models.Sale.find({where: {ticketFk: {inq: clonedTickets.map(t => t.id)}}}, options);
|
||||
const clonedServices =
|
||||
await models.TicketService.find({where: {ticketFk: {inq: clonedTickets.map(t => t.id)}}}, options);
|
||||
const clonedTicketPackaging =
|
||||
await models.TicketPackaging.find({where: {ticketFk: {inq: clonedTickets.map(t => t.id)}}}, options);
|
||||
|
||||
expect(clonedSales.length).toEqual(originalSales.length);
|
||||
expect(clonedServices.length).toEqual(originalServices.length);
|
||||
expect(clonedTicketPackaging.length).toEqual(originalTicketPackaging.length);
|
||||
});
|
||||
});
|
|
@ -26,7 +26,7 @@ module.exports = function(Self) {
|
|||
require('../methods/ticket/isLocked')(Self);
|
||||
require('../methods/ticket/freightCost')(Self);
|
||||
require('../methods/ticket/getComponentsSum')(Self);
|
||||
require('../methods/ticket/refund')(Self);
|
||||
require('../methods/ticket/cloneAll')(Self);
|
||||
require('../methods/ticket/deliveryNotePdf')(Self);
|
||||
require('../methods/ticket/deliveryNoteEmail')(Self);
|
||||
require('../methods/ticket/deliveryNoteCsv')(Self);
|
||||
|
@ -46,5 +46,4 @@ module.exports = function(Self) {
|
|||
require('../methods/ticket/invoiceTicketsAndPdf')(Self);
|
||||
require('../methods/ticket/docuwareDownload')(Self);
|
||||
require('../methods/ticket/myLastModified')(Self);
|
||||
require('../methods/ticket/clone')(Self);
|
||||
};
|
||||
|
|
|
@ -287,15 +287,24 @@ class Controller extends Section {
|
|||
}
|
||||
|
||||
refund(withWarehouse) {
|
||||
const params = {ticketsIds: [this.id], withWarehouse: withWarehouse};
|
||||
const query = 'Tickets/refund';
|
||||
const params = {
|
||||
ticketsIds: [this.id],
|
||||
withWarehouse: withWarehouse,
|
||||
negative: true // Asumimos que queremos cantidades negativas para reembolsos
|
||||
};
|
||||
const query = 'Tickets/cloneAll';
|
||||
return this.$http.post(query, params)
|
||||
.then(res => {
|
||||
const [refundTicket] = res.data;
|
||||
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
|
||||
this.vnApp.showSuccess(this.$t('The following refund ticket has been created', {
|
||||
ticketId: refundTicket.id
|
||||
}));
|
||||
this.$state.go('ticket.card.sale', {id: refundTicket.id});
|
||||
})
|
||||
.catch(error => {
|
||||
this.vnApp.showError(this.$t('Error creating refund ticket', {
|
||||
error: error.data?.error?.message || 'Unknown error'
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -217,24 +217,6 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('refund()', () => {
|
||||
it('should make a query and go to ticket.card.sale', () => {
|
||||
controller.$state.go = jest.fn();
|
||||
|
||||
controller._id = ticket.id;
|
||||
|
||||
const params = {
|
||||
ticketsIds: [16]
|
||||
};
|
||||
const response = {id: 99};
|
||||
$httpBackend.expectPOST('Tickets/refund', params).respond([response]);
|
||||
controller.refund();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', response);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendChangesSms()', () => {
|
||||
it('should make a query and open the sms dialog', () => {
|
||||
controller.$.sms = {open: () => {}};
|
||||
|
|
Loading…
Reference in New Issue