Invoice
February 17, 2015
This function produces a single invoice, stopping input when an empty description is entered:
(define (write-invoice)
(let-values (((ds qs ps tot) (read-items)))
(when (pair? ds)
(format #t "~10a~20a~%" "" "Praxis Grocery Store")
(format #t "~15a~11a~%~%" "" (date-format (today) "%d %b %Y"))
(do ((i 1 (+ i 1)) (ds ds (cdr ds)) (qs qs (cdr qs)) (ps ps (cdr ps)))
((null? ds))
(format #t "~3a~20a~3@a~6,2f~8,2f~%" i (car ds) (car qs) (car ps) (* (car qs) (car ps))))
(format #t "~32a~8,2f~%" " Subtotal" tot)
(format #t "~32a~8,2f~%" " Tax 5.25%" (* tot 0.0525))
(format #t "~32a~8,2f~%" " Total" (* tot 1.0525)))))
It calls read-items
to input the items and compute the subtotal:
(define (read-items)
(let loop ((ds (list)) (qs (list)) (ps (list)) (tot 0))
(display "Description? ")
(let ((descrip (get-line (current-input-port))))
(if (zero? (string-length descrip))
(values (reverse ds) (reverse qs) (reverse ps) tot)
(begin (display "Quantity? ")
(let ((quant (string->number (get-line (current-input-port)))))
(display "Unit price? ")
(let ((price (string->number (get-line (current-input-port)))))
(loop (cons descrip ds) (cons quant qs) (cons price ps)
(+ tot (* quant price))))))))))
Here’s an example:
> (write-invoice)
Description? Gallon 2% Milk
Quantity? 2
Unit price? 3.30
Description? Ground Beef 93% lean
Quantity? 1
Unit price? 5.98
Description? Can Clam Chowder
Quantity? 12
Unit price? 1.78
Description? 12oz Jar Honey
Quantity? 1
Unit price? 4.42
Description? Half-Dozen Eggs
Quantity? 1
Unit price? 1.18
Description?
Praxis Grocery Store
16 Feb 2015
1 Gallon 2% Milk 2 3.30 6.60
2 Ground Beef 93% lean 1 5.98 5.98
3 Can Clam Chowder 12 1.78 21.36
4 12oz Jar Honey 1 4.42 4.42
5 Half-Dozen Eggs 1 1.18 1.18
Subtotal 39.54
Tax 5.25% 2.08
Total 41.62
We used get-line
and format
from R6RS and date arithmetic from the Standard Prelude. Codepad still doesn’t seem to be able to save programs, so the complete program is assembled at the next page.
One Response to “Invoice”