RJBULK-APP/lib/types.ts

148 lines
3.4 KiB
TypeScript
Raw Normal View History

/**
* PB-backed types. Foreign keys are TEXT (we use the related record's `id`
* and join with expand= at query time). Enum-like fields are TEXT and
* validated against `DeliveryStatus` / `StatementAction` below.
*/
export type ID = string;
export interface Customer {
id: ID;
name: string;
contact_number?: string;
email?: string;
address?: string;
vat_number?: string;
created?: string;
updated?: string;
}
export interface Supplier {
id: ID;
name: string;
contact_number?: string;
email?: string;
address?: string;
vat_number?: string;
created?: string;
updated?: string;
}
export type DeliveryStatus = "Pending" | "EFT" | "CASH" | "CARD";
export const DELIVERY_STATUSES: DeliveryStatus[] = [
"Pending",
"EFT",
"CASH",
"CARD",
];
/** A delivery note is "open" (awaiting payment) when status is Pending. */
export const OPEN_STATUSES: DeliveryStatus[] = ["Pending"];
/** Hard-coded tank / plant options — matches the legacy Flask app. */
export const TANK_OPTIONS = [
"Tank 2",
"Tank 3",
"Tank 4",
"Bouwser",
"Tank C",
"Tank B",
"RJ BULK",
] as const;
export type TankOption = (typeof TANK_OPTIONS)[number];
export type PricingSource = "special" | "monthly" | "default";
export const PRICING_SOURCES: PricingSource[] = ["special", "monthly", "default"];
/** Customer name used as the "Cash Customers" placeholder filter. */
export const CASH_CUSTOMER_NAME = "Cash Customers";
export interface DeliveryNote {
id: ID;
number: string;
date: string;
/** FK -> customers.id */
customer: ID;
vehicle_registration?: string;
qty_litres_supplied: number;
plant_dispensing?: string;
status?: DeliveryStatus | "";
/** Legacy status from the SQLite dump (Statement Viewed, Invoiced, etc.) — preserved for reference. */
old_status?: string;
price_per_litre?: number;
total_value?: number;
pricing_source?: PricingSource | "";
created?: string;
updated?: string;
/** When fetched with `expand=customer`, the customer record is here. */
expand?: { customer?: Customer };
}
export interface FuelPurchase {
id: ID;
/** FK -> suppliers.id */
supplier: ID;
purchase_qty: number;
purchase_price: number;
purchase_date: string;
created?: string;
updated?: string;
expand?: { supplier?: Supplier };
}
export interface CustomerPricing {
id: ID;
/** FK -> customers.id */
customer: ID;
year: number;
month: number; // 1-12
price_per_litre: number;
special_price?: number;
/** FK -> users.id */
created_by?: ID;
created?: string;
updated?: string;
expand?: { customer?: Customer };
}
export interface MonthlyPriceIncrease {
id: ID;
year: number;
month: number;
/** Actually stores cent amount. */
percentage_increase: number;
/** FK -> users.id */
applied_by?: ID;
created?: string;
updated?: string;
}
export interface FuelSettings {
id: ID;
default_price_per_litre: number;
statement_cc_email?: string;
statement_from_email?: string;
statement_email_password?: string;
statement_app_email?: string;
}
export type StatementAction = "Email Sent" | "Preview Generated";
export const STATEMENT_ACTIONS: StatementAction[] = ["Email Sent", "Preview Generated"];
export interface StatementLogEntry {
id: ID;
action: StatementAction;
details?: string;
/** FK -> users.id */
actor?: ID;
created?: string;
updated?: string;
}
export interface AppUser {
id: ID;
email: string;
name?: string;
verified?: boolean;
}