diff --git a/db/changes/10330-jun2021/00-sale_getProblems.sql b/db/changes/10330-jun2021/00-sale_getProblems.sql new file mode 100644 index 000000000..6685378b3 --- /dev/null +++ b/db/changes/10330-jun2021/00-sale_getProblems.sql @@ -0,0 +1,192 @@ +DROP PROCEDURE IF EXISTS `vn`.`sale_getProblems`; + +DELIMITER $$ +$$ +CREATE + DEFINER = root@`%` PROCEDURE `vn`.`sale_getProblems`(IN vIsTodayRelative TINYINT(1)) +BEGIN +/** + * Calcula los problemas de cada venta + * para un conjunto de tickets. + * + * @table tmp.sale_getProblems(ticketFk, clientFk, warehouseFk, shipped) Identificadores de los tickets a calcular + * @return tmp.sale_problems + */ + DECLARE vWarehouse INT; + DECLARE vDate DATE; + DECLARE vAvailableCache INT; + DECLARE vDone INT DEFAULT 0; + DECLARE vComponentCount INT; + + DECLARE vCursor CURSOR FOR + SELECT DISTINCT tt.warehouseFk, IF(vIsTodayRelative, CURDATE(), date(tt.shipped)) + FROM tmp.sale_getProblems tt + WHERE DATE(tt.shipped) BETWEEN CURDATE() + AND TIMESTAMPADD(DAY, IF(vIsTodayRelative, 9.9, 1.9), CURDATE()); + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = 1; + + DROP TEMPORARY TABLE IF EXISTS tmp.sale_problems; + CREATE TEMPORARY TABLE tmp.sale_problems ( + ticketFk INT(11), + saleFk INT(11), + isFreezed INTEGER(1) DEFAULT 0, + risk DECIMAL(10,2) DEFAULT 0, + hasTicketRequest INTEGER(1) DEFAULT 0, + isAvailable INTEGER(1) DEFAULT 1, + itemShortage VARCHAR(250), + isTaxDataChecked INTEGER(1) DEFAULT 1, + itemDelay VARCHAR(250), + hasComponentLack INTEGER(1), + PRIMARY KEY (ticketFk, saleFk) + ) ENGINE = MEMORY; + + DROP TEMPORARY TABLE IF EXISTS tmp.ticket_list; + CREATE TEMPORARY TABLE tmp.ticket_list + (PRIMARY KEY (ticketFk)) + ENGINE = MEMORY + SELECT tp.ticketFk, c.id clientFk + FROM tmp.sale_getProblems tp + JOIN vn.client c ON c.id = tp.clientFk; + + SELECT COUNT(*) INTO vComponentCount + FROM vn.component c + WHERE c.isRequired; + + INSERT INTO tmp.sale_problems(ticketFk, hasComponentLack, saleFk) + SELECT tl.ticketFk, (COUNT(DISTINCT s.id) * vComponentCount > COUNT(c.id)), s.id + FROM tmp.ticket_list tl + JOIN vn.sale s ON s.ticketFk = tl.ticketFk + LEFT JOIN vn.saleComponent sc ON sc.saleFk = s.id + LEFT JOIN vn.component c ON c.id = sc.componentFk AND c.isRequired + GROUP BY tl.ticketFk, s.id; + + INSERT INTO tmp.sale_problems(ticketFk, isFreezed) + SELECT DISTINCT tl.ticketFk, TRUE + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isFreezed + ON DUPLICATE KEY UPDATE + isFreezed = c.isFreezed; + + DROP TEMPORARY TABLE IF EXISTS tmp.clientGetDebt; + CREATE TEMPORARY TABLE tmp.clientGetDebt + (PRIMARY KEY (clientFk)) + ENGINE = MEMORY + SELECT DISTINCT clientFk + FROM tmp.ticket_list; + + CALL clientGetDebt(CURDATE()); + + INSERT INTO tmp.sale_problems(ticketFk, risk) + SELECT DISTINCT tl.ticketFk, r.risk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.agencyMode a ON t.agencyModeFk = a.id + JOIN tmp.risk r ON r.clientFk = t.clientFk + JOIN vn.client c ON c.id = t.clientFk + JOIN vn.clientConfig cc + WHERE r.risk > c.credit + 10 + AND a.isRiskFree = FALSE + ON DUPLICATE KEY UPDATE + risk = r.risk; + + INSERT INTO tmp.sale_problems(ticketFk, hasTicketRequest) + SELECT DISTINCT tl.ticketFk, TRUE + FROM tmp.ticket_list tl + JOIN vn.ticketRequest tr ON tr.ticketFk = tl.ticketFk + WHERE tr.isOK IS NULL + ON DUPLICATE KEY UPDATE + hasTicketRequest = TRUE; + + OPEN vCursor; + + WHILE NOT vDone + DO + FETCH vCursor INTO vWarehouse, vDate; + + CALL cache.available_refresh(vAvailableCache, FALSE, vWarehouse, vDate); + + INSERT INTO tmp.sale_problems(ticketFk, isAvailable, saleFk) + SELECT tl.ticketFk, FALSE, s.id + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN cache.available av ON av.item_id = i.id + AND av.calc_id = vAvailableCache + WHERE date(t.shipped) = vDate + AND it.categoryFk != 6 + AND IFNULL(av.available, 0) < 0 + AND s.isPicked = FALSE + AND NOT i.generic + AND vWarehouse = t.warehouseFk + GROUP BY tl.ticketFk + ON DUPLICATE KEY UPDATE + isAvailable = FALSE, saleFk = VALUE(saleFk); + + INSERT INTO tmp.sale_problems(ticketFk, itemShortage, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, CONCAT('F: ',GROUP_CONCAT(i.id, ' ', i.longName, ' ')) problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + LEFT JOIN cache.available av ON av.item_id = i.id AND av.calc_id = vAvailableCache + WHERE IFNULL(av.available, 0) < 0 + AND s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk LIMIT 1) sub + ON DUPLICATE KEY UPDATE + itemShortage = sub.problem, saleFk = sub.saleFk; + + INSERT INTO tmp.sale_problems(ticketFk, itemDelay, saleFk) + SELECT ticketFk, problem, saleFk + FROM ( + SELECT tl.ticketFk, GROUP_CONCAT('I: ',i.id, ' ', i.longName, ' ') problem, s.id AS saleFk + FROM tmp.ticket_list tl + JOIN vn.ticket t ON t.id = tl.ticketFk + JOIN vn.sale s ON s.ticketFk = t.id + JOIN vn.item i ON i.id = s.itemFk + JOIN vn.itemType it on it.id = i.typeFk + LEFT JOIN vn.itemShelvingStock_byWarehouse issw ON issw.itemFk = i.id AND issw.warehouseFk = t.warehouseFk + WHERE s.quantity > IFNULL(issw.visible, 0) + AND s.quantity > 0 + AND s.isPicked = FALSE + AND s.reserved = FALSE + AND it.categoryFk != 6 + AND IF(vIsTodayRelative, TRUE, date(t.shipped) = vDate) + AND NOT i.generic + AND CURDATE() = vDate + AND t.warehouseFk = vWarehouse + GROUP BY tl.ticketFk LIMIT 1) sub + ON DUPLICATE KEY UPDATE + itemDelay = sub.problem, saleFk = sub.saleFk; + END WHILE; + + CLOSE vCursor; + + INSERT INTO tmp.sale_problems(ticketFk, isTaxDataChecked) + SELECT DISTINCT tl.ticketFk, FALSE + FROM tmp.ticket_list tl + JOIN vn.client c ON c.id = tl.clientFk + WHERE c.isTaxDataChecked = FALSE + ON DUPLICATE KEY UPDATE + isTaxDataChecked = FALSE; + + DROP TEMPORARY TABLE + tmp.clientGetDebt, + tmp.ticket_list; +END;;$$ +DELIMITER ; diff --git a/db/changes/10330-jun2021/01-ticket_componentMakeUpdate.sql b/db/changes/10330-jun2021/01-ticket_componentMakeUpdate.sql index ac3e85f08..058d6eb99 100644 --- a/db/changes/10330-jun2021/01-ticket_componentMakeUpdate.sql +++ b/db/changes/10330-jun2021/01-ticket_componentMakeUpdate.sql @@ -31,16 +31,9 @@ BEGIN */ DECLARE vPrice DECIMAL(10,2); DECLARE vBonus DECIMAL(10,2); - DECLARE EXIT HANDLER FOR SQLEXCEPTION - BEGIN - ROLLBACK; - RESIGNAL; - END; CALL ticket_componentPreview (vTicketFk, vLanded, vAddressFk, vZoneFk, vWarehouseFk); - START TRANSACTION; - IF (SELECT addressFk FROM ticket WHERE id = vTicketFk) <> vAddressFk THEN UPDATE ticket t @@ -95,7 +88,6 @@ BEGIN DROP TEMPORARY TABLE tmp.sale; DROP TEMPORARY TABLE IF EXISTS tmp.ticketComponent; END IF; - COMMIT; DROP TEMPORARY TABLE tmp.zoneGetShipped, tmp.ticketComponentPreview; END$$ diff --git a/modules/invoiceIn/front/create/index.html b/modules/invoiceIn/front/create/index.html new file mode 100644 index 000000000..4ec724854 --- /dev/null +++ b/modules/invoiceIn/front/create/index.html @@ -0,0 +1,62 @@ + + +
+
+ + + {{id}}: {{name}} + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/modules/invoiceIn/front/create/index.js b/modules/invoiceIn/front/create/index.js new file mode 100644 index 000000000..186f5d478 --- /dev/null +++ b/modules/invoiceIn/front/create/index.js @@ -0,0 +1,29 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; + +class Controller extends Section { + $onInit() { + this.invoiceIn = {}; + if (this.$params && this.$params.supplierFk) + this.invoiceIn.supplierFk = this.$params.supplierFk; + } + + get companyFk() { + return this.invoiceIn.companyFk || this.vnConfig.companyFk; + } + + set companyFk(value) { + this.invoiceIn.companyFk = value; + } + + onSubmit() { + this.$.watcher.submit().then( + res => this.$state.go('invoiceIn.card.basicData', {id: res.data.id}) + ); + } +} + +ngModule.vnComponent('vnInvoiceInCreate', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/invoiceIn/front/create/index.spec.js b/modules/invoiceIn/front/create/index.spec.js new file mode 100644 index 000000000..93109346c --- /dev/null +++ b/modules/invoiceIn/front/create/index.spec.js @@ -0,0 +1,52 @@ +import './index.js'; +import watcher from 'core/mocks/watcher'; + +describe('InvoiceIn', () => { + describe('Component vnInvoiceInCreate', () => { + let controller; + let $element; + + beforeEach(ngModule('invoiceIn')); + + beforeEach(inject(($componentController, $rootScope) => { + const $scope = $rootScope.$new(); + $scope.watcher = watcher; + $element = angular.element(''); + controller = $componentController('vnInvoiceInCreate', {$element, $scope}); + controller.$params = {}; + })); + + afterEach(() => { + $element.remove(); + }); + + describe('onInit()', () => { + it(`should defined the controller's invoiceIn property`, () => { + expect(controller.invoiceIn).toBeUndefined(); + + controller.$onInit(); + + expect(controller.invoiceIn).toEqual({}); + }); + + it(`should define invoiceIn and it's supplierFk when received via params`, () => { + controller.$params.supplierFk = 'supplierId'; + + controller.$onInit(); + + expect(controller.invoiceIn.supplierFk).toEqual('supplierId'); + }); + }); + + describe('onSubmit()', () => { + it(`should redirect to basic data by calling the $state.go function`, () => { + jest.spyOn(controller.$state, 'go'); + + controller.onSubmit(); + + expect(controller.$state.go).toHaveBeenCalledWith('invoiceIn.card.basicData', {id: 1234}); + }); + }); + }); +}); + diff --git a/modules/invoiceIn/front/create/locale/es.yml b/modules/invoiceIn/front/create/locale/es.yml new file mode 100644 index 000000000..35bfe3ca4 --- /dev/null +++ b/modules/invoiceIn/front/create/locale/es.yml @@ -0,0 +1 @@ +a:a \ No newline at end of file diff --git a/modules/invoiceIn/front/index.js b/modules/invoiceIn/front/index.js index 2102b338f..f82228f0a 100644 --- a/modules/invoiceIn/front/index.js +++ b/modules/invoiceIn/front/index.js @@ -8,4 +8,5 @@ import './descriptor'; import './descriptor-popover'; import './summary'; import './basic-data'; +import './create'; import './log'; diff --git a/modules/invoiceIn/front/locale/es.yml b/modules/invoiceIn/front/locale/es.yml index 2d8dc02da..ac432aba8 100644 --- a/modules/invoiceIn/front/locale/es.yml +++ b/modules/invoiceIn/front/locale/es.yml @@ -1,5 +1,5 @@ InvoiceIn: Facturas recibidas Search invoices in by reference: Buscar facturas recibidas por referencia Entries list: Listado de entradas -Invoice list: Listado de entradas +Invoice list: Listado de facturas recibidas InvoiceIn deleted: Factura eliminada \ No newline at end of file diff --git a/modules/invoiceIn/front/routes.json b/modules/invoiceIn/front/routes.json index 5f842f760..d09d8fda0 100644 --- a/modules/invoiceIn/front/routes.json +++ b/modules/invoiceIn/front/routes.json @@ -2,11 +2,17 @@ "module": "invoiceIn", "name": "Invoices in", "icon": "icon-invoiceIn", - "validations" : true, - "dependencies": ["worker", "supplier"], + "validations": true, + "dependencies": [ + "worker", + "supplier" + ], "menus": { "main": [ - {"state": "invoiceIn.index", "icon": "icon-invoiceIn"} + { + "state": "invoiceIn.index", + "icon": "icon-invoiceIn" + } ], "card": [ { @@ -32,7 +38,9 @@ "state": "invoiceIn.index", "component": "vn-invoice-in-index", "description": "InvoiceIn", - "acl": ["administrative"] + "acl": [ + "administrative" + ] }, { "url": "/:id", @@ -48,7 +56,9 @@ "params": { "invoice-in": "$ctrl.invoiceIn" }, - "acl": ["administrative"] + "acl": [ + "administrative" + ] }, { "url": "/basic-data", @@ -58,14 +68,27 @@ "params": { "invoice-in": "$ctrl.invoiceIn" }, - "acl": ["administrative"] + "acl": [ + "administrative" + ] + }, + { + "url": "/create?supplierFk", + "state": "invoiceIn.create", + "component": "vn-invoice-in-create", + "description": "New InvoiceIn", + "acl": [ + "administrative" + ] }, { "url": "/log", "state": "invoiceIn.card.log", "component": "vn-invoice-in-log", "description": "Log", - "acl": ["administrative"] + "acl": [ + "administrative" + ] } ] } \ No newline at end of file diff --git a/modules/supplier/front/descriptor/index.html b/modules/supplier/front/descriptor/index.html index 9603f7758..9781c95b8 100644 --- a/modules/supplier/front/descriptor/index.html +++ b/modules/supplier/front/descriptor/index.html @@ -56,6 +56,11 @@
+ +
diff --git a/modules/supplier/front/descriptor/locale/es.yml b/modules/supplier/front/descriptor/locale/es.yml index ad47a5477..d889a9eee 100644 --- a/modules/supplier/front/descriptor/locale/es.yml +++ b/modules/supplier/front/descriptor/locale/es.yml @@ -3,4 +3,5 @@ All entries with current supplier: Todas las entradas con el proveedor actual Go to client: Ir al cliente Verified supplier: Proveedor verificado Unverified supplier: Proveedor no verificado -Inactive supplier: Proveedor inactivo \ No newline at end of file +Inactive supplier: Proveedor inactivo +Create invoiceIn: Crear factura recibida \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6ca78ba5d..bc8cba293 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20760,4 +20760,4 @@ } } } -} +} \ No newline at end of file