feat: refs #7905 getBuysCsv #2900
|
@ -0,0 +1,2 @@
|
|||
INSERT IGNORE INTO salix.ACL (model,property,principalId)
|
||||
VALUES ('Entry','getBuysCsv','supplier');
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
/**
|
||||
* Flattens an array of objects by converting each object into a flat structure.
|
||||
*
|
||||
* @param {Array} dataArray Array of objects to be flattened
|
||||
* @return {Array} Array of flattened objects
|
||||
*/
|
||||
function flatten(dataArray) {
|
||||
return dataArray.map(item => flattenObj(item.__data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively flattens an object, converting nested properties into a single level object
|
||||
* with keys representing the original nested structure.
|
||||
*
|
||||
* @param {Object} data The object to be flattened
|
||||
* @param {String} [prefix=''] Optional prefix for nested keys
|
||||
* @return {Object} Flattened object
|
||||
*/
|
||||
function flattenObj(data, prefix = '') {
|
||||
let result = {};
|
||||
try {
|
||||
for (let key in data) {
|
||||
if (!data[key]) continue;
|
||||
|
||||
const newKey = prefix ? `${prefix}_${key}` : key;
|
||||
const value = data[key];
|
||||
|
||||
if (typeof value === 'object' && value !== null && !Array.isArray(value))
|
||||
Object.assign(result, flattenObj(value.__data, newKey));
|
||||
else
|
||||
result[newKey] = value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
module.exports = {
|
||||
flatten,
|
||||
flattenObj,
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
const {toCSV} = require('vn-loopback/util/csv');
|
||||
guillermo marked this conversation as resolved
|
||||
const {flatten} = require('vn-loopback/util/flatten');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('getBuysCsv', {
|
||||
description: 'Returns buys for one entry in CSV file format',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The entry id',
|
||||
http: {source: 'path'}
|
||||
}
|
||||
],
|
||||
returns: [
|
||||
guillermo marked this conversation as resolved
jsegarra
commented
El problema que veo en mi propuesta es con respecto al return El problema que veo en mi propuesta es con respecto al return
jsegarra
commented
Aunqaue puedes hacer que cuando tengas los datos o el stream, modificar ctx mediante Aunqaue puedes hacer que cuando tengas los datos o el stream, modificar ctx mediante
`ctx.res.setHeader('Content-Type', 'text/csv');
ctx.res.setHeader('Content-Disposition', 'attachment; filename="discounted_price.csv"');
` o ` ctx.res.setHeader('Content-Type', 'application/json');`
guillermo
commented
Ya me he pegado de "ostias" para intentar tenerlo todo en un método, al final lo separé por el return como bien has dicho. El segundo problema es que al retornar un JSON, claro el JSON puede tener objetos anidados, cosa que el CSV no, ya que es plano. Por eso también obté por hacer la query directamente, ya que, a parte de lo mencionado, al utilizan loopback te crea objetos metadata en la variable que luego hay que eliminar y no se... Ya me he pegado de "ostias" para intentar tenerlo todo en un método, al final lo separé por el return como bien has dicho.
El segundo problema es que al retornar un JSON, claro el JSON puede tener objetos anidados, cosa que el CSV no, ya que es plano.
Por eso también obté por hacer la query directamente, ya que, a parte de lo mencionado, al utilizan loopback te crea objetos metadata en la variable que luego hay que eliminar y no se...
jsegarra
commented
En ese caso eztraeria el core de la función getbuys a una función aparte y haría llamadas a esta nueva En ese caso eztraeria el core de la función getbuys a una función aparte y haría llamadas a esta nueva
Tipo lo que se hace en dms y docuware
jsegarra
commented
Ya te sigo, por lo que veo, cuando se usa toCSV no hay relaciones/includes
Ya te sigo, por lo que veo, cuando se usa toCSV no hay relaciones/includes
Sin embargo, modules/invoiceOut/back/methods/invoiceOut/negativeBasesCsv.js, obtiene datos y luego hace un map de los resultados
A lo mejor podriamos invertir tiempo para que dato un objeto(label:path), montar un csv
```
csv= {
nombre: 'name',
colorItem: 'item.color'
}
```
jgallego
commented
El tema de que el CSV no tenga objetos anidados No hay que darle una solución técnica sino hablar con el proveedor ya que implica que tenga que recuperar los datos de forma distinta El tema de que el CSV no tenga objetos anidados No hay que darle una solución técnica sino hablar con el proveedor ya que implica que tenga que recuperar los datos de forma distinta
|
||||
{
|
||||
arg: 'body',
|
||||
type: 'file',
|
||||
root: true
|
||||
}, {
|
||||
arg: 'Content-Type',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}, {
|
||||
arg: 'Content-Disposition',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: `/:id/getBuysCsv`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.getBuysCsv = async(ctx, id, options) => {
|
||||
const data = await Self.getBuys(ctx, id, null, options);
|
||||
const dataFlatted = flatten(data);
|
||||
return [toCSV(dataFlatted), 'text/csv', `inline; filename="buys-${id}.csv"`];
|
||||
};
|
||||
};
|
|
@ -3,6 +3,7 @@ module.exports = Self => {
|
|||
require('../methods/entry/filter')(Self);
|
||||
require('../methods/entry/getEntry')(Self);
|
||||
require('../methods/entry/getBuys')(Self);
|
||||
require('../methods/entry/getBuysCsv')(Self);
|
||||
require('../methods/entry/importBuys')(Self);
|
||||
require('../methods/entry/importBuysPreview')(Self);
|
||||
require('../methods/entry/lastItemBuys')(Self);
|
||||
|
|
@jsegarra se quiere que los proveedores puedan tener sus buys. Ya lo hicimos via json, ahora lo quieren via csv, pero con este enfoque duplicamos codigo, hay forma de tenerlo unificado o por parametros ?
Si, esto ya lo he visto pero tengo que buscar el commit
El ejemplo que tengo en la cabeza es cuando se planteo la necesidad de que printReport, según la cabecera generase un pdf o un html
Creo que la cabecera que buscamos es la de accept
El commit
bb96125bbd
#2900 (comment)