Skip to content

Commit bf480dd

Browse files
committed
OC notifications partyBankId
1 parent 5ff6e4b commit bf480dd

3 files changed

Lines changed: 34 additions & 25 deletions

File tree

‎obp-api/src/main/scala/code/bankconnectors/opencorridor/OpenCorridorSettlement.scala‎

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,22 +260,25 @@ object OpenCorridorSettlement extends MdcLoggable {
260260

261261
// Enqueue the Interface C messages in this same DB transaction (the outbox).
262262
// Credit notifications went to each beneficiary at promise-report-back time
263-
// (OpenCorridorProcessor); settlement sends each beneficiary an advice so
264-
// its already-paid-out credits get marked settled.
263+
// (OpenCorridorProcessor); settlement sends BOTH party banks an advice with
264+
// the FULL covered list, so each node stamps its already-paid-out credits
265+
// AND its own outbound promises settled — including the party that did not
266+
// trigger the settle, which otherwise never learns of the coverage (the
267+
// instruction only moves money, and at net zero it is not sent at all).
265268
settlementAdviceCount <- Future {
266-
covered.groupBy(_.mTo_BankId.get).map { case (beneficiaryBankId, rows) =>
267-
val advice = OutBoundOpenCorridorSettlementAdvice(
268-
settlement_id = settlementTrId,
269-
currency = currency,
270-
net_amount = netAbs.toString(),
271-
debtor_bank_id = debtorBankId,
272-
creditor_bank_id = creditorBankId,
273-
covered_transaction_request_ids = rows.map(_.mTransactionRequestId.get),
274-
idempotency_key = settlementTrId
275-
)
269+
val advice = OutBoundOpenCorridorSettlementAdvice(
270+
settlement_id = settlementTrId,
271+
currency = currency,
272+
net_amount = netAbs.toString(),
273+
debtor_bank_id = debtorBankId,
274+
creditor_bank_id = creditorBankId,
275+
covered_transaction_request_ids = covered.map(_.mTransactionRequestId.get),
276+
idempotency_key = settlementTrId
277+
)
278+
Set(bankIdA, bankIdB).map { partyBankId =>
276279
MessageOutbox.enqueue(
277280
MessageOutbox.TYPE_OPEN_CORRIDOR, settlementTrId, MessageOutbox.SUBJECT_TYPE_SETTLEMENT_ID,
278-
"obp_settlement_advice", beneficiaryBankId, Serialization.write(advice))
281+
"obp_settlement_advice", partyBankId, Serialization.write(advice))
279282
}.size
280283
}
281284
settlementInstructionCount <- Future {

‎obp-api/src/test/scala/code/api/v7_0_0/Http4s700RoutesTest.scala‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,13 +2643,15 @@ class Http4s700RoutesTest extends ServerSetupWithTestData {
26432643
outboxRows.size shouldBe 3
26442644
val adviceRows = outboxRows.filter(_.operationName == "obp_settlement_advice")
26452645
adviceRows.map(_.targetId).sorted shouldBe List(testBankId1.value, testBankId2.value).sorted
2646-
val bank2Advice = adviceRows.find(_.targetId == testBankId2.value)
2647-
.map(row => parse(row.payloadJson))
2648-
.getOrElse(fail("bank2's settlement advice should be enqueued"))
2649-
(bank2Advice \ "settlement_id") shouldBe JString(settlementId)
2650-
(bank2Advice \ "covered_transaction_request_ids") match {
2651-
case JArray(ids) => ids.collect { case JString(id) => id }.toSet shouldBe Set(promise1, promise2)
2652-
case _ => fail("covered_transaction_request_ids should be an array")
2646+
// Both party banks get the advice with the FULL covered list (both
2647+
// directions): each node stamps its credits AND its own promises from it.
2648+
adviceRows.foreach { row =>
2649+
val advice = parse(row.payloadJson)
2650+
(advice \ "settlement_id") shouldBe JString(settlementId)
2651+
(advice \ "covered_transaction_request_ids") match {
2652+
case JArray(ids) => ids.collect { case JString(id) => id }.toSet shouldBe Set(promise1, promise2, promise3)
2653+
case _ => fail("covered_transaction_request_ids should be an array")
2654+
}
26532655
}
26542656
val instructionRow = outboxRows.filter(_.operationName == "obp_settlement_instruction") match {
26552657
case row :: Nil => row

‎obp-commons/src/main/scala/com/openbankproject/commons/dto/OpenCorridorInterfaceC.scala‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,15 @@ case class OutBoundOpenCorridorSettlementInstruction(
107107
)
108108

109109
/**
110-
* `obp_settlement_advice` — published to each BENEFICIARY bank's vhost after a
111-
* netted settle: "the promises you already paid out against are now covered".
112-
* Purely reconciliatory — no money moves on this message (the debtor's
113-
* `obp_settlement_instruction` does that). One advice per beneficiary bank,
114-
* listing exactly the covered promise ids where that bank was the creditor.
110+
* `obp_settlement_advice` — published to BOTH party banks' vhosts after a
111+
* netted settle: "these promises are now covered". Purely reconciliatory — no
112+
* money moves on this message (the debtor's `obp_settlement_instruction` does
113+
* that, and at net zero no instruction exists at all — this advice is then the
114+
* only settle-time message either bank receives).
115+
* `covered_transaction_request_ids` is the FULL covered list of the pair, both
116+
* directions: each node stamps whatever matches its own records (credits it
117+
* paid out AND its own outbound promises); ids of the counterparty's records
118+
* match nothing there and are ignored.
115119
* Credit notifications themselves travel at promise-report-back time, not here.
116120
*/
117121
case class OutBoundOpenCorridorSettlementAdvice(

0 commit comments

Comments
 (0)