7648_myEntries #2744

Merged
jsegarra merged 7 commits from 7648_myEntries into master 2024-07-19 10:27:40 +00:00
13 changed files with 251 additions and 63 deletions

View File

@ -314,5 +314,4 @@ INSERT INTO mysql.roles_mapping (`User`, `Host`, `Role`, `Admin_option`)
SELECT SUBSTR(`User`, @prefixLen + 1), `Host`, `Role`, `Admin_option` SELECT SUBSTR(`User`, @prefixLen + 1), `Host`, `Role`, `Admin_option`
FROM mysql.roles_mapping FROM mysql.roles_mapping
WHERE `User` LIKE @prefixedLike AND `Host` = @genRoleHost; WHERE `User` LIKE @prefixedLike AND `Host` = @genRoleHost;
FLUSH PRIVILEGES; FLUSH PRIVILEGES;

View File

@ -118,7 +118,7 @@ INSERT INTO `hedera`.`tpvConfig`(`id`, `currency`, `terminal`, `transactionType`
INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`, `image`) INSERT INTO `account`.`user`(`id`,`name`,`nickname`, `password`,`role`,`active`,`email`,`lang`, `image`)
VALUES VALUES
(1101, 'brucewayne', 'Bruce Wayne', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'BruceWayne@mydomain.com', 'es','1101'), (1101, 'brucewayne', 'Bruce Wayne', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'BruceWayne@mydomain.com', 'es','1101'),
(1102, 'petterparker', 'Petter Parker', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'PetterParker@mydomain.com', 'en','1102'), (1102, 'petterparker', 'Petter Parker', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 131, 1, 'PetterParker@mydomain.com', 'en','1102'),
(1103, 'clarkkent', 'Clark Kent', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'ClarkKent@mydomain.com', 'fr','1103'), (1103, 'clarkkent', 'Clark Kent', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'ClarkKent@mydomain.com', 'fr','1103'),
(1104, 'tonystark', 'Tony Stark', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'TonyStark@mydomain.com', 'es','1104'), (1104, 'tonystark', 'Tony Stark', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'TonyStark@mydomain.com', 'es','1104'),
(1105, 'maxeisenhardt', 'Max Eisenhardt', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt','1105'), (1105, 'maxeisenhardt', 'Max Eisenhardt', '$2b$10$UzQHth.9UUQ1T5aiQJ21lOU0oVlbxoqH4PFM9V8T90KNSAcg0eEL2', 2, 1, 'MaxEisenhardt@mydomain.com', 'pt','1105'),
@ -1477,7 +1477,8 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
(5, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1, 5), (5, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1, 5),
(6, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2, 6), (6, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2, 6),
(7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1, 7), (7, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1, 7),
(8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2, 10); (8, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2, 10),
(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);
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `isRaid`, `evaNotes`) INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `invoiceNumber`, `reference`, `isExcludedFromAvailable`, `isRaid`, `evaNotes`)
VALUES VALUES
@ -1488,7 +1489,9 @@ INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed
(5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'IN2005', 'Movement 5', 0, 0, 'observation five'), (5, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 5, 0, 442, 'IN2005', 'Movement 5', 0, 0, 'observation five'),
(6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'IN2006', 'Movement 6', 0, 0, 'observation six'), (6, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 6, 0, 442, 'IN2006', 'Movement 6', 0, 0, 'observation six'),
(7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2007', 'Movement 7', 0, 0, 'observation seven'), (7, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2007', 'Movement 7', 0, 0, 'observation seven'),
(8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2008', 'Movement 8', 1, 1, ''); (8, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 7, 0, 442, 'IN2008', 'Movement 8', 1, 1, ''),
(9, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, ''),
(10, 2, DATE_ADD(util.VN_CURDATE(), INTERVAL +2 DAY), 10, 0, 442, 'IN2009', 'Movement 9', 1, 1, '');
INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`) INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `itemFk`, `itemTypeFk`, `saleTotal`, `saleWaste`, `rate`)
VALUES VALUES

View File

