initial release testing
This commit is contained in:
92
app/accounting/page.tsx
Normal file
92
app/accounting/page.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
import { createAccount, createManualJournalEntry } from "@/lib/actions";
|
||||
import { formatCurrency, formatDate } from "@/lib/format";
|
||||
import { getAccountBalances, getAccounts, getJournalEntries } from "@/lib/repository";
|
||||
|
||||
export default function AccountingPage() {
|
||||
const entries = getJournalEntries();
|
||||
const balances = getAccountBalances();
|
||||
const accounts = getAccounts();
|
||||
|
||||
return (
|
||||
<div className="grid">
|
||||
<section className="two-up">
|
||||
<article className="panel">
|
||||
<h2 className="section-title">Chart of Accounts</h2>
|
||||
<p className="section-copy">Seeded operational accounts are ready, and you can add your own accounts here.</p>
|
||||
<form action={createAccount} className="form-grid">
|
||||
<div className="form-row"><label htmlFor="account-code">Code</label><input className="input" id="account-code" name="code" required /></div>
|
||||
<div className="form-row"><label htmlFor="account-name">Name</label><input className="input" id="account-name" name="name" required /></div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="account-category">Category</label>
|
||||
<select className="select" id="account-category" name="category" defaultValue="expense">
|
||||
<option value="asset">Asset</option>
|
||||
<option value="liability">Liability</option>
|
||||
<option value="equity">Equity</option>
|
||||
<option value="revenue">Revenue</option>
|
||||
<option value="expense">Expense</option>
|
||||
</select>
|
||||
</div>
|
||||
<button className="button secondary" type="submit">Add Account</button>
|
||||
</form>
|
||||
</article>
|
||||
<article className="panel">
|
||||
<h2 className="section-title">Manual Journal Entry</h2>
|
||||
<p className="section-copy">Enter one line per row as `account code,debit,credit`. Debits and credits must balance.</p>
|
||||
<form action={createManualJournalEntry} className="form-grid">
|
||||
<div className="form-row"><label htmlFor="description">Description</label><input className="input" id="description" name="description" /></div>
|
||||
<div className="form-row"><label htmlFor="lines">Lines</label><textarea className="textarea" id="lines" name="lines" placeholder={"1000,250,0\n3000,0,250"} required /></div>
|
||||
<button className="button" type="submit">Post Journal Entry</button>
|
||||
</form>
|
||||
<div className="muted">
|
||||
Available accounts: {accounts.map((account) => `${account.code} ${account.name}`).join(" | ")}
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
<section className="panel">
|
||||
<h2 className="section-title">Account Balances</h2>
|
||||
<p className="section-copy">Balances are rolled up from every journal line currently posted.</p>
|
||||
<div className="table-wrap">
|
||||
<table className="table">
|
||||
<thead><tr><th>Code</th><th>Account</th><th>Category</th><th>Debits</th><th>Credits</th><th>Balance</th></tr></thead>
|
||||
<tbody>
|
||||
{balances.map((balance) => (
|
||||
<tr key={balance.code}>
|
||||
<td>{balance.code}</td>
|
||||
<td>{balance.name}</td>
|
||||
<td>{balance.category}</td>
|
||||
<td>{formatCurrency(balance.debitTotal)}</td>
|
||||
<td>{formatCurrency(balance.creditTotal)}</td>
|
||||
<td>{formatCurrency(balance.balance)}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
<section className="panel">
|
||||
<h2 className="section-title">Accounting Journal</h2>
|
||||
<p className="section-copy">Purchase receipts and sales shipments automatically create operational journal entries.</p>
|
||||
<div className="table-wrap">
|
||||
<table className="table">
|
||||
<thead><tr><th>When</th><th>Type</th><th>Reference</th><th>Description</th><th>Lines</th></tr></thead>
|
||||
<tbody>
|
||||
{entries.length === 0 ? (
|
||||
<tr><td colSpan={5} className="muted">Journal entries appear after PO receipts and SO shipments.</td></tr>
|
||||
) : (
|
||||
entries.map((entry) => (
|
||||
<tr key={entry.id}>
|
||||
<td>{formatDate(entry.createdAt)}</td>
|
||||
<td>{entry.entryType}</td>
|
||||
<td>{entry.referenceType} #{entry.referenceId ?? "n/a"}</td>
|
||||
<td>{entry.description}</td>
|
||||
<td>{entry.lines.map((line, index) => <div key={`${entry.id}-${index}`} className="muted">{line.accountCode} {line.accountName}: {formatCurrency(line.debit)} / {formatCurrency(line.credit)}</div>)}</td>
|
||||
</tr>
|
||||
))
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user