Merge branch 'dev' into 2574-itemTag_refactor
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Joan Sanchez 2020-11-10 12:39:17 +00:00
commit 08af948eb0
20 changed files with 303 additions and 42 deletions

View File

@ -1,13 +1,62 @@
const app = require('vn-loopback/server/server');
// #2495 updateCollectionSale reparar polución de unitarios
xdescribe('updateCollectionSale()', () => {
it('return a new collection', async() => {
describe('updateCollectionSale()', () => {
it('should return a new collection', async() => {
const sectorOneWarehouseID = 1;
let ctx = {req: {accessToken: {userId: 106}}};
let response = await app.models.Collection.updateCollectionSale(ctx, 1, 5, 5, 5, 1, 4, false, 'UXN', 1, 1);
ctx.args = {
sale: 1,
originalQuantity: 5,
quantity: 5,
quantityPicked: 5,
ticketFk: 1,
stateFk: 4,
isNicho: false,
shelvingFk: 'UXN',
itemFk: 1,
sectorFk: 1
};
let originalSaleTracking = await app.models.SaleTracking.findOne({
where: {
saleFk: ctx.args.sale,
stateFk: ctx.args.stateFk
}
});
let itemPlacement = await app.models.ItemPlacement.findOne({
where: {
itemFk: ctx.args.itemFk,
warehouseFk: sectorOneWarehouseID
}
});
const originalSale = await app.models.Sale.findById(ctx.args.sale);
const originalItemShelving = await app.models.ItemShelving.findOne({where: {shelvingFk: ctx.args.shelvingFk, itemFk: ctx.args.itemFk}});
const originalTicketLastState = await app.models.TicketLastState.findById(ctx.args.ticketFk);
let response = await app.models.Collection.updateCollectionSale(ctx);
expect(response.length).toBeGreaterThan(0);
expect(response[0][0].id).toEqual(1);
expect(response[0][0].quantity).toEqual(5);
// restores
if (originalSaleTracking)
await originalSaleTracking.save();
else {
originalSaleTracking = await app.models.SaleTracking.findOne({
where: {
saleFk: ctx.args.sale,
stateFk: ctx.args.stateFk
}
});
await originalSaleTracking.destroy();
}
await originalSale.save();
const itemShelvingsToDestroy = await app.models.ItemShelving.find({where: {shelvingFk: ctx.args.shelvingFk, itemFk: ctx.args.itemFk}});
for (itemShelving of itemShelvingsToDestroy)
await itemShelving.destroy();
await originalItemShelving.save();
await originalTicketLastState.save();
await itemPlacement.save();
});
});

View File

@ -65,25 +65,26 @@ module.exports = Self => {
}
});
Self.updateCollectionSale = async(ctx, sale, originalQuantity, quantity, quantityPicked, ticketFk, stateFk, isNicho, shelvingFk, itemFk, sectorFk) => {
Self.updateCollectionSale = async ctx => {
const userId = ctx.req.accessToken.userId;
const args = ctx.args;
if (originalQuantity == quantity) {
if (args.originalQuantity == args.quantity) {
query = `CALL vn.collection_updateSale(?,?,?,?,?)`;
await Self.rawSql(query, [sale, originalQuantity, userId, stateFk, ticketFk]);
await Self.rawSql(query, [args.sale, args.originalQuantity, userId, args.stateFk, args.ticketFk]);
}
if (!isNicho) {
if (!args.isNicho) {
query = `CALL vn.collection_faults(?,?,?)`;
await Self.rawSql(query, [shelvingFk, quantityPicked, itemFk]);
await Self.rawSql(query, [args.shelvingFk, args.quantityPicked, args.itemFk]);
} else {
query = `CALL vn.sector_getWarehouse(?)`;
const [result] = await Self.rawSql(query, [sectorFk]);
const [result] = await Self.rawSql(query, [args.sectorFk]);
query = `CALL vn.itemPlacementSave(?,?,?)`;
await Self.rawSql(query, [shelvingFk, quantityPicked, result[0]['warehouseFk']]);
await Self.rawSql(query, [args.shelvingFk, args.quantityPicked, result[0]['warehouseFk']]);
}
query = `CALL vn.sale_updateOriginalQuantity(?,?)`;
return await Self.rawSql(query, [sale, quantity]);
return await Self.rawSql(query, [args.sale, args.quantity]);
};
};

View File

@ -1,3 +1,4 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Supplier', 'updateFiscalData', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Supplier', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('Supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierLog', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierContact', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -0,0 +1,43 @@
DROP PROCEDURE IF EXISTS `vn`.`timeControl_calculate`;
DELIMITER $$
CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`timeControl_calculate`(vDatedFrom DATETIME, vDatedTo DATETIME)
BEGIN
SET @vIsOdd := TRUE;
SET @vUser := NULL;
SET @vDated := NULL;
DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate;
CREATE TEMPORARY TABLE tmp.timeControlCalculate
SELECT
userFk,
dated,
IF( timeWork >= 18000, @timeWork:=timeWork + 1200, @timeWork:=timeWork) timeWorkSeconds,
SEC_TO_TIME(@timeWork ) timeWorkSexagesimal,
@timeWork / 3600 timeWorkDecimal,
timed
FROM (SELECT SUM(timeWork) timeWork,
userFk,
dated,
GROUP_CONCAT(DATE_FORMAT(sub.timed,"%H:%i") ORDER BY sub.timed ASC SEPARATOR ' - ') timed
FROM (SELECT IF(@vUser = wtc.userFk, @vUser :=@vUser, @vUser := wtc.userFk),
IF(@vIsOdd, @vIsOdd := FALSE, @vIsOdd := TRUE),
IF(direction='in', @vIsOdd := TRUE, @vIsOdd := @vIsOdd),
IF(@vIsOdd, @vLastTimed:=UNIX_TIMESTAMP(timed),@vLastTimed:=@vLastTimed),
IF(@vIsOdd, 0, UNIX_TIMESTAMP(timed)-@vLastTimed) timeWork,
IF(direction='in', @vDated := DATE(wtc.timed), @vDated :=@vDated) dated,
wtc.timed timed,
wtc.userFk,
direction
FROM (SELECT DISTINCT(wtc.id), wtc.userFk, wtc.timed, wtc.direction
FROM workerTimeControl wtc
JOIN tmp.`user` w ON w.userFk = wtc.userFk
WHERE wtc.timed BETWEEN vDatedFrom AND vDatedTo
ORDER BY userFk, timed ASC
) wtc
WHERE wtc.timed BETWEEN vDatedFrom AND vDatedTo
) sub
GROUP BY userFk, dated
)sub2;
END$$
DELIMITER ;

View File

@ -1,2 +0,0 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('supplier', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('SupplierContact', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -123,15 +123,20 @@ let actions = {
},
waitForState: async function(state) {
await this.waitFor(state => {
await this.waitForFunction(state => {
let $state = angular.element(document.body).injector().get('$state');
return !$state.transition && $state.is(state);
}, {}, state);
await this.waitForFunction(() => {
return angular.element(() => {
return true;
});
});
await this.waitForSpinnerLoad();
},
waitForTransition: async function() {
await this.waitFor(() => {
await this.waitForFunction(() => {
const $state = angular.element(document.body).injector().get('$state');
return !$state.transition;
});
@ -522,7 +527,7 @@ let actions = {
},
waitForSpinnerLoad: async function() {
await this.waitFor('vn-topbar vn-spinner', {hidden: true});
await this.waitForSelector('vn-topbar vn-spinner', {hidden: true});
},
waitForWatcherData: async function(selector) {

View File

@ -925,7 +925,11 @@ export default {
thirdContactDeleteButton: 'vn-supplier-contact div:nth-child(3) vn-icon-button[icon="delete"]'
},
supplierBasicData: {
alias: 'vn-supplier-basic-data vn-textfield[ng-model="$ctrl.supplier.nickname"]',
isOfficial: 'vn-supplier-basic-data vn-check[ng-model="$ctrl.supplier.isOfficial"]',
isActive: 'vn-supplier-basic-data vn-check[ng-model="$ctrl.supplier.isActive"]',
notes: 'vn-supplier-basic-data vn-textarea[ng-model="$ctrl.supplier.note"]',
saveButton: 'vn-supplier-basic-data button[type="submit"]',
},
supplierFiscalData: {
socialName: 'vn-supplier-fiscal-data vn-textfield[ng-model="$ctrl.supplier.name"]',

View File

@ -48,7 +48,7 @@ describe('Ticket Create new tracking state path', () => {
});
it('should now access to the create state view by clicking the create floating button', async() => {
await page.waitFor('.vn-popup', {hidden: true}),
await page.waitFor('.vn-popup', {hidden: true});
await page.waitToClick(selectors.ticketTracking.createStateButton);
await page.waitForState('ticket.card.tracking.edit');
});

View File

@ -103,8 +103,7 @@ describe('Ticket descriptor path', () => {
expect(message.text).toBe('Data saved!');
});
xit(`should check the state of the stowaway ticket is embarked`, async() => {
await page.wait(500);
it(`should check the state of the stowaway ticket is embarked`, async() => {
const state = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText');
expect(state).toEqual('State Embarcando');

View File

@ -0,0 +1,70 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Supplier basic data path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('administrative', 'supplier');
await page.accessToSearchResult('1');
await page.accessToSection('supplier.card.basicData');
});
afterAll(async() => {
await browser.close();
});
it('should edit the basic data', async() => {
await page.clearInput(selectors.supplierBasicData.alias);
await page.write(selectors.supplierBasicData.alias, 'Plants Nick SL');
await page.waitToClick(selectors.supplierBasicData.isOfficial);
await page.waitToClick(selectors.supplierBasicData.isActive);
await page.write(selectors.supplierBasicData.notes, 'Some notes');
await page.waitToClick(selectors.supplierBasicData.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toBe('Data saved!');
});
it('should reload the section', async() => {
await page.reloadSection('supplier.card.basicData');
});
it('should check the alias was edited', async() => {
const result = await page.waitToGetProperty(selectors.supplierBasicData.alias, 'value');
expect(result).toEqual('Plants Nick SL');
});
it('should check the isOffical checkbox is now unchecked', async() => {
const result = await page.checkboxState(selectors.supplierBasicData.isOfficial);
expect(result).toBe('unchecked');
});
it('should check the isActive checkbox is now unchecked', async() => {
const result = await page.checkboxState(selectors.supplierBasicData.isActive);
expect(result).toBe('unchecked');
});
it('should check the notes were edited', async() => {
const result = await page.waitToGetProperty(selectors.supplierBasicData.notes, 'value');
expect(result).toEqual('Some notes');
});
it('should navigate to the log section', async() => {
await page.accessToSection('supplier.card.log');
});
it('should check the changes have been recorded', async() => {
const result = await page.waitToGetProperty('#newInstance:nth-child(3)', 'innerText');
expect(result).toEqual('note: Some notes');
});
});

View File

@ -69,6 +69,10 @@ describe('Supplier contact path', () => {
it(`should remove the created contact`, async() => {
await page.waitToClick(selectors.supplierContact.thirdContactDeleteButton, 'value');
const result = await page.countElement(selectors.supplierContact.anyContact);
expect(result).toEqual(2);
await page.waitToClick(selectors.supplierContact.saveButton);
const message = await page.waitForSnackbar();

View File

@ -7,8 +7,18 @@
}
},
"properties": {
"id": {
"type": "Number",
"id": true
},
"code": {
"type": "String"
},
"itemFk": {
"type": "Number"
},
"warehouseFk": {
"type": "Number"
}
},
"relations": {

View File

@ -8,18 +8,24 @@
},
"properties": {
"id": {
"type": "number",
"type": "Number",
"id": true,
"description": "Identifier"
},
"shelve": {
"type": "string"
"type": "String"
},
"shelvingFk": {
"type": "String"
},
"itemFk": {
"type": "Number"
},
"deep": {
"type": "number"
"type": "Number"
},
"quantity": {
"type": "number"
"type": "Number"
},
"created": {
"type": "Date"

View File

@ -0,0 +1,42 @@
<mg-ajax path="Suppliers/{{patch.params.id}}" options="vnPatch"></mg-ajax>
<vn-watcher
vn-id="watcher"
data="$ctrl.supplier"
form="form"
save="patch">
</vn-watcher>
<form name="form" ng-submit="watcher.submit()" class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-horizontal>
<vn-textfield
vn-one
label="Alias"
ng-model="$ctrl.supplier.nickname"
rule
vn-focus>
</vn-textfield>
</vn-horizontal>
<vn-horizontal>
<vn-check
label="Official"
ng-model="$ctrl.supplier.isOfficial">
</vn-check>
<vn-check
label="Active"
ng-model="$ctrl.supplier.isActive">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-textarea
vn-one
label="Notes"
ng-model="$ctrl.supplier.note"
rule>
</vn-textarea>
</vn-horizontal>
</vn-card>
<vn-button-bar>
<vn-submit label="Save"></vn-submit>
<vn-button label="Undo changes" ng-if="watcher.dataChanged()" ng-click="watcher.loadOriginalData()"></vn-button>
</vn-button-bar>
</form>

View File

@ -0,0 +1,10 @@
import ngModule from '../module';
import Section from 'salix/components/section';
ngModule.vnComponent('vnSupplierBasicData', {
template: require('./index.html'),
controller: Section,
bindings: {
supplier: '<'
}
});

View File

@ -0,0 +1,3 @@
Notes: Notas
Active: Activo
Official: Oficial

View File

@ -6,6 +6,7 @@ import './descriptor';
import './index/';
import './search-panel';
import './summary';
import './basic-data';
import './fiscal-data';
import './contact';
import './log';

View File

@ -48,6 +48,7 @@
"state": "supplier.card.basicData",
"component": "vn-supplier-basic-data",
"description": "Basic data",
"acl": ["administrative"],
"params": {
"supplier": "$ctrl.supplier"
}
@ -65,7 +66,7 @@
"state": "supplier.card.log",
"component": "vn-supplier-log",
"description": "Log"
},
},
{
"url": "/contact",
"state": "supplier.card.contact",

View File

@ -12,6 +12,12 @@
"type": "Number",
"forceId": false
},
"saleFk": {
"type": "Number"
},
"stateFk": {
"type": "Number"
},
"isChecked": {
"type": "boolean"
},

View File

@ -5,22 +5,30 @@
"model": "TicketLog",
"relation": "ticket",
"showField": "stateFk"
},
"options": {
"mysql": {
"table": "ticketTracking"
}
},
},
"options": {
"mysql": {
"table": "ticketTracking"
}
},
"properties": {
"id": {
"id": true,
"type": "Number",
"forceId": false
},
"created": {
"type": "Date",
"required": false
}
"id": {
"id": true,
"type": "Number",
"forceId": false
},
"created": {
"type": "Date"
},
"ticketFk": {
"type": "Number"
},
"stateFk": {
"type": "Number"
},
"workerFk": {
"type": "Number"
}
},
"relations": {
"ticket": {