Files
sendico/api/payments/quotation/internal/service/plan/plan_builder_plans.go
2026-02-11 18:15:04 +01:00

78 lines
2.4 KiB
Go

package plan
import (
"time"
"github.com/tech/sendico/payments/storage/model"
"github.com/tech/sendico/pkg/merrors"
paymenttypes "github.com/tech/sendico/pkg/payments/types"
sharedv1 "github.com/tech/sendico/pkg/proto/payments/shared/v1"
)
func buildFXConversionPlan(payment *model.Payment) (*model.PaymentPlan, error) {
if payment == nil {
return nil, merrors.InvalidArgument("plan builder: payment is required")
}
step := &model.PaymentStep{
StepID: "fx_convert",
Rail: model.RailLedger,
Action: model.RailOperationFXConvert,
CommitPolicy: model.CommitPolicyImmediate,
Amount: cloneMoney(payment.Intent.Amount),
}
return &model.PaymentPlan{
ID: payment.PaymentRef,
Steps: []*model.PaymentStep{step},
IdempotencyKey: payment.IdempotencyKey,
CreatedAt: planTimestamp(payment),
}, nil
}
func resolveSettlementAmount(payment *model.Payment, quote *sharedv1.PaymentQuote, fallback *paymenttypes.Money) *paymenttypes.Money {
if quote != nil && quote.GetExpectedSettlementAmount() != nil {
return moneyFromProto(quote.GetExpectedSettlementAmount())
}
if payment != nil && payment.LastQuote != nil && payment.LastQuote.ExpectedSettlementAmount != nil {
return cloneMoney(payment.LastQuote.ExpectedSettlementAmount)
}
return cloneMoney(fallback)
}
func resolveDebitAmount(payment *model.Payment, quote *sharedv1.PaymentQuote, fallback *paymenttypes.Money) *paymenttypes.Money {
if quote != nil && quote.GetDebitAmount() != nil {
return moneyFromProto(quote.GetDebitAmount())
}
if payment != nil && payment.LastQuote != nil && payment.LastQuote.DebitAmount != nil {
return cloneMoney(payment.LastQuote.DebitAmount)
}
return cloneMoney(fallback)
}
func resolveFeeAmount(payment *model.Payment, quote *sharedv1.PaymentQuote) *paymenttypes.Money {
if quote != nil && quote.GetExpectedFeeTotal() != nil {
return moneyFromProto(quote.GetExpectedFeeTotal())
}
if payment != nil && payment.LastQuote != nil {
return cloneMoney(payment.LastQuote.ExpectedFeeTotal)
}
return nil
}
func isPositiveMoney(amount *paymenttypes.Money) bool {
if amount == nil {
return false
}
val, err := decimalFromMoney(amount)
if err != nil {
return false
}
return val.IsPositive()
}
func planTimestamp(payment *model.Payment) time.Time {
if payment != nil && !payment.CreatedAt.IsZero() {
return payment.CreatedAt.UTC()
}
return time.Now().UTC()
}