Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 2167-entry_buy
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
65457d6dac
|
@ -8,7 +8,9 @@ Salix is also the scientific name of a beautifull tree! :)
|
|||
|
||||
Required applications.
|
||||
|
||||
* Node.js = 14.15.1 LTS
|
||||
* Node.js = 14.x LTS
|
||||
* Docker
|
||||
* Git
|
||||
* Docker
|
||||
|
||||
You will need to install globally the following items.
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE vn.`supplierAccount` ADD `beneficiary` VARCHAR(50) NULL DEFAULT NULL AFTER `bankFk`;
|
||||
UPDATE vn.supplierAccount SET beneficiary = `description`;
|
|
@ -1,24 +1,28 @@
|
|||
drop procedure weekWaste;
|
||||
DROP PROCEDURE IF EXISTS `bs`.`weekWaste`;
|
||||
|
||||
create definer = root@`%` procedure weekWaste__()
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER = `root`@`%` PROCEDURE `bs`.`weekWaste__`()
|
||||
BEGIN
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vYear INT;
|
||||
|
||||
SELECT week, year
|
||||
INTO vWeek, vYear
|
||||
FROM vn.time
|
||||
WHERE dated = DATE_ADD(CURDATE(), INTERVAL -1 WEEK);
|
||||
INTO vWeek, vYear
|
||||
FROM vn.time
|
||||
WHERE dated = DATE_ADD(CURDATE(), INTERVAL -1 WEEK);
|
||||
|
||||
SELECT *, 100 * dwindle / total AS percentage
|
||||
FROM (
|
||||
SELECT buyer,
|
||||
sum(saleTotal) as total,
|
||||
sum(saleWaste) as dwindle
|
||||
FROM bs.waste
|
||||
WHERE year = vYear and week = vWeek
|
||||
GROUP BY buyer
|
||||
) sub
|
||||
ORDER BY percentage DESC;
|
||||
END;
|
||||
SELECT *, 100 * dwindle / total AS percentage
|
||||
FROM (
|
||||
SELECT buyer,
|
||||
SUM(saleTotal) AS total,
|
||||
SUM(saleWaste) AS dwindle
|
||||
FROM bs.waste
|
||||
WHERE year = vYear
|
||||
AND week = vWeek
|
||||
GROUP BY buyer
|
||||
) sub
|
||||
ORDER BY percentage DESC;
|
||||
END;$$
|
||||
DELIMITER ;
|
||||
|
||||
|
|
|
@ -1,28 +1,32 @@
|
|||
drop procedure weekWaste_byWorker;
|
||||
DROP PROCEDURE IF EXISTS `bs`.`weekWaste_byWorker`;
|
||||
|
||||
create definer = root@`%` procedure weekWaste_byWorker__(IN vWorkerFk int)
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE
|
||||
DEFINER = root@`%` PROCEDURE `bs`.`weekWaste_byWorker__`(IN vWorkerFk INT)
|
||||
BEGIN
|
||||
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vYear INT;
|
||||
|
||||
SELECT week, year
|
||||
INTO vWeek, vYear
|
||||
FROM vn.time
|
||||
WHERE dated = TIMESTAMPADD(WEEK,-1,CURDATE());
|
||||
INTO vWeek, vYear
|
||||
FROM vn.time
|
||||
WHERE dated = TIMESTAMPADD(WEEK, -1, CURDATE());
|
||||
|
||||
SELECT *, 100 * mermas / total as porcentaje
|
||||
FROM (
|
||||
SELECT ws.family,
|
||||
sum(ws.saleTotal) as total,
|
||||
sum(ws.saleWaste) as mermas
|
||||
FROM bs.waste ws
|
||||
SELECT *, 100 * mermas / total AS porcentaje
|
||||
FROM (
|
||||
SELECT ws.family,
|
||||
SUM(ws.saleTotal) AS total,
|
||||
SUM(ws.saleWaste) AS mermas
|
||||
FROM bs.waste ws
|
||||
JOIN vn.worker w ON w.user = ws.buyer
|
||||
WHERE year = vYear AND week = vWeek
|
||||
AND w.id = vWorkerFk
|
||||
GROUP BY family
|
||||
|
||||
) sub
|
||||
ORDER BY porcentaje DESC;
|
||||
END;
|
||||
WHERE year = vYear
|
||||
AND week = vWeek
|
||||
AND w.id = vWorkerFk
|
||||
GROUP BY family
|
||||
) sub
|
||||
ORDER BY porcentaje DESC;
|
||||
END;;$$
|
||||
DELIMITER ;
|
||||
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
drop procedure weekWaste_getDetail;
|
||||
DROP PROCEDURE IF EXISTS `bs`.`weekWaste_getDetail`;
|
||||
|
||||
create definer = root@`%` procedure weekWaste_getDetail__()
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE
|
||||
DEFINER = root@`%` PROCEDURE `bs`.`weekWaste_getDetail__`()
|
||||
BEGIN
|
||||
DECLARE vLastWeek DATE;
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vLastWeek DATE;
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vYear INT;
|
||||
|
||||
SET vLastWeek = TIMESTAMPADD(WEEK,-1,CURDATE());
|
||||
SET vLastWeek = TIMESTAMPADD(WEEK, -1, CURDATE());
|
||||
SET vYear = YEAR(vLastWeek);
|
||||
SET vWeek = WEEK(vLastWeek, 1);
|
||||
|
||||
SELECT *, 100 * dwindle / total AS percentage
|
||||
FROM (
|
||||
SELECT buyer,
|
||||
ws.family,
|
||||
sum(ws.saleTotal) AS total,
|
||||
sum(ws.saleWaste) AS dwindle
|
||||
FROM bs.waste ws
|
||||
WHERE year = vYear AND week = vWeek
|
||||
GROUP BY buyer, family
|
||||
) sub
|
||||
ORDER BY percentage DESC;
|
||||
END;
|
||||
SELECT *, 100 * dwindle / total AS percentage
|
||||
FROM (
|
||||
SELECT buyer,
|
||||
ws.family,
|
||||
SUM(ws.saleTotal) AS total,
|
||||
SUM(ws.saleWaste) AS dwindle
|
||||
FROM bs.waste ws
|
||||
WHERE year = vYear
|
||||
AND week = vWeek
|
||||
GROUP BY buyer, family
|
||||
) sub
|
||||
ORDER BY percentage DESC;
|
||||
END;$$
|
||||
DELIMITER ;
|
||||
|
||||
|
|
|
@ -17,6 +17,5 @@ ALTER TABLE `bs`.`waste`
|
|||
ALTER TABLE `bs`.`waste` DROP PRIMARY KEY;
|
||||
|
||||
ALTER TABLE `bs`.`waste`
|
||||
AD PRIMARY KEY (buyer, year, week, family, itemFk);
|
||||
|
||||
ADD PRIMARY KEY (buyer, `year`, week, family, itemFk);
|
||||
|
||||
|
|
|
@ -2,27 +2,28 @@ UPDATE `bs`.nightTask t SET t.`procedure` = 'waste_addSales' WHERE t.id = 54;
|
|||
|
||||
DROP PROCEDURE IF EXISTS `bs`.`waste_Add`;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE
|
||||
DEFINER = root@`%` PROCEDURE `bs`.`waste_addSales`()
|
||||
DEFINER = root@`%` PROCEDURE `bs`.`waste_addSales`()
|
||||
BEGIN
|
||||
|
||||
DECLARE vWeek INT;
|
||||
DECLARE vYear INT;
|
||||
DECLARE vYear INT;
|
||||
|
||||
SELECT week, year
|
||||
SELECT week, year
|
||||
INTO vWeek, vYear
|
||||
FROM vn.time
|
||||
WHERE dated = CURDATE();
|
||||
FROM vn.time
|
||||
WHERE dated = CURDATE();
|
||||
|
||||
REPLACE bs.waste
|
||||
REPLACE bs.waste
|
||||
SELECT *, 100 * mermas / total as porcentaje
|
||||
FROM (
|
||||
SELECT buyer,
|
||||
year,
|
||||
week,
|
||||
week,
|
||||
family,
|
||||
itemFk,
|
||||
itemTypeFk,
|
||||
itemFk,
|
||||
itemTypeFk,
|
||||
floor(sum(value)) as total,
|
||||
floor(sum(IF(clientTypeFk = 'loses', value, 0))) as mermas
|
||||
FROM vn.saleValue
|
||||
|
@ -32,7 +33,5 @@ BEGIN
|
|||
|
||||
) sub
|
||||
ORDER BY mermas DESC;
|
||||
|
||||
END;
|
||||
|
||||
|
||||
END;$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
UPDATE salix.ACL
|
||||
SET principalId = "salesAssistant"
|
||||
WHERE model = 'Client' AND property = 'createReceipt';
|
|
@ -128,7 +128,7 @@
|
|||
</vn-data-viewer>
|
||||
</div>
|
||||
<vn-float-button
|
||||
vn-acl="administrative"
|
||||
vn-acl="salesAssistant"
|
||||
vn-acl-action="remove"
|
||||
icon="add"
|
||||
vn-tooltip="New payment"
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('loopback model Supplier-account', () => {
|
||||
describe('create', () => {
|
||||
const supplierId = 1;
|
||||
const bankEntityId = 2100;
|
||||
it('should throw an error when attempting to set an invalid iban account', async() => {
|
||||
let error;
|
||||
const expectedError = 'The IBAN does not have the correct format';
|
||||
const iban = 'incorrect format';
|
||||
try {
|
||||
await app.models.SupplierAccount.create(
|
||||
{
|
||||
supplierFk: supplierId,
|
||||
bankEntityFk: bankEntityId,
|
||||
iban: iban
|
||||
});
|
||||
} catch (e) {
|
||||
error = e;
|
||||
|
||||
expect(error.message).toContain(expectedError);
|
||||
}
|
||||
|
||||
expect(error).toBeDefined();
|
||||
});
|
||||
|
||||
it('should create a valid supplier account', async() => {
|
||||
const tx = await app.models.Claim.beginTransaction({});
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const iban = 'ES91 2100 0418 4502 0005 1332';
|
||||
|
||||
const activeCtx = {
|
||||
accessToken: {userId: 5},
|
||||
http: {
|
||||
req: {
|
||||
headers: {origin: 'http://localhost'}
|
||||
}
|
||||
}
|
||||
};
|
||||
activeCtx.http.req.__ = value => {
|
||||
return value;
|
||||
};
|
||||
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
active: activeCtx
|
||||
});
|
||||
const createdSupplierAccount = await app.models.SupplierAccount.create({
|
||||
supplierFk: supplierId,
|
||||
bankEntityFk: bankEntityId,
|
||||
iban: iban
|
||||
},
|
||||
options);
|
||||
|
||||
expect(createdSupplierAccount.iban).toBe(iban);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('loopback model address', () => {
|
||||
describe('loopback model Supplier', () => {
|
||||
let supplierOne;
|
||||
let supplierTwo;
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
const validateIban = require('vn-loopback/util/validateIban');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.validateAsync('iban', ibanValidation, {
|
||||
message: 'The IBAN does not have the correct format'
|
||||
});
|
||||
|
||||
async function ibanValidation(err, done) {
|
||||
let filter = {
|
||||
fields: ['code'],
|
||||
where: {id: this.countryFk}
|
||||
};
|
||||
let country = await Self.app.models.Country.findOne(filter);
|
||||
let code = country ? country.code.toLowerCase() : null;
|
||||
if (code != 'es')
|
||||
return done();
|
||||
|
||||
if (!validateIban(this.iban))
|
||||
err();
|
||||
done();
|
||||
}
|
||||
};
|
|
@ -7,7 +7,7 @@
|
|||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "supplierAccount"
|
||||
"table": "supplierAccount"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
|
@ -16,39 +16,18 @@
|
|||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"supplierFk": {
|
||||
"type": "Number"
|
||||
},
|
||||
"iban": {
|
||||
"type": "String"
|
||||
},
|
||||
"office": {
|
||||
"beneficiary": {
|
||||
"type": "String"
|
||||
},
|
||||
"DC": {
|
||||
"type": "String"
|
||||
},
|
||||
"number": {
|
||||
"type": "String"
|
||||
},
|
||||
"description": {
|
||||
"type": "String"
|
||||
},
|
||||
"bicSufix": {
|
||||
"type": "String"
|
||||
},
|
||||
"bankEntityFk": {
|
||||
"type": "Number"
|
||||
},
|
||||
"bankFk": {
|
||||
"type": "Number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"supplier": {
|
||||
"type": "belongsTo",
|
||||
"model": "Supplier",
|
||||
"foreignKey": "supplierFk"
|
||||
"foreignKey": "supplierFk"
|
||||
},
|
||||
"bankEntity": {
|
||||
"type": "belongsTo",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="SupplierAccounts"
|
||||
fields="['id', 'supplierFk', 'iban', 'bankEntityFk']"
|
||||
fields="['id', 'supplierFk', 'iban', 'bankEntityFk', 'beneficiary']"
|
||||
link="{supplierFk: $ctrl.$params.id}"
|
||||
include="$ctrl.include"
|
||||
data="$ctrl.supplierAccounts"
|
||||
|
@ -12,7 +12,7 @@
|
|||
data="$ctrl.supplierAccounts"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-lg">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal ng-repeat="supplierAccount in $ctrl.supplierAccounts">
|
||||
<vn-textfield vn-three
|
||||
|
@ -21,7 +21,7 @@
|
|||
ng-model="supplierAccount.iban"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete vn-two
|
||||
<vn-autocomplete vn-three
|
||||
label="Bank entity"
|
||||
ng-model="supplierAccount.bankEntityFk"
|
||||
url="BankEntities"
|
||||
|
@ -35,6 +35,11 @@
|
|||
ng-click="$ctrl.showBankEntity($event, $index)">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
<vn-textfield vn-three
|
||||
label="Beneficiary"
|
||||
ng-model="supplierAccount.beneficiary"
|
||||
info="Beneficiary information">
|
||||
</vn-textfield>
|
||||
<vn-none>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove account"
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Beneficiary information: Name of the bank account holder if different from the provider
|
|
@ -1,3 +1,5 @@
|
|||
Bank entity: Entidad bancaria
|
||||
swift: Swift BIC
|
||||
Add account: Añadir cuenta
|
||||
Beneficiary: Beneficiario
|
||||
Beneficiary information: Nombre del titular de la cuenta bancaria en caso de ser diferente del proveedor
|
|
@ -1,16 +1,13 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.observe('before save', async ctx => {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const models = Self.app.models;
|
||||
let changes = ctx.currentInstance || ctx.instance;
|
||||
if (changes) {
|
||||
let ticketId = changes.ticketFk;
|
||||
let isEditable = await models.Ticket.isEditable(httpCtx, ticketId);
|
||||
if (!isEditable)
|
||||
let isLocked = await models.Ticket.isLocked(ticketId);
|
||||
if (isLocked)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
|
||||
if (changes.ticketServiceTypeFk) {
|
||||
|
@ -21,13 +18,11 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.observe('before delete', async ctx => {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const models = Self.app.models;
|
||||
const service = await models.TicketService.findById(ctx.where.id);
|
||||
const isEditable = await models.Ticket.isEditable(httpCtx, service.ticketFk);
|
||||
const isLocked = await models.Ticket.isLocked(service.ticketFk);
|
||||
|
||||
if (!isEditable)
|
||||
if (isLocked)
|
||||
throw new UserError(`The current ticket can't be modified`);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
<vn-th field="name">Name</vn-th>
|
||||
<vn-th field="isBox">Package type</vn-th>
|
||||
<vn-th field="counter" number>Counter</vn-th>
|
||||
<vn-th field="externalId" number>externalId</vn-th>
|
||||
<vn-th field="worker">Worker</vn-th>
|
||||
<vn-th field="created" expand>Created</vn-th>
|
||||
</vn-tr>
|
||||
|
@ -41,6 +42,7 @@
|
|||
<vn-td>{{::expedition.packageItemName}}</vn-td>
|
||||
<vn-td>{{::expedition.freightItemName}}</vn-td>
|
||||
<vn-td number>{{::expedition.counter}}</vn-td>
|
||||
<vn-td number>{{::expedition.externalId}}</vn-td>
|
||||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
|
|
|
@ -17073,9 +17073,9 @@
|
|||
}
|
||||
},
|
||||
"ssri": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
|
||||
"integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
|
||||
"integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"figgy-pudding": "^3.5.1"
|
||||
|
|
Loading…
Reference in New Issue