Merge branch 'dev' into 4109-duplicated_folder
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
402aa567dd
|
@ -46,7 +46,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
const {data} = await Self.getUserStatus(recipient.name);
|
const {data} = await Self.getUserStatus(recipient.name);
|
||||||
if (data) {
|
if (data) {
|
||||||
if (data.status === 'offline' || data.status === 'busy') {
|
if (data.status === 'offline' || data.status === 'busy') {
|
||||||
// Send message to department room
|
// Send message to department room
|
||||||
const workerDepartment = await models.WorkerDepartment.findById(recipientId, {
|
const workerDepartment = await models.WorkerDepartment.findById(recipientId, {
|
||||||
include: {
|
include: {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('setSaleQuantity', {
|
Self.remoteMethod('setSaleQuantity', {
|
||||||
description: 'Update sale quantity',
|
description: 'Update sale quantity',
|
||||||
accessType: 'WRITE',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
|
@ -24,11 +24,13 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.setSaleQuantity = async ctx => {
|
Self.setSaleQuantity = async(saleId, quantity) => {
|
||||||
const args = ctx.args;
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const sale = await models.Sale.findById(args.saleId);
|
const sale = await models.Sale.findById(saleId);
|
||||||
return await sale.updateAttribute('quantity', args.quantity);
|
return await sale.updateAttributes({
|
||||||
|
originalQuantity: sale.quantity,
|
||||||
|
quantity: quantity
|
||||||
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,19 +5,12 @@ describe('setSaleQuantity()', () => {
|
||||||
const saleId = 30;
|
const saleId = 30;
|
||||||
const newQuantity = 10;
|
const newQuantity = 10;
|
||||||
|
|
||||||
const ctx = {
|
|
||||||
args: {
|
|
||||||
saleId: saleId,
|
|
||||||
quantity: newQuantity
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const originalSale = await models.Sale.findById(saleId);
|
const originalSale = await models.Sale.findById(saleId);
|
||||||
|
|
||||||
await models.Collection.setSaleQuantity(ctx);
|
await models.Collection.setSaleQuantity(saleId, newQuantity);
|
||||||
const updateSale = await models.Sale.findById(saleId);
|
const updateSale = await models.Sale.findById(saleId);
|
||||||
|
|
||||||
expect(updateSale.quantity).toBeLessThan(originalSale.quantity);
|
expect(updateSale.originalQuantity).toEqual(originalSale.quantity);
|
||||||
expect(updateSale.quantity).toEqual(newQuantity);
|
expect(updateSale.quantity).toEqual(newQuantity);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
create table `vn`.`invoiceOut_queue`
|
|
||||||
(
|
|
||||||
invoiceFk int(10) unsigned not null,
|
|
||||||
queued datetime default now() not null,
|
|
||||||
printed datetime null,
|
|
||||||
`status` VARCHAR(50) default '' null,
|
|
||||||
constraint invoiceOut_queue_pk
|
|
||||||
primary key (invoiceFk),
|
|
||||||
constraint invoiceOut_queue_invoiceOut_id_fk
|
|
||||||
foreign key (invoiceFk) references invoiceOut (id)
|
|
||||||
on update cascade on delete cascade
|
|
||||||
)
|
|
||||||
comment 'Queue for PDF invoicing';
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ CREATE TABLE `vn`.`clientUnpaid` (
|
||||||
`dated` date NOT NULL,
|
`dated` date NOT NULL,
|
||||||
`amount` double DEFAULT 0,
|
`amount` double DEFAULT 0,
|
||||||
PRIMARY KEY (`clientFk`),
|
PRIMARY KEY (`clientFk`),
|
||||||
CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON UPDATE CASCADE
|
CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `vn`.`client` (`id`) ON UPDATE CASCADE
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE `vn`.`invoiceOut_queue` (
|
||||||
|
`invoiceFk` int(10) unsigned not null,
|
||||||
|
`queued` datetime default now() not null,
|
||||||
|
`printed` datetime null,
|
||||||
|
`status` VARCHAR(50) DEFAULT '' NULL,
|
||||||
|
CONSTRAINT `invoiceOut_queue_pk` PRIMARY KEY (`invoiceFk`),
|
||||||
|
CONSTRAINT `invoiceOut_queue_invoiceOut_id_fk` FOREIGN KEY (`invoiceFk`) REFERENCES `vn`.`invoiceOut` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
|
||||||
|
) comment 'Queue for PDF invoicing';
|
|
@ -1633,51 +1633,59 @@ INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`)
|
||||||
|
|
||||||
INSERT INTO `hedera`.`visit`(`id`, `firstAgentFk`)
|
INSERT INTO `hedera`.`visit`(`id`, `firstAgentFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, NULL),
|
(1, NULL),
|
||||||
(2, NULL),
|
(2, NULL),
|
||||||
(3, NULL),
|
(3, NULL),
|
||||||
(4, NULL),
|
(4, NULL),
|
||||||
(5, NULL),
|
(5, NULL),
|
||||||
(6, NULL),
|
(6, NULL),
|
||||||
(7, NULL),
|
(7, NULL),
|
||||||
(8, NULL),
|
(8, NULL),
|
||||||
(9, NULL);
|
(9, NULL),
|
||||||
|
(10, NULL),
|
||||||
|
(11, NULL);
|
||||||
|
|
||||||
INSERT INTO `hedera`.`visitAgent`(`id`, `visitFk`)
|
INSERT INTO `hedera`.`visitAgent`(`id`, `visitFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1),
|
(1, 1),
|
||||||
(2, 2),
|
(2, 2),
|
||||||
(3, 3),
|
(3, 3),
|
||||||
(4, 4),
|
(4, 4),
|
||||||
(5, 5),
|
(5, 5),
|
||||||
(6, 6),
|
(6, 6),
|
||||||
(7, 7),
|
(7, 7),
|
||||||
(8, 8),
|
(8, 8),
|
||||||
(9, 9);
|
(9, 9),
|
||||||
|
(10, 10),
|
||||||
|
(11, 11);
|
||||||
|
|
||||||
INSERT INTO `hedera`.`visitAccess`(`id`, `agentFk`, `stamp`)
|
INSERT INTO `hedera`.`visitAccess`(`id`, `agentFk`, `stamp`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, CURDATE()),
|
(1, 1, CURDATE()),
|
||||||
(2, 2, CURDATE()),
|
(2, 2, CURDATE()),
|
||||||
(3, 3, CURDATE()),
|
(3, 3, CURDATE()),
|
||||||
(4, 4, CURDATE()),
|
(4, 4, CURDATE()),
|
||||||
(5, 5, CURDATE()),
|
(5, 5, CURDATE()),
|
||||||
(6, 6, CURDATE()),
|
(6, 6, CURDATE()),
|
||||||
(7, 7, CURDATE()),
|
(7, 7, CURDATE()),
|
||||||
(8, 8, CURDATE()),
|
(8, 8, CURDATE()),
|
||||||
(9, 9, CURDATE());
|
(9, 9, CURDATE()),
|
||||||
|
(10, 10, CURDATE()),
|
||||||
|
(11, 11, CURDATE());
|
||||||
|
|
||||||
INSERT INTO `hedera`.`visitUser`(`id`, `accessFk`, `userFk`, `stamp`)
|
INSERT INTO `hedera`.`visitUser`(`id`, `accessFk`, `userFk`, `stamp`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 1101, CURDATE()),
|
(1, 1, 1101, CURDATE()),
|
||||||
(2, 2, 1101, CURDATE()),
|
(2, 2, 1101, CURDATE()),
|
||||||
(3, 3, 1101, CURDATE()),
|
(3, 3, 1101, CURDATE()),
|
||||||
(4, 4, 1102, CURDATE()),
|
(4, 4, 1102, CURDATE()),
|
||||||
(5, 5, 1102, CURDATE()),
|
(5, 5, 1102, CURDATE()),
|
||||||
(6, 6, 1102, CURDATE()),
|
(6, 6, 1102, CURDATE()),
|
||||||
(7, 7, 1103, CURDATE()),
|
(7, 7, 1103, CURDATE()),
|
||||||
(8, 8, 1103, CURDATE()),
|
(8, 8, 1103, CURDATE()),
|
||||||
(9, 9, 1103, CURDATE());
|
(9, 9, 1103, CURDATE()),
|
||||||
|
(10, 10, 1102, DATE_SUB(CURDATE(), INTERVAL 1 DAY)),
|
||||||
|
(11, 11, 1103, DATE_SUB(CURDATE(), INTERVAL 1 DAY));
|
||||||
|
|
||||||
INSERT INTO `hedera`.`userSession`(`created`, `lastUpdate`, `ssid`, `data`, `userVisitFk`)
|
INSERT INTO `hedera`.`userSession`(`created`, `lastUpdate`, `ssid`, `data`, `userVisitFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -101,6 +101,47 @@ export default {
|
||||||
email: 'vn-user-mail-forwarding vn-textfield[ng-model="data.forwardTo"]',
|
email: 'vn-user-mail-forwarding vn-textfield[ng-model="data.forwardTo"]',
|
||||||
save: 'vn-user-mail-forwarding vn-submit'
|
save: 'vn-user-mail-forwarding vn-submit'
|
||||||
},
|
},
|
||||||
|
accountAcl: {
|
||||||
|
addAcl: 'vn-acl-index button vn-icon[icon="add"]',
|
||||||
|
thirdAcl: 'vn-acl-index vn-list> a:nth-child(3)',
|
||||||
|
deleteThirdAcl: 'vn-acl-index vn-list > a:nth-child(3) > vn-item-section > vn-icon-button[icon="delete"]',
|
||||||
|
role: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.principalId"]',
|
||||||
|
model: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.model"]',
|
||||||
|
property: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.property"]',
|
||||||
|
accessType: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.accessType"]',
|
||||||
|
permission: 'vn-acl-create vn-autocomplete[ng-model="$ctrl.acl.permission"]',
|
||||||
|
save: 'vn-acl-create vn-submit'
|
||||||
|
},
|
||||||
|
accountConnections: {
|
||||||
|
firstConnection: 'vn-connections vn-list > a:nth-child(1)',
|
||||||
|
deleteFirstConnection: 'vn-connections vn-list > a:nth-child(1) > vn-item-section > vn-icon-button[icon="exit_to_app"]'
|
||||||
|
},
|
||||||
|
accountAccounts: {
|
||||||
|
syncRoles: 'vn-account-accounts vn-button[label="Synchronize roles"]',
|
||||||
|
syncUser: 'vn-account-accounts vn-button[label="Synchronize user"]',
|
||||||
|
syncAll: 'vn-account-accounts vn-button[label="Synchronize all"]',
|
||||||
|
syncUserName: 'vn-textfield[ng-model="$ctrl.syncUser"]',
|
||||||
|
syncUserPassword: 'vn-textfield[ng-model="$ctrl.syncPassword"]',
|
||||||
|
buttonAccept: 'button[response="accept"]'
|
||||||
|
},
|
||||||
|
accountLdap: {
|
||||||
|
checkEnable: 'vn-account-ldap vn-check[ng-model="watcher.hasData"]',
|
||||||
|
server: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.server"]',
|
||||||
|
rdn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.rdn"]',
|
||||||
|
password: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.password"]',
|
||||||
|
userDn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.userDn"]',
|
||||||
|
groupDn: 'vn-account-ldap vn-textfield[ng-model="$ctrl.config.groupDn"]',
|
||||||
|
save: 'vn-account-ldap vn-submit'
|
||||||
|
},
|
||||||
|
accountSamba: {
|
||||||
|
checkEnable: 'vn-account-samba vn-check[ng-model="watcher.hasData"]',
|
||||||
|
adDomain: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adDomain"]',
|
||||||
|
adController: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adController"]',
|
||||||
|
adUser: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adUser"]',
|
||||||
|
adPassword: 'vn-account-samba vn-textfield[ng-model="$ctrl.config.adPassword"]',
|
||||||
|
verifyCert: 'vn-account-samba vn-check[ng-model="$ctrl.config.verifyCert"]',
|
||||||
|
save: 'vn-account-samba vn-submit'
|
||||||
|
},
|
||||||
clientsIndex: {
|
clientsIndex: {
|
||||||
createClientButton: `vn-float-button`
|
createClientButton: `vn-float-button`
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Account ACL path', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule('developer', 'account');
|
||||||
|
await page.accessToSection('account.acl');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should go to create new acl', async() => {
|
||||||
|
await page.waitToClick(selectors.accountAcl.addAcl);
|
||||||
|
await page.waitForState('account.acl.create');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create new acl', async() => {
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.role, 'sysadmin');
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.model, 'UserAccount');
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.accessType, '*');
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.permission, 'ALLOW');
|
||||||
|
await page.waitToClick(selectors.accountAcl.save);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should navigate to edit', async() => {
|
||||||
|
await page.doSearch();
|
||||||
|
await page.waitToClick(selectors.accountAcl.thirdAcl);
|
||||||
|
await page.waitForState('account.acl.edit');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should edit the third acl', async() => {
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.model, 'Supplier');
|
||||||
|
await page.autocompleteSearch(selectors.accountAcl.accessType, 'READ');
|
||||||
|
await page.waitToClick(selectors.accountAcl.save);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should delete the third result', async() => {
|
||||||
|
const result = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
|
||||||
|
await page.waitToClick(selectors.accountAcl.deleteThirdAcl);
|
||||||
|
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
const newResult = await page.waitToGetProperty(selectors.accountAcl.thirdAcl, 'innerText');
|
||||||
|
|
||||||
|
expect(message.text).toContain('ACL removed');
|
||||||
|
expect(result).not.toEqual(newResult);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,33 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Account Connections path', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
const account = 'sysadmin';
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule(account, 'account');
|
||||||
|
await page.accessToSection('account.connections');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check this is the last connection', async() => {
|
||||||
|
const firstResult = await page.waitToGetProperty(selectors.accountConnections.firstConnection, 'innerText');
|
||||||
|
|
||||||
|
expect(firstResult).toContain(account);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should kill this connection and then get redirected to the login page', async() => {
|
||||||
|
await page.waitToClick(selectors.accountConnections.deleteFirstConnection);
|
||||||
|
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Your session has expired, please login again');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,49 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Account Accounts path', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule('sysadmin', 'account');
|
||||||
|
await page.accessToSection('account.accounts');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sync roles', async() => {
|
||||||
|
await page.waitToClick(selectors.accountAccounts.syncRoles);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Roles synchronized!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sync user', async() => {
|
||||||
|
await page.waitToClick(selectors.accountAccounts.syncUser);
|
||||||
|
await page.write(selectors.accountAccounts.syncUserName, 'sysadmin');
|
||||||
|
await page.write(selectors.accountAccounts.syncUserPassword, 'nightmare');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.accountAccounts.buttonAccept);
|
||||||
|
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('User synchronized!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should relogin', async() => {
|
||||||
|
await page.loginAndModule('sysadmin', 'account');
|
||||||
|
await page.accessToSection('account.accounts');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should sync all', async() => {
|
||||||
|
await page.waitToClick(selectors.accountAccounts.syncAll);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Synchronizing in the background');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,32 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Account LDAP path', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule('sysadmin', 'account');
|
||||||
|
await page.accessToSection('account.ldap');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set data and save', async() => {
|
||||||
|
await page.waitToClick(selectors.accountLdap.checkEnable);
|
||||||
|
await page.write(selectors.accountLdap.server, '1234');
|
||||||
|
await page.write(selectors.accountLdap.rdn, '1234');
|
||||||
|
await page.write(selectors.accountLdap.password, 'nightmare');
|
||||||
|
await page.write(selectors.accountLdap.userDn, 'sysadmin');
|
||||||
|
await page.write(selectors.accountLdap.groupDn, '1234');
|
||||||
|
await page.waitToClick(selectors.accountLdap.save);
|
||||||
|
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,32 @@
|
||||||
|
import selectors from '../../helpers/selectors.js';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Account Samba path', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule('sysadmin', 'account');
|
||||||
|
await page.accessToSection('account.samba');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set data and save', async() => {
|
||||||
|
await page.waitToClick(selectors.accountSamba.checkEnable);
|
||||||
|
await page.write(selectors.accountSamba.adDomain, '1234');
|
||||||
|
await page.write(selectors.accountSamba.adController, '1234');
|
||||||
|
await page.write(selectors.accountSamba.adUser, 'nightmare');
|
||||||
|
await page.write(selectors.accountSamba.adPassword, 'sysadmin');
|
||||||
|
await page.waitToClick(selectors.accountSamba.verifyCert);
|
||||||
|
await page.waitToClick(selectors.accountSamba.save);
|
||||||
|
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -146,16 +146,17 @@ export default class MultiCheck extends FormInput {
|
||||||
if (!this.model || !this.model.data) return;
|
if (!this.model || !this.model.data) return;
|
||||||
|
|
||||||
const data = this.model.data;
|
const data = this.model.data;
|
||||||
const modelParams = this.model.userParams;
|
|
||||||
const params = {
|
const params = {
|
||||||
filter: {
|
filter: {
|
||||||
modelParams: modelParams,
|
|
||||||
limit: null
|
limit: null
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (this.model.userFilter)
|
||||||
|
Object.assign(params.filter, this.model.userFilter);
|
||||||
|
if (this.model.userParams)
|
||||||
|
Object.assign(params, this.model.userParams);
|
||||||
|
|
||||||
this.rows = data.length;
|
this.rows = data.length;
|
||||||
|
|
||||||
this.$http.get(this.model.url, {params})
|
this.$http.get(this.model.url, {params})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
this.allRowsCount = res.data.length;
|
this.allRowsCount = res.data.length;
|
||||||
|
|
|
@ -46,11 +46,13 @@
|
||||||
</div>
|
</div>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<div id="table"></div>
|
<div id="table"></div>
|
||||||
<vn-pagination
|
<div ng-transclude="pagination">
|
||||||
ng-if="$ctrl.model"
|
<vn-pagination
|
||||||
model="$ctrl.model"
|
ng-if="$ctrl.model"
|
||||||
class="vn-pt-md">
|
model="$ctrl.model"
|
||||||
</vn-pagination>
|
class="vn-pt-md">
|
||||||
|
</vn-pagination>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
|
|
|
@ -497,7 +497,8 @@ ngModule.vnComponent('smartTable', {
|
||||||
controller: SmartTable,
|
controller: SmartTable,
|
||||||
transclude: {
|
transclude: {
|
||||||
table: '?slotTable',
|
table: '?slotTable',
|
||||||
actions: '?slotActions'
|
actions: '?slotActions',
|
||||||
|
pagination: '?slotPagination'
|
||||||
},
|
},
|
||||||
bindings: {
|
bindings: {
|
||||||
model: '<?',
|
model: '<?',
|
||||||
|
|
|
@ -98,9 +98,6 @@ module.exports = Self => {
|
||||||
Self.latestBuysFilter = async(ctx, filter, options) => {
|
Self.latestBuysFilter = async(ctx, filter, options) => {
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
|
|
||||||
if (filter && filter.modelParams)
|
|
||||||
ctx.args = filter.modelParams;
|
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
|
|
@ -148,12 +148,12 @@
|
||||||
</td>
|
</td>
|
||||||
<td number>
|
<td number>
|
||||||
<vn-chip class="transparent" translate-attr="buy.groupingMode == 2 ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}">
|
<vn-chip class="transparent" translate-attr="buy.groupingMode == 2 ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}">
|
||||||
<span translate>{{::buy.packing | dashIfEmpty}}</span>
|
<span>{{::buy.packing | dashIfEmpty}}</span>
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
</td>
|
</td>
|
||||||
<td number>
|
<td number>
|
||||||
<vn-chip class="transparent" translate-attr="buy.groupingMode == 1 ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}">
|
<vn-chip class="transparent" translate-attr="buy.groupingMode == 1 ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}">
|
||||||
<span translate>{{::buy.grouping | dashIfEmpty}}</span>
|
<span>{{::buy.grouping | dashIfEmpty}}</span>
|
||||||
</vn-chip>
|
</vn-chip>
|
||||||
</td>
|
</td>
|
||||||
<td number>{{::buy.quantity}}</td>
|
<td number>{{::buy.quantity}}</td>
|
||||||
|
|
|
@ -159,8 +159,22 @@ export default class Controller extends Section {
|
||||||
lines: rowsToEdit
|
lines: rowsToEdit
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.checkedDummyCount && this.checkedDummyCount > 0)
|
if (this.checkedDummyCount && this.checkedDummyCount > 0) {
|
||||||
data.filter = this.$.model.userParams;
|
const params = {};
|
||||||
|
if (this.$.model.userParams) {
|
||||||
|
const userParams = this.$.model.userParams;
|
||||||
|
for (let param in userParams) {
|
||||||
|
let newParam = this.exprBuilder(param, userParams[param]);
|
||||||
|
if (!newParam)
|
||||||
|
newParam = {[param]: userParams[param]};
|
||||||
|
Object.assign(params, newParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.$.model.userFilter)
|
||||||
|
Object.assign(params, this.$.model.userFilter.where);
|
||||||
|
|
||||||
|
data.filter = params;
|
||||||
|
}
|
||||||
|
|
||||||
return this.$http.post('Buys/editLatestBuys', data)
|
return this.$http.post('Buys/editLatestBuys', data)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
|
|
@ -43,11 +43,9 @@ module.exports = Self => {
|
||||||
TIME(v.stamp) AS hour,
|
TIME(v.stamp) AS hour,
|
||||||
DATE(v.stamp) AS dated,
|
DATE(v.stamp) AS dated,
|
||||||
wtc.workerFk
|
wtc.workerFk
|
||||||
FROM hedera.userSession s
|
FROM hedera.visitUser v
|
||||||
JOIN hedera.visitUser v ON v.id = s.userVisitFk
|
|
||||||
JOIN client c ON c.id = v.userFk
|
JOIN client c ON c.id = v.userFk
|
||||||
LEFT JOIN account.user u ON c.salesPersonFk = u.id
|
JOIN account.user u ON c.salesPersonFk = u.id
|
||||||
LEFT JOIN worker w ON c.salesPersonFk = w.id
|
|
||||||
LEFT JOIN sharingCart sc ON sc.workerFk = c.salesPersonFk
|
LEFT JOIN sharingCart sc ON sc.workerFk = c.salesPersonFk
|
||||||
AND CURDATE() BETWEEN sc.started AND sc.ended
|
AND CURDATE() BETWEEN sc.started AND sc.ended
|
||||||
LEFT JOIN workerTeamCollegues wtc
|
LEFT JOIN workerTeamCollegues wtc
|
||||||
|
@ -58,7 +56,9 @@ module.exports = Self => {
|
||||||
const where = filter.where;
|
const where = filter.where;
|
||||||
where['wtc.workerFk'] = userId;
|
where['wtc.workerFk'] = userId;
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
|
stmt.merge(`GROUP BY clientFk, v.stamp`);
|
||||||
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
return conn.executeStmt(stmt, myOptions);
|
return conn.executeStmt(stmt, myOptions);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,12 +6,49 @@ describe('SalesMonitor clientsFilter()', () => {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
|
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
|
||||||
const filter = {order: 'dated DESC'};
|
|
||||||
|
const from = new Date();
|
||||||
|
const to = new Date();
|
||||||
|
from.setHours(0, 0, 0, 0);
|
||||||
|
to.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
'v.stamp': {between: [from, to]}
|
||||||
|
}
|
||||||
|
};
|
||||||
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
|
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(9);
|
expect(result.length).toEqual(3);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the clients web activity filtered', async() => {
|
||||||
|
const tx = await models.SalesMonitor.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
const ctx = {req: {accessToken: {userId: 18}}, args: {}};
|
||||||
|
const yesterday = new Date();
|
||||||
|
yesterday.setDate(yesterday.getDate() - 1);
|
||||||
|
const today = new Date();
|
||||||
|
yesterday.setHours(0, 0, 0, 0);
|
||||||
|
today.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
'v.stamp': {between: [yesterday, today]}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const result = await models.SalesMonitor.clientsFilter(ctx, filter, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(5);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -88,8 +88,16 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<table>
|
</table>
|
||||||
<slot-table>
|
</slot-table>
|
||||||
|
<slot-pagination>
|
||||||
|
<vn-pagination
|
||||||
|
model="model"
|
||||||
|
class="vn-pt-xs"
|
||||||
|
scroll-selector="vn-monitor-sales-clients smart-table"
|
||||||
|
scroll-offset="100">
|
||||||
|
</vn-pagination>
|
||||||
|
</slot-pagination>
|
||||||
</smart-table>
|
</smart-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-worker-descriptor-popover
|
<vn-worker-descriptor-popover
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
},
|
},
|
||||||
"created": {
|
"created": {
|
||||||
"type": "date"
|
"type": "date"
|
||||||
|
},
|
||||||
|
"originalQuantity":{
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -135,7 +135,8 @@ module.exports = Self => {
|
||||||
function formatDate(date) {
|
function formatDate(date) {
|
||||||
let day = date.getDate();
|
let day = date.getDate();
|
||||||
if (day < 10) day = `0${day}`;
|
if (day < 10) day = `0${day}`;
|
||||||
let month = date.getMonth();
|
|
||||||
|
let month = date.getMonth() + 1;
|
||||||
if (month < 10) month = `0${month}`;
|
if (month < 10) month = `0${month}`;
|
||||||
let year = date.getFullYear();
|
let year = date.getFullYear();
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ module.exports = Self => {
|
||||||
function formatDate(date) {
|
function formatDate(date) {
|
||||||
let day = date.getDate();
|
let day = date.getDate();
|
||||||
if (day < 10) day = `0${day}`;
|
if (day < 10) day = `0${day}`;
|
||||||
let month = date.getMonth();
|
let month = date.getMonth() + 1;
|
||||||
if (month < 10) month = `0${month}`;
|
if (month < 10) month = `0${month}`;
|
||||||
let year = date.getFullYear();
|
let year = date.getFullYear();
|
||||||
|
|
||||||
|
|
|
@ -14,5 +14,6 @@ FROM route r
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN account.user u ON u.id = w.userFk
|
||||||
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
|
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
|
||||||
LEFT JOIN agency a ON a.id = am.agencyFk
|
LEFT JOIN agency a ON a.id = am.agencyFk
|
||||||
LEFT JOIN supplier s ON s.id = a.supplierFk
|
LEFT JOIN supplierAgencyTerm sa ON sa.agencyFk = a.id
|
||||||
|
LEFT JOIN supplier s ON s.id = sa.supplierFk
|
||||||
WHERE r.id IN(?)
|
WHERE r.id IN(?)
|
Loading…
Reference in New Issue