mirror of
https://github.com/valitydev/control-center.git
synced 2024-11-06 02:25:17 +00:00
TD-37: Remove PAPI, old payouts and claims modules (#73)
This commit is contained in:
parent
20b80c0314
commit
247e79f30e
19
.github/workflows/pr.yaml
vendored
19
.github/workflows/pr.yaml
vendored
@ -15,8 +15,8 @@ jobs:
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
check:
|
||||
name: Check
|
||||
eslint:
|
||||
name: ESLint
|
||||
runs-on: ubuntu-latest
|
||||
needs: [init]
|
||||
steps:
|
||||
@ -27,7 +27,20 @@ jobs:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
- name: Check
|
||||
run: npm run ci:check
|
||||
run: npm run lint-cmd -- --quiet
|
||||
prettier:
|
||||
name: Prettier
|
||||
runs-on: ubuntu-latest
|
||||
needs: [init]
|
||||
steps:
|
||||
- name: Cache all
|
||||
uses: actions/cache@v3
|
||||
id: cache
|
||||
with:
|
||||
path: ./*
|
||||
key: ${{ github.sha }}
|
||||
- name: Check
|
||||
run: npm run prettier
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -7,7 +7,7 @@
|
||||
"start": "ng serve --proxy-config proxy.conf.js --port 4200",
|
||||
"build": "ng build --extra-webpack-config webpack.extra.js",
|
||||
"test": "ng test",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1552",
|
||||
"lint-cmd": "eslint \"src/**/*.{ts,js,html}\" --max-warnings 1385",
|
||||
"lint-cache-cmd": "npm run lint-cmd -- --cache",
|
||||
"lint": "npm run lint-cache-cmd",
|
||||
"lint-fix": "npm run lint-cache-cmd -- --fix",
|
||||
@ -16,7 +16,6 @@
|
||||
"prettier": "npm run prettier-preset -- --list-different",
|
||||
"prettier:fix": "npm run prettier-preset -- --write",
|
||||
"fix": "npm run lint-fix; npm run prettier:fix",
|
||||
"ci:check": "npm run parallel-cmd -- --names PRET,LINT \"npm run prettier\" \"npm run lint-cmd -- --quiet\"",
|
||||
"parallel-cmd": "concurrently --kill-others-on-fail --prefix-colors magenta,green,red,yellow,blue"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -4,7 +4,6 @@ const THRIFT_PROXY_CONFIG = {
|
||||
'/v3',
|
||||
'/stat',
|
||||
'/fistful',
|
||||
'/papi',
|
||||
'/file_storage',
|
||||
'/deanonimus',
|
||||
'/payout/management',
|
||||
|
22
src/app/api/claim-management/claim-management.service.ts
Normal file
22
src/app/api/claim-management/claim-management.service.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Injectable, Injector } from '@angular/core';
|
||||
import {
|
||||
codegenClientConfig,
|
||||
CodegenClient,
|
||||
} from '@vality/domain-proto/lib/claim_management-ClaimManagement';
|
||||
import context from '@vality/domain-proto/lib/claim_management/context';
|
||||
import * as service from '@vality/domain-proto/lib/claim_management/gen-nodejs/ClaimManagement';
|
||||
|
||||
import { createThriftApi } from '@cc/app/api/utils';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ClaimManagementService extends createThriftApi<CodegenClient>() {
|
||||
constructor(injector: Injector) {
|
||||
super(injector, {
|
||||
service,
|
||||
endpoint: '/v1/cm',
|
||||
metadata: () => import('@vality/domain-proto/lib/metadata.json').then((m) => m.default),
|
||||
context,
|
||||
...codegenClientConfig,
|
||||
});
|
||||
}
|
||||
}
|
2
src/app/api/claim-management/index.ts
Normal file
2
src/app/api/claim-management/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './claim-management.service';
|
||||
export * from './types';
|
1
src/app/api/claim-management/types/index.ts
Normal file
1
src/app/api/claim-management/types/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './claim-status';
|
@ -5,16 +5,10 @@ import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forRoot(
|
||||
[
|
||||
{
|
||||
path: '',
|
||||
redirectTo: '/old-payouts',
|
||||
pathMatch: 'full',
|
||||
},
|
||||
],
|
||||
{ paramsInheritanceStrategy: 'always', relativeLinkResolution: 'legacy' }
|
||||
),
|
||||
RouterModule.forRoot([], {
|
||||
paramsInheritanceStrategy: 'always',
|
||||
relativeLinkResolution: 'legacy',
|
||||
}),
|
||||
],
|
||||
providers: [AppAuthGuardService],
|
||||
exports: [RouterModule],
|
||||
|
@ -40,7 +40,7 @@ export class AppComponent implements OnInit {
|
||||
private getMenuItems() {
|
||||
const menuItems = [
|
||||
{ name: 'Domain config', route: '/domain', activateRoles: [DomainConfigRole.Checkout] },
|
||||
{ name: 'Payouts', route: '/old-payouts', activateRoles: [PayoutRole.Read] },
|
||||
{ name: 'Payouts', route: '/payouts', activateRoles: [PayoutRole.Read] },
|
||||
{ name: 'Claims', route: '/claims', activateRoles: [ClaimManagementRole.GetClaims] },
|
||||
{
|
||||
name: 'Payment adjustment',
|
||||
|
@ -21,12 +21,10 @@ import {
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { ClaimModule } from './claim/claim.module';
|
||||
import { CoreModule } from './core/core.module';
|
||||
import { DomainModule } from './domain';
|
||||
import icons from './icons.json';
|
||||
import { NotFoundModule } from './not-found';
|
||||
import { PayoutsModule as OldPayoutsModule } from './payouts/payouts.module';
|
||||
import { RepairingModule } from './repairing/repairing.module';
|
||||
import { DomainConfigModule } from './sections/domain-config';
|
||||
import { OperationsModule } from './sections/operations/operations.module';
|
||||
@ -66,8 +64,6 @@ moment.locale('en');
|
||||
MatMenuModule,
|
||||
MatSidenavModule,
|
||||
MatListModule,
|
||||
ClaimModule,
|
||||
OldPayoutsModule,
|
||||
PaymentAdjustmentModule,
|
||||
DomainModule,
|
||||
RepairingModule,
|
||||
|
@ -1,6 +0,0 @@
|
||||
<div class="mat-dialog-title">Confirm claim accepting</div>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [disabled]="isLoading" color="primary" (click)="accept()">CONFIRM</button>
|
||||
<button [disabled]="isLoading" mat-button [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,33 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { ClaimService } from '../claim.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'accept-claim.component.html',
|
||||
})
|
||||
export class AcceptClaimComponent {
|
||||
isLoading = false;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<AcceptClaimComponent>,
|
||||
private claimService: ClaimService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
accept() {
|
||||
this.isLoading = true;
|
||||
this.claimService.acceptClaim().subscribe(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.dialogRef.close();
|
||||
this.snackBar.open('Claim accepted', 'OK', { duration: 3000 });
|
||||
},
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while claim accepting', 'OK');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
export enum ClaimActionType {
|
||||
Create = 'create',
|
||||
Edit = 'edit',
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
<div *ngIf="claimInfoContainer.type === t.Create" fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Party ID:</label>
|
||||
<div>{{ claimInfoContainer?.partyId }}</div>
|
||||
</div>
|
||||
<div
|
||||
*ngIf="claimInfoContainer.type === t.Edit"
|
||||
fxLayout="row"
|
||||
fxLayoutGap="10px"
|
||||
fxLayout.sm="column"
|
||||
fxLayout.xs="column"
|
||||
>
|
||||
<div fxFlex="50" fxLayout="column" fxLayoutGap="10px">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Claim ID:</label>
|
||||
<div>{{ claimInfoContainer?.claimId }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Status:</label>
|
||||
<div>{{ claimInfoContainer?.status }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Revision:</label>
|
||||
<div>{{ claimInfoContainer?.revision }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column" *ngIf="claimInfoContainer?.reason">
|
||||
<label fxFlex="20">Reason:</label>
|
||||
<div>{{ claimInfoContainer.reason }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div fxFlex="50" fxLayout="column" fxLayoutGap="10px">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Party ID:</label>
|
||||
<div>{{ claimInfoContainer?.partyId }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Created At:</label>
|
||||
<div>{{ claimInfoContainer?.createdAt | date: 'dd.MM.yyyy HH:mm:ss' }}</div>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<label fxFlex="20">Updated At:</label>
|
||||
<div>{{ claimInfoContainer?.updatedAt | date: 'dd.MM.yyyy HH:mm:ss' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,15 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
|
||||
import { ClaimActionType } from '../../claim-action-type';
|
||||
import { ClaimInfoContainer } from '../../model';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-info-details',
|
||||
templateUrl: 'claim-info-details.component.html',
|
||||
})
|
||||
export class ClaimInfoDetailsComponent {
|
||||
@Input()
|
||||
claimInfoContainer: ClaimInfoContainer;
|
||||
|
||||
t = ClaimActionType;
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
||||
|
||||
import { ClaimInfoDetailsComponent } from './claim-info-details.component';
|
||||
|
||||
describe('ClaimInfoDetailsComponent', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ClaimInfoDetailsComponent],
|
||||
})
|
||||
.compileComponents()
|
||||
.then();
|
||||
}));
|
||||
|
||||
it('should create component', waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(ClaimInfoDetailsComponent);
|
||||
const component = fixture.debugElement.componentInstance;
|
||||
expect(component).toBeTruthy();
|
||||
}));
|
||||
|
||||
it('should render reason', waitForAsync(() => {
|
||||
const fixture = TestBed.createComponent(ClaimInfoDetailsComponent);
|
||||
const rendered = fixture.debugElement.componentInstance;
|
||||
expect(rendered).toBeTruthy();
|
||||
}));
|
||||
});
|
@ -1,64 +0,0 @@
|
||||
<mat-card *ngIf="claimInfoContainer">
|
||||
<mat-card-subtitle> Claim details</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<cc-claim-info-details [claimInfoContainer]="claimInfoContainer"></cc-claim-info-details>
|
||||
</mat-card-content>
|
||||
<mat-card-actions fxLayout="row" fxLayoutAlign="space-between stretch">
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<button
|
||||
mat-button
|
||||
[disabled]="
|
||||
(claimService.isLoading | async) ||
|
||||
!(claimService.isAddModificationAvailable | async)
|
||||
"
|
||||
(click)="add()"
|
||||
>
|
||||
ADD MODIFICATION
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
[disabled]="!hasUnsavedChanges() || (claimService.isLoading | async)"
|
||||
(click)="save()"
|
||||
>
|
||||
SAVE MODIFICATIONS
|
||||
</button>
|
||||
</div>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<button
|
||||
mat-button
|
||||
color="primary"
|
||||
[disabled]="hasUnsavedChanges() || (claimService.isLoading | async)"
|
||||
(click)="cloneClaim()"
|
||||
>
|
||||
CLONE CLAIM
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
color="primary"
|
||||
[disabled]="
|
||||
hasUnsavedChanges() ||
|
||||
claimInfoContainer?.status !== 'pending' ||
|
||||
(claimService.isLoading | async)
|
||||
"
|
||||
(click)="accept()"
|
||||
>
|
||||
ACCEPT CLAIM
|
||||
</button>
|
||||
<button
|
||||
mat-button
|
||||
color="warn"
|
||||
[disabled]="
|
||||
hasUnsavedChanges() ||
|
||||
claimInfoContainer?.status !== 'pending' ||
|
||||
(claimService.isLoading | async)
|
||||
"
|
||||
(click)="deny()"
|
||||
>
|
||||
DENY CLAIM
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer *ngIf="claimService.isLoading | async">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</mat-card-footer>
|
||||
</mat-card>
|
@ -1,101 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
import { UnitActionsNavListComponent } from '../../party-modification-creator-legacy';
|
||||
import { AcceptClaimComponent } from '../accept-claim/accept-claim.component';
|
||||
import { ClaimActionType } from '../claim-action-type';
|
||||
import { ClaimService } from '../claim.service';
|
||||
import { CloneClaimComponent } from '../clone-claim/clone-claim.component';
|
||||
import { DenyClaimComponent } from '../deny-claim/deny-claim.component';
|
||||
import { ClaimInfoContainer } from '../model';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-claim-info',
|
||||
templateUrl: 'claim-info.component.html',
|
||||
})
|
||||
export class ClaimInfoComponent implements OnInit {
|
||||
claimInfoContainer: ClaimInfoContainer;
|
||||
partyID: string;
|
||||
claimID: number;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
public claimService: ClaimService,
|
||||
private bottomSheet: MatBottomSheet,
|
||||
private snackBar: MatSnackBar,
|
||||
private dialog: MatDialog
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.claimService.claimInfoContainer$
|
||||
.pipe(filter((container) => container !== null))
|
||||
.subscribe((container) => {
|
||||
this.claimInfoContainer = container;
|
||||
this.partyID = container.partyId;
|
||||
this.claimID = container.claimId;
|
||||
});
|
||||
}
|
||||
|
||||
hasUnsavedChanges() {
|
||||
return this.claimService.hasUnsavedChanges();
|
||||
}
|
||||
|
||||
save() {
|
||||
switch (this.claimInfoContainer.type) {
|
||||
case ClaimActionType.Edit:
|
||||
this.claimService.saveChanges().subscribe(
|
||||
() => this.success(),
|
||||
(e) => this.failed(e)
|
||||
);
|
||||
break;
|
||||
case ClaimActionType.Create:
|
||||
this.claimService.createClaim().subscribe(
|
||||
(claimInfo) => {
|
||||
const editEndpoint = `/claims/${claimInfo.party_id}/${ClaimActionType.Edit}/${claimInfo.claim_id}`;
|
||||
this.router.navigate([editEndpoint]).then(() => this.success());
|
||||
},
|
||||
(e) => this.failed(e)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
add() {
|
||||
this.bottomSheet.open(UnitActionsNavListComponent, {
|
||||
data: { type: 'allActions', partyID: this.partyID },
|
||||
});
|
||||
}
|
||||
|
||||
cloneClaim() {
|
||||
this.dialog.open(CloneClaimComponent, {
|
||||
disableClose: true,
|
||||
data: { partyID: this.partyID, claimID: this.claimID },
|
||||
});
|
||||
}
|
||||
|
||||
accept() {
|
||||
this.dialog.open(AcceptClaimComponent, {
|
||||
disableClose: true,
|
||||
});
|
||||
}
|
||||
|
||||
deny() {
|
||||
this.dialog.open(DenyClaimComponent, {
|
||||
disableClose: true,
|
||||
width: '30vw',
|
||||
});
|
||||
}
|
||||
|
||||
private success() {
|
||||
this.snackBar.open('Changes saved', 'OK', { duration: 3000 });
|
||||
}
|
||||
|
||||
private failed(error) {
|
||||
console.error(error);
|
||||
this.snackBar.open('An error occurred', 'OK');
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppAuthGuardService, ClaimManagementRole } from '@cc/app/shared/services';
|
||||
|
||||
import { ClaimComponent } from './claim.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: 'claims/:party_id/:action/:claim_id',
|
||||
component: ClaimComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: [ClaimManagementRole.GetClaims],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'claims/:party_id/:action',
|
||||
component: ClaimComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: [ClaimManagementRole.GetClaims],
|
||||
},
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class ClaimRoutingModule {}
|
@ -1,4 +0,0 @@
|
||||
<cc-card-container>
|
||||
<cc-claim-info></cc-claim-info>
|
||||
<cc-party-modifications></cc-party-modifications>
|
||||
</cc-card-container>
|
@ -1,31 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimService } from './claim.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'claim.component.html',
|
||||
styleUrls: [],
|
||||
})
|
||||
export class ClaimComponent {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private claimService: ClaimService,
|
||||
private snackBar: MatSnackBar
|
||||
) {
|
||||
this.route.params
|
||||
.pipe(
|
||||
switchMap(({ action, party_id, claim_id }) =>
|
||||
this.claimService.resolveClaimInfo(action, party_id, claim_id)
|
||||
)
|
||||
)
|
||||
.subscribe({
|
||||
error: (error) => {
|
||||
console.error(error);
|
||||
this.snackBar.open('An error occurred while claim resolving', 'OK');
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatNativeDateModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
|
||||
import { CardContainerModule } from '@cc/components/card-container/card-container.module';
|
||||
import { PrettyJsonModule } from '@cc/components/pretty-json';
|
||||
|
||||
import { PapiModule } from '../papi/papi.module';
|
||||
import {
|
||||
ModificationNameModule,
|
||||
PartyModificationCreatorLegacyModule,
|
||||
} from '../party-modification-creator-legacy';
|
||||
import { DamselModule } from '../thrift-services/damsel';
|
||||
import { AcceptClaimComponent } from './accept-claim/accept-claim.component';
|
||||
import { ClaimInfoDetailsComponent } from './claim-info/claim-info-details/claim-info-details.component';
|
||||
import { ClaimInfoComponent } from './claim-info/claim-info.component';
|
||||
import { ClaimRoutingModule } from './claim-routing.module';
|
||||
import { ClaimComponent } from './claim.component';
|
||||
import { ClaimService } from './claim.service';
|
||||
import { CloneClaimComponent } from './clone-claim/clone-claim.component';
|
||||
import { DenyClaimComponent } from './deny-claim/deny-claim.component';
|
||||
import { PartyModificationContainerComponent } from './party-modification-container/party-modification-container.component';
|
||||
import { PartyModificationContainerService } from './party-modification-container/party-modification-container.service';
|
||||
import { RemoveConfirmComponent } from './party-modification-container/remove-confirm/remove-confirm.component';
|
||||
import { PartyModificationUnitsComponent } from './party-modification-units/party-modification-units.component';
|
||||
import { PartyModificationsComponent } from './party-modifications/party-modifications.component';
|
||||
import { PersistentContainerService } from './persistent-container.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
PapiModule,
|
||||
DamselModule,
|
||||
CommonModule,
|
||||
ReactiveFormsModule,
|
||||
ClaimRoutingModule,
|
||||
FlexLayoutModule,
|
||||
MatCardModule,
|
||||
MatButtonModule,
|
||||
MatTabsModule,
|
||||
MatBottomSheetModule,
|
||||
MatListModule,
|
||||
MatIconModule,
|
||||
MatDialogModule,
|
||||
MatInputModule,
|
||||
MatDatepickerModule,
|
||||
MatNativeDateModule,
|
||||
MatDividerModule,
|
||||
MatSelectModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatSnackBarModule,
|
||||
MatRadioModule,
|
||||
MatStepperModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
PartyModificationCreatorLegacyModule,
|
||||
ModificationNameModule,
|
||||
PrettyJsonModule,
|
||||
CardContainerModule,
|
||||
],
|
||||
declarations: [
|
||||
ClaimComponent,
|
||||
ClaimInfoComponent,
|
||||
ClaimInfoDetailsComponent,
|
||||
PartyModificationsComponent,
|
||||
PartyModificationContainerComponent,
|
||||
CloneClaimComponent,
|
||||
AcceptClaimComponent,
|
||||
DenyClaimComponent,
|
||||
PartyModificationUnitsComponent,
|
||||
RemoveConfirmComponent,
|
||||
],
|
||||
entryComponents: [
|
||||
CloneClaimComponent,
|
||||
AcceptClaimComponent,
|
||||
DenyClaimComponent,
|
||||
RemoveConfirmComponent,
|
||||
],
|
||||
providers: [ClaimService, PersistentContainerService, PartyModificationContainerService],
|
||||
})
|
||||
export class ClaimModule {}
|
@ -1,275 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
|
||||
import isEqual from 'lodash-es/isEqual';
|
||||
import toNumber from 'lodash-es/toNumber';
|
||||
import { BehaviorSubject, Observable, of, Subject, throwError } from 'rxjs';
|
||||
import { delay, map, repeatWhen, retryWhen, switchMap, takeWhile, tap } from 'rxjs/operators';
|
||||
|
||||
import { ClaimService as ClaimPapi } from '../papi/claim.service';
|
||||
import { ClaimInfo, ClaimStatus, PartyModificationUnit } from '../papi/model';
|
||||
import { PartyModificationEmitter } from '../party-modification-creator-legacy';
|
||||
import { ClaimActionType } from './claim-action-type';
|
||||
import { ClaimInfoContainer, ModificationGroup, PersistentContainer } from './model';
|
||||
import { convert } from './party-modification-group-converter';
|
||||
import { PersistentContainerService } from './persistent-container.service';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
claimInfoContainer$: Subject<ClaimInfoContainer> = new BehaviorSubject(null);
|
||||
|
||||
modificationGroups$: Subject<ModificationGroup[]> = new Subject();
|
||||
|
||||
private isLoading$: Subject<boolean> = new BehaviorSubject(false);
|
||||
|
||||
private isAddModificationAvailable$: Subject<boolean> = new BehaviorSubject(false);
|
||||
|
||||
private claimInfoContainer: ClaimInfoContainer;
|
||||
|
||||
private containers: PersistentContainer[];
|
||||
|
||||
get isLoading(): Observable<boolean> {
|
||||
return this.isLoading$;
|
||||
}
|
||||
|
||||
get isAddModificationAvailable(): Observable<boolean> {
|
||||
return this.isAddModificationAvailable$;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private papiClaimService: ClaimPapi,
|
||||
private persistentContainerService: PersistentContainerService,
|
||||
private partyModificationEmitter: PartyModificationEmitter
|
||||
) {
|
||||
this.persistentContainerService.containers$.subscribe((containers) => {
|
||||
this.containers = containers;
|
||||
this.modificationGroups$.next(convert(containers));
|
||||
});
|
||||
this.partyModificationEmitter.modification$.subscribe((modification) =>
|
||||
this.persistentContainerService.add(modification)
|
||||
);
|
||||
}
|
||||
|
||||
resolveClaimInfo(type: ClaimActionType, partyId: string, claimId?: string): Observable<void> {
|
||||
switch (type) {
|
||||
case ClaimActionType.Create:
|
||||
if (claimId) {
|
||||
return this.getClaimInfo(partyId, claimId).pipe(
|
||||
tap((claimInfo) => {
|
||||
this.persistentContainerService.init(
|
||||
claimInfo.modifications.modifications,
|
||||
false
|
||||
);
|
||||
this.claimInfoContainer = { type, partyId };
|
||||
this.claimInfoContainer$.next(this.claimInfoContainer);
|
||||
}),
|
||||
map(() => null),
|
||||
tap(() => this.isAddModificationAvailable$.next(this.getAvailability()))
|
||||
);
|
||||
} else {
|
||||
this.persistentContainerService.init([]);
|
||||
this.claimInfoContainer = { type, partyId };
|
||||
this.claimInfoContainer$.next(this.claimInfoContainer);
|
||||
this.isAddModificationAvailable$.next(this.getAvailability());
|
||||
return of();
|
||||
}
|
||||
case ClaimActionType.Edit:
|
||||
return this.getClaimInfo(partyId, claimId).pipe(
|
||||
tap((claimInfo) => {
|
||||
this.persistentContainerService.init(claimInfo.modifications.modifications);
|
||||
this.claimInfoContainer = this.toClaimInfoContainer(claimInfo);
|
||||
this.claimInfoContainer$.next(this.claimInfoContainer);
|
||||
}),
|
||||
map(() => null),
|
||||
tap(() => this.isAddModificationAvailable$.next(this.getAvailability()))
|
||||
);
|
||||
}
|
||||
return throwError('Unsupported claim action type');
|
||||
}
|
||||
|
||||
removeModification(typeHash: string) {
|
||||
this.persistentContainerService.remove(typeHash);
|
||||
}
|
||||
|
||||
saveChanges(): Observable<void> {
|
||||
this.isLoading$.next(true);
|
||||
const { partyId, claimId } = this.claimInfoContainer;
|
||||
const units = this.toModificationUnits(this.containers);
|
||||
return this.papiClaimService.getClaim(partyId, claimId).pipe(
|
||||
switchMap((claimInfo) =>
|
||||
this.papiClaimService
|
||||
.updateClaim(partyId, claimId, claimInfo.revision, units)
|
||||
.pipe(map(() => claimInfo.revision))
|
||||
),
|
||||
switchMap((revision) => this.pollClaimChange(revision)),
|
||||
tap(() => this.isLoading$.next(false))
|
||||
);
|
||||
}
|
||||
|
||||
createClaim(): Observable<ClaimInfo> {
|
||||
this.isLoading$.next(true);
|
||||
const units = this.toModificationUnits(this.containers);
|
||||
return this.papiClaimService.createClaim(this.claimInfoContainer.partyId, units).pipe(
|
||||
switchMap((createdClaim) =>
|
||||
this.pollClaimCreated(this.claimInfoContainer.partyId, createdClaim.claimId)
|
||||
),
|
||||
tap(() => this.isLoading$.next(false))
|
||||
);
|
||||
}
|
||||
|
||||
acceptClaim(): Observable<void> {
|
||||
const { claimId, partyId } = this.claimInfoContainer;
|
||||
return this.papiClaimService.getClaim(partyId, claimId).pipe(
|
||||
switchMap((claimInfo) =>
|
||||
this.papiClaimService
|
||||
.acceptClaim({
|
||||
partyId,
|
||||
claimId,
|
||||
revision: claimInfo.revision,
|
||||
})
|
||||
.pipe(map(() => claimInfo.revision))
|
||||
),
|
||||
switchMap((revision) => this.pollClaimChange(revision)),
|
||||
tap(() => this.isLoading$.next(false))
|
||||
);
|
||||
}
|
||||
|
||||
denyClaim(reason: string): Observable<void> {
|
||||
const { claimId, partyId } = this.claimInfoContainer;
|
||||
return this.papiClaimService.getClaim(partyId, claimId).pipe(
|
||||
switchMap((claimInfo) =>
|
||||
this.papiClaimService
|
||||
.denyClaim({
|
||||
claimId,
|
||||
partyId,
|
||||
revision: claimInfo.revision,
|
||||
reason,
|
||||
})
|
||||
.pipe(map(() => claimInfo.revision))
|
||||
),
|
||||
switchMap((revision) => this.pollClaimChange(revision)),
|
||||
tap(() => this.isLoading$.next(false))
|
||||
);
|
||||
}
|
||||
|
||||
hasUnsavedChanges(): boolean {
|
||||
return this.containers ? this.containers.filter((i) => !i.saved).length > 0 : false;
|
||||
}
|
||||
|
||||
private getAvailability(): boolean {
|
||||
switch (this.claimInfoContainer.type) {
|
||||
case ClaimActionType.Edit:
|
||||
return this.claimInfoContainer.status === ClaimStatus.Pending;
|
||||
case ClaimActionType.Create:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private toModificationUnits(containers: PersistentContainer[]): PartyModificationUnit {
|
||||
return {
|
||||
modifications: containers.reduce(
|
||||
(acc, { saved, modification }) => (saved ? acc : acc.concat(modification)),
|
||||
[]
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
private toClaimInfoContainer(claimInfo: ClaimInfo): ClaimInfoContainer {
|
||||
const modifications = claimInfo.modifications.modifications;
|
||||
const { claim_id, party_id, revision, status, reason, created_at, updated_at } = claimInfo;
|
||||
const extractedIds = this.extractIds(modifications);
|
||||
return {
|
||||
type: ClaimActionType.Edit,
|
||||
claimId: claim_id,
|
||||
partyId: party_id,
|
||||
revision,
|
||||
status,
|
||||
reason,
|
||||
createdAt: created_at,
|
||||
updatedAt: updated_at,
|
||||
extractedIds,
|
||||
};
|
||||
}
|
||||
|
||||
private extractIds(modifications: PartyModification[]): { shopId: string; contractId: string } {
|
||||
return modifications.reduce(
|
||||
(prev, current) => {
|
||||
if (!prev.shopId && current.shop_modification) {
|
||||
const shopId = current.shop_modification.id;
|
||||
return { ...prev, shopId };
|
||||
} else if (!prev.contractId && current.contract_modification) {
|
||||
const contractId = current.contract_modification.id;
|
||||
return { ...prev, contractId };
|
||||
} else {
|
||||
return prev;
|
||||
}
|
||||
},
|
||||
{ shopId: null, contractId: null }
|
||||
);
|
||||
}
|
||||
|
||||
private getClaimInfo(partyId: string, claimId: string): Observable<ClaimInfo> {
|
||||
return this.papiClaimService.getClaim(partyId, toNumber(claimId));
|
||||
}
|
||||
|
||||
private pollClaimChange(revision: string, delayMs = 2000, retryCount = 15): Observable<void> {
|
||||
const container = this.claimInfoContainer;
|
||||
const { partyId, claimId, status } = container;
|
||||
const currentPair = { status, revision };
|
||||
let newPair = {};
|
||||
return new Observable((observer) => {
|
||||
this.papiClaimService
|
||||
.getClaim(partyId, claimId)
|
||||
.pipe(
|
||||
repeatWhen((notifications) =>
|
||||
notifications.pipe(
|
||||
delay(delayMs),
|
||||
takeWhile(
|
||||
(_, retries) =>
|
||||
isEqual(newPair, currentPair) && retries <= retryCount
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe((claimInfo) => {
|
||||
newPair = {
|
||||
status: claimInfo.status,
|
||||
revision: claimInfo.revision,
|
||||
};
|
||||
if (!isEqual(newPair, currentPair)) {
|
||||
this.claimInfoContainer = this.toClaimInfoContainer(claimInfo);
|
||||
this.claimInfoContainer$.next(this.claimInfoContainer);
|
||||
this.persistentContainerService.init(claimInfo.modifications.modifications);
|
||||
observer.next();
|
||||
observer.complete();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private pollClaimCreated(
|
||||
partyId: string,
|
||||
claimId: number,
|
||||
delayMs = 2000,
|
||||
retryCount = 15
|
||||
): Observable<ClaimInfo> {
|
||||
return new Observable<ClaimInfo>((observer) => {
|
||||
this.papiClaimService
|
||||
.getClaim(partyId, claimId)
|
||||
.pipe(
|
||||
retryWhen((err) =>
|
||||
err.pipe(
|
||||
delay(delayMs),
|
||||
takeWhile(
|
||||
(error, retries) => error.status === 404 && retries <= retryCount
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.subscribe((claimInfo) => {
|
||||
observer.next(claimInfo);
|
||||
observer.complete();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<div class="mat-dialog-title">Confirm claim cloning</div>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="primary" (click)="cloneClaim()">CONFIRM</button>
|
||||
<button mat-button [mat-dialog-close]="false">CANCEL</button>
|
||||
</mat-dialog-actions>
|
@ -1,28 +0,0 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { ClaimActionType } from '../claim-action-type';
|
||||
|
||||
interface RouteData {
|
||||
partyID: string;
|
||||
claimID: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: 'clone-claim.component.html',
|
||||
})
|
||||
export class CloneClaimComponent {
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<CloneClaimComponent>,
|
||||
private router: Router,
|
||||
@Inject(MAT_DIALOG_DATA) private data: RouteData
|
||||
) {}
|
||||
|
||||
cloneClaim() {
|
||||
this.dialogRef.close();
|
||||
this.router.navigate([
|
||||
`/claims/${this.data.partyID}/${ClaimActionType.Create}/${this.data.claimID}`,
|
||||
]);
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<div class="mat-dialog-title">Confirm claim denying</div>
|
||||
<mat-dialog-content>
|
||||
<form fxLayout="row">
|
||||
<mat-form-field fxFlex class="example-full-width">
|
||||
<textarea matInput placeholder="Reason" [(ngModel)]="reason" name="reason"> </textarea>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button [disabled]="isLoading" color="primary" (click)="deny()">CONFIRM</button>
|
||||
<button [disabled]="isLoading" mat-button [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,35 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { ClaimService } from '../claim.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'deny-claim.component.html',
|
||||
})
|
||||
export class DenyClaimComponent {
|
||||
isLoading = false;
|
||||
|
||||
reason = '';
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<DenyClaimComponent>,
|
||||
private claimService: ClaimService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
deny() {
|
||||
this.isLoading = true;
|
||||
this.claimService.denyClaim(this.reason).subscribe(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.dialogRef.close();
|
||||
this.snackBar.open('Claim denied', 'OK', { duration: 3000 });
|
||||
},
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while claim denying', 'OK');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { ClaimStatus } from '../../papi/model';
|
||||
import { ClaimActionType } from '../claim-action-type';
|
||||
|
||||
export class ClaimInfoContainer {
|
||||
type: ClaimActionType;
|
||||
status?: ClaimStatus;
|
||||
partyId?: string;
|
||||
claimId?: number;
|
||||
revision?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
reason?: string;
|
||||
extractedIds?: {
|
||||
shopId: string;
|
||||
contractId: string;
|
||||
};
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
export * from './claim-info-container';
|
||||
export * from './party-modification-container';
|
||||
export * from './party-modification-unit';
|
||||
export * from './modification-group';
|
||||
export * from './modification-group-type';
|
||||
export * from './modification-unit-container';
|
||||
export * from './persistent-container';
|
@ -1,6 +0,0 @@
|
||||
export enum ModificationGroupType {
|
||||
ShopUnitContainer = 'ShopUnitContainer',
|
||||
ContractUnitContainer = 'ContractUnitContainer',
|
||||
ContractorUnitContainer = 'ContractorUnitContainer',
|
||||
Unknown = 'unknown',
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { ModificationGroupType } from './modification-group-type';
|
||||
import { PartyModificationUnit } from './party-modification-unit';
|
||||
|
||||
export class ModificationGroup {
|
||||
type: ModificationGroupType;
|
||||
units?: PartyModificationUnit[];
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import {
|
||||
ContractModificationUnit,
|
||||
ShopModificationUnit,
|
||||
} from '@vality/domain-proto/lib/payment_processing';
|
||||
|
||||
export class ModificationUnitContainer {
|
||||
saved: boolean;
|
||||
typeHash?: string;
|
||||
modificationUnit: ContractModificationUnit | ShopModificationUnit;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import {
|
||||
ContractModificationName,
|
||||
ShopModificationName,
|
||||
} from '../../party-modification-creator-legacy';
|
||||
import { ModificationUnitContainer } from './modification-unit-container';
|
||||
|
||||
export class PartyModificationContainer {
|
||||
name: ContractModificationName | ShopModificationName;
|
||||
unitContainers: ModificationUnitContainer[];
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { PartyModificationContainer } from './party-modification-container';
|
||||
|
||||
export class PartyModificationUnit {
|
||||
unitID: string;
|
||||
hasUnsaved: boolean;
|
||||
containers: PartyModificationContainer[];
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
|
||||
|
||||
export class PersistentContainer {
|
||||
modification: PartyModification;
|
||||
saved: boolean;
|
||||
typeHash?: string;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import {
|
||||
ContractModificationName,
|
||||
ContractorModificationName,
|
||||
ShopModificationName,
|
||||
} from '../party-modification-creator-legacy';
|
||||
|
||||
export enum ActionType {
|
||||
ContractAction = 'contractAction',
|
||||
ShopAction = 'shopAction',
|
||||
ContractorAction = 'contractorAction',
|
||||
}
|
||||
|
||||
export interface ModificationAction {
|
||||
type: ActionType;
|
||||
name?: ContractModificationName | ShopModificationName | ContractorModificationName;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<mat-card>
|
||||
<mat-card-subtitle>{{ container.name | ccModificationName: type }}</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<mat-tab-group (selectedIndexChange)="onChangeTabIndex($event)">
|
||||
<mat-tab *ngFor="let unit of modifications; let index = index">
|
||||
<ng-template mat-tab-label>
|
||||
{{ 'unit ' + (index + 1) }}
|
||||
<span class="unsaved-label">{{ unit.saved ? '' : '*' }}</span>
|
||||
</ng-template>
|
||||
<cc-pretty-json
|
||||
[object]="unit.modificationUnit"
|
||||
[cleanLook]="true"
|
||||
></cc-pretty-json>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card-content>
|
||||
<mat-card-actions *ngIf="!activeUnit?.saved" fxLayoutAlign="end center">
|
||||
<button mat-button color="primary" (click)="edit()">EDIT</button>
|
||||
<button mat-button color="warn" (click)="remove()">REMOVE</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
@ -1,5 +0,0 @@
|
||||
.unsaved-label {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
margin-left: 3px;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
|
||||
import { CreateModificationDialogComponent } from '../../party-modification-creator-legacy';
|
||||
import {
|
||||
ModificationGroupType,
|
||||
ModificationUnitContainer,
|
||||
PartyModificationContainer,
|
||||
} from '../model';
|
||||
import { PartyModificationContainerService } from './party-modification-container.service';
|
||||
import { RemoveConfirmComponent } from './remove-confirm/remove-confirm.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-party-modification-container',
|
||||
templateUrl: 'party-modification-container.component.html',
|
||||
styleUrls: ['./party-modification-container.component.scss'],
|
||||
})
|
||||
export class PartyModificationContainerComponent implements OnInit {
|
||||
@Input()
|
||||
container: PartyModificationContainer;
|
||||
|
||||
@Input()
|
||||
type: ModificationGroupType;
|
||||
|
||||
@Input()
|
||||
partyID: string;
|
||||
|
||||
modifications: ModificationUnitContainer[];
|
||||
|
||||
activeUnit: ModificationUnitContainer;
|
||||
|
||||
constructor(
|
||||
private dialog: MatDialog,
|
||||
private partyModificationContainerService: PartyModificationContainerService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.modifications = this.container.unitContainers.slice();
|
||||
this.activeUnit = this.modifications[0];
|
||||
}
|
||||
|
||||
remove() {
|
||||
const config = {
|
||||
data: {
|
||||
typeHash: this.activeUnit.typeHash,
|
||||
},
|
||||
};
|
||||
this.dialog.open<RemoveConfirmComponent>(RemoveConfirmComponent, config);
|
||||
}
|
||||
|
||||
edit() {
|
||||
const config = this.partyModificationContainerService.getDialogConfig(
|
||||
this.activeUnit.modificationUnit,
|
||||
this.container.name,
|
||||
this.type,
|
||||
this.partyID
|
||||
);
|
||||
this.dialog.open<CreateModificationDialogComponent>(
|
||||
CreateModificationDialogComponent,
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
onChangeTabIndex(index) {
|
||||
this.activeUnit = this.modifications[index];
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
ContractModificationUnit,
|
||||
ShopModificationUnit,
|
||||
} from '@vality/domain-proto/lib/payment_processing';
|
||||
|
||||
import {
|
||||
ContractModificationName,
|
||||
ShopModificationName,
|
||||
} from '../../party-modification-creator-legacy';
|
||||
import { ModificationGroupType } from '../model';
|
||||
import { ActionType } from '../modification-action';
|
||||
|
||||
@Injectable()
|
||||
export class PartyModificationContainerService {
|
||||
getDialogConfig(
|
||||
modification: ShopModificationUnit | ContractModificationUnit,
|
||||
name: ContractModificationName | ShopModificationName,
|
||||
type: string,
|
||||
partyID: string
|
||||
) {
|
||||
const actionType = this.getActionType(type);
|
||||
const unitID = modification.id;
|
||||
return {
|
||||
data: {
|
||||
action: {
|
||||
type: actionType,
|
||||
name,
|
||||
},
|
||||
unitID,
|
||||
partyID,
|
||||
modification,
|
||||
},
|
||||
width: '800px',
|
||||
disableClose: true,
|
||||
};
|
||||
}
|
||||
|
||||
private getActionType(type): ActionType {
|
||||
switch (type) {
|
||||
case ModificationGroupType.ContractUnitContainer:
|
||||
return ActionType.ContractAction;
|
||||
case ModificationGroupType.ShopUnitContainer:
|
||||
return ActionType.ShopAction;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
<div class="mat-dialog-title">Confirm remove</div>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="primary" (click)="remove()">CONFIRM</button>
|
||||
<button mat-button [mat-dialog-close]="false">CANCEL</button>
|
||||
</mat-dialog-actions>
|
@ -1,24 +0,0 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
|
||||
import { ClaimService } from '../../claim.service';
|
||||
|
||||
interface RemoveData {
|
||||
typeHash: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
templateUrl: 'remove-confirm.component.html',
|
||||
})
|
||||
export class RemoveConfirmComponent {
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<RemoveConfirmComponent>,
|
||||
private claimService: ClaimService,
|
||||
@Inject(MAT_DIALOG_DATA) private data: RemoveData
|
||||
) {}
|
||||
|
||||
remove() {
|
||||
this.dialogRef.close();
|
||||
this.claimService.removeModification(this.data.typeHash);
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
import {
|
||||
ContractModificationUnit,
|
||||
ContractorModificationUnit,
|
||||
ShopModificationUnit,
|
||||
} from '@vality/domain-proto/lib/claim_management';
|
||||
import groupBy from 'lodash-es/groupBy';
|
||||
import map from 'lodash-es/map';
|
||||
|
||||
import { UnitName } from '../party-modification-creator-legacy/party-modification-creation/unit-name';
|
||||
import {
|
||||
ModificationGroup,
|
||||
ModificationGroupType,
|
||||
PartyModificationUnit,
|
||||
PersistentContainer,
|
||||
} from './model';
|
||||
|
||||
interface PersistentUnit {
|
||||
modificationUnit: ShopModificationUnit | ContractModificationUnit | ContractorModificationUnit;
|
||||
saved: boolean;
|
||||
typeHash: string;
|
||||
}
|
||||
|
||||
const toContainers = (persistentUnits: PersistentUnit[]): any[] => {
|
||||
const grouped = groupBy(persistentUnits, (item) => {
|
||||
const modificationNames = Object.keys(item.modificationUnit.modification);
|
||||
if (modificationNames.length !== 1) {
|
||||
return 'unknown';
|
||||
}
|
||||
return modificationNames[0];
|
||||
});
|
||||
return map(grouped, (units, name) => ({
|
||||
name,
|
||||
unitContainers: units.map(({ modificationUnit, saved, typeHash }) => ({
|
||||
modificationUnit,
|
||||
saved,
|
||||
typeHash,
|
||||
})),
|
||||
}));
|
||||
};
|
||||
|
||||
const isHasUnsaved = (units: PersistentUnit[], unitID: string): boolean =>
|
||||
units.filter((i) => !i.saved && i.modificationUnit.id === unitID).length > 0;
|
||||
|
||||
const toUnits = (persistentUnits: PersistentUnit[]): PartyModificationUnit[] => {
|
||||
const grouped = groupBy(persistentUnits, (item) => item.modificationUnit.id);
|
||||
return map(grouped, (units, unitID) => ({
|
||||
unitID,
|
||||
hasUnsaved: isHasUnsaved(units, unitID),
|
||||
containers: toContainers(units),
|
||||
}));
|
||||
};
|
||||
|
||||
const toGroup = (
|
||||
name: UnitName,
|
||||
type: ModificationGroupType,
|
||||
containers: PersistentContainer[]
|
||||
): ModificationGroup => {
|
||||
const persistent = containers.map(({ modification, saved, typeHash }) => ({
|
||||
modificationUnit: modification[name],
|
||||
typeHash,
|
||||
saved,
|
||||
}));
|
||||
return {
|
||||
type,
|
||||
units: toUnits(persistent),
|
||||
};
|
||||
};
|
||||
|
||||
export const convert = (containers: PersistentContainer[]): ModificationGroup[] => {
|
||||
const grouped = groupBy(containers, (item) => {
|
||||
const { shop_modification, contract_modification } = item.modification;
|
||||
if (shop_modification) {
|
||||
return ModificationGroupType.ShopUnitContainer;
|
||||
}
|
||||
if (contract_modification) {
|
||||
return ModificationGroupType.ContractUnitContainer;
|
||||
}
|
||||
return ModificationGroupType.Unknown;
|
||||
});
|
||||
return map(grouped, (persistentContainer, type) => {
|
||||
switch (type) {
|
||||
case ModificationGroupType.ShopUnitContainer:
|
||||
return toGroup(UnitName.ShopModification, type, persistentContainer);
|
||||
case ModificationGroupType.ContractUnitContainer:
|
||||
return toGroup(UnitName.ContractModification, type, persistentContainer);
|
||||
case ModificationGroupType.Unknown:
|
||||
return { type: ModificationGroupType.Unknown };
|
||||
}
|
||||
});
|
||||
};
|
@ -1,37 +0,0 @@
|
||||
<div fxLayout="column" fxLayoutGap="5px">
|
||||
<mat-card>
|
||||
<mat-card-subtitle>{{
|
||||
type === 'ShopUnitContainer'
|
||||
? 'Shop modification units'
|
||||
: type === 'ContractUnitContainer'
|
||||
? 'Contract modification units'
|
||||
: ''
|
||||
}}</mat-card-subtitle>
|
||||
</mat-card>
|
||||
<mat-tab-group>
|
||||
<mat-tab *ngFor="let unit of units">
|
||||
<ng-template mat-tab-label>
|
||||
{{ unit.unitID }}
|
||||
<span class="unsaved-label">{{ !unit.hasUnsaved ? '' : '*' }}</span>
|
||||
</ng-template>
|
||||
<div class="tab-container" fxLayout="column" fxLayoutGap="10px">
|
||||
<div class="add-modification-container" fxLayoutAlign="end center">
|
||||
<button
|
||||
mat-button
|
||||
[disabled]="(isLoading | async) || !(isAddModificationAvailable | async)"
|
||||
(click)="add(unit.unitID)"
|
||||
>
|
||||
ADD MODIFICATION
|
||||
</button>
|
||||
</div>
|
||||
<cc-party-modification-container
|
||||
*ngFor="let container of unit.containers"
|
||||
[container]="container"
|
||||
[type]="type"
|
||||
[partyID]="partyID"
|
||||
>
|
||||
</cc-party-modification-container>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
@ -1,13 +0,0 @@
|
||||
.tab-container {
|
||||
margin: 3px;
|
||||
}
|
||||
|
||||
.unsaved-label {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.add-modification-container {
|
||||
padding-top: 5px;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { MatBottomSheet } from '@angular/material/bottom-sheet';
|
||||
|
||||
import { UnitActionsNavListComponent } from '../../party-modification-creator-legacy';
|
||||
import { ClaimService } from '../claim.service';
|
||||
import { ModificationGroupType, PartyModificationUnit } from '../model';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-party-modification-units',
|
||||
templateUrl: 'party-modification-units.component.html',
|
||||
styleUrls: ['./party-modification-units.component.scss'],
|
||||
})
|
||||
export class PartyModificationUnitsComponent {
|
||||
@Input()
|
||||
type: ModificationGroupType;
|
||||
|
||||
@Input()
|
||||
units: PartyModificationUnit[];
|
||||
|
||||
@Input()
|
||||
partyID: string;
|
||||
|
||||
isLoading = this.claimService.isLoading;
|
||||
isAddModificationAvailable = this.claimService.isAddModificationAvailable;
|
||||
|
||||
constructor(private bottomSheet: MatBottomSheet, private claimService: ClaimService) {}
|
||||
|
||||
add(unitID: string) {
|
||||
let type: string;
|
||||
switch (this.type) {
|
||||
case ModificationGroupType.ContractUnitContainer:
|
||||
type = 'contractActions';
|
||||
break;
|
||||
case ModificationGroupType.ShopUnitContainer:
|
||||
type = 'shopActions';
|
||||
break;
|
||||
case ModificationGroupType.ContractorUnitContainer:
|
||||
type = 'contractorActions';
|
||||
break;
|
||||
default:
|
||||
type = 'allActions';
|
||||
break;
|
||||
}
|
||||
this.bottomSheet.open(UnitActionsNavListComponent, {
|
||||
data: { type, unitID, partyID: this.partyID },
|
||||
});
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayout.md="column"
|
||||
fxLayout.sm="column"
|
||||
fxLayout.xs="column"
|
||||
fxLayoutGap="10px"
|
||||
>
|
||||
<div fxFlex="50" *ngIf="shopUnits.length > 0">
|
||||
<cc-party-modification-units
|
||||
unitsName="Shop modification units"
|
||||
[type]="'ShopUnitContainer'"
|
||||
[units]="shopUnits"
|
||||
[partyID]="partyID$ | async"
|
||||
>
|
||||
</cc-party-modification-units>
|
||||
</div>
|
||||
<div fxFlex="50" *ngIf="contractUnits.length > 0">
|
||||
<cc-party-modification-units
|
||||
unitsName="Contract modification units"
|
||||
[type]="'ContractUnitContainer'"
|
||||
[units]="contractUnits"
|
||||
[partyID]="partyID$ | async"
|
||||
>
|
||||
</cc-party-modification-units>
|
||||
</div>
|
||||
</div>
|
@ -1,50 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { first, pluck, shareReplay } from 'rxjs/operators';
|
||||
|
||||
import { ClaimService } from '../claim.service';
|
||||
import { ModificationGroupType, PartyModificationUnit } from '../model';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-party-modifications',
|
||||
templateUrl: 'party-modifications.component.html',
|
||||
})
|
||||
export class PartyModificationsComponent implements OnInit {
|
||||
shopUnits: PartyModificationUnit[] = [];
|
||||
|
||||
contractUnits: PartyModificationUnit[] = [];
|
||||
|
||||
partyID$: Observable<string> = this.route.params.pipe(
|
||||
pluck('party_id'),
|
||||
first(),
|
||||
shareReplay(1)
|
||||
);
|
||||
|
||||
constructor(
|
||||
private claimService: ClaimService,
|
||||
private snackBar: MatSnackBar,
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.claimService.modificationGroups$.subscribe((groups) => {
|
||||
this.shopUnits = [];
|
||||
this.contractUnits = [];
|
||||
for (const group of groups) {
|
||||
switch (group.type) {
|
||||
case ModificationGroupType.ShopUnitContainer:
|
||||
this.shopUnits = this.shopUnits.concat(group.units);
|
||||
break;
|
||||
case ModificationGroupType.ContractUnitContainer:
|
||||
this.contractUnits = this.contractUnits.concat(group.units);
|
||||
break;
|
||||
case ModificationGroupType.Unknown:
|
||||
this.snackBar.open('Detected unknown party modification unit', 'OK');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
|
||||
import remove from 'lodash-es/remove';
|
||||
import { Subject } from 'rxjs';
|
||||
|
||||
import { PersistentContainer } from './model';
|
||||
|
||||
@Injectable()
|
||||
export class PersistentContainerService {
|
||||
containers$: Subject<PersistentContainer[]> = new Subject();
|
||||
private containers: PersistentContainer[] = [];
|
||||
|
||||
init(persisted: PartyModification[], saved = true) {
|
||||
this.containers = persisted.map((modification) => ({
|
||||
modification,
|
||||
saved,
|
||||
typeHash: !saved ? this.makeTypeHash(modification) : null,
|
||||
}));
|
||||
this.containers$.next(this.containers);
|
||||
}
|
||||
|
||||
add(modification: PartyModification) {
|
||||
const typeHash = this.makeTypeHash(modification);
|
||||
const item = {
|
||||
modification,
|
||||
typeHash,
|
||||
saved: false,
|
||||
};
|
||||
const index = this.containers.findIndex((i) => i.typeHash === typeHash);
|
||||
if (index !== -1) {
|
||||
this.containers[index] = item;
|
||||
} else {
|
||||
this.containers.push(item);
|
||||
}
|
||||
this.containers$.next(this.containers.sort(this.sort)); // sort?
|
||||
}
|
||||
|
||||
remove(typeHash: string) {
|
||||
remove(this.containers, (i) => i.typeHash === typeHash);
|
||||
this.containers$.next(this.containers.sort(this.sort));
|
||||
}
|
||||
|
||||
private makeTypeHash(modification: PartyModification): string {
|
||||
const modificationKeys = Object.keys(modification);
|
||||
if (modificationKeys.length !== 1) {
|
||||
return null;
|
||||
}
|
||||
const modificationUnit = modification[modificationKeys[0]];
|
||||
return modificationUnit.id + this.getModificationName(modification);
|
||||
}
|
||||
|
||||
private getModificationName(modification: PartyModification): string {
|
||||
const modificationKeys = Object.keys(modification);
|
||||
if (modificationKeys.length !== 1) {
|
||||
return 'unknown';
|
||||
}
|
||||
const modificationUnit = modification[modificationKeys[0]];
|
||||
const modificationNames = Object.keys(modificationUnit.modification);
|
||||
if (modificationNames.length !== 1) {
|
||||
return 'unknown';
|
||||
}
|
||||
return Object.keys(modificationUnit.modification)[0];
|
||||
}
|
||||
|
||||
private sort(a: PersistentContainer, b: PersistentContainer): number {
|
||||
if (a.saved) {
|
||||
return 1;
|
||||
}
|
||||
if (b.saved) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
|
||||
|
||||
@ -36,7 +37,7 @@ const initializer =
|
||||
]);
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, KeycloakAngularModule],
|
||||
imports: [CommonModule, HttpClientModule, KeycloakAngularModule],
|
||||
providers: [
|
||||
ConfigService,
|
||||
KeycloakTokenInfoService,
|
||||
|
@ -1,60 +0,0 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { decode, encode } from '@cc/utils/java-thrift-formatter';
|
||||
|
||||
import { ConfigService } from '../core/config.service';
|
||||
import { ClaimCreated, ClaimInfo, PartyModificationUnit } from './model';
|
||||
import { ClaimAcceptParams, ClaimDenyParams, ClaimSearchParams } from './params';
|
||||
|
||||
@Injectable()
|
||||
export class ClaimService {
|
||||
private readonly papiEndpoint: string;
|
||||
|
||||
constructor(private http: HttpClient, configService: ConfigService) {
|
||||
this.papiEndpoint = configService.config.papiEndpoint;
|
||||
}
|
||||
|
||||
getClaims(params: ClaimSearchParams): Observable<ClaimInfo[]> {
|
||||
return this.http.post<ClaimInfo[]>(`${this.papiEndpoint}/walk/claim/search`, params);
|
||||
}
|
||||
|
||||
getClaim(partyID: string, claimID: number): Observable<ClaimInfo> {
|
||||
const params = new HttpParams().set('partyId', partyID).set('claimId', claimID.toString());
|
||||
return this.http
|
||||
.get<ClaimInfo>(`${this.papiEndpoint}/walk/claim`, { params })
|
||||
.pipe(map((claim) => decode(claim)));
|
||||
}
|
||||
|
||||
createClaim(partyID: string, unit: PartyModificationUnit): Observable<ClaimCreated> {
|
||||
const params = new HttpParams().set('partyId', partyID);
|
||||
return this.http.post<ClaimCreated>(`${this.papiEndpoint}/walk/claim`, encode(unit), {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
updateClaim(
|
||||
partyID: string,
|
||||
claimID: number,
|
||||
revision: string,
|
||||
unit: PartyModificationUnit
|
||||
): Observable<void> {
|
||||
const params = new HttpParams()
|
||||
.set('partyId', partyID)
|
||||
.set('claimId', claimID.toString())
|
||||
.set('revision', revision);
|
||||
return this.http.post<void>(`${this.papiEndpoint}/walk/claim/update`, encode(unit), {
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
acceptClaim(params: ClaimAcceptParams): Observable<void> {
|
||||
return this.http.post<void>(`${this.papiEndpoint}/walk/claim/accept`, params);
|
||||
}
|
||||
|
||||
denyClaim(params: ClaimDenyParams): Observable<void> {
|
||||
return this.http.post<void>(`${this.papiEndpoint}/walk/claim/deny`, params);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { Price } from './price';
|
||||
|
||||
export class CartLine {
|
||||
product: string;
|
||||
quantity: number;
|
||||
price: Price;
|
||||
metadata: any[];
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import { CartLine } from './card-line';
|
||||
|
||||
export class Cart {
|
||||
lines: CartLine[];
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export class Category {
|
||||
description: string;
|
||||
id: number;
|
||||
name: string;
|
||||
test: boolean;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
import { ClaimStatus } from './claim-status';
|
||||
|
||||
export class ClaimCreated {
|
||||
claimId: number;
|
||||
claimStatus: ClaimStatus;
|
||||
createdAt: string;
|
||||
revision: string;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import { ClaimStatus } from './claim-status';
|
||||
import { PartyModificationUnit } from './party-modification-unit';
|
||||
|
||||
export interface ClaimInfo {
|
||||
party_id: string;
|
||||
claim_id: number;
|
||||
status: ClaimStatus;
|
||||
assigned_user_id: string;
|
||||
description: string;
|
||||
reason: string;
|
||||
modifications: PartyModificationUnit;
|
||||
modification_unit: any;
|
||||
revision: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export class ContractTemplate {
|
||||
description: string;
|
||||
name: string;
|
||||
id: number;
|
||||
termsId: number;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
export class Currency {
|
||||
symbolicCode: string;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
export * from './claim-info';
|
||||
export * from './category';
|
||||
export * from './party-modification-unit';
|
||||
export * from './contract-template';
|
||||
export * from './payout';
|
||||
export * from './payouts-response';
|
||||
export * from './payout-statuses';
|
||||
export * from './payment';
|
||||
export * from './invoice';
|
||||
export * from './claim-created';
|
||||
export * from './payout-types';
|
||||
export * from './claim-status';
|
@ -1,15 +0,0 @@
|
||||
import { Cart } from './cart';
|
||||
|
||||
export class Invoice {
|
||||
id: string;
|
||||
ownerId: string;
|
||||
shopId: string;
|
||||
createdAt: string;
|
||||
status: any;
|
||||
product: string;
|
||||
description: string;
|
||||
due: string;
|
||||
amount: number;
|
||||
currencySymbolicCode: string;
|
||||
cart: Cart;
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import { PartyModification } from '@vality/domain-proto/lib/claim_management';
|
||||
|
||||
export class PartyModificationUnit {
|
||||
modifications: PartyModification[];
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
export class Payment {
|
||||
id: string;
|
||||
invoiceId: string;
|
||||
ownerId: string;
|
||||
shopId: string;
|
||||
createdAt: string;
|
||||
status: any;
|
||||
amount: number;
|
||||
fee: number;
|
||||
providerFee: number;
|
||||
externalFee: number;
|
||||
currencySymbolicCode: string;
|
||||
payer: any;
|
||||
ipAddress: string;
|
||||
fingerprint: string;
|
||||
email: string;
|
||||
sessionId: string;
|
||||
locationInfo: any;
|
||||
flow: any;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
export enum PayoutStatus {
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
paid = 'paid',
|
||||
unpaid = 'unpaid',
|
||||
cancelled = 'cancelled',
|
||||
confirmed = 'confirmed',
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export enum PayoutTypes {
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
bank_account = 'bank_account',
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
wallet = 'wallet',
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { PayoutStatus } from './payout-statuses';
|
||||
|
||||
export class Payout {
|
||||
id: string;
|
||||
amount: number;
|
||||
currencyCode: string;
|
||||
status: PayoutStatus;
|
||||
fromTime: string;
|
||||
toTime: string;
|
||||
createdAt: string;
|
||||
partyId: string;
|
||||
shopId: string;
|
||||
payoutType: string;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { Payout } from './payout';
|
||||
|
||||
export class PayoutsResponse {
|
||||
lastId: number;
|
||||
payouts: Payout[];
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { Currency } from './currency';
|
||||
|
||||
export class Price {
|
||||
amount: string;
|
||||
currency: Currency;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ClaimService } from './claim.service';
|
||||
import { PartyService } from './party.service';
|
||||
import { PayoutsService } from './payouts.service';
|
||||
|
||||
@NgModule({
|
||||
imports: [HttpClientModule],
|
||||
providers: [ClaimService, PayoutsService, PartyService],
|
||||
})
|
||||
export class PapiModule {}
|
@ -1,5 +0,0 @@
|
||||
export class ClaimAcceptParams {
|
||||
claimId: number;
|
||||
partyId: string;
|
||||
revision: string;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export class ClaimDenyParams {
|
||||
claimId: number;
|
||||
partyId: string;
|
||||
reason: string;
|
||||
revision: string;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
export class ClaimSearchParams {
|
||||
claimIds?: number[];
|
||||
partyId?: string;
|
||||
assignedUserId?: string;
|
||||
claimStatus?: string;
|
||||
contains?: string;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
export * from './claim-search-params';
|
||||
export * from './claim-accept-params';
|
||||
export * from './claim-deny-params';
|
||||
export * from './payout-search-params';
|
||||
export * from './payout-cancel-params';
|
||||
export * from './payout-create-params';
|
||||
export * from './report-search-params';
|
@ -1,3 +0,0 @@
|
||||
export class PayoutCancelParams {
|
||||
reason: string;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
export class PayoutCreateParams {
|
||||
fromTime: string;
|
||||
toTime: string;
|
||||
partyId: string;
|
||||
shopId: string;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
import { PayoutStatus, PayoutTypes } from '../model';
|
||||
|
||||
export class PayoutSearchParams {
|
||||
fromTime?: string;
|
||||
toTime?: string;
|
||||
status?: PayoutStatus;
|
||||
payoutType?: PayoutTypes;
|
||||
payoutIds?: string[];
|
||||
fromId?: number;
|
||||
size?: string;
|
||||
minAmount?: number;
|
||||
maxAmount?: number;
|
||||
currencyCode?: string;
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
export class ReportSearchParams {
|
||||
fromTime: string;
|
||||
toTime: string;
|
||||
from: string;
|
||||
size: string;
|
||||
merchantId?: string;
|
||||
invoiceId?: string;
|
||||
status?: string;
|
||||
categoryIds?: string[];
|
||||
paymentDomainRevision?: string;
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Party, Shop } from '@vality/domain-proto/lib/domain';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { decode } from '@cc/utils/java-thrift-formatter';
|
||||
|
||||
import { ConfigService } from '../core/config.service';
|
||||
import { ContractTemplate } from './model';
|
||||
|
||||
@Injectable()
|
||||
export class PartyService {
|
||||
private readonly papiEndpoint: string;
|
||||
|
||||
constructor(private http: HttpClient, configService: ConfigService) {
|
||||
this.papiEndpoint = configService.config.papiEndpoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use PartyManagementService
|
||||
*/
|
||||
getParty(partyId: string): Observable<Party> {
|
||||
return this.http
|
||||
.get<ContractTemplate[]>(`${this.papiEndpoint}/parties/${partyId}`)
|
||||
.pipe(map((party) => decode(party)));
|
||||
}
|
||||
|
||||
getShops = (partyID: string): Observable<Shop[]> =>
|
||||
this.getParty(partyID).pipe(map((party) => Array.from(party.shops.values())));
|
||||
|
||||
/**
|
||||
* @deprecated use PartyManagementService
|
||||
*/
|
||||
getShop = (partyID: string, shopID: string): Observable<Shop> =>
|
||||
this.getShops(partyID).pipe(map((shops) => shops.find((shop) => shop.id === shopID)));
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { ConfigService } from '../core/config.service';
|
||||
import { Payout, PayoutsResponse } from './model';
|
||||
import { PayoutCancelParams, PayoutCreateParams, PayoutSearchParams } from './params';
|
||||
|
||||
@Injectable()
|
||||
export class PayoutsService {
|
||||
private readonly papiEndpoint: string;
|
||||
|
||||
constructor(private http: HttpClient, configService: ConfigService) {
|
||||
this.papiEndpoint = configService.config.papiEndpoint;
|
||||
}
|
||||
|
||||
getPayouts(params?: PayoutSearchParams): Observable<PayoutsResponse> {
|
||||
let searchParams = new HttpParams();
|
||||
if (params) {
|
||||
Object.keys(params).forEach((key) => {
|
||||
searchParams = params[key] ? searchParams.set(key, params[key]) : searchParams;
|
||||
});
|
||||
}
|
||||
return this.http.get<PayoutsResponse>(`${this.papiEndpoint}/payouts`, {
|
||||
params: searchParams,
|
||||
});
|
||||
}
|
||||
|
||||
confirmPayouts(payoutIds: string[]): Observable<string[]> {
|
||||
return this.http.post<string[]>(`${this.papiEndpoint}/payouts/confirm`, { payoutIds });
|
||||
}
|
||||
|
||||
createPayout(params: PayoutCreateParams): Observable<Payout> {
|
||||
return this.http.post<Payout>(`${this.papiEndpoint}/payouts`, params);
|
||||
}
|
||||
|
||||
pay(payoutIds: string[]): Observable<void> {
|
||||
return this.http.post<void>(`${this.papiEndpoint}/payouts/pay`, { payoutIds });
|
||||
}
|
||||
|
||||
cancelPayout(payoutID: string, params: PayoutCancelParams): Observable<void> {
|
||||
return this.http.post<void>(`${this.papiEndpoint}/payouts/${payoutID}/cancel`, params);
|
||||
}
|
||||
}
|
@ -3,16 +3,17 @@ import { Contract, Party, PartyContractor, Shop } from '@vality/domain-proto/lib
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { PartyService } from '../../../papi/party.service';
|
||||
import { PartyManagementWithUserService } from '@cc/app/api/payment-processing';
|
||||
|
||||
import { PartyTarget } from '../party-target';
|
||||
import { SelectableItem } from './selectable-item';
|
||||
|
||||
@Injectable()
|
||||
export class PartyTargetService {
|
||||
constructor(private partyService: PartyService) {}
|
||||
constructor(private partyManagementWithUserService: PartyManagementWithUserService) {}
|
||||
|
||||
getSelectableItems(partyID: string, targetName: PartyTarget): Observable<SelectableItem[]> {
|
||||
return this.partyService.getParty(partyID).pipe(
|
||||
return this.partyManagementWithUserService.getParty(partyID).pipe(
|
||||
map((party) => {
|
||||
const result = [];
|
||||
const target = this.getTarget(party, targetName);
|
||||
|
@ -1,15 +0,0 @@
|
||||
<h4 class="mat-dialog-title">Cancel payouts</h4>
|
||||
<mat-dialog-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<textarea matInput placeholder="Reason" formControlName="reason"></textarea>
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="warn" (click)="submit()" [disabled]="isLoading || !this.form.valid">
|
||||
CONFIRM
|
||||
</button>
|
||||
<button mat-dialog-close mat-button color="default" [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,45 +0,0 @@
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { PayoutsService } from '../payouts.service';
|
||||
import { CancelPayoutService } from './cancel-payout.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: './cancel-payout.component.html',
|
||||
providers: [CancelPayoutService],
|
||||
})
|
||||
export class CancelPayoutComponent implements OnInit {
|
||||
form: FormGroup;
|
||||
isLoading: boolean;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<CancelPayoutComponent>,
|
||||
private cancelPayoutDialogService: CancelPayoutService,
|
||||
private payoutsService: PayoutsService,
|
||||
private snackBar: MatSnackBar,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public payoutId: string
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this.cancelPayoutDialogService.createFormGroup;
|
||||
}
|
||||
|
||||
submit() {
|
||||
this.isLoading = true;
|
||||
this.payoutsService.cancel(this.payoutId, this.form.value).subscribe(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.dialogRef.close();
|
||||
this.snackBar.open('Successfully cancelled', 'OK', { duration: 3000 });
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while payout cancel.', 'OK');
|
||||
console.error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
|
||||
@Injectable()
|
||||
export class CancelPayoutService {
|
||||
createFormGroup: FormGroup;
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.createFormGroup = this.prepareForm();
|
||||
}
|
||||
|
||||
private prepareForm(): FormGroup {
|
||||
return this.fb.group({
|
||||
reason: ['', Validators.required],
|
||||
});
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
<h4 class="mat-dialog-title">Confirm payouts</h4>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="default" (click)="submit()" [disabled]="isLoading">CONFIRM</button>
|
||||
<button mat-dialog-close mat-button color="default" [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,36 +0,0 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { PayoutsService } from '../payouts.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'confirm-payouts.component.html',
|
||||
})
|
||||
export class ConfirmPayoutsComponent {
|
||||
isLoading: boolean;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<ConfirmPayoutsComponent, 'success'>,
|
||||
private payoutsService: PayoutsService,
|
||||
private snackBar: MatSnackBar,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public payoutsIds: string[]
|
||||
) {}
|
||||
|
||||
submit() {
|
||||
this.isLoading = true;
|
||||
this.payoutsService.confirm(this.payoutsIds).subscribe(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.dialogRef.close('success');
|
||||
this.snackBar.open('Successfully confirmed', 'OK', { duration: 3000 });
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while confirming payouts', 'OK');
|
||||
console.error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
<h4 class="mat-dialog-title">Create payout</h4>
|
||||
<mat-dialog-content>
|
||||
<form *ngIf="form" [formGroup]="form" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Party ID" formControlName="partyId" />
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput placeholder="Shop ID" formControlName="shopId" />
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxLayout.xs="column">
|
||||
<mat-form-field fxFlex="50">
|
||||
<input matInput placeholder="From time" formControlName="fromTime" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="50">
|
||||
<input matInput placeholder="To time" formControlName="toTime" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="default" (click)="submit()" [disabled]="isLoading || !form.valid">
|
||||
CREATE
|
||||
</button>
|
||||
<button mat-dialog-close mat-button color="default" [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar *ngIf="isLoading" mode="indeterminate"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,50 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { FormGroup } from '@angular/forms';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { PayoutsService } from '../payouts.service';
|
||||
import { CreatePayoutService } from './create-payout.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'create-payout.component.html',
|
||||
providers: [CreatePayoutService, PayoutsService],
|
||||
})
|
||||
export class CreatePayoutComponent implements OnInit {
|
||||
form: FormGroup;
|
||||
isLoading: boolean;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<CreatePayoutComponent, 'success'>,
|
||||
private createPayoutService: CreatePayoutService,
|
||||
private payoutService: PayoutsService,
|
||||
private snackBar: MatSnackBar
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.form = this.createPayoutService.createPayoutGroup;
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (this.form.valid) {
|
||||
const formValues = this.form.value;
|
||||
this.isLoading = true;
|
||||
this.payoutService.create(this.createPayoutService.makeParams(formValues)).subscribe(
|
||||
() => {
|
||||
this.dialogRef.close('success');
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('Successfully created', 'OK', { duration: 3000 });
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
const message = error.message;
|
||||
this.snackBar.open(
|
||||
`${message ? message : 'An error occurred while creating payout.'}`,
|
||||
'OK'
|
||||
);
|
||||
console.error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { PayoutCreateParams } from '../../papi/params';
|
||||
|
||||
@Injectable()
|
||||
export class CreatePayoutService {
|
||||
createPayoutGroup: FormGroup;
|
||||
private dateFormat = 'DD-MM-YYYY HH:mm';
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.createPayoutGroup = this.prepareForm();
|
||||
}
|
||||
|
||||
makeParams(formValues: any): PayoutCreateParams {
|
||||
return {
|
||||
...formValues,
|
||||
fromTime: this.convertDate(formValues.fromTime),
|
||||
toTime: this.convertDate(formValues.toTime),
|
||||
};
|
||||
}
|
||||
|
||||
private convertDate(date: string): string {
|
||||
return moment(date, this.dateFormat).utc().format();
|
||||
}
|
||||
|
||||
private prepareForm(): FormGroup {
|
||||
const now = moment().format(this.dateFormat);
|
||||
return this.fb.group({
|
||||
fromTime: [now, Validators.required],
|
||||
toTime: [now, Validators.required],
|
||||
partyId: ['', Validators.required],
|
||||
shopId: ['', Validators.required],
|
||||
});
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
<h4 class="mat-dialog-title">Confirm payout pay</h4>
|
||||
<mat-dialog-actions>
|
||||
<button mat-button color="default" (click)="submit()" [disabled]="isLoading">CONFIRM</button>
|
||||
<button mat-dialog-close mat-button color="default" [mat-dialog-close]="false">CANCEL</button>
|
||||
<mat-progress-bar mode="indeterminate" *ngIf="isLoading"></mat-progress-bar>
|
||||
</mat-dialog-actions>
|
@ -1,36 +0,0 @@
|
||||
import { Component, Inject } from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { PayoutsService } from '../payouts.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'pay-payouts.component.html',
|
||||
})
|
||||
export class PayPayoutsComponent {
|
||||
isLoading: boolean;
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<PayPayoutsComponent, 'success'>,
|
||||
private payoutsService: PayoutsService,
|
||||
private snackBar: MatSnackBar,
|
||||
@Inject(MAT_DIALOG_DATA)
|
||||
public payoutsIds: string[]
|
||||
) {}
|
||||
|
||||
submit() {
|
||||
this.isLoading = true;
|
||||
this.payoutsService.pay(this.payoutsIds).subscribe(
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.dialogRef.close('success');
|
||||
this.snackBar.open('Successfully payed', 'OK', { duration: 3000 });
|
||||
},
|
||||
(error) => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while payout pay', 'OK');
|
||||
console.error(error);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
<div fxLayout="row" fxLayoutGap="10px">
|
||||
<button
|
||||
*ngIf="hasRole(payoutRole.Generate)"
|
||||
mat-raised-button
|
||||
color="primary"
|
||||
(click)="createPayout()"
|
||||
>
|
||||
CREATE
|
||||
</button>
|
||||
<div
|
||||
#payTooltip="matTooltip"
|
||||
matTooltip='Select payouts with status "unpaid"'
|
||||
[matTooltipDisabled]="isCanPay()"
|
||||
>
|
||||
<button
|
||||
*ngIf="hasRole(payoutRole.Pay)"
|
||||
[matBadgeHidden]="!isCanPay()"
|
||||
matBadge="{{ selectedPayouts.length }}"
|
||||
matBadgePosition="after"
|
||||
matBadgeColor="primary"
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
(click)="pay()"
|
||||
[disabled]="!isCanPay()"
|
||||
>
|
||||
PAY
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
#confirmTooltip="matTooltip"
|
||||
matTooltip='Select payouts with status "paid"'
|
||||
[matTooltipDisabled]="isCanConfirm()"
|
||||
>
|
||||
<button
|
||||
*ngIf="hasRole(payoutRole.Confirm)"
|
||||
[matBadgeHidden]="!isCanConfirm()"
|
||||
matBadge="{{ selectedPayouts.length }}"
|
||||
matBadgePosition="after"
|
||||
matBadgeColor="primary"
|
||||
mat-raised-button
|
||||
color="accent"
|
||||
(click)="confirmPayouts()"
|
||||
[disabled]="!isCanConfirm()"
|
||||
>
|
||||
CONFIRM
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
@ -1,75 +0,0 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { filter } from 'rxjs/operators';
|
||||
|
||||
import { AppAuthGuardService, PayoutRole } from '@cc/app/shared/services';
|
||||
|
||||
import { Payout, PayoutStatus } from '../../papi/model';
|
||||
import { ConfirmPayoutsComponent } from '../confirm-payouts/confirm-payouts.component';
|
||||
import { CreatePayoutComponent } from '../create-payout/create-payout.component';
|
||||
import { PayPayoutsComponent } from '../pay-payouts/pay-payouts.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-payouts-actions',
|
||||
templateUrl: 'payouts-actions.component.html',
|
||||
})
|
||||
export class PayoutsActionsComponent {
|
||||
@Input()
|
||||
selectedPayouts: Payout[];
|
||||
|
||||
@Output()
|
||||
doAction: EventEmitter<void> = new EventEmitter();
|
||||
|
||||
payoutRole = PayoutRole;
|
||||
|
||||
constructor(private dialogRef: MatDialog, private appAuthGuardService: AppAuthGuardService) {}
|
||||
|
||||
pay() {
|
||||
this.dialogRef
|
||||
.open(PayPayoutsComponent, {
|
||||
data: this.getIds(this.selectedPayouts),
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(filter((result) => result === 'success'))
|
||||
.subscribe(() => this.doAction.emit());
|
||||
}
|
||||
|
||||
confirmPayouts() {
|
||||
this.dialogRef
|
||||
.open(ConfirmPayoutsComponent, {
|
||||
data: this.getIds(this.selectedPayouts),
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(filter((result) => result === 'success'))
|
||||
.subscribe(() => this.doAction.emit());
|
||||
}
|
||||
|
||||
createPayout() {
|
||||
this.dialogRef
|
||||
.open(CreatePayoutComponent, {
|
||||
width: '720px',
|
||||
disableClose: true,
|
||||
})
|
||||
.afterClosed()
|
||||
.pipe(filter((result) => result === 'success'))
|
||||
.subscribe(() => this.doAction.emit());
|
||||
}
|
||||
|
||||
hasRole(role: PayoutRole): boolean {
|
||||
return this.appAuthGuardService.userHasRoles([role]);
|
||||
}
|
||||
|
||||
isCanPay(): boolean {
|
||||
const unpaid = this.selectedPayouts.filter((p) => p.status === PayoutStatus.unpaid);
|
||||
return this.selectedPayouts.length === unpaid.length && unpaid.length > 0;
|
||||
}
|
||||
|
||||
isCanConfirm(): boolean {
|
||||
const paid = this.selectedPayouts.filter((p) => p.status === PayoutStatus.paid);
|
||||
return this.selectedPayouts.length === paid.length && paid.length > 0;
|
||||
}
|
||||
|
||||
private getIds(payouts: Payout[]): string[] {
|
||||
return payouts.map((p) => p.id);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { AppAuthGuardService } from '@cc/app/shared/services';
|
||||
|
||||
import { PayoutsComponent } from './payouts.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: 'old-payouts',
|
||||
component: PayoutsComponent,
|
||||
canActivate: [AppAuthGuardService],
|
||||
data: {
|
||||
roles: ['payout:read'],
|
||||
},
|
||||
},
|
||||
]),
|
||||
],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class PayoutsRoutingModule {}
|
@ -1,74 +0,0 @@
|
||||
<table mat-table [dataSource]="dataSource">
|
||||
<ng-container matColumnDef="select">
|
||||
<th mat-header-cell *matHeaderCellDef>
|
||||
<mat-checkbox
|
||||
(change)="$event ? masterToggle() : null"
|
||||
[checked]="selection.hasValue() && isAllSelected()"
|
||||
[indeterminate]="selection.hasValue() && !isAllSelected()"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</th>
|
||||
<td mat-cell *matCellDef="let row">
|
||||
<mat-checkbox
|
||||
(click)="$event.stopPropagation()"
|
||||
(change)="$event ? selection.toggle(row) : null"
|
||||
[checked]="selection.isSelected(row)"
|
||||
>
|
||||
</mat-checkbox>
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef>Payout ID</th>
|
||||
<td mat-cell *matCellDef="let payout">{{ payout.id }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="partyId">
|
||||
<th mat-header-cell *matHeaderCellDef fxHide.xs fxHide.sm>Party ID</th>
|
||||
<td mat-cell *matCellDef="let payout" fxHide.xs fxHide.sm>{{ payout.partyId }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="shopId">
|
||||
<th mat-header-cell *matHeaderCellDef fxHide.xs fxHide.sm>Shop ID</th>
|
||||
<td mat-cell *matCellDef="let payout" fxHide.xs fxHide.sm>{{ payout.shopId }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="amount">
|
||||
<th mat-header-cell *matHeaderCellDef fxHide.xs>Amount</th>
|
||||
<td mat-cell *matCellDef="let payout" fxHide.xs>
|
||||
{{ payout.amount | ccFormatAmount }} {{ payout.currencyCode | ccCurrency }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="period">
|
||||
<th mat-header-cell *matHeaderCellDef fxHide.xs>Period</th>
|
||||
<td mat-cell *matCellDef="let payout" fxHide.xs>
|
||||
{{ payout.fromTime | date: 'dd.MM.yyyy HH:mm:ss' }}<br />
|
||||
— {{ payout.toTime | date: 'dd.MM.yyyy HH:mm:ss' }}
|
||||
</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef>Status</th>
|
||||
<td mat-cell *matCellDef="let payout">{{ payout.status }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="type">
|
||||
<th mat-header-cell *matHeaderCellDef>Type</th>
|
||||
<td mat-cell *matCellDef="let payout">{{ payout.payoutType }}</td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="payoutDetailButton">
|
||||
<th mat-header-cell *matHeaderCellDef class="action-cell"></th>
|
||||
<td mat-cell *matCellDef="let payout" class="action-cell">
|
||||
<mat-menu #appMenu="matMenu">
|
||||
<button
|
||||
*ngIf="hasRole('payout:cancel')"
|
||||
mat-menu-item
|
||||
(click)="cancelPayout(payout.id)"
|
||||
>
|
||||
Cancel payout
|
||||
</button>
|
||||
</mat-menu>
|
||||
<button mat-icon-button [matMenuTriggerFor]="appMenu">
|
||||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let payout; columns: displayedColumns"></tr>
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 20, 50, 100, 250, 500]" showFirstLastButtons></mat-paginator>
|
@ -1,15 +0,0 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.action-cell {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.revoke-dialog {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
import { SelectionModel } from '@angular/cdk/collections';
|
||||
import {
|
||||
Component,
|
||||
EventEmitter,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild,
|
||||
} from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { KeycloakService } from 'keycloak-angular';
|
||||
|
||||
import { Payout } from '../../papi/model';
|
||||
import { CancelPayoutComponent } from '../cancel-payout/cancel-payout.component';
|
||||
|
||||
@Component({
|
||||
selector: 'cc-payouts-table',
|
||||
templateUrl: 'payouts-table.component.html',
|
||||
styleUrls: ['./payouts-table.component.scss'],
|
||||
})
|
||||
export class PayoutsTableComponent implements OnInit, OnChanges {
|
||||
@Output()
|
||||
valueChanges: EventEmitter<Payout[]> = new EventEmitter();
|
||||
|
||||
@Input()
|
||||
payouts: Payout[];
|
||||
|
||||
dataSource: MatTableDataSource<Payout> = new MatTableDataSource();
|
||||
roles: string[];
|
||||
selection = new SelectionModel<Payout>(true, []);
|
||||
|
||||
@ViewChild(MatPaginator, { static: true })
|
||||
paginator: MatPaginator;
|
||||
|
||||
displayedColumns = [
|
||||
'select',
|
||||
'id',
|
||||
'partyId',
|
||||
'shopId',
|
||||
'amount',
|
||||
'period',
|
||||
'status',
|
||||
'type',
|
||||
'payoutDetailButton',
|
||||
];
|
||||
|
||||
constructor(private matDialog: MatDialog, private keycloakService: KeycloakService) {}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
const { payouts } = changes;
|
||||
if (payouts && payouts.currentValue) {
|
||||
this.selection.clear();
|
||||
this.dataSource.data = payouts.currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.roles = this.keycloakService.getUserRoles();
|
||||
this.selection.changed.subscribe((e) => this.valueChanges.emit(e.source.selected));
|
||||
this.dataSource.paginator = this.paginator;
|
||||
}
|
||||
|
||||
isAllSelected() {
|
||||
return this.selection.selected.length === this.payouts.length;
|
||||
}
|
||||
|
||||
masterToggle() {
|
||||
if (this.isAllSelected()) this.selection.clear();
|
||||
else this.selection.select(...this.payouts);
|
||||
}
|
||||
|
||||
cancelPayout(id: string) {
|
||||
this.matDialog.open(CancelPayoutComponent, {
|
||||
data: id,
|
||||
});
|
||||
}
|
||||
|
||||
hasRole(role: string): boolean {
|
||||
return this.roles.includes(role);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
<cc-card-container>
|
||||
<mat-card>
|
||||
<mat-card-subtitle> Search payouts </mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<cc-payouts-search-form
|
||||
(valueChanges)="formValueChanges($event)"
|
||||
(statusChanges)="formStatusChanges($event)"
|
||||
>
|
||||
</cc-payouts-search-form>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button
|
||||
mat-button
|
||||
color="primary"
|
||||
[disabled]="!formValid || isLoading"
|
||||
(click)="search()"
|
||||
>
|
||||
SEARCH
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-footer *ngIf="isLoading">
|
||||
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
|
||||
</mat-card-footer>
|
||||
</mat-card>
|
||||
<mat-card>
|
||||
<mat-card-subtitle>Payout actions</mat-card-subtitle>
|
||||
<mat-card-content fxLayout="row" fxLayoutGap="20px">
|
||||
<cc-payouts-actions
|
||||
[selectedPayouts]="selectedPayouts"
|
||||
(doAction)="search()"
|
||||
></cc-payouts-actions>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<cc-payouts-table
|
||||
[payouts]="payouts"
|
||||
(valueChanges)="tableOnChange($event)"
|
||||
></cc-payouts-table>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</cc-card-container>
|
@ -1,10 +0,0 @@
|
||||
.actions-button-container {
|
||||
position: fixed;
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
|
||||
mat-spinner {
|
||||
display: inline-block;
|
||||
margin-left: 15px;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
|
||||
import { Payout } from '../papi/model';
|
||||
import { PayoutSearchParams } from '../papi/params';
|
||||
import { PayoutsService } from './payouts.service';
|
||||
import { SearchFormService } from './search-form/search-form.service';
|
||||
|
||||
@Component({
|
||||
templateUrl: 'payouts.component.html',
|
||||
styleUrls: ['./payouts.component.scss'],
|
||||
providers: [SearchFormService],
|
||||
})
|
||||
export class PayoutsComponent {
|
||||
isLoading: boolean;
|
||||
payouts: Payout[];
|
||||
selectedPayouts: Payout[] = [];
|
||||
formValid: boolean;
|
||||
searchParams: PayoutSearchParams;
|
||||
|
||||
constructor(private payoutsService: PayoutsService, private snackBar: MatSnackBar) {}
|
||||
|
||||
formValueChanges(params: PayoutSearchParams) {
|
||||
this.searchParams = params;
|
||||
}
|
||||
|
||||
formStatusChanges(status: string) {
|
||||
this.formValid = status === 'VALID';
|
||||
}
|
||||
|
||||
tableOnChange(selectedPayouts: Payout[]) {
|
||||
this.selectedPayouts = selectedPayouts;
|
||||
}
|
||||
|
||||
search() {
|
||||
this.isLoading = true;
|
||||
this.payoutsService.get(this.searchParams).subscribe(
|
||||
(payouts) => {
|
||||
this.isLoading = false;
|
||||
this.payouts = payouts;
|
||||
},
|
||||
() => {
|
||||
this.isLoading = false;
|
||||
this.snackBar.open('An error occurred while search payouts', 'OK');
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
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 { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
|
||||
import { CommonPipesModule } from '@cc/app/shared/pipes';
|
||||
import { CardContainerModule } from '@cc/components/card-container/card-container.module';
|
||||
|
||||
import { PapiModule } from '../papi/papi.module';
|
||||
import { CancelPayoutComponent } from './cancel-payout/cancel-payout.component';
|
||||
import { ConfirmPayoutsComponent } from './confirm-payouts/confirm-payouts.component';
|
||||
import { CreatePayoutComponent } from './create-payout/create-payout.component';
|
||||
import { PayPayoutsComponent } from './pay-payouts/pay-payouts.component';
|
||||
import { PayoutsActionsComponent } from './payouts-actions/payouts-actions.component';
|
||||
import { PayoutsRoutingModule } from './payouts-routing.module';
|
||||
import { PayoutsTableComponent } from './payouts-table/payouts-table.component';
|
||||
import { PayoutsComponent } from './payouts.component';
|
||||
import { PayoutsService } from './payouts.service';
|
||||
import { SearchFormComponent } from './search-form/search-form.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
PayoutsRoutingModule,
|
||||
MatCardModule,
|
||||
MatProgressBarModule,
|
||||
MatSnackBarModule,
|
||||
FlexLayoutModule,
|
||||
PapiModule,
|
||||
ReactiveFormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatSelectModule,
|
||||
MatDatepickerModule,
|
||||
CdkTableModule,
|
||||
MatTableModule,
|
||||
MatCheckboxModule,
|
||||
MatButtonModule,
|
||||
MatDialogModule,
|
||||
MatIconModule,
|
||||
PapiModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatBadgeModule,
|
||||
MatMenuModule,
|
||||
MatTooltipModule,
|
||||
MatPaginatorModule,
|
||||
CardContainerModule,
|
||||
CommonPipesModule,
|
||||
],
|
||||
declarations: [
|
||||
PayoutsComponent,
|
||||
SearchFormComponent,
|
||||
PayoutsTableComponent,
|
||||
CreatePayoutComponent,
|
||||
CancelPayoutComponent,
|
||||
PayPayoutsComponent,
|
||||
ConfirmPayoutsComponent,
|
||||
PayoutsActionsComponent,
|
||||
],
|
||||
entryComponents: [
|
||||
CreatePayoutComponent,
|
||||
CancelPayoutComponent,
|
||||
PayPayoutsComponent,
|
||||
ConfirmPayoutsComponent,
|
||||
],
|
||||
providers: [PayoutsService],
|
||||
exports: [PayoutsTableComponent],
|
||||
})
|
||||
export class PayoutsModule {}
|
@ -1,32 +0,0 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { Payout } from '../papi/model';
|
||||
import { PayoutCancelParams, PayoutCreateParams, PayoutSearchParams } from '../papi/params';
|
||||
import { PayoutsService as PayoutsPapiService } from '../papi/payouts.service';
|
||||
|
||||
@Injectable()
|
||||
export class PayoutsService {
|
||||
constructor(private payoutsPapiService: PayoutsPapiService) {}
|
||||
|
||||
get(params: PayoutSearchParams): Observable<Payout[]> {
|
||||
return this.payoutsPapiService.getPayouts(params).pipe(map((response) => response.payouts));
|
||||
}
|
||||
|
||||
confirm(payoutsIds: string[]): Observable<void> {
|
||||
return this.payoutsPapiService.confirmPayouts(payoutsIds).pipe(map(() => null));
|
||||
}
|
||||
|
||||
pay(payoutsIds: string[]): Observable<void> {
|
||||
return this.payoutsPapiService.pay(payoutsIds).pipe(map(() => null));
|
||||
}
|
||||
|
||||
cancel(payoutId: string, params: PayoutCancelParams): Observable<void> {
|
||||
return this.payoutsPapiService.cancelPayout(payoutId, params).pipe(map(() => null));
|
||||
}
|
||||
|
||||
create(params: PayoutCreateParams): Observable<Payout> {
|
||||
return this.payoutsPapiService.createPayout(params);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user