import moment from 'moment' export function appendTag (row, keywords, field = 'Libellé') { // Append row.tag // if row.libellé contains one of words and not invert it gets tagged // if row.libellé contains no words and invert it gets tagged // according to keywords [{name: string, words: [], invert: bool}] row.tags = keywords.filter(k => { return strContains(row[field], k.words, k.invert) }) } function strContains (string, words, invert) { // Does a string contain one of words or the opposite if (!words) { return true } if (invert) { return words.every(v => { return string.toLowerCase().indexOf(v.toLowerCase()) < 0 }) } else { return words.some(v => { return string.toLowerCase().indexOf(v.toLowerCase()) >= 0 }) } } export function formatDate (row, field = 'Date') { row[field] = moment(row[field], 'DD/MM/YYYY', true) } export function total (rows, field = 'Montant') { var sum = rows.map(x => parseFloat(x[field])) .reduce((sum, x) => sum + x, 0) return Math.round(sum) } export function tag_filter (rows, tags, invert=false) { // filter rows by tags // invert inverts the selection return rows.filter(row => { if (invert) { return tags.some(t => { return row.tags.map(t => t.name.toLowerCase()) .indexOf(t.toLowerCase()) < 0 }) } else { return tags.every(t => { return row.tags.map(t => t.name.toLowerCase()) .indexOf(t.toLowerCase()) > -1 }) } }) } function objectMap (object, mapFn) { // map a function on object value return Object.keys(object).reduce(function(result, key) { result[key] = mapFn(object[key]) return result }, {}) } export function groupBy (rows, grouping, agg) { // Group rows by field then apply agg var groups = rows.reduce((stock, row) => { var group = grouping(row) if (stock[group]) { stock[group].push(row) } else { stock[group] = [row] } return stock }, {}) return objectMap(groups, group => agg(group)) }