返回 Skills
anthropics/knowledge-work-plugins· Apache-2.0 内容可用

month-end-prep

Walks an SMB owner through month-end close: reconciles QuickBooks against PayPal (and Square/Stripe) settlements, flags uncategorized transactions, suspicious duplicates, and missing receipts, then writes a plain-English P&L narrative and exports a close packet (xlsx + one-page PDF). Use when the user says "close the month," "month-end," "reconcile," "what's missing," "P&L," or asks why revenue or margin changed this month.

安装

与 skills.sh 相同的 Command / Prompt 安装方式


name: month-end-prep description: > Walks an SMB owner through month-end close: reconciles QuickBooks against PayPal (and Square/Stripe) settlements, flags uncategorized transactions, suspicious duplicates, and missing receipts, then writes a plain-English P&L narrative and exports a close packet (xlsx + one-page PDF). Use when the user says "close the month," "month-end," "reconcile," "what's missing," "P&L," or asks why revenue or margin changed this month.

Month End Prep

Quick start

Connect QuickBooks and at least one payment processor (PayPal, Square, or Stripe), then say "let's close the month." Claude walks you through each step of the checklist, pausing for your input at each gate before moving forward.

If a connector is missing, Claude falls back to asking for a CSV export — it won't silently skip a step.

Workflow

Work through these steps in order. Each step has a completion state; don't advance until the current step is settled.

Step 1 — Agree on the target month

Ask the user which month to close. Default to the prior calendar month if they don't specify. Confirm before pulling any data.

Step 2 — Pull QuickBooks P&L and transaction register

Fetch:

  • Profit & Loss report for the target month (revenue, COGS, gross margin, operating expenses, net income)
  • Transaction register: every income and expense line item

Flag immediately:

  • Uncategorized transactions — any line with category "Uncategorized" or blank
  • Ask Questions / Needs Review — QB's own flag

Present the count ("14 transactions need a category") and list them for the user to classify before proceeding. Don't advance with open uncategorized items unless the user explicitly says "skip for now."

See reference/quickbooks-reconcile.md for field mappings and API notes.

Step 3 — Pull payment processor settlements

Fetch settlement reports from PayPal, Square, or Stripe — whichever are connected — for the same calendar month.

Match each settlement deposit against the QuickBooks bank deposit line:

  • Match — amount and date agree within 2 days → mark as reconciled
  • Difference < $0.50 — rounding/fee; note but don't flag
  • Difference ≥ $0.50 — flag with the delta amount
  • Settlement exists, no QB deposit — flag as "missing in QuickBooks"
  • QB deposit exists, no settlement — flag as "deposit not in processor data"

See reference/paypal-settlements.md for settlement report field mappings (PayPal, Square, Stripe).

Step 4 — Detect suspicious duplicates

Scan the transaction register for likely duplicate charges or deposits. Flag a transaction as a suspicious duplicate when all three match:

  • Same amount (within $0.01)
  • Same vendor or customer name
  • Posted within 5 calendar days of each other

Present flagged pairs to the user. They decide whether each is legitimate (e.g., a recurring weekly subscription) or a real duplicate to void.

See reference/gotchas.md for common false-positive patterns and how to distinguish them.

Step 5 — Receipts check (Desktop connector)

If the Desktop connector is available, scan the receipts folder (ask the user for the path; default ~/Documents/Receipts) for the target month.

For each expense transaction in QuickBooks above $25 with no attached document:

  • Check for a matching receipt file (match by amount ± $0.50 and date within 3 days)
  • Matched → note as "receipt on file"
  • Not matched → flag as "missing receipt"

List missing receipts. The user can supply the file or mark as "receipt not required" (e.g., a recurring auto-pay with no receipt).

If Desktop connector is not available, ask the user to confirm which expenses they have receipts for — don't silently skip this step.

Step 6 — Owner sign-off gate

Present a summary before going further:

Uncategorized transactions:  X of X resolved
Settlement discrepancies:    X flagged, X resolved
Suspicious duplicates:       X flagged, X cleared
Missing receipts:            X outstanding

Ask: "Ready to write the P&L summary and export the close packet?"

