This commit is contained in:
Carlos Jimenez Ruiz 2019-11-12 08:52:07 +01:00
commit d284e36ee6
36 changed files with 270 additions and 149 deletions

View File

@ -0,0 +1,119 @@
USE `vn`;
DROP procedure IF EXISTS `itemDiary`;
DELIMITER $$
USE `vn`$$
CREATE DEFINER=`root`@`%` PROCEDURE `itemDiary`(IN vItemId INT, IN vWarehouse INT)
BEGIN
DECLARE vDateInventory DATETIME;
DECLARE vCurdate DATE DEFAULT CURDATE();
DECLARE vDayEnd DATETIME DEFAULT util.dayEnd(vCurdate);
-- traduccion: date, alertLevel, origin, reference, name, In, Out, Balance
SELECT Fechainventario INTO vDateInventory FROM vn2008.tblContadores;
SET @a = 0;
SELECT DATE(date) AS date,
alertLevel,
stateName,
origin,
reference,
clientFk,
name,
`in`,
`out`,
@a := @a + IFNULL(`in`,0) - IFNULL(`out`,0) as balance,
isPicked,
isTicket
FROM
( SELECT tr.landed as date,
b.quantity as `in`,
NULL as `out`,
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
st.name AS stateName,
s.name as name,
e.ref as reference,
e.id as origin,
s.id as clientFk,
TRUE isPicked,
FALSE AS isTicket
FROM vn.buy b
JOIN vn.entry e ON e.id = b.entryFk
JOIN vn.travel tr ON tr.id = e.travelFk
JOIN vn.supplier s ON s.id = e.supplierFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN tr.isReceived != FALSE THEN 3
WHEN tr.isDelivered THEN 1
ELSE 0
END
JOIN vn.state st ON st.code = al.code
WHERE tr.landed >= vDateInventory
AND vWarehouse = tr.warehouseInFk
AND b.itemFk = vItemId
AND e.isInventory = 0
AND e.isRaid = 0
UNION ALL
SELECT tr.shipped as date,
NULL as `in`,
b.quantity as `out`,
IF(tr.isReceived != FALSE,3, IF(tr.isDelivered,1,0)) as alertLevel,
st.name AS stateName,
s.name as name,
e.ref as reference,
e.id as origin,
s.id as clientFk,
TRUE isPicked,
FALSE AS isTicket
FROM vn.buy b
JOIN vn.entry e ON e.id = b.entryFk
JOIN vn.travel tr ON tr.id = e.travelFk
JOIN vn.warehouse w ON w.id = tr.warehouseOutFk
JOIN vn.supplier s ON s.id = e.supplierFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN tr.isReceived != FALSE THEN 3
WHEN tr.isDelivered THEN 1
ELSE 0
END
JOIN vn.state st ON st.code = al.code
WHERE tr.shipped >= vDateInventory
AND vWarehouse =tr.warehouseOutFk
AND s.id <> 4
AND b.itemFk = vItemId
AND e.isInventory = 0
AND w.isFeedStock = 0
AND e.isRaid = 0
UNION ALL
SELECT t.shipped as date,
NULL as `in`,
s.quantity as `out`,
al.alertLevel as alertLevel,
st.name AS stateName,
t.nickname as name,
t.refFk as reference,
t.id as origin,
t.clientFk,
stk.id as isPicked, -- TRUE as isPicked
TRUE as isTicket
FROM vn.sale s
JOIN vn.ticket t ON t.id = s.ticketFk
LEFT JOIN vn.ticketState ts ON ts.ticket = t.id
LEFT JOIN vn.state st ON st.code = ts.code
JOIN vn.client c ON c.id = t.clientFk
JOIN vn.alertLevel al ON al.alertLevel =
CASE
WHEN t.shipped < vCurdate THEN 3
WHEN t.shipped > vDayEnd THEN 0
ELSE IFNULL(ts.alertLevel, 0)
END
LEFT JOIN vn.saleTracking stk ON stk.saleFk = s.id AND stk.stateFk = 14 -- comentar
WHERE t.shipped >= vDateInventory
AND s.itemFk = vItemId
AND vWarehouse =t.warehouseFk
) AS itemDiary
ORDER BY date, isTicket, alertLevel DESC, isPicked DESC, `in` DESC, `out` DESC;
END$$
DELIMITER ;

View File

