Merge branch 'dev' into 5689-fixedPricesSize
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Satorres 2023-05-22 06:31:51 +00:00
commit e9222dbcb7
21 changed files with 103 additions and 76 deletions

View File

@ -5,11 +5,12 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2320.01] - 2023-05-25
## [2322.01] - 2023-06-08
### Added
-
### Changed
-
@ -18,6 +19,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2320.01] - 2023-05-25
### Added
- (Tickets -> Crear Factura) Al facturar se envia automáticamente el pdf al cliente
### Changed
- (Trabajadores -> Nuevo trabajador) Los clientes se crean sin 'TR' pero se añade tipo de negocio 'Trabajador'
### Fixed
-
## [2318.01] - 2023-05-08
### Added

View File

@ -0,0 +1,12 @@
-- vn.companyL10n source
CREATE OR REPLACE
ALGORITHM = UNDEFINED VIEW `vn`.`companyL10n` AS
select
`c`.`id` AS `id`,
ifnull(`ci`.`footnotes`, `c`.`footnotes`) AS `footnotes`
from
(`vn`.`company` `c`
left join `vn`.`companyI18n` `ci` on
(`ci`.`companyFk` = `c`.`id`
and `ci`.`lang` = `util`.`LANG`()));

View File

@ -1,14 +1,14 @@
INSERT INTO vn.businessType (code,description)
INSERT INTO `vn`.`businessType` (`code`, `description`)
VALUES ('worker','Trabajador');
ALTER TABLE `vn`.`workerConfig` ADD businessTypeFk varchar(100) NULL
ALTER TABLE `vn`.`workerConfig` ADD businessTypeFk varchar(100) NULL
COMMENT 'Tipo de negocio por defecto al dar de alta un trabajador nuevo';
UPDATE `vn`.`workerConfig`
SET businessTypeFk = 'worker'
WHERE id = 1;
UPDATE client c
JOIN worker w ON w.id = c.id
UPDATE `vn`.`client` c
JOIN `vn`.`worker` w ON w.id = c.id
SET c.name = REPLACE(c.name, 'TR ', ''),
c.businessTypeFk = 'worker';
c.businessTypeFk = 'worker';

View File

