diff --git a/Dockerfile b/Dockerfile
index e35fa07..1131bbf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -15,6 +15,10 @@ COPY . .
ARG NEXT_PUBLIC_POCKETBASE_URL
ENV NEXT_PUBLIC_POCKETBASE_URL=${NEXT_PUBLIC_POCKETBASE_URL}
+# WFDASH address the invoice match calls (overridable per phone in Settings)
+ARG NEXT_PUBLIC_WFDASH_URL=https://wfdash.apphub.co.za
+ENV NEXT_PUBLIC_WFDASH_URL=${NEXT_PUBLIC_WFDASH_URL}
+
# Generate PWA icons
RUN node scripts/generate-icons.js
diff --git a/app/settings/page.tsx b/app/settings/page.tsx
index d33a0f2..3fad176 100644
--- a/app/settings/page.tsx
+++ b/app/settings/page.tsx
@@ -6,6 +6,7 @@ import { useAuth } from '@/components/AuthProvider';
import BottomNav from '@/components/BottomNav';
import { getSettings, saveSettings, logout } from '@/lib/pocketbase';
import { AppSettings, DEFAULT_SETTINGS } from '@/lib/types';
+import { DEFAULT_WFDASH_URL } from '@/lib/invoiceCheck';
import { cn } from '@/lib/utils';
import { setDarkMode, applyDarkMode } from '@/lib/theme';
import {
@@ -305,7 +306,7 @@ export default function SettingsPage() {
Invoice check
- Adds a Check invoice button after you photograph an invoice. Only advises; nothing else changes.
+ After you photograph an invoice, items that match it exactly are marked collected (you can undo). Anything unsure is left for you.
{settings.aiCheckEnabled && (
- WFDASH address
+ WFDASH address (leave empty to use the default)
updateSetting('aiCheckUrl', e.target.value.trim())}
- placeholder="https://your-wfdash-address"
+ placeholder={process.env.NEXT_PUBLIC_WFDASH_URL || DEFAULT_WFDASH_URL}
className="mt-1 w-full h-11 rounded-xl border border-[rgba(38,37,30,0.15)] bg-white px-3 text-[14px]"
/>
diff --git a/lib/invoiceCheck.ts b/lib/invoiceCheck.ts
index a631caa..b164317 100644
--- a/lib/invoiceCheck.ts
+++ b/lib/invoiceCheck.ts
@@ -2,10 +2,13 @@
// everything assigned to this driver at that supplier. Exact matches (same
// product, invoice quantity = ordered quantity) are marked collected through
// the same writes the bulk-collect button uses, and can be undone.
-// Off unless the driver switches it on in Settings → Beta.
+// On by default; a driver can switch it off in Settings → Beta.
import { pb, getSettings, updateStockCollectionStatus } from './pocketbase';
+/** Used when neither the phone's setting nor the build sets an address. */
+export const DEFAULT_WFDASH_URL = 'https://wfdash.apphub.co.za';
+
export interface MatchedLine {
id: string;
kind: 'customer' | 'stock';
@@ -33,11 +36,11 @@ export interface InvoiceMatchResult {
/** Fired by the PO buttons; InvoiceMatchHost (once per page) does the work. */
export const RUN_EVENT = 'invoice-match:run';
-/** The WFDASH address to call, or '' when the helper is off or not set up. */
+/** The WFDASH address to call, or '' when the driver switched the helper off. */
export function invoiceCheckBase(): string {
const s = getSettings();
if (!s.aiCheckEnabled) return '';
- const url = (s.aiCheckUrl || process.env.NEXT_PUBLIC_WFDASH_URL || '').trim();
+ const url = (s.aiCheckUrl || process.env.NEXT_PUBLIC_WFDASH_URL || DEFAULT_WFDASH_URL).trim();
return url.replace(/\/+$/, '');
}
diff --git a/lib/pocketbase.ts b/lib/pocketbase.ts
index e6a8873..eec8b20 100644
--- a/lib/pocketbase.ts
+++ b/lib/pocketbase.ts
@@ -1,5 +1,6 @@
import PocketBase from 'pocketbase';
import {
+ AI_CHECK_DEFAULT_VERSION,
AppSettings,
DEFAULT_SETTINGS,
OrderItem,
@@ -914,7 +915,16 @@ export const getSettings = (): AppSettings => {
const saved = localStorage.getItem(SETTINGS_KEY);
if (saved) {
try {
- return { ...DEFAULT_SETTINGS, ...JSON.parse(saved) };
+ const stored = JSON.parse(saved) as Partial;
+ const settings: AppSettings = { ...DEFAULT_SETTINGS, ...stored };
+ // Phones saved while the invoice match was off by default: switch it
+ // on once. Saved back so a driver's later "off" is kept.
+ if ((stored.aiCheckDefaultVersion ?? 0) < AI_CHECK_DEFAULT_VERSION) {
+ settings.aiCheckEnabled = true;
+ settings.aiCheckDefaultVersion = AI_CHECK_DEFAULT_VERSION;
+ localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
+ }
+ return settings;
} catch {
return DEFAULT_SETTINGS;
}
diff --git a/lib/types.ts b/lib/types.ts
index a9bae88..c9ab228 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -264,12 +264,19 @@ export interface AppSettings {
darkMode: boolean;
fontSize: 'small' | 'normal' | 'large';
offlineMode: boolean;
- /** Beta: show a "Check invoice" helper on POs. Off by default; changes nothing else. */
+ /** Beta: match an invoice photo and collect exact matches. On by default. */
aiCheckEnabled: boolean;
- /** WFDASH base URL the helper calls, e.g. https://wfdash.example.com */
+ /** WFDASH base URL the helper calls; empty uses the built-in address. */
aiCheckUrl: string;
+ /**
+ * Bumped when the invoice match default changes. A phone saved before the
+ * match became default-on gets it switched on once; a later "off" sticks.
+ */
+ aiCheckDefaultVersion: number;
}
+export const AI_CHECK_DEFAULT_VERSION = 1;
+
export const DEFAULT_SETTINGS: AppSettings = {
locationInterval: 60,
minimumAccuracy: 50,
@@ -277,8 +284,9 @@ export const DEFAULT_SETTINGS: AppSettings = {
darkMode: false,
fontSize: 'normal',
offlineMode: false,
- aiCheckEnabled: false,
+ aiCheckEnabled: true,
aiCheckUrl: '',
+ aiCheckDefaultVersion: AI_CHECK_DEFAULT_VERSION,
};
export const PROBLEM_TYPES = [