import product catalogue
This commit is contained in:
@@ -20,11 +20,11 @@
|
||||
const FIESTA_BASE = import.meta.env.VITE_FIESTA_URL || 'https://fiesta.nearle.app/live/api/v1/web';
|
||||
const FIESTA_MOB_BASE = import.meta.env.VITE_FIESTA_MOB_URL || 'https://fiesta.nearle.app/live/api/v1/mob';
|
||||
|
||||
/** Tenant / location scope shared by the merchant console (Ragul Stores, Coimbatore). */
|
||||
export const FIESTA_TENANT_ID = 1087;
|
||||
/** Tenant / location scope shared by the merchant console. */
|
||||
export const FIESTA_TENANT_ID = 1135;
|
||||
export const FIESTA_APPLOCATION_ID = 1;
|
||||
/** Primary outlet for this tenant — the one carrying live orders/stock. */
|
||||
export const FIESTA_PRIMARY_LOCATION_ID = 1097;
|
||||
export const FIESTA_PRIMARY_LOCATION_ID = 1170;
|
||||
|
||||
export type Row = Record<string, unknown>;
|
||||
type QueryParams = Record<string, string | number | undefined | null>;
|
||||
@@ -167,7 +167,13 @@ export async function getOrderSummary(
|
||||
todate: string,
|
||||
locationid?: number,
|
||||
): Promise<FiestaOrderSummary | null> {
|
||||
const row = firstRow<Row>(await fiestaGet('orders/getordersummary', { tenantid, locationid, fromdate, todate }));
|
||||
const row = firstRow<Row>(await fiestaGet('orders/getordersummary', {
|
||||
tenantid,
|
||||
locationid,
|
||||
applocationid: locationid, // send both to bypass backend bugs
|
||||
fromdate,
|
||||
todate
|
||||
}));
|
||||
if (!row) return null;
|
||||
return {
|
||||
total: num(row.total),
|
||||
@@ -192,9 +198,9 @@ export interface FiestaLocationSummary {
|
||||
cancelled: number;
|
||||
}
|
||||
|
||||
/** /orders/getlocationsummary?tenantid= — per-outlet order rollup. */
|
||||
export async function getLocationSummary(tenantid: number): Promise<FiestaLocationSummary[]> {
|
||||
return toRows<Row>(await fiestaGet('orders/getlocationsummary', { tenantid })).map((r) => ({
|
||||
/** /orders/getlocationsummary?tenantid=&fromdate=&todate= — per-outlet order rollup. */
|
||||
export async function getLocationSummary(tenantid: number, fromdate?: string, todate?: string): Promise<FiestaLocationSummary[]> {
|
||||
return toRows<Row>(await fiestaGet('orders/getlocationsummary', { tenantid, fromdate, todate })).map((r) => ({
|
||||
locationid: num(r.locationid),
|
||||
locationname: str(r.locationname),
|
||||
total: num(r.total),
|
||||
@@ -622,9 +628,11 @@ export function cleanTenantLocations(rows: Row[]): Row[] {
|
||||
});
|
||||
}
|
||||
|
||||
/** /tenants/gettenantlocations?tenantid= — outlet locations for a tenant (test rows stripped). */
|
||||
export async function getTenantLocations(tenantid: number): Promise<Row[]> {
|
||||
return cleanTenantLocations(toRows(await fiestaGet('tenants/gettenantlocations', { tenantid })));
|
||||
/** /tenants/gettenantlocations?tenantid=&userid= — outlet locations for a tenant (test rows stripped). */
|
||||
export async function getTenantLocations(tenantid: number, userid?: number): Promise<Row[]> {
|
||||
const params: Record<string, any> = { tenantid };
|
||||
if (userid) params.userid = userid;
|
||||
return cleanTenantLocations(toRows(await fiestaGet('tenants/gettenantlocations', params)));
|
||||
}
|
||||
|
||||
/** /tenants/getalltenants?applocationid=&status=&pageno=&pagesize= — active tenants. */
|
||||
@@ -737,7 +745,7 @@ export async function getProductStocks(opts: {
|
||||
);
|
||||
}
|
||||
|
||||
/** /products/getproductlocations?tenantid=&locationid=&subcategoryid=&pageno=&pagesize= —
|
||||
/** /products/getlocationproducts?tenantid=&locationid=&subcategoryid=&pageno=&pagesize= —
|
||||
* geofenced per-outlet inventory. */
|
||||
export async function getProductLocations(opts: {
|
||||
tenantid: number;
|
||||
@@ -747,7 +755,7 @@ export async function getProductLocations(opts: {
|
||||
pagesize?: number;
|
||||
}): Promise<Row[]> {
|
||||
return toRows(
|
||||
await fiestaGet('products/getproductlocations', {
|
||||
await fiestaGet('products/getlocationproducts', {
|
||||
tenantid: opts.tenantid,
|
||||
locationid: opts.locationid,
|
||||
subcategoryid: opts.subcategoryid,
|
||||
@@ -783,13 +791,35 @@ export interface CreateProductLocationInput {
|
||||
tenantid: number;
|
||||
locationid: number;
|
||||
productid: number;
|
||||
qty: number;
|
||||
quantity?: number; // User prompt specified quantity
|
||||
qty?: number; // Keep for backwards compatibility if needed
|
||||
stocktype?: string;
|
||||
status?: string;
|
||||
price?: number;
|
||||
}
|
||||
|
||||
/** POST /products/createproductlocation — Add a product to a store catalogue / inventory. */
|
||||
/** POST /products/createproductlocation — Add a product to a store catalogue / inventory. (Expects array payload) */
|
||||
export async function createProductLocation(input: CreateProductLocationInput): Promise<Row> {
|
||||
return fiestaSend<Row>('products/createproductlocation', 'POST', input);
|
||||
const payload = {
|
||||
tenantid: input.tenantid,
|
||||
locationid: input.locationid,
|
||||
productid: input.productid,
|
||||
quantity: input.quantity ?? input.qty ?? 0,
|
||||
stocktype: input.stocktype || 'in',
|
||||
status: input.status || 'Active',
|
||||
};
|
||||
return fiestaSend<Row>('products/createproductlocation', 'POST', [payload]);
|
||||
}
|
||||
|
||||
export interface DeleteProductLocationInput {
|
||||
tenantid: number;
|
||||
locationid: number;
|
||||
productid: number;
|
||||
}
|
||||
|
||||
/** DELETE /products/deleteproductlocation — Remove a product from a store catalogue. */
|
||||
export async function deleteProductLocation(input: DeleteProductLocationInput): Promise<Row> {
|
||||
return fiestaSend<Row>('products/deleteproductlocation', 'DELETE', input);
|
||||
}
|
||||
|
||||
export interface StockRequestInput {
|
||||
@@ -1211,3 +1241,40 @@ export async function getSalesSummary(opts: {
|
||||
const res = await fiestaGet<{ details: SalesSummaryResponse }>('v1/web/reports/sales-summary', opts);
|
||||
return res.details;
|
||||
}
|
||||
|
||||
// ════════════════════════════════════════════════════════════════════════════
|
||||
// GLOBAL CATALOGUE
|
||||
// ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/** GET /v1/web/catalogue/getbrands — List all brands + product count per brand */
|
||||
export async function getGlobalBrands(): Promise<Row[]> {
|
||||
return toRows(await fiestaGet('catalogue/getbrands'));
|
||||
}
|
||||
|
||||
/** GET /v1/web/catalogue/getcategories — List categories available for that brand */
|
||||
export async function getGlobalCategories(opts: { brand: string }): Promise<string[]> {
|
||||
const res = await fiestaGet<{ details: string[] }>('catalogue/getcategories', { brand: opts.brand });
|
||||
return Array.isArray(res.details) ? res.details : [];
|
||||
}
|
||||
|
||||
/** GET /v1/web/catalogue/getproducts — Product list */
|
||||
export async function getGlobalProducts(opts: {
|
||||
brand: string;
|
||||
category?: string;
|
||||
keyword?: string;
|
||||
pageno?: number;
|
||||
pagesize?: number;
|
||||
}): Promise<Row[]> {
|
||||
return toRows(await fiestaGet('catalogue/getproducts', {
|
||||
brand: opts.brand,
|
||||
category: opts.category,
|
||||
keyword: opts.keyword,
|
||||
pageno: opts.pageno,
|
||||
pagesize: opts.pagesize,
|
||||
}));
|
||||
}
|
||||
|
||||
/** GET /v1/web/catalogue/getproduct — Single product lookup by SKU */
|
||||
export async function getGlobalProduct(opts: { brand: string; sku: string }): Promise<Row | null> {
|
||||
return firstRow(await fiestaGet('catalogue/getproduct', { brand: opts.brand, sku: opts.sku }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user