Skip to content

Commit 2b957fe

Browse files
committed
Extract statement data creation to a file
1 parent b781284 commit 2b957fe

File tree

2 files changed

+113
-102
lines changed

2 files changed

+113
-102
lines changed
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package theatre
2+
3+
import (
4+
"fmt"
5+
"math"
6+
)
7+
8+
type StatementData struct {
9+
Customer string
10+
Performances []EnrichedPerformance
11+
TotalAmount int
12+
TotalVolumeCredits int
13+
}
14+
15+
type EnrichedPerformance struct {
16+
PlayID string
17+
Audience int
18+
play Play
19+
amount int
20+
volumeCredits int
21+
}
22+
23+
type Plays map[string]Play
24+
25+
func (p Plays) playFor(aPerformance Performance) Play {
26+
return p[aPerformance.PlayID]
27+
}
28+
29+
func createStatementData(invoice Invoice, plays map[string]Play) (StatementData, error) {
30+
result := StatementData{}
31+
result.Customer = invoice.Customer
32+
33+
var enrichedPerformances []EnrichedPerformance
34+
for _, performance := range invoice.Performances {
35+
enrichedPerformance, err := enrichPerformance(performance, Plays(plays))
36+
if err != nil {
37+
return StatementData{}, err
38+
}
39+
enrichedPerformances = append(enrichedPerformances, enrichedPerformance)
40+
}
41+
result.Performances = enrichedPerformances
42+
43+
result.TotalAmount = totalAmount(result)
44+
result.TotalVolumeCredits = totalVolumeCredits(result)
45+
46+
return result, nil
47+
}
48+
49+
func enrichPerformance(performance Performance, plays Plays) (EnrichedPerformance, error) {
50+
result := EnrichedPerformance{}
51+
result.PlayID = performance.PlayID
52+
result.Audience = performance.Audience
53+
result.play = plays.playFor(performance)
54+
amount, err := amountFor(result)
55+
if err != nil {
56+
return EnrichedPerformance{}, err
57+
}
58+
result.amount = amount
59+
result.volumeCredits = volumeCreditsFor(result)
60+
61+
return result, nil
62+
}
63+
64+
func totalVolumeCredits(data StatementData) int {
65+
result := 0
66+
for _, perf := range data.Performances {
67+
result += perf.volumeCredits
68+
}
69+
return result
70+
}
71+
72+
func totalAmount(data StatementData) int {
73+
result := 0
74+
for _, perf := range data.Performances {
75+
result += perf.amount
76+
}
77+
return result
78+
}
79+
80+
func volumeCreditsFor(aPerformance EnrichedPerformance) int {
81+
result := int(math.Max(float64(aPerformance.Audience)-30, 0))
82+
// add extra credit for every ten comedy attendees
83+
if aPerformance.play.Type == "comedy" {
84+
result += int(math.Floor(float64(aPerformance.Audience) / 5))
85+
}
86+
return result
87+
}
88+
89+
func amountFor(aPerformance EnrichedPerformance) (int, error) {
90+
result := 0
91+
switch aPerformance.play.Type {
92+
case "tragedy":
93+
result = 40000
94+
if aPerformance.Audience > 30 {
95+
result += 1000 * (aPerformance.Audience - 30)
96+
}
97+
case "comedy":
98+
result = 30000
99+
if aPerformance.Audience > 20 {
100+
result += 10000 + 500*(aPerformance.Audience-20)
101+
}
102+
result += 300 * aPerformance.Audience
103+
default:
104+
return 0, fmt.Errorf("unknown type: %s", aPerformance.play.Type)
105+
}
106+
return result, nil
107+
}

refactoring/theatre/statement.go

Lines changed: 6 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package theatre
22

33
import (
44
"fmt"
5-
"math"
65

76
"github.com/leekchan/accounting"
87
)
@@ -22,110 +21,15 @@ type Performance struct {
2221
Audience int
2322
}
2423

25-
type EnrichedPerformance struct {
26-
PlayID string
27-
Audience int
28-
play Play
29-
amount int
30-
volumeCredits int
31-
}
32-
33-
type StatementPrinter struct {
34-
invoice Invoice
35-
plays map[string]Play
36-
}
24+
type StatementPrinter struct{}
3725

