stock request
This commit is contained in:
@@ -208,11 +208,18 @@ export async function checkEmailRequest(email: string): Promise<boolean> {
|
||||
/** Find a user in the tenant user list by email or authname (case-insensitive). */
|
||||
export function matchTenantUser(users: Row[], email: string): Row | null {
|
||||
const target = email.toLowerCase();
|
||||
const prefix = target.split('@')[0] + '@';
|
||||
|
||||
return (
|
||||
users.find(
|
||||
(u) =>
|
||||
str(u[RESPONSE_FIELDS.email]).toLowerCase() === target ||
|
||||
str(u.authname).toLowerCase() === target,
|
||||
str(u.authname).toLowerCase() === target
|
||||
) ??
|
||||
users.find(
|
||||
(u) =>
|
||||
str(u[RESPONSE_FIELDS.email]).toLowerCase().startsWith(prefix) ||
|
||||
str(u.authname).toLowerCase().startsWith(prefix)
|
||||
) ?? null
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1029,6 +1029,10 @@ export interface CreateTenantLocationInput {
|
||||
latitude?: string;
|
||||
longitude?: string;
|
||||
status?: string;
|
||||
moduleid?: number;
|
||||
applocationid?: number;
|
||||
partnerid?: number;
|
||||
roleid?: number;
|
||||
}
|
||||
|
||||
/** POST /tenants/createtenantlocation — Create a new store location under a tenant. */
|
||||
@@ -1043,6 +1047,8 @@ export interface UpdateTenantLocationInput {
|
||||
contactno?: string;
|
||||
email?: string;
|
||||
status?: string;
|
||||
suburb?: string;
|
||||
city?: string;
|
||||
}
|
||||
|
||||
/** PUT /tenants/updatetenantlocation — Update store location details/status. */
|
||||
@@ -1136,3 +1142,71 @@ export async function reassignDeliveries(opts: {
|
||||
return fiestaSend<Row>('riders/reassigndeliveries', 'POST', opts);
|
||||
}
|
||||
|
||||
/** POST /v1/web/tenants/createlocation — Create a new tenant location (outlet). */
|
||||
export async function createLocation(opts: {
|
||||
tenantid: number;
|
||||
locationname: string;
|
||||
suburb: string;
|
||||
contactno?: string;
|
||||
status?: string;
|
||||
}): Promise<Row> {
|
||||
// Use fiestaSend, note that we include /v1/web explicitly here as the FIESTA_BASE is likely just the root.
|
||||
// Wait, let's look at FIESTA_BASE in the file.
|
||||
// Actually, I'll just use the full endpoint path.
|
||||
return fiestaSend<Row>('v1/web/tenants/createlocation', 'POST', opts);
|
||||
}
|
||||
|
||||
/** PUT /v1/web/tenants/updatelocation — Update an existing tenant location (outlet). */
|
||||
export async function updateLocation(opts: {
|
||||
tenantid: number;
|
||||
locationid: number;
|
||||
locationname?: string;
|
||||
suburb?: string;
|
||||
contactno?: string;
|
||||
status?: string;
|
||||
}): Promise<Row> {
|
||||
return fiestaSend<Row>('v1/web/tenants/updatelocation', 'PUT', opts);
|
||||
}
|
||||
|
||||
/** DELETE /v1/web/tenants/deletelocation — Delete an existing tenant location (outlet). */
|
||||
export async function deleteLocation(opts: {
|
||||
tenantid: number;
|
||||
locationid: number;
|
||||
}) {
|
||||
const qs = new URLSearchParams({
|
||||
tenantid: String(opts.tenantid),
|
||||
locationid: String(opts.locationid),
|
||||
}).toString();
|
||||
return await fiestaSend(`tenants/deletelocation?${qs}`, 'POST');
|
||||
}
|
||||
|
||||
export interface SalesSummaryChartData {
|
||||
date: string;
|
||||
revenue: number;
|
||||
orders: number;
|
||||
}
|
||||
|
||||
export interface SalesSummaryTopLocation {
|
||||
locationname: string;
|
||||
revenue: number;
|
||||
}
|
||||
|
||||
export interface SalesSummaryResponse {
|
||||
totalRevenue: number;
|
||||
totalOrders: number;
|
||||
averageOrderValue: number;
|
||||
chartData: SalesSummaryChartData[];
|
||||
topLocations: SalesSummaryTopLocation[];
|
||||
}
|
||||
|
||||
/** GET /v1/web/reports/sales-summary — Fetches aggregated sales and revenue data. */
|
||||
export async function getSalesSummary(opts: {
|
||||
tenantid: number;
|
||||
locationid?: number;
|
||||
fromdate: string;
|
||||
todate: string;
|
||||
}): Promise<SalesSummaryResponse> {
|
||||
// Use fiestaGet wrapper which parses standard responses
|
||||
const res = await fiestaGet<{ details: SalesSummaryResponse }>('v1/web/reports/sales-summary', opts);
|
||||
return res.details;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
FIESTA_APPLOCATION_ID,
|
||||
FIESTA_PRIMARY_LOCATION_ID,
|
||||
getOrderSummary,
|
||||
getSalesSummary,
|
||||
getRevenueSummary,
|
||||
getTimeSeries,
|
||||
getLocationSummary,
|
||||
@@ -61,6 +62,7 @@ import {
|
||||
CreateTenantLocationInput,
|
||||
updateTenantLocation,
|
||||
UpdateTenantLocationInput,
|
||||
deleteLocation,
|
||||
createProductLocation,
|
||||
createStockRequest,
|
||||
getStockRequests,
|
||||
@@ -73,6 +75,8 @@ import {
|
||||
export const fiestaKeys = {
|
||||
orderSummary: (tenantid: number, fromdate: string, todate: string, locationid?: number) =>
|
||||
['fiesta', 'orderSummary', tenantid, fromdate, todate, locationid ?? 0] as const,
|
||||
salesSummary: (tenantid: number, locationid: number | undefined, fromdate: string, todate: string) =>
|
||||
['fiesta', 'salesSummary', tenantid, locationid, fromdate, todate] as const,
|
||||
revenueSummary: (params: Record<string, unknown>) => ['fiesta', 'revenueSummary', params] as const,
|
||||
timeSeries: (params: Record<string, unknown>) => ['fiesta', 'timeSeries', params] as const,
|
||||
locationSummary: (tenantid: number) => ['fiesta', 'locationSummary', tenantid] as const,
|
||||
@@ -143,6 +147,19 @@ export function useFiestaTimeSeries(opts: {
|
||||
});
|
||||
}
|
||||
|
||||
export function useFiestaSalesSummary(opts: {
|
||||
tenantid: number;
|
||||
locationid?: number;
|
||||
fromdate: string;
|
||||
todate: string;
|
||||
}) {
|
||||
return useQuery({
|
||||
queryKey: fiestaKeys.salesSummary(opts.tenantid, opts.locationid, opts.fromdate, opts.todate),
|
||||
queryFn: () => getSalesSummary(opts),
|
||||
enabled: Boolean(opts.tenantid && opts.fromdate && opts.todate),
|
||||
});
|
||||
}
|
||||
|
||||
export function useFiestaLocationSummary(tenantid: number = FIESTA_TENANT_ID) {
|
||||
return useQuery({
|
||||
queryKey: fiestaKeys.locationSummary(tenantid),
|
||||
@@ -848,4 +865,15 @@ export function useLogin() {
|
||||
});
|
||||
}
|
||||
|
||||
export function useFiestaDeleteLocation() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (input: { tenantid: number; locationid: number }) => deleteLocation(input),
|
||||
onSuccess: (_, variables) => {
|
||||
qc.invalidateQueries({ queryKey: fiestaKeys.tenantLocations(variables.tenantid) });
|
||||
qc.invalidateQueries({ queryKey: fiestaKeys.locationSummary(variables.tenantid) });
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export { FIESTA_TENANT_ID, FIESTA_APPLOCATION_ID, FIESTA_PRIMARY_LOCATION_ID };
|
||||
|
||||
Reference in New Issue
Block a user