FE-664: Add payment adjustment (#9)

This commit is contained in:
Rinat Arsaev 2018-10-23 12:31:54 +03:00 committed by Ildar Galeev
parent a3757b2563
commit 2fb2175b81
151 changed files with 2580 additions and 722 deletions

3
.gitignore vendored
View File

@ -38,4 +38,5 @@ testem.log
.DS_Store
Thumbs.db
/src/assets/gen-json/
/src/app/domain/gen-nodejs/
/src/app/thrift/gen-nodejs/
/src/app/gen-damsel/

View File

@ -38,18 +38,28 @@ submodules: $(SUBTARGETS)
init:
npm install
build: lint src/gen-nodejs src/gen-json
build: lint compile-thrift
npm run build
clean:
rm -rf dist src/app/domain/gen-* src/assets/gen-*
rm -rf dist src/app/thrift/gen-* src/assets/gen-* src/app/gen-damsel
# utils
src/gen-nodejs: node_modules/damsel/proto/domain_config.thrift
thrift -r -gen js:node,runtime_package=woody_js/src/client/gen -o ./src/app/domain ./node_modules/damsel/proto/domain_config.thrift
compile-thrift: thrift-to-js/domain-config thrift-to-json/domain-config thrift-to-js/payment-processing thrift-to-js/merch-stat thrift-to-ts
src/gen-json: node_modules/damsel/proto/domain_config.thrift
thrift-to-js/domain-config:
thrift -r -gen js:node,runtime_package=woody_js/src/client/gen -o ./src/app/thrift ./node_modules/damsel/proto/domain_config.thrift
thrift-to-json/domain-config:
thrift -r -gen json -o ./src/assets ./node_modules/damsel/proto/domain_config.thrift
thrift-to-js/payment-processing:
thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift ./node_modules/damsel/proto/payment_processing.thrift
thrift-to-js/merch-stat:
thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/thrift ./node_modules/damsel/proto/merch_stat.thrift
thrift-to-ts:
npm run thrift-ts
lint:
npm run lint

View File

@ -4,6 +4,4 @@
make wc_shell
thrift -r -gen js:node,runtime_package=woody_js/dist/thrift -o ./src/app/domain ./node_modules/damsel/proto/domain_config.thrift
thrift -r -gen json -o ./src/assets ./node_modules/damsel/proto/domain_config.thrift
make compile-thrift

852
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,8 @@
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
"e2e": "ng e2e",
"thrift-ts": "thrift-ts node_modules/damsel/proto -o src/app/gen-damsel -d false -c true"
},
"private": true,
"dependencies": {
@ -25,13 +26,14 @@
"@angular/router": "^6.1.0",
"angular2-prettyjson": "3.0.1",
"core-js": "^2.5.4",
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#1510cd7caa1e4338429a3a0783289d36e140472a",
"damsel": "git+ssh://git@github.com/rbkmoney/damsel.git#78492cc9d2329ef68c2eeeb43d62f5230a33c630",
"hammerjs": "^2.0.8",
"keycloak-angular": "3.0.2",
"keycloak-js": "3.4.0",
"lodash-es": "^4.17.10",
"moment": "^2.22.2",
"rxjs": "^6.0.0",
"thrift-ts": "git+ssh://git@github.com/rbkmoney/thrift-ts.git#6be548bef8b70c6cc0a66ce08ffaccb1263c982c",
"uuid": "^3.3.2",
"woody_js": "git+ssh://git@github.com/rbkmoney/woody_js.git#dfe1ec26573de991f59952aa64b409280fec6c58",
"zone.js": "~0.8.26"

View File

@ -4,5 +4,11 @@
"secure": false,
"logLevel": "debug",
"changeOrigin": true
},
"/stat": {
"target": "http://iddqd.rbk.test:8080",
"secure": false,
"logLevel": "debug",
"changeOrigin": true
}
}

View File

@ -5,3 +5,12 @@
.active {
background: #f5f5f5;
}
.toolbar {
position: fixed;
z-index: 2;
}
.content {
margin-top: 64px;
}

View File

@ -1,4 +1,4 @@
<mat-toolbar color="primary">
<mat-toolbar color="primary" class="toolbar">
<button mat-icon-button (click)="sidenav.toggle()">
<mat-icon>menu</mat-icon>
</button>
@ -29,7 +29,7 @@
</mat-list-item>
</mat-nav-list>
</mat-sidenav>
<mat-sidenav-content role="main">
<mat-sidenav-content role="main" class="content">
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>

View File

