arc/hesabixAPI/docs/PRODUCT_EXCEL_IMPORT_WAREHOUSE_SYNC.md

7.2 KiB
Raw Permalink Blame History

همگام‌سازی موجودی افتتاحیه با اسناد انبار در ایمپورت کالا

برای نحوهٔ مصرف موجودی افتتاحیه در فروش سریع و کنترل حالت موجودی دقیقاً برابر با مقدار فروش، سند کنترل موجودی دقیق در فروش سریع را ببینید.

هدف

ردیف دارای «تعداد اولیه» در ایمپورت Excel دو اثر هماهنگ دارد:

  1. ارزش و تعداد افتتاحیه در سند حسابداری opening_balance ثبت می‌شود.
  2. موجودی فیزیکی با سند انبار قطعی (WarehouseDocument) در انبار انتخاب‌شده ثبت می‌شود.

سند مالی منبع ارزش‌گذاری است و سند انبار منبع گزارش موجودی فیزیکی. سند انبار با source_type=opening_balance و source_document_id به سند مالی متصل می‌شود.

قواعد دامنه

  • تعداد مثبت با receipt و movement=in ثبت می‌شود.
  • کاهش تعداد در ایمپورت مجدد فقط به اندازه اختلاف با issue و movement=out ثبت می‌شود.
  • اسناد به تفکیک انبار گروه‌بندی می‌شوند؛ برای هر کالا سند جدا ساخته نمی‌شود.
  • اسناد به‌صورت خودکار posted می‌شوند.
  • تاریخ سند انبار همان تاریخ سند افتتاحیه است.
  • تکرار فایل یکسان سند یا حرکت جدید ایجاد نمی‌کند.
  • خدمت، کالای فاقد کنترل موجودی و کالای یونیک بدون اطلاعات instance پذیرفته نمی‌شوند.
  • کاربر علاوه بر products.edit و opening_balance.edit به inventory.write نیاز دارد.

الگوریتم اختلافی

برای کالاهای متاثر، مقدار مطلوب از خطوط سند افتتاحیه و مقدار همگام‌شده از مجموع رسید/حواله‌های posted متصل به همان سند خوانده می‌شود:

delta(product, warehouse) = desired_opening - linked_physical
  • delta > 0: رسید انبار
  • delta < 0: حواله خروج
  • delta = 0: بدون عملیات

تغییر انبار به‌صورت خروج از انبار قبلی و ورود به انبار جدید دیده می‌شود. تمام اسناد یک اجرای ایمپورت دارای import_batch_id مشترک در extra_info هستند.

جلوگیری از شمارش دوگانه

محاسبه موجودی مالی/قابل‌استفاده خطوط سند افتتاحیه را می‌خواند. بنابراین خطوط WarehouseDocument با source_type=opening_balance در این محاسبه دوباره اضافه نمی‌شوند. در مقابل، گزارش موجودی فیزیکی فقط WarehouseDocumentهای posted را می‌خواند و رسید افتتاحیه را لحاظ می‌کند.

برای مقدار افتتاحیه ۱۰، خروجی مورد انتظار:

financial = 10
physical  = 10
available = 10

تراکنش و خطا

ایجاد/ویرایش کالا، بازنویسی افتتاحیه، ساخت خطوط انبار و قطعی‌سازی در یک transaction انجام می‌شود. هر خطا کل عملیات را rollback می‌کند. cache فقط بعد از موفقیت نهایی invalidate می‌شود.

برای کاهش افتتاحیه، کنترل کسری براساس موجودی فیزیکی انجام می‌شود؛ زیرا مقدار مالی افتتاحیه در همان transaction به مقدار جدید رسیده است.

اگر برای کالای متاثر حرکت posted غیرمرتبط با افتتاحیه وجود داشته باشد، sync با خطای OPENING_BALANCE_WAREHOUSE_HISTORY_EXISTS متوقف می‌شود. در این وضعیت باید اختلاف با رسید، حواله یا تعدیل مستقل ثبت شود؛ بازنویسی گذشته مجاز نیست.

داده‌های قدیمی

برای اسناد افتتاحیه قدیمی، اگر هیچ گردش انبار دیگری وجود نداشته باشد، نخستین ایمپورت بعد از انتشار می‌تواند رسید لینک‌شده را ایجاد کند. اگر گردش قبلی وجود داشته باشد، سیستم عمداً از حدس‌زدن منشأ موجودی خودداری و عملیات را متوقف می‌کند. هرگونه backfill عمومی باید ابزار جداگانه با preview و تایید مدیر داشته باشد.

پاسخ API

فیلد warehouse_sync به پاسخ ایمپورت اضافه شده است:

{
  "receipts_created": 2,
  "issues_created": 0,
  "lines_created": 1500,
  "unchanged_lines": 0,
  "posted": true,
  "document_ids": [101, 102],
  "import_batch_id": "..."
}

در dry-run تعداد ردیف‌ها و انبارهای کاندید گزارش می‌شود و هیچ سندی ساخته یا قطعی نمی‌شود.

تست‌های رگرسیون

  • اولین ایمپورت: رسید کامل
  • تکرار همان فایل: بدون delta
  • افزایش و کاهش: فقط مقدار اختلاف
  • تغییر انبار: issue و receipt متناظر
  • گروه‌بندی چند کالا در یک سند برای هر انبار
  • الزام دسترسی inventory.write
  • جلوگیری از شمارش دوگانه
  • rollback در شکست ساخت یا post سند
  • رد کالای یونیک بدون instance

نتیجه اعتبارسنجی ۱۴۰۵/۰۷/۱۰ (۲۰۲۶-۱۰-۰۲)

  • compilation فایل‌های Python تغییرکرده موفق بود.
  • Ruff محدود برای خطاهای import/name روی فایل‌های جدید و تست‌ها موفق بود.
  • git diff --check موفق بود.
  • گاردهای --check و --dry-run ابزار تست ایزوله موفق بودند.
  • شش فایل تست هدف شامل تست‌های ایمپورت، افتتاحیه، sync اختلافی، موجودی فیزیکی و جلوگیری از شمارش دوباره اجرا شدند: 49 passed و 177 warnings در 31.97s.
  • دیتابیس تصادفی hesabix_test_* بعد از اجرا خودکار حذف شد و دیتابیس توسعه استفاده یا تغییر داده نشد.
  • به‌دلیل مشکل شناخته‌شده baseline migration، اجرای DB-free با shim مرحله Alembic انجام شد؛ این نتیجه تست integration واقعی PostgreSQL محسوب نمی‌شود.
  • SDK محلی Flutter/Dart در PATH محیط موجود نبود؛ بنابراین validation خودکار UI در این محیط اجرا نشد.

rollback عملیاتی

این قابلیت migration دیتابیس ندارد. rollback کد، اسناد قبلاً ساخته‌شده را حذف نمی‌کند. برای اصلاح یک اجرای نامعتبر باید از عملیات لغو رسمی سند انبار و ثبت سند اصلاحی استفاده شود؛ حذف مستقیم WarehouseDocument یا DocumentLine ممنوع است.