3 people like it.

Retail domain for Tesco

Simple retail domain for Tesco with scan, cancel and tendering and calculation of total price.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
22: 
23: 
24: 
25: 
26: 
27: 
28: 
29: 
30: 
31: 
32: 
33: 
34: 
35: 
36: 
37: 
38: 
39: 
40: 
41: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
57: 
58: 
59: 
60: 
61: 
62: 
63: 
64: 
65: 
66: 
67: 
68: 
69: 
70: 
71: 
72: 
73: 
74: 
75: 
76: 
77: 
78: 
79: 
80: 
// ------------------------------------------------------------------
// Domain.fs
// ------------------------------------------------------------------

namespace Tesco.Domain

type BarCode = string
type Name = string
type Price = decimal
type Quantity = decimal

type Product = 
  { Name : Name
    BarCode : BarCode
    Price : Price }

type ProductList = list<Product>

type TenderType = 
  | Cash 
  | Card 
  | Voucher 

type SaleLine = 
  | ScanLine of Product * Quantity
  | CancelLine of int
  | TenderLine of TenderType * Price

type Sale = list<SaleLine>

// ------------------------------------------------------------------
// Main.fs
// ------------------------------------------------------------------

module Tesco.Main
open Tesco.Domain

let database =
  [ { Name="Hand sanitizer"; BarCode="5055028300057"; Price=3.99M }
    { Name="Record cards"; BarCode="5014108161018"; Price=2.99M }
    { Name="PostIt Notes"; BarCode="051135813317"; Price=1.99M } ]

let findProduct barcode = 
  database |> List.tryFind (fun prod ->
    prod.BarCode = barcode)

open System

let totalPrice (sale:Sale) = 
  sale |> List.sumBy(fun line ->
    match line with
    | ScanLine(prod, quant) -> prod.Price * quant
    | CancelLine(index) ->
        match sale.[index] with
        | ScanLine(prod, quant) -> -(prod.Price * quant)
        | _ -> failwith "Can only cancel scan lines"
    | TenderLine(_, _) -> 0.0M)        

let rec readSale (sale:Sale) =
  let code = Console.ReadLine()
  if code = "q" then
    List.rev sale
  else
    match findProduct code with
    | Some prod -> 
        printfn "Adding: %s" prod.Name
        let line = ScanLine(prod, 1.0M)
        let sale = line::sale
        readSale sale
    | None ->
        printfn "No candy :-("
        readSale sale

[<EntryPoint>]
let main argv = 
    let sale = readSale []
    let total = totalPrice sale
    printfn "Your purchase:\n%A" sale
    printfn "\nTotal: %A" total
    0 // return an integer exit code
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
type Name = string

Full name: Tesco.Domain.Name
type Price = decimal

Full name: Tesco.Domain.Price
Multiple items
val decimal : value:'T -> decimal (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.decimal

--------------------
type decimal = System.Decimal

Full name: Microsoft.FSharp.Core.decimal

--------------------
type decimal<'Measure> = decimal

Full name: Microsoft.FSharp.Core.decimal<_>
type Quantity = decimal

Full name: Tesco.Domain.Quantity
type Product =
  {Name: Name;
   BarCode: BarCode;
   Price: Price;}

Full name: Tesco.Domain.Product
Multiple items
Product.Name: Name

--------------------
type Name = string

Full name: Tesco.Domain.Name
Multiple items
Product.BarCode: BarCode

--------------------
type BarCode = string

Full name: Tesco.Domain.BarCode
Multiple items
Product.Price: Price

--------------------
type Price = decimal

Full name: Tesco.Domain.Price
type ProductList = Product list

Full name: Tesco.Domain.ProductList
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
type TenderType =
  | Cash
  | Card
  | Voucher

Full name: Tesco.Domain.TenderType
union case TenderType.Cash: TenderType
union case TenderType.Card: TenderType
union case TenderType.Voucher: TenderType
type SaleLine =
  | ScanLine of Product * Quantity
  | CancelLine of int
  | TenderLine of TenderType * Price

Full name: Tesco.Domain.SaleLine
union case SaleLine.ScanLine: Product * Quantity -> SaleLine
union case SaleLine.CancelLine: int -> SaleLine
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
union case SaleLine.TenderLine: TenderType * Price -> SaleLine
type Sale = SaleLine list

Full name: Tesco.Domain.Sale
type BarCode = string

Full name: Tesco.Domain.BarCode
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
type List<'T> =
  | ( [] )
  | ( :: ) of Head: 'T * Tail: 'T list
  interface IEnumerable
  interface IEnumerable<'T>
  member Head : 'T
  member IsEmpty : bool
  member Item : index:int -> 'T with get
  member Length : int
  member Tail : 'T list
  static member Cons : head:'T * tail:'T list -> 'T list
  static member Empty : 'T list

Full name: Microsoft.FSharp.Collections.List<_>
val tryFind : predicate:('T -> bool) -> list:'T list -> 'T option

Full name: Microsoft.FSharp.Collections.List.tryFind
namespace System
val sumBy : projection:('T -> 'U) -> list:'T list -> 'U (requires member ( + ) and member get_Zero)

Full name: Microsoft.FSharp.Collections.List.sumBy
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val rev : list:'T list -> 'T list

Full name: Microsoft.FSharp.Collections.List.rev
union case Option.Some: Value: 'T -> Option<'T>
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
union case Option.None: Option<'T>
Multiple items
type EntryPointAttribute =
  inherit Attribute
  new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
Raw view Test code New version

More information

Link:http://fssnip.net/pU
Posted:9 years ago
Author:Tomas Petricek & Phil Trelford
Tags: retail , domain