3826
func (s StatementPrinter) Print(invoice Invoice, plays map[string]Play) (string, error) {
39-
s.invoice = invoice
40-
s.plays = plays
41-
statementData := StatementData{}
42-
statementData.Customer = s.invoice.Customer
43-
44-
var enrichedPerformances []EnrichedPerformance
45-
for _, performance := range s.invoice.Performances {
46-
enrichedPerformance, err := s.enrichPerformance(performance)
47-
if err != nil {
48-
return "", err
49-
}
50-
enrichedPerformances = append(enrichedPerformances, enrichedPerformance)
51-
}
52-
statementData.Performances = enrichedPerformances
53-
54-
statementData.totalAmount = s.totalAmount(statementData)
55-
statementData.totalVolumeCredits = s.totalVolumeCredits(statementData)
56-
57-
return renderPlainText(statementData), nil
58-
}
59-
60-
func (StatementPrinter) totalVolumeCredits(data StatementData) int {
61-
result := 0
62-
for _, perf := range data.Performances {
63-
result += perf.volumeCredits
64-
}
65-
return result
66-
}
67-
68-
func (StatementPrinter) totalAmount(data StatementData) int {
69-
result := 0
70-
for _, perf := range data.Performances {
71-
result += perf.amount
72-
}
73-
return result
74-
}
75-
76-
func (s StatementPrinter) enrichPerformance(performance Performance) (EnrichedPerformance, error) {
77-
result := EnrichedPerformance{}
78-
result.PlayID = performance.PlayID
79-
result.Audience = performance.Audience
80-
result.play = s.playFor(performance)
81-
amount, err := s.amountFor(result)
27+
statementData, err := createStatementData(invoice, plays)
8228
if err != nil {
83-
return EnrichedPerformance{}, err
84-
}
85-
result.amount = amount
86-
result.volumeCredits = s.volumeCreditsFor(result)
87-
88-
return result, nil
89-
}
90-
91-
func (StatementPrinter) volumeCreditsFor(aPerformance EnrichedPerformance) int {
92-
result := int(math.Max(float64(aPerformance.Audience)-30, 0))
93-
// add extra credit for every ten comedy attendees
94-
if aPerformance.play.Type == "comedy" {
95-
result += int(math.Floor(float64(aPerformance.Audience) / 5))
29+
return "", err
9630
}
97-
return result
98-
}
99-
100-
func (s StatementPrinter) playFor(aPerformance Performance) Play {
101-
return s.plays[aPerformance.PlayID]
102-
}
10331

104-
func (StatementPrinter) amountFor(aPerformance EnrichedPerformance) (int, error) {
105-
result := 0
106-
switch aPerformance.play.Type {
107-
case "tragedy":
108-
result = 40000
109-
if aPerformance.Audience > 30 {
110-
result += 1000 * (aPerformance.Audience - 30)
111-
}
112-
case "comedy":
113-
result = 30000
114-
if aPerformance.Audience > 20 {
115-
result += 10000 + 500*(aPerformance.Audience-20)
116-
}
117-
result += 300 * aPerformance.Audience
118-
default:
119-
return 0, fmt.Errorf("unknown type: %s", aPerformance.play.Type)
120-
}
121-
return result, nil
122-
}
123-
124-
type StatementData struct {
125-
Customer string
126-
Performances []EnrichedPerformance
127-
totalAmount int
128-
totalVolumeCredits int
32+
return renderPlainText(statementData), nil
12933
}
13034

13135
func renderPlainText(data StatementData) string {
@@ -140,8 +44,8 @@ func renderPlainText(data StatementData) string {
14044
)
14145
}
14246

143-
result += fmt.Sprintf("Amount owed is %s\n", usd(data.totalAmount))
144-
result += fmt.Sprintf("You earned %d credits\n", data.totalVolumeCredits)
47+
result += fmt.Sprintf("Amount owed is %s\n", usd(data.TotalAmount))
48+
result += fmt.Sprintf("You earned %d credits\n", data.TotalVolumeCredits)
14549
return result
14650
}
14751

0 commit comments

Comments
 (0)