diff --git a/back/models/buyer.json b/back/models/buyer.json index a17d3b538..a1297eda3 100644 --- a/back/models/buyer.json +++ b/back/models/buyer.json @@ -15,6 +15,9 @@ "nickname": { "type": "string", "required": true + }, + "display": { + "type": "boolean" } }, "acls": [ diff --git a/db/dump/fixtures.before.sql b/db/dump/fixtures.before.sql index f800a1da1..7f3ede501 100644 --- a/db/dump/fixtures.before.sql +++ b/db/dump/fixtures.before.sql @@ -3882,3 +3882,20 @@ INSERT INTO `vn`.`calendarHolidays` (calendarHolidaysTypeFk, dated, calendarHoli (1, '2001-05-17', 1, 5), (1, '2001-05-18', 1, 5); +INSERT INTO vn.stockBought (workerFk, bought, reserve, dated) + VALUES(35, 1.00, 1.00, '2001-01-01'); + +INSERT INTO vn.auctionConfig (id,conversionCoefficient,warehouseFk) + VALUES (1,0.6,6); + +INSERT INTO vn.warehouse (id,name,isFeedStock,delay,hasAvailable,isForTicket,countryFk,labelZone,hasComission,isInventory,isComparative,valuatedInventory,isManaged,hasConfectionTeam,hasStowaway,hasDms,isBuyerToBeEmailed,hasUbications,hasProduction,hasMachine,isLogiflora,isBionic,isHalt,isOrigin,isDestiny) + VALUES (6,'Warehouse six',0,0.004,1,0,1,0,0,1,1,0,1,0,0,0,0,1,1,0,0,1,0,0,0); + +INSERT INTO vn.travel (id,shipped,landed,warehouseInFk,warehouseOutFk,agencyFk__,`ref`,isDelivered,isReceived,m3,kg,cargoSupplierFk,totalEntries,agencyModeFk,editorFk,awbFk) + VALUES (11,'2001-01-01','2001-01-02',6,3,0,'eleventh travel',0,0,50.00,500,2,0,1,100,4); + +INSERT INTO vn.entry (id,supplierFk,invoiceNumber,isBooked,isExcludedFromAvailable,isConfirmed,isOrdered,isRaid,commission,created,evaNotes,travelFk,currencyFk,companyFk,isBlocked__,reference,editorFk,locked) + VALUES (9,69,'IN2009',0,1,0,0,1,0.0,'2000-12-01 00:00:00.000','',11,1,442,0,'Movement 9',100,'2024-07-30 08:13:49.000'); + +INSERT INTO vn.buy (entryFk,itemFk,quantity,dispatched,buyingValue,freightValue,isIgnored,stickers,packing,`grouping`,groupingMode,comissionValue,packageValue,packagingFk,price1,price2,price3,minPrice,printedStickers,workerFk,isChecked,isPickedOff,created,`__cm2`,weight,itemOriginalFk,editorFk,buyerFk) + VALUES (9,1,5000,0,50.0000,1.500,0,1,1,1,'packing',0.000,1.500,'4',0.00,99.60,99.40,0.00,0,0,1,0,'2024-07-30 08:13:51.000',0,1.00,1,100,35); diff --git a/db/routines/vn/procedures/stockBought_calculate.sql b/db/routines/vn/procedures/stockBought_calculate.sql new file mode 100644 index 000000000..54ac78d8e --- /dev/null +++ b/db/routines/vn/procedures/stockBought_calculate.sql @@ -0,0 +1,54 @@ +DELIMITER $$ +CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`stockBought_calculate`() +BEGIN +/** + * Inserts the purchase volume per buyer + * into stockBought according to the date. + * + * @param vDated Purchase date + */ + DECLARE vDated DATE; + SET vDated = util.VN_CURDATE(); + + CREATE OR REPLACE TEMPORARY TABLE tStockBought + SELECT workerFk, reserve + FROM stockBought + WHERE dated = vDated + AND reserve; + + DELETE FROM stockBought WHERE dated = vDated; + + INSERT INTO stockBought (workerFk, bought, dated) + SELECT it.workerFk, + ROUND(SUM( + (ac.conversionCoefficient * + (b.quantity / b.packing) * + buy_getVolume(b.id) + ) / (vc.trolleyM3 * 1000000) + ), 1), + vDated + FROM entry e + JOIN travel t ON t.id = e.travelFk + JOIN warehouse w ON w.id = t.warehouseInFk + JOIN buy b ON b.entryFk = e.id + JOIN item i ON i.id = b.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN auctionConfig ac + JOIN volumeConfig vc + WHERE t.shipped = vDated + AND t.warehouseInFk = ac.warehouseFk + GROUP BY it.workerFk; + + UPDATE stockBought s + JOIN tStockBought ts ON ts.workerFk = s.workerFk + SET s.reserve = ts.reserve + WHERE s.dated = vDated; + + INSERT INTO stockBought (workerFk, reserve, dated) + SELECT ts.workerFk, ts.reserve, vDated + FROM tStockBought ts + WHERE ts.workerFk NOT IN (SELECT workerFk FROM stockBought WHERE dated = vDated); + + DROP TEMPORARY TABLE tStockBought; +END$$ +DELIMITER ; diff --git a/db/routines/vn/views/buyer.sql b/db/routines/vn/views/buyer.sql index 7114c50bc..455c68770 100644 --- a/db/routines/vn/views/buyer.sql +++ b/db/routines/vn/views/buyer.sql @@ -2,10 +2,12 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vn`.`buyer` AS SELECT DISTINCT `u`.`id` AS `userFk`, - `u`.`nickname` AS `nickname` + `u`.`nickname` AS `nickname`, + `ic`.`display` AS `display` FROM ( `account`.`user` `u` JOIN `vn`.`itemType` `it` ON(`it`.`workerFk` = `u`.`id`) + JOIN `vn`.`itemCategory` `ic` ON(`ic`.`id` = `it`.`categoryFk`) ) WHERE `u`.`active` <> 0 ORDER BY `u`.`nickname` diff --git a/db/versions/11115-turquoiseRose/00-firstScript.sql b/db/versions/11115-turquoiseRose/00-firstScript.sql new file mode 100644 index 000000000..3982936fc --- /dev/null +++ b/db/versions/11115-turquoiseRose/00-firstScript.sql @@ -0,0 +1,30 @@ +-- Place your SQL code here +-- vn.stockBought definition + +CREATE TABLE IF NOT EXISTS vn.stockBought ( + id INT UNSIGNED auto_increment NOT NULL, + workerFk int(10) unsigned NOT NULL, + bought decimal(10,2) NOT NULL COMMENT 'purchase volume in m3 for the day', + reserve decimal(10,2) NULL COMMENT 'reserved volume in m3 for the day', + dated DATE NOT NULL DEFAULT current_timestamp(), + CONSTRAINT stockBought_pk PRIMARY KEY (id), + CONSTRAINT stockBought_unique UNIQUE KEY (workerFk,dated), + CONSTRAINT stockBought_worker_FK FOREIGN KEY (workerFk) REFERENCES vn.worker(id) +) +ENGINE=InnoDB +DEFAULT CHARSET=utf8mb3 +COLLATE=utf8mb3_unicode_ci; + + +INSERT IGNORE vn.stockBought (workerFk, bought, reserve, dated) + SELECT userFk, SUM(buyed), SUM(IFNULL(reserved,0)), dated + FROM vn.stockBuyed + WHERE userFk IS NOT NULL + AND buyed IS NOT NULL + GROUP BY userFk, dated; + +INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId) + VALUES ('StockBought','*','READ','ALLOW','ROLE','buyer'), + ('StockBought','*','WRITE','ALLOW','ROLE','buyer'), + ('Buyer','*','READ','ALLOW','ROLE','buyer'); + diff --git a/loopback/locale/en.json b/loopback/locale/en.json index 1e5733442..79f7eecc5 100644 --- a/loopback/locale/en.json +++ b/loopback/locale/en.json @@ -233,5 +233,9 @@ "It has been invoiced but the PDF could not be generated": "It has been invoiced but the PDF could not be generated", "It has been invoiced but the PDF of refund not be generated": "It has been invoiced but the PDF of refund not be generated", "Cannot add holidays on this day": "Cannot add holidays on this day", - "Cannot send mail": "Cannot send mail" -} + "Cannot send mail": "Cannot send mail", + "Payment method is required": "Payment method is required", + "This worker already exists": "This worker already exists", + "This personal mail already exists": "This personal mail already exists", + "This buyer has already made a reservation for this date": "This buyer has already made a reservation for this date" +} \ No newline at end of file diff --git a/loopback/locale/es.json b/loopback/locale/es.json index 5b5928993..a11fb6f7c 100644 --- a/loopback/locale/es.json +++ b/loopback/locale/es.json @@ -366,5 +366,6 @@ "It has been invoiced but the PDF could not be generated": "Se ha facturado pero no se ha podido generar el PDF", "It has been invoiced but the PDF of refund not be generated": "Se ha facturado pero no se ha podido generar el PDF del abono", "Payment method is required": "El método de pago es obligatorio", - "Cannot send mail": "Não é possível enviar o email" -} + "Cannot send mail": "Não é possível enviar o email", + "This buyer has already made a reservation for this date": "This buyer has already made a reservation for this date" +} \ No newline at end of file diff --git a/modules/account/back/models/mail-alias-account.js b/modules/account/back/models/mail-alias-account.js index 61ca344e9..0eee6a123 100644 --- a/modules/account/back/models/mail-alias-account.js +++ b/modules/account/back/models/mail-alias-account.js @@ -1,5 +1,6 @@ const ForbiddenError = require('vn-loopback/util/forbiddenError'); +const UserError = require('vn-loopback/util/user-error'); module.exports = Self => { Self.rewriteDbError(function(err) { diff --git a/modules/entry/back/methods/entry/filter.js b/modules/entry/back/methods/entry/filter.js index 1cd12b737..a8a9d4de1 100644 --- a/modules/entry/back/methods/entry/filter.js +++ b/modules/entry/back/methods/entry/filter.js @@ -1,4 +1,3 @@ - const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; const buildFilter = require('vn-loopback/util/filter').buildFilter; const mergeFilters = require('vn-loopback/util/filter').mergeFilters; diff --git a/modules/entry/back/methods/stock-bought/getStockBought.js b/modules/entry/back/methods/stock-bought/getStockBought.js new file mode 100644 index 000000000..da194ed80 --- /dev/null +++ b/modules/entry/back/methods/stock-bought/getStockBought.js @@ -0,0 +1,52 @@ +module.exports = Self => { + Self.remoteMethod('getStockBought', { + description: 'Returns the stock bought for a given date', + accessType: 'READ', + accepts: [{ + arg: 'dated', + type: 'date', + description: 'The date to filter', + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getStockBought`, + verb: 'GET' + } + }); + + Self.getStockBought = async(dated = Date.vnNew()) => { + const models = Self.app.models; + const today = Date.vnNew(); + dated.setHours(0, 0, 0, 0); + today.setHours(0, 0, 0, 0); + + if (dated.getTime() === today.getTime()) + await models.StockBought.rawSql(`CALL vn.stockBought_calculate()`); + + return models.StockBought.find( + { + where: { + dated: dated + }, + include: [ + { + relation: 'worker', + scope: { + include: [ + { + relation: 'user', + scope: { + fields: ['id', 'name'] + } + } + ] + } + } + ] + }); + }; +}; diff --git a/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js b/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js new file mode 100644 index 000000000..471d5c9c4 --- /dev/null +++ b/modules/entry/back/methods/stock-bought/getStockBoughtDetail.js @@ -0,0 +1,56 @@ +module.exports = Self => { + Self.remoteMethod('getStockBoughtDetail', { + description: 'Returns the detail of stock bought for a given date and a worker', + accessType: 'READ', + accepts: [{ + arg: 'workerFk', + type: 'number', + description: 'The worker to filter', + required: true, + }, { + arg: 'dated', + type: 'string', + description: 'The date to filter', + } + ], + returns: { + type: ['object'], + root: true + }, + http: { + path: `/getStockBoughtDetail`, + verb: 'GET' + } + }); + + Self.getStockBoughtDetail = async(workerFk, dated = Date.vnNew()) => { + console.log('dated: ', new Date(dated)); + console.log('new Date(dated).setHours(0, 0, 0, 0): ', new Date(dated).setHours(0, 0, 0, 0)); + return Self.rawSql( + `SELECT e.id entryFk, + i.id itemFk, + i.longName itemName, + b.quantity, + ROUND((ac.conversionCoefficient * + (b.quantity / b.packing) * + buy_getVolume(b.id) + ) / (vc.trolleyM3 * 1000000), + 2 + ) volume, + b.packagingFk, + b.packing + FROM entry e + JOIN travel t ON t.id = e.travelFk + JOIN buy b ON b.entryFk = e.id + JOIN item i ON i.id = b.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN worker w ON w.id = it.workerFk + JOIN auctionConfig ac + JOIN volumeConfig vc + WHERE t.warehouseInFk = ac.warehouseFk + AND it.workerFk = ? + AND t.shipped = ?`, + [workerFk, new Date(dated)] + ); + }; +}; diff --git a/modules/entry/back/model-config.json b/modules/entry/back/model-config.json index dc7fd86be..85f5e8285 100644 --- a/modules/entry/back/model-config.json +++ b/modules/entry/back/model-config.json @@ -25,5 +25,8 @@ }, "EntryType": { "dataSource": "vn" + }, + "StockBought": { + "dataSource": "vn" } } \ No newline at end of file diff --git a/modules/entry/back/models/stock-bought.js b/modules/entry/back/models/stock-bought.js new file mode 100644 index 000000000..ae52e7654 --- /dev/null +++ b/modules/entry/back/models/stock-bought.js @@ -0,0 +1,10 @@ +const UserError = require('vn-loopback/util/user-error'); +module.exports = Self => { + require('../methods/stock-bought/getStockBought')(Self); + require('../methods/stock-bought/getStockBoughtDetail')(Self); + Self.rewriteDbError(function(err) { + if (err.code === 'ER_DUP_ENTRY') + return new UserError(`This buyer has already made a reservation for this date`); + return err; + }); +}; diff --git a/modules/entry/back/models/stock-bought.json b/modules/entry/back/models/stock-bought.json new file mode 100644 index 000000000..18c9f0347 --- /dev/null +++ b/modules/entry/back/models/stock-bought.json @@ -0,0 +1,34 @@ +{ + "name": "StockBought", + "base": "VnModel", + "options": { + "mysql": { + "table": "stockBought" + } + }, + "properties": { + "id": { + "type": "number", + "id": true + }, + "workerFk": { + "type": "number" + }, + "bought": { + "type": "number" + }, + "reserve": { + "type": "number" + }, + "dated": { + "type": "date" + } + }, + "relations": { + "worker": { + "type": "belongsTo", + "model": "Worker", + "foreignKey": "workerFk" + } + } +}