Fixes #5181 Ticket.summary-recargo #1297

Merged
joan merged 6 commits from 5181-ticket.summary-recargo into dev 2023-02-13 07:02:34 +00:00
243 changed files with 1104 additions and 822 deletions
Showing only changes of commit 86e6672e49 - Show all commits

View File

@ -11,10 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- -
### Changed ### Changed
- - (General -> Inicio) Ahora permite recuperar la contraseña tanto con el correo de recuperación como el usuario
### Fixed ### Fixed
- - (Monitor de tickets) Cuando ordenas por columna, ya no se queda deshabilitado el botón de 'Actualizar'
- (Zone -> Días de entrega) Al hacer click en un día, muestra correctamente las zonas
## [2304.01] - 2023-02-09 ## [2304.01] - 2023-02-09

View File

@ -3,9 +3,9 @@ module.exports = Self => {
description: 'Send email to the user', description: 'Send email to the user',
accepts: [ accepts: [
{ {
arg: 'email', arg: 'user',
type: 'string', type: 'string',
description: 'The email of user', description: 'The user name or email',
required: true required: true
} }
], ],
@ -15,11 +15,20 @@ module.exports = Self => {
} }
}); });
Self.recoverPassword = async function(email) { Self.recoverPassword = async function(user) {
const models = Self.app.models; const models = Self.app.models;
const usesEmail = user.indexOf('@') !== -1;
if (!usesEmail) {
const account = await models.Account.findOne({
fields: ['email'],
where: {name: user}
});
user = account.email;
}
try { try {
await models.user.resetPassword({email, emailTemplate: 'recover-password'}); await models.user.resetPassword({email: user, emailTemplate: 'recover-password'});
} catch (err) { } catch (err) {
if (err.code === 'EMAIL_NOT_FOUND') if (err.code === 'EMAIL_NOT_FOUND')
return; return;

View File

@ -22,7 +22,7 @@ module.exports = Self => {
Self.latest = async filter => { Self.latest = async filter => {
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const minDate = new Date(); const minDate = Date.vnNew();
minDate.setFullYear(minDate.getFullYear() - 1); minDate.setFullYear(minDate.getFullYear() - 1);
const where = {dated: {gte: minDate}}; const where = {dated: {gte: minDate}};

View File

@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server');
describe('campaign latest()', () => { describe('campaign latest()', () => {
it('should return the campaigns from the last year', async() => { it('should return the campaigns from the last year', async() => {
const now = new Date(); const now = Date.vnNew();
const result = await app.models.Campaign.latest(); const result = await app.models.Campaign.latest();
const randomIndex = Math.floor(Math.random() * result.length); const randomIndex = Math.floor(Math.random() * result.length);
const campaignDated = result[randomIndex].dated; const campaignDated = result[randomIndex].dated;
@ -12,7 +12,7 @@ describe('campaign latest()', () => {
}); });
it('should return the campaigns from the current year', async() => { it('should return the campaigns from the current year', async() => {
const now = new Date(); const now = Date.vnNew();
const currentYear = now.getFullYear(); const currentYear = now.getFullYear();
const result = await app.models.Campaign.latest({ const result = await app.models.Campaign.latest({
where: {dated: {like: `%${currentYear}%`}} where: {dated: {like: `%${currentYear}%`}}

View File

@ -4,7 +4,7 @@ describe('campaign upcoming()', () => {
it('should return the upcoming campaign but from the last year', async() => { it('should return the upcoming campaign but from the last year', async() => {
const response = await app.models.Campaign.upcoming(); const response = await app.models.Campaign.upcoming();
const campaignDated = response.dated; const campaignDated = response.dated;
const now = new Date(); const now = Date.vnNew();
expect(campaignDated).toEqual(jasmine.any(Date)); expect(campaignDated).toEqual(jasmine.any(Date));
expect(campaignDated).toBeLessThanOrEqual(now); expect(campaignDated).toBeLessThanOrEqual(now);

View File

@ -14,7 +14,7 @@ module.exports = Self => {
}); });
Self.upcoming = async() => { Self.upcoming = async() => {
const minDate = new Date(); const minDate = Date.vnNew();
minDate.setFullYear(minDate.getFullYear() - 1); minDate.setFullYear(minDate.getFullYear() - 1);
return Self.findOne({ return Self.findOne({

View File

@ -21,7 +21,7 @@ module.exports = Self => {
if (!this.login) return; if (!this.login) return;
if (Date.now() > this.login.expires) if (Date.vnNow() > this.login.expires)
this.login = await requestToken(); this.login = await requestToken();
return this.login; return this.login;
@ -48,7 +48,7 @@ module.exports = Self => {
userId: requestData.userId, userId: requestData.userId,
token: requestData.authToken token: requestData.authToken
}, },
expires: Date.now() + (1000 * 60 * tokenLifespan) expires: Date.vnNow() + (1000 * 60 * tokenLifespan)
}; };
} }
} }

View File

@ -33,7 +33,7 @@ module.exports = Self => {
await models.Chat.create({ await models.Chat.create({
senderFk: sender.id, senderFk: sender.id,
recipient: to, recipient: to,
dated: new Date(), dated: Date.vnNew(),
checkUserStatus: 0, checkUserStatus: 0,
message: message, message: message,
status: 0, status: 0,

View File

@ -49,7 +49,7 @@ module.exports = Self => {
await models.Chat.create({ await models.Chat.create({
senderFk: sender.id, senderFk: sender.id,
recipient: `@${recipient.name}`, recipient: `@${recipient.name}`,
dated: new Date(), dated: Date.vnNew(),
checkUserStatus: 1, checkUserStatus: 1,
message: message, message: message,
status: 0, status: 0,

View File

@ -1,7 +1,7 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('Chat sendCheckingPresence()', () => { describe('Chat sendCheckingPresence()', () => {
const today = new Date(); const today = Date.vnNew();
today.setHours(6, 0); today.setHours(6, 0);
const chatModel = models.Chat; const chatModel = models.Chat;

View File

@ -24,7 +24,7 @@ module.exports = Self => {
} }
}); });
Self.setSaleQuantity = async(saleId, quantity) => { Self.setSaleQuantity = async(saleId, quantity, options) => {
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};
let tx; let tx;

View File

@ -32,7 +32,7 @@ module.exports = Self => {
where: {code: 'trash'} where: {code: 'trash'}
}, myOptions); }, myOptions);
const date = new Date(); const date = Date.vnNew();
date.setMonth(date.getMonth() - 4); date.setMonth(date.getMonth() - 4);
const dmsToDelete = await models.Dms.find({ const dmsToDelete = await models.Dms.find({

View File

@ -163,7 +163,7 @@ module.exports = Self => {
fields: ['alertLevel'] fields: ['alertLevel']
}); });
signedTime ? signedTime != undefined : signedTime = new Date(); signedTime ? signedTime != undefined : signedTime = Date.vnNew();
if (alertLevel >= 2) { if (alertLevel >= 2) {
let dir; let dir;

View File

@ -127,7 +127,7 @@ module.exports = Self => {
const uploadOptions = { const uploadOptions = {
headers: { headers: {
'Content-Type': 'multipart/form-data', 'Content-Type': 'multipart/form-data',
'X-File-ModifiedDate': new Date(), 'X-File-ModifiedDate': Date.vnNew(),
'Cookie': options.headers.headers.Cookie, 'Cookie': options.headers.headers.Cookie,
...data.getHeaders() ...data.getHeaders()
}, },

View File

@ -230,7 +230,7 @@ module.exports = Self => {
UPDATE edi.tableConfig UPDATE edi.tableConfig
SET updated = ? SET updated = ?
WHERE fileName = ? WHERE fileName = ?
`, [new Date(), baseName], options); `, [Date.vnNew(), baseName], options);
} }
console.log(`Updated table ${toTable}\n`); console.log(`Updated table ${toTable}\n`);

View File

@ -32,7 +32,7 @@ module.exports = Self => {
if (!config.cleanDays) return; if (!config.cleanDays) return;
const cleanDate = new Date(); const cleanDate = Date.vnNew();
cleanDate.setDate(cleanDate.getDate() - config.cleanDays); cleanDate.setDate(cleanDate.getDate() - config.cleanDays);
await models.NotificationQueue.destroyAll({ await models.NotificationQueue.destroyAll({

View File

@ -10,7 +10,7 @@ describe('Notification Clean()', () => {
const notification = await models.Notification.findOne({}, options); const notification = await models.Notification.findOne({}, options);
const notificationConfig = await models.NotificationConfig.findOne({}); const notificationConfig = await models.NotificationConfig.findOne({});
const cleanDate = new Date(); const cleanDate = Date.vnNew();
cleanDate.setDate(cleanDate.getDate() - (notificationConfig.cleanDays + 1)); cleanDate.setDate(cleanDate.getDate() - (notificationConfig.cleanDays + 1));
let before; let before;

View File

@ -77,7 +77,7 @@ module.exports = Self => {
const newImage = await Self.upsertWithWhere(data, { const newImage = await Self.upsertWithWhere(data, {
name: fileName, name: fileName,
collectionFk: collectionName, collectionFk: collectionName,
updated: (new Date).getTime() updated: Date.vnNow()
}, myOptions); }, myOptions);
// Resizes and saves the image // Resizes and saves the image

View File

@ -2,7 +2,33 @@ CREATE SCHEMA IF NOT EXISTS `vn2008`;
CREATE SCHEMA IF NOT EXISTS `tmp`; CREATE SCHEMA IF NOT EXISTS `tmp`;
UPDATE `util`.`config` UPDATE `util`.`config`
SET `environment`= 'test'; SET `environment`= 'development';
-- FOR MOCK vn.time
DROP PROCEDURE IF EXISTS `vn`.`mockVnTime`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`mockVnTime`()
BEGIN
DECLARE vDate DATE;
SET vDate = '2000-01-01';
WHILE ( YEAR(vDate) <= 2002 ) DO
INSERT IGNORE INTO vn.`time` (dated, period, `month`, `year`, `day`, week, yearMonth, salesYear)
VALUES (vDate, CONCAT(YEAR(vDate), (WEEK(vDate)+1)), MONTH(vDate), YEAR(vDate), DAY(vDate), WEEK(vDate)+1, CONCAT(YEAR(vDate), MONTH(vDate)), YEAR(vDate));
SET vDate = DATE_ADD(vDate, INTERVAL 1 DAY);
END WHILE;
END$$
DELIMITER ;
CALL `vn`.`mockVnTime`();
DROP PROCEDURE IF EXISTS `vn`.`mockVnTime`;
-- END MOCK vn.time
ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`itemTaxCountry` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`address` AUTO_INCREMENT = 1; ALTER TABLE `vn`.`address` AUTO_INCREMENT = 1;
@ -934,10 +960,10 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `freightItemFk`,
(7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL), (7, 2, 4, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -3 MONTH), 1, 18, NULL, 94, NULL,NULL),
(8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL), (8, 3, 5, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -4 MONTH), 1, 18, NULL, 94, 1, NULL),
(9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL), (9, 3, 6, 71, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1, 18, NULL, 94, 2, NULL),
(10, 7, 7, 71, NOW(), 1, 18, NULL, 94, 3, NULL), (10, 7, 7, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
(11, 7, 8, 71, NOW(), 1, 18, NULL, 94, 3, NULL), (11, 7, 8, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
(12, 7, 9, 71, NOW(), 1, 18, NULL, 94, 3, NULL), (12, 7, 9, 71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL),
(13, 1, 10,71, NOW(), 1, 18, NULL, 94, 3, NULL); (13, 1, 10,71, util.VN_NOW(), 1, 18, NULL, 94, 3, NULL);
INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`) INSERT INTO `vn`.`expeditionState`(`id`, `created`, `expeditionFk`, `typeFk`, `userFk`)
@ -1910,7 +1936,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker;
CREATE TEMPORARY TABLE tmp.worker CREATE TEMPORARY TABLE tmp.worker
(PRIMARY KEY (id)) (PRIMARY KEY (id))
ENGINE = MEMORY ENGINE = MEMORY
SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL +1 YEAR)), '-12-25'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` SELECT w.id, w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-12-25') as started, CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-12-25') as ended, CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk`
FROM `vn`.`worker` `w`; FROM `vn`.`worker` `w`;
INSERT INTO `vn`.`business`(`id`, `workerFk`, `companyCodeFk`, `started`, `ended`, `workerBusiness`, `reasonEndFk`, `notes`, `departmentFk`, `workerBusinessProfessionalCategoryFk`, `calendarTypeFk`, `isHourlyLabor`, `workerBusinessAgreementFk`, `workcenterFk`) INSERT INTO `vn`.`business`(`id`, `workerFk`, `companyCodeFk`, `started`, `ended`, `workerBusiness`, `reasonEndFk`, `notes`, `departmentFk`, `workerBusinessProfessionalCategoryFk`, `calendarTypeFk`, `isHourlyLabor`, `workerBusinessAgreementFk`, `workcenterFk`)
@ -1920,7 +1946,7 @@ DROP TEMPORARY TABLE IF EXISTS tmp.worker;
CREATE TEMPORARY TABLE tmp.worker CREATE TEMPORARY TABLE tmp.worker
(PRIMARY KEY (id)) (PRIMARY KEY (id))
ENGINE = MEMORY ENGINE = MEMORY
SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -2 YEAR)), '-12-25'), CONCAT(YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)), '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk` SELECT '1111' as 'id', w.id as `workerFk`, 'VNL', CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -2 YEAR)), '-12-25') as started, CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)) as ended, '-12-24'), CONCAT('E-46-', RPAD(CONCAT(w.id, 9), 8, w.id)), NULL as `notes`, NULL as `departmentFk`, 23, 1 as `workerBusinessProfessionalCategoryFk`, 1 as `calendarTypeFk`, 1 as `isHourlyLabor`, 1 as `workerBusinessAgreementFk`, 1 as `workcenterFk`
FROM `vn`.`worker` `w` FROM `vn`.`worker` `w`
WHERE `w`.`id` = 1109; WHERE `w`.`id` = 1109;

View File

@ -3,18 +3,17 @@ USE `util`;
DELIMITER ;; DELIMITER ;;
DROP FUNCTION IF EXISTS `util`.`mockedDate`; DROP FUNCTION IF EXISTS `util`.`mockedDate`;
CREATE FUNCTION `util`.`mockedDate`() CREATE FUNCTION `util`.`mockedDate`()
RETURNS DATETIME RETURNS DATETIME
DETERMINISTIC DETERMINISTIC
BEGIN BEGIN
RETURN NOW(); RETURN CONVERT_TZ('2001-01-01 11:00:00', 'utc', 'Europe/Madrid');
-- '2022-01-19 08:00:00'
END ;; END ;;
DELIMITER ; DELIMITER ;
DELIMITER ;; DELIMITER ;;
DROP FUNCTION IF EXISTS `util`.`VN_CURDATE`; DROP FUNCTION IF EXISTS `util`.`VN_CURDATE`;
CREATE FUNCTION `util`.`VN_CURDATE`() CREATE FUNCTION `util`.`VN_CURDATE`()
RETURNS DATE RETURNS DATE
DETERMINISTIC DETERMINISTIC
BEGIN BEGIN
@ -24,7 +23,7 @@ DELIMITER ;
DELIMITER ;; DELIMITER ;;
DROP FUNCTION IF EXISTS `util`.`VN_CURTIME`; DROP FUNCTION IF EXISTS `util`.`VN_CURTIME`;
CREATE FUNCTION `util`.`VN_CURTIME`() CREATE FUNCTION `util`.`VN_CURTIME`()
RETURNS TIME RETURNS TIME
DETERMINISTIC DETERMINISTIC
BEGIN BEGIN
@ -34,10 +33,10 @@ DELIMITER ;
DELIMITER ;; DELIMITER ;;
DROP FUNCTION IF EXISTS `util`.`VN_NOW`; DROP FUNCTION IF EXISTS `util`.`VN_NOW`;
CREATE FUNCTION `util`.`VN_NOW`() CREATE FUNCTION `util`.`VN_NOW`()
RETURNS DATETIME RETURNS DATETIME
DETERMINISTIC DETERMINISTIC
BEGIN BEGIN
RETURN mockedDate(); RETURN mockedDate();
END ;; END ;;
DELIMITER ; DELIMITER ;

View File

@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('buyUltimate()', () => { describe('buyUltimate()', () => {
const today = new Date(); const today = Date.vnNew();
it(`should create buyUltimate temporal table and update it's values`, async() => { it(`should create buyUltimate temporal table and update it's values`, async() => {
let stmts = []; let stmts = [];
let stmt; let stmt;

View File

@ -5,7 +5,7 @@ describe('buyUltimateFromInterval()', () => {
let today; let today;
let future; let future;
beforeAll(() => { beforeAll(() => {
let now = new Date(); let now = Date.vnNew();
now.setHours(0, 0, 0, 0); now.setHours(0, 0, 0, 0);
today = now; today = now;

View File

@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticket ticketCalculateClon()', () => { describe('ticket ticketCalculateClon()', () => {
const today = new Date(); const today = Date.vnNew();
it('should add the ticket to the order containing the original ticket', async() => { it('should add the ticket to the order containing the original ticket', async() => {
let stmts = []; let stmts = [];
let stmt; let stmt;

View File

@ -2,7 +2,7 @@ const app = require('vn-loopback/server/server');
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('ticket ticketCreateWithUser()', () => { describe('ticket ticketCreateWithUser()', () => {
const today = new Date(); const today = Date.vnNew();
it('should confirm the procedure creates the expected ticket', async() => { it('should confirm the procedure creates the expected ticket', async() => {
let stmts = []; let stmts = [];
let stmt; let stmt;

View File

@ -3,9 +3,9 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('timeBusiness_calculateByUser()', () => { describe('timeBusiness_calculateByUser()', () => {
it('should return the expected hours for today', async() => { it('should return the expected hours for today', async() => {
let start = new Date(); let start = Date.vnNew();
start.setHours(0, 0, 0, 0); start.setHours(0, 0, 0, 0);
let end = new Date(); let end = Date.vnNew();
end.setHours(0, 0, 0, 0); end.setHours(0, 0, 0, 0);
let stmts = []; let stmts = [];

View File

@ -3,11 +3,11 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
describe('timeControl_calculateByUser()', () => { describe('timeControl_calculateByUser()', () => {
it(`should return today's worked hours`, async() => { it(`should return today's worked hours`, async() => {
let start = new Date(); let start = Date.vnNew();
start.setHours(0, 0, 0, 0); start.setHours(0, 0, 0, 0);
start.setDate(start.getDate() - 1); start.setDate(start.getDate() - 1);
let end = new Date(); let end = Date.vnNew();
end.setHours(0, 0, 0, 0); end.setHours(0, 0, 0, 0);
end.setDate(end.getDate() + 1); end.setDate(end.getDate() + 1);
@ -17,7 +17,7 @@ describe('timeControl_calculateByUser()', () => {
stmts.push('START TRANSACTION'); stmts.push('START TRANSACTION');
stmts.push(` stmts.push(`
DROP TEMPORARY TABLE IF EXISTS DROP TEMPORARY TABLE IF EXISTS
tmp.timeControlCalculate, tmp.timeControlCalculate,
tmp.timeBusinessCalculate tmp.timeBusinessCalculate
`); `);
@ -48,14 +48,14 @@ describe('timeControl_calculateByUser()', () => {
}); });
it(`should return the worked hours between last sunday and monday`, async() => { it(`should return the worked hours between last sunday and monday`, async() => {
let lastSunday = new Date(); let lastSunday = Date.vnNew();
let daysSinceSunday = lastSunday.getDay(); let daysSinceSunday = lastSunday.getDay();
if (daysSinceSunday === 0) // this means today is sunday but you need the previous sunday :) if (daysSinceSunday === 0) // this means today is sunday but you need the previous sunday :)
daysSinceSunday = 7; daysSinceSunday = 7;
lastSunday.setHours(23, 0, 0, 0); lastSunday.setHours(23, 0, 0, 0);
lastSunday.setDate(lastSunday.getDate() - daysSinceSunday); lastSunday.setDate(lastSunday.getDate() - daysSinceSunday);
let monday = new Date(); let monday = Date.vnNew();
let daysSinceMonday = daysSinceSunday - 1; // aiming for monday (today could be monday) let daysSinceMonday = daysSinceSunday - 1; // aiming for monday (today could be monday)
monday.setHours(7, 0, 0, 0); monday.setHours(7, 0, 0, 0);
monday.setDate(monday.getDate() - daysSinceMonday); monday.setDate(monday.getDate() - daysSinceMonday);
@ -66,7 +66,7 @@ describe('timeControl_calculateByUser()', () => {
stmts.push('START TRANSACTION'); stmts.push('START TRANSACTION');
stmts.push(` stmts.push(`
DROP TEMPORARY TABLE IF EXISTS DROP TEMPORARY TABLE IF EXISTS
tmp.timeControlCalculate, tmp.timeControlCalculate,
tmp.timeBusinessCalculate tmp.timeBusinessCalculate
`); `);

View File

@ -6,7 +6,7 @@ describe('zone zone_getLanded()', () => {
let stmts = []; let stmts = [];
let stmt; let stmt;
stmts.push('START TRANSACTION'); stmts.push('START TRANSACTION');
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
let params = { let params = {
@ -40,7 +40,7 @@ describe('zone zone_getLanded()', () => {
it(`should return data for a shipped tomorrow`, async() => { it(`should return data for a shipped tomorrow`, async() => {
let stmts = []; let stmts = [];
let stmt; let stmt;
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
stmts.push('START TRANSACTION'); stmts.push('START TRANSACTION');

View File

@ -436,7 +436,7 @@ let actions = {
}, },
pickDate: async function(selector, date) { pickDate: async function(selector, date) {
date = date || new Date(); date = date || Date.vnNew();
const timeZoneOffset = date.getTimezoneOffset() * 60000; const timeZoneOffset = date.getTimezoneOffset() * 60000;
const localDate = (new Date(date.getTime() - timeZoneOffset)) const localDate = (new Date(date.getTime() - timeZoneOffset))

View File

@ -31,7 +31,7 @@ export default {
}, },
recoverPassword: { recoverPassword: {
recoverPasswordButton: 'vn-login a[ui-sref="recover-password"]', recoverPasswordButton: 'vn-login a[ui-sref="recover-password"]',
email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]', email: 'vn-recover-password vn-textfield[ng-model="$ctrl.user"]',
sendEmailButton: 'vn-recover-password vn-submit', sendEmailButton: 'vn-recover-password vn-submit',
}, },
accountIndex: { accountIndex: {
@ -1260,6 +1260,21 @@ export default {
importBuysButton: 'vn-entry-buy-import button[type="submit"]' importBuysButton: 'vn-entry-buy-import button[type="submit"]'
}, },
entryLatestBuys: { entryLatestBuys: {
table: 'tbody > tr:not(.empty-rows)',
chip: 'vn-chip > vn-icon',
generalSearchInput: 'vn-textfield[ng-model="$ctrl.filter.search"]',
firstReignIcon: 'vn-horizontal.item-category vn-one',
typeInput: 'vn-autocomplete[ng-model="$ctrl.filter.typeFk"]',
salesPersonInput: 'vn-autocomplete[ng-model="$ctrl.filter.salesPersonFk"]',
supplierInput: 'vn-autocomplete[ng-model="$ctrl.filter.supplierFk"]',
fromInput: 'vn-date-picker[ng-model="$ctrl.filter.from"]',
toInput: 'vn-date-picker[ng-model="$ctrl.filter.to"]',
activeCheck: 'vn-check[ng-model="$ctrl.filter.active"]',
floramondoCheck: 'vn-check[ng-model="$ctrl.filter.floramondo"]',
visibleCheck: 'vn-check[ng-model="$ctrl.filter.visible"]',
addTagButton: 'vn-icon-button[vn-tooltip="Add tag"]',
itemTagInput: 'vn-autocomplete[ng-model="itemTag.tagFk"]',
itemTagValueInput: 'vn-autocomplete[ng-model="itemTag.value"]',
firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)', firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)',
allBuysCheckBox: 'vn-entry-latest-buys thead vn-check', allBuysCheckBox: 'vn-entry-latest-buys thead vn-check',
secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]', secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]',

View File

@ -1,6 +1,7 @@
require('@babel/register')({presets: ['@babel/env']}); require('@babel/register')({presets: ['@babel/env']});
require('core-js/stable'); require('core-js/stable');
require('regenerator-runtime/runtime'); require('regenerator-runtime/runtime');
require('vn-loopback/server/boot/date')();
const axios = require('axios'); const axios = require('axios');
const Docker = require('../../db/docker.js'); const Docker = require('../../db/docker.js');

View File

@ -26,7 +26,7 @@ describe('RecoverPassword path', async() => {
expect(message.text).toContain('Notification sent!'); expect(message.text).toContain('Notification sent!');
}); });
it('should send email', async() => { it('should send email using email', async() => {
await page.waitForState('login'); await page.waitForState('login');
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton); await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
@ -37,4 +37,16 @@ describe('RecoverPassword path', async() => {
expect(message.text).toContain('Notification sent!'); expect(message.text).toContain('Notification sent!');
}); });
it('should send email using username', async() => {
await page.waitForState('login');
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
await page.write(selectors.recoverPassword.email, 'BruceWayne');
await page.waitToClick(selectors.recoverPassword.sendEmailButton);
const message = await page.waitForSnackbar();
await page.waitForState('login');
expect(message.text).toContain('Notification sent!');
});
}); });

View File

@ -4,7 +4,7 @@ import getBrowser from '../../helpers/puppeteer';
describe('Client credit insurance path', () => { describe('Client credit insurance path', () => {
let browser; let browser;
let page; let page;
let previousMonth = new Date(); let previousMonth = Date.vnNew();
previousMonth.setMonth(previousMonth.getMonth() - 1); previousMonth.setMonth(previousMonth.getMonth() - 1);
beforeAll(async() => { beforeAll(async() => {

View File

@ -22,7 +22,7 @@ describe('Worker time control path', () => {
const hankPymId = 1107; const hankPymId = 1107;
it('should go to the next month, go to current month and go 1 month in the past', async() => { it('should go to the next month, go to current month and go 1 month in the past', async() => {
let date = new Date(); let date = Date.vnNew();
date.setDate(1); date.setDate(1);
date.setMonth(date.getMonth() + 1); date.setMonth(date.getMonth() + 1);
let month = date.toLocaleString('default', {month: 'long'}); let month = date.toLocaleString('default', {month: 'long'});
@ -32,7 +32,7 @@ describe('Worker time control path', () => {
expect(result).toContain(month); expect(result).toContain(month);
date = new Date(); date = Date.vnNew();
date.setDate(1); date.setDate(1);
month = date.toLocaleString('default', {month: 'long'}); month = date.toLocaleString('default', {month: 'long'});
@ -41,7 +41,7 @@ describe('Worker time control path', () => {
expect(result).toContain(month); expect(result).toContain(month);
date = new Date(); date = Date.vnNew();
date.setDate(1); date.setDate(1);
date.setMonth(date.getMonth() - 1); date.setMonth(date.getMonth() - 1);
const timestamp = Math.round(date.getTime() / 1000); const timestamp = Math.round(date.getTime() / 1000);

View File

@ -4,7 +4,7 @@ import getBrowser from '../../helpers/puppeteer';
describe('Worker calendar path', () => { describe('Worker calendar path', () => {
const reasonableTimeBetweenClicks = 300; const reasonableTimeBetweenClicks = 300;
const date = new Date(); const date = Date.vnNew();
const lastYear = (date.getFullYear() - 1).toString(); const lastYear = (date.getFullYear() - 1).toString();
let browser; let browser;

View File

@ -22,7 +22,7 @@ describe('Item fixed prices path', () => {
}); });
it('should fill the fixed price data', async() => { it('should fill the fixed price data', async() => {
const now = new Date(); const now = Date.vnNew();
await page.autocompleteSearch(selectors.itemFixedPrice.fourthWarehouse, 'Warehouse one'); await page.autocompleteSearch(selectors.itemFixedPrice.fourthWarehouse, 'Warehouse one');
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthGroupingPrice, '1'); await page.writeOnEditableTD(selectors.itemFixedPrice.fourthGroupingPrice, '1');
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthPackingPrice, '1'); await page.writeOnEditableTD(selectors.itemFixedPrice.fourthPackingPrice, '1');

View File

@ -93,7 +93,7 @@ describe('Ticket Edit basic data path', () => {
it(`should split ticket without negatives`, async() => { it(`should split ticket without negatives`, async() => {
const newAgency = 'Gotham247'; const newAgency = 'Gotham247';
const newDate = new Date(); const newDate = Date.vnNew();
newDate.setDate(newDate.getDate() - 1); newDate.setDate(newDate.getDate() - 1);
await page.accessToSearchResult('14'); await page.accessToSearchResult('14');
@ -127,7 +127,7 @@ describe('Ticket Edit basic data path', () => {
}); });
it(`should old ticket have old date and agency`, async() => { it(`should old ticket have old date and agency`, async() => {
const oldDate = new Date(); const oldDate = Date.vnNew();
const oldAgency = 'Super-Man delivery'; const oldAgency = 'Super-Man delivery';
await page.accessToSearchResult('14'); await page.accessToSearchResult('14');

View File

@ -4,7 +4,7 @@ import getBrowser from '../../helpers/puppeteer';
describe('Ticket create path', () => { describe('Ticket create path', () => {
let browser; let browser;
let page; let page;
let nextMonth = new Date(); let nextMonth = Date.vnNew();
nextMonth.setMonth(nextMonth.getMonth() + 1); nextMonth.setMonth(nextMonth.getMonth() + 1);
beforeAll(async() => { beforeAll(async() => {

View File

@ -63,6 +63,6 @@ describe('Ticket index payout path', () => {
const reference = await page.waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText'); const reference = await page.waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText');
expect(count).toEqual(4); expect(count).toEqual(4);
expect(reference).toContain('Cash, Albaran: 7, 8Payment'); expect(reference).toContain('Cash,Albaran: 7, 8Payment');
}); });
}); });

View File

@ -18,7 +18,7 @@ describe('Route basic Data path', () => {
}); });
it('should edit the route basic data', async() => { it('should edit the route basic data', async() => {
const nextMonth = new Date(); const nextMonth = Date.vnNew();
nextMonth.setMonth(nextMonth.getMonth() + 1); nextMonth.setMonth(nextMonth.getMonth() + 1);
await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick'); await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick');

View File

@ -19,7 +19,7 @@ describe('InvoiceIn basic data path', () => {
}); });
it(`should edit the invoiceIn basic data`, async() => { it(`should edit the invoiceIn basic data`, async() => {
const now = new Date(); const now = Date.vnNew();
await page.pickDate(selectors.invoiceInBasicData.issued, now); await page.pickDate(selectors.invoiceInBasicData.issued, now);
await page.pickDate(selectors.invoiceInBasicData.operated, now); await page.pickDate(selectors.invoiceInBasicData.operated, now);
await page.autocompleteSearch(selectors.invoiceInBasicData.supplier, 'Verdnatura'); await page.autocompleteSearch(selectors.invoiceInBasicData.supplier, 'Verdnatura');

View File

@ -100,7 +100,7 @@ describe('InvoiceOut descriptor path', () => {
}); });
it(`should check the invoiceOut booked in the summary data`, async() => { it(`should check the invoiceOut booked in the summary data`, async() => {
let today = new Date(); let today = Date.vnNew();
let day = today.getDate(); let day = today.getDate();
if (day < 10) day = `0${day}`; if (day < 10) day = `0${day}`;

View File

@ -4,7 +4,7 @@ import getBrowser from '../../helpers/puppeteer';
describe('Travel create path', () => { describe('Travel create path', () => {
let browser; let browser;
let page; let page;
const date = new Date(); const date = Date.vnNew();
const day = 15; const day = 15;
date.setDate(day); date.setDate(day);

View File

@ -22,7 +22,7 @@ describe('Travel basic data path', () => {
}); });
it('should set a wrong delivery date then receive an error on submit', async() => { it('should set a wrong delivery date then receive an error on submit', async() => {
const lastMonth = new Date(); const lastMonth = Date.vnNew();
lastMonth.setMonth(lastMonth.getMonth() - 1); lastMonth.setMonth(lastMonth.getMonth() - 1);
await page.pickDate(selectors.travelBasicData.deliveryDate, lastMonth); await page.pickDate(selectors.travelBasicData.deliveryDate, lastMonth);

View File

@ -123,7 +123,7 @@ describe('Travel descriptor path', () => {
}); });
it('should update the landed date to a future date to enable cloneWithEntries', async() => { it('should update the landed date to a future date to enable cloneWithEntries', async() => {
const nextMonth = new Date(); const nextMonth = Date.vnNew();
nextMonth.setMonth(nextMonth.getMonth() + 1); nextMonth.setMonth(nextMonth.getMonth() + 1);
await page.pickDate(selectors.travelBasicData.deliveryDate, nextMonth); await page.pickDate(selectors.travelBasicData.deliveryDate, nextMonth);
await page.waitToClick(selectors.travelBasicData.save); await page.waitToClick(selectors.travelBasicData.save);

View File

@ -4,10 +4,15 @@ import getBrowser from '../../helpers/puppeteer';
describe('Entry lastest buys path', () => { describe('Entry lastest buys path', () => {
let browser; let browser;
let page; let page;
const httpRequests = [];
beforeAll(async() => { beforeAll(async() => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
page.on('request', req => {
if (req.url().includes(`Buys/latestBuysFilter`))
httpRequests.push(req.url());
});
await page.loginAndModule('buyer', 'entry'); await page.loginAndModule('buyer', 'entry');
}); });
@ -20,6 +25,87 @@ describe('Entry lastest buys path', () => {
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false}); await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
}); });
it('should filter by name', async() => {
await page.write(selectors.entryLatestBuys.generalSearchInput, 'Melee');
await page.keyboard.press('Enter');
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('search=Melee')))).toBeDefined();
});
it('should filter by reign and type', async() => {
await page.click(selectors.entryLatestBuys.firstReignIcon);
await page.autocompleteSearch(selectors.entryLatestBuys.typeInput, 'Alstroemeria');
await page.click(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('categoryFk')))).toBeDefined();
expect(httpRequests.find(req => req.includes(('typeFk')))).toBeDefined();
});
it('should filter by from date', async() => {
await page.pickDate(selectors.entryLatestBuys.fromInput, new Date());
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('from')))).toBeDefined();
});
it('should filter by to date', async() => {
await page.pickDate(selectors.entryLatestBuys.toInput, new Date());
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('to')))).toBeDefined();
});
it('should filter by sales person', async() => {
await page.autocompleteSearch(selectors.entryLatestBuys.salesPersonInput, 'buyerNick');
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('salesPersonFk')))).toBeDefined();
});
it('should filter by supplier', async() => {
await page.autocompleteSearch(selectors.entryLatestBuys.supplierInput, 'Farmer King');
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('supplierFk')))).toBeDefined();
});
it('should filter by active', async() => {
await page.waitToClick(selectors.entryLatestBuys.activeCheck);
await page.waitToClick(selectors.entryLatestBuys.activeCheck);
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('active=true')))).toBeDefined();
expect(httpRequests.find(req => req.includes(('active=false')))).toBeDefined();
});
it('should filter by visible', async() => {
await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('visible=true')))).toBeDefined();
expect(httpRequests.find(req => req.includes(('visible=false')))).toBeDefined();
});
it('should filter by floramondo', async() => {
await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('floramondo=true')))).toBeDefined();
expect(httpRequests.find(req => req.includes(('floramondo=false')))).toBeDefined();
});
it('should filter by tag Color', async() => {
await page.waitToClick(selectors.entryLatestBuys.addTagButton);
await page.autocompleteSearch(selectors.entryLatestBuys.itemTagInput, 'Color');
await page.autocompleteSearch(selectors.entryLatestBuys.itemTagValueInput, 'Brown');
await page.waitToClick(selectors.entryLatestBuys.chip);
expect(httpRequests.find(req => req.includes(('tags')))).toBeDefined();
});
it('should select all lines but one and then check the edit buys button appears', async() => { it('should select all lines but one and then check the edit buys button appears', async() => {
await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox); await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox); await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);

View File

@ -15,7 +15,7 @@ export default class Calendar extends FormInput {
constructor($element, $scope, vnWeekDays, moment) { constructor($element, $scope, vnWeekDays, moment) {
super($element, $scope); super($element, $scope);
this.weekDays = vnWeekDays.locales; this.weekDays = vnWeekDays.locales;
this.defaultDate = new Date(); this.defaultDate = Date.vnNew();
this.displayControls = true; this.displayControls = true;
this.moment = moment; this.moment = moment;
} }
@ -115,8 +115,8 @@ export default class Calendar extends FormInput {
let wday = date.getDay(); let wday = date.getDay();
let month = date.getMonth(); let month = date.getMonth();
const currentDay = new Date().getDate(); const currentDay = Date.vnNew().getDate();
const currentMonth = new Date().getMonth(); const currentMonth = Date.vnNew().getMonth();
let classes = { let classes = {
today: day === currentDay && month === currentMonth, today: day === currentDay && month === currentMonth,

View File

@ -2,7 +2,7 @@ describe('Component vnCalendar', () => {
let controller; let controller;
let $element; let $element;
let date = new Date(); let date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
date.setDate(1); date.setDate(1);
@ -48,7 +48,7 @@ describe('Component vnCalendar', () => {
it(`should return the selected element, then emit a 'selection' event`, () => { it(`should return the selected element, then emit a 'selection' event`, () => {
jest.spyOn(controller, 'emit'); jest.spyOn(controller, 'emit');
const day = new Date(); const day = Date.vnNew();
day.setHours(0, 0, 0, 0); day.setHours(0, 0, 0, 0);
const clickEvent = new Event('click'); const clickEvent = new Event('click');

View File

@ -4,7 +4,7 @@ describe('Component vnDatePicker', () => {
let $ctrl; let $ctrl;
let today; let today;
today = new Date(); today = Date.vnNew();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
beforeEach(ngModule('vnCore')); beforeEach(ngModule('vnCore'));

View File

@ -31,7 +31,7 @@ export default class InputTime extends Field {
date = this.modelDate date = this.modelDate
? new Date(this.modelDate) ? new Date(this.modelDate)
: new Date(); : Date.vnNew();
date.setHours(split[0], split[1], 0, 0); date.setHours(split[0], split[1], 0, 0);
} }

View File

@ -20,7 +20,7 @@ describe('Component vnInputTime', () => {
describe('field() setter', () => { describe('field() setter', () => {
it(`should display the formated the date`, () => { it(`should display the formated the date`, () => {
let date = new Date(); let date = Date.vnNew();
$ctrl.field = date; $ctrl.field = date;
let displayed = $filter('date')(date, 'HH:mm'); let displayed = $filter('date')(date, 'HH:mm');

View File

@ -0,0 +1,2 @@
import * as date from 'vn-loopback/server/boot/date';
date.default();

View File

@ -10,3 +10,4 @@ import './week-days';
import './report'; import './report';
import './email'; import './email';
import './file'; import './file';
import './date';

View File

@ -1,7 +1,7 @@
<h5 class="vn-mb-md vn-mt-lg" translate>Recover password</h5> <h5 class="vn-mb-md vn-mt-lg" translate>Recover password</h5>
<vn-textfield <vn-textfield
label="Email" label="User or recovery email"
ng-model="$ctrl.email" ng-model="$ctrl.user"
vn-focus> vn-focus>
</vn-textfield> </vn-textfield>
<div <div

View File

@ -20,7 +20,7 @@ export default class Controller {
submit() { submit() {
const params = { const params = {
email: this.email user: this.user
}; };
this.$http.post('Accounts/recoverPassword', params) this.$http.post('Accounts/recoverPassword', params)

View File

@ -1,3 +1,4 @@
Recover password: Recuperar contraseña Recover password: Recuperar contraseña
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
Notification sent!: ¡Notificación enviada! Notification sent!: ¡Notificación enviada!
User or recovery email: Usuario o correo de recuperación

View File

@ -197,7 +197,7 @@ export default class UploadPhoto extends Component {
timeout: this.canceler.promise, timeout: this.canceler.promise,
transformRequest: ([file]) => { transformRequest: ([file]) => {
const formData = new FormData(); const formData = new FormData();
const now = new Date(); const now = Date.vnNew();
const timestamp = now.getTime(); const timestamp = now.getTime();
const fileName = `${file.name}_${timestamp}`; const fileName = `${file.name}_${timestamp}`;

View File

@ -1,5 +1,5 @@
import './module'; import './module';
import './routes'; import './routes';
import './components'; import './components';
import './services';
import './styles'; import './styles';
import 'vn-loopback/server/boot/date';

View File

@ -14,6 +14,10 @@ import './modules/ticket/front/module.js';
import './modules/travel/front/module.js'; import './modules/travel/front/module.js';
import './modules/worker/front/module.js'; import './modules/worker/front/module.js';
import './modules/shelving/front/module.js'; import './modules/shelving/front/module.js';
import 'vn-loopback/server/boot/date';
// Set NODE_ENV
process.env.NODE_ENV = 'development';
core.run(vnInterceptor => { core.run(vnInterceptor => {
vnInterceptor.setApiPath(null); vnInterceptor.setApiPath(null);
@ -39,3 +43,4 @@ window.ngModule = function(moduleName, ...args) {
return angular.mock.module(...fns); return angular.mock.module(...fns);
}; };

View File

@ -1,5 +1,6 @@
// For a detailed explanation regarding each configuration property, visit: // For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html // https://jestjs.io/docs/en/configuration.html
/* eslint max-len: ["error", { "code": 150 }]*/
module.exports = { module.exports = {
name: 'front end', name: 'front end',

View File

@ -0,0 +1,17 @@
module.exports = () => {
Date.vnUTC = () => {
const env = process.env.NODE_ENV;
if (!env || env === 'development')
return new Date(Date.UTC(2001, 0, 1, 11));
return new Date(Date.UTC());
};
Date.vnNew = () => {
return new Date(Date.vnUTC());
};
Date.vnNow = () => {
return new Date(Date.vnUTC()).getTime();
};
};

View File

@ -95,7 +95,7 @@ module.exports = Self => {
}, myOptions); }, myOptions);
const claim = await models.Claim.findOne(filter, myOptions); const claim = await models.Claim.findOne(filter, myOptions);
const today = new Date(); const today = Date.vnNew();
const newRefundTicket = await models.Ticket.create({ const newRefundTicket = await models.Ticket.create({
clientFk: claim.ticket().clientFk, clientFk: claim.ticket().clientFk,
@ -172,7 +172,7 @@ module.exports = Self => {
async function saveObservation(observation, options) { async function saveObservation(observation, options) {
const query = `INSERT INTO vn.ticketObservation (ticketFk, observationTypeFk, description) VALUES(?, ?, ?) const query = `INSERT INTO vn.ticketObservation (ticketFk, observationTypeFk, description) VALUES(?, ?, ?)
ON DUPLICATE KEY ON DUPLICATE KEY
UPDATE description = CONCAT(vn.ticketObservation.description, VALUES(description),' ')`; UPDATE description = CONCAT(vn.ticketObservation.description, VALUES(description),' ')`;
await Self.rawSql(query, [ await Self.rawSql(query, [
observation.ticketFk, observation.ticketFk,

View File

@ -60,7 +60,7 @@ module.exports = Self => {
const landedPlusWeek = new Date(ticket.landed); const landedPlusWeek = new Date(ticket.landed);
landedPlusWeek.setDate(landedPlusWeek.getDate() + 7); landedPlusWeek.setDate(landedPlusWeek.getDate() + 7);
const hasClaimManagerRole = await models.Account.hasRole(userId, 'claimManager', myOptions); const hasClaimManagerRole = await models.Account.hasRole(userId, 'claimManager', myOptions);
const isClaimable = landedPlusWeek >= new Date(); const isClaimable = landedPlusWeek >= Date.vnNew();
if (ticket.isDeleted) if (ticket.isDeleted)
throw new UserError(`You can't create a claim for a removed ticket`); throw new UserError(`You can't create a claim for a removed ticket`);

View File

@ -1,6 +1,6 @@
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('regularizeClaim', { Self.remoteMethodCtx('regularizeClaim', {
description: `Imports lines from claimBeginning to a new ticket description: `Imports lines from claimBeginning to a new ticket
with specific shipped, landed dates, agency and company`, with specific shipped, landed dates, agency and company`,
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [{
@ -135,10 +135,10 @@ module.exports = Self => {
} }
async function getTicketId(params, options) { async function getTicketId(params, options) {
const minDate = new Date(); const minDate = Date.vnNew();
minDate.setHours(0, 0, 0, 0); minDate.setHours(0, 0, 0, 0);
const maxDate = new Date(); const maxDate = Date.vnNew();
maxDate.setHours(23, 59, 59, 59); maxDate.setHours(23, 59, 59, 59);
let ticket = await Self.app.models.Ticket.findOne({ let ticket = await Self.app.models.Ticket.findOne({
@ -155,8 +155,8 @@ module.exports = Self => {
} }
async function createTicket(ctx, options) { async function createTicket(ctx, options) {
ctx.args.shipped = new Date(); ctx.args.shipped = Date.vnNew();
ctx.args.landed = new Date(); ctx.args.landed = Date.vnNew();
ctx.args.agencyModeId = null; ctx.args.agencyModeId = null;
ctx.args.routeId = null; ctx.args.routeId = null;

View File

@ -54,7 +54,7 @@ describe('Claim createFromSales()', () => {
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
const todayMinusEightDays = new Date(); const todayMinusEightDays = Date.vnNew();
todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8); todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8);
const ticket = await models.Ticket.findById(ticketId, null, options); const ticket = await models.Ticket.findById(ticketId, null, options);
@ -85,7 +85,7 @@ describe('Claim createFromSales()', () => {
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
const todayMinusEightDays = new Date(); const todayMinusEightDays = Date.vnNew();
todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8); todayMinusEightDays.setDate(todayMinusEightDays.getDate() - 8);
const ticket = await models.Ticket.findById(ticketId, null, options); const ticket = await models.Ticket.findById(ticketId, null, options);

View File

@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
describe('Update Claim', () => { describe('Update Claim', () => {
const newDate = new Date(); const newDate = Date.vnNew();
const originalData = { const originalData = {
ticketFk: 3, ticketFk: 3,
clientFk: 1101, clientFk: 1101,

View File

@ -1,7 +1,7 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
describe('Update Claim', () => { describe('Update Claim', () => {
const newDate = new Date(); const newDate = Date.vnNew();
const original = { const original = {
ticketFk: 3, ticketFk: 3,
clientFk: 1101, clientFk: 1101,

View File

@ -32,7 +32,7 @@ module.exports = Self => {
c.id AS clientFk, c.id AS clientFk,
c.email AS clientEmail, c.email AS clientEmail,
eu.email salesPersonEmail eu.email salesPersonEmail
FROM client c FROM client c
JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk JOIN account.emailUser eu ON eu.userFk = c.salesPersonFk
JOIN ticket t ON t.clientFk = c.id JOIN ticket t ON t.clientFk = c.id
JOIN sale s ON s.ticketFk = t.id JOIN sale s ON s.ticketFk = t.id
@ -61,10 +61,10 @@ module.exports = Self => {
SET status = 'printed', SET status = 'printed',
printed = ? printed = ?
WHERE id = ?`, WHERE id = ?`,
[new Date(), queue.id]); [Date.vnNew(), queue.id]);
} catch (error) { } catch (error) {
await Self.rawSql(` await Self.rawSql(`
UPDATE clientConsumptionQueue UPDATE clientConsumptionQueue
SET status = ? SET status = ?
WHERE id = ?`, WHERE id = ?`,
[error.message, queue.id]); [error.message, queue.id]);

View File

@ -51,7 +51,7 @@ module.exports = function(Self) {
Self.createReceipt = async(ctx, options) => { Self.createReceipt = async(ctx, options) => {
const models = Self.app.models; const models = Self.app.models;
const args = ctx.args; const args = ctx.args;
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
let tx; let tx;

View File

@ -74,7 +74,7 @@ module.exports = function(Self) {
] ]
}, myOptions); }, myOptions);
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
const query = `SELECT vn.clientGetDebt(?, ?) AS debt`; const query = `SELECT vn.clientGetDebt(?, ?) AS debt`;
const data = await Self.rawSql(query, [id, date], myOptions); const data = await Self.rawSql(query, [id, date], myOptions);

View File

@ -25,7 +25,7 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
const query = `SELECT vn.clientGetDebt(?, ?) AS debt`; const query = `SELECT vn.clientGetDebt(?, ?) AS debt`;
const [debt] = await Self.rawSql(query, [clientFk, date], myOptions); const [debt] = await Self.rawSql(query, [clientFk, date], myOptions);

View File

@ -32,14 +32,14 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
const ticket = await Self.app.models.Ticket.findById(ticketId, null, myOptions); const ticket = await Self.app.models.Ticket.findById(ticketId, null, myOptions);
const query = ` const query = `
SELECT SELECT
t.id, t.id,
t.shipped, t.shipped,
a.name AS agencyName, a.name AS agencyName,
w.name AS warehouseName, w.name AS warehouseName,
ad.nickname AS nickname, ad.nickname AS nickname,
ad.city AS city, ad.city AS city,
@ -52,7 +52,7 @@ module.exports = Self => {
JOIN vn.warehouse w ON t.warehouseFk = w.id JOIN vn.warehouse w ON t.warehouseFk = w.id
JOIN vn.address ad ON t.addressFk = ad.id JOIN vn.address ad ON t.addressFk = ad.id
JOIN vn.province pr ON ad.provinceFk = pr.id JOIN vn.province pr ON ad.provinceFk = pr.id
WHERE t.shipped >= ? AND t.clientFk = ? AND ts.alertLevel = 0 WHERE t.shipped >= ? AND t.clientFk = ? AND ts.alertLevel = 0
AND t.id <> ? AND t.warehouseFk = ? AND t.id <> ? AND t.warehouseFk = ?
ORDER BY t.shipped ORDER BY t.shipped
LIMIT 10`; LIMIT 10`;

View File

@ -125,7 +125,7 @@ module.exports = Self => {
async function getRecoveries(recoveryModel, clientId, options) { async function getRecoveries(recoveryModel, clientId, options) {
const filter = { const filter = {
where: { where: {
and: [{clientFk: clientId}, {or: [{finished: null}, {finished: {gt: Date.now()}}]}] and: [{clientFk: clientId}, {or: [{finished: null}, {finished: {gt: Date.vnNow()}}]}]
}, },
limit: 1 limit: 1
}; };

View File

@ -23,7 +23,7 @@ describe('Client createWithInsurance', () => {
try { try {
const options = {transaction: tx}; const options = {transaction: tx};
const data = {clientFk: 1101, started: Date.now(), credit: 999, grade: 255}; const data = {clientFk: 1101, started: Date.vnNow(), credit: 999, grade: 255};
const result = await models.CreditClassification.createWithInsurance(data, options); const result = await models.CreditClassification.createWithInsurance(data, options);

View File

@ -51,7 +51,7 @@ module.exports = Self => {
const stmts = []; const stmts = [];
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
const stmt = new ParameterizedSQL( const stmt = new ParameterizedSQL(
`SELECT * `SELECT *
@ -65,14 +65,14 @@ module.exports = Self => {
co.created, co.created,
co.text observation, co.text observation,
uw.id workerFk, uw.id workerFk,
uw.name workerName, uw.name workerName,
c.creditInsurance, c.creditInsurance,
d.defaulterSinced d.defaulterSinced
FROM vn.defaulter d FROM vn.defaulter d
JOIN vn.client c ON c.id = d.clientFk JOIN vn.client c ON c.id = d.clientFk
LEFT JOIN vn.clientObservation co ON co.clientFk = c.id LEFT JOIN vn.clientObservation co ON co.clientFk = c.id
LEFT JOIN account.user u ON u.id = c.salesPersonFk LEFT JOIN account.user u ON u.id = c.salesPersonFk
LEFT JOIN account.user uw ON uw.id = co.workerFk LEFT JOIN account.user uw ON uw.id = co.workerFk
WHERE WHERE
d.created = ? d.created = ?
AND d.amount > 0 AND d.amount > 0

View File

@ -27,7 +27,7 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
const query = ` const query = `
SELECT count(*) AS hasActiveRecovery SELECT count(*) AS hasActiveRecovery

View File

@ -41,7 +41,7 @@ module.exports = Self => {
// Disable old mandate // Disable old mandate
if (oldMandate) if (oldMandate)
oldMandate.updateAttribute('finished', new Date()); oldMandate.updateAttribute('finished', Date.vnNew());
// Create a new mandate // Create a new mandate
await models.Mandate.create({ await models.Mandate.create({

View File

@ -59,14 +59,17 @@ class Controller extends Dialog {
if (value) { if (value) {
const accountingType = value.accountingType; const accountingType = value.accountingType;
if (accountingType.receiptDescription != null) {
this.receipt.description = accountingType.receiptDescription; this.receipt.description = [];
if (this.originalDescription) this.receipt.description += `, ${this.originalDescription}`; if (accountingType.receiptDescription != null && accountingType.receiptDescription != '')
} else if (this.originalDescription) this.receipt.description.push(accountingType.receiptDescription);
this.receipt.description = this.originalDescription; if (this.originalDescription)
this.receipt.description.push(this.originalDescription);
this.receipt.description.join(', ');
this.maxAmount = accountingType && accountingType.maxAmount; this.maxAmount = accountingType && accountingType.maxAmount;
this.receipt.payed = new Date(); this.receipt.payed = Date.vnNew();
if (accountingType.daysInFuture) if (accountingType.daysInFuture)
this.receipt.payed.setDate(this.receipt.payed.getDate() + accountingType.daysInFuture); this.receipt.payed.setDate(this.receipt.payed.getDate() + accountingType.daysInFuture);
} }

View File

@ -38,7 +38,7 @@ describe('Client', () => {
} }
}; };
expect(controller.receipt.description).toEqual('Cash, Albaran: 1, 2'); expect(controller.receipt.description.join(',')).toEqual('Cash,Albaran: 1, 2');
}); });
}); });

View File

@ -17,11 +17,11 @@ class Controller extends Section {
} }
setDefaultFilter() { setDefaultFilter() {
const minDate = new Date(); const minDate = Date.vnNew();
minDate.setHours(0, 0, 0, 0); minDate.setHours(0, 0, 0, 0);
minDate.setMonth(minDate.getMonth() - 2); minDate.setMonth(minDate.getMonth() - 2);
const maxDate = new Date(); const maxDate = Date.vnNew();
maxDate.setHours(23, 59, 59, 59); maxDate.setHours(23, 59, 59, 59);
this.filterParams = { this.filterParams = {

View File

@ -26,7 +26,7 @@ describe('Client', () => {
it('should call the window.open function', () => { it('should call the window.open function', () => {
jest.spyOn(window, 'open').mockReturnThis(); jest.spyOn(window, 'open').mockReturnThis();
const now = new Date(); const now = Date.vnNew();
controller.$.model.userParams = { controller.$.model.userParams = {
from: now, from: now,
to: now to: now
@ -49,7 +49,7 @@ describe('Client', () => {
describe('sendEmail()', () => { describe('sendEmail()', () => {
it('should make a GET query sending the report', () => { it('should make a GET query sending the report', () => {
const now = new Date(); const now = Date.vnNew();
controller.$.model.userParams = { controller.$.model.userParams = {
from: now, from: now,
to: now to: now

View File

@ -5,7 +5,7 @@ class Controller extends Section {
constructor($element, $) { constructor($element, $) {
super($element, $); super($element, $);
this.creditClassification = { this.creditClassification = {
started: this.$filter('date')(new Date(), 'yyyy-MM-dd HH:mm') started: this.$filter('date')(Date.vnNew(), 'yyyy-MM-dd HH:mm')
}; };
} }

View File

@ -24,7 +24,7 @@ describe('Client', () => {
describe('onSubmit()', () => { describe('onSubmit()', () => {
it('should perform a POST query', () => { it('should perform a POST query', () => {
let started = new Date(); let started = Date.vnNew();
controller.creditClassification = { controller.creditClassification = {
started: started, started: started,
credit: 300, credit: 300,

View File

@ -52,7 +52,7 @@ class Controller extends Section {
} }
returnDialog() { returnDialog() {
let params = {finished: Date.now()}; let params = {finished: Date.vnNow()};
this.$http.patch(`CreditClassifications/${this.classificationId}`, params).then(() => { this.$http.patch(`CreditClassifications/${this.classificationId}`, params).then(() => {
this._getClassifications(this.client.id); this._getClassifications(this.client.id);
}); });

View File

@ -39,7 +39,7 @@ describe('Client', () => {
it(`should return false if finds a classification without due date`, () => { it(`should return false if finds a classification without due date`, () => {
controller.classifications = [ controller.classifications = [
{finished: Date.now()}, {finished: Date.vnNow()},
{finished: null} {finished: null}
]; ];
@ -50,8 +50,8 @@ describe('Client', () => {
it(`should return true if all classifications are defined with due date`, () => { it(`should return true if all classifications are defined with due date`, () => {
controller.classifications = [ controller.classifications = [
{finished: Date.now()}, {finished: Date.vnNow()},
{finished: Date.now()} {finished: Date.vnNow()}
]; ];
let result = controller.canCreateNew(); let result = controller.canCreateNew();

View File

@ -5,7 +5,7 @@ class Controller extends Section {
constructor($element, $) { constructor($element, $) {
super($element, $); super($element, $);
this.insurance = { this.insurance = {
created: this.$filter('date')(new Date(), 'yyyy-MM-dd HH:mm:ss') created: this.$filter('date')(Date.vnNew(), 'yyyy-MM-dd HH:mm:ss')
}; };
} }

View File

@ -82,7 +82,7 @@ export default class Controller extends Section {
chipColor(date) { chipColor(date) {
const day = 24 * 60 * 60 * 1000; const day = 24 * 60 * 60 * 1000;
const today = new Date(); const today = Date.vnNew();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
const observationShipped = new Date(date); const observationShipped = new Date(date);

View File

@ -38,14 +38,14 @@ describe('client defaulter', () => {
describe('chipColor()', () => { describe('chipColor()', () => {
it('should return undefined when the date is the present', () => { it('should return undefined when the date is the present', () => {
let today = new Date(); let today = Date.vnNew();
let result = controller.chipColor(today); let result = controller.chipColor(today);
expect(result).toEqual(undefined); expect(result).toEqual(undefined);
}); });
it('should return warning when the date is 10 days in the past', () => { it('should return warning when the date is 10 days in the past', () => {
let pastDate = new Date(); let pastDate = Date.vnNew();
pastDate = pastDate.setDate(pastDate.getDate() - 11); pastDate = pastDate.setDate(pastDate.getDate() - 11);
let result = controller.chipColor(pastDate); let result = controller.chipColor(pastDate);
@ -53,7 +53,7 @@ describe('client defaulter', () => {
}); });
it('should return alert when the date is 20 days in the past', () => { it('should return alert when the date is 20 days in the past', () => {
let pastDate = new Date(); let pastDate = Date.vnNew();
pastDate = pastDate.setDate(pastDate.getDate() - 21); pastDate = pastDate.setDate(pastDate.getDate() - 21);
let result = controller.chipColor(pastDate); let result = controller.chipColor(pastDate);

View File

@ -5,7 +5,7 @@ class Controller extends Section {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.greuge = { this.greuge = {
shipped: new Date(), shipped: Date.vnNew(),
clientFk: this.$params.id clientFk: this.$params.id
}; };
} }

View File

@ -39,7 +39,7 @@ describe('Client notification', () => {
describe('campaignSelection() setter', () => { describe('campaignSelection() setter', () => {
it('should set the campaign from and to properties', () => { it('should set the campaign from and to properties', () => {
const dated = new Date(); const dated = Date.vnNew();
controller.campaignSelection = { controller.campaignSelection = {
dated: dated, dated: dated,
scopeDays: 14 scopeDays: 14
@ -61,8 +61,8 @@ describe('Client notification', () => {
controller.$.filters = {hide: () => {}}; controller.$.filters = {hide: () => {}};
controller.campaign = { controller.campaign = {
from: new Date(), from: Date.vnNew(),
to: new Date() to: Date.vnNew()
}; };
const data = controller.$.model.data; const data = controller.$.model.data;

View File

@ -5,7 +5,7 @@ class Controller extends Section {
constructor($element, $) { constructor($element, $) {
super($element, $); super($element, $);
this.recovery = { this.recovery = {
started: new Date() started: Date.vnNew()
}; };
} }

View File

@ -4,7 +4,7 @@ import Section from 'salix/components/section';
class Controller extends Section { class Controller extends Section {
setFinished(recovery) { setFinished(recovery) {
if (!recovery.finished) { if (!recovery.finished) {
let params = {finished: Date.now()}; let params = {finished: Date.vnNow()};
this.$http.patch(`Recoveries/${recovery.id}`, params).then( this.$http.patch(`Recoveries/${recovery.id}`, params).then(
() => this.$.model.refresh() () => this.$.model.refresh()
); );

View File

@ -100,7 +100,7 @@ class Controller extends Summary {
} }
chipColor(date) { chipColor(date) {
const today = new Date(); const today = Date.vnNew();
today.setHours(0, 0, 0, 0); today.setHours(0, 0, 0, 0);
const ticketShipped = new Date(date); const ticketShipped = new Date(date);

View File

@ -76,14 +76,14 @@ describe('Client', () => {
describe('chipColor()', () => { describe('chipColor()', () => {
it('should return warning when the date is the present', () => { it('should return warning when the date is the present', () => {
let today = new Date(); let today = Date.vnNew();
let result = controller.chipColor(today); let result = controller.chipColor(today);
expect(result).toEqual('warning'); expect(result).toEqual('warning');
}); });
it('should return success when the date is in the future', () => { it('should return success when the date is in the future', () => {
let futureDate = new Date(); let futureDate = Date.vnNew();
futureDate = futureDate.setDate(futureDate.getDate() + 10); futureDate = futureDate.setDate(futureDate.getDate() + 10);
let result = controller.chipColor(futureDate); let result = controller.chipColor(futureDate);
@ -91,7 +91,7 @@ describe('Client', () => {
}); });
it('should return undefined when the date is in the past', () => { it('should return undefined when the date is in the past', () => {
let pastDate = new Date(); let pastDate = Date.vnNew();
pastDate = pastDate.setDate(pastDate.getDate() - 10); pastDate = pastDate.setDate(pastDate.getDate() - 10);
let result = controller.chipColor(pastDate); let result = controller.chipColor(pastDate);

View File

@ -4,7 +4,7 @@ import Section from 'salix/components/section';
export default class Controller extends Section { export default class Controller extends Section {
setDefaultDate(hasData) { setDefaultDate(hasData) {
if (hasData && !this.clientUnpaid.dated) if (hasData && !this.clientUnpaid.dated)
this.clientUnpaid.dated = new Date(); this.clientUnpaid.dated = Date.vnNew();
} }
} }

View File

@ -14,7 +14,7 @@ describe('client unpaid', () => {
describe('setDefaultDate()', () => { describe('setDefaultDate()', () => {
it(`should not set today date if has dated`, () => { it(`should not set today date if has dated`, () => {
const hasData = true; const hasData = true;
const yesterday = new Date(); const yesterday = Date.vnNew();
yesterday.setDate(yesterday.getDate() - 1); yesterday.setDate(yesterday.getDate() - 1);
controller.clientUnpaid = { controller.clientUnpaid = {

View File

@ -150,10 +150,10 @@ module.exports = Self => {
const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions); const userConfig = await models.UserConfig.getUserConfig(ctx, myOptions);
const date = new Date(); const date = Date.vnNew();
date.setHours(0, 0, 0, 0); date.setHours(0, 0, 0, 0);
stmt = new ParameterizedSQL(` stmt = new ParameterizedSQL(`
SELECT SELECT
i.image, i.image,
i.id AS itemFk, i.id AS itemFk,
i.size, i.size,
@ -209,7 +209,7 @@ module.exports = Self => {
LEFT JOIN itemType t ON t.id = i.typeFk LEFT JOIN itemType t ON t.id = i.typeFk
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
LEFT JOIN origin ori ON ori.id = i.originFk LEFT JOIN origin ori ON ori.id = i.originFk
LEFT JOIN entry e ON e.id = b.entryFk AND e.created >= DATE_SUB(? ,INTERVAL 1 YEAR) LEFT JOIN entry e ON e.id = b.entryFk AND e.created >= DATE_SUB(? ,INTERVAL 1 YEAR)
LEFT JOIN supplier s ON s.id = e.supplierFk` LEFT JOIN supplier s ON s.id = e.supplierFk`
, [userConfig.warehouseFk, date]); , [userConfig.warehouseFk, date]);

View File

@ -332,10 +332,10 @@ describe('Entry latests buys filter()', () => {
const options = {transaction: tx}; const options = {transaction: tx};
try { try {
const from = new Date(); const from = Date.vnNew();
from.setHours(0, 0, 0, 0); from.setHours(0, 0, 0, 0);
const to = new Date(); const to = Date.vnNew();
to.setHours(23, 59, 59, 999); to.setHours(23, 59, 59, 999);
const ctx = { const ctx = {

View File

@ -1,198 +1,243 @@
<mg-ajax path="Tags" options="mgIndex as tags"></mg-ajax> <vn-crud-model url="Tags" fields="['id','name', 'isFree']" data="$ctrl.tags" auto-load="true">
<div class="search-panel"> <vn-crud-model url="ItemCategories" data="$ctrl.categories" auto-load="true"></vn-crud-model>
<form ng-submit="$ctrl.onSearch()"> <vn-side-menu side="right">
<vn-horizontal> <vn-horizontal class="input">
<vn-textfield <vn-textfield
label="General search" label="General search"
ng-model="filter.search" ng-model="$ctrl.filter.search"
info="Search items by id, name or barcode" info="Search items by id, name or barcode"
vn-focus> vn-focus
</vn-textfield> ng-keydown="$ctrl.onKeyPress($event)">
</vn-horizontal> </vn-textfield>
<vn-horizontal> </vn-horizontal>
<vn-autocomplete <vn-horizontal class="item-category">
vn-focus <vn-autocomplete
url="ItemCategories" vn-id="category"
label="Category" data="$ctrl.categories"
show-field="name" ng-model="$ctrl.filter.categoryFk"
value-field="id" show-field="name"
ng-model="filter.categoryFk"> value-field="id"
</vn-autocomplete> label="Category">
<vn-autocomplete </vn-autocomplete>
url="ItemTypes" <vn-one ng-repeat="category in $ctrl.categories">
label="Type" <vn-icon
where="{categoryFk: filter.categoryFk}" ng-class="{'active': $ctrl.filter.categoryFk == category.id}"
show-field="name" icon="{{::category.icon}}"
value-field="id" vn-tooltip="{{::category.name}}"
ng-model="filter.typeFk" ng-click="$ctrl.changeCategory(category.id)">
fields="['categoryFk']" </vn-icon>
include="'category'"> </vn-one>
<tpl-item> </vn-horizontal>
<div>{{name}}</div> <vn-vertical class="input">
<div class="text-caption text-secondary"> <vn-autocomplete
{{category.name}} vn-id="type"
</div> disabled="!$ctrl.filter.categoryFk"
</tpl-item>> url="ItemTypes"
</vn-autocomplete> label="Type"
</vn-horizontal> where="{categoryFk: $ctrl.filter.categoryFk}"
<vn-horizontal> show-field="name"
<vn-autocomplete value-field="id"
disabled="false" ng-model="$ctrl.filter.typeFk"
ng-model="filter.salesPersonFk" fields="['categoryFk']"
url="Workers/activeWithRole" include="'category'"
show-field="nickname" on-change="$ctrl.addFilters()">
search-function="{firstName: $search}" <tpl-item>
value-field="id" <div>{{name}}</div>
where="{role: {inq: ['logistic', 'buyer']}}" <div class="text-caption text-secondary">
label="Buyer"> {{category.name}}
</vn-autocomplete> </div> </tpl-item
<vn-autocomplete >>
vn-one </vn-autocomplete>
label="Supplier" </vn-vertical>
ng-model="filter.supplierFk" <vn-horizontal class="input horizontal">
url="Suppliers" <vn-autocomplete
fields="['name','nickname']" vn-id="salesPerson"
search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}" disabled="false"
show-field="name" ng-model="$ctrl.filter.salesPersonFk"
value-field="id"> url="Workers/activeWithRole"
<tpl-item>{{name}}: {{nickname}}</tpl-item> show-field="nickname"
</vn-autocomplete> search-function="{firstName: $search}"
</vn-horizontal> value-field="id"
<vn-horizontal> where="{role: {inq: ['logistic', 'buyer']}}"
<vn-date-picker label="Buyer"
vn-one on-change="$ctrl.addFilters()">
label="From" </vn-autocomplete>
ng-model="filter.from"> <vn-autocomplete
</vn-date-picker> vn-id="supplier"
<vn-date-picker label="Supplier"
vn-one ng-model="$ctrl.filter.supplierFk"
label="To" url="Suppliers"
ng-model="filter.to"> fields="['name','nickname']"
</vn-date-picker> search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
</vn-horizontal> show-field="name"
<vn-horizontal> value-field="id"
<vn-check on-change="$ctrl.addFilters()">
label="Is active" <tpl-item>{{name}}: {{nickname}}</tpl-item>
ng-model="filter.active" </vn-autocomplete>
triple-state="true"> </vn-horizontal>
</vn-check> <vn-vertical class="input">
<vn-check <vn-date-picker
label="Is visible" label="From"
ng-model="filter.visible" ng-model="$ctrl.filter.from"
triple-state="true"> on-change="$ctrl.addFilters()">
</vn-check> </vn-date-picker>
<vn-check <vn-date-picker
label="Is floramondo" label="To"
ng-model="filter.floramondo" ng-model="$ctrl.filter.to"
triple-state="true"> on-change="$ctrl.addFilters()">
</vn-check> </vn-date-picker>
</vn-horizontal> </vn-vertical>
<vn-horizontal class="vn-pt-sm"> <vn-horizontal class="checks">
<vn-one class="text-subtitle1" translate> <vn-check
Tags label="Is active"
</vn-one> ng-model="$ctrl.filter.active"
<vn-icon-button triple-state="true"
vn-none ng-click="$ctrl.addFilters()">
vn-bind="+" </vn-check>
vn-tooltip="Add tag" <vn-check
icon="add_circle" label="Is visible"
ng-click="filter.tags.push({})"> ng-model="$ctrl.filter.visible"
</vn-icon-button> triple-state="true"
</vn-horizontal> ng-click="$ctrl.addFilters()">
<vn-horizontal ng-repeat="itemTag in filter.tags"> </vn-check>
<vn-autocomplete <vn-check
vn-id="tag" label="Is floramondo"
ng-model="itemTag.tagFk" ng-model="$ctrl.filter.floramondo"
data="tags.model" triple-state="true"
show-field="name" ng-click="$ctrl.addFilters()">
label="Tag" </vn-check>
on-change="itemTag.value = null"> </vn-horizontal>
</vn-autocomplete> <vn-horizontal class="tags">
<vn-textfield <vn-one class="text-subtitle1" translate> Tags </vn-one>
ng-show="tag.selection.isFree || tag.selection.isFree == undefined" <vn-icon-button
vn-id="text" vn-none
label="Value" vn-tooltip="Add tag"
ng-model="itemTag.value"> icon="add_circle"
</vn-textfield> ng-click="$ctrl.filter.tags.push({})">
<vn-autocomplete </vn-icon-button>
vn-one </vn-horizontal>
ng-show="tag.selection.isFree === false" <vn-horizontal class="tags horizontal" ng-repeat="itemTag in $ctrl.filter.tags">
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}" <vn-autocomplete
search-function="{value: $search}" vn-id="tag"
label="Value" data="$ctrl.tags"
ng-model="itemTag.value" ng-model="itemTag.tagFk"
show-field="value" show-field="name"
value-field="value" label="Tag"
rule> on-change="itemTag.value = null">
</vn-autocomplete> </vn-autocomplete>
<vn-icon-button <vn-textfield
vn-none ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
vn-tooltip="Remove tag" label="Value"
icon="delete" ng-model="itemTag.value"
ng-click="filter.tags.splice($index, 1)" ng-keydown="$ctrl.onKeyPress($event)">
tabindex="-1"> </vn-textfield>
</vn-icon-button> <vn-autocomplete
</vn-horizontal> ng-show="tag.selection.isFree === false"
<vn-horizontal class="vn-pt-sm"> url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
<vn-one class="text-subtitle1" translate> search-function="{value: $search}"
More fields label="Value"
</vn-one> ng-model="itemTag.value"
<vn-icon-button show-field="value"
vn-none value-field="value"
vn-bind="+" on-change="$ctrl.addFilters()">
vn-tooltip="Add field" </vn-autocomplete>
icon="add_circle" <vn-icon-button
ng-click="$ctrl.fieldFilters.push({})"> vn-none
</vn-icon-button> vn-tooltip="Remove tag"
</vn-horizontal> icon="delete"
<vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters"> ng-click="$ctrl.removeTag(itemTag)">
<vn-autocomplete </vn-icon-button>
label="Field" </vn-horizontal>
ng-model="fieldFilter.name" <div class="chips">
data="$ctrl.moreFields" <vn-chip
value-field="name" ng-if="$ctrl.filter.search"
show-field="label" removable="true"
show-filter="false" vn-tooltip="Item id/name"
translate-fields="['label']" on-remove="$ctrl.removeItemFilter('search')"
selection="info" class="colored">
on-change="fieldFilter.value = null"> <span>Id/Name: {{$ctrl.filter.search}}</span>
</vn-autocomplete> </vn-chip>
<vn-one ng-switch="info.type"> <vn-chip
<div ng-switch-when="Number"> ng-if="category.selection"
<vn-input-number removable="true"
label="Value" vn-tooltip="Category"
ng-model="fieldFilter.value"> on-remove="$ctrl.removeItemFilter('categoryFk')"
</vn-input-number> class="colored">
</div> <span>{{category.selection.name}}</span>
<div ng-switch-when="Boolean"> </vn-chip>
<vn-check <vn-chip
label="Value" ng-if="type.selection"
ng-model="fieldFilter.value"> removable="true"
</vn-check> vn-tooltip="Type"
</div> on-remove="$ctrl.removeItemFilter('typeFk')"
<div ng-switch-when="Date"> class="colored">
<vn-date-picker <span>{{type.selection.name}}</span>
label="Value" </vn-chip>
ng-model="fieldFilter.value"> <vn-chip
</vn-date-picker> ng-if="salesPerson.selection"
</div> removable="true"
<div ng-switch-default> vn-tooltip="Sales person"
<vn-textfield on-remove="$ctrl.removeItemFilter('salesPersonFk')"
label="Value" class="colored">
ng-model="fieldFilter.value"> <span>Sales person: {{salesPerson.selection.nickname}}</span>
</vn-textfield> </vn-chip>
</div> <vn-chip
</vn-one> ng-if="supplier.selection"
<vn-icon-button removable="true"
vn-none vn-tooltip="Supplier"
vn-tooltip="Remove field" on-remove="$ctrl.removeItemFilter('supplierFk')"
icon="delete" class="colored">
ng-click="$ctrl.removeField($index, fieldFilter.name)" <span>Supplier: {{supplier.selection.name}}</span>
tabindex="-1"> </vn-chip>
</vn-icon-button> <vn-chip
</vn-horizontal> ng-if="$ctrl.filter.from"
<vn-horizontal class="vn-mt-lg"> removable="true"
<vn-submit label="Search"></vn-submit> vn-tooltip="From date"
</vn-horizontal> on-remove="$ctrl.removeItemFilter('from')"
</form> class="colored">
</div> <span>From: {{$ctrl.filter.from | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.to"
removable="true"
vn-tooltip="To date"
on-remove="$ctrl.removeItemFilter('to')"
class="colored">
<span>To: {{$ctrl.filter.to | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.active != null"
removable="true"
vn-tooltip="Active"
on-remove="$ctrl.removeItemFilter('active')"
class="colored">
<span>Active: {{$ctrl.filter.active ? '✓' : '✗'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.floramondo != null"
removable="true"
vn-tooltip="Floramondo"
on-remove="$ctrl.removeItemFilter('floramondo')"
class="colored">
<span>Floramondo: {{$ctrl.filter.floramondo ? '✓' : '✗'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.visible != null"
removable="true"
vn-tooltip="Visible"
on-remove="$ctrl.removeItemFilter('visible')"
class="colored">
<span>Visible: {{$ctrl.filter.visible ? '✓' : '✗'}}</span>
</vn-chip>
<vn-chip
ng-repeat="chipTag in $ctrl.filter.tags"
removable="true"
vn-tooltip="Tag"
on-remove="$ctrl.removeTag(chipTag)"
class="colored"
ng-if="chipTag.value">
<span>{{$ctrl.showTagInfo(chipTag)}}</span>
</vn-chip>
</vn-chip>
</div>
</vn-side-menu>

View File

@ -1,67 +1,61 @@
import ngModule from '../module'; import ngModule from '../module';
import SearchPanel from 'core/components/searchbar/search-panel'; import SearchPanel from 'core/components/searchbar/search-panel';
import './style.scss';
class Controller extends SearchPanel { class Controller extends SearchPanel {
constructor($element, $) { constructor($element, $) {
super($element, $); super($element, $);
let model = 'Item'; }
let moreFields = ['description', 'name'];
let properties; $onInit() {
let validations = window.validations; this.filter = {
isActive: true,
tags: []
};
}
if (validations && validations[model]) changeCategory(id) {
properties = validations[model].properties; if (this.filter.categoryFk != id) {
else this.filter.categoryFk = id;
properties = {}; this.addFilters();
this.moreFields = [];
for (let field of moreFields) {
let prop = properties[field];
this.moreFields.push({
name: field,
label: prop ? prop.description : field,
type: prop ? prop.type : null
});
} }
} }
get filter() { removeItemFilter(param) {
let filter = this.$.filter; this.filter[param] = null;
if (param == 'categoryFk') this.filter['typeFk'] = null;
for (let fieldFilter of this.fieldFilters) this.addFilters();
filter[fieldFilter.name] = fieldFilter.value;
return filter;
} }
set filter(value) { removeTag(tag) {
if (!value) const index = this.filter.tags.indexOf(tag);
value = {}; if (index > -1) this.filter.tags.splice(index, 1);
if (!value.tags) this.addFilters();
value.tags = [{}]; }
this.fieldFilters = []; onKeyPress($event) {
for (let field of this.moreFields) { if ($event.key === 'Enter')
if (value[field.name] != undefined) { this.addFilters();
this.fieldFilters.push({ }
name: field.name,
value: value[field.name], addFilters() {
info: field for (let i = 0; i < this.filter.tags.length; i++) {
}); if (!this.filter.tags[i].value)
} this.filter.tags.splice(i, 1);
} }
return this.model.addFilter({}, this.filter);
this.$.filter = value;
} }
removeField(index, field) { showTagInfo(itemTag) {
this.fieldFilters.splice(index, 1); if (!itemTag.tagFk) return itemTag.value;
delete this.$.filter[field]; return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`;
} }
} }
ngModule.component('vnLatestBuysSearchPanel', { ngModule.component('vnLatestBuysSearchPanel', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller controller: Controller,
bindings: {
model: '<'
}
}); });

Some files were not shown because too many files have changed in this diff Show More