import { DecimalPipe, CurrencyPipe, AsyncPipe } from '@angular/common'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { FormGroup, FormArray, FormControl, ReactiveFormsModule, Validators } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatBadgeModule } from '@angular/material/badge'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatIconModule } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; import { MatTableModule } from '@angular/material/table'; import { ActivatedRoute, Router } from '@angular/router'; import moment from 'moment'; import { AuthService } from '../auth/auth.service'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ToCsvService } from '../shared/to-csv.service'; import { MozimoDailyRegister } from './mozimo-daily-register'; import { MozimoDailyRegisterDataSource } from './mozimo-daily-register-datasource'; import { MozimoDailyRegisterItem } from './mozimo-daily-register-item'; import { MozimoDailyRegisterService } from './mozimo-daily-register.service'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { BehaviorSubject } from 'rxjs'; import { LocalTimePipe } from '../shared/local-time.pipe'; import { MatTooltipModule } from '@angular/material/tooltip'; @Component({ selector: 'app-mozimo-daily-register', templateUrl: './mozimo-daily-register.component.html', styleUrls: ['./mozimo-daily-register.component.css'], standalone: true, imports: [ AsyncPipe, CurrencyPipe, DecimalPipe, LocalTimePipe, MatAutocompleteModule, MatBadgeModule, MatButtonModule, MatCardModule, MatDatepickerModule, MatFormFieldModule, MatIconModule, MatInputModule, MatPaginatorModule, MatTableModule, MatTooltipModule, ReactiveFormsModule, ], providers: [LocalTimePipe], }) export class MozimoDailyRegisterComponent implements OnInit { @ViewChild('dateElement', { static: false }) dateElement!: ElementRef; @ViewChild(MatPaginator, { static: true }) paginator!: MatPaginator; info: MozimoDailyRegister = new MozimoDailyRegister(); body = new BehaviorSubject([]); dataSource: MozimoDailyRegisterDataSource = new MozimoDailyRegisterDataSource(this.body); form: FormGroup<{ date: FormControl; items: FormArray< FormGroup<{ received: FormControl; sale: FormControl; nc: FormControl; display: FormControl; ageing: FormControl; }> >; }>; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ displayedColumns = ['product', 'opening', 'received', 'sale', 'nc', 'display', 'ageing', 'variance', 'closing']; constructor( private route: ActivatedRoute, private router: Router, private toCsv: ToCsvService, private localTimePipe: LocalTimePipe, private snackBar: MatSnackBar, public auth: AuthService, private ser: MozimoDailyRegisterService, ) { this.form = new FormGroup({ date: new FormControl(new Date(), { nonNullable: true }), items: new FormArray< FormGroup<{ received: FormControl; sale: FormControl; nc: FormControl; display: FormControl; ageing: FormControl; }> >([]), }); } ngOnInit() { this.route.data.subscribe((value) => { const data = value as { info: MozimoDailyRegister }; this.info = data.info; this.form.patchValue({ date: moment(this.info.date, 'DD-MMM-YYYY').toDate(), }); this.form.controls.items.clear(); this.info.body.forEach((x) => this.form.controls.items.push( new FormGroup({ received: new FormControl(x.received, { nonNullable: true, validators: [Validators.min(0)] }), sale: new FormControl(x.sale, { nonNullable: true, validators: [Validators.min(0)] }), nc: new FormControl(x.nc, { nonNullable: true, validators: [Validators.min(0)] }), display: new FormControl(x.display, { nonNullable: false, validators: [Validators.min(0)] }), ageing: new FormControl(x.ageing, { nonNullable: false, validators: [Validators.min(0)] }), }), ), ); if (!this.dataSource.paginator) { this.dataSource.paginator = this.paginator; } this.body.next(this.info.body); }); } show() { const date = moment(this.form.value.date).format('DD-MMM-YYYY'); this.router.navigate(['/mozimo-daily-register', date]); } save() { this.ser.save(this.getMozimoDailyRegister()).subscribe({ next: () => { this.snackBar.open('', 'Success'); }, error: (error) => { this.snackBar.open(error, 'Danger'); }, }); } getMozimoDailyRegister(): MozimoDailyRegister { const formModel = this.form.value; this.info.date = moment(formModel.date).format('DD-MMM-YYYY'); const array = this.form.controls.items; this.info.body.forEach((item, index) => { item.received = +(array.controls[index].value.received ?? 0); item.sale = +(array.controls[index].value.sale ?? 0); item.nc = +(array.controls[index].value.nc ?? 0); const display = array.controls[index].value.display ?? null; const ageing = array.controls[index].value.ageing ?? null; item.display = display == null ? null : +display; item.ageing = ageing == null ? null : +ageing; }); return this.info; } exportCsv() { const headers = { Product: 'product', Opening: 'opening', Received: 'received', Sale: 'sale', Nc: 'nc', Display: 'display', Ageing: 'ageing', Variance: 'variance', Closing: 'closing', 'Last Edit Date': 'lastEditDate', }; const d = JSON.parse(JSON.stringify(this.dataSource.data)).map((x: MozimoDailyRegisterItem) => ({ id: x.id, product: x.product.name, opening: x.opening, received: x.received, sale: x.sale, nc: x.nc, display: x.display, ageing: x.ageing, variance: x.variance, closing: x.closing, lastEditDate: x.lastEditDate ? this.localTimePipe.transform(x.lastEditDate ?? '') : 'Unsaved', })); const csvData = new Blob([this.toCsv.toCsv(headers, d)], { type: 'text/csv;charset=utf-8;', }); const link = document.createElement('a'); link.href = window.URL.createObjectURL(csvData); link.setAttribute('download', 'mozimo-product-register.csv'); document.body.appendChild(link); link.click(); document.body.removeChild(link); } updateReceived($event: Event, row: MozimoDailyRegisterItem) { row.received = +($event.target as HTMLInputElement).value; this.body.next(this.info.body); } updateSale($event: Event, row: MozimoDailyRegisterItem) { row.sale = +($event.target as HTMLInputElement).value; this.body.next(this.info.body); } updateNc($event: Event, row: MozimoDailyRegisterItem) { row.nc = +($event.target as HTMLInputElement).value; this.body.next(this.info.body); } updateDisplay($event: Event, row: MozimoDailyRegisterItem) { const val = ($event.target as HTMLInputElement).value; row.display = val === '' ? null : +val; this.body.next(this.info.body); } updateAgeing($event: Event, row: MozimoDailyRegisterItem) { const val = ($event.target as HTMLInputElement).value; row.ageing = val === '' ? null : +val; this.body.next(this.info.body); } }