3372-ticket_sale multi-check for recalculatePrice #811
|
@ -0,0 +1,118 @@
|
|||
DROP PROCEDURE IF EXISTS `vn`.`sale_calculateComponentSalix`;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`sale_calculateComponentSalix`()
|
||||
proc: BEGIN
|
||||
/**
|
||||
* Actualiza los componentes
|
||||
*
|
||||
* @table tmp.recalculateSales
|
||||
*/
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vWarehouseFk SMALLINT;
|
||||
DECLARE vAgencyModeFk INT;
|
||||
DECLARE vAddressFk INT;
|
||||
DECLARE vTicketFk BIGINT;
|
||||
DECLARE vItemFk BIGINT;
|
||||
DECLARE vLanded DATE;
|
||||
DECLARE vIsEditable BOOLEAN;
|
||||
DECLARE vZoneFk INTEGER;
|
||||
DECLARE vOption INTEGER;
|
||||
|
||||
DECLARE vSale INTEGER;
|
||||
DECLARE vDone BOOL DEFAULT FALSE;
|
||||
|
||||
DECLARE vCur CURSOR FOR
|
||||
SELECT id from tmp.recalculateSales;
|
||||
|
||||
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||
|
||||
OPEN vCur;
|
||||
|
||||
l: LOOP
|
||||
SET vDone = FALSE;
|
||||
FETCH vCur INTO vSale;
|
||||
|
||||
IF vDone THEN
|
||||
LEAVE l;
|
||||
END IF;
|
||||
|
||||
SELECT t.refFk IS NULL AND (IFNULL(ts.alertLevel, 0) = 0 OR s.price = 0),
|
||||
s.ticketFk,
|
||||
s.itemFk ,
|
||||
t.zoneFk,
|
||||
t.warehouseFk,
|
||||
t.shipped,
|
||||
t.addressFk,
|
||||
t.agencyModeFk,
|
||||
t.landed
|
||||
INTO vIsEditable,
|
||||
vTicketFk,
|
||||
vItemFk,
|
||||
vZoneFk,
|
||||
vWarehouseFk,
|
||||
vShipped,
|
||||
vAddressFk,
|
||||
vAgencyModeFk,
|
||||
vLanded
|
||||
FROM ticket t
|
||||
JOIN sale s ON s.ticketFk = t.id
|
||||
LEFT JOIN ticketState ts ON ts.ticketFk = t.id
|
||||
WHERE s.id = vSale;
|
||||
|
||||
CALL zone_getLanded(vShipped, vAddressFk, vAgencyModeFk, vWarehouseFk, TRUE);
|
||||
|
||||
IF (SELECT COUNT(*) FROM tmp.zoneGetLanded LIMIT 1) = 0 THEN
|
||||
CALL util.throw('There is no zone for these parameters');
|
||||
END IF;
|
||||
|
||||
IF vLanded IS NULL OR vZoneFk IS NULL THEN
|
||||
|
||||
UPDATE ticket t
|
||||
SET t.landed = (SELECT landed FROM tmp.zoneGetLanded LIMIT 1)
|
||||
WHERE t.id = vTicketFk AND t.landed IS NULL;
|
||||
|
||||
IF vZoneFk IS NULL THEN
|
||||
SELECT zoneFk INTO vZoneFk FROM tmp.zoneGetLanded LIMIT 1;
|
||||
UPDATE ticket t
|
||||
SET t.zoneFk = vZoneFk
|
||||
WHERE t.id = vTicketFk AND t.zoneFk IS NULL;
|
||||
END IF;
|
||||
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.zoneGetLanded;
|
||||
|
||||
-- rellena la tabla buyUltimate con la ultima compra
|
||||
CALL buyUltimate (vWarehouseFk, vShipped);
|
||||
|
||||
DELETE FROM tmp.buyUltimate WHERE itemFk != vItemFk;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
|
||||
CREATE TEMPORARY TABLE tmp.ticketLot
|
||||
SELECT vWarehouseFk warehouseFk, NULL available, vItemFk itemFk, buyFk, vZoneFk zoneFk
|
||||
FROM tmp.buyUltimate
|
||||
WHERE itemFk = vItemFk;
|
||||
|
||||
CALL catalog_componentPrepare();
|
||||
CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped, vWarehouseFk);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
|
||||
CREATE TEMPORARY TABLE tmp.sale
|
||||
(PRIMARY KEY (saleFk)) ENGINE = MEMORY
|
||||
SELECT vSale saleFk,vWarehouseFk warehouseFk;
|
||||
|
||||
SET vOption = IF(vIsEditable, 1, 6);
|
||||
|
||||
CALL ticketComponentUpdateSale(vOption);
|
||||
CALL catalog_componentPurge();
|
||||
|
||||
DROP TEMPORARY TABLE tmp.buyUltimate;
|
||||
DROP TEMPORARY TABLE tmp.sale;
|
||||
|
||||
END LOOP;
|
||||
CLOSE vCur;
|
||||
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -1,26 +1,26 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('recalculatePrice', {
|
||||
description: 'Calculates the price of a sale and its components',
|
||||
description: 'Calculates the price of sales and its components',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
description: 'The sale id',
|
||||
type: 'number',
|
||||
arg: 'sales',
|
||||
description: 'The sales',
|
||||
type: ['object'],
|
||||
required: true,
|
||||
http: {source: 'path'}
|
||||
http: {source: 'body'}
|
||||
}],
|
||||
returns: {
|
||||
type: 'Number',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/recalculatePrice`,
|
||||
path: `/recalculatePrice`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.recalculatePrice = async(ctx, id, options) => {
|
||||
Self.recalculatePrice = async(ctx, sales, options) => {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
@ -34,18 +34,33 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
const sale = await Self.findById(id, null, myOptions);
|
||||
const isEditable = await models.Ticket.isEditable(ctx, sale.ticketFk, myOptions);
|
||||
const salesIds = [];
|
||||
const params = [];
|
||||
sales.forEach(sale => {
|
||||
salesIds.push(sale.id);
|
||||
params.push('?');
|
||||
});
|
||||
|
||||
const isEditable = await models.Ticket.isEditable(ctx, sales[0].ticketFk, myOptions);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const canEditSale = await models.Sale.canEdit(ctx, [id], myOptions);
|
||||
|
||||
const canEditSale = await models.Sale.canEdit(ctx, sales, myOptions);
|
||||
if (!canEditSale)
|
||||
throw new UserError(`Sale(s) blocked, please contact production`);
|
||||
|
||||
const recalculation = await Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id], myOptions);
|
||||
const paramsString = params.join();
|
||||
|
||||
const query = `
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.recalculateSales;
|
||||
CREATE TEMPORARY TABLE tmp.recalculateSales
|
||||
SELECT s.id
|
||||
FROM sale s
|
||||
WHERE s.id IN (${paramsString});
|
||||
CALL vn.sale_calculateComponentSalix();
|
||||
DROP TEMPORARY TABLE tmp.recalculateSales;`;
|
||||
|
||||
const recalculation = await Self.rawSql(query, salesIds, myOptions);
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('sale recalculatePrice()', () => {
|
||||
const saleId = 7;
|
||||
|
||||
it('should update the sale price', async() => {
|
||||
const tx = await models.Sale.beginTransaction({});
|
||||
|
||||
const sales = [
|
||||
{id: 7, ticketFk: 11},
|
||||
{id: 8, ticketFk: 11}
|
||||
];
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const response = await models.Sale.recalculatePrice(ctx, saleId, options);
|
||||
const response = await models.Sale.recalculatePrice(ctx, sales, options);
|
||||
|
||||
expect(response.affectedRows).toBeDefined();
|
||||
expect(response[0].affectedRows).toBeDefined();
|
||||
expect(response[1].affectedRows).toBeDefined();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -29,8 +31,8 @@ describe('sale recalculatePrice()', () => {
|
|||
const options = {transaction: tx};
|
||||
|
||||
const ctx = {req: {accessToken: {userId: 9}}};
|
||||
const immutableSaleId = 1;
|
||||
await models.Sale.recalculatePrice(ctx, immutableSaleId, options);
|
||||
const immutableSale = [{id: 1, ticketFk: 1}];
|
||||
await models.Sale.recalculatePrice(ctx, immutableSale, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -451,11 +451,14 @@ class Controller extends Section {
|
|||
|
||||
calculateSalePrice() {
|
||||
const sales = this.selectedValidSales();
|
||||
sales.forEach(sale => {
|
||||
this.$http.post(`Sales/${sale.id}/recalculatePrice`);
|
||||
});
|
||||
if (!sales) return;
|
||||
|
||||
const params = sales;
|
||||
alexm marked this conversation as resolved
|
||||
const query = `Sales/recalculatePrice`;
|
||||
this.$http.post(query, params).then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||
this.$.model.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
itemSearchFunc($search) {
|
||||
|
|
|
@ -688,10 +688,12 @@ describe('Ticket', () => {
|
|||
jest.spyOn(controller.vnApp, 'showSuccess').mockReturnThis();
|
||||
jest.spyOn(controller.$.model, 'refresh').mockReturnThis();
|
||||
|
||||
const selectedSale = controller.sales[0];
|
||||
selectedSale.checked = true;
|
||||
const selectedSaleOne = controller.sales[0];
|
||||
const selectedSaleTwo = controller.sales[1];
|
||||
selectedSaleOne.checked = true;
|
||||
selectedSaleTwo.checked = true;
|
||||
|
||||
$httpBackend.expect('POST', `Sales/1/recalculatePrice`).respond(200);
|
||||
$httpBackend.expect('POST', `Sales/recalculatePrice`).respond(200);
|
||||
controller.calculateSalePrice();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
not needed