Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 4564-report_eror-handler
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
ab7989911a
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -5,20 +5,31 @@ 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).
|
||||
|
||||
## [2302.01] - 2023-01-12
|
||||
## [2304.01] - 2023-02-09
|
||||
|
||||
### Added
|
||||
- [General](Inicio) Permite recuperar la contraseña
|
||||
- [Ticket](Opciones) Subir albarán a Docuware
|
||||
- [Ticket](Opciones) Enviar correo con PDF de Docuware
|
||||
- [Artículo](Datos Básicos) Añadido campo Unidades/Caja
|
||||
-
|
||||
|
||||
### Changed
|
||||
- [Reclamaciones](Descriptor) Cambiado el campo Agencia por Zona
|
||||
- [Tickets](Líneas preparadas) Actualizada sección para que sea más visual
|
||||
-
|
||||
|
||||
### Fixed
|
||||
- [General] Al utilizar el traductor de Google se descuadraban los iconos
|
||||
-
|
||||
|
||||
## [2302.01] - 2023-01-26
|
||||
|
||||
### Added
|
||||
- (General -> Inicio) Permite recuperar la contraseña
|
||||
- (Tickets -> Opciones) Subir albarán a Docuware
|
||||
- (Tickets -> Opciones) Enviar correo con PDF de Docuware
|
||||
- (Artículos -> Datos Básicos) Añadido campo Unidades/Caja
|
||||
|
||||
### Changed
|
||||
- (Reclamaciones -> Descriptor) Cambiado el campo Agencia por Zona
|
||||
- (Tickets -> Líneas preparadas) Actualizada sección para que sea más visual
|
||||
|
||||
### Fixed
|
||||
- (General) Al utilizar el traductor de Google se descuadraban los iconos
|
||||
|
||||
### Removed
|
||||
- [Tickets](Control clientes) Eliminada sección
|
||||
- (Tickets -> Control clientes) Eliminada sección
|
||||
|
|
|
@ -36,19 +36,26 @@ module.exports = Self => {
|
|||
JOIN osticket.ost_ticket_status ots ON ots.id = ot.status_id
|
||||
JOIN osticket.ost_thread ot2 ON ot2.object_id = ot.ticket_id AND ot2.object_type = 'T'
|
||||
JOIN (
|
||||
SELECT ote.thread_id, MAX(ote.created) created, MAX(ote.updated) updated
|
||||
FROM osticket.ost_thread_entry ote
|
||||
WHERE ote.staff_id AND ote.type = 'R'
|
||||
GROUP BY ote.thread_id
|
||||
SELECT sub2.thread_id, sub2.type, sub2.updated, sub2.created
|
||||
FROM (
|
||||
SELECT ote.thread_id, ote.created, ote.updated, ote.type
|
||||
FROM osticket.ost_thread_entry ote
|
||||
WHERE ote.staff_id
|
||||
ORDER BY ote.id DESC
|
||||
LIMIT 10000000000000000000) sub2
|
||||
GROUP BY sub2.thread_id
|
||||
) sub ON sub.thread_id = ot2.id
|
||||
WHERE ot.isanswered
|
||||
AND ots.state = ?
|
||||
AND IF(sub.updated > sub.created, sub.updated, sub.created) < DATE_SUB(CURDATE(), INTERVAL ? DAY)`;
|
||||
AND ots.id IN (?)
|
||||
AND sub.type = 'R'
|
||||
AND IF(sub.updated > sub.created, sub.updated, sub.created) < DATE_SUB(CURDATE(), INTERVAL ? DAY);`;
|
||||
|
||||
const ticketsId = [];
|
||||
const statusIdToClose = config.oldStatus.split(',');
|
||||
|
||||
con.connect(err => {
|
||||
if (err) throw err;
|
||||
con.query(sql, [config.oldStatus, config.day],
|
||||
con.query(sql, [statusIdToClose, config.day],
|
||||
(err, results) => {
|
||||
if (err) throw err;
|
||||
for (const result of results)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
UPDATE `vn`.`osTicketConfig`
|
||||
SET oldStatus='1,6'
|
||||
WHERE id=0;
|
||||
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE `vn`.`itemConfig` ADD defaultTag INT DEFAULT 56 NOT NULL;
|
||||
ALTER TABLE `vn`.`itemConfig` ADD CONSTRAINT itemConfig_FK FOREIGN KEY (defaultTag) REFERENCES vn.tag(id);
|
||||
ALTER TABLE `vn`.`itemConfig` ADD validPriorities varchar(50) DEFAULT '[1,2,3]' NOT NULL;
|
||||
ALTER TABLE `vn`.`itemConfig` ADD defaultPriority INT DEFAULT 2 NOT NULL;
|
||||
ALTER TABLE `vn`.`item` MODIFY COLUMN relevancy tinyint(1) DEFAULT 0 NOT NULL COMMENT 'La web ordena de forma descendiente por este campo para mostrar los artículos';
|
||||
|
||||
INSERT INTO `salix`.`ACL`
|
||||
(model, property, accessType, permission, principalType, principalId)
|
||||
VALUES('ItemConfig', '*', 'READ', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE `vn`.`workerTimeControlConfig` ADD teleworkingStart INT NULL COMMENT 'Hora comienzo jornada de los teletrabajdores expresada en segundos';
|
||||
ALTER TABLE `vn`.`workerTimeControlConfig` ADD teleworkingStartBreakTime INT NULL COMMENT 'Hora comienzo descanso de los teletrabjadores expresada en segundos';
|
||||
|
||||
UPDATE `vn`.`workerTimeControlConfig`
|
||||
SET `teleworkingStart`=28800, `teleworkingStartBreakTime`=32400
|
||||
WHERE `id`=1;
|
|
@ -2667,9 +2667,9 @@ INSERT INTO `vn`.`sectorCollectionSaleGroup` (`sectorCollectionFk`, `saleGroupFk
|
|||
VALUES
|
||||
(1, 1);
|
||||
|
||||
INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`)
|
||||
INSERT INTO `vn`.`workerTimeControlConfig` (`id`, `dayBreak`, `dayBreakDriver`, `shortWeekBreak`, `longWeekBreak`, `weekScope`, `mailPass`, `mailHost`, `mailSuccessFolder`, `mailErrorFolder`, `mailUser`, `minHoursToBreak`, `breakHours`, `hoursCompleteWeek`, `startNightlyHours`, `endNightlyHours`, `maxTimePerDay`, `breakTime`, `timeToBreakTime`, `dayMaxTime`, `shortWeekDays`, `longWeekDays`, `teleworkingStart`, `teleworkingStartBreakTime`)
|
||||
VALUES
|
||||
(1, 43200, 32400, 129600, 259200, 604800, '', '', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.33, 0.33, 40, '22:00:00', '06:00:00', 57600, 1200, 18000, 57600, 6, 13);
|
||||
(1, 43200, 32400, 129600, 259200, 604800, '', '', 'Leidos.exito', 'Leidos.error', 'timeControl', 5.33, 0.33, 40, '22:00:00', '06:00:00', 57600, 1200, 18000, 57600, 6, 13, 28800, 32400);
|
||||
|
||||
INSERT INTO `vn`.`host` (`id`, `code`, `description`, `warehouseFk`, `bankFk`)
|
||||
VALUES
|
||||
|
@ -2719,6 +2719,10 @@ INSERT INTO `vn`.`collection` (`id`, `created`, `workerFk`, `stateFk`, `itemPack
|
|||
VALUES
|
||||
(3, util.VN_NOW(), 1107, 5, NULL, 0, 0, 1, NULL, NULL);
|
||||
|
||||
INSERT INTO `vn`.`itemConfig` (`id`, `isItemTagTriggerDisabled`, `monthToDeactivate`, `wasteRecipients`, `validPriorities`, `defaultPriority`, `defaultTag`)
|
||||
VALUES
|
||||
(0, 0, 24, '', '[1,2,3]', 2, 56);
|
||||
|
||||
INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `created`, `level`, `wagon`, `smartTagFk`, `usedShelves`, `itemCount`, `liters`)
|
||||
VALUES
|
||||
(9, 3, util.VN_NOW(), NULL, 0, NULL, NULL, NULL, NULL);
|
||||
|
@ -2741,7 +2745,7 @@ INSERT INTO `vn`.`ticketLog` (`originFk`, userFk, `action`, changedModel, oldIns
|
|||
|
||||
INSERT INTO `vn`.`osTicketConfig` (`id`, `host`, `user`, `password`, `oldStatus`, `newStatusId`, `day`, `comment`, `hostDb`, `userDb`, `passwordDb`, `portDb`, `responseType`, `fromEmailId`, `replyTo`)
|
||||
VALUES
|
||||
(0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', 'open', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all');
|
||||
(0, 'http://localhost:56596/scp', 'ostadmin', 'Admin1', '1,6', 3, 60, 'Este CAU se ha cerrado automáticamente. Si el problema persiste responda a este mensaje.', 'localhost', 'osticket', 'osticket', 40003, 'reply', 1, 'all');
|
||||
|
||||
INSERT INTO `vn`.`mdbApp` (`app`, `baselineBranchFk`, `userFk`, `locked`)
|
||||
VALUES
|
||||
|
|
|
@ -428,6 +428,7 @@ export default {
|
|||
},
|
||||
itemCreateView: {
|
||||
temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
|
||||
priority: 'vn-autocomplete[ng-model="$ctrl.item.priority"]',
|
||||
type: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]',
|
||||
intrastat: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]',
|
||||
origin: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]',
|
||||
|
@ -521,7 +522,7 @@ export default {
|
|||
},
|
||||
itemLog: {
|
||||
anyLineCreated: 'vn-item-log > vn-log vn-tbody > vn-tr',
|
||||
fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) table tr:nth-child(3) td.after',
|
||||
fifthLineCreatedProperty: 'vn-item-log > vn-log vn-tbody > vn-tr:nth-child(5) table tr:nth-child(2) td.after',
|
||||
},
|
||||
ticketSummary: {
|
||||
header: 'vn-ticket-summary > vn-card > h5',
|
||||
|
|
|
@ -36,11 +36,20 @@ describe('Item Create', () => {
|
|||
await page.waitForState('item.create');
|
||||
});
|
||||
|
||||
it('should create the Infinity Gauntlet item', async() => {
|
||||
it('should throw an error when insert an invalid priority', async() => {
|
||||
await page.write(selectors.itemCreateView.temporalName, 'Infinity Gauntlet');
|
||||
await page.autocompleteSearch(selectors.itemCreateView.type, 'Crisantemo');
|
||||
await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares');
|
||||
await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand');
|
||||
await page.clearInput(selectors.itemCreateView.priority);
|
||||
await page.waitToClick(selectors.itemCreateView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('Valid priorities');
|
||||
});
|
||||
|
||||
it('should create the Infinity Gauntlet item', async() => {
|
||||
await page.autocompleteSearch(selectors.itemCreateView.priority, '2');
|
||||
await page.waitToClick(selectors.itemCreateView.createButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
|
|
|
@ -36,13 +36,13 @@
|
|||
ng-if="$ctrl.isAgricultural()"
|
||||
ng-click="$ctrl.showPdfInvoice()"
|
||||
translate>
|
||||
Show agricultural invoice as PDF
|
||||
Show agricultural receipt as PDF
|
||||
</vn-item>
|
||||
<vn-item
|
||||
ng-if="$ctrl.isAgricultural()"
|
||||
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
|
||||
translate>
|
||||
Send agricultural invoice as PDF
|
||||
Send agricultural receipt as PDF
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
<slot-body>
|
||||
|
|
|
@ -19,6 +19,6 @@ To book: Contabilizar
|
|||
Total amount: Total importe
|
||||
Total net: Total neto
|
||||
Total stems: Total tallos
|
||||
Show agricultural invoice as PDF: Ver factura agrícola como PDF
|
||||
Send agricultural invoice as PDF: Enviar factura agrícola como PDF
|
||||
New InvoiceIn: Nueva Factura
|
||||
Show agricultural receipt as PDF: Ver recibo agrícola como PDF
|
||||
Send agricultural receipt as PDF: Enviar recibo agrícola como PDF
|
||||
New InvoiceIn: Nueva Factura
|
||||
|
|
|
@ -37,7 +37,8 @@ module.exports = Self => {
|
|||
'typeFk',
|
||||
'intrastatFk',
|
||||
'originFk',
|
||||
'relevancy'
|
||||
'priority',
|
||||
'tag'
|
||||
];
|
||||
|
||||
for (const key in params) {
|
||||
|
@ -46,10 +47,14 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
const itemConfig = await models.ItemConfig.findOne({fields: ['validPriorities']}, myOptions);
|
||||
if (!itemConfig.validPriorities.includes(params.priority))
|
||||
throw new UserError(`Valid priorities: ${[...itemConfig.validPriorities]}`);
|
||||
|
||||
const provisionalName = params.provisionalName;
|
||||
delete params.provisionalName;
|
||||
|
||||
const itemType = await models.ItemType.findById(params.typeFk, myOptions);
|
||||
const itemType = await models.ItemType.findById(params.typeFk, {fields: ['isLaid']}, myOptions);
|
||||
|
||||
params.isLaid = itemType.isLaid;
|
||||
|
||||
|
@ -63,13 +68,14 @@ module.exports = Self => {
|
|||
|
||||
await Self.rawSql(query, null, myOptions);
|
||||
|
||||
let nameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}});
|
||||
const nameTag = await models.Tag.findById(params.tag, {fields: ['id']}, myOptions);
|
||||
|
||||
let newTags = [];
|
||||
|
||||
newTags.push({itemFk: item.id, tagFk: nameTag.id, value: provisionalName, priority: '2'});
|
||||
newTags.push({itemFk: item.id, tagFk: nameTag.id, value: provisionalName, priority: item.priority});
|
||||
typeTags.forEach(typeTag => {
|
||||
newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority});
|
||||
if (nameTag.id != typeTag.tagFk)
|
||||
newTags.push({itemFk: item.id, tagFk: typeTag.tagFk, value: '', priority: typeTag.priority});
|
||||
});
|
||||
|
||||
await models.ItemTag.create(newTags, myOptions);
|
||||
|
|
|
@ -11,7 +11,8 @@ describe('item new()', () => {
|
|||
originFk: 1,
|
||||
provisionalName: 'planta',
|
||||
typeFk: 2,
|
||||
relevancy: 0
|
||||
priority: 2,
|
||||
tag: 1
|
||||
};
|
||||
|
||||
let item = await models.Item.new(itemParams, options);
|
||||
|
@ -20,7 +21,7 @@ describe('item new()', () => {
|
|||
|
||||
item.isLaid = itemType.isLaid;
|
||||
|
||||
const temporalNameTag = await models.Tag.findOne({where: {name: 'Nombre temporal'}}, options);
|
||||
const temporalNameTag = await models.Tag.findById(itemParams.tag, {fields: ['id']}, options);
|
||||
|
||||
const temporalName = await models.ItemTag.findOne({
|
||||
where: {
|
||||
|
@ -31,7 +32,7 @@ describe('item new()', () => {
|
|||
|
||||
item = await models.Item.findById(item.id, null, options);
|
||||
|
||||
itemType = await models.ItemType.findById(item.typeFk, options);
|
||||
itemType = await models.ItemType.findById(item.typeFk, {fields: ['isLaid']}, options);
|
||||
|
||||
item.isLaid = itemType.isLaid;
|
||||
|
||||
|
|
|
@ -16,6 +16,22 @@
|
|||
"wasteRecipients": {
|
||||
"type": "string",
|
||||
"description": "Buyers waste report recipients"
|
||||
},
|
||||
"validPriorities": {
|
||||
"type": "array"
|
||||
},
|
||||
"defaultPriority": {
|
||||
"type": "int"
|
||||
},
|
||||
"defaultTag": {
|
||||
"type": "int"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"tag": {
|
||||
"type": "belongsTo",
|
||||
"model": "Tag",
|
||||
"foreignKey": "defaultTag"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,24 @@
|
|||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="Temporal name"
|
||||
ng-model="$ctrl.item.provisionalName"
|
||||
label="Name"
|
||||
ng-model="$ctrl.item.provisionalName"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
ng-model="$ctrl.item.tag"
|
||||
url="Tags"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
label="Tag">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
data="$ctrl.validPriorities"
|
||||
label="Priority"
|
||||
ng-model="$ctrl.item.priority"
|
||||
show-field="priority"
|
||||
value-field="priority">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
|
|
|
@ -4,9 +4,25 @@ import Section from 'salix/components/section';
|
|||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.item = {
|
||||
relevancy: 0
|
||||
};
|
||||
this.fetchDefaultPriorityTag();
|
||||
}
|
||||
|
||||
fetchDefaultPriorityTag() {
|
||||
this.validPriorities = [];
|
||||
const filter = {fields: ['defaultPriority', 'defaultTag', 'validPriorities'], limit: 1};
|
||||
this.$http.get(`ItemConfigs`, {filter})
|
||||
.then(res => {
|
||||
if (res.data) {
|
||||
const dataRow = res.data[0];
|
||||
dataRow.validPriorities.forEach(priority => {
|
||||
this.validPriorities.push({priority});
|
||||
});
|
||||
this.item = {
|
||||
priority: dataRow.defaultPriority,
|
||||
tag: dataRow.defaultTag
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
|
|
|
@ -32,94 +32,87 @@ module.exports = Self => {
|
|||
const models = Self.app.models;
|
||||
const conn = Self.dataSource.connector;
|
||||
const args = ctx.args;
|
||||
const $t = ctx.req.__; // $translate
|
||||
let tx;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
const stmts = [];
|
||||
let stmt;
|
||||
|
||||
try {
|
||||
if (!args.week || !args.year) {
|
||||
const from = new Date();
|
||||
const to = new Date();
|
||||
if (!args.week || !args.year) {
|
||||
const from = new Date();
|
||||
const to = new Date();
|
||||
|
||||
const time = await models.Time.findOne({
|
||||
where: {
|
||||
dated: {between: [from.setDate(from.getDate() - 10), to.setDate(to.getDate() - 4)]}
|
||||
},
|
||||
order: 'week ASC'
|
||||
}, myOptions);
|
||||
const time = await models.Time.findOne({
|
||||
where: {
|
||||
dated: {between: [from.setDate(from.getDate() - 10), to.setDate(to.getDate() - 4)]}
|
||||
},
|
||||
order: 'week ASC'
|
||||
}, myOptions);
|
||||
|
||||
args.week = time.week;
|
||||
args.year = time.year;
|
||||
}
|
||||
args.week = time.week;
|
||||
args.year = time.year;
|
||||
}
|
||||
|
||||
const started = getStartDateOfWeekNumber(args.week, args.year);
|
||||
started.setHours(0, 0, 0, 0);
|
||||
const started = getStartDateOfWeekNumber(args.week, args.year);
|
||||
started.setHours(0, 0, 0, 0);
|
||||
|
||||
const ended = new Date(started);
|
||||
ended.setDate(started.getDate() + 6);
|
||||
ended.setHours(23, 59, 59, 999);
|
||||
const ended = new Date(started);
|
||||
ended.setDate(started.getDate() + 6);
|
||||
ended.setHours(23, 59, 59, 999);
|
||||
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate');
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate');
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeControlCalculate');
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.timeBusinessCalculate');
|
||||
|
||||
if (args.workerId) {
|
||||
await models.WorkerTimeControl.destroyAll({
|
||||
userFk: args.workerId,
|
||||
timed: {between: [started, ended]},
|
||||
isSendMail: true
|
||||
}, myOptions);
|
||||
if (args.workerId) {
|
||||
await models.WorkerTimeControl.destroyAll({
|
||||
userFk: args.workerId,
|
||||
timed: {between: [started, ended]},
|
||||
isSendMail: true
|
||||
}, myOptions);
|
||||
|
||||
const where = {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week
|
||||
};
|
||||
await models.WorkerTimeControlMail.updateAll(where, {
|
||||
updated: new Date(), state: 'SENDED'
|
||||
}, myOptions);
|
||||
const where = {
|
||||
workerFk: args.workerId,
|
||||
year: args.year,
|
||||
week: args.week
|
||||
};
|
||||
await models.WorkerTimeControlMail.updateAll(where, {
|
||||
updated: new Date(), state: 'SENDED'
|
||||
}, myOptions);
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`CALL vn.timeControl_calculateByUser(?, ?, ?)
|
||||
stmt = new ParameterizedSQL(
|
||||
`CALL vn.timeControl_calculateByUser(?, ?, ?)
|
||||
`, [args.workerId, started, ended]);
|
||||
stmts.push(stmt);
|
||||
stmts.push(stmt);
|
||||
|
||||
stmt = new ParameterizedSQL(
|
||||
`CALL vn.timeBusiness_calculateByUser(?, ?, ?)
|
||||
stmt = new ParameterizedSQL(
|
||||
`CALL vn.timeBusiness_calculateByUser(?, ?, ?)
|
||||
`, [args.workerId, started, ended]);
|
||||
stmts.push(stmt);
|
||||
} else {
|
||||
await models.WorkerTimeControl.destroyAll({
|
||||
timed: {between: [started, ended]},
|
||||
isSendMail: true
|
||||
}, myOptions);
|
||||
stmts.push(stmt);
|
||||
} else {
|
||||
await models.WorkerTimeControl.destroyAll({
|
||||
timed: {between: [started, ended]},
|
||||
isSendMail: true
|
||||
}, myOptions);
|
||||
|
||||
const where = {
|
||||
year: args.year,
|
||||
week: args.week
|
||||
};
|
||||
await models.WorkerTimeControlMail.updateAll(where, {
|
||||
updated: new Date(), state: 'SENDED'
|
||||
}, myOptions);
|
||||
const where = {
|
||||
year: args.year,
|
||||
week: args.week
|
||||
};
|
||||
await models.WorkerTimeControlMail.updateAll(where, {
|
||||
updated: new Date(), state: 'SENDED'
|
||||
}, myOptions);
|
||||
|
||||
stmt = new ParameterizedSQL(`CALL vn.timeControl_calculateAll(?, ?)`, [started, ended]);
|
||||
stmts.push(stmt);
|
||||
stmt = new ParameterizedSQL(`CALL vn.timeControl_calculateAll(?, ?)`, [started, ended]);
|
||||
stmts.push(stmt);
|
||||
|
||||
stmt = new ParameterizedSQL(`CALL vn.timeBusiness_calculateAll(?, ?)`, [started, ended]);
|
||||
stmts.push(stmt);
|
||||
}
|
||||
stmt = new ParameterizedSQL(`CALL vn.timeBusiness_calculateAll(?, ?)`, [started, ended]);
|
||||
stmts.push(stmt);
|
||||
}
|
||||
|
||||
stmt = new ParameterizedSQL(`
|
||||
stmt = new ParameterizedSQL(`
|
||||
SELECT CONCAT(u.name, '@verdnatura.es') receiver,
|
||||
u.id workerFk,
|
||||
tb.dated,
|
||||
|
@ -154,25 +147,33 @@ module.exports = Self => {
|
|||
AND w.businessFk
|
||||
ORDER BY u.id, tb.dated
|
||||
`, [args.workerId]);
|
||||
const index = stmts.push(stmt) - 1;
|
||||
const index = stmts.push(stmt) - 1;
|
||||
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const days = await conn.executeStmt(sql, myOptions);
|
||||
stmts.push('DROP TEMPORARY TABLE tmp.timeControlCalculate');
|
||||
stmts.push('DROP TEMPORARY TABLE tmp.timeBusinessCalculate');
|
||||
|
||||
let previousWorkerFk = days[index][0].workerFk;
|
||||
let previousReceiver = days[index][0].receiver;
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const days = await conn.executeStmt(sql, myOptions);
|
||||
|
||||
const workerTimeControlConfig = await models.WorkerTimeControlConfig.findOne(null, myOptions);
|
||||
let previousWorkerFk = days[index][0].workerFk;
|
||||
let previousReceiver = days[index][0].receiver;
|
||||
|
||||
for (let day of days[index]) {
|
||||
const workerTimeControlConfig = await models.WorkerTimeControlConfig.findOne(null, myOptions);
|
||||
|
||||
for (let day of days[index]) {
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
try {
|
||||
workerFk = day.workerFk;
|
||||
if (day.timeWorkDecimal > 0 && day.timeWorkedDecimal == null
|
||||
&& (day.permissionRate ? day.permissionRate : true)) {
|
||||
&& (day.permissionRate == null ? true : day.permissionRate)) {
|
||||
if (day.timeTable == null) {
|
||||
const timed = new Date(day.dated);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(8),
|
||||
timed: timed.setHours(workerTimeControlConfig.teleworkingStart / 3600),
|
||||
manual: true,
|
||||
direction: 'in',
|
||||
isSendMail: true
|
||||
|
@ -181,7 +182,7 @@ module.exports = Self => {
|
|||
if (day.timeWorkDecimal >= workerTimeControlConfig.timeToBreakTime / 3600) {
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(9),
|
||||
timed: timed.setHours(workerTimeControlConfig.teleworkingStartBreakTime / 3600),
|
||||
manual: true,
|
||||
direction: 'middle',
|
||||
isSendMail: true
|
||||
|
@ -189,7 +190,10 @@ module.exports = Self => {
|
|||
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(9, 20),
|
||||
timed: timed.setHours(
|
||||
workerTimeControlConfig.teleworkingStartBreakTime / 3600,
|
||||
workerTimeControlConfig.breakTime / 60
|
||||
),
|
||||
manual: true,
|
||||
direction: 'middle',
|
||||
isSendMail: true
|
||||
|
@ -199,7 +203,11 @@ module.exports = Self => {
|
|||
const [hoursWork, minutesWork, secondsWork] = getTime(day.timeWorkSexagesimal);
|
||||
await models.WorkerTimeControl.create({
|
||||
userFk: day.workerFk,
|
||||
timed: timed.setHours(8 + hoursWork, minutesWork, secondsWork),
|
||||
timed: timed.setHours(
|
||||
workerTimeControlConfig.teleworkingStart / 3600 + hoursWork,
|
||||
minutesWork,
|
||||
secondsWork
|
||||
),
|
||||
manual: true,
|
||||
direction: 'out',
|
||||
isSendMail: true
|
||||
|
@ -307,7 +315,7 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
|
||||
if (firstWorkerTimeControl)
|
||||
firstWorkerTimeControl.updateAttribute('direction', 'in', myOptions);
|
||||
await firstWorkerTimeControl.updateAttribute('direction', 'in', myOptions);
|
||||
|
||||
const lastWorkerTimeControl = await models.WorkerTimeControl.findOne({
|
||||
where: {
|
||||
|
@ -318,7 +326,7 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
|
||||
if (lastWorkerTimeControl)
|
||||
lastWorkerTimeControl.updateAttribute('direction', 'out', myOptions);
|
||||
await lastWorkerTimeControl.updateAttribute('direction', 'out', myOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,15 +347,18 @@ module.exports = Self => {
|
|||
previousWorkerFk = day.workerFk;
|
||||
previousReceiver = day.receiver;
|
||||
}
|
||||
|
||||
if (tx) {
|
||||
await tx.commit();
|
||||
delete myOptions.transaction;
|
||||
}
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
if (tx) await tx.commit();
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
function getStartDateOfWeekNumber(week, year) {
|
||||
|
|
|
@ -10,7 +10,6 @@ describe('workerTimeControl sendMail()', () => {
|
|||
const ctx = {req: activeCtx, args: {}};
|
||||
|
||||
it('should fill time control of a worker without records in Journey and with rest', async() => {
|
||||
pending('https://redmine.verdnatura.es/issues/4903');
|
||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||
|
||||
try {
|
||||
|
@ -35,7 +34,6 @@ describe('workerTimeControl sendMail()', () => {
|
|||
});
|
||||
|
||||
it('should fill time control of a worker without records in Journey and without rest', async() => {
|
||||
pending('https://redmine.verdnatura.es/issues/4903');
|
||||
const workdayOf20Hours = 3;
|
||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||
|
||||
|
@ -63,7 +61,6 @@ describe('workerTimeControl sendMail()', () => {
|
|||
});
|
||||
|
||||
it('should fill time control of a worker with records in Journey and with rest', async() => {
|
||||
pending('https://redmine.verdnatura.es/issues/4903');
|
||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||
|
||||
try {
|
||||
|
@ -95,7 +92,6 @@ describe('workerTimeControl sendMail()', () => {
|
|||
});
|
||||
|
||||
it('should fill time control of a worker with records in Journey and without rest', async() => {
|
||||
pending('https://redmine.verdnatura.es/issues/4903');
|
||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||
|
||||
try {
|
||||
|
|
|
@ -2,7 +2,7 @@ const {Email} = require('vn-print');
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('weeklyHourRecordEmail', {
|
||||
description: 'Sends the buyer waste email',
|
||||
description: 'Sends the weekly hour record',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
|
|
|
@ -11,8 +11,17 @@
|
|||
"id": true,
|
||||
"type": "number"
|
||||
},
|
||||
"breakTime": {
|
||||
"type": "number"
|
||||
},
|
||||
"timeToBreakTime": {
|
||||
"type": "number"
|
||||
},
|
||||
"teleworkingStart": {
|
||||
"type": "number"
|
||||
},
|
||||
"teleworkingStartBreakTime": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "9.0.0",
|
||||
"version": "230401",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
subject: Your agricultural invoice
|
||||
title: Your agricultural invoice
|
||||
subject: Your agricultural receipt
|
||||
title: Your agricultural receipt
|
||||
dear: Dear supplier
|
||||
description: Attached you can find agricultural receipt generated from your last deliveries. Please return a signed and stamped copy to our administration department.
|
||||
conclusion: Thanks for your attention!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
subject: Tu factura agrícola
|
||||
title: Tu factura agrícola
|
||||
subject: Tu recibo agrícola
|
||||
title: Tu recibo agrícola
|
||||
dear: Estimado proveedor
|
||||
description: Adjunto puede encontrar recibo agrícola generado de sus últimas entregas. Por favor, devuelva una copia firmada y sellada a nuestro de departamento de administración.
|
||||
conclusion: ¡Gracias por tu atención!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
subject: Votre facture agricole
|
||||
title: Votre facture agricole
|
||||
subject: Votre reçu agricole
|
||||
title: Votre reçu agricole
|
||||
dear: Cher Fournisseur
|
||||
description: Vous trouverez en pièce jointe le reçu agricole généré à partir de vos dernières livraisons. Veuillez retourner une copie signée et tamponnée à notre service administratif.
|
||||
conclusion: Merci pour votre attention!
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
subject: A sua fatura agrícola
|
||||
title: A sua fatura agrícola
|
||||
subject: A sua recibo agrícola
|
||||
title: A sua recibo agrícola
|
||||
dear: Caro Fornecedor
|
||||
description: Em anexo encontra-se o recibo agrícola gerado a partir das suas últimas entregas. Por favor, devolva uma cópia assinada e carimbada ao nosso departamento de administração.
|
||||
conclusion: Obrigado pela atenção.
|
||||
|
|
Loading…
Reference in New Issue