Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4927-permitir-razonSocial-duplicada
This commit is contained in:
commit
f01b729a61
|
@ -9,10 +9,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- [General](Inicio) Permite recuperar la contraseña
|
- [General](Inicio) Permite recuperar la contraseña
|
||||||
|
- [Artículo](Datos Básicos) Añadido campo Unidades/Caja
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- [Tickets](Líneas preparadas) Actualizada sección para que sea más visual
|
||||||
- [Supplier](Crear/Editar) Permite añadir Proveedores con la misma razón social pero con países distintos
|
- [Supplier](Crear/Editar) Permite añadir Proveedores con la misma razón social pero con países distintos
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- [General] Al utilizar el traductor de Google se descuadraban los iconos
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- [Tickets](Control clientes) Eliminada sección
|
- [Tickets](Control clientes) Eliminada sección
|
||||||
|
|
|
@ -29,8 +29,12 @@ module.exports = Self => {
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT * FROM campaign`);
|
`SELECT * FROM (`);
|
||||||
|
stmt.merge('SELECT * FROM campaign');
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
|
stmt.merge('ORDER BY dated ASC');
|
||||||
|
stmt.merge('LIMIT 10000000000000000000');
|
||||||
|
stmt.merge(') sub');
|
||||||
stmt.merge('GROUP BY code');
|
stmt.merge('GROUP BY code');
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalId`)
|
||||||
|
VALUES ('ItemShelvingSale','*','*','ALLOW','employee');
|
|
@ -0,0 +1,4 @@
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
ALTER TABLE `vn`.`report` MODIFY COLUMN id tinyint(3) unsigned NOT NULL AUTO_INCREMENT;
|
||||||
|
ALTER TABLE `vn`.`printer` MODIFY COLUMN id tinyint(3) unsigned NOT NULL AUTO_INCREMENT;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
|
@ -1143,10 +1143,10 @@ INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `visible`, `grouping`,
|
||||||
|
|
||||||
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
|
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
|
||||||
VALUES
|
VALUES
|
||||||
('1', '1', '1', '', '1106'),
|
('1', '1', '1', util.VN_CURDATE(), '1106'),
|
||||||
('2', '2', '5', '', '1106'),
|
('2', '2', '5', util.VN_CURDATE(), '1106'),
|
||||||
('1', '7', '1', '', '1106'),
|
('1', '7', '1', util.VN_CURDATE(), '1106'),
|
||||||
('2', '8', '5', '', '1106');
|
('2', '8', '5', util.VN_CURDATE(), '1106');
|
||||||
|
|
||||||
INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`)
|
INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1779,7 +1779,7 @@ INSERT INTO `vn`.`claimDestination`(`id`, `description`, `addressFk`)
|
||||||
INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`)
|
INSERT INTO `vn`.`claimDevelopment`(`id`, `claimFk`, `claimResponsibleFk`, `workerFk`, `claimReasonFk`, `claimResultFk`, `claimRedeliveryFk`, `claimDestinationFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 1, 21, 1, 1, 2, 5),
|
(1, 1, 1, 21, 1, 1, 2, 5),
|
||||||
(2, 1, 1, 21, 7, 2, 2, 5),
|
(2, 1, 2, 21, 7, 2, 2, 5),
|
||||||
(3, 2, 7, 21, 9, 3, 2, 5),
|
(3, 2, 7, 21, 9, 3, 2, 5),
|
||||||
(4, 3, 7, 21, 15, 8, 2, 5),
|
(4, 3, 7, 21, 15, 8, 2, 5),
|
||||||
(5, 4, 7, 21, 7, 8, 2, 5);
|
(5, 4, 7, 21, 7, 8, 2, 5);
|
||||||
|
@ -2652,7 +2652,7 @@ INSERT INTO `vn`.`mdbVersion` (`app`, `branchFk`, `version`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, '2022-01-01', '2023-01-01');
|
(1, CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-01-01'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-01-01'));
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
||||||
|
|
|
@ -463,6 +463,7 @@ export default {
|
||||||
generic: 'vn-autocomplete[ng-model="$ctrl.item.genericFk"]',
|
generic: 'vn-autocomplete[ng-model="$ctrl.item.genericFk"]',
|
||||||
isFragile: 'vn-check[ng-model="$ctrl.item.isFragile"]',
|
isFragile: 'vn-check[ng-model="$ctrl.item.isFragile"]',
|
||||||
longName: 'vn-textfield[ng-model="$ctrl.item.longName"]',
|
longName: 'vn-textfield[ng-model="$ctrl.item.longName"]',
|
||||||
|
packingOut: 'vn-input-number[ng-model="$ctrl.item.packingOut"]',
|
||||||
isActiveCheckbox: 'vn-check[label="Active"]',
|
isActiveCheckbox: 'vn-check[label="Active"]',
|
||||||
priceInKgCheckbox: 'vn-check[label="Price in kg"]',
|
priceInKgCheckbox: 'vn-check[label="Price in kg"]',
|
||||||
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button',
|
newIntrastatButton: 'vn-item-basic-data vn-icon-button[vn-tooltip="New intrastat"] > button',
|
||||||
|
|
|
@ -2,68 +2,32 @@ import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Worker summary path', () => {
|
describe('Worker summary path', () => {
|
||||||
|
const workerId = 3;
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
await page.loginAndModule('employee', 'worker');
|
await page.loginAndModule('employee', 'worker');
|
||||||
|
const httpDataResponse = page.waitForResponse(response => {
|
||||||
|
return response.status() === 200 && response.url().includes(`Workers/${workerId}`);
|
||||||
|
});
|
||||||
await page.accessToSearchResult('agencyNick');
|
await page.accessToSearchResult('agencyNick');
|
||||||
|
await httpDataResponse;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should reach the employee summary section', async() => {
|
it('should reach the employee summary section and check all properties', async() => {
|
||||||
await page.waitForState('worker.card.summary');
|
expect(await page.getProperty(selectors.workerSummary.header, 'innerText')).toEqual('agency agency');
|
||||||
});
|
expect(await page.getProperty(selectors.workerSummary.id, 'innerText')).toEqual('3');
|
||||||
|
expect(await page.getProperty(selectors.workerSummary.email, 'innerText')).toEqual('agency@verdnatura.es');
|
||||||
it('should check the summary contains the name and userName on the header', async() => {
|
expect(await page.getProperty(selectors.workerSummary.department, 'innerText')).toEqual('CAMARA');
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.header, 'innerText');
|
expect(await page.getProperty(selectors.workerSummary.userId, 'innerText')).toEqual('3');
|
||||||
|
expect(await page.getProperty(selectors.workerSummary.userName, 'innerText')).toEqual('agency');
|
||||||
expect(result).toEqual('agency agency');
|
expect(await page.getProperty(selectors.workerSummary.role, 'innerText')).toEqual('agency');
|
||||||
});
|
expect(await page.getProperty(selectors.workerSummary.extension, 'innerText')).toEqual('1101');
|
||||||
|
|
||||||
it('should check the summary contains the basic data id', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.id, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the basic data email', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.email, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('agency@verdnatura.es');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the basic data department', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.department, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('CAMARA');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the user data id', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.userId, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('3');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the user data name', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.userName, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('agency');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the user data role', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.role, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('agency');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the summary contains the user data extension', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerSummary.extension, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toEqual('1101');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,13 +2,18 @@ import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Worker basic data path', () => {
|
describe('Worker basic data path', () => {
|
||||||
|
const workerId = 1106;
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
await page.loginAndModule('hr', 'worker');
|
await page.loginAndModule('hr', 'worker');
|
||||||
|
const httpDataResponse = page.waitForResponse(response => {
|
||||||
|
return response.status() === 200 && response.url().includes(`Workers/${workerId}`);
|
||||||
|
});
|
||||||
await page.accessToSearchResult('David Charles Haller');
|
await page.accessToSearchResult('David Charles Haller');
|
||||||
|
await httpDataResponse;
|
||||||
await page.accessToSection('worker.card.basicData');
|
await page.accessToSection('worker.card.basicData');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,35 +21,20 @@ describe('Worker basic data path', () => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should edit the form', async() => {
|
it('should edit the form and then reload the section and check the data was edited', async() => {
|
||||||
await page.clearInput(selectors.workerBasicData.name);
|
await page.overwrite(selectors.workerBasicData.name, 'David C.');
|
||||||
await page.write(selectors.workerBasicData.name, 'David C.');
|
await page.overwrite(selectors.workerBasicData.surname, 'H.');
|
||||||
await page.clearInput(selectors.workerBasicData.surname);
|
await page.overwrite(selectors.workerBasicData.phone, '444332211');
|
||||||
await page.write(selectors.workerBasicData.surname, 'H.');
|
await page.click(selectors.workerBasicData.saveButton);
|
||||||
await page.clearInput(selectors.workerBasicData.phone);
|
|
||||||
await page.write(selectors.workerBasicData.phone, '444332211');
|
|
||||||
await page.waitToClick(selectors.workerBasicData.saveButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved!');
|
expect(message.text).toContain('Data saved!');
|
||||||
});
|
|
||||||
|
|
||||||
it('should reload the section then check the name was edited', async() => {
|
|
||||||
await page.reloadSection('worker.card.basicData');
|
await page.reloadSection('worker.card.basicData');
|
||||||
const result = await page.waitToGetProperty(selectors.workerBasicData.name, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('David C.');
|
expect(await page.waitToGetProperty(selectors.workerBasicData.name, 'value')).toEqual('David C.');
|
||||||
});
|
expect(await page.waitToGetProperty(selectors.workerBasicData.surname, 'value')).toEqual('H.');
|
||||||
|
expect(await page.waitToGetProperty(selectors.workerBasicData.phone, 'value')).toEqual('444332211');
|
||||||
it('should the surname was edited', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerBasicData.surname, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('H.');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should the phone was edited', async() => {
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerBasicData.phone, 'value');
|
|
||||||
|
|
||||||
expect(result).toEqual('444332211');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,19 +16,16 @@ describe('Worker pbx path', () => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when the extension exceeds 4 characters', async() => {
|
it('should receive an error when the extension exceeds 4 characters and then sucessfully save the changes', async() => {
|
||||||
await page.write(selectors.workerPbx.extension, '55555');
|
await page.write(selectors.workerPbx.extension, '55555');
|
||||||
await page.waitToClick(selectors.workerPbx.saveButton);
|
await page.click(selectors.workerPbx.saveButton);
|
||||||
const message = await page.waitForSnackbar();
|
let message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(message.text).toContain('Extension format is invalid');
|
expect(message.text).toContain('Extension format is invalid');
|
||||||
});
|
|
||||||
|
|
||||||
it('should sucessfully save the changes', async() => {
|
await page.overwrite(selectors.workerPbx.extension, '4444');
|
||||||
await page.clearInput(selectors.workerPbx.extension);
|
await page.click(selectors.workerPbx.saveButton);
|
||||||
await page.write(selectors.workerPbx.extension, '4444');
|
message = await page.waitForSnackbar();
|
||||||
await page.waitToClick(selectors.workerPbx.saveButton);
|
|
||||||
const message = await page.waitForSnackbar();
|
|
||||||
|
|
||||||
expect(message.text).toContain('Data saved! User must access web');
|
expect(message.text).toContain('Data saved! User must access web');
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,43 +21,40 @@ describe('Worker time control path', () => {
|
||||||
const fourPm = '16:00';
|
const fourPm = '16:00';
|
||||||
const hankPymId = 1107;
|
const hankPymId = 1107;
|
||||||
|
|
||||||
it('should go to the next month', async() => {
|
it('should go to the next month, go to current month and go 1 month in the past', async() => {
|
||||||
const date = new Date();
|
let date = new Date();
|
||||||
date.setMonth(date.getMonth() + 1);
|
date.setMonth(date.getMonth() + 1);
|
||||||
const month = date.toLocaleString('default', {month: 'long'});
|
let month = date.toLocaleString('default', {month: 'long'});
|
||||||
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.nextMonthButton);
|
await page.click(selectors.workerTimeControl.nextMonthButton);
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.monthName, 'innerText');
|
let result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain(month);
|
expect(result).toContain(month);
|
||||||
});
|
|
||||||
|
|
||||||
it('should go to current month', async() => {
|
date = new Date();
|
||||||
const date = new Date();
|
month = date.toLocaleString('default', {month: 'long'});
|
||||||
const month = date.toLocaleString('default', {month: 'long'});
|
|
||||||
|
|
||||||
await page.waitToClick(selectors.workerTimeControl.previousMonthButton);
|
await page.click(selectors.workerTimeControl.previousMonthButton);
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.monthName, 'innerText');
|
result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain(month);
|
expect(result).toContain(month);
|
||||||
});
|
|
||||||
|
|
||||||
it('should go 1 month in the past', async() => {
|
date = new Date();
|
||||||
const date = new Date();
|
|
||||||
date.setMonth(date.getMonth() - 1);
|
date.setMonth(date.getMonth() - 1);
|
||||||
const timestamp = Math.round(date.getTime() / 1000);
|
const timestamp = Math.round(date.getTime() / 1000);
|
||||||
const month = date.toLocaleString('default', {month: 'long'});
|
month = date.toLocaleString('default', {month: 'long'});
|
||||||
|
|
||||||
await page.loginAndModule('salesBoss', 'worker');
|
await page.loginAndModule('salesBoss', 'worker');
|
||||||
await page.goto(`http://localhost:5000/#!/worker/${hankPymId}/time-control?timestamp=${timestamp}`);
|
await page.goto(`http://localhost:5000/#!/worker/${hankPymId}/time-control?timestamp=${timestamp}`);
|
||||||
await page.waitToClick(selectors.workerTimeControl.secondWeekDay);
|
await page.click(selectors.workerTimeControl.secondWeekDay);
|
||||||
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.monthName, 'innerText');
|
result = await page.getProperty(selectors.workerTimeControl.monthName, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain(month);
|
expect(result).toContain(month);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return error when insert 'out' of first entry`, async() => {
|
it(`should return error when insert 'out' of first entry`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -68,6 +65,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'in' monday`, async() => {
|
it(`should insert 'in' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
||||||
|
@ -78,6 +76,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'out' monday`, async() => {
|
it(`should insert 'out' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -88,11 +87,13 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove first entry of monday', async() => {
|
it('should remove first entry of monday', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
||||||
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
||||||
|
@ -103,13 +104,16 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should be the 'out' the first entry of monday`, async() => {
|
it(`should be the 'out' the first entry of monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual(fourPm);
|
expect(result).toEqual(fourPm);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should change week of month', async() => {
|
it('should change week of month', async() => {
|
||||||
await page.waitToClick(selectors.workerTimeControl.thrirdWeekDay);
|
await page.click(selectors.workerTimeControl.thrirdWeekDay);
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '00:00 h.');
|
const result = await page.getProperty(selectors.workerTimeControl.mondayWorkedHours, 'innerText');
|
||||||
|
|
||||||
|
expect(result).toEqual('00:00 h.');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,25 @@
|
||||||
|
/* eslint-disable max-len */
|
||||||
import selectors from '../../helpers/selectors.js';
|
import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Worker calendar path', () => {
|
describe('Worker calendar path', () => {
|
||||||
let reasonableTimeBetweenClicks = 400;
|
const reasonableTimeBetweenClicks = 300;
|
||||||
|
const date = new Date();
|
||||||
|
const lastYear = (date.getFullYear() - 1).toString();
|
||||||
|
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
|
async function accessAs(user) {
|
||||||
|
await page.loginAndModule(user, 'worker');
|
||||||
|
await page.accessToSearchResult('Charles Xavier');
|
||||||
|
await page.accessToSection('worker.card.calendar');
|
||||||
|
}
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
await page.loginAndModule('hr', 'worker');
|
accessAs('hr');
|
||||||
await page.accessToSearchResult('Charles Xavier');
|
|
||||||
await page.accessToSection('worker.card.calendar');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
|
@ -21,48 +30,40 @@ describe('Worker calendar path', () => {
|
||||||
it('should set two days as holidays on the calendar and check the total holidays increased by 1.5', async() => {
|
it('should set two days as holidays on the calendar and check the total holidays increased by 1.5', async() => {
|
||||||
await page.waitToClick(selectors.workerCalendar.holidays);
|
await page.waitToClick(selectors.workerCalendar.holidays);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.penultimateMondayOfJanuary);
|
await page.click(selectors.workerCalendar.penultimateMondayOfJanuary);
|
||||||
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.absence);
|
await page.click(selectors.workerCalendar.absence);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.lastMondayOfMarch);
|
await page.click(selectors.workerCalendar.lastMondayOfMarch);
|
||||||
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.halfHoliday);
|
await page.click(selectors.workerCalendar.halfHoliday);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.fistMondayOfMay);
|
await page.click(selectors.workerCalendar.fistMondayOfMay);
|
||||||
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.furlough);
|
await page.click(selectors.workerCalendar.furlough);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.secondTuesdayOfMay);
|
await page.click(selectors.workerCalendar.secondTuesdayOfMay);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.secondWednesdayOfMay);
|
await page.click(selectors.workerCalendar.secondWednesdayOfMay);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.secondThursdayOfMay);
|
await page.click(selectors.workerCalendar.secondThursdayOfMay);
|
||||||
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.halfFurlough);
|
await page.click(selectors.workerCalendar.halfFurlough);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
|
||||||
await page.waitToClick(selectors.workerCalendar.secondFridayOfJun);
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
|
await page.click(selectors.workerCalendar.secondFridayOfJun);
|
||||||
|
|
||||||
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
|
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 1.5 ');
|
||||||
|
|
||||||
expect(result).toContain(' 1.5 ');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(`as salesBoss`, () => {
|
describe(`as salesBoss`, () => {
|
||||||
it(`should log in and get to Charles Xavier's calendar`, async() => {
|
it(`should log in, get to Charles Xavier's calendar, undo what was done here, and check the total holidays used are back to what it was`, async() => {
|
||||||
await page.loginAndModule('salesBoss', 'worker');
|
accessAs('salesBoss');
|
||||||
await page.accessToSearchResult('Charles Xavier');
|
|
||||||
await page.accessToSection('worker.card.calendar');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should undo what was done here', async() => {
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
|
||||||
await page.waitToClick(selectors.workerCalendar.holidays);
|
await page.waitToClick(selectors.workerCalendar.holidays);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.penultimateMondayOfJanuary);
|
await page.waitToClick(selectors.workerCalendar.penultimateMondayOfJanuary);
|
||||||
|
@ -90,45 +91,24 @@ describe('Worker calendar path', () => {
|
||||||
await page.waitToClick(selectors.workerCalendar.halfFurlough);
|
await page.waitToClick(selectors.workerCalendar.halfFurlough);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.secondFridayOfJun);
|
await page.waitToClick(selectors.workerCalendar.secondFridayOfJun);
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the total holidays used are back to what it was', async() => {
|
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
|
||||||
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toContain(' 0 ');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe(`as Charles Xavier`, () => {
|
describe(`as Charles Xavier`, () => {
|
||||||
it(`should log in and get to his calendar`, async() => {
|
it('should log in and get to his calendar, make a futile attempt to add holidays, check the total holidays used are now the initial ones and use the year selector to go to the previous year', async() => {
|
||||||
await page.loginAndModule('CharlesXavier', 'worker');
|
accessAs('CharlesXavier');
|
||||||
await page.accessToSearchResult('Charles Xavier');
|
|
||||||
await page.accessToSection('worker.card.calendar');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should make a futile attempt to add holidays', async() => {
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
|
||||||
await page.waitToClick(selectors.workerCalendar.holidays);
|
await page.waitToClick(selectors.workerCalendar.holidays);
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
||||||
await page.waitToClick(selectors.workerCalendar.penultimateMondayOfJanuary);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should check the total holidays used are now the initial ones', async() => {
|
await page.click(selectors.workerCalendar.penultimateMondayOfJanuary);
|
||||||
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toContain(' 0 ');
|
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
|
||||||
});
|
|
||||||
|
|
||||||
it('should use the year selector to go to the previous year', async() => {
|
|
||||||
const date = new Date();
|
|
||||||
const lastYear = (date.getFullYear() - 1).toString();
|
|
||||||
|
|
||||||
await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
|
await page.autocompleteSearch(selectors.workerCalendar.year, lastYear);
|
||||||
|
|
||||||
await page.waitForTimeout(reasonableTimeBetweenClicks);
|
expect(await page.getProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText')).toContain(' 0 ');
|
||||||
const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText');
|
|
||||||
|
|
||||||
expect(result).toContain(' 0 ');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,6 +35,7 @@ describe('Item Edit basic data path', () => {
|
||||||
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
|
await page.waitToClick(selectors.itemBasicData.isActiveCheckbox);
|
||||||
await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox);
|
await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox);
|
||||||
await page.waitToClick(selectors.itemBasicData.isFragile);
|
await page.waitToClick(selectors.itemBasicData.isFragile);
|
||||||
|
await page.write(selectors.itemBasicData.packingOut, '5');
|
||||||
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
await page.waitToClick(selectors.itemBasicData.submitBasicDataButton);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
@ -128,4 +129,11 @@ describe('Item Edit basic data path', () => {
|
||||||
|
|
||||||
expect(result).toBe('checked');
|
expect(result).toBe('checked');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`should confirm the item packingOut was edited`, async() => {
|
||||||
|
const result = await page
|
||||||
|
.waitToGetProperty(selectors.itemBasicData.packingOut, 'value');
|
||||||
|
|
||||||
|
expect(result).toEqual('5');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@ class Icon {
|
||||||
Icon.$inject = ['$attrs'];
|
Icon.$inject = ['$attrs'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnIcon', {
|
ngModule.vnComponent('vnIcon', {
|
||||||
template: '<i class="{{::$ctrl.iconClass}} unselectable">{{::$ctrl.iconContent}}</i>',
|
template: '<i class="{{::$ctrl.iconClass}} unselectable notranslate">{{::$ctrl.iconContent}}</i>',
|
||||||
controller: Icon,
|
controller: Icon,
|
||||||
bindings: {
|
bindings: {
|
||||||
icon: '@'
|
icon: '@'
|
||||||
|
|
|
@ -153,6 +153,18 @@ vn-table {
|
||||||
background-color: $color-font-bg-dark;
|
background-color: $color-font-bg-dark;
|
||||||
color: $color-font-bg;
|
color: $color-font-bg;
|
||||||
}
|
}
|
||||||
|
&.dark-notice {
|
||||||
|
background-color: $color-notice;
|
||||||
|
color: $color-font-bg;
|
||||||
|
}
|
||||||
|
&.yellow {
|
||||||
|
background-color: $color-yellow;
|
||||||
|
color: $color-font-bg;
|
||||||
|
}
|
||||||
|
&.pink {
|
||||||
|
background-color: $color-pink;
|
||||||
|
color: $color-font-bg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
vn-icon-menu {
|
vn-icon-menu {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
|
@ -101,6 +101,8 @@ $color-marginal: #222;
|
||||||
$color-success: #a3d131;
|
$color-success: #a3d131;
|
||||||
$color-notice: #32b1ce;
|
$color-notice: #32b1ce;
|
||||||
$color-alert: #fa3939;
|
$color-alert: #fa3939;
|
||||||
|
$color-pink: #ff99cc;
|
||||||
|
$color-yellow: #ffff00;
|
||||||
$color-button: $color-secondary;
|
$color-button: $color-secondary;
|
||||||
|
|
||||||
$color-spacer: rgba(255, 255, 255, .3);
|
$color-spacer: rgba(255, 255, 255, .3);
|
||||||
|
|
|
@ -1,15 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
<<<<<<< HEAD
|
|
||||||
"dependencies": {
|
|
||||||
"@uirouter/angularjs": {
|
|
||||||
"version": "1.0.29",
|
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.29.tgz",
|
|
||||||
"integrity": "sha512-RImWnBarNixkMto0o8stEaGwZmvhv5cnuOLXyMU2pY8MP2rgEF74ZNJTLeJCW14LR7XDUxVH8Mk8bPI6lxedmQ==",
|
|
||||||
=======
|
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "salix-front",
|
"name": "salix-front",
|
||||||
|
@ -32,8 +25,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/@uirouter/angularjs": {
|
"node_modules/@uirouter/angularjs": {
|
||||||
"version": "1.0.30",
|
"version": "1.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@uirouter/core": "6.0.8"
|
"@uirouter/core": "6.0.8"
|
||||||
},
|
},
|
||||||
|
@ -46,17 +38,14 @@
|
||||||
},
|
},
|
||||||
"node_modules/@uirouter/core": {
|
"node_modules/@uirouter/core": {
|
||||||
"version": "6.0.8",
|
"version": "6.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw==",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/angular": {
|
"node_modules/angular": {
|
||||||
"version": "1.8.3",
|
"version": "1.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
|
"license": "MIT"
|
||||||
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw==",
|
|
||||||
"deprecated": "For the actively supported Angular, see https://www.npmjs.com/package/@angular/core. AngularJS support has officially ended. For extended AngularJS support options, see https://goo.gle/angularjs-path-forward."
|
|
||||||
},
|
},
|
||||||
"node_modules/angular-animate": {
|
"node_modules/angular-animate": {
|
||||||
"version": "1.8.2",
|
"version": "1.8.2",
|
||||||
|
@ -74,8 +63,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/angular-translate": {
|
"node_modules/angular-translate": {
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"angular": "^1.8.0"
|
"angular": "^1.8.0"
|
||||||
},
|
},
|
||||||
|
@ -85,8 +73,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/angular-translate-loader-partial": {
|
"node_modules/angular-translate-loader-partial": {
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"angular-translate": "~2.19.0"
|
"angular-translate": "~2.19.0"
|
||||||
}
|
}
|
||||||
|
@ -133,8 +120,7 @@
|
||||||
},
|
},
|
||||||
"node_modules/moment": {
|
"node_modules/moment": {
|
||||||
"version": "2.29.4",
|
"version": "2.29.4",
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
"license": "MIT",
|
||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
|
@ -179,97 +165,51 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@uirouter/angularjs": {
|
"@uirouter/angularjs": {
|
||||||
"version": "1.0.30",
|
"version": "1.0.30",
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/angularjs/-/angularjs-1.0.30.tgz",
|
|
||||||
"integrity": "sha512-qkc3RFZc91S5K0gc/QVAXc9LGDPXjR04vDgG/11j8+yyZEuQojXxKxdLhKIepiPzqLmGRVqzBmBc27gtqaEeZg==",
|
|
||||||
>>>>>>> dev
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"@uirouter/core": "6.0.8"
|
"@uirouter/core": "6.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@uirouter/core": {
|
"@uirouter/core": {
|
||||||
<<<<<<< HEAD
|
"version": "6.0.8"
|
||||||
"version": "6.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.7.tgz",
|
|
||||||
"integrity": "sha512-KUTJxL+6q0PiBnFx4/Z+Hsyg0pSGiaW5yZQeJmUxknecjpTbnXkLU8H2EqRn9N2B+qDRa7Jg8RcgeNDPY72O1w=="
|
|
||||||
},
|
},
|
||||||
"angular": {
|
"angular": {
|
||||||
"version": "1.8.2",
|
"version": "1.8.3"
|
||||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.2.tgz",
|
|
||||||
"integrity": "sha512-IauMOej2xEe7/7Ennahkbb5qd/HFADiNuLSESz9Q27inmi32zB0lnAsFeLEWcox3Gd1F6YhNd1CP7/9IukJ0Gw=="
|
|
||||||
=======
|
|
||||||
"version": "6.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@uirouter/core/-/core-6.0.8.tgz",
|
|
||||||
"integrity": "sha512-Gc/BAW47i4L54p8dqYCJJZuv2s3tqlXQ0fvl6Zp2xrblELPVfxmjnc0eurx3XwfQdaqm3T6uls6tQKkof/4QMw=="
|
|
||||||
},
|
|
||||||
"angular": {
|
|
||||||
"version": "1.8.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular/-/angular-1.8.3.tgz",
|
|
||||||
"integrity": "sha512-5qjkWIQQVsHj4Sb5TcEs4WZWpFeVFHXwxEBHUhrny41D8UrBAd6T/6nPPAsLngJCReIOqi95W3mxdveveutpZw=="
|
|
||||||
>>>>>>> dev
|
|
||||||
},
|
},
|
||||||
"angular-animate": {
|
"angular-animate": {
|
||||||
"version": "1.8.2",
|
"version": "1.8.2"
|
||||||
"resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.8.2.tgz",
|
|
||||||
"integrity": "sha512-Jbr9+grNMs9Kj57xuBU3Ju3NOPAjS1+g2UAwwDv7su1lt0/PLDy+9zEwDiu8C8xJceoTbmBNKiWGPJGBdCQLlA=="
|
|
||||||
},
|
},
|
||||||
"angular-moment": {
|
"angular-moment": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-KG8rvO9MoaBLwtGnxTeUveSyNtrL+RNgGl1zqWN36+HDCCVGk2DGWOzqKWB6o+eTTbO3Opn4hupWKIElc8XETA==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"moment": ">=2.8.0 <3.0.0"
|
"moment": ">=2.8.0 <3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"angular-translate": {
|
"angular-translate": {
|
||||||
<<<<<<< HEAD
|
|
||||||
"version": "2.18.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.4.tgz",
|
|
||||||
"integrity": "sha512-KohNrkH6J9PK+VW0L/nsRTcg5Fw70Ajwwe3Jbfm54Pf9u9Fd+wuingoKv+h45mKf38eT+Ouu51FPua8VmZNoCw==",
|
|
||||||
=======
|
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.19.0.tgz",
|
|
||||||
"integrity": "sha512-Z/Fip5uUT2N85dPQ0sMEe1JdF5AehcDe4tg/9mWXNDVU531emHCg53ZND9Oe0dyNiGX5rWcJKmsL1Fujus1vGQ==",
|
|
||||||
>>>>>>> dev
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"angular": "^1.8.0"
|
"angular": "^1.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"angular-translate-loader-partial": {
|
"angular-translate-loader-partial": {
|
||||||
<<<<<<< HEAD
|
|
||||||
"version": "2.18.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.18.4.tgz",
|
|
||||||
"integrity": "sha512-bsjR+FbB0sdA2528E/ugwKdlPPQhA1looxLxI3otayBTFXBpED33besfSZhYAISLgNMSL038vSssfRUen9qD8w==",
|
|
||||||
=======
|
|
||||||
"version": "2.19.0",
|
"version": "2.19.0",
|
||||||
"resolved": "https://registry.npmjs.org/angular-translate-loader-partial/-/angular-translate-loader-partial-2.19.0.tgz",
|
|
||||||
"integrity": "sha512-NnMw13LMV4bPQmJK7/pZOZAnPxe0M5OtUHchADs5Gye7V7feonuEnrZ8e1CKhBlv9a7IQyWoqcBa4Lnhg8gk5w==",
|
|
||||||
>>>>>>> dev
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"angular-translate": "~2.19.0"
|
"angular-translate": "~2.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"argparse": {
|
"argparse": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
|
||||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"croppie": {
|
"croppie": {
|
||||||
"version": "2.6.5",
|
"version": "2.6.5"
|
||||||
"resolved": "https://registry.npmjs.org/croppie/-/croppie-2.6.5.tgz",
|
|
||||||
"integrity": "sha512-IlChnVUGG5T3w2gRZIaQgBtlvyuYnlUWs2YZIXXR3H9KrlO1PtBT3j+ykxvy9eZIWhk+V5SpBmhCQz5UXKrEKQ=="
|
|
||||||
},
|
},
|
||||||
"esprima": {
|
"esprima": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1"
|
||||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
|
||||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
"version": "3.14.1",
|
"version": "3.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
|
|
||||||
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^1.0.7",
|
"argparse": "^1.0.7",
|
||||||
"esprima": "^4.0.0"
|
"esprima": "^4.0.0"
|
||||||
|
@ -277,45 +217,27 @@
|
||||||
},
|
},
|
||||||
"mg-crud": {
|
"mg-crud": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/mg-crud/-/mg-crud-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-mAR6t0aQHKnT0QHKHpLOi0kNPZfO36iMpIoiLjFHxuio6mIJyuveBJ4VNlNXJRxLh32/FLADEb41/sYo7QUKFw==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"angular": "^1.6.1"
|
"angular": "^1.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"moment": {
|
"moment": {
|
||||||
<<<<<<< HEAD
|
"version": "2.29.4"
|
||||||
"version": "2.29.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
|
||||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
|
||||||
=======
|
|
||||||
"version": "2.29.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
|
||||||
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
|
||||||
>>>>>>> dev
|
|
||||||
},
|
},
|
||||||
"oclazyload": {
|
"oclazyload": {
|
||||||
"version": "0.6.3",
|
"version": "0.6.3"
|
||||||
"resolved": "https://registry.npmjs.org/oclazyload/-/oclazyload-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-HpOSYUgjtt6sTB/C6+FWsExR+9HCnXKsUA96RWkDXfv11C8Cc9X2DlR0WIZwFIiG6FQU0pwB5dhoYyut8bFAOQ=="
|
|
||||||
},
|
},
|
||||||
"require-yaml": {
|
"require-yaml": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-yaml/-/require-yaml-0.0.1.tgz",
|
|
||||||
"integrity": "sha512-M6eVEgLPRbeOhgSCnOTtdrOOEQzbXRchg24Xa13c39dMuraFKdI9emUo97Rih0YEFzSICmSKg8w4RQp+rd9pOQ==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"js-yaml": "^4.1.0"
|
"js-yaml": ""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argparse": {
|
"argparse": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1"
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^2.0.1"
|
"argparse": "^2.0.1"
|
||||||
}
|
}
|
||||||
|
@ -323,14 +245,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3"
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
|
|
||||||
},
|
},
|
||||||
"validator": {
|
"validator": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0"
|
||||||
"resolved": "https://registry.npmjs.org/validator/-/validator-6.3.0.tgz",
|
|
||||||
"integrity": "sha512-BylxTwhqwjQI5MDJF7amCy/L0ejJO+74DvCsLV52Lq3+3bhVcVMKqNqOiNcQJm2G48u9EAcw4xFERAmFbwXM9Q=="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
arg: 'search',
|
arg: 'search',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: `If it's and integer searchs by id, otherwise it searchs by client name`,
|
description: `If it's a number searchs by id, otherwise it searchs by client name`,
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -34,31 +34,31 @@ module.exports = Self => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'integer',
|
type: 'number',
|
||||||
description: 'The claim id',
|
description: 'The claim id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'clientFk',
|
arg: 'clientFk',
|
||||||
type: 'integer',
|
type: 'number',
|
||||||
description: 'The client id',
|
description: 'The client id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'claimStateFk',
|
arg: 'claimStateFk',
|
||||||
type: 'integer',
|
type: 'number',
|
||||||
description: 'The claim state id',
|
description: 'The claim state id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'salesPersonFk',
|
arg: 'salesPersonFk',
|
||||||
type: 'integer',
|
type: 'number',
|
||||||
description: 'The salesPerson id',
|
description: 'The salesPerson id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'attenderFk',
|
arg: 'attenderFk',
|
||||||
type: 'integer',
|
type: 'number',
|
||||||
description: 'The attender worker id',
|
description: 'The attender worker id',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
},
|
},
|
||||||
|
@ -67,6 +67,18 @@ module.exports = Self => {
|
||||||
type: 'date',
|
type: 'date',
|
||||||
description: 'The to date filter',
|
description: 'The to date filter',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'itemFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The item id',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'claimResponsibleFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The claimResponsible id',
|
||||||
|
http: {source: 'query'}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -80,33 +92,58 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.filter = async(ctx, filter, options) => {
|
Self.filter = async(ctx, filter, options) => {
|
||||||
|
const models = Self.app.models;
|
||||||
const conn = Self.dataSource.connector;
|
const conn = Self.dataSource.connector;
|
||||||
|
const args = ctx.args;
|
||||||
const myOptions = {};
|
const myOptions = {};
|
||||||
let to;
|
let to;
|
||||||
|
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const where = buildFilter(ctx.args, (param, value) => {
|
let claimIdsByItemFk = [];
|
||||||
|
let claimIdsByClaimResponsibleFk = [];
|
||||||
|
|
||||||
|
if (args.itemFk) {
|
||||||
|
query = `SELECT cb.claimFk
|
||||||
|
FROM claimBeginning cb
|
||||||
|
LEFT JOIN sale s ON s.id = cb.saleFk
|
||||||
|
WHERE s.itemFk = ?`;
|
||||||
|
const claims = await Self.rawSql(query, [args.itemFk], myOptions);
|
||||||
|
claimIdsByItemFk = claims.map(claim => claim.claimFk);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.claimResponsibleFk) {
|
||||||
|
const claims = await models.ClaimDevelopment.find({
|
||||||
|
fields: ['claimFk'],
|
||||||
|
where: {claimResponsibleFk: args.claimResponsibleFk}
|
||||||
|
}, myOptions);
|
||||||
|
claimIdsByClaimResponsibleFk = claims.map(claim => claim.claimFk);
|
||||||
|
}
|
||||||
|
|
||||||
|
const where = buildFilter(args, (param, value) => {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
? {'cl.id': value}
|
? {'cl.id': value}
|
||||||
: {
|
: {
|
||||||
or: [
|
or: [
|
||||||
{'cl.clientName': {like: `%${value}%`}}
|
{'c.name': {like: `%${value}%`}}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
case 'clientName':
|
case 'clientName':
|
||||||
return {'cl.clientName': {like: `%${value}%`}};
|
return {'c.name': {like: `%${value}%`}};
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
return {'cl.clientFk': value};
|
|
||||||
case 'id':
|
case 'id':
|
||||||
case 'claimStateFk':
|
case 'claimStateFk':
|
||||||
case 'priority':
|
case 'priority':
|
||||||
return {[`cl.${param}`]: value};
|
return {[`cl.${param}`]: value};
|
||||||
|
case 'itemFk':
|
||||||
|
return {'cl.id': {inq: claimIdsByItemFk}};
|
||||||
|
case 'claimResponsibleFk':
|
||||||
|
return {'cl.id': {inq: claimIdsByClaimResponsibleFk}};
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
return {'cl.salesPersonFk': value};
|
return {'c.salesPersonFk': value};
|
||||||
case 'attenderFk':
|
case 'attenderFk':
|
||||||
return {'cl.workerFk': value};
|
return {'cl.workerFk': value};
|
||||||
case 'created':
|
case 'created':
|
||||||
|
@ -118,29 +155,23 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
filter = mergeFilters(ctx.args.filter, {where});
|
filter = mergeFilters(args.filter, {where});
|
||||||
|
|
||||||
const stmts = [];
|
const stmts = [];
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT *
|
`SELECT
|
||||||
FROM (
|
|
||||||
SELECT
|
|
||||||
cl.id,
|
cl.id,
|
||||||
cl.clientFk,
|
cl.clientFk,
|
||||||
c.name AS clientName,
|
c.name AS clientName,
|
||||||
cl.workerFk,
|
cl.workerFk,
|
||||||
u.name AS workerName,
|
u.name AS workerName,
|
||||||
cs.description,
|
cs.description,
|
||||||
cl.created,
|
cl.created
|
||||||
cs.priority,
|
|
||||||
cl.claimStateFk,
|
|
||||||
c.salesPersonFk
|
|
||||||
FROM claim cl
|
FROM claim cl
|
||||||
LEFT JOIN client c ON c.id = cl.clientFk
|
LEFT JOIN client c ON c.id = cl.clientFk
|
||||||
LEFT JOIN worker w ON w.id = cl.workerFk
|
LEFT JOIN account.user u ON u.id = cl.workerFk
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk`
|
||||||
LEFT JOIN claimState cs ON cs.id = cl.claimStateFk ) cl`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
|
@ -57,4 +57,44 @@ describe('claim filter()', () => {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return 3 results filtering by item id', async() => {
|
||||||
|
const tx = await app.models.Claim.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const result = await app.models.Claim.filter({args: {filter: {}, itemFk: 2}}, null, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
expect(result[0].id).toEqual(1);
|
||||||
|
expect(result[1].id).toEqual(2);
|
||||||
|
expect(result[2].id).toEqual(4);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 3 results filtering by claimResponsible id', async() => {
|
||||||
|
const tx = await app.models.Claim.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const result = await app.models.Claim.filter({args: {filter: {}, claimResponsibleFk: 7}}, null, options);
|
||||||
|
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
expect(result[0].id).toEqual(2);
|
||||||
|
expect(result[1].id).toEqual(3);
|
||||||
|
expect(result[2].id).toEqual(4);
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,6 +58,26 @@
|
||||||
ng-model="filter.created">
|
ng-model="filter.created">
|
||||||
</vn-date-picker>
|
</vn-date-picker>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one class="dense"
|
||||||
|
label="Item"
|
||||||
|
url="Items/withName"
|
||||||
|
ng-model="filter.itemFk"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
search-function="$ctrl.itemSearchFunc($search)"
|
||||||
|
order="id DESC">
|
||||||
|
<tpl-item>{{::id}} - {{::name}}</tpl-item>
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
ng-model="filter.claimResponsibleFk"
|
||||||
|
url="ClaimResponsibles"
|
||||||
|
show-field="description"
|
||||||
|
value-field="id"
|
||||||
|
label="Responsible">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
<vn-horizontal class="vn-mt-lg">
|
<vn-horizontal class="vn-mt-lg">
|
||||||
<vn-submit label="Search"></vn-submit>
|
<vn-submit label="Search"></vn-submit>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||||
|
|
||||||
|
class Controller extends SearchPanel {
|
||||||
|
itemSearchFunc($search) {
|
||||||
|
return /^\d+$/.test($search)
|
||||||
|
? {id: $search}
|
||||||
|
: {name: {like: '%' + $search + '%'}};
|
||||||
|
}
|
||||||
|
}
|
||||||
ngModule.vnComponent('vnClaimSearchPanel', {
|
ngModule.vnComponent('vnClaimSearchPanel', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: SearchPanel
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,7 +4,7 @@ import Dialog from 'core/components/dialog';
|
||||||
class Controller extends Dialog {
|
class Controller extends Dialog {
|
||||||
constructor($element, $, $transclude, vnReport) {
|
constructor($element, $, $transclude, vnReport) {
|
||||||
super($element, $, $transclude);
|
super($element, $, $transclude);
|
||||||
|
this.viewReceipt = true;
|
||||||
this.vnReport = vnReport;
|
this.vnReport = vnReport;
|
||||||
this.receipt = {};
|
this.receipt = {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ describe('Client', () => {
|
||||||
jest.spyOn(controller.vnReport, 'show');
|
jest.spyOn(controller.vnReport, 'show');
|
||||||
|
|
||||||
controller.$params = {id: 1101};
|
controller.$params = {id: 1101};
|
||||||
|
controller.viewReceipt = false;
|
||||||
|
|
||||||
$httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1});
|
$httpBackend.expect('POST', `Clients/1101/createReceipt`).respond({id: 1});
|
||||||
controller.responseHandler('accept');
|
controller.responseHandler('accept');
|
||||||
|
|
|
@ -11,7 +11,6 @@ describe('InvoiceOut createPdf()', () => {
|
||||||
const ctx = {req: activeCtx};
|
const ctx = {req: activeCtx};
|
||||||
|
|
||||||
it('should create a new PDF file and set true the hasPdf property', async() => {
|
it('should create a new PDF file and set true the hasPdf property', async() => {
|
||||||
pending('https://redmine.verdnatura.es/issues/4875');
|
|
||||||
const invoiceId = 1;
|
const invoiceId = 1;
|
||||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
active: activeCtx
|
active: activeCtx
|
||||||
|
|
|
@ -13,7 +13,6 @@ describe('InvoiceOut downloadZip()', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should return part of link to dowloand the zip', async() => {
|
it('should return part of link to dowloand the zip', async() => {
|
||||||
pending('https://redmine.verdnatura.es/issues/4875');
|
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -31,6 +30,8 @@ describe('InvoiceOut downloadZip()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return an error if the size of the files is too large', async() => {
|
it('should return an error if the size of the files is too large', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/5035');
|
||||||
|
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
|
|
@ -51,7 +51,6 @@ describe('InvoiceOut filter()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the invoice out matching hasPdf', async() => {
|
it('should return the invoice out matching hasPdf', async() => {
|
||||||
pending('https://redmine.verdnatura.es/issues/4875');
|
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ describe('InvoiceOut filter()', () => {
|
||||||
|
|
||||||
const result = await models.InvoiceOut.filter(ctx, {id: invoiceOut.id}, options);
|
const result = await models.InvoiceOut.filter(ctx, {id: invoiceOut.id}, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -17,12 +17,12 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
name="showInvoicePdf"
|
name="showInvoicePdf"
|
||||||
translate>
|
translate>
|
||||||
Show as PDF
|
as PDF
|
||||||
</a>
|
</a>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-click="$ctrl.showCsvInvoice()"
|
ng-click="$ctrl.showCsvInvoice()"
|
||||||
translate>
|
translate>
|
||||||
Show as CSV
|
as CSV
|
||||||
</vn-item>
|
</vn-item>
|
||||||
</vn-list>
|
</vn-list>
|
||||||
</vn-menu>
|
</vn-menu>
|
||||||
|
|
|
@ -2,6 +2,8 @@ Show invoice...: Ver factura...
|
||||||
Send invoice...: Enviar factura...
|
Send invoice...: Enviar factura...
|
||||||
Send PDF invoice: Enviar factura en PDF
|
Send PDF invoice: Enviar factura en PDF
|
||||||
Send CSV invoice: Enviar factura en CSV
|
Send CSV invoice: Enviar factura en CSV
|
||||||
|
as PDF: como PDF
|
||||||
|
as CSV: como CSV
|
||||||
Delete Invoice: Eliminar factura
|
Delete Invoice: Eliminar factura
|
||||||
Clone Invoice: Clonar factura
|
Clone Invoice: Clonar factura
|
||||||
Book invoice: Asentar factura
|
Book invoice: Asentar factura
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('filter', {
|
||||||
|
description: 'Returns all item shelving sale matching with the filter',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'object',
|
||||||
|
description: 'Filter defining where and paginated data'
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/filter`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.filter = async(filter, options) => {
|
||||||
|
const conn = Self.dataSource.connector;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
const stmt = new ParameterizedSQL(`
|
||||||
|
SELECT iss.created,
|
||||||
|
iss.saleFk,
|
||||||
|
iss.quantity,
|
||||||
|
iss.userFk,
|
||||||
|
ish.shelvingFk,
|
||||||
|
p.code,
|
||||||
|
u.name
|
||||||
|
FROM itemShelvingSale iss
|
||||||
|
LEFT JOIN itemShelving ish ON iss.itemShelvingFk = ish.id
|
||||||
|
LEFT JOIN shelving s ON ish.shelvingFk = s.code
|
||||||
|
LEFT JOIN parking p ON s.parkingFk = p.id
|
||||||
|
LEFT JOIN account.user u ON u.id = iss.userFk`
|
||||||
|
);
|
||||||
|
|
||||||
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
||||||
|
return conn.executeStmt(stmt);
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/item-shelving-sale/filter')(Self);
|
||||||
|
};
|
|
@ -11,9 +11,6 @@
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"id": true,
|
"id": true,
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
|
||||||
"shelve": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
},
|
||||||
"shelvingFk": {
|
"shelvingFk": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -21,12 +18,6 @@
|
||||||
"itemFk": {
|
"itemFk": {
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"deep": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"quantity": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"created": {
|
"created": {
|
||||||
"type": "date"
|
"type": "date"
|
||||||
}
|
}
|
||||||
|
@ -41,6 +32,11 @@
|
||||||
"type": "belongsTo",
|
"type": "belongsTo",
|
||||||
"model": "Account",
|
"model": "Account",
|
||||||
"foreignKey": "userFk"
|
"foreignKey": "userFk"
|
||||||
|
},
|
||||||
|
"shelving": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Shelving",
|
||||||
|
"foreignKey": "shelvingFk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,13 @@
|
||||||
ng-model="$ctrl.item.weightByPiece"
|
ng-model="$ctrl.item.weightByPiece"
|
||||||
rule>
|
rule>
|
||||||
</vn-input-number>
|
</vn-input-number>
|
||||||
|
<vn-input-number
|
||||||
|
vn-one
|
||||||
|
min="0"
|
||||||
|
label="Units/Box"
|
||||||
|
ng-model="$ctrl.item.packingOut"
|
||||||
|
rule>
|
||||||
|
</vn-input-number>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
label="Generic"
|
label="Generic"
|
||||||
|
|
|
@ -44,6 +44,7 @@ Weight/Piece: Peso/tallo
|
||||||
Search items by id, name or barcode: Buscar articulos por identificador, nombre o codigo de barras
|
Search items by id, name or barcode: Buscar articulos por identificador, nombre o codigo de barras
|
||||||
SalesPerson: Comercial
|
SalesPerson: Comercial
|
||||||
Concept: Concepto
|
Concept: Concepto
|
||||||
|
Units/Box: Unidades/Caja
|
||||||
|
|
||||||
# Sections
|
# Sections
|
||||||
Items: Artículos
|
Items: Artículos
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('salePreparingList', {
|
||||||
|
description: 'Returns a list with the lines of a ticket and its different states of preparation',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'The ticket id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/salePreparingList`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.salePreparingList = async(ctx, id, options) => {
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
query = `CALL vn.salePreparingList(?)`;
|
||||||
|
const [sales] = await Self.rawSql(query, [id], myOptions);
|
||||||
|
|
||||||
|
return sales;
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/sale/getClaimableFromTicket')(Self);
|
require('../methods/sale/getClaimableFromTicket')(Self);
|
||||||
|
require('../methods/sale/salePreparingList')(Self);
|
||||||
require('../methods/sale/reserve')(Self);
|
require('../methods/sale/reserve')(Self);
|
||||||
require('../methods/sale/deleteSales')(Self);
|
require('../methods/sale/deleteSales')(Self);
|
||||||
require('../methods/sale/updatePrice')(Self);
|
require('../methods/sale/updatePrice')(Self);
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="SaleTrackings/listSaleTracking"
|
url="sales"
|
||||||
|
filter="::$ctrl.filter"
|
||||||
link="{ticketFk: $ctrl.$params.id}"
|
link="{ticketFk: $ctrl.$params.id}"
|
||||||
limit="20"
|
limit="20"
|
||||||
data="sales"
|
data="$ctrl.sales"
|
||||||
order="itemFk DESC"
|
order="concept ASC"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-data-viewer model="model">
|
<vn-data-viewer model="model">
|
||||||
|
@ -12,31 +13,27 @@
|
||||||
<vn-table model="model">
|
<vn-table model="model">
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th shrink></vn-th>
|
<vn-th field="isChecked" center>Is checked</vn-th>
|
||||||
<vn-th field="itemFk" number>Item</vn-th>
|
<vn-th field="itemFk" number>Item</vn-th>
|
||||||
<vn-th expand>Description</vn-th>
|
<vn-th field="concept">Description</vn-th>
|
||||||
<vn-th field="quantity" number>Quantity</vn-th>
|
<vn-th field="quantity" number>Quantity</vn-th>
|
||||||
<vn-th field="originalQuantity" number>Original</vn-th>
|
<vn-th></vn-th>
|
||||||
<vn-th field="workerFk">Worker</vn-th>
|
|
||||||
<vn-th field="state" shrink>State</vn-th>
|
|
||||||
<vn-th field="created" expand>Created</vn-th>
|
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
<vn-tr ng-repeat="sale in sales">
|
<vn-tr ng-repeat="sale in $ctrl.sales">
|
||||||
<vn-td shrink>
|
<vn-td center>
|
||||||
<vn-icon
|
<span class="chip {{$ctrl.chipHasSaleGroupDetail(sale.preparingList.hasSaleGroupDetail)}} vn-mx-xs chip2" vn-tooltip="has saleGroupDetail"></span>
|
||||||
class="bright"
|
<span class="chip {{$ctrl.chipIsPreviousSelected(sale.preparingList.isPreviousSelected)}} vn-ml-xs" vn-tooltip="is previousSelected"></span>
|
||||||
icon="warning"
|
<span class="chip {{$ctrl.chipIsPrevious(sale.preparingList.isPrevious)}} vn-mr-xs" vn-tooltip="is previous"></span>
|
||||||
ng-if="sale.quantity != sale.originalQuantity"
|
<span class="chip {{$ctrl.chipIsPrepared(sale.preparingList.isPrepared)}} vn-mx-xs" vn-tooltip="is prepared"></span>
|
||||||
vn-tooltip="The quantity do not match">
|
<span class="chip {{$ctrl.chipIsControled(sale.preparingList.isControled)}} vn-mx-xs" vn-tooltip="is controled"></span>
|
||||||
</vn-icon>
|
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td number>
|
<vn-td number>
|
||||||
<span
|
<span
|
||||||
ng-click="itemDescriptor.show($event, sale.itemFk, sale.id)"
|
ng-click="$ctrl.showItemDescriptor($event, sale)"
|
||||||
class="link">
|
class="link">
|
||||||
{{sale.itemFk | zeroFill:6}}
|
{{::sale.itemFk | zeroFill:6}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td vn-fetched-tags>
|
<vn-td vn-fetched-tags>
|
||||||
|
@ -52,6 +49,54 @@
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
</vn-fetched-tags>
|
</vn-fetched-tags>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
|
<vn-td number>{{::sale.quantity}}</vn-td>
|
||||||
|
<vn-td actions>
|
||||||
|
<vn-icon-button
|
||||||
|
vn-click-stop="$ctrl.showSaleTracking(sale)"
|
||||||
|
vn-tooltip="Sale tracking"
|
||||||
|
icon="history">
|
||||||
|
</vn-icon-button>
|
||||||
|
<vn-icon-button
|
||||||
|
vn-click-stop="$ctrl.showItemShelvingSale(sale)"
|
||||||
|
vn-tooltip="ItemShelvings sale"
|
||||||
|
icon="icon-inventory">
|
||||||
|
</vn-icon-button>
|
||||||
|
</vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
</vn-card>
|
||||||
|
</vn-data-viewer>
|
||||||
|
<vn-item-descriptor-popover
|
||||||
|
vn-id="item-descriptor"
|
||||||
|
warehouse-fk="$ctrl.ticket.warehouseFk"
|
||||||
|
ticket-fk="$ctrl.ticket.id">
|
||||||
|
</vn-item-descriptor-popover>
|
||||||
|
|
||||||
|
<vn-popup vn-id="saleTracking">
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="modelSaleTracking"
|
||||||
|
url="SaleTrackings/listSaleTracking"
|
||||||
|
link="{saleFk: $ctrl.saleId}"
|
||||||
|
limit="20"
|
||||||
|
data="saleTrackings"
|
||||||
|
order="itemFk DESC"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-data-viewer model="modelSaleTracking">
|
||||||
|
<vn-card class="vn-w-lg">
|
||||||
|
<vn-table model="modelSaleTracking">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th field="quantity" number>Quantity</vn-th>
|
||||||
|
<vn-th field="originalQuantity" number>Original</vn-th>
|
||||||
|
<vn-th field="workerFk">Worker</vn-th>
|
||||||
|
<vn-th field="state" shrink>State</vn-th>
|
||||||
|
<vn-th field="created" expand>Created</vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<vn-tr ng-repeat="sale in saleTrackings">
|
||||||
<vn-td number>{{::sale.quantity}}</vn-td>
|
<vn-td number>{{::sale.quantity}}</vn-td>
|
||||||
<vn-td number>{{::sale.originalQuantity}}</vn-td>
|
<vn-td number>{{::sale.originalQuantity}}</vn-td>
|
||||||
<vn-td expand>
|
<vn-td expand>
|
||||||
|
@ -75,3 +120,48 @@
|
||||||
<vn-worker-descriptor-popover
|
<vn-worker-descriptor-popover
|
||||||
vn-id="worker-descriptor">
|
vn-id="worker-descriptor">
|
||||||
</vn-worker-descriptor-popover>
|
</vn-worker-descriptor-popover>
|
||||||
|
</vn-popup>
|
||||||
|
|
||||||
|
<vn-popup vn-id="itemShelvingSale">
|
||||||
|
<vn-crud-model
|
||||||
|
vn-id="modelSaleTracking"
|
||||||
|
url="ItemShelvingSales/filter"
|
||||||
|
link="{saleFk: $ctrl.saleId}"
|
||||||
|
limit="20"
|
||||||
|
data="$ctrl.itemShelvingSales"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-data-viewer model="modelSaleTracking">
|
||||||
|
<vn-card class="vn-w-lg">
|
||||||
|
<vn-table model="modelSaleTracking">
|
||||||
|
<vn-thead>
|
||||||
|
<vn-tr>
|
||||||
|
<vn-th field="quantity" number>Quantity</vn-th>
|
||||||
|
<vn-th field="workerFk">Worker</vn-th>
|
||||||
|
<vn-th field="shelving" shrink>Shelving</vn-th>
|
||||||
|
<vn-th field="parking" shrink>Parking</vn-th>
|
||||||
|
<vn-th field="created" expand>Created</vn-th>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-thead>
|
||||||
|
<vn-tbody>
|
||||||
|
<vn-tr ng-repeat="itemShelvingSale in $ctrl.itemShelvingSales">
|
||||||
|
<vn-td number>{{::itemShelvingSale.quantity}}</vn-td>
|
||||||
|
<vn-td expand>
|
||||||
|
<span
|
||||||
|
class="link"
|
||||||
|
ng-click="workerDescriptor.show($event, itemShelvingSale.userFk)">
|
||||||
|
{{::itemShelvingSale.name | dashIfEmpty}}
|
||||||
|
</span>
|
||||||
|
</vn-td>
|
||||||
|
<vn-td shrink>{{::itemShelvingSale.shelvingFk}}</vn-td>
|
||||||
|
<vn-td shrink>{{::itemShelvingSale.code}}</vn-td>
|
||||||
|
<vn-td expand>{{::itemShelvingSale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
|
||||||
|
</vn-tr>
|
||||||
|
</vn-tbody>
|
||||||
|
</vn-table>
|
||||||
|
</vn-card>
|
||||||
|
</vn-data-viewer>
|
||||||
|
<vn-worker-descriptor-popover
|
||||||
|
vn-id="worker-descriptor">
|
||||||
|
</vn-worker-descriptor-popover>
|
||||||
|
</vn-popup>
|
||||||
|
|
|
@ -1,12 +1,100 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
class Controller extends Section {}
|
class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
this.filter = {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'item'
|
||||||
|
}, {
|
||||||
|
relation: 'saleTracking',
|
||||||
|
scope: {
|
||||||
|
fields: ['isChecked']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get sales() {
|
||||||
|
return this._sales;
|
||||||
|
}
|
||||||
|
|
||||||
|
set sales(value) {
|
||||||
|
this._sales = value;
|
||||||
|
if (value) {
|
||||||
|
const query = `Sales/${this.$params.id}/salePreparingList`;
|
||||||
|
this.$http.get(query)
|
||||||
|
.then(res => {
|
||||||
|
this.salePreparingList = res.data;
|
||||||
|
for (const salePreparing of this.salePreparingList) {
|
||||||
|
for (const sale of this.sales) {
|
||||||
|
if (salePreparing.saleFk == sale.id)
|
||||||
|
sale.preparingList = salePreparing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
showItemDescriptor(event, sale) {
|
||||||
|
this.quicklinks = {
|
||||||
|
btnThree: {
|
||||||
|
icon: 'icon-transaction',
|
||||||
|
state: `item.card.diary({
|
||||||
|
id: ${sale.itemFk},
|
||||||
|
warehouseFk: ${this.ticket.warehouseFk},
|
||||||
|
lineFk: ${sale.id}
|
||||||
|
})`,
|
||||||
|
tooltip: 'Item diary'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.$.itemDescriptor.show(event.target, sale.itemFk);
|
||||||
|
}
|
||||||
|
|
||||||
|
chipHasSaleGroupDetail(hasSaleGroupDetail) {
|
||||||
|
if (hasSaleGroupDetail) return 'pink';
|
||||||
|
else return 'message';
|
||||||
|
}
|
||||||
|
|
||||||
|
chipIsPreviousSelected(isPreviousSelected) {
|
||||||
|
if (isPreviousSelected) return 'notice';
|
||||||
|
else return 'message';
|
||||||
|
}
|
||||||
|
|
||||||
|
chipIsPrevious(isPrevious) {
|
||||||
|
if (isPrevious) return 'dark-notice';
|
||||||
|
else return 'message';
|
||||||
|
}
|
||||||
|
|
||||||
|
chipIsPrepared(isPrepared) {
|
||||||
|
if (isPrepared) return 'warning';
|
||||||
|
else return 'message';
|
||||||
|
}
|
||||||
|
|
||||||
|
chipIsControled(isControled) {
|
||||||
|
if (isControled) return 'yellow';
|
||||||
|
else return 'message';
|
||||||
|
}
|
||||||
|
|
||||||
|
showSaleTracking(sale) {
|
||||||
|
this.saleId = sale.id;
|
||||||
|
this.$.saleTracking.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
showItemShelvingSale(sale) {
|
||||||
|
this.saleId = sale.id;
|
||||||
|
this.$.itemShelvingSale.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnTicketSaleTracking', {
|
ngModule.vnComponent('vnTicketSaleTracking', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
ticket: '<',
|
ticket: '<'
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
ItemShelvings sale: Carros línea
|
||||||
|
has saleGroupDetail: tiene detalle grupo lineas
|
||||||
|
is previousSelected: es previa seleccionada
|
||||||
|
is previous: es previa
|
||||||
|
is prepared: esta preparado
|
||||||
|
is controled: esta controlado
|
|
@ -0,0 +1,7 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
.chip {
|
||||||
|
display: inline-block;
|
||||||
|
min-width: 15px;
|
||||||
|
min-height: 25px;
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
const ctx = {req: activeCtx, args: {}};
|
const ctx = {req: activeCtx, args: {}};
|
||||||
|
|
||||||
it('should fill time control of a worker without records in Journey and with rest', async() => {
|
it('should fill time control of a worker without records in Journey and with rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -34,6 +35,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker without records in Journey and without rest', async() => {
|
it('should fill time control of a worker without records in Journey and without rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const workdayOf20Hours = 3;
|
const workdayOf20Hours = 3;
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker with records in Journey and with rest', async() => {
|
it('should fill time control of a worker with records in Journey and with rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -92,6 +95,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker with records in Journey and without rest', async() => {
|
it('should fill time control of a worker with records in Journey and without rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -201,6 +201,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('WorkerTimeControl_clockIn calls', () => {
|
describe('WorkerTimeControl_clockIn calls', () => {
|
||||||
it('should fail to add a time entry if the target user has an absence that day', async() => {
|
it('should fail to add a time entry if the target user has an absence that day', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
@ -247,6 +248,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('direction errors', () => {
|
describe('direction errors', () => {
|
||||||
it('should throw an error when trying "in" direction twice', async() => {
|
it('should throw an error when trying "in" direction twice', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -276,6 +278,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => {
|
it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -309,6 +312,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should throw an error when trying "out" before closing a "middle" couple', async() => {
|
it('Should throw an error when trying "out" before closing a "middle" couple', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -342,6 +346,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "middle" after "out"', async() => {
|
it('should throw an error when trying "middle" after "out"', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -375,6 +380,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "out" direction twice', async() => {
|
it('should throw an error when trying "out" direction twice', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -446,6 +452,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail as the 12h rest is fulfilled', async() => {
|
it('should not fail as the 12h rest is fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -482,6 +489,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 3500kg drivers with enforced 9h rest', () => {
|
describe('for 3500kg drivers with enforced 9h rest', () => {
|
||||||
it('should throw an error when the 9h enforced rest is not fulfilled', async() => {
|
it('should throw an error when the 9h enforced rest is not fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = jessicaJonesId;
|
const workerId = jessicaJonesId;
|
||||||
|
|
||||||
|
@ -516,6 +524,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail when the 9h enforced rest is fulfilled', async() => {
|
it('should not fail when the 9h enforced rest is fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = jessicaJonesId;
|
const workerId = jessicaJonesId;
|
||||||
|
|
||||||
|
@ -552,6 +561,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 36h weekly rest', () => {
|
describe('for 36h weekly rest', () => {
|
||||||
it('should throw an error when the 36h weekly rest is not fulfilled', async() => {
|
it('should throw an error when the 36h weekly rest is not fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -586,6 +596,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when the 36h weekly rest is not fulfilled again', async() => {
|
it('should throw an error when the 36h weekly rest is not fulfilled again', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -619,6 +630,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 72h weekly rest', () => {
|
describe('for 72h weekly rest', () => {
|
||||||
it('should throw when the 72h weekly rest is not fulfilled yet', async() => {
|
it('should throw when the 72h weekly rest is not fulfilled yet', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue