feat: enhance invoice correction form with item editing and price info display

This commit is contained in:
2026-06-08 13:35:58 +03:30
parent 788f4023f3
commit 5fa07c7ee8
12 changed files with 393 additions and 202 deletions
@@ -11,11 +11,7 @@ import {
TspProviderResponseStatus,
} from '@/shared/catalog';
import { CatalogInvoiceSettlementTypeTagComponent } from '@/shared/catalog/invoiceSettlementType';
import {
AppCardComponent,
KeyValueComponent,
SharedLightBottomsheetComponent,
} from '@/shared/components';
import { KeyValueComponent, SharedLightBottomsheetComponent } from '@/shared/components';
import { ISaleInvoiceFullResponse } from '@/shared/components/invoices/sale-invoice-full-response.model';
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
import {
@@ -38,25 +34,32 @@ import {
ViewChild,
} from '@angular/core';
import { UrlTree } from '@angular/router';
import { MenuItem } from 'primeng/api';
import { Button } from 'primeng/button';
import { Button, ButtonDirective } from 'primeng/button';
import { Card } from 'primeng/card';
import { Dialog } from 'primeng/dialog';
import { Divider } from 'primeng/divider';
import { Menu } from 'primeng/menu';
import { ProgressSpinner } from 'primeng/progressspinner';
import { TableModule } from 'primeng/table';
import { Observable } from 'rxjs';
import { AppConfirmationService } from '../confirmationDialog/confirmation-dialog.service';
import { InnerPagesHeaderComponent } from '../innerPagesHeader/inner-pages-header.component';
import { SharedCorrectionFormComponent } from './correctionForm';
import { CorrectionInvoiceFormValue, ICorrectionRequest, ReturnFromSaleFormValue } from './models';
import { SharedReturnFormComponent } from './returnForm/form.component';
export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
type TActionMenuItem = {
label: string;
icon: string;
command: () => void;
neededStatus?: TspProviderResponseStatus;
severity?: 'secondary' | 'info' | 'warn' | 'danger' | 'contrast';
};
@Component({
selector: 'shared-sale-invoice-single-view',
templateUrl: './sale-invoice-single-view.component.html',
imports: [
AppCardComponent,
KeyValueComponent,
Divider,
PageDataListComponent,
@@ -66,13 +69,16 @@ export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
PriceMaskDirective,
CatalogTaxProviderStatusTagComponent,
CatalogInvoiceTypeTagComponent,
Menu,
Button,
CatalogInvoiceSettlementTypeTagComponent,
SharedLightBottomsheetComponent,
ProgressSpinner,
SharedReturnFormComponent,
SharedCorrectionFormComponent,
Dialog,
ButtonDirective,
InnerPagesHeaderComponent,
Card,
],
})
export class SharedSaleInvoiceSingleViewComponent {
@@ -100,7 +106,7 @@ export class SharedSaleInvoiceSingleViewComponent {
@ViewChild('totalAmount', { static: false }) totalAmount!: TemplateRef<any>;
moreActionMenuItems = signal<MenuItem[]>([]);
moreActionMenuItems = signal<TActionMenuItem[]>([]);
showCorrectionForm = signal(false);
showReturnFromSaleForm = signal(false);
@@ -115,26 +121,85 @@ export class SharedSaleInvoiceSingleViewComponent {
this.inquiry = this.inquiry.bind(this);
}
showErrors = () => {};
inquiry = () => {
this.onInquiry.emit();
};
send = () => {
this.onSendToTsp.emit();
};
sendCorrection = (event: ICorrectionRequest) => {
this.onCorrection.emit(event);
};
resend = () => {
this.onResendToTsp.emit();
};
sendReturnFromSale = (event: IPosReturnFromSaleRequest) => {
this.onReturnFromSale.emit(event);
};
showCorrection = () => {
this.showCorrectionForm.set(true);
};
showReturnFromSale = () => {
this.showReturnFromSaleForm.set(true);
};
private readonly actions: TActionMenuItem[] = [
{
label: 'ارسال مجدد صورت‌حساب',
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.SEND_FAILURE,
severity: 'info',
command: this.resend,
},
{
label: 'ارسال صورت‌حساب',
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.NOT_SEND,
severity: 'info',
command: this.send,
},
{
label: 'استعلام وضعیت',
icon: 'pi pi-info',
neededStatus: TspProviderResponseStatus.FISCAL_QUEUED,
severity: 'info',
command: this.inquiry,
},
{
label: 'دلایل خطا',
icon: 'pi pi-question',
neededStatus: TspProviderResponseStatus.FAILURE,
severity: 'danger',
command: this.showErrors,
},
{
label: 'ابطال',
icon: 'pi pi-eraser',
neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'danger',
command: this.showRevokeConfirmation,
},
{
label: 'اصلاح',
icon: 'pi pi-file-edit',
neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'warn',
command: this.showCorrection,
},
{
label: 'برگشت از فروش',
icon: 'pi pi-cart-minus',
neededStatus: TspProviderResponseStatus.SUCCESS,
severity: 'warn',
command: this.showReturnFromSale,
},
];
get actionLoading() {
return this.sendToTspLoading || this.inquiryLoading || this.resendToTspLoading;
}
showErrors() {}
inquiry() {
this.onInquiry.emit();
}
send() {
this.onSendToTsp.emit();
}
sendCorrection(event: ICorrectionRequest) {
this.onCorrection.emit(event);
}
resend() {
this.onResendToTsp.emit();
}
sendReturnFromSale(event: IPosReturnFromSaleRequest) {
this.onReturnFromSale.emit(event);
}
async showRevokeConfirmation() {
await this.confirmationService.ask({
header: `ابطال صورت‌حساب‌ شماره ${this.invoice!.invoice_number}`,
@@ -156,72 +221,13 @@ export class SharedSaleInvoiceSingleViewComponent {
},
});
}
showCorrection() {
this.showCorrectionForm.set(true);
}
showReturnFromSale() {
this.showReturnFromSaleForm.set(true);
}
ngOnChanges(changes: SimpleChanges) {
if (changes['invoice'] && this.invoice) {
const invoiceStatus = this.invoice.status.value;
const actions: MenuItem[] = [
{
label: 'ارسال مجدد صورت‌حساب',
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.SEND_FAILURE,
command: this.resend,
},
{
label: 'ارسال صورت‌حساب',
icon: 'pi pi-send',
neededStatus: TspProviderResponseStatus.NOT_SEND,
command: this.send,
},
{
label: 'استعلام وضعیت',
icon: 'pi pi-info',
neededStatus: TspProviderResponseStatus.FISCAL_QUEUED,
command: this.inquiry,
},
{
label: 'دلایل خطا',
icon: 'pi pi-question',
neededStatus: TspProviderResponseStatus.FAILURE,
command: this.showErrors,
},
{
label: 'ابطال',
icon: 'pi pi-eraser',
neededStatus: TspProviderResponseStatus.SUCCESS,
command: this.showRevokeConfirmation,
},
{
label: 'اصلاح',
icon: 'pi pi-file-edit',
neededStatus: TspProviderResponseStatus.SUCCESS,
command: this.showCorrection,
},
{
label: 'برگشت از فروش',
icon: 'pi pi-cart-minus',
neededStatus: TspProviderResponseStatus.SUCCESS,
command: this.showReturnFromSale,
},
{
label: 'چاپ',
icon: 'pi pi-print',
neededStatus: '',
command: this.printInvoice,
},
];
this.moreActionMenuItems.set(
actions.filter(
// @ts-ignore
(action) => !action.neededStatus || action.neededStatus === invoiceStatus
)
this.actions.filter((action) => action.neededStatus === invoiceStatus)
);
}
}