Merge branch 'dev' into 3686-client_create
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
29f8fd1fc6
|
@ -0,0 +1,8 @@
|
||||||
|
CREATE TABLE `vn`.`claimConfig` (
|
||||||
|
`id` int(11) NOT NULL,
|
||||||
|
`pickupContact` varchar(250),
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO vn.claimConfig (id, pickupContact)
|
||||||
|
VALUES(1, 'Email: cmorenoa@logista.com Telf: 961594250 Extensión: 206');
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `vn`.`claimState` ADD `hasToNotify` TINYINT DEFAULT 0 NULL;
|
||||||
|
UPDATE `vn`.`claimState` SET `hasToNotify` = 1 WHERE `code` IN ('canceled', 'incomplete');
|
|
@ -812,25 +812,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
|
||||||
('VT', 'Sales');
|
('VT', 'Sales');
|
||||||
|
|
||||||
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
|
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`,
|
||||||
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`)
|
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V'),
|
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0, NULL, 'V', 0),
|
||||||
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H'),
|
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0, NULL, 'H', 0),
|
||||||
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL),
|
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0, NULL, NULL, 0),
|
||||||
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0, NULL, NULL, 0),
|
||||||
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0, NULL, NULL, 0),
|
||||||
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0, NULL, NULL, 0),
|
||||||
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0, NULL, NULL, 0),
|
||||||
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL, NULL),
|
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0, NULL, NULL, 0),
|
||||||
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL, NULL),
|
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 1, NULL, NULL, 0),
|
||||||
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0, NULL, NULL, 0),
|
||||||
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL, NULL),
|
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0, NULL, NULL, 0),
|
||||||
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL, NULL),
|
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0, NULL, NULL, 0),
|
||||||
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1, NULL, NULL),
|
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 1, 2, 'VT', 1, NULL, NULL, 1),
|
||||||
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL, NULL),
|
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1, NULL, NULL, 0),
|
||||||
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL),
|
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0),
|
||||||
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL),
|
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0, NULL, NULL, 0),
|
||||||
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL, NULL);
|
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0, NULL, NULL, 0);
|
||||||
|
|
||||||
-- Update the taxClass after insert of the items
|
-- Update the taxClass after insert of the items
|
||||||
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
|
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
|
||||||
|
@ -840,7 +840,7 @@ INSERT INTO `vn`.`priceFixed`(`id`, `itemFk`, `rate0`, `rate1`, `rate2`, `rate3`
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 0, 0, 2.5, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 0, 1, CURDATE()),
|
(1, 1, 0, 0, 2.5, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 0, 1, CURDATE()),
|
||||||
(2, 3, 10, 10, 10, 10, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 0, 1, CURDATE()),
|
(2, 3, 10, 10, 10, 10, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 0, 1, CURDATE()),
|
||||||
(3, 5, 8.5, 10, 7.5, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 1, 2, CURDATE());
|
(3, 13, 8.5, 10, 7.5, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL +1 MONTH), 1, 2, CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`expeditionBoxVol`(`boxFk`, `m3`, `ratio`)
|
INSERT INTO `vn`.`expeditionBoxVol`(`boxFk`, `m3`, `ratio`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1700,15 +1700,15 @@ INSERT INTO `vn`.`clientSample`(`id`, `clientFk`, `typeFk`, `created`, `workerFk
|
||||||
(4, 1102, 2, CURDATE(), 18, 18, 567),
|
(4, 1102, 2, CURDATE(), 18, 18, 567),
|
||||||
(5, 1102, 3, CURDATE(), 19, 19, 567);
|
(5, 1102, 3, CURDATE(), 19, 19, 567);
|
||||||
|
|
||||||
INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`)
|
INSERT INTO `vn`.`claimState`(`id`, `code`, `description`, `roleFk`, `priority`, `hasToNotify`)
|
||||||
VALUES
|
VALUES
|
||||||
( 1, 'pending', 'Pendiente', 1, 1),
|
( 1, 'pending', 'Pendiente', 1, 1, 0),
|
||||||
( 2, 'managed', 'Gestionado', 1, 5),
|
( 2, 'managed', 'Gestionado', 1, 5, 0),
|
||||||
( 3, 'resolved', 'Resuelto', 72, 7),
|
( 3, 'resolved', 'Resuelto', 72, 7, 0),
|
||||||
( 4, 'canceled', 'Anulado', 72, 6),
|
( 4, 'canceled', 'Anulado', 72, 6, 1),
|
||||||
( 5, 'incomplete', 'Incompleta', 72, 3),
|
( 5, 'incomplete', 'Incompleta', 72, 3, 1),
|
||||||
( 6, 'mana', 'Mana', 1, 4),
|
( 6, 'mana', 'Mana', 1, 4, 0),
|
||||||
( 7, 'lack', 'Faltas', 1, 2);
|
( 7, 'lack', 'Faltas', 1, 2, 0);
|
||||||
|
|
||||||
INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `observation`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`)
|
INSERT INTO `vn`.`claim`(`id`, `ticketCreated`, `claimStateFk`, `observation`, `clientFk`, `workerFk`, `responsibility`, `isChargedToMana`, `created`, `packages`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -346,16 +346,17 @@ export default {
|
||||||
saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button'
|
saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button'
|
||||||
},
|
},
|
||||||
itemFixedPrice: {
|
itemFixedPrice: {
|
||||||
add: 'vn-fixed-price vn-icon[icon="add_circle"]',
|
add: 'vn-fixed-price vn-icon-button[icon="add_circle"]',
|
||||||
fourthFixedPrice: 'vn-fixed-price vn-tr:nth-child(4)',
|
fourthFixedPrice: 'vn-fixed-price tr:nth-child(5)',
|
||||||
fourthItemID: 'vn-fixed-price vn-tr:nth-child(4) vn-autocomplete[ng-model="price.itemFk"]',
|
fourthItemID: 'vn-fixed-price tr:nth-child(5) vn-autocomplete[ng-model="price.itemFk"]',
|
||||||
fourthWarehouse: 'vn-fixed-price vn-tr:nth-child(4) vn-autocomplete[ng-model="price.warehouseFk"]',
|
fourthWarehouse: 'vn-fixed-price tr:nth-child(5) vn-autocomplete[ng-model="price.warehouseFk"]',
|
||||||
fourthPPU: 'vn-fixed-price vn-tr:nth-child(4) > vn-td-editable:nth-child(4)',
|
fourthPPU: 'vn-fixed-price tr:nth-child(5) > td:nth-child(4)',
|
||||||
fourthPPP: 'vn-fixed-price vn-tr:nth-child(4) > vn-td-editable:nth-child(5)',
|
fourthPPP: 'vn-fixed-price tr:nth-child(5) > td:nth-child(5)',
|
||||||
fourthMinPrice: 'vn-fixed-price vn-tr:nth-child(4) > vn-td-editable:nth-child(6)',
|
fourthHasMinPrice: 'vn-fixed-price tr:nth-child(5) > td:nth-child(6) > vn-check[ng-model="price.hasMinPrice"]',
|
||||||
fourthStarted: 'vn-fixed-price vn-tr:nth-child(4) vn-date-picker[ng-model="price.started"]',
|
fourthMinPrice: 'vn-fixed-price tr:nth-child(5) > td:nth-child(6) > vn-input-number[ng-model="price.minPrice"]',
|
||||||
fourthEnded: 'vn-fixed-price vn-tr:nth-child(4) vn-date-picker[ng-model="price.ended"]',
|
fourthStarted: 'vn-fixed-price tr:nth-child(5) vn-date-picker[ng-model="price.started"]',
|
||||||
fourthDeleteIcon: 'vn-fixed-price vn-tr:nth-child(4) > vn-td:nth-child(9) > vn-icon-button[icon="delete"]'
|
fourthEnded: 'vn-fixed-price tr:nth-child(5) vn-date-picker[ng-model="price.ended"]',
|
||||||
|
fourthDeleteIcon: 'vn-fixed-price tr:nth-child(5) > td:nth-child(9) > vn-icon-button[icon="delete"]'
|
||||||
},
|
},
|
||||||
itemCreateView: {
|
itemCreateView: {
|
||||||
temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
|
temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
|
||||||
|
|
|
@ -16,33 +16,17 @@ describe('Item fixed prices path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on the add new foxed price button', async() => {
|
it('should click on the add new foxed price button', async() => {
|
||||||
|
await page.doSearch();
|
||||||
await page.waitToClick(selectors.itemFixedPrice.add);
|
await page.waitToClick(selectors.itemFixedPrice.add);
|
||||||
await page.waitForSelector(selectors.itemFixedPrice.fourthFixedPrice);
|
await page.waitForSelector(selectors.itemFixedPrice.fourthFixedPrice);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill the fixed price data', async() => {
|
it('should fill the fixed price data', async() => {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const searchValue = 'Chest ammo box';
|
|
||||||
await page.waitToClick(selectors.itemFixedPrice.fourthItemID);
|
|
||||||
await page.write('body > div > div > div.content > div.filter.ng-scope > vn-textfield', searchValue);
|
|
||||||
try {
|
|
||||||
await page.waitForFunction(searchValue => {
|
|
||||||
const element = document.querySelector('li.active');
|
|
||||||
if (element)
|
|
||||||
return element.innerText.toLowerCase().includes(searchValue.toLowerCase());
|
|
||||||
}, {}, searchValue);
|
|
||||||
} catch (error) {
|
|
||||||
const builtSelector = await page.selectorFormater(selectors.ticketSales.moreMenuState);
|
|
||||||
const inputValue = await page.evaluate(() => {
|
|
||||||
return document.querySelector('.vn-drop-down.shown vn-textfield input').value;
|
|
||||||
});
|
|
||||||
throw new Error(`${builtSelector} value is ${inputValue}! ${error}`);
|
|
||||||
}
|
|
||||||
await page.keyboard.press('Enter');
|
|
||||||
await page.autocompleteSearch(selectors.itemFixedPrice.fourthWarehouse, 'Warehouse one');
|
await page.autocompleteSearch(selectors.itemFixedPrice.fourthWarehouse, 'Warehouse one');
|
||||||
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthPPU, '20');
|
await page.write(selectors.itemFixedPrice.fourthPPU, '1');
|
||||||
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthPPP, '10');
|
await page.write(selectors.itemFixedPrice.fourthPPP, '1');
|
||||||
await page.writeOnEditableTD(selectors.itemFixedPrice.fourthMinPrice, '5');
|
await page.write(selectors.itemFixedPrice.fourthMinPrice, '1');
|
||||||
await page.pickDate(selectors.itemFixedPrice.fourthStarted, now);
|
await page.pickDate(selectors.itemFixedPrice.fourthStarted, now);
|
||||||
await page.pickDate(selectors.itemFixedPrice.fourthEnded, now);
|
await page.pickDate(selectors.itemFixedPrice.fourthEnded, now);
|
||||||
const message = await page.waitForSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
@ -53,7 +37,9 @@ describe('Item fixed prices path', () => {
|
||||||
it('should reload the section and check the created price has the expected ID', async() => {
|
it('should reload the section and check the created price has the expected ID', async() => {
|
||||||
await page.accessToSection('item.index');
|
await page.accessToSection('item.index');
|
||||||
await page.accessToSection('item.fixedPrice');
|
await page.accessToSection('item.fixedPrice');
|
||||||
const result = await page.getProperty('vn-fixed-price > div > vn-card > vn-table > div > vn-tbody > vn-tr:nth-child(4) > vn-td:nth-child(1) > span', 'innerText');
|
await page.doSearch();
|
||||||
|
|
||||||
|
const result = await page.waitToGetProperty(selectors.itemFixedPrice.fourthItemID, 'value');
|
||||||
|
|
||||||
expect(result).toContain('13');
|
expect(result).toContain('13');
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,6 +32,9 @@ export default class SmartTable extends Component {
|
||||||
this._options = options;
|
this._options = options;
|
||||||
if (!options) return;
|
if (!options) return;
|
||||||
|
|
||||||
|
if (options.defaultSearch)
|
||||||
|
this.displaySearch();
|
||||||
|
|
||||||
const activeButtons = options.activeButtons;
|
const activeButtons = options.activeButtons;
|
||||||
const missingId = activeButtons && activeButtons.shownColumns && !this.viewConfigId;
|
const missingId = activeButtons && activeButtons.shownColumns && !this.viewConfigId;
|
||||||
if (missingId)
|
if (missingId)
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
"Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
"Sent units from ticket": "I sent *{{quantity}}* units of [{{concept}} ({{itemId}})]({{{itemUrl}}}) to *\"{{nickname}}\"* coming from ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
|
"Claim will be picked": "The product from the claim [({{claimId}})]({{{claimUrl}}}) from the client *{{clientName}}* will be picked",
|
||||||
"Claim state has changed to incomplete": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*",
|
"Claim state has changed to incomplete": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *incomplete*",
|
||||||
|
"Claim state has changed to canceled": "The state of the claim [({{claimId}})]({{{claimUrl}}}) from client *{{clientName}}* has changed to *canceled*",
|
||||||
"This ticket is not an stowaway anymore": "The ticket id [{{ticketId}}]({{{ticketUrl}}}) is not an stowaway anymore",
|
"This ticket is not an stowaway anymore": "The ticket id [{{ticketId}}]({{{ticketUrl}}}) is not an stowaway anymore",
|
||||||
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
"Customs agent is required for a non UEE member": "Customs agent is required for a non UEE member",
|
||||||
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
"Incoterms is required for a non UEE member": "Incoterms is required for a non UEE member",
|
||||||
|
|
|
@ -137,6 +137,7 @@
|
||||||
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
|
||||||
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*",
|
"Claim will be picked": "Se recogerá el género de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}*",
|
||||||
"Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*",
|
"Claim state has changed to incomplete": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *incompleta*",
|
||||||
|
"Claim state has changed to canceled": "Se ha cambiado el estado de la reclamación [({{claimId}})]({{{claimUrl}}}) del cliente *{{clientName}}* a *anulado*",
|
||||||
"This ticket is not an stowaway anymore": "El ticket id [{{ticketId}}]({{{ticketUrl}}}) ha dejado de ser un polizón",
|
"This ticket is not an stowaway anymore": "El ticket id [{{ticketId}}]({{{ticketUrl}}}) ha dejado de ser un polizón",
|
||||||
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
"Client checked as validated despite of duplication": "Cliente comprobado a pesar de que existe el cliente id {{clientId}}",
|
||||||
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
"ORDER_ROW_UNAVAILABLE": "No hay disponibilidad de este producto",
|
||||||
|
|
|
@ -47,7 +47,7 @@ describe('Update Claim', () => {
|
||||||
expect(error.message).toEqual(`You don't have enough privileges to change that field`);
|
expect(error.message).toEqual(`You don't have enough privileges to change that field`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should success to update the claim within privileges `, async() => {
|
it(`should success to update the claimState to 'canceled' and send a rocket message`, async() => {
|
||||||
const tx = await app.models.Claim.beginTransaction({});
|
const tx = await app.models.Claim.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -55,13 +55,15 @@ describe('Update Claim', () => {
|
||||||
|
|
||||||
const newClaim = await app.models.Claim.create(originalData, options);
|
const newClaim = await app.models.Claim.create(originalData, options);
|
||||||
|
|
||||||
|
const chatModel = app.models.Chat;
|
||||||
|
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
|
||||||
|
|
||||||
const canceledState = 4;
|
const canceledState = 4;
|
||||||
const claimManagerId = 72;
|
const claimManagerId = 72;
|
||||||
const ctx = {
|
const ctx = {
|
||||||
req: {
|
req: {
|
||||||
accessToken: {
|
accessToken: {userId: claimManagerId},
|
||||||
userId: claimManagerId
|
headers: {origin: 'http://localhost'}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
observation: 'valid observation',
|
observation: 'valid observation',
|
||||||
|
@ -69,11 +71,56 @@ describe('Update Claim', () => {
|
||||||
hasToPickUp: false
|
hasToPickUp: false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
ctx.req.__ = (value, params) => {
|
||||||
|
return params.nickname;
|
||||||
|
};
|
||||||
await app.models.Claim.updateClaim(ctx, newClaim.id, options);
|
await app.models.Claim.updateClaim(ctx, newClaim.id, options);
|
||||||
|
|
||||||
let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options);
|
let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options);
|
||||||
|
|
||||||
expect(updatedClaim.observation).toEqual(ctx.args.observation);
|
expect(updatedClaim.observation).toEqual(ctx.args.observation);
|
||||||
|
expect(chatModel.sendCheckingPresence).toHaveBeenCalled();
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should success to update the claimState to 'incomplete' and send a rocket message`, async() => {
|
||||||
|
const tx = await app.models.Claim.beginTransaction({});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const options = {transaction: tx};
|
||||||
|
|
||||||
|
const newClaim = await app.models.Claim.create(originalData, options);
|
||||||
|
|
||||||
|
const chatModel = app.models.Chat;
|
||||||
|
spyOn(chatModel, 'sendCheckingPresence').and.callThrough();
|
||||||
|
|
||||||
|
const incompleteState = 5;
|
||||||
|
const claimManagerId = 72;
|
||||||
|
const ctx = {
|
||||||
|
req: {
|
||||||
|
accessToken: {userId: claimManagerId},
|
||||||
|
headers: {origin: 'http://localhost'}
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
observation: 'valid observation',
|
||||||
|
claimStateFk: incompleteState,
|
||||||
|
hasToPickUp: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.req.__ = (value, params) => {
|
||||||
|
return params.nickname;
|
||||||
|
};
|
||||||
|
await app.models.Claim.updateClaim(ctx, newClaim.id, options);
|
||||||
|
|
||||||
|
let updatedClaim = await app.models.Claim.findById(newClaim.id, null, options);
|
||||||
|
|
||||||
|
expect(updatedClaim.observation).toEqual(ctx.args.observation);
|
||||||
|
expect(chatModel.sendCheckingPresence).toHaveBeenCalled();
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -96,9 +96,12 @@ module.exports = Self => {
|
||||||
// When claimState has been changed
|
// When claimState has been changed
|
||||||
if (args.claimStateFk) {
|
if (args.claimStateFk) {
|
||||||
const newState = await models.ClaimState.findById(args.claimStateFk, null, options);
|
const newState = await models.ClaimState.findById(args.claimStateFk, null, options);
|
||||||
|
if (newState.hasToNotify) {
|
||||||
if (newState.code == 'incomplete')
|
if (newState.code == 'incomplete')
|
||||||
notifyStateChange(ctx, salesPerson.id, claim);
|
notifyStateChange(ctx, salesPerson.id, claim, newState.code);
|
||||||
|
if (newState.code == 'canceled')
|
||||||
|
notifyStateChange(ctx, claim.workerFk, claim, newState.code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
@ -125,11 +128,12 @@ module.exports = Self => {
|
||||||
return canUpdate;
|
return canUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function notifyStateChange(ctx, workerId, claim) {
|
async function notifyStateChange(ctx, workerId, claim, state) {
|
||||||
const origin = ctx.req.headers.origin;
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
const origin = ctx.req.headers.origin;
|
||||||
const $t = ctx.req.__; // $translate
|
const $t = ctx.req.__; // $translate
|
||||||
const message = $t('Claim state has changed to incomplete', {
|
|
||||||
|
const message = $t(`Claim state has changed to ${state}`, {
|
||||||
claimId: claim.id,
|
claimId: claim.id,
|
||||||
clientName: claim.client().name,
|
clientName: claim.client().name,
|
||||||
claimUrl: `${origin}/#!/claim/${claim.id}/summary`
|
claimUrl: `${origin}/#!/claim/${claim.id}/summary`
|
||||||
|
|
|
@ -13,20 +13,24 @@
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "number",
|
||||||
"id": true,
|
"id": true,
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"code": {
|
"code": {
|
||||||
"type": "String",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "String",
|
"type": "string",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"priority": {
|
"priority": {
|
||||||
"type": "Number",
|
"type": "number",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"hasToNotify": {
|
||||||
|
"type": "boolean",
|
||||||
"required": true
|
"required": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,17 +39,25 @@ class Controller extends Descriptor {
|
||||||
loadData() {
|
loadData() {
|
||||||
const filter = {
|
const filter = {
|
||||||
include: [
|
include: [
|
||||||
{
|
{relation: 'supplier'},
|
||||||
relation: 'company',
|
{relation: 'invoiceInDueDay'},
|
||||||
|
{relation: 'company',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['id', 'code']
|
fields: ['id', 'code']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
return this.getData(`InvoiceIns/${this.id}`, {filter})
|
||||||
.then(res => this.entity = res.data);
|
.then(res => {
|
||||||
|
this.entity = res.data;
|
||||||
|
this.invoiceIn.amount = res.data.invoiceInDueDay.reduce(
|
||||||
|
(accumulator, currentValue) => {
|
||||||
|
return accumulator + (currentValue['amount'] || 0);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
checkToBook() {
|
checkToBook() {
|
||||||
|
|
|
@ -12,12 +12,25 @@ describe('vnInvoiceInDescriptor', () => {
|
||||||
|
|
||||||
controller = $componentController('vnInvoiceInDescriptor', {$element});
|
controller = $componentController('vnInvoiceInDescriptor', {$element});
|
||||||
controller.invoiceIn = {id: 1};
|
controller.invoiceIn = {id: 1};
|
||||||
$httpBackend.when('GET', `InvoiceIns/${controller.invoiceIn.id}`).respond({id: 1});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('loadData()', () => {
|
describe('loadData()', () => {
|
||||||
it(`should perform a get query to store the invoice in data into the controller`, () => {
|
it(`should perform a get query to store the invoice in data into the controller`, () => {
|
||||||
expect(controller.invoiceIn).toEqual({id: 1});
|
const invoiceIn = {
|
||||||
|
id: 1,
|
||||||
|
invoiceInDueDay: [
|
||||||
|
{amount: 1},
|
||||||
|
{amount: 2}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
const expectedAmount = invoiceIn.invoiceInDueDay[0].amount + invoiceIn.invoiceInDueDay[1].amount;
|
||||||
|
|
||||||
|
$httpBackend.when('GET', `InvoiceIns/${controller.invoiceIn.id}`).respond(invoiceIn);
|
||||||
|
controller.loadData();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.invoiceIn.id).toEqual(invoiceIn.id);
|
||||||
|
expect(controller.invoiceIn.amount).toEqual(expectedAmount);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ describe('fixed price filter()', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return no results filtering by hasMinPrice', async() => {
|
it('should return 1 result filtering by hasMinPrice', async() => {
|
||||||
const tx = await models.FixedPrice.beginTransaction({});
|
const tx = await models.FixedPrice.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -103,7 +103,7 @@ describe('fixed price filter()', () => {
|
||||||
};
|
};
|
||||||
const result = await models.FixedPrice.filter(ctx, null, options);
|
const result = await models.FixedPrice.filter(ctx, null, options);
|
||||||
|
|
||||||
expect(result.length).toEqual(0);
|
expect(result.length).toEqual(1);
|
||||||
|
|
||||||
await tx.rollback();
|
await tx.rollback();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
url="FixedPrices/filter"
|
url="FixedPrices/filter"
|
||||||
limit="20"
|
limit="20"
|
||||||
data="prices"
|
data="prices"
|
||||||
auto-load="true"
|
order="itemFk"
|
||||||
order="itemFk">
|
auto-load="false">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
auto-load="true"
|
auto-load="true"
|
||||||
|
@ -18,147 +18,166 @@
|
||||||
panel="vn-fixed-price-search-panel"
|
panel="vn-fixed-price-search-panel"
|
||||||
info="Search prices by item ID or code"
|
info="Search prices by item ID or code"
|
||||||
placeholder="Search fixed prices"
|
placeholder="Search fixed prices"
|
||||||
filter="{}"
|
|
||||||
model="model">
|
model="model">
|
||||||
</vn-searchbar>
|
</vn-searchbar>
|
||||||
</vn-portal>
|
</vn-portal>
|
||||||
<div class="vn-w-lg">
|
<div class="vn-w-xl">
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-table model="model">
|
<smart-table
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="itemFk" shrink>Item ID</vn-th>
|
|
||||||
<vn-th field="itemFk">Description</vn-th>
|
|
||||||
<vn-th field="warehouseFk">Warehouse</vn-th>
|
|
||||||
<vn-th field="rate2">P.P.U.</vn-th>
|
|
||||||
<vn-th field="rate3">P.P.P.</vn-th>
|
|
||||||
<vn-th field="minPrice">Min price</vn-th>
|
|
||||||
<vn-th field="started" style="width: 90px">Started</vn-th>
|
|
||||||
<vn-th field="ended" style="width: 90px">Ended</vn-th>
|
|
||||||
<vn-th shrink></vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="price in prices">
|
|
||||||
<vn-td shrink>
|
|
||||||
<span
|
|
||||||
ng-if="price.itemFk"
|
|
||||||
ng-click="itemDescriptor.show($event, price.itemFk)"
|
|
||||||
class="link">
|
|
||||||
{{price.itemFk}}
|
|
||||||
</span>
|
|
||||||
<vn-autocomplete
|
|
||||||
class="dense"
|
|
||||||
ng-if="!price.itemFk"
|
|
||||||
vn-focus
|
|
||||||
url="Items/withName"
|
|
||||||
ng-model="price.itemFk"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
search-function="$ctrl.itemSearchFunc($search)"
|
|
||||||
on-change="$ctrl.upsertPrice(price)"
|
|
||||||
order="id DESC"
|
|
||||||
tabindex="1">
|
|
||||||
<tpl-item>
|
|
||||||
{{::id}} - {{::name}}
|
|
||||||
</tpl-item>
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td vn-fetched-tags>
|
|
||||||
<div>
|
|
||||||
<vn-one title="{{price.name}}">{{price.name}}</vn-one>
|
|
||||||
<vn-one ng-if="price.subName">
|
|
||||||
<h3 title="{{price.subName}}">{{price.subName}}</h3>
|
|
||||||
</vn-one>
|
|
||||||
</div>
|
|
||||||
<vn-fetched-tags
|
|
||||||
max-length="6"
|
|
||||||
item="price"
|
|
||||||
tabindex="-1">
|
|
||||||
</vn-fetched-tags>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<vn-autocomplete
|
|
||||||
vn-one
|
|
||||||
label="Warehouse"
|
|
||||||
ng-model="price.warehouseFk"
|
|
||||||
url="Warehouses"
|
|
||||||
on-change="$ctrl.upsertPrice(price)"
|
|
||||||
tabindex="2">
|
|
||||||
</vn-autocomplete>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td-editable number>
|
|
||||||
<text>{{price.rate2 | currency: 'EUR':2}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number
|
|
||||||
class="dense"
|
|
||||||
vn-focus
|
|
||||||
ng-model="price.rate2"
|
|
||||||
on-change="$ctrl.upsertPrice(price)">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td-editable number>
|
|
||||||
<text>{{price.rate3 | currency: 'EUR':2}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number
|
|
||||||
class="dense"
|
|
||||||
vn-focus
|
|
||||||
ng-model="price.rate3"
|
|
||||||
on-change="$ctrl.upsertPrice(price)">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td-editable number>
|
|
||||||
<text>{{(price.hasMinPrice ? (price.minPrice | currency: 'EUR':2) : "-")}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number
|
|
||||||
class="dense"
|
|
||||||
vn-focus
|
|
||||||
ng-model="price.minPrice"
|
|
||||||
on-change="$ctrl.upsertPrice(price)"
|
|
||||||
step="0.01">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Started"
|
|
||||||
ng-model="price.started"
|
|
||||||
on-change="$ctrl.upsertPrice(price)">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<vn-date-picker
|
|
||||||
vn-one
|
|
||||||
label="Ended"
|
|
||||||
ng-model="price.ended"
|
|
||||||
on-change="$ctrl.upsertPrice(price)">
|
|
||||||
</vn-date-picker>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td shrink>
|
|
||||||
<vn-icon-button
|
|
||||||
icon="delete"
|
|
||||||
vn-tooltip="Delete"
|
|
||||||
ng-click="deleteFixedPrice.show({$index})">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
<div class="vn-pa-md">
|
|
||||||
<vn-icon-button
|
|
||||||
vn-tooltip="Add fixed price"
|
|
||||||
icon="add_circle"
|
|
||||||
vn-bind="+"
|
|
||||||
ng-click="model.insert()">
|
|
||||||
</vn-icon-button>
|
|
||||||
</div>
|
|
||||||
<vn-pagination
|
|
||||||
model="model"
|
model="model"
|
||||||
class="vn-pt-md">
|
options="$ctrl.smartTableOptions"
|
||||||
</vn-pagination>
|
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||||
|
<slot-table>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th field="itemFk">
|
||||||
|
<span translate>Item ID</span>
|
||||||
|
</th>
|
||||||
|
<th field="itemName">
|
||||||
|
<span translate>Description</span>
|
||||||
|
</th>
|
||||||
|
<th field="warehouseFk">
|
||||||
|
<span translate>Warehouse</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
field="rate2"
|
||||||
|
vn-tooltip="Price By Unit">
|
||||||
|
<span translate>P.P.U.</span>
|
||||||
|
</th>
|
||||||
|
<th
|
||||||
|
field="rate3"
|
||||||
|
vn-tooltip="Price By Package">
|
||||||
|
<span translate>P.P.P.</span>
|
||||||
|
</th>
|
||||||
|
<th field="minPrice">
|
||||||
|
<span translate>Min price</span>
|
||||||
|
</th>
|
||||||
|
<th field="started">
|
||||||
|
<span translate>Started</span>
|
||||||
|
</th>
|
||||||
|
<th field="ended">
|
||||||
|
<span translate>Ended</span>
|
||||||
|
</th>
|
||||||
|
<th shrink></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="price in prices">
|
||||||
|
<td shrink-field>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-focus
|
||||||
|
class="dense"
|
||||||
|
url="Items/withName"
|
||||||
|
ng-model="price.itemFk"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
search-function="$ctrl.itemSearchFunc($search)"
|
||||||
|
on-change="$ctrl.upsertPrice(price)"
|
||||||
|
order="id DESC"
|
||||||
|
tabindex="1">
|
||||||
|
<tpl-item>
|
||||||
|
<div>{{id}}</div>
|
||||||
|
<div class="text-caption text-secondary">
|
||||||
|
{{name}}
|
||||||
|
</div>
|
||||||
|
</tpl-item>
|
||||||
|
</vn-autocomplete>
|
||||||
|
</td>
|
||||||
|
<td vn-fetched-tags>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
vn-one
|
||||||
|
ng-if="price.itemFk"
|
||||||
|
ng-click="itemDescriptor.show($event, price.itemFk)"
|
||||||
|
class="link">
|
||||||
|
{{price.name}}
|
||||||
|
</span>
|
||||||
|
<vn-one ng-if="price.subName">
|
||||||
|
<h3 title="{{price.subName}}">{{price.subName}}</h3>
|
||||||
|
</vn-one>
|
||||||
|
</div>
|
||||||
|
<vn-fetched-tags
|
||||||
|
max-length="6"
|
||||||
|
item="price"
|
||||||
|
tabindex="-1">
|
||||||
|
</vn-fetched-tags>
|
||||||
|
</td>
|
||||||
|
<td shrink-field-expand>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
ng-model="price.warehouseFk"
|
||||||
|
data="warehouses"
|
||||||
|
on-change="$ctrl.upsertPrice(price)"
|
||||||
|
tabindex="2">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</td>
|
||||||
|
<td shrink-field>
|
||||||
|
<vn-input-number
|
||||||
|
ng-model="price.rate2"
|
||||||
|
on-change="$ctrl.upsertPrice(price)"
|
||||||
|
step="0.01">
|
||||||
|
</vn-input-number>
|
||||||
|
</td>
|
||||||
|
<td shrink-field>
|
||||||
|
<vn-input-number
|
||||||
|
ng-model="price.rate3"
|
||||||
|
on-change="$ctrl.upsertPrice(price)"
|
||||||
|
step="0.01">
|
||||||
|
</vn-input-number>
|
||||||
|
</td>
|
||||||
|
<td shrink-field-expand class="minPrice">
|
||||||
|
<vn-check
|
||||||
|
vn-one
|
||||||
|
ng-model="price.hasMinPrice">
|
||||||
|
</vn-check>
|
||||||
|
<vn-input-number
|
||||||
|
disabled="!price.hasMinPrice"
|
||||||
|
ng-model="price.minPrice"
|
||||||
|
on-change="$ctrl.upsertPrice(price)"
|
||||||
|
step="0.01">
|
||||||
|
</vn-input-number>
|
||||||
|
</td>
|
||||||
|
<td shrink-date>
|
||||||
|
<vn-date-picker
|
||||||
|
vn-one
|
||||||
|
ng-model="price.started"
|
||||||
|
on-change="$ctrl.upsertPrice(price)">
|
||||||
|
</vn-date-picker>
|
||||||
|
</td>
|
||||||
|
<td shrink-date>
|
||||||
|
<vn-date-picker
|
||||||
|
vn-one
|
||||||
|
ng-model="price.ended"
|
||||||
|
on-change="$ctrl.upsertPrice(price)">
|
||||||
|
</vn-date-picker>
|
||||||
|
</td>
|
||||||
|
<td shrink>
|
||||||
|
<vn-icon-button
|
||||||
|
icon="delete"
|
||||||
|
vn-tooltip="Delete"
|
||||||
|
ng-click="deleteFixedPrice.show({$index})">
|
||||||
|
</vn-icon-button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="vn-pa-md">
|
||||||
|
<vn-icon-button
|
||||||
|
vn-tooltip="Add fixed price"
|
||||||
|
icon="add_circle"
|
||||||
|
vn-bind="+"
|
||||||
|
ng-click="$ctrl.add()">
|
||||||
|
</vn-icon-button>
|
||||||
|
</div>
|
||||||
|
<vn-pagination
|
||||||
|
model="model"
|
||||||
|
class="vn-pt-md"
|
||||||
|
scroll-selector="vn-item-price-fixed vn-table"
|
||||||
|
scroll-offset="100">
|
||||||
|
</vn-pagination>
|
||||||
|
</slot-table>
|
||||||
|
</smart-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</div>
|
</div>
|
||||||
<vn-item-descriptor-popover
|
<vn-item-descriptor-popover
|
||||||
|
|
|
@ -5,13 +5,69 @@ import './style.scss';
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
|
|
||||||
|
this.smartTableOptions = {
|
||||||
|
activeButtons: {
|
||||||
|
search: true
|
||||||
|
},
|
||||||
|
defaultSearch: true,
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'itemName',
|
||||||
|
autocomplete: {
|
||||||
|
url: 'Items',
|
||||||
|
showField: 'name',
|
||||||
|
valueField: 'id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'warehouseFk',
|
||||||
|
autocomplete: {
|
||||||
|
url: 'Warehouses',
|
||||||
|
showField: 'name',
|
||||||
|
valueField: 'id',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'started',
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'ended',
|
||||||
|
searchable: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Inserts a new instance
|
|
||||||
*/
|
|
||||||
add() {
|
add() {
|
||||||
this.$.model.insert({});
|
if (!this.$.model.data || this.$.model.data.length == 0) {
|
||||||
|
this.$.model.data = [];
|
||||||
|
this.$.model.proxiedData = [];
|
||||||
|
this.$.model.insert({});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastIndex = this.$.model.data.length - 1;
|
||||||
|
const lastItem = this.$.model.data[lastIndex];
|
||||||
|
this.$.model.insert({
|
||||||
|
itemFk: lastItem.itemFk,
|
||||||
|
name: lastItem.name,
|
||||||
|
subName: lastItem.subName,
|
||||||
|
value5: lastItem.value5,
|
||||||
|
value6: lastItem.value6,
|
||||||
|
value7: lastItem.value7,
|
||||||
|
value8: lastItem.value8,
|
||||||
|
value9: lastItem.value9,
|
||||||
|
value10: lastItem.value10,
|
||||||
|
warehouseFk: lastItem.warehouseFk,
|
||||||
|
rate2: lastItem.rate2,
|
||||||
|
rate3: lastItem.rate3,
|
||||||
|
hasMinPrice: lastItem.hasMinPrice,
|
||||||
|
minPrice: lastItem.minPrice,
|
||||||
|
started: lastItem.started,
|
||||||
|
ended: lastItem.ended,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
upsertPrice(price) {
|
upsertPrice(price) {
|
||||||
|
@ -46,6 +102,22 @@ export default class Controller extends Section {
|
||||||
? {id: $search}
|
? {id: $search}
|
||||||
: {name: {like: '%' + $search + '%'}};
|
: {name: {like: '%' + $search + '%'}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exprBuilder(param, value) {
|
||||||
|
switch (param) {
|
||||||
|
case 'itemName':
|
||||||
|
return {'i.id': value};
|
||||||
|
case 'itemFk':
|
||||||
|
case 'warehouseFk':
|
||||||
|
case 'rate2':
|
||||||
|
case 'rate3':
|
||||||
|
param = `fp.${param}`;
|
||||||
|
return {[param]: value};
|
||||||
|
case 'minPrice':
|
||||||
|
param = `i.${param}`;
|
||||||
|
return {[param]: value};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnFixedPrice', {
|
ngModule.vnComponent('vnFixedPrice', {
|
||||||
|
|
|
@ -55,6 +55,8 @@ describe('fixed price', () => {
|
||||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
jest.spyOn(controller.$.model, 'remove');
|
jest.spyOn(controller.$.model, 'remove');
|
||||||
|
|
||||||
|
$httpBackend.expectGET('Warehouses').respond();
|
||||||
|
|
||||||
controller.removePrice($index);
|
controller.removePrice($index);
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).not.toHaveBeenCalled();
|
expect(controller.vnApp.showSuccess).not.toHaveBeenCalled();
|
||||||
|
|
|
@ -3,3 +3,5 @@ Search prices by item ID or code: Buscar por ID de artículo o código
|
||||||
Search fixed prices: Buscar precios fijados
|
Search fixed prices: Buscar precios fijados
|
||||||
Add fixed price: Añadir precio fijado
|
Add fixed price: Añadir precio fijado
|
||||||
This row will be removed: Esta linea se eliminará
|
This row will be removed: Esta linea se eliminará
|
||||||
|
Price By Unit: Precio Por Unidad
|
||||||
|
Price By Package: Precio Por Paquete
|
|
@ -1,5 +1,20 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
smart-table table{
|
||||||
vn-table vn-date-picker {
|
[shrink-field]{
|
||||||
max-width: 90px;
|
width: 80px;
|
||||||
|
max-width: 80px;
|
||||||
|
}
|
||||||
|
[shrink-field-expand]{
|
||||||
|
width: 150px;
|
||||||
|
max-width: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.minPrice {
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
vn-input-number {
|
||||||
|
width: 90px;
|
||||||
|
max-width: 90px;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -40,7 +40,8 @@ module.exports = Self => {
|
||||||
IFNULL(sc.workerSubstitute, c.salesPersonFk) AS salesPersonFk,
|
IFNULL(sc.workerSubstitute, c.salesPersonFk) AS salesPersonFk,
|
||||||
c.id AS clientFk,
|
c.id AS clientFk,
|
||||||
c.name AS clientName,
|
c.name AS clientName,
|
||||||
s.lastUpdate AS dated,
|
TIME(v.stamp) AS hour,
|
||||||
|
DATE(v.stamp) AS dated,
|
||||||
wtc.workerFk
|
wtc.workerFk
|
||||||
FROM hedera.userSession s
|
FROM hedera.userSession s
|
||||||
JOIN hedera.visitUser v ON v.id = s.userVisitFk
|
JOIN hedera.visitUser v ON v.id = s.userVisitFk
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="SalesMonitors/clientsFilter"
|
url="SalesMonitors/clientsFilter"
|
||||||
limit="6"
|
limit="6"
|
||||||
order="dated DESC"
|
filter="$ctrl.filter"
|
||||||
|
order="dated DESC, hour DESC"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-horizontal class="header">
|
<vn-horizontal class="header">
|
||||||
|
@ -15,54 +16,81 @@
|
||||||
vn-tooltip="Minimize/Maximize"
|
vn-tooltip="Minimize/Maximize"
|
||||||
ng-click="$ctrl.main.toggle()">
|
ng-click="$ctrl.main.toggle()">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-icon
|
|
||||||
icon="refresh"
|
|
||||||
vn-tooltip="Refresh"
|
|
||||||
ng-click="model.refresh()">
|
|
||||||
</vn-icon>
|
|
||||||
</vn-none>
|
</vn-none>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-card vn-id="card">
|
<vn-card vn-id="card">
|
||||||
<vn-table model="model" class="scrollable sm">
|
<smart-table
|
||||||
<vn-thead>
|
|
||||||
<vn-tr>
|
|
||||||
<vn-th field="dated">Hour</vn-th>
|
|
||||||
<vn-th field="salesPersonFk" class="expendable">Salesperson</vn-th>
|
|
||||||
<vn-th field="clientFk">Client</vn-th>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-thead>
|
|
||||||
<vn-tbody>
|
|
||||||
<vn-tr ng-repeat="visit in model.data">
|
|
||||||
<vn-td shrink-date>
|
|
||||||
<span class="chip">
|
|
||||||
{{::visit.dated | date: 'HH:mm'}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td class="shrink expendable">
|
|
||||||
<span
|
|
||||||
title="{{::visit.salesPerson}}"
|
|
||||||
vn-click-stop="workerDescriptor.show($event, visit.salesPersonFk)"
|
|
||||||
class="link">
|
|
||||||
{{::visit.salesPerson | dashIfEmpty}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
title="{{::visit.clientName}}"
|
|
||||||
vn-click-stop="clientDescriptor.show($event, visit.clientFk)"
|
|
||||||
class="link">
|
|
||||||
{{::visit.clientName}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
<vn-pagination
|
|
||||||
model="model"
|
model="model"
|
||||||
class="vn-pt-xs"
|
options="$ctrl.smartTableOptions"
|
||||||
scroll-selector="vn-monitor-sales-clients vn-table"
|
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||||
scroll-offset="100">
|
class="scrollable sm">
|
||||||
</vn-pagination>
|
<slot-actions>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-date-picker
|
||||||
|
class="vn-pa-xs"
|
||||||
|
label="From"
|
||||||
|
ng-model="$ctrl.dateFrom"
|
||||||
|
on-change="$ctrl.addFilterDate()">
|
||||||
|
</vn-date-picker>
|
||||||
|
<vn-date-picker
|
||||||
|
class="vn-pa-xs"
|
||||||
|
label="To"
|
||||||
|
ng-model="$ctrl.dateTo"
|
||||||
|
on-change="$ctrl.addFilterDate()">
|
||||||
|
</vn-date-picker>
|
||||||
|
</vn-horizontal>
|
||||||
|
</slot-actions>
|
||||||
|
<slot-table>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th field="dated">
|
||||||
|
<span translate>Date</span>
|
||||||
|
</th>
|
||||||
|
<th field="hour">
|
||||||
|
<span translate>Hour</span>
|
||||||
|
</th>
|
||||||
|
<th field="salesPersonFk" class="expendable">
|
||||||
|
<span translate>Salesperson</span>
|
||||||
|
</th>
|
||||||
|
<th field="clientFk">
|
||||||
|
<span translate>Client</span>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="visit in model.data">
|
||||||
|
<td shrink-date>
|
||||||
|
<span class="chip">
|
||||||
|
{{::visit.dated | date:'dd/MM/yy'}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td shrink-date>
|
||||||
|
<span class="chip">
|
||||||
|
{{::visit.hour | date: 'HH:mm'}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td class="shrink expendable">
|
||||||
|
<span
|
||||||
|
title="{{::visit.salesPerson}}"
|
||||||
|
vn-click-stop="workerDescriptor.show($event, visit.salesPersonFk)"
|
||||||
|
class="link">
|
||||||
|
{{::visit.salesPerson | dashIfEmpty}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
title="{{::visit.clientName}}"
|
||||||
|
vn-click-stop="clientDescriptor.show($event, visit.clientFk)"
|
||||||
|
class="link">
|
||||||
|
{{::visit.clientName}}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<table>
|
||||||
|
<slot-table>
|
||||||
|
</smart-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-worker-descriptor-popover
|
<vn-worker-descriptor-popover
|
||||||
vn-id="workerDescriptor">
|
vn-id="workerDescriptor">
|
||||||
|
@ -70,32 +98,3 @@
|
||||||
<vn-client-descriptor-popover
|
<vn-client-descriptor-popover
|
||||||
vn-id="clientDescriptor">
|
vn-id="clientDescriptor">
|
||||||
</vn-client-descriptor-popover>
|
</vn-client-descriptor-popover>
|
||||||
<vn-contextmenu vn-id="contextmenu" targets="['vn-monitor-sales-clients vn-table']" model="model"
|
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
|
||||||
<slot-menu>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.filterBySelection()">
|
|
||||||
Filter by selection
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.excludeSelection()">
|
|
||||||
Exclude selection
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isFilterAllowed()"
|
|
||||||
ng-click="contextmenu.removeFilter()">
|
|
||||||
Remove filter
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-click="contextmenu.removeAllFilters()">
|
|
||||||
Remove all filters
|
|
||||||
</vn-item>
|
|
||||||
<vn-item translate
|
|
||||||
ng-if="contextmenu.isActionAllowed()"
|
|
||||||
ng-click="contextmenu.copyValue()">
|
|
||||||
Copy value
|
|
||||||
</vn-item>
|
|
||||||
</slot-menu>
|
|
||||||
</vn-contextmenu>
|
|
|
@ -2,26 +2,89 @@ import ngModule from '../../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
|
||||||
export default class Controller extends Section {
|
export default class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
|
||||||
|
const date = new Date();
|
||||||
|
this.dateFrom = date;
|
||||||
|
this.dateTo = date;
|
||||||
|
this.filter = {
|
||||||
|
where: {
|
||||||
|
'v.stamp': {
|
||||||
|
between: this.dateRange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.smartTableOptions = {
|
||||||
|
activeButtons: {
|
||||||
|
search: true
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'clientFk',
|
||||||
|
autocomplete: {
|
||||||
|
url: 'Clients',
|
||||||
|
showField: 'name',
|
||||||
|
valueField: 'id'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'salesPersonFk',
|
||||||
|
autocomplete: {
|
||||||
|
url: 'Workers/activeWithInheritedRole',
|
||||||
|
where: `{role: 'salesPerson'}`,
|
||||||
|
searchFunction: '{firstName: $search}',
|
||||||
|
showField: 'nickname',
|
||||||
|
valueField: 'id',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'dated',
|
||||||
|
searchable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'hour',
|
||||||
|
searchable: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
exprBuilder(param, value) {
|
||||||
switch (param) {
|
switch (param) {
|
||||||
case 'dated':
|
|
||||||
return {'s.lastUpdate': {
|
|
||||||
between: this.dateRange(value)}
|
|
||||||
};
|
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
|
return {[`c.id`]: value};
|
||||||
case 'salesPersonFk':
|
case 'salesPersonFk':
|
||||||
return {[`c.${param}`]: value};
|
return {[`c.${param}`]: value};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dateRange(value) {
|
dateRange() {
|
||||||
const minHour = new Date(value);
|
let from = this.dateFrom;
|
||||||
|
let to = this.dateTo;
|
||||||
|
if (!from)
|
||||||
|
from = new Date();
|
||||||
|
if (!to)
|
||||||
|
to = new Date();
|
||||||
|
const minHour = new Date(from);
|
||||||
minHour.setHours(0, 0, 0, 0);
|
minHour.setHours(0, 0, 0, 0);
|
||||||
const maxHour = new Date(value);
|
const maxHour = new Date(to);
|
||||||
maxHour.setHours(23, 59, 59, 59);
|
maxHour.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
return [minHour, maxHour];
|
return [minHour, maxHour];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addFilterDate() {
|
||||||
|
this.$.model.filter = {
|
||||||
|
where: {
|
||||||
|
'v.stamp': {
|
||||||
|
between: this.dateRange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.$.model.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnMonitorSalesClients', {
|
ngModule.vnComponent('vnMonitorSalesClients', {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<vn-list>
|
<vn-list>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-if="!$ctrl.hasDocuwareFile"
|
ng-if="!$ctrl.hasDocuwareFile"
|
||||||
ng-click="$ctrl.showPdfDeliveryNote()"
|
ng-click="$ctrl.showPdfDeliveryNote('deliveryNote')"
|
||||||
translate>
|
translate>
|
||||||
as PDF
|
as PDF
|
||||||
</vn-item>
|
</vn-item>
|
||||||
|
@ -32,6 +32,12 @@
|
||||||
translate>
|
translate>
|
||||||
as PDF
|
as PDF
|
||||||
</a>
|
</a>
|
||||||
|
<vn-item
|
||||||
|
ng-if="!$ctrl.hasDocuwareFile"
|
||||||
|
ng-click="$ctrl.showPdfDeliveryNote('withoutPrices')"
|
||||||
|
translate>
|
||||||
|
as PDF without prices
|
||||||
|
</vn-item>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-click="$ctrl.showCsvDeliveryNote()"
|
ng-click="$ctrl.showCsvDeliveryNote()"
|
||||||
translate>
|
translate>
|
||||||
|
@ -44,7 +50,6 @@
|
||||||
vn-click-stop="sendDeliveryNoteMenu.show($event, 'left')"
|
vn-click-stop="sendDeliveryNoteMenu.show($event, 'left')"
|
||||||
translate>
|
translate>
|
||||||
Send Delivery Note...
|
Send Delivery Note...
|
||||||
|
|
||||||
<vn-menu vn-id="sendDeliveryNoteMenu">
|
<vn-menu vn-id="sendDeliveryNoteMenu">
|
||||||
<vn-list>
|
<vn-list>
|
||||||
<vn-item
|
<vn-item
|
||||||
|
@ -60,6 +65,11 @@
|
||||||
</vn-list>
|
</vn-list>
|
||||||
</vn-menu>
|
</vn-menu>
|
||||||
</vn-item>
|
</vn-item>
|
||||||
|
<vn-item
|
||||||
|
ng-click="$ctrl.showPdfDeliveryNote('proforma')"
|
||||||
|
translate>
|
||||||
|
Show Proforma
|
||||||
|
</vn-item>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-click="deleteConfirmation.show()"
|
ng-click="deleteConfirmation.show()"
|
||||||
ng-show="$ctrl.isEditable"
|
ng-show="$ctrl.isEditable"
|
||||||
|
|
|
@ -116,10 +116,11 @@ class Controller extends Section {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showPdfDeliveryNote() {
|
showPdfDeliveryNote(type) {
|
||||||
this.vnReport.show('delivery-note', {
|
this.vnReport.show('delivery-note', {
|
||||||
recipientId: this.ticket.client.id,
|
recipientId: this.ticket.client.id,
|
||||||
ticketId: this.id,
|
ticketId: this.id,
|
||||||
|
type: type
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,14 +122,15 @@ describe('Ticket Component vnTicketDescriptorMenu', () => {
|
||||||
describe('showPdfDeliveryNote()', () => {
|
describe('showPdfDeliveryNote()', () => {
|
||||||
it('should open a new window showing a delivery note PDF document', () => {
|
it('should open a new window showing a delivery note PDF document', () => {
|
||||||
jest.spyOn(window, 'open').mockReturnThis();
|
jest.spyOn(window, 'open').mockReturnThis();
|
||||||
|
const type = 'deliveryNote';
|
||||||
const expectedParams = {
|
const expectedParams = {
|
||||||
ticketId: ticket.id,
|
ticketId: ticket.id,
|
||||||
recipientId: ticket.client.id
|
recipientId: ticket.client.id,
|
||||||
|
type: type
|
||||||
};
|
};
|
||||||
const serializedParams = $httpParamSerializer(expectedParams);
|
const serializedParams = $httpParamSerializer(expectedParams);
|
||||||
const expectedPath = `api/report/delivery-note?${serializedParams}`;
|
const expectedPath = `api/report/delivery-note?${serializedParams}`;
|
||||||
controller.showPdfDeliveryNote();
|
controller.showPdfDeliveryNote(type);
|
||||||
|
|
||||||
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
expect(window.open).toHaveBeenCalledWith(expectedPath);
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,9 @@ Show Delivery Note...: Ver albarán...
|
||||||
Send Delivery Note...: Enviar albarán...
|
Send Delivery Note...: Enviar albarán...
|
||||||
as PDF: como PDF
|
as PDF: como PDF
|
||||||
as CSV: como CSV
|
as CSV: como CSV
|
||||||
|
as PDF without prices: como PDF sin precios
|
||||||
Send PDF: Enviar PDF
|
Send PDF: Enviar PDF
|
||||||
Send CSV: Enviar CSV
|
Send CSV: Enviar CSV
|
||||||
Send CSV Delivery Note: Enviar albarán en CSV
|
Send CSV Delivery Note: Enviar albarán en CSV
|
||||||
Send PDF Delivery Note: Enviar albarán en PDF
|
Send PDF Delivery Note: Enviar albarán en PDF
|
||||||
|
Show Proforma: Ver proforma
|
|
@ -80,6 +80,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p v-html="$t('sections.agency.description')"></p>
|
<p v-html="$t('sections.agency.description')"></p>
|
||||||
|
<p>{{claimConfig.pickupContact}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Footer block -->
|
<!-- Footer block -->
|
||||||
|
|
|
@ -7,6 +7,7 @@ module.exports = {
|
||||||
async serverPrefetch() {
|
async serverPrefetch() {
|
||||||
this.client = await this.fetchClient(this.claimId);
|
this.client = await this.fetchClient(this.claimId);
|
||||||
this.sales = await this.fetchSales(this.claimId);
|
this.sales = await this.fetchSales(this.claimId);
|
||||||
|
this.claimConfig = await this.fetchClaimConfig();
|
||||||
|
|
||||||
if (!this.client)
|
if (!this.client)
|
||||||
throw new Error('Something went wrong');
|
throw new Error('Something went wrong');
|
||||||
|
@ -25,6 +26,9 @@ module.exports = {
|
||||||
fetchSales(claimId) {
|
fetchSales(claimId) {
|
||||||
return this.rawSqlFromDef('sales', [claimId]);
|
return this.rawSqlFromDef('sales', [claimId]);
|
||||||
},
|
},
|
||||||
|
fetchClaimConfig() {
|
||||||
|
return this.findOneFromDef('claimConfig');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'report-header': reportHeader.build(),
|
'report-header': reportHeader.build(),
|
||||||
|
|
|
@ -14,4 +14,4 @@ phone: Teléfono
|
||||||
sections:
|
sections:
|
||||||
agency:
|
agency:
|
||||||
description: 'Para agilizar su recogida, por favor, póngase en contacto con la oficina
|
description: 'Para agilizar su recogida, por favor, póngase en contacto con la oficina
|
||||||
de Logista Parcel. <br/> Tlf: 96 166 77 88 - Ana Gómez (Ext. 2113) <em>(atcsalidas.i2valencia@integra2.es)</em>'
|
de Logista Parcel.'
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
SELECT pickupContact
|
||||||
|
FROM claimConfig;
|
|
@ -15,7 +15,7 @@
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="size50">
|
<div class="size50">
|
||||||
<div class="size75 vn-mt-ml">
|
<div class="size75 vn-mt-ml">
|
||||||
<h1 class="title uppercase">{{$t('title')}}</h1>
|
<h1 class="title uppercase">{{$t(type)}}</h1>
|
||||||
<table class="row-oriented ticket-info">
|
<table class="row-oriented ticket-info">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
<th>{{client.id}}</th>
|
<th>{{client.id}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font gray uppercase">{{$t('ticketId')}}</td>
|
<td class="font gray uppercase">{{$t(type)}}</td>
|
||||||
<th>{{ticket.id}}</th>
|
<th>{{ticket.id}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -77,10 +77,10 @@
|
||||||
<th width="5%">{{$t('reference')}}</th>
|
<th width="5%">{{$t('reference')}}</th>
|
||||||
<th class="number">{{$t('quantity')}}</th>
|
<th class="number">{{$t('quantity')}}</th>
|
||||||
<th width="50%">{{$t('concept')}}</th>
|
<th width="50%">{{$t('concept')}}</th>
|
||||||
<th class="number">{{$t('price')}}</th>
|
<th class="number" v-if="showPrices">{{$t('price')}}</th>
|
||||||
<th class="centered" width="5%">{{$t('discount')}}</th>
|
<th class="centered" width="5%" v-if="showPrices">{{$t('discount')}}</th>
|
||||||
<th class="centered">{{$t('vat')}}</th>
|
<th class="centered" v-if="showPrices">{{$t('vat')}}</th>
|
||||||
<th class="number">{{$t('amount')}}</th>
|
<th class="number" v-if="showPrices">{{$t('amount')}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody v-for="sale in sales" class="no-page-break">
|
<tbody v-for="sale in sales" class="no-page-break">
|
||||||
|
@ -88,10 +88,10 @@
|
||||||
<td width="5%">{{sale.itemFk | zerofill('000000')}}</td>
|
<td width="5%">{{sale.itemFk | zerofill('000000')}}</td>
|
||||||
<td class="number">{{sale.quantity}}</td>
|
<td class="number">{{sale.quantity}}</td>
|
||||||
<td width="50%">{{sale.concept}}</td>
|
<td width="50%">{{sale.concept}}</td>
|
||||||
<td class="number">{{sale.price | currency('EUR', $i18n.locale)}}</td>
|
<td class="number" v-if="showPrices">{{sale.price | currency('EUR', $i18n.locale)}}</td>
|
||||||
<td class="centered" width="5%">{{(sale.discount / 100) | percentage}}</td>
|
<td class="centered" width="5%" v-if="showPrices">{{(sale.discount / 100) | percentage}}</td>
|
||||||
<td class="centered">{{sale.vatType}}</td>
|
<td class="centered" v-if="showPrices">{{sale.vatType}}</td>
|
||||||
<td class="number">{{sale.price * sale.quantity * (1 - sale.discount / 100) | currency('EUR', $i18n.locale)}}</td>
|
<td class="number" v-if="showPrices">{{sale.price * sale.quantity * (1 - sale.discount / 100) | currency('EUR', $i18n.locale)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="description font light-gray">
|
<tr class="description font light-gray">
|
||||||
<td colspan="7">
|
<td colspan="7">
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot v-if="showPrices">
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="font bold">
|
<td colspan="6" class="font bold">
|
||||||
<span class="pull-right">{{$t('subtotal')}}</span>
|
<span class="pull-right">{{$t('subtotal')}}</span>
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
</div>
|
</div>
|
||||||
<!-- End of packages block -->
|
<!-- End of packages block -->
|
||||||
</div>
|
</div>
|
||||||
<div class="columns vn-mt-xl">
|
<div class="columns vn-mt-xl" v-if="showPrices">
|
||||||
<!-- Taxes block -->
|
<!-- Taxes block -->
|
||||||
<div id="taxes" class="size50 pull-right no-page-break" v-if="taxes">
|
<div id="taxes" class="size50 pull-right no-page-break" v-if="taxes">
|
||||||
<table class="column-oriented">
|
<table class="column-oriented">
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
<!-- Footer block -->
|
<!-- Footer block -->
|
||||||
<report-footer id="pageFooter"
|
<report-footer id="pageFooter"
|
||||||
v-bind:company-code="ticket.companyCode"
|
v-bind:company-code="ticket.companyCode"
|
||||||
v-bind:left-text="$t('ticket', [ticket.id])"
|
v-bind:left-text="footerType"
|
||||||
v-bind:center-text="client.socialName"
|
v-bind:center-text="client.socialName"
|
||||||
v-bind="$props">
|
v-bind="$props">
|
||||||
</report-footer>
|
</report-footer>
|
||||||
|
|
|
@ -44,6 +44,13 @@ module.exports = {
|
||||||
});
|
});
|
||||||
|
|
||||||
return total;
|
return total;
|
||||||
|
},
|
||||||
|
showPrices() {
|
||||||
|
return this.type != 'withoutPrices';
|
||||||
|
},
|
||||||
|
footerType() {
|
||||||
|
const translatedType = this.$t(this.type);
|
||||||
|
return `${translatedType} ${this.ticketId}`;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -119,6 +126,10 @@ module.exports = {
|
||||||
ticketId: {
|
ticketId: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
reportName: delivery-note
|
reportName: delivery-note
|
||||||
title: Delivery note
|
deliveryNote: Delivery note
|
||||||
ticketId: Delivery note
|
proforma: Proforma
|
||||||
|
withoutPrices: Delivery note
|
||||||
clientId: Client
|
clientId: Client
|
||||||
deliveryAddress: Delivery address
|
deliveryAddress: Delivery address
|
||||||
fiscalData: Fiscal data
|
fiscalData: Fiscal data
|
||||||
|
@ -17,7 +18,6 @@ total: Total
|
||||||
subtotal: Subtotal
|
subtotal: Subtotal
|
||||||
vatType: VAT Type
|
vatType: VAT Type
|
||||||
digitalSignature: Digital signature
|
digitalSignature: Digital signature
|
||||||
ticket: Delivery note {0}
|
|
||||||
plantPassport: Plant passport
|
plantPassport: Plant passport
|
||||||
packages: Packages
|
packages: Packages
|
||||||
services:
|
services:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
reportName: albaran
|
reportName: albaran
|
||||||
title: Albarán
|
deliveryNote: Albarán
|
||||||
ticketId: Albarán
|
proforma: Proforma
|
||||||
|
withoutPrices: Albarán
|
||||||
clientId: Cliente
|
clientId: Cliente
|
||||||
deliveryAddress: Dirección de entrega
|
deliveryAddress: Dirección de entrega
|
||||||
fiscalData: Datos fiscales
|
fiscalData: Datos fiscales
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
reportName: bon-de-livraison
|
reportName: bon-de-livraison
|
||||||
title: Bon de livraison
|
deliveryNote: Bon de livraison
|
||||||
ticketId: BL
|
proforma: Proforma
|
||||||
|
withoutPrices: Bon de livraison
|
||||||
clientId: Client
|
clientId: Client
|
||||||
deliveryAddress: Adresse de livraison
|
deliveryAddress: Adresse de livraison
|
||||||
fiscalData: Coordonnées
|
fiscalData: Coordonnées
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
reportName: nota-de-entrega
|
reportName: nota-de-entrega
|
||||||
title: Nota de Entrega
|
deliveryNote: Nota de Entrega
|
||||||
ticketId: Nota de Entrega
|
proforma: Proforma
|
||||||
|
withoutPrices: Nota de Entrega
|
||||||
clientId: Cliente
|
clientId: Cliente
|
||||||
deliveryAddress: Morada de Entrega
|
deliveryAddress: Morada de Entrega
|
||||||
fiscalData: Dados Fiscais
|
fiscalData: Dados Fiscais
|
||||||
|
|
Loading…
Reference in New Issue