mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
Revert old payments page (#376)
This commit is contained in:
parent
06b4a709d8
commit
44820f94e3
@ -115,6 +115,11 @@ export class AppComponent {
|
|||||||
url: '/payments',
|
url: '/payments',
|
||||||
services: PAYMENTS_ROUTING_CONFIG.services,
|
services: PAYMENTS_ROUTING_CONFIG.services,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Old Payments',
|
||||||
|
url: '/old-payments',
|
||||||
|
services: PAYMENTS_ROUTING_CONFIG.services,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Payouts',
|
label: 'Payouts',
|
||||||
url: '/payouts',
|
url: '/payouts',
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
<v-dialog
|
||||||
|
[progress]="progress$ | async"
|
||||||
|
title="Create payment adjustment ({{ dialogData.payments.length }})"
|
||||||
|
>
|
||||||
|
<cc-metadata-form
|
||||||
|
[extensions]="extensions$ | async"
|
||||||
|
[formControl]="control"
|
||||||
|
[metadata]="metadata$ | async"
|
||||||
|
namespace="payment_processing"
|
||||||
|
type="InvoicePaymentAdjustmentParams"
|
||||||
|
></cc-metadata-form>
|
||||||
|
<v-dialog-actions>
|
||||||
|
<button
|
||||||
|
*ngIf="this.errors.length"
|
||||||
|
[disabled]="control.invalid || !!(progress$ | async)"
|
||||||
|
mat-raised-button
|
||||||
|
(click)="closeAndSelectWithAnError()"
|
||||||
|
>
|
||||||
|
Close and select with an error
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
[disabled]="control.invalid || !!(progress$ | async)"
|
||||||
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
(click)="create()"
|
||||||
|
>
|
||||||
|
{{ this.errors.length ? 'Repeat for ' + this.errors.length : 'Create' }}
|
||||||
|
</button>
|
||||||
|
</v-dialog-actions>
|
||||||
|
</v-dialog>
|
@ -0,0 +1,75 @@
|
|||||||
|
import { Component, DestroyRef } from '@angular/core';
|
||||||
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { InvoicePaymentAdjustmentParams } from '@vality/domain-proto/payment_processing';
|
||||||
|
import { StatPayment } from '@vality/magista-proto/magista';
|
||||||
|
import {
|
||||||
|
DialogSuperclass,
|
||||||
|
NotifyLogService,
|
||||||
|
forkJoinToResult,
|
||||||
|
splitResultsErrors,
|
||||||
|
ForkJoinErrorResult,
|
||||||
|
} from '@vality/ng-core';
|
||||||
|
import { BehaviorSubject, from } from 'rxjs';
|
||||||
|
|
||||||
|
import { DomainMetadataFormExtensionsService } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
import { InvoicingService } from '../../../../api/payment-processing';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cc-create-payment-adjustment',
|
||||||
|
templateUrl: './create-payment-adjustment.component.html',
|
||||||
|
})
|
||||||
|
export class CreatePaymentAdjustmentComponent extends DialogSuperclass<
|
||||||
|
CreatePaymentAdjustmentComponent,
|
||||||
|
{ payments: StatPayment[] },
|
||||||
|
{ errors?: ForkJoinErrorResult<StatPayment>[] }
|
||||||
|
> {
|
||||||
|
control = new FormControl<InvoicePaymentAdjustmentParams>(null);
|
||||||
|
progress$ = new BehaviorSubject(0);
|
||||||
|
metadata$ = from(import('@vality/domain-proto/metadata.json').then((m) => m.default));
|
||||||
|
extensions$ = this.domainMetadataFormExtensionsService.extensions$;
|
||||||
|
errors: ForkJoinErrorResult<StatPayment>[] = [];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private invoicingService: InvoicingService,
|
||||||
|
private log: NotifyLogService,
|
||||||
|
private domainMetadataFormExtensionsService: DomainMetadataFormExtensionsService,
|
||||||
|
private destroyRef: DestroyRef,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
const payments = this.errors.length
|
||||||
|
? this.errors.map(({ data }) => data)
|
||||||
|
: this.dialogData.payments;
|
||||||
|
this.errors = [];
|
||||||
|
forkJoinToResult(
|
||||||
|
payments.map((p) =>
|
||||||
|
this.invoicingService.CreatePaymentAdjustment(
|
||||||
|
p.invoice_id,
|
||||||
|
p.id,
|
||||||
|
this.control.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
this.progress$,
|
||||||
|
payments,
|
||||||
|
)
|
||||||
|
.pipe(takeUntilDestroyed(this.destroyRef))
|
||||||
|
.subscribe((res) => {
|
||||||
|
const [result, errors] = splitResultsErrors(res);
|
||||||
|
if (errors.length) {
|
||||||
|
this.errors = errors;
|
||||||
|
this.log.error(this.errors.map((e) => e.error));
|
||||||
|
} else {
|
||||||
|
this.log.success(`${result.length} created successfully`);
|
||||||
|
this.closeWithSuccess();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
closeAndSelectWithAnError() {
|
||||||
|
this.closeWithError({ errors: this.errors });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<v-table
|
||||||
|
[columns]="columns"
|
||||||
|
[data]="data"
|
||||||
|
[hasMore]="hasMore"
|
||||||
|
[progress]="isLoading"
|
||||||
|
[rowSelected]="selected"
|
||||||
|
rowSelectable
|
||||||
|
(more)="more.emit()"
|
||||||
|
(rowSelectedChange)="selectedChange.emit($event)"
|
||||||
|
(update)="update.emit($event)"
|
||||||
|
>
|
||||||
|
<v-table-actions>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</v-table-actions>
|
||||||
|
</v-table>
|
@ -0,0 +1,104 @@
|
|||||||
|
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { InvoicePaymentStatus } from '@vality/domain-proto/domain';
|
||||||
|
import { StatPayment } from '@vality/magista-proto/magista';
|
||||||
|
import { Column, TagColumn, LoadOptions, createOperationColumn } from '@vality/ng-core';
|
||||||
|
import { getUnionKey } from '@vality/ng-thrift';
|
||||||
|
import startCase from 'lodash-es/startCase';
|
||||||
|
|
||||||
|
import { AmountCurrencyService } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
import { createFailureColumn, createPartyColumn, createShopColumn } from '../../../../shared';
|
||||||
|
import { createProviderColumn } from '../../../../shared/utils/table/create-provider-column';
|
||||||
|
import { createTerminalColumn } from '../../../../shared/utils/table/create-terminal-column';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'cc-payments-table',
|
||||||
|
templateUrl: './payments-table.component.html',
|
||||||
|
})
|
||||||
|
export class PaymentsTableComponent {
|
||||||
|
@Input() data!: StatPayment[];
|
||||||
|
@Input() isLoading?: boolean | null;
|
||||||
|
@Input() hasMore?: boolean | null;
|
||||||
|
@Input() selected?: StatPayment[];
|
||||||
|
|
||||||
|
@Output() selectedChange = new EventEmitter<StatPayment[]>();
|
||||||
|
@Output() update = new EventEmitter<LoadOptions>();
|
||||||
|
@Output() more = new EventEmitter<void>();
|
||||||
|
|
||||||
|
columns: Column<StatPayment>[] = [
|
||||||
|
{ field: 'id', click: (d) => this.toDetails(d), pinned: 'left' },
|
||||||
|
{ field: 'invoice_id', pinned: 'left' },
|
||||||
|
{
|
||||||
|
field: 'amount',
|
||||||
|
type: 'currency',
|
||||||
|
formatter: (data) =>
|
||||||
|
this.amountCurrencyService.toMajor(data.amount, data.currency_symbolic_code),
|
||||||
|
typeParameters: {
|
||||||
|
currencyCode: 'currency_symbolic_code',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'fee',
|
||||||
|
type: 'currency',
|
||||||
|
formatter: (data) =>
|
||||||
|
this.amountCurrencyService.toMajor(data.fee, data.currency_symbolic_code),
|
||||||
|
typeParameters: {
|
||||||
|
currencyCode: 'currency_symbolic_code',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
type: 'tag',
|
||||||
|
formatter: (data) => getUnionKey(data.status),
|
||||||
|
typeParameters: {
|
||||||
|
label: (data) => startCase(getUnionKey(data.status)),
|
||||||
|
tags: {
|
||||||
|
captured: { color: 'success' },
|
||||||
|
refunded: { color: 'success' },
|
||||||
|
charged_back: { color: 'success' },
|
||||||
|
pending: { color: 'pending' },
|
||||||
|
processed: { color: 'pending' },
|
||||||
|
failed: { color: 'warn' },
|
||||||
|
cancelled: { color: 'neutral' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as TagColumn<StatPayment, keyof InvoicePaymentStatus>,
|
||||||
|
{ field: 'created_at', type: 'datetime' },
|
||||||
|
createPartyColumn('owner_id'),
|
||||||
|
createShopColumn('shop_id', (d) => d.owner_id),
|
||||||
|
'domain_revision',
|
||||||
|
createTerminalColumn((d) => d.terminal_id.id),
|
||||||
|
createProviderColumn((d) => d.provider_id.id),
|
||||||
|
'external_id',
|
||||||
|
createFailureColumn<StatPayment>(
|
||||||
|
(d) => d.status?.failed?.failure?.failure,
|
||||||
|
(d) =>
|
||||||
|
getUnionKey(d.status?.failed?.failure) === 'failure'
|
||||||
|
? ''
|
||||||
|
: startCase(getUnionKey(d.status?.failed?.failure)),
|
||||||
|
),
|
||||||
|
createOperationColumn<StatPayment>([
|
||||||
|
{
|
||||||
|
label: 'Details',
|
||||||
|
click: (data) => this.toDetails(data),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private amountCurrencyService: AmountCurrencyService,
|
||||||
|
private router: Router,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private toDetails(data: StatPayment) {
|
||||||
|
return void this.router.navigate([
|
||||||
|
'party',
|
||||||
|
data.owner_id,
|
||||||
|
'invoice',
|
||||||
|
data.invoice_id,
|
||||||
|
'payment',
|
||||||
|
data.id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
1
src/app/sections/old-payments/index.ts
Normal file
1
src/app/sections/old-payments/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './payments.module';
|
22
src/app/sections/old-payments/payments-routing.module.ts
Normal file
22
src/app/sections/old-payments/payments-routing.module.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
import { PaymentsComponent } from './payments.component';
|
||||||
|
import { ROUTING_CONFIG } from './routing-config';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild([
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
component: PaymentsComponent,
|
||||||
|
canActivate: [AppAuthGuardService],
|
||||||
|
data: ROUTING_CONFIG,
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class PaymentsRoutingModule {}
|
65
src/app/sections/old-payments/payments.component.html
Normal file
65
src/app/sections/old-payments/payments.component.html
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<cc-page-layout title="Old Payments">
|
||||||
|
<cc-page-layout-actions>
|
||||||
|
<v-more-filters-button [filters]="filters"></v-more-filters-button>
|
||||||
|
</cc-page-layout-actions>
|
||||||
|
<v-filters
|
||||||
|
#filters
|
||||||
|
[active]="active$ | async"
|
||||||
|
merge
|
||||||
|
(clear)="filtersForm.reset(); otherFiltersControl.reset()"
|
||||||
|
>
|
||||||
|
<ng-template [formGroup]="filtersForm" vMainFilters>
|
||||||
|
<v-date-range-field formControlName="dateRange"></v-date-range-field>
|
||||||
|
<v-list-field
|
||||||
|
focusedHint="invoice_1, invoice_2.payment_2"
|
||||||
|
formControlName="invoice_ids"
|
||||||
|
label="Invoice and Payment Ids"
|
||||||
|
></v-list-field>
|
||||||
|
<v-input-field formControlName="external_id" label="External Id"></v-input-field>
|
||||||
|
<cc-merchant-field formControlName="party_id"></cc-merchant-field>
|
||||||
|
<cc-shop-field
|
||||||
|
[partyId]="filtersForm.value.party_id"
|
||||||
|
formControlName="shop_ids"
|
||||||
|
multiple
|
||||||
|
></cc-shop-field>
|
||||||
|
<v-input-field formControlName="payment_first6" label="Card BIN"></v-input-field>
|
||||||
|
<v-input-field formControlName="payment_last4" label="Card PAN"></v-input-field>
|
||||||
|
<v-input-field formControlName="payment_rrn" label="Payment RRN"></v-input-field>
|
||||||
|
<v-input-field formControlName="payment_email" label="Payer email"></v-input-field>
|
||||||
|
<v-input-field formControlName="error_message" label="Error message"></v-input-field>
|
||||||
|
</ng-template>
|
||||||
|
<ng-template vOtherFilters>
|
||||||
|
<cc-magista-thrift-form
|
||||||
|
[extensions]="extensions"
|
||||||
|
[formControl]="otherFiltersControl"
|
||||||
|
noToolbar
|
||||||
|
type="PaymentSearchQuery"
|
||||||
|
></cc-magista-thrift-form>
|
||||||
|
</ng-template>
|
||||||
|
</v-filters>
|
||||||
|
<cc-payments-table
|
||||||
|
[data]="(payments$ | async) || []"
|
||||||
|
[hasMore]="hasMore$ | async"
|
||||||
|
[isLoading]="isLoading$ | async"
|
||||||
|
[selected]="selected$ | async"
|
||||||
|
(more)="more()"
|
||||||
|
(selectedChange)="selected$.next($event)"
|
||||||
|
(update)="reload($event ?? {})"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
[disabled]="!(selected$ | async)?.length"
|
||||||
|
mat-raised-button
|
||||||
|
(click)="failMachines()"
|
||||||
|
>
|
||||||
|
Fail machines
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
[disabled]="!(selected$ | async)?.length"
|
||||||
|
color="primary"
|
||||||
|
mat-raised-button
|
||||||
|
(click)="createPaymentAdjustment()"
|
||||||
|
>
|
||||||
|
Create adjustments
|
||||||
|
</button>
|
||||||
|
</cc-payments-table>
|
||||||
|
</cc-page-layout>
|
187
src/app/sections/old-payments/payments.component.ts
Normal file
187
src/app/sections/old-payments/payments.component.ts
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
import { Component, OnInit, Inject, DestroyRef } from '@angular/core';
|
||||||
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
import { NonNullableFormBuilder } from '@angular/forms';
|
||||||
|
import { StatPayment } from '@vality/magista-proto/magista';
|
||||||
|
import {
|
||||||
|
DialogService,
|
||||||
|
DialogResponseStatus,
|
||||||
|
LoadOptions,
|
||||||
|
getNoTimeZoneIsoString,
|
||||||
|
clean,
|
||||||
|
DateRange,
|
||||||
|
QueryParamsService,
|
||||||
|
createDateRangeToToday,
|
||||||
|
isEqualDateRange,
|
||||||
|
debounceTimeWithFirst,
|
||||||
|
getValueChanges,
|
||||||
|
countChanged,
|
||||||
|
} from '@vality/ng-core';
|
||||||
|
import { isTypeWithAliases } from '@vality/ng-thrift';
|
||||||
|
import { endOfDay } from 'date-fns';
|
||||||
|
import { uniq } from 'lodash-es';
|
||||||
|
import isEqual from 'lodash-es/isEqual';
|
||||||
|
import { BehaviorSubject, of, merge } from 'rxjs';
|
||||||
|
import { startWith, map, distinctUntilChanged, shareReplay } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { FailMachinesDialogComponent, Type } from '../../shared/components/fail-machines-dialog';
|
||||||
|
import { MetadataFormExtension } from '../../shared/components/metadata-form';
|
||||||
|
import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../../tokens';
|
||||||
|
|
||||||
|
import { CreatePaymentAdjustmentComponent } from './components/create-payment-adjustment/create-payment-adjustment.component';
|
||||||
|
import { FetchPaymentsService } from './services/fetch-payments.service';
|
||||||
|
|
||||||
|
interface Filters {
|
||||||
|
filters: PaymentsComponent['filtersForm']['value'];
|
||||||
|
otherFilters: PaymentsComponent['otherFiltersControl']['value'];
|
||||||
|
dateRange: DateRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: 'payments.component.html',
|
||||||
|
})
|
||||||
|
export class PaymentsComponent implements OnInit {
|
||||||
|
isLoading$ = this.fetchPaymentsService.isLoading$;
|
||||||
|
payments$ = this.fetchPaymentsService.result$;
|
||||||
|
hasMore$ = this.fetchPaymentsService.hasMore$;
|
||||||
|
selected$ = new BehaviorSubject<StatPayment[]>([]);
|
||||||
|
filtersForm = this.fb.group({
|
||||||
|
dateRange: createDateRangeToToday(this.dateRangeDays),
|
||||||
|
invoice_ids: [undefined as string[]],
|
||||||
|
party_id: undefined as string,
|
||||||
|
shop_ids: [undefined as string[]],
|
||||||
|
payment_first6: undefined as string,
|
||||||
|
payment_last4: undefined as string,
|
||||||
|
payment_rrn: undefined as string,
|
||||||
|
payment_email: undefined as string,
|
||||||
|
error_message: undefined as string,
|
||||||
|
external_id: undefined as string,
|
||||||
|
});
|
||||||
|
otherFiltersControl = this.fb.control({
|
||||||
|
common_search_query_params: {},
|
||||||
|
payment_params: {},
|
||||||
|
});
|
||||||
|
extensions: MetadataFormExtension[] = [
|
||||||
|
{
|
||||||
|
determinant: (data) =>
|
||||||
|
of(
|
||||||
|
isTypeWithAliases(data, 'CommonSearchQueryParams', 'magista') ||
|
||||||
|
[
|
||||||
|
'invoice_ids',
|
||||||
|
'payment_email',
|
||||||
|
'payment_first6',
|
||||||
|
'payment_last4',
|
||||||
|
'payment_rrn',
|
||||||
|
'error_message',
|
||||||
|
'external_id',
|
||||||
|
].includes(data?.field?.name),
|
||||||
|
),
|
||||||
|
extension: () => of({ hidden: true }),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
active$ = getValueChanges(this.filtersForm).pipe(
|
||||||
|
map((filters) =>
|
||||||
|
countChanged(this.initFiltersValue, filters, { dateRange: isEqualDateRange }),
|
||||||
|
),
|
||||||
|
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||||
|
);
|
||||||
|
|
||||||
|
private initFiltersValue = this.filtersForm.value;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private qp: QueryParamsService<Filters>,
|
||||||
|
private fetchPaymentsService: FetchPaymentsService,
|
||||||
|
private dialogService: DialogService,
|
||||||
|
private fb: NonNullableFormBuilder,
|
||||||
|
@Inject(DATE_RANGE_DAYS) private dateRangeDays: number,
|
||||||
|
private dr: DestroyRef,
|
||||||
|
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.filtersForm.patchValue(
|
||||||
|
Object.assign(
|
||||||
|
{},
|
||||||
|
this.qp.params.filters,
|
||||||
|
clean({ dateRange: this.qp.params.dateRange }),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
this.otherFiltersControl.patchValue(Object.assign({}, this.qp.params.otherFilters));
|
||||||
|
merge(this.filtersForm.valueChanges, this.otherFiltersControl.valueChanges)
|
||||||
|
.pipe(
|
||||||
|
startWith(null),
|
||||||
|
debounceTimeWithFirst(this.debounceTimeMs),
|
||||||
|
map(() => {
|
||||||
|
const { dateRange, ...filters } = clean(this.filtersForm.value);
|
||||||
|
const otherFilters = clean(this.otherFiltersControl.value);
|
||||||
|
return { filters, dateRange, otherFilters };
|
||||||
|
}),
|
||||||
|
distinctUntilChanged(isEqual),
|
||||||
|
takeUntilDestroyed(this.dr),
|
||||||
|
)
|
||||||
|
.subscribe((filters) => {
|
||||||
|
void this.qp.set(filters);
|
||||||
|
this.load(filters);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
more() {
|
||||||
|
this.fetchPaymentsService.more();
|
||||||
|
}
|
||||||
|
|
||||||
|
load({ filters, otherFilters, dateRange }: Filters, options?: LoadOptions) {
|
||||||
|
const { invoice_ids, party_id, shop_ids, external_id, ...paymentParams } = filters;
|
||||||
|
const searchParams = clean({
|
||||||
|
...otherFilters,
|
||||||
|
common_search_query_params: {
|
||||||
|
...(otherFilters.common_search_query_params || {}),
|
||||||
|
party_id,
|
||||||
|
shop_ids,
|
||||||
|
from_time: getNoTimeZoneIsoString(dateRange.start),
|
||||||
|
to_time: getNoTimeZoneIsoString(endOfDay(dateRange.end)),
|
||||||
|
},
|
||||||
|
payment_params: { ...(otherFilters.payment_params || {}), ...paymentParams },
|
||||||
|
external_id,
|
||||||
|
invoice_ids,
|
||||||
|
});
|
||||||
|
this.fetchPaymentsService.load(searchParams, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
reload(options?: LoadOptions) {
|
||||||
|
this.fetchPaymentsService.reload(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPaymentAdjustment() {
|
||||||
|
this.dialogService
|
||||||
|
.open(CreatePaymentAdjustmentComponent, {
|
||||||
|
payments: this.selected$.value,
|
||||||
|
})
|
||||||
|
.afterClosed()
|
||||||
|
.subscribe((res) => {
|
||||||
|
if (res.status === DialogResponseStatus.Success) {
|
||||||
|
this.reload();
|
||||||
|
this.selected$.next([]);
|
||||||
|
} else if (res.data?.errors?.length) {
|
||||||
|
this.selected$.next(res.data.errors.map(({ data }) => data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
failMachines() {
|
||||||
|
this.dialogService
|
||||||
|
.open(FailMachinesDialogComponent, {
|
||||||
|
ids: uniq(this.selected$.value.map((s) => s.invoice_id)),
|
||||||
|
type: Type.Invoice,
|
||||||
|
})
|
||||||
|
.afterClosed()
|
||||||
|
.subscribe((res) => {
|
||||||
|
if (res.status === DialogResponseStatus.Success) {
|
||||||
|
this.reload();
|
||||||
|
this.selected$.next([]);
|
||||||
|
} else if (res.data?.errors?.length) {
|
||||||
|
this.selected$.next(
|
||||||
|
res.data.errors.map(({ index }) => this.selected$.value[index]),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
46
src/app/sections/old-payments/payments.module.ts
Normal file
46
src/app/sections/old-payments/payments.module.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import {
|
||||||
|
FiltersModule,
|
||||||
|
DateRangeFieldModule,
|
||||||
|
ListFieldModule,
|
||||||
|
TableModule,
|
||||||
|
DialogModule,
|
||||||
|
InputFieldModule,
|
||||||
|
} from '@vality/ng-core';
|
||||||
|
|
||||||
|
import { PageLayoutModule, ShopFieldModule } from '@cc/app/shared';
|
||||||
|
import { MerchantFieldModule } from '@cc/app/shared/components/merchant-field';
|
||||||
|
import { ThriftFormModule } from '@cc/app/shared/components/metadata-form';
|
||||||
|
|
||||||
|
import { MagistaThriftFormComponent } from '../../shared/components/thrift-api-crud';
|
||||||
|
|
||||||
|
import { CreatePaymentAdjustmentComponent } from './components/create-payment-adjustment/create-payment-adjustment.component';
|
||||||
|
import { PaymentsTableComponent } from './components/payments-table/payments-table.component';
|
||||||
|
import { PaymentsRoutingModule } from './payments-routing.module';
|
||||||
|
import { PaymentsComponent } from './payments.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
PaymentsRoutingModule,
|
||||||
|
PageLayoutModule,
|
||||||
|
FiltersModule,
|
||||||
|
DateRangeFieldModule,
|
||||||
|
ListFieldModule,
|
||||||
|
MerchantFieldModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
TableModule,
|
||||||
|
DialogModule,
|
||||||
|
ThriftFormModule,
|
||||||
|
MatButtonModule,
|
||||||
|
ShopFieldModule,
|
||||||
|
InputFieldModule,
|
||||||
|
FormsModule,
|
||||||
|
MagistaThriftFormComponent,
|
||||||
|
],
|
||||||
|
declarations: [PaymentsComponent, CreatePaymentAdjustmentComponent, PaymentsTableComponent],
|
||||||
|
})
|
||||||
|
export class PaymentsModule {}
|
5
src/app/sections/old-payments/routing-config.ts
Normal file
5
src/app/sections/old-payments/routing-config.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Services, RoutingConfig } from '@cc/app/shared/services';
|
||||||
|
|
||||||
|
export const ROUTING_CONFIG: RoutingConfig = {
|
||||||
|
services: [Services.MerchantStatistics],
|
||||||
|
};
|
@ -0,0 +1,67 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { StatPayment, PaymentSearchQuery } from '@vality/magista-proto/magista';
|
||||||
|
import {
|
||||||
|
FetchSuperclass,
|
||||||
|
FetchOptions,
|
||||||
|
FetchResult,
|
||||||
|
NotifyLogService,
|
||||||
|
clean,
|
||||||
|
} from '@vality/ng-core';
|
||||||
|
import isNil from 'lodash-es/isNil';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { map, catchError } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { MerchantStatisticsService } from '@cc/app/api/magista';
|
||||||
|
|
||||||
|
function splitInvoicePaymentId(invoicePaymentId: string) {
|
||||||
|
const [invoiceId, paymentId] = invoicePaymentId.split('.');
|
||||||
|
return { invoiceId, paymentId };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class FetchPaymentsService extends FetchSuperclass<StatPayment, PaymentSearchQuery> {
|
||||||
|
constructor(
|
||||||
|
private merchantStatisticsService: MerchantStatisticsService,
|
||||||
|
private log: NotifyLogService,
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fetch(
|
||||||
|
params: PaymentSearchQuery,
|
||||||
|
{ size, continuationToken }: FetchOptions,
|
||||||
|
): Observable<FetchResult<StatPayment>> {
|
||||||
|
const invoicePaymentIds = (params.invoice_ids || []).map((id) => splitInvoicePaymentId(id));
|
||||||
|
const invoiceIds = [...new Set(invoicePaymentIds.map(({ invoiceId }) => invoiceId))];
|
||||||
|
return this.merchantStatisticsService
|
||||||
|
.SearchPayments({
|
||||||
|
payment_params: {},
|
||||||
|
...params,
|
||||||
|
...clean({ invoice_ids: invoiceIds }),
|
||||||
|
common_search_query_params: Object.assign({}, params.common_search_query_params, {
|
||||||
|
continuation_token: continuationToken,
|
||||||
|
limit: size,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.pipe(
|
||||||
|
map(({ payments, continuation_token }) => ({
|
||||||
|
result: params.invoice_ids?.length
|
||||||
|
? payments.filter((p) =>
|
||||||
|
invoicePaymentIds.some(
|
||||||
|
(id) =>
|
||||||
|
id.invoiceId === p.invoice_id &&
|
||||||
|
(isNil(id.paymentId) || id.paymentId === p.id),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: payments,
|
||||||
|
continuationToken: continuation_token,
|
||||||
|
})),
|
||||||
|
catchError((err) => {
|
||||||
|
this.log.errorOperation(err, 'receive', 'payments');
|
||||||
|
return of({ result: [] });
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -40,6 +40,10 @@ const ROUTES: Routes = [
|
|||||||
path: 'payments',
|
path: 'payments',
|
||||||
loadChildren: () => import('./payments/payments.module').then((m) => m.PaymentsModule),
|
loadChildren: () => import('./payments/payments.module').then((m) => m.PaymentsModule),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'old-payments',
|
||||||
|
loadChildren: () => import('./old-payments/payments.module').then((m) => m.PaymentsModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'deposits',
|
path: 'deposits',
|
||||||
loadChildren: () => import('./deposits/deposits.module').then((m) => m.DepositsModule),
|
loadChildren: () => import('./deposits/deposits.module').then((m) => m.DepositsModule),
|
||||||
|
Loading…
Reference in New Issue
Block a user