Skip to content

Commit 08ba00a

Browse files
authored
Merge pull request #4 from bradydibble/claude/fix-sheets-export-error-PPxTw
Redesign Sheets export to normalized row format
2 parents 9a12834 + 5bcd35f commit 08ba00a

2 files changed

Lines changed: 45 additions & 14 deletions

File tree

src/lib/server/sheets.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,43 @@ async function getToken(credJson: string): Promise<string> {
1212
return token;
1313
}
1414

15+
async function sheetIsEmpty(
16+
spreadsheetId: string,
17+
range: string,
18+
token: string
19+
): Promise<boolean> {
20+
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}`;
21+
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
22+
if (!res.ok) return true;
23+
const body = await res.json();
24+
return !body.values || body.values.length === 0;
25+
}
26+
27+
export const HEADER_ROW = [
28+
'Date', 'Shift', 'Type', 'Calc ID',
29+
'Gross Tips', 'CC Fee Rate', 'CC Fees', 'Net Tips',
30+
'Kitchen %', 'Kitchen Pool', 'Liquor Sales', 'Bar Liquor %', 'Bar Pool', 'FOH Pool',
31+
'Name', 'Role', 'FOH Share', 'Bar Share', 'Kitchen Share', 'Total',
32+
];
33+
1534
/**
1635
* Append rows to a Google Sheet.
17-
* Values are plain strings/numbers; Sheets will auto-detect dates and numbers.
36+
* Writes the header row first only when the sheet is empty.
1837
*/
1938
export async function appendToSheet(
2039
spreadsheetId: string,
2140
sheetName: string,
22-
values: (string | number)[][],
41+
dataRows: (string | number)[][],
2342
credJson: string
2443
): Promise<void> {
2544
const token = await getToken(credJson);
26-
const range = encodeURIComponent(`'${sheetName}'`);
27-
const url = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}/values/${range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS`;
45+
const range = encodeURIComponent(`'${sheetName}'!A1`);
46+
const base = `https://sheets.googleapis.com/v4/spreadsheets/${spreadsheetId}`;
47+
48+
const empty = await sheetIsEmpty(spreadsheetId, range, token);
49+
const values = empty ? [HEADER_ROW, ...dataRows] : dataRows;
2850

51+
const url = `${base}/values/${range}:append?valueInputOption=USER_ENTERED&insertDataOption=INSERT_ROWS`;
2952
const res = await fetch(url, {
3053
method: 'POST',
3154
headers: {

src/routes/api/export/+server.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,13 @@ export const POST: RequestHandler = async ({ request, locals }) => {
2626
const credJson = process.env.GOOGLE_SERVICE_ACCOUNT_JSON;
2727
if (!credJson) error(400, 'GOOGLE_SERVICE_ACCOUNT_JSON env var not set.');
2828

29-
// Build the row matching PRD OR-8
30-
const headerRow = [
31-
'Date', 'Shift', 'Gross Tips', 'CC Fee Rate', 'CC Fees', 'Tips After Fees',
32-
'Kitchen %', 'Kitchen Pool', 'Liquor Sales', 'Bar Liquor %', 'Bar Pool', 'FOH Pool',
33-
...dists.map(d => d.name),
34-
];
29+
// Columns: Date, Shift, Type, Calc ID,
30+
// Gross Tips, CC Fee Rate, CC Fees, Net Tips,
31+
// Kitchen %, Kitchen Pool, Liquor Sales, Bar Liquor %, Bar Pool, FOH Pool,
32+
// Name, Role, FOH Share, Bar Share, Kitchen Share, Total
3533

36-
const dataRow = [
37-
calc.date, calc.shift,
34+
const summaryRow: (string | number)[] = [
35+
calc.date, calc.shift, 'summary', calc.id,
3836
formatCents(calc.gross_tips_cents),
3937
`${(calc.cc_fee_rate * 100).toFixed(1)}%`,
4038
formatCents(calc.cc_fees_cents),
@@ -45,14 +43,24 @@ export const POST: RequestHandler = async ({ request, locals }) => {
4543
`${(calc.bar_liquor_pct * 100).toFixed(0)}%`,
4644
formatCents(calc.bar_pool_cents),
4745
formatCents(calc.foh_pool_cents),
48-
...dists.map(d => formatCents(d.total_cents)),
46+
'', '', '', '', '', '',
4947
];
5048

49+
const staffRows: (string | number)[][] = dists.map(d => [
50+
calc.date, calc.shift, 'staff', calc.id,
51+
'', '', '', '', '', '', '', '', '', '',
52+
d.name, d.role,
53+
formatCents(d.foh_share_cents),
54+
formatCents(d.bar_pool_share_cents),
55+
formatCents(d.kitchen_share_cents),
56+
formatCents(d.total_cents),
57+
]);
58+
5159
try {
5260
await appendToSheet(
5361
spreadsheetId,
5462
settings.google_sheets_sheet_name || 'Tip History',
55-
[headerRow, dataRow],
63+
[summaryRow, ...staffRows],
5664
credJson
5765
);
5866
} catch (e) {

0 commit comments

Comments
 (0)