ticket.basicData Select zone for productionBoss #1604
gitea/salix/dev This commit looks good
Details
gitea/salix/dev This commit looks good
Details
This commit is contained in:
parent
ab2a47d363
commit
64a4e5f43d
|
@ -0,0 +1,38 @@
|
|||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_componentMakeUpdate`(
|
||||
vTicketFk INT,
|
||||
vClientFk INT,
|
||||
vAgencyModeFk INT,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk TINYINT,
|
||||
vCompanyFk SMALLINT,
|
||||
vShipped DATETIME,
|
||||
vLanded DATE,
|
||||
vIsDeleted BOOLEAN,
|
||||
vHasToBeUnrouted BOOLEAN,
|
||||
vOption INT)
|
||||
BEGIN
|
||||
|
||||
CALL vn.ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk);
|
||||
CALL vn.ticket_componentUpdate (
|
||||
vTicketFk,
|
||||
vClientFk,
|
||||
vAgencyModeFk,
|
||||
vAddressFk,
|
||||
vZoneFk,
|
||||
vWarehouseFk,
|
||||
vCompanyFk,
|
||||
vShipped,
|
||||
vLanded,
|
||||
vIsDeleted,
|
||||
vHasToBeUnrouted,
|
||||
vOption
|
||||
);
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.ticketComponent,
|
||||
tmp.ticketComponentPrice;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
|
@ -0,0 +1,111 @@
|
|||
USE `vn`;
|
||||
DROP procedure IF EXISTS `ticket_componentPreview`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_componentPreview`(
|
||||
vTicketFk INT,
|
||||
vLanded DATE,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk SMALLINT)
|
||||
BEGIN
|
||||
/**
|
||||
* Calcula los componentes de los articulos de un ticket
|
||||
*
|
||||
* @param vTicketFk id del ticket
|
||||
* @param vLanded nueva fecha de entrega
|
||||
* @param vAddressFk nuevo consignatario
|
||||
* @param vZoneFk nueva zona
|
||||
* @param vWarehouseFk nuevo warehouse
|
||||
*
|
||||
* @return tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
*/
|
||||
DECLARE vShipped DATE;
|
||||
DECLARE vBuyOrderItem INT DEFAULT 100;
|
||||
|
||||
DECLARE vHasDataChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasAddressChanged BOOL;
|
||||
DECLARE vHasZoneChanged BOOL DEFAULT FALSE;
|
||||
DECLARE vHasWarehouseChanged BOOL DEFAULT FALSE;
|
||||
|
||||
DECLARE vAddressTypeRateFk INT DEFAULT NULL;
|
||||
DECLARE vAgencyModeTypeRateFk INT DEFAULT NULL;
|
||||
|
||||
DECLARE vHasChangeAll BOOL DEFAULT FALSE;
|
||||
|
||||
SELECT DATE(landed) <> vLanded,
|
||||
addressFk <> vAddressFk,
|
||||
zoneFk <> vZoneFk,
|
||||
warehouseFk <> vWarehouseFk
|
||||
INTO
|
||||
vHasDataChanged,
|
||||
vHasAddressChanged,
|
||||
vHasZoneChanged,
|
||||
vHasWarehouseChanged
|
||||
FROM vn.ticket t
|
||||
WHERE t.id = vTicketFk;
|
||||
|
||||
IF vHasDataChanged OR vHasWarehouseChanged THEN
|
||||
SET vHasChangeAll = TRUE;
|
||||
END IF;
|
||||
|
||||
IF vHasAddressChanged THEN
|
||||
SET vAddressTypeRateFk = 5;
|
||||
END IF;
|
||||
|
||||
IF vHasZoneChanged THEN
|
||||
SET vAgencyModeTypeRateFk = 6;
|
||||
END IF;
|
||||
|
||||
SELECT TIMESTAMPADD(DAY, -travelingDays, vLanded) INTO vShipped
|
||||
FROM zone
|
||||
WHERE id = vZoneFk;
|
||||
|
||||
CALL buyUltimate(vWarehouseFk, vShipped);
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticketLot;
|
||||
CREATE TEMPORARY TABLE tmp.ticketLot ENGINE = MEMORY (
|
||||
SELECT
|
||||
vWarehouseFk AS warehouseFk,
|
||||
NULL AS available,
|
||||
s.itemFk,
|
||||
bu.buyFk
|
||||
FROM sale s
|
||||
LEFT JOIN tmp.buyUltimate bu ON bu.itemFk = s.itemFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
AND s.itemFk != vBuyOrderItem
|
||||
GROUP BY bu.warehouseFk, bu.itemFk);
|
||||
|
||||
CALL catalog_componentCalculate(vZoneFk, vAddressFk, vShipped);
|
||||
|
||||
REPLACE INTO tmp.ticketComponent (warehouseFk, itemFk, componentFk, cost)
|
||||
SELECT t.warehouseFk, s.itemFk, sc.componentFk, sc.value
|
||||
FROM saleComponent sc
|
||||
JOIN sale s ON s.id = sc.saleFk
|
||||
JOIN ticket t ON t.id = s.ticketFk
|
||||
JOIN componentRate cr ON cr.id = sc.componentFk
|
||||
WHERE s.ticketFk = vTicketFk
|
||||
AND (cr.isRenewable = FALSE
|
||||
OR
|
||||
(NOT vHasChangeAll
|
||||
AND (NOT (cr.componentTypeRate <=> vAddressTypeRateFk
|
||||
OR cr.componentTypeRate <=> vAgencyModeTypeRateFk))));
|
||||
|
||||
SET @shipped = vShipped;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.buyUltimate,
|
||||
tmp.ticketLot;
|
||||
|
||||
IF vShipped IS NULL THEN
|
||||
CALL util.throw('NO_ZONE_AVAILABLE');
|
||||
END IF;
|
||||
|
||||
IF vShipped < CURDATE() THEN
|
||||
CALL util.throw('ERROR_PAST_SHIPMENT');
|
||||
END IF;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
DROP procedure IF EXISTS `vn`.`ticket_priceDifference`;
|
||||
|
||||
DELIMITER $$
|
||||
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_priceDifference`(
|
||||
vTicketFk INT,
|
||||
vLanded DATE,
|
||||
vAddressFk INT,
|
||||
vZoneFk INT,
|
||||
vWarehouseFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Devuelve las diferencias de precio
|
||||
* de los movimientos de un ticket.
|
||||
*
|
||||
* @param vTicketFk Id del ticket
|
||||
* @param vLanded Fecha de recepcion
|
||||
* @param vAddressFk Id del consignatario
|
||||
* @param vZoneFk Id de la zona
|
||||
* @param vWarehouseFk Id del almacén
|
||||
*/
|
||||
CALL vn.ticket_componentPreview(vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk);
|
||||
|
||||
SELECT s.itemFk,
|
||||
i.name,
|
||||
i.size,
|
||||
i.category,
|
||||
IFNULL(s.quantity, 0) AS quantity,
|
||||
IFNULL(s.price, 0) AS price,
|
||||
ROUND(SUM(tc.cost), 2) AS newPrice,
|
||||
s.quantity * (s.price - ROUND(SUM(tc.cost), 2)) difference,
|
||||
s.id AS saleFk
|
||||
FROM sale s
|
||||
JOIN item i ON i.id = s.itemFk
|
||||
JOIN ticket t ON t.id = s.ticketFk
|
||||
LEFT JOIN tmp.ticketComponent tc ON tc.itemFk = s.itemFk
|
||||
AND tc.warehouseFk = t.warehouseFk
|
||||
LEFT JOIN saleComponent sc ON sc.saleFk = s.id
|
||||
AND sc.componentFk = tc.componentFk
|
||||
LEFT JOIN componentRate cr ON cr.id = tc.componentFk
|
||||
WHERE
|
||||
t.id = vTicketFk
|
||||
AND IF(sc.componentFk IS NULL
|
||||
AND cr.classRate IS NOT NULL, FALSE, TRUE)
|
||||
GROUP BY s.id ORDER BY s.id;
|
||||
|
||||
DROP TEMPORARY TABLE
|
||||
tmp.ticketComponent,
|
||||
tmp.ticketComponentPrice;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
|
|
@ -1448,6 +1448,14 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `atenderFk`
|
|||
(3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, 4, 3.06, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
|
||||
(4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketServiceType`(`id`, `name`)
|
||||
VALUES
|
||||
(1, 'Porte Agencia'),
|
||||
(2, 'Portes Retorno'),
|
||||
(3, 'Porte Carry'),
|
||||
(4, 'Cargo FITOSANITARIO'),
|
||||
(5, 'Documentos');
|
||||
|
||||
INSERT INTO `vn`.`ticketService`(`id`, `description`, `quantity`, `price`, `taxClassFk`, `ticketFk`)
|
||||
VALUES
|
||||
(1, 'Documentos', 1, 2.00, 1, 1),
|
||||
|
|
|
@ -441,7 +441,8 @@ export default {
|
|||
basicDataButton: 'vn-left-menu a[ui-sref="ticket.card.basicData.stepOne"]',
|
||||
clientAutocomplete: 'vn-autocomplete[field="$ctrl.clientFk"]',
|
||||
addressAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.addressFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.ticket.agencyModeFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[field="$ctrl.agencyModeId"]',
|
||||
zoneAutocomplete: 'vn-autocomplete[field="$ctrl.zoneId"]',
|
||||
nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button',
|
||||
finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit',
|
||||
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
|
||||
|
|
|
@ -14,6 +14,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
it(`should edit the ticket agency then click next`, async() => {
|
||||
let url = await nightmare
|
||||
.autocompleteSearch(selectors.ticketBasicData.agencyAutocomplete, 'Silla247Expensive')
|
||||
.waitToGetProperty(`${selectors.ticketBasicData.zoneAutocomplete} input`, 'value')
|
||||
.waitToClick(selectors.ticketBasicData.nextStepButton)
|
||||
.waitForURL('data/step-two')
|
||||
.parsedUrl();
|
||||
|
|
|
@ -92,8 +92,6 @@ export default class Autocomplete extends Input {
|
|||
set field(value) {
|
||||
this._field = value;
|
||||
|
||||
if (!value) return;
|
||||
|
||||
this.refreshSelection();
|
||||
this.emit('change', {value});
|
||||
}
|
||||
|
|
|
@ -198,7 +198,9 @@ async function backendStatus() {
|
|||
timer = setInterval(() => {
|
||||
const url = `${e2eConfig.url}/api/Applications/status`;
|
||||
request.get(url, (err, res) => {
|
||||
if (res.body == 'true') {
|
||||
if (err || attempts > 100) // 250ms * 100 => 25s timeout
|
||||
throw new Error('Could not connect to backend');
|
||||
else if (res && res.body == 'true') {
|
||||
clearInterval(timer);
|
||||
resolve(attempts);
|
||||
} else
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
"Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF",
|
||||
"You can't create an order for a frozen client": "You can't create an order for a frozen client",
|
||||
"This address doesn't exist": "This address doesn't exist",
|
||||
"NO_AGENCY_AVAILABLE": "NO_AGENCY_AVAILABLE",
|
||||
"Warehouse cannot be blank": "Warehouse cannot be blank",
|
||||
"Agency cannot be blank": "Agency cannot be blank",
|
||||
"The IBAN does not have the correct format": "The IBAN does not have the correct format",
|
||||
|
|
|
@ -82,7 +82,8 @@
|
|||
"INFINITE_LOOP": "Existe una dependencia entre dos Jefes",
|
||||
"The sales of the current ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||
"The sales of the receiver ticket can't be modified": "Las lineas del ticket al que envias no pueden ser modificadas",
|
||||
"NO_AGENCY_AVAILABLE": "No hay agencias disponibles",
|
||||
"NO_AGENCY_AVAILABLE": "No hay una zona de reparto disponible con estos parámetros",
|
||||
"ERROR_PAST_SHIPMENT": "No puedes seleccionar una fecha de envío en pasado",
|
||||
"The current ticket can't be modified": "El ticket actual no puede ser modificado",
|
||||
"The sales of this ticket can't be modified": "Las lineas de este ticket no pueden ser modificadas",
|
||||
"Please select at least one sale": "Por favor selecciona al menos una linea",
|
||||
|
@ -95,5 +96,6 @@
|
|||
"This item is not available": "Este artículo no está disponible",
|
||||
"This postcode already exists": "Este código postal ya existe",
|
||||
"Concept cannot be blank": "El concepto no puede quedar en blanco",
|
||||
"File doesn't exists": "El archivo no existe"
|
||||
"File doesn't exists": "El archivo no existe",
|
||||
"You don't have privileges to change the zone": "No tienes permisos para cambiar la zona"
|
||||
}
|
|
@ -1,14 +1,10 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('getLanded', {
|
||||
Self.remoteMethod('getLanded', {
|
||||
description: 'Returns the first shipped and landed possible for params',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'params',
|
||||
type: 'Object',
|
||||
description: `shipped, addressFk, agencyModeFk, warehouseFk`
|
||||
}, {
|
||||
arg: 'shipped',
|
||||
type: 'date',
|
||||
required: true
|
||||
|
@ -38,15 +34,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getLanded = async(ctx, params) => {
|
||||
Self.getLanded = async(shipped, addressFk, agencyModeFk, warehouseFk) => {
|
||||
let stmts = [];
|
||||
params = params || ctx.args;
|
||||
stmts.push(new ParameterizedSQL(
|
||||
`CALL vn.zoneGetLanded(?, ?, ?, ?)`, [
|
||||
params.shipped,
|
||||
params.addressFk,
|
||||
params.agencyModeFk,
|
||||
params.warehouseFk
|
||||
shipped,
|
||||
addressFk,
|
||||
agencyModeFk,
|
||||
warehouseFk
|
||||
]
|
||||
));
|
||||
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('getShipped', {
|
||||
Self.remoteMethod('getShipped', {
|
||||
description: 'Returns the first shipped possible for params',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'params',
|
||||
type: 'Object',
|
||||
description: `landed, addressFk, agencyModeFk, warehouseFk`
|
||||
}, {
|
||||
arg: 'landed',
|
||||
type: 'date',
|
||||
required: true
|
||||
|
@ -36,15 +32,14 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getShipped = async(ctx, params)=> {
|
||||
params = params || ctx.args;
|
||||
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk)=> {
|
||||
let query = `CALL vn.zoneGetShipped(?, ?, ?, ?)`;
|
||||
let [response] = await Self.rawSql(query, [
|
||||
params.landed,
|
||||
params.addressFk,
|
||||
params.agencyModeFk,
|
||||
params.warehouseFk
|
||||
let [[response]] = await Self.rawSql(query, [
|
||||
landed,
|
||||
addressFk,
|
||||
agencyModeFk,
|
||||
warehouseFk
|
||||
]);
|
||||
return (response[0] && response[0].shipped && response[0].shipped.toJSON()) || null;
|
||||
return response;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,13 +2,11 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('agency getLanded()', () => {
|
||||
it('should return a landing date', async() => {
|
||||
let data = {
|
||||
shipped: new Date(),
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getLanded({}, data);
|
||||
const shipped = new Date();
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
let result = await app.models.Agency.getLanded(shipped, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result.landed).toBeDefined();
|
||||
});
|
||||
|
|
|
@ -2,13 +2,12 @@ const app = require('vn-loopback/server/server');
|
|||
|
||||
describe('agency getShipped()', () => {
|
||||
it('should return a shipment date', async() => {
|
||||
let data = {
|
||||
landed: new Date(),
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getShipped({}, data);
|
||||
const landed = new Date();
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
});
|
||||
|
@ -17,14 +16,13 @@ describe('agency getShipped()', () => {
|
|||
let newDate = new Date();
|
||||
newDate.setMonth(newDate.getMonth() - 1);
|
||||
|
||||
let data = {
|
||||
landed: newDate,
|
||||
addressFk: 121,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Agency.getShipped({}, data);
|
||||
const landed = newDate;
|
||||
const addressFk = 121;
|
||||
const agencyModeFk = 7;
|
||||
const warehouseFk = 1;
|
||||
|
||||
expect(result).toBeNull();
|
||||
let result = await app.models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@ module.exports = Self => {
|
|||
r.bankFk,
|
||||
u.nickname userNickname,
|
||||
r.clientFk,
|
||||
FALSE pdf,
|
||||
FALSE hasPdf,
|
||||
FALSE isInvoice
|
||||
FROM vn.receipt r
|
||||
LEFT JOIN vn.worker w ON w.id = r.workerFk
|
||||
|
@ -64,7 +64,7 @@ module.exports = Self => {
|
|||
NULL,
|
||||
NULL,
|
||||
i.clientFk,
|
||||
i.pdf,
|
||||
i.hasPdf,
|
||||
TRUE isInvoice
|
||||
FROM vn.invoiceOut i
|
||||
JOIN vn.company c ON c.id = i.companyFk
|
||||
|
|
|
@ -83,7 +83,7 @@
|
|||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td center>
|
||||
<a ng-show="balance.pdf"
|
||||
<a ng-show="balance.hasPdf"
|
||||
target="_blank"
|
||||
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.accessToken}}">
|
||||
<vn-icon-button
|
||||
|
|
|
@ -83,7 +83,7 @@ module.exports = Self => {
|
|||
case 'max':
|
||||
return {amount: {lte: value}};
|
||||
case 'hasPdf':
|
||||
return {'i.pdf': value};
|
||||
return {'i.hasPdf': value};
|
||||
case 'created':
|
||||
return {'i.created': value};
|
||||
case 'amount':
|
||||
|
@ -109,7 +109,7 @@ module.exports = Self => {
|
|||
i.created,
|
||||
i.dued,
|
||||
i.clientFk,
|
||||
i.pdf AS hasPdf,
|
||||
i.hasPdf,
|
||||
c.socialName AS clientSocialName,
|
||||
co.code AS companyCode
|
||||
FROM invoiceOut i
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('priceDifference', {
|
||||
description: 'Returns sales with price difference if the ticket is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'ticketFk',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'data',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: 'landed, addressFk, agencyModeFk',
|
||||
http: {source: 'body'}
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:ticketFk/priceDifference`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.priceDifference = async(ctx, ticketFk, data) => {
|
||||
let thisTicketIsEditable = await Self.app.models.Ticket.isEditable(ctx, ticketFk);
|
||||
if (!thisTicketIsEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
let filter = {
|
||||
where: {
|
||||
ticketFk: ticketFk
|
||||
},
|
||||
order: 'concept ASC',
|
||||
include: [{
|
||||
relation: 'item'
|
||||
}]
|
||||
};
|
||||
let salesObj = {};
|
||||
salesObj.items = await Self.find(filter);
|
||||
salesObj.totalUnitPrice = 0.00;
|
||||
salesObj.totalNewPrice = 0.00;
|
||||
salesObj.totalDifference = 0.00;
|
||||
|
||||
let query = `CALL vn.ticketComponentPriceDifference(?, ?, ?, ?, ?)`;
|
||||
let [differences] = await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
data.landed,
|
||||
data.addressFk,
|
||||
data.agencyModeFk,
|
||||
data.warehouseFk
|
||||
]);
|
||||
|
||||
salesObj.items.forEach(sale => {
|
||||
differences.forEach(difference => {
|
||||
if (sale.id == difference.saleFk)
|
||||
sale.component = difference;
|
||||
});
|
||||
|
||||
salesObj.totalUnitPrice += sale.price;
|
||||
salesObj.totalNewPrice += sale.component.newPrice;
|
||||
salesObj.totalDifference += sale.component.difference;
|
||||
salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100;
|
||||
salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100;
|
||||
salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100;
|
||||
});
|
||||
|
||||
return salesObj;
|
||||
};
|
||||
};
|
|
@ -1,56 +1,116 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('componentUpdate', {
|
||||
Self.remoteMethodCtx('componentUpdate', {
|
||||
description: 'Save ticket sale components',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'ticketFk',
|
||||
type: 'number',
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'ticket id',
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'data',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: 'landed, addressFk, agencyModeFk, warehouseFk',
|
||||
http: {source: 'body'}
|
||||
arg: 'clientId',
|
||||
type: 'Number',
|
||||
description: 'The client id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'context',
|
||||
type: 'object',
|
||||
http: function(ctx) {
|
||||
return ctx;
|
||||
}
|
||||
arg: 'agencyModeId',
|
||||
type: 'Number',
|
||||
description: 'The agencyMode id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'addressId',
|
||||
type: 'Number',
|
||||
description: 'The address id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'zoneId',
|
||||
type: 'Number',
|
||||
description: 'The zone id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'companyId',
|
||||
type: 'Number',
|
||||
description: 'The company id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'shipped',
|
||||
type: 'Date',
|
||||
description: 'The shipped date',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'landed',
|
||||
type: 'Date',
|
||||
description: 'The landing date',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'isDeleted',
|
||||
type: 'Boolean',
|
||||
description: 'Ticket is deleted',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'hasToBeUnrouted',
|
||||
type: 'Boolean',
|
||||
description: 'Ticket should be removed from ticket',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'option',
|
||||
type: 'Number',
|
||||
description: 'Action id',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:ticketFk/componentUpdate`,
|
||||
path: `/:id/componentUpdate`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.componentUpdate = async(ticketFk, data, ctx) => {
|
||||
let userId = ctx.req.accessToken.userId;
|
||||
let hasDeliveryRole = await Self.app.models.Account.hasRole(userId, 'delivery');
|
||||
Self.componentUpdate = async(ctx, id, clientId, agencyModeId, addressId, zoneId, warehouseId,
|
||||
companyId, shipped, landed, isDeleted, hasToBeUnrouted, option) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const hasDeliveryRole = await models.Account.hasRole(userId, 'delivery');
|
||||
if (!hasDeliveryRole)
|
||||
data.hasToBeUnrouted = true;
|
||||
hasToBeUnrouted = true;
|
||||
|
||||
let query = 'CALL vn.ticketComponentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
|
||||
if (!isProductionBoss) {
|
||||
const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId);
|
||||
|
||||
if (zone.id != zoneId)
|
||||
throw new UserError(`You don't have privileges to change the zone`);
|
||||
}
|
||||
|
||||
let query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
let res = await Self.rawSql(query, [
|
||||
ticketFk,
|
||||
data.clientFk,
|
||||
data.agencyModeFk,
|
||||
data.addressFk,
|
||||
data.warehouseFk,
|
||||
data.companyFk,
|
||||
data.shipped,
|
||||
data.landed,
|
||||
data.isDeleted,
|
||||
data.hasToBeUnrouted,
|
||||
data.option
|
||||
id,
|
||||
clientId,
|
||||
agencyModeId,
|
||||
addressId,
|
||||
zoneId,
|
||||
warehouseId,
|
||||
companyId,
|
||||
shipped,
|
||||
landed,
|
||||
isDeleted,
|
||||
hasToBeUnrouted,
|
||||
option
|
||||
]);
|
||||
return res;
|
||||
};
|
||||
|
|
|
@ -20,7 +20,7 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.isEditable = async(ctx, ticketFk) => {
|
||||
const accessToken = ctx.active && ctx.active.accessToken || ctx.req && ctx.req.accessToken;
|
||||
const accessToken = ctx.req.accessToken;
|
||||
const userId = accessToken.userId;
|
||||
let state = await Self.app.models.TicketState.findOne({
|
||||
where: {ticketFk: ticketFk}
|
||||
|
|
|
@ -61,21 +61,14 @@ module.exports = Self => {
|
|||
|
||||
try {
|
||||
if (!params.shipped && params.landed) {
|
||||
params.shipped = await models.Agency.getShipped(ctx, {
|
||||
landed: params.landed,
|
||||
addressFk: address.id,
|
||||
agencyModeFk: params.agencyModeFk,
|
||||
warehouseFk: params.warehouseFk
|
||||
});
|
||||
const shippedResult = await models.Agency.getShipped(params.landed,
|
||||
address.id, params.agencyModeFk, params.warehouseFk);
|
||||
params.shipped = shippedResult.shipped;
|
||||
}
|
||||
|
||||
if (params.shipped && !params.landed) {
|
||||
const landedResult = await models.Agency.getLanded(ctx, {
|
||||
shipped: params.shipped,
|
||||
addressFk: address.id,
|
||||
agencyModeFk: params.agencyModeFk,
|
||||
warehouseFk: params.warehouseFk
|
||||
});
|
||||
const landedResult = await models.Agency.getLanded(params.shipped,
|
||||
address.id, params.agencyModeFk, params.warehouseFk);
|
||||
params.landed = landedResult.landed;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('priceDifference', {
|
||||
description: 'Returns sales with price difference if the ticket is editable',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'The ticket id',
|
||||
http: {source: 'path'}
|
||||
},
|
||||
{
|
||||
arg: 'landed',
|
||||
type: 'Date',
|
||||
description: 'The landing date',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'addressId',
|
||||
type: 'Number',
|
||||
description: 'The address id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'agencyModeId',
|
||||
type: 'Number',
|
||||
description: 'The agencyMode id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'zoneId',
|
||||
type: 'Number',
|
||||
description: 'The zone id',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/priceDifference`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.priceDifference = async(ctx, id, landed, addressId, agencyModeId, zoneId, warehouseId) => {
|
||||
const models = Self.app.models;
|
||||
const isEditable = await models.Ticket.isEditable(ctx, id);
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
|
||||
if (!isProductionBoss) {
|
||||
const zone = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId);
|
||||
|
||||
if (zone.id != zoneId)
|
||||
throw new UserError(`You don't have privileges to change the zone`);
|
||||
}
|
||||
|
||||
let salesObj = {};
|
||||
salesObj.items = await models.Sale.find({
|
||||
where: {
|
||||
ticketFk: id
|
||||
},
|
||||
order: 'concept ASC',
|
||||
include: [{
|
||||
relation: 'item'
|
||||
}]
|
||||
});
|
||||
salesObj.totalUnitPrice = 0.00;
|
||||
salesObj.totalNewPrice = 0.00;
|
||||
salesObj.totalDifference = 0.00;
|
||||
|
||||
const query = `CALL vn.ticket_priceDifference(?, ?, ?, ?, ?)`;
|
||||
const args = [id, landed, addressId, zoneId, warehouseId];
|
||||
const [difComponents] = await Self.rawSql(query, args);
|
||||
|
||||
const map = new Map();
|
||||
|
||||
difComponents.forEach(difComponent => {
|
||||
map.set(difComponent.saleFk, difComponent);
|
||||
});
|
||||
|
||||
salesObj.items.forEach(sale => {
|
||||
const difComponent = map.get(sale.id);
|
||||
|
||||
if (difComponent)
|
||||
sale.component = difComponent;
|
||||
|
||||
salesObj.totalUnitPrice += sale.price;
|
||||
salesObj.totalNewPrice += sale.component.newPrice;
|
||||
salesObj.totalDifference += sale.component.difference;
|
||||
salesObj.totalUnitPrice = Math.round(salesObj.totalUnitPrice * 100) / 100;
|
||||
salesObj.totalNewPrice = Math.round(salesObj.totalNewPrice * 100) / 100;
|
||||
salesObj.totalDifference = Math.round(salesObj.totalDifference * 100) / 100;
|
||||
});
|
||||
|
||||
return salesObj;
|
||||
};
|
||||
};
|
|
@ -28,22 +28,22 @@ describe('ticket componentUpdate()', () => {
|
|||
});
|
||||
|
||||
it('should change the agencyMode to modify the sale components value', async() => {
|
||||
let data = {
|
||||
clientFk: 102,
|
||||
agencyModeFk: 8,
|
||||
addressFk: 122,
|
||||
warehouseFk: 1,
|
||||
companyFk: 442,
|
||||
shipped: today,
|
||||
landed: tomorrow,
|
||||
isDeleted: false,
|
||||
hasToBeUnrouted: false,
|
||||
option: 1
|
||||
};
|
||||
const clientId = 102;
|
||||
const addressId = 122;
|
||||
const agencyModeId = 8;
|
||||
const warehouseId = 1;
|
||||
const zoneId = 5;
|
||||
const shipped = today;
|
||||
const companyId = 442;
|
||||
const isDeleted = false;
|
||||
const landed = tomorrow;
|
||||
const hasToBeUnrouted = false;
|
||||
const option = 1;
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 101}}};
|
||||
|
||||
await app.models.Ticket.componentUpdate(ticketId, data, ctx);
|
||||
await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId,
|
||||
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
|
||||
|
||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
||||
let firstvalueAfterChange = componentValue.value;
|
||||
|
@ -56,21 +56,21 @@ describe('ticket componentUpdate()', () => {
|
|||
});
|
||||
|
||||
it('should change the agencyMode to go back to the originals sale components value', async() => {
|
||||
let data = {
|
||||
clientFk: 102,
|
||||
agencyModeFk: 7,
|
||||
addressFk: 122,
|
||||
warehouseFk: 1,
|
||||
companyFk: 442,
|
||||
shipped: today,
|
||||
landed: tomorrow,
|
||||
isDeleted: false,
|
||||
hasToBeUnrouted: false,
|
||||
option: 1
|
||||
};
|
||||
const clientId = 102;
|
||||
const addressId = 122;
|
||||
const agencyModeId = 7;
|
||||
const warehouseId = 1;
|
||||
const zoneId = 3;
|
||||
const shipped = today;
|
||||
const companyId = 442;
|
||||
const isDeleted = false;
|
||||
const landed = tomorrow;
|
||||
const hasToBeUnrouted = false;
|
||||
const option = 1;
|
||||
|
||||
let ctx = {req: {accessToken: {userId: 101}}};
|
||||
await app.models.Ticket.componentUpdate(ticketId, data, ctx);
|
||||
await app.models.Ticket.componentUpdate(ctx, ticketId, clientId, agencyModeId, addressId,
|
||||
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
|
||||
|
||||
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
|
||||
let firstvalueAfterChange = componentValue.value;
|
||||
|
|
|
@ -3,16 +3,19 @@ let UserError = require('vn-loopback/util/user-error');
|
|||
|
||||
describe('sale priceDifference()', () => {
|
||||
it('should return ticket price differences', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
let tomorrow = new Date();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
let data = {
|
||||
landed: tomorrow,
|
||||
addressFk: 126,
|
||||
agencyModeFk: 7,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let result = await app.models.Sale.priceDifference(ctx, 16, data);
|
||||
|
||||
const ticketId = 16;
|
||||
const landed = tomorrow;
|
||||
const addressId = 126;
|
||||
const agencyModeId = 7;
|
||||
const zoneId = 3;
|
||||
const warehouseId = 1;
|
||||
|
||||
const httpCtx = {req: {accessToken: {userId: 106}}};
|
||||
let result = await app.models.Ticket.priceDifference(httpCtx, ticketId, landed,
|
||||
addressId, agencyModeId, zoneId, warehouseId);
|
||||
|
||||
expect(result.totalUnitPrice).toEqual(215.77);
|
||||
expect(result.totalNewPrice).toEqual(215.77);
|
||||
|
@ -20,15 +23,14 @@ describe('sale priceDifference()', () => {
|
|||
});
|
||||
|
||||
it('should return an error if the ticket is not editable', async() => {
|
||||
let ctx = {req: {accessToken: {userId: 9}}};
|
||||
const ticketId = 1;
|
||||
const landed = new Date();
|
||||
const addressId = 121;
|
||||
const zoneId = 3;
|
||||
const warehouseId = 1;
|
||||
let error;
|
||||
let data = {
|
||||
landed: new Date(),
|
||||
addressFk: 121,
|
||||
agencyModeFk: 1,
|
||||
warehouseFk: 1
|
||||
};
|
||||
await app.models.Sale.priceDifference(ctx, 1, data)
|
||||
const httpCtx = {req: {accessToken: {userId: 106}}};
|
||||
await app.models.Ticket.priceDifference(httpCtx, ticketId, landed, addressId, zoneId, warehouseId)
|
||||
.catch(e => {
|
||||
error = e;
|
||||
});
|
|
@ -1,6 +1,5 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/sale/getClaimableFromTicket')(Self);
|
||||
require('../methods/sale/priceDifference')(Self);
|
||||
require('../methods/sale/moveToTicket')(Self);
|
||||
require('../methods/sale/reserve')(Self);
|
||||
require('../methods/sale/removes')(Self);
|
||||
|
|
|
@ -4,10 +4,12 @@ const LoopBackContext = require('loopback-context');
|
|||
module.exports = Self => {
|
||||
Self.observe('before save', async ctx => {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const models = Self.app.models;
|
||||
let changes = ctx.currentInstance || ctx.instance;
|
||||
if (changes) {
|
||||
let ticketId = changes.ticketFk;
|
||||
let isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, ticketId);
|
||||
let isEditable = await models.Ticket.isEditable(httpCtx, ticketId);
|
||||
if (!isEditable)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
}
|
||||
|
@ -15,9 +17,10 @@ module.exports = Self => {
|
|||
|
||||
Self.observe('before delete', async ctx => {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const models = Self.app.models;
|
||||
const service = await models.TicketService.findById(ctx.where.id);
|
||||
const isEditable = await Self.app.models.Ticket.isEditable(loopBackContext, service.ticketFk);
|
||||
const isEditable = await models.Ticket.isEditable(httpCtx, service.ticketFk);
|
||||
|
||||
if (!isEditable)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
|
|
|
@ -7,6 +7,7 @@ module.exports = Self => {
|
|||
require('../methods/ticket/getTotal')(Self);
|
||||
require('../methods/ticket/getTaxes')(Self);
|
||||
require('../methods/ticket/subtotal')(Self);
|
||||
require('../methods/ticket/priceDifference')(Self);
|
||||
require('../methods/ticket/componentUpdate')(Self);
|
||||
require('../methods/ticket/new')(Self);
|
||||
require('../methods/ticket/isEditable')(Self);
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
<vn-crud-model
|
||||
url="/api/Zones"
|
||||
include="{relation: 'warehouse'}"
|
||||
data="zones"
|
||||
order="name"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
|
||||
<form name="form">
|
||||
<vn-card pad-large>
|
||||
<vn-horizontal>
|
||||
|
@ -7,8 +15,8 @@
|
|||
label="Client"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.clientFk"
|
||||
initial-data="$ctrl.clientFk"
|
||||
field="$ctrl.clientId"
|
||||
initial-data="$ctrl.clientId"
|
||||
order="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
|
@ -24,12 +32,12 @@
|
|||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/AgencyModes/isActive"
|
||||
label="Agency"
|
||||
url="/api/Warehouses"
|
||||
label="Warehouse"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.ticket.agencyModeFk"
|
||||
initial-data="$ctrl.ticket.agencyModeFk">
|
||||
field="$ctrl.ticket.warehouseFk"
|
||||
initial-data="$ctrl.ticket.warehouseFk">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
@ -53,16 +61,29 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
url="/api/Warehouses"
|
||||
label="Warehouse"
|
||||
url="/api/AgencyModes/isActive"
|
||||
label="Agency"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.ticket.warehouseFk"
|
||||
initial-data="$ctrl.ticket.warehouseFk">
|
||||
field="$ctrl.agencyModeId">
|
||||
</vn-autocomplete>
|
||||
<vn-one>
|
||||
<vn-check label="Deleted" field="$ctrl.ticket.isDeleted"></vn-check>
|
||||
</vn-one>
|
||||
<vn-autocomplete vn-one
|
||||
data="zones"
|
||||
label="Zone"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
field="$ctrl.zoneId"
|
||||
vn-acl="productionBoss">
|
||||
<tpl-item>
|
||||
<span>{{::name}} - {{::warehouse.name}} - Max. {{::hour | dateTime: 'HH:mm'}} h.</span>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check vn-one
|
||||
label="Deleted"
|
||||
field="$ctrl.ticket.isDeleted">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
</form>
|
||||
|
|
|
@ -10,7 +10,11 @@ class Controller {
|
|||
}
|
||||
|
||||
$onInit() {
|
||||
this.data.registerChild(this);
|
||||
this.basicData.registerChild(this);
|
||||
}
|
||||
|
||||
get ticket() {
|
||||
return this._ticket;
|
||||
}
|
||||
|
||||
set ticket(value) {
|
||||
|
@ -18,27 +22,23 @@ class Controller {
|
|||
|
||||
if (!value || !value.id) return;
|
||||
|
||||
this.onChangeAddress(value.clientFk);
|
||||
this.onChangeClient(value.clientFk);
|
||||
}
|
||||
|
||||
get ticket() {
|
||||
return this._ticket;
|
||||
}
|
||||
|
||||
set clientFk(value) {
|
||||
this.ticket.clientFk = value;
|
||||
this.ticket.addressFk = null;
|
||||
|
||||
this.onChangeAddress(value);
|
||||
}
|
||||
|
||||
get clientFk() {
|
||||
get clientId() {
|
||||
if (this.ticket)
|
||||
return this.ticket.clientFk;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
set clientId(value) {
|
||||
this.ticket.clientFk = value;
|
||||
this.ticket.addressFk = null;
|
||||
|
||||
this.onChangeClient(value);
|
||||
}
|
||||
|
||||
set shipped(value) {
|
||||
this.ticket.shipped = value;
|
||||
this.onChangeShipped(value);
|
||||
|
@ -51,11 +51,6 @@ class Controller {
|
|||
return null;
|
||||
}
|
||||
|
||||
set landed(value) {
|
||||
this.ticket.landed = value;
|
||||
this.onChangeLanded(value);
|
||||
}
|
||||
|
||||
get landed() {
|
||||
if (this.ticket)
|
||||
return this.ticket.landed;
|
||||
|
@ -63,47 +58,43 @@ class Controller {
|
|||
return null;
|
||||
}
|
||||
|
||||
onChangeShipped(value) {
|
||||
let params = {
|
||||
shipped: value,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
};
|
||||
|
||||
let query = `/api/Agencies/getLanded`;
|
||||
this.$http.get(query, {params}).then(res => {
|
||||
if (res.data && res.data.landed)
|
||||
this.ticket.landed = res.data.landed;
|
||||
else {
|
||||
return this.vnApp.showError(
|
||||
this.$translate.instant(`There's no available agency for this shipping date`)
|
||||
);
|
||||
}
|
||||
});
|
||||
set landed(value) {
|
||||
this.ticket.landed = value;
|
||||
this.onChangeLanded(value);
|
||||
}
|
||||
|
||||
onChangeLanded(value) {
|
||||
let params = {
|
||||
landed: value,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
};
|
||||
get agencyModeId() {
|
||||
if (this.ticket)
|
||||
return this.ticket.agencyModeFk;
|
||||
|
||||
let query = `/api/Agencies/getShipped`;
|
||||
this.$http.get(query, {params}).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.shipped = res.data;
|
||||
else {
|
||||
return this.vnApp.showError(
|
||||
this.$translate.instant(`There's no available agency for this landing date`)
|
||||
);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
onChangeAddress(value) {
|
||||
set agencyModeId(value) {
|
||||
this.ticket.agencyModeFk = value;
|
||||
|
||||
if (value)
|
||||
this.onChangeAgencyMode(value);
|
||||
}
|
||||
|
||||
get zoneId() {
|
||||
if (this.ticket)
|
||||
return this.ticket.zoneFk;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
set zoneId(value) {
|
||||
this.ticket.zoneFk = value;
|
||||
|
||||
if (value)
|
||||
this.onChangeZone(value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Autocompletes address on client change
|
||||
*/
|
||||
onChangeClient(value) {
|
||||
let filter = {
|
||||
include: [
|
||||
{
|
||||
|
@ -129,6 +120,96 @@ class Controller {
|
|||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a landing date
|
||||
*/
|
||||
getLanded(params) {
|
||||
let query = `/api/Agencies/getLanded`;
|
||||
return this.$http.get(query, {params});
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a shipment date
|
||||
*/
|
||||
getShipped(params) {
|
||||
let query = `/api/Agencies/getShipped`;
|
||||
return this.$http.get(query, {params});
|
||||
}
|
||||
|
||||
|
||||
onChangeShipped(shipped) {
|
||||
let params = {
|
||||
shipped: shipped,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
};
|
||||
let query = `/api/Agencies/getLanded`;
|
||||
this.$http.get(query, {params}).then(res => {
|
||||
if (res.data && res.data.landed)
|
||||
this.ticket.landed = res.data.landed;
|
||||
else {
|
||||
return this.vnApp.showError(
|
||||
this.$translate.instant(`No delivery zone available for this shipping date`)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onChangeLanded(landed) {
|
||||
let params = {
|
||||
landed: landed,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
};
|
||||
let query = `/api/Agencies/getShipped`;
|
||||
this.$http.get(query, {params}).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.shipped = res.data.shipped;
|
||||
else {
|
||||
return this.vnApp.showError(
|
||||
this.$translate.instant(`No delivery zone available for this landing date`)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets an agency from an specified zone
|
||||
*/
|
||||
onChangeZone(zoneId) {
|
||||
const query = `/api/Zones/${zoneId}`;
|
||||
this.$http.get(query).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.agencyModeFk = res.data.agencyModeFk;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets a zone from an agency
|
||||
*/
|
||||
onChangeAgencyMode(agencyModeId) {
|
||||
let params = {
|
||||
landed: this.ticket.landed,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: agencyModeId,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
};
|
||||
|
||||
this.ticket.zoneFk = null;
|
||||
let query = `/api/Agencies/getShipped`;
|
||||
this.$http.get(query, {params}).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.zoneFk = res.data.id;
|
||||
else {
|
||||
return this.vnApp.showMessage(
|
||||
this.$translate.instant('No delivery zone available for this parameters')
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async onStepChange() {
|
||||
if (this.isFormInvalid()) {
|
||||
return this.vnApp.showError(
|
||||
|
@ -136,35 +217,31 @@ class Controller {
|
|||
);
|
||||
}
|
||||
|
||||
let query = `/ticket/api/sales/${this.ticket.id}/priceDifference`;
|
||||
let data = {
|
||||
let query = `/api/tickets/${this.ticket.id}/priceDifference`;
|
||||
let params = {
|
||||
landed: this.ticket.landed,
|
||||
addressFk: this.ticket.addressFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
warehouseFk: this.ticket.warehouseFk
|
||||
addressId: this.ticket.addressFk,
|
||||
agencyModeId: this.ticket.agencyModeFk,
|
||||
zoneId: this.ticket.zoneFk,
|
||||
warehouseId: this.ticket.warehouseFk
|
||||
};
|
||||
|
||||
return this.$http.post(query, data).then(res => {
|
||||
return this.$http.post(query, params).then(res => {
|
||||
if (res.data)
|
||||
this.ticket.sale = res.data;
|
||||
|
||||
return true;
|
||||
}, err => {
|
||||
if (err.data.error.message === 'NO_AGENCY_AVAILABLE') {
|
||||
this.vnApp.showMessage(
|
||||
this.$translate.instant(`There's no available agency for this landing date`)
|
||||
);
|
||||
} else {
|
||||
this.vnApp.showMessage(
|
||||
this.$translate.instant(err.data.error.message)
|
||||
);
|
||||
}
|
||||
this.vnApp.showError(
|
||||
this.$translate.instant(err.data.error.message)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
isFormInvalid() {
|
||||
return !this.ticket.clientFk || !this.ticket.addressFk || !this.ticket.agencyModeFk
|
||||
|| !this.ticket.companyFk || !this.ticket.shipped || !this.ticket.landed;
|
||||
|| !this.ticket.companyFk || !this.ticket.shipped || !this.ticket.landed
|
||||
|| !this.ticket.zoneFk;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -177,6 +254,6 @@ ngModule.component('vnTicketBasicDataStepOne', {
|
|||
ticket: '<'
|
||||
},
|
||||
require: {
|
||||
data: '^vnTicketBasicData'
|
||||
basicData: '^vnTicketBasicData'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -18,21 +18,21 @@ describe('Ticket', () => {
|
|||
}));
|
||||
|
||||
describe('ticket() setter', () => {
|
||||
it('should set ticket property and call onChangeAddress() method', () => {
|
||||
spyOn(controller, 'onChangeAddress');
|
||||
it('should set ticket property and call onChangeClient() method', () => {
|
||||
spyOn(controller, 'onChangeClient');
|
||||
controller.ticket = {id: 1, clientFk: 101};
|
||||
|
||||
expect(controller.onChangeAddress).toHaveBeenCalledWith(101);
|
||||
expect(controller.onChangeClient).toHaveBeenCalledWith(101);
|
||||
});
|
||||
});
|
||||
|
||||
describe('clientFk() setter', () => {
|
||||
it('should set clientFk property and call onChangeAddress() method ', () => {
|
||||
spyOn(controller, 'onChangeAddress');
|
||||
controller.ticket = {id: 1, clientFk: 101};
|
||||
controller.clientFk = 102;
|
||||
describe('clientId() setter', () => {
|
||||
it('should set clientId property and call onChangeClient() method ', () => {
|
||||
spyOn(controller, 'onChangeClient');
|
||||
controller.ticket = {id: 1, clientId: 101};
|
||||
controller.clientId = 102;
|
||||
|
||||
expect(controller.onChangeAddress).toHaveBeenCalledWith(102);
|
||||
expect(controller.onChangeClient).toHaveBeenCalledWith(102);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -58,6 +58,57 @@ describe('Ticket', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('agencyModeId() setter', () => {
|
||||
it('should set agencyModeId property and call onChangeAgencyMode() method ', () => {
|
||||
const agencyModeId = 8;
|
||||
spyOn(controller, 'onChangeAgencyMode');
|
||||
controller.ticket = {id: 1};
|
||||
controller.agencyModeId = 8;
|
||||
|
||||
expect(controller.onChangeAgencyMode).toHaveBeenCalledWith(agencyModeId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('zoneId() setter', () => {
|
||||
it('should set zoneId property and call onChangeZone() method ', () => {
|
||||
const zoneId = 5;
|
||||
spyOn(controller, 'onChangeZone');
|
||||
controller.ticket = {id: 1};
|
||||
controller.zoneId = 5;
|
||||
|
||||
expect(controller.onChangeZone).toHaveBeenCalledWith(zoneId);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onChangeClient()', () => {
|
||||
it('should return a list of addresses from choosed client', async() => {
|
||||
const clientId = 102;
|
||||
let filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'province',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
filter = encodeURIComponent(JSON.stringify(filter));
|
||||
|
||||
$httpBackend.when('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`).respond(200);
|
||||
$httpBackend.expect('GET', `/api/Clients/${clientId}/addresses?filter=${filter}`);
|
||||
|
||||
controller.onChangeClient(clientId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onChangeShipped()', () => {
|
||||
it('should return an available landing date', async() => {
|
||||
let shipped = new Date();
|
||||
|
@ -111,11 +162,51 @@ describe('Ticket', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('onChangeZone()', () => {
|
||||
it('should return an available zone', async() => {
|
||||
const zoneId = 5;
|
||||
|
||||
$httpBackend.when('GET', `/api/Zones/${zoneId}`).respond(200);
|
||||
$httpBackend.expect('GET', `/api/Zones/${zoneId}`);
|
||||
|
||||
controller.onChangeZone(zoneId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onChangeAgencyMode()', () => {
|
||||
it('should return an available agency', async() => {
|
||||
const landed = new Date();
|
||||
const agencyModeId = 7;
|
||||
controller._ticket = {
|
||||
id: 1,
|
||||
landed: landed,
|
||||
addressFk: 121,
|
||||
agencyModeFk: agencyModeId,
|
||||
warehouseFk: 1
|
||||
};
|
||||
let params = {
|
||||
landed: landed,
|
||||
addressFk: 121,
|
||||
agencyModeFk: agencyModeId,
|
||||
warehouseFk: 1
|
||||
};
|
||||
|
||||
let serializedParams = $httpParamSerializer(params);
|
||||
$httpBackend.when('GET', `/api/Agencies/getShipped?${serializedParams}`).respond(200);
|
||||
$httpBackend.expect('GET', `/api/Agencies/getShipped?${serializedParams}`);
|
||||
|
||||
controller.onChangeAgencyMode(agencyModeId);
|
||||
$httpBackend.flush();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFormInvalid()', () => {
|
||||
it('should check if all form fields are valid', () => {
|
||||
controller.ticket = {
|
||||
clientFk: 1,
|
||||
addressFk: 121,
|
||||
zoneFk: 3,
|
||||
agencyModeFk: 1,
|
||||
companyFk: 442,
|
||||
warehouseFk: 1,
|
||||
|
@ -136,6 +227,7 @@ describe('Ticket', () => {
|
|||
id: 1,
|
||||
clientFk: 1,
|
||||
addressFk: 121,
|
||||
zoneFk: 3,
|
||||
agencyModeFk: 1,
|
||||
companyFk: 442,
|
||||
warehouseFk: 1,
|
||||
|
@ -145,8 +237,8 @@ describe('Ticket', () => {
|
|||
|
||||
let response = {error: new Error('NO_AGENCY_AVAILABLE')};
|
||||
|
||||
$httpBackend.whenPOST(`/ticket/api/sales/1/priceDifference`).respond(400, response);
|
||||
$httpBackend.expectPOST(`/ticket/api/sales/1/priceDifference`);
|
||||
$httpBackend.whenPOST(`/api/tickets/1/priceDifference`).respond(400, response);
|
||||
$httpBackend.expectPOST(`/api/tickets/1/priceDifference`);
|
||||
controller.onStepChange();
|
||||
$httpBackend.flush();
|
||||
});
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
There's no available agency for this landing date: No hay ninguna agencia disponible para la fecha de envío seleccionada
|
||||
No delivery zone available for this landing date: No hay una zona de reparto disponible para la fecha de envío seleccionada
|
||||
No delivery zone available for this shipping date: No hay una zona de reparto disponible para la fecha de preparación seleccionada
|
||||
No delivery zone available for this parameters: No hay una zona de reparto disponible con estos parámetros
|
||||
Deleted: Eliminado
|
||||
There's no available agency for this shipping date: No hay ninguna agencia disponible para la fecha de preparación seleccionada
|
||||
Zone: Zona
|
|
@ -29,13 +29,14 @@ class Controller {
|
|||
);
|
||||
}
|
||||
|
||||
let query = `/ticket/api/tickets/${this.ticket.id}/componentUpdate`;
|
||||
let data = {
|
||||
clientFk: this.ticket.clientFk,
|
||||
agencyModeFk: this.ticket.agencyModeFk,
|
||||
addressFk: this.ticket.addressFk,
|
||||
warehouseFk: this.ticket.warehouseFk,
|
||||
companyFk: this.ticket.companyFk,
|
||||
let query = `/api/tickets/${this.ticket.id}/componentUpdate`;
|
||||
let params = {
|
||||
clientId: this.ticket.clientFk,
|
||||
agencyModeId: this.ticket.agencyModeFk,
|
||||
addressId: this.ticket.addressFk,
|
||||
zoneId: this.ticket.zoneFk,
|
||||
warehouseId: this.ticket.warehouseFk,
|
||||
companyId: this.ticket.companyFk,
|
||||
shipped: this.ticket.shipped,
|
||||
landed: this.ticket.landed,
|
||||
isDeleted: this.ticket.isDeleted,
|
||||
|
@ -43,7 +44,7 @@ class Controller {
|
|||
option: this.ticket.option
|
||||
};
|
||||
|
||||
this.$http.post(query, data).then(res => {
|
||||
this.$http.post(query, params).then(res => {
|
||||
if (res.data) {
|
||||
this.$state.go('ticket.card.summary', {id: this.$state.params.id});
|
||||
this.card.reload();
|
||||
|
|
|
@ -36,6 +36,7 @@ describe('ticket', () => {
|
|||
id: 1,
|
||||
agencyModeFk: 1,
|
||||
addressFk: 121,
|
||||
zoneFk: 3,
|
||||
warehouseFk: 1,
|
||||
shipped: now,
|
||||
landed: now,
|
||||
|
@ -43,16 +44,17 @@ describe('ticket', () => {
|
|||
};
|
||||
|
||||
let data = {
|
||||
agencyModeFk: 1,
|
||||
addressFk: 121,
|
||||
warehouseFk: 1,
|
||||
agencyModeId: 1,
|
||||
addressId: 121,
|
||||
zoneId: 3,
|
||||
warehouseId: 1,
|
||||
shipped: now,
|
||||
landed: now,
|
||||
option: 1
|
||||
};
|
||||
|
||||
$httpBackend.whenPOST(`/ticket/api/tickets/1/componentUpdate`, data).respond('ok');
|
||||
$httpBackend.expectPOST(`/ticket/api/tickets/1/componentUpdate`, data);
|
||||
$httpBackend.whenPOST(`/api/tickets/1/componentUpdate`, data).respond('ok');
|
||||
$httpBackend.expectPOST(`/api/tickets/1/componentUpdate`, data);
|
||||
controller.onSubmit();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
|
Loading…
Reference in New Issue