UNPKG

csv-sort

Version:

Sort double-entry bookkeeping CSV from internet banking

12 lines (10 loc) 4.89 kB
/** * @name csv-sort * @fileoverview Sort double-entry bookkeeping CSV from internet banking * @version 7.0.20 * @author Roy Revelt, Codsen Ltd * @license MIT * {@link https://codsen.com/os/csv-sort/} */ import{pull as B}from"lodash-es";import{splitEasy as O}from"csv-split-easy";import R from"currency.js";function E(i){return typeof i=="number"&&!isNaN(i)?!0:(i=(i||"").toString().trim(),i?!isNaN(+i):!1)}var N=["\u062F.\u0625","\u060B","L","\u058F","\u0192","Kz","$","\u0192","\u20BC","KM","\u09F3","\u043B\u0432",".\u062F.\u0628","FBu","$b","R$","\u0E3F","Nu.","P","p.","BZ$","FC","CHF","\xA5","\u20A1","\u20B1","K\u010D","Fdj","kr","RD$","\u062F\u062C","kr","Nfk","Br","\u039E","\u20AC","\u20BE","\u20B5","GH\u20B5","D","FG","Q","L","kn","G","Ft","Rp","\u20AA","\u20B9","\u0639.\u062F","\uFDFC","kr","J$","JD","\xA5","KSh","\u043B\u0432","\u17DB","CF","\u20A9","\u20A9","KD","\u043B\u0432","\u20AD","\u20A8","M","\u0141","Lt","Ls","LD","MAD","lei","Ar","\u0434\u0435\u043D","K","\u20AE","MOP$","UM","\u20A8","Rf","MK","RM","MT","\u20A6","C$","kr","\u20A8","\uFDFC","B/.","S/.","K","\u20B1","\u20A8","z\u0142","Gs","\uFDFC","\uFFE5","lei","\u0414\u0438\u043D.","\u20BD","R\u20A3","\uFDFC","\u20A8","\u062C.\u0633.","kr","\xA3","Le","S","Db","E","\u0E3F","SM","T","\u062F.\u062A","T$","\u20A4","\u20BA","TT$","NT$","TSh","\u20B4","USh","$U","\u043B\u0432","Bs","\u20AB","VT","WS$","FCFA","\u0243","CFA","\u20A3","\uFDFC","R","Z$"];function f(i){return E(i)||N.some(b=>E(i.replace(b,"").replace(/[,.]/g,"")))?"numeric":i.trim()?"text":"empty"}var T="7.0.20";var K=T;function _(i){let b=null,C=null;if(typeof i!="string")throw new TypeError(`csv-sort/csvSort(): [THROW_ID_01] The input is of a wrong type! We accept either string of array of arrays. We got instead: ${typeof i}, equal to: ${JSON.stringify(i,null,4)}`);if(!i.trim())return{res:[[""]],msgContent:b,msgType:C};let n=O(i),s=[],g=!1,S=!0,v=[],o=null;for(let t=n.length-1;t>=0;t--)if(s.length){t===0&&(g=n[t].every(l=>f(l)==="text"||f(l)==="empty")),!g&&s.length!==n[t].length&&(S=!1);let e=null;for(let l=0,p=n[t].length;l<p;l++)if(e===null&&f(n[t][l].trim())==="empty"&&(e=l),e!==null&&f(n[t][l].trim())!=="empty"&&(e=null),f(n[t][l].trim())!==s[l]&&!g){let a=f(n[t][l].trim());if(Array.isArray(s[l]))s[l].includes(a)||s[l].push(f(n[t][l].trim()));else if(s[l]!==a){let u=s[l];s[l]=[],s[l].push(u),s[l].push(a)}}o!==null&&e!==null&&e>o&&(!g||g&&t!==0)&&(o=e)}else if(n[t].length!==1||n[t][0]!=="")for(let e=0,l=n[t].length;e<l;e++)s.push(f(n[t][e].trim())),o===null&&f(n[t][e].trim())==="empty"&&(o=e),o!==null&&f(n[t][e].trim())!=="empty"&&(o=null);o||(o=s.length);let w=0;for(let t=0,e=s.length;t<e&&s[t]==="empty";t++)w=t;w!==0&&(n=n.map(t=>t.slice(w+1,o)),s=s.slice(w+1,o));let V=[],m;s.forEach((t,e)=>{t==="numeric"&&V.push(e)});let k=g?1:0;if(V.length===1)m=V[0];else{if(V.length===0)throw new Error('csv-sort/csvSort(): [THROW_ID_03] Your CSV file does not contain numeric-only columns and computer was not able to detect the "Balance" column!');{let t=Array.from(V),e=[];for(let l=0,p=t.length;l<p;l++){let a=t[l],u,d=!0,$,h=!0;for(let c=k,I=n.length;c<I&&(d&&(u==null?u=n[c][a]:u===n[c][a]?(e.push(a),d=!1):u=n[c][a]),h&&($==null?$=n[c][a]:n[c][a]!==$&&(h=!1)),!!d);c++);h&&v.push(a)}if(t=B(t,...e),t.length===1)m=t[0];else if(t.length===0)throw new Error(`csv-sort/csvSort(): [THROW_ID_04] The computer can't find the "Balance" column! It saw some numeric-only columns, but they all seem to have certain rows with the same values as rows right below/above them!`)}}if(!m)throw new Error("csv-sort/csvSort(): [THROW_ID_05] Sadly computer couldn't find its way in this CSV and had to stop working on it.");let D=B(Array.from(s.reduce((t,e,l)=>((typeof e=="string"&&e==="numeric"||Array.isArray(e)&&e.includes("numeric"))&&t.push(l),t),[])),m,...v),r=[];r.push(n[n.length-1].slice(0,o));let y=[],x=g?1:0;for(let t=n.length-2;t>=x;t--)for(let e=n.length-2;e>=x;e--)if(!y.includes(e)){let l=!1;for(let p=0,a=D.length;p<a;p++){let u=null;n[e][D[p]]!==""&&(u=R(n[e][D[p]]));let d=null;n[e][m]!==""&&(d=R(n[e][m]));let $=null;r[0][m]!==""&&($=R(r[0][m]).format());let h=null;r[r.length-1][D[p]]!==""&&(h=R(r[r.length-1][D[p]]).format());let c=null;if(r[r.length-1][m]!==""&&(c=R(r[r.length-1][m])),u&&d.add(u).format()===$){r.unshift(n[e].slice(0,o)),y.push(e),l=!0;break}else if(u&&d.subtract(u).format()===$){r.unshift(n[e].slice(0,o)),y.push(e),l=!0;break}else if(h&&c.add(h).format()===d.format()){r.push(n[e].slice(0,o)),y.push(e),l=!0;break}else if(h&&c.subtract(h).format()===d.format()){r.push(n[e].slice(0,o)),y.push(e),l=!0;break}}if(l){l=!1;break}}return g&&(S&&n[0].length>s.length&&(n[0].length=s.length),r.unshift(n[0].slice(0,o))),n.length-(g?2:1)!==y.length&&(b="Not all rows were recognised!",C="alert"),{res:r,msgContent:b,msgType:C}}export{f as findType,E as isNumeric,_ as sort,K as version};