refs #5762 feat: multiplatform recover-password and change-password #1673

Merged
alexm merged 6 commits from 5762-recoverPassword-multiplatform into dev 2023-08-09 13:14:55 +00:00
15 changed files with 142 additions and 34 deletions
Showing only changes of commit 209cac2a6a - Show all commits

View File

@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2334.01] - 2023-08-24 ## [2334.01] - 2023-08-24
### Added ### Added

View File

@ -0,0 +1,87 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`client_create`(
vFirstname VARCHAR(50),
vSurnames VARCHAR(50),
vFi VARCHAR(9),
vAddress TEXT,
vPostcode CHAR(5),
vCity VARCHAR(25),
vProvinceFk SMALLINT(5),
vCompanyFk SMALLINT(5),
vPhone VARCHAR(11),
vEmail VARCHAR(255),
vUserFk INT
)
BEGIN
/**
* Create new client
*
* @params vFirstname firstName
* @params vSurnames surnames
* @params vFi company code from accounting transactions
* @params vAddress address
* @params vPostcode postCode
* @params vCity city
* @params vProvinceFk province
* @params vCompanyFk company in which he has become a client
* @params vPhone telephone number
* @params vEmail email address
* @params vUserFk user id
*/
DECLARE vPayMethodFk INT;
DECLARE vDueDay INT;
DECLARE vDefaultCredit DECIMAL(10, 2);
DECLARE vIsTaxDataChecked TINYINT(1);
DECLARE vHasCoreVnl BOOLEAN;
DECLARE vMandateTypeFk INT;
SELECT defaultPayMethodFk,
defaultDueDay,
defaultCredit,
defaultIsTaxDataChecked,
defaultHasCoreVnl,
defaultMandateTypeFk
INTO vPayMethodFk,
vDueDay,
vDefaultCredit,
vIsTaxDataChecked,
vHasCoreVnl,
vMandateTypeFk
FROM clientConfig;
INSERT INTO `client`
SET id = vUserFk,
name = CONCAT(vFirstname, ' ', vSurnames),
street = vAddress,
fi = TRIM(vFi),
phone = vPhone,
email = vEmail,
provinceFk = vProvinceFk,
city = vCity,
postcode = vPostcode,
socialName = UPPER(CONCAT(vSurnames, ' ', vFirstname)),
payMethodFk = vPayMethodFk,
dueDay = vDueDay,
credit = vDefaultCredit,
isTaxDataChecked = vIsTaxDataChecked,
hasCoreVnl = vHasCoreVnl,
isEqualizated = FALSE
ON duplicate KEY UPDATE
payMethodFk = vPayMethodFk,
dueDay = vDueDay,
credit = vDefaultCredit,
isTaxDataChecked = vIsTaxDataChecked,
hasCoreVnl = vHasCoreVnl,
isActive = TRUE;
INSERT INTO mandate (clientFk, companyFk, mandateTypeFk)
SELECT vUserFk, vCompanyFk, vMandateTypeFk
WHERE NOT EXISTS (
SELECT id
FROM mandate
WHERE clientFk = vUserFk
AND companyFk = vCompanyFk
AND mandateTypeFk = vMandateTypeFk
);
END$$
DELIMITER ;

View File

@ -0,0 +1,6 @@
UPDATE `salix`.`ACL`
SET principalId='salesPerson'
WHERE
model='Ticket'
AND property='setDeleted'
AND accessType='WRITE';

View File

