feat: add new form field components for company details and consumer management
- Implemented CompanyNameComponent, DescriptionComponent, DeviceIdComponent, EconomicCodeComponent, EmailComponent, FirstNameComponent, FiscalCodeComponent, GuildIdComponent, LastNameComponent, LegalNameComponent, LicenseStartsAtComponent, MobileComponent, MobileNumberComponent, ModelComponent, NameComponent, NationalCodeComponent, NationalIdComponent, PartnerTokenComponent, PosTypeComponent, PostalCodeComponent, ProviderIdComponent, QuantityComponent, RegistrationCodeComponent, RegistrationNumberComponent, SerialNumberComponent, SetOffComponent, SkuComponent, TerminalComponent, UnitPriceComponent, UsernameComponent. - Added field control configurations for new fields in the form. - Updated routing and branding configurations for TIS tenant. - Created consumer type models for handling individual and legal consumer data.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
header="ویرایش گذرواژه"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -14,4 +14,4 @@
|
||||
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
@@ -4,14 +4,14 @@ import { SharedPasswordInputComponent } from '@/shared/components';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IAccountRequest, IAccountResponse } from '../models';
|
||||
import { AccountsService } from '../services/main.service';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'account-password-form',
|
||||
templateUrl: './form.component.html',
|
||||
imports: [ReactiveFormsModule, Dialog, FormFooterActionsComponent, SharedPasswordInputComponent],
|
||||
imports: [ReactiveFormsModule, SharedDialogComponent, FormFooterActionsComponent, SharedPasswordInputComponent],
|
||||
})
|
||||
export class PartnerAccountPasswordFormComponent extends AbstractFormDialog<
|
||||
IAccountRequest,
|
||||
|
||||
+4
-1
@@ -7,7 +7,10 @@ export interface IAccountRawResponse {
|
||||
export interface IAccountResponse extends IAccountRawResponse {}
|
||||
|
||||
export interface IAccountRequest {
|
||||
name: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
role?: string;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface IAccountPasswordRequest {
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
/>
|
||||
|
||||
@if (selectedItemForEdit()) {
|
||||
<account-password-form
|
||||
<shared-change-password-form-dialog
|
||||
[(visible)]="visibleForm"
|
||||
[editMode]="editMode()"
|
||||
[accountId]="selectedItemForEdit()?.id!"
|
||||
[initialValues]="selectedItemForEdit() || undefined"
|
||||
(onSubmit)="refresh()"
|
||||
[title]="selectedItemForEdit()?.account?.username || ''"
|
||||
[loading]="passwordSubmitLoading()"
|
||||
(onSubmit)="updatePassword($event)"
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||
import {
|
||||
ChangePasswordFormDialogComponent,
|
||||
IChangePasswordSubmitPayload,
|
||||
} from '@/shared/components';
|
||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { PartnerAccountPasswordFormComponent } from '../components/form.component';
|
||||
import { finalize } from 'rxjs';
|
||||
import { partnerAccountsNamedRoutes } from '../constants';
|
||||
import { IAccountResponse } from '../models';
|
||||
import { AccountsService } from '../services/main.service';
|
||||
@@ -11,11 +15,12 @@ import { AccountsService } from '../services/main.service';
|
||||
@Component({
|
||||
selector: 'partner-accounts',
|
||||
templateUrl: './list.component.html',
|
||||
imports: [PageDataListComponent, PartnerAccountPasswordFormComponent],
|
||||
imports: [PageDataListComponent, ChangePasswordFormDialogComponent],
|
||||
})
|
||||
export class PartnerAccountsComponent extends AbstractList<IAccountResponse> {
|
||||
private readonly service = inject(AccountsService);
|
||||
private readonly router = inject(Router);
|
||||
passwordSubmitLoading = signal(false);
|
||||
|
||||
override setColumns(): void {
|
||||
this.columns = [
|
||||
@@ -48,4 +53,17 @@ export class PartnerAccountsComponent extends AbstractList<IAccountResponse> {
|
||||
toSinglePage(account: IAccountResponse) {
|
||||
this.router.navigateByUrl(partnerAccountsNamedRoutes.account.meta.pagePath!(account.id));
|
||||
}
|
||||
|
||||
updatePassword(payload: IChangePasswordSubmitPayload) {
|
||||
if (!this.selectedItemForEdit()?.id) return;
|
||||
|
||||
this.passwordSubmitLoading.set(true);
|
||||
this.service
|
||||
.update(this.selectedItemForEdit()!.id, { password: payload.password })
|
||||
.pipe(finalize(() => this.passwordSubmitLoading.set(false)))
|
||||
.subscribe(() => {
|
||||
this.visibleForm.set(false);
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
header="فرم کاربر"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -7,7 +7,7 @@
|
||||
(onHide)="close()"
|
||||
>
|
||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
||||
<app-input label="نام کاربری" [control]="form.controls.username" name="username" />
|
||||
<field-username [control]="form.controls.username" />
|
||||
<app-enum-select [control]="form.controls.role" name="role" type="consumerRole" />
|
||||
<shared-password-input
|
||||
[passwordControl]="form.controls.password"
|
||||
@@ -15,4 +15,4 @@
|
||||
/>
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
@@ -2,21 +2,22 @@ import { MustMatch, password } from '@/core/validators';
|
||||
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
||||
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
|
||||
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
|
||||
import { SharedPasswordInputComponent, UsernameComponent } from '@/shared/components';
|
||||
import { fieldControl } from '@/shared/constants/fields';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IConsumerAccountRequest, IConsumerAccountResponse } from '../../models';
|
||||
import { PartnerConsumerAccountsService } from '../../services/accounts.service';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-account-form',
|
||||
templateUrl: './form.component.html',
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
Dialog,
|
||||
InputComponent,
|
||||
SharedDialogComponent,
|
||||
UsernameComponent,
|
||||
FormFooterActionsComponent,
|
||||
SharedPasswordInputComponent,
|
||||
EnumSelectComponent,
|
||||
@@ -35,7 +36,7 @@ export class ConsumerAccountFormComponent extends AbstractFormDialog<
|
||||
if (this.editMode) {
|
||||
return this.fb.group(
|
||||
{
|
||||
username: [this.initialValues?.account.username || '', [Validators.required]],
|
||||
username: fieldControl.username(this.initialValues?.account.username || ''),
|
||||
password: ['', [password()]],
|
||||
confirmPassword: [''],
|
||||
},
|
||||
@@ -46,7 +47,7 @@ export class ConsumerAccountFormComponent extends AbstractFormDialog<
|
||||
}
|
||||
return this.fb.group(
|
||||
{
|
||||
username: [this.initialValues?.account.username || '', [Validators.required]],
|
||||
username: fieldControl.username(this.initialValues?.account.username || ''),
|
||||
role: ['', [Validators.required]],
|
||||
password: ['', [Validators.required, password()]],
|
||||
confirmPassword: ['', [Validators.required]],
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
<shared-dialog
|
||||
header="ایجاد فعالیت اقتصادی"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
[style]="{ width: '520px' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
<p-stepper [value]="activeStep()" [linear]="true">
|
||||
<p-step-list>
|
||||
<p-step [value]="1">فعالیت اقتصادی</p-step>
|
||||
<p-step [value]="2" [disabled]="!businessActivity()">فروشگاه</p-step>
|
||||
<p-step [value]="3" [disabled]="!complex()">پایانهی فروشگاهی</p-step>
|
||||
</p-step-list>
|
||||
</p-stepper>
|
||||
|
||||
<div class="mt-6">
|
||||
@switch (activeStep()) {
|
||||
@case (1) {
|
||||
<partner-consumer-businessActivities-form-content
|
||||
[consumerId]="consumerId"
|
||||
(onSubmit)="onBusinessActivitySubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
@case (2) {
|
||||
<partner-consumer-complex-form-content
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessActivity()?.id || ''"
|
||||
(onSubmit)="onComplexSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
@case (3) {
|
||||
<partner-consumer-pos-form-content
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessActivity()?.id || ''"
|
||||
[complexId]="complex()?.id || ''"
|
||||
(onSubmit)="onPosSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</shared-dialog>
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
import { Component, effect, EventEmitter, Input, Output, signal } from '@angular/core';
|
||||
import { Step, StepList, Stepper } from 'primeng/stepper';
|
||||
import { IBusinessActivityResponse, IComplexResponse, IPosResponse } from '../../../models';
|
||||
import { ConsumerComplexFormContentComponent } from '../../complexes/form.component';
|
||||
import { ConsumerPosFormContentComponent } from '../../poses/form.component';
|
||||
import { ConsumerBusinessActivitiesFormComponent } from '../form.component';
|
||||
|
||||
export interface ICreateBusinessActivityStepperResult {
|
||||
businessActivity: IBusinessActivityResponse;
|
||||
complex: IComplexResponse;
|
||||
pos: IPosResponse;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-businessActivities-create-wrapper',
|
||||
templateUrl: './create-wrapper.component.html',
|
||||
imports: [
|
||||
SharedDialogComponent,
|
||||
Stepper,
|
||||
StepList,
|
||||
Step,
|
||||
ConsumerBusinessActivitiesFormComponent,
|
||||
ConsumerComplexFormContentComponent,
|
||||
ConsumerPosFormContentComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerBusinessActivitiesCreateWrapperComponent extends AbstractDialog {
|
||||
@Input({ required: true }) consumerId!: string;
|
||||
@Output() onSubmit = new EventEmitter<ICreateBusinessActivityStepperResult>();
|
||||
|
||||
activeStep = signal(1);
|
||||
businessActivity = signal<IBusinessActivityResponse | null>(null);
|
||||
complex = signal<IComplexResponse | null>(null);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
effect(() => {
|
||||
if (this.visible) {
|
||||
this.resetWizard();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onBusinessActivitySubmit(response: IBusinessActivityResponse) {
|
||||
this.businessActivity.set(response);
|
||||
this.activeStep.set(2);
|
||||
}
|
||||
|
||||
onComplexSubmit(response: IComplexResponse) {
|
||||
this.complex.set(response);
|
||||
this.activeStep.set(3);
|
||||
}
|
||||
|
||||
onPosSubmit(response: IPosResponse) {
|
||||
const businessActivity = this.businessActivity();
|
||||
const complex = this.complex();
|
||||
|
||||
if (!businessActivity || !complex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onSubmit.emit({
|
||||
businessActivity,
|
||||
complex,
|
||||
pos: response,
|
||||
});
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
override close() {
|
||||
this.resetWizard();
|
||||
super.close();
|
||||
}
|
||||
|
||||
private resetWizard() {
|
||||
this.activeStep.set(1);
|
||||
this.businessActivity.set(null);
|
||||
this.complex.set(null);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
[header]="preparedTitle"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -14,4 +14,4 @@
|
||||
(onSubmit)="onFormSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IBusinessActivityResponse } from '../../models';
|
||||
import { ConsumerBusinessActivitiesFormComponent } from './form.component';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-businessActivities-form',
|
||||
templateUrl: './form-dialog.component.html',
|
||||
imports: [Dialog, ConsumerBusinessActivitiesFormComponent],
|
||||
imports: [SharedDialogComponent, ConsumerBusinessActivitiesFormComponent],
|
||||
})
|
||||
export class ConsumerBusinessActivitiesFormDialogComponent extends AbstractDialog {
|
||||
@Output() onSubmit = new EventEmitter<IBusinessActivityResponse>();
|
||||
|
||||
+6
-7
@@ -1,15 +1,14 @@
|
||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
||||
<app-input label="عنوان" [control]="$any(form).controls.name" name="name" />
|
||||
<app-input label="کد اقتصادی" [control]="$any(form).controls.economic_code" name="economic_code" />
|
||||
<catalog-guild-select label="صنف" [control]="$any(form).controls.guild_id" name="guild_id" />
|
||||
<field-name [control]="$any(form).controls.name" />
|
||||
<field-economic-code [control]="$any(form).controls.economic_code" />
|
||||
<field-fiscal-code [control]="$any(form).controls.fiscal_code" />
|
||||
<field-partner-token [control]="$any(form).controls.partner_token" />
|
||||
<field-guild-id [control]="$any(form).controls.guild_id" />
|
||||
|
||||
@if (!editMode) {
|
||||
<p-divider align="center"> اطلاعات لایسنس </p-divider>
|
||||
<uikit-datepicker
|
||||
label="تاریخ شروع لایسنس"
|
||||
<field-license-starts-at
|
||||
[control]="$any(form).controls.license_starts_at"
|
||||
name="license_starts_at"
|
||||
hint="مدت زمان لایسنسها ۱ ساله هستند."
|
||||
/>
|
||||
}
|
||||
|
||||
|
||||
+22
-11
@@ -1,10 +1,16 @@
|
||||
import { AbstractForm } from '@/shared/abstractClasses';
|
||||
import { CatalogGuildSelectComponent } from '@/shared/catalog/guild/components/select.component';
|
||||
import { InputComponent } from '@/shared/components';
|
||||
import {
|
||||
EconomicCodeComponent,
|
||||
FiscalCodeComponent,
|
||||
GuildIdComponent,
|
||||
LicenseStartsAtComponent,
|
||||
NameComponent,
|
||||
PartnerTokenComponent,
|
||||
} from '@/shared/components';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
||||
import { fieldControl } from '@/shared/constants/fields';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { Divider } from 'primeng/divider';
|
||||
import { IBusinessActivityRequest, IBusinessActivityResponse } from '../../models';
|
||||
import { PartnerConsumerBusinessActivitiesService } from '../../services/businessActivities.service';
|
||||
@@ -14,11 +20,14 @@ import { PartnerConsumerBusinessActivitiesService } from '../../services/busines
|
||||
templateUrl: './form.component.html',
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
InputComponent,
|
||||
NameComponent,
|
||||
EconomicCodeComponent,
|
||||
FiscalCodeComponent,
|
||||
PartnerTokenComponent,
|
||||
GuildIdComponent,
|
||||
LicenseStartsAtComponent,
|
||||
FormFooterActionsComponent,
|
||||
CatalogGuildSelectComponent,
|
||||
Divider,
|
||||
UikitFlatpickrJalaliComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerBusinessActivitiesFormComponent extends AbstractForm<
|
||||
@@ -32,9 +41,11 @@ export class ConsumerBusinessActivitiesFormComponent extends AbstractForm<
|
||||
|
||||
initForm = () => {
|
||||
const form = this.fb.group({
|
||||
name: [this.initialValues?.name || '', [Validators.required]],
|
||||
economic_code: [this.initialValues?.economic_code || '', [Validators.required]],
|
||||
guild_id: [this.initialValues?.guild?.id || '', [Validators.required]],
|
||||
name: fieldControl.name(this.initialValues?.name || ''),
|
||||
economic_code: fieldControl.economic_code(this.initialValues?.economic_code || ''),
|
||||
fiscal_code: fieldControl.fiscal_code(this.initialValues?.fiscal_code || ''),
|
||||
partner_token: fieldControl.partner_token(this.initialValues?.partner_token || ''),
|
||||
guild_id: fieldControl.guild_id(this.initialValues?.guild?.id || ''),
|
||||
license_starts_at: [''],
|
||||
});
|
||||
|
||||
@@ -46,7 +57,7 @@ export class ConsumerBusinessActivitiesFormComponent extends AbstractForm<
|
||||
'license_starts_at',
|
||||
this.fb.control<string>('', {
|
||||
nonNullable: true,
|
||||
validators: [Validators.required],
|
||||
validators: fieldControl.license_starts_at('')[1],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
+6
-1
@@ -16,9 +16,14 @@
|
||||
(onRefresh)="refresh()"
|
||||
>
|
||||
</app-page-data-list>
|
||||
<partner-consumer-businessActivities-create-wrapper
|
||||
[(visible)]="visibleCreateForm"
|
||||
[consumerId]="consumerId"
|
||||
(onSubmit)="refresh()"
|
||||
/>
|
||||
<partner-consumer-businessActivities-form
|
||||
[(visible)]="visibleForm"
|
||||
[editMode]="editMode()"
|
||||
[editMode]="true"
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="selectedItemForEdit()?.id || ''"
|
||||
[initialValues]="selectedItemForEdit() || undefined"
|
||||
|
||||
+12
-2
@@ -4,17 +4,22 @@ import {
|
||||
IColumn,
|
||||
PageDataListComponent,
|
||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { Component, inject, Input, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { partnerConsumerBusinessActivitiesNamedRoutes } from '../../constants/routes/businessActivities';
|
||||
import { IBusinessActivityResponse } from '../../models';
|
||||
import { PartnerConsumerBusinessActivitiesService } from '../../services/businessActivities.service';
|
||||
import { ConsumerBusinessActivitiesCreateWrapperComponent } from './create-wrapper/create-wrapper.component';
|
||||
import { ConsumerBusinessActivitiesFormDialogComponent } from './form-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-businessActivities-list',
|
||||
templateUrl: './list.component.html',
|
||||
imports: [PageDataListComponent, ConsumerBusinessActivitiesFormDialogComponent],
|
||||
imports: [
|
||||
PageDataListComponent,
|
||||
ConsumerBusinessActivitiesFormDialogComponent,
|
||||
ConsumerBusinessActivitiesCreateWrapperComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessActivityResponse> {
|
||||
@Input({ required: true }) consumerId!: string;
|
||||
@@ -50,6 +55,7 @@ export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessA
|
||||
|
||||
private readonly service = inject(PartnerConsumerBusinessActivitiesService);
|
||||
private readonly router = inject(Router);
|
||||
visibleCreateForm = signal(false);
|
||||
|
||||
override setColumns(): void {
|
||||
this.columns = this.header;
|
||||
@@ -59,6 +65,10 @@ export class ConsumerBusinessActivitiesComponent extends AbstractList<IBusinessA
|
||||
return this.service.getAll(this.consumerId);
|
||||
}
|
||||
|
||||
override openAddForm() {
|
||||
this.visibleCreateForm.set(true);
|
||||
}
|
||||
|
||||
toSinglePage(item: IBusinessActivityResponse) {
|
||||
this.router.navigateByUrl(
|
||||
partnerConsumerBusinessActivitiesNamedRoutes.businessActivity.meta.pagePath!(
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
header="شارژ کاربر"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -10,4 +10,4 @@
|
||||
<app-input label="تعداد شارژ کاربران" [control]="form.controls.quantity" type="number" [min]="1" />
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
+7
-2
@@ -3,14 +3,19 @@ import { InputComponent } from '@/shared/components';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IPartnerChargeAccountRequest } from '../../models';
|
||||
import { PartnerChargeAccountService } from '../../services/chargeAccount.service';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-charge-account-form-dialog',
|
||||
templateUrl: './charge-account-form-dialog.component.html',
|
||||
imports: [Dialog, ReactiveFormsModule, InputComponent, FormFooterActionsComponent],
|
||||
imports: [
|
||||
SharedDialogComponent,
|
||||
ReactiveFormsModule,
|
||||
InputComponent,
|
||||
FormFooterActionsComponent,
|
||||
],
|
||||
})
|
||||
export class PartnerChargeAccountFormDialogComponent extends AbstractFormDialog<
|
||||
IPartnerChargeAccountRequest,
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
<shared-dialog
|
||||
header="ایجاد فروشگاه"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
[style]="{ width: '400px' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
<p-stepper [value]="activeStep()" [linear]="true">
|
||||
<p-step-list>
|
||||
<p-step [value]="1">فروشگاه</p-step>
|
||||
<p-step [value]="2" [disabled]="!complex()">پایانهی روشگاهی</p-step>
|
||||
</p-step-list>
|
||||
</p-stepper>
|
||||
|
||||
<div class="mt-6">
|
||||
@switch (activeStep()) {
|
||||
@case (1) {
|
||||
<partner-consumer-complex-form-content
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessActivityId"
|
||||
(onSubmit)="onComplexSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
@case (2) {
|
||||
<partner-consumer-pos-form-content
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessActivityId"
|
||||
[complexId]="complex()?.id || ''"
|
||||
(onSubmit)="onPosSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</shared-dialog>
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
import { Component, effect, EventEmitter, Input, Output, signal } from '@angular/core';
|
||||
import { Step, StepList, Stepper } from 'primeng/stepper';
|
||||
import { IComplexResponse, IPosResponse } from '../../../models';
|
||||
import { ConsumerPosFormContentComponent } from '../../poses/form.component';
|
||||
import { ConsumerComplexFormContentComponent } from '../form.component';
|
||||
|
||||
export interface ICreateComplexStepperResult {
|
||||
complex: IComplexResponse;
|
||||
pos: IPosResponse;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-complexes-create-wrapper',
|
||||
templateUrl: './create-wrapper.component.html',
|
||||
imports: [
|
||||
SharedDialogComponent,
|
||||
Stepper,
|
||||
StepList,
|
||||
Step,
|
||||
ConsumerComplexFormContentComponent,
|
||||
ConsumerPosFormContentComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerComplexesCreateWrapperComponent extends AbstractDialog {
|
||||
@Input({ required: true }) consumerId!: string;
|
||||
@Input({ required: true }) businessActivityId!: string;
|
||||
@Output() onSubmit = new EventEmitter<ICreateComplexStepperResult>();
|
||||
|
||||
activeStep = signal(1);
|
||||
complex = signal<IComplexResponse | null>(null);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
effect(() => {
|
||||
if (this.visible) {
|
||||
this.resetWizard();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onComplexSubmit(response: IComplexResponse) {
|
||||
this.complex.set(response);
|
||||
this.activeStep.set(2);
|
||||
}
|
||||
|
||||
onPosSubmit(response: IPosResponse) {
|
||||
const complex = this.complex();
|
||||
if (!complex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onSubmit.emit({
|
||||
complex,
|
||||
pos: response,
|
||||
});
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
override close() {
|
||||
this.resetWizard();
|
||||
super.close();
|
||||
}
|
||||
|
||||
private resetWizard() {
|
||||
this.activeStep.set(1);
|
||||
this.complex.set(null);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
[header]="preparedTitle"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -15,4 +15,4 @@
|
||||
(onSubmit)="onFormSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IComplexResponse } from '../../models';
|
||||
import { ConsumerComplexFormContentComponent } from './form.component';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-complex-form',
|
||||
templateUrl: './form-dialog.component.html',
|
||||
imports: [Dialog, ConsumerComplexFormContentComponent],
|
||||
imports: [SharedDialogComponent, ConsumerComplexFormContentComponent],
|
||||
})
|
||||
export class ConsumerComplexFormDialogComponent extends AbstractDialog {
|
||||
@Output() onSubmit = new EventEmitter<IComplexResponse>();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<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.branch_code" name="branch_code" />
|
||||
<app-input label="آدرس" [control]="form.controls.address" name="address" />
|
||||
<field-name [control]="form.controls.name" />
|
||||
<field-branch-code [control]="form.controls.branch_code" />
|
||||
<field-address [control]="form.controls.address" />
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
|
||||
@@ -1,16 +1,27 @@
|
||||
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
||||
import { AbstractForm } from '@/shared/abstractClasses';
|
||||
import { InputComponent } from '@/shared/components';
|
||||
import {
|
||||
NameComponent,
|
||||
AddressComponent,
|
||||
BranchCodeComponent,
|
||||
} from '@/shared/components';
|
||||
import { fieldControl } from '@/shared/constants/fields';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { IComplexRequest, IComplexResponse } from '../../models';
|
||||
import { PartnerComplexesService } from '../../services/complexes.service';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-complex-form-content',
|
||||
templateUrl: './form.component.html',
|
||||
imports: [ReactiveFormsModule, InputComponent, FormFooterActionsComponent],
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
NameComponent,
|
||||
BranchCodeComponent,
|
||||
AddressComponent,
|
||||
FormFooterActionsComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerComplexFormContentComponent extends AbstractForm<
|
||||
IComplexRequest,
|
||||
@@ -24,9 +35,9 @@ export class ConsumerComplexFormContentComponent extends AbstractForm<
|
||||
|
||||
initForm = () => {
|
||||
return this.fb.group({
|
||||
name: [this.initialValues?.name || '', [Validators.required]],
|
||||
branch_code: [this.initialValues?.branch_code || ''],
|
||||
address: [this.initialValues?.address || '', [Validators.required]],
|
||||
name: fieldControl.name(this.initialValues?.name || ''),
|
||||
branch_code: fieldControl.branch_code(this.initialValues?.branch_code || ''),
|
||||
address: fieldControl.address(this.initialValues?.address || ''),
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -16,9 +16,15 @@
|
||||
(onRefresh)="refresh()"
|
||||
>
|
||||
</app-page-data-list>
|
||||
<partner-consumer-complexes-create-wrapper
|
||||
[(visible)]="visibleCreateForm"
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessId"
|
||||
(onSubmit)="refresh()"
|
||||
/>
|
||||
<partner-consumer-complex-form
|
||||
[(visible)]="visibleForm"
|
||||
[editMode]="editMode()"
|
||||
[editMode]="true"
|
||||
[consumerId]="consumerId"
|
||||
[businessActivityId]="businessId"
|
||||
[complexId]="selectedItemForEdit()?.id || ''"
|
||||
|
||||
@@ -4,17 +4,22 @@ import {
|
||||
IColumn,
|
||||
PageDataListComponent,
|
||||
} from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { Component, inject, Input, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { partnerConsumerComplexesNamedRoutes } from '../../constants/routes/complexes';
|
||||
import { IComplexResponse } from '../../models';
|
||||
import { PartnerComplexesService } from '../../services/complexes.service';
|
||||
import { ConsumerComplexesCreateWrapperComponent } from './create-wrapper/create-wrapper.component';
|
||||
import { ConsumerComplexFormDialogComponent } from './form-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-complexes-list',
|
||||
templateUrl: './list.component.html',
|
||||
imports: [PageDataListComponent, ConsumerComplexFormDialogComponent],
|
||||
imports: [
|
||||
PageDataListComponent,
|
||||
ConsumerComplexFormDialogComponent,
|
||||
ConsumerComplexesCreateWrapperComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
||||
@Input() consumerId!: string;
|
||||
@@ -23,6 +28,8 @@ export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
||||
@Input() header: IColumn[] = [
|
||||
{ field: 'id', header: 'شناسه', type: 'id' },
|
||||
{ field: 'name', header: 'عنوان' },
|
||||
{ field: 'branch_code', header: 'کد شعبه' },
|
||||
{ field: 'pos_count', header: 'تعداد پایانهها' },
|
||||
{
|
||||
field: 'created_at',
|
||||
header: 'تاریخ ایجاد',
|
||||
@@ -32,6 +39,7 @@ export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
||||
|
||||
private readonly service = inject(PartnerComplexesService);
|
||||
private readonly router = inject(Router);
|
||||
visibleCreateForm = signal(false);
|
||||
|
||||
override setColumns(): void {
|
||||
this.columns = this.header;
|
||||
@@ -41,6 +49,10 @@ export class ConsumerComplexesComponent extends AbstractList<IComplexResponse> {
|
||||
return this.service.getAll(this.consumerId, this.businessId);
|
||||
}
|
||||
|
||||
override openAddForm() {
|
||||
this.visibleCreateForm.set(true);
|
||||
}
|
||||
|
||||
toSinglePage(item: IComplexResponse) {
|
||||
this.router.navigateByUrl(
|
||||
partnerConsumerComplexesNamedRoutes.complex.meta.pagePath!(
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
<shared-dialog
|
||||
header="ایجاد مشتری جدید"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
[style]="{ width: '640px' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
<p-stepper [value]="activeStep()" [linear]="true">
|
||||
<p-step-list>
|
||||
<p-step [value]="1">اطلاعات اولیه</p-step>
|
||||
<p-step [value]="2" [disabled]="!consumer()">فعالیت اقتصادی</p-step>
|
||||
<p-step [value]="3" [disabled]="!businessActivity()">فروشگاه</p-step>
|
||||
<p-step [value]="4" [disabled]="!complex()">پایانهی فروشگاهی</p-step>
|
||||
</p-step-list>
|
||||
</p-stepper>
|
||||
|
||||
<div class="mt-6">
|
||||
@switch (activeStep()) {
|
||||
@case (1) {
|
||||
<partner-consumer-form-content (onSubmit)="onConsumerSubmit($event)" (onClose)="close()" />
|
||||
}
|
||||
@case (2) {
|
||||
<partner-consumer-businessActivities-form-content
|
||||
[consumerId]="consumer()?.id || ''"
|
||||
(onSubmit)="onBusinessActivitySubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
@case (3) {
|
||||
<partner-consumer-complex-form-content
|
||||
[consumerId]="consumer()?.id || ''"
|
||||
[businessActivityId]="businessActivity()?.id || ''"
|
||||
(onSubmit)="onComplexSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
@case (4) {
|
||||
<partner-consumer-pos-form-content
|
||||
[consumerId]="consumer()?.id || ''"
|
||||
[businessActivityId]="businessActivity()?.id || ''"
|
||||
[complexId]="complex()?.id || ''"
|
||||
(onSubmit)="onPosSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</shared-dialog>
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { Component, effect, EventEmitter, Output, signal } from '@angular/core';
|
||||
import { Step, StepList, Stepper } from 'primeng/stepper';
|
||||
import {
|
||||
IBusinessActivityResponse,
|
||||
IComplexResponse,
|
||||
IPartnerConsumerResponse,
|
||||
IPosResponse,
|
||||
} from '../../models';
|
||||
import { ConsumerBusinessActivitiesFormComponent } from '../businessActivities/form.component';
|
||||
import { ConsumerComplexFormContentComponent } from '../complexes/form.component';
|
||||
import { ConsumerUserFormContentComponent } from '../form.component';
|
||||
import { ConsumerPosFormContentComponent } from '../poses/form.component';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
export interface ICreateConsumerStepperResult {
|
||||
consumer: IPartnerConsumerResponse;
|
||||
businessActivity: IBusinessActivityResponse;
|
||||
complex: IComplexResponse;
|
||||
pos: IPosResponse;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'partner-create-consumer-wrapper',
|
||||
templateUrl: './create-consumer-wrapper.component.html',
|
||||
imports: [
|
||||
Stepper,
|
||||
StepList,
|
||||
Step,
|
||||
ConsumerUserFormContentComponent,
|
||||
ConsumerBusinessActivitiesFormComponent,
|
||||
ConsumerComplexFormContentComponent,
|
||||
ConsumerPosFormContentComponent,
|
||||
SharedDialogComponent,
|
||||
],
|
||||
})
|
||||
export class CreateConsumerWrapperComponent extends AbstractDialog {
|
||||
@Output() onSubmit = new EventEmitter<ICreateConsumerStepperResult>();
|
||||
|
||||
activeStep = signal(1);
|
||||
consumer = signal<IPartnerConsumerResponse | null>(null);
|
||||
businessActivity = signal<IBusinessActivityResponse | null>(null);
|
||||
complex = signal<IComplexResponse | null>(null);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
effect(() => {
|
||||
if (this.visible) {
|
||||
this.resetWizard();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onConsumerSubmit(response: IPartnerConsumerResponse) {
|
||||
this.consumer.set(response);
|
||||
this.activeStep.set(2);
|
||||
}
|
||||
|
||||
onBusinessActivitySubmit(response: IBusinessActivityResponse) {
|
||||
this.businessActivity.set(response);
|
||||
this.activeStep.set(3);
|
||||
}
|
||||
|
||||
onComplexSubmit(response: IComplexResponse) {
|
||||
this.complex.set(response);
|
||||
this.activeStep.set(4);
|
||||
}
|
||||
|
||||
onPosSubmit(response: IPosResponse) {
|
||||
const consumer = this.consumer();
|
||||
const businessActivity = this.businessActivity();
|
||||
const complex = this.complex();
|
||||
|
||||
if (!consumer || !businessActivity || !complex) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.onSubmit.emit({
|
||||
consumer,
|
||||
businessActivity,
|
||||
complex,
|
||||
pos: response,
|
||||
});
|
||||
|
||||
this.close();
|
||||
}
|
||||
|
||||
override close() {
|
||||
this.resetWizard();
|
||||
super.close();
|
||||
}
|
||||
|
||||
private resetWizard() {
|
||||
this.activeStep.set(1);
|
||||
this.consumer.set(null);
|
||||
this.businessActivity.set(null);
|
||||
this.complex.set(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<shared-dialog
|
||||
[header]="preparedTitle"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
[style]="{ width: '500px' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
<partner-consumer-form-content
|
||||
[consumerId]="consumerId"
|
||||
[initialValues]="initialValues"
|
||||
[editMode]="editMode"
|
||||
(onSubmit)="onFormSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
</shared-dialog>
|
||||
@@ -0,0 +1,27 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { IPartnerConsumerResponse } from '../models';
|
||||
import { ConsumerUserFormContentComponent } from './form.component';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-form',
|
||||
templateUrl: './form-dialog.component.html',
|
||||
imports: [SharedDialogComponent, ConsumerUserFormContentComponent],
|
||||
})
|
||||
export class ConsumerUserFormDialogComponent extends AbstractDialog {
|
||||
@Output() onSubmit = new EventEmitter<IPartnerConsumerResponse>();
|
||||
@Input() initialValues?: IPartnerConsumerResponse;
|
||||
@Input() editMode?: boolean;
|
||||
|
||||
@Input() consumerId?: string;
|
||||
|
||||
get preparedTitle() {
|
||||
return `${this.editMode ? 'ویرایش' : 'ایجاد'} مشتری`;
|
||||
}
|
||||
|
||||
onFormSubmit(response: IPartnerConsumerResponse) {
|
||||
this.onSubmit.emit(response);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,32 @@
|
||||
<p-dialog
|
||||
[header]="preparedTitle()"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
[style]="{ width: '500px' }"
|
||||
[closable]="true"
|
||||
(onHide)="close()"
|
||||
>
|
||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
||||
<app-input label="نام" [control]="form.controls.first_name" name="first_name" />
|
||||
<app-input label="نام خانوادگی" [control]="form.controls.last_name" name="last_name" />
|
||||
<app-input label="موبایل" [control]="form.controls.mobile_number" name="mobile_number" type="mobile" />
|
||||
<app-input label="کد ملی" [control]="form.controls.national_code" name="national_code" type="nationalId" />
|
||||
@if (!editMode) {
|
||||
<p-selectbutton
|
||||
[options]="consumerTypes"
|
||||
[(ngModel)]="selectedType"
|
||||
optionValue="value"
|
||||
optionLabel="name"
|
||||
(onChange)="changeType($event.value)"
|
||||
></p-selectbutton>
|
||||
}
|
||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4 mt-4">
|
||||
@if (selectedType() === "INDIVIDUAL" && form.controls.individual) {
|
||||
<field-first-name [control]="form.controls.individual.controls.first_name" />
|
||||
<field-last-name [control]="form.controls.individual.controls.last_name" />
|
||||
<field-mobile-number [control]="form.controls.individual.controls.mobile_number" />
|
||||
<field-national-code [control]="form.controls.individual.controls.national_code" />
|
||||
} @else if (form.controls.legal) {
|
||||
<field-legal-name [control]="form.controls.legal.controls.name" />
|
||||
<field-registration-code [control]="form.controls.legal.controls.registration_code" />
|
||||
}
|
||||
|
||||
@if (!editMode) {
|
||||
<p-divider align="center"> اطلاعات ورود </p-divider>
|
||||
<!-- @ts-ignore -->
|
||||
<app-input label="نام کاربری" [control]="form.controls.username" name="username" [isLtrInput]="true" />
|
||||
<shared-password-input
|
||||
[passwordControl]="form.controls.password"
|
||||
[confirmPasswordControl]="form.controls.confirmPassword"
|
||||
/>
|
||||
<p-divider align="center"> اطلاعات لایسنس </p-divider>
|
||||
<uikit-datepicker
|
||||
label="تاریخ شروع لایسنس"
|
||||
[control]="form.controls.license_starts_at"
|
||||
name="license_starts_at"
|
||||
hint="مدت زمان لایسنسها ۱ ساله هستند."
|
||||
/>
|
||||
}
|
||||
@if (!editMode) {
|
||||
<p-divider align="center"> اطلاعات ورود </p-divider>
|
||||
<!-- @ts-ignore -->
|
||||
<field-username [control]="form.controls.username" />
|
||||
<shared-password-input
|
||||
[passwordControl]="form.controls.password"
|
||||
[confirmPasswordControl]="form.controls.confirmPassword"
|
||||
/>
|
||||
}
|
||||
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
</p-dialog>
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
|
||||
@@ -1,55 +1,88 @@
|
||||
import { mobileValidator, MustMatch } from '@/core/validators';
|
||||
import { nationalIdValidator } from '@/core/validators/national-id.validator';
|
||||
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
|
||||
import { MustMatch } from '@/core/validators';
|
||||
import { AbstractForm } from '@/shared/abstractClasses';
|
||||
import { fieldControl } from '@/shared/constants/fields';
|
||||
import {
|
||||
FirstNameComponent,
|
||||
LastNameComponent,
|
||||
LegalNameComponent,
|
||||
MobileNumberComponent,
|
||||
NationalCodeComponent,
|
||||
RegistrationCodeComponent,
|
||||
SharedPasswordInputComponent,
|
||||
UsernameComponent,
|
||||
} from '@/shared/components';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
||||
import { nowJalali } from '@/utils';
|
||||
import { Component, computed, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { Component, inject, Input, signal } from '@angular/core';
|
||||
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
import { Divider } from 'primeng/divider';
|
||||
import { IConsumerRequest, IConsumerResponse } from '../models';
|
||||
import { SelectButton } from 'primeng/selectbutton';
|
||||
import { IPartnerConsumerRequest, IPartnerConsumerResponse } from '../models';
|
||||
import { ConsumersService } from '../services/main.service';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-form',
|
||||
selector: 'partner-consumer-form-content',
|
||||
templateUrl: './form.component.html',
|
||||
imports: [
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
Dialog,
|
||||
InputComponent,
|
||||
FirstNameComponent,
|
||||
LastNameComponent,
|
||||
MobileNumberComponent,
|
||||
NationalCodeComponent,
|
||||
LegalNameComponent,
|
||||
RegistrationCodeComponent,
|
||||
UsernameComponent,
|
||||
FormFooterActionsComponent,
|
||||
Divider,
|
||||
UikitFlatpickrJalaliComponent,
|
||||
SharedPasswordInputComponent,
|
||||
SelectButton,
|
||||
],
|
||||
})
|
||||
export class ConsumerUserFormComponent extends AbstractFormDialog<
|
||||
IConsumerRequest,
|
||||
IConsumerResponse
|
||||
export class ConsumerUserFormContentComponent extends AbstractForm<
|
||||
IPartnerConsumerRequest,
|
||||
IPartnerConsumerResponse
|
||||
> {
|
||||
@Input() consumerId?: string;
|
||||
private service = inject(ConsumersService);
|
||||
|
||||
preparedTitle = computed(() => `${this.editMode ? 'ویرایش' : 'ایجاد'} مشتری`);
|
||||
consumerTypes = [
|
||||
{
|
||||
value: 'INDIVIDUAL',
|
||||
name: 'حقیقی',
|
||||
},
|
||||
{
|
||||
value: 'LEGAL',
|
||||
name: 'حقوقی',
|
||||
},
|
||||
];
|
||||
|
||||
selectedType = signal<string>(this.initialValues?.type || this.consumerTypes[0].value);
|
||||
|
||||
initForm = () => {
|
||||
this.selectedType.set(this.initialValues?.type || this.consumerTypes[0].value);
|
||||
const legal = this.fb.group({
|
||||
name: fieldControl.legal_name(this.initialValues?.legal?.name || ''),
|
||||
registration_code: fieldControl.registration_code(
|
||||
this.initialValues?.legal?.registration_code || '',
|
||||
),
|
||||
});
|
||||
const individual = this.fb.group({
|
||||
first_name: fieldControl.first_name(this.initialValues?.individual?.first_name || ''),
|
||||
last_name: fieldControl.last_name(this.initialValues?.individual?.last_name || ''),
|
||||
mobile_number: fieldControl.mobile_number(
|
||||
this.initialValues?.individual?.mobile_number || '',
|
||||
),
|
||||
national_code: fieldControl.national_code(
|
||||
this.initialValues?.individual?.national_code || '',
|
||||
),
|
||||
});
|
||||
const form = this.fb.group({
|
||||
first_name: [this.initialValues?.first_name || '', [Validators.required]],
|
||||
last_name: [this.initialValues?.last_name || '', [Validators.required]],
|
||||
mobile_number: [
|
||||
this.initialValues?.mobile_number || '',
|
||||
[Validators.required, mobileValidator()],
|
||||
],
|
||||
national_code: [
|
||||
this.initialValues?.national_code || '',
|
||||
[Validators.required, nationalIdValidator()],
|
||||
],
|
||||
type: [this.initialValues?.type || this.consumerTypes[0].value, [Validators.required]],
|
||||
legal,
|
||||
individual,
|
||||
username: [''],
|
||||
password: [''],
|
||||
confirmPassword: [''],
|
||||
license_starts_at: [nowJalali(), [Validators.required]],
|
||||
});
|
||||
|
||||
if (this.editMode) {
|
||||
@@ -59,15 +92,13 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
|
||||
form.removeControl('password');
|
||||
// @ts-ignore
|
||||
form.removeControl('confirmPassword');
|
||||
// @ts-ignore
|
||||
form.removeControl('license_starts_at');
|
||||
form.removeValidators([MustMatch('password', 'confirmPassword')]);
|
||||
} else {
|
||||
form.addControl(
|
||||
'username',
|
||||
this.fb.control<string>('', {
|
||||
nonNullable: true,
|
||||
validators: [Validators.required],
|
||||
validators: fieldControl.username('')[1],
|
||||
}),
|
||||
);
|
||||
form.addControl(
|
||||
@@ -84,23 +115,43 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
|
||||
validators: [Validators.required],
|
||||
}),
|
||||
);
|
||||
form.addControl(
|
||||
'license_starts_at',
|
||||
this.fb.control<string>(nowJalali(), {
|
||||
nonNullable: true,
|
||||
validators: [Validators.required],
|
||||
}),
|
||||
);
|
||||
|
||||
form.addValidators([MustMatch('password', 'confirmPassword')]);
|
||||
}
|
||||
|
||||
if (form.controls.type.value === 'LEGAL') {
|
||||
// @ts-ignore
|
||||
form.addControl('legal', legal);
|
||||
// @ts-ignore
|
||||
form.removeControl('individual');
|
||||
} else {
|
||||
// @ts-ignore
|
||||
form.addControl('individual', individual);
|
||||
// @ts-ignore
|
||||
form.removeControl('legal');
|
||||
}
|
||||
|
||||
form.controls.type.valueChanges.subscribe((type) => {
|
||||
if (type === 'LEGAL') {
|
||||
// @ts-ignore
|
||||
form.addControl('legal', legal);
|
||||
// @ts-ignore
|
||||
form.removeControl('individual');
|
||||
} else {
|
||||
// @ts-ignore
|
||||
form.addControl('individual', individual);
|
||||
// @ts-ignore
|
||||
form.removeControl('legal');
|
||||
}
|
||||
});
|
||||
|
||||
return form;
|
||||
};
|
||||
|
||||
form = this.initForm();
|
||||
|
||||
override ngOnChanges() {
|
||||
this.form.patchValue(this.initialValues || {});
|
||||
this.form.patchValue((this.initialValues as any) || {});
|
||||
if (this.editMode && !this.consumerId) {
|
||||
throw 'missing some arguments';
|
||||
}
|
||||
@@ -108,7 +159,7 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
|
||||
this.form = this.initForm();
|
||||
}
|
||||
|
||||
override submitForm(payload: IConsumerRequest) {
|
||||
override submitForm(payload: IPartnerConsumerRequest) {
|
||||
if (this.editMode) {
|
||||
return this.service.update(this.consumerId!, payload);
|
||||
}
|
||||
@@ -116,4 +167,8 @@ export class ConsumerUserFormComponent extends AbstractFormDialog<
|
||||
const { confirmPassword, ...rest } = payload;
|
||||
return this.service.create(rest);
|
||||
}
|
||||
|
||||
changeType(newType: string) {
|
||||
this.form.controls.type.setValue(newType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
[header]="preparedTitle()"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -16,4 +16,4 @@
|
||||
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
|
||||
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
@@ -3,14 +3,19 @@ import { FormFooterActionsComponent } from '@/shared/components/formFooterAction
|
||||
import { UikitFlatpickrJalaliComponent } from '@/uikit';
|
||||
import { Component, computed, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { ILicenseRequest, ILicenseResponse } from '../../models';
|
||||
import { LicensesService } from '../../services/licenses.service';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-license-form',
|
||||
templateUrl: './form.component.html',
|
||||
imports: [ReactiveFormsModule, Dialog, FormFooterActionsComponent, UikitFlatpickrJalaliComponent],
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
SharedDialogComponent,
|
||||
FormFooterActionsComponent,
|
||||
UikitFlatpickrJalaliComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumerLicenseFormComponent extends AbstractFormDialog<
|
||||
ILicenseRequest,
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
<p-dialog
|
||||
<shared-dialog
|
||||
[header]="preparedTitle"
|
||||
[(visible)]="visible"
|
||||
[modal]="true"
|
||||
@@ -16,4 +16,4 @@
|
||||
(onSubmit)="onFormSubmit($event)"
|
||||
(onClose)="close()"
|
||||
/>
|
||||
</p-dialog>
|
||||
</shared-dialog>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Dialog } from 'primeng/dialog';
|
||||
import { IPosResponse } from '../../models';
|
||||
import { ConsumerPosFormContentComponent } from './form.component';
|
||||
import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumer-pos-form',
|
||||
templateUrl: './form-dialog.component.html',
|
||||
imports: [Dialog, ConsumerPosFormContentComponent],
|
||||
imports: [SharedDialogComponent, ConsumerPosFormContentComponent],
|
||||
})
|
||||
export class ConsumerPosFormDialogComponent extends AbstractDialog {
|
||||
@Output() onSubmit = new EventEmitter<IPosResponse>();
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
||||
<app-input label="عنوان" [control]="form.controls.name" name="name" />
|
||||
<app-enum-select [control]="form.controls.pos_type" type="posType" name="pos_type" />
|
||||
<field-name [control]="form.controls.name" />
|
||||
<field-pos-type [control]="form.controls.pos_type" />
|
||||
|
||||
@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" />
|
||||
<field-serial-number [control]="form.controls.serial_number" />
|
||||
<field-device-id [control]="form.controls.device_id" />
|
||||
<field-provider-id [control]="form.controls.provider_id" />
|
||||
}
|
||||
|
||||
@if (!editMode) {
|
||||
<p-divider align="center"> اطلاعات ورود </p-divider>
|
||||
<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,10 +1,16 @@
|
||||
// import { CatalogRolesComponent } from '@/shared/catalog/roles';
|
||||
import { MustMatch } from '@/core/validators';
|
||||
import { AbstractForm } from '@/shared/abstractClasses';
|
||||
import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
|
||||
import { CatalogProviderSelectComponent } from '@/shared/catalog';
|
||||
import { CatalogDeviceSelectComponent } from '@/shared/catalog/devices';
|
||||
import { InputComponent, SharedPasswordInputComponent } from '@/shared/components';
|
||||
import {
|
||||
NameComponent,
|
||||
SharedPasswordInputComponent,
|
||||
DeviceIdComponent,
|
||||
ProviderIdComponent,
|
||||
SerialNumberComponent,
|
||||
PosTypeComponent,
|
||||
UsernameComponent,
|
||||
} from '@/shared/components';
|
||||
import { fieldControl } from '@/shared/constants/fields';
|
||||
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
@@ -17,11 +23,13 @@ import { PartnerPosesService } from '../../services/poses.service';
|
||||
templateUrl: './form.component.html',
|
||||
imports: [
|
||||
ReactiveFormsModule,
|
||||
InputComponent,
|
||||
NameComponent,
|
||||
FormFooterActionsComponent,
|
||||
CatalogDeviceSelectComponent,
|
||||
CatalogProviderSelectComponent,
|
||||
EnumSelectComponent,
|
||||
DeviceIdComponent,
|
||||
ProviderIdComponent,
|
||||
PosTypeComponent,
|
||||
SerialNumberComponent,
|
||||
UsernameComponent,
|
||||
Divider,
|
||||
SharedPasswordInputComponent,
|
||||
],
|
||||
@@ -36,11 +44,11 @@ export class ConsumerPosFormContentComponent extends AbstractForm<IPosRequest, I
|
||||
|
||||
initForm = () => {
|
||||
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 || ''],
|
||||
name: fieldControl.name(this.initialValues?.name || ''),
|
||||
pos_type: fieldControl.pos_type(this.initialValues?.pos_type || ''),
|
||||
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: [''],
|
||||
@@ -81,13 +89,15 @@ 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: [Validators.required],
|
||||
validators: fieldControl.username('')[1],
|
||||
}),
|
||||
);
|
||||
// @ts-ignore
|
||||
form.addControl(
|
||||
'password',
|
||||
this.fb.control<string>('', {
|
||||
@@ -95,6 +105,7 @@ export class ConsumerPosFormContentComponent extends AbstractForm<IPosRequest, I
|
||||
validators: [Validators.required],
|
||||
}),
|
||||
);
|
||||
// @ts-ignore
|
||||
form.addControl(
|
||||
'confirmPassword',
|
||||
this.fb.control<string>('', {
|
||||
|
||||
+6
-2
@@ -4,6 +4,8 @@ export interface IBusinessActivityRawResponse {
|
||||
id: string;
|
||||
name: string;
|
||||
economic_code: string;
|
||||
fiscal_code: string;
|
||||
partner_token: string;
|
||||
guild: ISummary;
|
||||
created_at: string;
|
||||
license_info: LicenseInfo;
|
||||
@@ -13,9 +15,11 @@ export interface IBusinessActivityResponse extends IBusinessActivityRawResponse
|
||||
export interface IBusinessActivityRequest {
|
||||
name: string;
|
||||
economic_code: string;
|
||||
fiscal_code: string;
|
||||
partner_token: string;
|
||||
guild_id: string;
|
||||
username?: string;
|
||||
password?: string;
|
||||
license_starts_at?: string;
|
||||
expires_at?: string;
|
||||
}
|
||||
|
||||
interface LicenseInfo {
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
export interface IPartnerChargeAccountRawResponse {
|
||||
id: string;
|
||||
credit_id: string;
|
||||
license_activation_id: string;
|
||||
created_at: string;
|
||||
// tracking_code: string;
|
||||
// activation_expires_at: string;
|
||||
// charged_license_count: number;
|
||||
// activated_license_count: number;
|
||||
// remained_license_count: number;
|
||||
}
|
||||
|
||||
export interface IPartnerChargeAccountResponse extends IPartnerChargeAccountRawResponse {}
|
||||
|
||||
+4
-26
@@ -1,28 +1,6 @@
|
||||
export interface IConsumerRawResponse {
|
||||
id: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
mobile_number: string;
|
||||
national_code: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
fullname: string;
|
||||
license_info: ILicenseInfo;
|
||||
}
|
||||
export interface IConsumerResponse extends IConsumerRawResponse {}
|
||||
import { IConsumerRequest, IConsumerResponse } from '@/shared/models/consumer.type';
|
||||
|
||||
export interface IConsumerRequest {
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
mobile_number: string;
|
||||
national_code: string;
|
||||
username: string;
|
||||
password: string;
|
||||
license_starts_at: string;
|
||||
}
|
||||
export interface IPartnerConsumerRawResponse extends IConsumerResponse {}
|
||||
export interface IPartnerConsumerResponse extends IPartnerConsumerRawResponse {}
|
||||
|
||||
interface ILicenseInfo {
|
||||
id: string;
|
||||
starts_at: string;
|
||||
expires_at: string;
|
||||
}
|
||||
export interface IPartnerConsumerRequest extends IConsumerRequest {}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { PARTNER_BA_ACCOUNTS_CHARGE_API_ROUTES } from '../constants/apiRoutes/accountsCharge';
|
||||
import { IPartnerChargeAccountRequest } from '../models';
|
||||
import { IPartnerChargeAccountRequest, IPartnerChargeAccountResponse } from '../models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class PartnerChargeAccountService {
|
||||
@@ -20,8 +20,8 @@ export class PartnerChargeAccountService {
|
||||
consumerId: string,
|
||||
businessId: string,
|
||||
data: IPartnerChargeAccountRequest,
|
||||
): Observable<IPartnerChargeAccountRequest> {
|
||||
return this.http.post<IPartnerChargeAccountRequest>(
|
||||
): Observable<IPartnerChargeAccountResponse> {
|
||||
return this.http.post<IPartnerChargeAccountResponse>(
|
||||
this.apiRoutes.single(consumerId, businessId),
|
||||
data,
|
||||
);
|
||||
|
||||
@@ -3,7 +3,11 @@ import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
import { CONSUMERS_API_ROUTES } from '../constants';
|
||||
import { IConsumerRawResponse, IConsumerRequest, IConsumerResponse } from '../models';
|
||||
import {
|
||||
IPartnerConsumerRawResponse,
|
||||
IPartnerConsumerRequest,
|
||||
IPartnerConsumerResponse,
|
||||
} from '../models';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ConsumersService {
|
||||
@@ -11,18 +15,21 @@ export class ConsumersService {
|
||||
|
||||
private apiRoutes = CONSUMERS_API_ROUTES;
|
||||
|
||||
getAll(): Observable<IPaginatedResponse<IConsumerResponse>> {
|
||||
return this.http.get<IPaginatedResponse<IConsumerRawResponse>>(this.apiRoutes.list());
|
||||
getAll(): Observable<IPaginatedResponse<IPartnerConsumerResponse>> {
|
||||
return this.http.get<IPaginatedResponse<IPartnerConsumerRawResponse>>(this.apiRoutes.list());
|
||||
}
|
||||
getSingle(consumerId: string): Observable<IConsumerResponse> {
|
||||
return this.http.get<IConsumerRawResponse>(this.apiRoutes.single(consumerId));
|
||||
getSingle(consumerId: string): Observable<IPartnerConsumerResponse> {
|
||||
return this.http.get<IPartnerConsumerRawResponse>(this.apiRoutes.single(consumerId));
|
||||
}
|
||||
|
||||
create(userData: IConsumerRequest): Observable<IConsumerResponse> {
|
||||
return this.http.post<IConsumerResponse>(this.apiRoutes.list(), userData);
|
||||
create(userData: IPartnerConsumerRequest): Observable<IPartnerConsumerResponse> {
|
||||
return this.http.post<IPartnerConsumerResponse>(this.apiRoutes.list(), userData);
|
||||
}
|
||||
|
||||
update(consumerId: string, userData: IConsumerRequest): Observable<IConsumerResponse> {
|
||||
return this.http.patch<IConsumerResponse>(this.apiRoutes.single(consumerId), userData);
|
||||
update(
|
||||
consumerId: string,
|
||||
userData: IPartnerConsumerRequest,
|
||||
): Observable<IPartnerConsumerResponse> {
|
||||
return this.http.patch<IPartnerConsumerResponse>(this.apiRoutes.single(consumerId), userData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@ import { computed, inject, Injectable } from '@angular/core';
|
||||
import { MenuItem } from 'primeng/api';
|
||||
import { catchError, finalize } from 'rxjs';
|
||||
import { partnerConsumersNamedRoutes } from '../constants';
|
||||
import { IConsumerResponse } from '../models';
|
||||
import { IPartnerConsumerResponse } from '../models';
|
||||
import { ConsumersService } from '../services/main.service';
|
||||
|
||||
interface ConsumerState extends EntityState<IConsumerResponse> {
|
||||
interface ConsumerState extends EntityState<IPartnerConsumerResponse> {
|
||||
breadcrumbItems: MenuItem[];
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class ConsumerStore extends EntityStore<IConsumerResponse, ConsumerState> {
|
||||
export class ConsumerStore extends EntityStore<IPartnerConsumerResponse, ConsumerState> {
|
||||
private readonly service = inject(ConsumersService);
|
||||
constructor() {
|
||||
super({
|
||||
@@ -36,7 +36,7 @@ export class ConsumerStore extends EntityStore<IConsumerResponse, ConsumerState>
|
||||
routerLink: partnerConsumersNamedRoutes.consumers.meta.pagePath!(),
|
||||
},
|
||||
{
|
||||
title: this.entity()?.fullname,
|
||||
title: this.entity()?.name,
|
||||
routerLink: partnerConsumersNamedRoutes.consumer.meta.pagePath!(consumerId),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
(onEdit)="onEditClick($event)"
|
||||
(onRefresh)="refresh()"
|
||||
/>
|
||||
<partner-create-consumer-wrapper [(visible)]="visibleCreateForm" (onSubmit)="refresh()" />
|
||||
|
||||
<partner-consumer-form
|
||||
[(visible)]="visibleForm"
|
||||
[editMode]="editMode()"
|
||||
[editMode]="true"
|
||||
[consumerId]="selectedItemForEdit()?.id"
|
||||
[initialValues]="selectedItemForEdit() || undefined"
|
||||
(onSubmit)="refresh()"
|
||||
|
||||
@@ -1,39 +1,34 @@
|
||||
// import { CatalogRoleTagComponent } from '@/shared/catalog/roles';
|
||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { Component, inject, signal } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { ConsumerUserFormComponent } from '../components/form.component';
|
||||
import { CreateConsumerWrapperComponent } from '../components/createConsumerWrapper/create-consumer-wrapper.component';
|
||||
import { ConsumerUserFormDialogComponent } from '../components/form-dialog.component';
|
||||
import { partnerConsumersNamedRoutes } from '../constants';
|
||||
import { IConsumerResponse } from '../models';
|
||||
import { IPartnerConsumerResponse } from '../models';
|
||||
import { ConsumersService } from '../services/main.service';
|
||||
|
||||
@Component({
|
||||
selector: 'partner-consumers',
|
||||
templateUrl: './list.component.html',
|
||||
imports: [PageDataListComponent, ConsumerUserFormComponent],
|
||||
imports: [
|
||||
PageDataListComponent,
|
||||
ConsumerUserFormDialogComponent,
|
||||
CreateConsumerWrapperComponent,
|
||||
],
|
||||
})
|
||||
export class ConsumersComponent extends AbstractList<IConsumerResponse> {
|
||||
export class ConsumersComponent extends AbstractList<IPartnerConsumerResponse> {
|
||||
private readonly service = inject(ConsumersService);
|
||||
private readonly router = inject(Router);
|
||||
visibleCreateForm = signal(false);
|
||||
|
||||
override setColumns(): void {
|
||||
this.columns = [
|
||||
{ field: 'id', header: 'شناسه', type: 'id' },
|
||||
{ field: 'fullname', header: 'نام' },
|
||||
{ field: 'mobile_number', header: 'شماره موبایل' },
|
||||
{ field: 'national_code', header: 'کد ملی' },
|
||||
// { field: 'status', header: 'وضعیت' },
|
||||
// {
|
||||
// field: 'license_expires_at',
|
||||
// header: 'تاریخ انقضای لایسنس',
|
||||
// customDataModel(item) {
|
||||
// if (item.license_info) {
|
||||
// return formatJalali(item.license_info.expires_at);
|
||||
// }
|
||||
// return 'بدون لایسنس';
|
||||
// },
|
||||
// },
|
||||
{ field: 'name', header: 'نام' },
|
||||
{ field: 'business_counts', header: 'تعداد فعالیتهای اقتصادی فعال' },
|
||||
|
||||
{
|
||||
field: 'created_at',
|
||||
header: 'تاریخ ایجاد',
|
||||
@@ -46,7 +41,11 @@ export class ConsumersComponent extends AbstractList<IConsumerResponse> {
|
||||
return this.service.getAll();
|
||||
}
|
||||
|
||||
toSinglePage(consumer: IConsumerResponse) {
|
||||
override openAddForm() {
|
||||
this.visibleCreateForm.set(true);
|
||||
}
|
||||
|
||||
toSinglePage(consumer: IPartnerConsumerResponse) {
|
||||
this.router.navigateByUrl(partnerConsumersNamedRoutes.consumer.meta.pagePath!(consumer.id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
<ng-template #moreActions> </ng-template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="grid grid-cols-3 gap-4 items-center">
|
||||
<app-key-value label="نام مشتری" [value]="consumer()?.fullname" />
|
||||
<app-key-value label="شماره موبایل" [value]="consumer()?.mobile_number" />
|
||||
<app-key-value label="نام مشتری" [value]="consumer()?.name" />
|
||||
<app-key-value label="نوع مشتری" [value]="consumer()?.type" />
|
||||
<app-key-value label="وضعیت" [value]="consumer()?.status" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { BreadcrumbService } from '@/core/services';
|
||||
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||
import { getLicenseStatus } from '@/utils';
|
||||
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ConsumerAccountListComponent } from '../components/accounts/list.component';
|
||||
import { ConsumerBusinessActivitiesComponent } from '../components/businessActivities/list.component';
|
||||
import { ConsumerUserFormComponent } from '../components/form.component';
|
||||
import { ConsumerUserFormDialogComponent } from '../components/form-dialog.component';
|
||||
import { ConsumerStore } from '../store/consumer.store';
|
||||
|
||||
@Component({
|
||||
@@ -14,7 +13,7 @@ import { ConsumerStore } from '../store/consumer.store';
|
||||
imports: [
|
||||
AppCardComponent,
|
||||
KeyValueComponent,
|
||||
ConsumerUserFormComponent,
|
||||
ConsumerUserFormDialogComponent,
|
||||
ConsumerAccountListComponent,
|
||||
ConsumerBusinessActivitiesComponent,
|
||||
],
|
||||
@@ -31,10 +30,6 @@ export class ConsumerComponent {
|
||||
|
||||
readonly loading = computed(() => this.store.loading());
|
||||
readonly consumer = computed(() => this.store.entity());
|
||||
readonly license = computed(() => this.store.entity()?.license_info);
|
||||
readonly licenseStatus = computed(() =>
|
||||
getLicenseStatus(this.store.entity()?.license_info?.expires_at),
|
||||
);
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
emptyPlaceholderTitle="تا به حال لایسنسی نفروختهاید."
|
||||
[currentPage]="responseMetaData()?.page"
|
||||
[totalRecords]="responseMetaData()?.totalRecords || items().length"
|
||||
[perPage]="1"
|
||||
[perPage]="responseMetaData()?.perPage"
|
||||
[items]="items()"
|
||||
[loading]="loading()"
|
||||
(onRefresh)="refresh()"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { AbstractList } from '@/shared/abstractClasses/abstract-list';
|
||||
import { PageDataListComponent } from '@/shared/components/pageDataList/page-data-list.component';
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { ILicenseRawResponse, ILicenseResponse } from '../models';
|
||||
import { ILicenseResponse } from '../models';
|
||||
import { PartnerLicensesService } from '../services/main.service';
|
||||
import { AdminAgentsFilterComponent } from './filter-form.component';
|
||||
|
||||
@@ -17,19 +17,25 @@ export class PartnerLicenseListComponent extends AbstractList<ILicenseResponse>
|
||||
this.columns = [
|
||||
{ field: 'id', header: 'شناسه', type: 'id' },
|
||||
{
|
||||
field: 'consumer',
|
||||
header: 'مشتری',
|
||||
customDataModel(item: ILicenseRawResponse) {
|
||||
return `${item.consumer.first_name} ${item.consumer.last_name}`;
|
||||
field: 'business_activity',
|
||||
header: 'عنوان مشتری',
|
||||
type: 'nested',
|
||||
nestedOption: {
|
||||
path: 'business_activity.consumer.name',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'accounts_limit',
|
||||
header: 'تعداد کاربر قابل تعریف',
|
||||
customDataModel(item: ILicenseRawResponse) {
|
||||
return item.license.accounts_limit || '-';
|
||||
field: 'business_activity',
|
||||
header: 'عنوان فعالیت اقتصادی',
|
||||
type: 'nested',
|
||||
nestedOption: {
|
||||
path: 'business_activity.name',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'account_allocation_count',
|
||||
header: 'محدودیت کاربر',
|
||||
},
|
||||
{ field: 'expires_at', header: 'تاریخ انقضا', type: 'date' },
|
||||
{ field: 'created_at', header: 'تاریخ ایجاد', type: 'date' },
|
||||
];
|
||||
@@ -38,7 +44,7 @@ export class PartnerLicenseListComponent extends AbstractList<ILicenseResponse>
|
||||
override getDataRequest() {
|
||||
return this.service.getAll({
|
||||
page: this.responseMetaData()?.page || 1,
|
||||
pageSize: this.responseMetaData()?.perPage || 1,
|
||||
pageSize: this.responseMetaData()?.perPage || 10,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -1,3 +1,5 @@
|
||||
import { IConsumerResponse } from '@/shared/models/consumer.type';
|
||||
|
||||
export interface ILicenseRawResponse {
|
||||
id: string;
|
||||
starts_at: string;
|
||||
@@ -13,9 +15,4 @@ interface License {
|
||||
accounts_limit?: number;
|
||||
}
|
||||
|
||||
interface Consumer {
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
mobile_number: string;
|
||||
status: string;
|
||||
}
|
||||
interface Consumer extends IConsumerResponse {}
|
||||
|
||||
@@ -15,7 +15,7 @@ export class PartnerLicensesService {
|
||||
return this.http.get<IPaginatedResponse<ILicenseRawResponse>>(this.apiRoutes.list(), {
|
||||
params: {
|
||||
page: paginationQuery?.page || '1',
|
||||
pageSize: paginationQuery?.pageSize || '50',
|
||||
perPage: paginationQuery?.pageSize || '50',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user