diff --git a/apps/api/src/integrations/tahesab/dto.ts b/apps/api/src/integrations/tahesab/dto.ts index 5816305..e97bab6 100644 --- a/apps/api/src/integrations/tahesab/dto.ts +++ b/apps/api/src/integrations/tahesab/dto.ts @@ -205,6 +205,12 @@ export class SyncGroupsPageDto { pageSize?: number; } +/** اجرای دستی همگام‌سازی همهٔ مشتریان (وارد + به‌روز کردن لینک‌شده‌ها) */ +export class SyncAllCustomersDto { + @IsString() + connectionId!: string; +} + export class ExportPeopleToTahesabDto { @IsString() connectionId!: string; diff --git a/apps/api/src/integrations/tahesab/person-link.service.ts b/apps/api/src/integrations/tahesab/person-link.service.ts index 3208657..41074ec 100644 --- a/apps/api/src/integrations/tahesab/person-link.service.ts +++ b/apps/api/src/integrations/tahesab/person-link.service.ts @@ -969,6 +969,7 @@ export class TahesabPersonLinkService { ...(duplicate ? [`${duplicate} شماره تکراری`] : []), `${failed} خطا`, ].join('، '); + const error = errors.length ? errors.join('؛ ') : null; await this.prisma.accountingSyncJob.create({ data: { organizationId, @@ -978,6 +979,14 @@ export class TahesabPersonLinkService { result: { imported, updated, duplicate, failed, pages: page - 1 } as Prisma.InputJsonValue, }, }); + await this.prisma.accountingConnection.update({ + where: { id: connectionId }, + data: { + customerSyncLastRunAt: new Date(), + customerSyncLastSummary: summary, + customerSyncLastError: error, + }, + }); this.logger.log(`همگام‌سازی مشتریان ته‌حساب ${connectionId}: ${summary}`); return { imported, @@ -985,7 +994,7 @@ export class TahesabPersonLinkService { duplicate, failed, summary, - error: errors.length ? errors.join('؛ ') : null, + error, }; } diff --git a/apps/api/src/integrations/tahesab/tahesab.controller.ts b/apps/api/src/integrations/tahesab/tahesab.controller.ts index cca1fd0..4f009c6 100644 --- a/apps/api/src/integrations/tahesab/tahesab.controller.ts +++ b/apps/api/src/integrations/tahesab/tahesab.controller.ts @@ -37,6 +37,7 @@ import { SearchTahesabDto, SearchTahesabProductsDto, SyncAsnadReportDto, + SyncAllCustomersDto, SyncGroupsPageDto, UpdateTahesabConnectionDto, UpdateTahesabInvoiceSettingsDto, @@ -237,6 +238,16 @@ export class TahesabController { return this.links.syncGroupsPage(user.organizationId, dto); } + /** همهٔ مشتریان ته‌حساب: تازه‌ها وارد، لینک‌شده‌ها (نام/موبایل/کدملی/آدرس/شهر/رسته/گروه) به‌روز */ + @Post('sync/customers-now') + @Roles('owner', 'admin') + syncCustomersNow( + @CurrentUser() user: { organizationId: string }, + @Body() dto: SyncAllCustomersDto, + ) { + return this.links.syncAllCustomers(user.organizationId, dto.connectionId); + } + @Get('sync/unlinked-people') @Roles('owner', 'admin') unlinkedPeople( diff --git a/apps/web/src/views/TahesabSettingsView.vue b/apps/web/src/views/TahesabSettingsView.vue index 5b87bcb..636f0ec 100644 --- a/apps/web/src/views/TahesabSettingsView.vue +++ b/apps/web/src/views/TahesabSettingsView.vue @@ -148,6 +148,41 @@ async function saveAutoSync() { autoSyncSaving.value = false; } } + +/** همهٔ مشتریان ته‌حساب را می‌خواند: تازه‌ها وارد، لینک‌شده‌ها پروفایل‌شان به‌روز می‌شود */ +async function syncCustomersNow() { + if (!sync.connectionId) { + error.value = 'اتصال را انتخاب کنید.'; + return; + } + syncBusy.value = true; + importOverlay.open = true; + importOverlay.progress = null; + importOverlay.message = + 'در حال همگام‌سازی همهٔ مشتریان… نام، موبایل، کد ملی، آدرس، شهر، رسته و گروه به‌روز می‌شود.'; + error.value = ''; + ok.value = ''; + try { + const { data } = await api.post<{ + imported: number; + updated: number; + duplicate: number; + failed: number; + summary: string; + error: string | null; + }>('/integrations/tahesab/sync/customers-now', { + connectionId: sync.connectionId, + }); + ok.value = data.summary; + if (data.error) error.value = data.error; + await load(); + } catch (e) { + error.value = apiErr(e, 'همگام‌سازی مشتریان ناموفق بود'); + } finally { + syncBusy.value = false; + importOverlay.open = false; + } +} /** همان قاعدهٔ سرور: موبایل ایران 09… است، بقیهٔ شماره‌ها فقط رقم‌اند. */ function customerPhoneKey(value?: string | null): string { const fa = '۰۱۲۳۴۵۶۷۸۹'; @@ -1008,10 +1043,9 @@ onMounted(load);

بروزرسانی خودکار

- تعداد دفعات در روز و ساعت هر بار را برای همین اتصال مشخص کنید. سرور در آن ساعت‌ها، به وقت تهران، - مشتریان تازه را وارد می‌کند و نام مشتری‌های قبلی را هم با ته‌حساب تازه می‌کند. اگر شماره یکی باشد - همان مشتری می‌ماند و کد دیگر به‌عنوان مشتری تازه وارد نمی‌شود. شماره به شکل ۰۹۱۲ ذخیره می‌شود. - خاموش یعنی فقط ورود دستی. + «همگام‌سازی الان» همهٔ مشتریان ته‌حساب را می‌خواند: تازه‌ها را وارد می‌کند و برای مشتری‌های از قبل + لینک‌شده نام، موبایل، کد ملی، آدرس، شهر، رسته و گروه را از ته‌حساب تازه می‌کند. زمان‌بندی زیر + همان کار را در ساعت‌های انتخابی (به وقت تهران) تکرار می‌کند. خاموش یعنی فقط ورود دستی.

+ همگام‌سازی الان (وارد + به‌روز کردن قبلی‌ها) + + ذخیره زمان‌بندی