Skip to content
Permalink
Browse files
Merge pull request #47 from markvanveen/develop
Teller denomination
  • Loading branch information
markvanveen committed Oct 17, 2017
2 parents 8d2afbe + 44437a8 commit 07f88777e0e14237ea33bf432e2d39c9d0a08d78
Show file tree
Hide file tree
Showing 33 changed files with 812 additions and 20 deletions.
@@ -48,6 +48,7 @@ module.exports = function (config) {
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
singleRun: false,
browserNoActivityTimeout: 20000
});
};
@@ -13,8 +13,8 @@
"karma": "karma start ./karma.conf.js --single-run",
"devTest": "ng test",
"dev": "ng serve --verbose --proxy-config proxy.conf.json",
"runProd": "ng serve --proxy-config proxy.conf.json --prod --aot --build-optimizer",
"build": "ng build --prod --aot",
"runProd": "ng serve --proxy-config proxy.conf.json --prod",
"build": "ng build --prod",
"checkLicenses": "license-to-fail ./license.config.js",
"bundle-report": "webpack-bundle-analyzer dist/stats.json"
},
@@ -63,7 +63,7 @@
"zone.js": "0.8.17"
},
"devDependencies": {
"@angular/cli": "1.4.2",
"@angular/cli": "1.4.7",
"@angular/compiler-cli": "4.4.5",
"@types/hammerjs": "2.0.30",
"@types/jasmine": "2.5.38",
@@ -14,7 +14,7 @@
limitations under the License.
-->

<fims-layout-card-over title="{{'Trial Balance' | translate}}" [navigateBackTo]="['../']">
<fims-layout-card-over title="{{'Trial balance' | translate}}" [navigateBackTo]="['../']">
<fims-layout-card-over-header-menu>
<mat-checkbox [(ngModel)]="includeEmptyEntries" (change)="fetchTrialBalance($event)" translate>Include empty entries?</mat-checkbox>
</fims-layout-card-over-header-menu>
@@ -26,7 +26,7 @@ import {MatCheckboxChange} from '@angular/material';
})
export class TrailBalanceComponent implements OnInit {

includeEmptyEntries = true;
includeEmptyEntries = false;

trialBalance$: Observable<TrialBalance>;

@@ -14,6 +14,6 @@
limitations under the License.
-->

<a mat-fab color="accent" class="fims-fab-button" title="{{title}}" [routerLink]="link" *hasPermission="permission">
<a mat-fab color="accent" class="fims-fab-button" title="{{title}}" [routerLink]="link" [disabled]="disabled" *hasPermission="permission">
<mat-icon>{{icon}}</mat-icon>
</a>
@@ -33,6 +33,8 @@ export class FimsFabButtonComponent implements OnInit {

@Input() permission: FimsPermission;

@Input() disabled = false;

constructor() {
}

@@ -45,6 +45,6 @@ <h3 matLine translate>CREATED</h3>
</mat-list-item>
<mat-list-item *ngSwitchCase="'PAUSED'">
<mat-icon matListAvatar color="accent">hourglass_empty</mat-icon>
<h3 matLine translate>CREATED</h3>
<h3 matLine translate>PAUSED</h3>
</mat-list-item>
</ng-container>
@@ -0,0 +1,38 @@
<!--
Copyright 2017 The Mifos Initiative.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<fims-layout-card-over title="{{ 'Manage denominations' | translate}}" [navigateBackTo]="['../../../../../../../']">
<td-message
*ngIf="isTellerNotPaused$ | async"
label="{{'Teller is not paused' | translate }}"
sublabel="{{'Teller must be paused to create denominations' | translate }}"
color="warn"
icon="error">
</td-message>
<fims-data-table flex
[columns]="columns"
[data]="denominationData$ | async"
[sortable]="false"
[pageable]="false"
[actionColumn]="false">
</fims-data-table>
</fims-layout-card-over>
<fims-fab-button
title="{{'Create denomination' | translate}}"
icon="attach_money" [link]="['create']"
[permission]="{ id: 'teller_management', accessLevel: 'CHANGE'}"
[disabled]="isTellerNotPaused$ | async">
</fims-fab-button>
@@ -0,0 +1,80 @@
/**
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Component, OnDestroy, OnInit} from '@angular/core';
import {TableData} from '../../../../../common/data-table/data-table.component';
import {Subscription} from 'rxjs/Subscription';
import {Observable} from 'rxjs/Observable';
import * as fromOffices from '../../../../store/index';
import {OfficesStore} from '../../../../store/index';
import {LoadDenominationAction} from '../../../../store/teller/denomination/denomination.actions';
import {DatePipe} from '@angular/common';

@Component({
templateUrl: './denomination.list.component.html',
providers: [DatePipe]
})
export class TellerDenominationListComponent implements OnInit, OnDestroy {

private loadDenominationSubscription: Subscription;

denominationData$: Observable<TableData>;

isTellerNotPaused$: Observable<boolean>;

columns: any[] = [
{name: 'countedTotal', label: 'Counted total'},
{name: 'note', label: 'Note'},
{name: 'adjustingJournalEntry', label: 'Adjusting journal entry'},
{
name: 'createdOn', label: 'Created on', format: (v: any) => {
return this.datePipe.transform(v, 'short');
}
},
{name: 'createdBy', label: 'Created by'}
];

constructor(private store: OfficesStore, private datePipe: DatePipe) {}

ngOnInit(): void {
const selectedTeller$ = this.store.select(fromOffices.getSelectedTeller).filter(teller => !!teller);

this.isTellerNotPaused$ = selectedTeller$.map(teller => teller.state !== 'PAUSED');

this.loadDenominationSubscription = Observable.combineLatest(
this.store.select(fromOffices.getSelectedOffice).filter(office => !!office),
selectedTeller$,
(office, teller) => ({
office,
teller
})
).map(result => new LoadDenominationAction({
officeId: result.office.identifier,
tellerCode: result.teller.code
})).subscribe(this.store);

this.denominationData$ = this.store.select(fromOffices.getDenominationsEntities)
.map(tellers => ({
data: tellers,
totalElements: tellers.length,
totalPages: 1
}));
}

ngOnDestroy(): void {
this.loadDenominationSubscription.unsubscribe();
}

}
@@ -0,0 +1,23 @@
<!--
Copyright 2017 The Mifos Initiative.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<fims-layout-card-over title="{{'Create new denomination' | translate}}" *ngIf="currentSelection$ | async as selection">
<fims-denomination-form-component #form
[balanceSheet]="balanceSheet$ | async"
(onSave)="onSave(selection.officeId, selection.tellerId, $event)"
(onCancel)="onCancel()">
</fims-denomination-form-component>
</fims-layout-card-over>
@@ -0,0 +1,74 @@
/**
* Copyright 2017 The Mifos Initiative.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {Component} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import * as fromOffices from '../../../../../store/index';
import {OfficesStore} from '../../../../../store/index';
import {TellerDenomination} from '../../../../../../services/teller/domain/teller-denomination.model';
import {CREATE_DENOMINATION} from '../../../../../store/teller/denomination/denomination.actions';
import {Observable} from 'rxjs/Observable';
import {TellerService} from '../../../../../../services/teller/teller-service';
import {TellerBalanceSheet} from '../../../../../../services/teller/domain/teller-balance-sheet.model';

interface CurrentSelection {
officeId: string;
tellerId: string;
}

@Component({
templateUrl: './create.form.component.html'
})
export class CreateDenominationFormComponent {

currentSelection$: Observable<CurrentSelection>;

balanceSheet$: Observable<TellerBalanceSheet>;

constructor(private router: Router, private route: ActivatedRoute, private store: OfficesStore, private tellerService: TellerService) {
this.currentSelection$ = Observable.combineLatest(
this.store.select(fromOffices.getSelectedOffice).filter(office => !!office),
this.store.select(fromOffices.getSelectedTeller).filter(teller => !!teller),
(office, teller) => ({
office,
teller
})).map(result => ({
officeId: result.office.identifier,
tellerId: result.teller.code
}));

this.balanceSheet$ = this.currentSelection$
.switchMap(selection => this.tellerService.getBalance(selection.officeId, selection.tellerId));
}

onSave(officeId: string, tellerCode: string, denomination: TellerDenomination): void {
this.store.dispatch({ type: CREATE_DENOMINATION, payload: {
officeId,
tellerCode,
denomination,
activatedRoute: this.route
}});
}

onCancel(): void {
this.navigateAway();
}

navigateAway(): void {
this.router.navigate(['../'], { relativeTo: this.route });
}

}
@@ -0,0 +1,78 @@
<!--
Copyright 2017 The Mifos Initiative.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<td-steps mode="'vertical'">
<td-step #detailsStep label="{{'Denomination details' | translate}}"
[state]="form.valid ? 'complete' : form.pristine ? 'none' : 'required'" [active]="true">
<form [formGroup]="form" layout="column">
<mat-form-field layout-margin flex>
<textarea matInput placeholder="{{'Note(Optional)' | translate}}" formControlName="note"></textarea>
<mat-error *ngIf="form.get('note').hasError('required')" translate>
Required
</mat-error>
</mat-form-field>
<div layout-gt-xs="column" layout-margin formArrayName="details">
<h4 translate>Details</h4>
<div *ngFor="let detail of details; let i=index" [formGroupName]="i" layout="row">
<fims-text-input type="number" [form]="detail" controlName="value" placeholder="{{'Note value' | translate}}"></fims-text-input>
<fims-text-input type="number" [form]="detail" controlName="count" placeholder="{{'Count' | translate}}"></fims-text-input>
<mat-form-field layout-margin>
<input matInput
placeholder="{{'Subtotal' | translate}}"
[disabled]="true"
[value]="getTotalValue(detail) | displayFimsNumber"
flex/>
</mat-form-field>
<button mat-button (click)="removeDetail(i)" *ngIf="i > 0">{{'Remove detail' | translate}}</button>
</div>
<button mat-button (click)="addDetail()">{{'Add detail' | translate}}</button>
<table td-data-table>
<tbody>
<tr td-data-table-row>
<td td-data-table-cell>
<b translate>Total</b>
</td>
<td td-data-table-cell>
<b>{{overallTotal | displayFimsNumber}}</b>
</td>
<td td-data-table-cell></td>
<td td-data-table-cell></td>
</tr>
<tr td-data-table-row>
<td td-data-table-cell>
<b translate>Cash on hand</b>
</td>
<td td-data-table-cell>
<b>{{balanceSheet?.cashOnHand | displayFimsNumber}}</b>
</td>
<td td-data-table-cell></td>
<td td-data-table-cell></td>
</tr>
</tbody>
</table>
</div>
</form>
<ng-template td-step-actions>
<fims-form-final-action
[resourceName]="'DENOMINATION'"
[editMode]="false"
[disabled]="form.invalid"
(onCancel)="cancel()"
(onSave)="save()" flex>
</fims-form-final-action>
</ng-template>
</td-step>
</td-steps>

0 comments on commit 07f8877

Please sign in to comment.