@ -0,0 +1,15 @@
INSERT IGNORE INTO salix.ACL (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
VALUES ('Entry','filter','READ','ALLOW','ROLE','supplier');
INSERT IGNORE INTO salix.ACL (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
VALUES ('Entry','getBuys','READ','ALLOW','ROLE','supplier');
INSERT IGNORE INTO salix.ACL (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
VALUES ('Entry','buyLabel','READ','ALLOW','ROLE','supplier');
UPDATE salix.ACL
SET principalId='$authenticated'
Review

Created 2017?, mejor no ponerlo y que se ponga automatico

Created 2017?, mejor no ponerlo y que se ponga automatico
Review

Cierto, aunque este rol ya está creado asi que lo podriamos evitar

Cierto, aunque este rol ya está creado asi que lo podriamos evitar
WHERE id=(SELECT id FROM salix.ACL WHERE model='StarredModule' and property='*' and `accessType`='*' );
Review

Podias haber puesto directamente ese where jajaja

Podias haber puesto directamente ese where jajaja
jsegarra marked this conversation as resolved
Review

Despues de esto hace falta hacer un CALL account.role_sync()

Despues de esto hace falta hacer un `CALL account.role_sync()`
Review

Ya existe en prod

Ya existe en prod

View File

@ -29,7 +29,8 @@ module.exports = Self => {
http: { http: {
path: '/:id/buy-label', path: '/:id/buy-label',
verb: 'GET' verb: 'GET'
} },
accessScopes: ['DEFAULT', 'read:multimedia']
}); });
Self.buyLabel = (ctx, id) => Self.printReport(ctx, id, 'buy-label'); Self.buyLabel = (ctx, id) => Self.printReport(ctx, id, 'buy-label');

View File