Do not proceed to Steps 7–8 without explicit confirmation.

Step 7 — Write the P&L narrative

Write a plain-English summary of the month — the kind an owner would share with their spouse or accountant, not a CFO memo. Aim for 150–250 words.

Structure:

  1. Headline — one sentence: "March came in at $X net, up/down Y% from February."
  2. Revenue — what drove the number; name products, services, or customers if the data shows concentration.
  3. Gross margin — whether it held, rose, or compressed, and the main reason why.
  4. Key expenses — any line that moved more than 10% MoM or is outside the normal range; one sentence each.
  5. Bottom line — net income vs. prior month; ask if they have a target to compare.
  6. Watch list — 1–3 things to monitor next month.

Avoid jargon; define anything that isn't plain English ("MoM" = month over month).

See reference/examples/pl-narrative.md for a worked example.

Step 8 — Export the close packet

Produce two files:

close-packet-[YYYY-MM].xlsx — three sheets:

  • P&L — the QuickBooks P&L data, formatted
  • Reconciliation — matched and flagged transactions side by side
  • Action Items — any outstanding flags (uncategorized, missing receipts, etc.)

close-packet-[YYYY-MM]-summary.pdf — one page:

  • Month and business name at the top
  • Key figures (revenue, gross margin %, net income)
  • The P&L narrative from Step 7
  • Count of open action items, if any

Save both to the Desktop (or a path the user specifies). Confirm the file locations.

See reference/close-packet-format.md for column specs and PDF layout details.

Approval gates

  • Never run reconciliation on a month that has been filed. Confirm the books are still open before pulling data.
  • Never void or modify a QuickBooks transaction directly. Surface flags; the owner makes changes in QuickBooks.
  • Always pause at Step 6 before producing outputs. Unresolved flags must be acknowledged or explicitly skipped.

Graceful degradation

Missing connectorFallback
QuickBooksAsk for a QB export CSV (P&L + transaction detail)
Payment processorAsk for a settlement CSV from the processor's website
Desktop (receipts)Ask the user to confirm receipt status for each flagged expense

Reference files

附带文件

reference/close-packet-format.md
# Close Packet Format Reference

The close packet is two files: an xlsx workbook and a one-page PDF summary.

## File naming

```
close-packet-2024-03.xlsx
close-packet-2024-03-summary.pdf
```

Use ISO 8601 year-month (`YYYY-MM`) in the filename. Default save location is the
Desktop; use the user's preferred path if specified.

---

## xlsx workbook — three sheets

### Sheet 1: P&L

A formatted copy of the QuickBooks P&L for the target month. Two-column layout:
**Category** and **Amount**.

Required rows (in order):
1. Revenue subtotal
2. COGS subtotal
3. **Gross Profit** (bold)
4. **Gross Margin %** (bold, formatted as %)
5. Operating expenses by category (each on its own row)
6. Total Operating Expenses
7. **Net Income** (bold)

Include a MoM comparison column if prior-month data is available. Format amounts as
currency (`$#,##0.00`). Negative values in red.

### Sheet 2: Reconciliation

Side-by-side comparison of QuickBooks deposits vs. processor settlements.

Columns:
| Column | Source |
|---|---|
| Date (QB) | QuickBooks deposit date |
| Amount (QB) | QuickBooks deposit amount |
| Processor | PayPal / Square / Stripe |
| Date (Processor) | Processor arrival date |
| Amount (Processor) | Processor net payout |
| Delta | QB amount minus processor amount |
| Status | RECONCILED / MISSING_IN_QB / UNMATCHED_DEPOSIT / DATE_MISMATCH |

Color-code the Status column:
- RECONCILED → green fill
- DATE_MISMATCH → yellow fill
- MISSING_IN_QB or UNMATCHED_DEPOSIT → red fill

### Sheet 3: Action Items

Any open flags from the checklist. Columns:
| Column | Notes |
|---|---|
| Category | Uncategorized Txn / Missing Receipt / Duplicate / Reconciliation Flag |
| Date | Transaction date |
| Amount | Dollar amount |
| Vendor / Customer | Name |
| Description | What's wrong and what to do |

