From d5bfb87b6870c3b276b64ad4304abb1b1cbb4ab4 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 08:27:10 +0100 Subject: [PATCH 01/18] retry and better logs --- synced-pool.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/synced-pool.go b/synced-pool.go index 8412dc4..d06f281 100644 --- a/synced-pool.go +++ b/synced-pool.go @@ -363,17 +363,23 @@ func (p *SyncedPool) removeLocalGrain(id CartId) { func (p *SyncedPool) AddRemote(host string) { _, hasHost := p.remotes[host] - if host == "" || hasHost { + if host == "" || hasHost || host == p.Hostname { return } - // if host == "" || hasHost || host == p.Hostname { - // return - // } + client := NewConnection(fmt.Sprintf("%s:1338", host)) - r, err := client.Call(Ping, nil) - if err != nil { - log.Printf("Error connecting to remote %s: %s\n", host, err) - return + var r *FrameWithPayload + var err error + pings := 3 + for pings >= 0 { + r, err = client.Call(Ping, nil) + if err != nil { + log.Printf("Ping failed when adding %s, trying %d more times\n", host, pings) + pings-- + time.Sleep(time.Millisecond * 300) + continue + } + break } log.Printf("Connected to remote %s: %v\n", host, r) From 8bbe3a6f5129d76345d092836d86e1527f5fb76d Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 08:36:04 +0100 Subject: [PATCH 02/18] return hosts not ok --- synced-pool.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/synced-pool.go b/synced-pool.go index d06f281..e7611bd 100644 --- a/synced-pool.go +++ b/synced-pool.go @@ -93,7 +93,15 @@ func (p *SyncedPool) NegotiateHandler(data *FrameWithPayload, resultChan chan<- go p.AddRemote(host) } - resultChan <- MakeFrameWithPayload(RemoteNegotiateResponse, 200, []byte("ok")) + p.mu.RLock() + defer p.mu.RUnlock() + hosts := make([]string, 0, len(p.remotes)) + for _, r := range p.remotes { + if r.IsHealthy() { + hosts = append(hosts, r.Host) + } + } + resultChan <- MakeFrameWithPayload(RemoteNegotiateResponse, 200, []byte(strings.Join(hosts, ";"))) return nil } From d9563460f7c1722221aea3806c32f626c5358a55 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 08:54:16 +0100 Subject: [PATCH 03/18] handle ping --- synced-pool.go | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/synced-pool.go b/synced-pool.go index e7611bd..037cef9 100644 --- a/synced-pool.go +++ b/synced-pool.go @@ -369,18 +369,19 @@ func (p *SyncedPool) removeLocalGrain(id CartId) { } func (p *SyncedPool) AddRemote(host string) { - + p.mu.Lock() + defer p.mu.Unlock() _, hasHost := p.remotes[host] if host == "" || hasHost || host == p.Hostname { return } client := NewConnection(fmt.Sprintf("%s:1338", host)) - var r *FrameWithPayload + var err error pings := 3 for pings >= 0 { - r, err = client.Call(Ping, nil) + _, err = client.Call(Ping, nil) if err != nil { log.Printf("Ping failed when adding %s, trying %d more times\n", host, pings) pings-- @@ -389,39 +390,37 @@ func (p *SyncedPool) AddRemote(host string) { } break } - log.Printf("Connected to remote %s: %v\n", host, r) + log.Printf("Connected to remote %s", host) remote := RemoteHost{ Connection: client, MissedPings: 0, Host: host, } - p.mu.Lock() + p.remotes[host] = &remote - p.mu.Unlock() - - go func() { - for range time.Tick(time.Second * 3) { - - err := remote.Ping() - - for err != nil { - time.Sleep(time.Millisecond * 200) - if !remote.IsHealthy() { - log.Printf("Removing host, unable to communicate with %s", host) - p.RemoveHost(&remote) - return - } - err = remote.Ping() - } - } - }() connectedRemotes.Set(float64(len(p.remotes))) - log.Printf("Added remote %s\n", remote.Host) + go p.HandlePing(&remote) go remote.Initialize(p) - return +} + +func (p *SyncedPool) HandlePing(remote *RemoteHost) { + for range time.Tick(time.Second * 3) { + + err := remote.Ping() + + for err != nil { + time.Sleep(time.Millisecond * 200) + if !remote.IsHealthy() { + log.Printf("Removing host, unable to communicate with %s", remote.Host) + p.RemoveHost(remote) + return + } + err = remote.Ping() + } + } } func (p *SyncedPool) getGrain(id CartId) (Grain, error) { From 0fe6cb092040448b2ac094dde9cb6563de170361 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 18:52:51 +0100 Subject: [PATCH 04/18] discarded host handler --- discarded-host.go | 79 ++++++++++++++++++++++++++++++++++++++++++ discarded-host_test.go | 17 +++++++++ synced-pool.go | 47 +++++++++++-------------- 3 files changed, 117 insertions(+), 26 deletions(-) create mode 100644 discarded-host.go create mode 100644 discarded-host_test.go diff --git a/discarded-host.go b/discarded-host.go new file mode 100644 index 0000000..f1b6780 --- /dev/null +++ b/discarded-host.go @@ -0,0 +1,79 @@ +package main + +import ( + "fmt" + "log" + "net" + "sync" + "time" +) + +type DiscardedHost struct { + *Connection + Host string + Tries int +} + +type DiscardedHostHandler struct { + mu sync.RWMutex + port int + hosts []*DiscardedHost + onConnection *func(string) +} + +func (d *DiscardedHostHandler) run() { + for range time.Tick(time.Second) { + d.mu.RLock() + lst := make([]*DiscardedHost, 0, len(d.hosts)) + for _, host := range d.hosts { + if host.Tries >= 0 || host.Tries < 5 { + go d.testConnection(host) + lst = append(lst, host) + } + } + d.mu.RUnlock() + d.mu.Lock() + d.hosts = lst + d.mu.Unlock() + } + +} + +func (d *DiscardedHostHandler) testConnection(host *DiscardedHost) { + addr := fmt.Sprintf("%s:%d", host.Host, d.port) + conn, err := net.Dial("tcp", addr) + + if err != nil { + host.Tries++ + host.Tries = -1 + } else { + conn.Close() + if d.onConnection != nil { + fn := *d.onConnection + fn(host.Host) + } + } +} + +func NewDiscardedHostHandler(port int) *DiscardedHostHandler { + ret := &DiscardedHostHandler{ + hosts: make([]*DiscardedHost, 0), + port: port, + } + go ret.run() + return ret +} + +func (d *DiscardedHostHandler) SetReconnectHandler(fn func(string)) { + d.onConnection = &fn +} + +func (d *DiscardedHostHandler) AppendHost(host string) { + d.mu.Lock() + defer d.mu.Unlock() + log.Printf("Retrying host %s", host) + d.hosts = append(d.hosts, &DiscardedHost{ + Host: host, + Tries: 0, + }) +} diff --git a/discarded-host_test.go b/discarded-host_test.go new file mode 100644 index 0000000..a4303ff --- /dev/null +++ b/discarded-host_test.go @@ -0,0 +1,17 @@ +package main + +import ( + "testing" + "time" +) + +func TestDiscardedHost(t *testing.T) { + dh := NewDiscardedHostHandler(func(host string) { + t.Log(host) + }, 8080) + dh.AppendHost("localhost") + time.Sleep(2 * time.Second) + if dh.hosts[0].Tries == 0 { + t.Error("Host not tested") + } +} diff --git a/synced-pool.go b/synced-pool.go index 037cef9..aa91021 100644 --- a/synced-pool.go +++ b/synced-pool.go @@ -22,12 +22,13 @@ type HealthHandler interface { } type SyncedPool struct { - Server *GenericListener - mu sync.RWMutex - Hostname string - local *GrainLocalPool - remotes map[string]*RemoteHost - remoteIndex map[CartId]*RemoteGrain + Server *GenericListener + mu sync.RWMutex + discardedHostHandler *DiscardedHostHandler + Hostname string + local *GrainLocalPool + remotes map[string]*RemoteHost + remoteIndex map[CartId]*RemoteGrain } var ( @@ -110,13 +111,13 @@ func (p *SyncedPool) GrainOwnerChangeHandler(data *FrameWithPayload, resultChan idAndHostParts := strings.Split(string(data.Payload), ";") if len(idAndHostParts) != 2 { - log.Printf("Invalid remote grain change message\n") + log.Printf("Invalid remote grain change message") resultChan <- MakeFrameWithPayload(AckError, 500, []byte("invalid")) return nil } id := ToCartId(idAndHostParts[0]) host := idAndHostParts[1] - log.Printf("Handling remote grain owner change to %s for id %s\n", host, id) + log.Printf("Handling remote grain owner change to %s for id %s", host, id) for _, r := range p.remotes { if r.Host == host && r.IsHealthy() { go p.SpawnRemoteGrain(id, host) @@ -136,11 +137,11 @@ func (p *SyncedPool) RemoveRemoteGrain(id CartId) { func (p *SyncedPool) SpawnRemoteGrain(id CartId, host string) { if id.String() == "" { - log.Printf("Invalid grain id, %s\n", id) + log.Printf("Invalid grain id, %s", id) return } if p.local.grains[id] != nil { - log.Printf("Grain %s already exists locally, owner is (%s)\n", id, host) + log.Printf("Grain %s already exists locally, owner is (%s)", id, host) p.mu.Lock() delete(p.local.grains, id) p.mu.Unlock() @@ -148,15 +149,9 @@ func (p *SyncedPool) SpawnRemoteGrain(id CartId, host string) { remote, err := NewRemoteGrain(id, host) if err != nil { - log.Printf("Error creating remote grain %v\n", err) + log.Printf("Error creating remote grain %v", err) return } - // go func() { - // <-remote.Died - // p.RemoveRemoteGrain(id) - // p.HandleHostError(host) - // log.Printf("Remote grain %s died, host: %s\n", id.String(), host) - // }() p.mu.Lock() p.remoteIndex[id] = remote @@ -183,16 +178,16 @@ func NewSyncedPool(local *GrainLocalPool, hostname string, discovery Discovery) } log.Printf("Listening on %s", listen) - + dh := NewDiscardedHostHandler(1338) pool := &SyncedPool{ - Server: server, - Hostname: hostname, - local: local, - - remotes: make(map[string]*RemoteHost), - remoteIndex: make(map[CartId]*RemoteGrain), + Server: server, + Hostname: hostname, + local: local, + discardedHostHandler: dh, + remotes: make(map[string]*RemoteHost), + remoteIndex: make(map[CartId]*RemoteGrain), } - + dh.SetReconnectHandler(pool.AddRemote) server.AddHandler(Ping, pool.PongHandler) server.AddHandler(GetCartIds, pool.GetCartIdHandler) server.AddHandler(RemoteNegotiate, pool.NegotiateHandler) @@ -266,11 +261,11 @@ func (p *SyncedPool) ExcludeKnown(hosts []string) []string { } func (p *SyncedPool) RemoveHost(host *RemoteHost) { - p.mu.Lock() delete(p.remotes, host.Host) p.mu.Unlock() p.RemoveHostMappedCarts(host) + p.discardedHostHandler.AppendHost(host.Host) connectedRemotes.Set(float64(len(p.remotes))) } From d617fd9657c5bab4f2a483addd1308462360a108 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 19:02:42 +0100 Subject: [PATCH 05/18] better logs --- discarded-host.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/discarded-host.go b/discarded-host.go index f1b6780..c50d68d 100644 --- a/discarded-host.go +++ b/discarded-host.go @@ -29,6 +29,10 @@ func (d *DiscardedHostHandler) run() { if host.Tries >= 0 || host.Tries < 5 { go d.testConnection(host) lst = append(lst, host) + } else { + if host.Tries > 0 { + log.Printf("Host %s discarded after %d tries", host.Host, host.Tries) + } } } d.mu.RUnlock() @@ -71,7 +75,7 @@ func (d *DiscardedHostHandler) SetReconnectHandler(fn func(string)) { func (d *DiscardedHostHandler) AppendHost(host string) { d.mu.Lock() defer d.mu.Unlock() - log.Printf("Retrying host %s", host) + log.Printf("Adding host %s to retry list", host) d.hosts = append(d.hosts, &DiscardedHost{ Host: host, Tries: 0, From 3f6f78c83912d8aaf801c9017b0897647aebd41e Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 19:33:04 +0100 Subject: [PATCH 06/18] more features --- cart-grain.go | 96 ++++++++++++++++++++++++++++-------------- cart-grain_test.go | 19 +++++++++ discarded-host_test.go | 5 ++- proto/messages.pb.go | 92 ++++++++++++++++++++++++++++------------ proto/messages.proto | 6 ++- 5 files changed, 156 insertions(+), 62 deletions(-) diff --git a/cart-grain.go b/cart-grain.go index 0b772fa..eb6fdcb 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -26,13 +26,26 @@ func (id *CartId) UnmarshalJSON(data []byte) error { return nil } +type StockStatus int + +const ( + OutOfStock StockStatus = 0 + LowStock StockStatus = 1 + InStock StockStatus = 2 +) + type CartItem struct { - Id int `json:"id"` - Sku string `json:"sku"` - Name string `json:"name"` - Price int64 `json:"price"` - Quantity int `json:"qty"` - Image string `json:"image"` + Id int `json:"id"` + ParentId int `json:"parentId,omitempty"` + Sku string `json:"sku"` + Name string `json:"name"` + Price int64 `json:"price"` + OrgPrice int64 `json:"orgPrice"` + Stock StockStatus `json:"stock"` + Quantity int `json:"qty"` + Tax int `json:"tax"` + Disclaimer string `json:"disclaimer,omitempty"` + Image string `json:"image,omitempty"` } type CartDelivery struct { @@ -79,34 +92,47 @@ func (c *CartGrain) GetCurrentState() (*FrameWithPayload, error) { return &ret, nil } +func getInt(data interface{}) (int, error) { + switch v := data.(type) { + case float64: + return int(v), nil + case int: + return v, nil + default: + return 0, fmt.Errorf("invalid type") + } +} + func getItemData(sku string, qty int) (*messages.AddItem, error) { item, err := FetchItem(sku) if err != nil { return nil, err } - price := 0 - priceField, ok := item.Fields[4] - if ok { - priceFloat, ok := priceField.(float64) - if !ok { - price, ok = priceField.(int) - if !ok { - return nil, fmt.Errorf("invalid price type") - } - } else { - price = int(priceFloat) - } - } - if price == 0 { + orgPrice, _ := getInt(item.Fields[6]) + + price, priceErr := getInt(item.Fields[5]) + + if priceErr != nil { return nil, fmt.Errorf("invalid price") } + stock := InStock + if item.StockLevel == "0" || item.StockLevel == "" { + stock = OutOfStock + } else if item.StockLevel == "5+" { + stock = LowStock + } + return &messages.AddItem{ - Quantity: int32(qty), - Price: int64(price), - Sku: sku, - Name: item.Title, - Image: item.Img, + Quantity: int32(qty), + Price: int64(price), + OrgPrice: int64(orgPrice), + Sku: sku, + Name: item.Title, + Image: item.Img, + Stock: int32(stock), + Tax: 2500, + Disclaimer: item.Disclaimer, }, nil } @@ -219,13 +245,21 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa } else { c.mu.Lock() c.lastItemId++ + tax := 2500 + if msg.Tax > 0 { + tax = int(msg.Tax) + } c.Items = append(c.Items, &CartItem{ - Id: c.lastItemId, - Quantity: int(msg.Quantity), - Sku: msg.Sku, - Name: msg.Name, - Price: msg.Price, - Image: msg.Image, + Id: c.lastItemId, + Quantity: int(msg.Quantity), + Sku: msg.Sku, + Name: msg.Name, + Price: msg.Price, + Image: msg.Image, + Stock: StockStatus(msg.Stock), + Disclaimer: msg.Disclaimer, + OrgPrice: msg.OrgPrice, + Tax: tax, }) c.TotalPrice += msg.Price * int64(msg.Quantity) c.mu.Unlock() diff --git a/cart-grain_test.go b/cart-grain_test.go index 162c25d..ddafc40 100644 --- a/cart-grain_test.go +++ b/cart-grain_test.go @@ -67,6 +67,25 @@ func TestAddToCartShortCut(t *testing.T) { } } +func TestAddRequestToGrain(t *testing.T) { + grain, err := spawn(ToCartId("kalle")) + if err != nil { + t.Errorf("Error spawning: %v\n", err) + } + msg := GetMessage(AddRequestType, &messages.AddRequest{ + Quantity: 2, + Sku: "763281", + }) + result, err := grain.HandleMessage(msg, false) + if err != nil { + t.Errorf("Error handling message: %v\n", err) + } + if result.StatusCode != 200 { + t.Errorf("Call failed\n") + } + t.Log(result) +} + func TestAddToCart(t *testing.T) { grain, err := spawn(ToCartId("kalle")) if err != nil { diff --git a/discarded-host_test.go b/discarded-host_test.go index a4303ff..e272bf7 100644 --- a/discarded-host_test.go +++ b/discarded-host_test.go @@ -6,9 +6,10 @@ import ( ) func TestDiscardedHost(t *testing.T) { - dh := NewDiscardedHostHandler(func(host string) { + dh := NewDiscardedHostHandler(8080) + dh.SetReconnectHandler(func(host string) { t.Log(host) - }, 8080) + }) dh.AppendHost("localhost") time.Sleep(2 * time.Second) if dh.hosts[0].Tries == 0 { diff --git a/proto/messages.pb.go b/proto/messages.pb.go index 49ff5a8..9ac3e5d 100644 --- a/proto/messages.pb.go +++ b/proto/messages.pb.go @@ -78,11 +78,15 @@ type AddItem struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` - Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"Price,omitempty"` - Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"Sku,omitempty"` - Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"Name,omitempty"` - Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"Image,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` + Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"Price,omitempty"` + OrgPrice int64 `protobuf:"varint,9,opt,name=OrgPrice,proto3" json:"OrgPrice,omitempty"` + Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"Sku,omitempty"` + Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"Name,omitempty"` + Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"Image,omitempty"` + Stock int32 `protobuf:"varint,7,opt,name=Stock,proto3" json:"Stock,omitempty"` + Tax int32 `protobuf:"varint,8,opt,name=Tax,proto3" json:"Tax,omitempty"` + Disclaimer string `protobuf:"bytes,10,opt,name=Disclaimer,proto3" json:"Disclaimer,omitempty"` } func (x *AddItem) Reset() { @@ -129,6 +133,13 @@ func (x *AddItem) GetPrice() int64 { return 0 } +func (x *AddItem) GetOrgPrice() int64 { + if x != nil { + return x.OrgPrice + } + return 0 +} + func (x *AddItem) GetSku() string { if x != nil { return x.Sku @@ -150,6 +161,27 @@ func (x *AddItem) GetImage() string { return "" } +func (x *AddItem) GetStock() int32 { + if x != nil { + return x.Stock + } + return 0 +} + +func (x *AddItem) GetTax() int32 { + if x != nil { + return x.Tax + } + return 0 +} + +func (x *AddItem) GetDisclaimer() string { + if x != nil { + return x.Disclaimer + } + return "" +} + type RemoveItem struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -354,28 +386,34 @@ var file_messages_proto_rawDesc = []byte{ 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x6b, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x53, 0x6b, 0x75, 0x22, 0x77, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, - 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x50, 0x72, - 0x69, 0x63, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x6b, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x53, 0x6b, 0x75, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6d, 0x61, - 0x67, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x22, - 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, - 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x22, 0x3c, 0x0a, - 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, - 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x12, - 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x3f, 0x0a, 0x0b, 0x53, - 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x20, 0x0a, 0x0e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x0e, - 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x42, 0x0c, - 0x5a, 0x0a, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x09, 0x52, 0x03, 0x53, 0x6b, 0x75, 0x22, 0xdb, 0x01, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, + 0x65, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x50, + 0x72, 0x69, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x72, 0x67, 0x50, 0x72, 0x69, 0x63, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x4f, 0x72, 0x67, 0x50, 0x72, 0x69, 0x63, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x53, 0x6b, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x53, + 0x6b, 0x75, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x53, 0x74, 0x6f, + 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x61, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x03, 0x54, 0x61, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6c, 0x61, + 0x69, 0x6d, 0x65, 0x72, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, + 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, + 0x49, 0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, + 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x22, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x22, 0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, + 0x65, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x02, 0x49, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/messages.proto b/proto/messages.proto index 76ca6ca..30555e3 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -10,9 +10,13 @@ message AddRequest { message AddItem { int32 Quantity = 2; int64 Price = 3; + int64 OrgPrice = 9; string Sku = 4; string Name = 5; string Image = 6; + int32 Stock = 7; + int32 Tax = 8; + string Disclaimer = 10; } message RemoveItem { @@ -32,5 +36,3 @@ message SetDelivery { message RemoveDelivery { int64 Id = 1; } - - From 1c6c9b1894167b42e3a7b515e3876c51a5681446 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:02:34 +0100 Subject: [PATCH 07/18] more features --- cart-grain.go | 107 ++++++++++---- main.go | 2 +- message-types.go | 1 + proto/messages.pb.go | 322 ++++++++++++++++++++++++++++++++++++++----- proto/messages.proto | 26 ++++ 5 files changed, 390 insertions(+), 68 deletions(-) diff --git a/cart-grain.go b/cart-grain.go index eb6fdcb..7d7f675 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -35,23 +35,27 @@ const ( ) type CartItem struct { - Id int `json:"id"` - ParentId int `json:"parentId,omitempty"` - Sku string `json:"sku"` - Name string `json:"name"` - Price int64 `json:"price"` - OrgPrice int64 `json:"orgPrice"` - Stock StockStatus `json:"stock"` - Quantity int `json:"qty"` - Tax int `json:"tax"` - Disclaimer string `json:"disclaimer,omitempty"` - Image string `json:"image,omitempty"` + Id int `json:"id"` + ParentId int `json:"parentId,omitempty"` + Sku string `json:"sku"` + Name string `json:"name"` + Price int64 `json:"price"` + OrgPrice int64 `json:"orgPrice"` + Stock StockStatus `json:"stock"` + Quantity int `json:"qty"` + Tax int `json:"tax"` + Disclaimer string `json:"disclaimer,omitempty"` + ArticleType string `json:"type,omitempty"` + Image string `json:"image,omitempty"` + Outlet string `json:"outlet,omitempty"` } type CartDelivery struct { - Provider string `json:"provider"` - Price int64 `json:"price"` - Items []int `json:"items"` + Id int `json:"id"` + Provider string `json:"provider"` + Price int64 `json:"price"` + Items []int `json:"items"` + PickupPoint *messages.PickupPoint `json:"pickupPoint,omitempty"` } type CartGrain struct { @@ -59,10 +63,10 @@ type CartGrain struct { lastItemId int lastDeliveryId int storageMessages []Message - Id CartId `json:"id"` - Items []*CartItem `json:"items"` - TotalPrice int64 `json:"totalPrice"` - Deliveries []CartDelivery `json:"deliveries,omitempty"` + Id CartId `json:"id"` + Items []*CartItem `json:"items"` + TotalPrice int64 `json:"totalPrice"` + Deliveries []*CartDelivery `json:"deliveries,omitempty"` } type Grain interface { @@ -108,9 +112,9 @@ func getItemData(sku string, qty int) (*messages.AddItem, error) { if err != nil { return nil, err } - orgPrice, _ := getInt(item.Fields[6]) + orgPrice, _ := getInt(item.Fields[5]) - price, priceErr := getInt(item.Fields[5]) + price, priceErr := getInt(item.Fields[4]) if priceErr != nil { return nil, fmt.Errorf("invalid price") @@ -122,17 +126,25 @@ func getItemData(sku string, qty int) (*messages.AddItem, error) { } else if item.StockLevel == "5+" { stock = LowStock } + articleType, _ := item.Fields[1].(string) + outletGrade, ok := item.Fields[20].(string) + var outlet *string + if ok { + outlet = &outletGrade + } return &messages.AddItem{ - Quantity: int32(qty), - Price: int64(price), - OrgPrice: int64(orgPrice), - Sku: sku, - Name: item.Title, - Image: item.Img, - Stock: int32(stock), - Tax: 2500, - Disclaimer: item.Disclaimer, + Quantity: int32(qty), + Price: int64(price), + OrgPrice: int64(orgPrice), + Sku: sku, + Name: item.Title, + Image: item.Img, + Stock: int32(stock), + Tax: 2500, + ArticleType: articleType, + Disclaimer: item.Disclaimer, + Outlet: outlet, }, nil } @@ -321,13 +333,48 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa } } } - c.Deliveries = append(c.Deliveries, CartDelivery{ + c.Deliveries = append(c.Deliveries, &CartDelivery{ + Id: c.lastDeliveryId, Provider: msg.Provider, Price: 49, Items: items, }) } case RemoveDeliveryType: + msg, ok := message.Content.(*messages.RemoveDelivery) + if !ok { + err = fmt.Errorf("expected RemoveDelivery") + } else { + deliveries := make([]*CartDelivery, 0, len(c.Deliveries)) + for _, delivery := range c.Deliveries { + if delivery.Id == int(msg.Id) { + c.TotalPrice -= delivery.Price + } else { + deliveries = append(deliveries, delivery) + } + } + c.Deliveries = deliveries + } + case SetPickupPointType: + msg, ok := message.Content.(*messages.SetPickupPoint) + if !ok { + err = fmt.Errorf("expected SetPickupPoint") + } else { + for _, delivery := range c.Deliveries { + if delivery.Id == int(msg.DeliveryId) { + delivery.PickupPoint = &messages.PickupPoint{ + Id: msg.Id, + Address: msg.Address, + City: msg.City, + Zip: msg.Zip, + Country: msg.Country, + Name: msg.Name, + } + break + } + } + + } default: err = fmt.Errorf("unknown message type %d", message.Type) } diff --git a/main.go b/main.go index 95bd398..715ab5c 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,7 @@ func spawn(id CartId) (*CartGrain, error) { ret := &CartGrain{ lastItemId: 0, lastDeliveryId: 0, - Deliveries: []CartDelivery{}, + Deliveries: []*CartDelivery{}, Id: id, Items: []*CartItem{}, storageMessages: []Message{}, diff --git a/message-types.go b/message-types.go index 98506fc..ba70e1f 100644 --- a/message-types.go +++ b/message-types.go @@ -8,4 +8,5 @@ const ( RemoveDeliveryType = 5 ChangeQuantityType = 6 SetDeliveryType = 7 + SetPickupPointType = 8 ) diff --git a/proto/messages.pb.go b/proto/messages.pb.go index 9ac3e5d..1ab09dd 100644 --- a/proto/messages.pb.go +++ b/proto/messages.pb.go @@ -78,15 +78,17 @@ type AddItem struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` - Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"Price,omitempty"` - OrgPrice int64 `protobuf:"varint,9,opt,name=OrgPrice,proto3" json:"OrgPrice,omitempty"` - Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"Sku,omitempty"` - Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"Name,omitempty"` - Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"Image,omitempty"` - Stock int32 `protobuf:"varint,7,opt,name=Stock,proto3" json:"Stock,omitempty"` - Tax int32 `protobuf:"varint,8,opt,name=Tax,proto3" json:"Tax,omitempty"` - Disclaimer string `protobuf:"bytes,10,opt,name=Disclaimer,proto3" json:"Disclaimer,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` + Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"Price,omitempty"` + OrgPrice int64 `protobuf:"varint,9,opt,name=OrgPrice,proto3" json:"OrgPrice,omitempty"` + Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"Sku,omitempty"` + Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"Name,omitempty"` + Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"Image,omitempty"` + Stock int32 `protobuf:"varint,7,opt,name=Stock,proto3" json:"Stock,omitempty"` + Tax int32 `protobuf:"varint,8,opt,name=Tax,proto3" json:"Tax,omitempty"` + Disclaimer string `protobuf:"bytes,10,opt,name=Disclaimer,proto3" json:"Disclaimer,omitempty"` + ArticleType string `protobuf:"bytes,11,opt,name=ArticleType,proto3" json:"ArticleType,omitempty"` + Outlet *string `protobuf:"bytes,12,opt,name=Outlet,proto3,oneof" json:"Outlet,omitempty"` } func (x *AddItem) Reset() { @@ -182,6 +184,20 @@ func (x *AddItem) GetDisclaimer() string { return "" } +func (x *AddItem) GetArticleType() string { + if x != nil { + return x.ArticleType + } + return "" +} + +func (x *AddItem) GetOutlet() string { + if x != nil && x.Outlet != nil { + return *x.Outlet + } + return "" +} + type RemoveItem struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -285,8 +301,9 @@ type SetDelivery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"Provider,omitempty"` - Items []int64 `protobuf:"varint,2,rep,packed,name=Items,proto3" json:"Items,omitempty"` + Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"Provider,omitempty"` + Items []int64 `protobuf:"varint,2,rep,packed,name=Items,proto3" json:"Items,omitempty"` + PickupPoint *PickupPoint `protobuf:"bytes,3,opt,name=PickupPoint,proto3,oneof" json:"PickupPoint,omitempty"` } func (x *SetDelivery) Reset() { @@ -333,6 +350,191 @@ func (x *SetDelivery) GetItems() []int64 { return nil } +func (x *SetDelivery) GetPickupPoint() *PickupPoint { + if x != nil { + return x.PickupPoint + } + return nil +} + +type SetPickupPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeliveryId int64 `protobuf:"varint,1,opt,name=DeliveryId,proto3" json:"DeliveryId,omitempty"` + Id string `protobuf:"bytes,2,opt,name=Id,proto3" json:"Id,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=Name,proto3,oneof" json:"Name,omitempty"` + Address *string `protobuf:"bytes,4,opt,name=Address,proto3,oneof" json:"Address,omitempty"` + City *string `protobuf:"bytes,5,opt,name=City,proto3,oneof" json:"City,omitempty"` + Zip *string `protobuf:"bytes,6,opt,name=Zip,proto3,oneof" json:"Zip,omitempty"` + Country *string `protobuf:"bytes,7,opt,name=Country,proto3,oneof" json:"Country,omitempty"` +} + +func (x *SetPickupPoint) Reset() { + *x = SetPickupPoint{} + mi := &file_messages_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *SetPickupPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SetPickupPoint) ProtoMessage() {} + +func (x *SetPickupPoint) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SetPickupPoint.ProtoReflect.Descriptor instead. +func (*SetPickupPoint) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{5} +} + +func (x *SetPickupPoint) GetDeliveryId() int64 { + if x != nil { + return x.DeliveryId + } + return 0 +} + +func (x *SetPickupPoint) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *SetPickupPoint) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *SetPickupPoint) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address + } + return "" +} + +func (x *SetPickupPoint) GetCity() string { + if x != nil && x.City != nil { + return *x.City + } + return "" +} + +func (x *SetPickupPoint) GetZip() string { + if x != nil && x.Zip != nil { + return *x.Zip + } + return "" +} + +func (x *SetPickupPoint) GetCountry() string { + if x != nil && x.Country != nil { + return *x.Country + } + return "" +} + +type PickupPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=Name,proto3,oneof" json:"Name,omitempty"` + Address *string `protobuf:"bytes,3,opt,name=Address,proto3,oneof" json:"Address,omitempty"` + City *string `protobuf:"bytes,4,opt,name=City,proto3,oneof" json:"City,omitempty"` + Zip *string `protobuf:"bytes,5,opt,name=Zip,proto3,oneof" json:"Zip,omitempty"` + Country *string `protobuf:"bytes,6,opt,name=Country,proto3,oneof" json:"Country,omitempty"` +} + +func (x *PickupPoint) Reset() { + *x = PickupPoint{} + mi := &file_messages_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *PickupPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PickupPoint) ProtoMessage() {} + +func (x *PickupPoint) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PickupPoint.ProtoReflect.Descriptor instead. +func (*PickupPoint) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{6} +} + +func (x *PickupPoint) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *PickupPoint) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *PickupPoint) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address + } + return "" +} + +func (x *PickupPoint) GetCity() string { + if x != nil && x.City != nil { + return *x.City + } + return "" +} + +func (x *PickupPoint) GetZip() string { + if x != nil && x.Zip != nil { + return *x.Zip + } + return "" +} + +func (x *PickupPoint) GetCountry() string { + if x != nil && x.Country != nil { + return *x.Country + } + return "" +} + type RemoveDelivery struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -343,7 +545,7 @@ type RemoveDelivery struct { func (x *RemoveDelivery) Reset() { *x = RemoveDelivery{} - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -355,7 +557,7 @@ func (x *RemoveDelivery) String() string { func (*RemoveDelivery) ProtoMessage() {} func (x *RemoveDelivery) ProtoReflect() protoreflect.Message { - mi := &file_messages_proto_msgTypes[5] + mi := &file_messages_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -368,7 +570,7 @@ func (x *RemoveDelivery) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveDelivery.ProtoReflect.Descriptor instead. func (*RemoveDelivery) Descriptor() ([]byte, []int) { - return file_messages_proto_rawDescGZIP(), []int{5} + return file_messages_proto_rawDescGZIP(), []int{7} } func (x *RemoveDelivery) GetId() int64 { @@ -386,7 +588,7 @@ var file_messages_proto_rawDesc = []byte{ 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x53, 0x6b, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x53, 0x6b, 0x75, 0x22, 0xdb, 0x01, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, + 0x09, 0x52, 0x03, 0x53, 0x6b, 0x75, 0x22, 0xa5, 0x02, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x72, 0x69, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x50, @@ -400,20 +602,59 @@ var file_messages_proto_rawDesc = []byte{ 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x61, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x54, 0x61, 0x78, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6c, 0x61, - 0x69, 0x6d, 0x65, 0x72, 0x22, 0x1c, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, - 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, - 0x49, 0x64, 0x22, 0x3c, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, - 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, - 0x22, 0x3f, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, - 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x49, - 0x74, 0x65, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d, - 0x73, 0x22, 0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, - 0x65, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x02, 0x49, 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x69, 0x6d, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x41, 0x72, 0x74, 0x69, 0x63, + 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x06, 0x4f, 0x75, 0x74, 0x6c, 0x65, 0x74, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x4f, 0x75, 0x74, 0x6c, 0x65, 0x74, + 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x4f, 0x75, 0x74, 0x6c, 0x65, 0x74, 0x22, 0x1c, + 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x0e, 0x0a, 0x02, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x22, 0x3c, 0x0a, 0x0e, + 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, + 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, + 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x53, + 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x3c, 0x0a, 0x0b, + 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x69, 0x63, + 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x50, 0x69, 0x63, 0x6b, + 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x50, + 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xf9, 0x01, 0x0a, 0x0e, 0x53, + 0x65, 0x74, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x17, 0x0a, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, + 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, + 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x5a, + 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, + 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, + 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x43, 0x69, + 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x5a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xd6, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x63, 0x6b, 0x75, + 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, + 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, + 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, + 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x5a, 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, + 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x04, 0x52, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, + 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, + 0x5a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, + 0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, + 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, + 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -428,21 +669,24 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_messages_proto_goTypes = []any{ (*AddRequest)(nil), // 0: messages.AddRequest (*AddItem)(nil), // 1: messages.AddItem (*RemoveItem)(nil), // 2: messages.RemoveItem (*ChangeQuantity)(nil), // 3: messages.ChangeQuantity (*SetDelivery)(nil), // 4: messages.SetDelivery - (*RemoveDelivery)(nil), // 5: messages.RemoveDelivery + (*SetPickupPoint)(nil), // 5: messages.SetPickupPoint + (*PickupPoint)(nil), // 6: messages.PickupPoint + (*RemoveDelivery)(nil), // 7: messages.RemoveDelivery } var file_messages_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 6, // 0: messages.SetDelivery.PickupPoint:type_name -> messages.PickupPoint + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name } func init() { file_messages_proto_init() } @@ -450,13 +694,17 @@ func file_messages_proto_init() { if File_messages_proto != nil { return } + file_messages_proto_msgTypes[1].OneofWrappers = []any{} + file_messages_proto_msgTypes[4].OneofWrappers = []any{} + file_messages_proto_msgTypes[5].OneofWrappers = []any{} + file_messages_proto_msgTypes[6].OneofWrappers = []any{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_messages_proto_rawDesc, NumEnums: 0, - NumMessages: 6, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/messages.proto b/proto/messages.proto index 30555e3..1481331 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -17,6 +17,8 @@ message AddItem { int32 Stock = 7; int32 Tax = 8; string Disclaimer = 10; + string ArticleType = 11; + optional string Outlet = 12; } message RemoveItem { @@ -31,6 +33,30 @@ message ChangeQuantity { message SetDelivery { string Provider = 1; repeated int64 Items = 2; + optional PickupPoint PickupPoint = 3; + string Country = 4; + string Zip = 5; + optional string Address = 6; + optional string City = 7; +} + +message SetPickupPoint { + int64 DeliveryId = 1; + string Id = 2; + optional string Name = 3; + optional string Address = 4; + optional string City = 5; + optional string Zip = 6; + optional string Country = 7; +} + +message PickupPoint { + string Id = 1; + optional string Name = 2; + optional string Address = 3; + optional string City = 4; + optional string Zip = 5; + optional string Country = 6; } message RemoveDelivery { From 9a80d74325a5c6a82a21e36c398f632a27f8ddfc Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:13:40 +0100 Subject: [PATCH 08/18] more stuff --- cart-grain.go | 8 ++++++ pool-server.go | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/cart-grain.go b/cart-grain.go index 7d7f675..75a4a52 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -67,6 +67,7 @@ type CartGrain struct { Items []*CartItem `json:"items"` TotalPrice int64 `json:"totalPrice"` Deliveries []*CartDelivery `json:"deliveries,omitempty"` + Processing bool `json:"processing"` } type Grain interface { @@ -339,6 +340,13 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa Price: 49, Items: items, }) + c.Processing = true + go func() { + time.Sleep(5 * time.Second) + c.mu.Lock() + c.Processing = false + c.mu.Unlock() + }() } case RemoveDeliveryType: msg, ok := message.Content.(*messages.RemoveDelivery) diff --git a/pool-server.go b/pool-server.go index e7f5db9..948ac75 100644 --- a/pool-server.go +++ b/pool-server.go @@ -115,11 +115,78 @@ func (s *PoolServer) HandleSetDelivery(w http.ResponseWriter, r *http.Request) e return s.WriteResult(w, data) } +func (s *PoolServer) HandleSetPickupPoint(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + deliveryIdString := r.PathValue("deliveryId") + deliveryId, err := strconv.Atoi(deliveryIdString) + if err != nil { + return err + } + pickupPoint := messages.PickupPoint{} + err = json.NewDecoder(r.Body).Decode(&pickupPoint) + if err != nil { + return err + } + reply, err := s.pool.Process(ToCartId(id), Message{ + Type: SetPickupPointType, + Content: &messages.SetPickupPoint{ + DeliveryId: int64(deliveryId), + Id: pickupPoint.Id, + Name: pickupPoint.Name, + Address: pickupPoint.Address, + City: pickupPoint.City, + Zip: pickupPoint.Zip, + Country: pickupPoint.Country, + }, + }) + if err != nil { + return err + } + return s.WriteResult(w, reply) +} + +func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + deliveryIdString := r.PathValue("deliveryId") + deliveryId, err := strconv.Atoi(deliveryIdString) + if err != nil { + return err + } + reply, err := s.pool.Process(ToCartId(id), Message{ + Type: RemoveDeliveryType, + Content: &messages.RemoveDelivery{Id: int64(deliveryId)}, + }) + if err != nil { + return err + } + return s.WriteResult(w, reply) +} + +func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + itemIdString := r.PathValue("itemId") + itemId, err := strconv.Atoi(itemIdString) + if err != nil { + return err + } + reply, err := s.pool.Process(ToCartId(id), Message{ + Type: ChangeQuantityType, + Content: &messages.ChangeQuantity{Id: int64(itemId)}, + }) + if err != nil { + return err + } + return s.WriteResult(w, reply) +} + func (s *PoolServer) Serve() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /{id}", ErrorHandler(s.HandleGet)) mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(s.HandleAddSku)) mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(s.HandleDeleteItem)) + mux.HandleFunc("PUT /{id}/{itemId}", ErrorHandler(s.HandleQuantityChange)) mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) + mux.HandleFunc("DELETE /{id}/delivery/{deliveryId}", ErrorHandler(s.HandleRemoveDelivery)) + mux.HandleFunc("PUT /{id}/delivery/{deliveryId}/pickupPoint", ErrorHandler(s.HandleSetPickupPoint)) return mux } From 352c570f0b38373e49df207b6674ebfa4baf2c87 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:19:02 +0100 Subject: [PATCH 09/18] manually fix json casing --- pool-server.go | 19 +++++++++++++ proto/messages.pb.go | 66 ++++++++++++++++++++++---------------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/pool-server.go b/pool-server.go index 948ac75..3928c68 100644 --- a/pool-server.go +++ b/pool-server.go @@ -179,10 +179,29 @@ func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request return s.WriteResult(w, reply) } +func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + + pickupPoint := messages.AddRequest{} + err := json.NewDecoder(r.Body).Decode(&pickupPoint) + if err != nil { + return err + } + reply, err := s.pool.Process(ToCartId(id), Message{ + Type: AddRequestType, + Content: &pickupPoint, + }) + if err != nil { + return err + } + return s.WriteResult(w, reply) +} + func (s *PoolServer) Serve() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /{id}", ErrorHandler(s.HandleGet)) mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(s.HandleAddSku)) + mux.HandleFunc("POST /{id}", ErrorHandler(s.HandleAddRequest)) mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(s.HandleDeleteItem)) mux.HandleFunc("PUT /{id}/{itemId}", ErrorHandler(s.HandleQuantityChange)) mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) diff --git a/proto/messages.pb.go b/proto/messages.pb.go index 1ab09dd..6995f0b 100644 --- a/proto/messages.pb.go +++ b/proto/messages.pb.go @@ -25,8 +25,8 @@ type AddRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Quantity int32 `protobuf:"varint,1,opt,name=Quantity,proto3" json:"Quantity,omitempty"` - Sku string `protobuf:"bytes,2,opt,name=Sku,proto3" json:"Sku,omitempty"` + Quantity int32 `protobuf:"varint,1,opt,name=Quantity,proto3" json:"quantity,omitempty"` + Sku string `protobuf:"bytes,2,opt,name=Sku,proto3" json:"sku,omitempty"` } func (x *AddRequest) Reset() { @@ -78,17 +78,17 @@ type AddItem struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` - Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"Price,omitempty"` - OrgPrice int64 `protobuf:"varint,9,opt,name=OrgPrice,proto3" json:"OrgPrice,omitempty"` - Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"Sku,omitempty"` - Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"Name,omitempty"` - Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"Image,omitempty"` - Stock int32 `protobuf:"varint,7,opt,name=Stock,proto3" json:"Stock,omitempty"` - Tax int32 `protobuf:"varint,8,opt,name=Tax,proto3" json:"Tax,omitempty"` - Disclaimer string `protobuf:"bytes,10,opt,name=Disclaimer,proto3" json:"Disclaimer,omitempty"` - ArticleType string `protobuf:"bytes,11,opt,name=ArticleType,proto3" json:"ArticleType,omitempty"` - Outlet *string `protobuf:"bytes,12,opt,name=Outlet,proto3,oneof" json:"Outlet,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"quantity,omitempty"` + Price int64 `protobuf:"varint,3,opt,name=Price,proto3" json:"price,omitempty"` + OrgPrice int64 `protobuf:"varint,9,opt,name=OrgPrice,proto3" json:"orgPrice,omitempty"` + Sku string `protobuf:"bytes,4,opt,name=Sku,proto3" json:"sku,omitempty"` + Name string `protobuf:"bytes,5,opt,name=Name,proto3" json:"name,omitempty"` + Image string `protobuf:"bytes,6,opt,name=Image,proto3" json:"image,omitempty"` + Stock int32 `protobuf:"varint,7,opt,name=Stock,proto3" json:"stock,omitempty"` + Tax int32 `protobuf:"varint,8,opt,name=Tax,proto3" json:"tax,omitempty"` + Disclaimer string `protobuf:"bytes,10,opt,name=Disclaimer,proto3" json:"disclaimer,omitempty"` + ArticleType string `protobuf:"bytes,11,opt,name=ArticleType,proto3" json:"articleType,omitempty"` + Outlet *string `protobuf:"bytes,12,opt,name=Outlet,proto3,oneof" json:"outlet,omitempty"` } func (x *AddItem) Reset() { @@ -203,7 +203,7 @@ type RemoveItem struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` + Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"id,omitempty"` } func (x *RemoveItem) Reset() { @@ -248,8 +248,8 @@ type ChangeQuantity struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` - Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"Quantity,omitempty"` + Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"id,omitempty"` + Quantity int32 `protobuf:"varint,2,opt,name=Quantity,proto3" json:"quantity,omitempty"` } func (x *ChangeQuantity) Reset() { @@ -301,9 +301,9 @@ type SetDelivery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"Provider,omitempty"` - Items []int64 `protobuf:"varint,2,rep,packed,name=Items,proto3" json:"Items,omitempty"` - PickupPoint *PickupPoint `protobuf:"bytes,3,opt,name=PickupPoint,proto3,oneof" json:"PickupPoint,omitempty"` + Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"provider,omitempty"` + Items []int64 `protobuf:"varint,2,rep,packed,name=Items,proto3" json:"items,omitempty"` + PickupPoint *PickupPoint `protobuf:"bytes,3,opt,name=PickupPoint,proto3,oneof" json:"pickupPoint,omitempty"` } func (x *SetDelivery) Reset() { @@ -362,13 +362,13 @@ type SetPickupPoint struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - DeliveryId int64 `protobuf:"varint,1,opt,name=DeliveryId,proto3" json:"DeliveryId,omitempty"` - Id string `protobuf:"bytes,2,opt,name=Id,proto3" json:"Id,omitempty"` - Name *string `protobuf:"bytes,3,opt,name=Name,proto3,oneof" json:"Name,omitempty"` - Address *string `protobuf:"bytes,4,opt,name=Address,proto3,oneof" json:"Address,omitempty"` - City *string `protobuf:"bytes,5,opt,name=City,proto3,oneof" json:"City,omitempty"` - Zip *string `protobuf:"bytes,6,opt,name=Zip,proto3,oneof" json:"Zip,omitempty"` - Country *string `protobuf:"bytes,7,opt,name=Country,proto3,oneof" json:"Country,omitempty"` + DeliveryId int64 `protobuf:"varint,1,opt,name=DeliveryId,proto3" json:"deliveryId,omitempty"` + Id string `protobuf:"bytes,2,opt,name=Id,proto3" json:"id,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=Name,proto3,oneof" json:"name,omitempty"` + Address *string `protobuf:"bytes,4,opt,name=Address,proto3,oneof" json:"address,omitempty"` + City *string `protobuf:"bytes,5,opt,name=City,proto3,oneof" json:"city,omitempty"` + Zip *string `protobuf:"bytes,6,opt,name=Zip,proto3,oneof" json:"zip,omitempty"` + Country *string `protobuf:"bytes,7,opt,name=Country,proto3,oneof" json:"country,omitempty"` } func (x *SetPickupPoint) Reset() { @@ -455,12 +455,12 @@ type PickupPoint struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"Id,omitempty"` - Name *string `protobuf:"bytes,2,opt,name=Name,proto3,oneof" json:"Name,omitempty"` - Address *string `protobuf:"bytes,3,opt,name=Address,proto3,oneof" json:"Address,omitempty"` - City *string `protobuf:"bytes,4,opt,name=City,proto3,oneof" json:"City,omitempty"` - Zip *string `protobuf:"bytes,5,opt,name=Zip,proto3,oneof" json:"Zip,omitempty"` - Country *string `protobuf:"bytes,6,opt,name=Country,proto3,oneof" json:"Country,omitempty"` + Id string `protobuf:"bytes,1,opt,name=Id,proto3" json:"id,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=Name,proto3,oneof" json:"name,omitempty"` + Address *string `protobuf:"bytes,3,opt,name=Address,proto3,oneof" json:"address,omitempty"` + City *string `protobuf:"bytes,4,opt,name=City,proto3,oneof" json:"city,omitempty"` + Zip *string `protobuf:"bytes,5,opt,name=Zip,proto3,oneof" json:"zip,omitempty"` + Country *string `protobuf:"bytes,6,opt,name=Country,proto3,oneof" json:"country,omitempty"` } func (x *PickupPoint) Reset() { @@ -540,7 +540,7 @@ type RemoveDelivery struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"Id,omitempty"` + Id int64 `protobuf:"varint,1,opt,name=Id,proto3" json:"id,omitempty"` } func (x *RemoveDelivery) Reset() { From 411266645772f0006eb8bd83269c592bf2f3f199 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:35:04 +0100 Subject: [PATCH 10/18] update qty --- api-tests/cart.http | 38 ++++++++++++++++++++++++++++++++++++++ pool-server.go | 15 ++++++++------- synced-pool_test.go | 2 +- 3 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 api-tests/cart.http diff --git a/api-tests/cart.http b/api-tests/cart.http new file mode 100644 index 0000000..0ce09c9 --- /dev/null +++ b/api-tests/cart.http @@ -0,0 +1,38 @@ + +### Add item to cart +POST https://cart.tornberg.me/api/12345 +Content-Type: application/json + +{ + "sku": "763281", + "quantity": 1 +} + +### Update quanity of item in cart +PUT https://cart.tornberg.me/api/12345/1 +Content-Type: application/json + +{ + "quantity": 1 +} + +### Add item to cart +POST http://localhost:8080/cart/12345/item +Content-Type: application/json + +{ + "itemId": "67890", + "quantity": 2 +} + +### Remove item from cart +DELETE http://localhost:8080/cart/12345/item/67890 + +### Checkout cart +POST http://localhost:8080/cart/12345/checkout +Content-Type: application/json + +{ + "paymentMethod": "credit_card", + "shippingAddress": "123 Main St, Anytown, USA" +} \ No newline at end of file diff --git a/pool-server.go b/pool-server.go index 3928c68..1cf4345 100644 --- a/pool-server.go +++ b/pool-server.go @@ -164,14 +164,15 @@ func (s *PoolServer) HandleRemoveDelivery(w http.ResponseWriter, r *http.Request func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") - itemIdString := r.PathValue("itemId") - itemId, err := strconv.Atoi(itemIdString) + + changeQuantity := messages.ChangeQuantity{} + err := json.NewDecoder(r.Body).Decode(&changeQuantity) if err != nil { return err } reply, err := s.pool.Process(ToCartId(id), Message{ Type: ChangeQuantityType, - Content: &messages.ChangeQuantity{Id: int64(itemId)}, + Content: changeQuantity, }) if err != nil { return err @@ -182,14 +183,14 @@ func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request) error { id := r.PathValue("id") - pickupPoint := messages.AddRequest{} - err := json.NewDecoder(r.Body).Decode(&pickupPoint) + addRequest := messages.AddRequest{} + err := json.NewDecoder(r.Body).Decode(&addRequest) if err != nil { return err } reply, err := s.pool.Process(ToCartId(id), Message{ Type: AddRequestType, - Content: &pickupPoint, + Content: &addRequest, }) if err != nil { return err @@ -203,7 +204,7 @@ func (s *PoolServer) Serve() *http.ServeMux { mux.HandleFunc("GET /{id}/add/{sku}", ErrorHandler(s.HandleAddSku)) mux.HandleFunc("POST /{id}", ErrorHandler(s.HandleAddRequest)) mux.HandleFunc("DELETE /{id}/{itemId}", ErrorHandler(s.HandleDeleteItem)) - mux.HandleFunc("PUT /{id}/{itemId}", ErrorHandler(s.HandleQuantityChange)) + mux.HandleFunc("PUT /{id}", ErrorHandler(s.HandleQuantityChange)) mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) mux.HandleFunc("DELETE /{id}/delivery/{deliveryId}", ErrorHandler(s.HandleRemoveDelivery)) mux.HandleFunc("PUT /{id}/delivery/{deliveryId}/pickupPoint", ErrorHandler(s.HandleSetPickupPoint)) diff --git a/synced-pool_test.go b/synced-pool_test.go index 46ca9f7..8845055 100644 --- a/synced-pool_test.go +++ b/synced-pool_test.go @@ -16,7 +16,7 @@ func TestConnection(t *testing.T) { Id: id, storageMessages: []Message{}, Items: []*CartItem{}, - Deliveries: make([]CartDelivery, 0), + Deliveries: make([]*CartDelivery, 0), TotalPrice: 0, }, nil }) From b987f79173d7c5a8abcf602429067ecb3b3296e6 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:38:21 +0100 Subject: [PATCH 11/18] update to pointer --- api-tests/cart.http | 32 +++++++++++++++----------------- pool-server.go | 2 +- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/api-tests/cart.http b/api-tests/cart.http index 0ce09c9..d8c956d 100644 --- a/api-tests/cart.http +++ b/api-tests/cart.http @@ -9,30 +9,28 @@ Content-Type: application/json } ### Update quanity of item in cart -PUT https://cart.tornberg.me/api/12345/1 +PUT https://cart.tornberg.me/api/12345 Content-Type: application/json { + "id": 1, "quantity": 1 } -### Add item to cart -POST http://localhost:8080/cart/12345/item +### Delete item from cart +DELETE https://cart.tornberg.me/api/12345/1 + + +### Set delivery + +POST https://cart.tornberg.me/api/12345/delivery Content-Type: application/json { - "itemId": "67890", - "quantity": 2 -} - -### Remove item from cart -DELETE http://localhost:8080/cart/12345/item/67890 - -### Checkout cart -POST http://localhost:8080/cart/12345/checkout -Content-Type: application/json - -{ - "paymentMethod": "credit_card", - "shippingAddress": "123 Main St, Anytown, USA" + "provider": "postnord", + "items": [ + { + "id": 1, + } + ] } \ No newline at end of file diff --git a/pool-server.go b/pool-server.go index 1cf4345..f8698da 100644 --- a/pool-server.go +++ b/pool-server.go @@ -172,7 +172,7 @@ func (s *PoolServer) HandleQuantityChange(w http.ResponseWriter, r *http.Request } reply, err := s.pool.Process(ToCartId(id), Message{ Type: ChangeQuantityType, - Content: changeQuantity, + Content: &changeQuantity, }) if err != nil { return err From 2852ab5bb4b72858f4f72c0e7c2fe7772a7b089e Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:49:59 +0100 Subject: [PATCH 12/18] update http requests --- api-tests/cart.http | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/api-tests/cart.http b/api-tests/cart.http index d8c956d..5568ff1 100644 --- a/api-tests/cart.http +++ b/api-tests/cart.http @@ -28,9 +28,15 @@ Content-Type: application/json { "provider": "postnord", - "items": [ - { - "id": 1, - } - ] -} \ No newline at end of file + "items": [] +} + + +### Get cart +GET https://cart.tornberg.me/api/12345 + + +### Remove delivery method +DELETE https://cart.tornberg.me/api/12345/delivery/2 + + From c8cd8bc7454e28bc8215539f6376691d9391ad44 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 20:52:28 +0100 Subject: [PATCH 13/18] fix outlet and articletype --- cart-grain.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/cart-grain.go b/cart-grain.go index 75a4a52..c00fc2e 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -47,7 +47,7 @@ type CartItem struct { Disclaimer string `json:"disclaimer,omitempty"` ArticleType string `json:"type,omitempty"` Image string `json:"image,omitempty"` - Outlet string `json:"outlet,omitempty"` + Outlet *string `json:"outlet,omitempty"` } type CartDelivery struct { @@ -263,16 +263,18 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa tax = int(msg.Tax) } c.Items = append(c.Items, &CartItem{ - Id: c.lastItemId, - Quantity: int(msg.Quantity), - Sku: msg.Sku, - Name: msg.Name, - Price: msg.Price, - Image: msg.Image, - Stock: StockStatus(msg.Stock), - Disclaimer: msg.Disclaimer, - OrgPrice: msg.OrgPrice, - Tax: tax, + Id: c.lastItemId, + Quantity: int(msg.Quantity), + Sku: msg.Sku, + Name: msg.Name, + Price: msg.Price, + Image: msg.Image, + Stock: StockStatus(msg.Stock), + Disclaimer: msg.Disclaimer, + OrgPrice: msg.OrgPrice, + ArticleType: msg.ArticleType, + Outlet: msg.Outlet, + Tax: tax, }) c.TotalPrice += msg.Price * int64(msg.Quantity) c.mu.Unlock() From 0870a37d9051edc5cd632722b2323dd74db35620 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 21:02:36 +0100 Subject: [PATCH 14/18] update --- cart-grain.go | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/cart-grain.go b/cart-grain.go index c00fc2e..06de6a6 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -336,19 +336,20 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa } } } - c.Deliveries = append(c.Deliveries, &CartDelivery{ - Id: c.lastDeliveryId, - Provider: msg.Provider, - Price: 49, - Items: items, - }) - c.Processing = true - go func() { - time.Sleep(5 * time.Second) - c.mu.Lock() - c.Processing = false - c.mu.Unlock() - }() + if len(items) > 0 { + + c.Deliveries = append(c.Deliveries, &CartDelivery{ + Id: c.lastDeliveryId, + Provider: msg.Provider, + Price: 49, + Items: items, + }) + c.Processing = true + go func() { + time.Sleep(5 * time.Second) + c.Processing = false + }() + } } case RemoveDeliveryType: msg, ok := message.Content.(*messages.RemoveDelivery) From 69d92716c3cc6fae47ed47b17837bdd409cde869 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 22:53:32 +0100 Subject: [PATCH 15/18] checkout --- api-tests/cart.http | 2 +- cart-grain.go | 53 +++++++++++- cart-grain_test.go | 7 ++ go.mod | 1 + go.sum | 2 + message-types.go | 13 +-- packet.go | 1 + pool-server.go | 48 +++++++++++ proto/messages.pb.go | 196 ++++++++++++++++++++++++++++++++++--------- proto/messages.proto | 7 ++ 10 files changed, 283 insertions(+), 47 deletions(-) diff --git a/api-tests/cart.http b/api-tests/cart.http index 5568ff1..ed78675 100644 --- a/api-tests/cart.http +++ b/api-tests/cart.http @@ -23,7 +23,7 @@ DELETE https://cart.tornberg.me/api/12345/1 ### Set delivery -POST https://cart.tornberg.me/api/12345/delivery +POST https://cart.tornberg.me/api/1002/delivery Content-Type: application/json { diff --git a/cart-grain.go b/cart-grain.go index 06de6a6..27b2390 100644 --- a/cart-grain.go +++ b/cart-grain.go @@ -8,6 +8,7 @@ import ( "time" messages "git.tornberg.me/go-cart-actor/proto" + klarna "github.com/Flaconi/go-klarna" ) type CartId [16]byte @@ -221,6 +222,11 @@ func (c *CartGrain) FindItemWithSku(sku string) (*CartItem, bool) { return nil, false } +func GetTaxAmount(total int, tax int) int { + taxD := 10000 / float64(tax) + return int(float64(total) / float64((1 + taxD))) +} + func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPayload, error) { if message.TimeStamp == nil { now := time.Now().Unix() @@ -384,7 +390,52 @@ func (c *CartGrain) HandleMessage(message *Message, isReplay bool) (*FrameWithPa break } } - + } + case CreateCheckoutOrderType: + msg, ok := message.Content.(*messages.CreateCheckoutOrder) + if !ok { + err = fmt.Errorf("expected CreateCheckoutOrder") + } else { + orderLines := make([]*klarna.Line, 0, len(c.Items)) + totalTax := 0 + for _, item := range c.Items { + total := int(item.Price) * item.Quantity + taxAmount := GetTaxAmount(total, item.Tax) + totalTax += taxAmount + orderLines = append(orderLines, &klarna.Line{ + Type: "physical", + Reference: item.Sku, + Name: item.Name, + Quantity: item.Quantity, + UnitPrice: int(item.Price), + TaxRate: int(item.Tax), + QuantityUnit: "st", + TotalAmount: total, + TotalTaxAmount: taxAmount, + ImageURL: item.Image, + }) + } + order := klarna.CheckoutOrder{ + PurchaseCountry: "SE", + PurchaseCurrency: "SEK", + Locale: "sv-se", + OrderAmount: int(c.TotalPrice), + OrderTaxAmount: totalTax, + OrderLines: orderLines, + MerchantReference1: c.Id.String(), + MerchantURLS: &klarna.CheckoutMerchantURLS{ + Terms: msg.Terms, + Checkout: msg.Checkout, + Confirmation: msg.Confirmation, + Push: msg.Push, + }, + } + orderPayload, err := json.Marshal(order) + if err != nil { + return nil, err + } + result := MakeFrameWithPayload(RemoteCreateOrderReply, 200, orderPayload) + return &result, nil } default: err = fmt.Errorf("unknown message type %d", message.Type) diff --git a/cart-grain_test.go b/cart-grain_test.go index ddafc40..94d2e9d 100644 --- a/cart-grain_test.go +++ b/cart-grain_test.go @@ -16,6 +16,13 @@ func GetMessage(t uint16, data interface{}) *Message { } } +func TestTaxAmount(t *testing.T) { + taxAmount := GetTaxAmount(12500, 2500) + if taxAmount != 2500 { + t.Errorf("Expected 2500, got %d\n", taxAmount) + } +} + func TestAddToCartShortCut(t *testing.T) { grain, err := spawn(ToCartId("kalle")) if err != nil { diff --git a/go.mod b/go.mod index d3ffa02..ddeea29 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( ) require ( + github.com/Flaconi/go-klarna v0.0.0-20230216165926-e2f708c721d9 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/go.sum b/go.sum index 6b193fd..bbada89 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/Flaconi/go-klarna v0.0.0-20230216165926-e2f708c721d9 h1:U5gu3M9/khqtvgg6iRKo0+nxGEfPHWFHRlKrbZvFxIY= +github.com/Flaconi/go-klarna v0.0.0-20230216165926-e2f708c721d9/go.mod h1:+LVFV9FXH5cwN1VcU30WcNYRs5FhkEtL7/IqqTD42cU= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= diff --git a/message-types.go b/message-types.go index ba70e1f..84a9406 100644 --- a/message-types.go +++ b/message-types.go @@ -3,10 +3,11 @@ package main const ( AddRequestType = 1 AddItemType = 2 - //AddDeliveryType = 3 - RemoveItemType = 4 - RemoveDeliveryType = 5 - ChangeQuantityType = 6 - SetDeliveryType = 7 - SetPickupPointType = 8 + + RemoveItemType = 4 + RemoveDeliveryType = 5 + ChangeQuantityType = 6 + SetDeliveryType = 7 + SetPickupPointType = 8 + CreateCheckoutOrderType = 9 ) diff --git a/packet.go b/packet.go index 4146059..58c223c 100644 --- a/packet.go +++ b/packet.go @@ -6,6 +6,7 @@ const ( ResponseBody = FrameType(0x03) RemoteGetStateReply = FrameType(0x04) RemoteHandleMutationReply = FrameType(0x05) + RemoteCreateOrderReply = FrameType(0x06) ) // type CartPacket struct { diff --git a/pool-server.go b/pool-server.go index f8698da..cfc69f9 100644 --- a/pool-server.go +++ b/pool-server.go @@ -1,9 +1,11 @@ package main import ( + "bytes" "encoding/json" "log" "net/http" + "os" "strconv" messages "git.tornberg.me/go-cart-actor/proto" @@ -198,6 +200,50 @@ func (s *PoolServer) HandleAddRequest(w http.ResponseWriter, r *http.Request) er return s.WriteResult(w, reply) } +var ( + APIUsername = os.Getenv("KLARNA_API_USERNAME") + APIPassword = os.Getenv("KLARNA_API_PASSWORD") +) + +func (s *PoolServer) HandleCheckout(w http.ResponseWriter, r *http.Request) error { + id := r.PathValue("id") + + reply, err := s.pool.Process(ToCartId(id), Message{ + Type: CreateCheckoutOrderType, + Content: &messages.CreateCheckoutOrder{ + Terms: "https://tornberg.me/terms", + Checkout: "https://tornberg.me/checkout", + Confirmation: "https://tornberg.me/confirmation", + Push: "https://cart.tornberg.me/push", + }, + }) + if err != nil { + return err + } + if reply.StatusCode != 200 { + return s.WriteResult(w, reply) + } + + req, err := http.NewRequest("POST", "https://api.playground.klarna.com/checkout/v3/orders", bytes.NewReader(reply.Payload)) + if err != nil { + return err + } + + req.Header.Add("Content-Type", "application/json") + req.SetBasicAuth(APIUsername, APIPassword) + + res, err := http.DefaultClient.Do(req) + if nil != err { + return err + } + + buf := new(bytes.Buffer) + buf.ReadFrom(res.Body) + + w.Write(buf.Bytes()) + return nil +} + func (s *PoolServer) Serve() *http.ServeMux { mux := http.NewServeMux() mux.HandleFunc("GET /{id}", ErrorHandler(s.HandleGet)) @@ -208,5 +254,7 @@ func (s *PoolServer) Serve() *http.ServeMux { mux.HandleFunc("POST /{id}/delivery", ErrorHandler(s.HandleSetDelivery)) mux.HandleFunc("DELETE /{id}/delivery/{deliveryId}", ErrorHandler(s.HandleRemoveDelivery)) mux.HandleFunc("PUT /{id}/delivery/{deliveryId}/pickupPoint", ErrorHandler(s.HandleSetPickupPoint)) + mux.HandleFunc("GET /{id}/checkout", ErrorHandler(s.HandleCheckout)) + return mux } diff --git a/proto/messages.pb.go b/proto/messages.pb.go index 6995f0b..5aa0c92 100644 --- a/proto/messages.pb.go +++ b/proto/messages.pb.go @@ -304,6 +304,10 @@ type SetDelivery struct { Provider string `protobuf:"bytes,1,opt,name=Provider,proto3" json:"provider,omitempty"` Items []int64 `protobuf:"varint,2,rep,packed,name=Items,proto3" json:"items,omitempty"` PickupPoint *PickupPoint `protobuf:"bytes,3,opt,name=PickupPoint,proto3,oneof" json:"pickupPoint,omitempty"` + Country string `protobuf:"bytes,4,opt,name=Country,proto3" json:"country,omitempty"` + Zip string `protobuf:"bytes,5,opt,name=Zip,proto3" json:"zip,omitempty"` + Address *string `protobuf:"bytes,6,opt,name=Address,proto3,oneof" json:"address,omitempty"` + City *string `protobuf:"bytes,7,opt,name=City,proto3,oneof" json:"city,omitempty"` } func (x *SetDelivery) Reset() { @@ -357,6 +361,34 @@ func (x *SetDelivery) GetPickupPoint() *PickupPoint { return nil } +func (x *SetDelivery) GetCountry() string { + if x != nil { + return x.Country + } + return "" +} + +func (x *SetDelivery) GetZip() string { + if x != nil { + return x.Zip + } + return "" +} + +func (x *SetDelivery) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address + } + return "" +} + +func (x *SetDelivery) GetCity() string { + if x != nil && x.City != nil { + return *x.City + } + return "" +} + type SetPickupPoint struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -580,6 +612,75 @@ func (x *RemoveDelivery) GetId() int64 { return 0 } +type CreateCheckoutOrder struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Terms string `protobuf:"bytes,1,opt,name=Terms,proto3" json:"terms,omitempty"` + Checkout string `protobuf:"bytes,2,opt,name=Checkout,proto3" json:"checkout,omitempty"` + Confirmation string `protobuf:"bytes,3,opt,name=Confirmation,proto3" json:"confirmation,omitempty"` + Push string `protobuf:"bytes,4,opt,name=Push,proto3" json:"push,omitempty"` +} + +func (x *CreateCheckoutOrder) Reset() { + *x = CreateCheckoutOrder{} + mi := &file_messages_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *CreateCheckoutOrder) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateCheckoutOrder) ProtoMessage() {} + +func (x *CreateCheckoutOrder) ProtoReflect() protoreflect.Message { + mi := &file_messages_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateCheckoutOrder.ProtoReflect.Descriptor instead. +func (*CreateCheckoutOrder) Descriptor() ([]byte, []int) { + return file_messages_proto_rawDescGZIP(), []int{8} +} + +func (x *CreateCheckoutOrder) GetTerms() string { + if x != nil { + return x.Terms + } + return "" +} + +func (x *CreateCheckoutOrder) GetCheckout() string { + if x != nil { + return x.Checkout + } + return "" +} + +func (x *CreateCheckoutOrder) GetConfirmation() string { + if x != nil { + return x.Confirmation + } + return "" +} + +func (x *CreateCheckoutOrder) GetPush() string { + if x != nil { + return x.Push + } + return "" +} + var File_messages_proto protoreflect.FileDescriptor var file_messages_proto_rawDesc = []byte{ @@ -612,7 +713,7 @@ var file_messages_proto_rawDesc = []byte{ 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x8d, 0x01, 0x0a, 0x0b, 0x53, + 0x52, 0x08, 0x51, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x22, 0x86, 0x02, 0x0a, 0x0b, 0x53, 0x65, 0x74, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, @@ -620,41 +721,57 @@ var file_messages_proto_rawDesc = []byte{ 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x50, 0x69, 0x63, 0x6b, - 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x50, - 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xf9, 0x01, 0x0a, 0x0e, 0x53, - 0x65, 0x74, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x0a, - 0x0a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x0a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x17, 0x0a, - 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, - 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, - 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x5a, - 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, - 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, - 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x43, 0x69, - 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x5a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x43, - 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xd6, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x63, 0x6b, 0x75, - 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x5a, 0x69, 0x70, 0x12, 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x42, 0x0e, + 0x0a, 0x0c, 0x5f, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x42, 0x0a, + 0x0a, 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x43, + 0x69, 0x74, 0x79, 0x22, 0xf9, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x50, 0x69, 0x63, 0x6b, 0x75, + 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, + 0x72, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x44, 0x65, 0x6c, 0x69, + 0x76, 0x65, 0x72, 0x79, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, - 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, - 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, - 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x05, + 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, + 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x03, 0x5a, 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, - 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x43, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x5a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, - 0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, - 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, - 0x64, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0xd6, 0x01, 0x0a, 0x0b, 0x50, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, + 0x0e, 0x0a, 0x02, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x64, 0x12, + 0x17, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x07, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x88, 0x01, 0x01, 0x12, 0x17, 0x0a, 0x04, 0x43, 0x69, 0x74, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02, 0x52, 0x04, 0x43, 0x69, 0x74, 0x79, 0x88, 0x01, 0x01, + 0x12, 0x15, 0x0a, 0x03, 0x5a, 0x69, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, + 0x03, 0x5a, 0x69, 0x70, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x04, 0x52, 0x07, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x4e, 0x61, 0x6d, 0x65, 0x42, + 0x0a, 0x0a, 0x08, 0x5f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x5f, + 0x43, 0x69, 0x74, 0x79, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x5a, 0x69, 0x70, 0x42, 0x0a, 0x0a, 0x08, + 0x5f, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x22, 0x20, 0x0a, 0x0e, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x44, 0x65, 0x6c, 0x69, 0x76, 0x65, 0x72, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x49, 0x64, 0x22, 0x7f, 0x0a, 0x13, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x12, 0x14, 0x0a, 0x05, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x54, 0x65, 0x72, 0x6d, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x6f, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x43, 0x68, 0x65, 0x63, 0x6b, + 0x6f, 0x75, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x50, 0x75, 0x73, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x50, 0x75, 0x73, 0x68, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, + 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -669,16 +786,17 @@ func file_messages_proto_rawDescGZIP() []byte { return file_messages_proto_rawDescData } -var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_messages_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_messages_proto_goTypes = []any{ - (*AddRequest)(nil), // 0: messages.AddRequest - (*AddItem)(nil), // 1: messages.AddItem - (*RemoveItem)(nil), // 2: messages.RemoveItem - (*ChangeQuantity)(nil), // 3: messages.ChangeQuantity - (*SetDelivery)(nil), // 4: messages.SetDelivery - (*SetPickupPoint)(nil), // 5: messages.SetPickupPoint - (*PickupPoint)(nil), // 6: messages.PickupPoint - (*RemoveDelivery)(nil), // 7: messages.RemoveDelivery + (*AddRequest)(nil), // 0: messages.AddRequest + (*AddItem)(nil), // 1: messages.AddItem + (*RemoveItem)(nil), // 2: messages.RemoveItem + (*ChangeQuantity)(nil), // 3: messages.ChangeQuantity + (*SetDelivery)(nil), // 4: messages.SetDelivery + (*SetPickupPoint)(nil), // 5: messages.SetPickupPoint + (*PickupPoint)(nil), // 6: messages.PickupPoint + (*RemoveDelivery)(nil), // 7: messages.RemoveDelivery + (*CreateCheckoutOrder)(nil), // 8: messages.CreateCheckoutOrder } var file_messages_proto_depIdxs = []int32{ 6, // 0: messages.SetDelivery.PickupPoint:type_name -> messages.PickupPoint @@ -704,7 +822,7 @@ func file_messages_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_messages_proto_rawDesc, NumEnums: 0, - NumMessages: 8, + NumMessages: 9, NumExtensions: 0, NumServices: 0, }, diff --git a/proto/messages.proto b/proto/messages.proto index 1481331..6ce97e6 100644 --- a/proto/messages.proto +++ b/proto/messages.proto @@ -62,3 +62,10 @@ message PickupPoint { message RemoveDelivery { int64 Id = 1; } + +message CreateCheckoutOrder { + string Terms = 1; + string Checkout = 2; + string Confirmation = 3; + string Push = 4; +} \ No newline at end of file From 12d695bec3d422c1633592220c9dca8a8f083e1f Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 22:58:41 +0100 Subject: [PATCH 16/18] update deployment --- deployment/deployment.yaml | 29 +++++++++++++++++++++++++++++ main.go | 7 +++++++ 2 files changed, 36 insertions(+) diff --git a/deployment/deployment.yaml b/deployment/deployment.yaml index 61ecf17..debe0d2 100644 --- a/deployment/deployment.yaml +++ b/deployment/deployment.yaml @@ -1,3 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: klarna-api-credentials +data: + username: ZjQzZDY3YjEtNzA2Yy00NTk2LTliNTgtYjg1YjU2NDEwZTUw + password: a2xhcm5hX3Rlc3RfYXBpX0trUWhWVE5yYVZsV2FsTnhTRVp3Y1ZSSFF5UkVNRmxyY25Kd1AxSndQMGdzWmpRelpEWTNZakV0TnpBMll5MDBOVGsyTFRsaU5UZ3RZamcxWWpVMk5ERXdaVFV3TERFc2JUUkNjRFpWU1RsTllsSk1aMlEyVEc4MmRVODNZMkozUlRaaFdEZDViV3AwYkhGV1JqTjVNQzlaYXow +type: Opaque +--- apiVersion: apps/v1 kind: Deployment metadata: @@ -75,6 +84,16 @@ spec: env: - name: TZ value: "Europe/Stockholm" + - name: KLARNA_API_USERNAME + valueFrom: + secretKeyRef: + name: klarna-api-credentials + key: username + - name: KLARNA_API_PASSWORD + valueFrom: + secretKeyRef: + name: klarna-api-credentials + key: password - name: POD_IP valueFrom: fieldRef: @@ -165,6 +184,16 @@ spec: env: - name: TZ value: "Europe/Stockholm" + - name: KLARNA_API_USERNAME + valueFrom: + secretKeyRef: + name: klarna-api-credentials + key: username + - name: KLARNA_API_PASSWORD + valueFrom: + secretKeyRef: + name: klarna-api-credentials + key: password - name: POD_IP valueFrom: fieldRef: diff --git a/main.go b/main.go index 715ab5c..9648039 100644 --- a/main.go +++ b/main.go @@ -178,6 +178,13 @@ func main() { w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) }) + mux.HandleFunc("/push", func(w http.ResponseWriter, r *http.Request) { + log.Print(r.Body) + }) + mux.HandleFunc("/version", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("1.0.0")) + }) sigs := make(chan os.Signal, 1) done := make(chan bool, 1) From b79f7904b11996b20115384e1553f5f0e76f7021 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 23:17:29 +0100 Subject: [PATCH 17/18] cors --- pool-server.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pool-server.go b/pool-server.go index cfc69f9..4565dc6 100644 --- a/pool-server.go +++ b/pool-server.go @@ -60,6 +60,7 @@ func ErrorHandler(fn func(w http.ResponseWriter, r *http.Request) error) func(w func (s *PoolServer) WriteResult(w http.ResponseWriter, result *FrameWithPayload) error { w.Header().Set("Content-Type", "application/json") w.Header().Set("X-Pod-Name", s.pod_name) + w.Header().Set("Access-Control-Allow-Origin", "https://tornberg.me") if result.StatusCode != 200 { log.Printf("Call error: %d\n", result.StatusCode) if result.StatusCode >= 200 && result.StatusCode < 600 { @@ -239,6 +240,10 @@ func (s *PoolServer) HandleCheckout(w http.ResponseWriter, r *http.Request) erro buf := new(bytes.Buffer) buf.ReadFrom(res.Body) + w.Header().Set("Content-Type", "application/json") + w.Header().Set("X-Pod-Name", s.pod_name) + w.Header().Set("Access-Control-Allow-Origin", "https://tornberg.me") + w.WriteHeader(res.StatusCode) w.Write(buf.Bytes()) return nil From 9aa64b2808fcbe8239f7d904fbf8d1dcae796c33 Mon Sep 17 00:00:00 2001 From: matst80 Date: Thu, 14 Nov 2024 23:21:34 +0100 Subject: [PATCH 18/18] handle checkout ordertype --- message-handler.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/message-handler.go b/message-handler.go index 92f672f..87a2dac 100644 --- a/message-handler.go +++ b/message-handler.go @@ -219,3 +219,34 @@ func (h *RemoveDeliveryHandler) Is(m *Message) bool { _, ok := m.Content.(*messages.RemoveDelivery) return ok } + +type CheckoutHandler struct { + TypedMessageHandler +} + +func (h *CheckoutHandler) Write(m *Message, w io.Writer) error { + messageBytes, err := proto.Marshal(m.Content.(*messages.CreateCheckoutOrder)) + if err != nil { + return err + } + w.Write(messageBytes) + return nil +} + +func (h *CheckoutHandler) Read(data []byte) (interface{}, error) { + msg := &messages.CreateCheckoutOrder{} + + err := proto.Unmarshal(data, msg) + if err != nil { + return nil, err + } + return msg, nil +} + +func (h *CheckoutHandler) Is(m *Message) bool { + if m.Type != CreateCheckoutOrderType { + return false + } + _, ok := m.Content.(*messages.CreateCheckoutOrder) + return ok +}