make_post_sell/make_post_sell
russell@unturf.com 89156a5d6c
fix: invoices charge negotiated price, not list (Stripe/PayPal/Monero/DOGE)
CRITICAL financial defect. Cart UI showed the negotiated $21 total
for an accepted offer (list was $42), but EVERY payment pipeline —
Stripe (cart.py:848), PayPal (cart.py:1164), Monero quote
(crypto.py:269), Dogecoin quote (crypto.py:538) — pulled
invoice.total_in_cents, which summed line items and ignored the
cart_offer / cart_auction override entirely. Buyer's DOGE quote
asked for ~373 DOGE (≈$42 USD) for an offer they negotiated to $21.
Seller would have eaten $21 per accepted offer.

Fix:

- New column mps_invoice.negotiation_override_in_cents (nullable
  BigInteger). Migration 27bc1bfc33dc adds it idempotently.
- Invoice.total_in_cents short-circuits to the override + handling
  when the column is set. Coupons / discount math is bypassed (the
  buyer already negotiated; we don't stack on top).
- Invoice.apply_cart_negotiation(cart) helper copies the cart's
  override onto the invoice in one call. Idempotent. No-op for
  non-negotiated carts.
- Wired into every invoice-from-cart construction site (7 total):
  - views/crypto.py:161 (Monero quote)
  - views/crypto.py:454 (Dogecoin quote — fox's screenshot)
  - views/cart.py:827 (Stripe checkout)
  - views/cart.py:974 (PayPal create-order)
  - views/cart.py:1153 (Adyen sessions)
  - views/cart.py:1258 (PayPal complete-checkout)
  - views/cart.py:1388 (post-PayPal-approval finalize)

Two integration tests cover the model:
- test_negotiation_override_short_circuits_total walks the
  invoice-from-negotiated-cart flow, asserts $42 → $21 transition
  after apply_cart_negotiation, and confirms handling still adds
  on top.
- test_apply_cart_negotiation_noop_when_not_negotiated proves the
  helper is safe to call on plain carts (no negotiation_override
  set, line items sum normally).

Legacy invoices already in the DB have NULL on the new column —
they keep their line-item-summed totals, untouched.
2026-05-13 18:29:50 -04:00
..
lib feat: buyer can cancel accepted offer; post-accept pay window 2026-05-13 10:31:43 -04:00
models fix: invoices charge negotiated price, not list (Stripe/PayPal/Monero/DOGE) 2026-05-13 18:29:50 -04:00
scripts fix: invoices charge negotiated price, not list (Stripe/PayPal/Monero/DOGE) 2026-05-13 18:29:50 -04:00
static fix: offers/bids inbox polish + cart-checkout spacing + Pay/Cancel row 2026-05-13 18:22:20 -04:00
templates fix: offers/bids inbox polish + cart-checkout spacing + Pay/Cancel row 2026-05-13 18:22:20 -04:00
tests fix: invoices charge negotiated price, not list (Stripe/PayPal/Monero/DOGE) 2026-05-13 18:29:50 -04:00
views fix: invoices charge negotiated price, not list (Stripe/PayPal/Monero/DOGE) 2026-05-13 18:29:50 -04:00
__init__.py Add Monero (XMR) payment support 2025-09-22 01:45:54 +00:00
config_jinja2.py Time to open the sauce : ) 2021-12-31 21:39:40 -05:00
request_methods.py cache-bust static CSS with ?v={git_hash} on every deploy 2026-05-11 09:45:17 -04:00
routes.py feat: buyer can cancel accepted offer; post-accept pay window 2026-05-13 10:31:43 -04:00