Merge pull request '8389-testToMaster' (!3357) from 8389-testToMaster into master
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #3357 Reviewed-by: Guillermo Bonet <guillermo@verdnatura.es>
This commit is contained in:
commit
43edb1f82e
28
CHANGELOG.md
28
CHANGELOG.md
|
@ -1,3 +1,31 @@
|
|||
# Version 25.00 - 2025-01-14
|
||||
|
||||
### Added 🆕
|
||||
|
||||
- feat: refs #7235 add serialType parameter to getInvoiceDate and implement corresponding tests by:jgallego
|
||||
- feat: refs #7301 update lastEntriesFilter to include landedDate and enhance test cases (origin/7301-removeRedundantInventories) by:pablone
|
||||
- feat: refs #7880 error code and translations by:ivanm
|
||||
- feat: refs #7924 add isCustomInspectionRequired field to item and update related logic by:jgallego
|
||||
- feat: refs #8167 update canBeInvoiced method to include active status check and improve test cases by:jgallego
|
||||
- feat: refs #8167 update locale and improve invoicing logic with error handling by:jgallego
|
||||
- feat: refs #8246 added relation for the front's new field by:Jon
|
||||
- feat: refs #8266 added itemFk and needed fixtures by:jtubau
|
||||
- feat: refs #8324 country unique by:Carlos Andrés
|
||||
|
||||
### Changed 📦
|
||||
|
||||
|
||||
### Fixed 🛠️
|
||||
|
||||
- feat: refs #8266 added itemFk and needed fixtures by:jtubau
|
||||
- fix: add isCustomInspectionRequired column to item table for customs inspection indication by:jgallego
|
||||
- fix: canBeInvoiced only in makeInvoice by:alexm
|
||||
- fix: hotFix getMondayWeekYear by:alexm
|
||||
- fix: refs #6598 update ACL property assignment by:jorgep
|
||||
- fix: refs #6861 refs#6861 addPrevOK by:sergiodt
|
||||
- fix: refs #7301 remove debug console log and update test cases in lastEntriesFilter by:pablone
|
||||
- fix: refs #7301 update SQL fixtures and improve lastEntriesFilter logic by:pablone
|
||||
|
||||
# Version 24.52 - 2024-01-07
|
||||
|
||||
### Added 🆕
|
||||
|
|
|
@ -67,7 +67,6 @@ module.exports = Self => {
|
|||
INSERT INTO util.debug (variable, value)
|
||||
VALUES ('sendCheckingPresence_error', ?)
|
||||
`, [`User: ${userId}, recipient: ${recipientId}, message: ${message}, error: ${e}`]);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@ module.exports = Self => {
|
|||
if (acl.principalType == 'ROLE' && acl.permission == 'ALLOW') {
|
||||
const staticAcl = {
|
||||
model: model.name,
|
||||
property: '*',
|
||||
property: acl.property,
|
||||
accessType: acl.accessType,
|
||||
permission: acl.permission,
|
||||
principalType: acl.principalType,
|
||||
|
|
|
@ -974,26 +974,30 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
|
|||
('SER', 'Services'),
|
||||
('VT', 'Sales');
|
||||
|
||||
INSERT INTO `vn`.`item`(`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenseFk`,
|
||||
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `family`, `isFloramondo`, `genericFk`, `itemPackingTypeFk`, `hasMinPrice`, `weightByPiece`)
|
||||
VALUES
|
||||
(1, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 'EMB', 0, NULL, 'V', 0, 3),
|
||||
(2, 2, 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 'VT', 0, NULL, 'H', 0, 2),
|
||||
(3, 1, 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 'VT', 0, NULL, NULL, 0, 5),
|
||||
(4, 1, 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(5, 3, 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(6, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(7, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(8, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(9, 2, 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL),
|
||||
(10, 1, 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(11, 1, 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(12, 3, 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL),
|
||||
(13, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 1, 'VT', 1, NULL, NULL, 1, NULL),
|
||||
(14, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL),
|
||||
(15, 4, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL),
|
||||
(16, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL),
|
||||
(71, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL);
|
||||
INSERT INTO `vn`.`item`(
|
||||
`id`, `typeFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenseFk`,
|
||||
`comment`, `relevancy`, `image`, `subName`, `minPrice`, `family`, `isFloramondo`, `genericFk`,
|
||||
`itemPackingTypeFk`, `hasMinPrice`, `weightByPiece`, `isCustomInspectionRequired`
|
||||
)
|
||||
VALUES
|
||||
(1, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 'EMB', 0, NULL, 'V', 0, 3, 1),
|
||||
(2, 2, 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 'VT', 0, NULL, 'H', 0, 2, 1),
|
||||
(3, 1, 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 'VT', 0, NULL, NULL, 0, 5, 0),
|
||||
(4, 1, 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(5, 3, 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(6, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(7, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(8, 2, 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(9, 2, 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL, 0),
|
||||
(10, 1, 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(11, 1, 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(12, 3, 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0),
|
||||
(13, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 1, 'VT', 1, NULL, NULL, 1, NULL, 0),
|
||||
(14, 5, 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 1, NULL, NULL, 0, NULL, 0),
|
||||
(15, 4, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
||||
(16, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'EMB', 0, NULL, NULL, 0, NULL, 0),
|
||||
(71, 6, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 'VT', 0, NULL, NULL, 0, NULL, 0);
|
||||
|
||||
|
||||
-- Update the taxClass after insert of the items
|
||||
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2
|
||||
|
@ -1517,7 +1521,7 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
|
|||
(10, DATE_ADD(util.VN_CURDATE(), INTERVAL +5 DAY), DATE_ADD(util.VN_CURDATE(), INTERVAL +5 DAY), 5, 1, 1, 50.00, 500, 'nineth travel', 1, 2, 10, TRUE, 2),
|
||||
(11, util.VN_CURDATE() - INTERVAL 1 DAY , util.VN_CURDATE(), 6, 3, 0, 50.00, 500, 'eleventh travel', 1, 2, 4, FALSE, NULL),
|
||||
(12, util.VN_CURDATE() , util.VN_CURDATE() + INTERVAL 1 DAY, 6, 3, 0, 50.00, 500, 'eleventh travel', 1, 2, 4, FALSE, NULL),
|
||||
(13, util.VN_CURDATE() - INTERVAL 1 MONTH - INTERVAL 1 DAY, util.VN_CURDATE() - INTERVAL 1 MONTH, 6, 3, 0, 50.00, 500, 'eleventh travel', 1, 2, 4, FALSE, NULL);
|
||||
(13, util.VN_CURDATE() - INTERVAL 1 MONTH - INTERVAL 1 DAY, util.VN_CURDATE() - INTERVAL 1 MONTH, 6, 3, 0, 50.00, 500, 'eleventh travel', 1, 2, 4, FALSE, NULL);
|
||||
|
||||
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `evaNotes`, `typeFk`)
|
||||
VALUES
|
||||
|
@ -1575,7 +1579,7 @@ INSERT INTO `bs`.`waste`(`buyerFk`, `year`, `week`, `itemFk`, `itemTypeFk`, `sal
|
|||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 'grouping', NULL, 0.00, 1.75, 1.67, 0, 1, 0, 4, util.VN_CURDATE()),
|
||||
(16, 99,1,50.0000, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.60, 99.40, 0, 1, 0, 1.00, '2024-07-30 08:13:51.000'),
|
||||
(17, 11, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'packing', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH),
|
||||
(18, 12, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH);
|
||||
(18, 12, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 'grouping', NULL, 0.00, 99.6, 99.4, 0, 1, 0, 1, util.VN_CURDATE() - INTERVAL 2 MONTH);
|
||||
|
||||
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
|
||||
VALUES
|
||||
|
@ -3968,7 +3972,7 @@ VALUES(1, '');
|
|||
|
||||
INSERT INTO dipole.expedition_PrintOut (expeditionFk, ticketFk, addressFk, street, postalCode, city, shopName, isPrinted, created, printerFk, routeFk, parkingCode,
|
||||
truckName, clientFk, phone, province, agency, m3, workerCode, itemFk, quantity, longName, shelvingFk, comments)
|
||||
VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, NULL, 'NCC', NULL);
|
||||
VALUES(1, 1, 0, ' ', ' ', ' ', ' ', 0, '2001-01-01 00:00:00', 1, 0, ' ', ' ', 0, NULL, '', NULL, 0.000, NULL, 10, NULL, 'Ranged Reinforced weapon sniper rifle 700mm' , 'NCC', NULL);
|
||||
|
||||
INSERT INTO vn.accountDetail
|
||||
(id, value, accountDetailTypeFk, supplierAccountFk)
|
||||
|
@ -4041,7 +4045,7 @@ INSERT IGNORE INTO vn.saySimpleConfig (url, defaultChannel)
|
|||
INSERT INTO vn.workerIrpf (workerFk,spouseNif, geographicMobilityDate)
|
||||
VALUES (1106,'26493101E','2019-09-20');
|
||||
|
||||
INSERT INTO vn.referenceRate (currencyFk, dated, value)
|
||||
INSERT INTO vn.referenceRate (currencyFk, dated, value)
|
||||
VALUES (2, '2000-12-01', 1.0495),
|
||||
(2, '2001-01-01', 1.0531),
|
||||
(2, '2001-02-01', 7.6347);
|
||||
|
|
|
@ -107,7 +107,7 @@ BEGIN
|
|||
) INTO vHas0Amount;
|
||||
|
||||
IF vHas0Amount THEN
|
||||
CALL util.throw('Hay líneas vacías. Por favor, elimínelas');
|
||||
CALL util.throw('orderLinesWithZero');
|
||||
END IF;
|
||||
|
||||
START TRANSACTION;
|
||||
|
|
|
@ -16,10 +16,11 @@ BEGIN
|
|||
TRUE,
|
||||
sc.userFk,
|
||||
s.id
|
||||
FROM vn.sectorCollection sc
|
||||
JOIN vn.sectorCollectionSaleGroup scsg ON scsg.sectorCollectionFk = sc.id
|
||||
JOIN vn.saleGroupDetail sgd ON sgd.saleGroupFk = scsg.saleGroupFk
|
||||
JOIN vn.state s ON s.code = 'OK PREVIOUS'
|
||||
FROM sectorCollection sc
|
||||
JOIN sectorCollectionSaleGroup scsg ON scsg.sectorCollectionFk = sc.id
|
||||
JOIN saleGroupDetail sgd ON sgd.saleGroupFk = scsg.saleGroupFk
|
||||
JOIN state s ON s.code = 'OK PREVIOUS'
|
||||
JOIN itemShelvingSale iss ON iss.saleFk = sgd.saleFk
|
||||
WHERE sc.id = vSectorCollectionFk;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
INSERT INTO hedera.message (code, description)
|
||||
VALUES ('orderLinesWithZero','There are empty lines. Please delete them');
|
||||
|
||||
INSERT INTO hedera.messageI18n (code, lang, description)
|
||||
VALUES ('orderLinesWithZero','es','Hay líneas vacías. Por favor, elimínelas');
|
||||
|
||||
INSERT INTO hedera.messageI18n (code, lang, description)
|
||||
VALUES ('orderLinesWithZero','fr','Il y a des lignes vides. Veuillez les supprimer');
|
||||
|
||||
INSERT INTO hedera.messageI18n (code, lang, description)
|
||||
VALUES ('orderLinesWithZero','pt','Existem linhas vazias. Por favor, apague-os');
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
ALTER TABLE vn.country
|
||||
ADD CONSTRAINT country_unique_name UNIQUE KEY (name);
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE `vn`.`item`
|
||||
ADD COLUMN `isCustomInspectionRequired` TINYINT(1) NOT NULL DEFAULT 0 COMMENT 'Indicates if the item requires physical inspection at customs';
|
|
@ -211,6 +211,7 @@
|
|||
"Name should be uppercase": "Name should be uppercase",
|
||||
"You cannot update these fields": "You cannot update these fields",
|
||||
"CountryFK cannot be empty": "Country cannot be empty",
|
||||
"No tickets to invoice": "There are no tickets to invoice that meet the invoicing requirements",
|
||||
"You are not allowed to modify the alias": "You are not allowed to modify the alias",
|
||||
"You already have the mailAlias": "You already have the mailAlias",
|
||||
"This machine is already in use.": "This machine is already in use.",
|
||||
|
@ -246,8 +247,9 @@
|
|||
"ticketLostExpedition": "The ticket [{{ticketId}}]({{{ticketUrl}}}) has the following lost expedition:{{ expeditionId }}",
|
||||
"The raid information is not correct": "The raid information is not correct",
|
||||
"Payment method is required": "Payment method is required",
|
||||
"Sales already moved": "Sales already moved",
|
||||
"Holidays to past days not available": "Holidays to past days not available",
|
||||
"Sales already moved": "Sales already moved",
|
||||
"Holidays to past days not available": "Holidays to past days not available",
|
||||
"Price cannot be blank": "Price cannot be blank",
|
||||
"There are tickets to be invoiced": "There are tickets to be invoiced"
|
||||
"There are tickets to be invoiced": "There are tickets to be invoiced",
|
||||
"The address of the customer must have information about Incoterms and Customs Agent": "The address of the customer must have information about Incoterms and Customs Agent"
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@
|
|||
"Incorrect pin": "Pin incorrecto.",
|
||||
"You already have the mailAlias": "Ya tienes este alias de correo",
|
||||
"The alias cant be modified": "Este alias de correo no puede ser modificado",
|
||||
"No tickets to invoice": "No hay tickets para facturar",
|
||||
"No tickets to invoice": "No hay tickets para facturar que cumplan los requisitos de facturación",
|
||||
"this warehouse has not dms": "El Almacén no acepta documentos",
|
||||
"This ticket already has a cmr saved": "Este ticket ya tiene un cmr guardado",
|
||||
"Name should be uppercase": "El nombre debe ir en mayúscula",
|
||||
|
|
|
@ -339,7 +339,7 @@
|
|||
"Incorrect pin": "Pin incorrect.",
|
||||
"You already have the mailAlias": "Vous avez déjà cet alias de courrier",
|
||||
"The alias cant be modified": "Cet alias de courrier ne peut pas être modifié",
|
||||
"No tickets to invoice": "Pas de tickets à facturer",
|
||||
"No tickets to invoice": "Il n'y a pas de tickets à facturer qui répondent aux exigences de facturation",
|
||||
"this warehouse has not dms": "L'entrepôt n'accepte pas les documents",
|
||||
"This ticket already has a cmr saved": "Ce ticket a déjà un cmr enregistré",
|
||||
"Name should be uppercase": "Le nom doit être en majuscules",
|
||||
|
|
|
@ -339,7 +339,7 @@
|
|||
"Incorrect pin": "PIN incorreto.",
|
||||
"You already have the mailAlias": "Você já tem o alias de e-mail",
|
||||
"The alias cant be modified": "O alias não pode ser modificado",
|
||||
"No tickets to invoice": "Não há tickets para faturar",
|
||||
"No tickets to invoice": "Não há bilhetes para faturar que atendam aos requisitos de faturamento",
|
||||
"this warehouse has not dms": "Este armazém não tem DMS",
|
||||
"This ticket already has a cmr saved": "Este ticket já tem um CMR salvo",
|
||||
"Name should be uppercase": "O nome deve estar em maiúsculas",
|
||||
|
|
|
@ -29,14 +29,14 @@ module.exports = Self => {
|
|||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
let tx;
|
||||
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const user = await models.VnUser.findOne({
|
||||
|
|
|
@ -2,7 +2,7 @@ const UserError = require('vn-loopback/util/user-error');
|
|||
|
||||
module.exports = function(Self) {
|
||||
Self.remoteMethod('canBeInvoiced', {
|
||||
description: 'Change property isEqualizated in all client addresses',
|
||||
description: 'Check if a client can be invoiced',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ module.exports = function(Self) {
|
|||
Object.assign(myOptions, options);
|
||||
|
||||
const client = await models.Client.findById(id, {
|
||||
fields: ['id', 'isTaxDataChecked', 'hasToInvoice', 'payMethodFk'],
|
||||
fields: ['id', 'isTaxDataChecked', 'hasToInvoice', 'payMethodFk', 'isActive'],
|
||||
include:
|
||||
{
|
||||
relation: 'payMethod',
|
||||
|
@ -53,9 +53,6 @@ module.exports = function(Self) {
|
|||
if (client.payMethod().code === 'wireTransfer' && !company.supplierAccountFk)
|
||||
throw new UserError('The company has not informed the supplier account for bank transfers');
|
||||
|
||||
if (client.isTaxDataChecked && client.hasToInvoice)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return client.isTaxDataChecked && client.hasToInvoice && client.isActive;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,6 +8,8 @@ describe('client canBeInvoiced()', () => {
|
|||
const activeCtx = {
|
||||
accessToken: {userId: userId}
|
||||
};
|
||||
let tx;
|
||||
let options;
|
||||
|
||||
beforeAll(async() => {
|
||||
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||
|
@ -15,60 +17,45 @@ describe('client canBeInvoiced()', () => {
|
|||
});
|
||||
});
|
||||
|
||||
beforeEach(async() => {
|
||||
tx = await models.Client.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should return falsy for a client without the data checked', async() => {
|
||||
const tx = await models.Client.beginTransaction({});
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttribute('isTaxDataChecked', false, options);
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttribute('isTaxDataChecked', false, options);
|
||||
expect(canBeInvoiced).toEqual(false);
|
||||
});
|
||||
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
it('should return falsy for a client not active', async() => {
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttribute('isActive', false, options);
|
||||
|
||||
expect(canBeInvoiced).toEqual(false);
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
expect(canBeInvoiced).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return falsy for a client with invoicing disabled', async() => {
|
||||
const tx = await models.Client.beginTransaction({});
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttribute('hasToInvoice', false, options);
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
const client = await models.Client.findById(clientId, null, options);
|
||||
await client.updateAttribute('hasToInvoice', false, options);
|
||||
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
expect(canBeInvoiced).toEqual(false);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
expect(canBeInvoiced).toEqual(false);
|
||||
});
|
||||
|
||||
it('should return truthy for an invoiceable client', async() => {
|
||||
const tx = await models.Client.beginTransaction({});
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const canBeInvoiced = await models.Client.canBeInvoiced(clientId, companyId, options);
|
||||
|
||||
expect(canBeInvoiced).toEqual(true);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
expect(canBeInvoiced).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -84,6 +84,11 @@
|
|||
"type": "belongsTo",
|
||||
"model": "CustomsAgent",
|
||||
"foreignKey": "customsAgentFk"
|
||||
},
|
||||
"postcode": {
|
||||
"type": "belongsTo",
|
||||
"model": "Postcode",
|
||||
"foreignKey": "postalCode"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('clientsToInvoice', {
|
||||
description: 'Get the clients to make global invoicing',
|
||||
|
@ -47,7 +49,6 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
// Packaging liquidation
|
||||
const vIsAllInvoiceable = false;
|
||||
await Self.rawSql('CALL ticketPackaging_add(?, ?, ?, ?)', [
|
||||
clientId,
|
||||
|
@ -71,9 +72,6 @@ module.exports = Self => {
|
|||
AND t.shipped BETWEEN ? AND util.dayEnd(?)
|
||||
AND (t.clientFk = ? OR ? IS NULL )
|
||||
AND t.companyFk = ?
|
||||
AND c.hasToInvoice
|
||||
AND c.isTaxDataChecked
|
||||
AND c.isActive
|
||||
AND NOT t.isDeleted
|
||||
GROUP BY IF(c.hasToInvoiceByAddress, a.id, c.id)
|
||||
HAVING SUM(t.totalWithVat) > 0;`;
|
||||
|
|
|
@ -7,7 +7,12 @@ module.exports = Self => {
|
|||
arg: 'companyFk',
|
||||
type: 'number',
|
||||
required: true
|
||||
}
|
||||
},
|
||||
{
|
||||
arg: 'serialType',
|
||||
type: 'string',
|
||||
required: true
|
||||
},
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
|
@ -19,16 +24,16 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getInvoiceDate = async companyFk => {
|
||||
Self.getInvoiceDate = async(companyFk, serialType) => {
|
||||
const models = Self.app.models;
|
||||
const [invoiceDate] = await models.InvoiceOut.rawSql(
|
||||
`SELECT MAX(io.issued) issued
|
||||
FROM invoiceOut io
|
||||
JOIN invoiceOutSerial ios ON ios.code = io.serial
|
||||
WHERE ios.type = 'global'
|
||||
AND io.issued
|
||||
WHERE ios.type = ?
|
||||
AND io.issued
|
||||
AND io.companyFk = ?`,
|
||||
[companyFk]
|
||||
[serialType, companyFk]
|
||||
);
|
||||
return invoiceDate;
|
||||
};
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const LoopBackContext = require('loopback-context');
|
||||
|
||||
describe('InvoiceOut clientsToInvoice()', () => {
|
||||
const userId = 1;
|
||||
const clientId = 1101;
|
||||
const companyFk = 442;
|
||||
const maxShipped = new Date();
|
||||
const maxShipped = Date.vnNew();
|
||||
maxShipped.setMonth(11);
|
||||
maxShipped.setDate(31);
|
||||
maxShipped.setHours(23, 59, 59, 999);
|
||||
const invoiceDate = new Date();
|
||||
const invoiceDate = Date.vnNew();
|
||||
const activeCtx = {
|
||||
getLocale: () => {
|
||||
return 'en';
|
||||
|
@ -20,6 +21,21 @@ describe('InvoiceOut clientsToInvoice()', () => {
|
|||
headers: {origin: 'http://localhost'}
|
||||
};
|
||||
const ctx = {req: activeCtx};
|
||||
let tx;
|
||||
let options;
|
||||
|
||||
beforeEach(async() => {
|
||||
LoopBackContext.getCurrentContext = () => ({
|
||||
active: activeCtx,
|
||||
});
|
||||
|
||||
tx = await models.InvoiceOut.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should return a list of clients to invoice', async() => {
|
||||
spyOn(models.InvoiceOut, 'rawSql').and.callFake(query => {
|
||||
|
@ -37,24 +53,14 @@ describe('InvoiceOut clientsToInvoice()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
const addresses = await models.InvoiceOut.clientsToInvoice(
|
||||
ctx, clientId, invoiceDate, maxShipped, companyFk, options);
|
||||
|
||||
try {
|
||||
const addresses = await models.InvoiceOut.clientsToInvoice(
|
||||
ctx, clientId, invoiceDate, maxShipped, companyFk, options);
|
||||
|
||||
expect(addresses.length).toBeGreaterThan(0);
|
||||
expect(addresses[0].clientId).toBe(clientId);
|
||||
expect(addresses[0].clientName).toBe('Test Client');
|
||||
expect(addresses[0].id).toBe(1);
|
||||
expect(addresses[0].nickname).toBe('Address 1');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
expect(addresses.length).toBeGreaterThan(0);
|
||||
expect(addresses[0].clientId).toBe(clientId);
|
||||
expect(addresses[0].clientName).toBe('Test Client');
|
||||
expect(addresses[0].id).toBe(1);
|
||||
expect(addresses[0].nickname).toBe('Address 1');
|
||||
});
|
||||
|
||||
it('should handle errors and rollback transaction', async() => {
|
||||
|
@ -62,14 +68,20 @@ describe('InvoiceOut clientsToInvoice()', () => {
|
|||
return Promise.reject(new Error('Test Error'));
|
||||
});
|
||||
|
||||
const tx = await models.InvoiceOut.beginTransaction({});
|
||||
const options = {transaction: tx};
|
||||
|
||||
try {
|
||||
await models.InvoiceOut.clientsToInvoice(ctx, clientId, invoiceDate, maxShipped, companyFk, options);
|
||||
} catch (e) {
|
||||
expect(e.message).toBe('Test Error');
|
||||
await tx.rollback();
|
||||
}
|
||||
});
|
||||
|
||||
it('should return all list', async() => {
|
||||
const minShipped = Date.vnNew();
|
||||
minShipped.setFullYear(maxShipped.getFullYear() - 1);
|
||||
|
||||
const toInvoice = await models.InvoiceOut.clientsToInvoice(
|
||||
ctx, null, invoiceDate, maxShipped, companyFk, options);
|
||||
|
||||
expect(toInvoice).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
const moment = require('moment');
|
||||
|
||||
describe('getInvoiceDate()', () => {
|
||||
const companyFk = 442;
|
||||
let tx;
|
||||
let options;
|
||||
|
||||
beforeEach(async() => {
|
||||
tx = await models.InvoiceOut.beginTransaction({});
|
||||
options = {transaction: tx};
|
||||
});
|
||||
|
||||
afterEach(async() => {
|
||||
await tx.rollback();
|
||||
});
|
||||
|
||||
it('should return a correct date for serialType "global"', async() => {
|
||||
const serialType = 'global';
|
||||
const result = await models.InvoiceOut.getInvoiceDate(companyFk, serialType, options);
|
||||
|
||||
expect(moment(result.issued).format('YYYY-MM-DD')).toEqual('2000-12-01');
|
||||
});
|
||||
|
||||
it('should return null for serialType "multiple"', async() => {
|
||||
const serialType = 'multiple';
|
||||
const result = await models.InvoiceOut.getInvoiceDate(companyFk, serialType, options);
|
||||
|
||||
expect(result.issued).toBeNull();
|
||||
});
|
||||
|
||||
it('should return correct date for serialType "quick"', async() => {
|
||||
const serialType = 'quick';
|
||||
const result = await models.InvoiceOut.getInvoiceDate(companyFk, serialType, options);
|
||||
|
||||
expect(moment(result.issued).format('YYYY-MM-DD')).toEqual('2001-01-01');
|
||||
});
|
||||
});
|
||||
|
|
@ -154,6 +154,9 @@
|
|||
},
|
||||
"photoMotivation": {
|
||||
"type": "string"
|
||||
},
|
||||
"isCustomInspectionRequired": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
@ -222,4 +225,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,8 @@ module.exports = Self => {
|
|||
su.name scannerUserName,
|
||||
es.scanned,
|
||||
est.description state,
|
||||
de.longName
|
||||
de.longName,
|
||||
de.itemFk
|
||||
FROM vn.expedition e
|
||||
LEFT JOIN vn.expeditionStateType est ON est.id = e.stateTypeFk
|
||||
INNER JOIN vn.item i1 ON i1.id = e.freightItemFk
|
||||
|
|
|
@ -77,6 +77,8 @@ describe('ticket makeInvoice()', () => {
|
|||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toEqual(`The address of the customer must have information about Incoterms and Customs Agent`);
|
||||
expect(error.message).toEqual(
|
||||
`The address of the customer must have information about Incoterms and Customs Agent`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -132,18 +132,18 @@ module.exports = Self => {
|
|||
CAST(SUM(b.weight * b.stickers) AS DECIMAL(10,0)) loadedKg,
|
||||
CAST(
|
||||
SUM(
|
||||
vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000
|
||||
) AS DECIMAL(10,0)
|
||||
) volumeKg,
|
||||
CAST(
|
||||
GREATEST(
|
||||
SUM(b.weight * b.stickers) ,
|
||||
SUM(vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
IF(pkg.volume,
|
||||
pkg.volume,
|
||||
SUM(vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
IF(pkg.volume,
|
||||
pkg.volume,
|
||||
pkg.width * pkg.depth * pkg.height) / 1000000)
|
||||
) / t.kg * 100 AS INT
|
||||
) percentageKg
|
||||
|
@ -185,11 +185,12 @@ module.exports = Self => {
|
|||
CAST(SUM(b.weight * b.stickers) AS DECIMAL(10,0)) as loadedkg,
|
||||
CAST(
|
||||
SUM(
|
||||
vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
vc.aerealVolumetricDensity *
|
||||
b.stickers *
|
||||
IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000
|
||||
) AS DECIMAL(10,0)
|
||||
) as volumeKg
|
||||
) as volumeKg,
|
||||
MAX(i.isCustomInspectionRequired) isCustomInspectionRequired
|
||||
FROM tmp.travel tr
|
||||
JOIN entry e ON e.travelFk = tr.id
|
||||
JOIN buy b ON b.entryFk = e.id
|
||||
|
|
|
@ -112,4 +112,17 @@ describe('Travel extraCommunityFilter()', () => {
|
|||
|
||||
expect(result.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should return field isCustomInspectionRequired true', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
id: 2
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result[0].entries[0].isCustomInspectionRequired).toBeTruthy();
|
||||
expect(result[0].entries[1].isCustomInspectionRequired).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "24.52.0",
|
||||
"version": "25.02.0",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
Loading…
Reference in New Issue