Files
brewman/overlord/src/app/mozimo-daily-register/mozimo-daily-register.component.ts
T

222 lines
6.9 KiB
TypeScript

import { DecimalPipe } from '@angular/common';
import { Component, inject, input, computed, afterNextRender, linkedSignal, signal } from '@angular/core';
import { form as createForm, FormField, FormRoot } from '@angular/forms/signals';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatBadgeModule } from '@angular/material/badge';
import { MatButtonModule } from '@angular/material/button';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatPaginatorModule, PageEvent } from '@angular/material/paginator';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTableModule } from '@angular/material/table';
import { MatTooltipModule } from '@angular/material/tooltip';
import { Router } from '@angular/router';
import moment from 'moment';
import { AuthService } from '../auth/auth.service';
import { ErrorStateComponent } from '../shared/error-state/error-state.component';
import { LocalTimePipe } from '../shared/local-time.pipe';
import { SkeletonLoaderComponent } from '../shared/skeleton-loader/skeleton-loader.component';
import { ToCsvService } from '../shared/to-csv.service';
import { MozimoDailyRegister } from './mozimo-daily-register';
import { MozimoDailyRegisterItem } from './mozimo-daily-register-item';
import { MozimoDailyRegisterService } from './mozimo-daily-register.service';
export interface MozimoDailyRegisterFormData {
date: Date;
items: {
received: number;
sale: number;
nc: number;
display: number | null;
ageing: number | null;
}[];
}
@Component({
selector: 'app-mozimo-daily-register',
templateUrl: './mozimo-daily-register.component.html',
styleUrls: ['./mozimo-daily-register.component.css'],
imports: [
DecimalPipe,
LocalTimePipe,
MatAutocompleteModule,
MatBadgeModule,
MatButtonModule,
MatDatepickerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
MatPaginatorModule,
MatTableModule,
MatTooltipModule,
FormField,
FormRoot,
SkeletonLoaderComponent,
ErrorStateComponent,
],
providers: [LocalTimePipe],
})
export class MozimoDailyRegisterComponent {
private router = inject(Router);
private toCsv = inject(ToCsvService);
private localTimePipe = inject(LocalTimePipe);
private snackBar = inject(MatSnackBar);
auth = inject(AuthService);
private ser = inject(MozimoDailyRegisterService);
date = input(null, { transform: (v: string | null | undefined) => v ?? null });
pageSize = signal(50);
pageIndex = signal(0);
infoResource = this.ser.list(this.date);
info = computed(() => this.infoResource.value() ?? new MozimoDailyRegister());
model = linkedSignal({
source: this.info,
computation: (v): MozimoDailyRegisterFormData => ({
date: moment(v.date, 'DD-MMM-YYYY').toDate(),
items: v.body.map((x) => ({
received: x.received,
sale: x.sale,
nc: x.nc,
display: x.display,
ageing: x.ageing,
})),
}),
});
body = linkedSignal(() => this.info().body);
dataSource = computed(() => {
const data = this.info().body ?? [];
const pageIndex = this.pageIndex();
const pageSize = this.pageSize();
return data.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize);
});
form = createForm(this.model);
/** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */
displayedColumns = ['product', 'opening', 'received', 'sale', 'nc', 'display', 'ageing', 'variance', 'closing'];
constructor() {
afterNextRender(() => {
this.form().focusBoundControl();
});
}
show() {
const date = moment(this.model().date).format('DD-MMM-YYYY');
if (this.date() === date) {
this.infoResource.reload();
} else {
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 as string, 'Danger');
},
});
}
getMozimoDailyRegister(): MozimoDailyRegister {
const formModel = this.model();
const info = this.info();
info.date = moment(formModel.date).format('DD-MMM-YYYY');
const array = formModel.items;
if (array) {
info.body.forEach((item, index) => {
if (array[index]) {
item.received = array[index].received ?? 0;
item.sale = array[index].sale ?? 0;
item.nc = array[index].nc ?? 0;
item.display = array[index].display ?? null;
item.ageing = array[index].ageing ?? null;
}
});
}
return 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.info().body ?? [])).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.set([...this.info().body]);
}
updateSale($event: Event, row: MozimoDailyRegisterItem) {
row.sale = +($event.target as HTMLInputElement).value;
this.body.set([...this.info().body]);
}
updateNc($event: Event, row: MozimoDailyRegisterItem) {
row.nc = +($event.target as HTMLInputElement).value;
this.body.set([...this.info().body]);
}
updateDisplay($event: Event, row: MozimoDailyRegisterItem) {
const val = ($event.target as HTMLInputElement).value;
row.display = val === '' ? null : +val;
this.body.set([...this.info().body]);
}
updateAgeing($event: Event, row: MozimoDailyRegisterItem) {
const val = ($event.target as HTMLInputElement).value;
row.ageing = val === '' ? null : +val;
this.body.set([...this.info().body]);
}
handlePageEvent(e: PageEvent) {
this.pageSize.set(e.pageSize);
this.pageIndex.set(e.pageIndex);
}
}