feat: update POS and account components to use new field names and improve form handling
This commit is contained in:
@@ -5,7 +5,7 @@ import { IPosInitialValues } from './pos.model';
|
|||||||
export const columns: IColumn[] = [
|
export const columns: IColumn[] = [
|
||||||
// { field: 'id', header: 'شناسه', type: 'id' },
|
// { field: 'id', header: 'شناسه', type: 'id' },
|
||||||
{ field: 'name', header: 'عنوان' },
|
{ field: 'name', header: 'عنوان' },
|
||||||
{ field: 'serial', header: 'شماره سریال' },
|
{ field: 'serial_number', header: 'شماره سریال' },
|
||||||
{ field: 'pos_type', header: 'نوع دستگاه' },
|
{ field: 'pos_type', header: 'نوع دستگاه' },
|
||||||
{ field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
|
{ field: 'device', header: 'دستگاه', type: 'nested', nestedOption: { path: 'device.name' } },
|
||||||
{
|
{
|
||||||
@@ -14,7 +14,7 @@ export const columns: IColumn[] = [
|
|||||||
type: 'nested',
|
type: 'nested',
|
||||||
nestedOption: { path: 'provider.name' },
|
nestedOption: { path: 'provider.name' },
|
||||||
},
|
},
|
||||||
{ field: 'status', header: 'وضعیت' },
|
{ field: 'account', header: 'کاربر', type: 'nested', nestedOption: { path: 'account.username' } },
|
||||||
{
|
{
|
||||||
field: 'created_at',
|
field: 'created_at',
|
||||||
header: 'تاریخ ایجاد',
|
header: 'تاریخ ایجاد',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export interface IAccountRawResponse {
|
|||||||
role: string;
|
role: string;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
account: Account;
|
account: Account;
|
||||||
|
pos: PosComplex;
|
||||||
}
|
}
|
||||||
export interface IAccountResponse extends IAccountRawResponse {}
|
export interface IAccountResponse extends IAccountRawResponse {}
|
||||||
|
|
||||||
@@ -18,3 +19,9 @@ interface Account {
|
|||||||
username: string;
|
username: string;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PosComplex {
|
||||||
|
name: string;
|
||||||
|
branch_code: string;
|
||||||
|
business_activity: { name: string };
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
emptyPlaceholderTitle="حساب کاربریای یافت نشد"
|
emptyPlaceholderTitle="حساب کاربریای یافت نشد"
|
||||||
[items]="items()"
|
[items]="items()"
|
||||||
[showDetails]="true"
|
|
||||||
[loading]="loading()"
|
[loading]="loading()"
|
||||||
(onDetails)="toSinglePage($event)"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@if (selectedItemForEdit()) {
|
@if (selectedItemForEdit()) {
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ export class ConsumerAccountsComponent extends AbstractList<IAccountResponse> {
|
|||||||
type: 'nested',
|
type: 'nested',
|
||||||
nestedOption: { path: 'account.username' },
|
nestedOption: { path: 'account.username' },
|
||||||
},
|
},
|
||||||
{ field: 'role', header: 'نقش' },
|
|
||||||
{
|
{
|
||||||
field: 'status',
|
field: 'pos',
|
||||||
header: 'وضعیت',
|
header: 'پایانه',
|
||||||
type: 'nested',
|
customDataModel(item) {
|
||||||
nestedOption: { path: 'account.status' },
|
return `${item.pos.name} - ${item.pos.complex.name} - ${item.pos.complex.business_activity.name}`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'created_at',
|
field: 'created_at',
|
||||||
|
|||||||
@@ -3,11 +3,9 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="grid grid-cols-3 gap-4 items-center">
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
<app-key-value label="نام کاربری" [value]="account()?.account?.username" />
|
<app-key-value label="نام کاربری" [value]="account()?.account?.username" />
|
||||||
<app-key-value label="نقش" [value]="account()?.role" />
|
|
||||||
<app-key-value label="وضعیت" [value]="account()?.account?.status" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</app-card-data>
|
</app-card-data>
|
||||||
|
|
||||||
<consumer-account-permission-list />
|
<!-- <consumer-account-permission-list /> -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+6
-3
@@ -20,7 +20,7 @@ export class ConsumerComplexFormComponent extends AbstractFormDialog<
|
|||||||
private readonly service = inject(ConsumerComplexesService);
|
private readonly service = inject(ConsumerComplexesService);
|
||||||
|
|
||||||
@Input({ required: true }) businessActivityId!: string;
|
@Input({ required: true }) businessActivityId!: string;
|
||||||
@Input({ required: true }) complexId!: string;
|
@Input() complexId!: string;
|
||||||
|
|
||||||
initForm = () => {
|
initForm = () => {
|
||||||
return this.fb.group({
|
return this.fb.group({
|
||||||
@@ -33,7 +33,7 @@ export class ConsumerComplexFormComponent extends AbstractFormDialog<
|
|||||||
form = this.initForm();
|
form = this.initForm();
|
||||||
|
|
||||||
get preparedTitle() {
|
get preparedTitle() {
|
||||||
return `ویرایش شعبه ${this.initialValues?.name}`;
|
return `${this.editMode ? 'ویرایش' : 'ایجاد'} شعبه`;
|
||||||
}
|
}
|
||||||
|
|
||||||
override ngOnChanges(): void {
|
override ngOnChanges(): void {
|
||||||
@@ -42,6 +42,9 @@ export class ConsumerComplexFormComponent extends AbstractFormDialog<
|
|||||||
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
const formValue = this.form.value as IComplexRequest;
|
const formValue = this.form.value as IComplexRequest;
|
||||||
return this.service.update(this.businessActivityId, this.complexId, formValue);
|
if (this.editMode) {
|
||||||
|
return this.service.update(this.businessActivityId, this.complexId, formValue);
|
||||||
|
}
|
||||||
|
return this.service.create(this.businessActivityId, formValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -1,11 +1,16 @@
|
|||||||
<app-page-data-list
|
<app-page-data-list
|
||||||
pageTitle="لیست شعب"
|
pageTitle="مدیریت شعب"
|
||||||
|
[addNewCtaLabel]="'افزودن شعبه جدید'"
|
||||||
|
[showAdd]="true"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
|
[showAdd]="true"
|
||||||
emptyPlaceholderTitle="شعبهای یافت نشد."
|
emptyPlaceholderTitle="شعبهای یافت نشد."
|
||||||
|
emptyPlaceholderDescription="برای افزودن شعبه جدید، روی دکمهٔ بالا کلیک کنید."
|
||||||
[items]="items()"
|
[items]="items()"
|
||||||
[loading]="loading()"
|
[loading]="loading()"
|
||||||
[showDetails]="true"
|
[showDetails]="true"
|
||||||
[showEdit]="true"
|
[showEdit]="true"
|
||||||
|
(onAdd)="openAddForm()"
|
||||||
(onEdit)="onEditClick($event)"
|
(onEdit)="onEditClick($event)"
|
||||||
(onDetails)="toSinglePage($event)"
|
(onDetails)="toSinglePage($event)"
|
||||||
>
|
>
|
||||||
|
|||||||
+49
@@ -8,6 +8,55 @@
|
|||||||
>
|
>
|
||||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
<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.name" name="name" />
|
||||||
|
|
||||||
|
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
||||||
|
|
||||||
|
@if (!editMode) {
|
||||||
|
<p-divider align="center"> اطلاعات ورود </p-divider>
|
||||||
|
<app-input label="نام کاربری" [control]="form.controls.username" name="username" [isLtrInput]="true" />
|
||||||
|
<uikit-field label="رمز عبور" [control]="form.controls.password">
|
||||||
|
<p-password
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
formControlName="password"
|
||||||
|
autocomplete="new-password"
|
||||||
|
class="w-full"
|
||||||
|
[toggleMask]="true"
|
||||||
|
[feedback]="false"
|
||||||
|
[invalid]="form.controls.password.touched && form.controls.password.invalid"
|
||||||
|
[inputStyle]="{
|
||||||
|
width: '100%',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<span class="text-xs mt-1 text-muted-color">
|
||||||
|
رمز باید حداقل ۸ کاراکتر بوده و شامل حداقل یک حرف بزرگ، یک حرف کوچک، یک عدد و یک کاراکتر ویژه باشد.
|
||||||
|
</span>
|
||||||
|
</uikit-field>
|
||||||
|
|
||||||
|
<uikit-field label="تکرار رمز عبور" [control]="form.controls.confirmPassword">
|
||||||
|
<p-password
|
||||||
|
id="confirmPassword"
|
||||||
|
name="confirmPassword"
|
||||||
|
formControlName="confirmPassword"
|
||||||
|
autocomplete="new-password"
|
||||||
|
class="w-full"
|
||||||
|
[toggleMask]="true"
|
||||||
|
[feedback]="false"
|
||||||
|
[invalid]="form.controls.confirmPassword.touched && form.controls.confirmPassword.invalid"
|
||||||
|
[inputStyle]="{
|
||||||
|
width: '100%',
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</uikit-field>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (form.controls.pos_type.value === "PSP") {
|
||||||
|
<app-input label="سریال دستگاه" [control]="form.controls.serial_number" name="serial_number" />
|
||||||
|
<catalog-device-select [control]="form.controls.device_id" />
|
||||||
|
<catalog-provider-select [control]="form.controls.provider_id" />
|
||||||
|
}
|
||||||
|
|
||||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||||
</form>
|
</form>
|
||||||
</p-dialog>
|
</p-dialog>
|
||||||
|
|||||||
+100
-9
@@ -1,18 +1,35 @@
|
|||||||
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
||||||
import { CONSUMER_COMPONENTS_CONST } from '@/domains/consumer/constants';
|
import { MustMatch } from '@/core/validators';
|
||||||
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||||
|
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
|
||||||
|
import { CatalogProviderSelectComponent } from '@/shared/catalog';
|
||||||
|
import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices';
|
||||||
import { InputComponent } from '@/shared/components';
|
import { InputComponent } from '@/shared/components';
|
||||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||||
|
import { UikitFieldComponent } from '@/uikit';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Dialog } from 'primeng/dialog';
|
import { Dialog } from 'primeng/dialog';
|
||||||
|
import { Divider } from 'primeng/divider';
|
||||||
|
import { Password } from 'primeng/password';
|
||||||
import { IPosRequest, IPosResponse } from '../../models';
|
import { IPosRequest, IPosResponse } from '../../models';
|
||||||
import { ConsumerPosesService } from '../../services/poses.service';
|
import { ConsumerPosesService } from '../../services/poses.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'consumer-pos-form',
|
selector: 'consumer-pos-form',
|
||||||
templateUrl: './form.component.html',
|
templateUrl: './form.component.html',
|
||||||
imports: [ReactiveFormsModule, Dialog, InputComponent, FormFooterActionsComponent],
|
imports: [
|
||||||
|
ReactiveFormsModule,
|
||||||
|
Dialog,
|
||||||
|
InputComponent,
|
||||||
|
FormFooterActionsComponent,
|
||||||
|
CatalogDeviceSelectComponent,
|
||||||
|
CatalogProviderSelectComponent,
|
||||||
|
EnumSelectComponent,
|
||||||
|
UikitFieldComponent,
|
||||||
|
Password,
|
||||||
|
Divider,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IPosResponse> {
|
export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IPosResponse> {
|
||||||
private readonly service = inject(ConsumerPosesService);
|
private readonly service = inject(ConsumerPosesService);
|
||||||
@@ -21,14 +38,84 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
|
|||||||
@Input({ required: true }) complexId!: string;
|
@Input({ required: true }) complexId!: string;
|
||||||
@Input({ required: true }) posId!: string;
|
@Input({ required: true }) posId!: string;
|
||||||
|
|
||||||
initForm() {
|
initForm = () => {
|
||||||
return CONSUMER_COMPONENTS_CONST.pos.initForm(this.fb, this.initialValues);
|
const form = this.fb.group({
|
||||||
}
|
name: [this.initialValues?.name || '', [Validators.required]],
|
||||||
|
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
|
||||||
|
serial_number: [this.initialValues?.serial_number || ''],
|
||||||
|
device_id: [this.initialValues?.device?.id || ''],
|
||||||
|
provider_id: [this.initialValues?.provider?.id || ''],
|
||||||
|
username: [''],
|
||||||
|
password: [''],
|
||||||
|
confirmPassword: [''],
|
||||||
|
});
|
||||||
|
|
||||||
|
form.controls.pos_type.valueChanges.subscribe((value) => {
|
||||||
|
if (value === 'PSP') {
|
||||||
|
form.controls.serial_number.setValidators([Validators.required]);
|
||||||
|
form.controls.device_id.setValidators([Validators.required]);
|
||||||
|
form.controls.provider_id.setValidators([Validators.required]);
|
||||||
|
form.controls.serial_number.enable({ emitEvent: false });
|
||||||
|
form.controls.device_id.enable({ emitEvent: false });
|
||||||
|
form.controls.provider_id.enable({ emitEvent: false });
|
||||||
|
} else {
|
||||||
|
form.controls.serial_number.clearValidators();
|
||||||
|
form.controls.device_id.clearValidators();
|
||||||
|
form.controls.provider_id.clearValidators();
|
||||||
|
form.controls.serial_number.reset('');
|
||||||
|
form.controls.device_id.reset('');
|
||||||
|
form.controls.provider_id.reset('');
|
||||||
|
form.controls.serial_number.disable({ emitEvent: false });
|
||||||
|
form.controls.device_id.disable({ emitEvent: false });
|
||||||
|
form.controls.provider_id.disable({ emitEvent: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
form.controls.serial_number.updateValueAndValidity({ emitEvent: false });
|
||||||
|
form.controls.device_id.updateValueAndValidity({ emitEvent: false });
|
||||||
|
form.controls.provider_id.updateValueAndValidity({ emitEvent: false });
|
||||||
|
});
|
||||||
|
form.controls.pos_type.updateValueAndValidity({ emitEvent: true });
|
||||||
|
|
||||||
|
if (this.editMode) {
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('username');
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('password');
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('confirmPassword');
|
||||||
|
form.removeValidators([MustMatch('password', 'confirmPassword')]);
|
||||||
|
} else {
|
||||||
|
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.addValidators([MustMatch('password', 'confirmPassword')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return form;
|
||||||
|
};
|
||||||
|
|
||||||
form = this.initForm();
|
form = this.initForm();
|
||||||
|
|
||||||
get preparedTitle() {
|
get preparedTitle() {
|
||||||
return `ویرایش پایانه فروش ${this.initialValues?.name}`;
|
return `${this.editMode ? 'ویرایش' : 'ایجاد'} پایانه فروش`;
|
||||||
}
|
}
|
||||||
|
|
||||||
override ngOnChanges(): void {
|
override ngOnChanges(): void {
|
||||||
@@ -36,7 +123,11 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
const formValue = this.form.value as IPosRequest;
|
const formValue = this.form.value as IPosRequest & { confirmPassword?: string };
|
||||||
return this.service.update(this.businessActivityId, this.complexId, this.posId, formValue);
|
const { confirmPassword, ...rest } = formValue;
|
||||||
|
if (this.editMode) {
|
||||||
|
return this.service.update(this.businessActivityId, this.complexId, this.posId!, rest);
|
||||||
|
}
|
||||||
|
return this.service.create(this.businessActivityId, this.complexId, rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -1,11 +1,15 @@
|
|||||||
<app-page-data-list
|
<app-page-data-list
|
||||||
pageTitle="لیست پایانههای فروش"
|
pageTitle="لیست پایانههای فروش"
|
||||||
[columns]="columns"
|
[columns]="columns"
|
||||||
|
[addNewCtaLabel]="'افزودن پایانهی فروش جدید'"
|
||||||
emptyPlaceholderTitle="پایانهی فروشی یافت نشد."
|
emptyPlaceholderTitle="پایانهی فروشی یافت نشد."
|
||||||
|
emptyPlaceholderDescription="برای افزودن پایانهی فروش جدید، روی دکمهٔ بالا کلیک کنید."
|
||||||
[items]="items()"
|
[items]="items()"
|
||||||
[loading]="loading()"
|
[loading]="loading()"
|
||||||
[showDetails]="true"
|
[showDetails]="true"
|
||||||
[showEdit]="true"
|
[showEdit]="true"
|
||||||
|
[showAdd]="true"
|
||||||
|
(onAdd)="openAddForm()"
|
||||||
(onEdit)="onEditClick($event)"
|
(onEdit)="onEditClick($event)"
|
||||||
(onDetails)="toSinglePage($event)"
|
(onDetails)="toSinglePage($event)"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ interface LicenseInfo {
|
|||||||
starts_at: string;
|
starts_at: string;
|
||||||
expires_at: string;
|
expires_at: string;
|
||||||
accounts_limit: number;
|
accounts_limit: number;
|
||||||
|
allocated_account_count: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import ISummary from '@/core/models/summary';
|
|||||||
export interface IPosRawResponse {
|
export interface IPosRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
status: string;
|
status: string;
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
@@ -15,4 +15,10 @@ export interface IPosResponse extends IPosRawResponse {}
|
|||||||
|
|
||||||
export interface IPosRequest {
|
export interface IPosRequest {
|
||||||
name: string;
|
name: string;
|
||||||
|
serial_number: string;
|
||||||
|
pos_type: string;
|
||||||
|
device_id?: string;
|
||||||
|
provider_id?: string;
|
||||||
|
username?: string;
|
||||||
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ export class ConsumerComplexesService {
|
|||||||
return this.http.get<IComplexRawResponse>(this.apiRoutes.single(businessActivityId, complexId));
|
return this.http.get<IComplexRawResponse>(this.apiRoutes.single(businessActivityId, complexId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create(businessActivityId: string, data: IComplexRequest): Observable<IComplexResponse> {
|
||||||
|
return this.http.post<IComplexRawResponse>(this.apiRoutes.list(businessActivityId), data);
|
||||||
|
}
|
||||||
|
|
||||||
update(
|
update(
|
||||||
businessActivityId: string,
|
businessActivityId: string,
|
||||||
complexId: string,
|
complexId: string,
|
||||||
|
|||||||
@@ -29,6 +29,17 @@ export class ConsumerPosesService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create(
|
||||||
|
businessActivityId: string,
|
||||||
|
complexId: string,
|
||||||
|
data: IPosRequest,
|
||||||
|
): Observable<IPosResponse> {
|
||||||
|
return this.http.post<IPosRawResponse>(
|
||||||
|
this.apiRoutes.list(businessActivityId, complexId),
|
||||||
|
data,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
update(
|
update(
|
||||||
businessActivityId: string,
|
businessActivityId: string,
|
||||||
complexId: string,
|
complexId: string,
|
||||||
|
|||||||
+1
-1
@@ -6,8 +6,8 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="grid grid-cols-3 gap-4 items-center">
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
<app-key-value label="عنوان" [value]="pos()?.name" />
|
<app-key-value label="عنوان" [value]="pos()?.name" />
|
||||||
<app-key-value label="شماره سریال" [value]="pos()?.serial" />
|
|
||||||
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
|
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
|
||||||
|
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
|
||||||
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
|
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
|
||||||
<app-key-value label="مدل دستگاه" [value]="pos()?.model" />
|
<app-key-value label="مدل دستگاه" [value]="pos()?.model" />
|
||||||
<app-key-value label="ارایهدهنده" [value]="pos()?.provider?.name" />
|
<app-key-value label="ارایهدهنده" [value]="pos()?.provider?.name" />
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
<app-key-value label="کد اقتصادی" [value]="business()?.economic_code" />
|
<app-key-value label="کد اقتصادی" [value]="business()?.economic_code" />
|
||||||
<app-key-value label="صنف" [value]="business()?.guild?.name" />
|
<app-key-value label="صنف" [value]="business()?.guild?.name" />
|
||||||
</div>
|
</div>
|
||||||
|
<p-divider align="center">اطلاعات لایسنس</p-divider>
|
||||||
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
|
<app-key-value label="تاریخ پایان لایسنس" [value]="business()?.license_info?.expires_at" type="date" />
|
||||||
|
<app-key-value label="محدودیت کاربر" [value]="business()?.license_info?.accounts_limit" />
|
||||||
|
<app-key-value label="تعداد کاربران ایجاد شده" [value]="business()?.license_info?.allocated_account_count" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</app-card-data>
|
</app-card-data>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { BreadcrumbService } from '@/core/services';
|
|||||||
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||||
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';
|
||||||
|
import { Divider } from 'primeng/divider';
|
||||||
import { ConsumerComplexListComponent } from '../components/complexes/list.component';
|
import { ConsumerComplexListComponent } from '../components/complexes/list.component';
|
||||||
import { ConsumerBusinessActivityFormComponent } from '../components/form.component';
|
import { ConsumerBusinessActivityFormComponent } from '../components/form.component';
|
||||||
import { BusinessActivityStore } from '../store/businessActivity.store';
|
import { BusinessActivityStore } from '../store/businessActivity.store';
|
||||||
@@ -14,6 +15,7 @@ import { BusinessActivityStore } from '../store/businessActivity.store';
|
|||||||
KeyValueComponent,
|
KeyValueComponent,
|
||||||
ConsumerBusinessActivityFormComponent,
|
ConsumerBusinessActivityFormComponent,
|
||||||
ConsumerComplexListComponent,
|
ConsumerComplexListComponent,
|
||||||
|
Divider,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ConsumerBusinessActivityComponent {
|
export class ConsumerBusinessActivityComponent {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export class ConsumerPosListComponent extends AbstractList<IPosResponse> {
|
|||||||
override setColumns(): void {
|
override setColumns(): void {
|
||||||
this.columns = [
|
this.columns = [
|
||||||
...this.header.filter((header) =>
|
...this.header.filter((header) =>
|
||||||
['name', 'status', 'pos_type'].includes(header.field as string),
|
['name', 'account', 'pos_type', 'status'].includes(header.field as string),
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
field: 'complex.business_activity',
|
field: 'complex.business_activity',
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import ISummary from '@/core/models/summary';
|
|||||||
export interface IPosRawResponse {
|
export interface IPosRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
status: string;
|
status: string;
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="grid grid-cols-3 gap-4 items-center">
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
<app-key-value label="عنوان" [value]="pos()?.name" />
|
<app-key-value label="عنوان" [value]="pos()?.name" />
|
||||||
<app-key-value label="شماره سریال" [value]="pos()?.serial" />
|
|
||||||
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
|
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
|
||||||
|
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
|
||||||
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
|
<app-key-value label="نوع دستگاه" [value]="pos()?.device?.name" />
|
||||||
<app-key-value label="مدل دستگاه" [value]="pos()?.model" />
|
<app-key-value label="مدل دستگاه" [value]="pos()?.model" />
|
||||||
<app-key-value label="ارایهدهنده" [value]="pos()?.provider?.name" />
|
<app-key-value label="ارایهدهنده" [value]="pos()?.provider?.name" />
|
||||||
|
|||||||
@@ -8,10 +8,39 @@
|
|||||||
>
|
>
|
||||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
<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.name" name="name" />
|
||||||
<!-- <app-input label="مدل دستگاه" [control]="form.controls.model" name="model" /> -->
|
|
||||||
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
||||||
|
|
||||||
|
@if (!editMode) {
|
||||||
|
<app-input label="نام کاربری" [control]="form.controls.username" name="username" [isLtrInput]="true" />
|
||||||
|
<uikit-field label="رمز عبور" [control]="form.controls.password">
|
||||||
|
<p-password
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
formControlName="password"
|
||||||
|
autocomplete="new-password"
|
||||||
|
styleClass="w-full"
|
||||||
|
[toggleMask]="true"
|
||||||
|
[feedback]="false"
|
||||||
|
[invalid]="form.controls.password.touched && form.controls.password.invalid"
|
||||||
|
/>
|
||||||
|
</uikit-field>
|
||||||
|
|
||||||
|
<uikit-field label="تکرار رمز عبور" [control]="form.controls.confirmPassword">
|
||||||
|
<p-password
|
||||||
|
id="confirmPassword"
|
||||||
|
name="confirmPassword"
|
||||||
|
formControlName="confirmPassword"
|
||||||
|
autocomplete="new-password"
|
||||||
|
styleClass="w-full"
|
||||||
|
[toggleMask]="true"
|
||||||
|
[feedback]="false"
|
||||||
|
[invalid]="form.controls.confirmPassword.touched && form.controls.confirmPassword.invalid"
|
||||||
|
/>
|
||||||
|
</uikit-field>
|
||||||
|
}
|
||||||
|
|
||||||
@if (form.controls.pos_type.value === "PSP") {
|
@if (form.controls.pos_type.value === "PSP") {
|
||||||
<app-input label="سریال دستگاه" [control]="form.controls.serial" name="serial" />
|
<app-input label="سریال دستگاه" [control]="form.controls.serial_number" name="serial_number" />
|
||||||
<catalog-device-select [control]="form.controls.device_id" />
|
<catalog-device-select [control]="form.controls.device_id" />
|
||||||
<catalog-provider-select [control]="form.controls.provider_id" />
|
<catalog-provider-select [control]="form.controls.provider_id" />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
||||||
|
import { MustMatch } from '@/core/validators';
|
||||||
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||||
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
|
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
|
||||||
import { CatalogProviderSelectComponent } from '@/shared/catalog';
|
import { CatalogProviderSelectComponent } from '@/shared/catalog';
|
||||||
import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices';
|
import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices';
|
||||||
import { InputComponent } from '@/shared/components';
|
import { InputComponent } from '@/shared/components';
|
||||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||||
|
import { UikitFieldComponent } from '@/uikit';
|
||||||
import { Component, inject, Input } from '@angular/core';
|
import { Component, inject, Input } from '@angular/core';
|
||||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Dialog } from 'primeng/dialog';
|
import { Dialog } from 'primeng/dialog';
|
||||||
|
import { Password } from 'primeng/password';
|
||||||
import { IPosRequest, IPosResponse } from '../../models';
|
import { IPosRequest, IPosResponse } from '../../models';
|
||||||
import { PartnerPosesService } from '../../services/poses.service';
|
import { PartnerPosesService } from '../../services/poses.service';
|
||||||
|
|
||||||
@@ -22,6 +25,8 @@ import { PartnerPosesService } from '../../services/poses.service';
|
|||||||
CatalogDeviceSelectComponent,
|
CatalogDeviceSelectComponent,
|
||||||
CatalogProviderSelectComponent,
|
CatalogProviderSelectComponent,
|
||||||
EnumSelectComponent,
|
EnumSelectComponent,
|
||||||
|
UikitFieldComponent,
|
||||||
|
Password,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IPosResponse> {
|
export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IPosResponse> {
|
||||||
@@ -35,44 +40,74 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
|
|||||||
initForm = () => {
|
initForm = () => {
|
||||||
const form = this.fb.group({
|
const form = this.fb.group({
|
||||||
name: [this.initialValues?.name || '', [Validators.required]],
|
name: [this.initialValues?.name || '', [Validators.required]],
|
||||||
serial: [this.initialValues?.serial || '', [Validators.required]],
|
|
||||||
// model: [this.initialValues?.model || '', [Validators.required]],
|
|
||||||
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
|
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
|
||||||
|
serial_number: [this.initialValues?.serial_number || ''],
|
||||||
device_id: [this.initialValues?.device?.id || ''],
|
device_id: [this.initialValues?.device?.id || ''],
|
||||||
provider_id: [this.initialValues?.provider?.id || ''],
|
provider_id: [this.initialValues?.provider?.id || ''],
|
||||||
|
username: [''],
|
||||||
|
password: [''],
|
||||||
|
confirmPassword: [''],
|
||||||
});
|
});
|
||||||
|
|
||||||
form.controls.pos_type.valueChanges.subscribe((value) => {
|
form.controls.pos_type.valueChanges.subscribe((value) => {
|
||||||
if (value === 'PSP') {
|
if (value === 'PSP') {
|
||||||
form.addControl(
|
form.controls.serial_number.setValidators([Validators.required]);
|
||||||
'serial',
|
form.controls.device_id.setValidators([Validators.required]);
|
||||||
this.fb.control<string>(this.initialValues?.serial ?? '', {
|
form.controls.provider_id.setValidators([Validators.required]);
|
||||||
nonNullable: true,
|
form.controls.serial_number.enable({ emitEvent: false });
|
||||||
validators: [Validators.required],
|
form.controls.device_id.enable({ emitEvent: false });
|
||||||
}),
|
form.controls.provider_id.enable({ emitEvent: false });
|
||||||
);
|
|
||||||
form.addControl(
|
|
||||||
'device_id',
|
|
||||||
this.fb.control<string>(this.initialValues?.device?.id ?? '', {
|
|
||||||
nonNullable: true,
|
|
||||||
validators: [Validators.required],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
form.addControl(
|
|
||||||
'provider_id',
|
|
||||||
this.fb.control<string>(this.initialValues?.provider?.id ?? '', {
|
|
||||||
nonNullable: true,
|
|
||||||
validators: [Validators.required],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
form.controls.serial_number.clearValidators();
|
||||||
form.removeControl('serial');
|
form.controls.device_id.clearValidators();
|
||||||
// @ts-ignore
|
form.controls.provider_id.clearValidators();
|
||||||
form.removeControl('device_id');
|
form.controls.serial_number.reset('');
|
||||||
// @ts-ignore
|
form.controls.device_id.reset('');
|
||||||
form.removeControl('provider_id');
|
form.controls.provider_id.reset('');
|
||||||
|
form.controls.serial_number.disable({ emitEvent: false });
|
||||||
|
form.controls.device_id.disable({ emitEvent: false });
|
||||||
|
form.controls.provider_id.disable({ emitEvent: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form.controls.serial_number.updateValueAndValidity({ emitEvent: false });
|
||||||
|
form.controls.device_id.updateValueAndValidity({ emitEvent: false });
|
||||||
|
form.controls.provider_id.updateValueAndValidity({ emitEvent: false });
|
||||||
});
|
});
|
||||||
|
form.controls.pos_type.updateValueAndValidity({ emitEvent: true });
|
||||||
|
|
||||||
|
if (this.editMode) {
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('username');
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('password');
|
||||||
|
// @ts-ignore
|
||||||
|
form.removeControl('confirmPassword');
|
||||||
|
form.removeValidators([MustMatch('password', 'confirmPassword')]);
|
||||||
|
} else {
|
||||||
|
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.addValidators([MustMatch('password', 'confirmPassword')]);
|
||||||
|
}
|
||||||
|
|
||||||
return form;
|
return form;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,10 +122,11 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
|
|||||||
}
|
}
|
||||||
|
|
||||||
submitForm() {
|
submitForm() {
|
||||||
const formValue = this.form.value as IPosRequest;
|
const formValue = this.form.value as IPosRequest & { confirmPassword?: string };
|
||||||
if (this.editMode) {
|
if (this.editMode) {
|
||||||
return this.service.update(this.businessActivityId, this.complexId, this.posId, formValue);
|
return this.service.update(this.businessActivityId, this.complexId, this.posId, formValue);
|
||||||
}
|
}
|
||||||
return this.service.create(this.businessActivityId, this.complexId, formValue);
|
const { confirmPassword, ...rest } = formValue;
|
||||||
|
return this.service.create(this.businessActivityId, this.complexId, rest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import ISummary from '@/core/models/summary';
|
|||||||
export interface IPosRawResponse {
|
export interface IPosRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number?: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
status: string;
|
status: string;
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
@@ -15,10 +15,10 @@ export interface IPosResponse extends IPosRawResponse {}
|
|||||||
|
|
||||||
export interface IPosRequest {
|
export interface IPosRequest {
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number: string;
|
||||||
model?: string;
|
|
||||||
status: string;
|
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
device_id: string;
|
device_id?: string;
|
||||||
provider_id: string;
|
provider_id?: string;
|
||||||
|
username?: string;
|
||||||
|
password?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
>
|
>
|
||||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
<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.name" name="name" />
|
||||||
<app-input label="سریال دستگاه" [control]="form.controls.serial" name="serial" />
|
<app-input label="سریال دستگاه" [control]="form.controls.serial_number" name="serial_number" />
|
||||||
<!-- <app-input label="مدل دستگاه" [control]="form.controls.model" name="model" /> -->
|
<!-- <app-input label="مدل دستگاه" [control]="form.controls.model" name="model" /> -->
|
||||||
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
||||||
@if (form.controls.pos_type.value === "PSP") {
|
@if (form.controls.pos_type.value === "PSP") {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export class ConsumerPosFormComponent extends AbstractFormDialog<IPosRequest, IP
|
|||||||
initForm = () => {
|
initForm = () => {
|
||||||
const form = this.fb.group({
|
const form = this.fb.group({
|
||||||
name: [this.initialValues?.name || '', [Validators.required]],
|
name: [this.initialValues?.name || '', [Validators.required]],
|
||||||
serial: [this.initialValues?.serial || '', [Validators.required]],
|
serial_number: [this.initialValues?.serial_number || '', [Validators.required]],
|
||||||
// model: [this.initialValues?.model || '', [Validators.required]],
|
// model: [this.initialValues?.model || '', [Validators.required]],
|
||||||
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
|
pos_type: [this.initialValues?.pos_type || '', [Validators.required]],
|
||||||
device_id: [this.initialValues?.device?.id || ''],
|
device_id: [this.initialValues?.device?.id || ''],
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import ISummary from '@/core/models/summary';
|
|||||||
export interface IPosRawResponse {
|
export interface IPosRawResponse {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
status: string;
|
status: string;
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
@@ -15,7 +15,7 @@ export interface IPosResponse extends IPosRawResponse {}
|
|||||||
|
|
||||||
export interface IPosRequest {
|
export interface IPosRequest {
|
||||||
name: string;
|
name: string;
|
||||||
serial: string;
|
serial_number: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
status: string;
|
status: string;
|
||||||
pos_type: string;
|
pos_type: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user