feat(pos): add shop and statistics modules with components, services, and routing
- Implemented shop module with root component, loading state, and invoice handling. - Created statistics module with invoice type card component, API routes, and data models. - Added season picker component for selecting year and season. - Integrated services for fetching statistics data and managing state. - Established routing for statistics and shop views.
This commit is contained in:
@@ -50,7 +50,7 @@ export class PosSaleInvoicesFilterDrawerComponent implements OnChanges {
|
||||
customer_mobile: this.fb.control<string>(''),
|
||||
customer_national_id: this.fb.control<string>(''),
|
||||
customer_economic_code: this.fb.control<string>(''),
|
||||
status: this.fb.control<string | null>(null),
|
||||
status: this.fb.control<'NOT_SEND' | 'SUCCESS' | 'FAILURE' | 'QUEUED' | null>(null),
|
||||
total_amount_from: this.fb.control<number | null>(null),
|
||||
total_amount_to: this.fb.control<number | null>(null),
|
||||
});
|
||||
@@ -74,7 +74,7 @@ export class PosSaleInvoicesFilterDrawerComponent implements OnChanges {
|
||||
total_amount_from: this.value.total_amount_from ?? null,
|
||||
total_amount_to: this.value.total_amount_to ?? null,
|
||||
},
|
||||
{ emitEvent: false },
|
||||
{ emitEvent: false }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { POS_ROUTES } from '@/domains/pos/routes';
|
||||
import { InnerPagesHeaderComponent } from '@/shared/components/innerPagesHeader/inner-pages-header.component';
|
||||
import { gregorianToJalali } from '@/utils';
|
||||
import { Component, computed, inject, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Button, ButtonDirective } from 'primeng/button';
|
||||
import { Chip } from 'primeng/chip';
|
||||
import { Skeleton } from 'primeng/skeleton';
|
||||
@@ -32,6 +33,7 @@ import { SaleInvoiceCardComponent } from './sale-invoice-card.component';
|
||||
export class PosSaleInvoiceListComponent {
|
||||
private readonly service = inject(PosSaleInvoicesService);
|
||||
private readonly router = inject(Router);
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
|
||||
loading = signal(true);
|
||||
items = signal<IPosSaleInvoicesSummaryResponse[]>([]);
|
||||
@@ -57,16 +59,28 @@ export class PosSaleInvoiceListComponent {
|
||||
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
||||
.map(([key, value]) => {
|
||||
const typedKey = key as keyof IPosSaleInvoicesFilterDto;
|
||||
const formattedValue =
|
||||
typedKey === 'status' && value === 'NOT_SEND'
|
||||
? 'ارسال نشده'
|
||||
: typedKey === 'status' && value === 'SUCCESS'
|
||||
? 'موفق'
|
||||
: typedKey === 'status' && value === 'FAILURE'
|
||||
? 'ناموفق'
|
||||
: typedKey === 'status' && value === 'QUEUED'
|
||||
? 'در انتظار ارسال'
|
||||
: String(value);
|
||||
let formattedValue = '';
|
||||
if (typedKey === 'status') {
|
||||
formattedValue =
|
||||
value === 'NOT_SEND'
|
||||
? 'ارسال نشده'
|
||||
: value === 'SUCCESS'
|
||||
? 'موفق'
|
||||
: value === 'FAILURE'
|
||||
? 'ناموفق'
|
||||
: value === 'QUEUED'
|
||||
? 'در انتظار ارسال'
|
||||
: String(value);
|
||||
} else if (
|
||||
key === 'invoice_date_from' ||
|
||||
key === 'invoice_date_to' ||
|
||||
key === 'created_at_from' ||
|
||||
key === 'created_at_to'
|
||||
) {
|
||||
formattedValue = gregorianToJalali(value);
|
||||
} else {
|
||||
formattedValue = String(value);
|
||||
}
|
||||
return { key: typedKey, label: labels[typedKey] ?? typedKey, value: formattedValue };
|
||||
});
|
||||
});
|
||||
@@ -74,6 +88,7 @@ export class PosSaleInvoiceListComponent {
|
||||
backRoute = POS_ROUTES.path || '/';
|
||||
|
||||
ngOnInit() {
|
||||
this.hydrateFiltersFromQueryParams();
|
||||
this.getData();
|
||||
}
|
||||
|
||||
@@ -96,6 +111,7 @@ export class PosSaleInvoiceListComponent {
|
||||
|
||||
onFilterApply(query: IPosSaleInvoicesFilterDto) {
|
||||
this.filters.set(query);
|
||||
this.syncFiltersToQueryParams();
|
||||
this.getData();
|
||||
}
|
||||
|
||||
@@ -103,10 +119,57 @@ export class PosSaleInvoiceListComponent {
|
||||
const next = { ...this.filters() };
|
||||
delete next[key];
|
||||
this.filters.set(next);
|
||||
this.syncFiltersToQueryParams();
|
||||
this.getData();
|
||||
}
|
||||
|
||||
toSinglePage(item: IPosSaleInvoicesResponse) {
|
||||
this.router.navigateByUrl(posSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(item.id));
|
||||
}
|
||||
|
||||
private hydrateFiltersFromQueryParams() {
|
||||
const queryParams = this.route.snapshot.queryParams;
|
||||
const keys: (keyof IPosSaleInvoicesFilterDto)[] = [
|
||||
'invoice_date_from',
|
||||
'invoice_date_to',
|
||||
'created_at_from',
|
||||
'created_at_to',
|
||||
'code',
|
||||
'customer_name',
|
||||
'customer_mobile',
|
||||
'customer_national_id',
|
||||
'customer_economic_code',
|
||||
'status',
|
||||
'total_amount_from',
|
||||
'total_amount_to',
|
||||
];
|
||||
|
||||
const parsed = keys.reduce<IPosSaleInvoicesFilterDto>((acc, key) => {
|
||||
const value = queryParams[key];
|
||||
if (value !== undefined && value !== null && value !== '') {
|
||||
acc[key] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
this.filters.set(parsed);
|
||||
}
|
||||
|
||||
private syncFiltersToQueryParams() {
|
||||
const queryParams = Object.entries(this.filters()).reduce<Record<string, string>>(
|
||||
(acc, [key, value]) => {
|
||||
if (value !== undefined && value !== null && value !== '') {
|
||||
acc[key] = String(value);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
this.router.navigate([], {
|
||||
relativeTo: this.route,
|
||||
queryParams,
|
||||
replaceUrl: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export interface IPosSaleInvoicesFilterDto {
|
||||
customer_mobile?: string;
|
||||
customer_national_id?: string;
|
||||
customer_economic_code?: string;
|
||||
status?: string;
|
||||
status?: 'NOT_SEND' | 'SUCCESS' | 'FAILURE' | 'QUEUED';
|
||||
total_amount?: number | null;
|
||||
total_amount_from?: number | null;
|
||||
total_amount_to?: number | null;
|
||||
|
||||
Reference in New Issue
Block a user