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() }