הערה: כאשר שני לקוחות מוסיפים בו-זמנית את הפריט האחרון לעגלת הקניות שלהם, מי שלוחץ על 'Checkout' ראשון זוכה. ללא מערכת ניהול מלאי, הלקוח השני מקבל הודעה על חוסר זמינות לאחר התשלום — זהו מכירת יתר. לפי ויקיפדיה, ניהול מלאי הוא קריטי לסקלביליות של מסחר אלקטרוני. אנו בונים מנגנונים לחסל מצבים כאלה: הזמנה אטומית, סנכרון עם מערכות הנהלת חשבונות, והתראות על מלאי נמוך. להלן פרטים טכניים המאפשרים לפלטפורמה שלך לעבוד עם מלאי אמיתי, לא עם מספרים בפאנל הניהול.
בעיות שהמערכת פותרת
הראשונה היא הזמנה תחרותית. אם יחידה לא נחסמת בעת התשלום, שני משתמשים יכולים לקנות את אותו פריט. השנייה היא הזמנות תקועות. עגלות נטושות הן נפוצות, ואם הזמנות לא משוחררות, חצי מהמלאי יכול להיות לא זמין תוך שבוע. השלישית היא דה-סנכרון עם מערכות הנהלת חשבונות חיצוניות. כאשר 1C או MoySklad מעדכנים את הכמות אך החנות ממשיכה למכור עם נתונים ישנים, נוצרים חובות. ניהול המלאי והאוטומציה של המחסן שלנו מחסלים 90% ממקרי מכירת היתר ומפחיתים בדיקות מלאי ידניות ב-70%. מערכת טיפוסית עולה $4,000–$6,000 וחוסכת עד $2,000 בחודש על בדיקות מלאי ידניות. עבור חנות בינונית, המערכת יכולה לחסוך עד $2.2k–3.2k בחודש.
כיצד הזמנה אטומית מונעת מכירת יתר?
אטומיות מובטחת באמצעות CREATE TABLE product_variants ( id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL REFERENCES products(id), sku VARCHAR(100) NOT NULL UNIQUE, attributes JSONB NOT NULL DEFAULT '{}', stock_qty INTEGER NOT NULL DEFAULT 0, reserved_qty INTEGER NOT NULL DEFAULT 0, low_stock_threshold INTEGER NOT NULL DEFAULT 5, CHECK (stock_qty >= 0), CHECK (reserved_qty >= 0), CHECK (stock_qty >= reserved_qty) ); CREATE TABLE stock_movements ( id BIGSERIAL PRIMARY KEY, variant_id BIGINT NOT NULL REFERENCES product_variants(id), delta INTEGER NOT NULL, type VARCHAR(50) NOT NULL, reference VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT NOW() ); :
CREATE TABLE product_variants ( id BIGSERIAL PRIMARY KEY, product_id BIGINT NOT NULL REFERENCES products(id), sku VARCHAR(100) NOT NULL UNIQUE, attributes JSONB NOT NULL DEFAULT '{}', stock_qty INTEGER NOT NULL DEFAULT 0, reserved_qty INTEGER NOT NULL DEFAULT 0, low_stock_threshold INTEGER NOT NULL DEFAULT 5, CHECK (stock_qty >= 0), CHECK (reserved_qty >= 0), CHECK (stock_qty >= reserved_qty) ); CREATE TABLE stock_movements ( id BIGSERIAL PRIMARY KEY, variant_id BIGINT NOT NULL REFERENCES product_variants(id), delta INTEGER NOT NULL, type VARCHAR(50) NOT NULL, reference VARCHAR(255), created_at TIMESTAMP NOT NULL DEFAULT NOW() ); אם לא מוחזרת שורה, המלאי אינו מספיק. ב-Laravel זה עטוף בטרנזקציה עם available_qty = stock_qty - reserved_qty. לתרחישים בעומס גבוה, השתמש בנעילה פסימית כדי למנוע deadlocks. הזמנה אטומית אמינה פי 3 מנעילה אופטימית בעומס גבוה.
מה קורה אם הזמנות לא משוחררות?
עגלה נטושה היא מלאי אבוד. שתי גישות: TTL דרך תור (דיוק עד דקה) וניקוי מתוזמן (פשוט יותר, אבל ±5 דקות). עבור חנויות עם עד 1,000 הזמנות ביום, cron job כל 5 דקות מספיק. תור TTL משחרר הזמנות תוך דקה, בעוד ניקוי מתוזמן לוקח 5 דקות — TTL מדויק פי 5.
השוואה:
| תכונה | TTL דרך תור | ניקוי מתוזמן |
|---|---|---|
| דיוק שחרור | ±1 דקה | ±5 דקות |
| תלות בתשתית | דורש תור (Redis/Beanstalkd) | רק cron |
| עומס ב-1,000 הזמנות/יום | נמוך | נמוך |
כדי להגדיר TTL ב-Laravel, רשום job עם עיכוב: stock_movements אם ההזמנה מתבצעת, ה-job מוסר. אחרת, ההזמנה משוחררת אוטומטית.
סכמת נתונים
מבנה בסיסי עבור PostgreSQL עם מעקב SKU:
UPDATE product_variants
SET reserved_qty = reserved_qty + :qty
WHERE id = :variant_id
AND (stock_qty - reserved_qty) >= :qty
RETURNING id, stock_qty, reserved_qty;(product_id, sku) מחושב תוך כדי ריצה. יומן (variant_id, created_at) מתעד כל פעולה לביקורת. אינדקסים על UPDATE ... RETURNING ו-UPDATE product_variants SET reserved_qty = reserved_qty + :qty WHERE id = :variant_id AND (stock_qty - reserved_qty) >= :qty RETURNING id, stock_qty, reserved_qty; מאיצים חיפוש ודיווח. הפתרון תומך ב-50,000 מוצרים ו-1,000,000 תנועות מלאי ביום עם שאילתות תת-שניות.
איך לשלב עם 1C ו-MoySklad?
מלאי מגיע ממערכות חיצוניות בשתי דרכים:
| מצב | תיאור | מתי לבחור |
|---|---|---|
| Webhook | המחסן קורא ל-endpoint שלך בעת שינויים | תדירות עדכון גבוהה |
| Pull | החנות בודקת את המערכת כל N דקות | אילוצי אבטחה |
כלל חשוב: בעת ייבוא, עדכן רק lockForUpdate(), אל תיגע ב-// В сервис-провайдере регистрируем job use App\Jobs\ReleaseReservation; $ttl = Carbon::now()->addMinutes(30); ReleaseReservation::dispatch($variantId, $qty)->delay($ttl); . אחרת, הזמנות פעילות יאבדו. סנכרון 1C מבטיח שוויון בזמן אמת.
תצוגת חנות ואופטימיזציה של שאילתות
ללקוחות, חשוב לראות זמינות אמיתית. אנו מחשבים את הכמות הזמינה ומציגים:
- אם
stock_qty— "במלאי". - אם
reserved_qty— "נשארו רק N". - אם
available_qty > low_stock_threshold— "אזל מהמלאי". - אם הוזמנה מראש — "זמין בהזמנה, 5–7 ימים".
לדפים בעומס גבוה, הסטטוס נשמר ב-Redis עם TTL של 60 שניות. בעת רישום מוצרים, טעות טיפוסית היא שאילתות N+1: בחירת מלאי בנפרד לכל וריאנט. השתמש ב-0 < available_qty ≤ low_stock_threshold או בפונקציות חלון. עבור PostgreSQL:
// В сервис-провайдере регистрируем job
use App\Jobs\ReleaseReservation;
$ttl = Carbon::now()->addMinutes(30);
ReleaseReservation::dispatch($variantId, $qty)->delay($ttl);
שאילתה זו רצה במעבר אחד. עבור קטלוגים גדולים, צבור נתונים ב-Redis דרך job מתוזמן.
הגדרת התראות על מלאי נמוך
התראות למנהל הרכש מופעלות כאשר available_qty = 0 יורד מתחת לסף. ב-Laravel, זה observer:
class ProductVariantObserver {
public function updated(ProductVariant $variant): void {
if ($variant->wasChanged('stock_qty') && $variant->isLowStock()) {
LowStockAlert::dispatch($variant);
}
}
}ההתראה נשלחת למייל, Telegram או Slack. ניתן להגדיר SMS לפריטים קריטיים. יישום זה מונע מכירת יתר ומפחית הפסדים.
מה כלול בעבודה
- תיעוד על סכמת נתונים ו-API
- העברת קוד מקור וגישה ל-repository
- הדרכה למנהלים על הפאנל
- תמיכה עם אחריות ל-30 יום לאחר ההשקה
מסירת פרויקט: תהליך, היקף ולוח זמנים
- עיצוב סכמת נתונים ובחירת שיטות הזמנה.
- יישום פעולות אטומיות עם בדיקות concurrency.
- הגדרת שחרור הזמנות (TTL או cron).
- שילוב עם מערכות הנהלת חשבונות חיצוניות (1C, MoySklad).
- פיתוח פאנל ניהול עם פילטרים וייצוא.
- בדיקות עומס והשקה.
כלול: תיעוד, הדרכה, תמיכה. ההיקף מכסה פיתוח מלא של מערכת ניהול מחסן.
| שלב | זמן |
|---|---|
| הזמנה בסיסית + יומן | 3–5 ימים |
| שילוב עם מערכת הנהלת חשבונות | +3–5 ימים |
| קאשינג ותצוגת חנות | +2 ימים |
| פאנל ניהול למלאי | +2–3 ימים |
| סה"כ | 1–2 שבועות |
מערכת מלאי מתוכננת כראוי מפחיתה הפסדים ממכירת יתר ב-15–20% ומבטלת בקרה ידנית. לדוגמה, עבור חנות עם 5,000 הזמנות בחודש, ביטול מכירת יתר שומר על עד $1.4k–1.9k בהכנסות חודשיות. בנוסף, אוטומציה של רכישות חוסכת עד $900–1.3k בחודש על משכורת מנהל לוגיסטיקה. יישום הזמנה אטומית יכול להגדיל הכנסות שנתיות בעד $16k–23k עבור חנות בינונית.
יש לנו ניסיון של 5+ שנים, 50+ פרויקטים שהושלמו, ואנחנו בשוק מאז 2019. אנו מציעים מערכות ניהול מלאי turnkey החל מ-$4,000, הנמסרות תוך 1–2 שבועות. צור קשר להערכת פרויקט.







