رفتن به محتوای اصلی

ماژول باسلام

 این ماژول برای اتصال یک سیستم مدیریت محتوای محلی (CMS) به پلتفرم باسلام طراحی شده و مسئولیت سینک محصولات، آپدیت قیمت و موجودی، و ثبت سفارشات را بر عهده دارد.تمام عملیات با لاگینگ در فایل `basalam.log` و مدیریت خطاها از طریق اکسپشن انجام می‌شود.

هدف ماژول
-سینک محصولات: ارسال محصولات جدید از دیتابیس محلی به باسلام.
-آپدیت محصولات: به‌روزرسانی قیمت، موجودی و وضعیت انتشار محصولات.
-سینک سفارشات: ثبت سفارشات باسلام در دیتابیس محلی به عنوان فاکتور.

پیش‌نیازها
-توکن API: ذخیره‌شده در جدول `channels` برای احراز هویت.
-مپینگ‌ها: دسته‌بندی‌ها، شهرها و استان‌ها در تنظیمات کانال.
-تصاویر: ذخیره‌شده در مسیر محلی (مثل `./file/attach/`).
-دیتابیس: جداول `channels`, `products`, `channel_products`, `basalam_invoices` و غیره.

جریان کاری کلی
ماژول در سه بخش اصلی عمل می‌کند: سینک محصولات، آپدیت محصولات و سینک فاکتورها. جریان کلی به صورت زیر است:

[شروع]
  └── [گرفتن تنظیمات کانال (getChannelConfig) و Vendor ID (getUserVendorId)]

[سینک محصولات]
  └── [گرفتن محصولات غیرسینک (getUnSyncedProducts)]
      └── [آماده‌سازی داده‌ها (دسته‌بندی، تصاویر، ویژگی‌ها، واریانت‌ها)]
          └── [ارسال به API (addProduct)]
              └── [ثبت در دیتابیس محلی (insertChannelProduct)]
                  └── [لاگ و به‌روزرسانی آخرین سینک (setLastSync)]

[آپدیت محصولات]
  └── [گرفتن محصولات (getAllChannelProducts یا batchUpdateRecentProducts)]
      └── [محاسبه قیمت/موجودی (applySaleAndCost)]
          └── [ارسال دسته‌ای به API (sendBatchUpdate)]
              └── [به‌روزرسانی دیتابیس و لاگ]

[سینک فاکتورها]
  └── [گرفتن سفارشات جدید (syncInvoices)]
      └── [مپینگ مکان و ثبت عضو/آدرس]
          └── [ثبت فاکتور (new_sail, add_product)]
              └── [به‌روزرسانی لاگ و آخرین سینک]

[مدیریت خطاها]
  └── [لاگینگ در basalam.log و retry تا ۳ بار برای محصولات]

فرایند سینک محصولات
تابع اصلی: `syncProductsStep`

مراحل:
1.گرفتن تنظیمات: `getChannelConfig` توکن، مپینگ دسته‌بندی‌ها، شهرها/استان‌ها، نرخ تخفیف و هزینه عملیاتی را از جدول `channels` می‌خواند.
2.گرفتن Vendor ID: از API باسلام (`v3/users/me`) برای شناسایی فروشنده.
3.جمع‌آوری محصولات غیرسینک: `getUnSyncedProducts` محصولاتی که موجودی دارند، غیرفعال نیستند و هنوز سینک نشده‌اند (با محدودیت `batchSize`) را می‌گیرد.
4. آماده‌سازی داده‌ها:
   - دسته‌بندی: مپینگ دسته‌بندی محلی به باسلام با `getCategory`.
   - تصاویر: آپلود به API با `uploadProductImage` (فقط فرمت‌های JPEG/PNG/GIF/WEBP).
   - توضیحات: تمیز کردن متن با `cleanDescription` (حذف تگ‌های HTML و فضاهای اضافی).
   - ویژگی‌ها: ساخت attributes با `buildProductAttributes` (مثل جنس، رنگ).
   - واریانت‌ها: برای محصولات چندقیمت، `buildVariants` قیمت و موجودی هر واریانت را با اعمال تخفیف/هزینه محاسبه می‌کند.
