feat: add rapid invoice configuration module with form, service, and integration

This commit is contained in:
2026-05-23 20:25:35 +03:30
parent 7f07bf53c2
commit 12752f37d5
11 changed files with 108 additions and 13 deletions
@@ -41,8 +41,6 @@ export class PosConfigGoldPriceFormComponent extends AbstractForm<
this.loading.set(true); this.loading.set(true);
const initialValues = await this.service.get(); const initialValues = await this.service.get();
console.log('initialValues.price', initialValues);
this.form.controls.price.setValue((initialValues || 0) + ''); this.form.controls.price.setValue((initialValues || 0) + '');
this.loading.set(false); this.loading.set(false);
} }
@@ -0,0 +1,12 @@
<app-card-data cardTitle="ثبت سریع صورت‌حساب" class="w-full">
<p-message variant="text" severity="info" icon="pi pi-info-circle">
در صورتی که فروش شما تک محصولی / خدماتی است، این قابلیت را فعال کنید.
</p-message>
<form [formGroup]="form" class="mt-6" (submit)="submit()">
<div class="flex items-center gap-4">
<uikit-label name="rapidInvoice"> ثبت سریع صورت‌حساب </uikit-label>
<p-toggleSwitch [formControl]="form.controls.rapidInvoice" />
</div>
<app-form-footer-actions (onCancel)="close()" />
</form>
</app-card-data>
@@ -0,0 +1,55 @@
import { AbstractForm } from '@/shared/abstractClasses';
import { AppCardComponent } from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { UikitLabelComponent } from '@/uikit';
import { Component, inject, signal } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { Message } from 'primeng/message';
import { ToggleSwitch } from 'primeng/toggleswitch';
import { IPosConfigRapidInvoicePayload, IPosConfigRapidInvoiceResponse } from './models';
import { PosConfigRapidInvoiceService } from './services/main.service';
@Component({
selector: 'pos-config-rapid-invoice-form',
templateUrl: 'form.component.html',
imports: [
ReactiveFormsModule,
FormFooterActionsComponent,
AppCardComponent,
Message,
UikitLabelComponent,
ToggleSwitch,
],
})
export class PosConfigRapidInvoiceFormComponent extends AbstractForm<
IPosConfigRapidInvoicePayload,
IPosConfigRapidInvoiceResponse
> {
private readonly service = inject(PosConfigRapidInvoiceService);
loading = signal(true);
initForm = () => {
const form = this.fb.group({
rapidInvoice: [false],
});
return form;
};
form = this.initForm();
override async ngOnInit() {
this.loading.set(true);
const initialValues = await this.service.get();
this.form.controls.rapidInvoice.setValue(initialValues || false);
this.loading.set(false);
}
override submitForm() {
const formValue = this.form.value.rapidInvoice as IPosConfigRapidInvoicePayload;
this.toastService.success({ text: 'تغییرات با موفقیت اعمال شد.' });
return this.service.submit(formValue);
}
}
@@ -0,0 +1,3 @@
export type IPosConfigRapidInvoiceResponse = boolean;
export type IPosConfigRapidInvoicePayload = boolean;
@@ -0,0 +1,19 @@
import { Injectable } from '@angular/core';
import { LOCAL_STORAGE_KEYS } from 'src/assets/constants';
import { IPosConfigRapidInvoicePayload, IPosConfigRapidInvoiceResponse } from '../models';
@Injectable({ providedIn: 'root' })
export class PosConfigRapidInvoiceService {
get(): IPosConfigRapidInvoiceResponse {
const defaultPrice = Boolean(
window.localStorage.getItem(LOCAL_STORAGE_KEYS.POS_CONFIG_RAPID_INVOICE) === 'true'
);
this.submit(defaultPrice);
return defaultPrice;
}
submit(data: IPosConfigRapidInvoicePayload) {
window.localStorage.setItem(LOCAL_STORAGE_KEYS.POS_CONFIG_RAPID_INVOICE, data.toString());
}
}
@@ -2,6 +2,7 @@
@if (info()?.guild!.code.toLocaleLowerCase() === 'gold') { @if (info()?.guild!.code.toLocaleLowerCase() === 'gold') {
<pos-config-gold-price-form class="w-full" (onClose)="returnToMainPage()" /> <pos-config-gold-price-form class="w-full" (onClose)="returnToMainPage()" />
} }
<pos-config-rapid-invoice-form class="w-full" (onClose)="returnToMainPage()" />
<app-card-data cardTitle="تنظیمات فاکتور" class="w-full"> <app-card-data cardTitle="تنظیمات فاکتور" class="w-full">
<p-message variant="text" severity="info" icon="pi pi-info-circle"> <p-message variant="text" severity="info" icon="pi pi-info-circle">
هریک از موارد زیر را که می‌خواهید در چاپ فاکتور نمایش داده‌ شوند را انتخاب کنید هریک از موارد زیر را که می‌خواهید در چاپ فاکتور نمایش داده‌ شوند را انتخاب کنید
@@ -5,6 +5,7 @@ import { Router } from '@angular/router';
import { Message } from 'primeng/message'; import { Message } from 'primeng/message';
import { PosConfigGoldPriceFormComponent } from '../components/goldPrice/form.component'; import { PosConfigGoldPriceFormComponent } from '../components/goldPrice/form.component';
import { PosConfigPrintFormComponent } from '../components/print/form.component'; import { PosConfigPrintFormComponent } from '../components/print/form.component';
import { PosConfigRapidInvoiceFormComponent } from '../components/rapidInvoice/form.component';
@Component({ @Component({
selector: 'pos-config-page', selector: 'pos-config-page',
@@ -14,6 +15,7 @@ import { PosConfigPrintFormComponent } from '../components/print/form.component'
AppCardComponent, AppCardComponent,
Message, Message,
PosConfigGoldPriceFormComponent, PosConfigGoldPriceFormComponent,
PosConfigRapidInvoiceFormComponent,
], ],
}) })
export class PosConfigPageComponent { export class PosConfigPageComponent {
@@ -35,12 +35,12 @@ export class PayloadFormDialogComponent extends AbstractDialog {
goldPayload = computed(() => goldPayload = computed(() =>
this.isGoldMode() && this.editMode() this.isGoldMode() && this.editMode()
? (this.initialValues as IPosOrderItem<IGoldPayload>) ? (this.initialValues as IPosOrderItem<IGoldPayload>)
: undefined, : undefined
); );
standardPayload = computed(() => standardPayload = computed(() =>
this.isStandardMode() && this.editMode() this.isStandardMode() && this.editMode()
? (this.initialValues as IPosOrderItem<IStandardPayload>) ? (this.initialValues as IPosOrderItem<IStandardPayload>)
: undefined, : undefined
); );
onChangeTotalAmount = (totalAmount: number) => { onChangeTotalAmount = (totalAmount: number) => {
@@ -1,13 +1,15 @@
<shared-light-bottomsheet [(visible)]="visible"> <shared-light-bottomsheet [(visible)]="visible" header="انتخاب فصل">
<div class="mt-1"> <div class="mt-1">
<label class="mb-1 block text-sm font-medium text-slate-600">انتخاب سال</label> <div class="flex flex-col gap-4">
<select <uikit-label name="rapidInvoice"> انتخاب سال</uikit-label>
[(ngModel)]="selectedYearDraft" <select
class="w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-slate-700 outline-none"> [(ngModel)]="selectedYearDraft"
@for (yearItem of years; track yearItem.value) { class="w-full rounded-xl border border-slate-200 bg-white px-3 py-2 text-slate-700 outline-none">
<option [value]="yearItem.value">{{ yearItem.year }}</option> @for (yearItem of years; track yearItem.value) {
} <option [value]="yearItem.value">{{ yearItem.year }}</option>
</select> }
</select>
</div>
</div> </div>
<div class="mt-4 grid grid-cols-2 gap-2"> <div class="mt-4 grid grid-cols-2 gap-2">
@@ -1,4 +1,5 @@
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
import { UikitLabelComponent } from '@/uikit';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core'; import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
@@ -23,6 +24,7 @@ interface SeasonItem {
SharedLightBottomsheetComponent, SharedLightBottomsheetComponent,
FormFooterActionsComponent, FormFooterActionsComponent,
ButtonDirective, ButtonDirective,
UikitLabelComponent,
], ],
}) })
export class SeasonPickerDialogComponent extends AbstractDialog { export class SeasonPickerDialogComponent extends AbstractDialog {
@@ -4,6 +4,7 @@ export enum LOCAL_STORAGE_KEYS {
USER_DATA = 'userData', USER_DATA = 'userData',
LAST_LOGIN_TIME = 'lastLoginTime', LAST_LOGIN_TIME = 'lastLoginTime',
LOGIN_ATTEMPTS = 'loginAttempts', LOGIN_ATTEMPTS = 'loginAttempts',
POS_CONFIG_RAPID_INVOICE = 'posConfigRapidInvoice',
POS_CONFIG_PRINT = 'posConfigPrint', POS_CONFIG_PRINT = 'posConfigPrint',
POS_CONFIG_GOLD_PRICE = 'posConfigGoldPrice', POS_CONFIG_GOLD_PRICE = 'posConfigGoldPrice',
} }