If there are no open items, show a single row: "No open action items — books are clean."

---

## PDF summary — one page

Layout (top to bottom):

```
[Business Name]                    Close Packet — [Month Year]
────────────────────────────────────────────────────────────

KEY FIGURES
Revenue        $XX,XXX
Gross Margin   XX%
Net Income     $XX,XXX

P&L SUMMARY
[150–250 word plain-English narrative from Step 7]

ACTION ITEMS
X uncategorized transactions · X missing receipts · X open flags
[or "Books are clean — no open items." if all clear]

────────────────────────────────────────────────────────────
Prepared [Date] · Powered by Claude
```

Use a clean sans-serif font (Helvetica or equivalent). No logo required. Keep
margins ≥ 0.75 in on all sides so it prints cleanly.

**Generating the PDF:** Use the `xlsxwriter` or `reportlab` Python library if running
a script, or instruct Claude to render the content and export via the Desktop
connector's print-to-PDF capability. The user can also print the PDF from the xlsx
P&L sheet if a script isn't available.
reference/examples/pl-narrative.md
# P&L Narrative — Worked Example

## Scenario

**Business:** Cascade Candle Co. — small DTC candle maker, primarily Shopify +
occasional local markets.

**Month:** March 2024

**Key figures:**
- Revenue: $18,400 (Feb: $15,200) → +21% MoM
- COGS: $7,360 (Feb: $5,776) → gross margin 60% (Feb: 62%)
- Net income: $4,150 (Feb: $3,100) → +34% MoM

**Drivers:**
- Spring collection launched March 8 — strong first two weeks
- Beeswax costs rose ~8% MoM from a new supplier
- Shopify fees higher due to volume; otherwise expenses flat

---

## Example narrative

> **March came in at $4,150 net — your best month yet, up 34% from February.**
>
> Revenue hit $18,400, driven almost entirely by the Spring Collection launch on
> March 8. The Lavender + Sage three-pack was your top seller, accounting for
> roughly a third of units. The last week of the month slowed after the launch
> buzz faded, which is normal — watch whether that holds in April.
>
> Gross margin dipped slightly to 60% (from 62% in February). The culprit is
> beeswax: your new supplier is running about 8% higher than your previous one.
> At current volume that's roughly $200/month — not alarming, but worth a
> conversation with them or a price comparison before next order.
>
> Expenses were otherwise flat. Shopify fees ticked up proportionally with
> sales, which is expected.
>
> **Watch list for April:** (1) Whether the post-launch slowdown stabilizes or
> continues. (2) Beeswax pricing — lock in a rate if you can. (3) You have
> $2,800 in deposits from the Petal & Bloom wholesale order that haven't
> shipped yet — those aren't revenue until delivery.

---

## What makes this narrative work

- Opens with the headline number, not a preamble
- Names a specific product ("Lavender + Sage three-pack"), not just "top sellers"
- Explains the margin compression in concrete dollars, not just percentages
- Watch list is specific and actionable, not generic ("keep an eye on expenses")
- Flags the deposit that isn't revenue yet — this is a common SMB blind spot
reference/gotchas.md
# Gotchas

Common mistakes and edge cases in month-end close. Each entry has the pattern,
the reason it matters, and a Bad / Good example.

---

## Gotcha: Flagging split transactions as duplicates

**Why it matters:** A single purchase split across multiple GL categories appears
as multiple rows in the QB export — same vendor, same date, different amounts.
Flagging these as duplicates sends the owner on a wild goose chase.

### ✗ Bad

> Flagged as duplicate: Office Depot $47.50 on March 12 and Office Depot $62.50
> on March 12 — same vendor, same date.

Both rows share the same `TxnID` — they're splits of a $110 purchase across
"Office Supplies" and "Equipment."

### ✓ Good

Before flagging duplicates, group rows by `TxnID`. Only compare transactions
with distinct IDs. Splits of the same transaction are never duplicates.

---

## Gotcha: Treating a refund as a missing settlement

**Why it matters:** A PayPal refund appears as a negative transaction in the
settlement report. If you treat it as an unmatched outflow, you'll flag a
legitimate refund as a problem.

