2020-10-01 15:21:22 +00:00
|
|
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
2021-10-31 13:11:06 +00:00
|
|
|
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
|
|
|
|
import { MatDialog } from '@angular/material/dialog';
|
2019-06-12 11:55:10 +00:00
|
|
|
import { MatPaginator } from '@angular/material/paginator';
|
2021-10-31 13:11:06 +00:00
|
|
|
import { MatSelectChange } from '@angular/material/select';
|
2019-06-12 11:55:10 +00:00
|
|
|
import { MatSort } from '@angular/material/sort';
|
2020-10-01 15:21:22 +00:00
|
|
|
import { ActivatedRoute, Router } from '@angular/router';
|
2018-05-25 13:49:00 +00:00
|
|
|
import * as moment from 'moment';
|
2020-10-10 03:15:05 +00:00
|
|
|
|
2021-10-31 13:11:06 +00:00
|
|
|
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';
|
2020-10-01 15:21:22 +00:00
|
|
|
import { ToCsvService } from '../shared/to-csv.service';
|
2018-05-25 13:49:00 +00:00
|
|
|
|
2020-10-10 03:15:05 +00:00
|
|
|
import { ClosingStock } from './closing-stock';
|
|
|
|
import { ClosingStockDataSource } from './closing-stock-datasource';
|
2021-10-31 13:11:06 +00:00
|
|
|
import { ClosingStockItem } from './closing-stock-item';
|
|
|
|
import { ClosingStockService } from './closing-stock.service';
|
2020-10-10 03:15:05 +00:00
|
|
|
|
2018-05-25 13:49:00 +00:00
|
|
|
@Component({
|
|
|
|
selector: 'app-closing-stock',
|
|
|
|
templateUrl: './closing-stock.component.html',
|
2020-10-01 15:21:22 +00:00
|
|
|
styleUrls: ['./closing-stock.component.css'],
|
2018-05-25 13:49:00 +00:00
|
|
|
})
|
|
|
|
export class ClosingStockComponent implements OnInit {
|
2020-11-23 04:55:53 +00:00
|
|
|
@ViewChild(MatPaginator, { static: true }) paginator?: MatPaginator;
|
|
|
|
@ViewChild(MatSort, { static: true }) sort?: MatSort;
|
2020-11-23 11:12:54 +00:00
|
|
|
info: ClosingStock = new ClosingStock();
|
2021-10-31 13:11:06 +00:00
|
|
|
dataSource: ClosingStockDataSource = new ClosingStockDataSource(this.info.items);
|
2018-05-25 13:49:00 +00:00
|
|
|
form: FormGroup;
|
|
|
|
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
|
2021-10-31 13:11:06 +00:00
|
|
|
displayedColumns = [
|
|
|
|
'product',
|
|
|
|
'group',
|
|
|
|
'quantity',
|
|
|
|
'physical',
|
|
|
|
'variance',
|
|
|
|
'department',
|
|
|
|
'amount',
|
|
|
|
];
|
|
|
|
|
|
|
|
costCentres: CostCentre[];
|
2018-05-25 13:49:00 +00:00
|
|
|
|
2020-10-01 15:21:22 +00:00
|
|
|
constructor(
|
|
|
|
private route: ActivatedRoute,
|
|
|
|
private router: Router,
|
|
|
|
private fb: FormBuilder,
|
|
|
|
private toCsv: ToCsvService,
|
2021-10-31 13:11:06 +00:00
|
|
|
private dialog: MatDialog,
|
|
|
|
private toaster: ToasterService,
|
|
|
|
public auth: AuthService,
|
|
|
|
private ser: ClosingStockService,
|
2020-10-01 15:21:22 +00:00
|
|
|
) {
|
2021-10-31 13:11:06 +00:00
|
|
|
this.costCentres = [];
|
2018-05-25 13:49:00 +00:00
|
|
|
this.form = this.fb.group({
|
2020-10-01 15:21:22 +00:00
|
|
|
date: '',
|
2021-10-31 13:11:06 +00:00
|
|
|
costCentre: '',
|
|
|
|
stocks: this.fb.array([]),
|
2018-05-25 13:49:00 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnInit() {
|
2020-11-23 03:48:02 +00:00
|
|
|
this.route.data.subscribe((value) => {
|
2021-10-31 13:11:06 +00:00
|
|
|
const data = value as { info: ClosingStock; costCentres: CostCentre[] };
|
2020-10-01 15:21:22 +00:00
|
|
|
this.info = data.info;
|
2021-10-31 13:11:06 +00:00
|
|
|
this.costCentres = data.costCentres;
|
|
|
|
this.form.patchValue({
|
2020-10-01 15:21:22 +00:00
|
|
|
date: moment(this.info.date, 'DD-MMM-YYYY').toDate(),
|
2021-10-31 13:11:06 +00:00
|
|
|
costCentre: this.info.costCentre.id,
|
2018-05-25 13:49:00 +00:00
|
|
|
});
|
2021-10-31 13:11:06 +00:00
|
|
|
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);
|
2020-10-01 15:21:22 +00:00
|
|
|
});
|
2018-05-25 13:49:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
show() {
|
|
|
|
const info = this.getInfo();
|
2021-10-31 13:11:06 +00:00
|
|
|
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;
|
2018-05-25 13:49:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getInfo(): ClosingStock {
|
|
|
|
const formModel = this.form.value;
|
|
|
|
|
2020-11-23 11:12:54 +00:00
|
|
|
return new ClosingStock({
|
2020-10-01 15:21:22 +00:00
|
|
|
date: moment(formModel.date).format('DD-MMM-YYYY'),
|
2021-10-31 13:11:06 +00:00
|
|
|
costCentre: new CostCentre({ id: formModel.costCentre }),
|
2020-11-23 11:12:54 +00:00
|
|
|
});
|
2018-05-25 13:49:00 +00:00
|
|
|
}
|
2018-06-11 16:44:04 +00:00
|
|
|
|
2018-05-25 13:49:00 +00:00
|
|
|
exportCsv() {
|
2018-06-11 16:44:04 +00:00
|
|
|
const headers = {
|
|
|
|
Product: 'product',
|
|
|
|
Group: 'group',
|
|
|
|
Quantity: 'quantity',
|
2020-10-01 15:21:22 +00:00
|
|
|
Amount: 'amount',
|
2018-06-11 16:44:04 +00:00
|
|
|
};
|
2018-05-25 13:49:00 +00:00
|
|
|
|
2020-10-01 15:21:22 +00:00
|
|
|
const csvData = new Blob([this.toCsv.toCsv(headers, this.dataSource.data)], {
|
|
|
|
type: 'text/csv;charset=utf-8;',
|
|
|
|
});
|
2018-05-25 13:49:00 +00:00
|
|
|
const link = document.createElement('a');
|
|
|
|
link.href = window.URL.createObjectURL(csvData);
|
|
|
|
link.setAttribute('download', 'closing-stock.csv');
|
|
|
|
document.body.appendChild(link);
|
|
|
|
link.click();
|
|
|
|
document.body.removeChild(link);
|
|
|
|
}
|
2021-10-31 13:11:06 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-05-25 13:49:00 +00:00
|
|
|
}
|