Merge pull request 'master' (!2716) from master into test
gitea/salix/pipeline/head This commit looks good Details
gitea/salix/pipeline/pr-dev This commit looks good Details

Reviewed-on: #2716
Reviewed-by: Carlos Andrés <carlosap@verdnatura.es>
This commit is contained in:
Pablo Natek 2024-07-15 11:40:29 +00:00
commit 2baff02443
22 changed files with 262 additions and 165 deletions

View File

@ -63,8 +63,7 @@ module.exports = Self => {
iss.isPicked
FROM ticketCollection tc
LEFT JOIN collection c ON c.id = tc.collectionFk
JOIN ticket t ON t.id = tc.ticketFk
JOIN sale s ON s.ticketFk = t.id
JOIN sale s ON s.ticketFk = tc.ticketFk
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
LEFT JOIN saleGroup sg ON sg.id = sgd.saleGroupFk
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
@ -103,9 +102,8 @@ module.exports = Self => {
FROM sectorCollection sc
JOIN sectorCollectionSaleGroup ss ON ss.sectorCollectionFk = sc.id
JOIN saleGroup sg ON sg.id = ss.saleGroupFk
JOIN ticket t ON t.id = sg.ticketFk
JOIN sale s ON s.ticketFk = t.id
LEFT JOIN saleGroupDetail sgd ON sgd.saleFk = s.id
LEFT JOIN saleGroupDetail sgd ON sgd.saleGroupFk = sg.id
JOIN sale s ON s.id = sgd.saleFk
LEFT JOIN parking p2 ON p2.id = sg.parkingFk
JOIN item i ON i.id = s.itemFk
JOIN itemShelvingSale iss ON iss.saleFk = s.id

View File

@ -2,7 +2,7 @@
<soap:Header>
<mrw:AuthInfo>
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
<mrw:CodigoDepartamento/>
<mrw:UserName><%= mrw.user %></mrw:UserName>
<mrw:Password><%= mrw.password %></mrw:Password>

View File

@ -27,9 +27,9 @@ module.exports = Self => {
const mrw = await models.MrwConfig.findOne();
const {externalId} = await models.Expedition.findById(expeditionFk);
const clientType = await models.MrwConfig.getClientType(expeditionFk);
const template = fs.readFileSync(__dirname + '/cancelShipment.ejs', 'utf-8');
const renderedXml = ejs.render(template, {mrw, externalId});
const renderedXml = ejs.render(template, {mrw, externalId, clientType});
const response = await axios.post(mrw.url, renderedXml, {
headers: {
'Content-Type': 'application/soap+xml; charset=utf-8'

View File

@ -3,7 +3,7 @@
<soap:Header>
<mrw:AuthInfo>
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
<mrw:CodigoAbonado><%= expeditionData.clientType %></mrw:CodigoAbonado>
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
<mrw:CodigoDepartamento/>
<mrw:UserName><%= mrw.user %></mrw:UserName>
<mrw:Password><%= mrw.password %></mrw:Password>

View File

@ -22,6 +22,7 @@ module.exports = Self => {
Self.createShipment = async expeditionFk => {
const models = Self.app.models;
const mrw = await Self.getConfig();
const clientType = await models.MrwConfig.getClientType(expeditionFk);
const today = Date.vnNew();
const [hours, minutes] = mrw?.expeditionDeadLine ? mrw.expeditionDeadLine.split(':').map(Number) : [0, 0];
@ -52,8 +53,7 @@ module.exports = Self => {
CONCAT( e.ticketFk, LPAD(e.counter, mc.counterWidth, '0')) reference,
LPAD(IF(mw.serviceType IS NULL, ms.serviceType, mw.serviceType), mc.serviceTypeWidth, '0') serviceType,
IF(mw.weekdays, 'S', 'N') weekDays,
oa.description deliveryObservation,
LPAD(ms.clientType, mc.clientTypeWidth, '0') clientType
oa.description deliveryObservation
FROM expedition e
JOIN ticket t ON e.ticketFk = t.id
JOIN agencyMode am ON am.id = t.agencyModeFk
@ -63,8 +63,7 @@ module.exports = Self => {
JOIN client c ON t.clientFk = c.id
JOIN address a ON t.addressFk = a.id
LEFT JOIN addressObservation oa ON oa.addressFk = a.id
LEFT JOIN observationType ot ON ot.id = oa.observationTypeFk
AND ot.code = 'delivery'
AND oa.observationTypeFk IN (SELECT id FROM observationType ot WHERE ot.code = 'delivery')
JOIN province p ON a.provinceFk = p.id
JOIN country co ON co.id = p.countryFk
JOIN mrwConfig mc
@ -73,22 +72,19 @@ module.exports = Self => {
const [expeditionData] = await Self.rawSql(query, [expeditionFk]);
if (!expeditionData)
throw new UserError(`This expedition is not a MRW shipment`);
if (expeditionData?.shipped.setHours(0, 0, 0, 0) < today.setHours(0, 0, 0, 0))
throw new UserError(`This ticket has a shipped date earlier than today`);
const shipmentResponse = await Self.sendXmlDoc(
__dirname + `/createShipment.ejs`,
{mrw, expeditionData},
{mrw, expeditionData, clientType},
'application/soap+xml'
);
const shipmentId = Self.getTextByTag(shipmentResponse, 'NumeroEnvio');
if (!shipmentId) throw new UserError(Self.getTextByTag(shipmentResponse, 'Mensaje'));
const file = await models.MrwConfig.getLabel(shipmentId);
const file = await models.MrwConfig.getLabel(shipmentId, clientType);
return {shipmentId, file};
};

View File

@ -2,7 +2,7 @@
<soapenv:Header>
<mrw:AuthInfo>
<mrw:CodigoFranquicia><%= mrw.franchiseCode %></mrw:CodigoFranquicia>
<mrw:CodigoAbonado><%= mrw.subscriberCode %></mrw:CodigoAbonado>
<mrw:CodigoAbonado><%= clientType %></mrw:CodigoAbonado>
<mrw:CodigoDepartamento/>
<mrw:UserName><%= mrw.user %></mrw:UserName>
<mrw:Password><%= mrw.password %></mrw:Password>

View File

@ -6,7 +6,13 @@ module.exports = Self => {
arg: 'shipmentId',
type: 'string',
required: true
}],
},
{
arg: 'clientType',
type: 'string',
required: true
},
],
returns: {
type: 'string',
root: true
@ -17,10 +23,14 @@ module.exports = Self => {
}
});
Self.getLabel = async shipmentId => {
Self.getLabel = async(shipmentId, clientType) => {
const mrw = await Self.getConfig();
const getLabelResponse = await Self.sendXmlDoc(__dirname + `/getLabel.ejs`, {mrw, shipmentId}, 'text/xml');
const getLabelResponse = await Self.sendXmlDoc(
__dirname + `/getLabel.ejs`,
{mrw, shipmentId, clientType},
'text/xml'
);
return Self.getTextByTag(getLabelResponse, 'EtiquetaFile');
};

View File

@ -40,15 +40,12 @@ describe('MRWConfig createShipment()', () => {
);
await models.MrwService.create(
{'agencyModeCodeFk': 'mrw', 'clientType': '000001', 'serviceType': 105, 'kg': 10}
);
await createMrwConfig();
await models.Application.rawSql(
`INSERT INTO vn.mrwService
SET agencyModeCodeFk = 'mrw',
clientType = 1,
serviceType = 1,
kg = 1`, null
);
await models.Ticket.create(ticket1);
await models.Expedition.create(expedition1);
});
@ -82,7 +79,8 @@ describe('MRWConfig createShipment()', () => {
'user': 'user',
'password': 'password',
'franchiseCode': 'franchiseCode',
'subscriberCode': 'subscriberCode'
'subscriberCode': 'subscriberCode',
'clientTypeWidth': 6
}
);
}
@ -115,10 +113,10 @@ describe('MRWConfig createShipment()', () => {
it('should fail if expeditionFk is not a MrwExpedition', async() => {
let error;
await models.MrwConfig.createShipment(undefined).catch(e => {
await models.MrwConfig.createShipment(15).catch(e => {
error = e;
}).finally(async() => {
expect(error.message).toEqual(`This expedition is not a MRW shipment`);
expect(error.message).toEqual(`ClientType not available`);
});
});

View File

@ -20,7 +20,7 @@ module.exports = Self => {
}
});
Self.renderer = async (expeditionFk) => {
Self.renderer = async expeditionFk => {
const models = Self.app.models;
const viaexpressConfig = await models.ViaexpressConfig.findOne({
@ -109,7 +109,7 @@ module.exports = Self => {
const ticket = expedition.ticket();
const sender = ticket.company().client();
const shipped = ticket.shipped.toISOString();
const isInterdia = (ticket.agencyModeFk === viaexpressConfig.agencyModeFk)
const isInterdia = (ticket.agencyModeFk === viaexpressConfig.agencyModeFk);
const data = {
viaexpressConfig,
sender,

View File

@ -192,5 +192,8 @@
},
"RouteConfig": {
"dataSource": "vn"
},
"MrwService": {
"dataSource": "vn"
}
}

View File

@ -31,5 +31,30 @@ module.exports = Self => {
});
return parser.parseFromString(data.data, 'text/xml');
};
Self.getClientType = async function(expeditionFk) {
if (!expeditionFk) throw new UserError(`No expeditionFk defined`);
const {clientTypeWidth} = await Self.getConfig();
const result = await Self.app.models.Expedition.findById(expeditionFk,
{include: [{
relation: 'ticket',
scope: {
include: {
relation: 'agencyMode',
scope: {
include: {
relation: 'mrwService',
}
}
}
}
}]}
);
const clientType = result?.ticket()?.agencyMode()?.mrwService()?.clientType;
if (!clientType || !clientTypeWidth) throw new UserError(`ClientType not available`);
return clientType.toString().padStart(clientTypeWidth, '0');
};
};

View File

@ -45,6 +45,9 @@
},
"notified":{
"type": "date"
},
"clientTypeWidth": {
"type": "number"
}
}
}

View File

@ -0,0 +1,33 @@
{
"name": "MrwService",
"base": "VnModel",
"options": {
"mysql": {
"table": "mrwService"
}
},
"properties": {
"agencyModeCodeFk": {
"id": true,
"type": "string",
"required": true
},
"clientType": {
"type": "number",
"required": true
},
"serviceType": {
"type": "number"
},
"kg": {
"type": "number"
}
},
"relations": {
"agency": {
"type": "hasOne",
"model": "AgencyMode",
"foreignKey": "code"
}
}
}

View File

@ -1,102 +1,114 @@
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySale`(
vSaleFk INT
)
proc: BEGIN
/**
* Reserva una línea de venta en la ubicación más óptima
*
* @param vSaleFk Id de sale
* @param vItemShelvingSaleFk Id de reserva
*/
DECLARE vLastPickingOrder INT;
DECLARE vDone INT DEFAULT FALSE;
DECLARE vItemShelvingFk INT;
DECLARE vAvailable INT;
DECLARE vReservedQuantity INT;
DECLARE vOutStanding INT;
DECLARE vUserFk INT;
DECLARE vItemShelvingAvailable CURSOR FOR
SELECT ish.id itemShelvingFk,
ish.available
FROM sale s
JOIN itemShelving ish ON ish.itemFk = s.itemFk
JOIN shelving sh ON sh.code = ish.shelvingFk
JOIN parking p ON p.id = sh.parkingFk
JOIN sector sc ON sc.id = p.sectorFk
JOIN productionConfig pc
WHERE s.id = vSaleFk
AND NOT sc.isHideForPickers
ORDER BY s.id,
p.pickingOrder >= vLastPickingOrder,
sh.priority DESC,
ish.available >= s.quantity DESC,
s.quantity MOD ish.grouping = 0 DESC,
ish.grouping DESC,
IF(pc.orderMode = 'Location', p.pickingOrder, ish.created);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
SELECT MAX(p.pickingOrder), s.quantity - SUM(IFNULL(iss.quantity, 0))
INTO vLastPickingOrder, vOutStanding
FROM sale s
LEFT JOIN itemShelvingSale iss ON iss.saleFk = s.id
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
LEFT JOIN shelving sh ON sh.code = ish.shelvingFk
LEFT JOIN parking p ON p.id = sh.parkingFk
WHERE s.id = vSaleFk;
IF vOutStanding <= 0 THEN
LEAVE proc;
END IF;
SELECT getUser() INTO vUserFk;
OPEN vItemShelvingAvailable;
l: LOOP
SET vDone = FALSE;
FETCH vItemShelvingAvailable INTO vItemShelvingFk, vAvailable;
IF vOutStanding <= 0 OR vDone THEN
LEAVE l;
END IF;
START TRANSACTION;
SELECT id INTO vItemShelvingFk
FROM itemShelving
WHERE id = vItemShelvingFk
FOR UPDATE;
SELECT LEAST(vOutStanding, vAvailable) INTO vReservedQuantity;
SET vOutStanding = vOutStanding - vReservedQuantity;
IF vReservedQuantity > 0 THEN
INSERT INTO itemShelvingSale(
itemShelvingFk,
saleFk,
quantity,
userFk)
SELECT vItemShelvingFk,
vSaleFk,
vReservedQuantity,
vUserFk;
UPDATE itemShelving
SET available = available - vReservedQuantity
WHERE id = vItemShelvingFk;
END IF;
COMMIT;
END LOOP;
CLOSE vItemShelvingAvailable;
END$$
DELIMITER $$
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemShelvingSale_addBySale`(
vSaleFk INT
)
proc: BEGIN
/**
* Reserva una línea de venta en la ubicación más óptima
*
* @param vSaleFk Id de sale
* @param vItemShelvingSaleFk Id de reserva
*/
DECLARE vLastPickingOrder INT;
DECLARE vDone INT DEFAULT FALSE;
DECLARE vItemShelvingFk INT;
DECLARE vAvailable INT;
DECLARE vReservedQuantity INT;
DECLARE vOutStanding INT;
DECLARE vUserFk INT;
DECLARE vTotalReservedQuantity INT;
DECLARE vSaleQuantity INT;
DECLARE vItemShelvingAvailable CURSOR FOR
SELECT ish.id itemShelvingFk,
ish.available
FROM sale s
JOIN itemShelving ish ON ish.itemFk = s.itemFk
JOIN shelving sh ON sh.code = ish.shelvingFk
JOIN parking p ON p.id = sh.parkingFk
JOIN sector sc ON sc.id = p.sectorFk
JOIN productionConfig pc
WHERE s.id = vSaleFk
AND NOT sc.isHideForPickers
ORDER BY s.id,
p.pickingOrder >= vLastPickingOrder,
sh.priority DESC,
ish.available >= s.quantity DESC,
s.quantity MOD ish.grouping = 0 DESC,
ish.grouping DESC,
IF(pc.orderMode = 'Location', p.pickingOrder, ish.created);
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
RESIGNAL;
END;
SELECT MAX(p.pickingOrder), s.quantity - SUM(IFNULL(iss.quantity, 0)), s.quantity
INTO vLastPickingOrder, vOutStanding, vSaleQuantity
FROM sale s
LEFT JOIN itemShelvingSale iss ON iss.saleFk = s.id
LEFT JOIN itemShelving ish ON ish.id = iss.itemShelvingFk
LEFT JOIN shelving sh ON sh.code = ish.shelvingFk
LEFT JOIN parking p ON p.id = sh.parkingFk
WHERE s.id = vSaleFk;
IF vOutStanding <= 0 THEN
LEAVE proc;
END IF;
SELECT getUser() INTO vUserFk;
OPEN vItemShelvingAvailable;
l: LOOP
SET vDone = FALSE;
FETCH vItemShelvingAvailable INTO vItemShelvingFk, vAvailable;
IF vOutStanding <= 0 OR vDone THEN
SELECT SUM(IFNULL(quantity, 0))
INTO vTotalReservedQuantity
FROM itemShelvingSale
WHERE saleFk = vSaleFk;
IF vTotalReservedQuantity <> vSaleQuantity THEN
UPDATE sale
SET quantity = vTotalReservedQuantity
WHERE id = vSaleFk;
END IF;
LEAVE l;
END IF;
START TRANSACTION;
SELECT id INTO vItemShelvingFk
FROM itemShelving
WHERE id = vItemShelvingFk
FOR UPDATE;
SELECT LEAST(vOutStanding, vAvailable) INTO vReservedQuantity;
SET vOutStanding = vOutStanding - vReservedQuantity;
IF vReservedQuantity > 0 THEN
INSERT INTO itemShelvingSale(
itemShelvingFk,
saleFk,
quantity,
userFk)
SELECT vItemShelvingFk,
vSaleFk,
vReservedQuantity,
vUserFk;
UPDATE itemShelving
SET available = available - vReservedQuantity
WHERE id = vItemShelvingFk;
END IF;
COMMIT;
END LOOP;
CLOSE vItemShelvingAvailable;
END$$
DELIMITER ;

View File

@ -21,6 +21,7 @@ BEGIN
DECLARE vRemainingQuantity INT;
DECLARE vItemFk INT;
DECLARE vTotalQuantity INT;
DECLARE vStateCode VARCHAR(45);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
@ -32,10 +33,19 @@ BEGIN
CALL util.throw('Reservation completed');
END IF;
SELECT s.itemFk, iss.saleFk, iss.itemShelvingFk, SUM(IFNULL(iss.quantity,0))
INTO vItemFk, vSaleFk, vItemShelvingFk, vReservedQuantity
SELECT s.itemFk,
iss.saleFk,
iss.itemShelvingFk,
SUM(IFNULL(iss.quantity,0)),
IF(sgd.id, 'PREVIOUS_PREPARATION', 'PREPARED')
INTO vItemFk,
vSaleFk,
vItemShelvingFk,
vReservedQuantity,
vStateCode
FROM itemShelvingSale iss
JOIN sale s ON s.id = iss.saleFk
LEFT JOIN vn.saleGroupDetail sgd ON sgd.saleFk = iss.saleFk
WHERE iss.id = vItemShelvingSaleFk
AND NOT iss.isPicked;
@ -74,7 +84,7 @@ BEGIN
vTotalQuantity,
`account`.`myUser_getId`(),
NULL,
'PREPARED',
vStateCode,
TRUE);
UPDATE sale s

View File

@ -19,21 +19,20 @@ BEGIN
CREATE OR REPLACE TEMPORARY TABLE tmp.sale
(saleFk INT PRIMARY KEY)
SELECT
s.ticketFk,
s.id saleFk,
s.itemFk,
s.concept,
s.quantity,
MAKETIME(pb.HH,pb.mm,0) etd,
pb.routeFk,
FLOOR(s.quantity / IF(i.isBoxPickingMode, ish.packing, i.packingOut)) stickers,
IF(i.isBoxPickingMode, ish.packing, i.packingOut) packing,
b.packagingFk
SELECT s.ticketFk,
s.id saleFk,
s.itemFk,
s.concept,
s.quantity,
MAKETIME(pb.HH,pb.mm,0) etd,
pb.routeFk,
FLOOR(s.quantity / IF(i.isBoxPickingMode, ish.packing, i.packingOut)) stickers,
IF(i.isBoxPickingMode, ish.packing, i.packingOut) packing,
IF(pa.isPackageReturnable, pc.defaultBigPackageFk, b.packagingFk) packagingFk
FROM sale s
JOIN item i ON i.id = s.itemFk
JOIN itemShelving ish ON ish.itemFk = s.itemFk
LEFT JOIN ( SELECT iss.itemShelvingFk,
LEFT JOIN ( SELECT iss.itemShelvingFk,
s.itemFk,
SUM(iss.quantity) reserve
FROM itemShelvingSale iss
@ -52,6 +51,8 @@ BEGIN
LEFT JOIN ticketState ts ON ts.ticketFk = s.ticketFk
LEFT JOIN cache.last_buy lb ON lb.item_id = i.id AND lb.warehouse_id = vWarehouseFk
LEFT JOIN buy b ON b.id = lb.buy_id
LEFT JOIN packaging pa ON pa.id = b.packagingFk
JOIN packagingConfig pc
WHERE IF(i.isBoxPickingMode, ish.packing, i.packingOut)
<= LEAST(s.quantity, ish.visible - IFNULL(tISS.reserve,0))
AND NOT pb.problem

View File

@ -44,14 +44,14 @@ BEGIN
t.shipped,
IFNULL(a.hasDailyInvoice, co.hasDailyInvoice),
w.isManaged,
c.hasToInvoice
c.hasToInvoice
INTO vClientFk,
vIsTaxDataChecked,
vCompanyFk,
vShipped,
vHasDailyInvoice,
vWithPackage,
vHasToInvoice
vHasToInvoice
FROM ticket t
JOIN `client` c ON c.id = t.clientFk
JOIN province p ON p.id = c.provinceFk
@ -64,8 +64,12 @@ BEGIN
(SELECT vCurTicketFk, p.id, COUNT(*)
FROM expedition e
JOIN packaging p ON p.id = e.packagingFk
JOIN ticket t ON t.id = e.ticketFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
WHERE e.ticketFk = vCurTicketFk AND p.isPackageReturnable
AND vWithPackage
AND NOT dm.`code`= 'PICKUP'
GROUP BY p.itemFk);
-- No retornables o no catalogados

View File

@ -53,7 +53,7 @@
<vn-autocomplete vn-one
ng-model="$ctrl.location.countryFk"
url="Countries"
show-field="country"
show-field="name"
value-field="id"
label="Country">
</vn-autocomplete>

View File

@ -35,10 +35,10 @@
</vn-one>
<vn-one>
<vn-label-value label="Starting time"
value="{{$ctrl.summary.route.time | date: 'HH:MM'}}">
value="{{$ctrl.summary.route.started | date: 'HH:mm'}}">
</vn-label-value>
<vn-label-value label="Finishing time"
value="{{$ctrl.summary.route.finished | date: 'HH:MM'}}">
value="{{$ctrl.summary.route.finished | date: 'HH:mm'}}">
</vn-label-value>
<vn-label-value label="Km Start"
value="{{$ctrl.summary.route.kmStart}}">

View File

@ -171,8 +171,8 @@ module.exports = Self => {
const address = await models.Address.create({
clientFk: user.id,
street: street,
city: city,
provinceFk: provinceFk,
city,
provinceFk,
postalCode: postcode,
mobile: phone,
nickname: nickname,
@ -193,7 +193,9 @@ module.exports = Self => {
}
await user.updateAttribute('email', email, myOptions);
const {countryFk} = await Self.app.models.Province.findById(provinceFk, {
fields: ['countryFk']
});
await models.Worker.create({
id: user.id,
firstName,
@ -202,6 +204,7 @@ module.exports = Self => {
bossFk,
fi,
birth,
originCountryFk: countryFk
}, myOptions);
@ -212,11 +215,8 @@ module.exports = Self => {
const message = e.sqlMessage;
if (e.message && e.message.includes(`Email already exists`)) throw new UserError(`This personal mail already exists`);
if (code === 'ER_DUP_ENTRY' && message.includes(`CodigoTrabajador_UNIQUE`)) throw new UserError(`This worker code already exists`);
if (code === 'ER_DUP_ENTRY' && message.includes(`PRIMARY`)) throw new UserError(`This worker already exists`);
throw e;
}

View File

@ -27,11 +27,10 @@ module.exports = Self => {
});
async function tinIsValid(err, done) {
const filter = {
const country = await Self.app.models.Country.findOne({
fields: ['code'],
where: {id: this.countryFk}
};
const country = await Self.app.models.Country.findOne(filter);
where: {id: this.originCountryFk}
});
const code = country ? country.code.toLowerCase() : null;
if (!this.fi || !validateTin(this.fi, code))

View File

@ -60,6 +60,11 @@
"type": "hasMany",
"model": "Zone",
"foreignKey": "agencyModeFk"
},
"mrwService": {
"type": "belongsTo",
"model": "MrwService",
"foreignKey": "code"
}
},
"acls": [