diff --git a/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.html b/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.html index dd9b4dd..6f3ecf1 100644 --- a/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.html +++ b/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.html @@ -14,7 +14,7 @@ - +
diff --git a/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.ts b/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.ts index 9e31568..43e0e7d 100644 --- a/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.ts +++ b/src/app/domains/consumer/components/invoices/shared-saleInvoice.component.ts @@ -1,5 +1,6 @@ import { Maybe } from '@/core'; import { NativeBridgeService } from '@/core/services'; +import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog'; import { AppCardComponent, KeyValueComponent } from '@/shared/components'; import { PageLoadingComponent } from '@/shared/components/page-loading.component'; import { @@ -9,8 +10,15 @@ import { import { PriceMaskDirective } from '@/shared/directives'; import { UikitEmptyStateComponent } from '@/uikit'; import { getGoodUnitTypeProperties } from '@/utils'; -import { Component, EventEmitter, inject, Input, Output, TemplateRef, ViewChild } from '@angular/core'; -import { Badge } from 'primeng/badge'; +import { + Component, + EventEmitter, + inject, + Input, + Output, + TemplateRef, + ViewChild, +} from '@angular/core'; import { ButtonDirective } from 'primeng/button'; import { Divider } from 'primeng/divider'; import { TableModule } from 'primeng/table'; @@ -24,7 +32,6 @@ export type TConsumerSaleInvoice = 'full' | 'customer' | 'pos'; imports: [ AppCardComponent, KeyValueComponent, - Badge, Divider, ButtonDirective, PageDataListComponent, @@ -32,6 +39,7 @@ export type TConsumerSaleInvoice = 'full' | 'customer' | 'pos'; PageLoadingComponent, UikitEmptyStateComponent, PriceMaskDirective, + CatalogTaxProviderStatusTagComponent, ], }) export class ConsumerSaleInvoiceSharedComponent { diff --git a/src/app/domains/consumer/models/saleInvoice.io.ts b/src/app/domains/consumer/models/saleInvoice.io.ts index e97b79c..a6be113 100644 --- a/src/app/domains/consumer/models/saleInvoice.io.ts +++ b/src/app/domains/consumer/models/saleInvoice.io.ts @@ -1,4 +1,6 @@ import ISummary from '@/core/models/summary'; +import { TspProviderResponseStatus } from '@/shared/catalog'; +import { IEnumTranslate } from '@/shared/models/enum_translate.type'; export interface ISaleInvoiceFullRawResponse { id: string; @@ -13,6 +15,7 @@ export interface ISaleInvoiceFullRawResponse { notes?: string; customer?: Customer; unknown_customer?: UnknownCustomer; + status: IEnumTranslate; } export interface ISaleInvoiceFullResponse extends ISaleInvoiceFullRawResponse {} diff --git a/src/app/domains/consumer/modules/businessActivities/components/form.component.html b/src/app/domains/consumer/modules/businessActivities/components/form.component.html index 3ea83ce..5bc388e 100644 --- a/src/app/domains/consumer/modules/businessActivities/components/form.component.html +++ b/src/app/domains/consumer/modules/businessActivities/components/form.component.html @@ -11,6 +11,7 @@ + diff --git a/src/app/domains/consumer/modules/businessActivities/components/form.component.ts b/src/app/domains/consumer/modules/businessActivities/components/form.component.ts index c4a7fe8..8422cf0 100644 --- a/src/app/domains/consumer/modules/businessActivities/components/form.component.ts +++ b/src/app/domains/consumer/modules/businessActivities/components/form.component.ts @@ -6,6 +6,7 @@ import { PartnerTokenComponent, } from '@/shared/components'; import { SharedDialogComponent } from '@/shared/components/dialog/dialog.component'; +import { InvoiceNumberSequenceComponent } from '@/shared/components/fields/invoice_number_sequence.component'; import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component'; import { fieldControl } from '@/shared/constants/fields'; import { Component, inject, Input } from '@angular/core'; @@ -22,8 +23,9 @@ import { BusinessActivitiesService } from '../services/main.service'; FormFooterActionsComponent, NameComponent, EconomicCodeComponent, - FiscalIdComponent, PartnerTokenComponent, + InvoiceNumberSequenceComponent, + FiscalIdComponent, ], }) export class ConsumerBusinessActivityFormComponent extends AbstractFormDialog< @@ -38,6 +40,9 @@ export class ConsumerBusinessActivityFormComponent extends AbstractFormDialog< economic_code: fieldControl.economic_code(this.initialValues?.economic_code || ''), fiscal_id: fieldControl.fiscal_id(this.initialValues?.fiscal_id || ''), partner_token: fieldControl.partner_token(this.initialValues?.partner_token || ''), + invoice_number_sequence: fieldControl.invoice_number_sequence( + this.initialValues?.invoice_number_sequence || 1, + ), }); override submitForm(payload: IBusinessActivityRequest) { diff --git a/src/app/domains/consumer/modules/businessActivities/components/list.component.html b/src/app/domains/consumer/modules/businessActivities/components/list.component.html index a6cedad..301e178 100644 --- a/src/app/domains/consumer/modules/businessActivities/components/list.component.html +++ b/src/app/domains/consumer/modules/businessActivities/components/list.component.html @@ -10,10 +10,13 @@ (onRefresh)="refresh()" > - + +@if (visibleForm()) { + +} diff --git a/src/app/domains/consumer/modules/businessActivities/models/io.d.ts b/src/app/domains/consumer/modules/businessActivities/models/io.d.ts index 94a676c..874f2de 100644 --- a/src/app/domains/consumer/modules/businessActivities/models/io.d.ts +++ b/src/app/domains/consumer/modules/businessActivities/models/io.d.ts @@ -8,6 +8,7 @@ export interface IBusinessActivityRawResponse { partner_token: string; guild: ISummary; created_at: string; + invoice_number_sequence: number; license_info: LicenseInfo; } export interface IBusinessActivityResponse extends IBusinessActivityRawResponse {} @@ -17,6 +18,7 @@ export interface IBusinessActivityRequest { fiscal_id: string; partner_token: string; name: string; + invoice_number_sequence: number; } interface LicenseInfo { diff --git a/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.html b/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.html index 1f6dfaa..cf50bea 100644 --- a/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.html +++ b/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.html @@ -1,11 +1,7 @@
{{ saleInvoice.invoice_number }} - {{ saleInvoice.code }} - +

diff --git a/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.ts b/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.ts index e1748e8..9a75f73 100644 --- a/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.ts +++ b/src/app/domains/pos/modules/saleInvoices/components/sale-invoice-card.component.ts @@ -1,4 +1,5 @@ import { ToastService } from '@/core/services/toast.service'; +import { CatalogTaxProviderStatusTagComponent } from '@/shared/catalog/taxProviderStatus'; import { KeyValueComponent } from '@/shared/components'; import { Component, computed, EventEmitter, inject, Input, Output, signal } from '@angular/core'; import { RouterLink } from '@angular/router'; @@ -13,7 +14,15 @@ import { PosSaleInvoicesService } from '../services/main.service'; @Component({ selector: 'pos-saleInvoice-card', templateUrl: './sale-invoice-card.component.html', - imports: [Button, KeyValueComponent, Tag, Card, RouterLink, ButtonDirective], + imports: [ + Button, + KeyValueComponent, + Tag, + Card, + RouterLink, + ButtonDirective, + CatalogTaxProviderStatusTagComponent, + ], }) export class SaleInvoiceCardComponent { private readonly service = inject(PosSaleInvoicesService); @@ -62,7 +71,7 @@ export class SaleInvoiceCardComponent { getStatus() { this.gettingStatusLoading.set(true); this.service - .refreshFiscalStatus(this.saleInvoice.id) + .getInquiry(this.saleInvoice.id) .pipe(finalize(() => this.gettingStatusLoading.set(false))) .subscribe((res) => { this.toastService.info({ diff --git a/src/app/domains/pos/modules/saleInvoices/constants/apiRoutes/index.ts b/src/app/domains/pos/modules/saleInvoices/constants/apiRoutes/index.ts index f26ca87..8113473 100644 --- a/src/app/domains/pos/modules/saleInvoices/constants/apiRoutes/index.ts +++ b/src/app/domains/pos/modules/saleInvoices/constants/apiRoutes/index.ts @@ -4,10 +4,10 @@ export const POS_SALE_INVOICES_API_ROUTES = { list: () => baseUrl(), single: (invoiceId: string) => `${baseUrl()}/${invoiceId}`, fiscal: { - send: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/send`, + send: (invoiceId: string) => `${baseUrl()}/${invoiceId}/send`, retry: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/retry`, status: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/status`, - refreshStatus: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/status/refresh`, + getInquiry: (invoiceId: string) => `${baseUrl()}/${invoiceId}/inquiry`, attempts: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/attempts`, }, }; diff --git a/src/app/domains/pos/modules/saleInvoices/models/io.d.ts b/src/app/domains/pos/modules/saleInvoices/models/io.d.ts index 1944a68..4dd32c4 100644 --- a/src/app/domains/pos/modules/saleInvoices/models/io.d.ts +++ b/src/app/domains/pos/modules/saleInvoices/models/io.d.ts @@ -25,7 +25,7 @@ export interface IPosSaleInvoicesSummaryRawResponse { total_amount: string; customer: Customer; fiscal: null; - status: IEnumTranslate; + status: IEnumTranslate; } export interface IPosSaleInvoicesSummaryResponse extends IPosSaleInvoicesSummaryRawResponse {} diff --git a/src/app/domains/pos/modules/saleInvoices/services/main.service.ts b/src/app/domains/pos/modules/saleInvoices/services/main.service.ts index aa5b399..ce8aa80 100644 --- a/src/app/domains/pos/modules/saleInvoices/services/main.service.ts +++ b/src/app/domains/pos/modules/saleInvoices/services/main.service.ts @@ -5,10 +5,10 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { POS_SALE_INVOICES_API_ROUTES } from '../constants'; import { - IPosSaleInvoicesFilterDto, IPosSaleInvoiceFiscalActionResponse, IPosSaleInvoiceFiscalAttemptsResponse, IPosSaleInvoiceFiscalStatusResponse, + IPosSaleInvoicesFilterDto, IPosSaleInvoicesSummaryRawResponse, IPosSaleInvoicesSummaryResponse, } from '../models'; @@ -19,7 +19,9 @@ export class PosSaleInvoicesService { private apiRoutes = POS_SALE_INVOICES_API_ROUTES; - getAll(query: IPosSaleInvoicesFilterDto = {}): Observable> { + getAll( + query: IPosSaleInvoicesFilterDto = {}, + ): Observable> { return this.http.get>( this.apiRoutes.list(), { params: query as Record }, @@ -31,25 +33,35 @@ export class PosSaleInvoicesService { } sendFiscal(invoiceId: string): Observable { - return this.http.post(this.apiRoutes.fiscal.send(invoiceId), {}); + return this.http.post( + this.apiRoutes.fiscal.send(invoiceId), + {}, + ); } retryFiscal(invoiceId: string): Observable { - return this.http.post(this.apiRoutes.fiscal.retry(invoiceId), {}); + return this.http.post( + this.apiRoutes.fiscal.retry(invoiceId), + {}, + ); } getFiscalStatus(invoiceId: string): Observable { - return this.http.get(this.apiRoutes.fiscal.status(invoiceId)); + return this.http.get( + this.apiRoutes.fiscal.status(invoiceId), + ); } - refreshFiscalStatus(invoiceId: string): Observable { - return this.http.post( - this.apiRoutes.fiscal.refreshStatus(invoiceId), + getInquiry(invoiceId: string): Observable { + return this.http.get( + this.apiRoutes.fiscal.getInquiry(invoiceId), {}, ); } getFiscalAttempts(invoiceId: string): Observable { - return this.http.get(this.apiRoutes.fiscal.attempts(invoiceId)); + return this.http.get( + this.apiRoutes.fiscal.attempts(invoiceId), + ); } } diff --git a/src/app/layout/default/app.layout.component.ts b/src/app/layout/default/app.layout.component.ts index 8951f67..cf890e7 100644 --- a/src/app/layout/default/app.layout.component.ts +++ b/src/app/layout/default/app.layout.component.ts @@ -163,7 +163,11 @@ export class AppLayout { this.router.navigateByUrl('super_admin'); break; case 'CONSUMER': - this.router.navigateByUrl('consumer'); + if (this.authService.currentAccount()?.role === 'OWNER') + this.router.navigateByUrl('consumer'); + else { + this.router.navigateByUrl('pos'); + } break; case 'PARTNER': this.router.navigateByUrl('partner'); diff --git a/src/app/shared/abstractClasses/abstract-form.ts b/src/app/shared/abstractClasses/abstract-form.ts index f1ba607..c8916f2 100644 --- a/src/app/shared/abstractClasses/abstract-form.ts +++ b/src/app/shared/abstractClasses/abstract-form.ts @@ -38,6 +38,9 @@ export abstract class AbstractForm< ngOnInit() { this.form.patchValue(this.initialValues ?? {}); + // Object.entries(this.form.controls).forEach(([key, control]) => { + // console.log(key, control); + // }); } ngOnChanges() { diff --git a/src/app/shared/apiEnum/constants/apiRoutes.ts b/src/app/shared/apiEnum/constants/apiRoutes.ts index f2a7f0d..02676e3 100644 --- a/src/app/shared/apiEnum/constants/apiRoutes.ts +++ b/src/app/shared/apiEnum/constants/apiRoutes.ts @@ -19,5 +19,5 @@ export const ENUMS_API_ROUTES = { unitType: `${baseUrl}/unit_type`, goodPricingModel: `${baseUrl}/good_pricing_model`, consumerRole: `${baseUrl}/consumer_role`, - fiscalResponseStatus: `${baseUrl}/fiscal_response_status`, + fiscalResponseStatus: `${baseUrl}/tsp_provider_response_status`, }; diff --git a/src/app/shared/catalog/index.ts b/src/app/shared/catalog/index.ts index bab7efc..52c36fc 100644 --- a/src/app/shared/catalog/index.ts +++ b/src/app/shared/catalog/index.ts @@ -1,3 +1,4 @@ export * from './devices'; export * from './guild'; export * from './providers'; +export * from './taxProviderStatus'; diff --git a/src/app/shared/catalog/taxProviderStatus/index.ts b/src/app/shared/catalog/taxProviderStatus/index.ts new file mode 100644 index 0000000..23c9ca5 --- /dev/null +++ b/src/app/shared/catalog/taxProviderStatus/index.ts @@ -0,0 +1,2 @@ +export * from './tax-provider-status-tag.component'; +export * from './type'; diff --git a/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.html b/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.html new file mode 100644 index 0000000..23b4831 --- /dev/null +++ b/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.html @@ -0,0 +1 @@ + diff --git a/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.ts b/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.ts new file mode 100644 index 0000000..dd0f335 --- /dev/null +++ b/src/app/shared/catalog/taxProviderStatus/tax-provider-status-tag.component.ts @@ -0,0 +1,43 @@ +import { Component, Input } from '@angular/core'; +import { Tag } from 'primeng/tag'; +import { TspProviderResponseStatus } from './type'; + +@Component({ + selector: 'catalog-tax-provider-status-tag', + templateUrl: './tax-provider-status-tag.component.html', + imports: [Tag], +}) +export class CatalogTaxProviderStatusTagComponent { + @Input({ required: true }) status!: TspProviderResponseStatus; + @Input() translate!: string; + + get severity() { + switch (this.status) { + case 'SUCCESS': + return 'success'; + case 'FAILURE': + return 'danger'; + case 'NOT_SEND': + return 'warn'; + case 'QUEUED': + return 'info'; + default: + return 'secondary'; + } + } + + get label() { + switch (this.status) { + case 'SUCCESS': + return 'موفق'; + case 'FAILURE': + return 'ناموفق'; + case 'NOT_SEND': + return 'ارسال نشده'; + case 'QUEUED': + return 'در صف ارسال'; + default: + return 'نامشخص'; + } + } +} diff --git a/src/app/shared/catalog/taxProviderStatus/type.ts b/src/app/shared/catalog/taxProviderStatus/type.ts new file mode 100644 index 0000000..29e177b --- /dev/null +++ b/src/app/shared/catalog/taxProviderStatus/type.ts @@ -0,0 +1,9 @@ +export const TspProviderResponseStatus = { + SUCCESS: 'SUCCESS', + FAILURE: 'FAILURE', + NOT_SEND: 'NOT_SEND', + QUEUED: 'QUEUED', +} as const; + +export type TspProviderResponseStatus = + (typeof TspProviderResponseStatus)[keyof typeof TspProviderResponseStatus]; diff --git a/src/app/shared/components/fields/invoice_number_sequence.component.ts b/src/app/shared/components/fields/invoice_number_sequence.component.ts new file mode 100644 index 0000000..2c4b958 --- /dev/null +++ b/src/app/shared/components/fields/invoice_number_sequence.component.ts @@ -0,0 +1,20 @@ +import { Component, Input } from '@angular/core'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { InputComponent } from '../input/input.component'; + +@Component({ + selector: 'field-invoice-number-sequence', + template: ``, + imports: [ReactiveFormsModule, InputComponent], +}) +export class InvoiceNumberSequenceComponent { + @Input({ required: true }) control = new FormControl(1); + @Input() name = 'invoice_number_sequence'; + @Input() min? = 1; +} diff --git a/src/app/shared/constants/fields/index.ts b/src/app/shared/constants/fields/index.ts index 701adad..456556b 100644 --- a/src/app/shared/constants/fields/index.ts +++ b/src/app/shared/constants/fields/index.ts @@ -3,7 +3,7 @@ import { nationalIdValidator } from '@/core/validators/national-id.validator'; import { ValidatorFn, Validators } from '@angular/forms'; const required = () => [Validators.required] as ValidatorFn[]; -type ControlConfig = [string, ValidatorFn[]]; +type ControlConfig = [any, ValidatorFn[]]; export const fieldControl = { name: (value = '', isRequired = true): ControlConfig => [value, isRequired ? required() : []], @@ -78,6 +78,10 @@ export const fieldControl = { value, isRequired ? required() : [], ], + invoice_number_sequence: (value = 1, isRequired = true): ControlConfig => [ + value, + isRequired ? [Validators.required, Validators.min(1)] : [Validators.min(1)], + ], guild_id: (value = '', isRequired = true): ControlConfig => [value, isRequired ? required() : []], license_starts_at: (value = '', isRequired = true): ControlConfig => [ value,