From c0016f64fc67ad2ffa5fa8eb4632cd3e63826632 Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Tue, 3 Mar 2026 16:25:06 +0600 Subject: [PATCH 1/6] fix --- .../edit-candidate-dialog/edit-candidate-dialog.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts index c05383da2..c759cce94 100644 --- a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts +++ b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts @@ -78,7 +78,7 @@ export class EditCandidateDialogComponent } confirm() { - const { terminal, ...value } = getValue(this.form); + const { terminal, weightPercent: _weightPercent, ...value } = getValue(this.form); this.closeWithSuccess({ ...this.dialogData.candidate, terminal: { id: terminal }, From 77eb07f1bbd326c48aa6f8f22e955fe7b698968f Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:31:02 +0600 Subject: [PATCH 2/6] upd others --- .../candidates/candidates.component.ts | 48 ++++++---- .../edit-candidate-dialog.component.html | 3 +- .../edit-candidate-dialog.component.ts | 87 +++++++++---------- 3 files changed, 73 insertions(+), 65 deletions(-) diff --git a/src/app/parties/party/routing-rules/candidates/candidates.component.ts b/src/app/parties/party/routing-rules/candidates/candidates.component.ts index c1bc03c1c..94a3b25e1 100644 --- a/src/app/parties/party/routing-rules/candidates/candidates.component.ts +++ b/src/app/parties/party/routing-rules/candidates/candidates.component.ts @@ -429,33 +429,43 @@ export class CandidatesComponent { }); } - edit(idx: number) { + edit(candidateIdx: number) { this.routingRulesetService.refID$ .pipe( switchCombineWith((refId) => [ - this.routingRulesService.getCandidate(refId, idx), + this.routingRulesService.getCandidate(refId, candidateIdx), this.candidates$, ]), first(), - switchCombineWith(([_, candidate, candidates]) => [ - this.dialog - .open(EditCandidateDialogComponent, { - candidate, - othersWeight: candidates.reduce( - (acc, c, cIdx) => - acc + - (c.priority === candidate.priority && idx !== cIdx - ? c.weight || 0 - : 0), - 0, - ), - }) - .afterClosed(), - ]), - switchMap(([[refId], res]) => + switchCombineWith(([_, candidate, candidates]) => { + const others = candidates.filter( + (c) => c !== candidate && c.priority === candidate.priority && c.allowed, + ); + const ids = others.map((c) => candidates.findIndex((cd) => cd === c)); + return [ + this.dialog + .open(EditCandidateDialogComponent, { + candidate, + others, + }) + .afterClosed(), + ids, + others, + ]; + }), + switchMap(([[refId], res, ids]) => res.status === DialogResponseStatus.Success ? this.routingRulesService.updateRules([ - { refId, candidateIdx: idx, newCandidate: res.data }, + { + refId, + candidateIdx: candidateIdx, + newCandidate: res.data.candidate, + }, + ...res.data.others.map((newCandidate, idx) => ({ + refId, + candidateIdx: ids[idx], + newCandidate, + })), ]) : of(null), ), diff --git a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.html b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.html index 787dc014c..81bfae796 100644 --- a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.html +++ b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.html @@ -4,15 +4,14 @@
diff --git a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts index c759cce94..bc9e5fbfd 100644 --- a/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts +++ b/src/app/parties/party/routing-rules/candidates/components/edit-candidate-dialog/edit-candidate-dialog.component.ts @@ -1,6 +1,3 @@ -import { round } from 'lodash-es'; -import { distinctUntilChanged, map, shareReplay } from 'rxjs'; - import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, DestroyRef, OnInit, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; @@ -38,67 +35,69 @@ import { export class EditCandidateDialogComponent extends DialogSuperclass< EditCandidateDialogComponent, - { candidate: RoutingCandidate; othersWeight: number }, - RoutingCandidate + { candidate: RoutingCandidate; others: RoutingCandidate[] }, + { candidate: RoutingCandidate; others: RoutingCandidate[] } > implements OnInit { private fb = inject(FormBuilder); private dr = inject(DestroyRef); + private othersWeight = this.dialogData.others.reduce((acc, c) => acc + (c.weight || 0), 0); form = this.fb.nonNullable.group({ terminal: this.dialogData.candidate.terminal.id, description: this.dialogData.candidate.description, weight: this.dialogData.candidate.weight, - weightPercent: this.calcPercent(this.dialogData.candidate.weight), allowed: this.dialogData.candidate.allowed, }); - percent$ = getValueChanges(this.form.controls.weight).pipe( - distinctUntilChanged(), - map((weight) => this.calcPercent(Number(weight || 0))), - shareReplay({ bufferSize: 1, refCount: true }), - ); - weight$ = getValueChanges(this.form.controls.weightPercent).pipe( - distinctUntilChanged(), - map((weightPercent) => this.calcWeight(Number(weightPercent || 0))), - shareReplay({ bufferSize: 1, refCount: true }), - ); + weightPercentControl = this.fb.nonNullable.control(null); ngOnInit() { - this.weight$.pipe(takeUntilDestroyed(this.dr)).subscribe((weight) => { - this.form.controls.weight.setValue(Math.round(weight), { - emitEvent: false, + getValueChanges(this.weightPercentControl) + .pipe(takeUntilDestroyed(this.dr)) + .subscribe(() => { + this.form.controls.weight.setValue(null, { + emitEvent: false, + }); }); - }); - this.percent$.pipe(takeUntilDestroyed(this.dr)).subscribe((weightPercent) => { - this.form.controls.weightPercent.setValue(weightPercent, { - emitEvent: false, + getValueChanges(this.form.controls.weight) + .pipe(takeUntilDestroyed(this.dr)) + .subscribe(() => { + this.weightPercentControl.setValue(null, { + emitEvent: false, + }); }); - }); } confirm() { - const { terminal, weightPercent: _weightPercent, ...value } = getValue(this.form); + const { terminal, weight, ...value } = getValue(this.form); + const percent = getValue(this.weightPercentControl); + const isPercent = !!percent; + const weightNum = isPercent ? Number(percent) : Number(weight || 0); + this.closeWithSuccess({ - ...this.dialogData.candidate, - terminal: { id: terminal }, - ...value, + candidate: { + ...this.dialogData.candidate, + terminal: { id: terminal }, + ...value, + weight: weightNum, + }, + others: isPercent + ? this.dialogData.others.map((c) => ({ + ...c, + weight: + c.weight && this.othersWeight + ? Math.round( + (c.weight / this.othersWeight) * + (this.othersWeight - + (weight || 0) + + (percent + ? Math.round((percent / 100) * this.othersWeight) + : 0)), + ) + : 0, + })) + : this.dialogData.others, }); } - - private calcPercent(weight: number): number { - const res = this.dialogData.othersWeight - ? (weight / (this.dialogData.othersWeight + weight)) * 100 - : 100; - return round(Math.max(Math.min(res, 100), 0), 2); - } - - private calcWeight(weightPercent: number): number { - const res = this.dialogData.othersWeight - ? (weightPercent * this.dialogData.othersWeight) / (100 - weightPercent) - : weightPercent - ? 1 - : 0; - return round(Math.max(Math.min(res, 1_000_000), 0), 2); - } } From b3341f9b47f7355e54816e2f6840849b0603f6cf Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Fri, 6 Mar 2026 01:38:17 +0600 Subject: [PATCH 3/6] support payment external ids --- package-lock.json | 8 ++++---- package.json | 2 +- src/app/payments/payments.component.html | 6 +++++- src/app/payments/payments.component.ts | 7 ++++--- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index a870c9138..9b52ccff4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@vality/domain-proto": "^2.0.1-7a97267.0", "@vality/fistful-proto": "^2.0.1-7c61ac5.0", "@vality/machinegun-proto": "^1.0.1-cc2c27c.0", - "@vality/magista-proto": "^2.0.2-f3b4b14.0", + "@vality/magista-proto": "^2.0.2-2de1ebf.0", "@vality/ng-monaco-editor": "^20.0.0", "@vality/repairer-proto": "^2.0.2-1a48729.0", "@vality/scrooge-proto": "^0.1.1-42aba67.0", @@ -5973,9 +5973,9 @@ "license": "Apache-2.0" }, "node_modules/@vality/magista-proto": { - "version": "2.0.2-f3b4b14.0", - "resolved": "https://registry.npmjs.org/@vality/magista-proto/-/magista-proto-2.0.2-f3b4b14.0.tgz", - "integrity": "sha512-zehGV61ndFeWv+7zge8DjRa/4O+M1RtKrNFqhRlXNAhBTwciHXgxwxECvc7pqvG1AE6H0/3eeAxBCueMgn8s+g==", + "version": "2.0.2-2de1ebf.0", + "resolved": "https://registry.npmjs.org/@vality/magista-proto/-/magista-proto-2.0.2-2de1ebf.0.tgz", + "integrity": "sha512-kldv1gnEysjiBs1EnDG67wG3TcXrL9tRMT0/qgwmh9iPumtOW6BkXibc/VrcexeAsNRiM6R718YgYOJFF1+Rsw==", "license": "Apache-2.0" }, "node_modules/@vality/matez": { diff --git a/package.json b/package.json index 49a421ecd..88f7bc18a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@vality/domain-proto": "^2.0.1-7a97267.0", "@vality/fistful-proto": "^2.0.1-7c61ac5.0", "@vality/machinegun-proto": "^1.0.1-cc2c27c.0", - "@vality/magista-proto": "^2.0.2-f3b4b14.0", + "@vality/magista-proto": "^2.0.2-2de1ebf.0", "@vality/ng-monaco-editor": "^20.0.0", "@vality/repairer-proto": "^2.0.2-1a48729.0", "@vality/scrooge-proto": "^0.1.1-42aba67.0", diff --git a/src/app/payments/payments.component.html b/src/app/payments/payments.component.html index 7802d9850..c6def7412 100644 --- a/src/app/payments/payments.component.html +++ b/src/app/payments/payments.component.html @@ -15,7 +15,11 @@ formControlName="invoice_ids" label="Invoice and Payment Ids" > - + diff --git a/src/app/payments/payments.component.ts b/src/app/payments/payments.component.ts index d8ac337fc..98deb1bc8 100644 --- a/src/app/payments/payments.component.ts +++ b/src/app/payments/payments.component.ts @@ -98,7 +98,7 @@ export class PaymentsComponent implements OnInit { payment_rrn: undefined as string, payment_email: undefined as string, error_message: undefined as string, - external_id: undefined as string, + external_ids: [undefined as string[]], }); otherFiltersControl = this.fb.control({ common_search_query_params: {}, @@ -117,6 +117,7 @@ export class PaymentsComponent implements OnInit { 'payment_rrn', 'error_message', 'external_id', + 'external_ids', ].includes(data?.field?.name), ), extension: () => of({ hidden: true }), @@ -163,7 +164,7 @@ export class PaymentsComponent implements OnInit { } load({ filters, otherFilters, dateRange }: Filters, options?: LoadOptions) { - const { invoice_ids, party_id, shop_ids, external_id, ...paymentParams } = filters; + const { invoice_ids, party_id, shop_ids, external_ids, ...paymentParams } = filters; const searchParams = clean({ ...otherFilters, common_search_query_params: { @@ -174,7 +175,7 @@ export class PaymentsComponent implements OnInit { to_time: getNoTimeZoneIsoString(endOfDay(dateRange.end)), }, payment_params: { ...(otherFilters.payment_params || {}), ...paymentParams }, - external_id, + external_ids, invoice_ids, }); this.fetchPaymentsService.load(searchParams, options); From f5423d85f07667229d80f413f8235fa5f8b98724 Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Fri, 6 Mar 2026 01:57:36 +0600 Subject: [PATCH 4/6] support ext ids --- .../fistful-stat/query-dsl/types/withdrawal-params.ts | 3 ++- src/app/withdrawals/withdrawals.component.html | 3 ++- src/app/withdrawals/withdrawals.component.ts | 11 ++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/api/fistful-stat/query-dsl/types/withdrawal-params.ts b/src/api/fistful-stat/query-dsl/types/withdrawal-params.ts index aff4b9e28..f18254067 100644 --- a/src/api/fistful-stat/query-dsl/types/withdrawal-params.ts +++ b/src/api/fistful-stat/query-dsl/types/withdrawal-params.ts @@ -7,11 +7,12 @@ export interface WithdrawalParams extends PagedBaseParameters { party_id?: string; wallet_id?: string; withdrawal_id?: string; - withdrawal_ids?: string; + withdrawal_ids?: string[]; identity_id?: string; destination_id?: string; status?: Capitalize; external_id?: string; + external_ids?: string[]; amount_from?: number; amount_to?: number; currency_code?: string; diff --git a/src/app/withdrawals/withdrawals.component.html b/src/app/withdrawals/withdrawals.component.html index f92f189fd..f4d259895 100644 --- a/src/app/withdrawals/withdrawals.component.html +++ b/src/app/withdrawals/withdrawals.component.html @@ -5,6 +5,8 @@ + + Status @@ -17,7 +19,6 @@ } - diff --git a/src/app/withdrawals/withdrawals.component.ts b/src/app/withdrawals/withdrawals.component.ts index f2bba9acd..371ad1481 100644 --- a/src/app/withdrawals/withdrawals.component.ts +++ b/src/app/withdrawals/withdrawals.component.ts @@ -45,6 +45,7 @@ interface WithdrawalsForm { errorMessage: WithdrawalParams['error_message']; providerId: WithdrawalParams['withdrawal_provider_id']; terminalId: WithdrawalParams['withdrawal_terminal_id']; + externalIds: WithdrawalParams['external_ids']; } @Component({ @@ -73,6 +74,7 @@ export class WithdrawalsComponent implements OnInit { errorMessage: null, providerId: null, terminalId: null, + externalIds: null, }); active$ = getValueChanges(this.filtersForm).pipe( map((v) => countChanged(this.initFilters, v, { dateRange: isEqualDateRange })), @@ -121,13 +123,14 @@ export class WithdrawalsComponent implements OnInit { private initFilters = this.filtersForm.value; ngOnInit() { - this.filtersForm.patchValue(Object.assign({}, this.qp.params)); + this.filtersForm.patchValue(Object.assign({}, this.qp.params as never)); getValueChanges(this.filtersForm) .pipe(debounceTimeWithFirst(this.debounceTimeMs), takeUntilDestroyed(this.destroyRef)) .subscribe(() => this.update()); } update(options?: UpdateOptions) { + const value = this.filtersForm.value as never as WithdrawalsForm; const { dateRange, merchant, @@ -138,8 +141,9 @@ export class WithdrawalsComponent implements OnInit { errorMessage, providerId, terminalId, - } = this.filtersForm.value; - void this.qp.set(clean(this.filtersForm.value)); + externalIds, + } = value; + void this.qp.set(clean(value)); const params = clean({ party_id: merchant, from_time: dateRange?.start && getNoTimeZoneIsoString(dateRange?.start), @@ -152,6 +156,7 @@ export class WithdrawalsComponent implements OnInit { error_message: errorMessage, withdrawal_terminal_id: terminalId, withdrawal_provider_id: providerId, + external_ids: externalIds, }); this.fetchWithdrawalsService.load(params, options); } From add70016b2fbed06d964eef780a99c17e6499dee Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Fri, 6 Mar 2026 02:22:21 +0600 Subject: [PATCH 5/6] add provider and terminal exts --- src/app/payments/payments.component.ts | 47 ++++++++++++++++++- ...domain-metadata-form-extensions.service.ts | 2 +- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/app/payments/payments.component.ts b/src/app/payments/payments.component.ts index 98deb1bc8..ef584953a 100644 --- a/src/app/payments/payments.component.ts +++ b/src/app/payments/payments.component.ts @@ -2,7 +2,7 @@ import { endOfDay } from 'date-fns'; import { uniq } from 'lodash-es'; import isEqual from 'lodash-es/isEqual'; import { BehaviorSubject, merge, of } from 'rxjs'; -import { distinctUntilChanged, map, shareReplay, startWith } from 'rxjs/operators'; +import { distinctUntilChanged, map, shareReplay, startWith, switchMap } from 'rxjs/operators'; import { CommonModule } from '@angular/common'; import { Component, DestroyRef, OnInit, inject } from '@angular/core'; @@ -11,6 +11,8 @@ import { FormsModule, NonNullableFormBuilder, ReactiveFormsModule } from '@angul import { MatBadgeModule } from '@angular/material/badge'; import { MatButtonModule } from '@angular/material/button'; +import { metadata$ } from '@vality/domain-proto'; +import { DomainObject } from '@vality/domain-proto/domain'; import { StatPayment } from '@vality/magista-proto/magista'; import { DateRange, @@ -39,7 +41,10 @@ import { FailMachinesDialogComponent, Type } from '~/components/fail-machines-di import { MerchantFieldModule } from '~/components/merchant-field/merchant-field.module'; import { PageLayoutModule } from '~/components/page-layout'; import { ShopFieldModule } from '~/components/shop-field'; -import { MagistaThriftFormComponent } from '~/components/thrift-api-crud'; +import { + DomainMetadataFormExtensionsService, + MagistaThriftFormComponent, +} from '~/components/thrift-api-crud'; import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../tokens'; @@ -84,6 +89,8 @@ export class PaymentsComponent implements OnInit { private dateRangeDays = inject(DATE_RANGE_DAYS); private dr = inject(DestroyRef); private debounceTimeMs = inject(DEBOUNCE_TIME_MS); + private domainMetadataFormExtensionsService = inject(DomainMetadataFormExtensionsService); + isLoading$ = this.fetchPaymentsService.isLoading$; payments$ = this.fetchPaymentsService.result$; hasMore$ = this.fetchPaymentsService.hasMore$; @@ -122,6 +129,16 @@ export class PaymentsComponent implements OnInit { ), extension: () => of({ hidden: true }), }, + this.createDomainObjectsExtension( + (data) => of(data.field?.name === 'payment_terminal_id'), + 'TerminalObject', + 'terminal', + ), + this.createDomainObjectsExtension( + (data) => of(data.field?.name === 'payment_provider_id'), + 'ProviderObject', + 'provider', + ), ]; active$ = getValueChanges(this.filtersForm).pipe( map((filters) => @@ -230,4 +247,30 @@ export class PaymentsComponent implements OnInit { createInvoiceTemplate() { this.dialogService.open(CreateInvoiceTemplateDialogComponent); } + + private createDomainObjectsExtension( + determinant: ThriftFormExtension['determinant'], + objectType: string, + objectKey: keyof DomainObject, + convert = (v: unknown) => String(v), + ): ThriftFormExtension { + return { + determinant, + extension: (...args) => + metadata$.pipe( + switchMap((metadata) => + this.domainMetadataFormExtensionsService + .createDomainObjectsOptionsByType(metadata, objectType, objectKey)[0] + .extension(...args), + ), + map((extension) => ({ + ...extension, + options: extension.options?.map((o) => ({ + ...o, + value: convert(o.value), + })), + })), + ), + }; + } } diff --git a/src/components/thrift-api-crud/domain/services/domain-metadata-form-extensions/domain-metadata-form-extensions.service.ts b/src/components/thrift-api-crud/domain/services/domain-metadata-form-extensions/domain-metadata-form-extensions.service.ts index ac78b6d8a..14f6ccd35 100644 --- a/src/components/thrift-api-crud/domain/services/domain-metadata-form-extensions/domain-metadata-form-extensions.service.ts +++ b/src/components/thrift-api-crud/domain/services/domain-metadata-form-extensions/domain-metadata-form-extensions.service.ts @@ -147,7 +147,7 @@ export class DomainMetadataFormExtensionsService { ); } - private createDomainObjectsOptionsByType( + createDomainObjectsOptionsByType( metadata: ThriftAstMetadata[], objectType: string, objectKey: keyof DomainObject, From 37aca672109ddd78c6c7899c9fefbddf07adfc2a Mon Sep 17 00:00:00 2001 From: Rinat Arsaev <11846445+A77AY@users.noreply.github.com> Date: Fri, 6 Mar 2026 02:26:02 +0600 Subject: [PATCH 6/6] upd search withdrawals --- src/app/withdrawals/withdrawals.component.html | 12 ++++++++++-- src/app/withdrawals/withdrawals.module.ts | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/app/withdrawals/withdrawals.component.html b/src/app/withdrawals/withdrawals.component.html index f4d259895..8e21b286b 100644 --- a/src/app/withdrawals/withdrawals.component.html +++ b/src/app/withdrawals/withdrawals.component.html @@ -22,8 +22,16 @@ - - + + diff --git a/src/app/withdrawals/withdrawals.module.ts b/src/app/withdrawals/withdrawals.module.ts index 81eeec073..023180a60 100644 --- a/src/app/withdrawals/withdrawals.module.ts +++ b/src/app/withdrawals/withdrawals.module.ts @@ -26,6 +26,7 @@ import { ThriftFormModule, ThriftPipesModule } from '@vality/ng-thrift'; import { FistfulThriftFormComponent } from '~/components/fistful-thrift-form'; import { MerchantFieldModule } from '~/components/merchant-field'; import { PageLayoutModule } from '~/components/page-layout'; +import { DomainObjectFieldComponent } from '~/components/thrift-api-crud'; import { WalletFieldModule } from '~/components/wallet-field'; import { CreateAdjustmentDialogComponent } from './components/create-adjustment-dialog/create-adjustment-dialog.component'; @@ -61,6 +62,7 @@ import { WithdrawalsComponent } from './withdrawals.component'; FistfulThriftFormComponent, AutocompleteFieldModule, WalletFieldModule, + DomainObjectFieldComponent, ], declarations: [WithdrawalsComponent, CreateAdjustmentDialogComponent], })