-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
164 lines (132 loc) · 4.55 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
const fs = require("fs");
const path = require("path");
const prettyjson = require("prettyjson");
const yargs = require("yargs/yargs");
const { hideBin } = require("yargs/helpers");
const chartscii = require("chartscii");
const argv = yargs(hideBin(process.argv)).option("dirPath", {
type: "string",
demandOption: true,
describe: "The directory path",
}).argv;
const dirPath = argv.dirPath;
function parseFileName(fileName) {
const parts = fileName.split(" - ");
if (parts.length !== 3) {
console.error(`File does not match expected format: ${fileName}`);
return { year: null, amount: 0, isReimbursement: false };
}
const date = parts[0];
const amountPart = parts[2];
let amount = 0;
if (amountPart && !isNaN(parseFloat(amountPart.substring(1)))) {
amount = parseFloat(amountPart.substring(1));
}
const year = date.split("-")[0];
// Check if this is a reimbursement
const isReimbursement = fileName.includes('.reimbursed.');
return { year, amount, isReimbursement };
}
function getTotalsByYear(dirPath) {
const expensesByYear = {};
const reimbursementsByYear = {};
const receiptCounts = {};
const fileNames = fs.readdirSync(dirPath);
fileNames.forEach((fileName) => {
if (fileName.startsWith(".")) {
return;
}
const { year, amount, isReimbursement } = parseFileName(fileName);
if (amount > 0) {
// Initialize year data if not exists
if (!expensesByYear[year]) {
expensesByYear[year] = 0;
reimbursementsByYear[year] = 0;
receiptCounts[year] = 0;
}
// Always count as an expense regardless of reimbursement status
expensesByYear[year] = +(expensesByYear[year] + amount).toFixed(2);
// Additionally track as reimbursement if applicable
if (isReimbursement) {
reimbursementsByYear[year] = +(reimbursementsByYear[year] + amount).toFixed(2);
}
receiptCounts[year]++;
}
});
return { expensesByYear, reimbursementsByYear, receiptCounts };
}
const { expensesByYear, reimbursementsByYear, receiptCounts } = getTotalsByYear(dirPath);
const result = {};
const years = [...new Set([...Object.keys(expensesByYear), ...Object.keys(reimbursementsByYear)])].sort();
for (const year of years) {
result[year] = {
expenses: `$${(expensesByYear[year] || 0).toFixed(2)}`,
reimbursements: `$${(reimbursementsByYear[year] || 0).toFixed(2)}`,
receipts: receiptCounts[year],
};
}
console.log(prettyjson.render(result));
console.log();
// Create data arrays for charts
const expenseData = [];
const reimbursementData = [];
const combinedData = [];
for (const year of years) {
const expenseAmount = expensesByYear[year] || 0;
const reimbursementAmount = reimbursementsByYear[year] || 0;
expenseData.push({
label: year,
value: expenseAmount,
});
reimbursementData.push({
label: year,
value: reimbursementAmount,
});
// For combined chart
combinedData.push({
label: `${year} Exp`,
value: expenseAmount,
});
combinedData.push({
label: `${year} Rei`,
value: reimbursementAmount,
});
}
const chart = new chartscii(expenseData, {
width: 20,
height: years.length,
title: "Expenses by year",
fill: "░",
valueLabels: true,
valueLabelsPrefix: "$",
valueLabelsFloatingPoint: 2
});
const reimbursementChart = new chartscii(reimbursementData, {
width: 20,
height: years.length,
title: "Reimbursements by year",
fill: "░",
valueLabels: true,
valueLabelsPrefix: "$",
valueLabelsFloatingPoint: 2
});
console.log(chart.create());
console.log();
console.log(reimbursementChart.create());
console.log();
// Create a manual comparison chart
console.log("Comparison by year:");
const maxValue = Math.max(
...Object.values(expensesByYear),
...Object.values(reimbursementsByYear)
);
for (const year of years) {
const expenseAmount = expensesByYear[year] || 0;
const reimbursementAmount = reimbursementsByYear[year] || 0;
const expenseBarLength = Math.floor((expenseAmount / maxValue) * 20);
const reimbursementBarLength = Math.floor((reimbursementAmount / maxValue) * 20);
const expenseBar = "█".repeat(expenseBarLength) + "░".repeat(20 - expenseBarLength);
const reimbursementBar = "█".repeat(reimbursementBarLength) + "░".repeat(20 - reimbursementBarLength);
console.log(`${year} Expenses ╢${expenseBar} $${expenseAmount.toFixed(2)}`);
console.log(`${year} Reimbursements ╢${reimbursementBar} $${reimbursementAmount.toFixed(2)}`);}
console.log(" ╚════════════════════");