create invoice settlementStatus catalog and set to single invoice details, update single invoice detail actions

This commit is contained in:
2026-05-31 17:12:43 +03:30
parent 4ec6143068
commit c271a36f7e
15 changed files with 242 additions and 17 deletions
@@ -1,5 +1,7 @@
import { defaultBaseStateData, EntityState, EntityStore } from '@/core/state';
import { ISaleInvoiceFullResponse } from '@/domains/consumer/models';
import { TspProviderResponseStatus } from '@/shared/catalog';
import taxProviderStatusTranslatorUtil from '@/shared/catalog/taxProviderStatus/tax-provider-status-translator.util';
import { inject, Injectable } from '@angular/core';
import { catchError, finalize } from 'rxjs';
import { PosSaleInvoicesService } from '../services/main.service';
@@ -9,7 +11,10 @@ interface PosSaleInvoiceState extends EntityState<ISaleInvoiceFullResponse> {}
@Injectable({
providedIn: 'root',
})
export class PosSaleInvoiceStore extends EntityStore<ISaleInvoiceFullResponse, PosSaleInvoiceState> {
export class PosSaleInvoiceStore extends EntityStore<
ISaleInvoiceFullResponse,
PosSaleInvoiceState
> {
private readonly service = inject(PosSaleInvoicesService);
constructor() {
@@ -29,13 +34,29 @@ export class PosSaleInvoiceStore extends EntityStore<ISaleInvoiceFullResponse, P
catchError((error) => {
this.setError(error);
throw error;
}),
})
)
.subscribe((entity) => {
this.patchState({ entity });
});
}
updateStatus(status: TspProviderResponseStatus) {
this.patchState({
entity: {
...this.entity()!,
status: { value: status, translate: taxProviderStatusTranslatorUtil(status) },
},
});
}
sendToTsp(invoceId: string) {
return this.service.sendToTsp(invoceId);
}
inquiry(invoceId: string) {
return this.service.getInquiry(invoceId);
}
override reset(): void {
this.setState({
...defaultBaseStateData,
@@ -3,6 +3,9 @@
[loading]="loading()"
[invoice]="invoice()"
[backRoute]="backRoute()"
variant="pos"
/>
[sendToTspLoading]="sendToTspLoading()"
[inquiryLoading]="inquiryLoading()"
(onSendToTsp)="sendToTsp()"
(onInquiry)="inquiry()"
variant="pos" />
</div>
@@ -1,7 +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 { ActivatedRoute } from '@angular/router';
import { finalize } from 'rxjs';
import { posSaleInvoicesNamedRoutes } from '../constants';
import { PosSaleInvoiceStore } from '../store/main.store';
@@ -13,15 +16,102 @@ import { PosSaleInvoiceStore } from '../store/main.store';
export class PosSaleInvoiceComponent {
private readonly route = inject(ActivatedRoute);
private readonly store = inject(PosSaleInvoiceStore);
private readonly toastService = inject(ToastService);
pageParams = computed(() => pageParamsUtils(this.route));
invoiceId = signal<string>(this.pageParams()['invoiceId']);
inquiryLoading = signal(false);
sendToTspLoading = signal(false);
resendToTspLoading = signal(false);
correctionLoading = signal(false);
backFromSaleLoading = signal(false);
revokeLoading = signal(false);
readonly invoice = computed(() => this.store.entity());
readonly loading = computed(() => this.store.loading());
readonly backRoute = computed(() => posSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!());
sendToTsp() {
this.sendToTspLoading.set(true);
this.store
.sendToTsp(this.invoiceId())
.pipe(
finalize(() => {
this.sendToTspLoading.set(false);
})
)
.subscribe({
next: (res) => {
this.toastService.success({ text: res.message || 'ارسال صورت‌حساب با موفقیت انجام شد.' });
this.store.updateStatus(res.status);
},
});
}
inquiry() {
this.inquiryLoading.set(true);
this.store
.inquiry(this.invoiceId())
.pipe(
finalize(() => {
this.inquiryLoading.set(false);
})
)
.subscribe({
next: (res) => {
this.toastService.success({
text: `وضعیت صورت‌حساب ${taxProviderStatusTranslatorUtil(res.status)} می‌باشد.`,
});
this.store.updateStatus(res.status);
},
});
}
resendToTsp() {
this.resendToTspLoading.set(true);
this.store
.sendToTsp(this.invoiceId())
.pipe(
finalize(() => {
this.resendToTspLoading.set(false);
})
)
.subscribe();
}
correction() {
this.correctionLoading.set(true);
this.store
.sendToTsp(this.invoiceId())
.pipe(
finalize(() => {
this.correctionLoading.set(false);
})
)
.subscribe();
}
backFromSale() {
this.backFromSaleLoading.set(true);
this.store
.sendToTsp(this.invoiceId())
.pipe(
finalize(() => {
this.backFromSaleLoading.set(false);
})
)
.subscribe();
}
revoke() {
this.revokeLoading.set(true);
this.store
.sendToTsp(this.invoiceId())
.pipe(
finalize(() => {
this.revokeLoading.set(false);
})
)
.subscribe();
}
ngOnInit() {
this.store.getData(this.invoiceId());
}
@@ -9,7 +9,7 @@ import { Component, computed, EventEmitter, Input, Output } from '@angular/core'
imports: [CommonModule],
})
export class PosStatisticsInvoiceTypeCardComponent {
@Input() type: 'all' | 'success' | 'failure' | 'not_sended' | 'pending' | 'not_original' = 'all';
@Input() type: 'all' | 'success' | 'failure' | 'not_send' | 'pending' | 'not_original' = 'all';
@Input() count?: number = 0;
@Input() totalAmount?: number = 0;
@Input() totalTaxAmount?: number = 0;
@@ -48,7 +48,7 @@ export class PosStatisticsInvoiceTypeCardComponent {
bgColor: '#EF44441A',
borderColor: '#EF4444',
};
case 'not_sended':
case 'not_send':
return {
title: taxProviderStatusTranslatorUtil('NOT_SEND'),
icon: 'clock',
+1 -1
View File
@@ -3,7 +3,7 @@ export interface IPosStatisticsRawResponse {
success: IPosStatisticsItem;
failure: IPosStatisticsItem;
pending: IPosStatisticsItem;
not_sended: IPosStatisticsItem;
not_send: IPosStatisticsItem;
not_original: IPosStatisticsItem;
}
export interface IPosStatisticsResponse extends IPosStatisticsRawResponse {}
@@ -30,12 +30,12 @@
[count]="item()?.failure?.count"
(onClick)="toInvoicesPage('failure')" />
<pos-statistics-invoice-type-card
type="not_sended"
type="not_send"
[loading]="loading()"
[totalAmount]="item()?.not_sended?.total_amount"
[totalTaxAmount]="item()?.not_sended?.total_tax"
[count]="item()?.not_sended?.count"
(onClick)="toInvoicesPage('not_sended')" />
[totalAmount]="item()?.not_send?.total_amount"
[totalTaxAmount]="item()?.not_send?.total_tax"
[count]="item()?.not_send?.count"
(onClick)="toInvoicesPage('not_send')" />
<pos-statistics-invoice-type-card
type="pending"
[loading]="loading()"