@ -185,26 +185,27 @@ let actions = {
isVisible: function(selector) { isVisible: function(selector) {
return this.wait(selector) return this.wait(selector)
.evaluate(elementSelector => { .evaluate(elementSelector => {
const selectorMatches = document.querySelectorAll(elementSelector); let selectorMatches = document.querySelectorAll(elementSelector);
const element = selectorMatches[0]; let element = selectorMatches[0];
if (selectorMatches.length > 1) if (selectorMatches.length > 1)
throw new Error(`multiple matches of ${elementSelector} found`); throw new Error(`multiple matches of ${elementSelector} found`);
let isVisible = false; let isVisible = false;
if (element) { if (element) {
const eventHandler = event => { let eventHandler = event => {
event.preventDefault(); event.preventDefault();
isVisible = true; isVisible = true;
}; };
element.addEventListener('mouseover', eventHandler); element.addEventListener('mouseover', eventHandler);
const rect = element.getBoundingClientRect(); let rect = element.getBoundingClientRect();
const x = rect.left + rect.width / 2; let x = rect.left + rect.width / 2;
const y = rect.top + rect.height / 2; let y = rect.top + rect.height / 2;
const elementInCenter = document.elementFromPoint(x, y); let elementInCenter = document.elementFromPoint(x, y);
const elementInTopLeft = document.elementFromPoint(rect.left, rect.top); let elementInTopLeft = document.elementFromPoint(rect.left, rect.top);
const elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom); let elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom);
const e = new MouseEvent('mouseover', {
let e = new MouseEvent('mouseover', {
view: window, view: window,
bubbles: true, bubbles: true,
cancelable: true, cancelable: true,
@ -420,9 +421,19 @@ let actions = {
}, selector); }, selector);
}, },
waitForSpinnerLoad: function() { waitForStylePresent: function(selector, property, value) {
return this.waitForClassNotPresent('vn-spinner > div', 'is-active'); return this.wait((selector, property, value) => {
const element = document.querySelector(selector);
return element.style[property] == value;
}, selector, property, value);
}, },
waitForSpinnerLoad: function() {
return this.wait(() => {
const element = document.querySelector('vn-spinner > div');
return element.style.display == 'none';
});
}
}; };
for (let name in actions) { for (let name in actions) {

View File

@ -191,7 +191,8 @@ export default {
closeItemSummaryPreview: '.vn-popup.shown', closeItemSummaryPreview: '.vn-popup.shown',
fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]', fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]',
fieldsToShowForm: '.vn-dialog.shown form', fieldsToShowForm: '.vn-dialog.shown form',
firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1)', firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > img',
firstItemImageTd: 'vn-item-index vn-table a:nth-child(1) vn-td:nth-child(1)',
firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)', firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check', idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check',
stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check', stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check',
@ -367,7 +368,6 @@ export default {
shipButton: 'vn-ticket-descriptor vn-icon[icon="icon-stowaway"]', shipButton: 'vn-ticket-descriptor vn-icon[icon="icon-stowaway"]',
thursdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(4)', thursdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(4)',
saturdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(6)', saturdayButton: '.vn-popup.shown vn-tool-bar > vn-button:nth-child(6)',
closeStowawayDialog: '.vn-dialog.shown button[class="close"]',
acceptDeleteButton: '.vn-dialog.shown button[response="accept"]', acceptDeleteButton: '.vn-dialog.shown button[response="accept"]',
acceptChangeHourButton: '.vn-dialog.shown button[response="accept"]', acceptChangeHourButton: '.vn-dialog.shown button[response="accept"]',
descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span', descriptorDeliveryDate: 'vn-ticket-descriptor > div > div.body > div.attributes > vn-label-value:nth-child(6) > section > span',
@ -441,7 +441,7 @@ export default {
secondSaleIdInput: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete input', secondSaleIdInput: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete input',
secondSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete', secondSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(4) > vn-autocomplete',
secondSaleQuantity: 'vn-ticket-sale vn-table vn-tr:nth-child(2) vn-input-number input', secondSaleQuantity: 'vn-ticket-sale vn-table vn-tr:nth-child(2) vn-input-number input',
secondSaleConceptCell: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(6)', secondSaleConceptCell: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(2) > vn-td-editable:nth-child(6) > div',
secondSaleConceptInput: 'vn-ticket-sale vn-table vn-tr:nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield input', secondSaleConceptInput: 'vn-ticket-sale vn-table vn-tr:nth-child(2) > vn-td-editable.ng-isolate-scope.selected vn-textfield input',
totalImport: 'vn-ticket-sale > vn-vertical > vn-card > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong', totalImport: 'vn-ticket-sale > vn-vertical > vn-card > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong',
selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check', selectAllSalesCheckbox: 'vn-ticket-sale vn-thead vn-check',

View File

@ -138,6 +138,7 @@ describe('Client Edit fiscalData path', () => {
it(`should click on the 1st edit icon to confirm EQtax is checked`, async() => { it(`should click on the 1st edit icon to confirm EQtax is checked`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.clientAddresses.firstEditAddress) .waitToClick(selectors.clientAddresses.firstEditAddress)
.waitForSpinnerLoad()
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
expect(result).toBe('checked'); expect(result).toBe('checked');
@ -148,6 +149,7 @@ describe('Client Edit fiscalData path', () => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.clientAddresses.addressesButton) .waitToClick(selectors.clientAddresses.addressesButton)
.waitToClick(selectors.clientAddresses.secondEditAddress) .waitToClick(selectors.clientAddresses.secondEditAddress)
.waitForSpinnerLoad()
.checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox);
expect(result).toBe('checked'); expect(result).toBe('checked');
@ -293,6 +295,7 @@ describe('Client Edit fiscalData path', () => {
it(`should click on the 1st edit icon to access the address details and uncheck EQtax checkbox`, async() => { it(`should click on the 1st edit icon to access the address details and uncheck EQtax checkbox`, async() => {
const result = await nightmare const result = await nightmare
.waitToClick(selectors.clientAddresses.firstEditAddress) .waitToClick(selectors.clientAddresses.firstEditAddress)
.waitForTextInInput(selectors.clientAddresses.cityInput, 'Silla')
.waitToClick(selectors.clientAddresses.equalizationTaxCheckbox) .waitToClick(selectors.clientAddresses.equalizationTaxCheckbox)
.waitToClick(selectors.clientAddresses.saveButton) .waitToClick(selectors.clientAddresses.saveButton)
.waitForLastSnackbar(); .waitForLastSnackbar();

View File

@ -28,7 +28,7 @@ describe('Client add address notes path', () => {
.waitToClick(selectors.clientAddresses.saveButton) .waitToClick(selectors.clientAddresses.saveButton)
.waitForLastSnackbar(); .waitForLastSnackbar();
expect(result).toEqual('Observation type cannot be blank'); expect(result).toEqual('Some fields are invalid');
}); });
it('should not save an observation type without description', async() => { it('should not save an observation type without description', async() => {

View File

@ -13,6 +13,7 @@ describe('Item create niche path', () => {
it(`should click create a new niche and delete a former one`, async() => { it(`should click create a new niche and delete a former one`, async() => {
const result = await nightmare const result = await nightmare
.waitForTextInInput(`${selectors.itemNiches.firstWarehouseAutocomplete} input`, 'Warehouse One')
.waitToClick(selectors.itemNiches.addNicheButton) .waitToClick(selectors.itemNiches.addNicheButton)
.waitToClick(selectors.itemNiches.secondNicheRemoveButton) .waitToClick(selectors.itemNiches.secondNicheRemoveButton)
.autocompleteSearch(selectors.itemNiches.thirdWarehouseAutocomplete, 'Warehouse Two') .autocompleteSearch(selectors.itemNiches.thirdWarehouseAutocomplete, 'Warehouse Two')

View File

@ -27,7 +27,7 @@ describe('Item regularize path', () => {
expect(userLocalWarehouse).toContain('Warehouse Four'); expect(userLocalWarehouse).toContain('Warehouse Four');
}); });
it('should search for the item', async() => { it('should search for an item', async() => {
const resultCount = await nightmare const resultCount = await nightmare
.clearInput(selectors.itemsIndex.searchItemInput) .clearInput(selectors.itemsIndex.searchItemInput)
.write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm') .write(selectors.itemsIndex.searchItemInput, 'Ranged weapon pistol 9mm')

View File

@ -42,7 +42,8 @@ describe('Item index path', () => {
.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton) .waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton)
.waitToClick(selectors.itemsIndex.searchIcon) .waitToClick(selectors.itemsIndex.searchIcon)
.wait(selectors.itemsIndex.searchResult) .wait(selectors.itemsIndex.searchResult)
.isVisible(selectors.itemsIndex.firstItemImage); .waitImgLoad(selectors.itemsIndex.firstItemImage)
.isVisible(selectors.itemsIndex.firstItemImageTd);
expect(imageVisible).toBeTruthy(); expect(imageVisible).toBeTruthy();
}); });

View File

@ -57,8 +57,8 @@ describe('Ticket List sale path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
// #1865
it('should update the description of the new sale', async() => { xit('should update the description of the new sale', async() => {
const result = await nightmare const result = await nightmare
.focusElement(selectors.ticketSales.secondSaleConceptCell) .focusElement(selectors.ticketSales.secondSaleConceptCell)
.write(selectors.ticketSales.secondSaleConceptInput, 'Aegis of Valor\u000d') .write(selectors.ticketSales.secondSaleConceptInput, 'Aegis of Valor\u000d')

View File

@ -101,7 +101,10 @@ describe('Ticket descriptor path', () => {
it('should open the add stowaway dialog', async() => { it('should open the add stowaway dialog', async() => {
const isVisible = await nightmare const isVisible = await nightmare
.waitForSpinnerLoad() .wait(() => {
let element = document.querySelector('vn-ticket-descriptor');
return element.$ctrl.canShowStowaway === true;
})
.waitToClick(selectors.ticketDescriptor.moreMenu) .waitToClick(selectors.ticketDescriptor.moreMenu)
.waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway) .waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway)
.wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket) .wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket)
@ -127,7 +130,6 @@ describe('Ticket descriptor path', () => {
it(`should navigate back to the added ticket using the descriptors ship button`, async() => { it(`should navigate back to the added ticket using the descriptors ship button`, async() => {
const url = await nightmare const url = await nightmare
.waitToClick(selectors.ticketDescriptor.closeStowawayDialog)
.waitToClick(selectors.ticketDescriptor.shipButton) .waitToClick(selectors.ticketDescriptor.shipButton)
.waitForURL('#!/ticket/17/summary') .waitForURL('#!/ticket/17/summary')
.parsedUrl(); .parsedUrl();

View File

@ -15,6 +15,7 @@ describe('Ticket services path', () => {
it('should find the add descripton button disabled for this user role', async() => { it('should find the add descripton button disabled for this user role', async() => {
const result = await nightmare const result = await nightmare
.waitForClassPresent(selectors.ticketService.firstAddDescriptionButton, 'disabled')
.waitToClick(selectors.ticketService.addServiceButton) .waitToClick(selectors.ticketService.addServiceButton)
.wait(selectors.ticketService.firstAddDescriptionButton) .wait(selectors.ticketService.firstAddDescriptionButton)
.isDisabled(selectors.ticketService.firstAddDescriptionButton); .isDisabled(selectors.ticketService.firstAddDescriptionButton);
@ -129,7 +130,7 @@ describe('Ticket services path', () => {
expect(result).toEqual('Data saved!'); expect(result).toEqual('Data saved!');
}); });
it(`should confirm the service wasn't sucessfully removed`, async() => { it(`should confirm the service was removed`, async() => {
const result = await nightmare const result = await nightmare
.reloadSection('ticket.card.service') .reloadSection('ticket.card.service')
.waitForNumberOfElements(selectors.ticketService.serviceLine, 0) .waitForNumberOfElements(selectors.ticketService.serviceLine, 0)

View File

@ -17,7 +17,7 @@ describe('claim Summary path', () => {
it(`should display details from the claim and it's client on the top of the header`, async() => { it(`should display details from the claim and it's client on the top of the header`, async() => {
let result = await nightmare let result = await nightmare
.waitForSpinnerLoad() .waitForTextInElement(selectors.claimSummary.header, 'Tony Stark')
.waitToGetProperty(selectors.claimSummary.header, 'innerText'); .waitToGetProperty(selectors.claimSummary.header, 'innerText');
expect(result).toContain('4 -'); expect(result).toContain('4 -');

View File

@ -140,7 +140,14 @@ describe('InvoiceOut descriptor path', () => {
it(`should check the invoiceOut booked in the summary data`, async() => { it(`should check the invoiceOut booked in the summary data`, async() => {
let today = new Date(); let today = new Date();
let expectedDate = `${today.getDate()}/${(today.getMonth() + 1)}/${today.getFullYear()}`;
let day = today.getDate();
if (day < 10) day = `0${day}`;
let month = (today.getMonth() + 1);
if (month < 10) month = `0${month}`;
let expectedDate = `${day}/${month}/${today.getFullYear()}`;
const result = await nightmare const result = await nightmare
.waitToGetProperty(selectors.invoiceOutSummary.bookedLabel, 'innerText'); .waitToGetProperty(selectors.invoiceOutSummary.bookedLabel, 'innerText');

View File

@ -40,6 +40,11 @@ export default class Popup extends Component {
if (this.shown) return; if (this.shown) return;
this._shown = true; this._shown = true;
if (this.closeTimeout) {
this.$timeout.cancel(this.closeTimeout);
this.onClose();
}
let linkFn = this.$compile(this.template); let linkFn = this.$compile(this.template);
this.$contentScope = this.$.$new(); this.$contentScope = this.$.$new();
this.popup = linkFn(this.$contentScope, null, this.popup = linkFn(this.$contentScope, null,
@ -51,8 +56,7 @@ export default class Popup extends Component {
classList.add(this.displayMode); classList.add(this.displayMode);
classList.add(...this.constructor.$classNames); classList.add(...this.constructor.$classNames);
if (!this.transitionTimeout) this.document.body.appendChild(this.popup);
this.document.body.appendChild(this.popup);
this.keyDownHandler = e => this.onkeyDown(e); this.keyDownHandler = e => this.onkeyDown(e);
this.document.addEventListener('keydown', this.keyDownHandler); this.document.addEventListener('keydown', this.keyDownHandler);
@ -60,9 +64,9 @@ export default class Popup extends Component {
this.deregisterCallback = this.$transitions.onStart({}, this.deregisterCallback = this.$transitions.onStart({},
() => this.hide()); () => this.hide());
this.$timeout.cancel(this.transitionTimeout); this.$timeout.cancel(this.showTimeout);
this.transitionTimeout = this.$timeout(() => { this.showTimeout = this.$timeout(() => {
this.transitionTimeout = null; this.showTimeout = null;
classList.add('shown'); classList.add('shown');
}, 10); }, 10);
@ -74,35 +78,29 @@ export default class Popup extends Component {
*/ */
hide() { hide() {
if (!this.shown) return; if (!this.shown) return;
this._shown = false;
this.document.removeEventListener('keydown', this.keyDownHandler); this.document.removeEventListener('keydown', this.keyDownHandler);
this.keyDownHandler = null; this.keyDownHandler = null;
if (this.deregisterCallback) { this.deregisterCallback();
this.deregisterCallback(); this.deregisterCallback = null;
this.deregisterCallback = null;
}
this.popup.classList.remove('shown'); this.popup.classList.remove('shown');
this.$timeout.cancel(this.transitionTimeout); this.closeTimeout = this.$timeout(
this.transitionTimeout = this.$timeout(
() => this.onClose(), 200); () => this.onClose(), 200);
this.lastEvent = null; this.lastEvent = null;
this._shown = false;
this.emit('closeStart'); this.emit('closeStart');
} }
onClose() { onClose() {
this.transitionTimeout = null; this.closeTimeout = null;
this.document.body.removeChild(this.popup);
this.$contentScope.$destroy();
this.popup.remove(); this.popup.remove();
this.$contentScope.$destroy();
this.popup = null; this.popup = null;
this.windowEl = null; this.windowEl = null;
this.emit('close'); this.emit('close');
} }

View File

@ -103,7 +103,7 @@ vn-table {
text-align: center; text-align: center;
} }
&[expand] { &[expand] {
max-width: 10em; max-width: 25em;
min-width: 0; min-width: 0;
} }
vn-icon.bright, i.bright { vn-icon.bright, i.bright {

View File

@ -181,9 +181,9 @@ function e2eOnly() {
}) })
.on('jasmineDone', function() { .on('jasmineDone', function() {
const nightmare = createNightmare(); const nightmare = createNightmare();
nightmare.end(() => {}); nightmare.end(() => {});
})); })
);
} }
e2eOnly.description = `Runs the e2e tests only`; e2eOnly.description = `Runs the e2e tests only`;

View File

@ -1,7 +1,6 @@
{ {
"State cannot be blank": "State cannot be blank", "State cannot be blank": "State cannot be blank",
"Cannot be blank": "Cannot be blank", "Cannot be blank": "Cannot be blank",
"Observation type cannot be blank": "Observation type cannot be blank",
"The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero",
"The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero", "The grade must be an integer greater than or equal to zero": "The grade must be an integer greater than or equal to zero",
"Invalid email": "Invalid email", "Invalid email": "Invalid email",

View File

@ -21,7 +21,6 @@
"Worker cannot be blank": "El trabajador no puede estar en blanco", "Worker cannot be blank": "El trabajador no puede estar en blanco",
"Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado", "Cannot change the payment method if no salesperson": "No se puede cambiar la forma de pago si no hay comercial asignado",
"can't be blank": "El campo no puede estar vacío", "can't be blank": "El campo no puede estar vacío",
"Observation type cannot be blank": "El tipo de observación no puede estar en blanco",
"Observation type must be unique": "El tipo de observación no puede repetirse", "Observation type must be unique": "El tipo de observación no puede repetirse",
"The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero", "The credit must be an integer greater than or equal to zero": "The credit must be an integer greater than or equal to zero",
"The grade must be similar to the last one": "El grade debe ser similar al último", "The grade must be similar to the last one": "El grade debe ser similar al último",

View File

@ -18,7 +18,12 @@ module.exports = Self => {
}); });
Self.landsThatDay = async filter => { Self.landsThatDay = async filter => {
let query = `CALL vn.zone_getAvailable(?, ?);`; let query = `
CALL vn.zone_getAgency(?, ?);
SELECT * FROM tmp.zoneGetAgency;
DROP TEMPORARY TABLE tmp.zoneGetAgency;
`;
let result = await Self.rawSql(query, [filter.addressFk, filter.landed]); let result = await Self.rawSql(query, [filter.addressFk, filter.landed]);
return result[1]; return result[1];

View File

@ -56,10 +56,10 @@
"model": "ZoneExclusion", "model": "ZoneExclusion",
"foreignKey": "zoneFk" "foreignKey": "zoneFk"
}, },
"warehouses": { "warehouses": {
"type": "hasMany", "type": "hasMany",
"model": "ZoneWarehouse", "model": "ZoneWarehouse",
"foreignKey": "zoneFk" "foreignKey": "zoneFk"
} }
} }
} }

View File

@ -37,7 +37,6 @@ class Controller {
} }
onDrop($event) { onDrop($event) {
console.log($event);
const files = $event.dataTransfer.files; const files = $event.dataTransfer.files;
this.setDefaultParams().then(() => { this.setDefaultParams().then(() => {
this.dms.files = files; this.dms.files = files;

View File

@ -1,8 +1,4 @@
module.exports = function(Self) { module.exports = function(Self) {
Self.validatesPresenceOf('observationTypeFk', {
message: 'Observation type cannot be blank'
});
Self.validateAsync('typeUnique', typeIsUnique, { Self.validateAsync('typeUnique', typeIsUnique, {
message: 'Observation type must be unique' message: 'Observation type must be unique'
}); });

View File

@ -15,6 +15,9 @@
"description": { "description": {
"type": "string", "type": "string",
"required": true "required": true
},
"observationTypeFk": {
"required": true
} }
}, },
"relations": { "relations": {

View File

@ -140,7 +140,8 @@
data="types" data="types"
ng-model="observation.observationTypeFk" ng-model="observation.observationTypeFk"
show-field="description" show-field="description"
label="Observation type"> label="Observation type"
rule="AddressObservation">
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
vn-two vn-two

View File

@ -29,7 +29,6 @@ export default class Controller {
this.$.watcher.realSubmit() this.$.watcher.realSubmit()
.then(() => this.$.model.save(true)) .then(() => this.$.model.save(true))
.then(() => { .then(() => {
this.$.watcher.setPristine();
this.$.watcher.notifySaved(); this.$.watcher.notifySaved();
this.card.reload(); this.card.reload();
this.goToIndex(); this.goToIndex();

View File

@ -49,10 +49,7 @@ export default class Controller {
returnDialogEt(response) { returnDialogEt(response) {
if (response === 'accept') { if (response === 'accept') {
this.$http.patch(`Clients/${this.client.id}/addressesPropagateRe`, {isEqualizated: this.client.isEqualizated}).then( this.$http.patch(`Clients/${this.client.id}/addressesPropagateRe`, {isEqualizated: this.client.isEqualizated}).then(
res => { () => this.vnApp.showMessage(this.translate.instant('Equivalent tax spreaded'))
if (res.data)
this.vnApp.showMessage(this.translate.instant('Equivalent tax spreaded'));
}
); );
} }
} }

View File

@ -23,7 +23,7 @@
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th expand>Date</vn-th> <vn-th expand>Date</vn-th>
<vn-th number order="DESC">Ticket/Entry</vn-th> <vn-th number order="DESC">Id</vn-th>
<vn-th>State</vn-th> <vn-th>State</vn-th>
<vn-th>Reference</vn-th> <vn-th>Reference</vn-th>
<vn-th>Client</vn-th> <vn-th>Client</vn-th>

View File

@ -37,8 +37,8 @@ module.exports = Self => {
switch (param) { switch (param) {
case 'search': case 'search':
return {or: [ return {or: [
{ticketFk: value}, {'t.id': value},
{clientFk: value} {'c.id': value}
]}; ]};
} }
}); });

View File

@ -46,8 +46,7 @@ class Controller {
this.getShipped({ this.getShipped({
landed: this.ticket.landed, landed: this.ticket.landed,
addressFk: value, addressFk: value,
agencyModeFk: this.ticket.agencyModeFk, agencyModeFk: this.ticket.agencyModeFk
warehouseFk: this.ticket.warehouseFk
}); });
} }
} }
@ -78,8 +77,7 @@ class Controller {
this.getLanded({ this.getLanded({
shipped: value, shipped: value,
addressFk: this.ticket.addressFk, addressFk: this.ticket.addressFk,
agencyModeFk: this.ticket.agencyModeFk, agencyModeFk: this.ticket.agencyModeFk
warehouseFk: this.ticket.warehouseFk
}); });
} }
@ -92,8 +90,7 @@ class Controller {
this.getShipped({ this.getShipped({
landed: value, landed: value,
addressFk: this.ticket.addressFk, addressFk: this.ticket.addressFk,
agencyModeFk: this.ticket.agencyModeFk, agencyModeFk: this.ticket.agencyModeFk
warehouseFk: this.ticket.warehouseFk
}); });
} }
@ -107,8 +104,7 @@ class Controller {
this.getLanded({ this.getLanded({
shipped: this.ticket.shipped, shipped: this.ticket.shipped,
addressFk: this.ticket.addressFk, addressFk: this.ticket.addressFk,
agencyModeFk: value, agencyModeFk: value
warehouseFk: this.ticket.warehouseFk
}); });
} }
} }
@ -160,10 +156,7 @@ class Controller {
this.ticket.agencyModeFk = null; this.ticket.agencyModeFk = null;
const query = `Zones/${zoneId}`; const query = `Zones/${zoneId}`;
this.$http.get(query).then(res => { this.$http.get(query).then(res => {
if (res.data) { this.ticket.agencyModeFk = res.data.agencyModeFk;
this.ticket.agencyModeFk = res.data.agencyModeFk;
this.ticket.warehouseFk = res.data.warehouseFk;
}
}); });
} }
@ -205,7 +198,6 @@ class Controller {
if (res.data) { if (res.data) {
this.ticket.zoneFk = res.data.zoneFk; this.ticket.zoneFk = res.data.zoneFk;
this.ticket.agencyModeFk = res.data.agencyModeFk; this.ticket.agencyModeFk = res.data.agencyModeFk;
this.ticket.warehouseFk = res.data.warehouseFk;
this.ticket.landed = res.data.landed; this.ticket.landed = res.data.landed;
this.ticket.shipped = params.shipped; this.ticket.shipped = params.shipped;
} else { } else {
@ -226,7 +218,6 @@ class Controller {
if (res.data) { if (res.data) {
this.ticket.zoneFk = res.data.zoneFk; this.ticket.zoneFk = res.data.zoneFk;
this.ticket.agencyModeFk = res.data.agencyModeFk; this.ticket.agencyModeFk = res.data.agencyModeFk;
this.ticket.warehouseFk = res.data.warehouseFk;
this.ticket.landed = params.landed; this.ticket.landed = params.landed;
this.ticket.shipped = res.data.shipped; this.ticket.shipped = res.data.shipped;
} else { } else {

View File

@ -72,8 +72,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
landed: landed, landed: landed,
addressFk: 100, addressFk: 100,
agencyModeFk: 7, agencyModeFk: 7
warehouseFk: 1
}; };
controller.landed = landed; controller.landed = landed;
@ -99,8 +98,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
landed: landed, landed: landed,
addressFk: 121, addressFk: 121,
agencyModeFk: 7, agencyModeFk: 7
warehouseFk: 2
}; };
controller.landed = landed; controller.landed = landed;
@ -125,8 +123,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
shipped: shipped, shipped: shipped,
addressFk: 121, addressFk: 121,
agencyModeFk: 7, agencyModeFk: 7
warehouseFk: 1
}; };
controller.shipped = shipped; controller.shipped = shipped;
@ -150,8 +147,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
landed: landed, landed: landed,
addressFk: 121, addressFk: 121,
agencyModeFk: 7, agencyModeFk: 7
warehouseFk: 1
}; };
controller.landed = landed; controller.landed = landed;
@ -176,8 +172,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
shipped: shipped, shipped: shipped,
addressFk: 121, addressFk: 121,
agencyModeFk: agencyModeId, agencyModeFk: agencyModeId
warehouseFk: 1
}; };
controller.ticket.shipped = shipped; controller.ticket.shipped = shipped;
controller.agencyModeId = 8; controller.agencyModeId = 8;
@ -192,8 +187,7 @@ describe('Ticket', () => {
const spectedResult = { const spectedResult = {
landed: landed, landed: landed,
addressFk: 121, addressFk: 121,
agencyModeFk: agencyModeId, agencyModeFk: agencyModeId
warehouseFk: 1
}; };
controller.ticket.landed = landed; controller.ticket.landed = landed;
controller.agencyModeId = 7; controller.agencyModeId = 7;
@ -261,18 +255,13 @@ describe('Ticket', () => {
describe('onChangeZone()', () => { describe('onChangeZone()', () => {
it('should return an available zone', async() => { it('should return an available zone', async() => {
const zoneId = 5; const zoneId = 5;
const landed = new Date(); const agencyModeFk = 8;
controller._ticket = { $httpBackend.when('GET', `Zones/${zoneId}`).respond(200, {agencyModeFk});
id: 1,
landed: landed,
addressFk: 121,
warehouseFk: 1
};
$httpBackend.when('GET', `Zones/${zoneId}`).respond(200);
$httpBackend.expect('GET', `Zones/${zoneId}`); $httpBackend.expect('GET', `Zones/${zoneId}`);
controller.onChangeZone(zoneId); controller.onChangeZone(zoneId);
$httpBackend.flush(); $httpBackend.flush();
expect(controller.ticket.agencyModeFk).toEqual(agencyModeFk);
}); });
}); });

View File

@ -1,12 +1,9 @@
import ngModule from '../module'; import ngModule from '../module';
import Component from 'core/lib/component';
class Controller { class Controller extends Component {
constructor($state, $scope, $http, vnApp, $translate, aclService) { constructor($element, $, aclService) {
this.$scope = $scope; super($element, $);
this.$state = $state;
this.$http = $http;
this.vnApp = vnApp;
this.$translate = $translate;
this.aclService = aclService; this.aclService = aclService;
this.moreOptions = [ this.moreOptions = [
{name: 'Add turn', callback: this.showAddTurnDialog}, {name: 'Add turn', callback: this.showAddTurnDialog},
@ -46,7 +43,7 @@ class Controller {
return; return;
} }
this.newShipped = this.ticket.shipped; this.newShipped = this.ticket.shipped;
this.$scope.changeShippedDialog.show(); this.$.changeShippedDialog.show();
} }
changeShipped(response) { changeShipped(response) {
@ -104,7 +101,7 @@ class Controller {
return (!hasShowProperty || option.show === true || return (!hasShowProperty || option.show === true ||
typeof option.show === 'function' && option.show()) && hasAcl; typeof option.show === 'function' && option.show()) && hasAcl;
}); });
this.$scope.moreButton.data = options; this.$.moreButton.data = options;
} }
get isEditable() { get isEditable() {
@ -116,13 +113,13 @@ class Controller {
} }
showAddTurnDialog() { showAddTurnDialog() {
this.$scope.addTurn.show(); this.$.addTurn.show();
} }
addTurn(day) { addTurn(day) {
let params = {ticketFk: this.ticket.id, weekDay: day}; let params = {ticketFk: this.ticket.id, weekDay: day};
this.$http.patch(`TicketWeeklies`, params).then(() => { this.$http.patch(`TicketWeeklies`, params).then(() => {
this.$scope.addTurn.hide(); this.$.addTurn.hide();
this.vnApp.showSuccess(this.$translate.instant('Data saved!')); this.vnApp.showSuccess(this.$translate.instant('Data saved!'));
}); });
} }
@ -133,7 +130,7 @@ class Controller {
return; return;
} }
this.$scope.deleteConfirmation.show(); this.$.deleteConfirmation.show();
} }
deleteTicket(response) { deleteTicket(response) {
@ -147,11 +144,11 @@ class Controller {
} }
showAddStowaway() { showAddStowaway() {
this.$scope.addStowaway.show(); this.$.addStowaway.show();
} }
showRemoveStowaway() { showRemoveStowaway() {
this.$scope.removeStowaway.show(); this.$.removeStowaway.show();
} }
get ticket() { get ticket() {
@ -160,11 +157,11 @@ class Controller {
set ticket(value) { set ticket(value) {
this._ticket = value; this._ticket = value;
if (value)
this.canStowaway();
if (!value) return; if (!value) return;
this.canStowaway();
let links = { let links = {
btnOne: { btnOne: {
icon: 'person', icon: 'person',
@ -212,14 +209,14 @@ class Controller {
destination: address.mobile || null, destination: address.mobile || null,
message: this.$translate.instant('SMSPayment') message: this.$translate.instant('SMSPayment')
}; };
this.$scope.sms.open(); this.$.sms.open();
} }
/** /**
* Shows an invoice confirmation * Shows an invoice confirmation
*/ */
showMakeInvoiceDialog() { showMakeInvoiceDialog() {
this.$scope.makeInvoiceConfirmation.show(); this.$.makeInvoiceConfirmation.show();
} }
/** /**
@ -242,7 +239,7 @@ class Controller {
* Shows an invoice confirmation * Shows an invoice confirmation
*/ */
showRegenerateInvoiceDialog() { showRegenerateInvoiceDialog() {
this.$scope.regenerateInvoiceConfirmation.show(); this.$.regenerateInvoiceConfirmation.show();
} }
/** /**
@ -273,7 +270,7 @@ class Controller {
} }
confirmDeliveryNote() { confirmDeliveryNote() {
this.$scope.confirmDeliveryNote.show(); this.$.confirmDeliveryNote.show();
} }
sendDeliveryNote(response) { sendDeliveryNote(response) {
@ -285,7 +282,7 @@ class Controller {
} }
} }
Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate', 'aclService']; Controller.$inject = ['$element', '$scope', 'aclService'];
ngModule.component('vnTicketDescriptor', { ngModule.component('vnTicketDescriptor', {
template: require('./index.html'), template: require('./index.html'),

View File

@ -7,7 +7,8 @@ describe('Ticket Component vnTicketDescriptor', () => {
beforeEach(ngModule('ticket')); beforeEach(ngModule('ticket'));
beforeEach(angular.mock.inject(($componentController, _$state_, _$httpBackend_) => { beforeEach(angular.mock.inject(($componentController, _$httpBackend_, $rootScope, $compile, _$state_) => {
let $element = $compile(`<vn-autocomplete></vn-autocomplete>`)($rootScope);
$state = _$state_; $state = _$state_;
$state.getCurrentPath = () => { $state.getCurrentPath = () => {
return [ return [
@ -16,7 +17,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
]; ];
}; };
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
controller = $componentController('vnTicketDescriptor', {$state}); controller = $componentController('vnTicketDescriptor', {$element});
controller._ticket = {id: 2, invoiceOut: {id: 1}}; controller._ticket = {id: 2, invoiceOut: {id: 1}};
controller.cardReload = ()=> { controller.cardReload = ()=> {
return true; return true;
@ -24,25 +25,25 @@ describe('Ticket Component vnTicketDescriptor', () => {
})); }));
describe('showAddTurnDialog()', () => { describe('showAddTurnDialog()', () => {
it('should call contrtoller.$scope.addTurn.show()', () => { it('should call controller.$.addTurn.show()', () => {
controller.$scope.addTurn = {show: () => {}}; controller.$.addTurn = {show: () => {}};
spyOn(controller.$scope.addTurn, 'show'); spyOn(controller.$.addTurn, 'show');
controller.showAddTurnDialog(); controller.showAddTurnDialog();
expect(controller.$scope.addTurn.show).toHaveBeenCalledWith(); expect(controller.$.addTurn.show).toHaveBeenCalledWith();
}); });
}); });
describe('addTurn()', () => { describe('addTurn()', () => {
it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => { it('should make a query and call $.addTurn.hide() and vnApp.showSuccess()', () => {
controller.$scope.addTurn = {hide: () => {}}; controller.$.addTurn = {hide: () => {}};
spyOn(controller.$scope.addTurn, 'hide'); spyOn(controller.$.addTurn, 'hide');
$httpBackend.expectPATCH(`TicketWeeklies`).respond(); $httpBackend.expectPATCH(`TicketWeeklies`).respond();
controller.addTurn(1); controller.addTurn(1);
$httpBackend.flush(); $httpBackend.flush();
expect(controller.$scope.addTurn.hide).toHaveBeenCalledWith(); expect(controller.$.addTurn.hide).toHaveBeenCalledWith();
}); });
}); });
@ -57,11 +58,11 @@ describe('Ticket Component vnTicketDescriptor', () => {
it('should call deleteConfirmation.show() if the ticket is editable', () => { it('should call deleteConfirmation.show() if the ticket is editable', () => {
controller.ticket.tracking = {state: {alertLevel: 0}}; controller.ticket.tracking = {state: {alertLevel: 0}};
controller.$scope.deleteConfirmation = {show: () => {}}; controller.$.deleteConfirmation = {show: () => {}};
spyOn(controller.$scope.deleteConfirmation, 'show'); spyOn(controller.$.deleteConfirmation, 'show');
controller.showDeleteTicketDialog(); controller.showDeleteTicketDialog();
expect(controller.$scope.deleteConfirmation.show).toHaveBeenCalledWith(); expect(controller.$.deleteConfirmation.show).toHaveBeenCalledWith();
}); });
}); });
@ -136,21 +137,21 @@ describe('Ticket Component vnTicketDescriptor', () => {
describe('showAddStowaway()', () => { describe('showAddStowaway()', () => {
it('should show a dialog with a list of tickets available for an stowaway', () => { it('should show a dialog with a list of tickets available for an stowaway', () => {
controller.$scope.addStowaway = {}; controller.$.addStowaway = {};
controller.$scope.addStowaway.show = jasmine.createSpy('show'); controller.$.addStowaway.show = jasmine.createSpy('show');
controller.showAddStowaway(); controller.showAddStowaway();
expect(controller.$scope.addStowaway.show).toHaveBeenCalledWith(); expect(controller.$.addStowaway.show).toHaveBeenCalledWith();
}); });
}); });
describe('showRemoveStowaway()', () => { describe('showRemoveStowaway()', () => {
it('should show a dialog for an stowaway removal', () => { it('should show a dialog for an stowaway removal', () => {
controller.$scope.removeStowaway = {}; controller.$.removeStowaway = {};
controller.$scope.removeStowaway.show = jasmine.createSpy('show'); controller.$.removeStowaway.show = jasmine.createSpy('show');
controller.showRemoveStowaway(); controller.showRemoveStowaway();
expect(controller.$scope.removeStowaway.show).toHaveBeenCalledWith(); expect(controller.$.removeStowaway.show).toHaveBeenCalledWith();
}); });
}); });

View File

@ -14,11 +14,11 @@
<vn-tr> <vn-tr>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
<vn-th field="itemFk" number>Item</vn-th> <vn-th field="itemFk" number>Item</vn-th>
<vn-th>Description</vn-th> <vn-th expand>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 field="originalQuantity" number>Original</vn-th>
<vn-th field="workerFk">Worker</vn-th> <vn-th field="workerFk">Worker</vn-th>
<vn-th field="state">State</vn-th> <vn-th field="state" shrink>State</vn-th>
<vn-th field="created">Created</vn-th> <vn-th field="created">Created</vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
@ -56,7 +56,7 @@
{{::sale.userNickname | dashIfEmpty}} {{::sale.userNickname | dashIfEmpty}}
</span> </span>
</vn-td> </vn-td>
<vn-td>{{::sale.state}}</vn-td> <vn-td shrink>{{::sale.state}}</vn-td>
<vn-td>{{::sale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td> <vn-td>{{::sale.created | date: 'dd/MM/yyyy HH:mm'}}</vn-td>
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>

View File

@ -152,7 +152,6 @@
<field> <field>
<vn-textfield <vn-textfield
vn-id="concept" vn-id="concept"
vn-focus
ng-model="sale.concept" ng-model="sale.concept"
on-change="$ctrl.updateConcept(sale)"> on-change="$ctrl.updateConcept(sale)">
</vn-textfield> </vn-textfield>

View File

@ -60,6 +60,7 @@
</vn-auto> </vn-auto>
</vn-horizontal> </vn-horizontal>
<vn-icon-button <vn-icon-button
ng-if=$ctrl.defaultTaxClass
vn-tooltip="Add service" vn-tooltip="Add service"
vn-bind="+" vn-bind="+"
icon="add_circle" icon="add_circle"

View File

@ -33,11 +33,13 @@ class Controller {
} }
add() { add() {
this.$scope.model.insert({ if (this.defaultTaxClass) {
taxClassFk: this.defaultTaxClass.id, this.$scope.model.insert({
quantity: 1, taxClassFk: this.defaultTaxClass.id,
ticketFk: this.$stateParams.id quantity: 1,
}); ticketFk: this.$stateParams.id
});
}
} }
onNewServiceTypeOpen() { onNewServiceTypeOpen() {