diff --git a/Dockerfile b/Dockerfile index b42249099..9caaa30a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ RUN apt-get update \ curl \ ca-certificates \ gnupg2 \ - libfontconfig \ + libfontconfig lftp \ && apt-get -y install xvfb gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 \ libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 \ libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 \ diff --git a/back/methods/chat/send.js b/back/methods/chat/send.js index 67e0dbb87..fcb49f4b8 100644 --- a/back/methods/chat/send.js +++ b/back/methods/chat/send.js @@ -30,8 +30,13 @@ module.exports = Self => { const sender = await models.Account.findById(accessToken.userId); const recipient = to.replace('@', ''); - if (sender.name != recipient) - return sendMessage(sender, to, message); + if (sender.name != recipient) { + await sendMessage(sender, to, message); + + return true; + } + + return false; }; async function sendMessage(sender, channel, message) { diff --git a/back/methods/chat/sendCheckingPresence.js b/back/methods/chat/sendCheckingPresence.js index 429ecdab0..5c27d72fd 100644 --- a/back/methods/chat/sendCheckingPresence.js +++ b/back/methods/chat/sendCheckingPresence.js @@ -5,7 +5,7 @@ module.exports = Self => { description: 'Sends a RocketChat message to a connected user or department channel', accessType: 'WRITE', accepts: [{ - arg: 'recipientId', + arg: 'workerId', type: 'number', required: true, description: 'The recipient user id' diff --git a/back/methods/chat/spec/notifyIssue.spec.js b/back/methods/chat/spec/notifyIssue.spec.js index 96117c2c0..e20d43142 100644 --- a/back/methods/chat/spec/notifyIssue.spec.js +++ b/back/methods/chat/spec/notifyIssue.spec.js @@ -13,10 +13,9 @@ describe('Chat notifyIssue()', () => { spyOn(chatModel, 'send').and.callThrough(); spyOn(osTicketModel, 'rawSql').and.returnValue([]); - const response = await chatModel.notifyIssues(ctx); + await chatModel.notifyIssues(ctx); expect(chatModel.send).not.toHaveBeenCalled(); - expect(response).toBeUndefined(); }); it(`should return a response calling the send() method`, async() => { @@ -27,16 +26,15 @@ describe('Chat notifyIssue()', () => { username: 'batman', subject: 'Issue title'} ]); + // eslint-disable-next-line max-len const expectedMessage = `@all ➔ There's a new urgent ticket:\r\n[ID: *00001* - Issue title (@batman)](https://cau.verdnatura.es/scp/tickets.php?id=1)`; const department = await app.models.Department.findById(departmentId); let orgChatName = department.chatName; await department.updateAttribute('chatName', 'IT'); - const response = await chatModel.notifyIssues(ctx); + await chatModel.notifyIssues(ctx); - expect(response.statusCode).toEqual(200); - expect(response.message).toEqual('Fake notification sent'); expect(chatModel.send).toHaveBeenCalledWith(ctx, '#IT', expectedMessage); // restores diff --git a/back/methods/chat/spec/send.spec.js b/back/methods/chat/spec/send.spec.js index 2c23bb591..634e1d420 100644 --- a/back/methods/chat/spec/send.spec.js +++ b/back/methods/chat/spec/send.spec.js @@ -5,14 +5,13 @@ describe('Chat send()', () => { let ctx = {req: {accessToken: {userId: 1}}}; let response = await app.models.Chat.send(ctx, '@salesPerson', 'I changed something'); - expect(response.statusCode).toEqual(200); - expect(response.message).toEqual('Fake notification sent'); + expect(response).toEqual(true); }); it('should retrun false as response', async() => { let ctx = {req: {accessToken: {userId: 18}}}; let response = await app.models.Chat.send(ctx, '@salesPerson', 'I changed something'); - expect(response).toBeFalsy(); + expect(response).toEqual(false); }); }); diff --git a/back/methods/chat/spec/sendCheckingPresence.spec.js b/back/methods/chat/spec/sendCheckingPresence.spec.js index 2c48ef02c..712e7f947 100644 --- a/back/methods/chat/spec/sendCheckingPresence.spec.js +++ b/back/methods/chat/spec/sendCheckingPresence.spec.js @@ -20,10 +20,8 @@ describe('Chat sendCheckingPresence()', () => { }) ); - const response = await chatModel.sendCheckingPresence(ctx, workerId, 'I changed something'); + await chatModel.sendCheckingPresence(ctx, workerId, 'I changed something'); - expect(response.statusCode).toEqual(200); - expect(response.message).toEqual('Fake notification sent'); expect(chatModel.send).toHaveBeenCalledWith(ctx, '@HankPym', 'I changed something'); }); @@ -47,10 +45,8 @@ describe('Chat sendCheckingPresence()', () => { const department = await models.Department.findById(departmentId, null, options); await department.updateAttribute('chatName', 'cooler'); - const response = await chatModel.sendCheckingPresence(ctx, workerId, 'I changed something'); + await chatModel.sendCheckingPresence(ctx, workerId, 'I changed something'); - expect(response.statusCode).toEqual(200); - expect(response.message).toEqual('Fake notification sent'); expect(chatModel.send).toHaveBeenCalledWith(ctx, '#cooler', '@HankPym ➔ I changed something'); await tx.rollback(); diff --git a/back/methods/edi/sql/bucket.sql b/back/methods/edi/sql/bucket.sql new file mode 100644 index 000000000..92121386c --- /dev/null +++ b/back/methods/edi/sql/bucket.sql @@ -0,0 +1,14 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE bucket + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12) + SET + bucket_id = @col2, + bucket_type_id = @col4, + description = @col5, + x_size = @col6, + y_size = @col7, + z_size = @col8, + entry_date = STR_TO_DATE(@col10, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col11, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col12, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/bucket_type.sql b/back/methods/edi/sql/bucket_type.sql new file mode 100644 index 000000000..68498f183 --- /dev/null +++ b/back/methods/edi/sql/bucket_type.sql @@ -0,0 +1,10 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE bucket_type + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) + SET + bucket_type_id = @col2, + description = @col3, + entry_date = STR_TO_DATE(@col4, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col5, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col6, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/feature.sql b/back/methods/edi/sql/feature.sql new file mode 100644 index 000000000..081cfde7b --- /dev/null +++ b/back/methods/edi/sql/feature.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE `feature` + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) + SET + item_id = @col2, + feature_type_id = @col3, + feature_value = @col4, + entry_date = STR_TO_DATE(@col5, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col6, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col7, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/genus.sql b/back/methods/edi/sql/genus.sql new file mode 100644 index 000000000..dd882629c --- /dev/null +++ b/back/methods/edi/sql/genus.sql @@ -0,0 +1,10 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE genus + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) + SET + genus_id = @col2, + latin_genus_name = @col3, + entry_date = STR_TO_DATE(@col4, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col5, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col6, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/item.sql b/back/methods/edi/sql/item.sql new file mode 100644 index 000000000..543c83381 --- /dev/null +++ b/back/methods/edi/sql/item.sql @@ -0,0 +1,13 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE item + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12) + SET + id = @col2, + product_name = @col4, + name = @col5, + plant_id = @col7, + group_id = @col9, + entry_date = STR_TO_DATE(@col10, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col11, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col12, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/item_feature.sql b/back/methods/edi/sql/item_feature.sql new file mode 100644 index 000000000..23b0f3afa --- /dev/null +++ b/back/methods/edi/sql/item_feature.sql @@ -0,0 +1,12 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE `item_feature` + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8) + SET + item_id = @col2, + feature = @col3, + regulation_type = @col4, + presentation_order = @col5, + entry_date = STR_TO_DATE(@col6, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col7, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col8, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/item_group.sql b/back/methods/edi/sql/item_group.sql new file mode 100644 index 000000000..31da6c57f --- /dev/null +++ b/back/methods/edi/sql/item_group.sql @@ -0,0 +1,10 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE item_group + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6) + SET + group_code = @col2, + dutch_group_description = @col3, + entry_date = STR_TO_DATE(@col4, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col5, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col6, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/plant.sql b/back/methods/edi/sql/plant.sql new file mode 100644 index 000000000..50720fba5 --- /dev/null +++ b/back/methods/edi/sql/plant.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE plant + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9) + SET + plant_id = @col3, + genus_id = @col4, + specie_id = @col5, + entry_date = STR_TO_DATE(@col7, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col8, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col9, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/specie.sql b/back/methods/edi/sql/specie.sql new file mode 100644 index 000000000..e27478ae8 --- /dev/null +++ b/back/methods/edi/sql/specie.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE specie + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) + SET + specie_id = @col2, + genus_id = @col3, + latin_species_name = @col4, + entry_date = STR_TO_DATE(@col5, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col6, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col7, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/supplier.sql b/back/methods/edi/sql/supplier.sql new file mode 100644 index 000000000..a1d3376d6 --- /dev/null +++ b/back/methods/edi/sql/supplier.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE edi.supplier + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7, @col8, @col9, @col10, @col11, @col12, @col13, @col14, @col15, @col16, @col17, @col18, @col19, @col20) + SET + GLNAddressCode = @col2, + supplier_id = @col4, + company_name = @col3, + entry_date = STR_TO_DATE(@col9, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col10, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col11, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/type.sql b/back/methods/edi/sql/type.sql new file mode 100644 index 000000000..88c4ac026 --- /dev/null +++ b/back/methods/edi/sql/type.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE `type` + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) + SET + type_id = @col2, + type_group_id = @col3, + description = @col4, + entry_date = STR_TO_DATE(@col5, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col6, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col7, '%Y%m%d%H%i') diff --git a/back/methods/edi/sql/value.sql b/back/methods/edi/sql/value.sql new file mode 100644 index 000000000..c8c4deef5 --- /dev/null +++ b/back/methods/edi/sql/value.sql @@ -0,0 +1,11 @@ +LOAD DATA LOCAL INFILE ? + INTO TABLE `value` + FIELDS TERMINATED BY ';' + LINES TERMINATED BY '\n' (@col1, @col2, @col3, @col4, @col5, @col6, @col7) + SET + type_id = @col2, + type_value = @col3, + type_description = @col4, + entry_date = STR_TO_DATE(@col5, '%Y%m%d'), + expiry_date = IFNULL(NULL,STR_TO_DATE(@col6, '%Y%m%d')), + change_date_time = STR_TO_DATE(@col7, '%Y%m%d%H%i') diff --git a/back/methods/edi/updateData.js b/back/methods/edi/updateData.js new file mode 100644 index 000000000..df77906da --- /dev/null +++ b/back/methods/edi/updateData.js @@ -0,0 +1,155 @@ +/* eslint no-console: "off" */ +const path = require('path'); +const fs = require('fs-extra'); + +module.exports = Self => { + Self.remoteMethodCtx('updateData', { + description: 'Updates schema data from external provider', + accessType: 'WRITE', + returns: { + type: 'object', + root: true + }, + http: { + path: `/updateData`, + verb: 'GET' + } + }); + + Self.updateData = async() => { + const models = Self.app.models; + + const container = await models.TempContainer.container('edi'); + const tempPath = path.join(container.client.root, container.name); + + const [ftpConfig] = await Self.rawSql('SELECT host, user, password FROM edi.ftpConfig'); + console.debug(`Openning FTP connection to ${ftpConfig.host}...\n`); + + const FtpClient = require('ftps'); + const ftpClient = new FtpClient({ + host: ftpConfig.host, + username: ftpConfig.user, + password: ftpConfig.password, + procotol: 'ftp' + }); + + const files = await Self.rawSql('SELECT fileName, toTable, file, updated FROM edi.fileConfig'); + + let remoteFile; + let tempDir; + let tempFile; + for (const file of files) { + try { + const fileName = file.file; + + console.debug(`Downloading file ${fileName}...`); + + remoteFile = `codes/${fileName}.ZIP`; + tempDir = `${tempPath}/${fileName}`; + tempFile = `${tempPath}/${fileName}.zip`; + + await extractFile({ + ftpClient: ftpClient, + file: file, + paths: { + remoteFile: remoteFile, + tempDir: tempDir, + tempFile: tempFile + } + }); + } catch (error) { + if (fs.existsSync(tempFile)) + await fs.unlink(tempFile); + + await fs.rmdir(tempDir, {recursive: true}); + console.error(error); + } + } + + return true; + }; + + async function extractFile({ftpClient, file, paths}) { + // Download the zip file + ftpClient.get(paths.remoteFile, paths.tempFile); + + // Execute download command + ftpClient.exec(async(err, response) => { + if (response.error) { + console.debug(`Error downloading file... ${response.error}`); + return; + } + + const AdmZip = require('adm-zip'); + const zip = new AdmZip(paths.tempFile); + const entries = zip.getEntries(); + + zip.extractAllTo(paths.tempDir, false); + + if (fs.existsSync(paths.tempFile)) + await fs.unlink(paths.tempFile); + + await dumpData({file, entries, paths}); + + await fs.rmdir(paths.tempDir, {recursive: true}); + }); + } + + async function dumpData({file, entries, paths}) { + const toTable = file.toTable; + const baseName = file.fileName; + + for (const zipEntry of entries) { + const entryName = zipEntry.entryName; + console.log(`Reading file ${entryName}...`); + + const startIndex = (entryName.length - 10); + const endIndex = (entryName.length - 4); + const dateString = entryName.substring(startIndex, endIndex); + const lastUpdated = new Date(); + + // Format string date to a date object + let updated = null; + if (file.updated) { + updated = new Date(file.updated); + updated.setHours(0, 0, 0, 0); + } + + lastUpdated.setFullYear(`20${dateString.substring(4, 6)}`); + lastUpdated.setMonth(parseInt(dateString.substring(2, 4)) - 1); + lastUpdated.setDate(dateString.substring(0, 2)); + lastUpdated.setHours(0, 0, 0, 0); + + if (updated && lastUpdated <= updated) { + console.debug(`Table ${toTable} already updated, skipping...`); + continue; + } + + console.log('Dumping data...'); + const templatePath = path.join(__dirname, `./sql/${toTable}.sql`); + const sqlTemplate = fs.readFileSync(templatePath, 'utf8'); + + const rawPath = path.join(paths.tempDir, entryName); + + try { + const tx = await Self.beginTransaction({}); + const options = {transaction: tx}; + + await Self.rawSql(`DELETE FROM edi.${toTable}`, null, options); + await Self.rawSql(sqlTemplate, [rawPath], options); + await Self.rawSql(` + UPDATE edi.fileConfig + SET updated = ? + WHERE fileName = ? + `, [lastUpdated, baseName], options); + + tx.commit(); + } catch (error) { + tx.rollback(); + throw error; + } + + console.log(`Updated table ${toTable}\n`); + } + } +}; diff --git a/back/model-config.json b/back/model-config.json index 4c79d565b..4ce11b99d 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -109,6 +109,9 @@ }, "OsTicket": { "dataSource": "osticket" + }, + "Edi": { + "dataSource": "vn" } } diff --git a/back/models/edi.js b/back/models/edi.js new file mode 100644 index 000000000..bfddf2746 --- /dev/null +++ b/back/models/edi.js @@ -0,0 +1,3 @@ +module.exports = Self => { + require('../methods/edi/updateData')(Self); +}; diff --git a/back/models/edi.json b/back/models/edi.json new file mode 100644 index 000000000..d436e53ff --- /dev/null +++ b/back/models/edi.json @@ -0,0 +1,5 @@ +{ + "name": "Edi", + "base": "VnModel" +} + \ No newline at end of file diff --git a/db/changes/10420-valentines/00-ImportTicketAcl.sql b/db/changes/10420-valentines/00-ImportTicketAcl.sql index 98192a39c..df61fd5b8 100644 --- a/db/changes/10420-valentines/00-ImportTicketAcl.sql +++ b/db/changes/10420-valentines/00-ImportTicketAcl.sql @@ -1,2 +1,2 @@ -DELETE FROM salix.ACL +DELETE FROM `salix`.`ACL` WHERE model = 'ClaimEnd' AND property = 'importTicketSales'; diff --git a/db/changes/10420-valentines/00-aclCollection.sql b/db/changes/10420-valentines/00-aclCollection.sql index 81e53049c..57774ba29 100644 --- a/db/changes/10420-valentines/00-aclCollection.sql +++ b/db/changes/10420-valentines/00-aclCollection.sql @@ -1,3 +1,3 @@ -INSERT INTO salix.ACL +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES('Collection', 'setSaleQuantity', '*', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/changes/10420-valentines/00-aclDocuware.sql b/db/changes/10420-valentines/00-aclDocuware.sql index 21ed66c4c..c2d47d4ea 100644 --- a/db/changes/10420-valentines/00-aclDocuware.sql +++ b/db/changes/10420-valentines/00-aclDocuware.sql @@ -1,3 +1,3 @@ -INSERT INTO salix.ACL +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) VALUES('Docuware', '*', '*', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/changes/10420-valentines/00-defaultViewConfig.sql b/db/changes/10420-valentines/00-defaultViewConfig.sql index c65c1f403..e0d75e9d4 100644 --- a/db/changes/10420-valentines/00-defaultViewConfig.sql +++ b/db/changes/10420-valentines/00-defaultViewConfig.sql @@ -1,3 +1,3 @@ -UPDATE salix.defaultViewConfig +UPDATE `salix`.`defaultViewConfig` SET `columns`='{"intrastat":false,"stemMultiplier":false,"landed":false,"producer":false}' WHERE tableCode ='itemsIndex'; diff --git a/db/changes/10430-ash/00-aclAgencyTerm.sql b/db/changes/10430-ash/00-aclAgencyTerm.sql index d3e11e53e..c43965ed0 100644 --- a/db/changes/10430-ash/00-aclAgencyTerm.sql +++ b/db/changes/10430-ash/00-aclAgencyTerm.sql @@ -1,2 +1,2 @@ -INSERT INTO salix.ACL (model,property,accessType,principalId) +INSERT INTO `salix`.`ACL` (model,property,accessType,principalId) VALUES ('AgencyTerm','*','*','administrative'); diff --git a/db/changes/10430-ash/00-deliveryBoss.sql b/db/changes/10430-ash/00-deliveryBoss.sql index a4bcdcd0c..ac07bfa31 100644 --- a/db/changes/10430-ash/00-deliveryBoss.sql +++ b/db/changes/10430-ash/00-deliveryBoss.sql @@ -1,3 +1 @@ -UPDATE `account`.`user` -SET `role` = 57 -WHERE id IN (2294, 4365, 7294); \ No newline at end of file +UPDATE `account`.`user` SET `role` = 57 WHERE id IN (2294, 4365, 7294); \ No newline at end of file diff --git a/db/changes/10440-fallas/00-ACL.sql b/db/changes/10440-fallas/00-ACL.sql new file mode 100644 index 000000000..051a851f7 --- /dev/null +++ b/db/changes/10440-fallas/00-ACL.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId) +VALUES ('Edi', 'updateData', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/10440-fallas/00-aclEducationLevel.sql b/db/changes/10440-fallas/00-aclEducationLevel.sql new file mode 100644 index 000000000..26bf9d16f --- /dev/null +++ b/db/changes/10440-fallas/00-aclEducationLevel.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES('EducationLevel', '*', '*', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/10440-fallas/00-aclIntrastat.sql b/db/changes/10440-fallas/00-aclIntrastat.sql new file mode 100644 index 000000000..16410814d --- /dev/null +++ b/db/changes/10440-fallas/00-aclIntrastat.sql @@ -0,0 +1,3 @@ +INSERT INTO `salix`.`ACL` +(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) +VALUES('InvoiceInIntrastat', '*', '*', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/db/changes/10440-fallas/00-claim_packages.sql b/db/changes/10440-fallas/00-claim_packages.sql index 54e8ff326..3d82eb7b6 100644 --- a/db/changes/10440-fallas/00-claim_packages.sql +++ b/db/changes/10440-fallas/00-claim_packages.sql @@ -1 +1 @@ -ALTER TABLE vn.claim ADD packages smallint(10) unsigned DEFAULT 0 NULL COMMENT 'packages received by the client'; \ No newline at end of file +ALTER TABLE `vn`.`claim` ADD packages smallint(10) unsigned DEFAULT 0 NULL COMMENT 'packages received by the client'; diff --git a/db/changes/10440-fallas/00-component.sql b/db/changes/10440-fallas/00-component.sql new file mode 100644 index 000000000..8d2dd6517 --- /dev/null +++ b/db/changes/10440-fallas/00-component.sql @@ -0,0 +1,2 @@ +INSERT INTO `vn`.`component` (`name`,`typeFk`,`classRate`,`isRenewable`,`code`,`isRequired`) + VALUES ('maná reclamacion',7,4,0,'manaClaim',0); \ No newline at end of file diff --git a/db/changes/10440-fallas/00-country.sql b/db/changes/10440-fallas/00-country.sql new file mode 100644 index 000000000..6cc4ce1f9 --- /dev/null +++ b/db/changes/10440-fallas/00-country.sql @@ -0,0 +1,90 @@ +ALTER TABLE `vn`.`country` ADD `a3Code` INT NULL COMMENT 'Código país para a3'; + +UPDATE `vn`.`country` c +JOIN `vn2008`.`payroll_pais` `p` ON `p`.`pais` = `c`.`country` +SET `c`.`a3Code` = `p`.`codpais`; + +UPDATE `vn`.`country` +SET `a3Code` = 710 +WHERE `country` = 'Sud-Africa'; -- ÁFRICA DEL SUR + +UPDATE `vn`.`country` +SET `a3Code` = 643 +WHERE `country` = 'Rusia'; -- FEDERACIÓN DE RUSIA + +UPDATE `vn`.`country` +SET `a3Code` = 28 +WHERE `country` = 'Antigua'; -- ANTIGUA Y BARBUDA + +UPDATE `vn`.`country` +SET `a3Code` = 840 +WHERE `country` = 'USA'; -- ESTADOS UNIDOS + +UPDATE `vn`.`country` +SET `a3Code` = 404 +WHERE `country` = 'Kenya'; -- KENIA + +UPDATE `vn`.`country` +SET `a3Code` = 498 +WHERE `country` = 'Moldavia'; -- REPÚBLICA DE MOLDAVIA + +UPDATE `vn`.`country` +SET `a3Code` = 826 +WHERE `country` = 'Gran Bretaña'; -- REINO UNIDO + +UPDATE `vn`.`country` +SET `a3Code` = 484 +WHERE `country` = 'Mexico'; -- MÉJICO + +UPDATE `vn`.`country` +SET `a3Code` = 716 +WHERE `country` = 'Zimbawe'; -- ZINBABWE + +UPDATE `vn`.`country` +SET `a3Code` = 203 +WHERE `country` = 'Chequia'; -- REPÚBLICA CHECA + +UPDATE `vn`.`country` +SET `a3Code` = 764 +WHERE `country` = 'Thailandia'; -- TAILANDIA + +UPDATE `vn`.`country` +SET `a3Code` = 276 +WHERE `country` = 'Alemania'; -- REPÚBLICA FEDERAL DE ALEMANIA + +UPDATE `vn`.`country` +SET `a3Code` = 112 +WHERE `country` = 'Bielorrusia'; -- BELARUS + +UPDATE `vn`.`country` +SET `a3Code` = 528 +WHERE `country` = 'Holanda'; -- PAÍSES BAJOS + +UPDATE `vn`.`country` +SET `a3Code` = 410 +WHERE `country` = 'Corea del Sur'; -- COREA (REPÚBLICA) + +UPDATE `vn`.`country` +SET `a3Code` = 724 +WHERE `country` = 'España exento'; -- ESPAÑA + +-- Borrar registro USA de country: +UPDATE `vn`.`supplier` `s` + SET `s`.`countryFk` = 62 + WHERE `s`.`countryFk` = 12; + +UPDATE `vn`.`bankEntity` + SET `countryFk` = 62 + WHERE `countryFk` = 12; + +DELETE FROM `vn`.`country` + WHERE `id`= 12; + +UPDATE `vn2008`.`payroll_pais` +SET `pais`='COREA NORTE (REPÚBLICA DEM. POPULAR)' +WHERE `codpais`=408; +UPDATE `vn2008`.`payroll_pais` +SET `pais`='COREA SUR (REPÚBLICA) ' +WHERE `codpais`=410; + +RENAME TABLE `vn2008`.`payroll_pais` TO `vn2008`.`payroll_pais__`; \ No newline at end of file diff --git a/db/changes/10440-fallas/00-invoiceInIntrastat.sql b/db/changes/10440-fallas/00-invoiceInIntrastat.sql new file mode 100644 index 000000000..8f65fac29 --- /dev/null +++ b/db/changes/10440-fallas/00-invoiceInIntrastat.sql @@ -0,0 +1,2 @@ +INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`) + VALUES ('InvoiceInIntrastat','*','*','ALLOW','ROLE','employee'); \ No newline at end of file diff --git a/db/changes/10440-fallas/00-manaCustomerUpdate.sql b/db/changes/10440-fallas/00-manaCustomerUpdate.sql new file mode 100644 index 000000000..80838bca2 --- /dev/null +++ b/db/changes/10440-fallas/00-manaCustomerUpdate.sql @@ -0,0 +1,106 @@ +DROP PROCEDURE IF EXISTS `bs`.`manaCustomerUpdate`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `bs`.`manaCustomerUpdate`() +BEGIN + DECLARE vToDated DATE; + DECLARE vFromDated DATE; + DECLARE vForDeleteDated DATE; + DECLARE vManaId INT; + DECLARE vManaAutoId INT; + DECLARE vClaimManaId INT; + DECLARE vManaBankId INT; + DECLARE vManaGreugeTypeId INT; + + SELECT id INTO vManaId + FROM `component` WHERE code = 'mana'; + + SELECT id INTO vManaAutoId + FROM `component` WHERE code = 'autoMana'; + + SELECT id INTO vClaimManaId + FROM `component` WHERE code = 'manaClaim'; + + SELECT id INTO vManaBankId + FROM `bank` WHERE code = 'mana'; + + SELECT id INTO vManaGreugeTypeId + FROM `greugeType` WHERE code = 'mana'; + + SELECT IFNULL(max(dated), '2016-01-01') + INTO vFromDated + FROM bs.manaCustomer; + + DELETE + FROM bs.manaCustomer + WHERE dated = vFromDated; + + SELECT IFNULL(max(dated), '2016-01-01') + INTO vFromDated + FROM bs.manaCustomer; + + WHILE timestampadd(DAY,30,vFromDated) < CURDATE() DO + + SELECT + timestampadd(DAY,30,vFromDated), + timestampadd(DAY,-90,vFromDated) + INTO + vToDated, + vForDeleteDated; + + DELETE FROM bs.manaCustomer + WHERE dated <= vForDeleteDated; + + + INSERT INTO bs.manaCustomer(Id_Cliente, Mana, dated) + + SELECT + Id_Cliente, + cast(sum(mana) as decimal(10,2)) as mana, + vToDated as dated + FROM + + ( + SELECT cs.Id_Cliente, Cantidad * Valor as mana + FROM vn2008.Tickets t + JOIN vn2008.Consignatarios cs using(Id_Consigna) + JOIN vn2008.Movimientos m on m.Id_Ticket = t.Id_Ticket + JOIN vn2008.Movimientos_componentes mc on mc.Id_Movimiento = m.Id_Movimiento + WHERE Id_Componente IN (vManaAutoId, vManaId, vClaimManaId) + AND t.Fecha > vFromDated + AND date(t.Fecha) <= vToDated + + + UNION ALL + + SELECT r.Id_Cliente, - Entregado + FROM vn2008.Recibos r + WHERE Id_Banco = vManaBankId + AND Fechacobro > vFromDated + AND Fechacobro <= vToDated + + UNION ALL + + SELECT g.Id_Cliente, g.Importe + FROM vn2008.Greuges g + WHERE Greuges_type_id = vManaGreugeTypeId + AND Fecha > vFromDated + AND Fecha <= vToDated + + UNION ALL + + SELECT Id_Cliente, mana + FROM bs.manaCustomer + WHERE dated = vFromDated + ) sub + + GROUP BY Id_Cliente + HAVING Id_Cliente; + + SET vFromDated = vToDated; + + END WHILE; + +END$$ +DELIMITER ; diff --git a/db/changes/10440-fallas/00-manaSpellersRequery.sql b/db/changes/10440-fallas/00-manaSpellersRequery.sql new file mode 100644 index 000000000..9c1a10c6a --- /dev/null +++ b/db/changes/10440-fallas/00-manaSpellersRequery.sql @@ -0,0 +1,75 @@ +DROP PROCEDURE IF EXISTS `vn`.`manaSpellersRequery`; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`manaSpellersRequery`(vWorkerFk INTEGER) +BEGIN +/** + * Recalcula el mana consumido por un trabajador + * + * @param vWorkerFk Id Trabajador + */ + DECLARE vWorkerIsExcluded BOOLEAN; + DECLARE vFromDated DATE; + DECLARE vToDated DATE DEFAULT TIMESTAMPADD(DAY,1,CURDATE()); + DECLARE vMana INT; + DECLARE vAutoMana INT; + DECLARE vClaimMana INT; + DECLARE vManaBank INT; + DECLARE vManaGreugeType INT; + + SELECT COUNT(*) INTO vWorkerIsExcluded + FROM workerManaExcluded + WHERE workerFk = vWorkerFk; + + IF NOT vWorkerIsExcluded THEN + SELECT id INTO vMana + FROM `component` WHERE code = 'mana'; + + SELECT id INTO vAutoMana + FROM `component` WHERE code = 'autoMana'; + + SELECT id INTO vClaimMana + FROM `component` WHERE code = 'manaClaim'; + + SELECT id INTO vManaBank + FROM `bank` WHERE code = 'mana'; + + SELECT id INTO vManaGreugeType + FROM `greugeType` WHERE code = 'mana'; + + SELECT max(dated) INTO vFromDated + FROM clientManaCache; + + REPLACE workerMana (workerFk, amount) + SELECT vWorkerFk, sum(mana) FROM + ( + SELECT s.quantity * sc.value as mana + FROM ticket t + JOIN address a ON a.id = t.addressFk + JOIN client c ON c.id = a.clientFk + JOIN sale s ON s.ticketFk = t.id + JOIN saleComponent sc ON sc.saleFk = s.id + WHERE c.salesPersonFk = vWorkerFk AND sc.componentFk IN (vMana, vAutoMana, vClaimMana) + AND t.shipped > vFromDated AND t.shipped < vToDated + UNION ALL + SELECT - r.amountPaid + FROM receipt r + JOIN client c ON c.id = r.clientFk + WHERE c.salesPersonFk = vWorkerFk AND bankFk = vManaBank + AND payed > vFromDated + UNION ALL + SELECT g.amount + FROM greuge g + JOIN client c ON c.id = g.clientFk + WHERE c.salesPersonFk = vWorkerFk AND g.greugeTypeFk = vManaGreugeType + AND g.shipped > vFromDated and g.shipped < CURDATE() + UNION ALL + SELECT cc.mana + FROM clientManaCache cc + JOIN client c ON c.id = cc.clientFk + WHERE c.salesPersonFk = vWorkerFk AND cc.dated = vFromDated + ) sub; + END IF; +END$$ +DELIMITER ; diff --git a/db/changes/10440-fallas/00-travelThermograph.sql b/db/changes/10440-fallas/00-travelThermograph.sql new file mode 100644 index 000000000..f76f070a0 --- /dev/null +++ b/db/changes/10440-fallas/00-travelThermograph.sql @@ -0,0 +1,16 @@ +DROP TRIGGER `vn`.`travelThermograph_beforeInsert`; + +ALTER TABLE `vn`.`travelThermograph` CHANGE `temperature` `temperature__` enum('COOL','WARM','DRY') CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL NULL; + +CREATE OR REPLACE +ALGORITHM = UNDEFINED VIEW `vn2008`.`travel_thermograph` AS +select + `tt`.`thermographFk` AS `thermograph_id`, + `tt`.`created` AS `odbc_date`, + `tt`.`warehouseFk` AS `warehouse_id`, + `tt`.`travelFk` AS `travel_id`, + `tt`.`temperatureFk` AS `temperature`, + `tt`.`result` AS `result`, + `tt`.`dmsFk` AS `gestdoc_id` +from + `vn`.`travelThermograph` `tt`; \ No newline at end of file diff --git a/db/changes/10440-fallas/00-worker.sql b/db/changes/10440-fallas/00-worker.sql new file mode 100644 index 000000000..0e0def841 --- /dev/null +++ b/db/changes/10440-fallas/00-worker.sql @@ -0,0 +1,51 @@ + +ALTER TABLE `vn`.`worker` MODIFY COLUMN `maritalStatus__` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; +UPDATE `vn`.`worker` `w` + SET `w`.`maritalStatus__` = NULL; + +UPDATE `vn`.`worker` `w` + JOIN `vn`.`person` `p` ON `p`.`workerFk` = `w`.`id` + JOIN `postgresql`.`profile` `pr` ON `pr`.`person_id` = `p`.`id` + JOIN `vn2008`.`profile_labour_payroll` `pl` ON `pl`.`profile_id` = `pr`.`profile_id` + SET `w`.`maritalStatus__` = `pl`.`estadocivil`; + +ALTER TABLE `vn`.`worker` ADD `originCountryFk` mediumint(8) unsigned NULL COMMENT 'País de origen'; +ALTER TABLE `vn`.`worker` ADD `educationLevelFk` SMALLINT NULL; +ALTER TABLE `vn`.`worker` ADD `SSN` varchar(15) NULL; +ALTER TABLE `vn`.`worker` CHANGE `maritalStatus__` `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; +ALTER TABLE `vn`.`worker` MODIFY COLUMN `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; +ALTER TABLE `vn`.`worker` CHANGE `maritalStatus` maritalStatus enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL AFTER sectorFk; +ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_2` FOREIGN KEY (`educationLevelFk`) REFERENCES `vn`.`educationLevel`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_1` FOREIGN KEY (`originCountryFk`) REFERENCES `vn`.`country`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +INSERT INTO `vn`.`country` (`country`, `CEE`, `code`, `politicalCountryFk`, `isUeeMember`, `a3Code`) + VALUES + ('Argentina',2,'AR',80,0,32), + ('Cuba',2,'CU',81,0,192), + ('Guinea Ecuatorial',2,'GQ',82,0,226), + ('Guinea',2,'GN',83,0,324), + ('Honduras',2,'HN',84,0,340), + ('Mali',2,'ML',85,0,466), + ('Nicaragua',2,'NI',86,0,558), + ('Pakistán',2,'PK',87,0,586), + ('Paraguay',2,'PY',88,0,600), + ('Senegal',2,'SN',89,0,686), + ('Uruguay',2,'UY',90,0,858), + ('Venezuela',2,'VE',91,0,862), + ('Bulgaria',2,'BG',92,1,100), + ('Georgia',2,'GE',93,0,268); + +UPDATE `vn`.`worker` `w` + JOIN `vn`.`person` `p` ON `p`.`workerFk` = `w`.`id` + JOIN `postgresql`.`profile` `pr` ON `pr`.`person_id` = `p`.`id` + JOIN `vn2008`.`profile_labour_payroll` `pl` ON `pl`.`profile_id` = `pr`.`profile_id` + JOIN `vn`.`country` `co` ON `co`.`a3Code` = `pl`.`codpais` + SET `w`.`originCountryFk` = `co`.`id`; + +UPDATE `vn`.`worker` `w` + JOIN `vn`.`person` `p` ON `p`.`workerFk` = `w`.`id` + JOIN `postgresql`.`profile` `pr` ON `pr`.`person_id` = `p`.`id` + JOIN `vn2008`.`profile_labour_payroll` pl ON `pl`.`profile_id` = `pr`.`profile_id` + SET `w`.`SSN` = CONCAT(`pl`.`NSSProvincia`, `pl`.`NssNumero`, `pl`.`NssDC`); + +RENAME TABLE `vn2008`.`profile_labour_payroll` TO `vn2008`.`profile_labour_payroll__`; diff --git a/db/changes/10450-april/00-timeControl_getError.sql b/db/changes/10450-april/00-timeControl_getError.sql new file mode 100644 index 000000000..0caf8ab62 --- /dev/null +++ b/db/changes/10450-april/00-timeControl_getError.sql @@ -0,0 +1,73 @@ +DROP PROCEDURE IF EXISTS vn.timeControl_getError; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`timeControl_getError`(vDatedFrom DATETIME, vDatedTo DATETIME) +BEGIN +/* + * @param vDatedFrom + * @param vDatedTo + * @table tmp.`user`(userFk) + * Fichadas incorrectas de las cuales no se puede calcular horas trabajadas + * @return tmp.timeControlError (id) + */ + DECLARE vDayMaxTime INTEGER; + + SET @journeyCounter := 0; + SET @lastUserFk := NULL; + + SELECT dayMaxTime INTO vDayMaxTime + FROM workerTimeControlConfig LIMIT 1; + + DROP TEMPORARY TABLE IF EXISTS tmp.timeControl; + CREATE TEMPORARY TABLE tmp.timeControl + (INDEX(id), INDEX(journeyCounter)) + ENGINE = MEMORY + SELECT sub.id, + sub.direction, + sub.timed, + IF(sub.direction = 'in' OR @hasOut OR sub.userFk <> @lastUserFk, @journeyCounter := @journeyCounter + 1, @journeyCounter) journeyCounter, + @lastUserFk := sub.userFk workerFk, + IF(sub.direction = 'out', @hasOut:= TRUE, @hasOut:= FALSE) + FROM ( + SELECT DISTINCT wtc.id, + wtc.direction, + wtc.timed, + wtc.userFk + FROM workerTimeControl wtc + JOIN tmp.`user` w ON w.userFk = wtc.userFk + WHERE wtc.timed BETWEEN DATE_SUB(vDatedFrom, INTERVAL 1 DAY) AND DATE_ADD(vDatedTo, INTERVAL 1 DAY) + ORDER BY wtc.userFk, wtc.timed + ) sub; + + DROP TEMPORARY TABLE IF EXISTS tmp.timeControlAux; + CREATE TEMPORARY TABLE tmp.timeControlAux + (INDEX(id), INDEX(journeyCounter)) + ENGINE = MEMORY + SELECT * FROM tmp.timeControl; + + DROP TEMPORARY TABLE IF EXISTS tmp.timeControlError; + CREATE TEMPORARY TABLE tmp.timeControlError + (INDEX(id)) + ENGINE = MEMORY + SELECT id + FROM tmp.timeControlAux tca + JOIN (SELECT journeyCounter, + UNIX_TIMESTAMP(MAX(timed)) - UNIX_TIMESTAMP(MIN(timed)) timeWork, + SUM(direction = 'in') totalIn, + SUM(direction = 'out') totalOut, + timed + FROM tmp.timeControl + GROUP BY journeyCounter + HAVING COUNT(*) MOD 2 = 1 + OR totalIn <> 1 + OR totalOut <> 1 + OR timeWork >= vDayMaxTime + )sub ON sub.journeyCounter = tca.journeyCounter + WHERE sub.timed BETWEEN vDatedFrom AND vDatedTo; + + DROP TEMPORARY TABLE IF EXISTS tmp.timeControl; + DROP TEMPORARY TABLE IF EXISTS tmp.timeControlAux; + +END$$ +DELIMITER ; diff --git a/db/changes/10451-april/00-ClientUnpaid.sql b/db/changes/10451-april/00-ClientUnpaid.sql new file mode 100644 index 000000000..d84fe494a --- /dev/null +++ b/db/changes/10451-april/00-ClientUnpaid.sql @@ -0,0 +1,10 @@ +CREATE TABLE `vn`.`clientUnpaid` ( + `clientFk` int(11) NOT NULL, + `dated` date NOT NULL, + `amount` double DEFAULT 0, + PRIMARY KEY (`clientFk`), + CONSTRAINT `clientUnpaid_clientFk` FOREIGN KEY (`clientFk`) REFERENCES `client` (`id`) ON UPDATE CASCADE +); + +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) + VALUES('ClientUnpaid', '*', '*', 'ALLOW', 'ROLE', 'administrative'); \ No newline at end of file diff --git a/db/changes/10451-april/00-aclSaleRefund.sql b/db/changes/10451-april/00-aclSaleRefund.sql new file mode 100644 index 000000000..79baba63d --- /dev/null +++ b/db/changes/10451-april/00-aclSaleRefund.sql @@ -0,0 +1,6 @@ +UPDATE `salix`.`ACL` + SET `property`='refund' +WHERE `model`='Sale' AND `property`='payBack'; + +INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) +VALUES('Sale', 'refundAll', 'WRITE', 'ALLOW', 'ROLE', 'employee'); diff --git a/db/changes/10451-april/00-ticket_doRefund.sql b/db/changes/10451-april/00-ticket_doRefund.sql new file mode 100644 index 000000000..5540ff8cf --- /dev/null +++ b/db/changes/10451-april/00-ticket_doRefund.sql @@ -0,0 +1,113 @@ +DROP PROCEDURE IF EXISTS vn.ticket_doRefund; + +DELIMITER $$ +$$ +CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_doRefund`(IN vOriginTicket INT, OUT vNewTicket INT) +BEGIN + + DECLARE vDone BIT DEFAULT 0; + DECLARE vCustomer MEDIUMINT; + DECLARE vWarehouse TINYINT; + DECLARE vCompany MEDIUMINT; + DECLARE vAddress MEDIUMINT; + DECLARE vRefundAgencyMode INT; + DECLARE vItemFk INT; + DECLARE vQuantity DECIMAL (10,2); + DECLARE vConcept VARCHAR(50); + DECLARE vPrice DECIMAL (10,2); + DECLARE vDiscount TINYINT; + DECLARE vSaleNew INT; + DECLARE vSaleMain INT; + DECLARE vZoneFk INT; + DECLARE vDescription VARCHAR(50); + DECLARE vTaxClassFk INT; + DECLARE vTicketServiceTypeFk INT; + + DECLARE cSales CURSOR FOR + SELECT * + FROM tmp.sale; + + DECLARE cTicketServices CURSOR FOR + SELECT * + FROM tmp.ticketService; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + SELECT id INTO vRefundAgencyMode + FROM agencyMode WHERE `name` = 'ABONO'; + + SELECT clientFk, warehouseFk, companyFk, addressFk + INTO vCustomer, vWarehouse, vCompany, vAddress + FROM ticket + WHERE id = vOriginTicket; + + SELECT id INTO vZoneFk + FROM zone WHERE agencyModeFk = vRefundAgencyMode + LIMIT 1; + + INSERT INTO vn.ticket ( + clientFk, + shipped, + addressFk, + agencyModeFk, + nickname, + warehouseFk, + companyFk, + landed, + zoneFk + ) + SELECT + vCustomer, + CURDATE(), + vAddress, + vRefundAgencyMode, + a.nickname, + vWarehouse, + vCompany, + CURDATE(), + vZoneFk + FROM address a + WHERE a.id = vAddress; + + SET vNewTicket = LAST_INSERT_ID(); + + SET vDone := 0; + OPEN cSales; + FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount; + + WHILE NOT vDone DO + + INSERT INTO vn.sale(ticketFk, itemFk, quantity, concept, price, discount) + VALUES( vNewTicket, vItemFk, vQuantity, vConcept, vPrice, vDiscount ); + + SET vSaleNew = LAST_INSERT_ID(); + + INSERT INTO vn.saleComponent(saleFk,componentFk,`value`) + SELECT vSaleNew,componentFk,`value` + FROM vn.saleComponent + WHERE saleFk = vSaleMain; + + FETCH cSales INTO vSaleMain, vItemFk, vQuantity, vConcept, vPrice, vDiscount; + + END WHILE; + CLOSE cSales; + + SET vDone := 0; + OPEN cTicketServices; + FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk; + + WHILE NOT vDone DO + + INSERT INTO vn.ticketService(description, quantity, price, taxClassFk, ticketFk, ticketServiceTypeFk) + VALUES(vDescription, vQuantity, vPrice, vTaxClassFk, vNewTicket, vTicketServiceTypeFk); + + FETCH cTicketServices INTO vDescription, vQuantity, vPrice, vTaxClassFk, vTicketServiceTypeFk; + + END WHILE; + CLOSE cTicketServices; + + INSERT INTO vn.ticketRefund(refundTicketFk, originalTicketFk) + VALUES(vNewTicket, vOriginTicket); + +END$$ +DELIMITER ; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index 51de5f6f7..9450103c7 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -107,10 +107,36 @@ INSERT INTO `account`.`user`(`id`,`name`, `nickname`, `password`,`role`,`active` INSERT INTO `account`.`account`(`id`) SELECT id FROM `account`.`user`; +INSERT INTO `vn`.`educationLevel` (`id`, `name`) + VALUES + (1, 'ESTUDIOS PRIMARIOS COMPLETOS'), + (2, 'ENSEÑANZAS DE BACHILLERATO'); + INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`) SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9 FROM `vn`.`user`; +ALTER TABLE `vn`.`worker` ADD `originCountryFk` mediumint(8) unsigned NULL COMMENT 'País de origen'; +ALTER TABLE `vn`.`worker` ADD `educationLevelFk` SMALLINT NULL; +ALTER TABLE `vn`.`worker` ADD `SSN` varchar(15) NULL; +ALTER TABLE `vn`.`worker` CHANGE `maritalStatus__` `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; +ALTER TABLE `vn`.`worker` MODIFY COLUMN `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL; +ALTER TABLE `vn`.`worker` CHANGE `maritalStatus` maritalStatus enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL AFTER sectorFk; +ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_2` FOREIGN KEY (`educationLevelFk`) REFERENCES `vn`.`educationLevel`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_1` FOREIGN KEY (`originCountryFk`) REFERENCES `vn`.`country`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE; + +UPDATE `vn`.`worker` `w` + SET `maritalStatus` = 'S'; + +UPDATE `vn`.`worker` `w` + SET `originCountryFk` = '1'; + +UPDATE `vn`.`worker` `w` + SET `educationLevelFk` = '2'; + +UPDATE `vn`.`worker` `w` + SET `SSN` = '123456789123'; + UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20; UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9; UPDATE `vn`.`worker` SET bossFk = 19 WHERE id = 18; @@ -351,18 +377,18 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`) INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`,`mailAddress`,`hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`, `businessTypeFk`) VALUES - (1101, 'Bruce Wayne', '84612325V', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), - (1102, 'Petter Parker', '87945234L', 'Spider man', 'Aunt May', '20 Ingram Street, Queens, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), - (1103, 'Clark Kent', '06815934E', 'Super man', 'lois lane', '344 Clinton Street, Apartament 3-D', 'Silla', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 0, 19, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), - (1104, 'Tony Stark', '06089160W', 'Iron man', 'Pepper Potts', '10880 Malibu Point, 90265', 'Silla', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), - (1105, 'Max Eisenhardt', '251628698', 'Magneto', 'Rogue', 'Unkvn.VN_NOWn Whereabouts', 'Silla', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 8, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1, 'florist'), - (1106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'City of New York, New York, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1, 'florist'), - (1107, 'Hank Pym', '09854837G', 'Ant man', 'Hawk', 'Anthill, San Francisco, California', 'Silla', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1, 'florist'), - (1108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist'), - (1109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist'), - (1110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist'), - (1111, 'Missing', NULL, 'Missing man', 'Anton', 'The space, Universe far away', 'Silla', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, NULL), - (1112, 'Trash', NULL, 'Garbage man', 'Unkvn.VN_NOWn name', 'New York city, Underground', 'Silla', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5,vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, NULL); + (1101, 'Bruce Wayne', '84612325V', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Silla', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), + (1102, 'Petter Parker', '87945234L', 'Spider man', 'Aunt May', '20 Ingram Street, Queens, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), + (1103, 'Clark Kent', '06815934E', 'Super man', 'lois lane', '344 Clinton Street, Apartament 3-D', 'Silla', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), + (1104, 'Tony Stark', '06089160W', 'Iron man', 'Pepper Potts', '10880 Malibu Point, 90265', 'Silla', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'), + (1105, 'Max Eisenhardt', '251628698', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Silla', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1, 'florist'), + (1106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'City of New York, New York, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1, 'florist'), + (1107, 'Hank Pym', '09854837G', 'Ant man', 'Hawk', 'Anthill, San Francisco, California', 'Silla', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1, 'florist'), + (1108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Silla', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist'), + (1109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Silla', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist'), + (1110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Silla', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist'), + (1111, 'Missing', NULL, 'Missing man', 'Anton', 'The space, Universe far away', 'Silla', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, NULL), + (1112, 'Trash', NULL, 'Garbage man', 'Unknown name', 'New York city, Underground', 'Silla', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, vn.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 1, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, NULL); INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`) SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'SILLA', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, vn.VN_CURDATE(), 1 @@ -2488,6 +2514,13 @@ INSERT INTO `vn`.`invoiceInTax` (`invoiceInFk`, `taxableBase`, `expenceFk`, `for (6, 29.95, '7001000000', NULL, 7, 20), (7, 58.64, '6210000567', NULL, 8, 20); +INSERT INTO `vn`.`invoiceInIntrastat` (`invoiceInFk`, `net`, `intrastatFk`, `amount`, `stems`, `countryFk`) + VALUES + (1, 30.50, 5080000, 10.00, 162, 5), + (1, 10, 6021010, 20.00, 205, 5), + (2, 13.20, 5080000, 15.00, 580, 5), + (2, 16.10, 6021010, 25.00, 80, 5); + INSERT INTO `vn`.`ticketRecalc`(`ticketFk`) SELECT `id` FROM `vn`.`ticket` t diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 789c800b5..7bf56e2c8 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -181,12 +181,12 @@ let actions = { }, reloadSection: async function(state) { - await this.click('vn-icon[icon="preview"]'); + await this.click('vn-icon[icon="launch"]'); await this.accessToSection(state); }, forceReloadSection: async function(sectionRoute) { - await this.waitToClick('vn-icon[icon="preview"]'); + await this.waitToClick('vn-icon[icon="launch"]'); await this.waitToClick('button[response="accept"]'); await this.waitForSelector('vn-card.summary'); await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 21ed27158..799eb8fe7 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -321,6 +321,12 @@ export default { deleteFirstPhone: 'vn-client-contact vn-icon[icon="delete"]', saveButton: 'button[type=submit]' }, + clientUnpaid: { + hasDataCheckBox: 'vn-client-unpaid vn-check[ng-model="watcher.hasData"]', + dated: 'vn-client-unpaid vn-date-picker[ng-model="$ctrl.clientUnpaid.dated"]', + amount: 'vn-client-unpaid vn-input-number[ng-model="$ctrl.clientUnpaid.amount"]', + saveButton: 'vn-submit[label="Save"]' + }, itemsIndex: { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index tbody tr:nth-child(1)', @@ -392,7 +398,6 @@ export default { name: 'vn-item-basic-data vn-textfield[ng-model="$ctrl.item.name"]', relevancy: 'vn-item-basic-data vn-input-number[ng-model="$ctrl.item.relevancy"]', origin: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]', - compression: 'vn-item-basic-data vn-input-number[ng-model="$ctrl.item.compression"]', generic: 'vn-autocomplete[ng-model="$ctrl.item.genericFk"]', isFragile: 'vn-check[ng-model="$ctrl.item.isFragile"]', longName: 'vn-textfield[ng-model="$ctrl.item.longName"]', @@ -571,7 +576,7 @@ export default { moreMenuUnmarkReseved: 'vn-item[name="unreserve"]', moreMenuUpdateDiscount: 'vn-item[name="discount"]', moreMenuRecalculatePrice: 'vn-item[name="calculatePrice"]', - moreMenuPayBack: 'vn-item[name="payBack"]', + moreMenuRefund: 'vn-item[name="refund"]', moreMenuUpdateDiscountInput: 'vn-input-number[ng-model="$ctrl.edit.discount"] input', transferQuantityInput: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable > span > text', transferQuantityCell: '.vn-popover.shown vn-table > div > vn-tbody > vn-tr > vn-td-editable', @@ -586,6 +591,7 @@ export default { firstSalePriceInput: '.vn-popover.shown input[ng-model="$ctrl.field"]', firstSaleDiscount: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(10) > span', firstSaleDiscountInput: '.vn-popover.shown [ng-model="$ctrl.field"]', + saveSaleDiscountButton: '.vn-popover.shown vn-button[label="Save"]', firstSaleImport: 'vn-ticket-sale:nth-child(1) vn-td:nth-child(11)', firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleColour: 'vn-ticket-sale vn-tr:nth-child(1) vn-fetched-tags section', @@ -958,7 +964,7 @@ export default { supplierRef: 'vn-invoice-in-summary vn-label-value:nth-child(2) > section > span' }, invoiceInDescriptor: { - summaryIcon: 'vn-invoice-in-descriptor a[title="Preview"]', + summaryIcon: 'vn-invoice-in-descriptor a[title="Go to module summary"]', moreMenu: 'vn-invoice-in-descriptor vn-icon-button[icon=more_vert]', moreMenuDeleteInvoiceIn: '.vn-menu [name="deleteInvoice"]', moreMenuCloneInvoiceIn: '.vn-menu [name="cloneInvoice"]', diff --git a/e2e/paths/02-client/21_defaulter.spec.js b/e2e/paths/02-client/21_defaulter.spec.js index d51f2113f..c7640d028 100644 --- a/e2e/paths/02-client/21_defaulter.spec.js +++ b/e2e/paths/02-client/21_defaulter.spec.js @@ -28,7 +28,7 @@ describe('Client defaulter path', () => { const salesPersonName = await page.waitToGetProperty(selectors.clientDefaulter.firstSalesPersonName, 'innerText'); - expect(clientName).toEqual('Batman'); + expect(clientName).toEqual('Ororo Munroe'); expect(salesPersonName).toEqual('salesPersonNick'); }); diff --git a/e2e/paths/02-client/22_unpaid.spec.js b/e2e/paths/02-client/22_unpaid.spec.js new file mode 100644 index 000000000..441dba96f --- /dev/null +++ b/e2e/paths/02-client/22_unpaid.spec.js @@ -0,0 +1,41 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Client unpaid path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('administrative', 'client'); + await page.accessToSearchResult('Charles Xavier'); + await page.accessToSection('client.card.unpaid'); + await page.waitForState('client.card.unpaid'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should set cliet unpaid', async() => { + await page.waitToClick(selectors.clientUnpaid.hasDataCheckBox); + + await page.pickDate(selectors.clientUnpaid.dated); + await page.write(selectors.clientUnpaid.amount, '500'); + }); + + it('should save unpaid', async() => { + await page.waitToClick(selectors.clientUnpaid.saveButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toContain('Data saved!'); + }); + + it('should confirm the unpaid have been saved', async() => { + await page.reloadSection('client.card.unpaid'); + const result = await page.waitToGetProperty(selectors.clientUnpaid.amount, 'value'); + + expect(result).toEqual('500'); + }); +}); diff --git a/e2e/paths/03-worker/04_time_control.spec.js b/e2e/paths/03-worker/04_time_control.spec.js index 137d94c74..5709e6207 100644 --- a/e2e/paths/03-worker/04_time_control.spec.js +++ b/e2e/paths/03-worker/04_time_control.spec.js @@ -99,8 +99,8 @@ describe('Worker time control path', () => { expect(result).toEqual(scanTime); }); - // 3736 check proc vn.timeControl_calculate - xit(`should check Hank Pym worked 6:40 hours`, async() => { + + it(`should check Hank Pym worked 6:40 hours`, async() => { await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '06:40 h.'); }); }); diff --git a/e2e/paths/04-item/02_basic_data.spec.js b/e2e/paths/04-item/02_basic_data.spec.js index 0bbb6ad12..a663ea3bb 100644 --- a/e2e/paths/04-item/02_basic_data.spec.js +++ b/e2e/paths/04-item/02_basic_data.spec.js @@ -30,8 +30,6 @@ describe('Item Edit basic data path', () => { await page.autocompleteSearch(selectors.itemBasicData.origin, 'Spain'); await page.clearInput(selectors.itemBasicData.relevancy); await page.write(selectors.itemBasicData.relevancy, '1'); - await page.clearInput(selectors.itemBasicData.compression); - await page.write(selectors.itemBasicData.compression, '2'); await page.clearInput(selectors.itemBasicData.generic); await page.autocompleteSearch(selectors.itemBasicData.generic, '16'); await page.waitToClick(selectors.itemBasicData.isActiveCheckbox); @@ -96,13 +94,6 @@ describe('Item Edit basic data path', () => { expect(result).toEqual('Spain'); }); - it(`should confirm the item compression was edited`, async() => { - const result = await page - .waitToGetProperty(selectors.itemBasicData.compression, 'value'); - - expect(result).toEqual('2'); - }); - it(`should confirm the item generic was edited`, async() => { const result = await page .waitToGetProperty(selectors.itemBasicData.generic, 'value'); diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index 5078d5b91..d776f417d 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -175,7 +175,8 @@ describe('Ticket Edit sale path', () => { it('should update the discount', async() => { await page.waitToClick(selectors.ticketSales.firstSaleDiscount); await page.waitForSelector(selectors.ticketSales.firstSaleDiscountInput); - await page.type(selectors.ticketSales.firstSaleDiscountInput, '50\u000d'); + await page.type(selectors.ticketSales.firstSaleDiscountInput, '50'); + await page.waitToClick(selectors.ticketSales.saveSaleDiscountButton); const message = await page.waitForSnackbar(); expect(message.text).toContain('Data saved!'); @@ -212,10 +213,10 @@ describe('Ticket Edit sale path', () => { await page.accessToSection('ticket.card.sale'); }); - it('should select the third sale and create a pay back', async() => { + it('should select the third sale and create a refund', async() => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); - await page.waitToClick(selectors.ticketSales.moreMenuPayBack); + await page.waitToClick(selectors.ticketSales.moreMenuRefund); await page.waitForState('ticket.card.sale'); }); diff --git a/e2e/paths/10-travel/03_descriptor.spec.js b/e2e/paths/10-travel/03_descriptor.spec.js index 619228f35..f459ef043 100644 --- a/e2e/paths/10-travel/03_descriptor.spec.js +++ b/e2e/paths/10-travel/03_descriptor.spec.js @@ -134,7 +134,7 @@ describe('Travel descriptor path', () => { }); it('should navigate to the summary and then clone the travel and its entries using the descriptor menu to get redirected to the cloned travel basic data', async() => { - await page.waitToClick('vn-icon[icon="preview"]'); // summary icon + await page.waitToClick('vn-icon[icon="launch"]'); await page.waitForState('travel.card.summary'); await page.waitForTimeout(1000); await page.waitToClick(selectors.travelDescriptor.dotMenu); diff --git a/front/core/styles/icons/salixfont.css b/front/core/styles/icons/salixfont.css index e37ccbc1f..530772246 100644 --- a/front/core/styles/icons/salixfont.css +++ b/front/core/styles/icons/salixfont.css @@ -23,10 +23,21 @@ -moz-osx-font-smoothing: grayscale; } - +.icon-agency-term:before { + content: "\e950"; +} +.icon-deaulter:before { + content: "\e94b"; +} .icon-100:before { content: "\e95a"; } +.icon-history:before { + content: "\e968"; +} +.icon-Person:before { + content: "\e901"; +} .icon-accessory:before { content: "\e90a"; } @@ -74,6 +85,7 @@ } .icon-bucket:before { content: "\e97a"; + color: #000; } .icon-buscaman:before { content: "\e93b"; @@ -83,26 +95,32 @@ } .icon-calc_volum .path1:before { content: "\e915"; + color: rgb(0, 0, 0); } .icon-calc_volum .path2:before { content: "\e916"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path3:before { content: "\e917"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path4:before { content: "\e918"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path5:before { content: "\e919"; margin-left: -1em; + color: rgb(0, 0, 0); } .icon-calc_volum .path6:before { content: "\e91a"; margin-left: -1em; + color: rgb(255, 255, 255); } .icon-calendar:before { content: "\e93d"; @@ -137,9 +155,6 @@ .icon-credit:before { content: "\e927"; } -.icon-defaulter:before { - content: "\e94b"; -} .icon-deletedTicket:before { content: "\e935"; } @@ -206,9 +221,6 @@ .icon-headercol:before { content: "\e958"; } -.icon-history:before { - content: "\e968"; -} .icon-info:before { content: "\e952"; } @@ -281,9 +293,6 @@ .icon-pbx:before { content: "\e93c"; } -.icon-Person:before { - content: "\e901"; -} .icon-pets:before { content: "\e947"; } diff --git a/front/core/styles/icons/salixfont.eot b/front/core/styles/icons/salixfont.eot index 9325d3dae..48cc86413 100644 Binary files a/front/core/styles/icons/salixfont.eot and b/front/core/styles/icons/salixfont.eot differ diff --git a/front/core/styles/icons/salixfont.svg b/front/core/styles/icons/salixfont.svg index 22c33c181..2b8b1ac8a 100644 --- a/front/core/styles/icons/salixfont.svg +++ b/front/core/styles/icons/salixfont.svg @@ -15,7 +15,7 @@ - + @@ -87,6 +87,7 @@ + diff --git a/front/core/styles/icons/salixfont.ttf b/front/core/styles/icons/salixfont.ttf index 05df06213..4b090731c 100644 Binary files a/front/core/styles/icons/salixfont.ttf and b/front/core/styles/icons/salixfont.ttf differ diff --git a/front/core/styles/icons/salixfont.woff b/front/core/styles/icons/salixfont.woff index 70fca2294..502fed118 100644 Binary files a/front/core/styles/icons/salixfont.woff and b/front/core/styles/icons/salixfont.woff differ diff --git a/front/salix/components/descriptor-popover/style.scss b/front/salix/components/descriptor-popover/style.scss index 6ae8675bf..7203c8e8e 100644 --- a/front/salix/components/descriptor-popover/style.scss +++ b/front/salix/components/descriptor-popover/style.scss @@ -4,8 +4,14 @@ vn-descriptor-content > .descriptor { width: 256px; - & > .header > a:first-child { - visibility: hidden; - } + & > .header { + a:first-child { + display: none; + } + vn-icon-button:nth-child(2) { + display: block; + } + } + } } diff --git a/front/salix/components/descriptor/index.html b/front/salix/components/descriptor/index.html index 5b4c6f12c..e7a5b6297 100644 --- a/front/salix/components/descriptor/index.html +++ b/front/salix/components/descriptor/index.html @@ -12,10 +12,15 @@ name="goToModuleIndex"> + + - + vn-icon-button:nth-child(2) { + display: none; + } } & > .body { display: block; diff --git a/front/salix/locale/es.yml b/front/salix/locale/es.yml index 5e877c372..4e93ae18e 100644 --- a/front/salix/locale/es.yml +++ b/front/salix/locale/es.yml @@ -13,6 +13,8 @@ Preview: Vista previa Profile: Perfil Push on applications menu: Para abrir un módulo pulsa en el menú de aplicaciones Go to module index: Ir al índice del módulo +Go to module summary: Ir a la vista previa del módulo +Show summary: Mostrar vista previa What is new: Novedades de la versión Settings: Ajustes diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 9310ae436..77bd21780 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -219,7 +219,7 @@ "The worker has a marked absence that day": "El trabajador tiene marcada una ausencia ese día", "You can not modify is pay method checked": "No se puede modificar el campo método de pago validado", "Can't transfer claimed sales": "No puedes transferir lineas reclamadas", - "You don't have privileges to create pay back": "No tienes permisos para crear un abono", + "You don't have privileges to create refund": "No tienes permisos para crear un abono", "The item is required": "El artículo es requerido", "The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo", "date in the future": "Fecha en el futuro", diff --git a/loopback/server/datasources.json b/loopback/server/datasources.json index 0df03882c..8b741ec97 100644 --- a/loopback/server/datasources.json +++ b/loopback/server/datasources.json @@ -15,7 +15,8 @@ "legacyUtcDateProcessing": false, "timezone": "local", "connectTimeout": 40000, - "acquireTimeout": 20000 + "acquireTimeout": 20000, + "waitForConnections": true }, "osticket": { "connector": "memory", diff --git a/modules/account/front/descriptor/index.html b/modules/account/front/descriptor/index.html index d01e953c2..c709c1ec0 100644 --- a/modules/account/front/descriptor/index.html +++ b/modules/account/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.user.nickname" + summary="$ctrl.$.summary"> Change password + + + \ No newline at end of file diff --git a/modules/claim/back/methods/claim/filter.js b/modules/claim/back/methods/claim/filter.js index f4eecae6d..e86830200 100644 --- a/modules/claim/back/methods/claim/filter.js +++ b/modules/claim/back/methods/claim/filter.js @@ -27,7 +27,7 @@ module.exports = Self => { http: {source: 'query'} }, { - arg: 'client', + arg: 'clientName', type: 'string', description: 'The worker name', http: {source: 'query'} @@ -94,14 +94,19 @@ module.exports = Self => { ? {'cl.id': value} : { or: [ - {'cl.socialName': {like: `%${value}%`}} + {'cl.clientName': {like: `%${value}%`}} ] }; + case 'clientName': + return {'cl.clientName': {like: `%${value}%`}}; + case 'clientFk': + return {'cl.clientFk': value}; case 'id': case 'claimStateFk': case 'priority': return {[`cl.${param}`]: value}; case 'salesPersonFk': + return {'cl.salesPersonFk': value}; case 'attenderFk': return {'cl.workerFk': value}; case 'created': @@ -123,13 +128,14 @@ module.exports = Self => { SELECT cl.id, cl.clientFk, - c.socialName, + c.name AS clientName, cl.workerFk, u.name AS workerName, cs.description, cl.created, cs.priority, - cl.claimStateFk + cl.claimStateFk, + c.salesPersonFk FROM claim cl LEFT JOIN client c ON c.id = cl.clientFk LEFT JOIN worker w ON w.id = cl.workerFk diff --git a/modules/claim/back/methods/claim/specs/filter.spec.js b/modules/claim/back/methods/claim/specs/filter.spec.js index c54318e45..b26afe8c4 100644 --- a/modules/claim/back/methods/claim/specs/filter.spec.js +++ b/modules/claim/back/methods/claim/specs/filter.spec.js @@ -25,7 +25,7 @@ describe('claim filter()', () => { try { const options = {transaction: tx}; - const result = await app.models.Claim.filter({args: {filter: {}, search: 'Iron man'}}, null, options); + const result = await app.models.Claim.filter({args: {filter: {}, search: 'Tony Stark'}}, null, options); expect(result.length).toEqual(1); expect(result[0].id).toEqual(4); diff --git a/modules/claim/front/descriptor/index.html b/modules/claim/front/descriptor/index.html index 1337c6242..56fd0bb35 100644 --- a/modules/claim/front/descriptor/index.html +++ b/modules/claim/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.claim.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/claim/front/index/index.html b/modules/claim/front/index/index.html index 341d6eb2f..102e27245 100644 --- a/modules/claim/front/index/index.html +++ b/modules/claim/front/index/index.html @@ -10,16 +10,16 @@ - - - diff --git a/modules/claim/front/index/index.js b/modules/claim/front/index/index.js index bf0cb25c0..084618e16 100644 --- a/modules/claim/front/index/index.js +++ b/modules/claim/front/index/index.js @@ -11,11 +11,11 @@ class Controller extends Section { }, columns: [ { - field: 'clientFk', + field: 'clientName', autocomplete: { url: 'Clients', - showField: 'socialName', - valueField: 'socialName' + showField: 'name', + valueField: 'name' } }, { @@ -46,21 +46,12 @@ class Controller extends Section { exprBuilder(param, value) { switch (param) { + case 'clientName': + return {'cl.clientName': {like: `%${value}%`}}; case 'clientFk': - return {['cl.socialName']: value}; - case 'id': case 'claimStateFk': - case 'priority': + case 'workerFk': return {[`cl.${param}`]: value}; - case 'salesPersonFk': - case 'attenderFk': - return {'cl.workerFk': value}; - case 'created': - value.setHours(0, 0, 0, 0); - to = new Date(value); - to.setHours(23, 59, 59, 999); - - return {'cl.created': {between: [value, to]}}; } } diff --git a/modules/claim/front/search-panel/index.html b/modules/claim/front/search-panel/index.html index 22faf9ec4..d522763a1 100644 --- a/modules/claim/front/search-panel/index.html +++ b/modules/claim/front/search-panel/index.html @@ -18,7 +18,7 @@ + ng-model="filter.clientName"> diff --git a/modules/client/back/methods/client/checkDuplicated.js b/modules/client/back/methods/client/checkDuplicated.js new file mode 100644 index 000000000..acaffbf42 --- /dev/null +++ b/modules/client/back/methods/client/checkDuplicated.js @@ -0,0 +1,64 @@ +module.exports = Self => { + Self.remoteMethod('checkDuplicatedData', { + description: 'Checks if a client has same email, mobile or phone than other client and send an email', + accepts: [{ + arg: 'id', + type: 'number', + required: true, + description: 'The client id' + }], + returns: { + type: 'object', + root: true + }, + http: { + verb: 'GET', + path: '/:id/checkDuplicatedData' + } + }); + + Self.checkDuplicatedData = async function(id, options) { + const myOptions = {}; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + const client = await Self.app.models.Client.findById(id, myOptions); + + const emails = client.email ? client.email.split(',') : null; + + const findParams = []; + if (emails.length) { + for (let email of emails) + findParams.push({email: email}); + } + + if (client.phone) + findParams.push({phone: client.phone}); + + if (client.mobile) + findParams.push({mobile: client.mobile}); + + const filterObj = { + where: { + and: [ + {or: findParams}, + {id: {neq: client.id}} + ] + } + }; + + const clientSameData = await Self.findOne(filterObj, myOptions); + + if (clientSameData) { + await Self.app.models.Mail.create({ + receiver: 'direccioncomercial@verdnatura.es', + subject: `Cliente con email/teléfono/móvil duplicados`, + body: 'El cliente ' + client.id + ' comparte alguno de estos datos con el cliente ' + clientSameData.id + + '\n- Email: ' + client.email + + '\n- Teléfono: ' + client.phone + + '\n- Móvil: ' + client.mobile + }, myOptions); + } + }; +}; diff --git a/modules/client/back/methods/client/specs/checkDuplicated.spec.js b/modules/client/back/methods/client/specs/checkDuplicated.spec.js new file mode 100644 index 000000000..1b682ca35 --- /dev/null +++ b/modules/client/back/methods/client/specs/checkDuplicated.spec.js @@ -0,0 +1,24 @@ +const models = require('vn-loopback/server/server').models; + +describe('client checkDuplicated()', () => { + it('should send an mail if mobile/phone/email is duplicated', async() => { + const tx = await models.Client.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const id = 1110; + const mailModel = models.Mail; + spyOn(mailModel, 'create'); + + await models.Client.checkDuplicatedData(id, options); + + expect(mailModel.create).toHaveBeenCalled(); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); +}); diff --git a/modules/client/back/methods/client/specs/sendSms.spec.js b/modules/client/back/methods/client/specs/sendSms.spec.js index 121d427ce..47e788184 100644 --- a/modules/client/back/methods/client/specs/sendSms.spec.js +++ b/modules/client/back/methods/client/specs/sendSms.spec.js @@ -1,9 +1,7 @@ const models = require('vn-loopback/server/server').models; -const soap = require('soap'); describe('client sendSms()', () => { it('should now send a message and log it', async() => { - spyOn(soap, 'createClientAsync').and.returnValue('a so fake client'); const tx = await models.Client.beginTransaction({}); try { diff --git a/modules/client/back/methods/client/specs/updateAddress.spec.js b/modules/client/back/methods/client/specs/updateAddress.spec.js index efaa1b93c..5597c6e5a 100644 --- a/modules/client/back/methods/client/specs/updateAddress.spec.js +++ b/modules/client/back/methods/client/specs/updateAddress.spec.js @@ -6,6 +6,12 @@ describe('Address updateAddress', () => { const provinceId = 5; const incotermsId = 'FAS'; const customAgentOneId = 1; + const employeeId = 1; + const ctx = { + req: { + accessToken: {userId: employeeId} + } + }; it('should throw the non uee member error if no incoterms is defined', async() => { const tx = await models.Client.beginTransaction({}); @@ -14,11 +20,9 @@ describe('Address updateAddress', () => { try { const options = {transaction: tx}; - const ctx = { - args: { - provinceFk: provinceId, - customsAgentFk: customAgentOneId - } + ctx.args = { + provinceFk: provinceId, + customsAgentFk: customAgentOneId }; await models.Client.updateAddress(ctx, clientId, addressId, options); @@ -40,11 +44,9 @@ describe('Address updateAddress', () => { try { const options = {transaction: tx}; - const ctx = { - args: { - provinceFk: provinceId, - incotermsFk: incotermsId - } + ctx.args = { + provinceFk: provinceId, + incotermsFk: incotermsId }; await models.Client.updateAddress(ctx, clientId, addressId, options); @@ -66,13 +68,11 @@ describe('Address updateAddress', () => { const options = {transaction: tx}; const expectedResult = 'My edited address'; - const ctx = { - args: { - provinceFk: provinceId, - nickname: expectedResult, - incotermsFk: incotermsId, - customsAgentFk: customAgentOneId - } + ctx.args = { + provinceFk: provinceId, + nickname: expectedResult, + incotermsFk: incotermsId, + customsAgentFk: customAgentOneId }; await models.Client.updateAddress(ctx, clientId, addressId, options); @@ -88,6 +88,48 @@ describe('Address updateAddress', () => { } }); + it('should return an error for a user without enough privileges', async() => { + const tx = await models.Client.beginTransaction({}); + + try { + const options = {transaction: tx}; + ctx.args = { + isLogifloraAllowed: true + }; + + await models.Client.updateAddress(ctx, clientId, addressId, options); + await tx.rollback(); + } catch (e) { + await tx.rollback(); + error = e; + } + + expect(error.message).toEqual(`You don't have enough privileges`); + }); + + it('should update isLogifloraAllowed', async() => { + const tx = await models.Client.beginTransaction({}); + const salesAssistantId = 21; + + try { + const options = {transaction: tx}; + ctx.req.accessToken.userId = salesAssistantId; + ctx.args = { + isLogifloraAllowed: true + }; + + await models.Client.updateAddress(ctx, clientId, addressId, options); + const address = await models.Address.findById(addressId, null, options); + + expect(address.isLogifloraAllowed).toEqual(true); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + it('should update the address', async() => { const tx = await models.Client.beginTransaction({}); @@ -95,10 +137,8 @@ describe('Address updateAddress', () => { const options = {transaction: tx}; const expectedResult = 'My second time edited address'; - const ctx = { - args: { - nickname: expectedResult - } + ctx.args = { + nickname: expectedResult }; await models.Client.updateAddress(ctx, clientId, addressId, options); diff --git a/modules/client/back/methods/client/specs/updatePortfolio.spec.js b/modules/client/back/methods/client/specs/updatePortfolio.spec.js index 7b594bf74..4830156fc 100644 --- a/modules/client/back/methods/client/specs/updatePortfolio.spec.js +++ b/modules/client/back/methods/client/specs/updatePortfolio.spec.js @@ -26,10 +26,9 @@ describe('Client updatePortfolio', () => { throw e; } }); - + // task 3817 xit('should keep the same portfolioWeight when a salesperson is unassigned of a client', async() => { const salesPersonId = 19; - const tx = await models.Client.beginTransaction({}); try { diff --git a/modules/client/back/methods/client/updateAddress.js b/modules/client/back/methods/client/updateAddress.js index d1a498fe7..d7e20b876 100644 --- a/modules/client/back/methods/client/updateAddress.js +++ b/modules/client/back/methods/client/updateAddress.js @@ -68,6 +68,10 @@ module.exports = function(Self) { { arg: 'isEqualizated', type: 'boolean' + }, + { + arg: 'isLogifloraAllowed', + type: 'boolean' } ], returns: { @@ -83,11 +87,16 @@ module.exports = function(Self) { Self.updateAddress = async(ctx, clientId, addressId, options) => { const models = Self.app.models; const args = ctx.args; + const userId = ctx.req.accessToken.userId; const myOptions = {}; + const isSalesAssistant = await models.Account.hasRole(userId, 'salesAssistant', myOptions); if (typeof options == 'object') Object.assign(myOptions, options); + if (args.isLogifloraAllowed && !isSalesAssistant) + throw new UserError(`You don't have enough privileges`); + const address = await models.Address.findOne({ where: { id: addressId, diff --git a/modules/client/back/methods/defaulter/filter.js b/modules/client/back/methods/defaulter/filter.js index 49dbef388..889abba3a 100644 --- a/modules/client/back/methods/defaulter/filter.js +++ b/modules/client/back/methods/defaulter/filter.js @@ -56,7 +56,7 @@ module.exports = Self => { FROM ( SELECT DISTINCT c.id clientFk, - c.socialName clientName, + c.name clientName, c.salesPersonFk, u.nickname salesPersonName, d.amount, @@ -80,6 +80,7 @@ module.exports = Self => { stmt.merge(conn.makeWhere(filter.where)); stmt.merge(`GROUP BY d.clientFk`); stmt.merge(conn.makeOrderBy(filter.order)); + stmt.merge(conn.makeLimit(filter)); const itemsIndex = stmts.push(stmt) - 1; const sql = ParameterizedSQL.join(stmts, ';'); diff --git a/modules/client/back/methods/defaulter/specs/filter.spec.js b/modules/client/back/methods/defaulter/specs/filter.spec.js index ca14d1e43..0a970823e 100644 --- a/modules/client/back/methods/defaulter/specs/filter.spec.js +++ b/modules/client/back/methods/defaulter/specs/filter.spec.js @@ -47,12 +47,12 @@ describe('defaulter filter()', () => { try { const options = {transaction: tx}; - const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'spider'}}; + const ctx = {req: {accessToken: {userId: authUserId}}, args: {search: 'Petter Parker'}}; const result = await models.Defaulter.filter(ctx, null, options); const firstRow = result[0]; - expect(firstRow.clientName).toEqual('Spider man'); + expect(firstRow.clientName).toEqual('Petter Parker'); await tx.rollback(); } catch (e) { diff --git a/modules/client/back/model-config.json b/modules/client/back/model-config.json index 38f5c9427..b6bf715b1 100644 --- a/modules/client/back/model-config.json +++ b/modules/client/back/model-config.json @@ -44,6 +44,9 @@ "ClientType": { "dataSource": "vn" }, + "ClientUnpaid": { + "dataSource": "vn" + }, "Defaulter": { "dataSource": "vn" }, diff --git a/modules/client/back/models/address.json b/modules/client/back/models/address.json index 8daac0466..dd533cb32 100644 --- a/modules/client/back/models/address.json +++ b/modules/client/back/models/address.json @@ -50,6 +50,9 @@ }, "isEqualizated": { "type": "boolean" + }, + "isLogifloraAllowed": { + "type": "boolean" } }, "validations": [], diff --git a/modules/client/back/models/client-unpaid.json b/modules/client/back/models/client-unpaid.json new file mode 100644 index 000000000..a3d1a684c --- /dev/null +++ b/modules/client/back/models/client-unpaid.json @@ -0,0 +1,28 @@ +{ + "name": "ClientUnpaid", + "base": "VnModel", + "options": { + "mysql": { + "table": "clientUnpaid" + } + }, + "properties": { + "clientFk": { + "type": "number", + "id": true + }, + "dated": { + "type": "date" + }, + "amount": { + "type": "Number" + } + }, + "relations": { + "client": { + "type": "belongsTo", + "model": "Client", + "foreignKey": "clientFk" + } + } +} \ No newline at end of file diff --git a/modules/client/back/models/client.js b/modules/client/back/models/client.js index 9ec45f58d..5ccc1ec64 100644 --- a/modules/client/back/models/client.js +++ b/modules/client/back/models/client.js @@ -30,6 +30,7 @@ module.exports = Self => { require('../methods/client/consumption')(Self); require('../methods/client/createReceipt')(Self); require('../methods/client/updatePortfolio')(Self); + require('../methods/client/checkDuplicated')(Self); // Validations diff --git a/modules/client/front/address/edit/index.html b/modules/client/front/address/edit/index.html index 83f251de5..1f0b7d30a 100644 --- a/modules/client/front/address/edit/index.html +++ b/modules/client/front/address/edit/index.html @@ -38,7 +38,13 @@ label="Is equalizated" ng-model="$ctrl.address.isEqualizated" vn-acl="administrative, salesAssistant"> - + + + + + { const query = `Clients/updatePortfolio`; this.$http.get(query); + this.$http.get(`Clients/${this.$params.id}/checkDuplicatedData`); }); } } diff --git a/modules/client/front/create/index.js b/modules/client/front/create/index.js index 1aa21c91e..9ca58ed10 100644 --- a/modules/client/front/create/index.js +++ b/modules/client/front/create/index.js @@ -10,9 +10,10 @@ export default class Controller extends Section { } onSubmit() { - return this.$.watcher.submit().then( - json => this.$state.go('client.card.basicData', {id: json.data.id}) - ); + return this.$.watcher.submit().then(json => { + this.$state.go('client.card.basicData', {id: json.data.id}); + this.$http.get(`Clients/${this.client.id}/checkDuplicatedData`); + }); } get province() { diff --git a/modules/client/front/defaulter/index.html b/modules/client/front/defaulter/index.html index 59f7b7d67..92664079c 100644 --- a/modules/client/front/defaulter/index.html +++ b/modules/client/front/defaulter/index.html @@ -49,7 +49,7 @@ model="model"> -
+ Id + Client Created + Worker @@ -40,7 +40,7 @@ - {{::claim.socialName}} + {{::claim.clientName}} {{::claim.created | date:'dd/MM/yyyy'}} + Client diff --git a/modules/client/front/defaulter/index.js b/modules/client/front/defaulter/index.js index 82719bef0..80f510bf2 100644 --- a/modules/client/front/defaulter/index.js +++ b/modules/client/front/defaulter/index.js @@ -13,11 +13,11 @@ export default class Controller extends Section { }, columns: [ { - field: 'clientName', + field: 'clientFk', autocomplete: { url: 'Clients', - showField: 'socialName', - valueField: 'socialName' + showField: 'name', + valueField: 'id' } }, { @@ -114,7 +114,7 @@ export default class Controller extends Section { switch (param) { case 'creditInsurance': case 'amount': - case 'clientName': + case 'clientFk': case 'workerFk': case 'salesPersonFk': return {[`d.${param}`]: value}; diff --git a/modules/client/front/defaulter/index.spec.js b/modules/client/front/defaulter/index.spec.js index d7d1a684d..5801fa1f8 100644 --- a/modules/client/front/defaulter/index.spec.js +++ b/modules/client/front/defaulter/index.spec.js @@ -104,15 +104,15 @@ describe('client defaulter', () => { describe('exprBuilder()', () => { it('should search by sales person', () => { - let expr = controller.exprBuilder('salesPersonFk', '5'); + const expr = controller.exprBuilder('salesPersonFk', '5'); expect(expr).toEqual({'d.salesPersonFk': '5'}); }); - it('should search by client name', () => { - let expr = controller.exprBuilder('clientName', '1foo'); + it('should search by client', () => { + const expr = controller.exprBuilder('clientFk', '5'); - expect(expr).toEqual({'d.clientName': '1foo'}); + expect(expr).toEqual({'d.clientFk': '5'}); }); }); }); diff --git a/modules/client/front/descriptor/index.html b/modules/client/front/descriptor/index.html index e75246ebe..de7a86d3b 100644 --- a/modules/client/front/descriptor/index.html +++ b/modules/client/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + diff --git a/modules/client/front/index.js b/modules/client/front/index.js index d9f3a8a17..ea732beea 100644 --- a/modules/client/front/index.js +++ b/modules/client/front/index.js @@ -46,3 +46,4 @@ import './consumption'; import './consumption-search-panel'; import './defaulter'; import './notification'; +import './unpaid'; diff --git a/modules/client/front/locale/es.yml b/modules/client/front/locale/es.yml index 107931377..4eb99318c 100644 --- a/modules/client/front/locale/es.yml +++ b/modules/client/front/locale/es.yml @@ -61,4 +61,5 @@ Log: Historial Consumption: Consumo Compensation Account: Cuenta para compensar Amount to return: Cantidad a devolver -Delivered amount: Cantidad entregada \ No newline at end of file +Delivered amount: Cantidad entregada +Unpaid: Impagado \ No newline at end of file diff --git a/modules/client/front/main/index.js b/modules/client/front/main/index.js index 61cde8b22..1069d3487 100644 --- a/modules/client/front/main/index.js +++ b/modules/client/front/main/index.js @@ -23,6 +23,7 @@ export default class Client extends ModuleMain { case 'id': case 'fi': case 'postcode': + case 'provinceFk': case 'salesPersonFk': return {[param]: value}; } diff --git a/modules/client/front/notification/index.html b/modules/client/front/notification/index.html index f503c95c8..49e4e3c3f 100644 --- a/modules/client/front/notification/index.html +++ b/modules/client/front/notification/index.html @@ -67,7 +67,7 @@ {{::client.id}} @@ -83,7 +83,9 @@ - + +
@@ -153,3 +155,6 @@ + + \ No newline at end of file diff --git a/modules/client/front/routes.json b/modules/client/front/routes.json index 8398a8745..293243470 100644 --- a/modules/client/front/routes.json +++ b/modules/client/front/routes.json @@ -32,7 +32,8 @@ {"state": "client.card.creditInsurance.index", "icon": "icon-solunion"}, {"state": "client.card.contact", "icon": "contact_phone"}, {"state": "client.card.webPayment", "icon": "icon-onlinepayment"}, - {"state": "client.card.dms.index", "icon": "cloud_upload"} + {"state": "client.card.dms.index", "icon": "cloud_upload"}, + {"state": "client.card.unpaid", "icon": "icon-defaulter"} ] } ] @@ -374,6 +375,12 @@ "state": "client.notification", "component": "vn-client-notification", "description": "Notifications" + }, { + "url": "/unpaid", + "state": "client.card.unpaid", + "component": "vn-client-unpaid", + "acl": ["administrative"], + "description": "Unpaid" } ] } diff --git a/modules/client/front/search-panel/index.html b/modules/client/front/search-panel/index.html index 9caf4185b..234cb6f53 100644 --- a/modules/client/front/search-panel/index.html +++ b/modules/client/front/search-panel/index.html @@ -50,6 +50,15 @@ ng-model="filter.postcode"> + + + + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/modules/client/front/unpaid/index.js b/modules/client/front/unpaid/index.js new file mode 100644 index 000000000..a8ff64386 --- /dev/null +++ b/modules/client/front/unpaid/index.js @@ -0,0 +1,14 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +export default class Controller extends Section { + setDefaultDate(hasData) { + if (hasData && !this.clientUnpaid.dated) + this.clientUnpaid.dated = new Date(); + } +} + +ngModule.vnComponent('vnClientUnpaid', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/client/front/unpaid/index.spec.js b/modules/client/front/unpaid/index.spec.js new file mode 100644 index 000000000..bfeb7df19 --- /dev/null +++ b/modules/client/front/unpaid/index.spec.js @@ -0,0 +1,38 @@ +import './index'; + +describe('client unpaid', () => { + describe('Component vnClientUnpaid', () => { + let controller; + + beforeEach(ngModule('client')); + + beforeEach(inject($componentController => { + const $element = angular.element(''); + controller = $componentController('vnClientUnpaid', {$element}); + })); + + describe('setDefaultDate()', () => { + it(`should not set today date if has dated`, () => { + const hasData = true; + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + + controller.clientUnpaid = { + dated: yesterday + }; + controller.setDefaultDate(hasData); + + expect(controller.clientUnpaid.dated).toEqual(yesterday); + }); + + it(`should set today if not has dated`, () => { + const hasData = true; + + controller.clientUnpaid = {}; + controller.setDefaultDate(hasData); + + expect(controller.clientUnpaid.dated).toBeDefined(); + }); + }); + }); +}); diff --git a/modules/client/front/unpaid/locale/es.yml b/modules/client/front/unpaid/locale/es.yml new file mode 100644 index 000000000..d88764407 --- /dev/null +++ b/modules/client/front/unpaid/locale/es.yml @@ -0,0 +1 @@ +Unpaid client: Cliente impagado \ No newline at end of file diff --git a/modules/entry/front/descriptor/index.html b/modules/entry/front/descriptor/index.html index 04bef0024..f0e2439bb 100644 --- a/modules/entry/front/descriptor/index.html +++ b/modules/entry/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.entry.supplier.nickname" + summary="$ctrl.$.summary"> + + + \ No newline at end of file diff --git a/modules/invoiceIn/back/methods/invoice-in/summary.js b/modules/invoiceIn/back/methods/invoice-in/summary.js index acabe29d9..0e55eeaac 100644 --- a/modules/invoiceIn/back/methods/invoice-in/summary.js +++ b/modules/invoiceIn/back/methods/invoice-in/summary.js @@ -64,6 +64,34 @@ module.exports = Self => { }] } }, + { + relation: 'invoiceInIntrastat', + scope: { + fields: [ + 'id', + 'invoiceInFk', + 'net', + 'intrastatFk', + 'amount', + 'stems', + 'countryFk', + 'statisticalValue'], + include: [{ + relation: 'intrastat', + scope: { + fields: [ + 'id', + 'description'] + } + }, + { + relation: 'country', + scope: { + fields: ['code'] + } + }] + } + }, { relation: 'invoiceInTax', scope: { diff --git a/modules/invoiceIn/back/model-config.json b/modules/invoiceIn/back/model-config.json index f0745f53b..6765ae81c 100644 --- a/modules/invoiceIn/back/model-config.json +++ b/modules/invoiceIn/back/model-config.json @@ -8,6 +8,9 @@ "InvoiceInDueDay": { "dataSource": "vn" }, + "InvoiceInIntrastat": { + "dataSource": "vn" + }, "InvoiceInLog": { "dataSource": "vn" } diff --git a/modules/invoiceIn/back/models/invoice-in-intrastat.json b/modules/invoiceIn/back/models/invoice-in-intrastat.json new file mode 100644 index 000000000..65ab1f36a --- /dev/null +++ b/modules/invoiceIn/back/models/invoice-in-intrastat.json @@ -0,0 +1,50 @@ +{ + "name": "InvoiceInIntrastat", + "base": "VnModel", + "options": { + "mysql": { + "table": "invoiceInIntrastat" + } + }, + "properties": { + "id": { + "id": true, + "type": "number", + "description": "Identifier" + }, + "invoiceInFk": { + "type": "number" + }, + "net": { + "type": "number" + }, + "intrastatFk": { + "type": "number" + }, + "amount": { + "type": "number" + }, + "stems": { + "type": "number" + }, + "countryFk": { + "type": "number" + }, + "statisticalValue": { + "type": "number" + } + }, + "relations": { + "intrastat": { + "type": "belongsTo", + "model": "Intrastat", + "foreignKey": "intrastatFk" + }, + "country": { + "type": "belongsTo", + "model": "Country", + "foreignKey": "countryFk" + } + } + +} \ No newline at end of file diff --git a/modules/invoiceIn/back/models/invoice-in.json b/modules/invoiceIn/back/models/invoice-in.json index feb2d9aec..c6a736b06 100644 --- a/modules/invoiceIn/back/models/invoice-in.json +++ b/modules/invoiceIn/back/models/invoice-in.json @@ -64,6 +64,11 @@ "model": "InvoiceInDueDay", "foreignKey": "invoiceInFk" }, + "invoiceInIntrastat": { + "type": "hasMany", + "model": "InvoiceInIntrastat", + "foreignKey": "invoiceInFk" + }, "invoiceInTax": { "type": "hasMany", "model": "InvoiceInTax", diff --git a/modules/invoiceIn/front/descriptor/index.html b/modules/invoiceIn/front/descriptor/index.html index a51743091..33f9ee8c6 100644 --- a/modules/invoiceIn/front/descriptor/index.html +++ b/modules/invoiceIn/front/descriptor/index.html @@ -1,4 +1,7 @@ - + - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/invoiceIn/front/index.js b/modules/invoiceIn/front/index.js index 18e9d73c2..7b6d6a77c 100644 --- a/modules/invoiceIn/front/index.js +++ b/modules/invoiceIn/front/index.js @@ -10,5 +10,6 @@ import './summary'; import './basic-data'; import './tax'; import './dueDay'; +import './intrastat'; import './create'; import './log'; diff --git a/modules/invoiceIn/front/intrastat/index.html b/modules/invoiceIn/front/intrastat/index.html new file mode 100644 index 000000000..cb447132d --- /dev/null +++ b/modules/invoiceIn/front/intrastat/index.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + +
+ + + + {{id | zeroFill:8}}: {{description}} + + + + + + + + + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/modules/invoiceIn/front/intrastat/index.js b/modules/invoiceIn/front/intrastat/index.js new file mode 100644 index 000000000..659929513 --- /dev/null +++ b/modules/invoiceIn/front/intrastat/index.js @@ -0,0 +1,60 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +class Controller extends Section { + set invoceInIntrastat(value) { + this._invoceInIntrastat = value; + + if (value) this.calculateTotals(); + } + + get invoceInIntrastat() { + return this._invoceInIntrastat; + } + + calculateTotals() { + this.amountTotal = 0.0; + this.netTotal = 0.0; + this.stemsTotal = 0.0; + if (!this.invoceInIntrastat) return; + + this.invoceInIntrastat.forEach(intrastat => { + this.amountTotal += intrastat.amount; + this.netTotal += intrastat.net; + this.stemsTotal += intrastat.stems; + }); + } + + add() { + this.$.model.insert({}); + } + + deleteIntrastat($index) { + this.$.model.remove($index); + this.$.model.save().then(() => { + this.vnApp.showSuccess(this.$t('Data saved!')); + this.calculateTotals(); + }); + } + + onSubmit() { + this.$.watcher.check(); + this.$.model.save().then(() => { + this.$.watcher.notifySaved(); + this.$.watcher.updateOriginalData(); + this.calculateTotals(); + this.card.reload(); + }); + } +} + +ngModule.vnComponent('vnInvoiceInIntrastat', { + template: require('./index.html'), + controller: Controller, + require: { + card: '^vnInvoiceInCard' + }, + bindings: { + invoiceIn: '<' + } +}); diff --git a/modules/invoiceIn/front/intrastat/index.spec.js b/modules/invoiceIn/front/intrastat/index.spec.js new file mode 100644 index 000000000..d7d50ac5b --- /dev/null +++ b/modules/invoiceIn/front/intrastat/index.spec.js @@ -0,0 +1,85 @@ +import './index.js'; +import watcher from 'core/mocks/watcher'; +import crudModel from 'core/mocks/crud-model'; + +describe('InvoiceIn', () => { + describe('Component intrastat', () => { + let controller; + let $scope; + let vnApp; + + beforeEach(ngModule('invoiceIn')); + + beforeEach(inject(($componentController, $rootScope, _vnApp_) => { + vnApp = _vnApp_; + jest.spyOn(vnApp, 'showError'); + $scope = $rootScope.$new(); + $scope.model = crudModel; + $scope.watcher = watcher; + + const $element = angular.element(''); + controller = $componentController('vnInvoiceInIntrastat', {$element, $scope}); + controller.invoiceIn = {id: 1}; + })); + + describe('calculateTotals()', () => { + it('should set amountTotal, netTotal and stemsTotal to 0 if salesClaimed has no data', () => { + controller.invoceInIntrastat = []; + controller.calculateTotals(); + + expect(controller.amountTotal).toEqual(0); + expect(controller.netTotal).toEqual(0); + expect(controller.stemsTotal).toEqual(0); + }); + + it('should set amountTotal, netTotal and stemsTotal', () => { + controller.invoceInIntrastat = [ + { + id: 1, + invoiceInFk: 1, + net: 30.5, + intrastatFk: 5080000, + amount: 10, + stems: 162, + countryFk: 5, + statisticalValue: 0 + }, + { + id: 2, + invoiceInFk: 1, + net: 10, + intrastatFk: 6021010, + amount: 20, + stems: 205, + countryFk: 5, + statisticalValue: 0 + } + ]; + controller.calculateTotals(); + + expect(controller.amountTotal).toEqual(30); + expect(controller.netTotal).toEqual(40.5); + expect(controller.stemsTotal).toEqual(367); + }); + }); + + describe('onSubmit()', () => { + it('should make HTTP POST request to save intrastat values', () => { + controller.card = {reload: () => {}}; + jest.spyOn($scope.watcher, 'check'); + jest.spyOn($scope.watcher, 'notifySaved'); + jest.spyOn($scope.watcher, 'updateOriginalData'); + jest.spyOn(controller.card, 'reload'); + jest.spyOn($scope.model, 'save'); + + controller.onSubmit(); + + expect($scope.model.save).toHaveBeenCalledWith(); + expect($scope.watcher.updateOriginalData).toHaveBeenCalledWith(); + expect($scope.watcher.check).toHaveBeenCalledWith(); + expect($scope.watcher.notifySaved).toHaveBeenCalledWith(); + expect(controller.card.reload).toHaveBeenCalledWith(); + }); + }); + }); +}); diff --git a/modules/invoiceIn/front/locale/es.yml b/modules/invoiceIn/front/locale/es.yml index 1ebfa8fe2..4f36b33fa 100644 --- a/modules/invoiceIn/front/locale/es.yml +++ b/modules/invoiceIn/front/locale/es.yml @@ -9,10 +9,13 @@ InvoiceIn cloned: Factura clonada InvoiceIn deleted: Factura eliminada Invoice list: Listado de facturas recibidas InvoiceIn booked: Factura contabilizada +Net: Neto Remove tax: Quitar iva Remove due day: Quitar vencimiento Sage tax: Sage iva Sage transaction: Sage transaccion Search invoices in by reference: Buscar facturas recibidas por referencia To book: Contabilizar - +Total amount: Total importe +Total net: Total neto +Total stems: Total tallos diff --git a/modules/invoiceIn/front/routes.json b/modules/invoiceIn/front/routes.json index 0eb6258d3..4867b7db9 100644 --- a/modules/invoiceIn/front/routes.json +++ b/modules/invoiceIn/front/routes.json @@ -27,6 +27,10 @@ "state": "invoiceIn.card.dueDay", "icon": "icon-calendar" }, + { + "state": "invoiceIn.card.intrastat", + "icon": "icon-lines" + }, { "state": "invoiceIn.card.log", "icon": "history" @@ -109,6 +113,16 @@ }, "acl": ["administrative"] }, + { + "url": "/intrastat", + "state": "invoiceIn.card.intrastat", + "component": "vn-invoice-in-intrastat", + "description": "Intrastat", + "params": { + "invoice-in": "$ctrl.invoiceIn" + }, + "acl": ["administrative"] + }, { "url": "/log", "state": "invoiceIn.card.log", diff --git a/modules/invoiceIn/front/summary/index.html b/modules/invoiceIn/front/summary/index.html index ae6d985f8..3a826eeb7 100644 --- a/modules/invoiceIn/front/summary/index.html +++ b/modules/invoiceIn/front/summary/index.html @@ -120,6 +120,37 @@ + + +

+ + Intrastat + +

+ + + + Code + Amount + Net + Stems + Country + + + + + {{::intrastat.intrastatFk | zeroFill:8}}: {{::intrastat.intrastat.description}} + {{::intrastat.amount | currency: 'EUR':2}} + {{::intrastat.net}} + {{::intrastat.stems}} + {{::intrastat.country.code}} + + + +
+
diff --git a/modules/invoiceOut/front/descriptor/index.html b/modules/invoiceOut/front/descriptor/index.html index 135eae0e1..92f0b9de5 100644 --- a/modules/invoiceOut/front/descriptor/index.html +++ b/modules/invoiceOut/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.invoiceOut.ref" + summary="$ctrl.$.summary"> - \ No newline at end of file +
+ + + \ No newline at end of file diff --git a/modules/item/back/model-config.json b/modules/item/back/model-config.json index d134d9283..004aeb4b9 100644 --- a/modules/item/back/model-config.json +++ b/modules/item/back/model-config.json @@ -29,6 +29,9 @@ "ItemLog": { "dataSource": "vn" }, + "ItemPackingType": { + "dataSource": "vn" + }, "ItemPlacement": { "dataSource": "vn" }, diff --git a/modules/item/back/models/item.json b/modules/item/back/models/item.json index 9b78264f7..efde2690f 100644 --- a/modules/item/back/models/item.json +++ b/modules/item/back/models/item.json @@ -112,9 +112,6 @@ "itemPackingTypeFk": { "type": "string" }, - "compression": { - "type": "number" - }, "hasKgPrice": { "type": "boolean", "description": "Price per Kg" diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index b7db41094..22fd33a07 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -129,14 +129,6 @@ ng-model="$ctrl.item.density" rule> - - + description="$ctrl.item.name" + summary="$ctrl.$.summary"> + + +
- - diff --git a/modules/item/front/locale/es.yml b/modules/item/front/locale/es.yml index 27348d41c..12a729ef4 100644 --- a/modules/item/front/locale/es.yml +++ b/modules/item/front/locale/es.yml @@ -40,7 +40,6 @@ Create: Crear Client card: Ficha del cliente Shipped: F. envío stems: Tallos -Compression: Compresión Density: Densidad Search items by id, name or barcode: Buscar articulos por identificador, nombre o codigo de barras SalesPerson: Comercial diff --git a/modules/item/front/summary/index.html b/modules/item/front/summary/index.html index b5ea79efb..dfc0b6e01 100644 --- a/modules/item/front/summary/index.html +++ b/modules/item/front/summary/index.html @@ -94,9 +94,6 @@ - - diff --git a/modules/order/front/descriptor/index.html b/modules/order/front/descriptor/index.html index a96da252b..538789027 100644 --- a/modules/order/front/descriptor/index.html +++ b/modules/order/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.order.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/route/front/descriptor/index.html b/modules/route/front/descriptor/index.html index bda46952a..fc1d3419c 100644 --- a/modules/route/front/descriptor/index.html +++ b/modules/route/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.route.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/route/front/routes.json b/modules/route/front/routes.json index 0d66a5697..f5e7d9ae8 100644 --- a/modules/route/front/routes.json +++ b/modules/route/front/routes.json @@ -7,7 +7,7 @@ "menus": { "main": [ {"state": "route.index", "icon": "icon-delivery"}, - {"state": "route.agencyTerm.index", "icon": "contact_support"} + {"state": "route.agencyTerm.index", "icon": "icon-agency-term"} ], "card": [ {"state": "route.card.basicData", "icon": "settings"}, diff --git a/modules/supplier/front/descriptor/index.html b/modules/supplier/front/descriptor/index.html index dcc065eff..4691bfe9b 100644 --- a/modules/supplier/front/descriptor/index.html +++ b/modules/supplier/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.supplier.name" + summary="$ctrl.$.summary">
+ + + \ No newline at end of file diff --git a/modules/supplier/front/routes.json b/modules/supplier/front/routes.json index 35519b89a..86bfba40c 100644 --- a/modules/supplier/front/routes.json +++ b/modules/supplier/front/routes.json @@ -15,7 +15,7 @@ {"state": "supplier.card.address.index", "icon": "icon-delivery"}, {"state": "supplier.card.account", "icon": "icon-account"}, {"state": "supplier.card.contact", "icon": "contact_phone"}, - {"state": "supplier.card.agencyTerm.index", "icon": "contact_support"}, + {"state": "supplier.card.agencyTerm.index", "icon": "icon-agency-term"}, {"state": "supplier.card.log", "icon": "history"}, {"state": "supplier.card.consumption", "icon": "show_chart"} ] diff --git a/modules/ticket/back/methods/sale/payBack.js b/modules/ticket/back/methods/sale/refund.js similarity index 77% rename from modules/ticket/back/methods/sale/payBack.js rename to modules/ticket/back/methods/sale/refund.js index 098da4d5a..9c87f23d3 100644 --- a/modules/ticket/back/methods/sale/payBack.js +++ b/modules/ticket/back/methods/sale/refund.js @@ -1,7 +1,7 @@ const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { - Self.remoteMethodCtx('payBack', { + Self.remoteMethodCtx('refund', { description: 'Create ticket with the selected lines changing the sign to the quantites', accessType: 'WRITE', accepts: [{ @@ -21,12 +21,12 @@ module.exports = Self => { root: true }, http: { - path: `/payBack`, + path: `/refund`, verb: 'post' } }); - Self.payBack = async(ctx, sales, ticketId, options) => { + Self.refund = async(ctx, sales, ticketId, options) => { const myOptions = {}; let tx; @@ -47,21 +47,35 @@ module.exports = Self => { const hasValidRole = isClaimManager || isSalesAssistant; if (!hasValidRole) - throw new UserError(`You don't have privileges to create pay back`); + throw new UserError(`You don't have privileges to create refund`); for (let sale of sales) salesIds.push(sale.id); const query = ` DROP TEMPORARY TABLE IF EXISTS tmp.sale; + DROP TEMPORARY TABLE IF EXISTS tmp.ticketService; + CREATE TEMPORARY TABLE tmp.sale SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount FROM sale s WHERE s.id IN (?); + + CREATE TEMPORARY TABLE tmp.ticketService( + description VARCHAR(50), + quantity DECIMAL (10,2), + price DECIMAL (10,2), + taxClassFk INT, + ticketServiceTypeFk INT + ); + CALL vn.ticket_doRefund(?, @newTicket); - DROP TEMPORARY TABLE tmp.sale;`; + + DROP TEMPORARY TABLE tmp.sale; + DROP TEMPORARY TABLE tmp.ticketService;`; await Self.rawSql(query, [salesIds, ticketId], myOptions); + const [newTicket] = await Self.rawSql('SELECT @newTicket id', null, myOptions); ticketId = newTicket.id; diff --git a/modules/ticket/back/methods/sale/refundAll.js b/modules/ticket/back/methods/sale/refundAll.js new file mode 100644 index 000000000..6fcd27f0a --- /dev/null +++ b/modules/ticket/back/methods/sale/refundAll.js @@ -0,0 +1,78 @@ +const UserError = require('vn-loopback/util/user-error'); + +module.exports = Self => { + Self.remoteMethodCtx('refundAll', { + description: 'Create ticket with all lines and services changing the sign to the quantites', + accessType: 'WRITE', + accepts: [{ + arg: 'ticketId', + type: 'number', + required: true, + description: 'The ticket id' + }], + returns: { + type: 'number', + root: true + }, + http: { + path: `/refundAll`, + verb: 'post' + } + }); + + Self.refundAll = async(ctx, ticketId, options) => { + const myOptions = {}; + let tx; + + if (typeof options == 'object') + Object.assign(myOptions, options); + + if (!myOptions.transaction) { + tx = await Self.beginTransaction({}); + myOptions.transaction = tx; + } + + try { + const userId = ctx.req.accessToken.userId; + + const isClaimManager = await Self.app.models.Account.hasRole(userId, 'claimManager'); + const isSalesAssistant = await Self.app.models.Account.hasRole(userId, 'salesAssistant'); + const hasValidRole = isClaimManager || isSalesAssistant; + + if (!hasValidRole) + throw new UserError(`You don't have privileges to create refund`); + + const query = ` + DROP TEMPORARY TABLE IF EXISTS tmp.sale; + DROP TEMPORARY TABLE IF EXISTS tmp.ticketService; + + CREATE TEMPORARY TABLE tmp.sale + SELECT s.id, s.itemFk, - s.quantity, s.concept, s.price, s.discount + FROM sale s + JOIN ticket t ON t.id = s.ticketFk + WHERE t.id IN (?); + + CREATE TEMPORARY TABLE tmp.ticketService + SELECT ts.description, - ts.quantity, ts.price, ts.taxClassFk, ts.ticketServiceTypeFk + FROM ticketService ts + WHERE ts.ticketFk IN (?); + + CALL vn.ticket_doRefund(?, @newTicket); + + DROP TEMPORARY TABLE tmp.sale; + DROP TEMPORARY TABLE tmp.ticketService;`; + + await Self.rawSql(query, [ticketId, ticketId, ticketId], myOptions); + + const [newTicket] = await Self.rawSql('SELECT @newTicket id', null, myOptions); + ticketId = newTicket.id; + + if (tx) await tx.commit(); + + return ticketId; + } catch (e) { + if (tx) await tx.rollback(); + throw e; + } + }; +}; diff --git a/modules/ticket/back/methods/sale/specs/payBack.spec.js b/modules/ticket/back/methods/sale/specs/refund.spec.js similarity index 84% rename from modules/ticket/back/methods/sale/specs/payBack.spec.js rename to modules/ticket/back/methods/sale/specs/refund.spec.js index ffcf96456..40fd6c17e 100644 --- a/modules/ticket/back/methods/sale/specs/payBack.spec.js +++ b/modules/ticket/back/methods/sale/specs/refund.spec.js @@ -1,6 +1,6 @@ const models = require('vn-loopback/server/server').models; -describe('sale payBack()', () => { +describe('sale refund()', () => { it('should create ticket with the selected lines changing the sign to the quantites', async() => { const tx = await models.Sale.beginTransaction({}); const ctx = {req: {accessToken: {userId: 9}}}; @@ -14,7 +14,7 @@ describe('sale payBack()', () => { try { const options = {transaction: tx}; - const response = await models.Sale.payBack(ctx, sales, ticketId, options); + const response = await models.Sale.refund(ctx, sales, ticketId, options); const [newTicketId] = await models.Sale.rawSql('SELECT MAX(t.id) id FROM vn.ticket t;', null, options); expect(response).toEqual(newTicketId.id); @@ -26,7 +26,7 @@ describe('sale payBack()', () => { } }); - it(`should throw an error if the user doesn't have privileges to create a pay back`, async() => { + it(`should throw an error if the user doesn't have privileges to create a refund`, async() => { const tx = await models.Sale.beginTransaction({}); const ctx = {req: {accessToken: {userId: 1}}}; @@ -40,7 +40,7 @@ describe('sale payBack()', () => { try { const options = {transaction: tx}; - await models.Sale.payBack(ctx, sales, ticketId, options); + await models.Sale.refund(ctx, sales, ticketId, options); await tx.rollback(); } catch (e) { @@ -49,6 +49,6 @@ describe('sale payBack()', () => { } expect(error).toBeDefined(); - expect(error.message).toEqual(`You don't have privileges to create pay back`); + expect(error.message).toEqual(`You don't have privileges to create refund`); }); }); diff --git a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js index 8ec4ca487..f50253b10 100644 --- a/modules/ticket/back/methods/ticket/specs/sendSms.spec.js +++ b/modules/ticket/back/methods/ticket/specs/sendSms.spec.js @@ -1,5 +1,4 @@ const models = require('vn-loopback/server/server').models; -const soap = require('soap'); describe('ticket sendSms()', () => { it('should send a message and log it', async() => { @@ -8,7 +7,6 @@ describe('ticket sendSms()', () => { try { const options = {transaction: tx}; - spyOn(soap, 'createClientAsync').and.returnValue('a so fake client'); const ctx = {req: {accessToken: {userId: 9}}}; const id = 11; const destination = 222222222; diff --git a/modules/ticket/back/methods/ticket/specs/updateDiscount.spec.js b/modules/ticket/back/methods/ticket/specs/updateDiscount.spec.js index ae79185e4..1873207aa 100644 --- a/modules/ticket/back/methods/ticket/specs/updateDiscount.spec.js +++ b/modules/ticket/back/methods/ticket/specs/updateDiscount.spec.js @@ -90,7 +90,7 @@ describe('sale updateDiscount()', () => { expect(error.message).toEqual(`The sales of this ticket can't be modified`); }); - it('should update the discount if the salesPerson has mana', async() => { + it('should update the discount if the salesPerson has mana and manaCode = "mana"', async() => { const tx = await models.Ticket.beginTransaction({}); try { @@ -108,8 +108,49 @@ describe('sale updateDiscount()', () => { const newDiscount = 100; const manaDiscount = await models.Component.findOne({where: {code: 'mana'}}, options); const componentId = manaDiscount.id; + const manaCode = 'mana'; - await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, options); + await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, manaCode, options); + + const updatedSale = await models.Sale.findById(originalSaleId, null, options); + const createdSaleComponent = await models.SaleComponent.findOne({ + where: { + componentFk: componentId, + saleFk: originalSaleId + } + }, options); + + expect(createdSaleComponent.componentFk).toEqual(componentId); + expect(updatedSale.discount).toEqual(100); + + await tx.rollback(); + } catch (e) { + await tx.rollback(); + throw e; + } + }); + + it('should update the discount if the salesPerson has mana and manaCode = "manaClaim"', async() => { + const tx = await models.Ticket.beginTransaction({}); + + try { + const options = {transaction: tx}; + + const ctx = { + req: { + accessToken: {userId: 18}, + headers: {origin: 'localhost:5000'}, + __: () => {} + } + }; + const ticketId = 11; + const sales = [originalSaleId]; + const newDiscount = 100; + const manaDiscount = await models.Component.findOne({where: {code: 'manaClaim'}}, options); + const componentId = manaDiscount.id; + const manaCode = 'manaClaim'; + + await models.Ticket.updateDiscount(ctx, ticketId, sales, newDiscount, manaCode, options); const updatedSale = await models.Sale.findById(originalSaleId, null, options); const createdSaleComponent = await models.SaleComponent.findOne({ diff --git a/modules/ticket/back/methods/ticket/updateDiscount.js b/modules/ticket/back/methods/ticket/updateDiscount.js index cf217348a..b1291a45b 100644 --- a/modules/ticket/back/methods/ticket/updateDiscount.js +++ b/modules/ticket/back/methods/ticket/updateDiscount.js @@ -23,6 +23,12 @@ module.exports = Self => { description: 'The new discount', type: 'number', required: true + }, + { + arg: 'manaCode', + description: 'The type of mana', + type: 'string', + required: false } ], returns: { @@ -35,7 +41,7 @@ module.exports = Self => { } }); - Self.updateDiscount = async(ctx, id, salesIds, newDiscount, options) => { + Self.updateDiscount = async(ctx, id, salesIds, newDiscount, manaCode, options) => { const $t = ctx.req.__; // $translate const models = Self.app.models; const myOptions = {}; @@ -98,7 +104,7 @@ module.exports = Self => { }, fields: 'amount'}, myOptions); - const componentCode = usesMana ? 'mana' : 'buyerDiscount'; + const componentCode = usesMana ? manaCode : 'buyerDiscount'; const discountComponent = await models.Component.findOne({ where: {code: componentCode}}, myOptions); diff --git a/modules/ticket/back/models/sale.js b/modules/ticket/back/models/sale.js index 9efd66057..2652aded2 100644 --- a/modules/ticket/back/models/sale.js +++ b/modules/ticket/back/models/sale.js @@ -6,7 +6,8 @@ module.exports = Self => { require('../methods/sale/updateQuantity')(Self); require('../methods/sale/updateConcept')(Self); require('../methods/sale/recalculatePrice')(Self); - require('../methods/sale/payBack')(Self); + require('../methods/sale/refund')(Self); + require('../methods/sale/refundAll')(Self); require('../methods/sale/canEdit')(Self); Self.validatesPresenceOf('concept', { diff --git a/modules/ticket/front/descriptor-menu/index.html b/modules/ticket/front/descriptor-menu/index.html index 88ed4b46b..c99575d42 100644 --- a/modules/ticket/front/descriptor-menu/index.html +++ b/modules/ticket/front/descriptor-menu/index.html @@ -139,6 +139,11 @@ translate> Recalculate components + + Refund all + @@ -292,4 +297,12 @@ on-accept="$ctrl.recalculateComponents()" question="Are you sure you want to recalculate the components?" message="Recalculate components"> + + + + \ No newline at end of file diff --git a/modules/ticket/front/descriptor-menu/index.js b/modules/ticket/front/descriptor-menu/index.js index 6465c43ac..1c80a6f9d 100644 --- a/modules/ticket/front/descriptor-menu/index.js +++ b/modules/ticket/front/descriptor-menu/index.js @@ -272,6 +272,14 @@ class Controller extends Section { .then(() => this.reload()) .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); } + + refundAll() { + const params = {ticketId: this.id}; + const query = `Sales/refundAll`; + return this.$http.post(query, params).then(res => { + this.$state.go('ticket.card.sale', {id: res.data}); + }); + } } Controller.$inject = ['$element', '$scope', 'vnReport', 'vnEmail']; diff --git a/modules/ticket/front/descriptor-menu/index.spec.js b/modules/ticket/front/descriptor-menu/index.spec.js index faf45504e..75f3522ae 100644 --- a/modules/ticket/front/descriptor-menu/index.spec.js +++ b/modules/ticket/front/descriptor-menu/index.spec.js @@ -262,6 +262,19 @@ describe('Ticket Component vnTicketDescriptorMenu', () => { }); }); + describe('refundAll()', () => { + it('should make a query and go to ticket.card.sale', () => { + jest.spyOn(controller.$state, 'go').mockReturnValue(); + const expectedParams = {ticketId: ticket.id}; + + $httpBackend.expect('POST', `Sales/refundAll`, expectedParams).respond({ticketId: 16}); + controller.refundAll(); + $httpBackend.flush(); + + expect(controller.$state.go).toHaveBeenCalledWith('ticket.card.sale', {id: {ticketId: ticket.id}}); + }); + }); + describe('showSMSDialog()', () => { it('should set the destionationFk and destination properties and then call the sms open() method', () => { controller.$.sms = {open: () => {}}; diff --git a/modules/ticket/front/descriptor-menu/locale/es.yml b/modules/ticket/front/descriptor-menu/locale/es.yml index 761687e74..060d03154 100644 --- a/modules/ticket/front/descriptor-menu/locale/es.yml +++ b/modules/ticket/front/descriptor-menu/locale/es.yml @@ -7,4 +7,5 @@ Send PDF: Enviar PDF Send CSV: Enviar CSV Send CSV Delivery Note: Enviar albarán en CSV Send PDF Delivery Note: Enviar albarán en PDF -Show Proforma: Ver proforma \ No newline at end of file +Show Proforma: Ver proforma +Refund all: Abonar todo \ No newline at end of file diff --git a/modules/ticket/front/descriptor/index.html b/modules/ticket/front/descriptor/index.html index 8d7688826..2c27b19cd 100644 --- a/modules/ticket/front/descriptor/index.html +++ b/modules/ticket/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.ticket.client.name" + summary="$ctrl.$.summary"> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/modules/ticket/front/descriptor/locale/es.yml b/modules/ticket/front/descriptor/locale/es.yml index f56f29f92..2a7bf360f 100644 --- a/modules/ticket/front/descriptor/locale/es.yml +++ b/modules/ticket/front/descriptor/locale/es.yml @@ -29,4 +29,5 @@ SMS Minimum import: 'SMS Importe minimo' SMS Pending payment: 'SMS Pago pendiente' Restore ticket: Restaurar ticket You are going to restore this ticket: Vas a restaurar este ticket -Are you sure you want to restore this ticket?: ¿Seguro que quieres restaurar el ticket? \ No newline at end of file +Are you sure you want to restore this ticket?: ¿Seguro que quieres restaurar el ticket? +Are you sure you want to refund all?: ¿Seguro que quieres abonar todo? \ No newline at end of file diff --git a/modules/ticket/front/sale/index.html b/modules/ticket/front/sale/index.html index 5dc3c9428..836fadb9b 100644 --- a/modules/ticket/front/sale/index.html +++ b/modules/ticket/front/sale/index.html @@ -285,10 +285,21 @@ vn-focus label="Discount" ng-model="$ctrl.edit.discount" - on-change="$ctrl.changeDiscount()" clear-disabled="true" suffix="%"> + + + + + +

New price

@@ -297,6 +308,16 @@

+ + + + + + @@ -491,10 +512,10 @@ Unmark as reserved
- Pay Back + Refund \ No newline at end of file diff --git a/modules/ticket/front/sale/index.js b/modules/ticket/front/sale/index.js index 54167ce96..bb8a81bc4 100644 --- a/modules/ticket/front/sale/index.js +++ b/modules/ticket/front/sale/index.js @@ -6,6 +6,15 @@ class Controller extends Section { constructor($element, $) { super($element, $); this._sales = []; + this.manaCode = 'mana'; + } + + get manaCode() { + return this._manaCode; + } + + set manaCode(value) { + this._manaCode = value; } get ticket() { @@ -66,6 +75,14 @@ class Controller extends Section { this.$.editPricePopover.relocate(); }); }); + this.getCurrentWorkerMana(); + } + + getCurrentWorkerMana() { + this.$http.get(`WorkerManas/getCurrentWorkerMana`) + .then(res => { + this.currentWorkerMana = res.data; + }); } /** @@ -273,7 +290,7 @@ class Controller extends Section { return sale.id; }); - const params = {salesIds: saleIds, newDiscount: this.edit.discount}; + const params = {salesIds: saleIds, newDiscount: this.edit.discount, manaCode: this.manaCode}; const query = `Tickets/${this.$params.id}/updateDiscount`; this.$http.post(query, params).then(() => { this.vnApp.showSuccess(this.$t('Data saved!')); @@ -462,12 +479,12 @@ class Controller extends Section { }); } - createPayBack() { + createRefund() { const sales = this.selectedValidSales(); if (!sales) return; const params = {sales: sales, ticketId: this.ticket.id}; - const query = `Sales/payBack`; + const query = `Sales/refund`; this.resetChanges(); this.$http.post(query, params).then(res => { this.$state.go('ticket.card.sale', {id: res.data}); @@ -479,6 +496,14 @@ class Controller extends Section { ? {id: $search} : {name: {like: '%' + $search + '%'}}; } + + save() { + this.changeDiscount(); + } + + cancel() { + this.$.editDiscount.hide(); + } } ngModule.vnComponent('vnTicketSale', { diff --git a/modules/ticket/front/sale/index.spec.js b/modules/ticket/front/sale/index.spec.js index 15ce1798b..a8ac2f3de 100644 --- a/modules/ticket/front/sale/index.spec.js +++ b/modules/ticket/front/sale/index.spec.js @@ -43,7 +43,7 @@ describe('Ticket', () => { $scope.sms = {open: () => {}}; $scope.ticket = ticket; $scope.model = crudModel; - $scope.editDiscount = {relocate: () => {}}; + $scope.editDiscount = {relocate: () => {}, hide: () => {}}; $scope.editPricePopover = {relocate: () => {}}; $httpBackend = _$httpBackend_; Object.defineProperties($state.params, { @@ -115,10 +115,12 @@ describe('Ticket', () => { const expectedAmount = 250; $httpBackend.expect('GET', 'Tickets/1/getSalesPersonMana').respond(200, expectedAmount); + $httpBackend.expect('GET', 'WorkerManas/getCurrentWorkerMana').respond(200, expectedAmount); controller.getMana(); $httpBackend.flush(); expect(controller.edit.mana).toEqual(expectedAmount); + expect(controller.currentWorkerMana).toEqual(expectedAmount); }); }); @@ -446,7 +448,7 @@ describe('Ticket', () => { const expectedSales = [firstSelectedSale, secondSelectedSale]; const expectedSaleIds = [firstSelectedSale.id, secondSelectedSale.id]; - const expectedParams = {salesIds: expectedSaleIds, newDiscount: expectedDiscount}; + const expectedParams = {salesIds: expectedSaleIds, newDiscount: expectedDiscount, manaCode: 'mana'}; $httpBackend.expect('POST', `Tickets/1/updateDiscount`, expectedParams).respond(200, {discount: 10}); controller.updateDiscount(expectedSales); $httpBackend.flush(); @@ -701,15 +703,15 @@ describe('Ticket', () => { }); }); - describe('createPayBack()', () => { + describe('createRefund()', () => { it('should make an HTTP POST query and then call to the $state go() method', () => { jest.spyOn(controller, 'selectedValidSales').mockReturnValue(controller.sales); jest.spyOn(controller, 'resetChanges'); jest.spyOn(controller.$state, 'go'); const expectedId = 9999; - $httpBackend.expect('POST', `Sales/payBack`).respond(200, expectedId); - controller.createPayBack(); + $httpBackend.expect('POST', `Sales/refund`).respond(200, expectedId); + controller.createRefund(); $httpBackend.flush(); expect(controller.resetChanges).toHaveBeenCalledWith(); @@ -732,5 +734,14 @@ describe('Ticket', () => { expect(result).toEqual({name: {like: '%' + itemName + '%'}}); }); }); + + describe('cancel()', () => { + it('should call hide()', () => { + jest.spyOn(controller.$.editDiscount, 'hide').mockReturnThis(); + controller.cancel(); + + expect(controller.$.editDiscount.hide).toHaveBeenCalledWith(); + }); + }); }); }); diff --git a/modules/ticket/front/sale/locale/es.yml b/modules/ticket/front/sale/locale/es.yml index e4152600f..aab8ff493 100644 --- a/modules/ticket/front/sale/locale/es.yml +++ b/modules/ticket/front/sale/locale/es.yml @@ -36,4 +36,6 @@ Warehouse: Almacen Agency: Agencia Shipped: F. envio Packaging: Encajado -Pay Back: Abono \ No newline at end of file +Refund: Abono +Promotion mana: Maná promoción +Claim mana: Maná reclamación diff --git a/modules/travel/back/models/travel-thermograph.json b/modules/travel/back/models/travel-thermograph.json index 1e6dd1905..754df1c3e 100644 --- a/modules/travel/back/models/travel-thermograph.json +++ b/modules/travel/back/models/travel-thermograph.json @@ -20,9 +20,6 @@ "created": { "type": "date" }, - "temperature": { - "type": "string" - }, "temperatureFk": { "type": "string", "required": true diff --git a/modules/travel/front/descriptor/index.html b/modules/travel/front/descriptor/index.html index 28e908d18..bbf5721fd 100644 --- a/modules/travel/front/descriptor/index.html +++ b/modules/travel/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.travel.ref" + summary="$ctrl.$.summary"> @@ -42,3 +43,6 @@ + + + \ No newline at end of file diff --git a/modules/travel/front/summary/index.html b/modules/travel/front/summary/index.html index e74682fb9..bd9d6c9cb 100644 --- a/modules/travel/front/summary/index.html +++ b/modules/travel/front/summary/index.html @@ -158,7 +158,7 @@ {{thermograph.thermographFk}} - {{thermograph.temperature}} + {{thermograph.temperatureFk}} {{thermograph.result}} {{thermograph.warehouse.name}} {{thermograph.created | date: 'dd/MM/yyyy'}} diff --git a/modules/worker/back/model-config.json b/modules/worker/back/model-config.json index e35e39721..c155e331d 100644 --- a/modules/worker/back/model-config.json +++ b/modules/worker/back/model-config.json @@ -17,6 +17,9 @@ "Department": { "dataSource": "vn" }, + "EducationLevel": { + "dataSource": "vn" + }, "WorkCenter": { "dataSource": "vn" }, diff --git a/modules/worker/back/models/education-level.json b/modules/worker/back/models/education-level.json new file mode 100644 index 000000000..4ae2376c4 --- /dev/null +++ b/modules/worker/back/models/education-level.json @@ -0,0 +1,18 @@ +{ + "name": "EducationLevel", + "base": "VnModel", + "options": { + "mysql": { + "table": "educationLevel" + } + }, + "properties": { + "id": { + "id": true, + "type": "number" + }, + "name": { + "type": "string" + } + } +} \ No newline at end of file diff --git a/modules/worker/back/models/worker.json b/modules/worker/back/models/worker.json index cad38ac3b..c8054caff 100644 --- a/modules/worker/back/models/worker.json +++ b/modules/worker/back/models/worker.json @@ -13,7 +13,7 @@ }, "properties": { "id": { - "type": "Number", + "type": "number", "id": true, "description": "Identifier" }, @@ -26,14 +26,26 @@ "required": true }, "phone": { - "type" : "String" + "type" : "string" }, "userFk": { - "type" : "Number", + "type" : "number", "required": true }, "bossFk": { - "type" : "Number" + "type" : "number" + }, + "maritalStatus": { + "type" : "string" + }, + "originCountryFk": { + "type" : "number" + }, + "educationLevelFk": { + "type" : "number" + }, + "SSN": { + "type" : "string" } }, "relations": { diff --git a/modules/worker/front/basic-data/index.html b/modules/worker/front/basic-data/index.html index b61a4cf94..cbe683185 100644 --- a/modules/worker/front/basic-data/index.html +++ b/modules/worker/front/basic-data/index.html @@ -30,7 +30,6 @@ rule> + + + + + + + + + + + + diff --git a/modules/worker/front/basic-data/index.js b/modules/worker/front/basic-data/index.js index d2c7f5b70..ea75d7b97 100644 --- a/modules/worker/front/basic-data/index.js +++ b/modules/worker/front/basic-data/index.js @@ -2,6 +2,13 @@ import ngModule from '../module'; import Section from 'salix/components/section'; class Controller extends Section { + constructor($element, $) { + super($element, $); + this.maritalStatus = [ + {code: 'M', name: this.$t('Married')}, + {code: 'S', name: this.$t('Single')} + ]; + } onSubmit() { return this.$.watcher.submit() .then(() => this.card.reload()); diff --git a/modules/worker/front/basic-data/locale/es.yml b/modules/worker/front/basic-data/locale/es.yml new file mode 100644 index 000000000..278335265 --- /dev/null +++ b/modules/worker/front/basic-data/locale/es.yml @@ -0,0 +1,6 @@ +Marital status: Estado civil +Origin country: País origen +Education level: Nivel educación +SSN: NSS +Married: Casado/a +Single: Soltero/a \ No newline at end of file diff --git a/modules/worker/front/descriptor/index.html b/modules/worker/front/descriptor/index.html index 036b70eab..01681ebb8 100644 --- a/modules/worker/front/descriptor/index.html +++ b/modules/worker/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.worker.firstName +' '+ $ctrl.worker.lastName" + summary="$ctrl.$.summary">
+ + + {{::zone.id}} {{::zone.name}} - {{::zone.agencyMode.name}} + {{::zone.agencyModeName}} {{::zone.hour | date: 'HH:mm'}} {{::zone.price | currency: 'EUR':2}} diff --git a/modules/zone/front/descriptor/index.html b/modules/zone/front/descriptor/index.html index 355028c98..a3432a99d 100644 --- a/modules/zone/front/descriptor/index.html +++ b/modules/zone/front/descriptor/index.html @@ -1,6 +1,7 @@ + description="$ctrl.zone.name" + summary="$ctrl.$.summary"> + + + + =14" }, "dependencies": { + "adm-zip": "^0.5.9", "axios": "^0.25.0", "bmp-js": "^0.1.0", "compression": "^1.7.3", "fs-extra": "^5.0.0", + "ftps": "^1.2.0", "got": "^10.7.0", "helmet": "^3.21.2", "i18n": "^0.8.4", @@ -39,7 +41,6 @@ "require-yaml": "0.0.1", "sharp": "^0.27.1", "smbhash": "0.0.1", - "soap": "^0.35.0", "strong-error-handler": "^2.3.2", "uuid": "^3.3.3", "vn-loopback": "file:./loopback", @@ -104,7 +105,7 @@ "test": "jest --watch", "back": "nodemon --inspect -w modules ./node_modules/gulp/bin/gulp.js back", "lint": "eslint ./ --cache --ignore-pattern .gitignore", - "docker": "docker build -t salix-db ./db" + "docker": "docker build --progress=plain -t salix-db ./db" }, "jest": { "projects": [