Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 54s
nettax.sx — alternative to quote.sx's gross-tax default: cart-quote-net taxes the net (post-discount) base. allocate-discount spreads the basket discount across lines by extended-price share with a deterministic largest-remainder pass so per-line shares sum exactly to the discount; each line taxed on its net at its class rate. Both policies reproducible; pick per jurisdiction. Total 239/239 across 15 suites. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
93 lines
2.2 KiB
Plaintext
93 lines
2.2 KiB
Plaintext
;; lib/commerce/tests/nettax.sx — discount-aware (net) tax policy.
|
|
;; Uses (commerce-test name got expected) provided by conformance.sh.
|
|
|
|
(define
|
|
pcat
|
|
(make-catalog
|
|
(list
|
|
(list "widget" 1000 :standard)
|
|
(list "tea" 1000 :reduced))
|
|
(list)
|
|
(list)))
|
|
|
|
(define
|
|
rules
|
|
(list
|
|
(list :uk :standard :guest 2000)
|
|
(list :uk :reduced :guest 500)))
|
|
|
|
(define gctx (make-pricing-context pcat rules :uk :guest))
|
|
|
|
;; widget x3 = 3000 (standard), tea x6 = 6000 (reduced); subtotal 9000
|
|
(define
|
|
cart
|
|
(list (list "widget" :none 3) (list "tea" :none 6)))
|
|
|
|
(define ruleset (list (list :percent "TEN" :standard 1000)))
|
|
|
|
;; --- allocation: proportional, sums exactly to the discount ---
|
|
|
|
(commerce-test
|
|
"allocate-even"
|
|
(allocate-discount pcat cart 300)
|
|
(list 100 200))
|
|
(commerce-test
|
|
"allocate-sums-to-discount"
|
|
(ct-sum (allocate-discount pcat cart 300))
|
|
300)
|
|
|
|
;; remainder distribution: 100 over (3000,6000)/9000 = (33,66) rem 1 -> (34,66)
|
|
(commerce-test
|
|
"allocate-remainder"
|
|
(allocate-discount pcat cart 100)
|
|
(list 34 66))
|
|
(commerce-test
|
|
"allocate-remainder-sums"
|
|
(ct-sum (allocate-discount pcat cart 100))
|
|
100)
|
|
|
|
(commerce-test
|
|
"allocate-zero"
|
|
(allocate-discount pcat cart 0)
|
|
(list 0 0))
|
|
(commerce-test
|
|
"allocate-empty"
|
|
(allocate-discount pcat empty-cart 0)
|
|
(list))
|
|
|
|
;; --- net tax vs gross tax ---
|
|
;; discount = TEN 10% of standard 3000 = 300, allocated (100 200).
|
|
;; net: widget 2900@20%=580, tea 5800@5%=290 -> net tax 870 (gross was 900).
|
|
|
|
(commerce-test
|
|
"net-quote"
|
|
(cart-quote-net gctx cart ruleset (list))
|
|
{:codes (list "TEN") :subtotal 9000 :discount 300 :total 9570 :tax 870})
|
|
|
|
;; same cart through the gross policy taxes 900 (the documented default)
|
|
(commerce-test
|
|
"gross-quote-for-contrast"
|
|
(quote-tax (cart-quote gctx cart ruleset (list)))
|
|
900)
|
|
|
|
(commerce-test
|
|
"net-tax-lower"
|
|
(quote-tax (cart-quote-net gctx cart ruleset (list)))
|
|
870)
|
|
|
|
;; --- no discount: net policy == gross policy ---
|
|
|
|
(commerce-test
|
|
"no-discount-net-equals-gross"
|
|
(=
|
|
(cart-quote-net gctx cart (list) (list))
|
|
(cart-quote gctx cart (list) (list)))
|
|
true)
|
|
|
|
;; --- empty cart ---
|
|
|
|
(commerce-test
|
|
"net-empty"
|
|
(cart-quote-net gctx empty-cart ruleset (list))
|
|
{:codes (list) :subtotal 0 :discount 0 :total 0 :tax 0})
|