@ -27,7 +27,8 @@ export class AppComponent implements OnInit {
const menuItems = [
// {name: 'Domain config', route: '/domain', activateRole: 'dmt:checkout'},
{name: 'Payouts', route: '/payouts', activateRole: 'payout:read'},
{name: 'Claims', route: '/claims', activateRole: 'claim:get'}
{name: 'Claims', route: '/claims', activateRole: 'claim:get'},
{name: 'Payment adjustment', route: '/payment-adjustment', activateRole: 'adjustment:create'}
];
const roles = this.keycloakService.getUserRoles();
return menuItems.filter((item) => roles.includes(item.activateRole));

View File

@ -16,6 +16,7 @@ import { ClaimsModule } from './claims/claims.module';
import { AppRoutingModule } from './app-routing.module';
import { ClaimModule } from './claim/claim.module';
import { PayoutsModule } from './payouts/payouts.module';
import { PaymentAdjustmentModule } from './payment-adjustment/payment-adjustment.module';
@NgModule({
declarations: [
@ -34,7 +35,8 @@ import { PayoutsModule } from './payouts/payouts.module';
MatListModule,
ClaimsModule,
ClaimModule,
PayoutsModule
PayoutsModule,
PaymentAdjustmentModule
],
providers: [],
bootstrap: [AppComponent]

View File

@ -23,7 +23,7 @@ import {
import { FlexLayoutModule } from '@angular/flex-layout';
import { PapiModule } from '../papi/papi.module';
import { DomainModule } from '../domain/domain.module';
import { ThriftModule } from '../thrift/thrift.module';
import { ClaimRoutingModule } from './claim-routing.module';
import { ClaimComponent } from './claim.component';
import { ClaimInfoComponent } from './claim-info/claim-info.component';
@ -46,7 +46,7 @@ import { PersistentContainerService } from './persistent-container.service';
@NgModule({
imports: [
PapiModule,
DomainModule,
ThriftModule,
CommonModule,
SharedModule,
ReactiveFormsModule,

View File

@ -6,7 +6,6 @@ import toNumber from 'lodash-es/toNumber';
import { ClaimService as ClaimPapi } from '../papi/claim.service';
import { ClaimInfo, PartyModificationUnit } from '../papi/model';
import { PartyModification } from '../damsel';
import {
ClaimInfoContainer,
DomainModificationInfo,
@ -15,6 +14,7 @@ import {
} from './model';
import { PersistentContainerService } from './persistent-container.service';
import { convert } from './party-modification-group-converter';
import { PartyModification } from '../gen-damsel/payment_processing';
@Injectable()
export class ClaimService {

View File

@ -5,10 +5,11 @@ import { BehaviorSubject, Observable } from 'rxjs';
import { ActionType, ModificationAction } from '../modification-action';
import { DomainModificationInfo, ModificationGroupType } from '../model';
import { PartyModification } from '../../damsel/payment-processing';
import { PartyTarget } from '../../party-modification-target';
import { ClaimService } from '../claim.service';
import { CreateTerminalParams, DomainTypedManager } from '../../domain/domain-typed-manager';
import { CreateTerminalParams } from '../domain-typed-manager';
import { DomainTypedManager } from '../../thrift/domain-typed-manager';
import { PartyModification } from '../../gen-damsel/payment_processing';
@Component({
templateUrl: 'create-modification.component.html'

View File

@ -6,7 +6,7 @@ import {
TerminalSelector,
TerminalDecision
} from '../../damsel';
import { toGenTerminalDecision } from './gen-conversion';
import { toGenTerminalDecision } from '../../thrift/converters';
const createDecision = (partyID: string, shopID: string, terminalID: number): TerminalDecision =>
({

View File

@ -1,8 +1,7 @@
import { toGenDomainObject } from './gen-conversion';
import { addTerminalDecision } from './add-terminal-decision';
import { createTerminalObject } from './create-terminal-object';
import { CreateTerminalParams } from './create-terminal-params';
import { toGenCommit } from './gen-conversion';
import { toGenCommit, toGenDomainObject } from '../../thrift/converters';
import { ProviderObject, TerminalObject, Commit } from '../../damsel';
export const createShopTerminal = (terminalObjects: TerminalObject[], providerObject: ProviderObject, params: CreateTerminalParams): Commit => {

View File

@ -1,7 +1,7 @@
import { CreateTerminalParams } from './create-terminal-params';
import { generateID, toMap } from './utils';
import { toGenTerminalObject } from './gen-conversion';
import { TerminalObject } from '../../damsel/domain';
import { toGenTerminalObject } from '../../thrift/converters';
const convert = (id: number, params: CreateTerminalParams): TerminalObject => ({
ref: {

View File

@ -0,0 +1,2 @@
export * from '../../thrift/domain-typed-manager';
export * from './create-terminal-params';

View File

@ -1,4 +1,4 @@
import { ContractModificationUnit, ShopModificationUnit } from '../../damsel';
import { ContractModificationUnit, ShopModificationUnit } from '../../gen-damsel/payment_processing';
export class ModificationUnitContainer {
saved: boolean;

View File

@ -1,4 +1,4 @@
import { PartyModification } from '../../damsel/payment-processing';
import { PartyModification } from '../../gen-damsel/payment_processing';
export class PersistentContainer {
modification: PartyModification;

View File

@ -6,7 +6,7 @@ import {
PartyModificationUnit,
PersistentContainer
} from './model';
import { ContractModificationUnit, ShopModificationUnit } from '../damsel/payment-processing';
import { ContractModificationUnit, ShopModificationUnit } from '../gen-damsel/payment_processing';
interface PersistentUnit {
modificationUnit: ShopModificationUnit | ContractModificationUnit;

View File

@ -3,7 +3,7 @@ import { Subject } from 'rxjs';
import remove from 'lodash-es/remove';
import { PersistentContainer } from './model';
import { PartyModification } from '../damsel/payment-processing';
import { PartyModification } from '../gen-damsel/payment_processing';
@Injectable()
export class PersistentContainerService {

View File

@ -2,8 +2,8 @@ import { getVtbTemplateOptions } from './get-vtb-template-options';
import { getTcsTemplateOptions } from './get-tcs-template-options';
import { getRietTemplateOptions } from './get-riet-template-options';
import { getSngbTemplateOptions } from './get-sngb-template-options';
import { TerminalOption } from '../../../domain/domain-typed-manager/index';
import { DomainModificationInfo } from '../../model/index';
import { DomainModificationInfo } from '../../model';
import { TerminalOption } from '../../domain-typed-manager';
export const getOptions = (option: string, params: DomainModificationInfo): TerminalOption[] => {
const {shopUrl, partyId} = params;

View File

@ -1,4 +1,4 @@
import { TerminalOption } from '../../../domain/domain-typed-manager';
import { TerminalOption } from '../../domain-typed-manager';
export const getRietTemplateOptions = (): TerminalOption[] =>
([

View File

@ -1,5 +1,5 @@
import { getHost } from './get-host';
import { TerminalOption } from '../../../domain/domain-typed-manager';
import { TerminalOption } from '../../domain-typed-manager';
export const getTcsTemplateOptions = (shopUrl: string): TerminalOption[] =>
([

View File

@ -1,6 +1,6 @@
import last from 'lodash-es/last';
import { getHost } from './get-host';
import { TerminalOption } from '../../../domain/domain-typed-manager';
import { TerminalOption } from '../../domain-typed-manager';
const partyIDToSmid = (partyID: string) => last(partyID.split('-'));

View File

@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
import { DomainModificationInfo } from '../model';
import { TerminalObjectService } from './terminal-object.service';
import { ProviderObject } from '../../damsel/domain';
import { CreateTerminalParams, DomainTypedManager } from '../../domain/domain-typed-manager';
import { CreateTerminalParams, DomainTypedManager } from '../domain-typed-manager';
@Component({
selector: 'cc-terminal-object',

View File

@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { FormArray, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { TerminalOption } from '../../domain/domain-typed-manager';
import { TerminalOption } from '../domain-typed-manager';
import { getOptions, prepareTerminalName } from './form-default-values';
import { DomainModificationInfo } from '../model';

View File

@ -1,4 +1,4 @@
<table mat-table [dataSource]="claims" class="mat-elevation-z2">
<table mat-table [dataSource]="claims">
<ng-container matColumnDef="partyID">
<th mat-header-cell *matHeaderCellDef>Party ID</th>
<td mat-cell *matCellDef="let claim">{{ claim.partyId }}</td>

View File

@ -11,6 +11,8 @@
<mat-progress-bar mode="indeterminate"></mat-progress-bar>
</mat-card-footer>
</mat-card>
<cc-claims-table [claims]="claims"></cc-claims-table>
<div class="mat-elevation-z2">
<cc-claims-table [claims]="claims"></cc-claims-table>
</div>
</div>
</div>

View File

@ -0,0 +1,11 @@
import { MerchantCashFlowAccount } from './merchant-cash-flow-account';
import { ProviderCashFlowAccount } from './provider-cash-flow-account';
import { SystemCashFlowAccount } from './system-cash-flow-account';
import { ExternalCashFlowAccount } from './external-cash-flow-account';
export interface CashFlowAccount {
merchant?: MerchantCashFlowAccount;
provider?: ProviderCashFlowAccount;
system?: SystemCashFlowAccount;
external?: ExternalCashFlowAccount;
}

View File

@ -0,0 +1,6 @@
import { CurrencyRef } from './currency-ref';
export interface Cash {
amount: number;
currency: CurrencyRef;
}

View File

@ -0,0 +1,4 @@
export enum ExternalCashFlowAccount {
income,
outcome
}

View File

@ -0,0 +1,6 @@
import { CashFlowAccount } from './cash-flow-account';
export interface FinalCashFlowAccount {
accountType: CashFlowAccount;
accountId: number;
}

View File

@ -0,0 +1,9 @@
import { Cash } from './cash';
import { FinalCashFlowAccount } from './final-cash-flow-account';
export interface FinalCashFlowPosting {
source: FinalCashFlowAccount;
destination: FinalCashFlowAccount;
volume: Cash;
details?: string;
}

View File

@ -74,3 +74,5 @@ export * from './provider-selector';
export * from './system-account-selector';
export * from './system-account-set-decision';
export * from './system-account-set-ref';
export * from './invoice-payment-status';
export * from './invoice-payment-adjustment';

View File

@ -0,0 +1,5 @@
export interface InvoicePaymentAdjustmentStatus {
pending: {};
captured: { at: string };
cancelled: { at: string };
}

View File

@ -0,0 +1,12 @@
import { InvoicePaymentAdjustmentStatus } from './invoice-payment-adjustment-status';
import { FinalCashFlowPosting } from './final-cash-flow-posting';
export interface InvoicePaymentAdjustment {
id: string;
status: InvoicePaymentAdjustmentStatus;
createdAt: string;
domainRevision: number;
reason: string;
newCashFlow: FinalCashFlowPosting[];
oldCashFlowInverse: FinalCashFlowPosting[];
}

View File

@ -0,0 +1,10 @@
import { OperationFailure } from './operation-failure';
export interface InvoicePaymentStatus {
pending?: {};
processed: {};
captured: { reason?: string; };
cancelled: { reason?: string; };
refunded: {};
failed: { failure: OperationFailure; };
}

View File

@ -0,0 +1,5 @@
export enum MerchantCashFlowAccount {
settlement,
guarantee,
payout
}

View File

@ -0,0 +1,10 @@
import { SubFailure } from './sub-failure';
export interface OperationFailure {
operation_timeout?: {};
failure?: {
code: string;
reason?: string;
sub?: SubFailure;
};
}

View File

@ -0,0 +1,3 @@
export enum ProviderCashFlowAccount {
settlement
}

View File

@ -0,0 +1,4 @@
export interface SubFailure {
code: string;
sub?: SubFailure;
}

View File

@ -0,0 +1,3 @@
export enum SystemCashFlowAccount {
settlement
}

View File

@ -1,3 +1,2 @@
export * from './payment-processing';
export * from './domain';
export * from './domain-config';

View File

@ -1,6 +0,0 @@
import { ContractAdjustmentModification } from './contract-adjustment-modification';
export class ContractAdjustmentModificationUnit {
adjustmentId?: string;
modification?: ContractAdjustmentModification;
}

View File

@ -1,5 +0,0 @@
import { ContractAdjustmentParams } from './contract-adjustment-params';
export class ContractAdjustmentModification {
creation: ContractAdjustmentParams;
}

View File

@ -1,5 +0,0 @@
import { ContractTemplateRef } from '../domain';
export class ContractAdjustmentParams {
template: ContractTemplateRef;
}

View File

@ -1,6 +0,0 @@
import { ContractModification } from './contract-modification';
export class ContractModificationUnit {
id: string;
modification: ContractModification;
}

View File

@ -1,19 +0,0 @@
import {
ContractorID,
ReportPreferences,
LegalAgreement
} from '../domain';
import { ContractParams } from './contract-params';
import { ContractTermination } from './contract-termination';
import { ContractAdjustmentModificationUnit } from './contract-adjustment-modification-unit';
import { PayoutToolModificationUnit } from './payout-tool-modification-unit';
export class ContractModification {
creation?: ContractParams;
termination?: ContractTermination;
adjustmentModification?: ContractAdjustmentModificationUnit;
payoutToolModification?: PayoutToolModificationUnit;
legalAgreementBinding?: LegalAgreement;
reportPreferencesModification?: ReportPreferences;
contractorModification?: ContractorID;
}

View File

@ -1,15 +0,0 @@
import {
PaymentInstitutionRef,
ContractTemplateRef,
Contractor,
ContractorID
} from '../domain';
export class ContractParams {
contractorId: ContractorID;
template?: ContractTemplateRef;
paymentInstitution?: PaymentInstitutionRef;
// depricated
contractor: Contractor;
}

View File

@ -1,3 +0,0 @@
export class ContractTermination {
reason: string;
}

View File

@ -1,7 +0,0 @@
import { ContractorID } from '../domain';
import { ContractorModification } from './contractor-modification';
export class ContractorModificationUnit {
id: ContractorID;
modification: ContractorModification;
}

View File

@ -1,5 +0,0 @@
import { Contractor } from '../domain';
export class ContractorModification {
creation: Contractor;
}

View File

@ -1,20 +0,0 @@
export * from './schedule-modification';
export * from './contract-adjustment-modification';
export * from './contract-adjustment-modification-unit';
export * from './contract-adjustment-params';
export * from './contract-modification';
export * from './contract-modification-unit';
export * from './contract-params';
export * from './contract-termination';
export * from './party-modification';
export * from './payout-tool-modification';
export * from './payout-tool-modification-unit';
export * from './payout-tool-params';
export * from './proxy-modification';
export * from './shop-account-params';
export * from './shop-contract-modification';
export * from './shop-modification';
export * from './shop-modification-unit';
export * from './shop-params';
export * from './contractor-modification';
export * from './contract-adjustment-modification-unit';

View File

@ -1,9 +0,0 @@
import { ShopModificationUnit } from './shop-modification-unit';
import { ContractModificationUnit } from './contract-modification-unit';
import { ContractorModificationUnit } from './contractor-modification-unit';
export class PartyModification {
contractModification?: ContractModificationUnit;
shopModification?: ShopModificationUnit;
contractorModification?: ContractorModificationUnit;
}

View File

@ -1,7 +0,0 @@
import { PayoutToolID } from '../domain/payout-tool-id';
import { PayoutToolModification } from './payout-tool-modification';
export class PayoutToolModificationUnit {
payoutToolId: PayoutToolID;
modification: PayoutToolModification;
}

View File

@ -1,7 +0,0 @@
import { PayoutToolParams } from './payout-tool-params';
import { PayoutToolInfo } from '../domain';
export class PayoutToolModification {
creation?: PayoutToolParams;
infoModification?: PayoutToolInfo;
}

View File

@ -1,7 +0,0 @@
import { CurrencyRef } from '../domain/currency-ref';
import { PayoutToolInfo } from '../domain/payout-tool-info';
export class PayoutToolParams {
currency: CurrencyRef;
toolInfo: PayoutToolInfo;
}

View File

@ -1,6 +0,0 @@
import { Proxy } from '../domain/proxy';
// deprecated
export class ProxyModification {
proxy: Proxy;
}

View File

@ -1,5 +0,0 @@
import { BusinessScheduleRef } from '../domain';
export class ScheduleModification {
schedule?: BusinessScheduleRef;
}

View File

@ -1,5 +0,0 @@
import { CurrencyRef } from '../domain/currency-ref';
export class ShopAccountParams {
currency: CurrencyRef;
}

View File

@ -1,7 +0,0 @@
import { ContractID } from '../domain/contract-id';
import { PayoutToolID } from '../domain/payout-tool-id';
export class ShopContractModification {
contractId: ContractID;
payoutToolId: PayoutToolID;
}

View File

@ -1,6 +0,0 @@
import { ShopModification } from './shop-modification';
export class ShopModificationUnit {
id: string;
modification: ShopModification;
}

View File

@ -1,23 +0,0 @@
import { ShopParams } from './shop-params';
import { CategoryRef } from '../domain/category-ref';
import { ShopDetails } from '../domain/shop-details';
import { PayoutToolID } from '../domain/payout-tool-id';
import { ShopLocation } from '../domain/shop-location';
import { ShopContractModification } from './shop-contract-modification';
import { ProxyModification } from './proxy-modification';
import { ShopAccountParams } from './shop-account-params';
import { ScheduleModification } from './schedule-modification';
export class ShopModification {
creation?: ShopParams;
categoryModification?: CategoryRef;
detailsModification?: ShopDetails;
contractModification?: ShopContractModification;
payoutToolModification?: PayoutToolID;
locationModification?: ShopLocation;
shopAccountCreation?: ShopAccountParams;
payoutScheduleModification?: ScheduleModification;
// deprecated
proxyModification?: ProxyModification;
}

View File

@ -1,13 +0,0 @@
import { CategoryRef } from '../domain/category-ref';
import { ShopLocation } from '../domain/shop-location';
import { ShopDetails } from '../domain/shop-details';
import { ContractID } from '../domain/contract-id';
import { PayoutToolID } from '../domain/payout-tool-id';
export class ShopParams {
category?: CategoryRef;
location: ShopLocation;
details: ShopDetails;
contractId: ContractID;
payoutToolId: PayoutToolID;
}

View File

@ -1,47 +0,0 @@
import { Injectable, NgZone } from '@angular/core';
import { Observable } from 'rxjs';
import { createHttpClient } from './domain-connector';
import { DomainClient } from './domain-connector';
import {
Snapshot,
Version,
Commit,
Reference
} from '../damsel';
import * as Repository from './gen-nodejs/Repository';
type Exception = any;
@Injectable()
export class DmtService {
private domainClient: DomainClient;
constructor(private zone: NgZone) {
this.domainClient = createHttpClient(Repository);
}
checkout(reference: Reference): Observable<Snapshot> {
return Observable.create((observer) => {
this.domainClient.Checkout(reference, (ex: Exception, snapshot: Snapshot) => {
this.zone.run(() => {
ex ? observer.error(ex) : observer.next(snapshot);
observer.complete();
});
});
});
}
commit(version: Version, commit: Commit): Observable<Version> {
return Observable.create((observer) => {
this.domainClient.Commit(version, commit, (ex: Exception, nextVersion: Version) => {
this.zone.run(() => {
ex ? observer.error(ex) : observer.next(nextVersion);
observer.complete();
});
});
});
}
}

View File

@ -1,8 +0,0 @@
import connectClient from 'woody_js/dist/connect-client';
export type DomainService = any;
export type DomainClient = any;
export const createHttpClient = (service: DomainService): DomainClient =>
connectClient(location.hostname, location.port, '/v1/domain/repository', service);

View File

@ -1,2 +0,0 @@
export * from './domain-typed-manager';
export * from './create-terminal-params';

View File

@ -1,12 +0,0 @@
import { NgModule } from '@angular/core';
import { DomainTypedManager } from './domain-typed-manager';
import { DmtService } from './dmt.service';
@NgModule({
providers: [
DmtService,
DomainTypedManager
]
})
export class DomainModule {}

View File

@ -0,0 +1,8 @@
import { Price } from './price';
export class CartLine {
product: string;
quantity: number;
price: Price;
metadata: any[];
}

View File

@ -0,0 +1,5 @@
import { CartLine } from './card-line';
export class Cart {
lines: CartLine[];
}

View File

@ -0,0 +1,3 @@
export class Currency {
symbolicCode: string;
}

View File

@ -5,3 +5,5 @@ export * from './contract-template';
export * from './payout';
export * from './payouts-response';
export * from './payout-statuses';
export * from './payment';
export * from './invoice';

View File

@ -0,0 +1,15 @@
import { Cart } from './cart';
export class Invoice {
id: string;
ownerId: string;
shopId: string;
createdAt: string;
status: object;
product: string;
description: string;
due: string;
amount: number;
currencySymbolicCode: string;
cart: Cart;
}

View File

@ -1,4 +1,4 @@
import { PartyModification } from '../../damsel';
import { PartyModification } from '../../gen-damsel/payment_processing';
export class PartyModificationUnit {
modifications: PartyModification[];

View File

@ -0,0 +1,20 @@
export class Payment {
id: string;
invoiceId: string;
ownerId: string;
shopId: string;
createdAt: string;
status: object;
amount: number;
fee: number;
providerFee: number;
externalFee: number;
currencySymbolicCode: string;
payer: object;
ipAddress: string;
fingerprint: string;
email: string;
sessionId: string;
locationInfo: object;
flow: object;
}

View File

@ -0,0 +1,6 @@
import { Currency } from './currency';
export class Price {
amount: string;
currency: Currency;
}

View File

@ -5,6 +5,7 @@ import { ClaimService } from './claim.service';
import { CategoryService } from './category.service';
import { ContractService } from './contract.service';
import { PayoutsService } from './payouts.service';
import { ReportService } from './report.service';
import { PartyService } from './party.service';
@NgModule({
@ -14,6 +15,7 @@ import { PartyService } from './party.service';
CategoryService,
ContractService,
PayoutsService,
ReportService,
PartyService
]
})

View File

@ -4,3 +4,4 @@ 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';

View File

@ -0,0 +1,11 @@
export class ReportSearchParams {
fromTime: string;
toTime: string;
from: string;
size: string;
merchantId?: string;
invoiceId?: string;
status?: string;
categoryIds?: string[];
paymentDomainRevision?: string;
}

View File

@ -0,0 +1,36 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Invoice, Payment } from './model';
import { ReportSearchParams } from './params';
import { ConfigService } from '../core/config.service';
import { decode } from '../shared/papi-formatter';
interface Params {
[param: string]: string | string[];
}
@Injectable()
export class ReportService {
private papiEndpoint: string;
constructor(
private http: HttpClient,
private configService: ConfigService
) {
this.papiEndpoint = configService.config.papiEndpoint;
}
getInvoices(params: ReportSearchParams): Observable<Invoice[]> {
return this.http.get<{invoices: any[]}>(`${this.papiEndpoint}/mst/invoices`, {params: params as ReportSearchParams & Params})
.pipe(map((res) => decode(res.invoices)));
}
getPayments(params: ReportSearchParams): Observable<Payment[]> {
return this.http.get<{payments: any[]}>(`${this.papiEndpoint}/mst/payments`, {params: params as ReportSearchParams & Params})
.pipe(map((res) => decode(res.payments)));
}
}

View File

@ -2,7 +2,7 @@ import { Component, Input, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { DomainTypedManager } from '../../../domain/domain-typed-manager';
import { DomainTypedManager } from '../../../claim/domain-typed-manager';
import { BusinessScheduleObject } from '../../../damsel/domain';
@Component({

View File

@ -4,7 +4,7 @@ import { map } from 'rxjs/operators';
import sortBy from 'lodash-es/sortBy';
import { Observable } from 'rxjs';
import { DomainTypedManager } from '../../../domain/domain-typed-manager';
import { DomainTypedManager } from '../../../claim/domain-typed-manager';
import { PaymentInstitutionObject } from '../../../damsel/domain';
@Component({

View File

@ -9,11 +9,11 @@ import {
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { PartyModification } from '../damsel/payment-processing';
import { ContractModificationName, ShopModificationName } from '../claim/model';
import { toPartyModification } from './to-party-modification';
import { ActionType, ModificationAction } from '../claim/modification-action';
import { filterEmptyStringValues } from './filter-empty-string-value';
import { PartyModification } from '../gen-damsel/payment_processing';
@Component({
selector: 'cc-party-modification-creation',

View File

@ -3,7 +3,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { BusinessScheduleObject } from '../../../damsel/domain';
import { DomainTypedManager } from '../../../domain/domain-typed-manager';
import { DomainTypedManager } from '../../../claim/domain-typed-manager';
@Component({
selector: 'cc-schedule-ref',

View File

@ -0,0 +1,8 @@
<div fxLayout fxLayoutAlign="space-between">
<label class="mat-subheading-2" fxFlex="80">{{description}}</label>
<div *ngIf="hasAction" fxFlex="20">
<button [disabled]="actionDisabled" (click)="doAction()" mat-stroked-button>
{{actionButtonLabel | uppercase}}
</button>
</div>
</div>

View File

@ -0,0 +1,27 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'cc-action-item',
templateUrl: 'action-item.component.html'
})
export class ActionItemComponent {
@Input()
description: string;
@Input()
hasAction = false;
@Input()
actionButtonLabel: string;
@Input()
actionDisabled: boolean;
@Output()
action: EventEmitter<void> = new EventEmitter<void>();
doAction() {
this.action.emit();
}
}

View File

@ -0,0 +1,28 @@
import { ExecResultType } from '../executor.service';
export enum EventType {
BatchOperationStarted = 'BatchOperationStarted',
BatchOperationFinished = 'BatchOperationFinished',
BatchOperationFailed = 'BatchOperationFailed',
PaymentAdjustmentsCreated = 'PaymentAdjustmentsCreated',
PaymentAdjustmentsCancelled = 'PaymentAdjustmentsCancelled',
PaymentAdjustmentsCaptured = 'PaymentAdjustmentsCaptured',
CreatePaymentAdjustmentFailed = 'CreatePaymentAdjustmentFailed',
CancelPaymentAdjustmentFailed = 'CancelPaymentAdjustmentFailed',
CapturePaymentAdjustmentFailed = 'CapturePaymentAdjustmentFailed'
}
export type OperationType = ExecResultType;
export interface AdjustmentOperationEvent<T = {}> {
type: EventType;
operationType?: OperationType;
payload?: T[];
}
export interface OperationFailedPayload<C = {}, S = {}> {
code: C;
operationScope: S;
}
export interface OperationError<C, S> extends AdjustmentOperationEvent<OperationFailedPayload<C, S>> {}

View File

@ -0,0 +1,43 @@
import { Injectable } from '@angular/core';
import { Observable, Subject, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/internal/operators';
import groupBy from 'lodash-es/groupBy';
import { ExecutorService } from '../executor.service';
import { PaymentProcessingTypedManager } from '../../../thrift/payment-processing-typed-manager';
import { AdjustmentOperationEvent, EventType } from './adjustment-event';
import { ExecResultGroup } from './exec-result-group';
@Injectable()
export abstract class AdjustmentOperationService {
events$: Subject<AdjustmentOperationEvent> = new Subject<AdjustmentOperationEvent>();
progress$: Subject<number>;
constructor(
protected executorService: ExecutorService,
protected manager: PaymentProcessingTypedManager) {
this.progress$ = this.executorService.progress$;
}
batch(params: any[]): Observable<void> {
const execParams = this.toExecParams(params);
this.events$.next({type: EventType.BatchOperationStarted});
return this.executorService.exec(execParams)
.pipe(
map((res) => groupBy(res, 'type')),
tap(this.handleExecResult.bind(this)),
tap(() => this.events$.next({type: EventType.BatchOperationFinished})),
map(() => null),
catchError((err) => {
this.events$.next({type: EventType.BatchOperationFailed});
return throwError(err);
})
);
}
protected abstract toExecParams(params: any[]): any[];
protected abstract handleExecResult(group: ExecResultGroup): void;
}

View File

@ -0,0 +1,22 @@
import { InvoicePaymentAdjustmentParams, UserInfo } from '../../../gen-damsel/payment_processing';
export interface PaymentAdjustmentCreationParams {
user: UserInfo;
invoiceId: string;
paymentId: string;
params: InvoicePaymentAdjustmentParams;
}
export interface PaymentAdjustmentCancelParams {
user: UserInfo;
invoiceId: string;
paymentId: string;
adjustmentId: string;
}
export interface PaymentAdjustmentCaptureParams {
user: UserInfo;
invoiceId: string;
paymentId: string;
adjustmentId: string;
}

View File

@ -0,0 +1,51 @@
import { Injectable } from '@angular/core';
import { Observable, of, Subject } from 'rxjs';
import { mergeAll } from 'rxjs/internal/operators';
import { CaptureAdjustmentService } from './capture-adjustment.service';
import { CancelAdjustmentService } from './cancel-adjustment.service';
import { CreateAdjustmentService } from './create-adjustment.service';
import { AdjustmentOperationEvent } from './adjustment-event';
import {
PaymentAdjustmentCancelParams,
PaymentAdjustmentCaptureParams,
PaymentAdjustmentCreationParams
} from './adjustment-params';
@Injectable()
export class BatchPaymentAdjustmentService {
progress$: Subject<number> = new Subject<number>();
events$: Subject<AdjustmentOperationEvent> = new Subject<AdjustmentOperationEvent>();
constructor(
private createAdjustmentService: CreateAdjustmentService,
private cancelAdjustmentService: CancelAdjustmentService,
private captureAdjustmentService: CaptureAdjustmentService
) {
of(this.createAdjustmentService.events$, this.cancelAdjustmentService.events$, this.captureAdjustmentService.events$)
.pipe(mergeAll<AdjustmentOperationEvent>())
.subscribe((event) => {
this.events$.next(event);
});
of(this.createAdjustmentService.progress$, this.cancelAdjustmentService.progress$, this.captureAdjustmentService.progress$)
.pipe(mergeAll())
.subscribe((event) => {
this.progress$.next(event);
});
}
create(params: PaymentAdjustmentCreationParams[]): Observable<void> {
return this.createAdjustmentService.batch(params);
}
cancel(params: PaymentAdjustmentCancelParams[]): Observable<void> {
return this.cancelAdjustmentService.batch(params);
}
capture(params: PaymentAdjustmentCaptureParams[]): Observable<void> {
return this.captureAdjustmentService.batch(params);
}
}

View File

@ -0,0 +1,59 @@
import { AdjustmentOperationService } from './adjustment-operation.service';
import { ExecErrorResult, ExecResultType } from '../executor.service';
import {
AdjustmentOperationEvent,
EventType,
OperationError,
OperationFailedPayload
} from './adjustment-event';
import { CancelPaymentAdjustmentErrorCodes } from './error-codes';
import { ExecResultGroup } from './exec-result-group';
import { PaymentAdjustmentCancelParams } from './adjustment-params';
export class CancelAdjustmentService extends AdjustmentOperationService {
protected toExecParams(cancelParams: any[]): any[] {
return cancelParams.map((params) => ({
fn: this.manager.cancelPaymentAdjustment,
context: this.manager,
params
}));
}
protected handleExecResult(group: ExecResultGroup): void {
const {success, error} = group;
if (success) {
this.events$.next({
type: EventType.PaymentAdjustmentsCancelled,
operationType: ExecResultType.success,
payload: success.map(({container: {params}}) => params)
} as AdjustmentOperationEvent<PaymentAdjustmentCancelParams>);
}
if (error) {
this.events$.next({
type: EventType.CancelPaymentAdjustmentFailed,
operationType: ExecResultType.error,
payload: this.toErrorPayload(error)
} as OperationError<CancelPaymentAdjustmentErrorCodes | 'InternalServer', PaymentAdjustmentCancelParams>);
}
}
private toErrorPayload(result: ExecErrorResult[]): OperationFailedPayload[] {
return result.map((error) => {
const {exception, container: {params}} = error;
const errorCodes = [
'InvalidUser',
'InvoiceNotFound',
'InvoicePaymentNotFound',
'InvoicePaymentAdjustmentNotFound',
'InvalidPaymentAdjustmentStatus'
];
return {
code: errorCodes.includes(exception.name)
? exception.name
: 'InternalServer',
operationScope: params
};
});
}
}

View File

@ -0,0 +1,59 @@
import { AdjustmentOperationService } from './adjustment-operation.service';
import { ExecErrorResult, ExecResultType } from '../executor.service';
import {
AdjustmentOperationEvent,
EventType,
OperationError,
OperationFailedPayload
} from './adjustment-event';
import { CapturePaymentAdjustmentErrorCodes } from './error-codes';
import { ExecResultGroup } from './exec-result-group';
import { PaymentAdjustmentCaptureParams } from './adjustment-params';
export class CaptureAdjustmentService extends AdjustmentOperationService {
protected toExecParams(captureParams: any[]): any[] {
return captureParams.map((params) => ({
fn: this.manager.capturePaymentAdjustment,
context: this.manager,
params
}));
}
protected handleExecResult(group: ExecResultGroup): void {
const {success, error} = group;
if (success) {
this.events$.next({
type: EventType.PaymentAdjustmentsCaptured,
operationType: ExecResultType.success,
payload: success.map(({container: {params}}) => params)
} as AdjustmentOperationEvent<PaymentAdjustmentCaptureParams>);
}
if (error) {
this.events$.next({
type: EventType.CapturePaymentAdjustmentFailed,
operationType: ExecResultType.error,
payload: this.toErrorPayload(error)
} as OperationError<CapturePaymentAdjustmentErrorCodes | 'InternalServer', PaymentAdjustmentCaptureParams>);
}
}
private toErrorPayload(result: ExecErrorResult[]): OperationFailedPayload[] {
return result.map((error) => {
const {exception, container: {params}} = error;
const errorCodes = [
'InvalidUser',
'InvoiceNotFound',
'InvoicePaymentNotFound',
'InvoicePaymentAdjustmentNotFound',
'InvalidPaymentAdjustmentStatus'
];
return {
code: errorCodes.includes(exception.name)
? exception.name
: 'InternalServer',
operationScope: params
};
});
}
}

View File

@ -0,0 +1,69 @@
import { ExecErrorResult, ExecResultType, ExecSuccessResult } from '../executor.service';
import { AdjustmentOperationService } from './adjustment-operation.service';
import {
AdjustmentOperationEvent,
EventType,
OperationError,
OperationFailedPayload
} from './adjustment-event';
import { CreatePaymentAdjustmentErrorCodes } from './error-codes';
import { ExecResultGroup } from './exec-result-group';
import { PaymentAdjustmentCreationScope } from './payment-adjustment-creation-scope';
export class CreateAdjustmentService extends AdjustmentOperationService {
protected toExecParams(creationParams: any[]): any[] {
return creationParams.map((params) => ({
fn: this.manager.createPaymentAdjustment,
context: this.manager,
params
}));
}
protected handleExecResult(group: ExecResultGroup): void {
const {success, error} = group;
if (success) {
this.events$.next({
type: EventType.PaymentAdjustmentsCreated,
operationType: ExecResultType.success,
payload: this.toSuccessPayload(success)
} as AdjustmentOperationEvent<PaymentAdjustmentCreationScope>);
}
if (error) {
this.events$.next({
type: EventType.CreatePaymentAdjustmentFailed,
operationType: ExecResultType.error,
payload: this.toErrorPayload(error)
} as OperationError<CreatePaymentAdjustmentErrorCodes | 'InternalServer', PaymentAdjustmentCreationScope>);
}
}
private toSuccessPayload(result: ExecSuccessResult[]): PaymentAdjustmentCreationScope[] {
return result.map(({data, container: {params}}) => ({
adjustmentId: data && data.id,
creationParams: params
} as PaymentAdjustmentCreationScope));
}
private toErrorPayload(result: ExecErrorResult[]): OperationFailedPayload[] {
return result.map((error) => {
const {exception, container: {params}} = error;
const errorCodes = [
'InvoicePaymentAdjustmentPending',
'InvalidPaymentStatus',
'InvoicePaymentNotFound',
'InvoiceNotFound',
'InvalidUser'
];
return {
code: errorCodes.includes(exception.name)
? exception.name
: 'InternalServer',
operationScope: {
creationParams: params,
adjustmentId: exception.id ? exception.id : null
}
};
});
}
}

View File

@ -0,0 +1,23 @@
export enum CreatePaymentAdjustmentErrorCodes {
InvoicePaymentAdjustmentPending = 'InvoicePaymentAdjustmentPending',
InvalidPaymentStatus = 'InvalidPaymentStatus',
InvoicePaymentNotFound = 'InvoicePaymentNotFound',
InvoiceNotFound = 'InvoiceNotFound',
InvalidUser = 'InvalidUser'
}
export enum CancelPaymentAdjustmentErrorCodes {
InvalidUser = 'InvalidUser',
InvoiceNotFound = 'InvoiceNotFound',
InvoicePaymentNotFound = 'InvoicePaymentNotFound',
InvoicePaymentAdjustmentNotFound = 'InvoicePaymentAdjustmentNotFound',
InvalidPaymentAdjustmentStatus = 'InvalidPaymentAdjustmentStatus'
}
export enum CapturePaymentAdjustmentErrorCodes {
InvalidUser = 'InvalidUser',
InvoiceNotFound = 'InvoiceNotFound',
InvoicePaymentNotFound = 'InvoicePaymentNotFound',
InvoicePaymentAdjustmentNotFound = 'InvoicePaymentAdjustmentNotFound',
InvalidPaymentAdjustmentStatus = 'InvalidPaymentAdjustmentStatus'
}

View File

@ -0,0 +1,6 @@
import { ExecErrorResult, ExecSuccessResult } from '../executor.service';
export interface ExecResultGroup {
success?: ExecSuccessResult[];
error?: ExecErrorResult[];
}

View File

@ -0,0 +1,8 @@
export * from './adjustment-event';
export * from './error-codes';
export * from './adjustment-params';
export * from './payment-adjustment-creation-scope';
export * from './create-adjustment.service';
export * from './cancel-adjustment.service';
export * from './capture-adjustment.service';
export * from './batch-payment-adjustment.service';

View File

@ -0,0 +1,6 @@
import { PaymentAdjustmentCreationParams } from './adjustment-params';
export interface PaymentAdjustmentCreationScope {
adjustmentId?: string;
creationParams: PaymentAdjustmentCreationParams;
}

Some files were not shown because too many files have changed in this diff Show More