פיתוח אפליקציית ניהול מחסן ניידת (WMS)
אנו יוצרים אפליקציות המאפשרות לעובדי מחסן לבצע פעולות במהירות וללא שגיאות באמצעות מסופי איסוף נתונים ייעודיים (TSDs). הניסיון שלנו כולל אינטגרציה עם SAP, 1C ומערכות ERP אחרות, וכן הטמעת מצב לא מקוון לפעולה אמינה בתנאי רשת לא יציבים. WMS נייד אינו רק סריקת ברקוד. הוא הממשק בין עובד המחסן למערכת ניהול המלאי: קבלת סחורה, אחסון במיקומים, הרכבת הזמנות, העברות בין אזורים, ספירת מלאי, ושילוח. כל פעולה דורשת אישור באמצעות סריקה, והאפליקציה פועלת בתנאי Wi-Fi חלש, כפפות גומי ומשמרות של 10 שעות.
חומרה: TSDs ומחשבים ניידים
סמארטפון צרכני במחסן הוא פתרון זמני. מכשירי TSD מקצועיים (Zebra MC9300, Honeywell CT40, Point Mobile PM90) מציעים הגנת IP65/IP67, סוללות ניתנות להחלפה, סורקי לייזר מובנים עם טווח של 10 מטרים, ותמיכה בכל הקודים מסוג 1D ו-2D.
פיתוח עבור Zebra: DataWedge מוגדר באמצעות Intent API — האפליקציה מצהירה על פרופיל ב-datawedge.db או באופן תוכנתי באמצעות broadcast. הסריקה מגיעה כ-Intent עם extra com.symbol.datawedge.data_string:
class WarehouseActivity : AppCompatActivity() {
private val scanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val barcode = intent.getStringExtra("com.symbol.datawedge.data_string") ?: return
val source = intent.getStringExtra("com.symbol.datawedge.label_type") // EAN13, CODE128, QR_CODE
viewModel.processBarcode(barcode, source)
}
}
override fun onResume() {
super.onResume()
registerReceiver(scanReceiver, IntentFilter("com.symbol.datawedge.api.RESULT_ACTION"))
// Включаем DataWedge profile для нашего приложения
sendDataWedgeIntent("com.symbol.datawedge.api.SWITCH_TO_PROFILE", "WarehousePro")
}
}עבור Honeywell — Honeywell Scanning SDK (מנגנון Intent דומה). לאחידות: הפשטה של class WarehouseActivity : AppCompatActivity() { private val scanReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val barcode = intent.getStringExtra("com.symbol.datawedge.data_string") ?: return val source = intent.getStringExtra("com.symbol.datawedge.label_type") // EAN13, CODE128, QR_CODE viewModel.processBarcode(barcode, source) } } override fun onResume() { super.onResume() registerReceiver(scanReceiver, IntentFilter("com.symbol.datawedge.api.RESULT_ACTION")) // Включаем DataWedge profile для нашего приложения sendDataWedgeIntent("com.symbol.datawedge.api.SWITCH_TO_PROFILE", "WarehousePro") } } עם מימושים ScannerProvider, ZebraScanner, HoneywellScanner. יש לקבוע את סוג המכשיר באמצעות CameraScanner.
משימות ותורים: מודל בצד השרת
עובד המחסן רואה רשימת משימות ממוינת לפי עדיפות ומסלול (כדי למזער תנועות במחסן). משימה מכילה: סוג פעולה, רשימת SKUs עם תיאורים וכמויות, וכתובות מיקום אחסון (מדף-רמה-מיקום).
@Entity(tableName = "tasks")
data class WarehouseTask(
@PrimaryKey val taskId: String,
val type: TaskType, // RECEIVING, PUTAWAY, PICKING, REPLENISHMENT, INVENTORY
val status: TaskStatus, // ASSIGNED, IN_PROGRESS, COMPLETED, BLOCKED
val priority: Int,
val assignedUserId: String,
val lines: List<TaskLine>,
val syncedAt: Long,
)
@Entity(tableName = "task_lines")
data class TaskLine(
@PrimaryKey val lineId: String,
val taskId: String,
val sku: String,
val description: String,
val expectedQty: Double,
val actualQty: Double?,
val fromLocation: String?,
val toLocation: String,
val lotNumber: String?,
val expiryDate: String?,
)מצב לא מקוון: בעת אובדן Wi-Fi, המשימות זמינות מ-Room. כל הפעולות מתועדות מקומית עם חותמת זמן ומסונכרנות בקבוצה כאשר החיבור חוזר. קונפליקטים בגרסאות (משתמש אחר עיבד את אותו פריט) — השרת פותר לפי חותמת זמן, והאפליקציה מודיעה על שינויים.
הרכבת הזמנות לפי מסלול
הרכבת הזמנות היא הפעולה הקריטית ביותר בזמן. מיון משימות לפי מסלול מעבר: צורת S (נחשונית) או שכן קרוב ביותר לפי כתובות מיקום. מיושם בצד השרת; האפליקציה הניידת מקבלת רשימה ממוינת כבר.
אינדיקטור חזותי למיקום הנוכחי: הדגשה על דיאגרמת מחסן או פשוט כתובת גדולה (Build.MANUFACTURER) במסך מלא. אישור באמצעות סריקת ברקוד המיקום — הגנה מפני שגיאות. לאחר סריקת המיקום, יש לסרוק את ברקוד הפריט, להזין כמות (או אוטומטית 1 אם מדובר בהרכבה של פריט בודד).
sealed class PickingStep {
object ScanLocation : PickingStep()
data class ScanItem(val expectedSku: String) : PickingStep()
data class EnterQuantity(val sku: String, val required: Double) : PickingStep()
data class Completed(val lineId: String) : PickingStep()
}
class PickingViewModel : ViewModel() {
private val _step = MutableStateFlow<PickingStep>(PickingStep.ScanLocation)
fun processBarcode(barcode: String) {
when (val step = _step.value) {
is PickingStep.ScanLocation -> {
if (barcode == currentLine.toLocation) {
_step.value = PickingStep.ScanItem(currentLine.sku)
} else {
_events.tryEmit(Event.WrongLocation(barcode, currentLine.toLocation))
}
}
is PickingStep.ScanItem -> {
if (barcode == step.expectedSku || isAlias(barcode, step.expectedSku)) {
_step.value = PickingStep.EnterQuantity(step.expectedSku, currentLine.expectedQty)
} else {
_events.tryEmit(Event.WrongItem(barcode))
}
}
else -> {
/* обработка других шагов */
}
}
}
} אינטגרציה עם WMS/ERP
אינטגרציות אופייניות: SAP WM/EWM באמצעות RFC/BAPI או REST (SAP API Hub), 1C:UPP/ERP באמצעות שירות HTTP, Microsoft Dynamics 365 באמצעות Dataverse API, WMS מותאם אישית באמצעות REST/gRPC.
אסטרטגיית אינטגרציה: אין לקרוא ל-ERP ישירות מהאפליקציה הניידת — אנו משתמשים בשירות middleware שמאגר פעולות, מטפל בשגיאות ERP, ואינו מפיל את הלקוח הנייד במהלך תגובות SAP של 30 שניות.
כיצד להבטיח שהאפליקציה תעבוד ללא חיבור?
אנו משתמשים ב-Room לאחסון מקומי של משימות ופעולות. בעת אובדן רשת, כל הפעולות מתועדות מקומית, ועם שחזור החיבור, הן מסונכרנות בקבוצות. קונפליקטים נפתרים לפי חותמת זמן. גישה זו מבטיחה פעולה רציפה גם עם Wi-Fi לא יציב.
למה לבחור ב-TSDs תעשייתיים?
סמארטפונים אינם מיועדים לאבק, לחות ונפילות. מכשירי TSD תעשייתיים כוללים IP65/IP67, סוללות ניתנות להחלפה וסורקי לייזר מובנים. זה מפחית זמני השבתה ושגיאות סריקה. בפועל, אורך חיי TSD ארוך פי 3-5 מסמארטפון רגיל במחסן.
מה כלול בעבודה
- ביקורת תהליכי מחסן נוכחיים ובחירת ערימת טכנולוגיה אופטימלית.
- פיתוח אפליקציה ניידת ל-iOS, Android או חוצת פלטפורמות.
- הגדרת DataWedge/Honeywell SDK ואינטגרציית TSD.
- הטמעת מצב לא מקוון עם סנכרון.
- אינטגרציית ERP (SAP, 1C, Dynamics) באמצעות middleware.
- בדיקות במחסן, הדרכת עובדים ותיעוד.
- תמיכה לאחר השקה (אחריות ל-12 חודשים).
המדדים שלנו
מעל 50 פרויקטים מיושמים באוטומציה של מחסנים. ניסיון של 5+ שנים בפיתוח WMS נייד. מהנדסים מוסמכים עבור Zebra ו-SAP. צרו קשר להערכת עלות פרויקט.
| מצב פעולה | יתרונות | חסרונות |
|---|---|---|
| מקוון | נתונים בזמן אמת, סנכרון ERP מיידי | תלוי בחיבור יציב, עיכובים בערוצים איטיים |
| לא מקוון | עובד ללא חיבור, תגובת UI מיידית | קונפליקטים אפשריים בעבודה מקבילה, צורך בפתרון התנגשויות |
פיתוח אפליקציית WMS ניידת עם תמיכת TSD של Zebra/Honeywell, מצב לא מקוון, הרכבת הזמנות לפי מסלול ואינטגרציית REST: 3-5 חודשים. מחזור מלא (קבלה, אחסון, הרכבה, ספירת מלאי, שילוח) עם אינטגרציית SAP/1C: 5-8 חודשים. העלות מחושבת באופן אישי. קבלו ייעוץ — נעריך את הפרויקט שלכם.







