mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
IMP-251: Remove payouts page and revert "remove claims payouts" (#383)
This commit is contained in:
parent
3ddefcdfca
commit
5e3c5a5932
16
package-lock.json
generated
16
package-lock.json
generated
@ -21,11 +21,11 @@
|
|||||||
"@angular/router": "18.0.5",
|
"@angular/router": "18.0.5",
|
||||||
"@ngneat/input-mask": "6.0.0",
|
"@ngneat/input-mask": "6.0.0",
|
||||||
"@vality/deanonimus-proto": "2.0.1-2a02d87.0",
|
"@vality/deanonimus-proto": "2.0.1-2a02d87.0",
|
||||||
"@vality/domain-proto": "2.0.1-6051aa9.0",
|
"@vality/domain-proto": "2.0.1-e5d3c83.0",
|
||||||
"@vality/dominator-proto": "1.0.1-41bee97.0",
|
"@vality/dominator-proto": "1.0.1-41bee97.0",
|
||||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||||
"@vality/machinegun-proto": "1.0.0",
|
"@vality/machinegun-proto": "1.0.0",
|
||||||
"@vality/magista-proto": "2.0.2-28d11b9.0",
|
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||||
"@vality/ng-core": "18.2.0",
|
"@vality/ng-core": "18.2.0",
|
||||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||||
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
|
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
|
||||||
@ -6571,9 +6571,9 @@
|
|||||||
"integrity": "sha512-mokuK6w+ExASdDE6+L9bM2SaS0yVPSyBvXavY8rRtNzZgVdmj7KSRiyGmXz41grhS6jcvD8aR85Nj4o7/iogmQ=="
|
"integrity": "sha512-mokuK6w+ExASdDE6+L9bM2SaS0yVPSyBvXavY8rRtNzZgVdmj7KSRiyGmXz41grhS6jcvD8aR85Nj4o7/iogmQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/domain-proto": {
|
"node_modules/@vality/domain-proto": {
|
||||||
"version": "2.0.1-6051aa9.0",
|
"version": "2.0.1-e5d3c83.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/domain-proto/-/domain-proto-2.0.1-6051aa9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/domain-proto/-/domain-proto-2.0.1-e5d3c83.0.tgz",
|
||||||
"integrity": "sha512-QbiCNs316WvQHG/LTpkIhT3FTT6Mv/9vm1dKsEk0vPAQSPCvFZKZ6FKk/wEG9KCKzI1ESIJ1ClKo4n9dt8w3ew=="
|
"integrity": "sha512-G6FpLCyx7kZZIox90PFUe0FsiAzUTtHZ42gqK7pTyHn2mOzampUuQyyn9MwPkQv6atGLXXiSzEY+qmZIWWkvHQ=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/dominator-proto": {
|
"node_modules/@vality/dominator-proto": {
|
||||||
"version": "1.0.1-41bee97.0",
|
"version": "1.0.1-41bee97.0",
|
||||||
@ -6610,9 +6610,9 @@
|
|||||||
"integrity": "sha512-HSK9WXE+cT+1skU5w3xI++GM/RO7YXaNDFL8mGMiE5Mga8hVUlb+yLBvvNM+zCslqiI+dENFQjviZeFROWH3Kw=="
|
"integrity": "sha512-HSK9WXE+cT+1skU5w3xI++GM/RO7YXaNDFL8mGMiE5Mga8hVUlb+yLBvvNM+zCslqiI+dENFQjviZeFROWH3Kw=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/magista-proto": {
|
"node_modules/@vality/magista-proto": {
|
||||||
"version": "2.0.2-28d11b9.0",
|
"version": "2.0.2-ec1bdb9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@vality/magista-proto/-/magista-proto-2.0.2-28d11b9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@vality/magista-proto/-/magista-proto-2.0.2-ec1bdb9.0.tgz",
|
||||||
"integrity": "sha512-BsDy5ejotfTtUlwuoX3kz+PYJ5NSTW6m5ZRGv+p5HaKXSjR7tserPdv0q133Wp4T+sg0ED0Qr9Peqsrn+9XlDQ=="
|
"integrity": "sha512-XWF7qM/CARRAey0scGVhfGU6jNq+UdlGE2mg3jn4eIFDuIWQJqsT+Bah300RBUrl+XgFsmj95C6HWRfeA5Q8kw=="
|
||||||
},
|
},
|
||||||
"node_modules/@vality/ng-core": {
|
"node_modules/@vality/ng-core": {
|
||||||
"version": "18.2.0",
|
"version": "18.2.0",
|
||||||
|
@ -29,11 +29,11 @@
|
|||||||
"@angular/router": "18.0.5",
|
"@angular/router": "18.0.5",
|
||||||
"@ngneat/input-mask": "6.0.0",
|
"@ngneat/input-mask": "6.0.0",
|
||||||
"@vality/deanonimus-proto": "2.0.1-2a02d87.0",
|
"@vality/deanonimus-proto": "2.0.1-2a02d87.0",
|
||||||
"@vality/domain-proto": "2.0.1-6051aa9.0",
|
"@vality/domain-proto": "2.0.1-e5d3c83.0",
|
||||||
"@vality/dominator-proto": "1.0.1-41bee97.0",
|
"@vality/dominator-proto": "1.0.1-41bee97.0",
|
||||||
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
"@vality/fistful-proto": "2.0.1-88e69a5.0",
|
||||||
"@vality/machinegun-proto": "1.0.0",
|
"@vality/machinegun-proto": "1.0.0",
|
||||||
"@vality/magista-proto": "2.0.2-28d11b9.0",
|
"@vality/magista-proto": "2.0.2-ec1bdb9.0",
|
||||||
"@vality/ng-core": "18.2.0",
|
"@vality/ng-core": "18.2.0",
|
||||||
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
"@vality/ng-thrift": "18.0.1-pr-13-bdb6d51.0",
|
||||||
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
|
"@vality/payout-manager-proto": "2.0.1-eb4091a.0",
|
||||||
|
@ -9,8 +9,6 @@ import {
|
|||||||
StatPaymentResponse,
|
StatPaymentResponse,
|
||||||
RefundSearchQuery,
|
RefundSearchQuery,
|
||||||
StatRefundResponse,
|
StatRefundResponse,
|
||||||
PayoutSearchQuery,
|
|
||||||
StatPayoutResponse,
|
|
||||||
ChargebackSearchQuery,
|
ChargebackSearchQuery,
|
||||||
} from '@vality/magista-proto/magista';
|
} from '@vality/magista-proto/magista';
|
||||||
import { combineLatest, from, map, Observable, switchMap } from 'rxjs';
|
import { combineLatest, from, map, Observable, switchMap } from 'rxjs';
|
||||||
@ -58,11 +56,6 @@ export class MerchantStatisticsService {
|
|||||||
return this.client$.pipe(switchMap((c) => c.SearchRefunds(refundSearchQuery)));
|
return this.client$.pipe(switchMap((c) => c.SearchRefunds(refundSearchQuery)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
||||||
SearchPayouts(payoutSearchQuery: PayoutSearchQuery): Observable<StatPayoutResponse> {
|
|
||||||
return this.client$.pipe(switchMap((c) => c.SearchPayouts(payoutSearchQuery)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
SearchChargebacks(chargebackSearchQuery: ChargebackSearchQuery) {
|
SearchChargebacks(chargebackSearchQuery: ChargebackSearchQuery) {
|
||||||
return this.client$.pipe(switchMap((c) => c.SearchChargebacks(chargebackSearchQuery)));
|
return this.client$.pipe(switchMap((c) => c.SearchChargebacks(chargebackSearchQuery)));
|
||||||
|
@ -9,7 +9,7 @@ import { AppAuthGuardService } from '@cc/app/shared/services';
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
redirectTo: '/payouts',
|
redirectTo: '/payments',
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -13,7 +13,6 @@ import { ROUTING_CONFIG as CLAIMS_ROUTING_CONFIG } from './sections/claims/routi
|
|||||||
import { ROUTING_CONFIG as DEPOSITS_ROUTING_CONFIG } from './sections/deposits/routing-config';
|
import { ROUTING_CONFIG as DEPOSITS_ROUTING_CONFIG } from './sections/deposits/routing-config';
|
||||||
import { ROUTING_CONFIG as DOMAIN_ROUTING_CONFIG } from './sections/domain/routing-config';
|
import { ROUTING_CONFIG as DOMAIN_ROUTING_CONFIG } from './sections/domain/routing-config';
|
||||||
import { ROUTING_CONFIG as PAYMENTS_ROUTING_CONFIG } from './sections/payments/routing-config';
|
import { ROUTING_CONFIG as PAYMENTS_ROUTING_CONFIG } from './sections/payments/routing-config';
|
||||||
import { ROUTING_CONFIG as PAYOUTS_ROUTING_CONFIG } from './sections/payouts/payouts/routing-config';
|
|
||||||
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
import { ROUTING_CONFIG as REPAIRING_ROUTING_CONFIG } from './sections/repairing/routing-config';
|
||||||
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
import { ROUTING_CONFIG as PARTIES_ROUTING_CONFIG } from './sections/search-parties/routing-config';
|
||||||
import { SHOPS_ROUTING_CONFIG } from './sections/shops';
|
import { SHOPS_ROUTING_CONFIG } from './sections/shops';
|
||||||
@ -120,11 +119,6 @@ export class AppComponent {
|
|||||||
url: '/old-payments',
|
url: '/old-payments',
|
||||||
services: PAYMENTS_ROUTING_CONFIG.services,
|
services: PAYMENTS_ROUTING_CONFIG.services,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'Payouts',
|
|
||||||
url: '/payouts',
|
|
||||||
services: PAYOUTS_ROUTING_CONFIG.services,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Chargebacks',
|
label: 'Chargebacks',
|
||||||
url: '/chargebacks',
|
url: '/chargebacks',
|
||||||
|
@ -24,7 +24,6 @@ import { ToolbarComponent } from './core/components/toolbar/toolbar.component';
|
|||||||
import { CoreModule } from './core/core.module';
|
import { CoreModule } from './core/core.module';
|
||||||
import icons from './icons.json';
|
import icons from './icons.json';
|
||||||
import { ClaimsModule } from './sections/claims/claims.module';
|
import { ClaimsModule } from './sections/claims/claims.module';
|
||||||
import { PayoutsModule } from './sections/payouts';
|
|
||||||
import { SearchPartiesModule } from './sections/search-parties/search-parties.module';
|
import { SearchPartiesModule } from './sections/search-parties/search-parties.module';
|
||||||
import { SectionsModule } from './sections/sections.module';
|
import { SectionsModule } from './sections/sections.module';
|
||||||
import { CandidateCardComponent } from './shared/components/candidate-card/candidate-card.component';
|
import { CandidateCardComponent } from './shared/components/candidate-card/candidate-card.component';
|
||||||
@ -60,7 +59,6 @@ registerLocaleData(localeRu);
|
|||||||
SearchPartiesModule,
|
SearchPartiesModule,
|
||||||
ClaimsModule,
|
ClaimsModule,
|
||||||
KeycloakTokenInfoModule,
|
KeycloakTokenInfoModule,
|
||||||
PayoutsModule,
|
|
||||||
SectionsModule,
|
SectionsModule,
|
||||||
SidenavInfoComponent,
|
SidenavInfoComponent,
|
||||||
ToolbarComponent,
|
ToolbarComponent,
|
||||||
|
@ -153,6 +153,7 @@ export class CreateShopDialogComponent
|
|||||||
this.form.value;
|
this.form.value;
|
||||||
const contractorId = short().uuid();
|
const contractorId = short().uuid();
|
||||||
const contractId = short().uuid();
|
const contractId = short().uuid();
|
||||||
|
const payoutToolId = short().generate();
|
||||||
const shopId = short().uuid();
|
const shopId = short().uuid();
|
||||||
this.claimManagementService
|
this.claimManagementService
|
||||||
.UpdateClaim(
|
.UpdateClaim(
|
||||||
@ -184,6 +185,27 @@ export class CreateShopDialogComponent
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
party_modification: {
|
||||||
|
contract_modification: {
|
||||||
|
id: contractId,
|
||||||
|
modification: {
|
||||||
|
payout_tool_modification: {
|
||||||
|
payout_tool_id: payoutToolId,
|
||||||
|
modification: {
|
||||||
|
creation: {
|
||||||
|
currency: currency,
|
||||||
|
tool_info: {
|
||||||
|
russian_bank_account:
|
||||||
|
DEFAULT_RUSSIAN_BANK_ACCOUNT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
party_modification: {
|
party_modification: {
|
||||||
shop_modification: {
|
shop_modification: {
|
||||||
@ -194,6 +216,7 @@ export class CreateShopDialogComponent
|
|||||||
category: category,
|
category: category,
|
||||||
location: DEFAULT_SHOP_LOCATION,
|
location: DEFAULT_SHOP_LOCATION,
|
||||||
contract_id: contractId,
|
contract_id: contractId,
|
||||||
|
payout_tool_id: payoutToolId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -47,6 +47,12 @@ export const MODIFICATIONS_NAME_TREE: ModificationsNameTree<Modification> = {
|
|||||||
creation: 'Contract Adjustment Creation',
|
creation: 'Contract Adjustment Creation',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
payout_tool_modification: {
|
||||||
|
modification: {
|
||||||
|
creation: 'Contract Payout Tool Creation',
|
||||||
|
info_modification: 'Contract Payout Tool Info',
|
||||||
|
},
|
||||||
|
},
|
||||||
legal_agreement_binding: 'Contract Legal Agreement Binding',
|
legal_agreement_binding: 'Contract Legal Agreement Binding',
|
||||||
report_preferences_modification: 'Contract Report Preferences',
|
report_preferences_modification: 'Contract Report Preferences',
|
||||||
contractor_modification: 'Contract Contractor',
|
contractor_modification: 'Contract Contractor',
|
||||||
@ -58,8 +64,10 @@ export const MODIFICATIONS_NAME_TREE: ModificationsNameTree<Modification> = {
|
|||||||
category_modification: 'Shop Category',
|
category_modification: 'Shop Category',
|
||||||
details_modification: 'Shop Details',
|
details_modification: 'Shop Details',
|
||||||
contract_modification: 'Shop Contract',
|
contract_modification: 'Shop Contract',
|
||||||
|
payout_tool_modification: 'Shop Payout Tool',
|
||||||
location_modification: 'Shop Location',
|
location_modification: 'Shop Location',
|
||||||
shop_account_creation: 'Shop Account Creation',
|
shop_account_creation: 'Shop Account Creation',
|
||||||
|
payout_schedule_modification: 'Shop Schedule',
|
||||||
cash_register_modification_unit: {
|
cash_register_modification_unit: {
|
||||||
modification: {
|
modification: {
|
||||||
creation: 'Shop Cash Register Creation',
|
creation: 'Shop Cash Register Creation',
|
||||||
|
@ -1 +0,0 @@
|
|||||||
export * from './payouts.module';
|
|
@ -1,22 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { AppAuthGuardService } from '@cc/app/shared/services';
|
|
||||||
|
|
||||||
import { PayoutDetailsComponent } from './payout-details.component';
|
|
||||||
import { ROUTING_CONFIG } from './routing-config';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: PayoutDetailsComponent,
|
|
||||||
canActivate: [AppAuthGuardService],
|
|
||||||
data: ROUTING_CONFIG,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
exports: [RouterModule],
|
|
||||||
})
|
|
||||||
export class PayoutDetailsRoutingModule {}
|
|
@ -1,70 +0,0 @@
|
|||||||
<cc-page-layout [description]="(payout$ | async)?.id" [progress]="progress$ | async" title="Payout">
|
|
||||||
<cc-page-layout-actions *ngIf="payout$ | async as payout">
|
|
||||||
<button
|
|
||||||
[disabled]="canBeCancelled(payout.status | ngtUnionKey)"
|
|
||||||
color="warn"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="cancel(payout.id)"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
[disabled]="canBeConfirmed(payout.status | ngtUnionKey)"
|
|
||||||
color="primary"
|
|
||||||
mat-raised-button
|
|
||||||
(click)="confirm(payout.id)"
|
|
||||||
>
|
|
||||||
Confirm
|
|
||||||
</button>
|
|
||||||
</cc-page-layout-actions>
|
|
||||||
<ng-container *ngIf="payout$ | async as payout">
|
|
||||||
<mat-card>
|
|
||||||
<mat-card-content style="display: grid; gap: 16px">
|
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px">
|
|
||||||
<cc-details-item title="Payout ID">{{ payout.payout_id }}</cc-details-item>
|
|
||||||
<cc-details-item title="Amount">
|
|
||||||
{{ payout.amount | ccFormatAmount }}
|
|
||||||
{{ payout.currency.symbolic_code | ccCurrency }}
|
|
||||||
</cc-details-item>
|
|
||||||
<cc-details-item title="Fee">
|
|
||||||
{{ payout.fee | ccFormatAmount }}
|
|
||||||
{{ payout.currency.symbolic_code | ccCurrency }}
|
|
||||||
</cc-details-item>
|
|
||||||
<cc-details-item title="Status">{{
|
|
||||||
payout.status | ngtUnionKey
|
|
||||||
}}</cc-details-item>
|
|
||||||
<cc-details-item *ngIf="payout.status.cancelled" title="Status Details">{{
|
|
||||||
payout.status.cancelled.details
|
|
||||||
}}</cc-details-item>
|
|
||||||
<cc-details-item title="Created At">{{
|
|
||||||
payout.created_at | date: 'dd.MM.yyyy HH:mm:ss'
|
|
||||||
}}</cc-details-item>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ng-container *ngIf="party$ | async as party">
|
|
||||||
<div><mat-divider></mat-divider></div>
|
|
||||||
<h2 class="mat-headline-4">Party</h2>
|
|
||||||
<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px">
|
|
||||||
<cc-details-item title="ID">{{ payout.party_id }}</cc-details-item>
|
|
||||||
<cc-details-item title="Email">
|
|
||||||
{{ party.contact_info?.email }}
|
|
||||||
</cc-details-item>
|
|
||||||
</div>
|
|
||||||
</ng-container>
|
|
||||||
|
|
||||||
<div><mat-divider></mat-divider></div>
|
|
||||||
<h2 class="mat-headline-4">Shop</h2>
|
|
||||||
<cc-shop-details [shop]="shop$ | async"></cc-shop-details>
|
|
||||||
|
|
||||||
<ng-container *ngIf="payoutTool$ | async as payoutTool">
|
|
||||||
<div><mat-divider></mat-divider></div>
|
|
||||||
<h2 class="mat-headline-4">Payout Tool</h2>
|
|
||||||
<cc-payout-tool-details [payoutTool]="payoutTool"></cc-payout-tool-details>
|
|
||||||
</ng-container>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
|
|
||||||
<h2 class="mat-h1 mat-no-margin">Cash Flow</h2>
|
|
||||||
<v-table [columns]="cashFlowColumns" [data]="payout.cash_flow"></v-table>
|
|
||||||
</ng-container>
|
|
||||||
</cc-page-layout>
|
|
@ -1,93 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
|
||||||
import { PayoutID, PayoutStatus } from '@vality/magista-proto/magista';
|
|
||||||
import { Column, progressTo } from '@vality/ng-core';
|
|
||||||
import { getUnionKey, getUnionValue } from '@vality/ng-thrift';
|
|
||||||
import { FinalCashFlowPosting } from '@vality/payout-manager-proto/internal/proto/domain';
|
|
||||||
import startCase from 'lodash-es/startCase';
|
|
||||||
import { combineLatest, BehaviorSubject } from 'rxjs';
|
|
||||||
import { map, shareReplay, startWith, switchMap } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { PartyManagementService } from '@cc/app/api/payment-processing';
|
|
||||||
import { PayoutManagementService } from '@cc/app/api/payout-manager';
|
|
||||||
|
|
||||||
import { createCurrencyColumn } from '../../../shared';
|
|
||||||
import { PayoutActionsService } from '../services/payout-actions.service';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cc-payout-details',
|
|
||||||
templateUrl: './payout-details.component.html',
|
|
||||||
providers: [PayoutActionsService],
|
|
||||||
})
|
|
||||||
export class PayoutDetailsComponent {
|
|
||||||
progress$ = new BehaviorSubject(0);
|
|
||||||
payout$ = this.route.params.pipe(
|
|
||||||
startWith(this.route.snapshot.params),
|
|
||||||
map((p) => p?.payoutId),
|
|
||||||
switchMap((id: string) =>
|
|
||||||
this.payoutManagementService.GetPayout(id).pipe(progressTo(this.progress$)),
|
|
||||||
),
|
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
|
||||||
);
|
|
||||||
shop$ = this.payout$.pipe(
|
|
||||||
switchMap(({ party_id, shop_id }) =>
|
|
||||||
this.partyManagementService.GetShop(party_id, shop_id),
|
|
||||||
),
|
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
|
||||||
);
|
|
||||||
party$ = this.payout$.pipe(
|
|
||||||
switchMap(({ party_id }) => this.partyManagementService.Get(party_id)),
|
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
|
||||||
);
|
|
||||||
payoutTool$ = combineLatest([this.payout$, this.shop$]).pipe(
|
|
||||||
switchMap(([{ party_id, payout_tool_id }, { contract_id }]) =>
|
|
||||||
this.partyManagementService
|
|
||||||
.GetContract(party_id, contract_id)
|
|
||||||
.pipe(
|
|
||||||
map((contract) => contract.payout_tools.find((t) => t.id === payout_tool_id)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
|
||||||
);
|
|
||||||
cashFlowColumns: Column<FinalCashFlowPosting>[] = [
|
|
||||||
{
|
|
||||||
field: 'source',
|
|
||||||
description: (d) => getUnionValue(d.source.account_type),
|
|
||||||
formatter: (d) => startCase(getUnionKey(d.source.account_type)),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'destination',
|
|
||||||
description: (d) => getUnionValue(d.destination.account_type),
|
|
||||||
formatter: (d) => startCase(getUnionKey(d.destination.account_type)),
|
|
||||||
},
|
|
||||||
createCurrencyColumn(
|
|
||||||
'volume',
|
|
||||||
(d) => d.volume.amount,
|
|
||||||
(d) => d.volume.currency.symbolic_code,
|
|
||||||
),
|
|
||||||
'details',
|
|
||||||
];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private route: ActivatedRoute,
|
|
||||||
private payoutManagementService: PayoutManagementService,
|
|
||||||
private partyManagementService: PartyManagementService,
|
|
||||||
private payoutActionsService: PayoutActionsService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
canBeConfirmed(status: keyof PayoutStatus) {
|
|
||||||
return this.payoutActionsService.canBeConfirmed(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
canBeCancelled(status: keyof PayoutStatus) {
|
|
||||||
return this.payoutActionsService.canBeCancelled(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel(id: PayoutID) {
|
|
||||||
this.payoutActionsService.cancel(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
confirm(id: PayoutID) {
|
|
||||||
this.payoutActionsService.confirm(id);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatCardModule } from '@angular/material/card';
|
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
||||||
import { ActionsModule, TableModule } from '@vality/ng-core';
|
|
||||||
import { ThriftPipesModule } from '@vality/ng-thrift';
|
|
||||||
|
|
||||||
import { ShopDetailsModule, PageLayoutModule } from '@cc/app/shared/components';
|
|
||||||
import { PayoutToolDetailsModule } from '@cc/app/shared/components/payout-tool-details/payout-tool-details.module';
|
|
||||||
import { CommonPipesModule } from '@cc/app/shared/pipes';
|
|
||||||
import { DetailsItemModule } from '@cc/components/details-item';
|
|
||||||
import { HeadlineModule } from '@cc/components/headline';
|
|
||||||
|
|
||||||
import { PayoutDetailsRoutingModule } from './payout-details-routing.module';
|
|
||||||
import { PayoutDetailsComponent } from './payout-details.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [PayoutDetailsComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
PayoutDetailsRoutingModule,
|
|
||||||
HeadlineModule,
|
|
||||||
MatCardModule,
|
|
||||||
DetailsItemModule,
|
|
||||||
MatDividerModule,
|
|
||||||
CommonPipesModule,
|
|
||||||
ThriftPipesModule,
|
|
||||||
ShopDetailsModule,
|
|
||||||
PayoutToolDetailsModule,
|
|
||||||
MatPaginatorModule,
|
|
||||||
MatButtonModule,
|
|
||||||
ActionsModule,
|
|
||||||
TableModule,
|
|
||||||
PageLayoutModule,
|
|
||||||
],
|
|
||||||
})
|
|
||||||
export class PayoutDetailsModule {}
|
|
@ -1,5 +0,0 @@
|
|||||||
import { Services, RoutingConfig } from '@cc/app/shared/services';
|
|
||||||
|
|
||||||
export const ROUTING_CONFIG: RoutingConfig = {
|
|
||||||
services: [Services.PayoutManagement],
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: 'payouts',
|
|
||||||
loadChildren: () => import('./payouts/payouts.module').then((m) => m.PayoutsModule),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'payouts/:payoutId',
|
|
||||||
loadChildren: () =>
|
|
||||||
import('./payout-details/payout-details.module').then(
|
|
||||||
(m) => m.PayoutDetailsModule,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
exports: [RouterModule],
|
|
||||||
})
|
|
||||||
export class PayoutsRoutingModule {}
|
|
@ -1,9 +0,0 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { PayoutsRoutingModule } from './payouts-routing.module';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [CommonModule, PayoutsRoutingModule],
|
|
||||||
})
|
|
||||||
export class PayoutsModule {}
|
|
@ -1,16 +0,0 @@
|
|||||||
<v-dialog [progress]="progress$ | async" title="Cancel payout">
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>Details</mat-label>
|
|
||||||
<input [formControl]="detailsControl" matInput required type="text" />
|
|
||||||
</mat-form-field>
|
|
||||||
<v-dialog-actions>
|
|
||||||
<button
|
|
||||||
[disabled]="detailsControl.invalid || !!(progress$ | async)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
(click)="accept()"
|
|
||||||
>
|
|
||||||
Accept
|
|
||||||
</button>
|
|
||||||
</v-dialog-actions>
|
|
||||||
</v-dialog>
|
|
@ -1,46 +0,0 @@
|
|||||||
import { Component, DestroyRef } from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
import { FormControl } from '@angular/forms';
|
|
||||||
import {
|
|
||||||
DialogResponseStatus,
|
|
||||||
DialogSuperclass,
|
|
||||||
NotifyLogService,
|
|
||||||
progressTo,
|
|
||||||
} from '@vality/ng-core';
|
|
||||||
import { PayoutID } from '@vality/payout-manager-proto/payout_manager';
|
|
||||||
import { BehaviorSubject } from 'rxjs';
|
|
||||||
|
|
||||||
import { PayoutManagementService } from '@cc/app/api/payout-manager';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cc-cancel-payout-dialog',
|
|
||||||
templateUrl: './cancel-payout-dialog.component.html',
|
|
||||||
})
|
|
||||||
export class CancelPayoutDialogComponent extends DialogSuperclass<
|
|
||||||
CancelPayoutDialogComponent,
|
|
||||||
{ id: PayoutID }
|
|
||||||
> {
|
|
||||||
detailsControl = new FormControl() as FormControl<string>;
|
|
||||||
progress$ = new BehaviorSubject(0);
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private payoutManagementService: PayoutManagementService,
|
|
||||||
private log: NotifyLogService,
|
|
||||||
private destroyRef: DestroyRef,
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
accept() {
|
|
||||||
this.payoutManagementService
|
|
||||||
.CancelPayout(this.dialogData.id, this.detailsControl.value)
|
|
||||||
.pipe(progressTo(this.progress$), takeUntilDestroyed(this.destroyRef))
|
|
||||||
.subscribe({
|
|
||||||
next: () => {
|
|
||||||
this.dialogRef.close({ status: DialogResponseStatus.Success });
|
|
||||||
this.log.success('Payout canceled successfully');
|
|
||||||
},
|
|
||||||
error: this.log.error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
<v-dialog [progress]="!!(progress$ | async)" title="Create payout">
|
|
||||||
<div [formGroup]="control" style="display: grid; grid-template-columns: 1fr; gap: 16px">
|
|
||||||
<cc-merchant-field formControlName="partyId" required></cc-merchant-field>
|
|
||||||
<cc-shop-field
|
|
||||||
[partyId]="this.control.value.partyId"
|
|
||||||
formControlName="shopId"
|
|
||||||
required
|
|
||||||
></cc-shop-field>
|
|
||||||
<div style="display: flex; gap: 24px">
|
|
||||||
<mat-form-field style="flex: 1">
|
|
||||||
<input
|
|
||||||
formControlName="amount"
|
|
||||||
matInput
|
|
||||||
placeholder="Amount"
|
|
||||||
required
|
|
||||||
type="number"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field style="flex: 1">
|
|
||||||
<input
|
|
||||||
formControlName="currency"
|
|
||||||
matInput
|
|
||||||
placeholder="Currency"
|
|
||||||
required
|
|
||||||
type="text"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<cc-payout-tool-field
|
|
||||||
[partyId]="this.control.value.partyId"
|
|
||||||
[shopId]="this.control.value.shopId"
|
|
||||||
formControlName="payoutToolId"
|
|
||||||
></cc-payout-tool-field>
|
|
||||||
</div>
|
|
||||||
<v-dialog-actions>
|
|
||||||
<button
|
|
||||||
[disabled]="control.invalid || !!(progress$ | async)"
|
|
||||||
color="primary"
|
|
||||||
mat-button
|
|
||||||
(click)="create()"
|
|
||||||
>
|
|
||||||
Create
|
|
||||||
</button>
|
|
||||||
</v-dialog-actions>
|
|
||||||
</v-dialog>
|
|
@ -1,78 +0,0 @@
|
|||||||
import { ChangeDetectionStrategy, Component, DestroyRef } from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
import { FormBuilder } from '@angular/forms';
|
|
||||||
import {
|
|
||||||
DialogResponseStatus,
|
|
||||||
DialogSuperclass,
|
|
||||||
NotifyLogService,
|
|
||||||
progressTo,
|
|
||||||
toMinor,
|
|
||||||
} from '@vality/ng-core';
|
|
||||||
import { PayoutParams } from '@vality/payout-manager-proto/payout_manager';
|
|
||||||
import isNil from 'lodash-es/isNil';
|
|
||||||
import omitBy from 'lodash-es/omitBy';
|
|
||||||
import { BehaviorSubject } from 'rxjs';
|
|
||||||
|
|
||||||
import { PayoutManagementService } from '@cc/app/api/payout-manager';
|
|
||||||
|
|
||||||
interface CreatePayoutDialogForm {
|
|
||||||
partyId: string;
|
|
||||||
shopId: string;
|
|
||||||
currency: string;
|
|
||||||
amount: number;
|
|
||||||
payoutToolId?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cc-create-payout-dialog',
|
|
||||||
templateUrl: './create-payout-dialog.component.html',
|
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
||||||
})
|
|
||||||
export class CreatePayoutDialogComponent extends DialogSuperclass<CreatePayoutDialogComponent> {
|
|
||||||
progress$ = new BehaviorSubject(0);
|
|
||||||
control = this.fb.group<CreatePayoutDialogForm>({
|
|
||||||
partyId: null,
|
|
||||||
shopId: null,
|
|
||||||
currency: null,
|
|
||||||
amount: null,
|
|
||||||
payoutToolId: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private fb: FormBuilder,
|
|
||||||
private payoutManagementService: PayoutManagementService,
|
|
||||||
private log: NotifyLogService,
|
|
||||||
private destroyRef: DestroyRef,
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
create() {
|
|
||||||
const { value } = this.control;
|
|
||||||
this.payoutManagementService
|
|
||||||
.CreatePayout(
|
|
||||||
omitBy(
|
|
||||||
{
|
|
||||||
shop_params: {
|
|
||||||
shop_id: value.shopId,
|
|
||||||
party_id: value.partyId,
|
|
||||||
},
|
|
||||||
cash: {
|
|
||||||
amount: toMinor(value.amount, value.currency), // TODO use domain currencies refs
|
|
||||||
currency: { symbolic_code: value.currency },
|
|
||||||
},
|
|
||||||
payout_tool_id: value.payoutToolId,
|
|
||||||
},
|
|
||||||
isNil,
|
|
||||||
) as PayoutParams,
|
|
||||||
)
|
|
||||||
.pipe(takeUntilDestroyed(this.destroyRef), progressTo(this.progress$))
|
|
||||||
.subscribe({
|
|
||||||
next: () => {
|
|
||||||
this.log.success('Payout created successfully');
|
|
||||||
this.dialogRef.close({ status: DialogResponseStatus.Success });
|
|
||||||
},
|
|
||||||
error: this.log.error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { RouterModule } from '@angular/router';
|
|
||||||
|
|
||||||
import { AppAuthGuardService } from '@cc/app/shared/services';
|
|
||||||
|
|
||||||
import { PayoutsComponent } from './payouts.component';
|
|
||||||
import { ROUTING_CONFIG } from './routing-config';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
RouterModule.forChild([
|
|
||||||
{
|
|
||||||
path: '',
|
|
||||||
component: PayoutsComponent,
|
|
||||||
canActivate: [AppAuthGuardService],
|
|
||||||
data: ROUTING_CONFIG,
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
],
|
|
||||||
exports: [RouterModule],
|
|
||||||
})
|
|
||||||
export class PayoutsRoutingModule {}
|
|
@ -1,61 +0,0 @@
|
|||||||
<cc-page-layout title="Payouts">
|
|
||||||
<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()">
|
|
||||||
<ng-template [formGroup]="filtersForm">
|
|
||||||
<v-date-range-field formControlName="dateRange" required></v-date-range-field>
|
|
||||||
<mat-form-field>
|
|
||||||
<input
|
|
||||||
autocomplete="off"
|
|
||||||
formControlName="payoutId"
|
|
||||||
matInput
|
|
||||||
placeholder="Payout ID"
|
|
||||||
/>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-select
|
|
||||||
formControlName="payoutStatusTypes"
|
|
||||||
multiple
|
|
||||||
placeholder="Payout Status Type"
|
|
||||||
>
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let type of statusTypeEnum | enumKeys"
|
|
||||||
[value]="statusTypeEnum[type]"
|
|
||||||
>
|
|
||||||
{{ type }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-select formControlName="payoutToolType" placeholder="Payout Tool Type">
|
|
||||||
<mat-option [value]="null">any</mat-option>
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let type of payoutToolTypeEnum | enumKeys"
|
|
||||||
[value]="payoutToolTypeEnum[type]"
|
|
||||||
>
|
|
||||||
{{ type }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
<cc-merchant-field formControlName="partyId"></cc-merchant-field>
|
|
||||||
<cc-shop-field
|
|
||||||
[partyId]="filtersForm.value.partyId"
|
|
||||||
formControlName="shops"
|
|
||||||
multiple
|
|
||||||
></cc-shop-field>
|
|
||||||
</ng-template>
|
|
||||||
</v-filters>
|
|
||||||
<v-table
|
|
||||||
[columns]="columns"
|
|
||||||
[data]="payouts$ | async"
|
|
||||||
[hasMore]="hasMore$ | async"
|
|
||||||
[progress]="inProgress$ | async"
|
|
||||||
(more)="more()"
|
|
||||||
(update)="reload($event)"
|
|
||||||
>
|
|
||||||
<v-table-actions>
|
|
||||||
<button color="primary" mat-raised-button (click)="create()">Create</button>
|
|
||||||
</v-table-actions>
|
|
||||||
</v-table>
|
|
||||||
</cc-page-layout>
|
|
@ -1,164 +0,0 @@
|
|||||||
import { Component, OnInit, Inject, DestroyRef } from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
import { NonNullableFormBuilder } from '@angular/forms';
|
|
||||||
import { Party, Shop, ShopID, PartyID } from '@vality/domain-proto/domain';
|
|
||||||
import { magista } from '@vality/magista-proto';
|
|
||||||
import { StatPayout } from '@vality/magista-proto/magista';
|
|
||||||
import {
|
|
||||||
DialogService,
|
|
||||||
QueryParamsService,
|
|
||||||
clean,
|
|
||||||
getValueChanges,
|
|
||||||
getNoTimeZoneIsoString,
|
|
||||||
createDateRangeToToday,
|
|
||||||
Column,
|
|
||||||
createOperationColumn,
|
|
||||||
DateRange,
|
|
||||||
UpdateOptions,
|
|
||||||
debounceTimeWithFirst,
|
|
||||||
countChanged,
|
|
||||||
} from '@vality/ng-core';
|
|
||||||
import { getUnionKey } from '@vality/ng-thrift';
|
|
||||||
import { endOfDay } from 'date-fns';
|
|
||||||
import startCase from 'lodash-es/startCase';
|
|
||||||
import { map, shareReplay } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { createCurrencyColumn, createPartyColumn, createShopColumn } from '../../../shared';
|
|
||||||
import { DATE_RANGE_DAYS, DEBOUNCE_TIME_MS } from '../../../tokens';
|
|
||||||
import { PayoutActionsService } from '../services/payout-actions.service';
|
|
||||||
|
|
||||||
import { CreatePayoutDialogComponent } from './components/create-payout-dialog/create-payout-dialog.component';
|
|
||||||
import { FetchPayoutsService } from './services/fetch-payouts.service';
|
|
||||||
|
|
||||||
interface PayoutsSearchForm {
|
|
||||||
payoutId: string;
|
|
||||||
partyId: Party['id'];
|
|
||||||
dateRange: DateRange;
|
|
||||||
shops: Shop['id'][];
|
|
||||||
payoutStatusTypes: magista.PayoutStatusType[];
|
|
||||||
payoutToolType: magista.PayoutToolType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'cc-payouts',
|
|
||||||
templateUrl: './payouts.component.html',
|
|
||||||
providers: [FetchPayoutsService, PayoutActionsService],
|
|
||||||
})
|
|
||||||
export class PayoutsComponent implements OnInit {
|
|
||||||
filtersForm = this.fb.group({
|
|
||||||
payoutId: null as string,
|
|
||||||
partyId: null as PartyID,
|
|
||||||
dateRange: createDateRangeToToday(this.dateRangeDays),
|
|
||||||
shops: [null as ShopID[]],
|
|
||||||
payoutStatusTypes: [null as magista.PayoutStatusType[]],
|
|
||||||
payoutToolType: [null as magista.PayoutToolType],
|
|
||||||
});
|
|
||||||
inProgress$ = this.fetchPayoutsService.isLoading$;
|
|
||||||
payouts$ = this.fetchPayoutsService.result$;
|
|
||||||
hasMore$ = this.fetchPayoutsService.hasMore$;
|
|
||||||
columns: Column<StatPayout>[] = [
|
|
||||||
{ field: 'id', link: (d) => `/payouts/${d.id}` },
|
|
||||||
createPartyColumn('party_id'),
|
|
||||||
createShopColumn('shop_id', (d) => d.party_id),
|
|
||||||
{ field: 'created_at', type: 'datetime' },
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
type: 'tag',
|
|
||||||
formatter: (d) => getUnionKey(d.status),
|
|
||||||
typeParameters: {
|
|
||||||
label: (d) => startCase(getUnionKey(d.status)),
|
|
||||||
tags: {
|
|
||||||
unpaid: { color: 'pending' },
|
|
||||||
paid: { color: 'success' },
|
|
||||||
cancelled: { color: 'warn' },
|
|
||||||
confirmed: { color: 'success' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
createCurrencyColumn(
|
|
||||||
'amount',
|
|
||||||
(d) => d.amount,
|
|
||||||
(d) => d.currency_symbolic_code,
|
|
||||||
),
|
|
||||||
createCurrencyColumn(
|
|
||||||
'fee',
|
|
||||||
(d) => d.fee,
|
|
||||||
(d) => d.currency_symbolic_code,
|
|
||||||
),
|
|
||||||
{ field: 'payoutToolType', formatter: (d) => getUnionKey(d.payout_tool_info) },
|
|
||||||
createOperationColumn([
|
|
||||||
{
|
|
||||||
label: 'Cancel',
|
|
||||||
disabled: (d) => !this.payoutActionsService.canBeCancelled(getUnionKey(d.status)),
|
|
||||||
click: (d) => this.payoutActionsService.cancel(d.id),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Confirm',
|
|
||||||
disabled: (d) => !this.payoutActionsService.canBeConfirmed(getUnionKey(d.status)),
|
|
||||||
click: (d) => this.payoutActionsService.confirm(d.id),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
];
|
|
||||||
statusTypeEnum = magista.PayoutStatusType;
|
|
||||||
payoutToolTypeEnum = magista.PayoutToolType;
|
|
||||||
active$ = getValueChanges(this.filtersForm).pipe(
|
|
||||||
map((v) => countChanged(this.initFilters, v)),
|
|
||||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
|
||||||
);
|
|
||||||
|
|
||||||
private initFilters = this.filtersForm.value;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private fetchPayoutsService: FetchPayoutsService,
|
|
||||||
private qp: QueryParamsService<Partial<PayoutsSearchForm>>,
|
|
||||||
private dialogService: DialogService,
|
|
||||||
@Inject(DATE_RANGE_DAYS) private dateRangeDays: number,
|
|
||||||
private payoutActionsService: PayoutActionsService,
|
|
||||||
private fb: NonNullableFormBuilder,
|
|
||||||
private destroyRef: DestroyRef,
|
|
||||||
@Inject(DEBOUNCE_TIME_MS) private debounceTimeMs: number,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.filtersForm.patchValue(this.qp.params);
|
|
||||||
getValueChanges(this.filtersForm)
|
|
||||||
.pipe(debounceTimeWithFirst(this.debounceTimeMs), takeUntilDestroyed(this.destroyRef))
|
|
||||||
.subscribe((value) => {
|
|
||||||
void this.qp.set(clean(value));
|
|
||||||
this.search();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
more() {
|
|
||||||
this.fetchPayoutsService.more();
|
|
||||||
}
|
|
||||||
|
|
||||||
search(options?: UpdateOptions) {
|
|
||||||
const value = clean(this.filtersForm.value);
|
|
||||||
this.fetchPayoutsService.load(
|
|
||||||
clean({
|
|
||||||
common_search_query_params: clean({
|
|
||||||
from_time:
|
|
||||||
value.dateRange?.start && getNoTimeZoneIsoString(value.dateRange?.start),
|
|
||||||
to_time:
|
|
||||||
value.dateRange?.end &&
|
|
||||||
getNoTimeZoneIsoString(endOfDay(value.dateRange?.end)),
|
|
||||||
party_id: value.partyId,
|
|
||||||
shop_ids: value.shops,
|
|
||||||
}),
|
|
||||||
payout_id: value.payoutId,
|
|
||||||
payout_status_types: value.payoutStatusTypes,
|
|
||||||
payout_type: value.payoutToolType,
|
|
||||||
}),
|
|
||||||
options,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
reload(options?: UpdateOptions) {
|
|
||||||
this.fetchPayoutsService.reload(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
create() {
|
|
||||||
this.dialogService.open(CreatePayoutDialogComponent);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatCardModule } from '@angular/material/card';
|
|
||||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
|
||||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
|
||||||
import {
|
|
||||||
DialogModule,
|
|
||||||
ActionsModule,
|
|
||||||
DateRangeFieldModule,
|
|
||||||
TableModule,
|
|
||||||
FiltersModule,
|
|
||||||
EnumKeysPipe,
|
|
||||||
} from '@vality/ng-core';
|
|
||||||
import { ThriftPipesModule } from '@vality/ng-thrift';
|
|
||||||
|
|
||||||
import {
|
|
||||||
PayoutToolFieldModule,
|
|
||||||
ShopFieldModule,
|
|
||||||
StatusModule,
|
|
||||||
PageLayoutModule,
|
|
||||||
} from '@cc/app/shared/components';
|
|
||||||
import { MerchantFieldModule } from '@cc/app/shared/components/merchant-field';
|
|
||||||
import { CommonPipesModule } from '@cc/app/shared/pipes';
|
|
||||||
|
|
||||||
import { CancelPayoutDialogComponent } from './components/cancel-payout-dialog/cancel-payout-dialog.component';
|
|
||||||
import { CreatePayoutDialogComponent } from './components/create-payout-dialog/create-payout-dialog.component';
|
|
||||||
import { PayoutsRoutingModule } from './payouts-routing.module';
|
|
||||||
import { PayoutsComponent } from './payouts.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
declarations: [PayoutsComponent, CreatePayoutDialogComponent, CancelPayoutDialogComponent],
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
PayoutsRoutingModule,
|
|
||||||
MatButtonModule,
|
|
||||||
MatCardModule,
|
|
||||||
MatProgressBarModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
MatInputModule,
|
|
||||||
FormsModule,
|
|
||||||
MerchantFieldModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatSelectModule,
|
|
||||||
MatDatepickerModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatMenuModule,
|
|
||||||
CommonPipesModule,
|
|
||||||
ThriftPipesModule,
|
|
||||||
StatusModule,
|
|
||||||
MatDialogModule,
|
|
||||||
ShopFieldModule,
|
|
||||||
PayoutToolFieldModule,
|
|
||||||
DialogModule,
|
|
||||||
ActionsModule,
|
|
||||||
PageLayoutModule,
|
|
||||||
DateRangeFieldModule,
|
|
||||||
TableModule,
|
|
||||||
FiltersModule,
|
|
||||||
EnumKeysPipe,
|
|
||||||
],
|
|
||||||
})
|
|
||||||
export class PayoutsModule {}
|
|
@ -1,5 +0,0 @@
|
|||||||
import { Services, RoutingConfig } from '@cc/app/shared/services';
|
|
||||||
|
|
||||||
export const ROUTING_CONFIG: RoutingConfig = {
|
|
||||||
services: [Services.MerchantStatistics],
|
|
||||||
};
|
|
@ -1,55 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core';
|
|
||||||
import { StatPayout, PayoutSearchQuery } from '@vality/magista-proto/magista';
|
|
||||||
import { FetchSuperclass, NotifyLogService, FetchResult, FetchOptions } from '@vality/ng-core';
|
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { map, catchError } from 'rxjs/operators';
|
|
||||||
import { Overwrite } from 'utility-types';
|
|
||||||
|
|
||||||
import { MerchantStatisticsService } from '@cc/app/api/magista';
|
|
||||||
|
|
||||||
export type SearchParams = Overwrite<
|
|
||||||
PayoutSearchQuery,
|
|
||||||
{
|
|
||||||
common_search_query_params: Omit<
|
|
||||||
PayoutSearchQuery['common_search_query_params'],
|
|
||||||
'continuation_token' | 'limit'
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
>;
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class FetchPayoutsService extends FetchSuperclass<StatPayout, SearchParams> {
|
|
||||||
constructor(
|
|
||||||
private merchantStatisticsService: MerchantStatisticsService,
|
|
||||||
private log: NotifyLogService,
|
|
||||||
) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fetch(
|
|
||||||
params: SearchParams,
|
|
||||||
options: FetchOptions,
|
|
||||||
): Observable<FetchResult<StatPayout>> {
|
|
||||||
return this.merchantStatisticsService
|
|
||||||
.SearchPayouts({
|
|
||||||
...params,
|
|
||||||
common_search_query_params: {
|
|
||||||
...params.common_search_query_params,
|
|
||||||
...(options.continuationToken
|
|
||||||
? { continuation_token: options.continuationToken }
|
|
||||||
: {}),
|
|
||||||
limit: options.size,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.pipe(
|
|
||||||
map(({ continuation_token, payouts }) => ({
|
|
||||||
result: payouts,
|
|
||||||
continuationToken: continuation_token,
|
|
||||||
})),
|
|
||||||
catchError((err) => {
|
|
||||||
this.log.error(err);
|
|
||||||
return of({ result: [] });
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import { Injectable, DestroyRef } from '@angular/core';
|
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
||||||
import { PayoutID, PayoutStatus } from '@vality/magista-proto/magista';
|
|
||||||
import {
|
|
||||||
DialogResponseStatus,
|
|
||||||
DialogService,
|
|
||||||
ConfirmDialogComponent,
|
|
||||||
NotifyLogService,
|
|
||||||
} from '@vality/ng-core';
|
|
||||||
import { switchMap } from 'rxjs';
|
|
||||||
import { filter } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { PayoutManagementService } from '@cc/app/api/payout-manager';
|
|
||||||
|
|
||||||
import { CancelPayoutDialogComponent } from '../payouts/components/cancel-payout-dialog/cancel-payout-dialog.component';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class PayoutActionsService {
|
|
||||||
constructor(
|
|
||||||
private payoutManagementService: PayoutManagementService,
|
|
||||||
private dialogService: DialogService,
|
|
||||||
private log: NotifyLogService,
|
|
||||||
private destroyRef: DestroyRef,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
canBeConfirmed(status: keyof PayoutStatus) {
|
|
||||||
return (['paid'] as (keyof PayoutStatus)[]).includes(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
canBeCancelled(status: keyof PayoutStatus) {
|
|
||||||
return (['paid', 'confirmed', 'unpaid'] as (keyof PayoutStatus)[]).includes(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
cancel(id: PayoutID) {
|
|
||||||
this.dialogService.open(CancelPayoutDialogComponent, { id });
|
|
||||||
}
|
|
||||||
|
|
||||||
confirm(id: PayoutID) {
|
|
||||||
this.dialogService
|
|
||||||
.open(ConfirmDialogComponent, { title: 'Confirm payout' })
|
|
||||||
.afterClosed()
|
|
||||||
.pipe(
|
|
||||||
filter(({ status }) => status === DialogResponseStatus.Success),
|
|
||||||
switchMap(() => this.payoutManagementService.ConfirmPayout(id)),
|
|
||||||
takeUntilDestroyed(this.destroyRef),
|
|
||||||
)
|
|
||||||
.subscribe({
|
|
||||||
error: this.log.error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
import { Claim } from '@vality/domain-proto/claim_management';
|
import { Claim, PayoutToolModificationUnit } from '@vality/domain-proto/claim_management';
|
||||||
import { Party } from '@vality/domain-proto/domain';
|
import { Party } from '@vality/domain-proto/domain';
|
||||||
import { isTypeWithAliases } from '@vality/ng-thrift';
|
import { isTypeWithAliases } from '@vality/ng-thrift';
|
||||||
import uniqBy from 'lodash-es/uniqBy';
|
import uniqBy from 'lodash-es/uniqBy';
|
||||||
@ -34,6 +34,20 @@ function createClaimOptions(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createClaimPayoutToolOptions(
|
||||||
|
modificationUnits: PayoutToolModificationUnit[],
|
||||||
|
): MetadataFormExtensionOption[] {
|
||||||
|
return uniqBy(
|
||||||
|
modificationUnits.map((unit) => ({
|
||||||
|
label: 'From claim',
|
||||||
|
details: unit.modification,
|
||||||
|
value: unit.payout_tool_id,
|
||||||
|
color: 'primary',
|
||||||
|
})),
|
||||||
|
'value',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function mergeClaimAndPartyOptions(
|
function mergeClaimAndPartyOptions(
|
||||||
claimOptions: MetadataFormExtensionOption[],
|
claimOptions: MetadataFormExtensionOption[],
|
||||||
partyOptions: MetadataFormExtensionOption[],
|
partyOptions: MetadataFormExtensionOption[],
|
||||||
@ -125,5 +139,22 @@ export function createPartyClaimDomainMetadataFormExtensions(
|
|||||||
isIdentifier: true,
|
isIdentifier: true,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
determinant: (data) => of(isTypeWithAliases(data, 'PayoutToolID', 'domain')),
|
||||||
|
extension: () =>
|
||||||
|
of({
|
||||||
|
options: createClaimPayoutToolOptions(
|
||||||
|
claim.changeset
|
||||||
|
.map(
|
||||||
|
(unit) =>
|
||||||
|
unit.modification.party_modification?.contract_modification
|
||||||
|
?.modification?.payout_tool_modification,
|
||||||
|
)
|
||||||
|
.filter(Boolean),
|
||||||
|
),
|
||||||
|
generate: () => of(short().generate()),
|
||||||
|
isIdentifier: true,
|
||||||
|
}),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user