update sale invoices models and some ui fix
This commit is contained in:
+13
-15
@@ -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
@@ -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,6 +13,7 @@
|
||||
</form>
|
||||
|
||||
<div class="form-group">
|
||||
@if (!isUnknownCustomer()) {
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<uikit-label> نوع تسویهحساب </uikit-label>
|
||||
<p-selectButton
|
||||
@@ -22,6 +23,8 @@
|
||||
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
@@ -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">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './devices';
|
||||
export * from './guild';
|
||||
export * from './invoiceTypes';
|
||||
export * from './providers';
|
||||
export * from './taxProviderStatus';
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './invoice-type-tag.component';
|
||||
export * from './type';
|
||||
@@ -0,0 +1 @@
|
||||
<p-tag [severity]="severity" size="large" [value]="translate || label"></p-tag>
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Tag } from 'primeng/tag';
|
||||
import { InvoiceTypes } from './type';
|
||||
|
||||
@Component({
|
||||
selector: 'catalog-invoice-type-tag',
|
||||
templateUrl: './invoice-type-tag.component.html',
|
||||
imports: [Tag],
|
||||
})
|
||||
export class CatalogInvoiceTypeTagComponent {
|
||||
@Input({ required: true }) status!: InvoiceTypes;
|
||||
@Input() translate!: string;
|
||||
|
||||
get severity() {
|
||||
switch (this.status) {
|
||||
case 'ORIGINAL':
|
||||
return 'success';
|
||||
case 'CORRECTION':
|
||||
return 'warn';
|
||||
case 'REVOKE':
|
||||
return 'danger';
|
||||
}
|
||||
}
|
||||
|
||||
get label() {
|
||||
switch (this.status) {
|
||||
case 'ORIGINAL':
|
||||
return 'اصلی';
|
||||
case 'CORRECTION':
|
||||
return 'اصلاحی';
|
||||
case 'REVOKE':
|
||||
return 'ابطالی';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export const InvoiceTypes = {
|
||||
ORIGINAL: 'ORIGINAL',
|
||||
CORRECTION: 'CORRECTION',
|
||||
REVOKE: 'REVOKE',
|
||||
} as const;
|
||||
|
||||
export type InvoiceTypes = (typeof InvoiceTypes)[keyof typeof InvoiceTypes];
|
||||
@@ -1,4 +1,11 @@
|
||||
<div class="flex justify-end gap-2">
|
||||
<p-button [label]="cancelLabel" severity="secondary" (click)="cancel()" />
|
||||
<p-button [label]="submitLabel" type="submit" [disabled]="disabled" [loading]="loading" (onClick)="submit()" />
|
||||
<button pButton [label]="cancelLabel" severity="secondary" (click)="cancel()"></button>
|
||||
<button
|
||||
pButton
|
||||
[label]="submitLabel"
|
||||
type="submit"
|
||||
class="min-w-28"
|
||||
[disabled]="disabled"
|
||||
[loading]="loading"
|
||||
(onClick)="submit()"></button>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { Button } from 'primeng/button';
|
||||
import { ButtonDirective } from 'primeng/button';
|
||||
|
||||
@Component({
|
||||
selector: 'app-form-footer-actions',
|
||||
templateUrl: './form-footer-actions.component.html',
|
||||
imports: [Button],
|
||||
imports: [ButtonDirective],
|
||||
})
|
||||
export class FormFooterActionsComponent {
|
||||
@Input() submitLabel = 'تایید';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
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 ISaleInvoiceFullRawResponse {
|
||||
@@ -11,11 +12,16 @@ export interface ISaleInvoiceFullRawResponse {
|
||||
pos: Pos;
|
||||
payments: Payment[];
|
||||
items: Item[];
|
||||
invoice_number: number;
|
||||
type: IEnumTranslate<InvoiceTypes>;
|
||||
created_at: string;
|
||||
notes?: string;
|
||||
customer?: Customer;
|
||||
unknown_customer?: UnknownCustomer;
|
||||
status: IEnumTranslate<TspProviderResponseStatus>;
|
||||
main_id: Maybe<string>;
|
||||
tax_id: Maybe<string>;
|
||||
reference_invoice: Maybe<string>;
|
||||
notes: Maybe<string>;
|
||||
}
|
||||
|
||||
export interface ISaleInvoiceFullResponse extends ISaleInvoiceFullRawResponse {}
|
||||
|
||||
@@ -17,14 +17,17 @@
|
||||
</ng-template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="listKeyValue">
|
||||
<app-key-value label="کد رهگیری" [value]="invoice.code" />
|
||||
<app-key-value label="شماره صورتحساب" [value]="invoice.invoice_number" />
|
||||
<app-key-value label="تاریخ فاکتور" [value]="invoice.invoice_date" type="dateTime" />
|
||||
<app-key-value label="تاریخ ایجاد فاکتور" [value]="invoice.created_at" type="dateTime" />
|
||||
<app-key-value label="نوع صورتحساب">
|
||||
<catalog-invoice-type-tag [status]="invoice.type.value" />
|
||||
</app-key-value>
|
||||
<app-key-value label="وضعیت صدور به سامانهی مودیان">
|
||||
<catalog-tax-provider-status-tag [status]="invoice.status.value" [translate]="invoice.status.translate" />
|
||||
</app-key-value>
|
||||
<div class="col-span-full">
|
||||
<app-key-value label="توضیحات" [value]="invoice.notes" />
|
||||
<app-key-value label="توضیحات" [value]="invoice.notes || '----'" />
|
||||
</div>
|
||||
</div>
|
||||
<p-divider align="center"> اطلاعات پرداخت </p-divider>
|
||||
|
||||
@@ -3,7 +3,10 @@ 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 { PosInfoStore } from '@/domains/pos/store';
|
||||
import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog';
|
||||
import {
|
||||
CatalogInvoiceTypeTagComponent,
|
||||
CatalogTaxProviderStatusTagComponent,
|
||||
} from '@/shared/catalog';
|
||||
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||
import { ISaleInvoiceFullResponse } from '@/shared/components/invoices/sale-invoice-full-response.model';
|
||||
import { PageLoadingComponent } from '@/shared/components/page-loading.component';
|
||||
@@ -45,6 +48,7 @@ export type TSaleInvoiceSingleViewVariant = 'full' | 'customer' | 'pos';
|
||||
UikitEmptyStateComponent,
|
||||
PriceMaskDirective,
|
||||
CatalogTaxProviderStatusTagComponent,
|
||||
CatalogInvoiceTypeTagComponent,
|
||||
],
|
||||
})
|
||||
export class SharedSaleInvoiceSingleViewComponent {
|
||||
|
||||
@@ -88,12 +88,12 @@ export class KeyValueComponent {
|
||||
}
|
||||
switch (this.type) {
|
||||
case 'simple':
|
||||
return this.value || '-';
|
||||
return this.value || '-----';
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
valueType = computed(() =>
|
||||
this.variant || ['boolean', 'has', 'active'].includes(this.type) ? 'tag' : 'text',
|
||||
this.variant || ['boolean', 'has', 'active'].includes(this.type) ? 'tag' : 'text'
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user