update sale invoices models and some ui fix

This commit is contained in:
2026-05-26 12:06:43 +03:30
parent eb671d5949
commit 9fdd5e451c
20 changed files with 147 additions and 77 deletions
@@ -1,5 +1,5 @@
<p-card class="border border-surface-border p-0! relative overflow-visible">
<div class="flex items-center gap-4 justify-between w-full">
<p-card class="border-surface-border relative overflow-visible border p-0!">
<div class="flex w-full items-center justify-between gap-4">
<span> {{ saleInvoice.invoice_number }} - {{ saleInvoice.code }} </span>
<catalog-tax-provider-status-tag [status]="saleInvoice.status.value" [translate]="saleInvoice.status.translate" />
</div>
@@ -9,48 +9,46 @@
{{ preparedInvoiceType() }}
</app-key-value>
<app-key-value alignment="end" label="مبلغ کل" [value]="saleInvoice.total_amount" type="price" />
<app-key-value alignment="end" label="نوع فاکتور">
<catalog-invoice-type-tag [status]="saleInvoice.type.value" />
</app-key-value>
<app-key-value alignment="end" label="تاریخ فاکتور" [value]="saleInvoice.created_at" type="dateTime" />
<app-key-value alignment="end" label="تاریخ ایجاد" [value]="saleInvoice.created_at" type="dateTime" />
</div>
<hr />
<div class="flex items-center justify-center gap-4">
@if (["success", "failure"].includes(saleInvoice.status.value.toLowerCase())) {
@if (['success', 'failure'].includes(saleInvoice.status.value.toLowerCase())) {
<p-button
label="ابطال"
type="button"
severity="danger"
(click)="revokeInvoice()"
[loading]="revokingInvoiceLoading()"
[disabled]="onAction()"
></p-button>
[disabled]="onAction()"></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "not_send") {
@if (saleInvoice.status.value.toLowerCase() === 'not_send') {
<p-button
label="ارسال فاکتور"
type="button"
(click)="sendInvoice()"
[loading]="sendingLoading()"
[disabled]="onAction()"
></p-button>
[disabled]="onAction()"></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "queued") {
@if (saleInvoice.status.value.toLowerCase() === 'queued') {
<p-button
label="استعلام وضعیت ارسال"
type="button"
severity="info"
(click)="getStatus()"
[loading]="gettingStatusLoading()"
[disabled]="onAction()"
></p-button>
[disabled]="onAction()"></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "failure") {
@if (saleInvoice.status.value.toLowerCase() === 'failure') {
<p-button
label="ارسال مجدد"
type="button"
(click)="resendInvoice()"
[loading]="resendingLoading()"
[disabled]="onAction()"
></p-button>
[disabled]="onAction()"></p-button>
}
<a [routerLink]="singlePageRoute()" pButton type="button" (click)="viewDetails()" outlined>مشاهده جزییات</a>
</div>
@@ -1,4 +1,5 @@
import { ToastService } from '@/core/services/toast.service';
import { CatalogInvoiceTypeTagComponent } from '@/shared/catalog';
import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog/taxProviderStatus';
import { KeyValueComponent } from '@/shared/components';
import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core';
@@ -20,6 +21,7 @@ import { PosSaleInvoicesService } from '../services/main.service';
RouterLink,
ButtonDirective,
CatalogTaxProviderStatusTagComponent,
CatalogInvoiceTypeTagComponent,
],
})
export class SaleInvoiceCardComponent {
@@ -39,11 +41,11 @@ export class SaleInvoiceCardComponent {
this.sendingLoading() ||
this.gettingStatusLoading() ||
this.resendingLoading() ||
this.revokingInvoiceLoading(),
this.revokingInvoiceLoading()
);
singlePageRoute = computed(() =>
posSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(this.saleInvoice?.id),
posSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(this.saleInvoice?.id)
);
preparedInvoiceType = computed(() => {
if (!this.saleInvoice) return '';
@@ -76,7 +78,7 @@ export class SaleInvoiceCardComponent {
} else {
this.toastService.success({ text: 'ارسال فاکتور با موفقیت انجام شد.' });
}
this.toastService.success({ text: 'ارسال فاکتور با موفقیت انجام شد.' });
// this.toastService.success({ text: 'ارسال فاکتور با موفقیت انجام شد.' });
this.refreshRequested.emit();
});
}
+18 -18
View File
@@ -1,22 +1,8 @@
import { Maybe } from '@/core';
import ISummary from '@/core/models/summary';
import { TspProviderResponseStatus } from '@/shared/catalog';
import { InvoiceTypes, TspProviderResponseStatus } from '@/shared/catalog';
import { IEnumTranslate } from '@/shared/models/enum_translate.type';
export interface IPosSaleInvoicesRawResponse {
id: string;
code: string;
invoice_date: string;
notes?: string;
total_amount: string;
pos: Pos;
consumer_account: ConsumerAccount;
created_at: string;
items_count: number;
payments: Payments[];
}
export interface IPosSaleInvoicesResponse extends IPosSaleInvoicesRawResponse {}
export interface IPosSaleInvoicesSummaryRawResponse {
id: string;
code: string;
@@ -24,12 +10,26 @@ export interface IPosSaleInvoicesSummaryRawResponse {
invoice_date: string;
created_at: string;
total_amount: string;
customer: Customer;
fiscal: null;
customer: Maybe<Customer>;
status: IEnumTranslate<TspProviderResponseStatus>;
type: IEnumTranslate<InvoiceTypes>;
main_id: Maybe<string>;
tax_id: Maybe<string>;
reference_invoice: Maybe<string>;
notes: Maybe<string>;
}
export interface IPosSaleInvoicesSummaryResponse extends IPosSaleInvoicesSummaryRawResponse {}
export interface IPosSaleInvoicesRawResponse extends IPosSaleInvoicesSummaryRawResponse {
pos: Pos;
consumer_account: ConsumerAccount;
items_count: number;
payments: Payments[];
}
export interface IPosSaleInvoicesResponse extends IPosSaleInvoicesRawResponse {}
interface ConsumerAccount {
role: string;
account: Account;
@@ -49,17 +49,17 @@ export class PosOrderSectionComponent {
customerNameToShow = computed(() => {
const type = this.store.customer().type;
const info = this.store.customer().info;
let customerNameToShow = 'نامشخص';
let customerNameToShow = 'رهگذر';
switch (type) {
case 'UNKNOWN':
customerNameToShow = `${info?.customer_unknown?.name || 'نامشخص'} (نوع دوم)`;
customerNameToShow = `${info?.customer_unknown?.name || 'رهگذر'} (نوع دوم)`;
break;
case 'INDIVIDUAL':
customerNameToShow = `${info?.customer_individual ? info?.customer_individual.first_name + ' ' + info?.customer_individual.last_name : 'نامشخص'} (نوع اول)`;
customerNameToShow = `${info?.customer_individual ? info?.customer_individual.first_name + ' ' + info?.customer_individual.last_name : '-----'} (نوع اول)`;
break;
case 'LEGAL':
customerNameToShow = `${info?.customer_legal?.company_name || 'نامشخص'} (نوع اول)`;
customerNameToShow = `${info?.customer_legal?.company_name || '-----'} (نوع اول)`;
break;
}
@@ -13,15 +13,18 @@
</form>
<div class="form-group">
<div class="flex items-center justify-between gap-3">
<uikit-label> نوع تسویه‌حساب </uikit-label>
<p-selectButton
[options]="settlementTypeItems"
[(ngModel)]="selectedSettlementType"
[allowEmpty]="false"
optionLabel="label"
optionValue="value" />
</div>
@if (!isUnknownCustomer()) {
<div class="flex items-center justify-between gap-3">
<uikit-label> نوع تسویه‌حساب </uikit-label>
<p-selectButton
[options]="settlementTypeItems"
[(ngModel)]="selectedSettlementType"
[allowEmpty]="false"
optionLabel="label"
optionValue="value" />
</div>
}
v
<uikit-field label="تعداد مراحل پرداخت با پوز" name="pay_by_terminal_steps">
<p-select
[options]="payByTerminalSteps()"
@@ -76,6 +76,7 @@ export class PosPaymentFormDialogComponent extends AbstractFormDialog<IPayment,
readonly submitOrderLoading = computed(() => this.store.submitOrderLoading());
readonly isGoldGuild = computed(() => this.posInfo.entity()?.guild.code.toLowerCase() === 'gold');
readonly isUnknownCustomer = computed(() => this.store.customer().type === 'UNKNOWN');
payByTerminalSteps = signal(
Array.from({ length: 10 }, (_, i) => ({
@@ -8,7 +8,7 @@ import { Component, computed, EventEmitter, Input, Output } from '@angular/core'
imports: [CommonModule],
})
export class PosStatisticsInvoiceTypeCardComponent {
@Input() type: 'all' | 'success' | 'failure' | 'notSended' | 'pending' | 'credit' = 'all';
@Input() type: 'all' | 'success' | 'failure' | 'not_sended' | 'pending' | 'not_original' = 'all';
@Input() count?: number = 0;
@Input() totalAmount?: number = 0;
@Input() totalTaxAmount?: number = 0;
@@ -36,18 +36,18 @@ export class PosStatisticsInvoiceTypeCardComponent {
case 'success':
return {
title: 'تایید شده',
icon: 'check',
icon: 'check-circle',
bgColor: '#22C55E1A',
borderColor: '#22C55E',
};
case 'failure':
return {
title: 'خطادار',
icon: 'times',
icon: 'ban',
bgColor: '#EF44441A',
borderColor: '#EF4444',
};
case 'notSended':
case 'not_sended':
return {
title: 'ارسال نشده',
icon: 'clock',
@@ -61,9 +61,9 @@ export class PosStatisticsInvoiceTypeCardComponent {
bgColor: '#3B82F61A',
borderColor: '#3B82F6',
};
case 'credit':
case 'not_original':
return {
title: 'اعتبار',
title: 'ارجاعی',
icon: 'credit-card',
bgColor: '#8B5CF61A',
borderColor: '#8B5CF6',
+2 -2
View File
@@ -3,8 +3,8 @@ export interface IPosStatisticsRawResponse {
success: IPosStatisticsItem;
failure: IPosStatisticsItem;
pending: IPosStatisticsItem;
notSended: IPosStatisticsItem;
credit: IPosStatisticsItem;
not_sended: 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="notSended"
type="not_sended"
[loading]="loading()"
[totalAmount]="item()?.notSended?.total_amount"
[totalTaxAmount]="item()?.notSended?.total_tax"
[count]="item()?.notSended?.count"
(onClick)="toInvoicesPage('notSended')" />
[totalAmount]="item()?.not_sended?.total_amount"
[totalTaxAmount]="item()?.not_sended?.total_tax"
[count]="item()?.not_sended?.count"
(onClick)="toInvoicesPage('not_sended')" />
<pos-statistics-invoice-type-card
type="pending"
[loading]="loading()"
@@ -44,11 +44,11 @@
[count]="item()?.pending?.count"
(onClick)="toInvoicesPage('pending')" />
<pos-statistics-invoice-type-card
type="credit"
type="not_original"
[loading]="loading()"
[totalAmount]="item()?.credit?.total_amount"
[totalTaxAmount]="item()?.credit?.total_tax"
[count]="item()?.credit?.count" />
[totalAmount]="item()?.not_original?.total_amount"
[totalTaxAmount]="item()?.not_original?.total_tax"
[count]="item()?.not_original?.count" />
}
</div>
<div class="fixed inset-x-0 bottom-0 p-4">