Moved from tslint to eslint as tslint was depreciated.
Added prettier and also prettied all the typescript files using prettier ESLint is using the AirBnB rules which are the most strict to lint the files.
This commit is contained in:
@ -1,10 +1,8 @@
|
||||
import {DataSource} from '@angular/cdk/collections';
|
||||
import {Observable} from 'rxjs';
|
||||
import {Inventory, Journal} from '../core/voucher';
|
||||
|
||||
import { DataSource } from '@angular/cdk/collections';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Inventory, Journal } from '../core/voucher';
|
||||
|
||||
export class PurchaseDataSource extends DataSource<Inventory> {
|
||||
|
||||
constructor(private data: Observable<Inventory[]>) {
|
||||
super();
|
||||
}
|
||||
@ -13,6 +11,5 @@ export class PurchaseDataSource extends DataSource<Inventory> {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
}
|
||||
disconnect() {}
|
||||
}
|
||||
|
||||
@ -1,31 +1,67 @@
|
||||
<h1 mat-dialog-title>Edit Purchase Entry</h1>
|
||||
<div mat-dialog-content>
|
||||
<form [formGroup]="form">
|
||||
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px">
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="space-around start"
|
||||
fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px"
|
||||
>
|
||||
<mat-form-field fxFlex="52">
|
||||
<input type="text" matInput placeholder="Product" #productElement [matAutocomplete]="autoP"
|
||||
formControlName="product" autocomplete="off">
|
||||
<mat-autocomplete #autoP="matAutocomplete" autoActiveFirstOption [displayWith]="displayProductName"
|
||||
(optionSelected)="productSelected($event)">
|
||||
<mat-option *ngFor="let product of products | async" [value]="product">{{product.name}}</mat-option>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Product"
|
||||
#productElement
|
||||
[matAutocomplete]="autoP"
|
||||
formControlName="product"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<mat-autocomplete
|
||||
#autoP="matAutocomplete"
|
||||
autoActiveFirstOption
|
||||
[displayWith]="displayProductName"
|
||||
(optionSelected)="productSelected($event)"
|
||||
>
|
||||
<mat-option *ngFor="let product of products | async" [value]="product">{{
|
||||
product.name
|
||||
}}</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="12">
|
||||
<mat-label>Quantity</mat-label>
|
||||
<input type="text" matInput placeholder="Quantity" formControlName="quantity" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Quantity"
|
||||
formControlName="quantity"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="12">
|
||||
<mat-label>Price</mat-label>
|
||||
<input type="text" matInput placeholder="Price" formControlName="price" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Price"
|
||||
formControlName="price"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="12">
|
||||
<mat-label>Tax</mat-label>
|
||||
<input type="text" matInput placeholder="Tax" formControlName="tax" autocomplete="off">
|
||||
<input type="text" matInput placeholder="Tax" formControlName="tax" autocomplete="off" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="12">
|
||||
<mat-label>Discount</mat-label>
|
||||
<input type="text" matInput placeholder="Discount" formControlName="discount" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Discount"
|
||||
formControlName="discount"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</form>
|
||||
@ -34,4 +70,3 @@
|
||||
<button mat-button [mat-dialog-close]="false" cdkFocusInitial>Cancel</button>
|
||||
<button mat-button (click)="accept()" color="primary">Ok</button>
|
||||
</div>
|
||||
|
||||
|
||||
@ -8,9 +8,8 @@ describe('PurchaseDialogComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ PurchaseDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [PurchaseDialogComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import {Component, Inject, OnInit} from '@angular/core';
|
||||
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 {Observable, of as observableOf} from 'rxjs';
|
||||
import {Product} from '../core/product';
|
||||
import {ProductService} from '../product/product.service';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import { Product } from '../core/product';
|
||||
import { ProductService } from '../product/product.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-purchase-dialog',
|
||||
templateUrl: './purchase-dialog.component.html',
|
||||
styleUrls: ['./purchase-dialog.component.css']
|
||||
styleUrls: ['./purchase-dialog.component.css'],
|
||||
})
|
||||
export class PurchaseDialogComponent implements OnInit {
|
||||
products: Observable<Product[]>;
|
||||
@ -21,7 +21,8 @@ export class PurchaseDialogComponent implements OnInit {
|
||||
public dialogRef: MatDialogRef<PurchaseDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any,
|
||||
private fb: FormBuilder,
|
||||
private productSer: ProductService) {
|
||||
private productSer: ProductService,
|
||||
) {
|
||||
this.createForm();
|
||||
this.listenToProductAutocompleteChange();
|
||||
}
|
||||
@ -32,7 +33,7 @@ export class PurchaseDialogComponent implements OnInit {
|
||||
quantity: this.data.inventory.quantity,
|
||||
price: this.data.inventory.rate,
|
||||
tax: this.data.inventory.tax,
|
||||
discount: this.data.inventory.discount
|
||||
discount: this.data.inventory.discount,
|
||||
});
|
||||
this.product = this.data.inventory.product;
|
||||
}
|
||||
@ -43,20 +44,19 @@ export class PurchaseDialogComponent implements OnInit {
|
||||
quantity: '',
|
||||
price: '',
|
||||
tax: '',
|
||||
discount: ''
|
||||
discount: '',
|
||||
});
|
||||
}
|
||||
|
||||
listenToProductAutocompleteChange(): void {
|
||||
const control = this.form.get('product');
|
||||
this.products = control.valueChanges
|
||||
.pipe(
|
||||
startWith(null),
|
||||
map(x => (x !== null && x.length >= 1) ? x : null),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap(x => (x === null) ? observableOf([]) : this.productSer.autocomplete(x))
|
||||
);
|
||||
this.products = control.valueChanges.pipe(
|
||||
startWith(null),
|
||||
map((x) => (x !== null && x.length >= 1 ? x : null)),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x))),
|
||||
);
|
||||
}
|
||||
|
||||
displayProductName(product?: Product): string | undefined {
|
||||
@ -70,10 +70,10 @@ 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 = +formValue.quantity;
|
||||
const price = +formValue.price;
|
||||
const tax = +formValue.tax;
|
||||
const discount = +formValue.discount;
|
||||
this.data.inventory.product = this.product;
|
||||
this.data.inventory.quantity = quantity;
|
||||
this.data.inventory.rate = price;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {PurchaseResolver} from './purchase-resolver.service';
|
||||
import { PurchaseResolver } from './purchase-resolver.service';
|
||||
|
||||
describe('PurchaseResolver', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [PurchaseResolver]
|
||||
providers: [PurchaseResolver],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from '@angular/router';
|
||||
import {Observable} from 'rxjs/internal/Observable';
|
||||
import {Voucher} from '../core/voucher';
|
||||
import {VoucherService} from '../core/voucher.service';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { Voucher } from '../core/voucher';
|
||||
import { VoucherService } from '../core/voucher.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PurchaseResolver implements Resolve<Voucher> {
|
||||
|
||||
constructor(private ser: VoucherService) {
|
||||
}
|
||||
constructor(private ser: VoucherService) {}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Voucher> {
|
||||
const id = route.paramMap.get('id');
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {PurchaseRoutingModule} from './purchase-routing.module';
|
||||
import { PurchaseRoutingModule } from './purchase-routing.module';
|
||||
|
||||
describe('PurchaseRoutingModule', () => {
|
||||
let purchaseRoutingModule: PurchaseRoutingModule;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {RouterModule, Routes} from '@angular/router';
|
||||
import {PurchaseResolver} from './purchase-resolver.service';
|
||||
import {AuthGuard} from '../auth/auth-guard.service';
|
||||
import {PurchaseComponent} from './purchase.component';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { PurchaseResolver } from './purchase-resolver.service';
|
||||
import { AuthGuard } from '../auth/auth-guard.service';
|
||||
import { PurchaseComponent } from './purchase.component';
|
||||
|
||||
const purchaseRoutes: Routes = [
|
||||
{
|
||||
@ -11,39 +11,30 @@ const purchaseRoutes: Routes = [
|
||||
component: PurchaseComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
permission: 'Purchase'
|
||||
permission: 'Purchase',
|
||||
},
|
||||
resolve: {
|
||||
voucher: PurchaseResolver
|
||||
voucher: PurchaseResolver,
|
||||
},
|
||||
runGuardsAndResolvers: 'always'
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':id',
|
||||
component: PurchaseComponent,
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
permission: 'Purchase'
|
||||
permission: 'Purchase',
|
||||
},
|
||||
resolve: {
|
||||
voucher: PurchaseResolver
|
||||
voucher: PurchaseResolver,
|
||||
},
|
||||
runGuardsAndResolvers: 'always'
|
||||
}
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild(purchaseRoutes)
|
||||
|
||||
],
|
||||
exports: [
|
||||
RouterModule
|
||||
],
|
||||
providers: [
|
||||
PurchaseResolver
|
||||
]
|
||||
imports: [CommonModule, RouterModule.forChild(purchaseRoutes)],
|
||||
exports: [RouterModule],
|
||||
providers: [PurchaseResolver],
|
||||
})
|
||||
export class PurchaseRoutingModule {
|
||||
}
|
||||
export class PurchaseRoutingModule {}
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
}
|
||||
|
||||
.selected {
|
||||
background: #fff3cd
|
||||
background: #fff3cd;
|
||||
}
|
||||
|
||||
.unposted {
|
||||
background: #f8d7da
|
||||
background: #f8d7da;
|
||||
}
|
||||
|
||||
.center {
|
||||
|
||||
@ -1,105 +1,176 @@
|
||||
<mat-card>
|
||||
<mat-card-title-group>
|
||||
<mat-card-title>Purchase</mat-card-title>
|
||||
<mat-icon matSuffix (click)="voucher.isStarred = !voucher.isStarred" class="pointer"
|
||||
[class.gold]="voucher.isStarred">
|
||||
<mat-icon
|
||||
matSuffix
|
||||
(click)="voucher.isStarred = !voucher.isStarred"
|
||||
class="pointer"
|
||||
[class.gold]="voucher.isStarred"
|
||||
>
|
||||
{{ voucher.isStarred ? 'star' : 'star_border' }}
|
||||
</mat-icon>
|
||||
</mat-card-title-group>
|
||||
<mat-card-content>
|
||||
<form [formGroup]="form" fxLayout="column">
|
||||
<div fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column" fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px">
|
||||
<div
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="space-around start"
|
||||
fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px"
|
||||
>
|
||||
<mat-form-field fxFlex="40">
|
||||
<input matInput [matDatepicker]="date" placeholder="Date" formControlName="date" autocomplete="off"
|
||||
#dateElement (focus)="dateElement.select()">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="date"
|
||||
placeholder="Date"
|
||||
formControlName="date"
|
||||
autocomplete="off"
|
||||
#dateElement
|
||||
(focus)="dateElement.select()"
|
||||
/>
|
||||
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
|
||||
<mat-datepicker #date></mat-datepicker>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="40">
|
||||
<input type="text" matInput placeholder="Account" #accountElement [matAutocomplete]="autoA"
|
||||
formControlName="account" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Account"
|
||||
#accountElement
|
||||
[matAutocomplete]="autoA"
|
||||
formControlName="account"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<mat-hint *ngIf="accBal">
|
||||
Balance as on Date: <strong>{{accBal.date | currency:'INR' | accounting}}</strong> /
|
||||
Final balance: <strong>{{accBal.total | currency:'INR' | accounting}}</strong>
|
||||
Balance as on Date: <strong>{{ accBal.date | currency: 'INR' | accounting }}</strong> /
|
||||
Final balance: <strong>{{ accBal.total | currency: 'INR' | accounting }}</strong>
|
||||
</mat-hint>
|
||||
<mat-autocomplete #autoA="matAutocomplete" autoActiveFirstOption [displayWith]="displayAccount"
|
||||
(optionSelected)="accountSelected($event)">
|
||||
<mat-option *ngFor="let account of accounts | async" [value]="account">{{account.name}}</mat-option>
|
||||
<mat-autocomplete
|
||||
#autoA="matAutocomplete"
|
||||
autoActiveFirstOption
|
||||
[displayWith]="displayAccount"
|
||||
(optionSelected)="accountSelected($event)"
|
||||
>
|
||||
<mat-option *ngFor="let account of accounts | async" [value]="account">{{
|
||||
account.name
|
||||
}}</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="20">
|
||||
<mat-label>Amount</mat-label>
|
||||
<span matPrefix>₹ </span>
|
||||
<input type="text" matInput formControlName="amount">
|
||||
<input type="text" matInput formControlName="amount" />
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div formGroupName="addRow" fxLayout="row" fxLayoutAlign="space-around start" fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
|
||||
<div
|
||||
formGroupName="addRow"
|
||||
fxLayout="row"
|
||||
fxLayoutAlign="space-around start"
|
||||
fxLayout.lt-md="column"
|
||||
fxLayoutGap="20px"
|
||||
fxLayoutGap.lt-md="0px"
|
||||
>
|
||||
<mat-form-field fxFlex="50">
|
||||
<input type="text" matInput placeholder="Product" #productElement [matAutocomplete]="autoP"
|
||||
formControlName="product" autocomplete="off">
|
||||
<mat-autocomplete #autoP="matAutocomplete" autoActiveFirstOption [displayWith]="displayProductName"
|
||||
(optionSelected)="productSelected($event)">
|
||||
<mat-option *ngFor="let product of products | async" [value]="product">{{product.name}}</mat-option>
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Product"
|
||||
#productElement
|
||||
[matAutocomplete]="autoP"
|
||||
formControlName="product"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<mat-autocomplete
|
||||
#autoP="matAutocomplete"
|
||||
autoActiveFirstOption
|
||||
[displayWith]="displayProductName"
|
||||
(optionSelected)="productSelected($event)"
|
||||
>
|
||||
<mat-option *ngFor="let product of products | async" [value]="product">{{
|
||||
product.name
|
||||
}}</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10">
|
||||
<mat-label>Quantity</mat-label>
|
||||
<input type="text" matInput placeholder="Quantity" formControlName="quantity" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Quantity"
|
||||
formControlName="quantity"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10">
|
||||
<mat-label>Price</mat-label>
|
||||
<input type="text" matInput placeholder="Price" formControlName="price" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Price"
|
||||
formControlName="price"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10">
|
||||
<mat-label>Tax</mat-label>
|
||||
<input type="text" matInput placeholder="Tax" formControlName="tax" autocomplete="off">
|
||||
<input type="text" matInput placeholder="Tax" formControlName="tax" autocomplete="off" />
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="10">
|
||||
<mat-label>Discount</mat-label>
|
||||
<input type="text" matInput placeholder="Discount" formControlName="discount" autocomplete="off">
|
||||
<input
|
||||
type="text"
|
||||
matInput
|
||||
placeholder="Discount"
|
||||
formControlName="discount"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-raised-button color="primary" (click)="addRow()" fxFlex="10">Add</button>
|
||||
</div>
|
||||
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
|
||||
|
||||
<!-- Product Column -->
|
||||
<ng-container matColumnDef="product">
|
||||
<mat-header-cell *matHeaderCellDef>Product</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{row.product.name}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.product.name }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Quantity Column -->
|
||||
<ng-container matColumnDef="quantity">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Quantity</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.quantity | number:'1.2-2'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{
|
||||
row.quantity | number: '1.2-2'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Rate Column -->
|
||||
<ng-container matColumnDef="rate">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Rate</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.rate | currency:'INR'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.rate | currency: 'INR' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Tax Column -->
|
||||
<ng-container matColumnDef="tax">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Tax</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.tax | percent:'1.2-2'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.tax | percent: '1.2-2' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Discount Column -->
|
||||
<ng-container matColumnDef="discount">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Discount</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.discount | percent:'1.2-2'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{
|
||||
row.discount | percent: '1.2-2'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Amount Column -->
|
||||
<ng-container matColumnDef="amount">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Amount</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{row.amount | currency:'INR'}}</mat-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{
|
||||
row.amount | currency: 'INR'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Action Column -->
|
||||
@ -116,16 +187,21 @@
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
<mat-form-field>
|
||||
<mat-label>Narration</mat-label>
|
||||
<textarea matInput matTextareaAutosize matAutosizeMinRows="5" placeholder="Narration"
|
||||
formControlName="narration"></textarea>
|
||||
<textarea
|
||||
matInput
|
||||
matTextareaAutosize
|
||||
matAutosizeMinRows="5"
|
||||
placeholder="Narration"
|
||||
formControlName="narration"
|
||||
></textarea>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxLayoutGap="0.5%" fxLayoutAlign="center">
|
||||
<div class="img-container" fxFlex="20%" *ngFor="let item of voucher.files">
|
||||
<img [src]="item.thumbnail" (click)="zoomImage(item)">
|
||||
<img [src]="item.thumbnail" (click)="zoomImage(item)" />
|
||||
<button mat-icon-button class="overlay" (click)="deleteImage(item)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
@ -133,29 +209,47 @@
|
||||
<div class="img-container" fxFlex="20%">
|
||||
<label ng-href for="fileUp">
|
||||
<img
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjE1MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjUwIiB5PSI3NSIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMDBweDtmb250LWZhbWlseTpBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZjtkb21pbmFudC1iYXNlbGluZTpjZW50cmFsIj4rPC90ZXh0Pjwvc3ZnPg==">
|
||||
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTUwIj48cmVjdCB3aWR0aD0iMTAwIiBoZWlnaHQ9IjE1MCIgZmlsbD0iI2VlZSIvPjx0ZXh0IHRleHQtYW5jaG9yPSJtaWRkbGUiIHg9IjUwIiB5PSI3NSIgc3R5bGU9ImZpbGw6I2FhYTtmb250LXdlaWdodDpib2xkO2ZvbnQtc2l6ZToxMDBweDtmb250LWZhbWlseTpBcmlhbCxIZWx2ZXRpY2Esc2Fucy1zZXJpZjtkb21pbmFudC1iYXNlbGluZTpjZW50cmFsIj4rPC90ZXh0Pjwvc3ZnPg=="
|
||||
/>
|
||||
</label>
|
||||
<input type="file" id="fileUp" multiple accept="image/*" style="display: none;"
|
||||
(change)="detectFiles($event)">
|
||||
<input
|
||||
type="file"
|
||||
id="fileUp"
|
||||
multiple
|
||||
accept="image/*"
|
||||
style="display: none"
|
||||
(change)="detectFiles($event)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button color="primary" (click)="save()" [disabled]="!canSave()">
|
||||
{{(voucher.id) ? 'Update' : 'Save'}}
|
||||
{{ voucher.id ? 'Update' : 'Save' }}
|
||||
</button>
|
||||
<button mat-raised-button (click)="post()" *ngIf="voucher.id"
|
||||
[disabled]="voucher.posted || auth.user.perms.indexOf('post-vouchers') === -1">
|
||||
{{(voucher.posted) ? 'Posted' : 'Post'}}
|
||||
<button
|
||||
mat-raised-button
|
||||
(click)="post()"
|
||||
*ngIf="voucher.id"
|
||||
[disabled]="voucher.posted || auth.user.perms.indexOf('post-vouchers') === -1"
|
||||
>
|
||||
{{ voucher.posted ? 'Posted' : 'Post' }}
|
||||
</button>
|
||||
<button mat-raised-button color="warn" (click)="confirmDelete()" *ngIf="voucher.id" [disabled]="!canSave()">
|
||||
<button
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
(click)="confirmDelete()"
|
||||
*ngIf="voucher.id"
|
||||
[disabled]="!canSave()"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
<mat-card-subtitle *ngIf="voucher.id">
|
||||
Created on <strong>{{voucher.creationDate | localTime}}</strong> and
|
||||
Last Edited on <strong>{{voucher.lastEditDate | localTime}}</strong>
|
||||
by <strong>{{voucher.user.name}}</strong>. {{(voucher.poster) ? 'Posted by ' + voucher.poster : ''}}
|
||||
Created on <strong>{{ voucher.creationDate | localTime }}</strong> and Last Edited on
|
||||
<strong>{{ voucher.lastEditDate | localTime }}</strong> by
|
||||
<strong>{{ voucher.user.name }}</strong
|
||||
>. {{ voucher.poster ? 'Posted by ' + voucher.poster : '' }}
|
||||
</mat-card-subtitle>
|
||||
</mat-card>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {PurchaseComponent} from './purchase.component';
|
||||
import { PurchaseComponent } from './purchase.component';
|
||||
|
||||
describe('PurchaseComponent', () => {
|
||||
let component: PurchaseComponent;
|
||||
@ -8,9 +8,8 @@ describe('PurchaseComponent', () => {
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [PurchaseComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
declarations: [PurchaseComponent],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@ -1,29 +1,29 @@
|
||||
import {AfterViewInit, Component, ElementRef, OnInit, OnDestroy, ViewChild} from '@angular/core';
|
||||
import {FormBuilder, FormGroup} from '@angular/forms';
|
||||
import { AfterViewInit, Component, ElementRef, OnInit, OnDestroy, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import {ActivatedRoute, Router} from '@angular/router';
|
||||
import {BehaviorSubject, fromEvent, Observable, of, of as observableOf, zip} from 'rxjs';
|
||||
import {PurchaseDataSource} from './purchase-datasource';
|
||||
import {Account} from '../core/account';
|
||||
import {VoucherService} from '../core/voucher.service';
|
||||
import {AccountService} from '../core/account.service';
|
||||
import {DbFile, Inventory, Voucher} from '../core/voucher';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject, fromEvent, Observable, of, of as observableOf, zip } from 'rxjs';
|
||||
import { PurchaseDataSource } from './purchase-datasource';
|
||||
import { Account } from '../core/account';
|
||||
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 {AuthService} from '../auth/auth.service';
|
||||
import {ConfirmDialogComponent} from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import {ToasterService} from '../core/toaster.service';
|
||||
import {debounceTime, distinctUntilChanged, map, startWith, switchMap} from 'rxjs/operators';
|
||||
import {PurchaseDialogComponent} from './purchase-dialog.component';
|
||||
import {ImageDialogComponent} from '../shared/image-dialog/image-dialog.component';
|
||||
import {ProductService} from '../product/product.service';
|
||||
import {Product} from '../core/product';
|
||||
import {Hotkey, HotkeysService} from 'angular2-hotkeys';
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { PurchaseDialogComponent } from './purchase-dialog.component';
|
||||
import { ImageDialogComponent } from '../shared/image-dialog/image-dialog.component';
|
||||
import { ProductService } from '../product/product.service';
|
||||
import { Product } from '../core/product';
|
||||
import { Hotkey, HotkeysService } from 'angular2-hotkeys';
|
||||
|
||||
@Component({
|
||||
selector: 'app-purchase',
|
||||
templateUrl: './purchase.component.html',
|
||||
styleUrls: ['./purchase.component.css']
|
||||
styleUrls: ['./purchase.component.css'],
|
||||
})
|
||||
export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
@ViewChild('accountElement', { static: true }) accountElement: ElementRef;
|
||||
@ -51,7 +51,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
private auth: AuthService,
|
||||
private ser: VoucherService,
|
||||
private productSer: ProductService,
|
||||
private accountSer: AccountService
|
||||
private accountSer: AccountService,
|
||||
) {
|
||||
this.createForm();
|
||||
this.listenToAccountAutocompleteChange();
|
||||
@ -59,28 +59,49 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.data
|
||||
.subscribe((data: { voucher: Voucher }) => {
|
||||
this.loadVoucher(data.voucher);
|
||||
});
|
||||
this.hotkeys.add(new Hotkey('f2', (event: KeyboardEvent): boolean => {
|
||||
setTimeout(() => {
|
||||
this.dateElement.nativeElement.focus();
|
||||
}, 0);
|
||||
return false; // Prevent bubbling
|
||||
}, ['INPUT', 'SELECT', 'TEXTAREA']));
|
||||
this.hotkeys.add(new Hotkey('ctrl+s', (event: KeyboardEvent): boolean => {
|
||||
if (this.canSave()) {
|
||||
this.save();
|
||||
}
|
||||
return false; // Prevent bubbling
|
||||
}, ['INPUT', 'SELECT', 'TEXTAREA']));
|
||||
this.hotkeys.add(new Hotkey('ctrl+p', (event: KeyboardEvent): boolean => {
|
||||
if (this.voucher.id && !this.voucher.posted && this.auth.user.perms.indexOf('post-vouchers') !== -1) {
|
||||
this.post();
|
||||
}
|
||||
return false; // Prevent bubbling
|
||||
}, ['INPUT', 'SELECT', 'TEXTAREA']));
|
||||
this.route.data.subscribe((data: { voucher: Voucher }) => {
|
||||
this.loadVoucher(data.voucher);
|
||||
});
|
||||
this.hotkeys.add(
|
||||
new Hotkey(
|
||||
'f2',
|
||||
(event: KeyboardEvent): boolean => {
|
||||
setTimeout(() => {
|
||||
this.dateElement.nativeElement.focus();
|
||||
}, 0);
|
||||
return false; // Prevent bubbling
|
||||
},
|
||||
['INPUT', 'SELECT', 'TEXTAREA'],
|
||||
),
|
||||
);
|
||||
this.hotkeys.add(
|
||||
new Hotkey(
|
||||
'ctrl+s',
|
||||
(event: KeyboardEvent): boolean => {
|
||||
if (this.canSave()) {
|
||||
this.save();
|
||||
}
|
||||
return false; // Prevent bubbling
|
||||
},
|
||||
['INPUT', 'SELECT', 'TEXTAREA'],
|
||||
),
|
||||
);
|
||||
this.hotkeys.add(
|
||||
new Hotkey(
|
||||
'ctrl+p',
|
||||
(event: KeyboardEvent): boolean => {
|
||||
if (
|
||||
this.voucher.id &&
|
||||
!this.voucher.posted &&
|
||||
this.auth.user.perms.indexOf('post-vouchers') !== -1
|
||||
) {
|
||||
this.post();
|
||||
}
|
||||
return false; // Prevent bubbling
|
||||
},
|
||||
['INPUT', 'SELECT', 'TEXTAREA'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
@ -102,9 +123,9 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
quantity: '',
|
||||
price: '',
|
||||
tax: '',
|
||||
discount: ''
|
||||
discount: '',
|
||||
},
|
||||
narration: this.voucher.narration
|
||||
narration: this.voucher.narration,
|
||||
});
|
||||
this.dataSource = new PurchaseDataSource(this.inventoryObservable);
|
||||
this.updateView();
|
||||
@ -118,10 +139,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 = +formValue.quantity;
|
||||
const price = +formValue.price;
|
||||
const tax = +formValue.tax;
|
||||
const discount = +formValue.discount;
|
||||
if (this.product === null || quantity <= 0 || price <= 0) {
|
||||
return;
|
||||
}
|
||||
@ -138,7 +159,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
discount: discount,
|
||||
amount: quantity * price * (1 + tax) * (1 - discount),
|
||||
product: this.product,
|
||||
batch: null
|
||||
batch: null,
|
||||
});
|
||||
this.resetAddRow();
|
||||
this.updateView();
|
||||
@ -150,7 +171,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
quantity: '',
|
||||
price: '',
|
||||
tax: '',
|
||||
discount: ''
|
||||
discount: '',
|
||||
});
|
||||
this.product = null;
|
||||
setTimeout(() => {
|
||||
@ -160,13 +181,15 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
updateView() {
|
||||
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)));
|
||||
this.form
|
||||
.get('amount')
|
||||
.setValue(Math.abs(this.voucher.inventories.map((x) => x.amount).reduce((p, c) => p + c, 0)));
|
||||
}
|
||||
|
||||
editRow(row: Inventory) {
|
||||
const dialogRef = this.dialog.open(PurchaseDialogComponent, {
|
||||
width: '750px',
|
||||
data: {inventory: Object.assign({}, row)}
|
||||
data: { inventory: Object.assign({}, row) },
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((result: boolean | Inventory) => {
|
||||
@ -174,7 +197,10 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
return;
|
||||
}
|
||||
const j = result as Inventory;
|
||||
if (j.product.id !== row.product.id && this.voucher.inventories.filter((x) => x.product.id === j.product.id).length) {
|
||||
if (
|
||||
j.product.id !== row.product.id &&
|
||||
this.voucher.inventories.filter((x) => x.product.id === j.product.id).length
|
||||
) {
|
||||
return;
|
||||
}
|
||||
Object.assign(row, j);
|
||||
@ -191,15 +217,15 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.form = this.fb.group({
|
||||
date: '',
|
||||
account: '',
|
||||
amount: {value: '', disabled: true},
|
||||
amount: { value: '', disabled: true },
|
||||
addRow: this.fb.group({
|
||||
product: '',
|
||||
quantity: '',
|
||||
price: '',
|
||||
tax: '',
|
||||
discount: ''
|
||||
discount: '',
|
||||
}),
|
||||
narration: ''
|
||||
narration: '',
|
||||
});
|
||||
this.accBal = null;
|
||||
}
|
||||
@ -210,39 +236,40 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
} else if (this.voucher.posted && this.auth.user.perms.indexOf('edit-posted-vouchers') !== -1) {
|
||||
return true;
|
||||
} else {
|
||||
return this.voucher.user.id === this.auth.user.id || this.auth.user.perms.indexOf("edit-other-user's-vouchers") !== -1;
|
||||
return (
|
||||
this.voucher.user.id === this.auth.user.id ||
|
||||
this.auth.user.perms.indexOf("edit-other-user's-vouchers") !== -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
post() {
|
||||
this.ser.post(this.voucher.id)
|
||||
.subscribe(
|
||||
(result) => {
|
||||
this.loadVoucher(result);
|
||||
this.toaster.show('Success', 'Voucher Posted');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
}
|
||||
);
|
||||
this.ser.post(this.voucher.id).subscribe(
|
||||
(result) => {
|
||||
this.loadVoucher(result);
|
||||
this.toaster.show('Success', 'Voucher Posted');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
save() {
|
||||
const voucher: Voucher = this.getVoucher();
|
||||
this.ser.saveOrUpdate(voucher)
|
||||
.subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
if (voucher.id === result.id) {
|
||||
this.loadVoucher(result);
|
||||
} else {
|
||||
this.ser.saveOrUpdate(voucher).subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
if (voucher.id === result.id) {
|
||||
this.loadVoucher(result);
|
||||
} else {
|
||||
this.router.navigate(['/purchase', result.id]);
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
}
|
||||
);
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
getVoucher(): Voucher {
|
||||
@ -254,22 +281,21 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
delete() {
|
||||
this.ser.delete(this.voucher.id)
|
||||
.subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigate(['/purchase'], {replaceUrl: true});
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
}
|
||||
);
|
||||
this.ser.delete(this.voucher.id).subscribe(
|
||||
(result) => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigate(['/purchase'], { replaceUrl: true });
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
confirmDelete(): void {
|
||||
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
||||
width: '250px',
|
||||
data: {title: 'Delete Voucher?', content: 'Are you sure? This cannot be undone.'}
|
||||
data: { title: 'Delete Voucher?', content: 'Are you sure? This cannot be undone.' },
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((result: boolean) => {
|
||||
@ -281,26 +307,24 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
listenToAccountAutocompleteChange(): void {
|
||||
const control = this.form.get('account');
|
||||
this.accounts = control.valueChanges
|
||||
.pipe(
|
||||
startWith(null),
|
||||
map(x => (x !== null && x.length >= 1) ? x : null),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap(x => (x === null) ? observableOf([]) : this.accountSer.autocomplete(x))
|
||||
);
|
||||
this.accounts = control.valueChanges.pipe(
|
||||
startWith(null),
|
||||
map((x) => (x !== null && x.length >= 1 ? x : null)),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.accountSer.autocomplete(x))),
|
||||
);
|
||||
}
|
||||
|
||||
listenToProductAutocompleteChange(): void {
|
||||
const control = this.form.get('addRow').get('product');
|
||||
this.products = control.valueChanges
|
||||
.pipe(
|
||||
startWith(null),
|
||||
map(x => (x !== null && x.length >= 1) ? x : null),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap(x => (x === null) ? observableOf([]) : this.productSer.autocomplete(x))
|
||||
);
|
||||
this.products = control.valueChanges.pipe(
|
||||
startWith(null),
|
||||
map((x) => (x !== null && x.length >= 1 ? x : null)),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x))),
|
||||
);
|
||||
}
|
||||
|
||||
displayAccount(account?: Account): string | undefined {
|
||||
@ -323,7 +347,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
zoomImage(file: DbFile) {
|
||||
this.dialog.open(ImageDialogComponent, {
|
||||
width: '750px',
|
||||
data: file.resized
|
||||
data: file.resized,
|
||||
});
|
||||
}
|
||||
|
||||
@ -338,11 +362,12 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
for (const file of files) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e: any) => {
|
||||
zip(of(e.target.result),
|
||||
zip(
|
||||
of(e.target.result),
|
||||
this.resizeImage(e.target.result, 100, 150),
|
||||
this.resizeImage(e.target.result, 825, 1170)
|
||||
).subscribe(
|
||||
val => this.voucher.files.push({id: null, thumbnail: val[1], resized: val[2]})
|
||||
this.resizeImage(e.target.result, 825, 1170),
|
||||
).subscribe((val) =>
|
||||
this.voucher.files.push({ id: null, thumbnail: val[1], resized: val[2] }),
|
||||
);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
@ -371,7 +396,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
canvas.height = height;
|
||||
ctx.drawImage(img, 0, 0, width, height);
|
||||
return canvas.toDataURL('image/jpeg', 0.95);
|
||||
})
|
||||
}),
|
||||
);
|
||||
img.src = image;
|
||||
return ex;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {PurchaseModule} from './purchase.module';
|
||||
import { PurchaseModule } from './purchase.module';
|
||||
|
||||
describe('PurchaseModule', () => {
|
||||
let purchaseModule: PurchaseModule;
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatNativeDateModule } from '@angular/material/core';
|
||||
import {
|
||||
DateAdapter,
|
||||
MAT_DATE_FORMATS,
|
||||
MAT_DATE_LOCALE,
|
||||
MatNativeDateModule,
|
||||
} from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
@ -15,16 +20,16 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import {SharedModule} from '../shared/shared.module';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {CdkTableModule} from '@angular/cdk/table';
|
||||
import {PurchaseRoutingModule} from './purchase-routing.module';
|
||||
import {PurchaseComponent} from './purchase.component';
|
||||
import {MomentDateAdapter} from '@angular/material-moment-adapter';
|
||||
import {A11yModule} from '@angular/cdk/a11y';
|
||||
import {PurchaseDialogComponent} from './purchase-dialog.component';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
import {HotkeyModule} from "angular2-hotkeys";
|
||||
import { SharedModule } from '../shared/shared.module';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { PurchaseRoutingModule } from './purchase-routing.module';
|
||||
import { PurchaseComponent } from './purchase.component';
|
||||
import { MomentDateAdapter } from '@angular/material-moment-adapter';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { PurchaseDialogComponent } from './purchase-dialog.component';
|
||||
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||
import { HotkeyModule } from 'angular2-hotkeys';
|
||||
|
||||
export const MY_FORMATS = {
|
||||
parse: {
|
||||
@ -62,16 +67,12 @@ export const MY_FORMATS = {
|
||||
MatTableModule,
|
||||
ReactiveFormsModule,
|
||||
SharedModule,
|
||||
PurchaseRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
PurchaseComponent,
|
||||
PurchaseDialogComponent
|
||||
PurchaseRoutingModule,
|
||||
],
|
||||
declarations: [PurchaseComponent, PurchaseDialogComponent],
|
||||
providers: [
|
||||
{provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE]},
|
||||
{provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
|
||||
]
|
||||
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
|
||||
{ provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
|
||||
],
|
||||
})
|
||||
export class PurchaseModule {
|
||||
}
|
||||
export class PurchaseModule {}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
import {inject, TestBed} from '@angular/core/testing';
|
||||
import { inject, TestBed } from '@angular/core/testing';
|
||||
|
||||
import {VoucherService} from './purchase.service';
|
||||
import { VoucherService } from './purchase.service';
|
||||
|
||||
describe('PurchaseService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [VoucherService]
|
||||
providers: [VoucherService],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user