Skip to content

Commit

Permalink
portalicious: retry transfers
Browse files Browse the repository at this point in the history
AB#31728
  • Loading branch information
aberonni committed Dec 13, 2024
1 parent 1bb97db commit c83c6c1
Show file tree
Hide file tree
Showing 13 changed files with 276 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
PaginateQuery,
PaginateQueryService,
} from '~/services/paginate-query.service';
import { ToastService } from '~/services/toast.service';
import { Locale } from '~/utils/locale';

export enum QueryTableColumnType {
Expand Down Expand Up @@ -111,13 +112,15 @@ export type QueryTableSelectionEvent<TData> = { selectAll: true } | TData[];
QueryTableGlobalSearchComponent,
QueryTableColumnManagementComponent,
],
providers: [ToastService],
templateUrl: './query-table.component.html',
styles: ``,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class QueryTableComponent<TData extends { id: PropertyKey }, TContext> {
locale = inject<Locale>(LOCALE_ID);
paginateQueryService = inject(PaginateQueryService);
toastService = inject(ToastService);

items = input.required<TData[]>();
isPending = input.required<boolean>();
Expand All @@ -135,7 +138,6 @@ export class QueryTableComponent<TData extends { id: PropertyKey }, TContext> {
enableColumnManagement = input<boolean>(false);
readonly onUpdateContextMenuItem = output<TData>();
readonly onUpdatePaginateQuery = output<PaginateQuery>();
readonly onUpdateSelection = output<QueryTableSelectionEvent<TData>>();

@ViewChild('table') table: Table;
@ViewChild('contextMenu') contextMenu: Menu;
Expand Down Expand Up @@ -349,10 +351,11 @@ export class QueryTableComponent<TData extends { id: PropertyKey }, TContext> {

selectedItems = model<TData[]>([]);
selectAll = model<boolean>(false);
tableSelection = signal<QueryTableSelectionEvent<TData>>([]);

onSelectionChange(items: TData[]) {
this.selectedItems.set(items);
this.onUpdateSelection.emit(items);
this.tableSelection.set(items);
}

onSelectAllChange(event: TableSelectAllChangeEvent) {
Expand All @@ -362,9 +365,9 @@ export class QueryTableComponent<TData extends { id: PropertyKey }, TContext> {
this.selectAll.set(checked);

if (checked) {
this.onUpdateSelection.emit({ selectAll: true });
this.tableSelection.set({ selectAll: true });
} else {
this.onUpdateSelection.emit([]);
this.tableSelection.set([]);
}
}

Expand All @@ -377,7 +380,58 @@ export class QueryTableComponent<TData extends { id: PropertyKey }, TContext> {
resetSelection() {
this.selectedItems.set([]);
this.selectAll.set(false);
this.onUpdateSelection.emit([]);
this.tableSelection.set([]);
}

public getActionData({
fieldForFilter,
currentPaginateQuery,
noSelectionToastMessage,
triggeredFromContextMenu = false,
contextMenuItem,
}: {
fieldForFilter: keyof TData & string;
noSelectionToastMessage: string;
currentPaginateQuery?: PaginateQuery;
triggeredFromContextMenu?: boolean;
contextMenuItem?: TData;
}) {
let selection = this.tableSelection();

if ('selectAll' in selection && !this.serverSideFiltering()) {
const filteredValue = this.table.filteredValue;

if (!filteredValue) {
this.toastService.showGenericError();
return;
}

selection = [...(filteredValue as TData[])];
}

if (Array.isArray(selection) && selection.length === 0) {
if (triggeredFromContextMenu) {
if (!contextMenuItem) {
this.toastService.showGenericError();
return;
}
selection = [contextMenuItem];
} else {
this.toastService.showToast({
severity: 'error',
detail: noSelectionToastMessage,
});
return;
}
}

return this.paginateQueryService.selectionEventToActionData({
selection,
fieldForFilter,
totalCount: this.totalRecords(),
currentPaginateQuery,
previewItemForSelectAll: this.items()[0],
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
[serverSideTotalRecords]="totalRegistrations()"
(onUpdatePaginateQuery)="paginateQuery.set($event)"
[enableSelection]="true"
(onUpdateSelection)="tableSelection.set($event)"
[contextMenuItems]="contextMenuItems()"
(onUpdateContextMenuItem)="contextMenuRegistration.set($event)"
[enableColumnManagement]="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
QueryTableColumn,
QueryTableColumnType,
QueryTableComponent,
QueryTableSelectionEvent,
} from '~/components/query-table/query-table.component';
import { ProjectApiService } from '~/domains/project/project.api.service';
import { RegistrationApiService } from '~/domains/registration/registration.api.service';
Expand All @@ -28,11 +27,7 @@ import {
registrationLink,
} from '~/domains/registration/registration.helper';
import { Registration } from '~/domains/registration/registration.model';
import {
PaginateQuery,
PaginateQueryService,
} from '~/services/paginate-query.service';
import { ToastService } from '~/services/toast.service';
import { PaginateQuery } from '~/services/paginate-query.service';
import { TranslatableStringService } from '~/services/translatable-string.service';

@Component({
Expand All @@ -41,7 +36,6 @@ import { TranslatableStringService } from '~/services/translatable-string.servic
imports: [QueryTableComponent],
templateUrl: './registrations-table.component.html',
styles: ``,
providers: [ToastService],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class RegistrationsTableComponent {
Expand All @@ -51,10 +45,8 @@ export class RegistrationsTableComponent {
overrideFilters = input<Exclude<PaginateQuery['filter'], undefined>>({});
showSelectionInHeader = input<boolean>(false);

private paginateQueryService = inject(PaginateQueryService);
private projectApiService = inject(ProjectApiService);
private registrationApiService = inject(RegistrationApiService);
private toastService = inject(ToastService);
private translatableStringService = inject(TranslatableStringService);

PermissionEnum = PermissionEnum;
Expand All @@ -64,7 +56,6 @@ export class RegistrationsTableComponent {

protected RegistrationStatusEnum = RegistrationStatusEnum;
protected paginateQuery = signal<PaginateQuery | undefined>(undefined);
protected tableSelection = signal<QueryTableSelectionEvent<Registration>>([]);
public contextMenuRegistration = signal<Registration | undefined>(undefined);

private registrationsPaginateQuery = computed<PaginateQuery>(() => {
Expand Down Expand Up @@ -168,31 +159,12 @@ export class RegistrationsTableComponent {
}: {
triggeredFromContextMenu?: boolean;
} = {}) {
let selection = this.tableSelection();

if (Array.isArray(selection) && selection.length === 0) {
if (triggeredFromContextMenu) {
const contextMenuRegistration = this.contextMenuRegistration();
if (!contextMenuRegistration) {
this.toastService.showGenericError();
return;
}
selection = [contextMenuRegistration];
} else {
this.toastService.showToast({
severity: 'error',
detail: $localize`:@@no-registrations-selected:Select one or more registrations and try again.`,
});
return;
}
}

return this.paginateQueryService.selectionEventToActionData({
selection,
return this.table.getActionData({
triggeredFromContextMenu,
contextMenuItem: this.contextMenuRegistration(),
fieldForFilter: 'referenceId',
totalCount: this.totalRegistrations(),
currentPaginateQuery: this.registrationsPaginateQuery(),
previewItemForSelectAll: this.registrations()[0],
noSelectionToastMessage: $localize`:@@no-registrations-selected:Select one or more registrations and try again.`,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HttpParamsOptions } from '@angular/common/http';
import { Injectable, Signal } from '@angular/core';

import { ExportType } from '@121-service/src/metrics/enum/export-type.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';

import { DomainApiService } from '~/domains/domain-api.service';
import {
Expand Down Expand Up @@ -49,12 +50,22 @@ export class MetricApiService extends DomainApiService {
projectId: Signal<number>;
payment: Signal<number>;
}) {
return this.generateQueryOptions<{ data: PaymentMetricDetails[] }>({
return this.generateQueryOptions<
{ data: PaymentMetricDetails[] },
PaymentMetricDetails[]
>({
path: [...BASE_ENDPOINT(projectId), 'export-list', ExportType.payment],
params: {
minPayment: payment,
maxPayment: payment,
},
processResponse: (response) => {
// TODO: AB#32158 - Should we filter out deleted transactions here?
return response.data.filter(
(transaction) =>
transaction.registrationStatus !== RegistrationStatusEnum.deleted,
);
},
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { FinancialServiceProviders } from '@121-service/src/financial-service-providers/enum/financial-service-provider-name.enum';
import { ProgramStats } from '@121-service/src/metrics/dto/program-stats.dto';
import { TransactionStatusEnum } from '@121-service/src/payments/transactions/enums/transaction-status.enum';
import { RegistrationStatusEnum } from '@121-service/src/registration/enum/registration-status.enum';

import { Dto } from '~/utils/dto-type';

Expand All @@ -23,4 +24,5 @@ export interface PaymentMetricDetails {
amount: number;
financialserviceprovider: FinancialServiceProviders;
fullName: string;
registrationStatus: RegistrationStatusEnum;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Injectable, Signal } from '@angular/core';

import { CreatePaymentDto } from '@121-service/src/payments/dto/create-payment.dto';
import { FspInstructions } from '@121-service/src/payments/dto/fsp-instructions.dto';
import { RetryPaymentDto } from '@121-service/src/payments/dto/retry-payment.dto';
import { BulkActionResultPaymentDto } from '@121-service/src/registration/dto/bulk-action-result.dto';

import { DomainApiService } from '~/domains/domain-api.service';
Expand Down Expand Up @@ -72,6 +73,31 @@ export class PaymentApiService extends DomainApiService {
});
}

retryFailedTransfers({
projectId,
paymentId,
referenceIds,
}: {
projectId: Signal<number>;
paymentId: number;
referenceIds: string[];
}) {
const body: Dto<RetryPaymentDto> = {
payment: paymentId,
referenceIds: {
referenceIds,
},
};

return this.httpWrapperService.perform121ServiceRequest<
Dto<BulkActionResultPaymentDto>
>({
method: 'PATCH',
endpoint: this.pathToQueryKey([...BASE_ENDPOINT(projectId)]).join('/'),
body,
});
}

exportFspInstructions({
projectId,
paymentId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<app-confirmation-dialog
#retryTransfersConfirmationDialog
header="Retry failed transfers"
i18n-header="@@retry-failed-transfers"
headerIcon="pi pi-refresh"
proceedLabel="Retry transfers"
i18n-proceedLabel
[mutation]="retryFailedTransfersMutation"
[mutationData]="referenceIdsForRetryTransfers()"
>
<p i18n>
You are about to retry
{{ referenceIdsForRetryTransfers().length }} payment(s). The transfer status
will change to Pending until received by the registration.
</p>
</app-confirmation-dialog>
Loading

0 comments on commit c83c6c1

Please sign in to comment.