feat(accounting): search journal entry component
Add search journal entry component.
This commit is contained in:
@@ -6,6 +6,7 @@ import { AccountingComponent } from './accounting.component';
|
||||
import { FrequentPostingsComponent } from './frequent-postings/frequent-postings.component';
|
||||
import { ViewTransactionComponent } from './view-transaction/view-transaction.component';
|
||||
import { CreateJournalEntryComponent } from './create-journal-entry/create-journal-entry.component';
|
||||
import { SearchJournalEntryComponent } from './search-journal-entry/search-journal-entry.component';
|
||||
|
||||
const routes: Routes = [
|
||||
Route.withShell([
|
||||
@@ -33,6 +34,11 @@ const routes: Routes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'journal-entries',
|
||||
component: SearchJournalEntryComponent,
|
||||
data: { title: extract('Search Journal Entry'), breadcrumb: 'Search Journal Entry' }
|
||||
},
|
||||
{
|
||||
path: 'journal-entries/create',
|
||||
component: CreateJournalEntryComponent,
|
||||
|
||||
@@ -18,11 +18,9 @@
|
||||
<p matLine>Manual journal entry transactions recorded in a journal</p>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item>
|
||||
<mat-list-item [routerLink]="['/accounting/journal-entries']">
|
||||
<mat-icon matListIcon>search</mat-icon>
|
||||
<a matLine href="https://www.google.com">
|
||||
Search Journal Entries
|
||||
</a>
|
||||
<h4 matLine>Search Journal Entries</h4>
|
||||
<p matLine>Advanced search option for journal entries</p>
|
||||
</mat-list-item>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { ViewTransactionComponent } from './view-transaction/view-transaction.co
|
||||
import { RevertTransactionComponent } from './revert-transaction/revert-transaction.component';
|
||||
import { ViewJournalEntryComponent } from './view-journal-entry/view-journal-entry.component';
|
||||
import { CreateJournalEntryComponent } from './create-journal-entry/create-journal-entry.component';
|
||||
import { SearchJournalEntryComponent } from './search-journal-entry/search-journal-entry.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -24,7 +25,8 @@ import { CreateJournalEntryComponent } from './create-journal-entry/create-journ
|
||||
ViewTransactionComponent,
|
||||
RevertTransactionComponent,
|
||||
ViewJournalEntryComponent,
|
||||
CreateJournalEntryComponent
|
||||
CreateJournalEntryComponent,
|
||||
SearchJournalEntryComponent
|
||||
],
|
||||
entryComponents: [
|
||||
RevertTransactionComponent,
|
||||
|
||||
@@ -36,6 +36,10 @@ export class AccountingService {
|
||||
return this.http.get(`/journalentries`, { params: httpParams });
|
||||
}
|
||||
|
||||
getJournalEntries() {
|
||||
return this.http.get('/journalentries');
|
||||
}
|
||||
|
||||
revertTransaction(transactionId: string, comments: string) {
|
||||
let httpParams = new HttpParams();
|
||||
httpParams = httpParams.set('command', 'reverse');
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<div class="container" fxLayout="row wrap" fxLayoutGap="2%">
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-select placeholder="Office" [formControl]="officeName" (selectionChange)="applyFilter($event.value, 'officeName')">
|
||||
<mat-option *ngFor="let office of officeData" [value]="office.name">
|
||||
{{ office.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-select placeholder="Affected GL Entry" [formControl]="glAccountCode" (selectionChange)="applyFilter($event.value, 'glAccountCode')">
|
||||
<mat-option *ngFor="let affectedGLEntryDebit of glAccountData" [value]="affectedGLEntryDebit.glCode">
|
||||
{{ affectedGLEntryDebit.name + ' (' + affectedGLEntryDebit.glCode + ')' }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="31%">
|
||||
<mat-select placeholder="Filter" [formControl]="filter" (selectionChange)="applyFilter($event.value, 'filter')">
|
||||
<mat-option *ngFor="let filter of filterData" [value]="filter.value">
|
||||
{{ filter.option }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="31%">
|
||||
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="transactionDateFromPicker" placeholder="Transaction Date From" [formControl]="transactionDateFrom">
|
||||
<mat-datepicker-toggle matSuffix [for]="transactionDateFromPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #transactionDateFromPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="31%">
|
||||
<input matInput [min]="minDate" [max]="maxDate" [matDatepicker]="transactionDateToPicker" placeholder="Transaction Date To" [formControl]="transactionDateTo">
|
||||
<mat-datepicker-toggle matSuffix [for]="transactionDateToPicker"></mat-datepicker-toggle>
|
||||
<mat-datepicker #transactionDateToPicker></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="31%">
|
||||
<input matInput placeholder="Transaction ID" [formControl]="transactionId" (keyup)="applyFilter($event.target.value, 'transactionId')">
|
||||
</mat-form-field>
|
||||
<!-- <mat-form-field fxFlex="33%">
|
||||
<mat-select placeholder="Transaction ID" [formControl]="transactionId">
|
||||
<mat-option *ngFor="let transaction of dataSource?.data" [value]="transaction.transactionId">
|
||||
{{ transaction.transactionId }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field> -->
|
||||
</div>
|
||||
|
||||
<div class="mat-elevation-z8 container">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" matSort>
|
||||
|
||||
<ng-container matColumnDef="id">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Entry ID </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.id }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="officeName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Office </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.officeName }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="transactionId">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction ID </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.transactionId }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="transactionDate">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Transaction Date </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.transactionDate }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="glAccountType">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Type </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.glAccountType.value }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="createdByUserName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Created by </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.createdByUserName }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="glAccountCode">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Account Code </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.glAccountCode }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="glAccountName">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Account Name </th>
|
||||
<td mat-cell *matCellDef="let transaction"> {{ transaction.glAccountName }} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="debit">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Debit </th>
|
||||
<td mat-cell *matCellDef="let transaction"><span *ngIf="transaction.entryType.value === 'DEBIT'"> {{ (transaction.currency.displaySymbol || transaction.currency.code) + ' ' + transaction.amount }} </span></td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="credit">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Credit </th>
|
||||
<td mat-cell *matCellDef="let transaction"><span *ngIf="transaction.entryType.value === 'CREDIT'"> {{ (transaction.currency.displaySymbol || transaction.currency.code) + ' ' + transaction.amount }} </span></td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="viewTransaction(row)" class="select"></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[10, 25, 50, 100]" showFirstLastButtons></mat-paginator>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchJournalEntryComponent } from './search-journal-entry.component';
|
||||
|
||||
describe('SearchJournalEntryComponent', () => {
|
||||
let component: SearchJournalEntryComponent;
|
||||
let fixture: ComponentFixture<SearchJournalEntryComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SearchJournalEntryComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchJournalEntryComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,100 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { MatPaginator, MatSort, MatTableDataSource } from '@angular/material';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { AccountingService } from '../accounting.service';
|
||||
|
||||
@Component({
|
||||
selector: 'mifosx-search-journal-entry',
|
||||
templateUrl: './search-journal-entry.component.html',
|
||||
styleUrls: ['./search-journal-entry.component.scss']
|
||||
})
|
||||
export class SearchJournalEntryComponent implements OnInit {
|
||||
|
||||
officeName = new FormControl();
|
||||
glAccountCode = new FormControl();
|
||||
transactionDateFrom = new FormControl(new Date(2000, 0, 1));
|
||||
transactionDateTo = new FormControl(new Date());
|
||||
transactionId = new FormControl();
|
||||
minDate = new Date(2000, 0, 1);
|
||||
maxDate = new Date();
|
||||
filter = new FormControl('');
|
||||
displayedColumns: string[] = ['id', 'officeName', 'transactionId', 'transactionDate', 'glAccountType', 'createdByUserName', 'glAccountCode', 'glAccountName', 'debit', 'credit'];
|
||||
dataSource: any;
|
||||
officeData: any;
|
||||
glAccountData: any;
|
||||
filterData = [
|
||||
{
|
||||
option: 'All',
|
||||
value: ''
|
||||
},
|
||||
{
|
||||
option: 'Manual Entries',
|
||||
value: true
|
||||
},
|
||||
{
|
||||
option: 'System Entries',
|
||||
value: false
|
||||
}
|
||||
];
|
||||
filterValue: any = { officeName: '', glAccountCode: '', filter: '', transactionId: '' };
|
||||
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
constructor(private accountingService: AccountingService,
|
||||
private router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.getOffices();
|
||||
this.getGlAccounts();
|
||||
this.getJournalEntries();
|
||||
}
|
||||
|
||||
getJournalEntries() {
|
||||
this.accountingService.getJournalEntries().subscribe((journalEntryData: any) => {
|
||||
this.dataSource = new MatTableDataSource(journalEntryData.pageItems);
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sortingDataAccessor = (transaction: any, property: any) => {
|
||||
switch (property) {
|
||||
case 'glAccountType': return transaction.glAccountType.value;
|
||||
case 'debit': return transaction.amount;
|
||||
case 'credit': return transaction.amount;
|
||||
default: return transaction[property];
|
||||
}
|
||||
};
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.filterPredicate = this.filterPredicate;
|
||||
});
|
||||
}
|
||||
|
||||
filterPredicate(data: any, filterValue: string) {
|
||||
return data.officeName.indexOf(filterValue['officeName']) != -1
|
||||
&& data.glAccountCode.indexOf(filterValue['glAccountCode']) != -1
|
||||
&& data.manualEntry.toString().indexOf(filterValue['filter']) != -1
|
||||
&& data.transactionId.indexOf(filterValue['transactionId']) != -1;
|
||||
}
|
||||
|
||||
applyFilter(filterValue: string, property: string) {
|
||||
this.filterValue[property] = filterValue;
|
||||
this.dataSource.filter = this.filterValue;
|
||||
}
|
||||
|
||||
getOffices() {
|
||||
this.accountingService.getOffices().subscribe(officeData => {
|
||||
this.officeData = officeData;
|
||||
});
|
||||
}
|
||||
|
||||
getGlAccounts() {
|
||||
this.accountingService.getGlAccounts().subscribe(glAccountData => {
|
||||
this.glAccountData = glAccountData;
|
||||
});
|
||||
}
|
||||
|
||||
viewTransaction(journalEntry: any) {
|
||||
this.router.navigate(['/accounting/transactions/view', journalEntry.transactionId]);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user