### ✗ Bad

> Flagged: PayPal outflow of –$89.00 on March 18 has no matching QB deposit.
> Possible missing transaction.

The –$89.00 is a refund to a customer. It should match a QB credit memo, not
a deposit.

### ✓ Good

Separate inflows (positive) from outflows (negative) before reconciling. Match
negative processor amounts against QB credit memos or refund transactions, not
deposits. Only flag an unmatched negative if no credit memo exists in QB.

---

## Gotcha: Comparing gross PayPal amount to net QB deposit

**Why it matters:** QuickBooks often records the net bank deposit (after PayPal
fees), but PayPal's transaction report shows the gross sale amount. Comparing
gross to net will always show a discrepancy equal to the fee.

### ✗ Bad

> Discrepancy: PayPal settlement $500.00, QB deposit $484.80 — delta $15.20.
> Flagged as reconciliation error.

The $15.20 is PayPal's 3.04% processing fee. This is expected and correct.

### ✓ Good

Use the **net payout** field from the PayPal settlement report
(`transaction_info.transaction_amount.value` minus
`transaction_info.fee_amount.value`) when comparing to the QB bank deposit.
If the delta is < $0.50 after fee adjustment, mark as RECONCILED.

---

## Gotcha: Advancing past Step 6 when there are unresolved flags

**Why it matters:** The close packet is the final artifact the owner files or
shares with their accountant. Exporting it with open flags bakes errors into
the record.

### ✗ Bad

> Owner hasn't responded about the 3 uncategorized transactions. Generating
> the close packet now so they have something to look at.

### ✓ Good

Hold at the Step 6 gate until the owner acknowledges every flag — either
resolving it ("categorize this as office supplies") or explicitly deferring it
("mark that as 'to review later'"). Only then export. Open items that the owner
deferred should appear in the Action Items sheet, not be silently dropped.
reference/paypal-settlements.md
# Payment Processor Settlements Reference

## Contents

