You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
pollen-tfl/pricing-table.rkt

108 lines
3.3 KiB
Racket

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#lang racket/base
(require racket/dict
racket/match
"sku.rkt")
(provide (all-defined-out)
(all-from-out "sku.rkt"))
(define (round-cents float)
(/ (floor (* float 100)) 100))
(define (round-up inc x)
(* (ceiling (/ x inc)) inc))
(define (calc-multi-price base-price people)
(round-cents
(sub1 (round-up 10 (case people
[(1 2) base-price]
[(5) (* base-price 2)]
[(10) (* base-price 3)]
[(20) (* base-price 4)]
[(40) (* base-price 5)]
[(60) (* base-price 6)]
[(80) (* base-price 7)]
[else (error "Too many people")])))))
(define (calc-multi-license sku people)
(define base-price (sku-base-price sku))
(calc-multi-price base-price people))
(define license-increments '(1 2 5 10 20 40 60 80))
(define (make-price-list base-price)
(map (λ(n) (cons n (calc-multi-license base-price n))) license-increments))
(define (get-price sku [people 1])
(with-handlers ([exn:fail? (λ(e) (get-price sku (add1 people)))])
(calc-multi-license sku people)))
(define (get-variant-id sku which)
(dict-ref (sku-variant-ids sku) which))
(define (bc-url item-number)
(format "http://typo.la/bc.html?item=~a" item-number))
(define (make-buy-url sku which)
(bc-url (get-variant-id sku which)))
(define (grid->table grid)
(define (table-row row [cell-tag 'td])
`(tr (th ((style "width:40%")) ,(car row)) ,@(map (λ(c) `(,cell-tag ,c)) (cdr row))))
(define (table-header row)
(table-row row 'th))
`(table ((class "buy-table"))
,(table-header (car grid))
,@(map table-row (cdr grid))))
(define (people->string p)
(string-append (match p
[2 "12"]
[5 "35"]
[10 "610"]) " people"))
(require txexpr racket/string)
(define (textify x)
(cond
;; convert nbsp to string
[(string? x) (string-replace x #px"[\\s#\u00A0]+" " ")]
[(eq? 'nbsp x) " "]
[(list? x) (string-append* (map textify (if (txexpr? x)
(get-elements x)
x)))]))
(module+ test
(require rackunit)
(check-equal?
(textify
'(span (a ((href "equity.html")) "Equity") " + " (a ((href "concourse.html")) "Concourse Standard") " + " (a ((href "triplicate.html")) "Triplicate")))
"Equity + Concourse Standard + Triplicate"))
(define (buy-link sku people)
(define price (get-price sku people))
(define item (textify (sku-name sku)))
`(a ((class "checkout_clicker")
(href "#")
(item ,item)
(label ,(format "~a (~a-person license)" item people))
(quantity ,(number->string people))
(amount ,(number->string price))
(success "/order-success.html")
(failure "/order-failure.html"))
,(format "$~a" price)))
(define (make-buy-grid #:people people-list #:skus sku-list)
(cons
(cons "" (map people->string people-list))
(map (λ(sku) (cons (sku-name sku)
(map (λ(p) (buy-link sku p)) people-list))) sku-list)))
(define (make-buy-table #:people [people-list '(2 5 10)] #:skus sku-list)
(grid->table (make-buy-grid #:people people-list #:skus sku-list)))