Orchestrator refactoring + planned amounts
This commit is contained in:
@@ -157,7 +157,7 @@ require (
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.42.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect
|
||||
)
|
||||
|
||||
@@ -380,8 +380,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -401,8 +401,8 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.79.2 h1:fRMD94s2tITpyJGtBBn7MkMseNpOZU8ZxgC3MMBaXRU=
|
||||
google.golang.org/grpc v1.79.2/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
|
||||
@@ -91,18 +91,27 @@ type PaymentEndpoint struct {
|
||||
}
|
||||
|
||||
type PaymentOperation struct {
|
||||
StepRef string `json:"stepRef,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
StepRef string `json:"stepRef,omitempty"`
|
||||
Code string `json:"code,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Money *PaymentOperationMoney `json:"money,omitempty"`
|
||||
OperationRef string `json:"operationRef,omitempty"`
|
||||
Gateway string `json:"gateway,omitempty"`
|
||||
FailureCode string `json:"failureCode,omitempty"`
|
||||
FailureReason string `json:"failureReason,omitempty"`
|
||||
StartedAt time.Time `json:"startedAt,omitempty"`
|
||||
CompletedAt time.Time `json:"completedAt,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentOperationMoney struct {
|
||||
Planned *PaymentOperationMoneySnapshot `json:"planned,omitempty"`
|
||||
Executed *PaymentOperationMoneySnapshot `json:"executed,omitempty"`
|
||||
}
|
||||
|
||||
type PaymentOperationMoneySnapshot struct {
|
||||
Amount *paymenttypes.Money `json:"amount,omitempty"`
|
||||
ConvertedAmount *paymenttypes.Money `json:"convertedAmount,omitempty"`
|
||||
OperationRef string `json:"operationRef,omitempty"`
|
||||
Gateway string `json:"gateway,omitempty"`
|
||||
FailureCode string `json:"failureCode,omitempty"`
|
||||
FailureReason string `json:"failureReason,omitempty"`
|
||||
StartedAt time.Time `json:"startedAt,omitempty"`
|
||||
CompletedAt time.Time `json:"completedAt,omitempty"`
|
||||
}
|
||||
|
||||
type paymentQuoteResponse struct {
|
||||
@@ -581,19 +590,20 @@ func toUserVisibleOperations(steps []*orchestrationv2.StepExecution) []PaymentOp
|
||||
|
||||
func toPaymentOperation(step *orchestrationv2.StepExecution) PaymentOperation {
|
||||
operationRef, gateway := operationRefAndGateway(step.GetStepCode(), step.GetRefs())
|
||||
amount := normalizeOperationMoney(toMoney(step.GetExecutedMoney()))
|
||||
convertedAmount := normalizeOperationMoney(toMoney(step.GetConvertedMoney()))
|
||||
plannedAmount := stepPlannedAmount(step)
|
||||
plannedConvertedAmount := stepPlannedConvertedAmount(step)
|
||||
executedAmount := stepExecutedAmount(step)
|
||||
executedConvertedAmount := stepExecutedConvertedAmount(step)
|
||||
op := PaymentOperation{
|
||||
StepRef: step.GetStepRef(),
|
||||
Code: step.GetStepCode(),
|
||||
State: enumJSONName(step.GetState().String()),
|
||||
Label: strings.TrimSpace(step.GetUserLabel()),
|
||||
Amount: amount,
|
||||
ConvertedAmount: convertedAmount,
|
||||
OperationRef: operationRef,
|
||||
Gateway: gateway,
|
||||
StartedAt: timestampAsTime(step.GetStartedAt()),
|
||||
CompletedAt: timestampAsTime(step.GetCompletedAt()),
|
||||
StepRef: step.GetStepRef(),
|
||||
Code: step.GetStepCode(),
|
||||
State: enumJSONName(step.GetState().String()),
|
||||
Label: strings.TrimSpace(step.GetUserLabel()),
|
||||
Money: toOperationMoney(plannedAmount, plannedConvertedAmount, executedAmount, executedConvertedAmount),
|
||||
OperationRef: operationRef,
|
||||
Gateway: gateway,
|
||||
StartedAt: timestampAsTime(step.GetStartedAt()),
|
||||
CompletedAt: timestampAsTime(step.GetCompletedAt()),
|
||||
}
|
||||
failure := step.GetFailure()
|
||||
if failure == nil {
|
||||
@@ -607,6 +617,89 @@ func toPaymentOperation(step *orchestrationv2.StepExecution) PaymentOperation {
|
||||
return op
|
||||
}
|
||||
|
||||
func stepPlannedAmount(step *orchestrationv2.StepExecution) *paymenttypes.Money {
|
||||
if step == nil {
|
||||
return nil
|
||||
}
|
||||
if money := step.GetMoney(); money != nil {
|
||||
if planned := money.GetPlanned(); planned != nil {
|
||||
if normalized := normalizeOperationMoney(toMoney(planned.GetAmount())); normalized != nil {
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stepPlannedConvertedAmount(step *orchestrationv2.StepExecution) *paymenttypes.Money {
|
||||
if step == nil {
|
||||
return nil
|
||||
}
|
||||
if money := step.GetMoney(); money != nil {
|
||||
if planned := money.GetPlanned(); planned != nil {
|
||||
if normalized := normalizeOperationMoney(toMoney(planned.GetConvertedAmount())); normalized != nil {
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stepExecutedAmount(step *orchestrationv2.StepExecution) *paymenttypes.Money {
|
||||
if step == nil {
|
||||
return nil
|
||||
}
|
||||
if money := step.GetMoney(); money != nil {
|
||||
if executed := money.GetExecuted(); executed != nil {
|
||||
if normalized := normalizeOperationMoney(toMoney(executed.GetAmount())); normalized != nil {
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stepExecutedConvertedAmount(step *orchestrationv2.StepExecution) *paymenttypes.Money {
|
||||
if step == nil {
|
||||
return nil
|
||||
}
|
||||
if money := step.GetMoney(); money != nil {
|
||||
if executed := money.GetExecuted(); executed != nil {
|
||||
if normalized := normalizeOperationMoney(toMoney(executed.GetConvertedAmount())); normalized != nil {
|
||||
return normalized
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func toOperationMoney(
|
||||
plannedAmount *paymenttypes.Money,
|
||||
plannedConvertedAmount *paymenttypes.Money,
|
||||
executedAmount *paymenttypes.Money,
|
||||
executedConvertedAmount *paymenttypes.Money,
|
||||
) *PaymentOperationMoney {
|
||||
planned := toOperationMoneySnapshot(plannedAmount, plannedConvertedAmount)
|
||||
executed := toOperationMoneySnapshot(executedAmount, executedConvertedAmount)
|
||||
if planned == nil && executed == nil {
|
||||
return nil
|
||||
}
|
||||
return &PaymentOperationMoney{
|
||||
Planned: planned,
|
||||
Executed: executed,
|
||||
}
|
||||
}
|
||||
|
||||
func toOperationMoneySnapshot(amount *paymenttypes.Money, convertedAmount *paymenttypes.Money) *PaymentOperationMoneySnapshot {
|
||||
if amount == nil && convertedAmount == nil {
|
||||
return nil
|
||||
}
|
||||
return &PaymentOperationMoneySnapshot{
|
||||
Amount: amount,
|
||||
ConvertedAmount: convertedAmount,
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeOperationMoney(value *paymenttypes.Money) *paymenttypes.Money {
|
||||
if value == nil {
|
||||
return nil
|
||||
|
||||
@@ -343,83 +343,235 @@ func TestToPaymentOperation_MapsAmount(t *testing.T) {
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
})
|
||||
|
||||
if got := op.Amount; got != nil {
|
||||
t.Fatalf("expected nil amount without executed_money, got=%+v", got)
|
||||
}
|
||||
if got := op.ConvertedAmount; got != nil {
|
||||
t.Fatalf("expected no converted_amount for non-fx operation, got=%+v", got)
|
||||
if got := op.Money; got != nil {
|
||||
t.Fatalf("expected nil money payload without step money, got=%+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_PrefersExecutedMoney(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-4b",
|
||||
StepCode: "hop.4.card_payout.send",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
ExecutedMoney: &moneyv1.Money{Amount: "99.95", Currency: "EUR"},
|
||||
StepRef: "step-4b",
|
||||
StepCode: "hop.4.card_payout.send",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Planned: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "88.00", Currency: "EUR"},
|
||||
},
|
||||
Executed: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "99.95", Currency: "EUR"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Amount == nil {
|
||||
t.Fatal("expected amount to be mapped")
|
||||
if op.Money == nil || op.Money.Executed == nil || op.Money.Executed.Amount == nil {
|
||||
t.Fatal("expected executed amount to be mapped")
|
||||
}
|
||||
if got, want := op.Amount.Amount, "99.95"; got != want {
|
||||
t.Fatalf("amount.value mismatch: got=%q want=%q", got, want)
|
||||
if got, want := op.Money.Executed.Amount.Amount, "99.95"; got != want {
|
||||
t.Fatalf("executed amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Amount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("amount.currency mismatch: got=%q want=%q", got, want)
|
||||
if got, want := op.Money.Executed.Amount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("executed amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got := op.ConvertedAmount; got != nil {
|
||||
t.Fatalf("expected no converted_amount for non-fx operation, got=%+v", got)
|
||||
if op.Money.Planned == nil || op.Money.Planned.Amount == nil {
|
||||
t.Fatal("expected planned amount to be exposed")
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Amount, "88.00"; got != want {
|
||||
t.Fatalf("planned amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("planned amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got := op.Money.Executed.ConvertedAmount; got != nil {
|
||||
t.Fatalf("expected no executed converted_amount for non-fx operation, got=%+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_UsesPlannedMoneyBeforeExecution(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-4c",
|
||||
StepCode: "hop.4.card_payout.send",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_PENDING,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Planned: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "77.10", Currency: "USD"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Money == nil || op.Money.Planned == nil || op.Money.Planned.Amount == nil {
|
||||
t.Fatal("expected planned amount from structured planned money")
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Amount, "77.10"; got != want {
|
||||
t.Fatalf("planned amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Currency, "USD"; got != want {
|
||||
t.Fatalf("planned amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got := op.Money.Executed; got != nil {
|
||||
t.Fatalf("expected no executed snapshot before execution, got=%+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_UsesStructuredMoneyEnvelope(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-4d",
|
||||
StepCode: "hop.4.card_payout.send",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_PENDING,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Planned: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "66.00", Currency: "USD"},
|
||||
},
|
||||
Executed: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "67.00", Currency: "USD"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Money == nil || op.Money.Executed == nil || op.Money.Executed.Amount == nil {
|
||||
t.Fatal("expected amount from structured executed money")
|
||||
}
|
||||
if got, want := op.Money.Executed.Amount.Amount, "67.00"; got != want {
|
||||
t.Fatalf("executed amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if op.Money.Planned == nil || op.Money.Planned.Amount == nil {
|
||||
t.Fatal("expected planned amount from structured money")
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Amount, "66.00"; got != want {
|
||||
t.Fatalf("planned amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_MapsFxTwoAmounts(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-5",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
ConvertedMoney: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
StepRef: "step-5",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Executed: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
ConvertedAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if got := op.Amount; got != nil {
|
||||
if op.Money == nil || op.Money.Executed == nil {
|
||||
t.Fatal("expected executed snapshot to be mapped")
|
||||
}
|
||||
if got := op.Money.Executed.Amount; got != nil {
|
||||
t.Fatalf("expected nil base amount without executed_money, got=%+v", got)
|
||||
}
|
||||
if op.ConvertedAmount == nil {
|
||||
if op.Money.Executed.ConvertedAmount == nil {
|
||||
t.Fatal("expected fx converted amount to be mapped")
|
||||
}
|
||||
if got, want := op.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
if got, want := op.Money.Executed.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
t.Fatalf("converted amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.ConvertedAmount.Currency, "EUR"; got != want {
|
||||
if got, want := op.Money.Executed.ConvertedAmount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("converted amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_UsesPlannedFxAmountsBeforeExecution(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-5b",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_PENDING,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Planned: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "109.50", Currency: "USDT"},
|
||||
ConvertedAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Money == nil || op.Money.Planned == nil {
|
||||
t.Fatal("expected planned snapshot from structured money")
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Amount, "109.50"; got != want {
|
||||
t.Fatalf("base amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Currency, "USDT"; got != want {
|
||||
t.Fatalf("base amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if op.Money.Planned.ConvertedAmount == nil {
|
||||
t.Fatal("expected fx converted amount from structured planned money")
|
||||
}
|
||||
if got, want := op.Money.Planned.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
t.Fatalf("converted amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Planned.ConvertedAmount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("converted amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got := op.Money.Executed; got != nil {
|
||||
t.Fatalf("expected nil executed snapshot before execution, got=%+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_UsesStructuredFxMoneyEnvelope(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-5c",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Planned: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "109.50", Currency: "USDT"},
|
||||
ConvertedAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
},
|
||||
Executed: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "110.00", Currency: "USDT"},
|
||||
ConvertedAmount: &moneyv1.Money{Amount: "101.00", Currency: "EUR"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Money == nil || op.Money.Executed == nil || op.Money.Planned == nil {
|
||||
t.Fatal("expected snapshots from structured money")
|
||||
}
|
||||
if got, want := op.Money.Executed.Amount.Amount, "110.00"; got != want {
|
||||
t.Fatalf("amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Executed.ConvertedAmount.Amount, "101.00"; got != want {
|
||||
t.Fatalf("converted amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if op.Money.Planned.Amount == nil || op.Money.Planned.ConvertedAmount == nil {
|
||||
t.Fatal("expected planned amounts from structured money")
|
||||
}
|
||||
if got, want := op.Money.Planned.Amount.Amount, "109.50"; got != want {
|
||||
t.Fatalf("planned amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Money.Planned.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
t.Fatalf("planned converted amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToPaymentOperation_FxWithExecutedMoney_StillProvidesTwoAmounts(t *testing.T) {
|
||||
op := toPaymentOperation(&orchestrationv2.StepExecution{
|
||||
StepRef: "step-6",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
ExecutedMoney: &moneyv1.Money{Amount: "109.50", Currency: "USDT"},
|
||||
ConvertedMoney: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
StepRef: "step-6",
|
||||
StepCode: "hop.2.settlement.fx_convert",
|
||||
State: orchestrationv2.StepExecutionState_STEP_EXECUTION_STATE_COMPLETED,
|
||||
Money: &orchestrationv2.StepExecutionMoney{
|
||||
Executed: &orchestrationv2.StepExecutionMoneySnapshot{
|
||||
Amount: &moneyv1.Money{Amount: "109.50", Currency: "USDT"},
|
||||
ConvertedAmount: &moneyv1.Money{Amount: "100.00", Currency: "EUR"},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if op.Amount == nil {
|
||||
if op.Money == nil || op.Money.Executed == nil || op.Money.Executed.Amount == nil {
|
||||
t.Fatal("expected fx base amount to be mapped")
|
||||
}
|
||||
if got, want := op.Amount.Amount, "109.50"; got != want {
|
||||
if got, want := op.Money.Executed.Amount.Amount, "109.50"; got != want {
|
||||
t.Fatalf("base amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.Amount.Currency, "USDT"; got != want {
|
||||
if got, want := op.Money.Executed.Amount.Currency, "USDT"; got != want {
|
||||
t.Fatalf("base amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if op.ConvertedAmount == nil {
|
||||
if op.Money.Executed.ConvertedAmount == nil {
|
||||
t.Fatal("expected fx quote amount to be mapped")
|
||||
}
|
||||
if got, want := op.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
if got, want := op.Money.Executed.ConvertedAmount.Amount, "100.00"; got != want {
|
||||
t.Fatalf("converted amount.value mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
if got, want := op.ConvertedAmount.Currency, "EUR"; got != want {
|
||||
if got, want := op.Money.Executed.ConvertedAmount.Currency, "EUR"; got != want {
|
||||
t.Fatalf("converted amount.currency mismatch: got=%q want=%q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user