update many things

This commit is contained in:
2026-05-04 20:02:10 +03:30
parent 797aecd489
commit ec452bca22
72 changed files with 1375 additions and 606 deletions
@@ -4,24 +4,32 @@
<uikit-empty-state> </uikit-empty-state>
} @else {
<div class="flex flex-col gap-6">
<app-card-data cardTitle="اطلاعات فاکتور" [editable]="false">
<app-card-data cardTitle="اطلاعات فاکتور" [editable]="false" [backRoute]="backRoute">
<ng-template #moreActions>
<button pButton type="button" label="چاپ" icon="pi pi-print" outlined (click)="printInvoice()"></button>
<button
pButton
type="button"
label="چاپ"
icon="pi pi-print"
outlined
size="small"
(click)="printInvoice()"
></button>
</ng-template>
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
<app-key-value label="کد رهگیری" [value]="invoice.code" />
<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-tax-provider-status-tag [status]="invoice.status.value" [translate]="invoice.status.translate" />
</app-key-value>
<div class="col-span-3">
<div class="col-span-full">
<app-key-value label="توضیحات" [value]="invoice.notes" />
</div>
</div>
<p-divider align="center"> اطلاعات پرداخت </p-divider>
<div class="grid grid-cols-3 gap-4 items-center">
<div class="grid md:grid-cols-3 sm:grid-cols-2 sm:gap-4 gap-3 items-center">
<app-key-value label="مجموع قابل پرداخت" [value]="invoice.total_amount" type="price" />
@for (payment of invoice.payments; track $index) {
<app-key-value
@@ -33,7 +41,7 @@
</div>
<p-divider align="center"> اطلاعات صادر کننده </p-divider>
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
<app-key-value label="کسب و کار" [value]="invoice.pos!.complex.business_activity.name" />
<app-key-value label="مجموعه" [value]="invoice.pos!.complex.name" />
<app-key-value label="پایانه‌ی فروش" [value]="invoice.pos!.name" />
@@ -43,7 +51,7 @@
@if (variant !== "customer") {
<p-divider align="center"> اطلاعات مشتری </p-divider>
@if (invoice.customer) {
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
@if (invoice.customer.type === "INDIVIDUAL") {
<app-key-value label="نوع مشتری" value="حقیقی" />
<app-key-value label="نام" [value]="invoice.customer.individual?.first_name" />
@@ -60,7 +68,7 @@
}
</div>
} @else if (invoice.unknown_customer) {
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
<app-key-value label="نوع مشتری" value="نوع دوم" />
<app-key-value label="عنوان" [value]="invoice.unknown_customer.name" />
<app-key-value label="کد ثبتی" [value]="invoice.unknown_customer.national_code" />
@@ -19,6 +19,7 @@ import {
TemplateRef,
ViewChild,
} from '@angular/core';
import { UrlTree } from '@angular/router';
import { ButtonDirective } from 'primeng/button';
import { Divider } from 'primeng/divider';
import { TableModule } from 'primeng/table';
@@ -48,6 +49,7 @@ export class ConsumerSaleInvoiceSharedComponent {
@Input({ required: true }) loading!: boolean;
@Input() invoice?: Maybe<ISaleInvoiceFullResponse>;
@Input() variant: TConsumerSaleInvoice = 'full';
@Input() backRoute?: UrlTree | string | any[];
@Output() onRefresh = new EventEmitter<void>();
@@ -21,7 +21,7 @@ export class ConsumerBusinessActivityGoodsListComponent extends AbstractList<ICo
@Input() header: IColumn[] = [
{ field: 'id', header: 'شناسه', type: 'id' },
{ field: 'name', header: 'عنوان' },
{ field: 'sku', header: 'شناسه‌ی عمومی' },
{ field: 'sku', header: 'شناسه‌ عمومی' },
{
field: 'category',
header: 'دسته‌بندی',
@@ -1,10 +1,10 @@
<div class="flex flex-col gap-6">
<app-card-data cardTitle="اطلاعات پایانه‌ی فروش" [editable]="true" [(editMode)]="editMode">
<app-card-data cardTitle="اطلاعات پایانه‌ فروش" [editable]="true" [(editMode)]="editMode">
<ng-template #moreActions>
<p-button type="button" variant="outlined" (onClick)="toPosLanding()"> ورود به پایانه </p-button>
<p-button type="button" variant="outlined" size="small" (onClick)="toPosLanding()"> ورود به پایانه </p-button>
</ng-template>
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
<app-key-value label="عنوان" [value]="pos()?.name" />
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
@@ -1,5 +1,5 @@
<app-page-data-list
pageTitle="آخرین فاکتورهای صادر شده‌ی امروز"
pageTitle="آخرین فاکتورهای صادر شده امروز"
[columns]="columns"
emptyPlaceholderTitle="تا به این لحظه فاکتوری صادر نشده است."
[items]="items()"
@@ -1,10 +1,10 @@
<div class="flex flex-col gap-6">
<app-card-data cardTitle="اطلاعات پایانه‌ی فروش" [editable]="true" [(editMode)]="editMode">
<app-card-data cardTitle="اطلاعات پایانه‌ فروش" [editable]="true" [(editMode)]="editMode">
<ng-template #moreActions>
<p-button type="button" variant="outlined" (onClick)="toPosLanding()"> ورود به پایانه </p-button>
<p-button type="button" variant="outlined" size="small" (onClick)="toPosLanding()"> ورود به پایانه </p-button>
</ng-template>
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<div class="listKeyValue">
<app-key-value label="عنوان" [value]="pos()?.name" />
<app-key-value label="نوع پایانه" [value]="pos()?.pos_type" />
<app-key-value label="شماره سریال" [value]="pos()?.serial_number" />
@@ -13,7 +13,7 @@
name="starts_at"
hint="مدت زمان لایسنس‌ها ۱ ساله هستند."
/>
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
<!-- <uikit-datepicker label="تاریخ انقضا لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
</shared-dialog>
@@ -8,7 +8,7 @@
<app-key-value label="عنوان" [value]="businessActivity()?.name" />
<app-key-value label="کد اقتصادی" [value]="businessActivity()?.economic_code" />
<app-key-value label="صنف" [value]="businessActivity()?.guild?.name" />
<app-key-value label="تاریخ انقضای مجوز" [value]="businessActivity()?.license_info?.expires_at" type="date" />
<app-key-value label="تاریخ انقضا مجوز" [value]="businessActivity()?.license_info?.expires_at" type="date" />
<app-key-value label="تعداد کاربران مجاز" [value]="businessActivity()?.license_info?.accounts_limit" />
</div>
</div>
@@ -1,5 +1,5 @@
<div class="flex flex-col gap-6">
<app-card-data cardTitle="اطلاعات پایانه‌ی فروش" [editable]="true" [(editMode)]="editMode">
<app-card-data cardTitle="اطلاعات پایانه‌ فروش" [editable]="true" [(editMode)]="editMode">
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<app-key-value label="عنوان" [value]="pos()?.name" />
@@ -1,8 +1,9 @@
<form [formGroup]="form" (submit)="submit()">
<app-input [control]="form.controls.first_name" name="first_name" label="نام" />
<app-input [control]="form.controls.last_name" name="last_name" label="نام خانوادگی" />
<app-input [control]="form.controls.national_id" name="national_id" label="کد ملی" type="nationalId" />
<app-input [control]="form.controls.economic_code" name="economic_code" label="کد اقتصادی" maxlength="11" />
<field-first-name [control]="form.controls.first_name" />
<field-last-name [control]="form.controls.last_name" />
<field-mobile-number [control]="form.controls.mobile_number" />
<field-national-id [control]="form.controls.national_id" />
<field-economic-code [control]="form.controls.economic_code" />
<app-form-footer-actions submitLabel="ثبت مشتری و ادامه" (onCancel)="close()" (onSubmit)="submit()" />
</form>
@@ -1,11 +1,16 @@
import { postalCodeValidator } from '@/core/validators';
import { nationalIdValidator } from '@/core/validators/national-id.validator';
import { AbstractForm } from '@/shared/abstractClasses';
import { InputComponent } from '@/shared/components';
import {
EconomicCodeComponent,
FirstNameComponent,
LastNameComponent,
MobileNumberComponent,
NationalIdComponent,
} from '@/shared/components';
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
import { fieldControl } from '@/shared/constants';
import { CustomerType } from '@/shared/localEnum/constants/customerTypes';
import { Component, inject } from '@angular/core';
import { ReactiveFormsModule, Validators } from '@angular/forms';
import { Component, computed, inject } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { Observable } from 'rxjs';
import { IIndividualCustomer } from '../../../models/customer';
import { PosLandingStore } from '../../../store/main.store';
@@ -13,36 +18,31 @@ import { PosLandingStore } from '../../../store/main.store';
@Component({
selector: 'pos-customer-individual-form',
templateUrl: './form.component.html',
imports: [ReactiveFormsModule, InputComponent, FormFooterActionsComponent],
imports: [
ReactiveFormsModule,
FormFooterActionsComponent,
FirstNameComponent,
LastNameComponent,
NationalIdComponent,
EconomicCodeComponent,
MobileNumberComponent,
],
})
export class CustomerIndividualFormComponent extends AbstractForm<
IIndividualCustomer,
IIndividualCustomer
> {
private readonly store = inject(PosLandingStore);
costumerInfo = computed(() => this.store.customer().info?.customer_individual);
override showSuccessMessage = false;
form = this.fb.group({
first_name: [
this.store.customer().info?.customer_individual?.first_name || '',
[Validators.required],
],
last_name: [
this.store.customer().info?.customer_individual?.last_name || '',
[Validators.required],
],
national_id: [
this.store.customer().info?.customer_individual?.national_id || '',
[Validators.required, nationalIdValidator()],
],
economic_code: [
this.store.customer().info?.customer_individual?.economic_code || '',
[Validators.required],
],
postal_code: [
this.store.customer().info?.customer_individual?.postal_code || '',
[postalCodeValidator()],
],
first_name: fieldControl.first_name(this.costumerInfo()?.first_name || ''),
last_name: fieldControl.last_name(this.costumerInfo()?.last_name || ''),
national_id: fieldControl.national_id(this.costumerInfo()?.national_id || ''),
postal_code: fieldControl.postal_code(this.costumerInfo()?.postal_code || ''),
economic_code: fieldControl.economic_code(this.costumerInfo()?.economic_code || ''),
mobile_number: fieldControl.mobile_number(this.costumerInfo()?.mobile_number || ''),
});
override submitForm() {
@@ -1,5 +1,5 @@
<form [formGroup]="form" (submit)="submit()">
<app-input [control]="form.controls.name" name="name" label="نام مشتری" />
<app-input [control]="form.controls.national_id" name="national_id" label="شماره ملی" type="nationalId" />
<app-input [control]="form.controls.name" name="name" label="نام" />
<app-form-footer-actions submitLabel="ثبت بدون اطلاعات خریدار و ادامه" (onCancel)="close()" />
</form>
@@ -12,7 +12,7 @@
<button
pButton
type="button"
icon="pi pi-refresh"
icon="pi pi-trash"
outlined
severity="danger"
size="small"
@@ -75,6 +75,15 @@ export class PosGoldPayloadFormComponent extends AbstractForm<
this.updateCalculateAmount(value as any);
});
form.controls.payload.controls.profit_amount.valueChanges.subscribe((value) => {
// if ((form.controls.discount_amount.value || 0) > (value || 0)) {
form.controls.discount_amount.setValue(0);
// }
});
form.controls.payload.controls.profit_percentage.valueChanges.subscribe((value) => {
form.controls.discount_amount.setValue(0);
});
form.setValue({
unit_price: 200_000_000,
quantity: 2,
@@ -3,6 +3,7 @@ export interface IIndividualCustomer {
last_name: string;
national_id: string;
postal_code: string;
mobile_number: string;
economic_code: string;
is_favorite?: boolean;
}
@@ -5,10 +5,11 @@
<p-button
icon="pi pi-filter"
type="button"
size="small"
[outlined]="!activeFilters().length"
(click)="toggleFilterVisible()"
></p-button>
<button pButton icon="pi pi-refresh" type="button" outlined (click)="refresh()"></button>
<button pButton icon="pi pi-refresh" type="button" size="small" outlined (click)="refresh()"></button>
</div>
</ng-template>
</app-inner-pages-header>
@@ -14,19 +14,43 @@
</div>
<hr />
<div class="flex items-center justify-center gap-4">
@if (["success", "failure"].includes(saleInvoice.status.value.toLowerCase())) {
<p-button
label="ابطال"
type="button"
severity="danger"
(click)="revokeInvoice()"
[loading]="revokingInvoiceLoading()"
[disabled]="onAction()"
></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "not_send") {
<p-button label="ارسال فاکتور" type="button" (click)="sendInvoice()" [loading]="sendingLoading()"></p-button>
<p-button
label="ارسال فاکتور"
type="button"
(click)="sendInvoice()"
[loading]="sendingLoading()"
[disabled]="onAction()"
></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "queued") {
<p-button
label="استعلام وضعیت ارسال"
type="button"
severity="info"
(click)="getStatus()"
[loading]="gettingStatusLoading()"
[disabled]="onAction()"
></p-button>
}
@if (saleInvoice.status.value.toLowerCase() === "failure") {
<p-button label="ارسال فاکتور" type="button" (click)="resendInvoice()" [loading]="resendingLoading()"></p-button>
<p-button
label="ارسال مجدد"
type="button"
(click)="resendInvoice()"
[loading]="resendingLoading()"
[disabled]="onAction()"
></p-button>
}
<a [routerLink]="singlePageRoute()" pButton type="button" (click)="viewDetails()" outlined>مشاهده جزییات</a>
</div>
@@ -5,7 +5,6 @@ import { Component, computed, EventEmitter, inject, Input, Output, signal } from
import { RouterLink } from '@angular/router';
import { Button, ButtonDirective } from 'primeng/button';
import { Card } from 'primeng/card';
import { Tag } from 'primeng/tag';
import { finalize } from 'rxjs';
import { posSaleInvoicesNamedRoutes } from '../constants';
import { IPosSaleInvoicesSummaryResponse } from '../models';
@@ -17,7 +16,6 @@ import { PosSaleInvoicesService } from '../services/main.service';
imports: [
Button,
KeyValueComponent,
Tag,
Card,
RouterLink,
ButtonDirective,
@@ -34,6 +32,15 @@ export class SaleInvoiceCardComponent {
sendingLoading = signal(false);
gettingStatusLoading = signal(false);
resendingLoading = signal(false);
revokingInvoiceLoading = signal(false);
onAction = computed(
() =>
this.sendingLoading() ||
this.gettingStatusLoading() ||
this.resendingLoading() ||
this.revokingInvoiceLoading(),
);
singlePageRoute = computed(() =>
posSaleInvoicesNamedRoutes.saleInvoice.meta.pagePath!(this.saleInvoice?.id),
@@ -74,9 +81,6 @@ export class SaleInvoiceCardComponent {
.getInquiry(this.saleInvoice.id)
.pipe(finalize(() => this.gettingStatusLoading.set(false)))
.subscribe((res) => {
this.toastService.info({
text: `وضعیت: ${res.status || 'نامشخص'}`,
});
this.refreshRequested.emit();
});
}
@@ -91,5 +95,16 @@ export class SaleInvoiceCardComponent {
this.refreshRequested.emit();
});
}
revokeInvoice() {
this.revokingInvoiceLoading.set(true);
this.service
.revoke(this.saleInvoice.id)
.pipe(finalize(() => this.revokingInvoiceLoading.set(false)))
.subscribe(() => {
this.toastService.success({ text: 'ابطال فاکتور با موفقیت انجام شد.' });
this.refreshRequested.emit();
});
}
viewDetails() {}
}
@@ -8,6 +8,7 @@ export const POS_SALE_INVOICES_API_ROUTES = {
retry: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/retry`,
status: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/status`,
getInquiry: (invoiceId: string) => `${baseUrl()}/${invoiceId}/inquiry`,
revoke: (invoiceId: string) => `${baseUrl()}/${invoiceId}/revoke`,
attempts: (invoiceId: string) => `${baseUrl()}/${invoiceId}/fiscal/attempts`,
},
};
@@ -1,4 +1,5 @@
import ISummary from '@/core/models/summary';
import { TspProviderResponseStatus } from '@/shared/catalog';
import { IEnumTranslate } from '@/shared/models/enum_translate.type';
export interface IPosSaleInvoicesRawResponse {
@@ -59,6 +59,13 @@ export class PosSaleInvoicesService {
);
}
revoke(invoiceId: string): Observable<IPosSaleInvoiceFiscalStatusResponse> {
return this.http.post<IPosSaleInvoiceFiscalStatusResponse>(
this.apiRoutes.fiscal.revoke(invoiceId),
{},
);
}
getFiscalAttempts(invoiceId: string): Observable<IPosSaleInvoiceFiscalAttemptsResponse> {
return this.http.get<IPosSaleInvoiceFiscalAttemptsResponse>(
this.apiRoutes.fiscal.attempts(invoiceId),
@@ -1 +1,3 @@
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice()" variant="pos" />
<div class="p-4">
<consumer-saleInvoice-shared [loading]="loading()" [invoice]="invoice()" [backRoute]="backRoute()" variant="pos" />
</div>
@@ -2,6 +2,7 @@ import { ConsumerSaleInvoiceSharedComponent } from '@/domains/consumer/component
import pageParamsUtils from '@/utils/page-params.utils';
import { Component, computed, inject, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { posSaleInvoicesNamedRoutes } from '../constants';
import { PosSaleInvoiceStore } from '../store/main.store';
@Component({
@@ -19,6 +20,8 @@ export class PosSaleInvoiceComponent {
readonly invoice = computed(() => this.store.entity());
readonly loading = computed(() => this.store.loading());
readonly backRoute = computed(() => posSaleInvoicesNamedRoutes.saleInvoices.meta.pagePath!());
ngOnInit() {
this.store.getData(this.invoiceId());
}
@@ -37,7 +37,7 @@ export const SUPER_ADMIN_MENU_ITEMS = [
routerLink: ['/super_admin/guilds'],
},
{
label: 'شناسه‌ی کالاها',
label: 'شناسه کالاها',
icon: 'pi pi-fw pi-good',
routerLink: [stockKeepingUnitsNamedRoutes.stockKeepingUnits.meta.pagePath!()],
},
@@ -25,7 +25,7 @@
name="license.starts_at"
hint="مدت زمان لایسنس‌ها ۱ ساله هستند."
/> -->
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.license.controls.expires_at" name="license.expires_at" /> -->
<!-- <uikit-datepicker label="تاریخ انقضا لایسنس" [control]="form.controls.license.controls.expires_at" name="license.expires_at" /> -->
<!-- <app-partner-select label="شریک تجاری" [control]="form.controls.license.controls.partner_id" /> -->
}
@@ -13,7 +13,7 @@
name="starts_at"
hint="مدت زمان لایسنس‌ها ۱ ساله هستند."
/>
<!-- <uikit-datepicker label="تاریخ انقضای لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
<!-- <uikit-datepicker label="تاریخ انقضا لایسنس" [control]="form.controls.expires_at" name="expires_at" /> -->
<app-partner-select label="شریک تجاری" [control]="form.controls.partner_id" [showClear]="true" />
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
</form>
@@ -37,7 +37,7 @@ export class ConsumersComponent extends AbstractList<IAdminConsumerResponse> {
},
// {
// field: 'license_expires_at',
// header: 'تاریخ انقضای لایسنس',
// header: 'تاریخ انقضا لایسنس',
// customDataModel(item) {
// if (item.license_info) {
// return formatJalali(item.license_info.expires_at);
@@ -1,5 +1,5 @@
<div class="flex flex-col gap-6">
<app-card-data cardTitle="اطلاعات پایانه‌ی فروش" [editable]="true" [(editMode)]="editMode">
<app-card-data cardTitle="اطلاعات پایانه‌ فروش" [editable]="true" [(editMode)]="editMode">
<div class="flex flex-col gap-4">
<div class="grid grid-cols-3 gap-4 items-center">
<app-key-value label="عنوان" [value]="pos()?.name" />
@@ -15,7 +15,7 @@
/>
}
<app-input label="عنوان" [control]="form.controls.name" name="name" />
<field-sku label="شناسه‌ی کالا" [control]="form.controls.sku_id" name="sku_id" />
<field-sku label="شناسه کالا" [control]="form.controls.sku_id" name="sku_id" />
<admin-guild-categories-select
[guildId]="guildId"
label="دسته‌بندی"
@@ -20,7 +20,7 @@ export class GuildGoodsListComponent extends AbstractList<IGuildGoodsResponse> {
@Input() header: IColumn[] = [
{ field: 'image_url', header: 'تصویر', type: 'thumbnail' },
{ field: 'name', header: 'عنوان' },
{ field: 'sku', header: 'شناسه‌ی کالا', type: 'nested', nestedOption: { path: 'sku.name' } },
{ field: 'sku', header: 'شناسه کالا', type: 'nested', nestedOption: { path: 'sku.name' } },
{
field: 'category',
header: 'دسته‌بندی',
@@ -1,5 +1,5 @@
<app-page-data-list
pageTitle="گزارش شارژ‌های ثبت شده‌ی کاربر"
pageTitle="لیست شارژ‌ کاربر"
[columns]="columns"
emptyPlaceholderTitle="تا به حال شارژ کاربری انجام نشده‌ است"
[items]="items()"
@@ -17,15 +17,16 @@ export class AdminPartnerChargeAccountListComponent extends AbstractList<IAdminP
override setColumns(): void {
this.columns = [
{ field: 'tracking_code', header: 'کد پیگیری' },
{ field: 'charged_license_count', header: 'تعداد شارژ کاربر' },
{ field: 'remained_license_count', header: 'شارژ باقی مانده' },
{ field: 'charged_license_count', header: 'تعداد شارژ کاربر', type: 'number' },
{ field: 'remained_license_count', header: 'شارژ باقی مانده', type: 'number' },
{
field: 'activation_count',
header: 'مقدار مصرف شده',
type: 'number',
},
{
field: 'activation_expires_at',
header: 'تاریخ انقضای فروش',
header: 'تاریخ انقضا فروش',
type: 'date',
dateOption: {
expiredMode: true,
@@ -1,5 +1,5 @@
<app-page-data-list
pageTitle="گزارش شارژ‌های ثبت شده‌ی لایسنس‌ها"
pageTitle="لیست شارژ‌ لایسنس‌"
[columns]="columns"
emptyPlaceholderTitle="تا به حال شارژ لایسنسی انجام نشده‌ است"
[items]="items()"
@@ -18,15 +18,16 @@ export class AdminPartnerChargeLicenseTransactionListComponent extends AbstractL
override setColumns(): void {
this.columns = [
{ field: 'tracking_code', header: 'کد پیگیری' },
{ field: 'charged_license_count', header: 'لایسنس‌های خریداری شده' },
{ field: 'remained_license_count', header: 'لایسنس‌های باقی‌مانده' },
{ field: 'charged_license_count', header: 'لایسنس خریداری شده', type: 'number' },
{ field: 'remained_license_count', header: 'لایسنس باقی‌مانده', type: 'number' },
{
field: 'activation_count',
header: 'لایسنس‌های فروخته شده',
header: 'لایسنس فروخته شده',
type: 'number',
},
{
field: 'activation_expires_at',
header: 'تاریخ انقضای فروش',
header: 'تاریخ انقضا فروش',
type: 'date',
dateOption: {
expiredMode: true,
@@ -1,5 +1,5 @@
<app-page-data-list
pageTitle="لیست لایسنس‌های فروخته شده"
pageTitle="لیست لایسنس فروخته شده"
[columns]="columns"
emptyPlaceholderTitle="تا به حال لایسنسی فروخته نشده‌ است"
[items]="items()"
@@ -27,11 +27,11 @@ export class AdminPartnerLicensesComponent extends AbstractList<IPartnerActivate
},
{
field: 'license',
header: 'تعداد کاربر قابل تعریف',
header: 'تعداد کاربر مجاز',
type: 'nested',
nestedOption: { path: 'license.accounts_limit' },
nestedOption: { path: 'license.accounts_limit', type: 'number' },
},
{ field: 'expires_at', header: 'تاریخ انقضای لایسنس', type: 'date' },
{ field: 'expires_at', header: 'تاریخ انقضا لایسنس', type: 'date' },
];
}
@@ -35,7 +35,7 @@ export class PartnersComponent extends AbstractList<IPartnerResponse> {
},
{
field: 'license_renew',
header: 'تعداد لایسنس‌های تمدیدی',
header: 'تعداد لایسنس تمدیدی',
customDataModel: this.licensesRenewStatus,
},
{ field: 'status', header: 'وضعیت' },
@@ -8,12 +8,52 @@
<div class="grid grid-cols-3 gap-4 items-center">
<app-key-value label="عنوان شریک تجاری" [value]="partner()?.name" />
<app-key-value label="کد شریک تجاری" [value]="partner()?.code" />
<div class="col-span-3 grid grid-cols-3 gap-4 mt-6">
<partner-license-info-template
title="لایسنس‌ها"
[total]="partner()?.licenses_status?.total || 0"
[expired]="partner()?.licenses_status?.expired || 0"
[activated]="partner()?.licenses_status?.used || 0"
[remained]="
(partner()?.licenses_status?.total || 0) -
(partner()?.licenses_status?.used || 0) -
(partner()?.licenses_status?.expired || 0)
"
/>
<partner-license-info-template
title="شارژ کاربران"
[total]="partner()?.account_quota_status?.total || 0"
[expired]="partner()?.account_quota_status?.expired || 0"
[activated]="partner()?.account_quota_status?.used || 0"
[remained]="
(partner()?.account_quota_status?.total || 0) -
(partner()?.account_quota_status?.used || 0) -
(partner()?.account_quota_status?.expired || 0)
"
/>
<partner-license-info-template
title="تمدید لایسنس‌ها"
[total]="partner()?.license_renew_status?.total || 0"
[expired]="partner()?.license_renew_status?.expired || 0"
[activated]="partner()?.license_renew_status?.used || 0"
[remained]="
(partner()?.license_renew_status?.total || 0) -
(partner()?.license_renew_status?.used || 0) -
(partner()?.license_renew_status?.expired || 0)
"
/>
</div>
<!--
<p-divider align="center" class="col-span-3">اطلاعات لایسنس‌ها</p-divider>
<app-key-value label="مجموع لایسنس‌های خریداری شده" [value]="partner()?.licenses_status?.total" />
<app-key-value label="مجموع لایسنس‌های منقضی شده" [value]="partner()?.licenses_status?.expired" />
<app-key-value label="مجموع لایسنس‌های فروخته شده" [value]="partner()?.licenses_status?.used" />
<app-key-value type="number" label="مجموع لایسنس خریداری شده" [value]="partner()?.licenses_status?.total" />
<app-key-value type="number" label="مجموع لایسنس منقضی شده" [value]="partner()?.licenses_status?.expired" />
<app-key-value type="number" label="مجموع لایسنس فروخته شده" [value]="partner()?.licenses_status?.used" />
<app-key-value
label="مجموع لایسنس‌های باقی‌مانده"
type="number"
label="مجموع لایسنس باقی‌مانده"
[value]="
(partner()?.licenses_status?.total || 0) -
(partner()?.licenses_status?.used || 0) -
@@ -21,10 +61,19 @@
"
/>
<p-divider align="center" class="col-span-3">اطلاعات شارژ کاربران</p-divider>
<app-key-value label="مجموع کاربران خریداری شده" [value]="partner()?.account_quota_status?.total" />
<app-key-value label="مجموع کاربران منقضی شده" [value]="partner()?.account_quota_status?.expired" />
<app-key-value label="مجموع کاربران فروخته شده" [value]="partner()?.account_quota_status?.used" />
<app-key-value
type="number"
label="مجموع کاربران خریداری شده"
[value]="partner()?.account_quota_status?.total"
/>
<app-key-value
type="number"
label="مجموع کاربران منقضی شده"
[value]="partner()?.account_quota_status?.expired"
/>
<app-key-value type="number" label="مجموع کاربران فروخته شده" [value]="partner()?.account_quota_status?.used" />
<app-key-value
type="number"
label="مجموع کاربران باقی‌مانده"
[value]="
(partner()?.account_quota_status?.total || 0) -
@@ -33,17 +82,18 @@
"
/>
<p-divider align="center" class="col-span-3">اطلاعات تمدید لایسنس‌ها</p-divider>
<app-key-value label="مجموع تمدید خریداری شده" [value]="partner()?.license_renew_status?.total" />
<app-key-value label="مجموع تمدید منقضی شده" [value]="partner()?.license_renew_status?.expired" />
<app-key-value label="مجموع تمدید فروخته شده" [value]="partner()?.license_renew_status?.used" />
<app-key-value type="number" label="مجموع تمدید خریداری شده" [value]="partner()?.license_renew_status?.total" />
<app-key-value type="number" label="مجموع تمدید منقضی شده" [value]="partner()?.license_renew_status?.expired" />
<app-key-value type="number" label="مجموع تمدید فروخته شده" [value]="partner()?.license_renew_status?.used" />
<app-key-value
type="number"
label="مجموع تمدید باقی‌مانده"
[value]="
(partner()?.license_renew_status?.total || 0) -
(partner()?.license_renew_status?.used || 0) -
(partner()?.license_renew_status?.expired || 0)
"
/>
/>-->
</div>
</div>
</app-card-data>
@@ -1,9 +1,9 @@
import { BreadcrumbService } from '@/core/services';
import { PartnerLicenseInfoTemplateComponent } from '@/domains/partner/modules/dashboard/components/licenseInfo/license-info-template.component';
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
import { Component, computed, effect, inject, signal } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Button } from 'primeng/button';
import { Divider } from 'primeng/divider';
import { ConsumerAccountListComponent } from '../components/accounts/list.component';
import { PartnerChargeLicenseFormDialogComponent } from '../components/charge-license-form-dialog.component';
import { AdminPartnerChargeAccountFormDialogComponent } from '../components/chargeAccount/charge-account-form-dialog.component';
@@ -28,7 +28,7 @@ import { PartnerStore } from '../store/partner.store';
PartnerChargeLicenseFormDialogComponent,
AdminPartnerLicensesComponent,
AdminPartnerChargeLicenseTransactionListComponent,
Divider,
PartnerLicenseInfoTemplateComponent,
],
})
export class PartnerComponent {
@@ -1,10 +1,10 @@
<app-page-data-list
[pageTitle]="'مدیریت شناسه‌ی کالاها'"
[addNewCtaLabel]="'افزودن شناسه‌ی کالا'"
[pageTitle]="'مدیریت شناسه کالاها'"
[addNewCtaLabel]="'افزودن شناسه کالا'"
[columns]="columns"
[showAdd]="true"
emptyPlaceholderTitle="شناسه‌ی کالایی یافت نشد"
emptyPlaceholderDescription="برای افزودن شناسه‌ی کالا، روی دکمهٔ بالا کلیک کنید."
emptyPlaceholderTitle="شناسه کالایی یافت نشد"
emptyPlaceholderDescription="برای افزودن شناسه کالا، روی دکمهٔ بالا کلیک کنید."
[items]="items()"
[loading]="loading()"
[showDetails]="false"