Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ We're open-sourcing 11 plugins built and inspired by our own work:
| **[enterprise-search](./enterprise-search)** | Find anything across email, chat, docs, and wikis — one query across all your company's tools. | Slack, Notion, Guru, Jira, Asana, Microsoft 365 |
| **[bio-research](./bio-research)** | Connect to preclinical research tools and databases (literature search, genomics analysis, target prioritization) to accelerate early-stage life sciences R&D. | PubMed, BioRender, bioRxiv, ClinicalTrials.gov, ChEMBL, Synapse, Wiley, Owkin, Open Targets, Benchling |
| **[cowork-plugin-management](./cowork-plugin-management)** | Create new plugins or customize existing ones for your organization's specific tools and workflows. | — |
| **[specialty-retail](./specialty-retail)** | Workflows for SMB dealers carrying floorplan-financed inventory (hot tub, pool, furniture, powersports, RV, marine). Floorplan accounting, refurb P&L, ASC 606 deposit-to-delivery revenue recognition, OEM vendor pricing sync. Pairs with `small-business`. | QuickBooks, Stripe, Gmail, Google Drive, Microsoft 365 |

Install these directly from Cowork, browse the full collection here on GitHub, or build your own.

Expand Down
10 changes: 10 additions & 0 deletions specialty-retail/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "specialty-retail",
"version": "0.1.0",
"description": "Workflows for specialty retailers that carry floorplan-financed inventory — hot tub / pool / spa dealers, furniture stores, powersports, RV, marine, and similar. Covers floorplan-financing reconciliation (Wells Fargo CDF, Synchrony, consumer-finance dealer programs), per-unit refurbished-inventory P&L, ASC 606 deposit-at-sale / recognize-at-delivery revenue recognition, and OEM vendor pricing sync. Pairs well with the small-business plugin — this one handles the operational complexities specific to dealers.",
"author": {
"name": "East Texas Hot Tub Company",
"url": "https://easttexashottub.com"
},
"keywords": ["specialty-retail", "dealer", "floorplan", "consumer-financing", "asc-606", "wholesale", "inventory", "refurb", "hot-tub", "pool", "powersports", "rv", "furniture"]
}
24 changes: 24 additions & 0 deletions specialty-retail/.mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"mcpServers": {
"quickbooks": {
"type": "http",
"url": "https://ai-inc.quickbooks.intuit.com/v1/mcp"
},
"stripe": {
"type": "http",
"url": "https://mcp.stripe.com"
},
"google drive": {
"type": "http",
"url": "https://drivemcp.googleapis.com/mcp/v1"
},
"gmail": {
"type": "http",
"url": "https://gmailmcp.googleapis.com/mcp/v1"
},
"ms365": {
"type": "http",
"url": "https://microsoft365.mcp.claude.com/mcp"
}
}
}
84 changes: 84 additions & 0 deletions specialty-retail/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Specialty Retail Plugin

Workflows for specialty retailers that carry **floorplan-financed inventory** — hot tub and spa dealers, pool builders, furniture stores, powersports, RV, marine, appliance retailers, and similar. The generic `small-business` plugin assumes you bill customers and pay vendors and that's it. Specialty retail has extra moving parts the generic plugin can't see:

- **Inventory floorplan financing** — units sit on someone else's balance sheet (Wells Fargo CDF, Synchrony, dealer credit lines) until you sell them, with interest and free-flooring windows you have to track.
- **Refurbished inventory** — you bring used units back into stock, sink labor + parts into them, and need per-unit cost-basis tracking so you know if refurbs make money.
- **Deposit-at-sale, recognize-at-delivery** — large-ticket items collect deposits weeks or months before delivery. Per ASC 606 the revenue doesn't book until you deliver, but most small-business accounting tools treat the deposit as revenue immediately.
- **OEM pricing portals** — Watkins (Hot Spring/Endless Pools/Tylö), Sundance, Bullfrog, Coast Spas, Ashley HomeStore, Polaris, Honda Marine, Sea-Doo, etc. all have dealer portals where you pull current-year wholesale + retail pricing monthly. Most dealers do this by hand.

This plugin pairs with the existing `small-business` plugin — it doesn't replace it. Use `small-business` for the generic close + cash + AR flows, and add `specialty-retail` for the dealer-specific operations.

## Installation

### Cowork

