Update sales.ts
This commit is contained in:
1 parent
46d422fa2f
commit
713fa271b7
1 file changed
+42
-43
+42
-43
@@ -1,3 +1,4 @@
|
|||||||
|
// ... existing imports and interfaces ...
|
||||||
export interface SaleItem {
|
export interface SaleItem {
|
||||||
product_name: string;
|
product_name: string;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
@@ -6,7 +7,7 @@ export interface SaleItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Sale {
|
export interface Sale {
|
||||||
id?: string;
|
id?: string; // Make sure ID is optional in interface
|
||||||
customer_name: string | null;
|
customer_name: string | null;
|
||||||
amount_tendered: number;
|
amount_tendered: number;
|
||||||
user_name: string;
|
user_name: string;
|
||||||
@@ -19,12 +20,11 @@ export interface Sale {
|
|||||||
payment_type: string;
|
payment_type: string;
|
||||||
items: SaleItem[];
|
items: SaleItem[];
|
||||||
sale_date: string;
|
sale_date: string;
|
||||||
status: "completed" | "void" | "refunded";
|
status: string;
|
||||||
discount_type: string;
|
discount_type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const API_URL =
|
const API_URL = "https://firestore.googleapis.com/v1/projects/pos-system-22c92/databases/(default)/documents/sales";
|
||||||
"https://firestore.googleapis.com/v1/projects/pos-system-22c92/databases/(default)/documents/sales";
|
|
||||||
|
|
||||||
// Helper to unwrap Firestore values
|
// Helper to unwrap Firestore values
|
||||||
const unwrapValue = (field: any) => {
|
const unwrapValue = (field: any) => {
|
||||||
@@ -42,24 +42,22 @@ export const getSales = async (): Promise<Sale[]> => {
|
|||||||
let sales: Sale[] = [];
|
let sales: Sale[] = [];
|
||||||
let nextPageToken: string | null = null;
|
let nextPageToken: string | null = null;
|
||||||
|
|
||||||
// Loop to fetch ALL pages of data
|
|
||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
const queryParams = new URLSearchParams({ pageSize: "300" });
|
const queryParams = new URLSearchParams({ pageSize: '300' });
|
||||||
if (nextPageToken) queryParams.append("pageToken", nextPageToken);
|
if (nextPageToken) queryParams.append('pageToken', nextPageToken);
|
||||||
|
|
||||||
const response = await fetch(`${API_URL}?${queryParams.toString()}`);
|
const response = await fetch(`${API_URL}?${queryParams.toString()}`);
|
||||||
if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
|
if (!response.ok) throw new Error(`HTTP Error: ${response.status}`);
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
nextPageToken = data.nextPageToken || null;
|
nextPageToken = data.nextPageToken || null;
|
||||||
const rawList = data.documents || [];
|
const rawList = data.documents || [];
|
||||||
|
|
||||||
const batch = rawList.map((doc: any) => {
|
const batch = rawList.map((doc: any) => {
|
||||||
const id = doc.name ? doc.name.split("/").pop() : "unknown";
|
const id = doc.name ? doc.name.split('/').pop() : 'unknown';
|
||||||
const fields = doc.fields || {};
|
const fields = doc.fields || {};
|
||||||
|
|
||||||
// Unwrap Items Array manually since it's nested
|
|
||||||
const itemsWrapper = fields.items?.arrayValue?.values || [];
|
const itemsWrapper = fields.items?.arrayValue?.values || [];
|
||||||
const items: SaleItem[] = itemsWrapper.map((item: any) => ({
|
const items: SaleItem[] = itemsWrapper.map((item: any) => ({
|
||||||
product_name: unwrapValue(item.mapValue.fields.product_name),
|
product_name: unwrapValue(item.mapValue.fields.product_name),
|
||||||
@@ -72,22 +70,23 @@ export const getSales = async (): Promise<Sale[]> => {
|
|||||||
id,
|
id,
|
||||||
customer_name: unwrapValue(fields.customer_name),
|
customer_name: unwrapValue(fields.customer_name),
|
||||||
amount_tendered: unwrapValue(fields.amount_tendered) || 0,
|
amount_tendered: unwrapValue(fields.amount_tendered) || 0,
|
||||||
user_name: unwrapValue(fields.user_name) || "Unknown",
|
user_name: unwrapValue(fields.user_name) || 'Unknown',
|
||||||
tax_amount: unwrapValue(fields.tax_amount) || 0,
|
tax_amount: unwrapValue(fields.tax_amount) || 0,
|
||||||
refund_reason: unwrapValue(fields.refund_reason),
|
refund_reason: unwrapValue(fields.refund_reason),
|
||||||
total_amount: unwrapValue(fields.total_amount) || 0,
|
total_amount: unwrapValue(fields.total_amount) || 0,
|
||||||
discount_amount: unwrapValue(fields.discount_amount) || 0,
|
discount_amount: unwrapValue(fields.discount_amount) || 0,
|
||||||
change_due: unwrapValue(fields.change_due) || 0,
|
change_due: unwrapValue(fields.change_due) || 0,
|
||||||
refunded_at: unwrapValue(fields.refunded_at),
|
refunded_at: unwrapValue(fields.refunded_at),
|
||||||
payment_type: unwrapValue(fields.payment_type) || "Cash",
|
payment_type: unwrapValue(fields.payment_type) || 'Cash',
|
||||||
items,
|
items,
|
||||||
sale_date: unwrapValue(fields.sale_date),
|
sale_date: unwrapValue(fields.sale_date),
|
||||||
status: unwrapValue(fields.status) || "completed",
|
status: unwrapValue(fields.status) || 'completed',
|
||||||
discount_type: unwrapValue(fields.discount_type) || "None",
|
discount_type: unwrapValue(fields.discount_type) || 'None'
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
sales = [...sales, ...batch];
|
sales = [...sales, ...batch];
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch sales page:", error);
|
console.error("Failed to fetch sales page:", error);
|
||||||
throw error;
|
throw error;
|
||||||
@@ -97,36 +96,30 @@ export const getSales = async (): Promise<Sale[]> => {
|
|||||||
return sales;
|
return sales;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateSaleStatus = async (
|
export const updateSaleStatus = async (id: string, status: 'void' | 'refunded', reason: string): Promise<void> => {
|
||||||
id: string,
|
|
||||||
status: "void" | "refunded",
|
|
||||||
reason: string
|
|
||||||
): Promise<void> => {
|
|
||||||
const url = `${API_URL}/${id}?updateMask.fieldPaths=status&updateMask.fieldPaths=refund_reason&updateMask.fieldPaths=refunded_at`;
|
const url = `${API_URL}/${id}?updateMask.fieldPaths=status&updateMask.fieldPaths=refund_reason&updateMask.fieldPaths=refunded_at`;
|
||||||
const now = new Date().toISOString();
|
const now = new Date().toISOString();
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: "PATCH",
|
method: 'PATCH',
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
fields: {
|
fields: {
|
||||||
status: { stringValue: status },
|
status: { stringValue: status },
|
||||||
refund_reason: { stringValue: reason },
|
refund_reason: { stringValue: reason },
|
||||||
refunded_at: { timestampValue: now },
|
refunded_at: { timestampValue: now }
|
||||||
},
|
}
|
||||||
}),
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok)
|
if (!response.ok) throw new Error(`Failed to update sale status: ${response.status}`);
|
||||||
throw new Error(`Failed to update sale status: ${response.status}`);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createSale = async (sale: Sale): Promise<void> => {
|
// Updated to return string (The new ID)
|
||||||
|
export const createSale = async (sale: Sale): Promise<string> => {
|
||||||
const payload = {
|
const payload = {
|
||||||
fields: {
|
fields: {
|
||||||
customer_name: sale.customer_name
|
customer_name: sale.customer_name ? { stringValue: sale.customer_name } : { nullValue: null },
|
||||||
? { stringValue: sale.customer_name }
|
|
||||||
: { nullValue: null },
|
|
||||||
amount_tendered: { doubleValue: sale.amount_tendered },
|
amount_tendered: { doubleValue: sale.amount_tendered },
|
||||||
user_name: { stringValue: sale.user_name },
|
user_name: { stringValue: sale.user_name },
|
||||||
tax_amount: { doubleValue: sale.tax_amount },
|
tax_amount: { doubleValue: sale.tax_amount },
|
||||||
@@ -141,30 +134,36 @@ export const createSale = async (sale: Sale): Promise<void> => {
|
|||||||
discount_type: { stringValue: sale.discount_type },
|
discount_type: { stringValue: sale.discount_type },
|
||||||
items: {
|
items: {
|
||||||
arrayValue: {
|
arrayValue: {
|
||||||
values: sale.items.map((item) => ({
|
values: sale.items.map(item => ({
|
||||||
mapValue: {
|
mapValue: {
|
||||||
fields: {
|
fields: {
|
||||||
product_name: { stringValue: item.product_name },
|
product_name: { stringValue: item.product_name },
|
||||||
quantity: { integerValue: String(item.quantity) },
|
quantity: { integerValue: String(item.quantity) },
|
||||||
price: { doubleValue: item.price },
|
price: { doubleValue: item.price },
|
||||||
total: { doubleValue: item.total },
|
total: { doubleValue: item.total }
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
})),
|
}))
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const response = await fetch(API_URL, {
|
const response = await fetch(API_URL, {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
// @ts-ignore
|
|
||||||
const errText = await response.text();
|
const errText = await response.text();
|
||||||
throw new Error(`Failed to create sale: ${response.status}`);
|
throw new Error(`Failed to create sale: ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse response to get the ID
|
||||||
|
const data = await response.json();
|
||||||
|
// data.name is like "projects/.../documents/sales/DOCUMENT_ID"
|
||||||
|
const newId = data.name.split('/').pop();
|
||||||
|
|
||||||
|
return newId;
|
||||||
};
|
};
|
||||||
Reference in new issue
Block a user