Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-05-07 23:28:12 +03:30
parent b2a1eb8e5b
commit ce40bd8c75
54 changed files with 260 additions and 183 deletions
@@ -1,3 +1,4 @@
import { Maybe } from '@/core';
import { NativeBridgeService } from '@/core/services';
import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog';
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
@@ -46,7 +47,7 @@ export class ConsumerSaleInvoiceSharedComponent {
private readonly nativeBridge = inject(NativeBridgeService);
@Input({ required: true }) loading!: boolean;
@Input({ required: true }) invoice!: ISaleInvoiceFullResponse;
@Input() invoice!: Maybe<ISaleInvoiceFullResponse>;
@Input() variant: TConsumerSaleInvoice = 'full';
@Input() backRoute?: UrlTree | string | any[];
@@ -55,7 +56,7 @@ export class ConsumerSaleInvoiceSharedComponent {
@ViewChild('totalAmount', { static: false }) totalAmount!: TemplateRef<any>;
printInvoice = () => {
if (this.nativeBridge.isEnabled()) {
if (this.nativeBridge.isEnabled() && this.invoice) {
const result = this.nativeBridge.print({
title: 'salam',
items: [
@@ -19,7 +19,6 @@
@case (1) {
<partner-consumer-businessActivities-form-content
[consumerId]="consumerId"
[visible]="visible"
(onSubmit)="onBusinessActivitySubmit($event)"
(onClose)="close()"
/>
@@ -11,7 +11,6 @@
[businessActivityId]="businessActivityId"
[initialValues]="initialValues"
[editMode]="editMode"
[visible]="visible"
(onSubmit)="onFormSubmit($event)"
(onClose)="close()"
/>
@@ -38,7 +38,6 @@ export class ConsumerBusinessActivitiesFormComponent extends AbstractForm<
@Input({ required: true }) consumerId!: string;
@Input() businessActivityId!: string;
@Input({ required: true }) visible!: boolean;
initForm = () => {
const form = this.fb.group({
@@ -1,5 +1,5 @@
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
import { MustMatch } from '@/core/validators';
import { MustMatch, usernameValidator } from '@/core/validators';
import { AbstractForm } from '@/shared/abstractClasses';
import {
DeviceIdComponent,
@@ -49,9 +49,9 @@ export class ConsumerPosFormContentComponent extends AbstractForm<IPosRequest, I
serial_number: fieldControl.serial_number(this.initialValues?.serial_number || ''),
device_id: fieldControl.device_id(this.initialValues?.device?.id || ''),
provider_id: fieldControl.provider_id(this.initialValues?.provider?.id || ''),
username: [''],
password: [''],
confirmPassword: [''],
username: fieldControl.username(),
password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(),
});
form.controls.pos_type.valueChanges.subscribe((value) => {
@@ -89,30 +89,8 @@ export class ConsumerPosFormContentComponent extends AbstractForm<IPosRequest, I
form.removeControl('confirmPassword');
form.removeValidators([MustMatch('password', 'confirmPassword')]);
} else {
// @ts-ignore
form.addControl(
'username',
this.fb.control<string>('', {
nonNullable: true,
validators: fieldControl.username('')[1],
}),
);
// @ts-ignore
form.addControl(
'password',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
// @ts-ignore
form.addControl(
'confirmPassword',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.controls.username.setValidators([Validators.required, usernameValidator()]);
form.controls.username.updateValueAndValidity({ emitEvent: false });
form.addValidators([MustMatch('password', 'confirmPassword')]);
}
@@ -102,10 +102,21 @@ export class PosLayoutComponent implements AfterViewInit {
}
doPay() {
this.nativeBridgeService.pay({
amount: 1000,
id: '1',
// this.nativeBridgeService.pay({
// amount: 10_000,
// id: '1',
// });
this.nativeBridgeService.print({
title: 'salam',
items: [
{
label: 'مجموع قیمت',
value: '10_000',
},
],
});
// @ts-ignore
// window.NativeBridge.pay(12312, 'test');
}
ngOnInit() {
@@ -4,6 +4,7 @@
<field-mobile-number [control]="form.controls.mobile_number" />
<field-national-id [control]="form.controls.national_id" />
<field-economic-code [control]="form.controls.economic_code" />
<field-postal-code [control]="form.controls.postal_code" />
<app-form-footer-actions submitLabel="ثبت مشتری و ادامه" (onCancel)="close()" (onSubmit)="submit()" />
</form>
@@ -5,6 +5,7 @@ import {
LastNameComponent,
MobileNumberComponent,
NationalIdComponent,
PostalCodeComponent,
} from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { fieldControl } from '@/shared/constants';
@@ -26,6 +27,7 @@ import { PosLandingStore } from '../../../store/main.store';
NationalIdComponent,
EconomicCodeComponent,
MobileNumberComponent,
PostalCodeComponent,
],
})
export class CustomerIndividualFormComponent extends AbstractForm<
@@ -12,7 +12,7 @@
}
</div>
<div class="flex justify-between items-center">
<span>مالیات (۱۰٪)</span>
<span>ارزش افزوده</span>
<span [appPriceMask]="taxAmount"></span>
</div>
<hr />
@@ -132,9 +132,14 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
const totalAmountBeforeProfit = unitWithQuantity + wageAmount + commissionAmount;
const baseTotalAmount = totalAmountBeforeProfit + profitAmount;
const baseAmountForDiscountCalculation =
this.discountType() === 1 ? profitAmount : baseTotalAmount;
this.discountType() === 1 ? profitAmount : unitWithQuantity;
const taxAmount = (profitAmount + commissionAmount + wageAmount - discountAmount) * 0.1;
const taxAmount =
(profitAmount +
commissionAmount +
wageAmount -
(this.discountType() === 1 ? discountAmount : 0)) *
0.1;
const totalAmount = baseTotalAmount - discountAmount + taxAmount;
this.unitWithQuantity.set(unitWithQuantity);
@@ -23,7 +23,7 @@
/>
<app-input label="شناسه اقتصادی" [control]="form.controls.customer_economic_code" name="customer_economic_code" />
<div class="grid grid-cols-2 gap-2">
<!-- <div class="grid grid-cols-2 gap-2">
<uikit-datepicker label="از تاریخ فاکتور" [control]="form.controls.invoice_date_from" name="invoice_date_from" />
<uikit-datepicker label="تا تاریخ فاکتور" [control]="form.controls.invoice_date_to" name="invoice_date_to" />
</div>
@@ -31,7 +31,7 @@
<div class="grid grid-cols-2 gap-2">
<uikit-datepicker label="از تاریخ صدور" [control]="form.controls.created_at_from" name="created_at_from" />
<uikit-datepicker label="تا تاریخ صدور" [control]="form.controls.created_at_to" name="created_at_to" />
</div>
</div> -->
<div class="grid grid-cols-2 gap-2">
<app-input label="از مبلغ" [control]="form.controls.total_amount_from" name="total_amount_from" type="price" />
@@ -3,7 +3,6 @@ import { Component, computed, inject, signal } from '@angular/core';
import { Router } from '@angular/router';
import { Button, ButtonDirective } from 'primeng/button';
import { Chip } from 'primeng/chip';
import { Paginator } from 'primeng/paginator';
import { Skeleton } from 'primeng/skeleton';
import { finalize } from 'rxjs';
import { posSaleInvoicesNamedRoutes } from '../constants/routes';
@@ -27,7 +26,6 @@ import { SaleInvoiceCardComponent } from './sale-invoice-card.component';
Button,
Chip,
SaleInvoiceCardComponent,
Paginator,
],
})
export class PosSaleInvoiceListComponent {
@@ -51,7 +51,7 @@ export class SaleInvoiceCardComponent {
if (customer) {
const { legal, individual } = customer;
let text = 'الکترونیکی نوع اول - ';
let text = 'نوع اول - ';
console.log(customer);
if (legal) {
text += `حقوقی (${legal.company_name})`;
@@ -61,7 +61,7 @@ export class SaleInvoiceCardComponent {
}
return text;
}
return 'الکترونیکی نوع دوم (بدون اطلاعات خریدار)';
return 'نوع دوم (بدون اطلاعات خریدار)';
});
sendInvoice() {
@@ -4,7 +4,7 @@
emptyPlaceholderTitle="حساب کاربری‌ای یافت نشد."
[items]="items()"
[loading]="loading()"
[showDetails]="true"
[showIndex]="false"
(onRefresh)="refresh()"
>
</app-page-data-list>
@@ -2,7 +2,6 @@
[pageTitle]="'مدیریت دسته‌بندی‌های کالا'"
[addNewCtaLabel]="'افزودن دسته‌بندی'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="دسته‌بندی یافت نشد"
emptyPlaceholderDescription="برای افزودن دسته‌بندی، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
@@ -1,7 +1,8 @@
<shared-dialog header="فرم صنف" [(visible)]="visible" [modal]="true" [style]="{ width: '500px' }" [closable]="true" ()>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-input label="کد" [control]="form.controls.code" name="code" />
<field-name [control]="form.controls.name" />
<field-code [control]="form.controls.code" />
<field-invoice-templates [control]="form.controls.invoice_template" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
@@ -1,11 +1,12 @@
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { InputComponent } from '@/shared/components';
import { CodeComponent, FieldInvoiceTemplatesComponent, NameComponent } from '@/shared/components';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { fieldControl } from '@/shared/constants';
import { Component, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { ReactiveFormsModule } from '@angular/forms';
import { IGuildRequest, IGuildResponse } from '../models';
import { GuildsService } from '../services/main.service';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
interface T {
name: string;
@@ -15,21 +16,23 @@ interface T {
@Component({
selector: 'admin-guild-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, SharedDialogComponent, InputComponent, FormFooterActionsComponent],
imports: [
ReactiveFormsModule,
SharedDialogComponent,
FormFooterActionsComponent,
NameComponent,
CodeComponent,
FieldInvoiceTemplatesComponent,
],
})
export class GuildFormComponent extends AbstractFormDialog<IGuildRequest, IGuildResponse> {
@Input() guildId?: string;
private service = inject(GuildsService);
form = this.fb.group({
name: [
{ value: this.initialValues?.name, disabled: this.submitLoading() },
Validators.required,
],
code: [
{ value: this.initialValues?.code, disabled: this.submitLoading() },
Validators.required,
],
name: fieldControl.name(this.initialValues?.name, true),
code: fieldControl.code(this.initialValues?.code, true),
invoice_template: fieldControl.invoice_template(this.initialValues?.invoice_template.id, true),
});
override ngOnChanges() {
@@ -1,6 +1,6 @@
<app-page-data-list
pageTitle="مدیریت کالاها"
[addNewCtaLabel]="'افزودن کالای'"
[addNewCtaLabel]="'افزودن کالا'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="کالایی یافت نشد"
+4 -1
View File
@@ -1,7 +1,10 @@
import ISummary from '@/core/models/summary';
export interface IGuildRawResponse {
id: string;
name: string;
code: string;
invoice_template: ISummary;
created_at: string;
}
export interface IGuildResponse extends IGuildRawResponse {}
@@ -9,7 +12,7 @@ export interface IGuildResponse extends IGuildRawResponse {}
export interface IGuildRequest {
name: string;
code: string;
invoice_template_type: string;
invoice_template: string;
}
export interface IGoodCategoriesRawResponse {
@@ -2,13 +2,13 @@
[pageTitle]="'مدیریت اصناف'"
[addNewCtaLabel]="'افزودن صنف'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="صنفی یافت نشد"
emptyPlaceholderDescription="برای افزودن صنف، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showDetails]="true"
[showAdd]="true"
[showEdit]="true"
(onAdd)="openAddForm()"
(onDetails)="toSinglePage($event)"
(onRefresh)="refresh()"
@@ -6,6 +6,7 @@
emptyPlaceholderDescription="برای افزودن حساب کاربری، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showIndex]="false"
(onAdd)="openAddForm()"
(onRefresh)="refresh()"
>
@@ -8,12 +8,11 @@
>
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
<app-shared-upload-file accept="image/*" name="image" (onSelect)="changeFile($event)" />
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<app-input label="کد" [control]="form.controls.code" name="code" />
<field-name [control]="form.controls.name" />
<field-code [control]="form.controls.code" />
@if (!editMode) {
<p-divider align="center"> اطلاعات ورود </p-divider>
<!-- @ts-ignore -->
<app-input label="نام کاربری" [control]="form.controls.username" name="username" [isLtrInput]="true" />
<field-username [control]="form.controls.username" />
<shared-password-input
[passwordControl]="form.controls.password"
[confirmPasswordControl]="form.controls.confirmPassword"
@@ -1,11 +1,17 @@
import { Maybe } from '@/core';
import { MustMatch } from '@/core/validators';
import { MustMatch, usernameValidator } from '@/core/validators';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import {
CodeComponent,
NameComponent,
SharedPasswordInputComponent,
UsernameComponent,
} from '@/shared/components';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { onSelectFileArgs } from '@/shared/components/uploadFile/model';
import { SharedUploadFileComponent } from '@/shared/components/uploadFile/upload-file.component';
import { fieldControl } from '@/shared/constants';
import { buildFormData } from '@/utils';
import { Component, computed, inject, Input, signal } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
@@ -19,11 +25,13 @@ import { PartnersService } from '../services/main.service';
imports: [
ReactiveFormsModule,
SharedDialogComponent,
InputComponent,
FormFooterActionsComponent,
Divider,
SharedPasswordInputComponent,
SharedUploadFileComponent,
UsernameComponent,
NameComponent,
CodeComponent,
],
})
export class GuildFormComponent extends AbstractFormDialog<IPartnerRequest, IPartnerResponse> {
@@ -32,35 +40,16 @@ export class GuildFormComponent extends AbstractFormDialog<IPartnerRequest, IPar
private initForm() {
const form = this.fb.group({
name: [this.initialValues?.name, [Validators.required]],
code: [this.initialValues?.code, [Validators.required]],
username: [''],
password: [''],
confirmPassword: [''],
name: fieldControl.name(this.initialValues?.name || ''),
code: fieldControl.code(this.initialValues?.code || ''),
username: fieldControl.username(),
password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(),
});
if (!this.editMode) {
form.addControl(
'username',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.addControl(
'password',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.addControl(
'confirmPassword',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.controls.username.setValidators([Validators.required, usernameValidator()]);
form.controls.username.updateValueAndValidity({ emitEvent: false });
form.addValidators([MustMatch('password', 'confirmPassword')]);
} else {
// @ts-ignore
@@ -20,7 +20,7 @@
<p-avatar
[image]="item.logo_url"
[title]="item.name"
[label]="item.logo_url ? '' : item.code.slice(0, 2)"
[label]="item.logo_url ? '' : item.name.slice(0, 2)"
shape="square"
size="large"
></p-avatar>
@@ -1,8 +1,9 @@
import { MustMatch } from '@/core/validators';
import { MustMatch, usernameValidator } from '@/core/validators';
import { AbstractFormDialog } from '@/shared/abstractClasses';
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { fieldControl } from '@/shared/constants';
import { Component, computed, inject, Input } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Divider } from 'primeng/divider';
@@ -27,35 +28,16 @@ export class ProviderFormComponent extends AbstractFormDialog<IProviderRequest,
private initForm() {
const form = this.fb.group({
name: [this.initialValues?.name, [Validators.required]],
code: [this.initialValues?.code, [Validators.required]],
username: [''],
password: [''],
confirmPassword: [''],
name: fieldControl.name(this.initialValues?.name || ''),
code: fieldControl.code(this.initialValues?.code || ''),
username: fieldControl.username(),
password: fieldControl.password(),
confirmPassword: fieldControl.confirmPassword(),
});
if (!this.editMode) {
form.addControl(
'username',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.addControl(
'password',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.addControl(
'confirmPassword',
this.fb.control<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
);
form.controls.username.setValidators([Validators.required, usernameValidator()]);
form.controls.username.updateValueAndValidity({ emitEvent: false });
form.addValidators([MustMatch('password', 'confirmPassword')]);
} else {
// @ts-ignore
@@ -2,13 +2,13 @@
pageTitle="مدیریت حساب‌های کاربری"
[addNewCtaLabel]="'افزودن حساب کاربری'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="حساب کاربری‌ای یافت نشد."
emptyPlaceholderDescription="برای افزودن حساب کاربری، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showDetails]="true"
[showAdd]="true"
[showIndex]="false"
(onAdd)="openAddForm()"
(onRefresh)="refresh()"
>