more cart
Build and Publish / BuildAndDeployArm64 (push) Failing after 6s
Build and Publish / BuildAndDeployAmd64 (push) Failing after 4s

This commit is contained in:
2026-07-01 22:11:37 +02:00
parent 1c97a4bdb0
commit 26fd6dc970
23 changed files with 1717 additions and 250 deletions
+51
View File
@@ -151,6 +151,33 @@ func BuildCheckoutOrderPayload(grain *checkout.CheckoutGrain, meta *CheckoutMeta
})
}
// Reflected applied promotions as negative discount lines
if grain.CartState != nil {
for _, ap := range grain.CartState.AppliedPromotions {
if ap.Pending {
continue
}
discountVal := int64(0)
if ap.Discount != nil {
discountVal = ap.Discount.IncVat.Int64()
}
if discountVal <= 0 {
continue
}
lines = append(lines, &Line{
Type: "discount",
Reference: "promo-" + ap.PromotionId,
Name: "Promotion: " + ap.Name,
Quantity: 1,
UnitPrice: int(-discountVal),
QuantityUnit: "st",
TotalAmount: int(-discountVal),
TaxRate: 2500,
TotalTaxAmount: int(-discountVal * 2500 / 12500),
})
}
}
order := &CheckoutOrder{
PurchaseCountry: country,
PurchaseCurrency: currency,
@@ -285,6 +312,30 @@ func BuildAdyenCheckoutSession(grain *checkout.CheckoutGrain, meta *CheckoutMeta
})
}
// Reflected applied promotions as negative discount lines
if grain.CartState != nil {
for _, ap := range grain.CartState.AppliedPromotions {
if ap.Pending {
continue
}
discountVal := int64(0)
if ap.Discount != nil {
discountVal = ap.Discount.IncVat.Int64()
}
if discountVal <= 0 {
continue
}
lineItems = append(lineItems, adyenCheckout.LineItem{
Quantity: common.PtrInt64(1),
AmountIncludingTax: common.PtrInt64(-discountVal),
Description: common.PtrString("Promotion: " + ap.Name),
AmountExcludingTax: common.PtrInt64(-discountVal * 10000 / 12500),
TaxAmount: common.PtrInt64(-discountVal * 2500 / 12500),
TaxPercentage: common.PtrInt64(2500),
})
}
}
return &adyenCheckout.CreateCheckoutSessionRequest{
Reference: grain.Id.String(),
Amount: adyenCheckout.Amount{
+46
View File
@@ -212,6 +212,31 @@ func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
// Data Retention (C5) GDPR Purge
retentionDays := config.EnvInt("CHECKOUT_RETENTION_DAYS", 0, func(n int) bool { return n >= 0 })
if retentionDays > 0 {
purgeInterval := config.EnvDuration("CHECKOUT_PURGE_INTERVAL", 24*time.Hour)
log.Printf("checkout: data retention enabled. Retaining checkouts for %d days, purging every %v", retentionDays, purgeInterval)
go func() {
ticker := time.NewTicker(purgeInterval)
defer ticker.Stop()
// Run immediately on startup
runPurge(ctx, diskStorage, pool, retentionDays)
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
runPurge(ctx, diskStorage, pool, retentionDays)
}
}
}()
} else {
log.Print("checkout: data retention / GDPR purge disabled (CHECKOUT_RETENTION_DAYS not set or <= 0)")
}
otelShutdown, err := telemetry.SetupOTelSDK(ctx)
if err != nil {
log.Fatalf("Unable to start otel %v", err)
@@ -299,3 +324,24 @@ func main() {
stop()
}
}
func runPurge(ctx context.Context, diskStorage *actor.DiskStorage[checkout.CheckoutGrain], pool *actor.SimpleGrainPool[checkout.CheckoutGrain], retentionDays int) {
log.Printf("checkout: starting data retention purge...")
retention := time.Duration(retentionDays) * 24 * time.Hour
localIds := make(map[uint64]bool)
for _, id := range pool.GetLocalIds() {
localIds[id] = true
}
isGrainActive := func(id uint64) bool {
return localIds[id]
}
purged, err := diskStorage.PurgeOlderThan(ctx, retention, isGrainActive)
if err != nil {
log.Printf("checkout: data retention purge failed: %v", err)
} else {
log.Printf("checkout: data retention purge completed. Purged %d expired checkout logs", purged)
}
}