feat: add stock keeping units list component and related services
feat: implement checkbox component with label and hint support feat: create sale invoice full response model for invoice details feat: add single view component for displaying sale invoice details feat: define various list configurations for account, business activity, and consumer management feat: establish list configurations for managing devices, goods, and licenses feat: create list configurations for managing partners and their accounts feat: implement user management list configuration
This commit is contained in:
@@ -111,6 +111,37 @@ example: (value = '', isRequired = true): ControlConfig => [
|
|||||||
- `<field-example [control]="form.controls.example" />`
|
- `<field-example [control]="form.controls.example" />`
|
||||||
- For numeric/price behavior, use `app-input` `type="number"` or `type="price"` and optional `[fixed]`.
|
- For numeric/price behavior, use `app-input` `type="number"` or `type="price"` and optional `[fixed]`.
|
||||||
|
|
||||||
|
## List Component Configs
|
||||||
|
|
||||||
|
- Centralized list metadata is stored in `src/app/shared/constants/list-configs/` — **never** in domain modules.
|
||||||
|
- Structure by data type, not domain (e.g. `good-list.const.ts`, `sku-list.const.ts`, `category-list.const.ts`).
|
||||||
|
- Each config implements `IListConfig` (defined in `list-config.model.ts`):
|
||||||
|
- `pageTitle`: display title for the list page
|
||||||
|
- `addNewCtaLabel`: call-to-action button label
|
||||||
|
- `emptyPlaceholderTitle` and `emptyPlaceholderDescription`: empty state messaging
|
||||||
|
- `columns`: array of `IColumn[]` definitions
|
||||||
|
- Usage in list components:
|
||||||
|
```ts
|
||||||
|
@Input() header: IColumn[] = goodListConfig.columns;
|
||||||
|
listConfig = goodListConfig;
|
||||||
|
```
|
||||||
|
- Any domain needing a list config imports from `@/shared/constants/list-configs` — no cross-domain dependencies.
|
||||||
|
- **Do not** define configs inside domains or duplicate them across modules.
|
||||||
|
|
||||||
|
## Breadcrumb Usage in Stores & Views
|
||||||
|
|
||||||
|
- Entity stores expose `breadcrumbItems` as a computed signal.
|
||||||
|
- Call `store.breadcrumbItems()` in view components and extend with current page:
|
||||||
|
```ts
|
||||||
|
setBreadcrumb() {
|
||||||
|
this.breadcrumbService.setItems([
|
||||||
|
...this.store.breadcrumbItems(),
|
||||||
|
{ title: 'Current Page' },
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Root page breadcrumbs are set in the store's `getData()` method once entity is loaded.
|
||||||
|
|
||||||
## Validation Checklist
|
## Validation Checklist
|
||||||
|
|
||||||
- For TypeScript-only changes, run:
|
- For TypeScript-only changes, run:
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export class NativeBridgeService {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
print(request: INativePrintRequest): INativeBridgeResult {
|
print(request: INativePrintRequest[]): INativeBridgeResult {
|
||||||
return this.invokePrint(request);
|
return this.invokePrint(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ export class NativeBridgeService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private invokePrint(payload: INativePrintRequest): INativeBridgeResult {
|
private invokePrint(payload: INativePrintRequest[]): INativeBridgeResult {
|
||||||
if (!this.isEnabled() || !this.canPrint()) {
|
if (!this.isEnabled() || !this.canPrint()) {
|
||||||
this.toastService.warn({ text: 'متاسفانه ارتباط با چاپگر برقرار نیست.' });
|
this.toastService.warn({ text: 'متاسفانه ارتباط با چاپگر برقرار نیست.' });
|
||||||
return { success: false, error: 'متاسفانه ارتباط با چاپگر برقرار نیست.' };
|
return { success: false, error: 'متاسفانه ارتباط با چاپگر برقرار نیست.' };
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ export class ConsumerSaleInvoiceSharedComponent {
|
|||||||
|
|
||||||
printInvoice = () => {
|
printInvoice = () => {
|
||||||
if (this.invoice) {
|
if (this.invoice) {
|
||||||
const printResult = this.nativeBridge.print({
|
const printResult = this.nativeBridge.print([
|
||||||
|
{
|
||||||
title: `فروشگاه ${this.posName()}`,
|
title: `فروشگاه ${this.posName()}`,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@@ -78,7 +79,8 @@ export class ConsumerSaleInvoiceSharedComponent {
|
|||||||
{ label: 'تاریخ', value: formatJalali(this.invoice.invoice_date, 'YYYY/MM/DD') },
|
{ label: 'تاریخ', value: formatJalali(this.invoice.invoice_date, 'YYYY/MM/DD') },
|
||||||
{ label: 'مبلغ کل', value: this.invoice.total_amount },
|
{ label: 'مبلغ کل', value: this.invoice.total_amount },
|
||||||
],
|
],
|
||||||
});
|
},
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
IChangePasswordSubmitPayload,
|
IChangePasswordSubmitPayload,
|
||||||
} from '@/shared/components';
|
} from '@/shared/components';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { accountListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, signal } from '@angular/core';
|
import { Component, inject, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { finalize } from 'rxjs';
|
import { finalize } from 'rxjs';
|
||||||
@@ -23,27 +24,7 @@ export class ConsumerAccountsComponent extends AbstractList<IAccountResponse> {
|
|||||||
passwordSubmitLoading = signal(false);
|
passwordSubmitLoading = signal(false);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = accountListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{
|
|
||||||
field: 'username',
|
|
||||||
header: 'نام کاربری',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.username' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'pos',
|
|
||||||
header: 'پایانه',
|
|
||||||
customDataModel(item) {
|
|
||||||
return `${item.pos.name} - ${item.pos.complex.name} - ${item.pos.complex.business_activity.name}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
+2
-10
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { complexListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { consumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
import { consumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
||||||
@@ -19,16 +20,7 @@ import { ConsumerComplexFormComponent } from './form.component';
|
|||||||
export class ConsumerComplexListComponent extends AbstractList<IComplexResponse> {
|
export class ConsumerComplexListComponent extends AbstractList<IComplexResponse> {
|
||||||
@Input({ required: true }) businessId!: string;
|
@Input({ required: true }) businessId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = complexListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'branch_code', header: 'کد شعبه' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(ConsumerComplexesService);
|
private readonly service = inject(ConsumerComplexesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
+4
-16
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { goodListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { IConsumerBusinessActivityGoodResponse } from '../../models/goods_io';
|
import { IConsumerBusinessActivityGoodResponse } from '../../models/goods_io';
|
||||||
import { BusinessActivityGoodsService } from '../../services/goods.service';
|
import { BusinessActivityGoodsService } from '../../services/goods.service';
|
||||||
@@ -18,22 +19,9 @@ export class ConsumerBusinessActivityGoodsListComponent extends AbstractList<ICo
|
|||||||
@Input({ required: true }) businessId!: string;
|
@Input({ required: true }) businessId!: string;
|
||||||
@Input({ required: true }) guildId!: string;
|
@Input({ required: true }) guildId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = goodListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
listConfig = goodListConfig;
|
||||||
{ field: 'sku', header: 'شناسه عمومی' },
|
|
||||||
{
|
|
||||||
field: 'category',
|
|
||||||
header: 'دستهبندی',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'category.name' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
service = inject(BusinessActivityGoodsService);
|
service = inject(BusinessActivityGoodsService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { businessActivityListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { consumerBusinessActivityNamedRoutes } from '../constants';
|
import { consumerBusinessActivityNamedRoutes } from '../constants';
|
||||||
@@ -18,33 +19,7 @@ import { ConsumerBusinessActivityFormComponent } from './form.component';
|
|||||||
})
|
})
|
||||||
export class ConsumerBusinessActivityListComponent extends AbstractList<IBusinessActivityResponse> {
|
export class ConsumerBusinessActivityListComponent extends AbstractList<IBusinessActivityResponse> {
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = businessActivityListConfig.columns;
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'guild', header: 'صنف', type: 'nested', nestedOption: { path: 'guild.name' } },
|
|
||||||
{ field: 'economic_code', header: 'کد اقتصادی' },
|
|
||||||
{
|
|
||||||
field: 'license_info',
|
|
||||||
header: 'محدودیت کاربر',
|
|
||||||
customDataModel(item) {
|
|
||||||
const licenseInfo = (item as IBusinessActivityResponse).license_info;
|
|
||||||
if (!licenseInfo) {
|
|
||||||
return 'بدون مجوز';
|
|
||||||
}
|
|
||||||
return `${licenseInfo.accounts_limit} کاربر`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'license_info',
|
|
||||||
header: 'انقضا مجوز',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'license_info.expires_at', type: 'date' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(BusinessActivitiesService);
|
private readonly service = inject(BusinessActivitiesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
|
||||||
|
import { customerListConfig } from '@/shared/constants/list-configs/customer-list.const';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { ConsumerBusinessActivityFormComponent } from '../components/form-dialog.component';
|
import { ConsumerBusinessActivityFormComponent } from '../components/form-dialog.component';
|
||||||
@@ -18,42 +20,7 @@ import { CustomersService } from '../services/main.service';
|
|||||||
})
|
})
|
||||||
export class ConsumerCustomerListComponent extends AbstractList<ICustomerResponse> {
|
export class ConsumerCustomerListComponent extends AbstractList<ICustomerResponse> {
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = customerListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{
|
|
||||||
field: 'type',
|
|
||||||
header: 'نوع مشتری',
|
|
||||||
customDataModel(item) {
|
|
||||||
return item.type === 'LEGAL' ? 'حقوقی' : 'حقیقی';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
field: 'name',
|
|
||||||
header: 'عنوان',
|
|
||||||
customDataModel(item: ICustomerResponse) {
|
|
||||||
if (item.type === 'LEGAL') {
|
|
||||||
return item.legal!.company_name;
|
|
||||||
}
|
|
||||||
return `${item.individual!.first_name} ${item.individual!.last_name}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'economic_code',
|
|
||||||
header: 'کد اقتصادی',
|
|
||||||
customDataModel(item: ICustomerResponse) {
|
|
||||||
if (item.type === 'LEGAL') {
|
|
||||||
return item.legal!.economic_code;
|
|
||||||
}
|
|
||||||
return item.individual!.economic_code;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(CustomersService);
|
private readonly service = inject(CustomersService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice()" variant="customer" />
|
<shared-sale-invoice-single-view [loading]="loading()" [invoice]="invoice()" variant="customer" />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { BreadcrumbService } from '@/core/services';
|
import { BreadcrumbService } from '@/core/services';
|
||||||
import { ConsumerSaleInvoiceSharedComponent } from '@/domains/consumer/components/invoices/shared-saleInvoice.component';
|
import { SharedSaleInvoiceSingleViewComponent } from '@/shared/components/invoices/sale-invoice-single-view.component';
|
||||||
import pageParamsUtils from '@/utils/page-params.utils';
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
import { Component, computed, effect, inject, signal } from '@angular/core';
|
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
@@ -9,7 +9,7 @@ import { ConsumerCustomerSaleInvoiceStore } from '../../store/saleInvoice.store'
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'consumer-customer-saleInvoice',
|
selector: 'consumer-customer-saleInvoice',
|
||||||
templateUrl: './single.component.html',
|
templateUrl: './single.component.html',
|
||||||
imports: [ConsumerSaleInvoiceSharedComponent],
|
imports: [SharedSaleInvoiceSingleViewComponent],
|
||||||
})
|
})
|
||||||
export class ConsumerCustomerSaleInvoiceComponent {
|
export class ConsumerCustomerSaleInvoiceComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { CONSUMER_COMPONENTS_CONST } from '@/domains/consumer/constants';
|
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import {
|
import {
|
||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { posListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input, TemplateRef, ViewChild } from '@angular/core';
|
import { Component, inject, Input, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { CookieService } from 'ngx-cookie-service';
|
import { CookieService } from 'ngx-cookie-service';
|
||||||
@@ -22,7 +22,7 @@ import { ConsumerPosFormComponent } from './form.component';
|
|||||||
})
|
})
|
||||||
export class ConsumerPosListComponent extends AbstractList<IPosResponse> {
|
export class ConsumerPosListComponent extends AbstractList<IPosResponse> {
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = CONSUMER_COMPONENTS_CONST.pos.columns;
|
@Input() header: IColumn[] = posListConfig.columns;
|
||||||
|
|
||||||
private readonly service = inject(ConsumerPosesService);
|
private readonly service = inject(ConsumerPosesService);
|
||||||
private readonly cookieService = inject(CookieService);
|
private readonly cookieService = inject(CookieService);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { saleInvoiceListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { consumerSaleInvoicesNamedRoutes } from '../constants/routes';
|
import { consumerSaleInvoicesNamedRoutes } from '../constants/routes';
|
||||||
@@ -17,37 +18,7 @@ import { ConsumerSaleInvoicesService } from '../services/main.service';
|
|||||||
})
|
})
|
||||||
export class ConsumerSaleInvoiceListComponent extends AbstractList<IConsumerSaleInvoicesResponse> {
|
export class ConsumerSaleInvoiceListComponent extends AbstractList<IConsumerSaleInvoicesResponse> {
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = saleInvoiceListConfig.columns;
|
||||||
{ field: 'code', header: 'کد رهگیری' },
|
|
||||||
{
|
|
||||||
field: 'total_amount',
|
|
||||||
header: 'قیمت نهایی',
|
|
||||||
type: 'price',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'pos',
|
|
||||||
header: 'پایانه',
|
|
||||||
customDataModel(item: IConsumerSaleInvoicesResponse) {
|
|
||||||
return `${item.pos.name} (${item.pos.complex.name} - ${item.pos.complex.business_activity.name})`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'consumer_account',
|
|
||||||
header: 'ایجاد شده توسط',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'consumer_account.account.username' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'invoice_date',
|
|
||||||
header: 'تاریخ فاکتور',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(ConsumerSaleInvoicesService);
|
private readonly service = inject(ConsumerSaleInvoicesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice()" />
|
<shared-sale-invoice-single-view [loading]="loading()" [invoice]="invoice()" />
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { BreadcrumbService } from '@/core/services';
|
import { BreadcrumbService } from '@/core/services';
|
||||||
import { ConsumerSaleInvoiceSharedComponent } from '@/domains/consumer/components/invoices/shared-saleInvoice.component';
|
import { SharedSaleInvoiceSingleViewComponent } from '@/shared/components/invoices/sale-invoice-single-view.component';
|
||||||
import pageParamsUtils from '@/utils/page-params.utils';
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
import { Component, computed, effect, inject, signal } from '@angular/core';
|
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
@@ -8,7 +8,7 @@ import { ConsumerSaleInvoiceStore } from '../store/main.store';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'consumer-saleInvoice',
|
selector: 'consumer-saleInvoice',
|
||||||
templateUrl: './single.component.html',
|
templateUrl: './single.component.html',
|
||||||
imports: [ConsumerSaleInvoiceSharedComponent],
|
imports: [SharedSaleInvoiceSingleViewComponent],
|
||||||
})
|
})
|
||||||
export class ConsumerSaleInvoiceComponent {
|
export class ConsumerSaleInvoiceComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {
|
|||||||
IChangePasswordSubmitPayload,
|
IChangePasswordSubmitPayload,
|
||||||
} from '@/shared/components';
|
} from '@/shared/components';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { partnerAccountListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, signal } from '@angular/core';
|
import { Component, inject, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { finalize } from 'rxjs';
|
import { finalize } from 'rxjs';
|
||||||
@@ -23,27 +24,7 @@ export class PartnerAccountsComponent extends AbstractList<IAccountResponse> {
|
|||||||
passwordSubmitLoading = signal(false);
|
passwordSubmitLoading = signal(false);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = partnerAccountListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{
|
|
||||||
field: 'username',
|
|
||||||
header: 'نام کاربری',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.username' },
|
|
||||||
},
|
|
||||||
{ field: 'role', header: 'نقش' },
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
header: 'وضعیت',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.status' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { partnerConsumerAccountListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { IConsumerAccountResponse } from '../../models';
|
import { IConsumerAccountResponse } from '../../models';
|
||||||
import { PartnerConsumerAccountsService } from '../../services/accounts.service';
|
import { PartnerConsumerAccountsService } from '../../services/accounts.service';
|
||||||
@@ -17,37 +18,7 @@ import { ConsumerAccountFormComponent } from './form.component';
|
|||||||
export class ConsumerAccountListComponent extends AbstractList<IConsumerAccountResponse> {
|
export class ConsumerAccountListComponent extends AbstractList<IConsumerAccountResponse> {
|
||||||
@Input({ required: true }) consumerId!: string;
|
@Input({ required: true }) consumerId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = partnerConsumerAccountListConfig.columns;
|
||||||
{
|
|
||||||
field: 'account',
|
|
||||||
header: 'نام کاربری',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.username' },
|
|
||||||
},
|
|
||||||
{ field: 'role', header: 'نوع حساب', type: 'nested', nestedOption: { path: 'role.translate' } },
|
|
||||||
{
|
|
||||||
field: 'pos',
|
|
||||||
header: 'پایانه',
|
|
||||||
customDataModel(item: IConsumerAccountResponse) {
|
|
||||||
if (item.pos) {
|
|
||||||
return `${item.pos.name} (${item.pos.complex.name} - ${item.pos.complex.business_activity.name})`;
|
|
||||||
}
|
|
||||||
return '-';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
header: 'وضعیت',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.status.translate' },
|
|
||||||
variant: 'tag',
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// field: 'created_at',
|
|
||||||
// header: 'تاریخ ایجاد',
|
|
||||||
// type: 'date',
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
private readonly service = inject(PartnerConsumerAccountsService);
|
private readonly service = inject(PartnerConsumerAccountsService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
|
|||||||
+2
-22
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { businessActivityListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input, signal } from '@angular/core';
|
import { Component, inject, Input, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { partnerConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
import { partnerConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
||||||
@@ -24,28 +25,7 @@ import { ConsumerBusinessActivitiesFormDialogComponent } from './form-dialog.com
|
|||||||
export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessActivityResponse> {
|
export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessActivityResponse> {
|
||||||
@Input({ required: true }) consumerId!: string;
|
@Input({ required: true }) consumerId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = businessActivityListConfig.columns;
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'guild', header: 'صنف', type: 'nested', nestedOption: { path: 'guild.name' } },
|
|
||||||
{ field: 'economic_code', header: 'کد اقتصادی' },
|
|
||||||
{
|
|
||||||
field: 'license_info',
|
|
||||||
header: 'محدودیت کاربر',
|
|
||||||
customDataModel(item) {
|
|
||||||
const licenseInfo = (item as IBusinessActivityResponse).license_info;
|
|
||||||
if (!licenseInfo) {
|
|
||||||
return 'بدون مجوز';
|
|
||||||
}
|
|
||||||
return `${licenseInfo.accounts_limit} کاربر`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'license_info',
|
|
||||||
header: 'انقضا مجوز',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'license_info.expires_at', type: 'date' },
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(PartnerConsumerBusinessActivitiesService);
|
private readonly service = inject(PartnerConsumerBusinessActivitiesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { complexListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input, signal } from '@angular/core';
|
import { Component, inject, Input, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { partnerConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
import { partnerConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
||||||
@@ -25,17 +26,7 @@ export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
|||||||
@Input() consumerId!: string;
|
@Input() consumerId!: string;
|
||||||
@Input() businessId!: string;
|
@Input() businessId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = complexListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'branch_code', header: 'کد شعبه' },
|
|
||||||
{ field: 'pos_count', header: 'تعداد پایانهها' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(PartnerComplexesService);
|
private readonly service = inject(PartnerComplexesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { posListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { partnerConsumerPosesNamedRoutes } from '../../constants/routes/poses';
|
import { partnerConsumerPosesNamedRoutes } from '../../constants/routes/poses';
|
||||||
@@ -21,31 +22,7 @@ export class ConsumerPosesComponent extends AbstractList<IPosResponse> {
|
|||||||
@Input({ required: true }) businessId!: string;
|
@Input({ required: true }) businessId!: string;
|
||||||
@Input({ required: true }) complexId!: string;
|
@Input({ required: true }) complexId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = posListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
// { field: 'serial_number', header: 'شماره سریال' },
|
|
||||||
// { field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
|
|
||||||
{ field: 'pos_type', header: 'نوع پایانه' },
|
|
||||||
{
|
|
||||||
field: 'account',
|
|
||||||
header: 'کاربر',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.username' },
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// field: 'provider',
|
|
||||||
// header: 'ارایهدهنده',
|
|
||||||
// type: 'nested',
|
|
||||||
// nestedOption: { path: 'provider.name' },
|
|
||||||
// },
|
|
||||||
// { field: 'status', header: 'وضعیت' },
|
|
||||||
// {
|
|
||||||
// field: 'created_at',
|
|
||||||
// header: 'تاریخ ایجاد',
|
|
||||||
// type: 'date',
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(PartnerPosesService);
|
private readonly service = inject(PartnerPosesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { consumerListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, signal } from '@angular/core';
|
import { Component, inject, signal } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { CreateConsumerWrapperComponent } from '../components/createConsumerWrapper/create-consumer-wrapper.component';
|
import { CreateConsumerWrapperComponent } from '../components/createConsumerWrapper/create-consumer-wrapper.component';
|
||||||
@@ -20,17 +21,7 @@ export class ConsumersComponent extends AbstractList<IPartnerConsumerResponse> {
|
|||||||
visibleCreateForm = signal(false);
|
visibleCreateForm = signal(false);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = consumerListConfig.columns;
|
||||||
{ field: 'name', header: 'نام' },
|
|
||||||
{ field: 'type', header: 'نوع', type: 'nested', nestedOption: { path: 'type.translate' } },
|
|
||||||
{ field: 'business_counts', header: 'تعداد فعالیت اقتصادی فعال' },
|
|
||||||
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { partnerCustomerListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { partnerCustomersNamedRoutes } from '../constants';
|
import { partnerCustomersNamedRoutes } from '../constants';
|
||||||
@@ -17,19 +18,7 @@ import { CustomersService } from '../services/main.service';
|
|||||||
})
|
})
|
||||||
export class PartnerCustomerListComponent extends AbstractList<ICustomerResponse> {
|
export class PartnerCustomerListComponent extends AbstractList<ICustomerResponse> {
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = partnerCustomerListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
|
|
||||||
{
|
|
||||||
field: 'first_name',
|
|
||||||
header: 'عنوان',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(CustomersService);
|
private readonly service = inject(CustomersService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -16,50 +16,19 @@
|
|||||||
|
|
||||||
<div class="overflow-y-auto">
|
<div class="overflow-y-auto">
|
||||||
<ul class="list-none p-4 m-0">
|
<ul class="list-none p-4 m-0">
|
||||||
|
@for (menuItem of menuItems; track $index) {
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
pRipple
|
pRipple
|
||||||
routerLink="/sale_invoices"
|
[routerLink]="menuItem.routerLink"
|
||||||
(click)="drawerRef.close($event)"
|
(click)="drawerRef.close($event)"
|
||||||
class="flex items-center cursor-pointer p-4 rounded-border text-surface-700 dark:text-surface-100 hover:bg-surface-100 dark:hover:bg-surface-700 duration-150 transition-colors p-ripple"
|
class="flex items-center cursor-pointer p-4 rounded-border text-surface-700 dark:text-surface-100 hover:bg-surface-100 dark:hover:bg-surface-700 duration-150 transition-colors p-ripple"
|
||||||
>
|
>
|
||||||
<i class="pi pi-home me-2"></i>
|
<i class="{{ menuItem.icon }} me-2"></i>
|
||||||
<span class="font-medium">فاکتورها</span>
|
<span class="font-medium">{{ menuItem.label }}</span>
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
pRipple
|
|
||||||
routerLink="/"
|
|
||||||
(click)="drawerRef.close($event)"
|
|
||||||
class="flex items-center cursor-pointer p-4 rounded-border text-surface-700 dark:text-surface-100 hover:bg-surface-100 dark:hover:bg-surface-700 duration-150 transition-colors p-ripple"
|
|
||||||
>
|
|
||||||
<i class="pi pi-home me-2"></i>
|
|
||||||
<span class="font-medium">فروش کالا</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
pRipple
|
|
||||||
routerLink="/about"
|
|
||||||
(click)="drawerRef.close($event)"
|
|
||||||
class="flex items-center cursor-pointer p-4 rounded-border text-surface-700 dark:text-surface-100 hover:bg-surface-100 dark:hover:bg-surface-700 duration-150 transition-colors p-ripple"
|
|
||||||
>
|
|
||||||
<i class="pi pi-home me-2"></i>
|
|
||||||
<span class="font-medium">دربارهی سیستم</span>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
pRipple
|
|
||||||
routerLink="/support"
|
|
||||||
(click)="drawerRef.close($event)"
|
|
||||||
class="flex items-center cursor-pointer p-4 rounded-border text-surface-700 dark:text-surface-100 hover:bg-surface-100 dark:hover:bg-surface-700 duration-150 transition-colors p-ripple"
|
|
||||||
>
|
|
||||||
<i class="pi pi-home me-2"></i>
|
|
||||||
<span class="font-medium">ارتباط با پشتیبانی</span>
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-auto">
|
<div class="mt-auto">
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ import { Button } from 'primeng/button';
|
|||||||
import { Drawer } from 'primeng/drawer';
|
import { Drawer } from 'primeng/drawer';
|
||||||
import { Ripple } from 'primeng/ripple';
|
import { Ripple } from 'primeng/ripple';
|
||||||
import { filter } from 'rxjs';
|
import { filter } from 'rxjs';
|
||||||
|
import config from 'src/config';
|
||||||
|
import { posAboutNamedRoutes } from '../../modules/about/constants';
|
||||||
|
import { posConfigNamedRoutes } from '../../modules/configs/constants';
|
||||||
|
import { posSaleInvoicesNamedRoutes } from '../../modules/saleInvoices/constants';
|
||||||
|
import { posSupportNamedRoutes } from '../../modules/support/constants';
|
||||||
import { PosInfoStore } from '../../store';
|
import { PosInfoStore } from '../../store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -31,9 +36,36 @@ export class PosMainMenuSidebarComponent extends AbstractDialog {
|
|||||||
return '';
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
readonly menuItems = [
|
||||||
|
{
|
||||||
|
label: 'فروش',
|
||||||
|
routerLink: config.isPosApplication ? '/' : '/pos',
|
||||||
|
icon: 'pi pi-fw pi-home',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'فاکتورها',
|
||||||
|
routerLink: posSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!(),
|
||||||
|
icon: 'pi pi-fw pi-receipt',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'تنظیمات',
|
||||||
|
routerLink: posConfigNamedRoutes.config.meta.pagePath!(),
|
||||||
|
icon: 'pi pi-fw pi-cog',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'درباره ما',
|
||||||
|
routerLink: posAboutNamedRoutes.about.meta.pagePath!(),
|
||||||
|
icon: 'pi pi-fw pi-info-circle',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'پشتیبانی',
|
||||||
|
routerLink: posSupportNamedRoutes.support.meta.pagePath!(),
|
||||||
|
icon: 'pi pi-fw pi-phone',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.isPwaBuild = this.swUpdate.isEnabled;
|
this.isPwaBuild = this.swUpdate.isEnabled;
|
||||||
console.log(this.swUpdate);
|
|
||||||
|
|
||||||
if (!this.isPwaBuild) return;
|
if (!this.isPwaBuild) return;
|
||||||
|
|
||||||
@@ -42,7 +74,6 @@ export class PosMainMenuSidebarComponent extends AbstractDialog {
|
|||||||
.then((data: { appData?: { appVersion?: string } }) => {
|
.then((data: { appData?: { appVersion?: string } }) => {
|
||||||
this.appVersion = data?.appData?.appVersion || this.appVersion;
|
this.appVersion = data?.appData?.appVersion || this.appVersion;
|
||||||
this.toastService.info({ text: this.appVersion });
|
this.toastService.info({ text: this.appVersion });
|
||||||
console.log('appVersion:', data?.appData);
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log('err', err);
|
console.log('err', err);
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import { UnitType } from '@/utils';
|
|||||||
export interface IGoodRawResponse {
|
export interface IGoodRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
sku: string;
|
sku: {
|
||||||
|
id: string;
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
category: ISummary;
|
category: ISummary;
|
||||||
unit_type: UnitType;
|
unit_type: UnitType;
|
||||||
pricing_model: string;
|
pricing_model: string;
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<form [formGroup]="form" (submit)="submit()">
|
||||||
|
<app-checkbox [control]="form.controls.business_name" name="business_name" label="نمایش عنوان کسبوکار" />
|
||||||
|
<app-checkbox [control]="form.controls.complex_name" name="complex_name" label="نمایش عنوان شعبه" />
|
||||||
|
<app-checkbox [control]="form.controls.pos_name" name="pos_name" label="نمایش عنوان پایانه فروش" />
|
||||||
|
<app-checkbox [control]="form.controls.invoice_template" name="invoice_template" label="نمایش الگوی صورتحساب" />
|
||||||
|
<app-checkbox [control]="form.controls.fiscal_id" name="fiscal_id" label="نمایش شماره منحصر به فرد مالیاتی" />
|
||||||
|
<app-checkbox [control]="form.controls.economic_code" name="economic_code" label="نمایش شماره اقتصادی" />
|
||||||
|
<app-checkbox [control]="form.controls.customer_name" name="customer_name" label="نمایش عنوان خریدار" />
|
||||||
|
<app-checkbox [control]="form.controls.customer_mobile" name="customer_mobile" label="نمایش شماره موبایل خریدار" />
|
||||||
|
<app-checkbox
|
||||||
|
[control]="form.controls.customer_national_id"
|
||||||
|
name="customer_national_id"
|
||||||
|
label="نمایش کد ملی خریدار"
|
||||||
|
/>
|
||||||
|
<app-checkbox
|
||||||
|
[control]="form.controls.customer_postal_code"
|
||||||
|
name="customer_postal_code"
|
||||||
|
label="نمایش کد پستی خریدار"
|
||||||
|
/>
|
||||||
|
<app-checkbox
|
||||||
|
[control]="form.controls.customer_economic_code"
|
||||||
|
name="customer_economic_code"
|
||||||
|
label="نمایش شناسهملی / اقتصادی خریدار"
|
||||||
|
/>
|
||||||
|
<app-checkbox [control]="form.controls.payment_type" name="payment_type" label="نمایش نوع پرداخت" />
|
||||||
|
<app-checkbox [control]="form.controls.show_payment_info" name="show_payment_info" label="نمایش جزییات پرداخت" />
|
||||||
|
<app-checkbox [control]="form.controls.show_items" name="show_items" label="نمایش کالاهای خریداری شده" />
|
||||||
|
|
||||||
|
<app-form-footer-actions (onSubmit)="submit()" (onCancel)="close()" />
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { AbstractForm } from '@/shared/abstractClasses';
|
||||||
|
import { AppCheckboxComponent } from '@/shared/components/checkbox/checkbox.component';
|
||||||
|
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { IPosConfigPrintRequestPayload, IPosConfigPrintResponse } from './models';
|
||||||
|
import { PosConfigPrintService } from './services/main.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pos-config-print-form',
|
||||||
|
templateUrl: 'form.component.html',
|
||||||
|
imports: [ReactiveFormsModule, AppCheckboxComponent, FormFooterActionsComponent],
|
||||||
|
})
|
||||||
|
export class PosConfigPrintFormComponent extends AbstractForm<
|
||||||
|
IPosConfigPrintRequestPayload,
|
||||||
|
IPosConfigPrintResponse
|
||||||
|
> {
|
||||||
|
private readonly service = inject(PosConfigPrintService);
|
||||||
|
|
||||||
|
initForm = () => {
|
||||||
|
const form = this.fb.group({
|
||||||
|
business_name: [true, []],
|
||||||
|
complex_name: [false],
|
||||||
|
pos_name: [false],
|
||||||
|
invoice_template: [false],
|
||||||
|
fiscal_id: [false],
|
||||||
|
economic_code: [false],
|
||||||
|
customer_name: [false],
|
||||||
|
customer_mobile: [false],
|
||||||
|
customer_national_id: [false],
|
||||||
|
customer_postal_code: [false],
|
||||||
|
customer_economic_code: [false],
|
||||||
|
payment_type: [false],
|
||||||
|
show_payment_info: [false],
|
||||||
|
show_items: [false],
|
||||||
|
});
|
||||||
|
|
||||||
|
return form;
|
||||||
|
};
|
||||||
|
|
||||||
|
form = this.initForm();
|
||||||
|
|
||||||
|
submitForm() {
|
||||||
|
const formValue = this.form.value as IPosConfigPrintRequestPayload;
|
||||||
|
return this.service.submit(formValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
export interface IPosConfigPrintResponse extends Partial<IPosConfigPrintRequestPayload> {}
|
||||||
|
|
||||||
|
export interface IPosConfigPrintRequestPayload {
|
||||||
|
business_name: boolean;
|
||||||
|
complex_name: boolean;
|
||||||
|
pos_name: boolean;
|
||||||
|
invoice_template: boolean;
|
||||||
|
fiscal_id: boolean;
|
||||||
|
economic_code: boolean;
|
||||||
|
customer_name: boolean;
|
||||||
|
customer_mobile: boolean;
|
||||||
|
customer_national_id: boolean;
|
||||||
|
customer_postal_code: boolean;
|
||||||
|
customer_economic_code: boolean;
|
||||||
|
payment_type: boolean;
|
||||||
|
show_payment_info: boolean;
|
||||||
|
show_items: boolean;
|
||||||
|
items: {
|
||||||
|
name: boolean;
|
||||||
|
sku: boolean;
|
||||||
|
quantity: boolean;
|
||||||
|
base_amount: boolean;
|
||||||
|
tax: boolean;
|
||||||
|
discount: boolean;
|
||||||
|
karat: boolean;
|
||||||
|
profit: boolean;
|
||||||
|
commission: boolean;
|
||||||
|
wage: boolean;
|
||||||
|
total_amount: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { LOCAL_STORAGE_KEYS } from 'src/assets/constants';
|
||||||
|
import { IPosConfigPrintRequestPayload, IPosConfigPrintResponse } from '../models';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class PosConfigPrintService {
|
||||||
|
get(): IPosConfigPrintResponse {
|
||||||
|
const data = window.localStorage.getItem(LOCAL_STORAGE_KEYS.POS_CONFIG_PRINT);
|
||||||
|
if (data) {
|
||||||
|
return JSON.parse(data) as IPosConfigPrintResponse;
|
||||||
|
}
|
||||||
|
const defaultData = {
|
||||||
|
business_name: true,
|
||||||
|
complex_name: true,
|
||||||
|
pos_name: true,
|
||||||
|
invoice_template: true,
|
||||||
|
fiscal_id: true,
|
||||||
|
economic_code: true,
|
||||||
|
customer_name: true,
|
||||||
|
customer_mobile: true,
|
||||||
|
customer_national_id: true,
|
||||||
|
customer_postal_code: true,
|
||||||
|
customer_economic_code: true,
|
||||||
|
payment_type: true,
|
||||||
|
show_payment_info: true,
|
||||||
|
show_items: false,
|
||||||
|
items: {
|
||||||
|
name: false,
|
||||||
|
sku: false,
|
||||||
|
quantity: false,
|
||||||
|
base_amount: false,
|
||||||
|
tax: false,
|
||||||
|
discount: false,
|
||||||
|
karat: false,
|
||||||
|
profit: false,
|
||||||
|
commission: false,
|
||||||
|
wage: false,
|
||||||
|
total_amount: false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
this.submit(defaultData);
|
||||||
|
return defaultData;
|
||||||
|
}
|
||||||
|
|
||||||
|
submit(data: IPosConfigPrintRequestPayload) {
|
||||||
|
window.localStorage.setItem(LOCAL_STORAGE_KEYS.POS_CONFIG_PRINT, JSON.stringify(data));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './routes/index';
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { NamedRoutes } from '@/core';
|
||||||
|
import { Routes } from '@angular/router';
|
||||||
|
import config from 'src/config';
|
||||||
|
|
||||||
|
export type TPosConfigRouteNames = 'config';
|
||||||
|
const baseRoute = `${config.isPosApplication ? '' : '/pos'}/config`;
|
||||||
|
|
||||||
|
export const posConfigNamedRoutes: NamedRoutes<TPosConfigRouteNames> = {
|
||||||
|
config: {
|
||||||
|
path: 'config',
|
||||||
|
loadComponent: () => import('../../views/root.component').then((m) => m.PosConfigPageComponent),
|
||||||
|
meta: {
|
||||||
|
title: 'تنظیمات',
|
||||||
|
pagePath: () => baseRoute,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const POS_CONFIG_ROUTES: Routes = [posConfigNamedRoutes.config];
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './root.component';
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<div class="w-full h-full flex items-center justify-center p-4">
|
||||||
|
<app-card-data cardTitle="تنظیمات فاکتور" class="w-full">
|
||||||
|
<p-message variant="text" severity="info" icon="pi pi-info-circle">
|
||||||
|
هریک از موارد زیر را که میخواهید در چاپ فاکتور نمایش داده شوند را انتخاب کنید
|
||||||
|
</p-message>
|
||||||
|
<pos-config-print-form class="block w-full mt-6" (onClose)="returnToMainPage()" (onSubmit)="returnToMainPage()" />
|
||||||
|
</app-card-data>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { AppCardComponent } from '@/shared/components';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { Message } from 'primeng/message';
|
||||||
|
import { PosConfigPrintFormComponent } from '../components/print/form.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pos-config-page',
|
||||||
|
templateUrl: './root.component.html',
|
||||||
|
imports: [PosConfigPrintFormComponent, AppCardComponent, Message],
|
||||||
|
})
|
||||||
|
export class PosConfigPageComponent {
|
||||||
|
private readonly router = inject(Router);
|
||||||
|
returnToMainPage() {
|
||||||
|
this.router.navigateByUrl('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<div class="w-full overflow-visible flex gap-3">
|
<div class="w-full overflow-visible flex gap-3 px-4">
|
||||||
@if (loading()) {
|
@if (loading()) {
|
||||||
@for (i of [1, 2, 3, 4, 5]; track i) {
|
@for (i of [1, 2, 3, 4, 5]; track i) {
|
||||||
<p-skeleton width="6rem" height="2.5rem" />
|
<p-skeleton width="6rem" height="2.5rem" />
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<div class="flex flex-col min-h-full">
|
<div class="flex flex-col min-h-full">
|
||||||
<div class="bg-surface-card z-10 p-4 border-b border-surface-border shadow-[0_-4px_16px_rgba(0,0,0,0.08)] rounded-xl">
|
<div
|
||||||
<div class="flex items-center justify-end mb-4">
|
class="bg-surface-card z-10 py-4 border-b border-surface-border shadow-[0_-4px_16px_rgba(0,0,0,0.08)] rounded-b-xl"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-end mb-4 px-4">
|
||||||
<!-- <div class="flex items-center gap-2 text-muted-color">
|
<!-- <div class="flex items-center gap-2 text-muted-color">
|
||||||
<i class="pi pi-list"></i>
|
<i class="pi pi-list"></i>
|
||||||
<span class="text-base font-bold">لیست کالاها</span>
|
<span class="text-base font-bold">لیست کالاها</span>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
}
|
}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-sm text-muted-color">
|
<span class="text-sm text-muted-color">
|
||||||
{{ good.sku }}
|
{{ good.sku.code }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+4
-2
@@ -54,7 +54,8 @@ export class PosOrderSubmittedDialogComponent extends AbstractDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
printInvoice() {
|
printInvoice() {
|
||||||
const printResult = this.nativeBridgeService.print({
|
const printResult = this.nativeBridgeService.print([
|
||||||
|
{
|
||||||
title: `فروشگاه ${this.posName()}`,
|
title: `فروشگاه ${this.posName()}`,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@@ -64,7 +65,8 @@ export class PosOrderSubmittedDialogComponent extends AbstractDialog {
|
|||||||
{ label: 'تاریخ', value: formatJalali(this.invoice.invoice_date, 'YYYY/MM/DD') },
|
{ label: 'تاریخ', value: formatJalali(this.invoice.invoice_date, 'YYYY/MM/DD') },
|
||||||
{ label: 'مبلغ کل', value: this.invoice.total_amount },
|
{ label: 'مبلغ کل', value: this.invoice.total_amount },
|
||||||
],
|
],
|
||||||
});
|
},
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToTsp() {}
|
sendToTsp() {}
|
||||||
|
|||||||
@@ -76,12 +76,16 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
this.updateCalculateAmount(value as any);
|
this.updateCalculateAmount(value as any);
|
||||||
});
|
});
|
||||||
|
|
||||||
form.controls.payload.controls.profit_amount.valueChanges.pipe(takeUntilDestroyed()).subscribe(() => {
|
form.controls.payload.controls.profit_amount.valueChanges
|
||||||
|
.pipe(takeUntilDestroyed())
|
||||||
|
.subscribe(() => {
|
||||||
// if ((form.controls.discount_amount.value || 0) > (value || 0)) {
|
// if ((form.controls.discount_amount.value || 0) > (value || 0)) {
|
||||||
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
form.controls.payload.controls.profit_percentage.valueChanges.pipe(takeUntilDestroyed()).subscribe(() => {
|
form.controls.payload.controls.profit_percentage.valueChanges
|
||||||
|
.pipe(takeUntilDestroyed())
|
||||||
|
.subscribe(() => {
|
||||||
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
form.controls.discount_amount.setValue(0, { emitEvent: false });
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,6 +94,13 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
|
|||||||
|
|
||||||
form = this.initialForm();
|
form = this.initialForm();
|
||||||
|
|
||||||
|
override ngAfterViewInit(): void {
|
||||||
|
if (this.editMode) {
|
||||||
|
this.form.patchValue(this.initialValues || {}, { emitEvent: false });
|
||||||
|
this.updateCalculateAmount(this.form.value as any);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override submitForm(payload: IPosOrderItem) {
|
override submitForm(payload: IPosOrderItem) {
|
||||||
this.onSubmit.emit({
|
this.onSubmit.emit({
|
||||||
...payload,
|
...payload,
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice()" [backRoute]="backRoute()" variant="pos" />
|
<shared-sale-invoice-single-view
|
||||||
|
[loading]="loading()"
|
||||||
|
[invoice]="invoice()"
|
||||||
|
[backRoute]="backRoute()"
|
||||||
|
variant="pos"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ConsumerSaleInvoiceSharedComponent } from '@/domains/consumer/components/invoices/shared-saleInvoice.component';
|
import { SharedSaleInvoiceSingleViewComponent } from '@/shared/components/invoices/sale-invoice-single-view.component';
|
||||||
import pageParamsUtils from '@/utils/page-params.utils';
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
@@ -8,7 +8,7 @@ import { PosSaleInvoiceStore } from '../store/main.store';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'pos-saleInvoice',
|
selector: 'pos-saleInvoice',
|
||||||
templateUrl: './single.component.html',
|
templateUrl: './single.component.html',
|
||||||
imports: [ConsumerSaleInvoiceSharedComponent],
|
imports: [SharedSaleInvoiceSingleViewComponent],
|
||||||
})
|
})
|
||||||
export class PosSaleInvoiceComponent {
|
export class PosSaleInvoiceComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Route } from '@angular/router';
|
import { Route } from '@angular/router';
|
||||||
import { POS_ABOUT_ROUTES } from './modules/about/constants';
|
import { POS_ABOUT_ROUTES } from './modules/about/constants';
|
||||||
|
import { POS_CONFIG_ROUTES } from './modules/configs/constants';
|
||||||
import { POS_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants';
|
import { POS_SALE_INVOICES_ROUTES } from './modules/saleInvoices/constants';
|
||||||
import { POS_SUPPORT_ROUTES } from './modules/support/constants';
|
import { POS_SUPPORT_ROUTES } from './modules/support/constants';
|
||||||
|
|
||||||
@@ -15,5 +16,6 @@ export const POS_ROUTES = {
|
|||||||
...POS_SALE_INVOICES_ROUTES,
|
...POS_SALE_INVOICES_ROUTES,
|
||||||
...POS_ABOUT_ROUTES,
|
...POS_ABOUT_ROUTES,
|
||||||
...POS_SUPPORT_ROUTES,
|
...POS_SUPPORT_ROUTES,
|
||||||
|
...POS_CONFIG_ROUTES,
|
||||||
],
|
],
|
||||||
} as Route;
|
} as Route;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { superAdminConsumerAccountListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { IConsumerAccountResponse } from '../../models';
|
import { IConsumerAccountResponse } from '../../models';
|
||||||
import { AdminConsumerAccountsService } from '../../services/accounts.service';
|
import { AdminConsumerAccountsService } from '../../services/accounts.service';
|
||||||
@@ -17,38 +18,7 @@ import { ConsumerAccountFormComponent } from './form.component';
|
|||||||
export class ConsumerAccountListComponent extends AbstractList<IConsumerAccountResponse> {
|
export class ConsumerAccountListComponent extends AbstractList<IConsumerAccountResponse> {
|
||||||
@Input({ required: true }) consumerId!: string;
|
@Input({ required: true }) consumerId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = superAdminConsumerAccountListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{
|
|
||||||
field: 'username',
|
|
||||||
header: 'نام کاربری',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'account.username' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'role',
|
|
||||||
header: 'نوع حساب',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'role.translate' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'pos',
|
|
||||||
header: 'پایانه مرتبط',
|
|
||||||
customDataModel: (item) =>
|
|
||||||
`${item.pos.name} (${item.pos.complex.name} - ${item.pos.complex.business_activity.name})`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
header: 'وضعیت',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'status.translate' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
private readonly service = inject(AdminConsumerAccountsService);
|
private readonly service = inject(AdminConsumerAccountsService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
|
|||||||
+2
-10
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { businessActivityListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
import { superAdminConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
||||||
@@ -19,16 +20,7 @@ import { ConsumerBusinessActivitiesFormComponent } from './form.component';
|
|||||||
export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessActivityResponse> {
|
export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessActivityResponse> {
|
||||||
@Input({ required: true }) consumerId!: string;
|
@Input({ required: true }) consumerId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = businessActivityListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'guild', header: 'صنف', type: 'nested', nestedOption: { path: 'guild.name' } },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(AdminConsumerBusinessActivitiesService);
|
private readonly service = inject(AdminConsumerBusinessActivitiesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { complexListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
import { superAdminConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
||||||
@@ -20,15 +21,7 @@ export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
|||||||
@Input() consumerId!: string;
|
@Input() consumerId!: string;
|
||||||
@Input() businessId!: string;
|
@Input() businessId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() header: IColumn[] = complexListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
private readonly service = inject(AdminComplexesService);
|
private readonly service = inject(AdminComplexesService);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
@@ -20,11 +20,7 @@ export class BusinessActivityStore extends EntityStore<
|
|||||||
private readonly service = inject(AdminConsumerBusinessActivitiesService);
|
private readonly service = inject(AdminConsumerBusinessActivitiesService);
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -71,11 +67,7 @@ export class BusinessActivityStore extends EntityStore<
|
|||||||
|
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
@@ -17,11 +17,7 @@ export class ComplexStore extends EntityStore<IComplexResponse, ComplexState> {
|
|||||||
private readonly service = inject(AdminComplexesService);
|
private readonly service = inject(AdminComplexesService);
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -71,11 +67,7 @@ export class ComplexStore extends EntityStore<IComplexResponse, ComplexState> {
|
|||||||
|
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
@@ -17,11 +17,7 @@ export class ConsumerStore extends EntityStore<IAdminConsumerResponse, ConsumerS
|
|||||||
private readonly service = inject(ConsumersService);
|
private readonly service = inject(ConsumersService);
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
import { computed, inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
import { MenuItem } from 'primeng/api';
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
@@ -17,11 +17,7 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
private readonly service = inject(AdminPosesService);
|
private readonly service = inject(AdminPosesService);
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -74,11 +70,7 @@ export class PosStore extends EntityStore<IPosResponse, PosState> {
|
|||||||
|
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
breadcrumbItems: [],
|
breadcrumbItems: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { consumerListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { ConsumerUserFormComponent } from '../components/form.component';
|
import { ConsumerUserFormComponent } from '../components/form.component';
|
||||||
@@ -18,41 +19,8 @@ export class ConsumersComponent extends AbstractList<IAdminConsumerResponse> {
|
|||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = consumerListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'نام' },
|
|
||||||
{ field: 'business_counts', header: 'تعداد فعالیت اقتصادی' },
|
|
||||||
{
|
|
||||||
field: 'partner',
|
|
||||||
header: 'ایجاد شده توسط',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'partner.name' },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
header: 'وضعیت',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'status.translate' },
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// field: 'license_expires_at',
|
|
||||||
// header: 'تاریخ انقضا لایسنس',
|
|
||||||
// customDataModel(item) {
|
|
||||||
// if (item.license_info) {
|
|
||||||
// return formatJalali(item.license_info.expires_at);
|
|
||||||
// }
|
|
||||||
// return 'بدون لایسنس';
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
return this.service.getAll();
|
return this.service.getAll();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { deviceBrandListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { DeviceBrandFormComponent } from '../components/form.component';
|
import { DeviceBrandFormComponent } from '../components/form.component';
|
||||||
import { IDeviceBrandResponse } from '../models';
|
import { IDeviceBrandResponse } from '../models';
|
||||||
@@ -15,15 +16,7 @@ export class DeviceBrandsComponent extends AbstractList<IDeviceBrandResponse> {
|
|||||||
private readonly service = inject(DeviceBrandsService);
|
private readonly service = inject(DeviceBrandsService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = deviceBrandListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { deviceListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { UserComplexFormComponent } from '../components/form.component';
|
import { UserComplexFormComponent } from '../components/form.component';
|
||||||
import { IDeviceResponse } from '../models';
|
import { IDeviceResponse } from '../models';
|
||||||
@@ -15,21 +16,7 @@ export class DevicesComponent extends AbstractList<IDeviceResponse> {
|
|||||||
private readonly service = inject(SuperAdminDeviceService);
|
private readonly service = inject(SuperAdminDeviceService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = deviceListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{
|
|
||||||
field: 'brand',
|
|
||||||
header: 'برند دستگاه',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'brand.name' },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
[fullHeight]="fullHeight"
|
[fullHeight]="fullHeight"
|
||||||
[showAdd]="true"
|
[showAdd]="true"
|
||||||
[showEdit]="true"
|
[showEdit]="true"
|
||||||
|
[showAll]="showAllBtn"
|
||||||
[allItemsPageRoute]="allItemsPageRoute()"
|
[allItemsPageRoute]="allItemsPageRoute()"
|
||||||
(onEdit)="onEditClick($event)"
|
(onEdit)="onEditClick($event)"
|
||||||
(onAdd)="openAddForm()"
|
(onAdd)="openAddForm()"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { categoryListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, computed, inject, Input } from '@angular/core';
|
import { Component, computed, inject, Input } from '@angular/core';
|
||||||
import { guildGoodCategoriesNamedRoutes } from '../../constants/routes/goodCategories';
|
import { guildGoodCategoriesNamedRoutes } from '../../constants/routes/goodCategories';
|
||||||
import { IGoodCategoriesResponse } from '../../models';
|
import { IGoodCategoriesResponse } from '../../models';
|
||||||
@@ -18,16 +19,10 @@ import { GuildGoodCategoryFormComponent } from './form.component';
|
|||||||
export class GuildGoodCategoriesListComponent extends AbstractList<IGoodCategoriesResponse> {
|
export class GuildGoodCategoriesListComponent extends AbstractList<IGoodCategoriesResponse> {
|
||||||
@Input() guildId!: string;
|
@Input() guildId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() showAllBtn?: boolean;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
@Input() header: IColumn[] = categoryListConfig.columns;
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'goods_count', header: 'تعداد کالاها' },
|
listConfig = categoryListConfig;
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
service = inject(GuildGoodCategoriesService);
|
service = inject(GuildGoodCategoriesService);
|
||||||
|
|
||||||
allItemsPageRoute = computed(() =>
|
allItemsPageRoute = computed(() =>
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
pageTitle="مدیریت کالاها"
|
pageTitle="مدیریت کالاها"
|
||||||
[addNewCtaLabel]="'افزودن کالا'"
|
[addNewCtaLabel]="'افزودن کالا'"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
[showAdd]="true"
|
|
||||||
emptyPlaceholderTitle="کالایی یافت نشد"
|
emptyPlaceholderTitle="کالایی یافت نشد"
|
||||||
emptyPlaceholderDescription="برای افزودن کالای، روی دکمهٔ بالا کلیک کنید."
|
emptyPlaceholderDescription="برای افزودن کالای، روی دکمهٔ بالا کلیک کنید."
|
||||||
[items]="items()"
|
[items]="items()"
|
||||||
[loading]="loading()"
|
[loading]="loading()"
|
||||||
[showAdd]="true"
|
[showAdd]="true"
|
||||||
[showEdit]="true"
|
[showEdit]="true"
|
||||||
|
[showAll]="showAllBtn"
|
||||||
|
[allItemsPageRoute]="showAllPageRoute()"
|
||||||
[fullHeight]="fullHeight"
|
[fullHeight]="fullHeight"
|
||||||
(onEdit)="onEditClick($event)"
|
(onEdit)="onEditClick($event)"
|
||||||
(onAdd)="openAddForm()"
|
(onAdd)="openAddForm()"
|
||||||
|
|||||||
@@ -4,7 +4,9 @@ import {
|
|||||||
IColumn,
|
IColumn,
|
||||||
PageDataListComponent,
|
PageDataListComponent,
|
||||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { goodListConfig } from '@/shared/constants/list-configs';
|
||||||
|
import { Component, computed, inject, Input } from '@angular/core';
|
||||||
|
import { guildGoodsNamedRoutes } from '../../constants/routes/goods';
|
||||||
import { IGuildGoodsResponse } from '../../models';
|
import { IGuildGoodsResponse } from '../../models';
|
||||||
import { GuildGoodsService } from '../../services/goods.service';
|
import { GuildGoodsService } from '../../services/goods.service';
|
||||||
import { GuildGoodFormComponent } from './form.component';
|
import { GuildGoodFormComponent } from './form.component';
|
||||||
@@ -17,19 +19,14 @@ import { GuildGoodFormComponent } from './form.component';
|
|||||||
export class GuildGoodsListComponent extends AbstractList<IGuildGoodsResponse> {
|
export class GuildGoodsListComponent extends AbstractList<IGuildGoodsResponse> {
|
||||||
@Input() guildId!: string;
|
@Input() guildId!: string;
|
||||||
@Input() fullHeight?: boolean;
|
@Input() fullHeight?: boolean;
|
||||||
@Input() header: IColumn[] = [
|
@Input() showAllBtn?: boolean;
|
||||||
{ field: 'image_url', header: 'تصویر', type: 'thumbnail' },
|
@Input() header: IColumn[] = goodListConfig.columns;
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'sku', header: 'شناسه کالا', type: 'nested', nestedOption: { path: 'sku.name' } },
|
listConfig = goodListConfig;
|
||||||
{
|
|
||||||
field: 'category',
|
|
||||||
header: 'دستهبندی',
|
|
||||||
type: 'nested',
|
|
||||||
nestedOption: { path: 'category.name' },
|
|
||||||
},
|
|
||||||
];
|
|
||||||
service = inject(GuildGoodsService);
|
service = inject(GuildGoodsService);
|
||||||
|
|
||||||
|
showAllPageRoute = computed(() => guildGoodsNamedRoutes.goods.meta.pagePath!(this.guildId));
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = this.header;
|
this.columns = this.header;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
<app-page-data-list
|
||||||
|
[pageTitle]="'مدیریت شناسه کالاها'"
|
||||||
|
[addNewCtaLabel]="'افزودن شناسه'"
|
||||||
|
[columns]="columns"
|
||||||
|
emptyPlaceholderTitle="شناسهای یافت نشد"
|
||||||
|
emptyPlaceholderDescription="برای افزودن شناسه، روی دکمهٔ بالا کلیک کنید."
|
||||||
|
[items]="items()"
|
||||||
|
[loading]="loading()"
|
||||||
|
[fullHeight]="fullHeight"
|
||||||
|
[showAdd]="true"
|
||||||
|
[showEdit]="true"
|
||||||
|
[allItemsPageRoute]="allItemsPageRoute()"
|
||||||
|
(onEdit)="onEditClick($event)"
|
||||||
|
(onAdd)="openAddForm()"
|
||||||
|
(onRefresh)="refresh()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<stock-keeping-unit-form
|
||||||
|
[(visible)]="visibleForm"
|
||||||
|
[initialValues]="selectedItemForEdit() || undefined"
|
||||||
|
[guildId]="guildId"
|
||||||
|
[editMode]="editMode()"
|
||||||
|
(onSubmit)="refresh()"
|
||||||
|
/>
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
|
import {
|
||||||
|
IColumn,
|
||||||
|
PageDataListComponent,
|
||||||
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { skuListConfig } from '@/shared/constants/list-configs';
|
||||||
|
import { Component, computed, inject, Input } from '@angular/core';
|
||||||
|
import { stockKeepingUnitsNamedRoutes } from '../../constants/routes/stockKeepingUnits';
|
||||||
|
import { IStockKeepingUnitResponse } from '../../models';
|
||||||
|
import { StockKeepingUnitsService } from '../../services/stockKeepingUnits.service';
|
||||||
|
import { StockKeepingUnitFormComponent } from './form.component';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'admin-guild-stock-keeping-units-list',
|
||||||
|
templateUrl: './list.component.html',
|
||||||
|
imports: [PageDataListComponent, StockKeepingUnitFormComponent],
|
||||||
|
})
|
||||||
|
export class GuildStockKeepingUnitsListComponent extends AbstractList<IStockKeepingUnitResponse> {
|
||||||
|
@Input() guildId!: string;
|
||||||
|
@Input() fullHeight?: boolean;
|
||||||
|
@Input() header: IColumn[] = skuListConfig.columns;
|
||||||
|
|
||||||
|
listConfig = skuListConfig;
|
||||||
|
service = inject(StockKeepingUnitsService);
|
||||||
|
|
||||||
|
allItemsPageRoute = computed(() =>
|
||||||
|
stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.pagePath!(this.guildId),
|
||||||
|
);
|
||||||
|
|
||||||
|
override setColumns(): void {
|
||||||
|
this.columns = this.header;
|
||||||
|
}
|
||||||
|
|
||||||
|
override getDataRequest() {
|
||||||
|
return this.service.getAll(this.guildId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ export const guildGoodsNamedRoutes: NamedRoutes<TGuildGoodsRouteNames> = {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
meta: {
|
meta: {
|
||||||
title: 'کالاها',
|
title: 'کالاها',
|
||||||
|
pagePath: (guildId: string) => `/super_admin/guilds/${guildId}/goods`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// goodCategory: {
|
// goodCategory: {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export const stockKeepingUnitsNamedRoutes: NamedRoutes<TStockKeepingUnitsRouteNa
|
|||||||
path: 'stock-keeping-units',
|
path: 'stock-keeping-units',
|
||||||
loadComponent: () =>
|
loadComponent: () =>
|
||||||
import('../../views/stockKeepingUnits/list.component').then(
|
import('../../views/stockKeepingUnits/list.component').then(
|
||||||
(m) => m.StockKeepingUnitsComponent,
|
(m) => m.GuildStockKeepingUnitsComponent,
|
||||||
),
|
),
|
||||||
meta: {
|
meta: {
|
||||||
title: 'شناسه کالاها',
|
title: 'شناسه کالاها',
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import { EntityState, EntityStore } from '@/core/state';
|
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
|
||||||
import { inject, Injectable } from '@angular/core';
|
import { computed, inject, Injectable } from '@angular/core';
|
||||||
|
import { MenuItem } from 'primeng/api';
|
||||||
import { catchError, finalize } from 'rxjs';
|
import { catchError, finalize } from 'rxjs';
|
||||||
|
import { guildsNamedRoutes } from '../constants';
|
||||||
import { IGuildResponse } from '../models';
|
import { IGuildResponse } from '../models';
|
||||||
import { GuildsService } from '../services/main.service';
|
import { GuildsService } from '../services/main.service';
|
||||||
|
|
||||||
interface GuildState extends EntityState<IGuildResponse> {}
|
interface GuildState extends EntityState<IGuildResponse> {
|
||||||
|
breadcrumbItems: MenuItem[];
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -13,11 +17,25 @@ export class GuildStore extends EntityStore<IGuildResponse, GuildState> {
|
|||||||
private readonly service = inject(GuildsService);
|
private readonly service = inject(GuildsService);
|
||||||
constructor() {
|
constructor() {
|
||||||
super({
|
super({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
breadcrumbItems: [],
|
||||||
entity: null,
|
});
|
||||||
initialized: false,
|
}
|
||||||
isRefreshing: false,
|
|
||||||
|
breadcrumbItems = computed(() => this._state().breadcrumbItems);
|
||||||
|
|
||||||
|
private setBreadcrumb(guildId: string) {
|
||||||
|
this.patchState({
|
||||||
|
breadcrumbItems: [
|
||||||
|
{
|
||||||
|
...guildsNamedRoutes.guilds.meta,
|
||||||
|
routerLink: guildsNamedRoutes.guilds.meta.pagePath!(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: this.entity()?.name,
|
||||||
|
routerLink: guildsNamedRoutes.guild.meta.pagePath!(guildId),
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,16 +54,14 @@ export class GuildStore extends EntityStore<IGuildResponse, GuildState> {
|
|||||||
)
|
)
|
||||||
.subscribe((entity) => {
|
.subscribe((entity) => {
|
||||||
this.patchState({ entity });
|
this.patchState({ entity });
|
||||||
|
this.setBreadcrumb(guildId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
override reset(): void {
|
override reset(): void {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
...defaultBaseStateData,
|
||||||
error: null,
|
breadcrumbItems: [],
|
||||||
entity: null,
|
|
||||||
initialized: false,
|
|
||||||
isRefreshing: false,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { Component, inject, signal } from '@angular/core';
|
import { BreadcrumbService } from '@/core/services';
|
||||||
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { GuildGoodCategoriesListComponent } from '../../components/categories/list.component';
|
import { GuildGoodCategoriesListComponent } from '../../components/categories/list.component';
|
||||||
|
import { guildGoodCategoriesNamedRoutes } from '../../constants/routes/goodCategories';
|
||||||
|
import { GuildStore } from '../../store/guild.store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'admin-guild-good-categories',
|
selector: 'admin-guild-good-categories',
|
||||||
@@ -10,6 +14,22 @@ import { GuildGoodCategoriesListComponent } from '../../components/categories/li
|
|||||||
})
|
})
|
||||||
export class GuildGoodCategoriesComponent {
|
export class GuildGoodCategoriesComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
private readonly breadcrumbService = inject(BreadcrumbService);
|
||||||
|
private readonly store = inject(GuildStore);
|
||||||
|
|
||||||
readonly guildId = signal<string>(this.route.snapshot.paramMap.get('guildId')!);
|
pageParams = computed(() => pageParamsUtils(this.route));
|
||||||
|
readonly guildId = signal<string>(this.pageParams()['guildId']!);
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.setBreadcrumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
setBreadcrumb() {
|
||||||
|
this.breadcrumbService.setItems([
|
||||||
|
...this.store.breadcrumbItems(),
|
||||||
|
{
|
||||||
|
title: guildGoodCategoriesNamedRoutes.goodCategories.meta.title,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,35 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { Component, inject, signal } from '@angular/core';
|
import { BreadcrumbService } from '@/core/services';
|
||||||
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { GuildGoodsListComponent } from '../../components/goods/list.component';
|
import { GuildGoodsListComponent } from '../../components/goods/list.component';
|
||||||
|
import { guildGoodsNamedRoutes } from '../../constants/routes/goods';
|
||||||
|
import { GuildStore } from '../../store/guild.store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'admin-guild_goods',
|
selector: 'admin-guild-goods',
|
||||||
templateUrl: './list.component.html',
|
templateUrl: './list.component.html',
|
||||||
imports: [GuildGoodsListComponent],
|
imports: [GuildGoodsListComponent],
|
||||||
})
|
})
|
||||||
export class GuildGoodsComponent {
|
export class GuildGoodsComponent {
|
||||||
route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
guildId = signal<string>(this.route.snapshot.paramMap.get('guildId')!);
|
private readonly breadcrumbService = inject(BreadcrumbService);
|
||||||
|
private readonly store = inject(GuildStore);
|
||||||
|
|
||||||
|
pageParams = computed(() => pageParamsUtils(this.route));
|
||||||
|
readonly guildId = signal<string>(this.pageParams()['guildId']!);
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.setBreadcrumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
setBreadcrumb() {
|
||||||
|
this.breadcrumbService.setItems([
|
||||||
|
...this.store.breadcrumbItems(),
|
||||||
|
{
|
||||||
|
title: guildGoodsNamedRoutes.goods.meta.title,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export class GuildsComponent extends AbstractList<IGuildResponse> {
|
|||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = [
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
{ field: 'name', header: 'عنوان' },
|
||||||
{ field: 'code', header: 'کد' },
|
{ field: 'code', header: 'کد' },
|
||||||
{ field: 'businessActivitiesCount', header: 'تعداد فعالیتهای اقتصادی مرتبط' },
|
{ field: 'businessActivitiesCount', header: 'تعداد فعالیتهای اقتصادی مرتبط' },
|
||||||
|
|||||||
@@ -9,10 +9,13 @@
|
|||||||
</app-card-data>
|
</app-card-data>
|
||||||
|
|
||||||
<div class="max-h-125 flex">
|
<div class="max-h-125 flex">
|
||||||
<admin-guild-good-categories-list [guildId]="guildId()" class="w-full" />
|
<admin-guild-good-categories-list [guildId]="guildId()" [showAllBtn]="true" class="w-full" />
|
||||||
</div>
|
</div>
|
||||||
<div class="max-h-125 flex">
|
<div class="max-h-125 flex">
|
||||||
<admin-guild-goods-list [guildId]="guildId()" class="w-full" />
|
<admin-guild-goods-list [guildId]="guildId()" [showAllBtn]="true" class="w-full" />
|
||||||
|
</div>
|
||||||
|
<div class="max-h-125 flex">
|
||||||
|
<admin-guild-stock-keeping-units-list [guildId]="guildId()" class="w-full" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<admin-guild-form
|
<admin-guild-form
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
import { BreadcrumbService } from '@/core/services';
|
||||||
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { GuildGoodCategoriesListComponent } from '../components/categories/list.component';
|
import { GuildGoodCategoriesListComponent } from '../components/categories/list.component';
|
||||||
import { GuildFormComponent } from '../components/form.component';
|
import { GuildFormComponent } from '../components/form.component';
|
||||||
import { GuildGoodsListComponent } from '../components/goods/list.component';
|
import { GuildGoodsListComponent } from '../components/goods/list.component';
|
||||||
|
import { GuildStockKeepingUnitsListComponent } from '../components/stockKeepingUnits/list.component';
|
||||||
import { GuildStore } from '../store/guild.store';
|
import { GuildStore } from '../store/guild.store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -14,11 +16,13 @@ import { GuildStore } from '../store/guild.store';
|
|||||||
KeyValueComponent,
|
KeyValueComponent,
|
||||||
GuildGoodCategoriesListComponent,
|
GuildGoodCategoriesListComponent,
|
||||||
GuildGoodsListComponent,
|
GuildGoodsListComponent,
|
||||||
|
GuildStockKeepingUnitsListComponent,
|
||||||
GuildFormComponent,
|
GuildFormComponent,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class GuildComponent {
|
export class GuildComponent {
|
||||||
private readonly store = inject(GuildStore);
|
private readonly store = inject(GuildStore);
|
||||||
|
private readonly breadcrumbService = inject(BreadcrumbService);
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
|
||||||
readonly guildId = signal<string>(this.route.snapshot.paramMap.get('guildId')!);
|
readonly guildId = signal<string>(this.route.snapshot.paramMap.get('guildId')!);
|
||||||
@@ -30,4 +34,12 @@ export class GuildComponent {
|
|||||||
getData() {
|
getData() {
|
||||||
this.store.getData(this.guildId());
|
this.store.getData(this.guildId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.setBreadcrumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
setBreadcrumb() {
|
||||||
|
this.breadcrumbService.setItems([...this.store.breadcrumbItems()]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-22
@@ -1,22 +1 @@
|
|||||||
<app-page-data-list
|
<admin-guild-stock-keeping-units-list [guildId]="guildId()" class="w-full" />
|
||||||
[pageTitle]="'مدیریت شناسه کالاها'"
|
|
||||||
[addNewCtaLabel]="'افزودن شناسه کالا'"
|
|
||||||
[columns]="columns"
|
|
||||||
emptyPlaceholderTitle="شناسه کالایی یافت نشد"
|
|
||||||
emptyPlaceholderDescription="برای افزودن شناسه کالا، روی دکمهٔ بالا کلیک کنید."
|
|
||||||
[items]="items()"
|
|
||||||
[loading]="loading()"
|
|
||||||
[showDetails]="false"
|
|
||||||
[showAdd]="true"
|
|
||||||
(onAdd)="openAddForm()"
|
|
||||||
(onRefresh)="refresh()"
|
|
||||||
>
|
|
||||||
</app-page-data-list>
|
|
||||||
<stock-keeping-unit-form
|
|
||||||
[guildId]="guildId()"
|
|
||||||
[(visible)]="visibleForm"
|
|
||||||
[initialValues]="selectedItemForEdit()!"
|
|
||||||
[editMode]="false"
|
|
||||||
[stockKeepingUnitId]="selectedItemForEdit()?.id"
|
|
||||||
(onSubmit)="refresh()"
|
|
||||||
/>
|
|
||||||
|
|||||||
+20
-18
@@ -1,33 +1,35 @@
|
|||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { BreadcrumbService } from '@/core/services';
|
||||||
import pageParamsUtils from '@/utils/page-params.utils';
|
import pageParamsUtils from '@/utils/page-params.utils';
|
||||||
import { Component, computed, inject, signal } from '@angular/core';
|
import { Component, computed, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { StockKeepingUnitFormComponent } from '../../components/stockKeepingUnits/form.component';
|
import { GuildStockKeepingUnitsListComponent } from '../../components/stockKeepingUnits/list.component';
|
||||||
import { IStockKeepingUnitResponse } from '../../models';
|
import { stockKeepingUnitsNamedRoutes } from '../../constants/routes/stockKeepingUnits';
|
||||||
import { StockKeepingUnitsService } from '../../services/stockKeepingUnits.service';
|
import { GuildStore } from '../../store/guild.store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'superAdmin-stockKeepingUnits',
|
selector: 'admin-guild-stock-keeping-units',
|
||||||
templateUrl: './list.component.html',
|
templateUrl: './list.component.html',
|
||||||
imports: [PageDataListComponent, StockKeepingUnitFormComponent],
|
imports: [GuildStockKeepingUnitsListComponent],
|
||||||
})
|
})
|
||||||
export class StockKeepingUnitsComponent extends AbstractList<IStockKeepingUnitResponse> {
|
export class GuildStockKeepingUnitsComponent {
|
||||||
private readonly route = inject(ActivatedRoute);
|
private readonly route = inject(ActivatedRoute);
|
||||||
|
private readonly breadcrumbService = inject(BreadcrumbService);
|
||||||
|
private readonly store = inject(GuildStore);
|
||||||
|
|
||||||
pageParams = computed(() => pageParamsUtils(this.route));
|
pageParams = computed(() => pageParamsUtils(this.route));
|
||||||
readonly guildId = signal<string>(this.pageParams()['guildId']!);
|
readonly guildId = signal<string>(this.pageParams()['guildId']!);
|
||||||
|
|
||||||
private readonly service = inject(StockKeepingUnitsService);
|
ngOnInit() {
|
||||||
|
this.setBreadcrumb();
|
||||||
override setColumns(): void {
|
|
||||||
this.columns = [
|
|
||||||
{ field: 'code', header: 'کد' },
|
|
||||||
{ field: 'name', header: 'عنوان' },
|
|
||||||
{ field: 'VAT', header: 'مالیات ارزش افزوده' },
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
setBreadcrumb() {
|
||||||
return this.service.getAll(this.guildId());
|
this.breadcrumbService.setItems([
|
||||||
|
...this.store.breadcrumbItems(),
|
||||||
|
{
|
||||||
|
title: stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.title,
|
||||||
|
},
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { licenseListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { ILicenseRawResponse, ILicenseResponse } from '../models';
|
import { ILicenseResponse } from '../models';
|
||||||
import { LicensesService } from '../services/main.service';
|
import { LicensesService } from '../services/main.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -14,24 +15,7 @@ export class LicensesComponent extends AbstractList<ILicenseResponse> {
|
|||||||
private readonly service = inject(LicensesService);
|
private readonly service = inject(LicensesService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = licenseListConfig.columns;
|
||||||
{
|
|
||||||
field: 'consumer',
|
|
||||||
header: 'مشتری',
|
|
||||||
customDataModel(item) {
|
|
||||||
return `${item.consumer.first_name} ${item.consumer.last_name}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'partner',
|
|
||||||
header: 'ارایه شده توسط',
|
|
||||||
customDataModel(item: ILicenseRawResponse) {
|
|
||||||
return item.license.charged_license_transaction.partner.name || 'برند نرمافزار';
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ field: 'expires_at', header: 'تاریخ انقضا', type: 'date' },
|
|
||||||
{ field: 'created_at', header: 'تاریخ ایجاد', type: 'date' },
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { partnerListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject, TemplateRef, ViewChild } from '@angular/core';
|
import { Component, inject, TemplateRef, ViewChild } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Avatar } from 'primeng/avatar';
|
import { Avatar } from 'primeng/avatar';
|
||||||
@@ -24,30 +25,15 @@ export class PartnersComponent extends AbstractList<IPartnerResponse> {
|
|||||||
@ViewChild('licensesRenewStatus', { static: true }) licensesRenewStatus!: TemplateRef<any>;
|
@ViewChild('licensesRenewStatus', { static: true }) licensesRenewStatus!: TemplateRef<any>;
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = partnerListConfig.columns.map((col) => {
|
||||||
{ field: 'name', header: 'عنوان', customDataModel: this.name },
|
if (col.field === 'name') return { ...col, customDataModel: this.name };
|
||||||
{ field: 'code', header: 'کد' },
|
if (col.field === 'licenses') return { ...col, customDataModel: this.licensesStatus };
|
||||||
{ field: 'licenses', header: 'تعداد لایسنسها', customDataModel: this.licensesStatus },
|
if (col.field === 'account_quota')
|
||||||
{
|
return { ...col, customDataModel: this.accountQuotaStatus };
|
||||||
field: 'account_quota',
|
if (col.field === 'license_renew')
|
||||||
header: 'تعداد کاربرهای خریداری شده',
|
return { ...col, customDataModel: this.licensesRenewStatus };
|
||||||
customDataModel: this.accountQuotaStatus,
|
return col;
|
||||||
},
|
});
|
||||||
{
|
|
||||||
field: 'license_renew',
|
|
||||||
header: 'تعداد لایسنس تمدیدی',
|
|
||||||
customDataModel: this.licensesRenewStatus,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
field: 'status',
|
|
||||||
header: 'وضعیت',
|
|
||||||
type: 'nested',
|
|
||||||
variant: 'tag',
|
|
||||||
nestedOption: {
|
|
||||||
path: 'status.translate',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { providerListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { ProviderFormComponent } from '../components/form.component';
|
import { ProviderFormComponent } from '../components/form.component';
|
||||||
import { IProviderResponse } from '../models';
|
import { IProviderResponse } from '../models';
|
||||||
@@ -15,15 +16,7 @@ export class ProvidersComponent extends AbstractList<IProviderResponse> {
|
|||||||
private readonly service = inject(ProvidersService);
|
private readonly service = inject(ProvidersService);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = providerListConfig.columns;
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
|
||||||
{ field: 'name', header: 'نام' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { userListConfig } from '@/shared/constants/list-configs';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { UserAccountFormComponent } from '../components/form.component';
|
import { UserAccountFormComponent } from '../components/form.component';
|
||||||
@@ -18,16 +19,7 @@ export class UsersComponent extends AbstractList<IUserResponse> {
|
|||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
|
||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = userListConfig.columns;
|
||||||
{ field: 'fullname', header: 'نام' },
|
|
||||||
{ field: 'mobile_number', header: 'شماره موبایل' },
|
|
||||||
{ field: 'national_code', header: 'کد ملی' },
|
|
||||||
{
|
|
||||||
field: 'created_at',
|
|
||||||
header: 'تاریخ ایجاد',
|
|
||||||
type: 'date',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override getDataRequest() {
|
override getDataRequest() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export abstract class AbstractForm<
|
|||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngAfterViewInit() {
|
||||||
this.form.reset(this.initialValues ?? this.defaultValues);
|
this.form.reset(this.initialValues ?? this.defaultValues);
|
||||||
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
// Object.entries(this.form.controls).forEach(([key, control]) => {
|
||||||
// console.log(key, control);
|
// console.log(key, control);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable, shareReplay } from 'rxjs';
|
||||||
import { ENUMS_API_ROUTES } from './constants/apiRoutes';
|
import { ENUMS_API_ROUTES } from './constants/apiRoutes';
|
||||||
import { TEnumApi } from './models';
|
import { TEnumApi } from './models';
|
||||||
import { IApiEnumResponse } from './models/io';
|
import { IApiEnumResponse } from './models/io';
|
||||||
@@ -10,8 +10,19 @@ export class EnumsService {
|
|||||||
constructor(private http: HttpClient) {}
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
private apiRoutes = ENUMS_API_ROUTES;
|
private apiRoutes = ENUMS_API_ROUTES;
|
||||||
|
private readonly cache = new Map<TEnumApi, Observable<IApiEnumResponse[]>>();
|
||||||
|
|
||||||
getAll(type: TEnumApi): Observable<IApiEnumResponse[]> {
|
getAll(type: TEnumApi): Observable<IApiEnumResponse[]> {
|
||||||
return this.http.get<IApiEnumResponse[]>(this.apiRoutes[type]);
|
const cached = this.cache.get(type);
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
const request$ = this.http
|
||||||
|
.get<IApiEnumResponse[]>(this.apiRoutes[type])
|
||||||
|
.pipe(shareReplay({ bufferSize: 1, refCount: true }));
|
||||||
|
|
||||||
|
this.cache.set(type, request$);
|
||||||
|
return request$;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -4,6 +4,7 @@ import { UikitFieldComponent, UikitLabelComponent } from '@/uikit';
|
|||||||
import { formatWithCurrency } from '@/utils';
|
import { formatWithCurrency } from '@/utils';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import {
|
import {
|
||||||
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
ContentChild,
|
ContentChild,
|
||||||
DestroyRef,
|
DestroyRef,
|
||||||
@@ -31,6 +32,7 @@ interface IAmountPercentageInputSelect {
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-amount-percentage-input',
|
selector: 'app-amount-percentage-input',
|
||||||
templateUrl: './amount-percentage-input.component.html',
|
templateUrl: './amount-percentage-input.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
imports: [
|
imports: [
|
||||||
UikitFieldComponent,
|
UikitFieldComponent,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
@@ -175,10 +177,10 @@ export class AmountPercentageInputComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const isPercentageType = this.selectedType.value === 'percentage';
|
const amountValue = Number(this.amountControl.value || 0);
|
||||||
this.modifyControlsData(
|
const percentageValue = Number(this.percentageControl.value || 0);
|
||||||
isPercentageType ? this.percentageControl.value : this.amountControl.value,
|
const isPercentageType = percentageValue > 0 && amountValue <= 0;
|
||||||
);
|
this.preparedLabel.set(this.prepareLabel(isPercentageType));
|
||||||
|
|
||||||
this.selectedType.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
this.selectedType.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((value) => {
|
||||||
this.preparedLabel.set(this.prepareLabel(value === 'percentage'));
|
this.preparedLabel.set(this.prepareLabel(value === 'percentage'));
|
||||||
@@ -186,9 +188,9 @@ export class AmountPercentageInputComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges() {
|
||||||
const isPercentageType = this.selectedType.value === 'percentage';
|
const amountValue = Number(this.amountControl.value || 0);
|
||||||
this.modifyControlsData(
|
const percentageValue = Number(this.percentageControl.value || 0);
|
||||||
isPercentageType ? this.percentageControl.value : this.amountControl.value,
|
const isPercentageType = percentageValue > 0 && amountValue <= 0;
|
||||||
);
|
this.preparedLabel.set(this.prepareLabel(isPercentageType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<p-checkBox [formControl]="control" [name]="name" [id]="name" binary class="shrink-0"> </p-checkBox>
|
||||||
|
<uikit-label [name]="name"> {{ label }} </uikit-label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (hint) {
|
||||||
|
<small [attr.id]="name + '-help'" class="text-muted-color">{{ hint }}</small>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Maybe } from '@/core';
|
||||||
|
import { UikitLabelComponent } from '@/uikit';
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
import { FormControl } from '@angular/forms';
|
||||||
|
import { Checkbox } from 'primeng/checkbox';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-checkbox',
|
||||||
|
templateUrl: 'checkbox.component.html',
|
||||||
|
imports: [Checkbox, UikitLabelComponent],
|
||||||
|
})
|
||||||
|
export class AppCheckboxComponent {
|
||||||
|
@Input({ required: true }) control!: FormControl<Maybe<any>>;
|
||||||
|
@Input({ required: true }) name!: string;
|
||||||
|
@Input({ required: true }) label!: string;
|
||||||
|
@Input() disabled = false;
|
||||||
|
@Input() size?: 'small' | 'large';
|
||||||
|
@Input() showErrors = true;
|
||||||
|
@Input() hint?: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import ISummary from '@/core/models/summary';
|
||||||
|
import { TspProviderResponseStatus } from '@/shared/catalog';
|
||||||
|
import { IEnumTranslate } from '@/shared/models/enum_translate.type';
|
||||||
|
|
||||||
|
export interface ISaleInvoiceFullRawResponse {
|
||||||
|
id: string;
|
||||||
|
code: string;
|
||||||
|
total_amount: string;
|
||||||
|
invoice_date: string;
|
||||||
|
consumer_account: ConsumerAccount;
|
||||||
|
pos: Pos;
|
||||||
|
payments: Payment[];
|
||||||
|
items: Item[];
|
||||||
|
created_at: string;
|
||||||
|
notes?: string;
|
||||||
|
customer?: Customer;
|
||||||
|
unknown_customer?: UnknownCustomer;
|
||||||
|
status: IEnumTranslate<TspProviderResponseStatus>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISaleInvoiceFullResponse extends ISaleInvoiceFullRawResponse {}
|
||||||
|
|
||||||
|
interface Item {
|
||||||
|
id: string;
|
||||||
|
good: ISummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Payment {
|
||||||
|
amount: string;
|
||||||
|
payment_method: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Customer {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
legal?: CustomerLegal;
|
||||||
|
individual?: CustomerIndividual;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CustomerIndividual {
|
||||||
|
first_name: string;
|
||||||
|
last_name: string;
|
||||||
|
national_id: string;
|
||||||
|
postal_code: string;
|
||||||
|
economic_code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CustomerLegal {
|
||||||
|
company_name: string;
|
||||||
|
registration_number: string;
|
||||||
|
postal_code: string;
|
||||||
|
economic_code: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Pos extends ISummary {
|
||||||
|
complex: Complex;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Complex extends ISummary {
|
||||||
|
business_activity: ISummary;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConsumerAccount {
|
||||||
|
role: string;
|
||||||
|
account: {
|
||||||
|
username: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UnknownCustomer {
|
||||||
|
name?: string;
|
||||||
|
national_code?: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
@if (loading) {
|
||||||
|
<shared-page-loading />
|
||||||
|
} @else if (!invoice) {
|
||||||
|
<uikit-empty-state> </uikit-empty-state>
|
||||||
|
} @else {
|
||||||
|
<div class="flex flex-col gap-6">
|
||||||
|
<app-card-data cardTitle="اطلاعات فاکتور" [editable]="false" [backRoute]="backRoute">
|
||||||
|
<ng-template #moreActions>
|
||||||
|
<button
|
||||||
|
pButton
|
||||||
|
type="button"
|
||||||
|
label="چاپ"
|
||||||
|
icon="pi pi-print"
|
||||||
|
outlined
|
||||||
|
size="small"
|
||||||
|
(click)="printInvoice()"
|
||||||
|
></button>
|
||||||
|
</ng-template>
|
||||||
|
<div class="flex flex-col gap-4">
|
||||||
|
<div class="listKeyValue">
|
||||||
|
<app-key-value label="کد رهگیری" [value]="invoice.code" />
|
||||||
|
<app-key-value label="تاریخ فاکتور" [value]="invoice.invoice_date" type="dateTime" />
|
||||||
|
<app-key-value label="تاریخ ایجاد فاکتور" [value]="invoice.created_at" type="dateTime" />
|
||||||
|
<app-key-value label="وضعیت صدور به سامانهی مودیان">
|
||||||
|
<catalog-tax-provider-status-tag [status]="invoice.status.value" [translate]="invoice.status.translate" />
|
||||||
|
</app-key-value>
|
||||||
|
<div class="col-span-full">
|
||||||
|
<app-key-value label="توضیحات" [value]="invoice.notes" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p-divider align="center"> اطلاعات پرداخت </p-divider>
|
||||||
|
<div class="grid md:grid-cols-3 sm:grid-cols-2 sm:gap-4 gap-3 items-center">
|
||||||
|
<app-key-value label="مجموع قابل پرداخت" [value]="invoice.total_amount" type="price" />
|
||||||
|
@for (payment of invoice.payments; track $index) {
|
||||||
|
<app-key-value
|
||||||
|
[label]="`${payment.payment_method === 'SET_OF' ? 'تهاتر' : payment.payment_method === 'TERMINAL' ? 'پایانه' : 'نقدی'}`"
|
||||||
|
[value]="payment.amount"
|
||||||
|
type="price"
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p-divider align="center"> اطلاعات صادر کننده </p-divider>
|
||||||
|
<div class="listKeyValue">
|
||||||
|
<app-key-value label="کسب و کار" [value]="invoice.pos!.complex.business_activity.name" />
|
||||||
|
<app-key-value label="مجموعه" [value]="invoice.pos!.complex.name" />
|
||||||
|
<app-key-value label="پایانه فروش" [value]="invoice.pos!.name" />
|
||||||
|
<app-key-value label="ایجاد کننده" [value]="invoice.consumer_account.account.username" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (variant !== "customer") {
|
||||||
|
<p-divider align="center"> اطلاعات مشتری </p-divider>
|
||||||
|
@if (invoice.customer) {
|
||||||
|
<div class="listKeyValue">
|
||||||
|
@if (invoice.customer.type === "INDIVIDUAL") {
|
||||||
|
<app-key-value label="نوع مشتری" value="حقیقی" />
|
||||||
|
<app-key-value label="نام" [value]="invoice.customer.individual?.first_name" />
|
||||||
|
<app-key-value label="نام خانوادگی" [value]="invoice.customer.individual?.last_name" />
|
||||||
|
<app-key-value label="کد اقتصادی" [value]="invoice.customer.individual?.economic_code" />
|
||||||
|
<app-key-value label="کد ملی" [value]="invoice.customer.individual?.national_id" />
|
||||||
|
<app-key-value label="کد پستی" [value]="invoice.customer.individual?.postal_code" />
|
||||||
|
} @else {
|
||||||
|
<app-key-value label="نوع مشتری" value="حقوقی" />
|
||||||
|
<app-key-value label="نام شرکت" [value]="invoice.customer.legal?.company_name" />
|
||||||
|
<app-key-value label="کد اقتصادی" [value]="invoice.customer.legal?.economic_code" />
|
||||||
|
<app-key-value label="کد ثبتی" [value]="invoice.customer.legal?.registration_number" />
|
||||||
|
<app-key-value label="کد پستی" [value]="invoice.customer.legal?.postal_code" />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
} @else if (invoice.unknown_customer) {
|
||||||
|
<div class="listKeyValue">
|
||||||
|
<app-key-value label="نوع مشتری" value="نوع دوم" />
|
||||||
|
<app-key-value label="عنوان" [value]="invoice.unknown_customer.name" />
|
||||||
|
<app-key-value label="کد ثبتی" [value]="invoice.unknown_customer.national_code" />
|
||||||
|
</div>
|
||||||
|
} @else {
|
||||||
|
<p class="text-center text-text-color pt-3 pb-5">اطلاعات مشتری ثبت نشده است.</p>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</app-card-data>
|
||||||
|
<app-card-data cardTitle="کالاهای خریداری شده" [editable]="false">
|
||||||
|
<app-page-data-list
|
||||||
|
[columns]="columns"
|
||||||
|
[expandColumns]="expandableColumns"
|
||||||
|
[expandable]="true"
|
||||||
|
expandableItemKey="payload"
|
||||||
|
[items]="invoice.items"
|
||||||
|
[loading]="loading"
|
||||||
|
pageTitle=""
|
||||||
|
[showRefresh]="false"
|
||||||
|
>
|
||||||
|
<ng-template #totalAmount let-item>
|
||||||
|
@if (!item.discount_amount) {
|
||||||
|
<span [appPriceMask]="item.total_amount"></span>
|
||||||
|
} @else {
|
||||||
|
<!-- <div class="flex flex-col items-end">
|
||||||
|
<span class="line-through text-muted-color text-xs" [appPriceMask]="item.total_amount"></span>
|
||||||
|
<span [appPriceMask]="item.total_amount - item.discount_amount"></span>
|
||||||
|
</div> -->
|
||||||
|
}
|
||||||
|
</ng-template>
|
||||||
|
</app-page-data-list>
|
||||||
|
</app-card-data>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
import { Maybe } from '@/core';
|
||||||
|
import { NativeBridgeService } from '@/core/services';
|
||||||
|
import { PosInfoStore } from '@/domains/pos/store';
|
||||||
|
import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog';
|
||||||
|
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||||
|
import { ISaleInvoiceFullResponse } from '@/shared/components/invoices/sale-invoice-full-response.model';
|
||||||
|
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||||
|
import {
|
||||||
|
IColumn,
|
||||||
|
PageDataListComponent,
|
||||||
|
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
import { PriceMaskDirective } from '@/shared/directives';
|
||||||
|
import { UikitEmptyStateComponent } from '@/uikit';
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
computed,
|
||||||
|
EventEmitter,
|
||||||
|
inject,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
TemplateRef,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
|
import { UrlTree } from '@angular/router';
|
||||||
|
import { ButtonDirective } from 'primeng/button';
|
||||||
|
import { Divider } from 'primeng/divider';
|
||||||
|
import { TableModule } from 'primeng/table';
|
||||||
|
|
||||||
|
export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'shared-sale-invoice-single-view',
|
||||||
|
templateUrl: './sale-invoice-single-view.component.html',
|
||||||
|
imports: [
|
||||||
|
AppCardComponent,
|
||||||
|
KeyValueComponent,
|
||||||
|
Divider,
|
||||||
|
ButtonDirective,
|
||||||
|
PageDataListComponent,
|
||||||
|
TableModule,
|
||||||
|
PageLoadingComponent,
|
||||||
|
UikitEmptyStateComponent,
|
||||||
|
PriceMaskDirective,
|
||||||
|
CatalogTaxProviderStatusTagComponent,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class SharedSaleInvoiceSingleViewComponent {
|
||||||
|
private readonly nativeBridge = inject(NativeBridgeService);
|
||||||
|
private readonly posInfoStore = inject(PosInfoStore);
|
||||||
|
|
||||||
|
@Input({ required: true }) loading!: boolean;
|
||||||
|
@Input() invoice!: Maybe<ISaleInvoiceFullResponse>;
|
||||||
|
@Input() variant: TSaleInvoiceSingleViewVariant = 'full';
|
||||||
|
@Input() backRoute?: UrlTree | string | any[];
|
||||||
|
|
||||||
|
@Output() onRefresh = new EventEmitter<void>();
|
||||||
|
|
||||||
|
@ViewChild('totalAmount', { static: false }) totalAmount!: TemplateRef<any>;
|
||||||
|
|
||||||
|
readonly posName = computed(() => {
|
||||||
|
if (this.posInfoStore.entity()) {
|
||||||
|
const { name, businessActivity, complex } = this.posInfoStore.entity()!;
|
||||||
|
return `${name} (${businessActivity.name} - ${complex.name})`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
});
|
||||||
|
|
||||||
|
printInvoice = () => {
|
||||||
|
if (this.invoice) {
|
||||||
|
this.nativeBridge.print([
|
||||||
|
{
|
||||||
|
title: 'اطلاعات صورتحساب',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'شماره منحصر به فرد مالیاتی',
|
||||||
|
value: 'this.invoice',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'شماره صورتحساب',
|
||||||
|
value: this.invoice.code,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'موضوع صورتحساب',
|
||||||
|
value: 'this.invoice',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'نوع صورتحساب',
|
||||||
|
value: 'this.invoice',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'تاریخ و ساعت',
|
||||||
|
value: this.invoice.invoice_date,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'وضعیت صورتحساب مالیاتی',
|
||||||
|
value: this.invoice.status.translate,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: `اطلاعات فروشنده`,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'عنوان فروشگاه',
|
||||||
|
value: this.invoice.pos.complex.business_activity.name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'عنوان شعبه',
|
||||||
|
value: this.invoice.pos.complex.name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'عنوان پایانه فروش',
|
||||||
|
value: this.invoice.pos.name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'شماره اقتصادی',
|
||||||
|
value: 'this.invoice.pos.complex.business_activity.economic_code',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: `اطلاعات خریدار`,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
label: 'نام خریدار',
|
||||||
|
value:
|
||||||
|
(this.invoice.customer
|
||||||
|
? this.invoice.customer.type === 'LEGAL'
|
||||||
|
? this.invoice.customer.legal?.company_name
|
||||||
|
: `${this.invoice.customer.individual?.first_name} ${this.invoice.customer.individual?.last_name}`
|
||||||
|
: this.invoice.unknown_customer?.name) || '-',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'شماره اقتصادی',
|
||||||
|
value: this.invoice.customer
|
||||||
|
? this.invoice.customer.type === 'LEGAL'
|
||||||
|
? this.invoice.customer.legal?.economic_code
|
||||||
|
: this.invoice.customer.individual?.economic_code || '-'
|
||||||
|
: '-',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
columns: IColumn[] = [
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
header: 'عنوان',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: {
|
||||||
|
path: 'good.name',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'sku_code',
|
||||||
|
header: 'شناسه کالا',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'unit_price',
|
||||||
|
header: 'قیمت واحد',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'quantity',
|
||||||
|
header: 'مقدار',
|
||||||
|
customDataModel(item) {
|
||||||
|
return `${item.quantity} ${item.measure_unit_text}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'total_amount',
|
||||||
|
header: 'قیمت نهایی',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expandableColumns: IColumn[] = [
|
||||||
|
{
|
||||||
|
field: 'commission',
|
||||||
|
header: 'کارمزد',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'wages',
|
||||||
|
header: 'اجرت',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'profit',
|
||||||
|
header: 'سود',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expandedRows: { [key: string]: boolean } = {};
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
this.onRefresh.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
|
|
||||||
<ng-template #emptymessage>
|
<ng-template #emptymessage>
|
||||||
<tr class="">
|
<tr class="">
|
||||||
<td [colSpan]="(columns.length + 1).toString()" class="w-full">
|
<td [colSpan]="(columns.length + (showIndex ? 1 : 0) + (actionsCount() > 0 ? 1 : 0)).toString()" class="w-full">
|
||||||
<ng-container [ngTemplateOutlet]="emptyMessageCard"></ng-container>
|
<ng-container [ngTemplateOutlet]="emptyMessageCard"></ng-container>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div class="h-full bg-surface-overlay rounded-(--p-card-border-radius) overflow-hidden">
|
<div class="h-full bg-surface-overlay rounded-lg shadow border border-surface-border p-0! overflow-hidden">
|
||||||
<ng-template #captionTemplate let-isMobileView="isMobileView">
|
<ng-template #captionTemplate let-isMobileView="isMobileView">
|
||||||
@if (pageTitle || showAdd || filter || showRefresh || moreActions) {
|
@if (pageTitle || showAdd || filter || showRefresh || moreActions) {
|
||||||
<ng-container [ngTemplateOutlet]="caption">
|
<ng-container [ngTemplateOutlet]="caption">
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const accountListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت حسابهای کاربری',
|
||||||
|
addNewCtaLabel: 'افزودن حساب',
|
||||||
|
emptyPlaceholderTitle: 'حسابی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن حساب کاربری، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
header: 'نام کاربری',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.username' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'pos',
|
||||||
|
header: 'پایانه',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return `${item.pos.name} - ${item.pos.complex.name} - ${item.pos.complex.business_activity.name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const businessActivityListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت کسب و کار',
|
||||||
|
addNewCtaLabel: 'افزودن کسب و کار',
|
||||||
|
emptyPlaceholderTitle: 'کسب و کاری یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن کسب و کار، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'guild', header: 'صنف', type: 'nested', nestedOption: { path: 'guild.name' } },
|
||||||
|
{ field: 'economic_code', header: 'کد اقتصادی' },
|
||||||
|
{
|
||||||
|
field: 'license_info',
|
||||||
|
header: 'محدودیت کاربر',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
const licenseInfo = item.license_info;
|
||||||
|
if (!licenseInfo) {
|
||||||
|
return 'بدون مجوز';
|
||||||
|
}
|
||||||
|
return `${licenseInfo.accounts_limit} کاربر`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'license_info',
|
||||||
|
header: 'انقضا مجوز',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'license_info.expires_at', type: 'date' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const categoryListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت دستهبندیهای کالا',
|
||||||
|
addNewCtaLabel: 'افزودن دستهبندی',
|
||||||
|
emptyPlaceholderTitle: 'دستهبندی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن دستهبندی، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'image_url', header: 'تصویر', type: 'thumbnail' },
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const complexListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت شعب',
|
||||||
|
addNewCtaLabel: 'افزودن شعبه',
|
||||||
|
emptyPlaceholderTitle: 'شعبهای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن شعبه، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'branch_code', header: 'کد شعبه' },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const consumerListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت مشتریها',
|
||||||
|
addNewCtaLabel: 'افزودن مشتری',
|
||||||
|
emptyPlaceholderTitle: 'مشتریای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن مشتری، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{
|
||||||
|
field: 'business_counts',
|
||||||
|
header: 'تعداد کسبوکارها',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.business_counts || 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'partner',
|
||||||
|
header: 'ارایهدهنده',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'partner.name' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
header: 'وضعیت',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'status.translate' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const customerListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت مشتریها',
|
||||||
|
addNewCtaLabel: 'افزودن مشتری',
|
||||||
|
emptyPlaceholderTitle: 'مشتریای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن مشتری، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'type',
|
||||||
|
header: 'نوع مشتری',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.type === 'LEGAL' ? 'حقوقی' : 'حقیقی';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'name',
|
||||||
|
header: 'عنوان',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
if (item.type === 'LEGAL') {
|
||||||
|
return item.legal?.company_name;
|
||||||
|
}
|
||||||
|
return `${item.individual?.first_name} ${item.individual?.last_name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'economic_code',
|
||||||
|
header: 'کد اقتصادی',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
if (item.type === 'LEGAL') {
|
||||||
|
return item.legal?.economic_code;
|
||||||
|
}
|
||||||
|
return item.individual?.economic_code;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const deviceBrandListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت برندهای دستگاه',
|
||||||
|
addNewCtaLabel: 'افزودن برند',
|
||||||
|
emptyPlaceholderTitle: 'برندی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن برند دستگاه، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const deviceListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت دستگاهها',
|
||||||
|
addNewCtaLabel: 'افزودن دستگاه',
|
||||||
|
emptyPlaceholderTitle: 'دستگاهای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن دستگاه، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'brand', header: 'برند', type: 'nested', nestedOption: { path: 'brand.name' } },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const goodListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت کالاها',
|
||||||
|
addNewCtaLabel: 'افزودن کالا',
|
||||||
|
emptyPlaceholderTitle: 'کالایی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن کالای، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'image_url', header: 'تصویر', type: 'thumbnail' },
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'sku', header: 'شناسه کالا', type: 'nested', nestedOption: { path: 'sku.code' } },
|
||||||
|
{
|
||||||
|
field: 'measure_unit',
|
||||||
|
header: 'واحد اندازهگیری',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'measure_unit.name' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'category',
|
||||||
|
header: 'دستهبندی',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'category.name' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
export * from './account-list.const';
|
||||||
|
export * from './business-activity-list.const';
|
||||||
|
export * from './category-list.const';
|
||||||
|
export * from './complex-list.const';
|
||||||
|
export * from './consumer-list.const';
|
||||||
|
export * from './device-brand-list.const';
|
||||||
|
export * from './device-list.const';
|
||||||
|
export * from './good-list.const';
|
||||||
|
export * from './license-list.const';
|
||||||
|
export * from './list-config.model';
|
||||||
|
export * from './partner-account-list.const';
|
||||||
|
export * from './partner-consumer-account-list.const';
|
||||||
|
export * from './partner-customer-list.const';
|
||||||
|
export * from './partner-list.const';
|
||||||
|
export * from './pos-list.const';
|
||||||
|
export * from './provider-list.const';
|
||||||
|
export * from './sale-invoice-list.const';
|
||||||
|
export * from './sku-list.const';
|
||||||
|
export * from './superAdmin-consumer-account-list.const';
|
||||||
|
export * from './user-list.const';
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const licenseListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت لایسنسها',
|
||||||
|
addNewCtaLabel: 'افزودن لایسنس',
|
||||||
|
emptyPlaceholderTitle: 'لایسنسی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن لایسنس، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'consumer',
|
||||||
|
header: 'مشتری',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return `${item.consumer.first_name} ${item.consumer.last_name}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'partner',
|
||||||
|
header: 'ارایه شده توسط',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.license?.charged_license_transaction?.partner?.name || 'برند نرمافزار';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ field: 'expires_at', header: 'تاریخ انقضا', type: 'date' },
|
||||||
|
{ field: 'created_at', header: 'تاریخ ایجاد', type: 'date' },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { IColumn } from '@/shared/components/pageDataList/page-data-list.component';
|
||||||
|
|
||||||
|
export interface IListConfig {
|
||||||
|
pageTitle: string;
|
||||||
|
addNewCtaLabel: string;
|
||||||
|
emptyPlaceholderTitle: string;
|
||||||
|
emptyPlaceholderDescription: string;
|
||||||
|
columns: IColumn[];
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const partnerAccountListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت حسابهای کاربری',
|
||||||
|
addNewCtaLabel: 'افزودن حساب',
|
||||||
|
emptyPlaceholderTitle: 'حسابی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن حساب کاربری، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
header: 'نام کاربری',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.username' },
|
||||||
|
},
|
||||||
|
{ field: 'role', header: 'نقش' },
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
header: 'وضعیت',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.status' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const partnerConsumerAccountListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت حسابهای مشتری',
|
||||||
|
addNewCtaLabel: 'افزودن حساب',
|
||||||
|
emptyPlaceholderTitle: 'حسابی یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن حساب، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'account',
|
||||||
|
header: 'نام کاربری',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.username' },
|
||||||
|
},
|
||||||
|
{ field: 'role', header: 'نوع حساب', type: 'nested', nestedOption: { path: 'role.translate' } },
|
||||||
|
{
|
||||||
|
field: 'pos',
|
||||||
|
header: 'پایانه',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
if (item.pos) {
|
||||||
|
return `${item.pos.name} (${item.pos.complex.name} - ${item.pos.complex.business_activity.name})`;
|
||||||
|
}
|
||||||
|
return '-';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
header: 'وضعیت',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.status.translate' },
|
||||||
|
variant: 'tag',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const partnerCustomerListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت مشتریان',
|
||||||
|
addNewCtaLabel: 'افزودن مشتری',
|
||||||
|
emptyPlaceholderTitle: 'مشتریای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن مشتری، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'first_name', header: 'نام' },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const partnerListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت ارایهدهندگان',
|
||||||
|
addNewCtaLabel: 'افزودن ارایهدهنده',
|
||||||
|
emptyPlaceholderTitle: 'ارایهدهندگانای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن ارایهدهنده، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'code', header: 'کد' },
|
||||||
|
{
|
||||||
|
field: 'licenses',
|
||||||
|
header: 'تعداد لایسنسها',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.licenses || 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'account_quota',
|
||||||
|
header: 'تعداد کاربرهای خریداری شده',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.account_quota || 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'license_renew',
|
||||||
|
header: 'تعداد لایسنس تمدیدی',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return item.license_renew || 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'status',
|
||||||
|
header: 'وضعیت',
|
||||||
|
type: 'nested',
|
||||||
|
variant: 'tag',
|
||||||
|
nestedOption: {
|
||||||
|
path: 'status.translate',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const posListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت پایانههای فروش',
|
||||||
|
addNewCtaLabel: 'افزودن پایانه',
|
||||||
|
emptyPlaceholderTitle: 'پایانهای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن پایانه، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{ field: 'serial_number', header: 'شماره سریال' },
|
||||||
|
{ field: 'pos_type', header: 'نوع دستگاه' },
|
||||||
|
{ field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
|
||||||
|
{
|
||||||
|
field: 'provider',
|
||||||
|
header: 'ارایهدهنده',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'provider.name' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'account',
|
||||||
|
header: 'کاربر',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'account.username' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const providerListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت تامینکنندگان',
|
||||||
|
addNewCtaLabel: 'افزودن تامینکننده',
|
||||||
|
emptyPlaceholderTitle: 'تامینکنندهای یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن تامینکننده، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'name', header: 'عنوان' },
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { IListConfig } from './list-config.model';
|
||||||
|
|
||||||
|
export const saleInvoiceListConfig: IListConfig = {
|
||||||
|
pageTitle: 'مدیریت فاکتورهای فروش',
|
||||||
|
addNewCtaLabel: 'افزودن فاکتور',
|
||||||
|
emptyPlaceholderTitle: 'فاکتوری یافت نشد',
|
||||||
|
emptyPlaceholderDescription: 'برای افزودن فاکتور، روی دکمهٔ بالا کلیک کنید.',
|
||||||
|
columns: [
|
||||||
|
{ field: 'code', header: 'کد رهگیری' },
|
||||||
|
{
|
||||||
|
field: 'total_amount',
|
||||||
|
header: 'قیمت نهایی',
|
||||||
|
type: 'price',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'pos',
|
||||||
|
header: 'پایانه',
|
||||||
|
customDataModel(item: any) {
|
||||||
|
return `${item.pos.name} (${item.pos.complex.name} - ${item.pos.complex.business_activity.name})`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'consumer_account',
|
||||||
|
header: 'ایجاد شده توسط',
|
||||||
|
type: 'nested',
|
||||||
|
nestedOption: { path: 'consumer_account.account.username' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'invoice_date',
|
||||||
|
header: 'تاریخ فاکتور',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'created_at',
|
||||||
|
header: 'تاریخ ایجاد',
|
||||||
|
type: 'date',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user