-
Notifications
You must be signed in to change notification settings - Fork 1
/
OrderItems.go
127 lines (111 loc) · 4.02 KB
/
OrderItems.go
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package menubotlib
import (
"fmt"
"math"
"regexp"
"strconv"
"strings"
)
type MenuIndication struct {
ItemMenuNum int `json:"ItemMenuNum"`
ItemAmount string `json:"ItemAmount"`
}
type OrderItems struct {
MenuIndications []MenuIndication `json:"MenuIndications"`
}
// Example:
//{"MenuIndications":[{"ItemMenuNum":1,"ItemAmount":"2x3"},{"ItemMenuNum":2,"ItemAmount":"1x5"}]}
//{"MenuIndications":[{"ItemMenuNum":9,"ItemAmount":"12"},{"ItemMenuNum":10,"ItemAmount":"1x3, 3x2, 2x1"},{"ItemMenuNum":6,"ItemAmount":"5"}]}
func findItemInSelections(ItmMnuNum int, ctlgselections []CatalogueSelection) (CatalogueItem, error) {
for _, selection := range ctlgselections {
for _, item := range selection.Items {
if item.CatalogueItemID == ItmMnuNum {
return item, nil
}
}
}
return CatalogueItem{}, fmt.Errorf("item menu num not found")
}
func tallyOptions(options []string, userInput string) (int, error) {
userItems := strings.Split(userInput, ",")
totalPrice := 0
for _, userItem := range userItems {
userItem = strings.TrimSpace(userItem)
var optionNumber, amount int
_, err := fmt.Sscanf(userItem, "%dx%d", &optionNumber, &amount)
if err != nil {
return -99, fmt.Errorf("while tallying order, error parsing userInput: %s, %v", userItem, err)
}
if optionNumber <= 0 || optionNumber > len(options) {
return -99, fmt.Errorf("while tallying order, invalid option number: %d", optionNumber)
}
var price int
// Define the regular expression pattern
re := regexp.MustCompile(`@ R(\d+)`)
// Find the match
match := re.FindStringSubmatch(options[optionNumber-1])
if len(match) < 2 {
return -99, fmt.Errorf("while tallying order, price for item number: " + strconv.Itoa(optionNumber) + " not found in item option string")
}
// Convert the extracted string to an integer
price, err = strconv.Atoi(match[1])
if err != nil {
return -99, fmt.Errorf("while tallying order, error parsing option price: %s, %v", options[optionNumber-1], err)
}
totalPrice += amount * price
}
return totalPrice, nil
}
// Helper function to find the best price based on the order amount and options available
func findBestPrice(orderAmount int, options []string) (int, error) {
bestPrice := math.MaxInt32
for _, option := range options {
var optionWeight int
var optionPrice int
_, err := fmt.Sscanf(option, "%dg @ R%d", &optionWeight, &optionPrice)
if err == nil && orderAmount >= optionWeight {
if bestPrice == -1 || optionPrice < bestPrice {
bestPrice = optionPrice
}
}
}
if bestPrice == math.MaxInt32 {
// No valid price found
return -99, fmt.Errorf("while tallying order, error finding best price")
}
return bestPrice, nil
}
func (c *OrderItems) CalculatePrice(ctlgselections []CatalogueSelection) (int, string) {
cartSummary := ""
cartTotal := 0
for _, orderItem := range c.MenuIndications {
// Look up the item in the sections
foundItem, err := findItemInSelections(orderItem.ItemMenuNum, ctlgselections)
if err != nil {
// Add excluded items to the cart summary.
cartSummary += fmt.Sprintf("while tallying the order, user specified Item menu nunmber: %d not found in price list", orderItem.ItemMenuNum)
continue
}
switch foundItem.PricingType {
case WeightItem:
weight, err := strconv.Atoi(orderItem.ItemAmount)
if err != nil {
cartSummary += fmt.Sprintf("while tallying the order, error converting userInput to weight: %s to integer: %v", orderItem.ItemAmount, err)
}
price, err := findBestPrice(weight, foundItem.Options)
if err != nil {
cartSummary += fmt.Sprintln("while tallying the order, error finding best price")
}
cartTotal += (weight * price)
case SingleItem:
optionsTotal, err := tallyOptions(foundItem.Options, orderItem.ItemAmount)
if err != nil {
cartSummary += fmt.Sprintf("while tallying the order, error extracting the order item price: %v", err)
}
cartTotal += optionsTotal
default:
cartSummary += fmt.Sprintf("while tallying the order, unknown pricing type: %s", foundItem.PricingType)
}
}
return cartTotal, cartSummary
}