| Server IP : 173.209.174.21 / Your IP : 216.73.216.89 Web Server : Apache/2.4.58 (Ubuntu) System : Linux wcfs-server 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64 User : nodor ( 1000) PHP Version : 8.3.6 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/wcfs/NAOPOS/src/lib/ |
Upload File : |
import { ReportCategory } from "@/types/sales";
const API_BASE = (import.meta.env.VITE_POS_API_BASE_URL || "/api").replace(
/\/$/,
"",
);
export interface QuickButtonConfig {
id: string;
label: string;
shortLabel: string;
taxable: boolean;
taxRate?: number;
reportCategory: ReportCategory;
}
export interface PosSettings {
groceryTaxRate: number;
quickButtons: QuickButtonConfig[];
}
export const defaultQuickButtons: QuickButtonConfig[] = [
{
id: "unleaded",
label: "Unleaded",
shortLabel: "GAS",
taxable: true,
reportCategory: "Unleaded",
},
{
id: "unleaded-plus",
label: "Unleaded Plus",
shortLabel: "GAS+",
taxable: true,
reportCategory: "Unleaded Plus",
},
{
id: "diesel",
label: "Diesel",
shortLabel: "DSL",
taxable: true,
reportCategory: "Diesel",
},
{
id: "off-road-diesel",
label: "Off Road Diesel",
shortLabel: "ORD",
taxable: false,
reportCategory: "Off Road Diesel",
},
{
id: "hardware",
label: "Hardware",
shortLabel: "HDW",
taxable: true,
reportCategory: "Hardware",
},
{
id: "oil",
label: "Oil",
shortLabel: "OIL",
taxable: true,
reportCategory: "Oil",
},
];
export const defaultPosSettings: PosSettings = {
groceryTaxRate: 2,
quickButtons: defaultQuickButtons,
};
const reportCategoryOptions: ReportCategory[] = [
"Taxable",
"Non-Taxable",
"Unleaded",
"Unleaded Plus",
"Diesel",
"Off Road Diesel",
"Oil",
"Hardware",
"Other",
];
export const reportBuckets = reportCategoryOptions;
function normalizeQuickButton(
button: Partial<QuickButtonConfig>,
index: number,
fallback: QuickButtonConfig,
): QuickButtonConfig {
return {
id: button.id || fallback.id || `button-${index}`,
label: button.label || fallback.label || "Item",
shortLabel: button.shortLabel || fallback.shortLabel || "BTN",
taxable: Boolean(button.taxable),
taxRate:
typeof button.taxRate === "number" && !Number.isNaN(button.taxRate)
? button.taxRate
: fallback.taxRate,
reportCategory: reportCategoryOptions.includes(
button.reportCategory as ReportCategory,
)
? (button.reportCategory as ReportCategory)
: fallback.reportCategory,
};
}
export function normalizePosSettings(
value: Partial<PosSettings> | null | undefined,
): PosSettings {
const quickButtonsSource =
value?.quickButtons && value.quickButtons.length > 0
? value.quickButtons
: defaultQuickButtons;
return {
groceryTaxRate:
typeof value?.groceryTaxRate === "number" &&
!Number.isNaN(value.groceryTaxRate)
? value.groceryTaxRate
: defaultPosSettings.groceryTaxRate,
quickButtons: quickButtonsSource.map((button, index) =>
normalizeQuickButton(
button,
index,
defaultQuickButtons[index] ||
defaultQuickButtons[defaultQuickButtons.length - 1],
),
),
};
}
export async function loadPosSettings(): Promise<PosSettings | null> {
try {
const response = await fetch(`${API_BASE}/settings.php`);
if (!response.ok) return null;
const data = (await response.json()) as Partial<PosSettings>;
return normalizePosSettings(data);
} catch (error) {
console.error("Failed to load POS settings", error);
return null;
}
}
export async function savePosSettings(settings: PosSettings): Promise<boolean> {
try {
const response = await fetch(`${API_BASE}/settings.php`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(settings),
});
return response.ok;
} catch (error) {
console.error("Failed to save POS settings", error);
return false;
}
}