@ -10,7 +10,7 @@ describe('Ticket create path', () => {
beforeAll(async() => { beforeAll(async() => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('employee', 'ticket'); await page.loginAndModule('salesPerson', 'ticket');
}); });
afterAll(async() => { afterAll(async() => {

View File

@ -179,6 +179,7 @@
"You can not use the same password": "You can not use the same password", "You can not use the same password": "You can not use the same password",
"Valid priorities": "Valid priorities: %d", "Valid priorities": "Valid priorities: %d",
"Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}", "Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}",
"This ticket cannot be left empty.": "This ticket cannot be left empty. %s",
"Social name should be uppercase": "Social name should be uppercase", "Social name should be uppercase": "Social name should be uppercase",
"Street should be uppercase": "Street should be uppercase", "Street should be uppercase": "Street should be uppercase",
"You don't have enough privileges.": "You don't have enough privileges.", "You don't have enough privileges.": "You don't have enough privileges.",

View File

@ -306,6 +306,7 @@
"Valid priorities": "Prioridades válidas: %d", "Valid priorities": "Prioridades válidas: %d",
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}", "Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado", "You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias", "The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado", "You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado", "This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",

View File

@ -1,40 +1,40 @@
<vn-horizontal> <vn-horizontal>
<vn-auto> <vn-auto>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value5}" ng-class="::{empty: !$ctrl.item.tag5}"
title="{{::$ctrl.item.tag5}}: {{::$ctrl.item.value5}}"> title="{{::$ctrl.item.tag5}}: {{::$ctrl.item.value5}}">
{{::$ctrl.item.value5}} {{::$ctrl.item.value5}}
</section> </section>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value6}" ng-class="::{empty: !$ctrl.item.tag6}"
title="{{::$ctrl.item.tag6}}: {{::$ctrl.item.value6}}"> title="{{::$ctrl.item.tag6}}: {{::$ctrl.item.value6}}">
{{::$ctrl.item.value6}} {{::$ctrl.item.value6}}
</section> </section>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value7}" ng-class="::{empty: !$ctrl.item.tag7}"
title="{{::$ctrl.item.tag7}}: {{::$ctrl.item.value7}}"> title="{{::$ctrl.item.tag7}}: {{::$ctrl.item.value7}}">
{{::$ctrl.item.value7}} {{::$ctrl.item.value7}}
</section> </section>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value8}" ng-class="::{empty: !$ctrl.item.tag8}"
title="{{::$ctrl.item.tag8}}: {{::$ctrl.item.value8}}"> title="{{::$ctrl.item.tag8}}: {{::$ctrl.item.value8}}">
{{::$ctrl.item.value8}} {{::$ctrl.item.value8}}
</section> </section>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value9}" ng-class="::{empty: !$ctrl.item.tag9}"
title="{{::$ctrl.item.tag9}}: {{::$ctrl.item.value9}}"> title="{{::$ctrl.item.tag9}}: {{::$ctrl.item.value9}}">
{{::$ctrl.item.value9}} {{::$ctrl.item.value9}}
</section> </section>
<section <section
class="inline-tag ellipsize" class="inline-tag ellipsize"
ng-class="::{empty: !$ctrl.item.value10}" ng-class="::{empty: !$ctrl.item.tag10}"
title="{{::$ctrl.item.tag10}}: {{::$ctrl.item.value10}}"> title="{{::$ctrl.item.tag10}}: {{::$ctrl.item.value10}}">
{{::$ctrl.item.value10}} {{::$ctrl.item.value10}}
</section> </section>
</vn-auto> </vn-auto>
</vn-horizontal> </vn-horizontal>

View File

