diff --git a/back/model-config.json b/back/model-config.json index 323e5f233..dc5cde217 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -2,6 +2,9 @@ "Account": { "dataSource": "vn" }, + "AccountingType": { + "dataSource": "vn" + }, "Bank": { "dataSource": "vn" }, diff --git a/back/models/accounting-type.json b/back/models/accounting-type.json new file mode 100644 index 000000000..796793342 --- /dev/null +++ b/back/models/accounting-type.json @@ -0,0 +1,30 @@ +{ + "name": "AccountingType", + "base": "VnModel", + "options": { + "mysql": { + "table": "accountingType" + } + }, + "properties": { + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "description": { + "type": "String", + "required": true + }, + "receiptDescription": { + "type": "String", + "required": true + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/back/models/bank.json b/back/models/bank.json index 119ea9743..33a2637d6 100644 --- a/back/models/bank.json +++ b/back/models/bank.json @@ -2,39 +2,49 @@ "name": "Bank", "base": "VnModel", "options": { - "mysql": { - "table": "bank" - } + "mysql": { + "table": "bank" + } }, "properties": { - "id": { - "type": "Number", - "id": true, - "description": "Identifier" - }, - "bank": { - "type": "string", - "required": true - }, - "account": { - "type": "string", - "required": true - }, - "cash": { - "type": "string", - "required": true - }, - "entityFk": { - "type": "string", - "required": true - }, - "isActive": { - "type": "string", - "required": true - }, - "currencyFk": { - "type": "string", - "required": true - } + "id": { + "type": "Number", + "id": true, + "description": "Identifier" + }, + "bank": { + "type": "String", + "required": true + }, + "account": { + "type": "String", + "required": true + }, + "accountingTypeFk": { + "type": "Number", + "required": true, + "mysql": { + "columnName": "cash" + } + }, + "entityFk": { + "type": "Number", + "required": true + }, + "isActive": { + "type": "Boolean", + "required": true + }, + "currencyFk": { + "type": "Number", + "required": true + } + }, + "relations": { + "accountingType": { + "type": "belongsTo", + "model": "AccountingType", + "foreignKey": "accountingTypeFk" + } } - } \ No newline at end of file +} \ No newline at end of file diff --git a/db/changes/10200-normality/00-itemLastEntries.sql b/db/changes/10200-normality/00-itemLastEntries.sql new file mode 100644 index 000000000..ce600b39f --- /dev/null +++ b/db/changes/10200-normality/00-itemLastEntries.sql @@ -0,0 +1,44 @@ + +USE `vn`; +DROP procedure IF EXISTS `vn`.`itemLastEntries`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `itemLastEntries__`(IN `vItem` INT, IN `vDays` DATE) +BEGIN + SELECT + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.`grouping`, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packageFk , + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id + WHERE b.itemFk = vItem And tr.shipped BETWEEN vDays AND DATE_ADD(CURDATE(), INTERVAl + 10 DAY) + ORDER BY tr.landed DESC , b.id DESC; +END$$ + +DELIMITER ; +; diff --git a/db/changes/10210-summer/00-accountingType.sql b/db/changes/10210-summer/00-accountingType.sql new file mode 100644 index 000000000..1dbe29952 --- /dev/null +++ b/db/changes/10210-summer/00-accountingType.sql @@ -0,0 +1,2 @@ +ALTER TABLE `vn`.`accountingType` +ADD COLUMN `receiptDescription` VARCHAR(50) NULL AFTER `description`; diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index fa738863c..4dc540955 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -116,13 +116,13 @@ INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `park ('GVC', '1', '0', '1', '0', '106'), ('HEJ', '2', '0', '1', '0', '106'); -INSERT INTO `vn`.`accountingType`(`id`, `description`) +INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`) VALUES - (1, 'Digital money'), - (2, 'Cash'), - (3, 'Card'), - (4, 'Stolen Money'), - (5, 'Miscellaneous'); + (1, 'Digital money', ''), + (2, 'Cash', 'Cash'), + (3, 'Card', 'Pay on receipt'), + (4, 'Stolen Money', ''), + (5, 'Miscellaneous', ''); INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`) VALUES @@ -133,8 +133,8 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`) INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`) VALUES - (1, 'Pay on receipt', '0000000000', 4, 0, 1, 1), - (2, 'Cash', '1111111111', 1, 0, 1, 1); + (1, 'Pay on receipt', '0000000000', 3, 0, 1, 1), + (2, 'Cash', '1111111111', 2, 0, 1, 1); INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`) VALUES @@ -765,6 +765,26 @@ INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `create (8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 18), (9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18), (10, 7, 7, 71, CURDATE(), 1, 1, 1, 18); + +INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`) + VALUES + (1, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL), + (2, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 66, 1, NULL), + (3, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 65, 1, NULL), + (4, 1, 60, 'AMR', 1, 1, NULL, 1, 05080000, 1, 4751000000, 0, NULL, 0, 69, 2, NULL), + (5, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 74, 2, NULL), + (6, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 62, 2, NULL), + (7, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 64, 2, NULL), + (8, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 75, 1, NULL), + (9, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 76, 1, NULL), + (10, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 77, 1, NULL), + (11, 1, 60, 'AMR', 1, 1, NULL, 1, 05080000, 1, 4751000000, 0, NULL, 0, 78, 2, NULL), + (12, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 82, 2, NULL), + (13, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 83, 2, NULL), + (14, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 84, 2, NULL), + (15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL), + (16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL), + (71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88, 2, NULL); INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`) VALUES @@ -777,6 +797,19 @@ INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPack ('cc', 1640038.00, 56.00, 220.00, 128.00, 1, CURDATE(), 15, 90.00), ('pallet 100', 2745600.00, 100.00, 220.00, 120.00, 1, CURDATE(), 16, 0.00); +INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `workerFk`, `packagingFk`) + VALUES + (1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1), + (2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 1), + (3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 1), + (4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 1), + (5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1), + (6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 1), + (7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 1), + (8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 1), + (9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 1), + (10, 7, 7, 71, CURDATE(), 1, 1, 1, 1); + INSERT INTO `vn`.`ticketPackaging`(`id`, `ticketFk`, `packagingFk`, `quantity`, `created`, `pvp`) VALUES (1, 1, 2, 2, CURDATE(), NULL), diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 47fcc7edf..3a48d881e 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -189,8 +189,9 @@ export default { newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]', newPaymentAmount: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"]', saveButton: '.vn-dialog.shown [response="accept"]', - firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)' - + firstLineBalance: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)', + firstLineReference: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable', + firstLineReferenceInput: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable > div > field > vn-textfield' }, webPayment: { confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]', diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js index 108f76710..6c16d455d 100644 --- a/e2e/paths/02-client/14_balance.spec.js +++ b/e2e/paths/02-client/14_balance.spec.js @@ -53,15 +53,28 @@ describe('Client balance path', () => { expect(message.type).toBe('success'); }); - it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => { + it('should edit the 1st line reference', async() => { + await page.waitToClick(selectors.clientBalance.firstLineReference); + await page.write(selectors.clientBalance.firstLineReferenceInput, 'Miscellaneous payment'); + await page.keyboard.press('Enter'); + const message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); + }); + + it('should check balance is now 0, the reference was saved and the company is now VNL becouse the user local settings were removed', async() => { await page.waitForSpinnerLoad(); let company = await page .waitToGetProperty(selectors.clientBalance.company, 'value'); + let reference = await page + .waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText'); + let firstBalanceLine = await page - .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText'); + .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText'); expect(company).toEqual('VNL'); + expect(reference).toEqual('Miscellaneous payment'); expect(firstBalanceLine).toContain('0.00'); }); @@ -76,7 +89,7 @@ describe('Client balance path', () => { it('should check balance is now -100', async() => { let result = await page - .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText'); + .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText'); expect(result).toContain('-€100.00'); }); @@ -92,7 +105,7 @@ describe('Client balance path', () => { it('should check balance is now 50', async() => { let result = await page - .waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText'); + .waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText'); expect(result).toEqual('€50.00'); }); diff --git a/e2e/paths/04-item/13_request.spec.js b/e2e/paths/04-item/13_request.spec.js index ab48e0c37..66cd7a0f5 100644 --- a/e2e/paths/04-item/13_request.spec.js +++ b/e2e/paths/04-item/13_request.spec.js @@ -31,7 +31,7 @@ describe('Item request path', () => { it('should the status of the request should now be accepted', async() => { let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText'); - expect(status).toContain('Aceptada'); + expect(status).toContain('Accepted'); }); it('should now click on the second declain request icon then type the reason', async() => { @@ -40,6 +40,6 @@ describe('Item request path', () => { await page.respondToDialog('accept'); let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText'); - expect(status).toContain('Denegada'); + expect(status).toContain('Denied'); }); }); diff --git a/front/core/components/contextmenu/index.js b/front/core/components/contextmenu/index.js index 90c14b7e3..db74848a6 100755 --- a/front/core/components/contextmenu/index.js +++ b/front/core/components/contextmenu/index.js @@ -67,13 +67,13 @@ export default class Contextmenu { get cell() { if (!this.target) return null; - return this.target.closest('vn-td, .vn-td'); + return this.target.closest('vn-td, .vn-td, vn-td-editable'); } get cellIndex() { if (!this.row) return null; - const cells = this.row.querySelectorAll('vn-td, .vn-td'); + const cells = this.row.querySelectorAll('vn-td, .vn-td, vn-td-editable'); return Array.from(cells).findIndex( cellItem => cellItem == this.cell ); diff --git a/gulpfile.js b/gulpfile.js index 096c44584..40590d7c2 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -403,8 +403,8 @@ module.exports = { back, backOnly, backWatch, - backTestOnce, backTest, + backTestOnce, e2e, i, install, diff --git a/modules/client/back/methods/receipt/filter.js b/modules/client/back/methods/receipt/filter.js index 532d72811..b32249d4b 100644 --- a/modules/client/back/methods/receipt/filter.js +++ b/modules/client/back/methods/receipt/filter.js @@ -42,11 +42,11 @@ module.exports = Self => { r.workerFk, c.code company, r.created, - r.invoiceFk ref, + r.invoiceFk description, NULL debit, r.amountPaid credit, r.bankFk, - u.nickname userNickname, + u.name userName, r.clientFk, FALSE hasPdf, FALSE isInvoice diff --git a/modules/client/front/balance/create/index.html b/modules/client/front/balance/create/index.html index 506e86f4b..6cfdc0666 100644 --- a/modules/client/front/balance/create/index.html +++ b/modules/client/front/balance/create/index.html @@ -17,11 +17,17 @@ + fields="['accountingTypeFk']" + include="{relation: 'accountingType'}" + order="id" + ng-model="$ctrl.receipt.bankFk" + search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}" + selection="$ctrl.bankSelection"> + {{id}}: {{bank}} + + + + diff --git a/modules/client/front/balance/create/index.js b/modules/client/front/balance/create/index.js index 880774f55..8b01cab4a 100644 --- a/modules/client/front/balance/create/index.js +++ b/modules/client/front/balance/create/index.js @@ -50,6 +50,19 @@ class Controller extends Dialog { return this.receipt.description; } + get bankSelection() { + return this._bankSelection; + } + + set bankSelection(value) { + this._bankSelection = value; + + if (value) { + const accountingType = value.accountingType; + this.receipt.description = accountingType && accountingType.receiptDescription; + } + } + getAmountPaid() { const filter = { where: { diff --git a/modules/client/front/balance/create/index.spec.js b/modules/client/front/balance/create/index.spec.js new file mode 100644 index 000000000..11fdb1040 --- /dev/null +++ b/modules/client/front/balance/create/index.spec.js @@ -0,0 +1,76 @@ +import './index'; + +describe('Client', () => { + describe('Component vnClientBalancCreate', () => { + let controller; + let $httpBackend; + let $httpParamSerializer; + + beforeEach(ngModule('client')); + + beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => { + $httpBackend = _$httpBackend_; + $httpParamSerializer = _$httpParamSerializer_; + let $scope = $rootScope.$new(); + const $element = angular.element(''); + const $transclude = { + $$boundTransclude: { + $$slots: [] + } + }; + controller = $componentController('vnClientBalanceCreate', {$element, $scope, $transclude}); + controller.receipt = { + clientFk: 101, + companyFk: 442 + }; + })); + + describe('bankSelection() setter', () => { + it('should set the receipt description property', () => { + controller.bankSelection = { + id: 1, + bank: 'Cash', + accountingType: { + id: 2, + receiptDescription: 'Cash' + } + }; + + expect(controller.receipt.description).toEqual('Cash'); + }); + }); + + describe('getAmountPaid()', () => { + it('should make an http GET query and then set the receipt amountPaid property', () => { + controller.$params = {id: 101}; + const receipt = controller.receipt; + const filter = { + where: { + clientFk: 101, + companyFk: 442 + } + }; + const serializedParams = $httpParamSerializer({filter}); + $httpBackend.expect('GET', `ClientRisks?${serializedParams}`,).respond([{amount: 20}]); + controller.getAmountPaid(); + $httpBackend.flush(); + + expect(receipt.amountPaid).toEqual(20); + }); + }); + + describe('responseHandler()', () => { + it('should make an http POST query and then call to the parent responseHandler() method', () => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + controller.$params = {id: 101}; + + $httpBackend.expect('POST', `Receipts`,).respond({id: 1}); + controller.responseHandler('accept'); + $httpBackend.flush(); + + expect(controller.vnApp.showSuccess).toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/modules/client/front/balance/index/index.html b/modules/client/front/balance/index/index.html index 1ad7efad9..cf0c07cfc 100644 --- a/modules/client/front/balance/index/index.html +++ b/modules/client/front/balance/index/index.html @@ -68,25 +68,33 @@ - {{::balance.userNickname}} + {{::balance.userName}} - -
- - {{'BILL' | translate: {ref: balance.ref} }} - - - {{::balance.ref}} - -
-
+ + +
+ + {{'BILL' | translate: {ref: balance.description} }} + + + {{balance.description}} + +
+
+ + + + +
{{::balance.bankFk}} {{::balance.debit | currency: 'EUR':2}} {{::balance.credit | currency: 'EUR':2}} diff --git a/modules/client/front/balance/index/index.js b/modules/client/front/balance/index/index.js index 8f5261176..7e09e018c 100644 --- a/modules/client/front/balance/index/index.js +++ b/modules/client/front/balance/index/index.js @@ -39,6 +39,10 @@ class Controller extends Section { this.getBalances(); } + get isAdministrative() { + return this.aclService.hasAny(['administrative']); + } + getData() { return this.$.model.applyFilter(null, { clientId: this.$params.id, @@ -58,7 +62,7 @@ class Controller extends Section { return balance.companyFk === selectedCompany; }); - return currentBalance.amount; + return currentBalance && currentBalance.amount; } getBalances() { @@ -79,6 +83,13 @@ class Controller extends Section { this.$.invoiceOutDescriptor.show(event.target, balance.id); } + + changeDescription(balance) { + const params = {description: balance.description}; + const endpoint = `Receipts/${balance.id}`; + this.$http.patch(endpoint, params) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); + } } Controller.$inject = ['$element', '$scope']; diff --git a/modules/client/front/balance/index/index.spec.js b/modules/client/front/balance/index/index.spec.js index 496407847..bdbea3846 100644 --- a/modules/client/front/balance/index/index.spec.js +++ b/modules/client/front/balance/index/index.spec.js @@ -3,10 +3,12 @@ import './index'; describe('Client', () => { describe('Component vnClientBalanceIndex', () => { let controller; + let $httpBackend; beforeEach(ngModule('client')); - beforeEach(inject(($componentController, $rootScope) => { + beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => { + $httpBackend = _$httpBackend_; let $scope = $rootScope.$new(); const $element = angular.element(''); controller = $componentController('vnClientBalanceIndex', {$element, $scope}); @@ -133,5 +135,21 @@ describe('Client', () => { expect(controller.getBalances).toHaveBeenCalledWith(); }); }); + + describe('changeDescription()', () => { + it('should make an http PATCH query', () => { + const expectedParams = {description: 'Web'}; + + $httpBackend.expect('PATCH', `Receipts/1`, expectedParams).respond(200); + controller.changeDescription({ + id: 1, + description: 'Web', + accountingType: { + description: 'Cash' + } + }); + $httpBackend.flush(); + }); + }); }); }); diff --git a/modules/item/back/methods/item/getLastEntries.js b/modules/item/back/methods/item/getLastEntries.js deleted file mode 100644 index a438afcb6..000000000 --- a/modules/item/back/methods/item/getLastEntries.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = Self => { - Self.remoteMethod('getLastEntries', { - description: 'Returns last entries', - accessType: 'READ', - accepts: [{ - arg: 'filter', - type: 'object', - required: true, - description: 'itemFk, id' - }], - returns: { - type: 'Array', - root: true - }, - http: { - path: `/getLastEntries`, - verb: 'GET' - } - }); - - Self.getLastEntries = async filter => { - let where = filter.where; - let query = `CALL vn.itemLastEntries(?, ?)`; - let [lastEntries] = await Self.rawSql(query, [where.itemFk, where.date]); - - return lastEntries; - }; -}; diff --git a/modules/item/back/methods/item/lastEntriesFilter.js b/modules/item/back/methods/item/lastEntriesFilter.js new file mode 100644 index 000000000..63e154b9e --- /dev/null +++ b/modules/item/back/methods/item/lastEntriesFilter.js @@ -0,0 +1,62 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; + +module.exports = Self => { + Self.remoteMethod('lastEntriesFilter', { + description: 'Returns last entries', + accessType: 'READ', + accepts: [{ + arg: 'filter', + type: 'object', + required: true, + description: 'itemFk, id' + }], + returns: { + type: 'Array', + root: true + }, + http: { + path: `/lastEntriesFilter`, + verb: 'GET' + } + }); + + Self.lastEntriesFilter = async filter => { + const conn = Self.dataSource.connector; + const stmt = new ParameterizedSQL( + `SELECT + w.id AS warehouseFk, + w.name AS warehouse, + tr.landed, + b.id AS buyFk, + b.entryFk, + b.isIgnored, + b.price2, + b.price3, + b.stickers, + b.packing, + b.grouping, + b.groupingMode, + b.weight, + i.stems, + b.quantity, + b.buyingValue, + b.packageFk , + s.id AS supplierFk, + s.name AS supplier + FROM itemType it + RIGHT JOIN (entry e + LEFT JOIN supplier s ON s.id = e.supplierFk + RIGHT JOIN buy b ON b.entryFk = e.id + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN ink ON ink.id = i.inkFk + LEFT JOIN travel tr ON tr.id = e.travelFk + LEFT JOIN warehouse w ON w.id = tr.warehouseInFk + LEFT JOIN origin o ON o.id = i.originFk + ) ON it.id = i.typeFk + LEFT JOIN edi.ekt ek ON b.ektFk = ek.id`); + stmt.merge(conn.makeSuffix(filter)); + + return conn.executeStmt(stmt); + }; +}; diff --git a/modules/item/back/methods/item/specs/getLastEntries.spec.js b/modules/item/back/methods/item/specs/getLastEntries.spec.js deleted file mode 100644 index 5c996d8e3..000000000 --- a/modules/item/back/methods/item/specs/getLastEntries.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -const app = require('vn-loopback/server/server'); - -describe('item getLastEntries()', () => { - it('should return one entry for a given item', async() => { - let date = new Date(); - let filter = {where: {itemFk: 1, date: date}}; - let result = await app.models.Item.getLastEntries(filter); - - expect(result.length).toEqual(1); - }); - - it('should return five entries for a given item', async() => { - let date = new Date(); - - date.setMonth(date.getMonth() - 2, 1); - - let filter = {where: {itemFk: 1, date: date}}; - let result = await app.models.Item.getLastEntries(filter); - - expect(result.length).toEqual(5); - }); -}); diff --git a/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js new file mode 100644 index 000000000..f64bfed8a --- /dev/null +++ b/modules/item/back/methods/item/specs/lastEntriesFilter.spec.js @@ -0,0 +1,24 @@ +const app = require('vn-loopback/server/server'); + +describe('item lastEntriesFilter()', () => { + const minDate = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxDate = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + it('should return one entry for a given item', async() => { + const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}}; + const result = await app.models.Item.lastEntriesFilter(filter); + + expect(result.length).toEqual(1); + }); + + it('should return five entries for a given item', async() => { + minDate.setMonth(minDate.getMonth() - 2, 1); + + const filter = {where: {itemFk: 1, landed: {between: [minDate, maxDate]}}}; + const result = await app.models.Item.lastEntriesFilter(filter); + + expect(result.length).toEqual(5); + }); +}); diff --git a/modules/item/back/models/item.js b/modules/item/back/models/item.js index d273404ea..9ddd056e6 100644 --- a/modules/item/back/models/item.js +++ b/modules/item/back/models/item.js @@ -5,7 +5,7 @@ module.exports = Self => { require('../methods/item/clone')(Self); require('../methods/item/updateTaxes')(Self); require('../methods/item/getBalance')(Self); - require('../methods/item/getLastEntries')(Self); + require('../methods/item/lastEntriesFilter')(Self); require('../methods/item/getSummary')(Self); require('../methods/item/getCard')(Self); require('../methods/item/regularize')(Self); diff --git a/modules/item/front/basic-data/index.html b/modules/item/front/basic-data/index.html index 7b3504b3c..99146deb0 100644 --- a/modules/item/front/basic-data/index.html +++ b/modules/item/front/basic-data/index.html @@ -109,6 +109,14 @@ ng-model="$ctrl.item.density" rule> + + + auto-load="true" + order="landed DESC, buyFk DESC" + limit="20"> - + @@ -20,8 +24,8 @@ Ig - Warehouse - Landed + Warehouse + Landed Entry P.P.U P.P.P @@ -29,11 +33,11 @@ Packing Grouping Stems - Quantity + Quantity Cost Kg. - Cube - Provider + Cube + Provider @@ -70,6 +74,30 @@ - - + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + \ No newline at end of file diff --git a/modules/item/front/last-entries/index.js b/modules/item/front/last-entries/index.js index 3f9d7be36..11a2bf20e 100644 --- a/modules/item/front/last-entries/index.js +++ b/modules/item/front/last-entries/index.js @@ -6,17 +6,23 @@ class Controller extends Section { constructor($element, $) { super($element, $); - let defaultDate = new Date(); - defaultDate.setDate(defaultDate.getDate() - 75); - defaultDate.setHours(0, 0, 0, 0); + const from = new Date(); + from.setDate(from.getDate() - 75); + from.setHours(0, 0, 0, 0); + + const to = new Date(); + to.setDate(to.getDate() + 10); + to.setHours(23, 59, 59, 59); this.filter = { where: { itemFk: this.$params.id, - date: defaultDate + shipped: { + between: [from, to] + } } }; - this._date = defaultDate; + this._date = from; } set date(value) { @@ -31,6 +37,32 @@ class Controller extends Section { get date() { return this._date; } + + exprBuilder(param, value) { + switch (param) { + case 'id': + case 'quantity': + case 'packageFk': + return {[`b.${param}`]: value}; + case 'supplierFk': + return {[`s.id`]: value}; + case 'warehouseFk': + return {'tr.warehouseInFk': value}; + case 'landed': + return {'tr.landed': { + between: this.dateRange(value)} + }; + } + } + + dateRange(value) { + const minHour = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxHour = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + return [minHour, maxHour]; + } } Controller.$inject = ['$element', '$scope']; diff --git a/modules/item/front/request-search-panel/index.html b/modules/item/front/request-search-panel/index.html index 453f3105b..10d5f9762 100644 --- a/modules/item/front/request-search-panel/index.html +++ b/modules/item/front/request-search-panel/index.html @@ -56,12 +56,14 @@ label="For me" ng-model="filter.mine"> - - + + {{name}} + diff --git a/modules/item/front/request-search-panel/index.js b/modules/item/front/request-search-panel/index.js index 82639b6e2..823346e30 100644 --- a/modules/item/front/request-search-panel/index.js +++ b/modules/item/front/request-search-panel/index.js @@ -1,7 +1,19 @@ import ngModule from '../module'; import SearchPanel from 'core/components/searchbar/search-panel'; +class Controller extends SearchPanel { + constructor($element, $) { + super($element, $); + + this.states = [ + {code: 'pending', name: this.$t('Pending')}, + {code: 'accepted', name: this.$t('Accepted')}, + {code: 'denied', name: this.$t('Denied')} + ]; + } +} + ngModule.vnComponent('vnRequestSearchPanel', { template: require('./index.html'), - controller: SearchPanel + controller: Controller }); diff --git a/modules/item/front/request/index.html b/modules/item/front/request/index.html index a677d0754..29a103746 100644 --- a/modules/item/front/request/index.html +++ b/modules/item/front/request/index.html @@ -24,14 +24,15 @@ Ticket ID Shipped - Description + Description Requested Price - Atender - Item + Atender + Item Achieved - Concept + Concept State + @@ -83,7 +84,7 @@ {{request.itemDescription}} - {{$ctrl.getState(request.isOk)}} + {{$ctrl.getState(request.isOk)}}
- \ No newline at end of file + + + + + + Filter by selection + + + Exclude selection + + + Remove filter + + + Remove all filters + + + \ No newline at end of file diff --git a/modules/item/front/request/index.js b/modules/item/front/request/index.js index 3801c926f..231d5eda7 100644 --- a/modules/item/front/request/index.js +++ b/modules/item/front/request/index.js @@ -17,18 +17,19 @@ export default class Controller extends Section { this.filterParams = { mine: true, from: today, - to: nextWeek + to: nextWeek, + state: 'pending' }; } } getState(isOk) { if (isOk === null) - return 'Nueva'; + return 'Pending'; else if (isOk) - return 'Aceptada'; + return 'Accepted'; else - return 'Denegada'; + return 'Denied'; } confirmRequest(request) { @@ -92,6 +93,31 @@ export default class Controller extends Section { this.vnApp.showSuccess(this.$t('Data saved!')); }); } + + exprBuilder(param, value) { + switch (param) { + case 'ticketFk': + case 'quantity': + case 'price': + case 'isOk': + return {[`tr.${param}`]: value}; + case 'attenderName': + return {[`ua.name`]: value}; + case 'shipped': + return {'t.shipped': { + between: this.dateRange(value)} + }; + } + } + + dateRange(value) { + const minHour = new Date(value); + minHour.setHours(0, 0, 0, 0); + const maxHour = new Date(value); + maxHour.setHours(23, 59, 59, 59); + + return [minHour, maxHour]; + } } ngModule.vnComponent('vnItemRequest', { diff --git a/modules/item/front/request/index.spec.js b/modules/item/front/request/index.spec.js index a33a21ec2..0fc061023 100644 --- a/modules/item/front/request/index.spec.js +++ b/modules/item/front/request/index.spec.js @@ -24,17 +24,17 @@ describe('Item', () => { let isOk = null; let result = controller.getState(isOk); - expect(result).toEqual('Nueva'); + expect(result).toEqual('Pending'); isOk = 1; result = controller.getState(isOk); - expect(result).toEqual('Aceptada'); + expect(result).toEqual('Accepted'); isOk = 0; result = controller.getState(isOk); - expect(result).toEqual('Denegada'); + expect(result).toEqual('Denied'); }); }); diff --git a/modules/item/front/request/locale/es.yml b/modules/item/front/request/locale/es.yml index 33710a327..c61a00130 100644 --- a/modules/item/front/request/locale/es.yml +++ b/modules/item/front/request/locale/es.yml @@ -3,4 +3,7 @@ Specify the reasons to deny this request: Especifica las razones para descartar Buy requests: Peticiones de compra Search request by id or alias: Buscar peticiones por identificador o alias Requested: Solicitado -Achieved: Conseguido \ No newline at end of file +Achieved: Conseguido +Pending: Pendiente +Accepted: Aceptada +Denied: Rechazada \ No newline at end of file diff --git a/modules/order/back/methods/order/filter.js b/modules/order/back/methods/order/filter.js index bfa64c4dd..66b4244d0 100644 --- a/modules/order/back/methods/order/filter.js +++ b/modules/order/back/methods/order/filter.js @@ -136,14 +136,10 @@ module.exports = Self => { let stmts = []; let stmt; - stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.filter'); - stmt = new ParameterizedSQL( - `CREATE TEMPORARY TABLE tmp.filter - (INDEX (id)) - ENGINE = MEMORY - SELECT + `SELECT o.id, + o.total, o.date_send landed, o.date_make created, o.customer_id clientFk, @@ -178,36 +174,13 @@ module.exports = Self => { } stmt.merge(conn.makeWhere(filter.where)); - stmt.merge({ - sql: `GROUP BY o.id` - }); + stmt.merge(`GROUP BY o.id`); stmt.merge(conn.makePagination(filter)); stmts.push(stmt); - stmts.push(` - CREATE TEMPORARY TABLE tmp.order - (INDEX (orderFk)) - ENGINE = MEMORY - SELECT id AS orderFk - FROM tmp.filter`); + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql); - stmts.push('CALL hedera.order_getTotal()'); - - stmt = new ParameterizedSQL( - `SELECT f.*, ot.* - FROM tmp.filter f - LEFT JOIN tmp.orderTotal ot ON ot.orderFk = f.id`); - const orderIndex = stmts.push(stmt) - 1; - - stmts.push(` - DROP TEMPORARY TABLE - tmp.order, - tmp.orderTotal, - tmp.filter`); - - let sql = ParameterizedSQL.join(stmts, ';'); - let result = await conn.executeStmt(sql); - - return result[orderIndex]; + return result; }; }; diff --git a/modules/order/back/models/order.json b/modules/order/back/models/order.json index ab10ad194..38755c2a5 100644 --- a/modules/order/back/models/order.json +++ b/modules/order/back/models/order.json @@ -79,6 +79,9 @@ "mysql": { "columnName": "confirm_date" } + }, + "total": { + "type": "Number" } }, "relations": { diff --git a/modules/order/front/locale/es.yml b/modules/order/front/locale/es.yml index fbc384f21..c35898378 100644 --- a/modules/order/front/locale/es.yml +++ b/modules/order/front/locale/es.yml @@ -23,4 +23,5 @@ Created from: Creado desde Search order by id: Buscar el pedido por identificador order: pedido Confirm lines: Confirmar las lineas -Confirm: Confirmar \ No newline at end of file +Confirm: Confirmar +Real hour: Hora real \ No newline at end of file diff --git a/modules/order/front/search-panel/locale/es.yml b/modules/order/front/search-panel/locale/es.yml index 949f9b202..9546c7f74 100644 --- a/modules/order/front/search-panel/locale/es.yml +++ b/modules/order/front/search-panel/locale/es.yml @@ -7,4 +7,5 @@ Agency: Agencia Application: Aplicación SalesPerson: Comercial Order confirmed: Pedido confirmado -Show empty: Mostrar vacías \ No newline at end of file +Show empty: Mostrar vacías +Search orders by id: Buscar pedido por id \ No newline at end of file diff --git a/modules/ticket/back/methods/expedition/filter.js b/modules/ticket/back/methods/expedition/filter.js index 3ff2fcb59..79c7131ea 100644 --- a/modules/ticket/back/methods/expedition/filter.js +++ b/modules/ticket/back/methods/expedition/filter.js @@ -29,20 +29,24 @@ module.exports = Self => { e.ticketFk, e.isBox, e.workerFk, - i1.name namePackage, + i1.name packageItemName, e.counter, e.checked, - i2.name nameBox, + i2.name freightItemName, e.itemFk, u.nickname userNickname, e.created, - e.externalId + e.externalId, + i3.name packagingName, + i3.id packagingItemFk, + e.packagingFk FROM vn.expedition e LEFT JOIN vn.item i2 ON i2.id = e.itemFk INNER JOIN vn.item i1 ON i1.id = e.isBox - LEFT JOIN vn.worker w ON w.id = e.workerFk - LEFT JOIN account.user u ON u.id = w.userFk + LEFT JOIN vn.packaging p ON p.id = e.packagingFk + LEFT JOIN vn.item i3 ON i3.id = p.itemFk + LEFT JOIN account.user u ON u.id = e.workerFk `); stmt.merge(Self.buildSuffix(filter, 'e')); diff --git a/modules/ticket/back/methods/ticket-request/filter.js b/modules/ticket/back/methods/ticket-request/filter.js index ecd88caeb..4b7b088f4 100644 --- a/modules/ticket/back/methods/ticket-request/filter.js +++ b/modules/ticket/back/methods/ticket-request/filter.js @@ -44,8 +44,8 @@ module.exports = Self => { type: 'Date', description: `Date to` }, { - arg: 'isOk', - type: 'Boolean', + arg: 'state', + type: 'String', description: `Search request by request state` } ], @@ -77,8 +77,13 @@ module.exports = Self => { return {'t.id': value}; case 'attenderFk': return {'tr.attenderFk': value}; - case 'isOk': - return {'tr.isOk': value}; + case 'state': + switch (value) { + case 'pending': + return {'tr.isOk': null}; + default: + return {'tr.isOk': value}; + } case 'clientFk': return {'t.clientFk': value}; case 'from': diff --git a/modules/ticket/back/models/expedition.json b/modules/ticket/back/models/expedition.json index 4a9682e03..c0b8d6508 100644 --- a/modules/ticket/back/models/expedition.json +++ b/modules/ticket/back/models/expedition.json @@ -24,12 +24,6 @@ }, "counter": { "type": "Number" - }, - "checked": { - "type": "Number" - }, - "externalId": { - "type": "Number" } }, "relations": { @@ -43,7 +37,7 @@ "model": "agency-mode", "foreignKey": "agencyModeFk" }, - "item": { + "packageItem": { "type": "belongsTo", "model": "Item", "foreignKey": "itemFk" @@ -58,10 +52,15 @@ "model": "TicketPackaging", "foreignKey": "ticketFk" }, - "box": { + "freightItem": { "type": "belongsTo", "model": "Item", "foreignKey": "isBox" + }, + "packaging": { + "type": "belongsTo", + "model": "Package", + "foreignKey": "packagingFk" } } } diff --git a/modules/ticket/front/basic-data/step-one/index.js b/modules/ticket/front/basic-data/step-one/index.js index 68f5ac54d..45fd397dd 100644 --- a/modules/ticket/front/basic-data/step-one/index.js +++ b/modules/ticket/front/basic-data/step-one/index.js @@ -155,7 +155,7 @@ class Controller extends Component { let query = `Clients/${value}`; this.$http.get(query).then(res => { if (res.data) - this.ticket.addressFk = res.data.defaultAddressFk; + this.addressId = res.data.defaultAddressFk; }); } diff --git a/modules/ticket/front/descriptor/index.js b/modules/ticket/front/descriptor/index.js index 7ce94f53d..fdcd50e3c 100644 --- a/modules/ticket/front/descriptor/index.js +++ b/modules/ticket/front/descriptor/index.js @@ -8,7 +8,6 @@ class Controller extends Descriptor { set ticket(value) { this.entity = value; - this.isTicketEditable(); } get entity() { @@ -18,6 +17,7 @@ class Controller extends Descriptor { set entity(value) { super.entity = value; this.canStowaway(); + this.isTicketEditable(); if (value && this.$params.sendSMS) this.showSMSDialog(); @@ -45,7 +45,8 @@ class Controller extends Descriptor { } isTicketEditable() { - this.$http.get(`Tickets/${this.$state.params.id}/isEditable`).then(res => { + if (!this.ticket) return; + this.$http.get(`Tickets/${this.id}/isEditable`).then(res => { this.isEditable = res.data; }); } diff --git a/modules/ticket/front/expedition/index.html b/modules/ticket/front/expedition/index.html index 3b17a3b88..fc7b473cc 100644 --- a/modules/ticket/front/expedition/index.html +++ b/modules/ticket/front/expedition/index.html @@ -14,12 +14,10 @@ Expedition - Envialia Item Name Package type Counter - Checked Worker Created @@ -33,18 +31,16 @@ {{expedition.id | zeroFill:6}} - {{expedition.externalId | zeroFill:6}} - {{expedition.itemFk | zeroFill:6}} + ng-class="{link: expedition.packagingItemFk}" + ng-click="itemDescriptor.show($event, expedition.packagingItemFk)"> + {{expedition.packagingFk}} - {{::expedition.namePackage}} - {{::expedition.nameBox}} + {{::expedition.packageItemName}} + {{::expedition.freightItemName}} {{::expedition.counter}} - {{::expedition.checked}}