refactor/checkout (#8)
Co-authored-by: matst80 <mats.tornberg@gmail.com> Reviewed-on: #8 Co-authored-by: Mats Törnberg <mats@tornberg.me> Co-committed-by: Mats Törnberg <mats@tornberg.me>
This commit was merged in pull request #8.
This commit is contained in:
184
pkg/checkout/checkout-grain.go
Normal file
184
pkg/checkout/checkout-grain.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package checkout
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.k6n.net/go-cart-actor/pkg/cart"
|
||||
)
|
||||
|
||||
// CheckoutId is the same as CartId for simplicity
|
||||
type CheckoutId = cart.CartId
|
||||
|
||||
type PickupPoint struct {
|
||||
DeliveryId uint32 `json:"deliveryId,omitempty"`
|
||||
Id string `json:"id"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Address *string `json:"address,omitempty"`
|
||||
City *string `json:"city,omitempty"`
|
||||
Zip *string `json:"zip,omitempty"`
|
||||
Country *string `json:"country,omitempty"`
|
||||
}
|
||||
|
||||
type CheckoutDelivery struct {
|
||||
Id uint32 `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
Price cart.Price `json:"price"`
|
||||
Items []uint32 `json:"items"`
|
||||
PickupPoint *PickupPoint `json:"pickupPoint,omitempty"`
|
||||
}
|
||||
type PaymentStatus string
|
||||
type CheckoutPaymentStatus PaymentStatus
|
||||
|
||||
const (
|
||||
PaymentStatusPending PaymentStatus = "pending"
|
||||
PaymentStatusFailed PaymentStatus = "failed"
|
||||
PaymentStatusSuccess PaymentStatus = "success"
|
||||
CheckoutPaymentStatusPending CheckoutPaymentStatus = "pending"
|
||||
CheckoutPaymentStatusFailed CheckoutPaymentStatus = "failed"
|
||||
CheckoutPaymentStatusSuccess CheckoutPaymentStatus = "success"
|
||||
CheckoutPaymentStatusCancelled CheckoutPaymentStatus = "partial"
|
||||
)
|
||||
|
||||
type Payment struct {
|
||||
PaymentId string `json:"paymentId"`
|
||||
Status PaymentStatus `json:"status"`
|
||||
Amount int64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Method *string `json:"method,omitempty"`
|
||||
Events []*PaymentEvent `json:"events,omitempty"`
|
||||
ProcessorReference *string `json:"processorReference,omitempty"`
|
||||
StartedAt *time.Time `json:"startedAt,omitempty"`
|
||||
CompletedAt *time.Time `json:"completedAt,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentEvent struct {
|
||||
Name string `json:"name"`
|
||||
Success bool `json:"success"`
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
func (p *Payment) IsSettled() bool {
|
||||
if p == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
switch p.Status {
|
||||
case PaymentStatusSuccess:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
type ConfirmationStatus struct {
|
||||
Code *string `json:"code,omitempty"`
|
||||
ViewCount int `json:"viewCount"`
|
||||
LastViewedAt time.Time `json:"lastViewedAt"`
|
||||
}
|
||||
|
||||
type CheckoutGrain struct {
|
||||
mu sync.RWMutex
|
||||
lastDeliveryId uint32
|
||||
lastGiftcardId uint32
|
||||
lastAccess time.Time
|
||||
lastChange time.Time
|
||||
Version uint32
|
||||
Id CheckoutId `json:"id"`
|
||||
CartId cart.CartId `json:"cartId"`
|
||||
CartVersion uint64 `json:"cartVersion"`
|
||||
CartState *cart.CartGrain `json:"cartState"` // snapshot of items
|
||||
CartTotalPrice *cart.Price `json:"cartTotalPrice"`
|
||||
OrderId *string `json:"orderId"`
|
||||
Deliveries []*CheckoutDelivery `json:"deliveries,omitempty"`
|
||||
PaymentInProgress uint16 `json:"paymentInProgress"`
|
||||
InventoryReserved bool `json:"inventoryReserved"`
|
||||
Confirmation *ConfirmationStatus `json:"confirmationViewed,omitempty"`
|
||||
Payments []*Payment `json:"payments,omitempty"`
|
||||
}
|
||||
|
||||
func NewCheckoutGrain(id uint64, cartId cart.CartId, cartVersion uint64, ts time.Time, cartState *cart.CartGrain) *CheckoutGrain {
|
||||
return &CheckoutGrain{
|
||||
lastDeliveryId: 0,
|
||||
lastGiftcardId: 0,
|
||||
lastAccess: ts,
|
||||
lastChange: ts,
|
||||
Id: CheckoutId(id),
|
||||
CartId: cartId,
|
||||
CartVersion: cartVersion,
|
||||
Deliveries: []*CheckoutDelivery{},
|
||||
Payments: []*Payment{},
|
||||
CartState: cartState,
|
||||
CartTotalPrice: cartState.TotalPrice,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) GetId() uint64 {
|
||||
return uint64(c.Id)
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) GetLastChange() time.Time {
|
||||
return c.lastChange
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) GetLastAccess() time.Time {
|
||||
return c.lastAccess
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) GetCurrentState() (*CheckoutGrain, error) {
|
||||
c.lastAccess = time.Now()
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) GetState() ([]byte, error) {
|
||||
return json.Marshal(c)
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) FindPayment(paymentId string) (*Payment, bool) {
|
||||
if paymentId == "" {
|
||||
return nil, false
|
||||
}
|
||||
for _, payment := range c.Payments {
|
||||
if payment != nil && payment.PaymentId == paymentId {
|
||||
return payment, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) SettledPayments() []*Payment {
|
||||
if len(c.Payments) == 0 {
|
||||
return nil
|
||||
}
|
||||
settled := make([]*Payment, 0, len(c.Payments))
|
||||
for _, payment := range c.Payments {
|
||||
if payment != nil && payment.IsSettled() {
|
||||
settled = append(settled, payment)
|
||||
}
|
||||
}
|
||||
if len(settled) == 0 {
|
||||
return nil
|
||||
}
|
||||
return settled
|
||||
}
|
||||
|
||||
func (c *CheckoutGrain) OpenPayments() []*Payment {
|
||||
if len(c.Payments) == 0 {
|
||||
return nil
|
||||
}
|
||||
pending := make([]*Payment, 0, len(c.Payments))
|
||||
for _, payment := range c.Payments {
|
||||
if payment == nil {
|
||||
continue
|
||||
}
|
||||
if !payment.IsSettled() {
|
||||
pending = append(pending, payment)
|
||||
}
|
||||
}
|
||||
if len(pending) == 0 {
|
||||
return nil
|
||||
}
|
||||
return pending
|
||||
}
|
||||
Reference in New Issue
Block a user