@ -28,7 +28,7 @@
vn-fetched-tags { vn-fetched-tags {
& > vn-horizontal { & > vn-horizontal {
align-items: center; align-items: center;
max-width: 210px;
& > vn-auto { & > vn-auto {
flex-wrap: wrap; flex-wrap: wrap;
@ -43,19 +43,19 @@ vn-fetched-tags {
& > .inline-tag { & > .inline-tag {
color: $color-font-secondary; color: $color-font-secondary;
text-align: center; text-align: center;
font-size: .75rem; font-size: .8rem;
height: 12px; height: 13px;
padding: 1px; padding: 1px;
width: 64px; width: 64px;
min-width: 64px; min-width: 64px;
max-width: 64px; max-width: 64px;
flex: 1; flex: 1;
border: 1px solid $color-spacer; border: 1px solid $color-font-secondary;
&.empty { &.empty {
border: 1px solid $color-spacer-light; border: 1px solid darken($color-font-secondary, 30%);
} }
} }
} }
} }
} }

View File

@ -46,8 +46,6 @@ class Controller extends Section {
} }
deleteRoadmaps() { deleteRoadmaps() {
console.log(this.checked);
for (const roadmap of this.checked) { for (const roadmap of this.checked) {
this.$http.delete(`Roadmaps/${roadmap.id}`) this.$http.delete(`Roadmaps/${roadmap.id}`)
.then(() => this.$.model.refresh()) .then(() => this.$.model.refresh())

View File

@ -1,4 +1,5 @@
const loggable = require('vn-loopback/util/log'); const loggable = require('vn-loopback/util/log');
const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('componentUpdate', { Self.remoteMethodCtx('componentUpdate', {
@ -112,7 +113,6 @@ module.exports = Self => {
} }
try { try {
const userId = ctx.req.accessToken.userId;
const models = Self.app.models; const models = Self.app.models;
const $t = ctx.req.__; // $translate const $t = ctx.req.__; // $translate
await models.Ticket.isEditableOrThrow(ctx, args.id, myOptions); await models.Ticket.isEditableOrThrow(ctx, args.id, myOptions);
@ -127,11 +127,8 @@ module.exports = Self => {
args.warehouseFk, args.warehouseFk,
myOptions); myOptions);
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) { if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk)
const error = `You don't have privileges to change the zone`; throw new UserError(`You don't have privileges to change the zone`);
throw new UserError(error);
}
} }
if (args.isWithoutNegatives) { if (args.isWithoutNegatives) {

View File

@ -248,6 +248,7 @@ module.exports = Self => {
am.name AS agencyMode, am.name AS agencyMode,
am.id AS agencyModeFk, am.id AS agencyModeFk,
st.name AS state, st.name AS state,
st.classColor,
wk.lastName AS salesPerson, wk.lastName AS salesPerson,
ts.stateFk AS stateFk, ts.stateFk AS stateFk,
ts.alertLevel AS alertLevel, ts.alertLevel AS alertLevel,

View File

@ -5,6 +5,8 @@ describe('sale transferSales()', () => {
const userId = 1101; const userId = 1101;
const activeCtx = { const activeCtx = {
accessToken: {userId: userId}, accessToken: {userId: userId},
headers: {origin: ''},
__: value => value
}; };
const ctx = {req: activeCtx}; const ctx = {req: activeCtx};

View File

@ -37,6 +37,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId; const userId = ctx.req.accessToken.userId;
const models = Self.app.models; const models = Self.app.models;
const myOptions = {userId}; const myOptions = {userId};
const $t = ctx.req.__; // $translate
let tx; let tx;
if (typeof options == 'object') if (typeof options == 'object')
@ -95,9 +96,18 @@ module.exports = Self => {
const isTicketEmpty = await models.Ticket.isEmpty(id, myOptions); const isTicketEmpty = await models.Ticket.isEmpty(id, myOptions);
if (isTicketEmpty) { if (isTicketEmpty) {
await originalTicket.updateAttributes({ try {
isDeleted: true await models.Ticket.setDeleted(ctx, id, myOptions);
}, myOptions); } catch (e) {
if (e.statusCode === 400) {
throw new UserError(
`This ticket cannot be left empty.`,
'TRANSFER_SET_DELETED',
$t(e.message, ...e.translateArgs)
);
}
throw e;
}
} }
if (tx) await tx.commit(); if (tx) await tx.commit();

View File

@ -27,6 +27,9 @@
"code": { "code": {
"type": "string", "type": "string",
"required": false "required": false
},
"classColor": {
"type": "string"
} }
} }
} }

View File

@ -71,8 +71,9 @@ module.exports = Self => {
'Stored on': 'created', 'Stored on': 'created',
'Document ID': 'id' 'Document ID': 'id'
}; };
workerDocuware = workerDocuware =
await models.Docuware.getById('hr', worker.lastName + worker.firstName, docuwareParse) ?? []; await models.Docuware.getById('hr', worker.lastName + ' ' + worker.firstName, docuwareParse) ?? [];
for (document of workerDocuware) { for (document of workerDocuware) {
const defaultData = { const defaultData = {
file: 'dw' + document.id + '.png', file: 'dw' + document.id + '.png',