feat: add correction and return from sale functionalities to sale invoices
- Added new API routes for correction and return from sale in POS_SALE_INVOICES_API_ROUTES. - Implemented correction and return from sale methods in PosSaleInvoicesService. - Updated PosSaleInvoiceStore to include actions for correction and return from sale. - Enhanced single.component to handle correction and return from sale events. - Created correction and return from sale forms with appropriate validation and submission logic. - Updated sale-invoice-single-view component to manage correction and return from sale actions. - Added models for correction and return from sale requests. - Improved user interface messages and form handling for better user experience.
This commit is contained in:
@@ -2,6 +2,8 @@ import { Maybe } from '@/core';
|
||||
import { NativeBridgeService } from '@/core/services';
|
||||
import { ToastService } from '@/core/services/toast.service';
|
||||
import { PosConfigPrintService } from '@/domains/pos/modules/configs/components/print/services/main.service';
|
||||
import { IPosReturnFromSaleRequest } from '@/domains/pos/modules/saleInvoices/models/returnFromSale';
|
||||
import { IPosOrderItem } from '@/domains/pos/modules/shop/models';
|
||||
import { PosInfoStore } from '@/domains/pos/store';
|
||||
import {
|
||||
CatalogInvoiceTypeTagComponent,
|
||||
@@ -44,6 +46,8 @@ import { ProgressSpinner } from 'primeng/progressspinner';
|
||||
import { TableModule } from 'primeng/table';
|
||||
import { Observable } from 'rxjs';
|
||||
import { AppConfirmationService } from '../confirmationDialog/confirmation-dialog.service';
|
||||
import { SharedCorrectionFormComponent } from './correctionForm';
|
||||
import { CorrectionInvoiceFormValue, ICorrectionRequest, ReturnFromSaleFormValue } from './models';
|
||||
import { SharedReturnFormComponent } from './returnForm/form.component';
|
||||
|
||||
export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||
@@ -68,6 +72,7 @@ export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||
SharedLightBottomsheetComponent,
|
||||
ProgressSpinner,
|
||||
SharedReturnFormComponent,
|
||||
SharedCorrectionFormComponent,
|
||||
],
|
||||
})
|
||||
export class SharedSaleInvoiceSingleViewComponent {
|
||||
@@ -90,18 +95,20 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
@Output() onSendToTsp = new EventEmitter<Observable<any>>();
|
||||
@Output() onResendToTsp = new EventEmitter<Observable<any>>();
|
||||
@Output() onInquiry = new EventEmitter<Observable<any>>();
|
||||
@Output() onCorrection = new EventEmitter<ICorrectionRequest>();
|
||||
@Output() onReturnFromSale = new EventEmitter<IPosReturnFromSaleRequest>();
|
||||
|
||||
@ViewChild('totalAmount', { static: false }) totalAmount!: TemplateRef<any>;
|
||||
|
||||
moreActionMenuItems = signal<MenuItem[]>([]);
|
||||
showCorrectionForm = signal(false);
|
||||
showBackFromSaleForm = signal(false);
|
||||
showReturnFromSaleForm = signal(false);
|
||||
|
||||
constructor() {
|
||||
this.showErrors = this.showErrors.bind(this);
|
||||
this.showRevokeConfirmation = this.showRevokeConfirmation.bind(this);
|
||||
this.showCorrection = this.showCorrection.bind(this);
|
||||
this.showBackFromSale = this.showBackFromSale.bind(this);
|
||||
this.showReturnFromSale = this.showReturnFromSale.bind(this);
|
||||
this.printInvoice = this.printInvoice.bind(this);
|
||||
this.send = this.send.bind(this);
|
||||
this.resend = this.resend.bind(this);
|
||||
@@ -119,9 +126,15 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
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}`,
|
||||
@@ -143,9 +156,11 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
},
|
||||
});
|
||||
}
|
||||
showCorrection() {}
|
||||
showBackFromSale() {
|
||||
this.showBackFromSaleForm.set(true);
|
||||
showCorrection() {
|
||||
this.showCorrectionForm.set(true);
|
||||
}
|
||||
showReturnFromSale() {
|
||||
this.showReturnFromSaleForm.set(true);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
@@ -192,7 +207,7 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
label: 'برگشت از فروش',
|
||||
icon: 'pi pi-cart-minus',
|
||||
neededStatus: TspProviderResponseStatus.SUCCESS,
|
||||
command: this.showBackFromSale,
|
||||
command: this.showReturnFromSale,
|
||||
},
|
||||
{
|
||||
label: 'چاپ',
|
||||
@@ -461,4 +476,70 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
refresh() {
|
||||
this.onRefresh.emit();
|
||||
}
|
||||
|
||||
private mapCorrectionRequest(event: CorrectionInvoiceFormValue): ICorrectionRequest {
|
||||
const items = (event.items || []).map(({ id, pricing_model, ...item }) => item);
|
||||
|
||||
const total_amount = items.reduce((sum, item) => sum + Number(item.total_amount || 0), 0);
|
||||
const discount_amount = items.reduce((sum, item) => sum + Number(item.discount_amount || 0), 0);
|
||||
const tax_amount = items.reduce((sum, item) => sum + Number(item.tax_amount || 0), 0);
|
||||
|
||||
return {
|
||||
invoice_date: event.invoice_date,
|
||||
items,
|
||||
total_amount,
|
||||
discount_amount,
|
||||
tax_amount,
|
||||
};
|
||||
}
|
||||
|
||||
correctionSubmit(event: CorrectionInvoiceFormValue) {
|
||||
this.sendCorrection(this.mapCorrectionRequest(event));
|
||||
}
|
||||
|
||||
private mapReturnFromSaleRequest(event: ReturnFromSaleFormValue): IPosReturnFromSaleRequest {
|
||||
const invoiceItems = this.invoice?.items || [];
|
||||
const itemMap = new Map(invoiceItems.map((item) => [item.id, item]));
|
||||
|
||||
const items: IPosOrderItem[] = (event.items || [])
|
||||
.map((item) => {
|
||||
const source = itemMap.get(item.id);
|
||||
if (!source) return null;
|
||||
|
||||
const quantity = Number(item.quantity || 0);
|
||||
const unit_price = Number(source.unit_price || 0);
|
||||
const discount_amount = Number(source.discount || 0);
|
||||
const base_total_amount = unit_price * quantity;
|
||||
const total_amount = Number(source.total_amount || 0);
|
||||
const tax_amount = Number(source.payload?.wages || 0);
|
||||
|
||||
return {
|
||||
good_id: source.good_id,
|
||||
service_id: source.service_id || undefined,
|
||||
quantity,
|
||||
unit_price,
|
||||
discount_amount,
|
||||
base_total_amount,
|
||||
total_amount,
|
||||
tax_amount,
|
||||
measure_unit: source.good_snapshot.measure_unit,
|
||||
payload: source.payload as any,
|
||||
notes: source.notes,
|
||||
image_url: source.good_snapshot.image_url,
|
||||
} as IPosOrderItem;
|
||||
})
|
||||
.filter((item): item is IPosOrderItem => !!item);
|
||||
|
||||
return {
|
||||
invoice_date: this.invoice?.invoice_date || '',
|
||||
items,
|
||||
total_amount: items.reduce((sum, item) => sum + Number(item.total_amount || 0), 0),
|
||||
discount_amount: items.reduce((sum, item) => sum + Number(item.discount_amount || 0), 0),
|
||||
tax_amount: items.reduce((sum, item) => sum + Number(item.tax_amount || 0), 0),
|
||||
};
|
||||
}
|
||||
|
||||
returnSubmit(event: ReturnFromSaleFormValue) {
|
||||
this.sendReturnFromSale(this.mapReturnFromSaleRequest(event));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user