Feature: Allow math expressions on all journal inputs and also round them properly.
Chore: Prettied index.html, main.ts and styles.css Updated Dependencies
This commit is contained in:
parent
cefb3ebdcc
commit
cfeef1795d
|
@ -3,6 +3,9 @@
|
|||
"version": "7.3.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"prettier": "prettier",
|
||||
"husky": "husky",
|
||||
"eslint": "eslint",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
|
@ -12,14 +15,14 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^10.1.4",
|
||||
"@angular/cdk": "^10.2.3",
|
||||
"@angular/cdk": "^10.2.4",
|
||||
"@angular/common": "^10.1.4",
|
||||
"@angular/compiler": "^10.1.4",
|
||||
"@angular/core": "^10.1.4",
|
||||
"@angular/flex-layout": "^10.0.0-beta.32",
|
||||
"@angular/forms": "^10.1.4",
|
||||
"@angular/material": "^10.2.3",
|
||||
"@angular/material-moment-adapter": "^10.2.3",
|
||||
"@angular/material": "^10.2.4",
|
||||
"@angular/material-moment-adapter": "^10.2.4",
|
||||
"@angular/platform-browser": "^10.1.4",
|
||||
"@angular/platform-browser-dynamic": "^10.1.4",
|
||||
"@angular/router": "^10.1.4",
|
||||
|
@ -29,49 +32,51 @@
|
|||
"@types/mousetrap": "1.6.3",
|
||||
"angular2-hotkeys": "^2.2.0",
|
||||
"core-js": "^3.6.5",
|
||||
"mathjs": "^7.3.0",
|
||||
"moment": "^2.27.0",
|
||||
"mathjs": "^7.4.0",
|
||||
"moment": "^2.29.1",
|
||||
"rxjs": "^6.6.3",
|
||||
"rxjs-tslint": "^0.1.5",
|
||||
"tslib": "^2.0.0",
|
||||
"zone.js": "~0.10.2"
|
||||
"tslib": "^2.0.2",
|
||||
"zone.js": "^0.10.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.1001.4",
|
||||
"@angular-eslint/builder": "0.4.0-beta.2",
|
||||
"@angular-eslint/eslint-plugin": "0.4.0-beta.2",
|
||||
"@angular-eslint/eslint-plugin-template": "0.4.0-beta.2",
|
||||
"@angular-eslint/schematics": "^0.4.0-beta.2",
|
||||
"@angular-eslint/template-parser": "0.4.0-beta.2",
|
||||
"@angular-eslint/builder": "^0.5.0-beta.2",
|
||||
"@angular-eslint/eslint-plugin": "^0.5.0-beta.2",
|
||||
"@angular-eslint/eslint-plugin-template": "^0.5.0-beta.2",
|
||||
"@angular-eslint/schematics": "^0.5.0-beta.2",
|
||||
"@angular-eslint/template-parser": "^0.5.0-beta.2",
|
||||
"@angular/cli": "^10.1.4",
|
||||
"@angular/compiler-cli": "^10.1.4",
|
||||
"@angular/language-service": "^10.1.4",
|
||||
"@types/jasmine": "^3.5.11",
|
||||
"@types/jasmine": "^3.5.14",
|
||||
"@types/jasminewd2": "^2.0.3",
|
||||
"@types/node": "^14.0.23",
|
||||
"@typescript-eslint/eslint-plugin": "3.9.0",
|
||||
"@typescript-eslint/parser": "3.9.0",
|
||||
"codelyzer": "^6.0.0",
|
||||
"eslint": "^7.6.0",
|
||||
"@types/node": "^14.11.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.4.0",
|
||||
"@typescript-eslint/eslint-plugin-tslint": "^4.3.0",
|
||||
"@typescript-eslint/parser": "^4.3.0",
|
||||
"codelyzer": "^6.0.1",
|
||||
"eslint": "^7.10.0",
|
||||
"eslint-config-airbnb-typescript": "^11.0.0",
|
||||
"eslint-config-prettier": "^6.12.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jsdoc": "^30.6.3",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"husky": "^4.3.0",
|
||||
"jasmine-core": "~3.5.0",
|
||||
"jasmine-spec-reporter": "~5.0.0",
|
||||
"karma": "^5.1.0",
|
||||
"jasmine-core": "^3.6.0",
|
||||
"jasmine-spec-reporter": "^6.0.0",
|
||||
"karma": "^5.2.3",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.2",
|
||||
"karma-jasmine": "~3.3.0",
|
||||
"karma-jasmine": "^4.0.1",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"lint-staged": "^10.4.0",
|
||||
"mathjs": "^7.3.0",
|
||||
"prettier": "^2.1.2",
|
||||
"protractor": "~7.0.0",
|
||||
"standard-version": "^8.0.2",
|
||||
"ts-node": "^8.10.2",
|
||||
"typescript": "3.9.6"
|
||||
"standard-version": "^9.0.0",
|
||||
"ts-node": "^9.0.0",
|
||||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.0.3"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
|
@ -84,7 +89,7 @@
|
|||
"npx prettier --write"
|
||||
],
|
||||
"./src/*.{js,jsx,ts,tsx, css, html}": [
|
||||
"eslint --cache --fix"
|
||||
"npx eslint --cache --fix"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Batch } from '../core/voucher';
|
||||
import { BatchService } from '../core/batch.service';
|
||||
|
||||
|
@ -21,6 +22,7 @@ export class IssueDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<IssueDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private batchSer: BatchService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -65,7 +67,7 @@ export class IssueDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const quantity = +formValue.quantity;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
this.data.inventory.batch = this.batch;
|
||||
this.data.inventory.product = this.batch.product;
|
||||
this.data.inventory.quantity = quantity;
|
||||
|
|
|
@ -9,6 +9,8 @@ import { IssueDataSource } from './issue-datasource';
|
|||
import { VoucherService } from '../core/voucher.service';
|
||||
import { Batch, Inventory, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -49,6 +51,7 @@ export class IssueComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private batchSer: BatchService,
|
||||
private issueGridSer: IssueGridService,
|
||||
|
@ -123,7 +126,7 @@ export class IssueComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
addRow() {
|
||||
const formValue = this.form.get('addRow').value;
|
||||
const quantity = +formValue.quantity;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
const isConsumption = this.form.value.source === '7b845f95-dfef-fa4a-897c-f0baf15284a3';
|
||||
if (this.batch === null || quantity <= 0) {
|
||||
return;
|
||||
|
@ -175,8 +178,9 @@ export class IssueComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
updateView() {
|
||||
this.inventoryObservable.next(this.voucher.inventories);
|
||||
const amount = Math.abs(
|
||||
this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0),
|
||||
const amount = round(
|
||||
Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0)),
|
||||
2,
|
||||
);
|
||||
this.form.get('amount').setValue(amount);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Account } from '../core/account';
|
||||
import { AccountService } from '../core/account.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Account } from '../core/account';
|
||||
import { AccountService } from '../core/account.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-journal-dialog',
|
||||
|
@ -22,6 +23,7 @@ export class JournalDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<JournalDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -70,11 +72,10 @@ export class JournalDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const debit = +formValue.debit;
|
||||
const amount = +formValue.amount;
|
||||
this.data.journal.debit = debit;
|
||||
const amount = this.math.journalAmount(formValue.amount, +formValue.debit);
|
||||
this.data.journal.debit = amount.debit;
|
||||
this.data.journal.account = this.account;
|
||||
this.data.journal.amount = amount;
|
||||
this.data.journal.amount = amount.amount;
|
||||
this.dialogRef.close(this.data.journal);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ import { VoucherService } from '../core/voucher.service';
|
|||
import { AccountService } from '../core/account.service';
|
||||
import { DbFile, Journal, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { evaluate } from 'mathjs';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -46,6 +47,7 @@ export class JournalComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
|
@ -131,7 +133,7 @@ export class JournalComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
addRow() {
|
||||
const formValue = this.form.get('addRow').value;
|
||||
const amount = this.rowAmount(formValue.amount, +formValue.debit);
|
||||
const amount = this.math.journalAmount(formValue.amount, +formValue.debit);
|
||||
if (this.account === null || amount.amount === 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -154,22 +156,10 @@ export class JournalComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.resetAddRow();
|
||||
}
|
||||
|
||||
rowAmount(amount: string = '', debit: number): any {
|
||||
try {
|
||||
amount = amount.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
const val = evaluate(amount);
|
||||
if (val < 0) {
|
||||
debit *= -1;
|
||||
}
|
||||
return { debit: debit, amount: Math.abs(val) };
|
||||
} catch {
|
||||
return { debit: debit, amount: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
resetAddRow() {
|
||||
const amount = Math.abs(
|
||||
this.voucher.journals.map((x) => x.debit * x.amount).reduce((p, c) => p + c),
|
||||
const amount = round(
|
||||
Math.abs(this.voucher.journals.map((x) => x.debit * x.amount).reduce((p, c) => p + c)),
|
||||
2,
|
||||
);
|
||||
const debit = this.form.get('addRow').value.debit;
|
||||
this.form.get('addRow').reset({
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Account } from '../core/account';
|
||||
import { AccountService } from '../core/account.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-payment-dialog',
|
||||
|
@ -22,6 +23,7 @@ export class PaymentDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<PaymentDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -68,7 +70,7 @@ export class PaymentDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const amount = +formValue.amount;
|
||||
const amount = this.math.parseAmount(formValue.amount, 2);
|
||||
this.data.journal.account = this.account;
|
||||
this.data.journal.amount = amount;
|
||||
this.dialogRef.close(this.data.journal);
|
||||
|
|
|
@ -10,7 +10,8 @@ import { VoucherService } from '../core/voucher.service';
|
|||
import { AccountService } from '../core/account.service';
|
||||
import { DbFile, Journal, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { evaluate } from 'mathjs';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -48,6 +49,7 @@ export class PaymentComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
|
@ -133,7 +135,7 @@ export class PaymentComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
|
||||
addRow() {
|
||||
const amount = this.rowAmount(this.form.get('addRow').value.amount);
|
||||
const amount = this.math.parseAmount(this.form.get('addRow').value.amount, 2);
|
||||
const debit = 1;
|
||||
if (this.account === null || amount <= 0) {
|
||||
return;
|
||||
|
@ -157,15 +159,15 @@ export class PaymentComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.resetAddRow();
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
rowAmount(amount: string = ''): number {
|
||||
try {
|
||||
amount = amount.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
return evaluate(amount);
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//
|
||||
// rowAmount(amount: string = ''): number {
|
||||
// try {
|
||||
// amount = amount.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
// return round(evaluate(amount), 2);
|
||||
// } catch {
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
resetAddRow() {
|
||||
this.form.get('addRow').reset({
|
||||
|
@ -182,7 +184,10 @@ export class PaymentComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
updateView() {
|
||||
const journals = this.voucher.journals.filter((x) => x.debit === 1);
|
||||
this.journalObservable.next(journals);
|
||||
this.paymentJournal.amount = Math.abs(journals.map((x) => x.amount).reduce((p, c) => p + c, 0));
|
||||
this.paymentJournal.amount = round(
|
||||
Math.abs(journals.map((x) => x.amount).reduce((p, c) => p + c, 0)),
|
||||
2,
|
||||
);
|
||||
this.form.get('paymentAmount').setValue(this.paymentJournal.amount);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
|||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Batch } from '../core/voucher';
|
||||
import { BatchService } from '../core/batch.service';
|
||||
|
||||
|
@ -21,6 +22,7 @@ export class PurchaseReturnDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<PurchaseReturnDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private batchSer: BatchService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -65,7 +67,7 @@ export class PurchaseReturnDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const quantity = +formValue.quantity;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
this.data.inventory.batch = this.batch;
|
||||
this.data.inventory.product = this.batch.product;
|
||||
this.data.inventory.quantity = quantity;
|
||||
|
|
|
@ -10,6 +10,8 @@ import { VoucherService } from '../core/voucher.service';
|
|||
import { AccountService } from '../core/account.service';
|
||||
import { Batch, DbFile, Inventory, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -48,6 +50,7 @@ export class PurchaseReturnComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private batchSer: BatchService,
|
||||
private accountSer: AccountService,
|
||||
|
@ -135,7 +138,7 @@ export class PurchaseReturnComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
|
||||
addRow() {
|
||||
const formValue = this.form.get('addRow').value;
|
||||
const quantity = +formValue.quantity;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
if (this.batch === null || quantity <= 0 || this.batch.quantityRemaining < quantity) {
|
||||
return;
|
||||
}
|
||||
|
@ -175,7 +178,10 @@ export class PurchaseReturnComponent implements OnInit, AfterViewInit, OnDestroy
|
|||
this.inventoryObservable.next(this.voucher.inventories);
|
||||
this.form
|
||||
.get('amount')
|
||||
.setValue(Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0)));
|
||||
.setValue(
|
||||
round(Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0))),
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
editRow(row: Inventory) {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Product } from '../core/product';
|
||||
import { ProductService } from '../product/product.service';
|
||||
|
||||
|
@ -21,6 +23,7 @@ export class PurchaseDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<PurchaseDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private productSer: ProductService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -70,16 +73,16 @@ export class PurchaseDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const quantity = +formValue.quantity;
|
||||
const price = +formValue.price;
|
||||
const tax = +formValue.tax;
|
||||
const discount = +formValue.discount;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
const price = this.math.parseAmount(formValue.price, 2);
|
||||
const tax = this.math.parseAmount(formValue.tax, 5);
|
||||
const discount = this.math.parseAmount(formValue.discount, 5);
|
||||
this.data.inventory.product = this.product;
|
||||
this.data.inventory.quantity = quantity;
|
||||
this.data.inventory.rate = price;
|
||||
this.data.inventory.tax = tax;
|
||||
this.data.inventory.discount = discount;
|
||||
this.data.inventory.amount = quantity * price * (1 + tax) * (1 - discount);
|
||||
this.data.inventory.amount = round(quantity * price * (1 + tax) * (1 - discount), 2);
|
||||
this.dialogRef.close(this.data.inventory);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import { VoucherService } from '../core/voucher.service';
|
|||
import { AccountService } from '../core/account.service';
|
||||
import { DbFile, Inventory, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -19,6 +21,7 @@ import { ImageDialogComponent } from '../shared/image-dialog/image-dialog.compon
|
|||
import { ProductService } from '../product/product.service';
|
||||
import { Product } from '../core/product';
|
||||
import { Hotkey, HotkeysService } from 'angular2-hotkeys';
|
||||
import { conditionallyCreateMapObjectLiteral } from '@angular/compiler/src/render3/view/util';
|
||||
|
||||
@Component({
|
||||
selector: 'app-purchase',
|
||||
|
@ -49,6 +52,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private productSer: ProductService,
|
||||
private accountSer: AccountService,
|
||||
|
@ -139,10 +143,10 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
|
||||
addRow() {
|
||||
const formValue = this.form.get('addRow').value;
|
||||
const quantity = +formValue.quantity;
|
||||
const price = +formValue.price;
|
||||
const tax = +formValue.tax;
|
||||
const discount = +formValue.discount;
|
||||
const quantity = this.math.parseAmount(formValue.quantity, 2);
|
||||
const price = this.math.parseAmount(formValue.price, 2);
|
||||
const tax = this.math.parseAmount(formValue.tax, 5);
|
||||
const discount = this.math.parseAmount(formValue.discount, 5);
|
||||
if (this.product === null || quantity <= 0 || price <= 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -157,7 +161,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
rate: price,
|
||||
tax: tax,
|
||||
discount: discount,
|
||||
amount: quantity * price * (1 + tax) * (1 - discount),
|
||||
amount: round(quantity * price * (1 + tax) * (1 - discount), 2),
|
||||
product: this.product,
|
||||
batch: null,
|
||||
});
|
||||
|
@ -183,7 +187,10 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.inventoryObservable.next(this.voucher.inventories);
|
||||
this.form
|
||||
.get('amount')
|
||||
.setValue(Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0)));
|
||||
.setValue(
|
||||
round(Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0))),
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
editRow(row: Inventory) {
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { Account } from '../core/account';
|
||||
import { AccountService } from '../core/account.service';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-receipt-dialog',
|
||||
|
@ -22,6 +23,7 @@ export class ReceiptDialogComponent implements OnInit {
|
|||
public dialogRef: MatDialogRef<ReceiptDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private math: MathService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
this.createForm();
|
||||
|
@ -68,7 +70,7 @@ export class ReceiptDialogComponent implements OnInit {
|
|||
|
||||
accept(): void {
|
||||
const formValue = this.form.value;
|
||||
const amount = +formValue.amount;
|
||||
const amount = this.math.parseAmount(formValue.amount, 2);
|
||||
this.data.journal.account = this.account;
|
||||
this.data.journal.amount = amount;
|
||||
this.dialogRef.close(this.data.journal);
|
||||
|
|
|
@ -10,7 +10,8 @@ import { VoucherService } from '../core/voucher.service';
|
|||
import { AccountService } from '../core/account.service';
|
||||
import { DbFile, Journal, Voucher } from '../core/voucher';
|
||||
import * as moment from 'moment';
|
||||
import { evaluate } from 'mathjs';
|
||||
import { round } from 'mathjs';
|
||||
import { MathService } from '../shared/math.service';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
|
@ -48,6 +49,7 @@ export class ReceiptComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
private hotkeys: HotkeysService,
|
||||
private toaster: ToasterService,
|
||||
private auth: AuthService,
|
||||
private math: MathService,
|
||||
private ser: VoucherService,
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
|
@ -136,7 +138,7 @@ export class ReceiptComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
}
|
||||
|
||||
addRow() {
|
||||
const amount = this.rowAmount(this.form.get('addRow').value.amount);
|
||||
const amount = this.math.parseAmount(this.form.get('addRow').value.amount, 2);
|
||||
const debit = -1;
|
||||
if (this.account === null || amount <= 0) {
|
||||
return;
|
||||
|
@ -160,15 +162,15 @@ export class ReceiptComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
this.resetAddRow();
|
||||
this.updateView();
|
||||
}
|
||||
|
||||
rowAmount(amount: string = ''): number {
|
||||
try {
|
||||
amount = amount.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
return evaluate(amount);
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
//
|
||||
// rowAmount(amount: string = ''): number {
|
||||
// try {
|
||||
// amount = amount.replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
// return round(evaluate(amount), 2);
|
||||
// } catch {
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
|
||||
resetAddRow() {
|
||||
this.form.get('addRow').reset({
|
||||
|
@ -185,7 +187,10 @@ export class ReceiptComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||
updateView() {
|
||||
const journals = this.voucher.journals.filter((x) => x.debit === -1);
|
||||
this.journalObservable.next(journals);
|
||||
this.receiptJournal.amount = Math.abs(journals.map((x) => x.amount).reduce((p, c) => p + c, 0));
|
||||
this.receiptJournal.amount = round(
|
||||
Math.abs(journals.map((x) => x.amount).reduce((p, c) => p + c, 0)),
|
||||
2,
|
||||
);
|
||||
this.form.get('receiptAmount').setValue(this.receiptJournal.amount);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MathService } from './math.service';
|
||||
|
||||
describe('MathService', () => {
|
||||
let service: MathService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(MathService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { evaluate, round } from 'mathjs';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class MathService {
|
||||
constructor() {}
|
||||
|
||||
journalAmount(amount: string = '', debit: number): any {
|
||||
const val = this.parseAmount(amount, 2);
|
||||
if (val < 0) {
|
||||
debit *= -1;
|
||||
}
|
||||
return { debit: debit, amount: Math.abs(val) };
|
||||
}
|
||||
|
||||
parseAmount(amount: string = '', rounding: number = 2): number {
|
||||
const cleaned = ('' + amount).replace(new RegExp('(₹[s]*)|(,)|(s)', 'g'), '');
|
||||
if (cleaned === '') {
|
||||
return 0;
|
||||
} else {
|
||||
return round(evaluate(cleaned), rounding);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
export const environment = {
|
||||
production: true,
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10 // refresh token 10 minutes before expiry
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
export const environment = {
|
||||
production: false,
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10 // refresh token 10 minutes before expiry
|
||||
ACCESS_TOKEN_REFRESH_MINUTES: 10, // refresh token 10 minutes before expiry
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
|
||||
<meta charset="utf-8">
|
||||
<title>Overlord</title>
|
||||
<base href="/">
|
||||
<head>
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" />
|
||||
<meta charset="utf-8" />
|
||||
<title>Overlord</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
|
@ -9,5 +8,6 @@ if (environment.production) {
|
|||
enableProdMode();
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch((err) => console.error(err));
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
/* You can add global styles to this file, and also import other style files */
|
||||
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: Roboto, 'Helvetica Neue', sans-serif;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue