jira-invoice 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js ADDED
@@ -0,0 +1,415 @@
1
+ /**
2
+ * CLI interactivo para generar invoices PDF desde CSV de Jira.
3
+ */
4
+ import { readdirSync, statSync } from "node:fs";
5
+ import { dirname, join, resolve } from "node:path";
6
+ import { Command } from "commander";
7
+ import { input, confirm, search } from "@inquirer/prompts";
8
+ import chalk from "chalk";
9
+ import Table from "cli-table3";
10
+ import ora from "ora";
11
+ import { parse } from "./parser.js";
12
+ import { render } from "./renderer.js";
13
+ import { configExists, loadConfig } from "./store.js";
14
+ import { runSetupWizard, selectCompany } from "./setup.js";
15
+ // ── CSV file selector (árbol + filtro por texto) ─────────────────────────────
16
+ const GO_UP = "__GO_UP__";
17
+ function listDir(dir) {
18
+ const items = [];
19
+ // Parent directory
20
+ const parent = resolve(dir, "..");
21
+ if (parent !== dir) {
22
+ items.push({ label: "📁 ..", value: GO_UP, isDir: true });
23
+ }
24
+ try {
25
+ const entries = readdirSync(dir, { withFileTypes: true })
26
+ .filter((e) => !e.name.startsWith("."))
27
+ .filter((e) => e.isDirectory() || e.name.endsWith(".csv"))
28
+ .sort((a, b) => {
29
+ if (a.isDirectory() && !b.isDirectory())
30
+ return -1;
31
+ if (!a.isDirectory() && b.isDirectory())
32
+ return 1;
33
+ return a.name.localeCompare(b.name);
34
+ });
35
+ for (const e of entries) {
36
+ const full = join(dir, e.name);
37
+ if (e.isDirectory()) {
38
+ items.push({ label: `📁 ${e.name}/`, value: full, isDir: true });
39
+ }
40
+ else {
41
+ items.push({ label: ` ${e.name}`, value: full, isDir: false });
42
+ }
43
+ }
44
+ }
45
+ catch {
46
+ // permission errors
47
+ }
48
+ return items;
49
+ }
50
+ async function selectCsvFile(startDir) {
51
+ let cwd = startDir ?? process.cwd();
52
+ while (true) {
53
+ const shortCwd = cwd.replace(process.env.HOME ?? "", "~");
54
+ const items = listDir(cwd);
55
+ const selected = await search({
56
+ message: `📂 ${chalk.dim(shortCwd)} — escribe para filtrar:`,
57
+ source: (term) => {
58
+ const q = (term ?? "").toLowerCase();
59
+ if (!q) {
60
+ return items.map((it) => ({
61
+ name: it.isDir ? chalk.yellow(it.label) : chalk.white(it.label),
62
+ value: it.value,
63
+ }));
64
+ }
65
+ // Strip icon prefix for matching
66
+ return items
67
+ .filter((it) => it.label.toLowerCase().includes(q))
68
+ .map((it) => ({
69
+ name: it.isDir ? chalk.yellow(it.label) : chalk.white(it.label),
70
+ value: it.value,
71
+ }));
72
+ },
73
+ });
74
+ if (selected === GO_UP) {
75
+ cwd = resolve(cwd, "..");
76
+ continue;
77
+ }
78
+ try {
79
+ if (statSync(selected).isDirectory()) {
80
+ cwd = selected;
81
+ continue;
82
+ }
83
+ }
84
+ catch {
85
+ // fallthrough
86
+ }
87
+ return selected;
88
+ }
89
+ }
90
+ // ── Header ──────────────────────────────────────────────────────────────────
91
+ function printHeader() {
92
+ console.log();
93
+ console.log(chalk.blue("┌─────────────────────────────────────────┐"));
94
+ console.log(chalk.blue("│") + chalk.bold.white(" ⚡ Invoice Generator") + chalk.blue(" │"));
95
+ console.log(chalk.blue("│") + chalk.dim(" Genera invoices PDF desde CSV de Jira") + chalk.blue(" │"));
96
+ console.log(chalk.blue("└─────────────────────────────────────────┘"));
97
+ console.log();
98
+ }
99
+ // ── Preview table ───────────────────────────────────────────────────────────
100
+ function printPreview(entries, rate, hasLimit) {
101
+ const head = hasLimit
102
+ ? [
103
+ chalk.bold.white(" #"),
104
+ chalk.bold.white("Fecha"),
105
+ chalk.bold.white("Ticket"),
106
+ chalk.bold.white("Tarea"),
107
+ chalk.bold.white("Trabajadas"),
108
+ chalk.bold.white("Horas"),
109
+ chalk.bold.white("Subtotal"),
110
+ ]
111
+ : [
112
+ chalk.bold.white(" #"),
113
+ chalk.bold.white("Fecha"),
114
+ chalk.bold.white("Ticket"),
115
+ chalk.bold.white("Tarea"),
116
+ chalk.bold.white("Horas"),
117
+ chalk.bold.white("Subtotal"),
118
+ ];
119
+ const colWidths = hasLimit
120
+ ? [5, 14, 13, 36, 12, 9, 12]
121
+ : [5, 14, 13, 50, 9, 12];
122
+ const t = new Table({ head, colWidths, style: { head: [], border: ["blue"] } });
123
+ for (let i = 0; i < entries.length; i++) {
124
+ const e = entries[i];
125
+ const desc = e.desc.length > (hasLimit ? 28 : 42)
126
+ ? e.desc.slice(0, hasLimit ? 28 : 42) + "…"
127
+ : e.desc;
128
+ const row = hasLimit
129
+ ? [
130
+ chalk.dim(String(i + 1)),
131
+ chalk.bold.cyan(formatDate(e.date)),
132
+ chalk.bold.blue(e.ticket),
133
+ desc,
134
+ chalk.dim(`${e.rawHours.toFixed(1)} h`),
135
+ chalk.yellow(`${e.hours.toFixed(1)} h`),
136
+ chalk.bold.green(`$${fmtMoney(e.hours * rate)}`),
137
+ ]
138
+ : [
139
+ chalk.dim(String(i + 1)),
140
+ chalk.bold.cyan(formatDate(e.date)),
141
+ chalk.bold.blue(e.ticket),
142
+ desc,
143
+ chalk.yellow(`${e.hours.toFixed(1)} h`),
144
+ chalk.bold.green(`$${fmtMoney(e.hours * rate)}`),
145
+ ];
146
+ t.push(row);
147
+ }
148
+ const totalH = entries.reduce((s, e) => s + e.hours, 0);
149
+ const totalA = totalH * rate;
150
+ const emptyPad = hasLimit ? ["", "", "", ""] : ["", "", ""];
151
+ t.push([
152
+ ...emptyPad,
153
+ chalk.bold(`${totalH.toFixed(1)} h`),
154
+ chalk.bold.green(`$${fmtMoney(totalA)}`),
155
+ ]);
156
+ console.log(t.toString());
157
+ console.log();
158
+ }
159
+ // ── Edit row ────────────────────────────────────────────────────────────────
160
+ async function editLoop(entries, rate, hasLimit) {
161
+ const result = [...entries];
162
+ while (true) {
163
+ const rowStr = await input({
164
+ message: "✏️ Editar fila # (o enter para continuar):",
165
+ default: "",
166
+ });
167
+ if (!rowStr.trim())
168
+ break;
169
+ const idx = parseInt(rowStr) - 1;
170
+ if (isNaN(idx) || idx < 0 || idx >= result.length) {
171
+ console.log(chalk.red(` Fila inválida. Usa 1-${result.length}`));
172
+ continue;
173
+ }
174
+ const e = result[idx];
175
+ console.log();
176
+ console.log(chalk.dim(` Editando fila ${idx + 1}: ${e.ticket} ${e.desc}`));
177
+ const newDateStr = await input({
178
+ message: " Fecha (dd/Mon/yy):",
179
+ default: formatDate(e.date),
180
+ });
181
+ const newTicket = await input({
182
+ message: " Ticket:",
183
+ default: e.ticket,
184
+ });
185
+ const newDesc = await input({
186
+ message: " Descripción:",
187
+ default: e.desc,
188
+ });
189
+ const newHoursStr = await input({
190
+ message: " Horas:",
191
+ default: e.hours.toFixed(1),
192
+ validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) >= 0) || "Número inválido",
193
+ });
194
+ // Parse the date
195
+ const [dd, mon, yy] = newDateStr.split("/");
196
+ const MONTHS = {
197
+ Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4, Jun: 5,
198
+ Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11,
199
+ };
200
+ const newDate = new Date(2000 + parseInt(yy), MONTHS[mon] ?? 0, parseInt(dd));
201
+ const newHours = parseFloat(newHoursStr);
202
+ result[idx] = {
203
+ date: newDate,
204
+ ticket: newTicket,
205
+ desc: newDesc,
206
+ hours: newHours,
207
+ rawHours: e.rawHours,
208
+ };
209
+ console.log(chalk.green(" ✓ Fila actualizada"));
210
+ console.log();
211
+ printPreview(result, rate, hasLimit);
212
+ }
213
+ return result;
214
+ }
215
+ // ── Warnings ────────────────────────────────────────────────────────────────
216
+ function checkWarnings(entries, maxHoursPerDay) {
217
+ if (maxHoursPerDay === null)
218
+ return;
219
+ const byDay = new Map();
220
+ for (const e of entries) {
221
+ const key = e.date.toISOString().slice(0, 10);
222
+ byDay.set(key, (byDay.get(key) ?? 0) + e.hours);
223
+ }
224
+ const capped = [];
225
+ for (const [d, h] of byDay) {
226
+ if (Math.abs(h - maxHoursPerDay) > 0.05 && h < maxHoursPerDay) {
227
+ capped.push(d);
228
+ }
229
+ }
230
+ if (capped.length > 0) {
231
+ console.log(chalk.yellow(`⚠ ${capped.length} día(s) con menos de ${maxHoursPerDay}h facturables`));
232
+ for (const d of capped.sort()) {
233
+ console.log(chalk.dim(` • ${d}: ${byDay.get(d).toFixed(2)} h`));
234
+ }
235
+ console.log();
236
+ }
237
+ }
238
+ // ── Helpers ─────────────────────────────────────────────────────────────────
239
+ const MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
240
+ const MONTH_LONG = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
241
+ function formatDate(d) {
242
+ const dd = String(d.getDate()).padStart(2, "0");
243
+ return `${dd}/${MONTH_NAMES[d.getMonth()]}/${String(d.getFullYear()).slice(2)}`;
244
+ }
245
+ function fmtMoney(n) {
246
+ return n.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
247
+ }
248
+ function defaultDateStr() {
249
+ const now = new Date();
250
+ return `${MONTH_LONG[now.getMonth()]} ${String(now.getDate()).padStart(2, "0")}, ${now.getFullYear()}`;
251
+ }
252
+ // ── Load or setup config ────────────────────────────────────────────────────
253
+ async function getConfig() {
254
+ if (configExists()) {
255
+ return loadConfig();
256
+ }
257
+ return runSetupWizard();
258
+ }
259
+ // ── Interactive mode ────────────────────────────────────────────────────────
260
+ async function runInteractive() {
261
+ printHeader();
262
+ // 1. Config
263
+ let config = await getConfig();
264
+ // 2. Select company
265
+ const { company, config: updatedConfig } = await selectCompany(config);
266
+ config = updatedConfig;
267
+ const hasLimit = company.maxHoursPerDay !== null;
268
+ console.log();
269
+ const cur = company.currency ?? "USD";
270
+ console.log(`${chalk.green("✓")} Empresa: ${chalk.bold(company.name)} (${company.rate} ${cur}/h${hasLimit ? `, max ${company.maxHoursPerDay}h/día` : ""})`);
271
+ // 3. CSV path
272
+ const csvPath = await selectCsvFile();
273
+ // 4. Parse
274
+ console.log();
275
+ const spinner = ora({ text: chalk.blue("Leyendo CSV..."), color: "blue" }).start();
276
+ const { entries: parsedEntries, format } = parse(csvPath, company.maxHoursPerDay);
277
+ spinner.succeed(`${chalk.bold(String(parsedEntries.length))} entradas encontradas ${chalk.dim(`(${format} format)`)}`);
278
+ console.log();
279
+ // 5. Rate
280
+ const rateStr = await input({
281
+ message: `💵 Tarifa por hora (${cur}):`,
282
+ default: company.rate.toFixed(2),
283
+ validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) > 0) || "Ingresa un número válido",
284
+ });
285
+ const rate = parseFloat(rateStr);
286
+ // 6. Preview
287
+ console.log();
288
+ console.log(chalk.dim.blue("─── Vista previa ───────────────────────────────────────"));
289
+ console.log();
290
+ printPreview(parsedEntries, rate, hasLimit);
291
+ checkWarnings(parsedEntries, company.maxHoursPerDay);
292
+ // 7. Edit loop
293
+ const entries = await editLoop(parsedEntries, rate, hasLimit);
294
+ // 8. Invoice date (vacío = fecha actual)
295
+ const invDateInput = await input({
296
+ message: "📅 Fecha del invoice (enter = hoy):",
297
+ default: "",
298
+ });
299
+ const invDate = invDateInput.trim() || defaultDateStr();
300
+ // 9. Invoice number
301
+ const endDt = entries[entries.length - 1].date;
302
+ const defaultNum = `INV-${endDt.getFullYear()}-${String(endDt.getMonth() + 1).padStart(2, "0")}${String(endDt.getDate()).padStart(2, "0")}`;
303
+ const invNum = await input({
304
+ message: "🔢 Número de invoice:",
305
+ default: defaultNum,
306
+ });
307
+ // 10. Show raw hours in PDF?
308
+ let showRawHours = false;
309
+ if (hasLimit) {
310
+ showRawHours = await confirm({
311
+ message: "📊 ¿Incluir columna de horas trabajadas en el PDF?",
312
+ default: false,
313
+ });
314
+ }
315
+ // 11. Output path
316
+ const startDt = entries[0].date;
317
+ const fmtDt = (d) => `${String(d.getDate()).padStart(2, "0")}${MONTH_NAMES[d.getMonth()]}${String(d.getFullYear()).slice(2)}`;
318
+ const defaultOut = join(dirname(csvPath), `invoice_${fmtDt(startDt)}_to_${fmtDt(endDt)}.pdf`);
319
+ const outPath = await input({
320
+ message: "💾 Guardar PDF en:",
321
+ default: defaultOut,
322
+ });
323
+ // 12. Summary
324
+ console.log();
325
+ const totalH = entries.reduce((s, e) => s + e.hours, 0);
326
+ const summary = new Table({ style: { head: [], border: ["blue"] } });
327
+ summary.push({ Empresa: company.name }, { "Invoice #": invNum }, { Fecha: invDate }, { Tarifa: `${cur} ${rate.toFixed(2)}/h` }, { "Total horas": `${totalH.toFixed(1)} h` }, { "Total monto": `${cur} ${fmtMoney(totalH * rate)}` }, { Archivo: outPath });
328
+ console.log(summary.toString());
329
+ console.log();
330
+ // 13. Confirm
331
+ const ok = await confirm({ message: "¿Generar invoice?", default: true });
332
+ if (!ok) {
333
+ console.log(chalk.dim("Cancelado."));
334
+ process.exit(0);
335
+ }
336
+ // 14. Generate
337
+ console.log();
338
+ const genSpinner = ora({ text: chalk.blue("Generando PDF..."), color: "blue" }).start();
339
+ const { totalHours, totalAmount } = await render(entries, rate, invDate, invNum, outPath, config.user, company, showRawHours, cur);
340
+ genSpinner.succeed(chalk.bold.green("Invoice generado exitosamente"));
341
+ console.log();
342
+ console.log(` ${chalk.dim("Horas:")} ${chalk.bold(`${totalHours.toFixed(1)} h`)}`);
343
+ console.log(` ${chalk.dim("Monto:")} ${chalk.bold.green(`${cur} ${fmtMoney(totalAmount)}`)}`);
344
+ console.log(` ${chalk.dim("Archivo:")} ${chalk.cyan(outPath)}`);
345
+ console.log();
346
+ }
347
+ // ── Direct mode ─────────────────────────────────────────────────────────────
348
+ async function runDirect(csv, opts) {
349
+ if (!configExists()) {
350
+ console.log(chalk.red("No hay configuración. Ejecuta `invoice` primero para configurar."));
351
+ process.exit(1);
352
+ }
353
+ const config = loadConfig();
354
+ let company;
355
+ if (opts.company) {
356
+ const found = config.companies.find((c) => c.id === opts.company);
357
+ if (!found) {
358
+ console.log(chalk.red(`Empresa no encontrada: ${opts.company}`));
359
+ console.log(chalk.dim(`Empresas disponibles: ${config.companies.map((c) => c.id).join(", ")}`));
360
+ process.exit(1);
361
+ }
362
+ company = found;
363
+ }
364
+ else if (config.companies.length === 1) {
365
+ company = config.companies[0];
366
+ }
367
+ else {
368
+ console.log(chalk.red("Hay múltiples empresas. Usa --company <id> para especificar."));
369
+ console.log(chalk.dim(`Empresas disponibles: ${config.companies.map((c) => c.id).join(", ")}`));
370
+ process.exit(1);
371
+ }
372
+ const rate = opts.rate ? parseFloat(opts.rate) : company.rate;
373
+ const { entries } = parse(csv, company.maxHoursPerDay);
374
+ const endDt = entries[entries.length - 1].date;
375
+ const startDt = entries[0].date;
376
+ const fmtDt = (d) => `${String(d.getDate()).padStart(2, "0")}${MONTH_NAMES[d.getMonth()]}${String(d.getFullYear()).slice(2)}`;
377
+ const invDate = opts.date || defaultDateStr();
378
+ const invNum = opts.number ?? `INV-${endDt.getFullYear()}-${String(endDt.getMonth() + 1).padStart(2, "0")}${String(endDt.getDate()).padStart(2, "0")}`;
379
+ const outPath = opts.output ?? `invoice_${fmtDt(startDt)}_to_${fmtDt(endDt)}.pdf`;
380
+ const cur = company.currency ?? "USD";
381
+ const { totalHours, totalAmount } = await render(entries, rate, invDate, invNum, outPath, config.user, company, false, cur);
382
+ console.log(`${chalk.green("✓")} ${chalk.bold(outPath)} ${chalk.dim(`${totalHours.toFixed(1)} h · ${cur} ${fmtMoney(totalAmount)}`)}`);
383
+ }
384
+ // ── Entry point ─────────────────────────────────────────────────────────────
385
+ export function main() {
386
+ const program = new Command();
387
+ program
388
+ .name("invoice")
389
+ .description("Genera invoices PDF desde CSV de Jira Logged Time")
390
+ .version("1.0.0")
391
+ .action(async () => {
392
+ try {
393
+ await runInteractive();
394
+ }
395
+ catch (err) {
396
+ if (err instanceof Error && err.message.includes("User force closed")) {
397
+ console.log(chalk.dim("\nSaliendo..."));
398
+ process.exit(0);
399
+ }
400
+ throw err;
401
+ }
402
+ });
403
+ program
404
+ .command("generate")
405
+ .description("Modo directo (no interactivo)")
406
+ .argument("<csv>", "CSV exportado de Jira")
407
+ .option("--rate <number>", "Tarifa por hora (default: tarifa de la empresa)")
408
+ .option("--date <string>", "Fecha del invoice (default: hoy)")
409
+ .option("--number <string>", "Número de invoice")
410
+ .option("--output <string>", "Ruta del PDF de salida")
411
+ .option("--company <id>", "ID de la empresa")
412
+ .action(runDirect);
413
+ program.parse();
414
+ }
415
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { ContactInfo, BillToInfo } from "./types.js";
2
+ export declare const FROM: ContactInfo;
3
+ export declare const TO: BillToInfo;
4
+ export declare const DEFAULT_RATE = 30.2;
5
+ export declare const MAX_HOURS_PER_DAY = 8;
package/dist/config.js ADDED
@@ -0,0 +1,18 @@
1
+ // ── Tu información ──────────────────────────────────────────────────────────
2
+ export const FROM = {
3
+ name: "Ricardo Lara",
4
+ email: "riclara@gmail.com",
5
+ addr1: "Crr 13 # 19 – 90 T5 135",
6
+ addr2: "La Ceja – Ant, Colombia",
7
+ };
8
+ // ── Cliente por defecto ─────────────────────────────────────────────────────
9
+ export const TO = {
10
+ name: "Spectrio LLC",
11
+ addr1: "7624 Bald Cypress Pl",
12
+ addr2: "Tampa, FL 33614",
13
+ addr3: "United States",
14
+ };
15
+ // ── Tarifa y límites ────────────────────────────────────────────────────────
16
+ export const DEFAULT_RATE = 30.20; // USD por hora
17
+ export const MAX_HOURS_PER_DAY = 8.0; // tope diario facturable
18
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,MAAM,CAAC,MAAM,IAAI,GAAgB;IAC/B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,mBAAmB;IAC1B,KAAK,EAAE,yBAAyB;IAChC,KAAK,EAAE,yBAAyB;CACjC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,EAAE,GAAe;IAC5B,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,sBAAsB;IAC7B,KAAK,EAAE,iBAAiB;IACxB,KAAK,EAAE,eAAe;CACvB,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,eAAe;AAClD,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,CAAC,yBAAyB"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { main } from "./cli.js";
3
+ main();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,IAAI,EAAE,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Parsea CSVs exportados de Jira Logged Time.
3
+ * Soporta dos formatos:
4
+ * - pivot: una columna por fecha (ej. 05/Jan/26, 06/Jan/26 ...)
5
+ * - date_col: columna 'Date' con rangos (ej. 19/Jan/26 to 30/Jan/26)
6
+ */
7
+ import type { WorkEntry, CsvFormat } from "./types.js";
8
+ export declare function parse(path: string, maxHoursPerDay: number | null): {
9
+ entries: WorkEntry[];
10
+ format: CsvFormat;
11
+ };