-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathview.go
143 lines (122 loc) · 3.95 KB
/
view.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"context"
"fmt"
"html/template"
"log"
"net/http"
"sort"
"github.com/ThreeDotsLabs/watermill/components/cqrs"
"github.com/czeslavo/process-manager/1_voiding/billing"
"github.com/czeslavo/process-manager/1_voiding/manager"
"github.com/czeslavo/process-manager/1_voiding/messages"
"github.com/czeslavo/process-manager/1_voiding/reports"
)
func runHttpServer(
ctx context.Context,
commandBus *cqrs.CommandBus,
reportsService *reports.Service,
billingService *billing.Service,
processManager *manager.DocumentVoidingProcessManager,
) {
http.HandleFunc("/documents/void", func(w http.ResponseWriter, r *http.Request) {
documentID := r.PostFormValue("id")
if err := commandBus.Send(ctx, &messages.RequestDocumentVoiding{
DocumentID: documentID,
}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
http.Redirect(w, r, "/", http.StatusMovedPermanently)
})
http.HandleFunc("/reports/publish", func(w http.ResponseWriter, r *http.Request) {
customerID := r.PostFormValue("id")
if err := commandBus.Send(ctx, &messages.PublishReport{CustomerID: customerID}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
http.Redirect(w, r, "/", http.StatusMovedPermanently)
})
http.HandleFunc("/processes/ack", func(w http.ResponseWriter, r *http.Request) {
processID := r.PostFormValue("id")
if err := commandBus.Send(ctx, &messages.AcknowledgeProcessFailure{ProcessID: processID}); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
http.Redirect(w, r, "/", http.StatusMovedPermanently)
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl, err := template.ParseFiles("./index.html")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
if err := tmpl.Execute(w, buildReadModel(reportsService, billingService, processManager)); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
func buildReadModel(reportsService *reports.Service, billingService *billing.Service, processManager *manager.DocumentVoidingProcessManager) interface{} {
type document struct {
ID string
Amount string
IsVoided bool
VoidingProcessState string
}
type report struct {
CustomerID string
TotalAmount string
Documents []document
IsPublished bool
}
type process struct {
State string
ID string
DocumentID string
}
type readModel struct {
Reports []report
Processes []process
}
var reportsToDisplay []report
for _, r := range reportsService.GetReports() {
var docs []document
for _, docID := range r.DocumentIDs {
doc, err := billingService.GetDocument(docID)
if err != nil {
panic(err)
}
var processState string
process, ongoing := processManager.GetProcessForDocument(doc.ID)
if ongoing {
processState = process.State.String()
}
docs = append(docs, document{
ID: doc.ID,
Amount: fmt.Sprintf("%.2f", doc.TotalAmount),
IsVoided: doc.IsVoided,
VoidingProcessState: processState,
})
}
reportsToDisplay = append(
reportsToDisplay, report{
CustomerID: r.CustomerID,
TotalAmount: fmt.Sprintf("%.2f", r.TotalAmount),
Documents: docs,
IsPublished: r.IsPublished,
})
}
var processesToDisplay []process
for _, p := range processManager.GetAllOngoingOrFailed() {
processesToDisplay = append(
processesToDisplay, process{
State: p.State.String(),
ID: p.ID,
DocumentID: p.DocumentID,
})
}
sort.Slice(reportsToDisplay, func(i, j int) bool { return reportsToDisplay[i].CustomerID > reportsToDisplay[j].CustomerID })
sort.Slice(processesToDisplay, func(i, j int) bool { return processesToDisplay[i].ID > processesToDisplay[j].ID })
return readModel{
Reports: reportsToDisplay,
Processes: processesToDisplay,
}
}