Install from [claude.com/plugins](https://claude.com/plugins/).

### Claude Code

```bash
claude plugin marketplace add anthropics/knowledge-work-plugins
claude plugin install specialty-retail@knowledge-work-plugins
```

## What's in this plugin

### Skills (4)

| Skill | What it does | Just say... |
|---|---|---|
| **floorplan-accounting** | Reconciles your dealer floorplan against your GL, accrues per-unit interest after the free-flooring window expires, and posts paydowns when units sell. Supports Wells Fargo CDF, Synchrony, and dealer-specific credit lines. | "reconcile the floorplan", "WF CDF statement", "free-flooring", "floorplan interest" |
| **refurb-pnl** | Per-unit P&L for refurbished inventory. Tracks labor hours, parts costs, freight, and sale price against the original acquisition cost. Surfaces which refurbs actually make money and which don't. | "refurb P&L", "how did the refurbs do this month", "is the refurb program working" |
| **delivery-revenue-recognition** | ASC 606-compliant revenue recognition for deposit-at-sale, recognize-at-delivery transactions. Posts deposits to Customer Deposits liability until delivery, then recognizes revenue + sales tax + COGS at delivery. Flags any deposit aged > 180 days for review. | "recognize the revenue", "what's stuck in deposits", "ASC 606", "delivery posting" |
| **vendor-pricing-sync** | Monthly pull of current-year wholesale + retail pricing from an OEM dealer portal (Watkins, Sundance, Bullfrog, etc.), diff against your product table, surface changes for review, apply on approval. Handles authentication, XLSX/PDF parsing, and effective-date verification. | "pull Watkins pricing", "sync vendor pricing", "is our wholesale current", "update MSRP" |

There are no commands yet in this plugin — the skills auto-trigger by description, and the four jobs they cover are each one-shot enough that they don't need a multi-step command wrapper. (PRs welcome to add them if you want them as explicit slash commands.)

## What you'll need to connect

**Core:**
- **QuickBooks** — your GL. Required for `floorplan-accounting` and `delivery-revenue-recognition`. Optional for `refurb-pnl` (the skill can also read a Supabase/Postgres ledger directly via SQL if your shop is on a custom ERP).

**Optional, depending on which skills you use:**
- **Stripe** — for `delivery-revenue-recognition` (matches Stripe payment intents to invoice deliveries).
- **Google Drive / OneDrive** — for `vendor-pricing-sync` (download archive of monthly OEM price sheets) and `floorplan-accounting` (filing dealer statements).

**Vendor portal credentials** (kept in your OS keychain, never in plugin files):
- Watkins Access (Hot Spring, Endless Pools, Tylö)
- Wells Fargo CDF (sec2.financeaccess.com)
- Synchrony Dealer Portal (if used)
- Any other OEM portal your shop uses

The `vendor-pricing-sync` skill is the only one that hits a vendor portal directly (via Playwright if you have it installed, or a CSV/XLSX upload fallback otherwise).

## How it pairs with `small-business`

The generic `small-business` plugin handles:
- `/close-month`, `/plan-payroll`, `/run-campaign`, etc.
- Generic AR/AP, cash flow, margin, 1099 prep

This plugin adds the layer specific to dealers carrying floorplan-financed inventory:
- The floorplan reconciliation that `small-business`'s `month-end-prep` doesn't know how to do
- The per-unit refurb tracking that doesn't exist in generic SMB accounting
- The deposit-to-delivery revenue recognition that prevents misclassifying customer deposits as sales income
- The OEM portal pricing sync that keeps your inventory cost basis current

Install both. They complement each other.

## Adapting for your dealer category

These skills were authored against a hot-tub-and-spa dealer's actual books, but the patterns generalize. To adapt:

1. **Floorplan accounting** — swap "Wells Fargo CDF" for your floorplan lender. The math (free-flooring window → accrue interest → paydown at sale) is identical across dealer credit programs.
2. **Refurb P&L** — works as-is for any used-inventory program. The skill reads cost basis + labor + parts + sale price.
3. **Delivery revenue recognition** — works for any large-ticket deposit-at-sale model. Furniture (couch delivered 6 weeks later), powersports (special order), RV (factory build).
4. **Vendor pricing sync** — swap "Watkins Access" for your OEM portal. The skill is portal-agnostic; you provide the login flow and the XLSX/PDF parsing rules.

Skill files are markdown. Fork, edit, deploy. No code required.

## Background

Built and contributed by [East Texas Hot Tub Company](https://easttexashottub.com), a hot-tub-and-spa dealer in Tyler, Texas running on Claude as their AI bookkeeper and operating system. Released under Apache 2.0.

We built these workflows for our own books and decided that other floorplan-carrying SMB dealers would benefit from the same patterns. If you adapt these for your category and want to contribute back, PRs welcome.
195 changes: 195 additions & 0 deletions specialty-retail/skills/delivery-revenue-recognition/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
name: delivery-revenue-recognition
description: >
ASC 606-compliant revenue recognition for deposit-at-sale, recognize-at-delivery
transactions. When a customer puts a deposit down weeks or months before
delivery, that deposit is a liability (Customer Deposits), not revenue. This
skill identifies invoices stuck in deposit state, generates the JEs that
recognize revenue + sales tax + COGS at delivery, and flags deposits aged
past a configurable threshold (default 180 days) for review. Use when the
user says "recognize the revenue", "what's stuck in customer deposits",
"ASC 606", "deposit posting", or "delivered but not invoiced".
compatibility: "Requires QuickBooks (or any GL with a Customer Deposits liability account) + a sales-order / invoice system that tracks deposit_at_sale and delivered_at timestamps separately."
---

# Delivery Revenue Recognition

ASC 606-compliant revenue recognition for the deposit-at-sale, recognize-at-delivery business model. This is the standard pattern for any large-ticket item where the customer pays before taking delivery:

- Hot tubs, swim spas, saunas (4–12 week order-to-delivery)
- Custom furniture (6–8 week production lead times)
- Powersports / RV / boats (factory-build orders)
- Appliances (special-order kitchens)
- Pre-sold inventory ordered to a customer specification

## Why this matters

Generic SMB accounting tools recognize revenue when the customer pays. Under ASC 606, **revenue is recognized when the performance obligation is satisfied** — for tangible-goods delivery, that's when the customer takes possession.

The wrong way:
```
Customer pays $5,000 deposit on April 1
→ Books show $5,000 revenue + $413 sales tax on April 1
→ Unit delivers June 15 — books already recognized it
→ April P&L overstated, June P&L understated
→ Sales tax remitted in April based on overstatement
→ If unit never delivers (customer cancels): revenue must be reversed, sales tax refunded
```

The right way:
```
Customer pays $5,000 deposit on April 1
→ DR Bank $5,000 / CR Customer Deposits (liability) $5,000
→ Unit delivers June 15
→ DR Customer Deposits $5,000 / CR Revenue $4,587 / CR Sales Tax Payable $413
→ DR COGS / CR Inventory at delivery (separate JE)
→ Revenue recognized in the month of delivery, sales tax remitted on that month's filing
```

This skill identifies which invoices need the delivery JE and produces it.

## Workflow

### Step 1 — Pull invoices in deposit state

For each invoice with a deposit applied but the unit not yet delivered:

```sql
SELECT
i.id,
i.invoice_number,
i.customer_id,
c.name AS customer_name,
i.invoice_date,
i.total,
i.balance_due,
so.id AS sales_order_id,
so.delivered_at,
so.status AS so_status,
SUM(p.amount) AS deposit_applied,
CURRENT_DATE - i.invoice_date AS days_open
FROM invoices i
JOIN sales_orders so ON so.id = i.sales_order_id
LEFT JOIN payment_applications pa ON pa.invoice_id = i.id
LEFT JOIN payments p ON p.id = pa.payment_id
JOIN customers c ON c.id = i.customer_id
WHERE so.status IN ('sold', 'awaiting_delivery', 'partial')
AND so.delivered_at IS NULL
AND i.status IN ('open', 'partial')
GROUP BY i.id, c.name, so.id;
```

Equivalent QuickBooks query: invoices linked to sales orders, with status not "Delivered" and at least one received payment.

### Step 2 — Split into action buckets

| Bucket | Criteria | Action |
|---|---|---|
| **Ready to recognize** | so.delivered_at IS NOT NULL AND no delivery JE posted | Generate delivery JE (Step 3) |
| **Awaiting delivery** | so.delivered_at IS NULL AND days_open ≤ 180 | Hold — deposit correctly in liability |
| **Aged for review** | days_open > 180 AND so.delivered_at IS NULL | Flag for user review |
| **Stuck / orphaned** | so.status='cancelled' AND deposit still applied | Flag — needs refund or reclassification |

The "aged for review" threshold defaults to 180 days. Configurable per-dealer (some categories have factory lead times that exceed this naturally — RV custom builds can run 9+ months).

### Step 3 — Generate the delivery JE for each "ready" invoice

For each invoice in the "ready to recognize" bucket:

```
Date: <so.delivered_at>
Description: Revenue recognition — Invoice #<number>, Customer <name>, delivered <date>

DR Customer Deposits (2410 or similar) <deposit_applied>
DR Accounts Receivable (1200) <balance_due if any>
CR Revenue — <product category> (4010/4020/etc.) <invoice subtotal>
CR Sales Tax Payable (2200) <sales tax amount>
```

Separately, post COGS at delivery if your inventory method requires it:

```
DR COGS — <product category> (5010/5020/etc.) <unit cost>
CR Inventory — <product category> (1210/1220/etc.) <unit cost>
```

Show the proposed JEs to the user **before posting**. Group multiple deliveries from the same date into one batch for approval but post them as separate JEs (one per invoice) so the audit trail stays clean.

### Step 4 — Apply approved JEs

After the user approves a batch, post via the GL connection. Record the JE IDs back on the invoice in a `recognition_je_id` field if the schema supports it; otherwise note it in the JE description for traceability.

### Step 5 — Handle the "aged for review" bucket

For deposits aged past the threshold without delivery:

For each flagged invoice, surface:
- Customer name and contact
- Invoice number, deposit amount, days open
- Sales order status, expected delivery date if set
- Last activity (last payment, last note, last contact)

Present as a watchlist. Common dispositions:
- **Factory lead time** — confirm with the customer, update the sales order delivery ETA, leave the deposit in liability
- **Customer abandoned the order** — start a refund process (separate skill or manual) and reclassify the deposit if non-refundable
- **Lost track / book error** — investigate; may need a corrective JE

Do **not** auto-recognize aged deposits as revenue without a delivery event. That would be both ASC 606 non-compliant and a real audit risk.

### Step 6 — Handle the "stuck / orphaned" bucket

For cancelled sales orders with applied deposits still showing:

If the deposit was refunded:
```
DR Customer Deposits <amount>
CR Bank <amount>
```

If the deposit was kept as a forfeiture per a signed contract clause:
```
DR Customer Deposits <amount>
CR Other Income — Forfeitures (4090 or similar) <amount>
```

Both require user approval. Forfeiture is also potentially taxable as ordinary income — flag for CPA review on amounts over $1,000.

### Step 7 — Output summary

```
Delivery Revenue Recognition — [scope]

Ready to recognize: N invoices, $XXX,XXX revenue + $X,XXX sales tax
Awaiting delivery: N invoices in deposit (correctly held)
Aged > 180 days: N invoices for review ($XX,XXX total)
Stuck / cancelled: N invoices with leftover deposits ($X,XXX total)

Proposed JEs (ready batch):
[list of JEs with DR/CR detail]

Awaiting your approval to post. Reply 'approve all', or specify which to post.
```

## Approval gates

- **Never auto-post.** Always present proposed JEs and wait for explicit approval.
- **Never recognize revenue without a delivery event.** Aged deposits stay in liability until delivery, refund, or forfeiture per signed contract.
- **Never plug the difference.** If deposit_applied doesn't equal invoice total exactly (off by sales tax handling, deposit overpayment, etc.), surface the discrepancy and ask.
- **Flag forfeitures over $1,000 for CPA review.** Forfeiture income has tax implications.
- **Closed-period awareness.** Don't post into a closed period. If delivery date falls in a closed period, the JE must be approved as a prior-period correction.

## Graceful degradation

| Missing piece | Fallback |
|---|---|
| No sales_orders.delivered_at field | Ask user to provide a delivery list (invoice # + delivery date) |
| Customer Deposits account not in CoA | Recommend setting up a current liability account (typical CoA code 2410) |
| Sales tax handling unclear | Ask user how their state recognizes tax (some states tax on deposit, some on delivery) |
| Inventory method unclear | Skip the COGS JE if user can't confirm method; flag for follow-up |

## Reference

- `reference/asc-606-summary.md` — Plain-English ASC 606 for SMB dealers (not legal advice)
- `reference/state-sales-tax-timing.md` — Which US states tax at deposit vs delivery (TX, CA, NY, FL, etc.)
- `reference/cancelled-order-handling.md` — Refund vs forfeiture mechanics
- `reference/examples/hot-tub-delivery.md` — Worked example: April deposit → June delivery for a Hot Spring Grandee
Loading