- [PayPal](#paypal)
- [Square](#square)
- [Stripe](#stripe)
- [Reconciliation logic (all processors)](#reconciliation-logic-all-processors)

---

## PayPal

### Settlement report structure

The PayPal connector returns a **Transaction History** or **Settlement** report.
Key fields:

| Field | Notes |
|---|---|
| `transaction_info.transaction_id` | PayPal transaction ID |
| `transaction_info.transaction_initiation_date` | When the transaction occurred |
| `transaction_info.transaction_amount.value` | Gross amount (positive = money in) |
| `transaction_info.fee_amount.value` | PayPal fee (negative) |
| `transaction_info.transaction_status` | Use only `S` (Success) and `P` (Pending) |
| `payer_info.email_address` | Customer email — useful for matching |

**Deposit date vs. transaction date:** PayPal batches payouts. A sale on April 28
may not deposit until May 2. Match by **deposit date** when reconciling against QB
bank entries, not transaction date.

**Refunds:** Appear as negative amounts with `transaction_type` = `T1107` or
`T1114`. They should offset the original sale — don't flag a refund as a
discrepancy against the QB register unless there's no corresponding QB credit.

**Holds:** Transactions in status `F` (Funds on Hold) have not been deposited yet.
Note them separately — they'll appear in next month's settlement.

---

## Square

### Settlement report structure

Square calls these **Payouts**. Each payout covers 1–2 business days of sales.

Key fields from the Square Payouts API:

| Field | Notes |
|---|---|
| `id` | Payout ID |
| `arrived_at` | Date the funds landed in the bank account |
| `amount_money.amount` | Net payout in cents (already minus Square fees) |
| `status` | Use only `PAID` status for reconciliation |

**Fees:** Square deducts fees before the payout — so `amount_money.amount` is net.
When matching against QB, compare to the net bank deposit, not the gross sale total.

**Same-day payouts:** If the user has Square Instant Transfer, funds may arrive on
the transaction date. The default is next business day.

---

## Stripe

### Settlement report structure

Stripe calls these **Payouts**. The Stripe connector returns payout objects plus
the balance transactions within each payout.

Key fields:

| Field | Notes |
|---|---|
| `id` | Payout ID |
| `arrival_date` | Unix timestamp of bank arrival date |
| `amount` | Net payout in cents (fees already deducted) |
| `status` | Use only `paid` for reconciliation |

**Stripe fees:** Like Square, fees are deducted before payout. Compare net amounts.

**Stripe Connect / platform accounts:** If the user runs a platform on Stripe
Connect, individual transfer payouts may look unusual. Ask the user to confirm
their Stripe account type if payout patterns don't match expectations.

---

## Reconciliation logic (all processors)

Use this logic to match processor deposits against QuickBooks bank deposits:

```
for each processor deposit in target month:
    find QB deposit where:
        abs(QB.amount - processor.net_amount) < $0.50
        AND abs(QB.date - processor.arrival_date) <= 2 days

    if match found:
        mark as RECONCILED
    elif abs(QB.amount - processor.net_amount) < $0.50 (date mismatch only):
        flag as DATE_MISMATCH (usually a timing difference — low priority)
    elif processor deposit not matched at all:
        flag as MISSING_IN_QB
    elif QB deposit not matched to any processor record:
        flag as UNMATCHED_DEPOSIT (may be ACH, check, or other income)
```

**Multi-processor businesses:** Run this logic independently per processor, then
aggregate flags. A QB deposit that doesn't match PayPal may legitimately be a
Square payout — don't flag it until you've checked all connected processors.
reference/quickbooks-reconcile.md
# QuickBooks — Reconciliation Reference

## Reports to pull

### Profit & Loss (P&L)

Use the **Profit and Loss** report via the QuickBooks connector:
- Date range: first day to last day of target month
- Accounting method: **Accrual** unless the user has told you they run cash-basis
- Include all accounts

Key fields used downstream:
| Field | Notes |
|---|---|
| `TotalRevenue` | Top-line revenue |
| `GrossProfit` | Revenue minus COGS |
| `GrossProfitMargin` | Compute as GrossProfit / TotalRevenue |
| `NetIncome` | Bottom line |
| `TotalExpenses` | Operating expenses subtotal |

### Transaction Register

Pull the **Transaction List by Date** report or equivalent for the target month.
This is the line-item detail used for uncategorized flagging and duplicate detection.

Key fields:
| Field | Notes |
|---|---|
| `TxnDate` | Transaction date (not posting date) |
| `TxnType` | Invoice, Payment, Expense, Deposit, etc. |
| `Amount` | Positive = income, negative = expense in most QB exports |
| `AccountRef.name` | The GL account category |
| `EntityRef.name` | Vendor or customer name |
| `Memo` | Free-text description |
| `AttachmentCount` | > 0 means a receipt is attached in QB |

## Identifying uncategorized transactions

Flag a transaction as uncategorized if `AccountRef.name` is any of:
- "Uncategorized Income"
- "Uncategorized Expense"
- "Uncategorized Asset"
- blank / null
- "Ask My Accountant" (QB's built-in "I don't know" category)

## Pagination

The QB API returns a maximum of 1,000 rows per request. For businesses with high
transaction volumes, paginate using `startPosition` and `maxResults` parameters.
Request in 500-row batches to stay safely under the limit.

## Common data issues

**Split transactions** — a single purchase split across multiple categories appears as
multiple rows with the same date and vendor but different amounts. These are NOT
duplicates. Before flagging duplicates, group rows by `TxnID` — rows sharing an ID
are splits of one transaction.

**Bank feeds vs. manual entries** — bank-feed transactions have `PrivateNote` set to
"bank feed" or similar. Manual entries often lack a memo. Neither is a signal of a
problem on its own, but it helps explain why a transaction might lack a receipt.

**PayPal transactions already in QB** — if the user has the PayPal-QB auto-sync
enabled, PayPal transactions will already appear in the register. Don't double-count
them during reconciliation (Step 3). Check whether the QB deposit lines have
"PayPal" in the account or memo before matching.

**Retainer / deposit transactions** — a customer deposit is not revenue until the
work is delivered. If the user is on cash-basis accounting this distinction matters
less, but flag any large Deposit-type transactions without a matching Invoice for
their awareness.