Merge branch 'dev' into 6964_itemOlder
gitea/salix/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Sergio De la torre 2024-04-04 13:45:20 +00:00
commit 2ed5237568
43 changed files with 158 additions and 105 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ print.*.json
db.json db.json
junit.xml junit.xml
.DS_Store .DS_Store
storage

View File

@ -30,7 +30,7 @@ module.exports = Self => {
path: `/:id/downloadFile`, path: `/:id/downloadFile`,
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.downloadFile = async function(ctx, id) { Self.downloadFile = async function(ctx, id) {

View File

@ -43,7 +43,7 @@ module.exports = Self => {
path: `/:id/download`, path: `/:id/download`,
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.download = async function(id, fileCabinet, filter) { Self.download = async function(id, fileCabinet, filter) {

View File

@ -48,7 +48,7 @@ module.exports = Self => {
path: `/:collection/:size/:id/download`, path: `/:collection/:size/:id/download`,
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.download = async function(ctx, collection, size, id) { Self.download = async function(ctx, collection, size, id) {

View File

@ -7,9 +7,8 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` EVENT `vn`.`clientsDisable`
DO BEGIN DO BEGIN
UPDATE account.user u UPDATE account.user u
JOIN client c ON c.id = u.id JOIN client c ON c.id = u.id
JOIN clientType ct ON ct.id = c.typeFk
SET u.active = FALSE SET u.active = FALSE
WHERE ct.code = 'normal' WHERE c.typeFk = 'normal'
AND u.id NOT IN ( AND u.id NOT IN (
SELECT DISTINCT c.id SELECT DISTINCT c.id
FROM client c FROM client c

View File

@ -15,6 +15,13 @@ proc:BEGIN
DECLARE vHasTooMuchCollections BOOL; DECLARE vHasTooMuchCollections BOOL;
DECLARE vLockTime INT DEFAULT 15; DECLARE vLockTime INT DEFAULT 15;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
DO RELEASE_LOCK('collection_assign');
RESIGNAL;
END;
-- Si hay colecciones sin terminar, sale del proceso -- Si hay colecciones sin terminar, sale del proceso
CALL collection_get(vUserFk); CALL collection_get(vUserFk);

View File

@ -219,9 +219,11 @@ proc:BEGIN
UPDATE tmp.productionBuffer pb UPDATE tmp.productionBuffer pb
JOIN ( JOIN (
SELECT SUM(litros) liters, SELECT SUM(litros) liters,
@lines:= COUNT(*) + @lines `lines`, @lines:= COUNT(*) + @lines,
COUNT(*) `lines`,
MAX(i.`size`) height, MAX(i.`size`) height,
@volume := SUM(sv.volume) + @volume volume @volume := SUM(sv.volume) + @volume,
SUM(sv.volume) volume
FROM saleVolume sv FROM saleVolume sv
JOIN sale s ON s.id = sv.saleFk JOIN sale s ON s.id = sv.saleFk
JOIN item i ON i.id = s.itemFk JOIN item i ON i.id = s.itemFk

View File

@ -33,6 +33,7 @@ BEGIN
ii.operated = IFNULL(ii.operated,d.operated), ii.operated = IFNULL(ii.operated,d.operated),
ii.issued = IFNULL(ii.issued,d.issued), ii.issued = IFNULL(ii.issued,d.issued),
ii.bookEntried = IFNULL(ii.bookEntried,d.bookEntried), ii.bookEntried = IFNULL(ii.bookEntried,d.bookEntried),
e.isBooked = TRUE,
e.isConfirmed = TRUE e.isConfirmed = TRUE
WHERE d.id = vDuaFk; WHERE d.id = vDuaFk;

View File

@ -60,7 +60,11 @@ BEGIN
(i.value8 <=> its.value8) match8, (i.value8 <=> its.value8) match8,
a.available, a.available,
IFNULL(ip.counter, 0) `counter`, IFNULL(ip.counter, 0) `counter`,
IF(b.groupingMode = 1, b.grouping, b.packing) minQuantity, CASE
WHEN b.groupingMode = 1 THEN b.grouping
WHEN b.groupingMode = 2 THEN b.packing
ELSE 1
END AS minQuantity,
iss.visible located iss.visible located
FROM vn.item i FROM vn.item i
JOIN cache.available a ON a.item_id = i.id JOIN cache.available a ON a.item_id = i.id

View File

@ -1,12 +1,12 @@
DELIMITER $$ DELIMITER $$
$$ $$
CREATE OR REPLACE PROCEDURE vn.sale_boxPickingPrint( CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE vn.sale_boxPickingPrint(
IN vPrinterFk INT, IN vPrinterFk INT,
IN vSaleFk INT, IN vSaleFk INT,
IN vPacking INT, IN vPacking INT,
IN vSectorFk INT, IN vSectorFk INT,
IN vUserFk INT, IN vUserFk INT,
IN vPackagingFk INT, IN vPackagingFk VARCHAR(10),
IN vPackingSiteFk INT) IN vPackingSiteFk INT)
BEGIN BEGIN
/** Splits a line of sale to a different ticket and prints the transport sticker /** Splits a line of sale to a different ticket and prints the transport sticker
@ -61,6 +61,8 @@ BEGIN
w1: WHILE vQuantity >= vPacking DO w1: WHILE vQuantity >= vPacking DO
SET vQuantity = vQuantity - vPacking;
SET vItemShelvingFk = NULL; SET vItemShelvingFk = NULL;
SELECT sub.id SELECT sub.id
@ -209,6 +211,7 @@ w1: WHILE vQuantity >= vPacking DO
UPDATE itemShelvingSale UPDATE itemShelvingSale
SET saleFk = vNewSaleFk SET saleFk = vNewSaleFk
WHERE id = vItemShelvingSaleFk; WHERE id = vItemShelvingSaleFk;
END IF; END IF;
INSERT IGNORE INTO saleTracking(saleFk, isChecked, workerFk, stateFk) INSERT IGNORE INTO saleTracking(saleFk, isChecked, workerFk, stateFk)
@ -235,7 +238,7 @@ w1: WHILE vQuantity >= vPacking DO
) )
SELECT vAgencyModeFk, SELECT vAgencyModeFk,
vNewTicketFk, vNewTicketFk,
i.id, pc.defaultFreightItemFk,
vUserFk, vUserFk,
vPackagingFk, vPackagingFk,
ps.code, ps.code,
@ -246,9 +249,8 @@ w1: WHILE vQuantity >= vPacking DO
NOW() NOW()
FROM packingSite ps FROM packingSite ps
JOIN host h ON h.id = ps.hostFk JOIN host h ON h.id = ps.hostFk
JOIN item i ON i.name = 'Shipping cost' JOIN productionConfig pc
WHERE ps.id = vPackingSiteFk WHERE ps.id = vPackingSiteFk;
LIMIT 1;
SET vExpeditionFk = LAST_INSERT_ID(); SET vExpeditionFk = LAST_INSERT_ID();
@ -277,6 +279,7 @@ w1: WHILE vQuantity >= vPacking DO
DELETE FROM sale DELETE FROM sale
WHERE quantity = 0 WHERE quantity = 0
AND id = vSaleFk; AND id = vSaleFk;
END WHILE; END WHILE;
END$$ END$$

View File

@ -0,0 +1,2 @@
-- Place your SQL code here
ALTER TABLE vn.productionConfig ADD defaultFreightItemFk INT UNSIGNED DEFAULT 71 NOT NULL COMMENT 'Default value for expedition table';

View File

@ -0,0 +1 @@
CREATE INDEX expeditionLog_action_IDX USING BTREE ON srt.expeditionLog (`action`);

View File

@ -0,0 +1 @@
CREATE INDEX expeditionLog_expeditionFk_IDX USING BTREE ON srt.expeditionLog (expeditionFk);

View File

@ -59,7 +59,8 @@ export default class Token {
getStorage(storage) { getStorage(storage) {
this.token = storage.getItem('vnToken'); this.token = storage.getItem('vnToken');
this.tokenMultimedia = storage.getItem('vnTokenMultimedia'); // Cambio realizado temporalmente
this.tokenMultimedia = this.token; // storage.getItem('vnTokenMultimedia');
if (!this.token) return; if (!this.token) return;
const created = storage.getItem('vnTokenCreated'); const created = storage.getItem('vnTokenCreated');
this.created = created && new Date(created); this.created = created && new Date(created);

View File

@ -117,6 +117,21 @@
"video/mp4" "video/mp4"
] ]
}, },
"supplierStorage": {
"name": "supplierStorage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./storage/dms",
"maxFileSize": "31457280",
"allowedContentTypes": [
"image/png",
"image/jpeg",
"image/jpg",
"image/webp",
"video/mp4",
"application/pdf"
]
},
"accessStorage": { "accessStorage": {
"name": "accessStorage", "name": "accessStorage",
"connector": "loopback-component-storage", "connector": "loopback-component-storage",

View File

@ -35,7 +35,7 @@ module.exports = Self => {
path: '/:id/claim-pickup-pdf', path: '/:id/claim-pickup-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.claimPickupPdf = (ctx, id) => Self.printReport(ctx, id, 'claim-pickup-order'); Self.claimPickupPdf = (ctx, id) => Self.printReport(ctx, id, 'claim-pickup-order');

View File

@ -33,7 +33,7 @@ module.exports = Self => {
path: `/:id/downloadFile`, path: `/:id/downloadFile`,
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.downloadFile = async function(ctx, id) { Self.downloadFile = async function(ctx, id) {

View File

@ -96,9 +96,9 @@ module.exports = Self => {
// When claimState has been changed // When claimState has been changed
if (args.claimStateFk) { if (args.claimStateFk) {
const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions); const newState = await models.ClaimState.findById(args.claimStateFk, null, myOptions);
await notifyStateChange(ctx, salesPerson.id, claim, newState.code); await notifyStateChange(ctx, salesPerson.id, claim, newState.description);
if (newState.code == 'canceled') if (newState.code == 'canceled')
await notifyStateChange(ctx, claim.workerFk, claim, newState.code); await notifyStateChange(ctx, claim.workerFk, claim, newState.description);
} }
if (tx) await tx.commit(); if (tx) await tx.commit();

View File

@ -46,7 +46,7 @@ module.exports = Self => {
path: '/:id/campaign-metrics-pdf', path: '/:id/campaign-metrics-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.campaignMetricsPdf = (ctx, id) => Self.printReport(ctx, id, 'campaign-metrics'); Self.campaignMetricsPdf = (ctx, id) => Self.printReport(ctx, id, 'campaign-metrics');

View File

@ -34,7 +34,7 @@ module.exports = Self => {
path: '/:id/entry-order-pdf', path: '/:id/entry-order-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.entryOrderPdf = (ctx, id) => Self.printReport(ctx, id, 'entry-order'); Self.entryOrderPdf = (ctx, id) => Self.printReport(ctx, id, 'entry-order');

View File

@ -32,7 +32,7 @@ module.exports = Self => {
path: '/:id/download', path: '/:id/download',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.download = async function(ctx, id, options) { Self.download = async function(ctx, id, options) {

View File

@ -32,7 +32,7 @@ module.exports = Self => {
path: '/downloadZip', path: '/downloadZip',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.downloadZip = async function(ctx, ids, options) { Self.downloadZip = async function(ctx, ids, options) {

View File

@ -35,7 +35,7 @@ module.exports = Self => {
path: '/:reference/exportation-pdf', path: '/:reference/exportation-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.exportationPdf = (ctx, reference) => Self.printReport(ctx, reference, 'exportation'); Self.exportationPdf = (ctx, reference) => Self.printReport(ctx, reference, 'exportation');

View File

@ -38,7 +38,7 @@ module.exports = Self => {
path: '/:reference/invoice-csv', path: '/:reference/invoice-csv',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.invoiceCsv = async reference => { Self.invoiceCsv = async reference => {

View File

@ -40,7 +40,7 @@ module.exports = Self => {
path: '/negativeBasesCsv', path: '/negativeBasesCsv',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.negativeBasesCsv = async(ctx, options) => { Self.negativeBasesCsv = async(ctx, options) => {

View File

@ -11,7 +11,7 @@ module.exports = Self => {
path: `/download`, path: `/download`,
verb: 'POST', verb: 'POST',
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.download = async() => { Self.download = async() => {

View File

@ -30,7 +30,7 @@ module.exports = Self => {
path: '/downloadCmrsZip', path: '/downloadCmrsZip',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.downloadCmrsZip = async function(ctx, ids, options) { Self.downloadCmrsZip = async function(ctx, ids, options) {

View File

@ -30,7 +30,7 @@ module.exports = Self => {
path: '/downloadZip', path: '/downloadZip',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.downloadZip = async function(ctx, id, options) { Self.downloadZip = async function(ctx, id, options) {

View File

@ -35,7 +35,7 @@ module.exports = Self => {
path: '/:id/driver-route-pdf', path: '/:id/driver-route-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });

View File

@ -45,7 +45,7 @@ module.exports = Self => {
path: '/:id/campaign-metrics-pdf', path: '/:id/campaign-metrics-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] // accessScopes: ['read:multimedia']
}); });
Self.campaignMetricsPdf = (ctx, id) => Self.printReport(ctx, id, 'supplier-campaign-metrics'); Self.campaignMetricsPdf = (ctx, id) => Self.printReport(ctx, id, 'supplier-campaign-metrics');

View File

@ -8,6 +8,9 @@
"SupplierDms": { "SupplierDms": {
"dataSource": "vn" "dataSource": "vn"
}, },
"SupplierContainer": {
"dataSource": "supplierStorage"
},
"SupplierAddress": { "SupplierAddress": {
"dataSource": "vn" "dataSource": "vn"
}, },

View File

@ -35,6 +35,6 @@ module.exports = Self => {
WHERE tc.ticketFk = ? AND s.order < s2.id WHERE tc.ticketFk = ? AND s.order < s2.id
LIMIT 1;`, LIMIT 1;`,
[ticketFk], myOptions); [ticketFk], myOptions);
return result.length > 0 && result[0]['ticketFk'] > 0; return result[0]?.ticketFk > 0 && result[0].ticketFk;
}; };
}; };

View File

@ -27,7 +27,7 @@ describe('ticketCollection hasUncheckedTicket()', () => {
}, myOptions); }, myOptions);
const result = await models.TicketCollection.hasUncheckedTicket(ticketFk, myOptions); const result = await models.TicketCollection.hasUncheckedTicket(ticketFk, myOptions);
expect(result).toBe(true); expect(result).toBeTruthy();
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();

View File

@ -147,6 +147,10 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
); );
} }
} catch (error) { } catch (error) {
await Self.rawSql(`
INSERT INTO util.debug (variable, value)
VALUES ('invoicingTicketError', ?)
`, [ticket.id + ' - ' + error]);
// Domain not found // Domain not found
if (error.responseCode == 450) return invalidEmail(ticket); if (error.responseCode == 450) return invalidEmail(ticket);

View File

@ -38,7 +38,7 @@ module.exports = Self => {
path: '/:id/delivery-note-csv', path: '/:id/delivery-note-csv',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.deliveryNoteCsv = async id => { Self.deliveryNoteCsv = async id => {

View File

@ -42,7 +42,7 @@ module.exports = Self => {
path: '/:id/delivery-note-pdf', path: '/:id/delivery-note-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.deliveryNotePdf = (ctx, id) => Self.printReport(ctx, id, 'delivery-note'); Self.deliveryNotePdf = (ctx, id) => Self.printReport(ctx, id, 'delivery-note');

View File

@ -79,7 +79,7 @@ module.exports = Self => {
path: '/extra-community-pdf', path: '/extra-community-pdf',
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.extraCommunityPdf = ctx => Self.printReport(ctx, null, 'extra-community'); Self.extraCommunityPdf = ctx => Self.printReport(ctx, null, 'extra-community');

View File

@ -30,7 +30,7 @@ module.exports = Self => {
path: `/:id/downloadFile`, path: `/:id/downloadFile`,
verb: 'GET' verb: 'GET'
}, },
accessScopes: ['read:multimedia'] //accessScopes: ['read:multimedia']
}); });
Self.downloadFile = async function(ctx, id) { Self.downloadFile = async function(ctx, id) {

View File

@ -18,7 +18,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="zone in zoneCollisions"> <tr v-for="zone in zones" v-bind:key="zone.zoneFk">
<td>{{ zone.zn.name }}</td> <td>{{ zone.zn.name }}</td>
<td>{{ zone.zoneFk }}</td> <td>{{ zone.zoneFk }}</td>
<td>{{ zone.z.price }}</td> <td>{{ zone.z.price }}</td>

View File

@ -8,5 +8,10 @@ module.exports = {
}, },
props: { props: {
zoneCollisions: {type: Array, required: true} zoneCollisions: {type: Array, required: true}
},
computed: {
zones() {
return JSON.parse(this.zoneCollisions);
}
} }
}; };

View File

@ -1,3 +1,9 @@
td{
overflow: hidden;
max-width: 100px;
text-overflow: ellipsis;
}
h1 { h1 {
text-align: center; text-align: center;
} }

View File

@ -1,19 +1,18 @@
SELECT SELECT r.id,
r.id, r.m3,
r.m3, r.created,
r.created, r.time,
r.time, u.nickName userNickName,
u.nickName userNickName, v.tradeMark vehicleTradeMark,
v.tradeMark vehicleTradeMark, v.model vehicleModel,
v.model vehicleModel, v.numberPlate plateNumber,
v.numberPlate plateNumber, IFNULL(s.name, am.name) agencyName
IFNULL(s.name, am.name) AS agencyName FROM route r
FROM route r LEFT JOIN vehicle v ON v.id = r.vehicleFk
LEFT JOIN vehicle v ON v.id = r.vehicleFk LEFT JOIN worker w ON w.id = r.workerFk
LEFT JOIN worker w ON w.id = r.workerFk LEFT JOIN account.user u ON u.id = w.id
LEFT JOIN account.user u ON u.id = w.id LEFT JOIN agencyMode am ON am.id = r.agencyModeFk
LEFT JOIN agencyMode am ON am.id = r.agencyModeFk LEFT JOIN agency a ON a.id = am.agencyFk
LEFT JOIN agency a ON a.id = am.agencyFk LEFT JOIN supplierAgencyTerm sa ON sa.agencyFk = a.id
LEFT JOIN supplierAgencyTerm sa ON sa.agencyFk = a.id LEFT JOIN supplier s ON s.id = sa.supplierFk
LEFT JOIN supplier s ON s.id = sa.supplierFk WHERE r.id IN(?)
WHERE r.id IN(?)

View File

@ -1,43 +1,42 @@
SELECT SELECT t.nickname addressName,
t.nickname addressName, t.packages,
t.packages, t.priority,
t.priority, t.id,
t.id, t.clientFk,
t.clientFk, t.companyFk,
t.companyFk, t.routeFk,
t.routeFk, if(a.phone, a.phone, c.phone) phone,
if(a.phone, a.phone, c.phone) AS phone, if(a.mobile, a.mobile, c.mobile) mobile,
if(a.mobile, a.mobile, c.mobile) AS mobile, wh.name warehouseName,
wh.name warehouseName, a.city,
a.city, a.street,
a.street, a.postalCode,
a.postalCode, LPAD(a.id, 5, '0') addressFk,
LPAD(a.id, 5, '0') AS addressFk, p.name province,
p.name province, 0 import,
0 AS import, am.name ticketAgency,
am.name ticketAgency, tob.description,
tob.description, u.nickName salesPersonName,
u.nickName salesPersonName, ipkg.itemPackingTypes
ipkg.itemPackingTypes FROM route r
FROM route r JOIN ticket t ON t.routeFk = r.id
JOIN ticket t ON t.routeFk = r.id LEFT JOIN address a ON a.id = t.addressFk
LEFT JOIN address a ON a.id = t.addressFk LEFT JOIN client c ON c.id = t.clientFk
LEFT JOIN client c ON c.id = t.clientFk LEFT JOIN worker w ON w.id = client_getSalesPerson(t.clientFk, CURDATE())
LEFT JOIN worker w ON w.id = client_getSalesPerson(t.clientFk, CURDATE()) LEFT JOIN account.user u ON u.id = w.id
LEFT JOIN account.user u ON u.id = w.id LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id AND tob.observationTypeFk = 3
LEFT JOIN ticketObservation tob ON tob.ticketFk = t.id AND tob.observationTypeFk = 3 LEFT JOIN province p ON a.provinceFk = p.id
LEFT JOIN province p ON a.provinceFk = p.id LEFT JOIN warehouse wh ON wh.id = t.warehouseFk
LEFT JOIN warehouse wh ON wh.id = t.warehouseFk LEFT JOIN agencyMode am ON am.id = t.agencyModeFk
LEFT JOIN agencyMode am ON am.id = t.agencyModeFk LEFT JOIN (
LEFT JOIN ( SELECT t.id AS ticketFk,
SELECT t.id AS ticketFk, GROUP_CONCAT(DISTINCT(i.itemPackingTypeFk)) AS itemPackingTypes
GROUP_CONCAT(DISTINCT(i.itemPackingTypeFk)) AS itemPackingTypes FROM route r
FROM route r JOIN ticket t ON t.routeFk = r.id
JOIN ticket t ON t.routeFk = r.id JOIN sale s ON s.ticketFk = t.id
JOIN sale s ON s.ticketFk = t.id JOIN item i ON i.id = s.itemFk
JOIN item i ON i.id = s.itemFk WHERE r.id IN (?)
WHERE r.id IN (?) GROUP BY t.id
GROUP BY t.id ) ipkg ON ipkg.ticketFk = t.id
) ipkg ON ipkg.ticketFk = t.id WHERE r.id IN (?)
WHERE r.id IN (?) ORDER BY t.priority, t.id;
ORDER BY t.priority, t.id;