Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2056-entry_descriptor
gitea/salix/2056-entry_descriptor This commit looks good Details

This commit is contained in:
Bernat Exposito Domenech 2020-02-21 12:48:37 +01:00
commit 50a8da2064
29 changed files with 396 additions and 159 deletions

View File

@ -1,19 +1,3 @@
ALTER TABLE `vn`.`ticket`
ADD COLUMN `zonePrice` DECIMAL(10,2) NULL DEFAULT NULL AFTER `collectionFk`,
ADD COLUMN `zoneBonus` DECIMAL(10,2) NULL DEFAULT NULL AFTER `zonePrice`,
ADD COLUMN `zoneClosure` TIME NULL AFTER `zoneBonus`;
CREATE TABLE `vn`.`zoneCalcTicket` (
`zoneFk` int(11) NOT NULL PRIMARY KEY,
CONSTRAINT `zoneCalcTicketfk_1` FOREIGN KEY (`zoneFk`) REFERENCES `vn`.`zone` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP EVENT IF EXISTS vn.`zone_doCalc`;
CREATE DEFINER=`root`@`%` EVENT vn.`zone_doCalc`
ON SCHEDULE EVERY 15 SECOND STARTS '2020-01-31 11:32:30'
ON COMPLETION PRESERVE ENABLE
DO CALL util.procNoOverlap('vn.zone_doCalc');
DROP TABLE `vn`.`zoneConfig`;
DROP procedure IF EXISTS vn.`zoneClosure_recalc`;
ADD COLUMN `zoneBonus` DECIMAL(10,2) NULL DEFAULT NULL AFTER `zonePrice`;

View File

@ -0,0 +1,96 @@
USE `vn`;
DROP procedure IF EXISTS `ticketCreateWithUser`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticketCreateWithUser`(
vClientId INT
,vShipped DATE
,vWarehouseFk INT
,vCompanyFk INT
,vAddressFk INT
,vAgencyModeFk INT
,vRouteFk INT
,vlanded DATE
,vUserId INT
,OUT vNewTicket INT)
BEGIN
DECLARE vZoneFk INT;
DECLARE vPrice DECIMAL(10,2);
DECLARE vBonus DECIMAL(10,2);
IF vClientId IS NULL THEN
CALL util.throw ('CLIENT_NOT_ESPECIFIED');
END IF;
IF NOT vAddressFk OR vAddressFk IS NULL THEN
SELECT id INTO vAddressFk
FROM address
WHERE clientFk = vClientId AND isDefaultAddress;
END IF;
IF vAgencyModeFk IS NOT NULL THEN
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT zoneFk, price, bonus INTO vZoneFk, vPrice, vBonus
FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
IF vZoneFk IS NULL OR vZoneFk = 0 THEN
CALL util.throw ('NOT_ZONE_WITH_THIS_PARAMETERS');
END IF;
END IF;
INSERT INTO ticket (
clientFk,
shipped,
addressFk,
agencyModeFk,
nickname,
warehouseFk,
routeFk,
companyFk,
landed,
zoneFk,
zonePrice,
zoneBonus
)
SELECT
vClientId,
vShipped,
a.id,
vAgencyModeFk,
a.nickname,
vWarehouseFk,
IF(vRouteFk,vRouteFk,NULL),
vCompanyFk,
vlanded,
vZoneFk,
vPrice,
vBonus
FROM address a
JOIN agencyMode am ON am.id = a.agencyModeFk
WHERE a.id = vAddressFk;
SET vNewTicket = LAST_INSERT_ID();
INSERT INTO ticketObservation(ticketFk, observationTypeFk, description)
SELECT vNewTicket, ao.observationTypeFk, ao.description
FROM addressObservation ao
JOIN address a ON a.id = ao.addressFk
WHERE a.id = vAddressFk;
INSERT INTO vn.ticketLog
SET originFk = vNewTicket, userFk = vUserId, `action` = 'insert', description = CONCAT('Ha creado el ticket:', ' ', vNewTicket);
IF (SELECT ct.isCreatedAsServed FROM vn.clientType ct JOIN vn.client c ON c.typeFk = ct.code WHERE c.id = vClientId ) <> FALSE THEN
INSERT INTO vncontrol.inter(state_id, Id_Ticket, Id_Trabajador)
SELECT id, vNewTicket, getWorker()
FROM state
WHERE `code` = 'DELIVERED';
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,82 @@
USE `vn`;
DROP procedure IF EXISTS `ticket_componentUpdate`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `ticket_componentUpdate`(
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
DECLARE vPrice DECIMAL(10,2);
DECLARE vBonus DECIMAL(10,2);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
START TRANSACTION;
IF (SELECT addressFk FROM ticket WHERE id = vTicketFk) <> vAddressFk THEN
UPDATE ticket t
JOIN address a ON a.id = vAddressFk
SET t.nickname = a.nickname
WHERE t.id = vTicketFk;
END IF;
CALL vn.zone_getShippedWarehouse(vlanded, vAddressFk, vAgencyModeFk);
SELECT zoneFk, price, bonus INTO vZoneFk, vPrice, vBonus
FROM tmp.zoneGetShipped
WHERE shipped = vShipped AND warehouseFk = vWarehouseFk LIMIT 1;
UPDATE ticket t
SET
t.clientFk = vClientFk,
t.agencyModeFk = vAgencyModeFk,
t.addressFk = vAddressFk,
t.zoneFk = vZoneFk,
t.zonePrice = vPrice,
t.zoneBonus = vBonus,
t.warehouseFk = vWarehouseFk,
t.companyFk = vCompanyFk,
t.landed = vLanded,
t.shipped = vShipped,
t.isDeleted = vIsDeleted
WHERE
t.id = vTicketFk;
IF vHasToBeUnrouted THEN
UPDATE ticket t SET t.routeFk = NULL
WHERE t.id = vTicketFk;
END IF;
IF vOption <> 8 THEN
DROP TEMPORARY TABLE IF EXISTS tmp.sale;
CREATE TEMPORARY TABLE tmp.sale
(PRIMARY KEY (saleFk))
ENGINE = MEMORY
SELECT id AS saleFk, vWarehouseFk warehouseFk
FROM sale s WHERE s.ticketFk = vTicketFk;
CALL ticketComponentUpdateSale (vOption);
DROP TEMPORARY TABLE tmp.sale;
END IF;
COMMIT;
END$$
DELIMITER ;

View File

@ -1,56 +0,0 @@
USE `vn`;
DROP procedure IF EXISTS `zone_doCalc`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_doCalc`()
proc: BEGIN
/**
* Updates ticket fields related with zone
*/
DECLARE vDone BOOL;
DECLARE vTicketFk INT;
DECLARE vShipped DATE;
DECLARE vZoneFk INT;
DECLARE cCur CURSOR FOR
SELECT t.id, t.shipped, t.zoneFk
FROM zoneCalcTicket zct
JOIN ticket t ON t.zoneFk = zct.zoneFk
WHERE shipped >= CURDATE();
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET vDone = TRUE;
OPEN cCur;
myLoop: LOOP
SET vDone = FALSE;
FETCH cCur INTO vTicketFk, vShipped, vZoneFk;
IF vDone THEN
LEAVE myLoop;
END IF;
DROP TEMPORARY TABLE IF EXISTS tmp.zone;
CREATE TEMPORARY TABLE tmp.zone
(INDEX (id))
ENGINE = MEMORY
SELECT vZoneFk id;
CALL zone_getOptionsForShipment(vShipped, TRUE);
UPDATE ticket t
LEFT JOIN tmp.zoneOption zo ON TRUE
SET zonePrice = zo.price, zoneBonus = zo.bonus, zoneClosure = zo.`hour`
WHERE t.id = vTicketFk;
END LOOP;
CLOSE cCur;
DELETE FROM zoneCalcTicket;
END$$
DELIMITER ;

View File

@ -0,0 +1,49 @@
USE `vn`;
DROP procedure IF EXISTS `zoneClosure_recalc`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zoneClosure_recalc`()
proc: BEGIN
/**
* Recalculates the delivery time (hour) for every zone in days + scope in future
*/
DECLARE vScope INT;
DECLARE vCounter INT DEFAULT 0;
DECLARE vShipped DATE DEFAULT CURDATE();
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
DO RELEASE_LOCK('vn.zoneClosure_recalc');
RESIGNAL;
END;
IF NOT GET_LOCK('vn.zoneClosure_recalc', 0) THEN
LEAVE proc;
END IF;
SELECT scope INTO vScope
FROM zoneConfig;
DROP TEMPORARY TABLE IF EXISTS tmp.zone;
CREATE TEMPORARY TABLE tmp.zone
(INDEX (id))
ENGINE = MEMORY
SELECT id FROM zone;
TRUNCATE TABLE zoneClosure;
WHILE vCounter <= vScope DO
CALL zone_getOptionsForShipment(vShipped, TRUE);
INSERT INTO zoneClosure(zoneFk, dated, `hour`)
SELECT zoneFk, vShipped, `hour` FROM tmp.zoneOption;
SET vCounter = vCounter + 1;
SET vShipped = TIMESTAMPADD(DAY, 1, vShipped);
END WHILE;
DROP TEMPORARY TABLE tmp.zone;
DO RELEASE_LOCK('vn.zoneClosure_recalc');
END$$
DELIMITER ;

View File

@ -7,6 +7,7 @@ CREATE DEFINER=`root`@`%` PROCEDURE `zone_doCalcInitialize`()
proc: BEGIN
/**
* Initialize ticket
* si en 01-07-20 aun esta este proc, kkear
*/
DECLARE vDone BOOL;
DECLARE vTicketFk INT;
@ -16,7 +17,7 @@ proc: BEGIN
DECLARE cCur CURSOR FOR
SELECT t.id, t.landed, t.zoneFk
FROM ticket t
WHERE (zonePrice IS NULL OR zoneBonus IS NULL OR zoneClosure IS NULL)
WHERE (zonePrice IS NULL OR zoneBonus IS NULL)
AND landed >= '2019-01-01' AND shipped >= '2019-01-01'
GROUP BY landed, zoneFk;
@ -43,12 +44,12 @@ proc: BEGIN
UPDATE ticket t
LEFT JOIN tmp.zoneOption zo ON TRUE
SET zonePrice = zo.price, zoneBonus = zo.bonus, zoneClosure = zo.`hour`
SET zonePrice = zo.price, zoneBonus = zo.bonus
WHERE t.zoneFk = vZoneFk AND landed = vLanded;
UPDATE ticket t
LEFT JOIN vn.zone z ON z.id = t.zoneFk
SET zonePrice = z.price, zoneBonus = z.bonus, zoneClosure = z.`hour`
SET zonePrice = z.price, zoneBonus = z.bonus
WHERE t.zonePrice IS NULL AND z.id = vZoneFk
AND landed >= '2019-01-01' AND shipped >= '2019-01-01';
@ -56,7 +57,6 @@ proc: BEGIN
CLOSE cCur;
DELETE FROM zoneCalcTicket;
END$$
DELIMITER ;

View File

@ -6,7 +6,7 @@ USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `zone_getShippedWarehouse`(vLanded DATE, vAddressFk INT, vAgencyModeFk INT)
BEGIN
/**
* Devuelve la ­nima fecha de envío para cada warehouse
* Devuelve la ƒÂ­nima fecha de envío para cada warehouse
*
* @param vLanded La fecha de recepcion
* @param vAddressFk Id del consignatario
@ -25,7 +25,9 @@ BEGIN
TIMESTAMPADD(DAY,-zo.travelingDays, vLanded) shipped,
zo.`hour`,
zw.warehouseFk,
z.agencyModeFk
z.agencyModeFk,
zo.price,
zo.bonus
FROM tmp.zoneOption zo
JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk
JOIN zone z ON z.id = zo.zoneFk

View File

@ -499,6 +499,8 @@ INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
(12, 12, 4),
(13, 13, 5);
INSERT INTO `vn`.`zoneConfig` (`scope`) VALUES ('1');
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
VALUES
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), CURDATE(), 1),
@ -1530,7 +1532,7 @@ INSERT INTO `vn`.`ticketRequest`(`id`, `description`, `requesterFk`, `attenderFk
VALUES
(1, 'Ranged weapon longbow 2m', 18, 35, 5, 1, 9.10, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
(2, 'Melee weapon combat first 15cm', 18, 35, 10, 2, 1.07, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
(3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, 4, 3.06, 0, NULL, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY)),
(3, 'Melee weapon heavy shield 1x0.5m', 18, 35, 20, NULL, 3.06, NULL, NULL, 23, CURDATE()),
(4, 'Melee weapon combat first 15cm', 18, 35, 15, NULL, 1.30, NULL, NULL, 11, CURDATE()),
(5, 'Melee weapon combat first 15cm', 18, 35, 15, 4, 1.30, 0, NULL, 18, CURDATE());

View File

@ -179,6 +179,13 @@ let actions = {
await this.click(selector);
},
writeOnEditableTD: async function(selector, text) {
let builtSelector = await this.selectorFormater(selector);
await this.waitToClick(selector);
await this.type(builtSelector, text);
await this.keyboard.press('Enter');
},
focusElement: async function(selector) {
await this.wait(selector);
return await this.evaluate(selector => {
@ -284,22 +291,14 @@ let actions = {
}, {}, selector, text);
},
selectorFormater: async function(selector) {
let builtSelector = `${selector} input`;
if (selector.includes('vn-autocomplete'))
return builtSelector = `${selector} input`;
selectorFormater: function(selector) {
if (selector.includes('vn-textarea'))
return builtSelector = `${selector} textarea`;
if (selector.includes('vn-textfield'))
return builtSelector = `${selector} input`;
return `${selector} textarea`;
if (selector.includes('vn-input-file'))
return builtSelector = `${selector} section`;
return `${selector} section`;
return builtSelector;
return `${selector} input`;
},
waitForTextInField: async function(selector, text) {

View File

@ -250,6 +250,17 @@ export default {
inactiveIcon: 'vn-item-descriptor vn-icon[icon="icon-unavailable"]',
navigateBackToIndex: 'vn-item-descriptor vn-icon[icon="chevron_left"]'
},
itemRequest: {
firstRequestItemID: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(7)',
firstRequestQuantity: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td-editable:nth-child(8)',
firstRequestConcept: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(9)',
secondRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(10)',
firstRequestStatus: 'vn-item-request vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(10)',
secondRequestDecline: 'vn-item-request vn-tbody > vn-tr:nth-child(1) vn-icon-button[icon="thumb_down"]',
declineReason: 'vn-textarea[ng-model="$ctrl.denyObservation"]',
acceptDeclineReason: 'button[response="accept"]',
},
itemBasicData: {
basicDataButton: 'vn-left-menu a[ui-sref="item.card.basicData"]',
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',

View File

@ -0,0 +1,48 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Item request path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'item');
await page.accessToSection('item.request');
});
afterAll(async() => {
await browser.close();
});
it('should reach the item request section', async() => {
const result = await page.expectURL('/item/request');
expect(result).toBe(true);
});
it('should fill the id and quantity then check the concept was updated', async() => {
await page.writeOnEditableTD(selectors.itemRequest.firstRequestItemID, '4');
await page.writeOnEditableTD(selectors.itemRequest.firstRequestQuantity, '10');
await page.waitForTextInElement(selectors.itemRequest.firstRequestConcept, 'Melee weapon heavy shield 1x0.5m');
let filledConcept = await page.waitToGetProperty(selectors.itemRequest.firstRequestConcept, 'innerText');
expect(filledConcept).toContain('Melee weapon heavy shield 1x0.5m');
});
it('should the status of the request should now be accepted', async() => {
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
expect(status).toContain('Aceptada');
});
it('should now click on the second declain request icon then type the reason', async() => {
await page.waitToClick(selectors.itemRequest.secondRequestDecline);
await page.write(selectors.itemRequest.declineReason, 'not quite as expected');
await page.waitToClick(selectors.itemRequest.acceptDeclineReason);
await page.waitForContentLoaded();
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
expect(status).toContain('Denegada');
});
});

View File

@ -15,7 +15,7 @@ export function directive($parse) {
const element = $element[0];
$element.on('click', () => {
const controller = element.$ctrl;
controller.$oldDisabled = field.$ctrl.disabled;
controller.$oldDisabled = controller.disabled;
controller.disabled = true;
cb($scope).finally(() => {

View File

@ -11,7 +11,7 @@
"Zone": {
"dataSource": "vn"
},
"ZoneCalcTicket": {
"ZoneClosure": {
"dataSource": "vn"
},
"ZoneEvent": {

View File

@ -1,6 +1,5 @@
const app = require('vn-loopback/server/server');
module.exports = Self => {
app.on('started', function() {
let models = ['Zone', 'ZoneEvent', 'ZoneExclusion'];
@ -14,10 +13,13 @@ module.exports = Self => {
async function doCalc(ctx) {
try {
await Self.create({zoneFk: ctx.instance.zoneFk || ctx.instance.id});
await Self.rawSql(`
CREATE EVENT zoneClosure_doRecalc
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 15 SECOND
DO CALL zoneClosure_recalc;
`);
} catch (err) {
if (err.code != 'ER_DUP_ENTRY')
throw err;
if (err.code != 'ER_EVENT_ALREADY_EXISTS') throw err;
}
}
});

View File

@ -1,15 +1,23 @@
{
"name": "ZoneCalcTicket",
"name": "ZoneClosure",
"base": "VnModel",
"options": {
"mysql": {
"table": "zoneCalcTicket"
"table": "zoneClosure"
}
},
"properties": {
"zoneFk": {
"id": true,
"type": "Number"
},
"dated": {
"type": "Date",
"required": true
},
"hour": {
"type": "date",
"required": true
}
},
"relations": {

View File

@ -5,60 +5,60 @@ module.exports = function(Self) {
description: 'Creates client address updating default address',
accepts: [{
arg: 'id',
type: 'Number',
type: 'number',
description: 'The client id',
http: {source: 'path'}
},
{
arg: 'nickname',
type: 'String',
type: 'string',
required: true
},
{
arg: 'city',
type: 'String',
type: 'string',
required: true
},
{
arg: 'street',
type: 'String',
type: 'string',
required: true
},
{
arg: 'phone',
type: 'String'
type: 'string'
},
{
arg: 'mobile',
type: 'String'
type: 'string'
},
{
arg: 'postalCode',
type: 'String'
type: 'string'
},
{
arg: 'provinceId',
type: 'Number'
type: 'number'
},
{
arg: 'agencyModeId',
type: 'Number'
type: 'number'
},
{
arg: 'incotermsId',
type: 'String'
type: 'string'
},
{
arg: 'customsAgentId',
type: 'Number'
type: 'number'
},
{
arg: 'isActive',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isDefaultAddress',
type: 'Boolean'
type: 'boolean'
}],
returns: {
root: true,

View File

@ -10,63 +10,63 @@ module.exports = function(Self) {
},
{
arg: 'clientId',
type: 'Number',
type: 'number',
description: 'The client id',
http: {source: 'path'}
},
{
arg: 'addressId',
type: 'Number',
type: 'number',
description: 'The address id',
http: {source: 'path'}
},
{
arg: 'nickname',
type: 'String'
type: 'string'
},
{
arg: 'city',
type: 'String'
type: 'string'
},
{
arg: 'street',
type: 'String'
type: 'string'
},
{
arg: 'phone',
type: 'String'
type: 'any'
},
{
arg: 'mobile',
type: 'String'
type: 'any'
},
{
arg: 'postalCode',
type: 'String'
type: 'any'
},
{
arg: 'provinceFk',
type: 'Number'
type: 'any'
},
{
arg: 'agencyModeFk',
type: 'Number'
type: 'any'
},
{
arg: 'incotermsFk',
type: 'String'
type: 'any'
},
{
arg: 'customsAgentFk',
type: 'Number'
type: 'any'
},
{
arg: 'isActive',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isEqualizated',
type: 'Boolean'
type: 'boolean'
}],
returns: {
root: true,

View File

@ -17,75 +17,75 @@ module.exports = Self => {
},
{
arg: 'socialName',
type: 'String'
type: 'string'
},
{
arg: 'fi',
type: 'String'
type: 'string'
},
{
arg: 'street',
type: 'String'
type: 'string'
},
{
arg: 'postcode',
type: 'String'
type: 'string'
},
{
arg: 'city',
type: 'String'
type: 'string'
},
{
arg: 'countryFk',
type: 'Number'
type: 'number'
},
{
arg: 'provinceFk',
type: 'Number'
type: 'number'
},
{
arg: 'hasToInvoiceByAddress',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'hasToInvoice',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isActive',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isFreezed',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isVies',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isToBeMailed',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isEqualizated',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isTaxDataVerified',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'isTaxDataChecked',
type: 'Boolean'
type: 'boolean'
},
{
arg: 'despiteOfClient',
type: 'Number'
type: 'number'
}],
returns: {
arg: 'res',
type: 'String',
type: 'string',
root: true
},
http: {

View File

@ -55,10 +55,11 @@ class Controller extends Component {
}
showSMSDialog() {
const phone = this.$params.phone || this.client.phone;
const client = this.client;
const phone = this.$params.phone || client.mobile || client.phone;
const message = this.$params.message || '';
this.newSMS = {
destinationFk: this.client.id,
destinationFk: client.id,
destination: phone,
message: message
};

View File

@ -85,7 +85,7 @@
<vn-td>
<vn-icon
ng-if="request.response.length"
ranslate-attr="{title: request.response}"
translate-attr="{title: request.response}"
icon="insert_drive_file">
</vn-icon>
<vn-icon-button

View File

@ -1,12 +1,12 @@
const app = require('vn-loopback/server/server');
describe('ticket-request filter()', () => {
it('should return all ticket requests', async() => {
it('should now return all ticket requests', async() => {
let ctx = {req: {accessToken: {userId: 9}}, args: {}};
let result = await app.models.TicketRequest.filter(ctx);
expect(result.length).toEqual(2);
expect(result.length).toEqual(3);
});
it('should return the ticket request matching a generic search value which is the ticket ID', async() => {
@ -42,7 +42,7 @@ describe('ticket-request filter()', () => {
let result = await app.models.TicketRequest.filter(ctx);
let requestId = result[0].id;
expect(requestId).toEqual(4);
expect(requestId).toEqual(3);
});
it('should return the ticket request matching the isOk triple-state', async() => {
@ -51,7 +51,7 @@ describe('ticket-request filter()', () => {
let result = await app.models.TicketRequest.filter(ctx);
let requestId = result[0].id;
expect(requestId).toEqual(4);
expect(requestId).toEqual(3);
});
it('should return the ticket request matching the client ID', async() => {
@ -69,7 +69,7 @@ describe('ticket-request filter()', () => {
let result = await app.models.TicketRequest.filter(ctx);
let requestId = result[0].id;
expect(requestId).toEqual(4);
expect(requestId).toEqual(3);
});
it('should return the ticket request matching the salesPerson ID', async() => {
@ -78,6 +78,6 @@ describe('ticket-request filter()', () => {
let result = await app.models.TicketRequest.filter(ctx);
let requestId = result[0].id;
expect(requestId).toEqual(4);
expect(requestId).toEqual(3);
});
});

View File

@ -108,8 +108,10 @@ module.exports = Self => {
await Promise.all(promises);
query = `call vn.manaSpellersRequery(?)`;
await Self.rawSql(query, [salesPersonId], options);
if (salesPersonId) {
const query = `call vn.manaSpellersRequery(?)`;
await Self.rawSql(query, [salesPersonId], options);
}
await tx.commit();
} catch (error) {

View File

@ -27,7 +27,9 @@ class Controller extends ModuleCard {
'isFreezed',
'isTaxDataChecked',
'credit',
'email'
'email',
'phone',
'mobile'
],
include: {
relation: 'salesPerson',

View File

@ -241,7 +241,9 @@ class Controller extends Component {
showSMSDialog() {
const address = this.ticket.address;
const phone = this.$params.phone || address.mobile;
const client = this.ticket.client;
const phone = this.$params.phone || address.mobile || address.phone ||
client.mobile || client.phone;
const message = this.$params.message || this.$translate.instant('SMSPayment');
this.newSMS = {
destinationFk: this.ticket.clientFk,

View File

@ -431,6 +431,9 @@ class Controller {
showSMSDialog() {
const address = this.ticket.address;
const client = this.ticket.client;
const phone = address.mobile || address.phone ||
client.mobile || client.phone;
const sales = this.checkedLines();
const items = sales.map(sale => {
return `${sale.quantity} ${sale.concept}`;
@ -443,7 +446,7 @@ class Controller {
};
this.newSMS = {
destinationFk: this.ticket.clientFk,
destination: address.mobile || null,
destination: phone,
message: this.$translate.instant('SMSAvailability', params)
};
this.$scope.sms.open();