transform pos payload forms to shared

This commit is contained in:
2026-05-31 10:34:43 +03:30
parent f2a496134b
commit f50219a094
17 changed files with 72 additions and 59 deletions
+1
View File
@@ -43,3 +43,4 @@ testem.log
Thumbs.db Thumbs.db
.env.* .env.*
.env
@@ -7,14 +7,14 @@
(onHide)="close()"> (onHide)="close()">
@if (good) { @if (good) {
@if (isGoldMode()) { @if (isGoldMode()) {
<pos-gold-payload-form <shared-gold-payload-form
[initialValues]="goldPayload()" [initialValues]="goldPayload()"
[vatPercentage]="vatPercentage()" [vatPercentage]="vatPercentage()"
[editMode]="editMode()" [editMode]="editMode()"
[isRapidInvoice]="isRapidInvoice()" [isRapidInvoice]="isRapidInvoice()"
(onSubmit)="submit($event)" /> (onSubmit)="submit($event)" />
} @else if (isStandardMode()) { } @else if (isStandardMode()) {
<pos-standard-payload-form <shared-standard-payload-form
[initialValues]="standardPayload()" [initialValues]="standardPayload()"
[vatPercentage]="vatPercentage()" [vatPercentage]="vatPercentage()"
[measureUnit]="good.measure_unit" [measureUnit]="good.measure_unit"
@@ -1,20 +1,23 @@
import { IGoodResponse } from '@/domains/pos/models/good.io'; import { IGoodResponse } from '@/domains/pos/models/good.io';
import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog'; import { AbstractDialog } from '@/shared/abstractClasses/abstract-dialog';
import { SharedLightBottomsheetComponent } from '@/shared/components/dialog/light-bottomsheet.component'; import {
SharedGoldPayloadFormComponent,
SharedLightBottomsheetComponent,
SharedStandardPayloadFormComponent,
} from '@/shared/components';
import { IGoldPayload, IStandardPayload } from '@/shared/models';
import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core'; import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core';
import { PosConfigRapidInvoiceService } from '../../../configs/components/rapidInvoice/services/main.service'; import { PosConfigRapidInvoiceService } from '../../../configs/components/rapidInvoice/services/main.service';
import { IGoldPayload, IPosOrderItem, IStandardPayload } from '../../models'; import { IPosOrderItem } from '../../models';
import { PosLandingStore } from '../../store/main.store'; import { PosLandingStore } from '../../store/main.store';
import { PosGoldPayloadFormComponent } from './gold/form.component';
import { PosStandardPayloadFormComponent } from './standard/form.component';
@Component({ @Component({
selector: 'pos-payload-form-dialog', selector: 'pos-payload-form-dialog',
templateUrl: './payload-form.component.html', templateUrl: './payload-form.component.html',
imports: [ imports: [
PosGoldPayloadFormComponent, SharedGoldPayloadFormComponent,
SharedStandardPayloadFormComponent,
SharedLightBottomsheetComponent, SharedLightBottomsheetComponent,
PosStandardPayloadFormComponent,
], ],
}) })
export class PayloadFormDialogComponent extends AbstractDialog { export class PayloadFormDialogComponent extends AbstractDialog {
@@ -1,6 +1,5 @@
export * from './customer'; export * from './customer';
export * from './io'; export * from './io';
export * from './payload';
export * from './payment'; export * from './payment';
export * from './posPaymentResult'; export * from './posPaymentResult';
export * from './types'; export * from './types';
@@ -1,6 +1,6 @@
import ISummary from '@/core/models/summary'; import ISummary from '@/core/models/summary';
import { IGoodResponse } from '@/domains/pos/models/good.io'; import { IGoodResponse } from '@/domains/pos/models/good.io';
import { TPosOrderGoodPayload } from './payload'; import { TPosOrderGoodPayload } from '@/shared/models';
export interface IPosOrderItem<T = TPosOrderGoodPayload> { export interface IPosOrderItem<T = TPosOrderGoodPayload> {
unit_price: number; unit_price: number;
@@ -3,11 +3,11 @@ import { Component, Input } from '@angular/core';
import { Card } from 'primeng/card'; import { Card } from 'primeng/card';
@Component({ @Component({
selector: 'pos-form-dialog-amount-card-template', selector: 'shared-calculated-amount-card',
templateUrl: './form-dialog-amount-card-template.component.html', templateUrl: './calculated-amount-card.component.html',
imports: [Card, PriceMaskDirective], imports: [Card, PriceMaskDirective],
}) })
export class PosFormDialogAmountCardTemplateComponent { export class CalculatedAmountCardComponent {
@Input({ required: true }) baseTotalAmount!: number; @Input({ required: true }) baseTotalAmount!: number;
@Input({ required: true }) totalAmount!: number; @Input({ required: true }) totalAmount!: number;
@Input({ required: true }) discountAmount!: number; @Input({ required: true }) discountAmount!: number;
@@ -0,0 +1,2 @@
export * from './dialog.component';
export * from './light-bottomsheet.component';
+4 -1
View File
@@ -1,12 +1,15 @@
// export * from './abstract-select.component'; // export * from './abstract-select.component';
export * from './amountPercentageInput/amount-percentage-input.component';
export * from './breadcrumb.component'; export * from './breadcrumb.component';
export * from './calculatedAmountCard/calculated-amount-card.component';
export * from './card-data.component'; export * from './card-data.component';
export * from './changePasswordFormDialog/change-password-form-dialog.component'; export * from './changePasswordFormDialog/change-password-form-dialog.component';
export * from './dialog/dialog.component'; export * from './dialog';
export * from './fields'; export * from './fields';
export * from './inlineConfirmation/inline-confirmation.component'; export * from './inlineConfirmation/inline-confirmation.component';
export * from './inlineEdit/inline-edit.component'; export * from './inlineEdit/inline-edit.component';
export * from './input/input.component'; export * from './input/input.component';
export * from './key-value.component/key-value.component'; export * from './key-value.component/key-value.component';
export * from './passwordInput/password-input.component'; export * from './passwordInput/password-input.component';
export * from './posPayment';
export * from './table-action-row.component'; export * from './table-action-row.component';
@@ -52,7 +52,7 @@
<hr /> <hr />
<div class="flex w-full flex-col justify-center gap-4"> <div class="flex w-full flex-col justify-center gap-4">
<pos-form-dialog-amount-card-template <shared-calculated-amount-card
[totalAmount]="totalAmount()" [totalAmount]="totalAmount()"
[baseTotalAmount]="baseTotalAmount()" [baseTotalAmount]="baseTotalAmount()"
[discountAmount]="form.controls.discount_amount.value || 0" [discountAmount]="form.controls.discount_amount.value || 0"
@@ -1,37 +1,46 @@
import { greaterThanValidator } from '@/core/validators/greater.validator'; import { greaterThanValidator } from '@/core/validators/greater.validator';
import { PosConfigGoldPriceService } from '@/domains/pos/modules/configs/components/goldPrice/services/main.service'; import { PosConfigGoldPriceService } from '@/domains/pos/modules/configs/components/goldPrice/services/main.service';
import { IPosOrderItem } from '@/domains/pos/modules/shop/models';
import { AbstractForm } from '@/shared/abstractClasses'; import { AbstractForm } from '@/shared/abstractClasses';
import { EnumSelectComponent } from '@/shared/apiEnum/select.component'; import { EnumSelectComponent } from '@/shared/apiEnum/select.component';
import { InputComponent } from '@/shared/components'; import {
import { AmountPercentageInputComponent } from '@/shared/components/amountPercentageInput/amount-percentage-input.component'; AmountPercentageInputComponent,
CalculatedAmountCardComponent,
InputComponent,
} from '@/shared/components';
import { TGoldKarat } from '@/shared/localEnum/constants/goldKarat'; import { TGoldKarat } from '@/shared/localEnum/constants/goldKarat';
import { formatWithCurrency } from '@/utils'; import { IGoldPayload } from '@/shared/models';
import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core'; import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; import { FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { ButtonDirective } from 'primeng/button'; import { ButtonDirective } from 'primeng/button';
import { SelectButton, SelectButtonChangeEvent } from 'primeng/selectbutton'; import { SelectButton, SelectButtonChangeEvent } from 'primeng/selectbutton';
import { IGoldPayload, IPosOrderItem } from '../../../models';
import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-card-template.component';
@Component({ @Component({
selector: 'pos-gold-payload-form', selector: 'shared-gold-payload-form',
templateUrl: './form.component.html', templateUrl: './gold-form.component.html',
imports: [ imports: [
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
InputComponent, InputComponent,
EnumSelectComponent, EnumSelectComponent,
PosFormDialogAmountCardTemplateComponent,
SelectButton, SelectButton,
AmountPercentageInputComponent, AmountPercentageInputComponent,
ButtonDirective, ButtonDirective,
CalculatedAmountCardComponent,
], ],
}) })
export class PosGoldPayloadFormComponent extends AbstractForm< export class SharedGoldPayloadFormComponent extends AbstractForm<
IPosOrderItem<IGoldPayload>, IPosOrderItem<IGoldPayload>,
IPosOrderItem<IGoldPayload> IPosOrderItem<IGoldPayload>
> { > {
@Input({ required: true }) vatPercentage!: number;
@Input() isRapidInvoice: boolean = false;
@Input() ctaText: string = '';
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
@Output() onChangeTotalAmount = new EventEmitter<number>();
override defaultValues: Partial<IPosOrderItem<IGoldPayload>> = { override defaultValues: Partial<IPosOrderItem<IGoldPayload>> = {
// unit_price: 200_000_000, // unit_price: 200_000_000,
// quantity: 2, // quantity: 2,
@@ -43,12 +52,6 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
} as any, } as any,
}; };
@Input({ required: true }) vatPercentage!: number;
@Input() isRapidInvoice!: boolean;
@Output() onSubmitForm = new EventEmitter<IGoldPayload>();
@Output() onChangeTotalAmount = new EventEmitter<number>();
private readonly posGoldConfig = inject(PosConfigGoldPriceService); private readonly posGoldConfig = inject(PosConfigGoldPriceService);
readonly discountTypeItems = [ readonly discountTypeItems = [
@@ -74,7 +77,11 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
goldDefaultUnitPrice = signal<number>(0); goldDefaultUnitPrice = signal<number>(0);
preparedCTAText = computed(() => preparedCTAText = computed(() =>
this.editMode ? 'اعمال ویرایش' : this.isRapidInvoice ? 'ثبت و پرداخت' : 'افزودن به لیست خرید' this.ctaText || this.editMode
? 'اعمال ویرایش'
: this.isRapidInvoice
? 'ثبت و پرداخت'
: 'افزودن به لیست خرید'
); );
private readonly initialForm = () => { private readonly initialForm = () => {
@@ -169,13 +176,6 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
this.onChangeTotalAmount.emit(totalAmount); this.onChangeTotalAmount.emit(totalAmount);
} }
toAmountFormat(amount: number) {
if (!amount) {
return '';
}
return `(${formatWithCurrency(amount)})`;
}
changeDiscountCalculation($event: SelectButtonChangeEvent) { changeDiscountCalculation($event: SelectButtonChangeEvent) {
this.discountType.set($event.value); this.discountType.set($event.value);
@@ -0,0 +1,2 @@
export * from './gold-form.component';
export * from './standard-form.component';
@@ -19,7 +19,7 @@
<hr /> <hr />
<div class="flex w-full flex-col justify-center gap-4"> <div class="flex w-full flex-col justify-center gap-4">
<pos-form-dialog-amount-card-template <shared-calculated-amount-card
[totalAmount]="totalAmount()" [totalAmount]="totalAmount()"
[baseTotalAmount]="baseTotalAmount()" [baseTotalAmount]="baseTotalAmount()"
[discountAmount]="discountAmount()" [discountAmount]="discountAmount()"
@@ -1,34 +1,37 @@
import ISummary from '@/core/models/summary'; import ISummary from '@/core/models/summary';
import { greaterThanValidator } from '@/core/validators'; import { greaterThanValidator } from '@/core/validators';
import { AbstractForm } from '@/shared/abstractClasses'; import { AbstractForm } from '@/shared/abstractClasses';
import { InputComponent } from '@/shared/components'; import {
import { AmountPercentageInputComponent } from '@/shared/components/amountPercentageInput/amount-percentage-input.component'; AmountPercentageInputComponent,
import { formatWithCurrency } from '@/utils'; CalculatedAmountCardComponent,
InputComponent,
} from '@/shared/components';
import { IStandardPayload } from '@/shared/models';
import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core'; import { Component, computed, EventEmitter, Input, Output, signal } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { ReactiveFormsModule, Validators } from '@angular/forms'; import { ReactiveFormsModule, Validators } from '@angular/forms';
import { ButtonDirective } from 'primeng/button'; import { ButtonDirective } from 'primeng/button';
import { IPosOrderItem, IStandardPayload } from '../../../models'; import { IPosOrderItem } from '../../../domains/pos/modules/shop/models';
import { PosFormDialogAmountCardTemplateComponent } from '../form-dialog-amount-card-template.component';
@Component({ @Component({
selector: 'pos-standard-payload-form', selector: 'shared-standard-payload-form',
templateUrl: './form.component.html', templateUrl: './standard-form.component.html',
imports: [ imports: [
ReactiveFormsModule, ReactiveFormsModule,
InputComponent, InputComponent,
PosFormDialogAmountCardTemplateComponent,
AmountPercentageInputComponent, AmountPercentageInputComponent,
ButtonDirective, ButtonDirective,
CalculatedAmountCardComponent,
], ],
}) })
export class PosStandardPayloadFormComponent extends AbstractForm< export class SharedStandardPayloadFormComponent extends AbstractForm<
IPosOrderItem<IStandardPayload>, IPosOrderItem<IStandardPayload>,
IPosOrderItem<IStandardPayload> IPosOrderItem<IStandardPayload>
> { > {
@Input({ required: true }) measureUnit!: ISummary; @Input({ required: true }) measureUnit!: ISummary;
@Input({ required: true }) vatPercentage!: number; @Input({ required: true }) vatPercentage!: number;
@Input() isRapidInvoice!: boolean; @Input() isRapidInvoice: boolean = false;
@Input() ctaText: string = '';
@Output() onChangeTotalAmount = new EventEmitter<number>(); @Output() onChangeTotalAmount = new EventEmitter<number>();
private readonly initialForm = () => { private readonly initialForm = () => {
@@ -66,16 +69,13 @@ export class PosStandardPayloadFormComponent extends AbstractForm<
taxAmount = signal<number>(0); taxAmount = signal<number>(0);
preparedCTAText = computed(() => preparedCTAText = computed(() =>
this.editMode ? 'اعمال ویرایش' : this.isRapidInvoice ? 'ثبت و پرداخت' : 'افزودن به لیست خرید' this.ctaText || this.editMode
? 'اعمال ویرایش'
: this.isRapidInvoice
? 'ثبت و پرداخت'
: 'افزودن به لیست خرید'
); );
toPriceFormat(amount: number) {
if (!amount) {
return '';
}
return `(${formatWithCurrency(amount)})`;
}
updateCalculateAmount(value: Partial<IPosOrderItem<IStandardPayload>>) { updateCalculateAmount(value: Partial<IPosOrderItem<IStandardPayload>>) {
const baseTotalAmount = (value.unit_price ?? 0) * (value.quantity ?? 0); const baseTotalAmount = (value.unit_price ?? 0) * (value.quantity ?? 0);
const discountAmount = Number(value.discount_amount ?? '0'); const discountAmount = Number(value.discount_amount ?? '0');
+3
View File
@@ -0,0 +1,3 @@
export * from './consumer.type';
export * from './enum_translate.type';
export * from './posPayments.type';
+2 -2
View File
@@ -1,9 +1,9 @@
// TIS tenant environment configuration // TIS tenant environment configuration
export const environment = { export const environment = {
production: true, production: true,
apiBaseUrl: 'https://psp-api.shift-am.ir', // apiBaseUrl: 'https://psp-api.shift-am.ir',
// apiBaseUrl: 'http://192.168.128.73:5002', // apiBaseUrl: 'http://192.168.128.73:5002',
// apiBaseUrl: 'http://localhost:5002', apiBaseUrl: 'http://localhost:5002',
host: 'localhost', host: 'localhost',
port: 5000, port: 5000,
enableLogging: false, enableLogging: false,