Compare commits
3 Commits
b57d6b4e4b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 93ebc80da3 | |||
| 4e4cc08224 | |||
| e5f53c2265 |
@@ -1,6 +1,8 @@
|
||||
import { TspProviderResponseStatus } from '@/shared/catalog';
|
||||
import { IPosSaleInvoicesSummaryResponse } from './io';
|
||||
|
||||
export interface IPosSaleInvoiceFiscalActionResponse {
|
||||
invoice: IPosSaleInvoicesSummaryResponse;
|
||||
message?: string;
|
||||
status: TspProviderResponseStatus;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
[sendToTspLoading]="sendToTspLoading()"
|
||||
[inquiryLoading]="inquiryLoading()"
|
||||
[resendToTspLoading]="resendToTspLoading()"
|
||||
[correctionLoading]="correctionLoading()"
|
||||
[returnFromSaleLoading]="backFromSaleLoading()"
|
||||
(onSendToTsp)="sendToTsp()"
|
||||
(onResendToTsp)="resendToTsp()"
|
||||
(onInquiry)="inquiry()"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ToastService } from '@/core/services/toast.service';
|
||||
import taxProviderStatusTranslatorUtil from '@/shared/catalog/taxProviderStatus/tax-provider-status-translator.util';
|
||||
import { SharedSaleInvoiceSingleViewComponent } from '@/shared/components/invoices/sale-invoice-single-view.component';
|
||||
import pageParamsUtils from '@/utils/page-params.utils';
|
||||
import { Component, computed, inject, signal } from '@angular/core';
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { finalize } from 'rxjs';
|
||||
import { distinctUntilChanged, finalize, map } from 'rxjs';
|
||||
import { posSaleInvoicesNamedRoutes } from '../constants';
|
||||
import { IPosCorrectionRequest } from '../models/correction';
|
||||
import { IPosReturnFromSaleRequest } from '../models/returnFromSale';
|
||||
@@ -20,8 +20,20 @@ export class PosSaleInvoiceComponent {
|
||||
private readonly store = inject(PosSaleInvoiceStore);
|
||||
private readonly toastService = inject(ToastService);
|
||||
|
||||
pageParams = computed(() => pageParamsUtils(this.route));
|
||||
invoiceId = signal<string>(this.pageParams()['invoiceId']);
|
||||
invoiceId = signal<string>('');
|
||||
|
||||
constructor() {
|
||||
this.route.paramMap
|
||||
.pipe(
|
||||
map((params) => params.get('invoiceId') ?? ''),
|
||||
distinctUntilChanged(),
|
||||
takeUntilDestroyed()
|
||||
)
|
||||
.subscribe((invoiceId) => {
|
||||
this.invoiceId.set(invoiceId);
|
||||
this.store.getData(invoiceId);
|
||||
});
|
||||
}
|
||||
|
||||
inquiryLoading = signal(false);
|
||||
sendToTspLoading = signal(false);
|
||||
@@ -94,7 +106,12 @@ export class PosSaleInvoiceComponent {
|
||||
this.correctionLoading.set(false);
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
.subscribe((res) => {
|
||||
this.toastService.success({
|
||||
text: `اصلاحیهی صورتحساب با شمارهی ${res.invoice?.invoice_number} با موفقیت ایجاد شد.`,
|
||||
});
|
||||
this.store.updateStatus(res.status);
|
||||
});
|
||||
}
|
||||
returnFromSale(data: IPosReturnFromSaleRequest) {
|
||||
this.backFromSaleLoading.set(true);
|
||||
@@ -105,7 +122,12 @@ export class PosSaleInvoiceComponent {
|
||||
this.backFromSaleLoading.set(false);
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
.subscribe((res) => {
|
||||
this.toastService.success({
|
||||
text: `برگشت از فروش با شمارهی ${res.invoice?.invoice_number} با موفقیت ایجاد شد.`,
|
||||
});
|
||||
this.store.updateStatus(res.status);
|
||||
});
|
||||
}
|
||||
revoke() {
|
||||
this.revokeLoading.set(true);
|
||||
@@ -116,10 +138,11 @@ export class PosSaleInvoiceComponent {
|
||||
this.revokeLoading.set(false);
|
||||
})
|
||||
)
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.store.getData(this.invoiceId());
|
||||
.subscribe((res) => {
|
||||
this.toastService.success({
|
||||
text: `صورتحساب شمارهی ${res.invoice?.invoice_number} با موفقیت ابطال شد.`,
|
||||
});
|
||||
this.store.updateStatus(res.status);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
<pos-order-price-info-card [info]="totalPriceInfo" />
|
||||
|
||||
<app-form-footer-actions [loading]="submitLoading()" (onCancel)="close()" />
|
||||
<app-form-footer-actions [loading]="loading || submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
|
||||
<shared-light-bottomsheet
|
||||
|
||||
@@ -42,6 +42,7 @@ export class SharedCorrectionFormComponent extends AbstractForm<
|
||||
@Input() beforeSubmit?: (payload: CorrectionInvoiceFormValue) => Promise<boolean> | boolean;
|
||||
@Input({ required: true }) invoiceDate!: string;
|
||||
@Input() visible = false;
|
||||
@Input() loading = false;
|
||||
|
||||
form = this.fb.group({
|
||||
invoice_date: [this.invoiceDate],
|
||||
|
||||
@@ -22,5 +22,5 @@
|
||||
|
||||
<pos-order-price-info-card [info]="totalPriceInfo" />
|
||||
|
||||
<app-form-footer-actions (onCancel)="close()" />
|
||||
<app-form-footer-actions [loading]="loading || submitLoading()" (onCancel)="close()" />
|
||||
</form>
|
||||
|
||||
@@ -4,18 +4,18 @@
|
||||
@if (invoice.referenced_by) {
|
||||
<p-message severity="warn" [closable]="false">
|
||||
این صورتحساب، مرجع صورتحساب شمارهی
|
||||
<a [href]="referenceByInvoiceRoute()" class="text-lg font-bold">
|
||||
<span (click)="navigateToRelatedInvoice(invoice.referenced_by.id)" class="text-lg font-bold">
|
||||
{{ invoice.referenced_by.invoice_number }}
|
||||
</a>
|
||||
</span>
|
||||
میباشد.
|
||||
</p-message>
|
||||
}
|
||||
@if (invoice.reference_invoice) {
|
||||
<p-message severity="info" [closable]="false">
|
||||
صورتحساب مرجع به شمارهی
|
||||
<a [href]="referenceInvoiceRoute()" class="text-lg font-bold">
|
||||
<span (click)="navigateToRelatedInvoice(invoice.reference_invoice.id)" class="text-lg font-bold">
|
||||
{{ invoice.reference_invoice.invoice_number }}
|
||||
</a>
|
||||
</span>
|
||||
میباشد.
|
||||
</p-message>
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
} from '@/shared/catalog';
|
||||
import { CatalogInvoiceSettlementTypeTagComponent } from '@/shared/catalog/invoiceSettlementType';
|
||||
import { PriceMaskDirective } from '@/shared/directives';
|
||||
import { Component, computed, inject, Input } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Component, inject, Input } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Card } from 'primeng/card';
|
||||
import { Divider } from 'primeng/divider';
|
||||
import { Message } from 'primeng/message';
|
||||
@@ -37,6 +37,7 @@ export class SaleInvoiceSingleInfoCardComponent {
|
||||
@Input() variant: TSaleInvoiceSingleViewVariant = 'full';
|
||||
|
||||
private readonly route = inject(ActivatedRoute);
|
||||
private readonly router = inject(Router);
|
||||
|
||||
columns: IColumn[] = [
|
||||
{
|
||||
@@ -107,34 +108,18 @@ export class SaleInvoiceSingleInfoCardComponent {
|
||||
},
|
||||
];
|
||||
|
||||
referenceInvoiceRoute = computed(() => {
|
||||
const referenceInvoiceId = this.invoice?.reference_invoice?.id;
|
||||
navigateToRelatedInvoice(invoiceId: string) {
|
||||
const pagePath = this.route.pathFromRoot
|
||||
.flatMap((route) => route.snapshot.url.map((segment) => segment.path))
|
||||
.join('/');
|
||||
|
||||
if (!pagePath || !referenceInvoiceId) {
|
||||
return pagePath;
|
||||
if (pagePath && invoiceId) {
|
||||
const pathParts = pagePath.split('/').filter(Boolean);
|
||||
pathParts[pathParts.length - 1] = invoiceId;
|
||||
|
||||
this.router.navigateByUrl(`/${pathParts.join('/')}`, {
|
||||
skipLocationChange: false,
|
||||
});
|
||||
}
|
||||
|
||||
const pathParts = pagePath.split('/').filter(Boolean);
|
||||
pathParts[pathParts.length - 1] = referenceInvoiceId;
|
||||
|
||||
return `/${pathParts.join('/')}`;
|
||||
});
|
||||
referenceByInvoiceRoute = computed(() => {
|
||||
const referenceInvoiceId = this.invoice?.referenced_by?.id;
|
||||
const pagePath = this.route.pathFromRoot
|
||||
.flatMap((route) => route.snapshot.url.map((segment) => segment.path))
|
||||
.join('/');
|
||||
|
||||
if (!pagePath || !referenceInvoiceId) {
|
||||
return pagePath;
|
||||
}
|
||||
|
||||
const pathParts = pagePath.split('/').filter(Boolean);
|
||||
pathParts[pathParts.length - 1] = referenceInvoiceId;
|
||||
|
||||
return `/${pathParts.join('/')}`;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<ng-template #actions>
|
||||
<p-button (click)="showQrCode()" icon="pi pi-qrcode" outlined size="small" />
|
||||
<p-button (click)="printInvoice()" icon="pi pi-print" outlined size="small" label="چاپ" />
|
||||
@if (!isApplication && canDoActionOnInvoice()) {
|
||||
@if (!isApplication && canDoActionOnInvoice) {
|
||||
<p-button (click)="menu.toggle($event)" icon="pi pi-ellipsis-v" label="عملیات بیشتر" outlined size="small">
|
||||
</p-button>
|
||||
<p-menu #menu [model]="moreActionMenuItems()" [popup]="true"></p-menu>
|
||||
@@ -18,7 +18,7 @@
|
||||
<shared-sale-invoice-single-info-card [loading]="loading" [invoice]="invoice" [variant]="variant" />
|
||||
</div>
|
||||
|
||||
@if (isApplication && moreActionMenuItems().length && canDoActionOnInvoice()) {
|
||||
@if (isApplication && moreActionMenuItems().length && canDoActionOnInvoice) {
|
||||
<div class="border-surface-border bg-surface-card sticky bottom-0 z-10 mt-4 w-full rounded-t-2xl border-t p-3">
|
||||
<div class="flex flex-wrap justify-center gap-2">
|
||||
@for (action of moreActionMenuItems(); track action.label || $index) {
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (canDoActionOnInvoice()) {
|
||||
@if (canDoActionOnInvoice) {
|
||||
<shared-light-bottomsheet [(visible)]="showReturnFromSaleForm" header=" برگشت از فروش">
|
||||
<shared-return-form
|
||||
[initialValues]="invoice.items"
|
||||
@@ -50,6 +50,7 @@
|
||||
[initialValues]="invoice.items"
|
||||
[invoiceDate]="invoice.invoice_date"
|
||||
[beforeSubmit]="beforeCorrectionSubmitHandler.bind(this)"
|
||||
[loading]="correctionLoading || false"
|
||||
(onSubmit)="correctionSubmit($event)"
|
||||
(onClose)="cancelCorrection()" />
|
||||
</shared-light-bottomsheet>
|
||||
@@ -64,15 +65,15 @@
|
||||
(onClose)="cancelCorrectionPayment()" />
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<shared-light-bottomsheet [(visible)]="showQrCodeDialog" header="کد QR">
|
||||
<div class="flex flex-col gap-4">
|
||||
<span class="text-center text-lg font-bold">
|
||||
برای امکان دسترسی به صورتحساب به صورت آنلاین، کد QR را اسکن کنید.
|
||||
</span>
|
||||
<p-card class="mx-auto">
|
||||
<qrcode [qrdata]="publicInvoiceRoute()" [width]="220" [errorCorrectionLevel]="'M'"></qrcode>
|
||||
</p-card>
|
||||
</div>
|
||||
</shared-light-bottomsheet>
|
||||
<shared-light-bottomsheet [(visible)]="showQrCodeDialog" header="کد QR">
|
||||
<div class="flex flex-col gap-4">
|
||||
<span class="text-center text-lg font-bold">
|
||||
برای امکان دسترسی به صورتحساب به صورت آنلاین، کد QR را اسکن کنید.
|
||||
</span>
|
||||
<p-card class="mx-auto">
|
||||
<qrcode [qrdata]="publicInvoiceRoute" [width]="220" [errorCorrectionLevel]="'M'"></qrcode>
|
||||
</p-card>
|
||||
</div>
|
||||
</shared-light-bottomsheet>
|
||||
}
|
||||
|
||||
@@ -110,19 +110,21 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
showQrCodeDialog = signal(false);
|
||||
showCorrectionPaymentDialog = signal(false);
|
||||
correctionRequiredPayment = signal(0);
|
||||
paymentData = signal<Maybe<IPayment>>(null);
|
||||
readonly isApplication = config.isPosApplication;
|
||||
private pendingCorrectionSubmitResolver: Maybe<(allowed: boolean) => void> = null;
|
||||
private pendingCorrectionSubmitResolver: Maybe<(allowed: boolean, payment?: IPayment) => void> =
|
||||
null;
|
||||
|
||||
publicInvoiceRoute = computed(() => {
|
||||
get publicInvoiceRoute() {
|
||||
if (this.invoice) {
|
||||
return `${window.location.origin}/sale-invoices/${this.invoice.id}`;
|
||||
}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
canDoActionOnInvoice = computed(() => {
|
||||
get canDoActionOnInvoice() {
|
||||
return !this.invoice?.referenced_by;
|
||||
});
|
||||
}
|
||||
|
||||
showErrors = () => {};
|
||||
inquiry = () => {
|
||||
@@ -282,6 +284,7 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
total_amount,
|
||||
discount_amount,
|
||||
tax_amount,
|
||||
payments: this.paymentData() || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -310,7 +313,12 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (await this.beforeCorrectionSubmit?.(mapped)) ?? true;
|
||||
return (
|
||||
(await this.beforeCorrectionSubmit?.({
|
||||
...mapped,
|
||||
payments: this.paymentData() || undefined,
|
||||
})) ?? true
|
||||
);
|
||||
}
|
||||
|
||||
confirmCorrectionPayment(_event: {
|
||||
@@ -318,7 +326,8 @@ export class SharedSaleInvoiceSingleViewComponent {
|
||||
settlementType: 'CASH' | 'CREDIT' | 'MIXED';
|
||||
}) {
|
||||
this.showCorrectionPaymentDialog.set(false);
|
||||
this.pendingCorrectionSubmitResolver?.(true);
|
||||
this.paymentData.set(_event.payment);
|
||||
this.pendingCorrectionSubmitResolver?.(true, _event.payment);
|
||||
this.pendingCorrectionSubmitResolver = null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user