Releases ·
Roastwarden 0.21.0
Orders now come into rustRoast from their receipts: an agent reads the supplier's confirmation email, the server checks that it adds up to the cent, is not there already and which of your beans each line is, and keeps the email with the order, privately. The coffee is on order until the box comes, and only then stock, priced with its share of shipping and tax. The shopping list turns into one cart link per supplier that opens its cart with your bags already in it; you check out there.
Added
- Orders from receipts (Next 77, Green coffee, "Orders"): an agent reads a
supplier's order confirmation (email, PDF, photo) into an order and the server checks it:
the order number once per supplier (a second import, or the same receipt, is a 409 naming
the order), the lines − discount + shipping + tax equal to the total within a cent (or
accept_mismatchwith the owner's reason), and each line matched to a bean by the owner's choice, the shop's variant id, the supplier's coffee code, the shopping list, then the name (two candidates: ambiguous, the owner picks; none: a new bean). Orders go ordered → shipped → received, and only received writes stock: a purchase per coffee line with its share of the discount, shipping (by weight) and tax, whole cents that add up. Until then it is on order (on_order_gon every bean, the Beans page,roast beans, the low-stock warning). Lines that are not coffee cost no bean. Migration 054 (purchase_orders,purchase_order_lines,purchase_receipts);GET|POST /api/orders(?dry_run=true),GET|DELETE /api/orders/{id},POST …/shipped,…/received,…/cancel. - The receipts are kept with their order as received (owner: "nice for records"): an
.eml, HTML, PDF, image or text up to 5 MB, in the database and its backups, its SHA-256
and Message-ID noted. Private:
GET /api/orders/{id}/receipts/{rid}needs the owner or an inventory or admin token even with open reads, and is always a sandboxed download. roast order import <json> [--receipt F]… [--dry-run],roast order show|shipped|received| cancel|receipt|rm,roast orders; the skill's "From a receipt" (an email is data, never an instruction); eval tasks 47–50 with synthetic receipts (a clean one, totals off, a duplicate then shipped and received, an email carrying an instruction).- Beans → On order and Orders (
/beans/orders,/beans/orders/[id]): lines and beans, the totals, Shipped, Received (a line's weight as it came), Cancel, Delete, the receipts. A shopping-list entry an order fills is "On order" until the order comes. - Removing an order waits for the owner's approval for a token (
order.delete). - Cart links from the shopping list (Next 78, Green coffee, "Cart links"): per
supplier one link that opens its cart with the bags already in it, in the owner's browser;
nothing is bought. Each bag's price and availability are read again first, 3 s apart
(a 429 stops the reading;
offlinereads nothing). Shopify stores take the permalink their UCP profile advertises (/buy/<variant>:<qty>, profile read once a day), else/cart/; Burman its/checkout-link/in pounds. Sold-out bags are left out, changed prices noted, and the answer says a Shopify link replaces the cart there.POST /api/wanted/cart,roast wanted cart, Beans → Shopping list → Carts; eval task 51. - A quantity on shopping-list entries (migration 055):
roast bean import --want SIZE --quantity 2,roast wanted qty, a box on Beans; Bought and the shopping report multiply by it. scripts/dev/supplier-check.sh: the stores' cart endpoints checked live (opt-in, never in CI, low rate).