9cd21ce11e
- Add CLI package with commander.js for interacting with Bigcapital API - Implement listing commands for all modules: items, invoices, customers, vendors, bills, accounts, expenses, credit-notes, vendor-credits, payments, estimates, receipts, journals, inventory, tax-rates, warehouses, and users - Add comprehensive financial reports: balance-sheet, profit-loss, cashflow, trial-balance, general-ledger, journal, receivable-aging, payable-aging, customer-balance, vendor-balance, sales-by-items, purchases-by-items, inventory-valuation, and sales-tax-liability - Support configuration management for API key, base URL, and org ID - Add professional table formatting with chalk and cli-table3 - Include loading spinners and error handling Usage: bigcapital config set api-key <key> bigcapital items list bigcapital reports balance-sheet --from 2024-01-01 --to 2024-12-31 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
import { Command } from 'commander';
|
|
import chalk from 'chalk';
|
|
import ora from 'ora';
|
|
import { fetchVendorCredits } from '@bigcapital/sdk-ts';
|
|
import { createAuthenticatedFetcher } from '../config';
|
|
import { handleError } from '../utils/errors';
|
|
import { createTable, formatCurrency, formatDate, truncate, formatStatus } from '../utils/table';
|
|
|
|
export function createVendorCreditsCommand(): Command {
|
|
const command = new Command('vendor-credits')
|
|
.description('Manage vendor credits');
|
|
|
|
command
|
|
.command('list')
|
|
.description('List all vendor credits')
|
|
.option('-l, --limit <number>', 'Limit number of results per page', '50')
|
|
.option('-p, --page <number>', 'Page number', '1')
|
|
.option('-v, --vendor <id>', 'Filter by vendor ID')
|
|
.action(async (options) => {
|
|
const spinner = ora('Loading vendor credits...').start();
|
|
|
|
try {
|
|
const fetcher = createAuthenticatedFetcher();
|
|
|
|
const query = {
|
|
page: parseInt(options.page, 10),
|
|
pageSize: Math.min(parseInt(options.limit, 10), 100),
|
|
...(options.vendor && { vendorId: parseInt(options.vendor, 10) }),
|
|
};
|
|
|
|
const response = await fetchVendorCredits(fetcher, query);
|
|
|
|
spinner.stop();
|
|
|
|
const vendorCredits = (response as unknown as { vendorCredits: Array<{
|
|
id: number;
|
|
vendorCreditNumber?: string;
|
|
vendor?: { displayName?: string };
|
|
vendorCreditDate?: string;
|
|
total?: number;
|
|
balance?: number;
|
|
status?: string;
|
|
}> }).vendorCredits;
|
|
|
|
if (!vendorCredits || vendorCredits.length === 0) {
|
|
console.log(chalk.yellow('No vendor credits found.'));
|
|
return;
|
|
}
|
|
|
|
const pagination = (response as unknown as {
|
|
pagination?: { total: number; page: number; pageSize?: number; page_size?: number }
|
|
}).pagination;
|
|
if (pagination) {
|
|
const pageSize = pagination.pageSize || pagination.page_size || 10;
|
|
const totalPages = Math.ceil(pagination.total / pageSize);
|
|
console.log(chalk.gray(`\nPage ${pagination.page} of ${totalPages} (${pagination.total} total vendor credits)\n`));
|
|
}
|
|
|
|
const table = createTable(['ID', 'VC #', 'Vendor', 'Date', 'Total', 'Balance', 'Status']);
|
|
|
|
vendorCredits.forEach((vc) => {
|
|
table.push([
|
|
vc.id,
|
|
vc.vendorCreditNumber || '-',
|
|
truncate(vc.vendor?.displayName, 20),
|
|
formatDate(vc.vendorCreditDate),
|
|
formatCurrency(vc.total),
|
|
formatCurrency(vc.balance),
|
|
formatStatus(vc.status),
|
|
]);
|
|
});
|
|
|
|
console.log(table.toString());
|
|
|
|
if (pagination) {
|
|
const pageSize = pagination.pageSize || pagination.page_size || 10;
|
|
const totalPages = Math.ceil(pagination.total / pageSize);
|
|
if (pagination.page < totalPages) {
|
|
console.log(chalk.gray(`\nUse --page ${pagination.page + 1} to see more results`));
|
|
}
|
|
}
|
|
} catch (error) {
|
|
spinner.stop();
|
|
handleError(error);
|
|
}
|
|
});
|
|
|
|
return command;
|
|
}
|