@ -50,6 +50,7 @@ describe('Item Edit basic data path', () => {
it(`should create a new intrastat and save it`, async() => {
await page.click($.newIntrastatButton);
await page.waitForSelector($.intrastatForm);
await page.fillForm($.intrastatForm, {
id: '588420239',
description: 'Tropical Flowers'

View File

@ -139,7 +139,7 @@ export default class CrudModel extends ModelProxy {
filter.limit = this.page * this.limit;
}
return this.sendRequest(filter, append, true);
return this.sendRequest(filter, append);
}
clear() {
@ -231,12 +231,12 @@ export default class CrudModel extends ModelProxy {
return params;
}
sendRequest(filter, append, loadMore) {
sendRequest(filter, append) {
this.cancelRequest();
this.canceler = this.$q.defer();
this.isPaging = append;
if (!loadMore)
if (!append && this.status != 'ready')
this.status = 'loading';
let params = Object.assign(

View File

@ -150,7 +150,7 @@ describe('Component vnCrudModel', () => {
controller.loadMore(true);
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true, true);
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
});
});

View File

@ -7,11 +7,10 @@ export default class DataViewer {
}
get status() {
if (this.model)
return this.model.status;
if (this.isLoading)
return 'loading';
if (this.model)
return this.model.status;
if (!this.data)
return 'clear';
if (this.data.length)

View File

@ -14,9 +14,12 @@
order="changedModel"
auto-load="true">
</vn-crud-model>
<vn-data-viewer model="model" class="vn-w-md vn-px-sm">
<vn-data-viewer
model="model"
is-loading="model.isLoading"
class="vn-w-md vn-px-sm">
<div class="change vn-mb-sm" ng-repeat="log in $ctrl.logs">
<div class="user-wrapper">
<div class="left">
<vn-avatar class="vn-mt-xs"
ng-class="::{system: !log.user}"
val="{{::log.user ? log.user.nickname : 'System'}}"
@ -33,7 +36,7 @@
<div class="header vn-mb-sm">
<div
class="date text-secondary text-caption"
title="{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}">
title="{{::log.creationDate | date:'dd/MM/yyyy HH:mm:ss'}}">
{{::$ctrl.relativeDate(log.creationDate)}}
</div>
<span class="chip" ng-class="::$ctrl.actionsClass[log.action]" translate>

View File

@ -4,7 +4,7 @@ vn-log {
.change {
display: flex;
& > .user-wrapper {
& > .left {
position: relative;
padding-right: 10px;
@ -34,7 +34,7 @@ vn-log {
bottom: -8px;
}
}
&:last-child > .user-wrapper > .line {
&:last-child > .left > .line {
display: none;
}
.detail {

View File

@ -172,4 +172,4 @@
"Comment added to client": "Comment added to client",
"This ticket is already a refund": "This ticket is already a refund",
"A claim with that sale already exists": "A claim with that sale already exists"
}
}

View File

@ -1,3 +1,4 @@
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {
Self.remoteMethodCtx('editableStates', {
description: 'Gets the editable states according the user role ',
@ -19,25 +20,16 @@ module.exports = Self => {
Self.editableStates = async(ctx, filter, options) => {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
const myOptions = {};
const myOptions = {...(options || {})};
if (typeof options == 'object')
Object.assign(myOptions, options);
let statesList = await models.State.find(filter, myOptions);
const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions);
const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions);
const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions);
if (isProduction || isAdministrative)
return statesList;
if (!isProduction && !isAdministrative)
filter = mergeFilters(filter, {where: {alertLevel: 0}});
if (isSalesPerson) {
return statesList = statesList.filter(stateList =>
stateList.alertLevel === 0 || stateList.code === 'PICKER_DESIGNED'
);
}
const states = await models.State.find(filter, myOptions);
return statesList.filter(stateList => stateList.alertLevel === 0);
return states;
};
};

View File

@ -24,31 +24,6 @@ describe('ticket editableStates()', () => {
}
});
it(`should return the expected states by a specific role`, async() => {
const tx = await models.State.beginTransaction({});
try {
const options = {transaction: tx};
const productionRole = 18;
const ctx = {req: {accessToken: {userId: productionRole}}};
const editableStates = await models.State.editableStates(ctx, filter, options);
const deliveredState = editableStates.some(state => state.code == 'DELIVERED');
const pickerDesignedState = editableStates.some(state => state.code == 'PICKER_DESIGNED');
expect(deliveredState).toBeFalsy();
expect(pickerDesignedState).toBeTruthy();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it(`should return again the expected state by a specific role`, async() => {
const tx = await models.State.beginTransaction({});
@ -70,4 +45,25 @@ describe('ticket editableStates()', () => {
throw e;
}
});
it(`should return the expected state matching with the name`, async() => {
const tx = await models.State.beginTransaction({});
try {
const options = {transaction: tx};
const employeeRole = 1;
const ctx = {req: {accessToken: {userId: employeeRole}}};
const filter = {where: {name: {like: '%Previa OK%'}}};
const [editableStates] = await models.State.editableStates(ctx, filter, options);
expect(editableStates.name).toBe('Previa OK');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -124,6 +124,7 @@ module.exports = Self => {
const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions);
if (!isDeliveryBoss) {
const zoneShipped = await models.Agency.getShipped(
ctx,
args.landed,
args.addressFk,
args.agencyModeFk,

View File

@ -100,7 +100,7 @@ module.exports = Self => {
}
if (!args.shipped && args.landed) {
const shippedResult = await models.Agency.getShipped(args.landed,
const shippedResult = await models.Agency.getShipped(ctx, args.landed,
address.id, args.agencyModeId, args.warehouseId, myOptions);
args.shipped = (shippedResult && shippedResult.shipped) || args.landed;
}

View File

@ -81,6 +81,7 @@ module.exports = Self => {
const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions);
if (!isDeliveryBoss) {
const zoneShipped = await models.Agency.getShipped(
ctx,
args.landed,
args.addressId,
args.agencyModeId,

View File

@ -1,7 +1,7 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethod('getShipped', {
Self.remoteMethodCtx('getShipped', {
description: 'Returns the first shipped possible for params',
accessType: 'READ',
accepts: [{
@ -34,18 +34,22 @@ module.exports = Self => {
}
});
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk, options) => {
Self.getShipped = async(ctx, landed, addressFk, agencyModeFk, warehouseFk, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
const stmts = [];
const userId = ctx.req.accessToken.userId;
const models = Self.app.models;
const isProductionAssistant = await models.VnUser.hasRole(userId, 'productionAssi', myOptions);
stmts.push(new ParameterizedSQL(
`CALL vn.zone_getShipped(?, ?, ?, TRUE)`, [
`CALL vn.zone_getShipped(?, ?, ?, ?)`, [
landed,
addressFk,
agencyModeFk
agencyModeFk,
isProductionAssistant
]
));

View File

@ -1,6 +1,9 @@
const {models} = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('agency getShipped()', () => {
const employeeId = 1;
const ctx = {req: {accessToken: {userId: employeeId}}};
it('should return a shipment date', async() => {
const landed = Date.vnNew();
landed.setDate(landed.getDate() + 1);
@ -12,8 +15,7 @@ describe('agency getShipped()', () => {
try {
const options = {transaction: tx};
const result = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
const result = await models.Agency.getShipped(ctx, landed, addressFk, agencyModeFk, warehouseFk, options);
expect(result).toBeDefined();
@ -37,7 +39,7 @@ describe('agency getShipped()', () => {
try {
const options = {transaction: tx};
const result = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
const result = await models.Agency.getShipped(ctx, landed, addressFk, agencyModeFk, warehouseFk, options);
expect(result).toBeUndefined();

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "salix-back",
"version": "23.18.01",
"version": "23.22.01",
"lockfileVersion": 1,
"requires": true,
"packages": {

View File

@ -1,6 +1,6 @@
{
"name": "salix-back",
"version": "23.20.01",
"version": "23.22.01",
"author": "Verdnatura Levante SL",
"description": "Salix backend",
"license": "GPL-3.0",

View File

@ -4,13 +4,14 @@ const db = require('../../database');
module.exports = {
name: 'report-footer',
async serverPrefetch() {
this.company = await db.findOne(
`SELECT
ci.footnotes
FROM companyI18n ci
JOIN company c ON c.id = ci.companyFk
WHERE c.code = ? AND ci.lang = (SELECT lang FROM account.user WHERE id = ?)`,
[this.companyCode, this.recipientId]);
this.company = await db.findOne(`
SELECT IFNULL(ci.footnotes, cl.footnotes) as footnotes
FROM company c
LEFT JOIN companyL10n cl ON c.id = cl.id
LEFT JOIN companyI18n ci ON ci.companyFk = cl.id
AND ci.lang = (SELECT lang FROM account.user where id = ?)
WHERE c.code = ?`,
[this.recipientId, this.companyCode]);
},
props: ['leftText', 'companyCode', 'recipientId', 'centerText']