Metal Tracking
JewelTrak’s Metals module handles the bench-jeweler reality of buying scrap gold and silver — both pulling pieces off your own shelves to melt down (inventory-source) and buying directly from walk-in customers (customer-source). The customer-source path is FL Ch. 538 compliant out of the box: seller identity capture, photo upload, signed affidavit, multi-lot per karat, 30-day police hold, 1099-B threshold tracking, and LeadsOnline export.
Even if you’re not in Florida, the workflow + audit trail is built on the strictest secondhand-dealer statute in the US, so anywhere else’s compliance is a subset of what’s already enforced.
The model — three things to know
- A lot is a single karat purity (10K, 14K, 18K, etc.) at a single weight from a single seller transaction. One walk-in customer selling you their 14K ring + their 18K bracelet creates two lots (one per karat), grouped under one “buy ticket.”
- An inventory-source lot is born when you scrap an existing JT inventory item — the cost basis flows from the inventory’s PurchasePrice. No compliance fields needed since you’re the legal owner.
- A customer-source lot captures the FL Ch. 538 packet on the seller and the goods: ID type/number/state, photo of seller + goods, signed affidavit, payment method. All five panels are required before save.
Setup before first use
- Org Settings → Identification → Secondhand Dealer License # — your FL Ch. 538 license number (or equivalent in your state). This prints on every buy ticket. Without it, the ticket renders a fillable blank for handwriting.
- Per-store: same field on Settings → Stores → [your store] → Identification.
- Default Gold/Silver Cost in Org Settings drives the per-DWT prefill on inventory-source scrap buys. Update when bullion spot moves significantly.
Buying — inventory source
Use this when you’re melting down a piece you already own.
- Inventory list → select item(s) → Bulk Actions → Scrap.
- Confirm the weight + karat (prefilled from inventory; editable on the form).
- Cost basis = inventory’s PurchasePrice, prorated by weight if a partial scrap.
- Save → metal_lot row created with
Source='Inventory', the inventory item is marked Scrapped + decremented from QOH.
No compliance fields, no police hold (you already own it).
Buying — customer source (FL Ch. 538 path)
Use this for every walk-in selling you scrap. This is the path that keeps you out of trouble with FL secondhand-dealer enforcement.
Go to Sales menu → Metals → Buy → New and pick Customer Source.
The form has 5 required panels:
- Seller identity. First/last/middle name, address, DOB, signature on file. Pulls from contact if recognized.
- Physical description. Height, weight, hair color, eye color, race, gender. Required even when the seller is in your customer database (Ch. 538 wants a contemporaneous physical description on every transaction).
- ID document. Type (Driver’s License / State ID / Passport / Military), number, issuing state, expiration. Photo of the ID must be uploaded — JT stores it in R2 with the lot, tenant-scoped.
- Photo of the goods. Required by Ch. 538. Take it after laying the goods out flat with a ruler visible.
- Signed affidavit. PDF template auto-generated from the form values. Customer reviews, signs (touch signature or printed paper), and you upload the signed copy.
Then add one or more lot lines — one row per karat. Each row captures weight, gross/fine, agreed $/DWT, total payable. The form blocks save until at least one lot has a non-zero weight.
Payment method (cash / check / Zelle / etc.) — Ch. 538 wants this recorded.
Save → buy ticket prints with everything Ch. 538 + IRS need:
- Your dealer license #
- Seller’s full identity panel
- ID + goods photos referenced by lot ID
- Per-karat breakdown
- Total paid + payment method
- Acquisition timestamp
- Affidavit reference
Police hold
Customer-source lots are automatically held for 30 days before you can sell them to a refiner. The lot detail page shows the release date.
If a police officer requests a hold on a specific lot during this window, mark it on the lot detail page (Police Hold button) with the requesting officer’s name + agency + case #. Held lots can’t be sold even after the 30-day window expires until the hold is released.
Inventory-source lots are not held — they’re your own.
Selling to a refiner
When all of a sale’s lots are past their hold period:
- Sales menu → Metals → Sale → New.
- Pick the refinery (customer record flagged IsRefinery).
- Add lots — the page lists every lot that’s clear to sell, grouped by karat.
- Confirm settlement weights + agreed $/DWT (often per-karat, sometimes adjusted after refinery’s own assay).
- Save + finalize → JT moves the lots out of stock and creates a
metal_salerow with the per-lot payments. Settlement payment comes back through Sales → AR like any other invoice.
Compliance reports
Sales → Metals → Compliance has three exports:
- LeadsOnline CSV — every customer-source buy in a date range, in LeadsOnline’s exact column shape. Upload through the LeadsOnline web portal weekly (most jurisdictions require ≤7 day reporting).
- 1099-B threshold report — every seller who crossed the IRS threshold ($600/year aggregate as of 2026) in a tax year. Drives 1099-B issuance.
- Holds clearing widget — shows which lots’ police holds expire in the next 30 days so you can plan refinery sales.
Voiding
A buy ticket can be voided same-day if the cash was returned. After end-of-day reconciliation, voids are blocked — write-off is the only path (creates an offsetting credit entry in the audit log; the original ticket stays intact for compliance).
Lot tag printing
Coming soon. Format decision pending (Godex EZPL vs HTML print-preview). For now, the lot detail page renders an inline buy-ticket label suitable for hand-writing or printing in HTML mode.
What this replaces
JT’s legacy /scrap-refinery module is deprecated. All scrap activity flows through /metals. The old scrap_batches table stays in the database read-only so historical receipts on /returns/[id] still render.
Audit trail
Every buy + sale + write-off + hold + release writes to the audit log. The lot detail page also shows an inline activity timeline. If FL Inspector requests records, the audit-log filter tableName=metal_lots produces the full chronological view.
Troubleshooting
- Buy save fails with “missing seller identity photo” — Ch. 538 won’t let you save a customer-source lot without the ID photo. Upload before retry.
- Refinery sale won’t include a specific lot — That lot is still inside its 30-day police hold or has an active officer-requested hold. Check the lot detail page.
- LeadsOnline export is empty — Date range only covers customer-source buys. Inventory-source scraps don’t reach LeadsOnline because there’s no seller to report. Adjust the filter if needed.
- 1099-B report shows a customer who shouldn’t be on it — Aggregation is by ContactID across all buys in the tax year. Confirm you haven’t merged two customers and re-run.
- Dealer License # prints as a blank underline — You haven’t set the
SecondhandDealerLicensefield in Org or Store settings. Fill it once and every future ticket carries it.