@@ -371,7 +371,7 @@ export class LogJobService {
371371 ( b ) => b . accountIban === yapealChfBank . iban && b . creditDebitIndicator === BankTxIndicator . DEBIT ,
372372 ) ;
373373 const chfReceiverScryptExchangeTx = recentScryptExchangeTx . filter (
374- ( k ) => k . type === ExchangeTxType . DEPOSIT && k . status === 'ok ' && k . currency === 'CHF' ,
374+ ( k ) => k . type === ExchangeTxType . DEPOSIT && k . status !== 'failed ' && k . currency === 'CHF' ,
375375 ) ;
376376
377377 // sender and receiver data
@@ -395,47 +395,38 @@ export class LogJobService {
395395
396396 // EUR: Bank -> Scrypt
397397 const eurSenderScryptBankTx = recentScryptBankTx . filter (
398- ( b ) => eurBankIbans . includes ( b . accountIban ) && b . creditDebitIndicator === BankTxIndicator . DEBIT ,
398+ ( b ) =>
399+ eurBankIbans . includes ( b . accountIban ) &&
400+ b . creditDebitIndicator === BankTxIndicator . DEBIT &&
401+ b . instructedCurrency ,
399402 ) ;
400403 const eurReceiverScryptExchangeTx = recentScryptExchangeTx . filter (
401- ( k ) => k . type === ExchangeTxType . DEPOSIT && k . status === 'ok ' && k . currency === 'EUR' && k . txId ,
404+ ( k ) => k . type === ExchangeTxType . DEPOSIT && k . status !== 'failed ' && k . currency === 'EUR' ,
402405 ) ;
403406
404407 // CHF: Scrypt -> Yapeal
405408 const chfSenderScryptExchangeTx = recentScryptExchangeTx . filter (
406- ( k ) => k . type === ExchangeTxType . WITHDRAWAL && k . status === 'ok ' && k . currency === 'CHF' ,
409+ ( k ) => k . type === ExchangeTxType . WITHDRAWAL && k . status !== 'failed ' && k . currency === 'CHF' ,
407410 ) ;
408411 const chfReceiverScryptBankTx = recentScryptBankTx . filter (
409412 ( b ) => b . accountIban === yapealChfBank . iban && b . creditDebitIndicator === BankTxIndicator . CREDIT ,
410413 ) ;
411414
412415 // EUR: Scrypt -> Bank
413416 const eurSenderScryptExchangeTx = recentScryptExchangeTx . filter (
414- ( k ) => k . type === ExchangeTxType . WITHDRAWAL && k . status === 'ok ' && k . currency === 'EUR' ,
417+ ( k ) => k . type === ExchangeTxType . WITHDRAWAL && k . status !== 'failed ' && k . currency === 'EUR' ,
415418 ) ;
416419 const eurReceiverScryptBankTx = recentScryptBankTx . filter (
417420 ( b ) => eurBankIbans . includes ( b . accountIban ) && b . creditDebitIndicator === BankTxIndicator . CREDIT ,
418421 ) ;
419422
420- // sender and receiver data for Bank -> Scrypt
421- const { sender : recentChfYapealScryptTx , receiver : recentChfBankTxScrypt } = this . filterSenderPendingList (
422- chfSenderScryptBankTx ,
423- chfReceiverScryptExchangeTx ,
424- ) ;
425- const { sender : recentEurBankToScryptTx , receiver : recentEurBankTxScrypt } = this . filterSenderPendingList (
426- eurSenderScryptBankTx ,
427- eurReceiverScryptExchangeTx ,
428- ) ;
423+ // Bank -> Scrypt: 1:1 matching, unmatched senders only
424+ const recentChfYapealScryptTx = this . getUnmatchedSenders ( chfSenderScryptBankTx , chfReceiverScryptExchangeTx ) ;
425+ const recentEurBankToScryptTx = this . getUnmatchedSenders ( eurSenderScryptBankTx , eurReceiverScryptExchangeTx ) ;
429426
430- // sender and receiver data for Scrypt -> Bank
431- const { sender : recentChfScryptYapealTx , receiver : recentChfScryptBankTx } = this . filterSenderPendingList (
432- chfSenderScryptExchangeTx ,
433- chfReceiverScryptBankTx ,
434- ) ;
435- const { sender : recentEurScryptToBankTx , receiver : recentEurScryptBankTx } = this . filterSenderPendingList (
436- eurSenderScryptExchangeTx ,
437- eurReceiverScryptBankTx ,
438- ) ;
427+ // Scrypt -> Bank: 1:1 matching, unmatched senders only
428+ const recentChfScryptYapealTx = this . getUnmatchedSenders ( chfSenderScryptExchangeTx , chfReceiverScryptBankTx ) ;
429+ const recentEurScryptToBankTx = this . getUnmatchedSenders ( eurSenderScryptExchangeTx , eurReceiverScryptBankTx ) ;
439430
440431 // assetLog
441432 return assets . reduce ( ( prev , curr ) => {
@@ -593,55 +584,38 @@ export class LogJobService {
593584 [ ...recentChfYapealScryptTx , ...recentEurBankToScryptTx ] ,
594585 BankTxType . SCRYPT ,
595586 ) ;
596- const pendingChfBankScryptMinusAmount = this . getPendingBankAmount (
597- [ curr ] ,
598- recentChfBankTxScrypt ,
599- ExchangeTxType . DEPOSIT ,
600- yapealChfBank . iban ,
601- ) ;
602- const pendingEurBankScryptMinusAmount = isScryptEurAsset
603- ? this . getPendingBankAmount ( [ curr ] , recentEurBankTxScrypt , ExchangeTxType . DEPOSIT )
604- : isEurBankAsset
605- ? 0
606- : this . getPendingBankAmount ( [ curr ] , recentEurBankTxScrypt , ExchangeTxType . DEPOSIT , yapealEurBank . iban ) ;
587+ // With 1:1 matching, matched receivers are already excluded from sender lists — no minus needed
588+ const pendingChfBankScryptMinusAmount = 0 ;
589+ const pendingEurBankScryptMinusAmount = 0 ;
607590
608- // unfiltered lists
591+ // unfiltered lists (1:1 matching)
609592 const pendingBankScryptPlusAmountUnfiltered = isScryptEurAsset
610593 ? this . getPendingBankAmount (
611594 eurBankAssets ,
612- eurSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. bankTxId ) ,
595+ this . getUnmatchedSenders (
596+ eurSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. bankTxId ) ,
597+ eurReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. exchangeTxId ) ,
598+ ) ,
613599 BankTxType . SCRYPT ,
614600 )
615601 : isEurBankAsset
616602 ? 0
617603 : this . getPendingBankAmount (
618604 [ curr ] ,
619605 [
620- ...chfSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. chf ?. bankTxId ) ,
621- ...eurSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. bankTxId ) ,
606+ ...this . getUnmatchedSenders (
607+ chfSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. chf ?. bankTxId ) ,
608+ chfReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. chf ?. exchangeTxId ) ,
609+ ) ,
610+ ...this . getUnmatchedSenders (
611+ eurSenderScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. bankTxId ) ,
612+ eurReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. exchangeTxId ) ,
613+ ) ,
622614 ] ,
623615 BankTxType . SCRYPT ,
624616 ) ;
625- const pendingChfBankScryptMinusAmountUnfiltered = this . getPendingBankAmount (
626- [ curr ] ,
627- chfReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. chf ?. exchangeTxId ) ,
628- ExchangeTxType . DEPOSIT ,
629- yapealChfBank . iban ,
630- ) ;
631- const pendingEurBankScryptMinusAmountUnfiltered = isScryptEurAsset
632- ? this . getPendingBankAmount (
633- [ curr ] ,
634- eurReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. exchangeTxId ) ,
635- ExchangeTxType . DEPOSIT ,
636- )
637- : isEurBankAsset
638- ? 0
639- : this . getPendingBankAmount (
640- [ curr ] ,
641- eurReceiverScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds ?. toScrypt ?. eur ?. exchangeTxId ) ,
642- ExchangeTxType . DEPOSIT ,
643- yapealEurBank . iban ,
644- ) ;
617+ const pendingChfBankScryptMinusAmountUnfiltered = 0 ;
618+ const pendingEurBankScryptMinusAmountUnfiltered = 0 ;
645619
646620 // Scrypt to Bank //
647621
@@ -657,17 +631,16 @@ export class LogJobService {
657631 : isEurBankAsset
658632 ? 0
659633 : this . getPendingBankAmount ( [ curr ] , recentEurScryptToBankTx , ExchangeTxType . WITHDRAWAL , yapealEurBank . iban ) ;
660- const pendingScryptBankMinusAmount = isScryptEurAsset
661- ? this . getPendingBankAmount ( eurBankAssets , recentEurScryptBankTx , BankTxType . SCRYPT )
662- : isEurBankAsset
663- ? 0
664- : this . getPendingBankAmount ( [ curr ] , [ ...recentChfScryptBankTx , ...recentEurScryptBankTx ] , BankTxType . SCRYPT ) ;
634+ const pendingScryptBankMinusAmount = 0 ;
665635
666- // unfiltered lists
636+ // unfiltered lists (1:1 matching)
667637 const pendingChfScryptBankPlusAmountUnfiltered = financeLogPairIds ?. fromScrypt ?. chf ?. exchangeTxId
668638 ? this . getPendingBankAmount (
669639 [ curr ] ,
670- chfSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . chf . exchangeTxId ) ,
640+ this . getUnmatchedSenders (
641+ chfSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . chf . exchangeTxId ) ,
642+ chfReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . chf . bankTxId ) ,
643+ ) ,
671644 ExchangeTxType . WITHDRAWAL ,
672645 yapealChfBank . iban ,
673646 )
@@ -676,7 +649,10 @@ export class LogJobService {
676649 ? financeLogPairIds ?. fromScrypt ?. eur ?. exchangeTxId
677650 ? this . getPendingBankAmount (
678651 [ curr ] ,
679- eurSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . exchangeTxId ) ,
652+ this . getUnmatchedSenders (
653+ eurSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . exchangeTxId ) ,
654+ eurReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . bankTxId ) ,
655+ ) ,
680656 ExchangeTxType . WITHDRAWAL ,
681657 )
682658 : 0
@@ -685,31 +661,15 @@ export class LogJobService {
685661 : financeLogPairIds ?. fromScrypt ?. eur ?. exchangeTxId
686662 ? this . getPendingBankAmount (
687663 [ curr ] ,
688- eurSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . exchangeTxId ) ,
664+ this . getUnmatchedSenders (
665+ eurSenderScryptExchangeTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . exchangeTxId ) ,
666+ eurReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . bankTxId ) ,
667+ ) ,
689668 ExchangeTxType . WITHDRAWAL ,
690669 yapealEurBank . iban ,
691670 )
692671 : 0 ;
693- const pendingScryptBankMinusAmountUnfiltered = isScryptEurAsset
694- ? financeLogPairIds ?. fromScrypt ?. eur ?. bankTxId
695- ? this . getPendingBankAmount (
696- eurBankAssets ,
697- eurReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . bankTxId ) ,
698- BankTxType . SCRYPT ,
699- )
700- : 0
701- : isEurBankAsset
702- ? 0
703- : financeLogPairIds ?. fromScrypt ?. chf ?. bankTxId || financeLogPairIds ?. fromScrypt ?. eur ?. bankTxId
704- ? this . getPendingBankAmount (
705- [ curr ] ,
706- [
707- ...chfReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . chf . bankTxId ) ,
708- ...eurReceiverScryptBankTx . filter ( ( t ) => t . id >= financeLogPairIds . fromScrypt . eur . bankTxId ) ,
709- ] ,
710- BankTxType . SCRYPT ,
711- )
712- : 0 ;
672+ const pendingScryptBankMinusAmountUnfiltered = 0 ;
713673
714674 const fromKrakenUnfiltered =
715675 pendingChfKrakenYapealPlusAmountUnfiltered +
@@ -1097,6 +1057,32 @@ export class LogJobService {
10971057 ) ;
10981058 }
10991059
1060+ public getUnmatchedSenders (
1061+ senderTx : ( BankTx | ExchangeTx ) [ ] ,
1062+ receiverTx : ( BankTx | ExchangeTx ) [ ] ,
1063+ ) : ( BankTx | ExchangeTx ) [ ] {
1064+ const before7Days = Util . daysBefore ( 7 ) ;
1065+ const recentSenders = senderTx . filter ( ( s ) => s . created > before7Days ) ;
1066+
1067+ if ( ! recentSenders . length || ! receiverTx . length ) return [ ...recentSenders ] ;
1068+
1069+ const receiverRefs = new Set < string > ( ) ;
1070+ for ( const r of receiverTx ) {
1071+ const ref = this . getTxReference ( r ) ;
1072+ if ( ref ) receiverRefs . add ( ref ) ;
1073+ }
1074+
1075+ return recentSenders . filter ( ( s ) => {
1076+ const ref = this . getTxReference ( s ) ;
1077+ return ! ref || ! receiverRefs . has ( ref ) ;
1078+ } ) ;
1079+ }
1080+
1081+ private getTxReference ( tx : BankTx | ExchangeTx ) : string | undefined {
1082+ if ( tx instanceof BankTx ) return tx . remittanceInfo ?. trim ( ) || undefined ;
1083+ return tx . txId ?. trim ( ) || undefined ;
1084+ }
1085+
11001086 public filterSenderPendingList (
11011087 senderTx : ( BankTx | ExchangeTx ) [ ] ,
11021088 receiverTx : ( BankTx | ExchangeTx ) [ ] | undefined ,
0 commit comments