@ -95,6 +95,11 @@ module.exports = Self => {
arg: 'to', arg: 'to',
type: 'date', type: 'date',
description: `The to date filter` description: `The to date filter`
},
{
arg: 'days',
type: 'number',
description: `N days interval`
} }
], ],
returns: { returns: {
@ -112,7 +117,6 @@ module.exports = Self => {
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const conn = Self.dataSource.connector; const conn = Self.dataSource.connector;
const where = buildFilter(ctx.args, (param, value) => { const where = buildFilter(ctx.args, (param, value) => {
switch (param) { switch (param) {
@ -146,7 +150,13 @@ module.exports = Self => {
} }
}); });
filter = mergeFilters(ctx.args.filter, {where}); filter = mergeFilters(ctx.args.filter, {where});
const userId = ctx.req.accessToken.userId;
const client = await Self.app.models.Client.findById(userId, myOptions);
const supplier = await Self.app.models.Supplier.findOne({where: {nif: client.fi}}, myOptions);
if (supplier) {
if (!filter.where) filter.where = {};
filter.where[`e.supplierFk`] = supplier.id;
}
const stmts = []; const stmts = [];
let stmt; let stmt;
stmt = new ParameterizedSQL( stmt = new ParameterizedSQL(
@ -158,7 +168,7 @@ module.exports = Self => {
e.invoiceNumber, e.invoiceNumber,
e.isBooked, e.isBooked,
e.isExcludedFromAvailable, e.isExcludedFromAvailable,
e.evaNotes AS observation, e.evaNotes observation,
e.isConfirmed, e.isConfirmed,
e.isOrdered, e.isOrdered,
e.isRaid, e.isRaid,
@ -170,17 +180,32 @@ module.exports = Self => {
e.gestDocFk, e.gestDocFk,
e.invoiceInFk, e.invoiceInFk,
t.landed, t.landed,
s.name AS supplierName, s.name supplierName,
s.nickname AS supplierAlias, s.nickname supplierAlias,
co.code AS companyCode, co.code companyCode,
cu.code AS currencyCode cu.code currencyCode,
t.shipped,
t.landed,
t.ref AS travelRef,
t.warehouseInFk,
w.name warehouseInName
FROM vn.entry e FROM vn.entry e
JOIN vn.supplier s ON s.id = e.supplierFk JOIN vn.supplier s ON s.id = e.supplierFk
JOIN vn.travel t ON t.id = e.travelFk JOIN vn.travel t ON t.id = e.travelFk
JOIN vn.warehouse w ON w.id = t.warehouseInFk
JOIN vn.company co ON co.id = e.companyFk JOIN vn.company co ON co.id = e.companyFk
JOIN vn.currency cu ON cu.id = e.currencyFk` JOIN vn.currency cu ON cu.id = e.currencyFk`
); );
if (ctx.args.days) {
stmt.merge({
sql: `
AND t.shipped <= util.VN_CURDATE() + INTERVAL ? DAY
AND t.shipped >= util.VN_CURDATE()
`,
params: [ctx.args.days]
});
}
stmt.merge(conn.makeSuffix(filter)); stmt.merge(conn.makeSuffix(filter));
const itemsIndex = stmts.push(stmt) - 1; const itemsIndex = stmts.push(stmt) - 1;

View File

@ -1,7 +1,8 @@
const UserError = require('vn-loopback/util/user-error');
const mergeFilters = require('vn-loopback/util/filter').mergeFilters; const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('getBuys', { Self.remoteMethodCtx('getBuys', {
description: 'Returns buys for one entry', description: 'Returns buys for one entry',
accessType: 'READ', accessType: 'READ',
accepts: [{ accepts: [{
@ -27,13 +28,20 @@ module.exports = Self => {
} }
}); });
Self.getBuys = async(id, filter, options) => { Self.getBuys = async(ctx, id, filter, options) => {
const userId = ctx.req.accessToken.userId;
const models = Self.app.models; const models = Self.app.models;
const myOptions = {}; const myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(myOptions, options);
const client = await Self.app.models.Client.findById(userId, myOptions);
const supplier = await Self.app.models.Supplier.findOne({where: {nif: client.fi}}, myOptions);
if (supplier) {
const isEntryOwner = (await Self.findById(id)).supplierFk === supplier.id;
if (!isEntryOwner) throw new UserError('Access Denied');
jsegarra marked this conversation as resolved
Review

Diria que mejor usar un throw new ForbiddenError(...);

Diria que mejor usar un `throw new ForbiddenError(`...`);`
Review

lo vemos porque en el proyecto también se usa UserError para casos similares

lo vemos porque en el proyecto también se usa UserError para casos similares
}
let defaultFilter = { let defaultFilter = {
where: {entryFk: id}, where: {entryFk: id},
fields: [ fields: [
@ -49,9 +57,23 @@ module.exports = Self => {
'buyingValue', 'buyingValue',
'price2', 'price2',
'price3', 'price3',
'printedStickers' 'printedStickers',
'entryFk'
], ],
include: { include: [{
relation: 'entry',
scope: {
fields: [
'id', 'supplierFk'
],
include: {
relation: 'supplier', scope: {
fields: ['id']
}
}
}
},
{
relation: 'item', relation: 'item',
scope: { scope: {
fields: [ fields: [
@ -82,9 +104,8 @@ module.exports = Self => {
} }
} }
} }
} }]
}; };
defaultFilter = mergeFilters(defaultFilter, filter); defaultFilter = mergeFilters(defaultFilter, filter);
return models.Buy.find(defaultFilter, myOptions); return models.Buy.find(defaultFilter, myOptions);

View File

@ -9,7 +9,8 @@ describe('Entry filter()', () => {
const ctx = { const ctx = {
args: { args: {
search: 1 search: 1
} },
req: {accessToken: {userId: 9}}
}; };
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);
@ -32,12 +33,13 @@ describe('Entry filter()', () => {
const ctx = { const ctx = {
args: { args: {
currencyFk: 1 currencyFk: 1
} },
req: {accessToken: {userId: 9}}
}; };
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(9); expect(result.length).toEqual(11);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -46,26 +48,73 @@ describe('Entry filter()', () => {
} }
}); });
it('should return the entry matching the supplier', async() => { describe('should return the entry matching the supplier', () => {
const tx = await models.Entry.beginTransaction({}); it('when userId is supplier ', async() => {
const options = {transaction: tx}; const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try { try {
const ctx = { const ctx = {
args: { args: {days: 6},
supplierFk: 2 req: {accessToken: {userId: 1102}}
} };
};
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(6); expect(result.length).toEqual(2);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
await tx.rollback(); await tx.rollback();
throw e; throw e;
} }
});
it('when userId is supplier fetching other supplier', async() => {
const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
supplierFk: 1
},
req: {accessToken: {userId: 1102}}
};
const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(8);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
it('when userId is not supplier', async() => {
const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
supplierFk: 2
},
req: {accessToken: {userId: 9}}
};
const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(8);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
}); });
it('should return the entry matching the company', async() => { it('should return the entry matching the company', async() => {
@ -76,12 +125,13 @@ describe('Entry filter()', () => {
const ctx = { const ctx = {
args: { args: {
companyFk: 442 companyFk: 442
} },
req: {accessToken: {userId: 9}}
}; };
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);
expect(result.length).toEqual(8); expect(result.length).toEqual(10);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {
@ -98,7 +148,8 @@ describe('Entry filter()', () => {
const ctx = { const ctx = {
args: { args: {
isBooked: true, isBooked: true,
} },
req: {accessToken: {userId: 9}}
}; };
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);
@ -121,7 +172,8 @@ describe('Entry filter()', () => {
args: { args: {
reference: 'movement', reference: 'movement',
travelFk: '2' travelFk: '2'
} },
req: {accessToken: {userId: 9}}
}; };
const result = await models.Entry.filter(ctx, options); const result = await models.Entry.filter(ctx, options);

View File

@ -1,24 +1,82 @@
const UserError = require('vn-loopback/util/user-error');
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
describe('entry getBuys()', () => { describe('entry getBuys()', () => {
const entryId = 4; const entryId = 4;
it('should get the buys and items of an entry', async() => { describe('should get the buys and items of an entry ', () => {
const tx = await models.Entry.beginTransaction({}); it('when is supplier and entry owner', async() => {
const options = {transaction: tx}; const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try { try {
const result = await models.Entry.getBuys(entryId, options); const ctx = {
args: {
search: 1
},
req: {accessToken: {userId: 2}}
};
const length = result.length; const result = await models.Entry.getBuys(ctx, entryId, options);
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(4); const length = result.length;
expect(anyResult.item).toBeDefined(); const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
await tx.rollback(); expect(result.length).toEqual(4);
} catch (e) { expect(anyResult.item).toBeDefined();
await tx.rollback();
throw e; await tx.rollback();
} } catch (e) {
await tx.rollback();
throw e;
}
});
it('when is supplier but not entry owner', async() => {
const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
const entryId = 1;
try {
const ctx = {
args: {
search: 1
},
req: {accessToken: {userId: 1102}}
};
const result = await models.Entry.getBuys(ctx, entryId, options);
expect(result).toBeUndefined();
} catch (error) {
expect(error).toBeInstanceOf(UserError);
expect(error.message).toBe('Access Denied');
}
});
it('when is not supplier', async() => {
const tx = await models.Entry.beginTransaction({});
const options = {transaction: tx};
try {
const ctx = {
args: {
search: 1
},
req: {accessToken: {userId: 9}}
};
const result = await models.Entry.getBuys(ctx, entryId, options);
const length = result.length;
const anyResult = result[Math.floor(Math.random() * Math.floor(length))];
expect(result.length).toEqual(4);
expect(anyResult.item).toBeDefined();
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
}); });
}); });

View File

@ -79,7 +79,7 @@ describe('Travel extraCommunityFilter()', () => {
const result = await app.models.Travel.extraCommunityFilter(ctx, filter); const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
expect(result.length).toEqual(8); expect(result.length).toEqual(9);
}); });
it('should return the travel matching "cargoSupplierFk"', async() => { it('should return the travel matching "cargoSupplierFk"', async() => {
@ -110,6 +110,6 @@ describe('Travel extraCommunityFilter()', () => {
const result = await app.models.Travel.extraCommunityFilter(ctx, filter); const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
expect(result.length).toEqual(1); expect(result.length).toEqual(2);
}); });
}); });

View File

@ -50,7 +50,7 @@ describe('Travel filter()', () => {
const result = await app.models.Travel.filter(ctx); const result = await app.models.Travel.filter(ctx);
expect(result.length).toEqual(5); expect(result.length).toEqual(6);
}); });
it('should return the routes matching "shipped from" and "shipped to"', async() => { it('should return the routes matching "shipped from" and "shipped to"', async() => {
@ -80,6 +80,6 @@ describe('Travel filter()', () => {
const result = await app.models.Travel.filter(ctx); const result = await app.models.Travel.filter(ctx);
expect(result.length).toEqual(5); expect(result.length).toEqual(6);
}); });
}); });

View File

@ -59,7 +59,7 @@
<tr> <tr>
<td colspan="3" class="barcode"> <td colspan="3" class="barcode">
<div v-html="getBarcode(buy.id)"></div> <div v-html="getBarcode(buy.id)"></div>
<span>{{buy.id}}</span> <span>{{buy.itemFk}}</span>
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -7,7 +7,7 @@ module.exports = {
name: 'buy-label', name: 'buy-label',
mixins: [vnReport], mixins: [vnReport],
async serverPrefetch() { async serverPrefetch() {
this.buys = await this.rawSqlFromDef('buys', [this.id]); this.buys = await this.rawSqlFromDef('buys', [this.id, this.id]);
this.maxLabelNum = Math.max(...this.buys.map(buy => buy.labelNum)); this.maxLabelNum = Math.max(...this.buys.map(buy => buy.labelNum));
const date = new Date(); const date = new Date();
this.weekNum = moment(date).isoWeek(); this.weekNum = moment(date).isoWeek();

View File

@ -1,4 +1,15 @@
SELECT ROW_NUMBER() OVER(ORDER BY b.id) labelNum, WITH RECURSIVE numbers AS (
jsegarra marked this conversation as resolved
Review

Este SQL lo veo raro, ver con @pablone

Este SQL lo veo raro, ver con @pablone
Review

El SQL es de guillermo, solamente he hecho cherry-pick

El SQL es de guillermo, solamente he hecho cherry-pick
Review

¿A que te refieres con raro?

Es un SQL recursivo, lo utilizo para generar el número de etiquetas que tiene el campo stickers.

Es decir, antes si filtrábamos en la tabla buy por entryFk = 156841, salían 7 registros por ejemplo, entonces aparecían 7 páginas.

Pako lo que quería es que si la linea tiene stickers 20, de esa línea apareciesen 20 páginas, así con las 6 restantes,

Simplemente se utiliza para eso.

¿A que te refieres con raro? Es un SQL recursivo, lo utilizo para generar el número de etiquetas que tiene el campo stickers. Es decir, antes si filtrábamos en la tabla buy por entryFk = 156841, salían 7 registros por ejemplo, entonces aparecían 7 páginas. Pako lo que quería es que si la linea tiene stickers 20, de esa línea apareciesen 20 páginas, así con las 6 restantes, Simplemente se utiliza para eso.
SELECT 1 n
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < (
SELECT MAX(stickers)
FROM buy
WHERE entryFk = ?
)
)
SELECT ROW_NUMBER() OVER(ORDER BY b.id, num.n) labelNum,
i.name, i.name,
i.`size`, i.`size`,
i.category, i.category,
@ -8,10 +19,13 @@ SELECT ROW_NUMBER() OVER(ORDER BY b.id) labelNum,
b.`grouping`, b.`grouping`,
i.stems, i.stems,
b.id, b.id,
b.itemFk,
p.name producer p.name producer
FROM buy b FROM buy b
JOIN item i ON i.id = b.itemFk JOIN item i ON i.id = b.itemFk
LEFT JOIN producer p ON p.id = i.producerFk LEFT JOIN producer p ON p.id = i.producerFk
LEFT JOIN ink ON ink.id = i.inkFk LEFT JOIN ink ON ink.id = i.inkFk
LEFT JOIN origin o ON o.id = i.originFk LEFT JOIN origin o ON o.id = i.originFk
WHERE b.entryFk = ? JOIN numbers num
WHERE b.entryFk = ?
AND num.n <= b.stickers