Files
cross-financial-management/src/modules/gl/glAccounts.controller.ts
T
Joshua OosthuizenandClaude Sonnet 5 b137176c40 Add Stock catalog (items/warehouses) and fix session persistence
Stock is scoped to a catalog + cost centers only, per direction that
physical GRV/stock-take/recipe transactions belong in an external
system (Matrix), not this accounting app. Stock Control/GRN/Variance/
PPV GL accounts are now plain postable accounts rather than locked
control accounts.

Also fixes session loss on page refresh: auth stores now persist to
localStorage, and ProtectedRoute waits for rehydration before deciding
to redirect to login.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JWqiUSojMLUoN7mrJqdEbN
2026-09-04 10:35:04 +02:00

44 lines
1.7 KiB
TypeScript

import { Request, Response } from 'express';
import { z } from 'zod';
import * as glAccountsService from './glAccounts.service';
const glAccountTypeSchema = z.enum(['ASSET', 'LIABILITY', 'EQUITY', 'INCOME', 'EXPENSE']);
const debitCreditSchema = z.enum(['DEBIT', 'CREDIT']);
const controlAccountTypeSchema = z.enum(['AR', 'AP', 'TAX_OUTPUT', 'TAX_INPUT', 'BANK', 'RETAINED_EARNINGS']);
export const createGLAccountSchema = z.object({
accountName: z.string().min(1),
accountType: glAccountTypeSchema,
normalBalance: debitCreditSchema,
isControlAccount: z.boolean().optional(),
controlType: controlAccountTypeSchema.optional(),
isPostable: z.boolean().optional(),
segmentSelections: z
.array(z.object({ segmentDefId: z.number().int(), segmentValueId: z.number().int() }))
.min(1),
});
export const listGLAccountsQuerySchema = z.object({
branchScope: z.string().optional(),
accountType: glAccountTypeSchema.optional(),
});
export async function createGLAccountHandler(req: Request, res: Response): Promise<void> {
const input = req.body as z.infer<typeof createGLAccountSchema>;
res.status(201).json(await glAccountsService.createGLAccount(input));
}
export async function listGLAccountsHandler(req: Request, res: Response): Promise<void> {
const { accountType } = req.query as unknown as z.infer<typeof listGLAccountsQuerySchema>;
res.json(await glAccountsService.listGLAccounts(req.branchScope!, accountType));
}
export async function getGLAccountHandler(req: Request, res: Response): Promise<void> {
const account = await glAccountsService.getGLAccountByCode(req.params.accountCode);
if (!account) {
res.status(404).json({ error: 'GL account not found' });
return;
}
res.json(account);
}