Chore: Changed the account_type and voucher_type enum.
The account type enum is not stored in the database as an enum. The voucher_type enum is now a table in the database. Feature: Closing stock can now be saved and in each department.
This commit is contained in:
@ -65,9 +65,7 @@ export class ClosingStockDataSource extends DataSource<ClosingStockItem> {
|
||||
const isAsc = sort.direction === 'asc';
|
||||
switch (sort.active) {
|
||||
case 'product':
|
||||
return compare(a.product, b.product, isAsc);
|
||||
case 'group':
|
||||
return compare(a.group, b.group, isAsc);
|
||||
return compare(`${a.group} - ${a.product}`, `${b.group} - ${b.product}`, isAsc);
|
||||
case 'quantity':
|
||||
return compare(+a.quantity, +b.quantity, isAsc);
|
||||
case 'amount':
|
||||
|
||||
@ -1,14 +1,24 @@
|
||||
import { CostCentre } from '../core/cost-centre';
|
||||
import { Product } from '../core/product';
|
||||
|
||||
export class ClosingStockItem {
|
||||
product: string;
|
||||
id: string | null;
|
||||
product: Product;
|
||||
group: string;
|
||||
quantity: number;
|
||||
amount: number;
|
||||
physical: number;
|
||||
variance: number;
|
||||
costCentre?: CostCentre;
|
||||
|
||||
public constructor(init?: Partial<ClosingStockItem>) {
|
||||
this.product = '';
|
||||
this.id = null;
|
||||
this.product = new Product();
|
||||
this.group = '';
|
||||
this.quantity = 0;
|
||||
this.amount = 0;
|
||||
this.variance = 0;
|
||||
this.physical = 0;
|
||||
Object.assign(this, init);
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ export class ClosingStockResolver implements Resolve<ClosingStock> {
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<ClosingStock> {
|
||||
const date = route.paramMap.get('date');
|
||||
return this.ser.list(date);
|
||||
const costCentre = route.queryParamMap.get('d') || null;
|
||||
return this.ser.list(date, costCentre);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { AuthGuard } from '../auth/auth-guard.service';
|
||||
import { CostCentreListResolver } from '../cost-centre/cost-centre-list-resolver.service';
|
||||
|
||||
import { ClosingStockResolver } from './closing-stock-resolver.service';
|
||||
import { ClosingStockComponent } from './closing-stock.component';
|
||||
@ -17,7 +18,9 @@ const closingStockRoutes: Routes = [
|
||||
},
|
||||
resolve: {
|
||||
info: ClosingStockResolver,
|
||||
costCentres: CostCentreListResolver,
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
{
|
||||
path: ':date',
|
||||
@ -28,7 +31,9 @@ const closingStockRoutes: Routes = [
|
||||
},
|
||||
resolve: {
|
||||
info: ClosingStockResolver,
|
||||
costCentres: CostCentreListResolver,
|
||||
},
|
||||
runGuardsAndResolvers: 'always',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -2,3 +2,16 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.middle {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
@ -14,7 +14,15 @@
|
||||
fxLayoutGap.lt-md="0px"
|
||||
fxLayoutAlign="space-around start"
|
||||
>
|
||||
<mat-form-field fxFlex>
|
||||
<mat-form-field fxFlex="60">
|
||||
<mat-label>Department</mat-label>
|
||||
<mat-select formControlName="costCentre" name="costCentre">
|
||||
<mat-option *ngFor="let at of costCentres" [value]="at.id">
|
||||
{{ at.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex="40">
|
||||
<input
|
||||
matInput
|
||||
[matDatepicker]="dateInput"
|
||||
@ -28,45 +36,123 @@
|
||||
</mat-form-field>
|
||||
<button mat-raised-button color="primary" (click)="show()">Show</button>
|
||||
</div>
|
||||
<mat-table
|
||||
#table
|
||||
[dataSource]="dataSource"
|
||||
matSort
|
||||
aria-label="Elements"
|
||||
formArrayName="stocks"
|
||||
>
|
||||
<!-- Product Column -->
|
||||
<ng-container matColumnDef="product" class="first">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="first">Product</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.product.name }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group Column -->
|
||||
<ng-container matColumnDef="group">
|
||||
<mat-header-cell *matHeaderCellDef class="middle">Group</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="middle">{{ row.group }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Quantity Column -->
|
||||
<ng-container matColumnDef="quantity">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="right middle"
|
||||
>Closing Stock</mat-header-cell
|
||||
>
|
||||
<mat-cell *matCellDef="let row" class="right middle">{{
|
||||
row.quantity | number: '0.2-2'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Physical Column -->
|
||||
<ng-container matColumnDef="physical">
|
||||
<mat-header-cell *matHeaderCellDef class="middle">Physical Stock</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row; let i = index" [formGroupName]="i" class="middle">
|
||||
<mat-form-field fxFlex="100%">
|
||||
<mat-label>Physical</mat-label>
|
||||
<input
|
||||
matInput
|
||||
type="number"
|
||||
placeholder="Physical"
|
||||
formControlName="physical"
|
||||
(change)="updatePhysical($event, row)"
|
||||
/>
|
||||
</mat-form-field>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Variance Column -->
|
||||
<ng-container matColumnDef="variance" class="middle">
|
||||
<mat-header-cell *matHeaderCellDef class="right">Variance</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right middle">{{
|
||||
row.quantity - row.physical | number: '0.2-2'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Department Column -->
|
||||
<ng-container matColumnDef="department">
|
||||
<mat-header-cell *matHeaderCellDef class="middle">Department</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row; let i = index" [formGroupName]="i" class="middle">
|
||||
<mat-form-field fxFlex="100%">
|
||||
<mat-label>Department</mat-label>
|
||||
<mat-select
|
||||
formControlName="costCentre"
|
||||
name="costCentre"
|
||||
(selectionChange)="updateDepartment($event.value, row)"
|
||||
>
|
||||
<mat-option *ngFor="let at of costCentres" [value]="at.id">
|
||||
{{ at.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Amount Column -->
|
||||
<ng-container matColumnDef="amount" class="last">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="right last"
|
||||
>Amount</mat-header-cell
|
||||
>
|
||||
<mat-cell *matCellDef="let row" class="right">{{
|
||||
row.amount | currency: 'INR'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator
|
||||
#paginator
|
||||
[length]="dataSource.data.length"
|
||||
[pageIndex]="0"
|
||||
[pageSize]="50"
|
||||
[pageSizeOptions]="[25, 50, 100, 250, 300, 5000]"
|
||||
>
|
||||
</mat-paginator>
|
||||
</form>
|
||||
<mat-table #table [dataSource]="dataSource" matSort aria-label="Elements">
|
||||
<!-- Product Column -->
|
||||
<ng-container matColumnDef="product">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Product</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.product }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Group Column -->
|
||||
<ng-container matColumnDef="group">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header>Group</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">{{ row.group }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Quantity Column -->
|
||||
<ng-container matColumnDef="quantity">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="right">Quantity</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{
|
||||
row.quantity | number: '0.2-2'
|
||||
}}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Amount Column -->
|
||||
<ng-container matColumnDef="amount">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header class="right">Amount</mat-header-cell>
|
||||
<mat-cell *matCellDef="let row" class="right">{{ row.amount | currency: 'INR' }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator
|
||||
#paginator
|
||||
[length]="dataSource.data.length"
|
||||
[pageIndex]="0"
|
||||
[pageSize]="50"
|
||||
[pageSizeOptions]="[25, 50, 100, 250, 300, 5000]"
|
||||
>
|
||||
</mat-paginator>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button mat-raised-button color="primary" (click)="save()" [disabled]="form.pristine">
|
||||
Save
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
(click)="post()"
|
||||
*ngIf="canDelete()"
|
||||
[disabled]="info.posted || !auth.allowed('post-vouchers')"
|
||||
>
|
||||
{{ info.posted ? 'Posted' : 'Post' }}
|
||||
</button>
|
||||
<button
|
||||
mat-raised-button
|
||||
color="warn"
|
||||
(click)="confirmDelete()"
|
||||
*ngIf="canDelete()"
|
||||
[disabled]="!canSave()"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
|
||||
@ -1,14 +1,23 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSelectChange } from '@angular/material/select';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import * as moment from 'moment';
|
||||
|
||||
import { AuthService } from '../auth/auth.service';
|
||||
import { CostCentre } from '../core/cost-centre';
|
||||
import { ToasterService } from '../core/toaster.service';
|
||||
import { User } from '../core/user';
|
||||
import { ConfirmDialogComponent } from '../shared/confirm-dialog/confirm-dialog.component';
|
||||
import { ToCsvService } from '../shared/to-csv.service';
|
||||
|
||||
import { ClosingStock } from './closing-stock';
|
||||
import { ClosingStockDataSource } from './closing-stock-datasource';
|
||||
import { ClosingStockItem } from './closing-stock-item';
|
||||
import { ClosingStockService } from './closing-stock.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-closing-stock',
|
||||
@ -19,37 +28,96 @@ export class ClosingStockComponent implements OnInit {
|
||||
@ViewChild(MatPaginator, { static: true }) paginator?: MatPaginator;
|
||||
@ViewChild(MatSort, { static: true }) sort?: MatSort;
|
||||
info: ClosingStock = new ClosingStock();
|
||||
dataSource: ClosingStockDataSource = new ClosingStockDataSource(this.info.body);
|
||||
dataSource: ClosingStockDataSource = new ClosingStockDataSource(this.info.items);
|
||||
form: FormGroup;
|
||||
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
||||
displayedColumns = ['product', 'group', 'quantity', 'amount'];
|
||||
displayedColumns = [
|
||||
'product',
|
||||
'group',
|
||||
'quantity',
|
||||
'physical',
|
||||
'variance',
|
||||
'department',
|
||||
'amount',
|
||||
];
|
||||
|
||||
costCentres: CostCentre[];
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
private fb: FormBuilder,
|
||||
private toCsv: ToCsvService,
|
||||
private dialog: MatDialog,
|
||||
private toaster: ToasterService,
|
||||
public auth: AuthService,
|
||||
private ser: ClosingStockService,
|
||||
) {
|
||||
this.costCentres = [];
|
||||
this.form = this.fb.group({
|
||||
date: '',
|
||||
costCentre: '',
|
||||
stocks: this.fb.array([]),
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.data.subscribe((value) => {
|
||||
const data = value as { info: ClosingStock };
|
||||
|
||||
const data = value as { info: ClosingStock; costCentres: CostCentre[] };
|
||||
this.info = data.info;
|
||||
this.form.setValue({
|
||||
this.costCentres = data.costCentres;
|
||||
this.form.patchValue({
|
||||
date: moment(this.info.date, 'DD-MMM-YYYY').toDate(),
|
||||
costCentre: this.info.costCentre.id,
|
||||
});
|
||||
this.form.setControl(
|
||||
'stocks',
|
||||
this.fb.array(
|
||||
this.info.items.map((x) =>
|
||||
this.fb.group({
|
||||
physical: '' + x.physical,
|
||||
costCentre: x.costCentre?.id,
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
this.dataSource = new ClosingStockDataSource(this.info.items, this.paginator, this.sort);
|
||||
});
|
||||
this.dataSource = new ClosingStockDataSource(this.info.body, this.paginator, this.sort);
|
||||
}
|
||||
|
||||
show() {
|
||||
const info = this.getInfo();
|
||||
this.router.navigate(['closing-stock', info.date]);
|
||||
this.router.navigate(['closing-stock', info.date], {
|
||||
queryParams: {
|
||||
d: info.costCentre.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
save() {
|
||||
this.ser.save(this.getClosingStock()).subscribe(
|
||||
() => {
|
||||
this.toaster.show('Success', '');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
getClosingStock(): ClosingStock {
|
||||
const formModel = this.form.value;
|
||||
this.info.date = moment(formModel.date).format('DD-MMM-YYYY');
|
||||
const array = this.form.get('stocks') as FormArray;
|
||||
this.info.items.forEach((item, index) => {
|
||||
item.physical = +array.controls[index].value.physical;
|
||||
item.costCentre =
|
||||
array.controls[index].value.costCentre == null
|
||||
? undefined
|
||||
: new CostCentre({ id: array.controls[index].value.costCentre });
|
||||
});
|
||||
console.log('getClosingStock', this.info);
|
||||
return this.info;
|
||||
}
|
||||
|
||||
getInfo(): ClosingStock {
|
||||
@ -57,6 +125,7 @@ export class ClosingStockComponent implements OnInit {
|
||||
|
||||
return new ClosingStock({
|
||||
date: moment(formModel.date).format('DD-MMM-YYYY'),
|
||||
costCentre: new CostCentre({ id: formModel.costCentre }),
|
||||
});
|
||||
}
|
||||
|
||||
@ -78,4 +147,69 @@ export class ClosingStockComponent implements OnInit {
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
|
||||
updatePhysical($event: Event, row: ClosingStockItem) {
|
||||
row.physical = +($event.target as HTMLInputElement).value;
|
||||
}
|
||||
|
||||
updateDepartment($event: MatSelectChange, row: ClosingStockItem) {
|
||||
row.costCentre = new CostCentre({ id: $event.value });
|
||||
}
|
||||
|
||||
canDelete() {
|
||||
return this.info.items.find((x) => !!x.id) !== undefined;
|
||||
}
|
||||
|
||||
canSave() {
|
||||
if (this.info.items.find((x) => !!x.id) !== undefined) {
|
||||
return true;
|
||||
}
|
||||
if (this.info.posted && this.auth.allowed('edit-posted-vouchers')) {
|
||||
return true;
|
||||
}
|
||||
return (
|
||||
this.info.user.id === (this.auth.user as User).id ||
|
||||
this.auth.allowed("edit-other-user's-vouchers")
|
||||
);
|
||||
}
|
||||
|
||||
post() {
|
||||
this.ser.post(this.info.date, this.info.costCentre.id as string).subscribe(
|
||||
(result) => {
|
||||
// this.loadVoucher(result);
|
||||
this.toaster.show('Success', 'Voucher Posted');
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
delete() {
|
||||
this.ser.delete(this.info.date, this.info.costCentre.id as string).subscribe(
|
||||
() => {
|
||||
this.toaster.show('Success', '');
|
||||
this.router.navigate(['/closing-stock'], { replaceUrl: true });
|
||||
},
|
||||
(error) => {
|
||||
this.toaster.show('Danger', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
confirmDelete(): void {
|
||||
const dialogRef = this.dialog.open(ConfirmDialogComponent, {
|
||||
width: '250px',
|
||||
data: {
|
||||
title: 'Delete Closing Stock information?',
|
||||
content: 'Are you sure? This cannot be undone.',
|
||||
},
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe((result: boolean) => {
|
||||
if (result) {
|
||||
this.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
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';
|
||||
|
||||
@ -59,6 +60,7 @@ export const MY_FORMATS = {
|
||||
ReactiveFormsModule,
|
||||
SharedModule,
|
||||
ClosingStockRoutingModule,
|
||||
MatSelectModule,
|
||||
],
|
||||
declarations: [ClosingStockComponent],
|
||||
providers: [
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { catchError } from 'rxjs/operators';
|
||||
|
||||
import { ErrorLoggerService } from '../core/error-logger.service';
|
||||
import { Voucher } from '../core/voucher';
|
||||
|
||||
import { ClosingStock } from './closing-stock';
|
||||
|
||||
@ -16,10 +17,38 @@ const serviceName = 'ClosingStockService';
|
||||
export class ClosingStockService {
|
||||
constructor(private http: HttpClient, private log: ErrorLoggerService) {}
|
||||
|
||||
list(date: string | null): Observable<ClosingStock> {
|
||||
list(date: string | null, costCentre: string | null): Observable<ClosingStock> {
|
||||
const listUrl = date === null ? url : `${url}/${date}`;
|
||||
const options = { params: new HttpParams() };
|
||||
if (costCentre !== null) {
|
||||
options.params = options.params.set('d', costCentre);
|
||||
}
|
||||
return this.http
|
||||
.get<ClosingStock>(listUrl)
|
||||
.get<ClosingStock>(listUrl, options)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'list'))) as Observable<ClosingStock>;
|
||||
}
|
||||
|
||||
save(closingStock: ClosingStock): Observable<ClosingStock> {
|
||||
return this.http
|
||||
.post<ClosingStock>(url, closingStock)
|
||||
.pipe(catchError(this.log.handleError(serviceName, 'save'))) as Observable<ClosingStock>;
|
||||
}
|
||||
|
||||
post(date: string, costCentre: string): Observable<ClosingStock> {
|
||||
const options = { params: new HttpParams().set('d', costCentre) };
|
||||
return this.http
|
||||
.post<ClosingStock>(`${url}/${date}`, {}, options)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'Post Voucher')),
|
||||
) as Observable<ClosingStock>;
|
||||
}
|
||||
|
||||
delete(date: string, costCentre: string): Observable<ClosingStock> {
|
||||
const options = { params: new HttpParams().set('d', costCentre) };
|
||||
return this.http
|
||||
.delete<ClosingStock>(`${url}/${date}`, options)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'Delete Voucher')),
|
||||
) as Observable<ClosingStock>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,27 @@
|
||||
import { CostCentre } from '../core/cost-centre';
|
||||
import { User } from '../core/user';
|
||||
|
||||
import { ClosingStockItem } from './closing-stock-item';
|
||||
|
||||
export class ClosingStock {
|
||||
date: string;
|
||||
body: ClosingStockItem[];
|
||||
costCentre: CostCentre;
|
||||
items: ClosingStockItem[];
|
||||
creationDate: string;
|
||||
lastEditDate: string;
|
||||
user: User;
|
||||
posted: boolean;
|
||||
poster: User;
|
||||
|
||||
public constructor(init?: Partial<ClosingStock>) {
|
||||
this.date = '';
|
||||
this.body = [];
|
||||
this.costCentre = new CostCentre();
|
||||
this.items = [];
|
||||
this.creationDate = '';
|
||||
this.lastEditDate = '';
|
||||
this.user = new User();
|
||||
this.posted = false;
|
||||
this.poster = new User();
|
||||
Object.assign(this, init);
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,8 +27,7 @@ export class Product {
|
||||
name: string;
|
||||
skus: StockKeepingUnit[];
|
||||
price: number | undefined;
|
||||
tax: number | undefined;
|
||||
discount: number | undefined;
|
||||
fractionUnits: string | undefined;
|
||||
|
||||
isActive: boolean;
|
||||
isFixture: boolean;
|
||||
|
||||
@ -71,7 +71,7 @@ export class VoucherService {
|
||||
}
|
||||
|
||||
saveOrUpdate(voucher: Voucher): Observable<Voucher> {
|
||||
const endpoint = voucher.type.replace(/ /g, '-').toLowerCase();
|
||||
const endpoint = voucher.type.replace(/_/g, '-').toLowerCase();
|
||||
if (!voucher.id) {
|
||||
return this.save(voucher, endpoint);
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ export class ProductLedgerComponent implements OnInit, AfterViewInit {
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) =>
|
||||
x === null ? observableOf([]) : this.productSer.autocomplete(x, false, false),
|
||||
x === null ? observableOf([]) : this.productSer.autocomplete(x, null, false, false),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { ProductService } from './product.service';
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ProductResolver implements Resolve<Product> {
|
||||
constructor(private ser: ProductService, private router: Router) {}
|
||||
constructor(private ser: ProductService) {}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot): Observable<Product> {
|
||||
const id = route.paramMap.get('id');
|
||||
|
||||
@ -53,6 +53,7 @@ export class ProductService {
|
||||
|
||||
autocomplete(
|
||||
query: string,
|
||||
isPurchased: boolean | null,
|
||||
extended: boolean = false,
|
||||
skus: boolean = true,
|
||||
date?: string,
|
||||
@ -61,6 +62,9 @@ export class ProductService {
|
||||
const options = {
|
||||
params: new HttpParams().set('q', query).set('e', extended.toString()).set('s', skus),
|
||||
};
|
||||
if (isPurchased !== null) {
|
||||
options.params = options.params.set('p', isPurchased.toString());
|
||||
}
|
||||
if (!!vendorId && !!date) {
|
||||
options.params = options.params.set('v', vendorId as string).set('d', date as string);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ export class PurchaseDialogComponent implements OnInit {
|
||||
map((x) => (x !== null && x.length >= 1 ? x : null)),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x))),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x, true))),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -100,6 +100,7 @@ export class PurchaseComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
? observableOf([])
|
||||
: this.productSer.autocomplete(
|
||||
x,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
moment(this.form.value.date).format('DD-MMM-YYYY'),
|
||||
|
||||
@ -77,7 +77,7 @@ export class RateContractDetailComponent implements OnInit, AfterViewInit {
|
||||
map((x) => (x !== null && x.length >= 1 ? x : null)),
|
||||
debounceTime(150),
|
||||
distinctUntilChanged(),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x))),
|
||||
switchMap((x) => (x === null ? observableOf([]) : this.productSer.autocomplete(x, true))),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user