Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2973-module_zone_transactions

This commit is contained in:
Carlos Jimenez Ruiz 2021-06-21 14:35:01 +02:00
commit b651fdebe6
12 changed files with 376 additions and 18 deletions

View File

@ -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 ;

View File

@ -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$$

View File

@ -0,0 +1,62 @@
<vn-watcher
vn-id="watcher"
url="InvoiceIns"
data="$ctrl.invoiceIn"
insert-mode="true"
form="form">
</vn-watcher>
<form name="form" vn-http-submit="$ctrl.onSubmit()" class="vn-w-md">
<div class="vn-w-md">
<vn-card class="vn-pa-lg">
<vn-autocomplete
vn-focus
vn-id="supplier"
url="Suppliers"
label="Supplier"
search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
show-field="name"
value-field="id"
ng-model="$ctrl.invoiceIn.supplierFk"
order="id"
vn-focus>
<tpl-item>{{id}}: {{name}}</tpl-item>
</vn-autocomplete>
<vn-textfield
vn-one
label="supplierRef"
ng-model="$ctrl.invoiceIn.supplierRef">
</vn-textfield>
<vn-date-picker
label="Issued"
ng-model="$ctrl.invoiceIn.issued">
</vn-date-picker>
<vn-autocomplete
vn-one
label="Currency"
ng-model="$ctrl.invoiceIn.currencyFk"
url="Currencies"
show-field="code"
value-field="id">
</vn-autocomplete>
<vn-autocomplete
vn-one
label="Company"
ng-model="$ctrl.companyFk"
url="companies"
show-field="code"
value-field="id">
</vn-autocomplete>
</vn-card>
<vn-button-bar>
<vn-submit
disabled="!watcher.dataChanged()"
label="Create">
</vn-submit>
<vn-button
class="cancel"
label="Cancel"
ui-sref="InvoiceIn.index">
</vn-button>
</vn-button-bar>
</div>
</form>

View File

@ -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
});

View File

@ -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('<vn-invoice-in-create></vn-invoice-in-create>');
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});
});
});
});
});

View File

@ -0,0 +1 @@
a:a

View File

@ -8,4 +8,5 @@ import './descriptor';
import './descriptor-popover';
import './summary';
import './basic-data';
import './create';
import './log';

View File

@ -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

View File

@ -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"
]
}
]
}

View File

@ -56,6 +56,11 @@
</vn-quick-link>
</div>
<div ng-transclude="btnThree">
<vn-quick-link
tooltip="Create invoiceIn"
state="['invoiceIn.create', {supplierFk: $ctrl.id}]"
icon="icon-invoice-in-create">
</vn-quick-link>
</div>
</div>
</slot-body>

View File

@ -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
Inactive supplier: Proveedor inactivo
Create invoiceIn: Crear factura recibida

2
package-lock.json generated
View File

@ -20760,4 +20760,4 @@
}
}
}
}
}