RJBULK-APP/lib/delivery-notes.ts

79 lines
2.5 KiB
TypeScript
Raw Normal View History

import { pbList } from "./pocketbase";
import { DELIVERY_STATUSES } from "./types";
export interface DeliveryNoteInput {
number: string;
date: string;
customer: string;
vehicle_registration?: string;
qty_litres_supplied: number;
plant_dispensing?: string;
status?: string;
price_per_litre?: number;
total_value?: number;
pricing_source?: string;
}
export async function getLatestNoteNumber(token: string): Promise<string> {
const res = await pbList<any>("delivery_notes", { perPage: 500, fields: "number" }, token);
if (res.items.length === 0) return "1";
// Find the highest numeric value across all notes, regardless of any prefix.
// Preserves prefix (e.g. "DN-001" -> "DN-002") and pads to the same width.
let bestPrefix = "";
let bestNum = 0;
let bestWidth = 1;
for (const n of res.items) {
const raw = (n.number || "").trim();
if (!raw) continue;
const m = raw.match(/^(\D*)(\d+)$/);
if (!m) continue;
const num = parseInt(m[2], 10);
if (num > bestNum) {
bestPrefix = m[1];
bestNum = num;
bestWidth = m[2].length;
}
}
if (bestNum === 0) return "1";
const next = bestNum + 1;
return bestPrefix + String(next).padStart(bestWidth, "0");
}
export async function getDefaultPrice(token: string): Promise<number> {
try {
const res = await pbList<any>("fuel_settings", { perPage: 1 }, token);
if (res.items.length > 0) return Number(res.items[0].default_price_per_litre) || 0;
} catch {}
return 0;
}
export async function getCustomerPriceForDate(
customerId: string,
date: string,
token: string,
): Promise<{ price: number; source: string }> {
const d = new Date(date);
if (isNaN(d.getTime())) return { price: await getDefaultPrice(token), source: "default" };
const y = d.getFullYear();
const m = d.getMonth() + 1;
try {
const filter = `customer = "${customerId}" && year = ${y} && month = ${m}`;
const res = await pbList<any>("customer_pricing", { perPage: 1, filter }, token);
if (res.items.length > 0) {
const row = res.items[0];
const price = row.special_price ?? row.price_per_litre;
return { price: Number(price) || 0, source: row.special_price != null ? "special" : "monthly" };
}
} catch {}
return { price: await getDefaultPrice(token), source: "default" };
}
export function cleanEmpty(obj: any) {
const out: any = {};
for (const [k, v] of Object.entries(obj)) {
if (v === "" || v === null || v === undefined) continue;
out[k] = v;
}
return out;
}