5. ارسال به API: درخواست POST به `/v4/vendors/{vendorId}/products` با `addProduct`.
6. ثبت محلی: ذخیره ID محصول باسلام در جدول `channel_products` با `insertChannelProduct`.
7. لاگ و retry: ثبت نتیجه در `channel_insert_log` با `upsertChannelInsertLog`. در صورت خطا، تا ۳ بار با فاصله ۱ ساعت retry می‌کند.
8. ثبت زمان سینک: به‌روزرسانی با `setLastSync`.

نکته:
- برای محصولات چندواریانتی، تمام واریانت‌ها با یک درخواست ارسال می‌شوند و در صورت اضافه شدن واریانت بعد از ثبت محصول امکان اضافه کردن واریانت از طریق api نمیباشد. 
- تابع `syncAllChannels` این فرایند را برای همه کانال‌های باسلام اجرا می‌کند.

فرایند آپدیت محصولات
توابع اصلی: `batchUpdateAllProducts`, `batchUpdateRecentProducts`

مراحل:
1. گرفتن تنظیمات و Vendor ID: مشابه سینک.
2. جمع‌آوری محصولات:
   - `getAllChannelProducts`: تمام محصولات کانال.
   - `batchUpdateRecentProducts`: فقط محصولاتی که از آخرین سینک تغییر کرده‌اند (بر اساس `last_edit_date`).
3. محاسبه تغییرات:
   - قیمت: با `applySaleAndCost` یا `applySaleAndCostWithParams` (تخفیف/افزایش + هزینه عملیاتی).
   - موجودی: اعمال درصد موجودی (اگر فعال باشد).
   - وضعیت: منتشر (2976) یا پیش‌نویس (3790).
4. ارسال دسته‌ای: درخواست PATCH به `/v4/vendors/{vendorId}/products` با `sendBatchUpdate`.
5. به‌روزرسانی محلی: ذخیره تغییرات در `channel_products` با `insertChannelProduct`.
6. لاگ و سینک: ثبت نتیجه و به‌روزرسانی `setLastSync`.

قابلیت اضافی:
- افزودن پسوند به نام: `batchAppendToProductNames` یک متن (مثل «.») به نام محصولات اضافه می‌کند و به API ارسال می‌کند.

نکته:
- تابع `updateAllChannels` آپدیت را برای همه کانال‌ها اجرا می‌کند.
- برای تک محصول، `updateSingleProduct` استفاده می‌شود.

فرایند سینک فاکتورها
تابع اصلی: `syncInvoices`

 مراحل:
1. گرفتن تنظیمات و Vendor ID: مشابه قبل.
2. گرفتن سفارشات: درخواست GET به `/v3/vendor-parcels` برای سفارشات جدید (از آخرین سینک تا حداکثر ۷ روز قبل).
3. پردازش سفارشات (فقط وضعیت 3739):
   - چک تکراری: اگر سفارش قبلاً ثبت شده، رد می‌شود.
   - مپینگ مکان: شهر/استان باسلام به محلی مپ می‌شود.
   - ثبت عضو: اگر مشتری جدید است، با `persist_member` حساب می‌سازد.
   - ثبت آدرس: اگر آدرس جدید است، با `simple_address` اضافه می‌شود.
   - ثبت فاکتور: با `new_sail` فاکتور فروش ساخته می‌شود، اقلام با `add_product` اضافه می‌شوند.
   - وضعیت پرداخت: به «پرداخت‌شده» تغییر می‌کند.
   - ذخیره: در جدول `basalam_invoices` با داده خام سفارش.
4. تراکنش: استفاده از COMMIT/ROLLBACK برای اطمینان از صحت دیتابیس.
5. لاگ و سینک: ثبت نتیجه و به‌روزرسانی `setLastSync`.

 نکته:
- تابع `syncAllInvoice` این فرایند را برای همه کانال‌ها اجرا می‌کند.

 مدیریت خطاها
- لاگینگ: تمام عملیات در `basalam.log` با فرمت `[تاریخ][ERROR] پیام` ثبت می‌شود.
- اکسپشن‌ها: خطاهای API، دیتابیس و فایل‌ها با پیام واضح گزارش می‌شوند.
- retry: سینک محصولات تا ۳ بار با فاصله ۱ ساعت retry می‌شود.
- تراکنش: برای فاکتورها از تراکنش دیتابیس استفاده می‌شود.