From a83f436a083c23f7e1936eb38334daddf777e060 Mon Sep 17 00:00:00 2001 From: Bill Ballou Date: Sun, 4 Jan 2026 21:11:04 -0500 Subject: [PATCH] Split Attachment column into Invoice and Receipt fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add separate Invoice and Receipt columns to Bills table for clearer document organization - Update upload-attachment.sh to accept column parameter (defaults to Invoice, use Receipt for payment confirmations) - Update all documentation examples and workflows - Add receipt upload step to payment workflows - Update validation checklist to verify both fields 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- SKILL.md | 46 +++++++++++++++++++++++------------- scripts/upload-attachment.sh | 21 +++++++++------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/SKILL.md b/SKILL.md index 5664485..d329d9c 100644 --- a/SKILL.md +++ b/SKILL.md @@ -78,7 +78,8 @@ Python: `int(datetime(2025, 10, 1).timestamp())` | Status | Choice | "Open", "Partial", "Paid" | | Memo | Text | | | EntryTransaction | Ref:Transactions | Link to journal entry | -| Attachment | Attachments | Invoice/receipt files (use `["L", id]` format) | +| Invoice | Attachments | Vendor invoice document (use `["L", id]` format) | +| Receipt | Attachments | Payment receipt/confirmation (use `["L", id]` format) | | Amount | Formula | Sum of BillLines.Amount | | AmountPaid | Formula | Sum of BillPayments.Amount | | AmountDue | Formula | Amount - AmountPaid | @@ -219,12 +220,12 @@ add_records("TransactionLines", [ update_records("Bills", [{"id": 1, "fields": {"EntryTransaction": 1}}]) ``` -**Step 5: Upload Invoice Attachment (if available)** +**Step 5: Upload Invoice (if available)** -If an invoice PDF is available, upload and link it: +If an invoice PDF is available, upload and link it to the Invoice field: ```bash -# Get session token, then upload -./scripts/upload-attachment.sh invoice.pdf Bills 1 $TOKEN +# Get session token, then upload to Invoice field +bash /path/to/scripts/upload-attachment.sh invoice.pdf Bills 1 $TOKEN Invoice ``` Or for batch uploads, use a script (see Batch Operations). @@ -257,6 +258,9 @@ add_records("BillPayments", [{ # Step 4: Update bill status update_records("Bills", [{"id": 1, "fields": {"Status": "Paid"}}]) + +# Step 5: Upload receipt (if available) +bash /path/to/scripts/upload-attachment.sh receipt.pdf Bills 1 $TOKEN Receipt ``` ### Pay Bill via Owner Reimbursement @@ -288,6 +292,9 @@ add_records("BillPayments", [{ # Step 4: Update bill status update_records("Bills", [{"id": 1, "fields": {"Status": "Paid"}}]) + +# Step 5: Upload receipt (if available) +bash /path/to/scripts/upload-attachment.sh receipt.pdf Bills 1 $TOKEN Receipt ``` ### Reimburse Owner @@ -329,14 +336,17 @@ When invoice files are available, upload them after bill entry: 3. Loop: upload each file, link to corresponding bill ```bash -# Example batch upload pattern +# Example batch upload pattern for invoices TOKEN=$(request_session_token with write permission) for each (bill_id, invoice_path): curl -X POST -H "Authorization: Bearer $TOKEN" \ -F "file=@$invoice_path" \ https://grist-mcp.bballou.com/api/v1/attachments # Returns attachment_id - update_records("Bills", [{"id": bill_id, "fields": {"Attachment": ["L", attachment_id]}}]) + update_records("Bills", [{"id": bill_id, "fields": {"Invoice": ["L", attachment_id]}}]) + +# For receipts (after payment): + update_records("Bills", [{"id": bill_id, "fields": {"Receipt": ["L", attachment_id]}}]) ``` Example batch update: @@ -529,7 +539,8 @@ After entering bills, verify: - [ ] AP balance correct: `SELECT Balance FROM Accounts WHERE Code = '2000'` - [ ] Expense accounts increased appropriately - [ ] Vendor balances reflect unpaid bills -- [ ] Invoice attachments linked: `SELECT id, BillNumber FROM Bills WHERE Attachment IS NULL` +- [ ] Invoices attached: `SELECT id, BillNumber FROM Bills WHERE Invoice IS NULL` +- [ ] Receipts attached for paid bills: `SELECT id, BillNumber FROM Bills WHERE Status = 'Paid' AND Receipt IS NULL` ## Common Mistakes @@ -542,7 +553,7 @@ After entering bills, verify: | Missing EntryTransaction link | Always update Bill.EntryTransaction after creating journal entry | | Bill status not updated | Manually set Status to "Paid" after full payment | | Using string dates | Dates must be Unix timestamps (seconds), not strings | -| Missing invoice attachments | Upload invoices after bill entry if files available | +| Missing invoice/receipt | Upload invoice after bill entry, receipt after payment | ## Uploading Attachments @@ -561,23 +572,26 @@ Use `scripts/upload-attachment.sh` in this skill directory: ```bash # Get session token first (via MCP request_session_token tool) # Then run: -./scripts/upload-attachment.sh invoice.pdf Bills 13 - -# Or pass token directly: -./scripts/upload-attachment.sh invoice.pdf Bills 13 sess_abc123... +bash scripts/upload-attachment.sh invoice.pdf Bills 13 # Invoice column (default) +bash scripts/upload-attachment.sh invoice.pdf Bills 13 $TOKEN # With token +bash scripts/upload-attachment.sh receipt.pdf Bills 13 $TOKEN Receipt # Receipt column # Environment variable for custom endpoint: -GRIST_MCP_URL=https://custom.example.com ./scripts/upload-attachment.sh ... +GRIST_MCP_URL=https://custom.example.com bash scripts/upload-attachment.sh ... ``` -Run `./scripts/upload-attachment.sh` without arguments for full usage. +Run `bash scripts/upload-attachment.sh` without arguments for full usage. ### Linking Attachments Manually Grist attachment columns use format: `["L", attachment_id]` ```python -update_records("Bills", [{"id": 13, "fields": {"Attachment": ["L", 1]}}]) +# Link invoice to bill +update_records("Bills", [{"id": 13, "fields": {"Invoice": ["L", 1]}}]) + +# Link receipt to bill (after payment) +update_records("Bills", [{"id": 13, "fields": {"Receipt": ["L", 2]}}]) ``` ## Formula Columns (Auto-Calculated) diff --git a/scripts/upload-attachment.sh b/scripts/upload-attachment.sh index 664b75b..b4421b5 100755 --- a/scripts/upload-attachment.sh +++ b/scripts/upload-attachment.sh @@ -1,10 +1,11 @@ #!/bin/bash # upload-attachment.sh - Upload file and link to Grist record -# Usage: ./upload-attachment.sh [token] +# Usage: ./upload-attachment.sh
[token] [column] # # Examples: -# ./upload-attachment.sh invoice.pdf Bills 13 -# ./upload-attachment.sh receipt.jpg Bills 13 sess_abc123... +# ./upload-attachment.sh invoice.pdf Bills 13 # defaults to Invoice column +# ./upload-attachment.sh invoice.pdf Bills 13 sess_abc123... # with token +# ./upload-attachment.sh receipt.pdf Bills 13 sess_abc123... Receipt # specify column set -e @@ -12,17 +13,21 @@ FILE="$1" TABLE="$2" RECORD_ID="$3" TOKEN="$4" +COLUMN="${5:-Invoice}" # Default to Invoice column if [[ -z "$FILE" || -z "$TABLE" || -z "$RECORD_ID" ]]; then - echo "Usage: $0
[token]" + echo "Usage: $0
[token] [column]" echo "" echo "Arguments:" echo " file Path to file to upload" echo " table Grist table name (e.g., Bills)" echo " record_id Record ID to attach file to" echo " token Session token (optional, will prompt if not provided)" + echo " column Attachment column name (default: Invoice, use Receipt for payment receipts)" echo "" - echo "Example: $0 invoice.pdf Bills 13" + echo "Examples:" + echo " $0 invoice.pdf Bills 13 # Upload invoice" + echo " $0 receipt.pdf Bills 13 \$TOKEN Receipt # Upload receipt" exit 1 fi @@ -53,12 +58,12 @@ fi echo "Uploaded: attachment_id=$ATTACHMENT_ID" # Link to record via proxy -echo "Linking to $TABLE id=$RECORD_ID..." +echo "Linking to $TABLE id=$RECORD_ID column=$COLUMN..." LINK_RESPONSE=$(curl -s -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ - -d "{\"method\": \"update_records\", \"table\": \"$TABLE\", \"records\": [{\"id\": $RECORD_ID, \"fields\": {\"Attachment\": [\"L\", $ATTACHMENT_ID]}}]}" \ + -d "{\"method\": \"update_records\", \"table\": \"$TABLE\", \"records\": [{\"id\": $RECORD_ID, \"fields\": {\"$COLUMN\": [\"L\", $ATTACHMENT_ID]}}]}" \ "$BASE_URL/api/v1/proxy") echo "$LINK_RESPONSE" | jq . -echo "Done! Attachment $ATTACHMENT_ID linked to $TABLE record $RECORD_ID" +echo "Done! Attachment $ATTACHMENT_ID linked to $TABLE.$COLUMN record $RECORD_ID"