This commit is contained in:
Juan Ferrer 2019-10-15 16:19:38 +02:00
commit a2881e5b1a
57 changed files with 10576 additions and 6269 deletions

View File

@ -29,8 +29,8 @@ module.exports = Self => {
const accessToken = ctx.options && ctx.options.accessToken || ctx.req && ctx.req.accessToken;
const userId = accessToken.userId;
const models = Self.app.models;
const sender = await models.Account.findById(userId, options);
const recipient = await models.Account.findById(data.recipientFk, options);
const sender = await models.Account.findById(userId, null, options);
const recipient = await models.Account.findById(data.recipientFk, null, options);
await Self.create({
sender: sender.name,

View File

@ -0,0 +1 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('UserPhone', '*', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

@ -0,0 +1,18 @@
CREATE TABLE `vn`.`userLog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`originFk` int(11) NOT NULL,
`userFk` int(10) unsigned DEFAULT NULL,
`action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL,
`creationDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`description` text CHARACTER SET utf8,
`changedModel` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
`oldInstance` text COLLATE utf8_unicode_ci,
`newInstance` text COLLATE utf8_unicode_ci,
`changedModelId` int(11) DEFAULT NULL,
`changedModelValue` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `originFk` (`originFk`),
KEY `userFk` (`userFk`),
CONSTRAINT `userLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `userLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

View File

@ -0,0 +1,9 @@
CREATE TABLE `vn`.`userPhoneType` (
`code` VARCHAR(45) NOT NULL,
`description` VARCHAR(255) NULL,
PRIMARY KEY (`code`));
INSERT INTO `vn`.`userPhoneType` (`code`, `description`) VALUES ('businessPhone', 'Telefono de empresa del usuario');
INSERT INTO `vn`.`userPhoneType` (`code`, `description`) VALUES ('personalPhone', 'Telefono personal del usuario');

View File

@ -0,0 +1,63 @@
CREATE TABLE `vn`.`userPhone` (
`id` INT NOT NULL AUTO_INCREMENT,
`userFk` INT(10) UNSIGNED NOT NULL,
`typeFk` VARCHAR(45) NOT NULL,
`phone` INT(15) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `UserFK_Phone` (`userFk` ASC, `phone` ASC));
ALTER TABLE `vn`.`userPhone`
ADD CONSTRAINT `fgnTypeFk`
FOREIGN KEY (typeFk)
REFERENCES `vn`.`userPhoneType` (code)
ON DELETE RESTRICT
ON UPDATE CASCADE;
ALTER TABLE `vn`.`userPhone`
ADD CONSTRAINT `fgnUserFk`
FOREIGN KEY (userFk)
REFERENCES `account`.`user` (id)
ON DELETE CASCADE
ON UPDATE CASCADE;
insert into vn.userPhone(userFk,typeFk,phone)
select id,'PersonalPhone', phone
from vn.client
where phone is not null;
insert into vn.userPhone(userFk,typeFk,phone)
select id,'businessPhone', phone
from vn.worker
where phone is not null AND phone > '';
insert into vn.userPhone(userFk,typeFk,phone)
SELECT
`w`.`userFk`,
'businessPhone',
`m`.`value` AS `mediaValue`
FROM
(((((`postgresql`.`person` `p`
JOIN `postgresql`.`profile` `po` ON ((`po`.`person_id` = `p`.`person_id`)))
JOIN `postgresql`.`profile_media` `pom` ON ((`pom`.`profile_id` = `po`.`profile_id`)))
JOIN `postgresql`.`media` `m` ON ((`m`.`media_id` = `pom`.`media_id`)))
JOIN `postgresql`.`media_type` `mt` ON ((`mt`.`media_type_id` = `m`.`media_type_id`)))
JOIN `vn`.`worker` `w` ON ((`w`.`id` = `p`.`id_trabajador`)))
WHERE
(`mt`.`name` = 'movil empresa');
insert into vn.userPhone(userFk,typeFk,phone)
SELECT
`w`.`userFk`,
'personalPhone',
`m`.`value` AS `mediaValue`
FROM
(((((`postgresql`.`person` `p`
JOIN `postgresql`.`profile` `po` ON ((`po`.`person_id` = `p`.`person_id`)))
JOIN `postgresql`.`profile_media` `pom` ON ((`pom`.`profile_id` = `po`.`profile_id`)))
JOIN `postgresql`.`media` `m` ON ((`m`.`media_id` = `pom`.`media_id`)))
JOIN `postgresql`.`media_type` `mt` ON ((`mt`.`media_type_id` = `m`.`media_type_id`)))
JOIN `vn`.`worker` `w` ON ((`w`.`id` = `p`.`id_trabajador`)))
WHERE
(`mt`.`name` = 'movil personal')

File diff suppressed because one or more lines are too long

View File

@ -65,6 +65,11 @@ INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasA
(4, 'Warehouse Four', 1, 1, 1, 1, 0),
(5, 'Warehouse Five', 1, 1, 1, 1, 0);
INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPreparedByPacking`, `code`, `pickingPlacement`, `path`)
VALUES
(1, 'First sector', 1, 1, 'FIRST', 999, 999),
(2, 'Second sector', 2, 0, 'SECOND', 100, 150);
INSERT INTO `vn`.`warehouseAlias`(`id`, `name`)
VALUES
(1, 'Main Warehouse');
@ -194,8 +199,8 @@ INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city
(108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1),
(109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1),
(110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, NULL, 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1),
(200, 'Missing', NULL, 'Missing man', 'Anton', 'The space', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1),
(400, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1);
(111, 'Missing', NULL, 'Missing man', 'Anton', 'The space', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1),
(112, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city', 'Silla', 46460, 1111111111, 222222222, 333333333, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, NULL, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1);
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `phone`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'SILLA', 46460, 623111111, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, CURDATE(), 1
@ -221,8 +226,8 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr
(8, 'Charles Xavier', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1, 1111111111, 222222222, 1, 108, 2, NULL, NULL, 0, 1),
(9, 'Bruce Banner', 'Somewhere in New York', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 1),
(10, 'Jessica Jones', 'NYCC 2015 Poster', 'Silla', 46460, 1, 1111111111, 222222222, 1, 110, 2, NULL, NULL, 0, 1),
(11, 'Missing', 'The space', 'Silla', 46460, 1, 1111111111, 222222222, 1, 200, 10, NULL, NULL, 0, 1),
(12, 'Trash', 'New York city', 'Silla', 46460, 1, 1111111111, 222222222, 1, 400, 10, NULL, NULL, 0, 1),
(11, 'Missing', 'The space', 'Silla', 46460, 1, 1111111111, 222222222, 1, 111, 10, NULL, NULL, 0, 1),
(12, 'Trash', 'New York city', 'Silla', 46460, 1, 1111111111, 222222222, 1, 112, 10, NULL, NULL, 0, 1),
(101, 'address 01', 'Somewhere in Thailand', 'Silla', 46460, 1, 1111111111, 222222222, 1, 109, 2, NULL, NULL, 0, 0),
(102, 'address 02', 'Somewhere in Poland', 'Silla', 46460, 1, 3333333333, 444444444, 1, 109, 2, NULL, NULL, 0, 0),
(103, 'address 03', 'Somewhere in Japan', 'Silla', 46460, 1, 3333333333, 444444444, 1, 109, 2, NULL, NULL, 0, 0),
@ -252,9 +257,7 @@ INSERT INTO `vn`.`address`(`id`, `nickname`, `street`, `city`, `postalCode`, `pr
(127, 'address 27', 'Your pocket', 'Silla', 46460, 1, 1111111111, 222222222, 1, 107, 2, NULL, NULL, 0, 0),
(128, 'address 28', 'Cerebro', 'Silla', 46460, 1, 1111111111, 222222222, 1, 108, 2, NULL, NULL, 0, 0),
(129, 'address 29', 'Luke Cages Bar', 'Silla', 46460, 1, 1111111111, 222222222, 1, 110, 2, NULL, NULL, 0, 0),
(130, 'address 30', 'Non valid address', 'Silla', 46460, 1, 1111111111, 222222222, 0, 101, 2, NULL, NULL, 0, 0),
(131, 'Missing', 'The space', 'Silla', 46460, 1, 1111111111, 222222222, 1, 200, 10, NULL, NULL, 0, 0),
(132, 'Trash', 'New York city', 'Silla', 46460, 1, 1111111111, 222222222, 1, 400, 10, NULL, NULL, 0, 0);
(130, 'address 30', 'Non valid address', 'Silla', 46460, 1, 1111111111, 222222222, 0, 101, 2, NULL, NULL, 0, 0);
INSERT INTO `vn`.`address`( `nickname`, `street`, `city`, `postalCode`, `provinceFk`, `isActive`, `clientFk`, `agencyModeFk`, `isDefaultAddress`)
SELECT name, CONCAT(name, 'Street'), 'SILLA', 46460, 1, 1, id, 2, 1

File diff suppressed because it is too large Load Diff

View File

@ -45,20 +45,20 @@ TABLES=(
claimReason
claimRedelivery
claimResult
ticketUpdateAction
state
)
dump_tables ${TABLES[@]}
TABLES=(
vn2008
accion_dits
bionic_updating_options
businessReasonEnd
container
department
escritos
Grupos
iva_group_codigo
state
tarifa_componentes
tarifa_componentes_series
)

View File

@ -12,7 +12,10 @@ module.exports = function createNightmare(width = 1280, height = 720) {
typeInterval: 10,
x: 0,
y: 0,
waitTimeout: 2000
waitTimeout: 2000,
// openDevTools: {
// mode: 'detach'
// }
}).viewport(width, height);
nightmare.on('console', (type, message, ...args) => {

View File

@ -362,7 +362,8 @@ export default {
moreMenuDeleteTicket: '.vn-popover.shown .vn-drop-down li[name="Delete ticket"]',
moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
changeShippedHourInput: 'vn-ticket-descriptor .vn-dialog.shown vn-input-time input',
changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]',
changeShippedHourInput: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"] vn-input-time[vn-id="newShipped"]',
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
@ -428,7 +429,7 @@ export default {
firstSaleDiscountInput: 'vn-ticket-sale:nth-child(1) vn-ticket-sale-edit-discount vn-input-number input',
firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(9)',
firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)',
firstSaleColour: 'vn-tr:nth-child(1) vn-fetched-tags section',
firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-fetched-tags section',
firstSaleLength: 'vn-ticket-sale vn-tr:nth-child(1) vn-td-editable:nth-child(6) section:nth-child(3)',
firstSaleCheckbox: 'vn-ticket-sale vn-tr:nth-child(1) vn-check[ng-model="sale.checked"]',
secondSaleColour: 'vn-tr:nth-child(2) vn-fetched-tags section',

View File

@ -30,20 +30,11 @@ describe('Ticket descriptor path', () => {
expect(url.hash).toContain('/summary');
});
it('should open the change shipped hours dialog by using the more menu option', async() => {
const visible = await nightmare
it(`should update the shipped hour using the descriptor menu`, async() => {
const result = await nightmare
.waitToClick(selectors.ticketDescriptor.moreMenu)
.waitToClick(selectors.ticketDescriptor.moreMenuChangeShippedHour)
.wait(selectors.ticketDescriptor.changeShippedHourInput)
.isVisible(selectors.ticketDescriptor.changeShippedHourInput);
expect(visible).toBeTruthy();
});
it(`should update the shipped hour`, async() => {
const result = await nightmare
.pickTime(selectors.ticketDescriptor.changeShippedHourInput, '08:15')
.write(selectors.ticketDescriptor.changeShippedHourInput, '08:15')
.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton)
.waitForLastSnackbar();
@ -127,16 +118,6 @@ describe('Ticket descriptor path', () => {
expect(result).toEqual('Data saved!');
});
it(`should navigate to the added ticket using the descriptors ship button`, async() => {
const url = await nightmare
.waitToClick(selectors.ticketDescriptor.closeStowawayDialog)
.waitToClick(selectors.ticketDescriptor.shipButton)
.waitForURL('#!/ticket/17/summary')
.parsedUrl();
expect(url.hash).toContain('#!/ticket/17/summary');
});
it(`should check the state of the stowaway ticket is embarked`, async() => {
const state = await nightmare
.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText');
@ -144,15 +125,6 @@ describe('Ticket descriptor path', () => {
expect(state).toEqual('State Embarcando');
});
it(`should navigate to the ship ticket using the descriptors ship button`, async() => {
const url = await nightmare
.waitToClick(selectors.ticketDescriptor.shipButton)
.waitForURL('#!/ticket/16/summary')
.parsedUrl();
expect(url.hash).toContain('#!/ticket/16/summary');
});
it(`should navigate back to the added ticket using the descriptors ship button`, async() => {
const url = await nightmare
.waitToClick(selectors.ticketDescriptor.closeStowawayDialog)

View File

@ -78,7 +78,7 @@ describe('Ticket services path', () => {
.waitToClick(selectors.ticketService.saveDescriptionButton)
.waitForLastSnackbar();
expect(result).toEqual(`can't be blank`);
expect(result).toEqual(`Name can't be empty`);
});
it('should create a new description then add price then create the service', async() => {

View File

@ -69,7 +69,7 @@ function vnAcl(aclService, $timeout) {
if (!toAdd && position > -1)
acls.splice(position, 1);
// todo: add acl and enabled element if previusly was disabled
// XXX: add acl and enabled element if previusly was disabled
}
return {

View File

@ -303,7 +303,7 @@ function webpackDevServer(done) {
new WebpackDevServer(compiler, wpConfig.devServer)
.listen(devServer.port, devServer.host, function(err) {
if (err) throw new PluginError('webpack-dev-server', err);
// TODO: Keep the server alive or continue?
// XXX: Keep the server alive or continue?
done();
});
}

View File

@ -134,7 +134,7 @@ module.exports = function(Self) {
break;
}
val = recordSet && recordSet.id || val; // FIXME preparar todos los modelos con campo name
val = recordSet && recordSet.id || val;
break;
}
}

View File

@ -108,5 +108,6 @@
"This postal code is not valid": "This postal code is not valid",
"is invalid": "is invalid",
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto",
"The department name can't be repeated": "El nombre del departamento no puede repetirse"
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado"
}

View File

@ -27,24 +27,3 @@ exports.getFinalState = function(ctx) {
exports.isMultiple = function(ctx) {
return !ctx.isNewInstance && !ctx.currentInstance;
};
/* exports.fkToValue = async function(instance, ctx, model) {
let transaction = ctx.options && ctx.options.transaction;
let cleanInstance = JSON.parse(JSON.stringify(instance));
let result = {};
for (let key in cleanInstance) {
let val = cleanInstance[key];
if (val === undefined || val === null) continue;
for (let key1 in model.relations) {
let val1 = model.relations[key1];
if (val1.keyFrom == key && key != 'id') {
let recordSet = await val1.modelTo.findById(val, {}, {transaction});
val = recordSet.name || recordSet.id; // FIXME preparar todos los modelos con campo name
break;
}
}
result[key] = val;
}
return result;
};
*/

View File

@ -1,3 +1,3 @@
Traveling days: Días de viaje
Closure hour (ETD): Hora de cierre (ETD)
Closing hour (ETD): Hora de cierre (ETD)
Bonus: Bonificación

View File

@ -30,7 +30,7 @@
<vn-label-value label="Agency"
value="{{$ctrl.zone.agencyMode.name}}">
</vn-label-value>
<vn-label-value label="Closure hour (ETD)"
<vn-label-value label="Closing hour (ETD)"
value="{{$ctrl.zone.hour | dateTime: 'HH:mm'}}">
</vn-label-value>
<vn-label-value label="Traveling days"

View File

@ -13,7 +13,7 @@
</vn-label-value>
</vn-one>
<vn-one>
<vn-label-value label="Estimated hour (ETD)"
<vn-label-value label="Closing hour (ETD)"
value="{{$ctrl.summary.hour | dateTime: 'HH:mm'}}">
</vn-label-value>
<vn-label-value label="Traveling days"

View File

@ -1,3 +1,5 @@
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
Self.remoteMethodCtx('createFromSales', {
description: 'Create a claim',
@ -25,13 +27,19 @@ module.exports = Self => {
});
Self.createFromSales = async(ctx, params) => {
let model = Self.app.models;
let models = Self.app.models;
let userId = ctx.req.accessToken.userId;
let tx = await Self.beginTransaction({});
try {
let options = {transaction: tx};
const worker = await Self.app.models.Worker.findOne({
const ticketId = params.claim.ticketFk;
const ticket = await models.Ticket.findById(ticketId, null, options);
if (ticket.isDeleted)
throw new UserError(`You can't create a claim for a removed ticket`);
const worker = await models.Worker.findOne({
where: {userFk: userId}
}, options);
@ -40,7 +48,7 @@ module.exports = Self => {
let promises = [];
for (const sale of params.sales) {
const newClaimBeginning = model.ClaimBeginning.create({
const newClaimBeginning = models.ClaimBeginning.create({
saleFk: sale.id,
claimFk: newClaim.id,
quantity: sale.quantity

View File

@ -26,7 +26,7 @@ module.exports = function(Self) {
let address = data.address;
let newAddress = await Address.create(address, options);
let client = await Client.findById(address.clientFk, options);
let client = await Client.findById(address.clientFk, null, options);
if (data.isDefaultAddress) {
await client.updateAttributes({

View File

@ -17,7 +17,7 @@ describe('Client activeWorkersWithRole', () => {
let isBuyer = await app.models.Account.hasRole(result[0].id, 'buyer');
expect(result.length).toEqual(10);
expect(result.length).toEqual(11);
expect(isBuyer).toBeTruthy();
});
});

View File

@ -1,16 +0,0 @@
const app = require('vn-loopback/server/server');
/**
* ¡Importante!
* Envio SMS de prueba a servicio real Masmovil. No llega a enviarse
* por destinatario inválido, pero puede llegar a fallar.
*/
describe('sms send()', () => {
it('should return the expected message and status code', async() => {
let ctx = {req: {accessToken: {userId: 1}}};
let result = await app.models.Sms.send(ctx, 105, 'Invalid', 'My SMS Body');
expect(result.statusCode).toEqual(200);
expect(result.status).toEqual('Envio en procesamiento');
});
});

View File

@ -5,7 +5,7 @@ module.exports = function(Self) {
Self.validateBinded('credit', Self.validateCredit, {
message: 'The credit must be an integer greater than or equal to zero',
allowNull: false, // FIXME: Ignored by loopback when it's false
allowNull: false,
allowBlank: false
});

View File

@ -61,33 +61,43 @@
</vn-thead>
<vn-tbody>
<vn-tr ng-repeat="balance in $ctrl.balances">
<vn-td>{{::balance.payed | dateTime:'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::balance.created | dateTime:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td>
<span
<span title="{{::balance.payed | dateTime:'dd/MM/yyyy'}}">
{{::balance.payed | dateTime:'dd/MM/yyyy'}}
</span>
</vn-td>
<vn-td>
<span title="{{::balance.created | dateTime:'dd/MM/yyyy HH:mm'}}">
{{::balance.created | dateTime:'dd/MM/yyyy HH:mm'}}
</span>
</vn-td>
<vn-td>
<span
class="link"
ng-click="$ctrl.showWorkerDescriptor($event, balance.workerFk)">
{{::balance.userNickname}}
</span>
</vn-td>
<vn-td>
<vn-td expand>
<span
title="{{balance.isInvoice ? 'BILL' : balance.ref | translate: {ref: balance.ref} }}"
ng-class="{'link': balance.isInvoice}"
ng-click="$ctrl.showInvoiceOutDescriptor($event, balance)"
ng-show="balance.ref">{{balance.isInvoice ? 'BILL' : balance.ref | translate: {ref: balance.ref} }}
ng-show="balance.ref">
{{balance.isInvoice ? 'BILL' : balance.ref | translate: {ref: balance.ref} }}
</span>
</vn-td>
<vn-td number>{{::balance.bankFk}}</vn-td>
<vn-td number>{{::balance.debit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{::balance.credit | currency: 'EUR':2}}</vn-td>
<vn-td number>{{balance.balance | currency: 'EUR':2}}</vn-td>
<vn-td center>
<vn-td center shrink>
<vn-check
ng-model="balance.isConciliate"
disabled="true">
</vn-check>
</vn-td>
<vn-td center>
<vn-td center shrink>
<a ng-show="balance.hasPdf"
target="_blank"
href="api/InvoiceOuts/{{::balance.id}}/download?access_token={{::$ctrl.accessToken}}">

View File

@ -9,7 +9,7 @@ class Controller {
this.$translate = $translate;
this.accessToken = vnToken.token;
this.companyFk = vnConfig.companyFk;
this.vnConfig = vnConfig;
this.filter = {
include: {
relation: 'company',
@ -29,6 +29,17 @@ class Controller {
},
};
}
get companyFk() {
if (!this._companyFk)
return this.vnConfig.companyFk;
return this._companyFk;
}
set companyFk(id) {
this._companyFk = id;
}
setOrder(value) {
this.params.params.companyFk = value;
this.filter.where.companyFk = value;

View File

@ -77,11 +77,11 @@ module.exports = Self => {
let where = buildFilter(ctx.args, (param, value) => {
switch (param) {
case 'search':
return {ref: {like: `%${value}%`}};
return {'i.ref': {like: `%${value}%`}};
case 'min':
return {amount: {gte: value}};
return {'i.amount': {gte: value}};
case 'max':
return {amount: {lte: value}};
return {'i.amount': {lte: value}};
case 'hasPdf':
return {'i.hasPdf': value};
case 'created':

View File

@ -22,7 +22,7 @@ module.exports = Self => {
Self.regenerate = async(ctx, id) => {
const userId = ctx.req.accessToken.userId;
const models = Self.app.models;
const invoiceReportFk = 30; // FIXME - Should be deprecated
const invoiceReportFk = 30; // Should be deprecated
const worker = await models.Worker.findOne({where: {userFk: userId}});
const tx = await Self.beginTransaction({});

View File

@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server');
describe('invoiceOut regenerate()', () => {
const invoiceReportFk = 30; // FIXME - Should be deprecated
const invoiceReportFk = 30;
const invoiceOutId = 1;
afterAll(async done => {

View File

@ -1,7 +1,5 @@
vn-item-descriptor-popover {
vn-item-descriptor {
display: block;
width: 16em;
min-height: 28em;
}
body > .vn-popover vn-item-descriptor {
display: block;
width: 16em;
min-height: 28em;
}

View File

@ -55,7 +55,7 @@
</vn-check>
</vn-td>
<vn-td>{{::order.sourceApp}}</vn-td>
<vn-td center>{{::order.created | date:'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td center>{{::order.created | dateTime: 'dd/MM/yyyy HH:mm'}}</vn-td>
<vn-td center>{{::order.landed | date:'dd/MM/yyyy'}}</vn-td>
<vn-td>{{::order.companyCode}}</vn-td>
<vn-td number>{{::order.total | currency: 'EUR': 2 | dashIfEmpty}}</vn-td>

View File

@ -67,7 +67,7 @@
</vn-input-time>
</vn-horizontal>
<vn-horizontal>
<vn-textfield
<vn-textArea
vn-one
label="Description"
ng-model="$ctrl.route.description"

View File

@ -61,14 +61,14 @@ describe('sale updatePrice()', () => {
it('should set price as a decimal number and check the sale has the mana component', async() => {
let ctx = {req: {accessToken: {userId: 9}}};
let price = 5.3;
let price = 5.4;
await app.models.Sale.updatePrice(ctx, saleId, price);
let saleUpdated = await app.models.Sale.findById(saleId);
createdSaleComponent = await app.models.SaleComponent.findOne({where: {saleFk: saleId, componentFk: manaComponentId}});
expect(saleUpdated.price).toBe(price);
expect(createdSaleComponent.value).toEqual(-2.14);
expect(createdSaleComponent.value).toEqual(-2.04);
});
it('should check that the mana of salesPerson changed', async() => {

View File

@ -55,11 +55,6 @@ module.exports = Self => {
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',
@ -77,7 +72,7 @@ module.exports = Self => {
});
Self.componentUpdate = async(ctx, id, clientId, agencyModeId, addressId, zoneId, warehouseId,
companyId, shipped, landed, isDeleted, hasToBeUnrouted, option) => {
companyId, shipped, landed, isDeleted, option) => {
const userId = ctx.req.accessToken.userId;
const models = Self.app.models;
const isEditable = await models.Ticket.isEditable(ctx, id);
@ -85,10 +80,6 @@ module.exports = Self => {
if (!isEditable)
throw new UserError(`The sales of this ticket can't be modified`);
const hasDeliveryRole = await models.Account.hasRole(userId, 'delivery');
if (!hasDeliveryRole)
hasToBeUnrouted = true;
const isProductionBoss = await models.Account.hasRole(userId, 'productionBoss');
if (!isProductionBoss) {
const zoneShipped = await models.Agency.getShipped(landed, addressId, agencyModeId, warehouseId);
@ -97,6 +88,8 @@ module.exports = Self => {
throw new UserError(`You don't have privileges to change the zone`);
}
// Force unroute
const hasToBeUnrouted = true;
let query = 'CALL vn.ticket_componentMakeUpdate(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
let res = await Self.rawSql(query, [
id,

View File

@ -37,13 +37,12 @@ describe('ticket componentUpdate()', () => {
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(ctx, ticketId, clientId, agencyModeId, addressId,
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
zoneId, warehouseId, companyId, shipped, landed, isDeleted, option);
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
let firstvalueAfterChange = componentValue.value;
@ -65,12 +64,11 @@ describe('ticket componentUpdate()', () => {
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(ctx, ticketId, clientId, agencyModeId, addressId,
zoneId, warehouseId, companyId, shipped, landed, isDeleted, hasToBeUnrouted, option);
zoneId, warehouseId, companyId, shipped, landed, isDeleted, option);
[componentValue] = await app.models.SaleComponent.rawSql(componentOfSaleSeven);
let firstvalueAfterChange = componentValue.value;

View File

@ -10,12 +10,5 @@
initial-data="$ctrl.ticket.option">
</vn-autocomplete>
</vn-horizontal>
<vn-horizontal>
<vn-check
vn-one label="Remove from route"
ng-model="$ctrl.ticket.hasToBeUnrouted"
vn-acl="delivery">
</vn-check>
</vn-horizontal>
</vn-card>
</form>

View File

@ -15,7 +15,6 @@ class Controller {
$onChanges() {
this.ticket.option = 1;
this.ticket.hasToBeUnrouted = true;
}
onStepChange(state) {
@ -40,15 +39,15 @@ class Controller {
shipped: this.ticket.shipped,
landed: this.ticket.landed,
isDeleted: this.ticket.isDeleted,
hasToBeUnrouted: this.ticket.hasToBeUnrouted,
option: this.ticket.option
};
this.$http.post(query, params).then(res => {
if (res.data) {
this.$state.go('ticket.card.summary', {id: this.$state.params.id});
this.card.reload();
}
this.vnApp.showMessage(
this.$translate.instant(`The ticket has been unrouted`)
);
this.card.reload();
this.$state.go('ticket.card.summary', {id: this.$state.params.id});
});
}
}

View File

@ -31,6 +31,7 @@ describe('ticket', () => {
});
it('should perform a post query correctly then call two functions()', () => {
spyOn(controller.vnApp, 'showMessage');
controller.card = {reload: () => {}};
spyOn(controller.card, 'reload');
@ -60,8 +61,9 @@ describe('ticket', () => {
controller.onSubmit();
$httpBackend.flush();
expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.summary', jasmine.any(Object));
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('The ticket has been unrouted');
expect(controller.card.reload).toHaveBeenCalledWith();
expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.summary', jasmine.any(Object));
});
});
});

View File

@ -1,4 +1,4 @@
Charge: Cargo
Choose an option: Selecciona una opción
Charge difference to: Diferencia a cargo de
Remove from route: Sacar de la ruta
The ticket has been unrouted: El ticket ha sido desenrutado

View File

@ -7,10 +7,10 @@
class="modal-form"
on-open="model.refresh()">
<tpl-body>
<vn-horizontal class="header vn-pa-md">
<section class="header vn-pa-md">
<h5><span translate>Stowaways to add</span></h5>
</vn-horizontal>
<vn-horizontal class="vn-pa-md"> <!-- FIXME: Dialog width -->
</section>
<vn-horizontal class="vn-pa-md">
<vn-data-viewer model="model">
<vn-table model="model" auto-load="false">
<vn-thead>

View File

@ -15,7 +15,6 @@ class Controller {
{name: 'Delete ticket', callback: this.showDeleteTicketDialog},
{name: 'Change shipped hour', callback: this.showChangeShipped},
{name: 'Send SMS', callback: this.showSMSDialog},
{name: 'Show pallet report', callback: this.openRptRoute},
{
name: 'Add stowaway',
callback: this.showAddStowaway,
@ -147,11 +146,6 @@ class Controller {
}
}
openRptRoute() {
let url = `/api/report/rpt-route?routeFk=${this.ticket.routeFk}`;
window.open(url);
}
showAddStowaway() {
this.$scope.addStowaway.show();
}

View File

@ -7,9 +7,10 @@ vn-add-stowaway {
}
vn-dialog.modal-form {
vn-horizontal.header {
section.header {
background-color: $color-main;
color: $color-font-dark;
text-align: center;
h5 {
color: inherit;

View File

@ -1,6 +1,6 @@
<div class="header vn-pa-md">
<section class="header vn-pa-md">
<h5>MANÁ: {{$ctrl.mana | currency: 'EUR':0}}</h5>
</div>
</section>
<div class="vn-pa-md">
<vn-input-number
vn-focus

View File

@ -218,9 +218,9 @@
enable="true">
</vn-spinner>
<div ng-if="$ctrl.mana != null">
<div class="header vn-pa-md">
<section class="header vn-pa-md">
<h5>MANÁ: {{$ctrl.mana | currency: 'EUR':0}}</h5>
</div>
</section>
<div class="vn-pa-md">
<vn-input-number
vn-focus

View File

@ -11,11 +11,27 @@ class Controller {
this.$http = $http;
this.edit = {};
this.moreOptions = [
{callback: this.markAsReserved, name: 'Mark as reserved'},
{callback: this.unmarkAsReserved, name: 'Unmark as reserved'},
{callback: this.showEditDialog, name: 'Update discount', show: () => !this.hasInvoice()},
{callback: this.createClaim, name: 'Add claim'},
{callback: this.showSMSDialog, name: 'Send SMS'}
{name: 'Send SMS', callback: this.showSMSDialog},
{
name: 'Mark as reserved',
callback: this.markAsReserved,
show: () => this.isEditable
},
{
name: 'Unmark as reserved',
callback: this.unmarkAsReserved,
show: () => this.isEditable
},
{
name: 'Update discount',
callback: this.showEditDialog,
show: () => this.isEditable
},
{
name: 'Add claim',
callback: this.createClaim,
show: () => this.isEditable
},
];
this._sales = [];
this.imagesPath = '//verdnatura.es/vn-image-data/catalog';
@ -431,15 +447,6 @@ class Controller {
this.$scope.sms.open();
}
/**
* Returns if the current ticket
* is already invoiced
* @return {Boolean} - True if invoiced
*/
hasInvoice() {
return this.ticket.refFk !== null;
}
/**
* Inserts a new instance
*/

View File

@ -89,17 +89,19 @@ vn-ticket-sale {
}
}
.edit-price {
width: 200px;
min-width: 200px;
.header {
section.header {
background-color: $color-main;
color: $color-font-dark;
text-align: center;
h5 {
color: inherit;
margin: 0 auto;
}
}
p.simulatorTitle {
margin-bottom: 0px;
font-size: 12px;

View File

@ -38,5 +38,8 @@ module.exports = Self => {
timed: data.timed,
manual: 1
});
/* return Self.rawSql('CALL vn.workerTimeControl_add(?, ?, ?, ?)', [
subordinate.userFk, null, data.timed, true]); */
};
};

View File

@ -49,5 +49,14 @@
},
"Device": {
"dataSource": "vn"
},
"UserPhoneType": {
"dataSource": "vn"
},
"UserPhone": {
"dataSource": "vn"
},
"UserLog": {
"dataSource": "vn"
}
}

View File

@ -0,0 +1,58 @@
{
"name": "UserLog",
"base": "VnModel",
"options": {
"mysql": {
"table": "userLog"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"forceId": false
},
"originFk": {
"type": "Number",
"required": true
},
"userFk": {
"type": "Number"
},
"action": {
"type": "String",
"required": true
},
"changedModel": {
"type": "String"
},
"oldInstance": {
"type": "Object"
},
"newInstance": {
"type": "Object"
},
"creationDate": {
"type": "Date"
},
"changedModelId": {
"type": "Number"
},
"changedModelValue": {
"type": "String"
},
"description": {
"type": "String"
}
},
"relations": {
"user": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "userFk"
}
},
"scope": {
"order": ["creationDate DESC", "id DESC"]
}
}

View File

@ -0,0 +1,18 @@
{
"name": "UserPhoneType",
"base": "VnModel",
"options": {
"mysql": {
"table": "userPhoneType"
}
},
"properties": {
"code": {
"id": true,
"type": "String"
},
"description": {
"type": "String"
}
}
}

View File

@ -0,0 +1,34 @@
{
"name": "UserPhone",
"base": "Loggable",
"log": {
"model":"UserLog"
},
"options": {
"mysql": {
"table": "userPhone"
}
},
"properties": {
"id": {
"id": true,
"type": "String"
},
"phone": {
"type": "Number",
"required": true
}
},
"relations": {
"user": {
"type": "belongsTo",
"model": "Account",
"foreignKey": "userFk"
},
"type": {
"type": "belongsTo",
"model": "UserPhoneType",
"foreignKey": "typeFk"
}
}
}

View File

@ -235,9 +235,7 @@ class Controller {
if (response === 'ACCEPT') {
let data = {workerFk: this.worker.id, timed: this.newTime};
let query = `/api/WorkerTimeControls/addTime`;
this.$http.post(query, data).then(() => {
this.refresh();
});
this.$http.post(query, data).then(() => this.refresh());
}
}
}

View File

@ -105,7 +105,6 @@
</td>
</tr>
</template>
<!-- FIXME - APPLY CSS POST-RENDER -->
<tr >
<td colspan="7"></td>
</tr>

View File

@ -59,8 +59,8 @@ module.exports = {
percent(input) {
return new Intl.NumberFormat('es', {
style: 'percent',
minimumFractionDigits: 0,
maximumFractionDigits: 0
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(parseFloat(input));
},
date(input) {

View File

@ -55,7 +55,7 @@ let baseConfig = {
}, {
loader: 'sass-loader',
options: {
// FIXME: Don't work in Firefox
// XXX: Don't work in Firefox
// https://github.com/webpack-contrib/style-loader/issues/303
// sourceMap: true,
includePaths: [