חילוץ פריטים מחשבוניות

Line Items Extraction - מערכת חילוץ פריטים מתקדמת עם AI + Regex Hybrid

סקירה כללית

מערכת חילוץ הפריטים (Line Items Extraction) היא מודול מתקדם לחילוץ אוטומטי של פריטים, כמויות, מחירים ונתונים פיננסיים מחשבוניות וקבלות.

חילוץ AI

Google Gemini, OpenAI, Anthropic

חילוץ Regex

10+ תבניות מתקדמות

תמיכה בשפות

עברית + אנגלית + תרגום

עדכון אחרון (דצמבר 2025):
  • תמיכה מלאה בזיהוי שפת המסמך (עברית/אנגלית)
  • שמירת נתונים בשפה המקורית + תרגום
  • נורמליזציה של יחידות מידה
  • 35+ שדות לכל פריט

יכולות המערכת

חילוץ נתונים
  • תיאור פריט בשפה מקורית
  • תרגום אוטומטי (עברית/אנגלית)
  • קוד מוצר / מק"ט (SKU)
  • ברקוד ומספר קטלוגי
  • כמות ויחידת מידה
  • מחיר יחידה וסה"כ שורה
  • הנחה (אחוז וסכום)
  • מע"מ (שיעור וסכום)
  • קטגוריה וסוג פריט
יכולות טכניות
  • חילוץ Hybrid (AI + Regex)
  • השוואה ובחירת התוצאה הטובה
  • ציון ביטחון (Confidence Score)
  • זיהוי אוטומטי של שפת המסמך
  • נורמליזציה של יחידות (ק"ג → kg)
  • תמיכה ב-3 ספקי AI
  • Fallback אוטומטי בין ספקים
  • שמירת metadata מלא

שיטות חילוץ

Regex

חילוץ באמצעות תבניות Regular Expression מתקדמות.

  • מהיר ויעיל
  • לא דורש API חיצוני
  • 10+ תבניות לפורמטים שונים
  • דיוק: 75-85%
Regex Only
AI

חילוץ באמצעות מודלי שפה מתקדמים.

  • דיוק גבוה מאוד
  • הבנת הקשר
  • תרגום אוטומטי
  • דיוק: 90-95%
AI Powered
Hybrid

שילוב של שתי השיטות עם השוואה.

  • מריץ את שתי השיטות
  • משווה תוצאות
  • בוחר את הטובה יותר
  • דיוק: 92-98%
Hybrid Mode

מצב Hybrid - כיצד זה עובד

טקסט OCR
חילוץ Regex
+
חילוץ AI
השוואה
תוצאה מיטבית
אלגוריתם ההשוואה:
def _calculate_extraction_score(items, confidence):
    # Base confidence weight (40%)
    score = confidence * 0.4

    # Completeness score per item (40%)
    for item in items:
        item_score = 0
        if item.get('description'): item_score += 0.2
        if item.get('quantity'): item_score += 0.15
        if item.get('unit_price'): item_score += 0.15
        if item.get('line_total'): item_score += 0.15
        if item.get('product_code') or item.get('sku'): item_score += 0.1
        if item.get('vat_rate'): item_score += 0.1
        ...

    # Bonus for number of items (20%)
    items_bonus = min(len(items) * 0.02, 0.2)

    return min(score + completeness + items_bonus, 1.0)
מיזוג תוצאות: כאשר שתי השיטות מחזירות אותו מספר פריטים, המערכת ממזגת את התוצאות:
  • שדות מספריים (כמות, מחיר) - מועדף Regex (יותר מדויק)
  • שדות טקסט (תיאור, קטגוריה) - מועדף AI (הבנה טובה יותר)
  • שדות שפה - מגיעים מ-AI בלבד

תמיכה בשפות

המערכת מזהה אוטומטית את שפת המסמך ושומרת את הנתונים בהתאם:

מסמך בעברית
descriptionשקי מלט 50 ק"ג
description_englishCement bags 50 kg
description_hebrewNULL
original_languagehe
unit_of_measureק"ג
unit_of_measure_normalizedkg
English Document
description24" LCD Monitor
description_englishNULL
description_hebrewמסך LCD 24 אינץ'
original_languageen
unit_of_measureunit
unit_of_measure_normalizedunit
חשוב: השדה description תמיד מכיל את הטקסט בשפה המקורית של המסמך. התרגום נשמר בשדות הנפרדים description_english או description_hebrew.

שדות מסד נתונים - DocumentLineItem

שם שדה סוג תיאור
זיהוי פריט
line_numberIntegerמספר שורה בחשבונית
product_codeString(50)קוד מוצר
skuString(50)מק"ט (Stock Keeping Unit)
barcodeString(50)ברקוד
catalog_numberString(50)מספר קטלוגי
serial_numberString(100)מספר סריאלי
תיאור ושפה
descriptionString(500)תיאור בשפה המקורית
description_englishString(500)תרגום לאנגלית (אם מקור עברית)
description_hebrewString(500)תרגום לעברית (אם מקור אנגלית)
original_languageString(5)שפת המקור: 'he', 'en', 'mixed'
כמות ומחיר
quantityNumeric(10,3)כמות
unit_priceNumeric(12,2)מחיר ליחידה
line_totalNumeric(12,2)סה"כ שורה
unit_of_measureString(30)יחידת מידה (מקור)
unit_of_measure_normalizedString(20)יחידה מנורמלת (אנגלית)
currencyString(3)מטבע (ILS, USD, EUR)
הנחה
discount_percentFloatאחוז הנחה
discount_amountNumeric(10,2)סכום הנחה
price_before_discountNumeric(12,2)מחיר לפני הנחה
מע"מ
vat_rateFloatשיעור מע"מ (%)
vat_amountNumeric(10,2)סכום מע"מ
is_vat_exemptBooleanפטור ממע"מ
tax_codeString(20)קוד מס
קטגוריה
categoryString(100)קטגוריה (שפה מקורית)
category_englishString(100)קטגוריה באנגלית
subcategoryString(100)תת-קטגוריה
item_typeString(50)סוג: product/service/shipping
הערות ומידע נוסף
notesTextהערות
internal_notesTextהערות פנימיות
warranty_infoString(255)מידע אחריות
cost_priceNumeric(12,2)מחיר עלות
Metadata חילוץ
extraction_methodString(20)'regex', 'ai', 'hybrid', 'manual'
ai_providerString(30)'google', 'openai', 'anthropic'
confidence_scoreFloatציון ביטחון (0-1)
confidence_detailsJSONפירוט ציונים
raw_textTextטקסט גולמי מ-OCR
התאמה למלאי
matched_inventory_idIntegerFK לפריט מלאי
matched_product_idIntegerFK למוצר
match_confidenceFloatציון התאמה

API Reference

חילוץ פריטים ממסמך
GET /api/email-scanning/documents/<document_id>/line-items

מחזיר את כל הפריטים שחולצו מהמסמך.

// Response Example
{
    "success": true,
    "data": {
        "items": [
            {
                "id": 1,
                "line_number": 1,
                "description": "שקי מלט 50 ק\"ג",
                "description_english": "Cement bags 50 kg",
                "original_language": "he",
                "product_code": "BLD-001",
                "sku": "BLD-001",
                "quantity": 20,
                "unit_price": 45.00,
                "line_total": 900.00,
                "unit_of_measure": "ק\"ג",
                "unit_of_measure_normalized": "kg",
                "extraction_method": "hybrid",
                "ai_provider": "google",
                "confidence_score": 0.92
            }
        ],
        "total_items": 6,
        "extraction_method": "hybrid",
        "confidence": 0.92
    }
}
הפעלה מחודשת של חילוץ
POST /api/email-scanning/documents/<document_id>/extract-line-items
// Request Body
{
    "use_ai": true,
    "ai_provider": "google",  // optional: "google", "openai", "anthropic"
    "force": true             // optional: re-extract even if exists
}

// Response
{
    "success": true,
    "data": {
        "items_extracted": 6,
        "extraction_method": "hybrid",
        "ai_provider": "google",
        "confidence": 0.92,
        "document_language": "he"
    }
}

ספקי AI נתמכים

Google Gemini

מודל: gemini-2.0-flash

יתרונות:

  • תמיכה מצוינת בעברית
  • מהיר ויעיל
  • תמחור נמוך

Environment Variable:

GOOGLE_AI_API_KEY
OpenAI

מודל: gpt-4o-mini

יתרונות:

  • דיוק גבוה מאוד
  • הבנת הקשר מעולה
  • תיעוד נרחב

Environment Variable:

OPENAI_API_KEY
Anthropic Claude

מודל: claude-3-haiku

יתרונות:

  • חשיבה אנליטית
  • מבנה JSON מדויק
  • בטיחות מובנית

Environment Variable:

ANTHROPIC_API_KEY
סדר עדיפות: המערכת בוחרת ספק לפי הזמינות: Google → OpenAI → Anthropic. אם אף ספק לא זמין, נעשה שימוש ב-Regex בלבד.

הגדרות

Environment Variables
# AI API Keys
GOOGLE_AI_API_KEY=AIzaSy...
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...

# OCR Configuration
OCR_DEFAULT_LANGUAGE=heb+eng
OCR_CONFIDENCE_THRESHOLD=0.7

# Line Items Extraction
LINE_ITEMS_USE_AI=true
LINE_ITEMS_AI_PROVIDER=google  # google, openai, anthropic, auto
LINE_ITEMS_HYBRID_MODE=true
קבצים רלוונטיים
קובץ תיאור
app/models_email_scanning.py מודל DocumentLineItem (35+ שדות)
app/services/ocr_service.py LineItemExtractor class (~720 שורות)
app/tasks/ocr_tasks.py Celery tasks לעיבוד OCR
app/api_email_scanning.py API endpoints לחילוץ פריטים

דוגמאות קוד

Python - חילוץ פריטים
from app.services.ocr_service import ocr_service

# Extract line items from OCR text
invoice_text = """
חשבונית מס' 1087
מק"ט        פריט                 כמות   מחיר    סה"כ
BLD-001     שקי מלט 50 ק"ג        20   45.00    900.00
BLD-002     בלוקים 20x20x40      100    8.50    850.00
"""

# Hybrid extraction (AI + Regex)
result = ocr_service.extract_line_items(invoice_text)

print(f"Method: {result['extraction_method']}")
print(f"AI Provider: {result.get('ai_provider', 'N/A')}")
print(f"Items found: {len(result['items'])}")
print(f"Confidence: {result['confidence']:.0%}")

for item in result['items']:
    print(f"  - {item['sku']}: {item['description']} = {item['line_total']}")
JavaScript - קריאה ל-API
// Get line items from document
async function getLineItems(documentId) {
    const response = await fetch(
        `/api/email-scanning/documents/${documentId}/line-items`,
        {
            credentials: 'include',
            headers: { 'Content-Type': 'application/json' }
        }
    );

    const result = await response.json();
    const data = result.data || result;

    console.log(`Extraction method: ${data.extraction_method}`);
    console.log(`Items: ${data.items.length}`);

    data.items.forEach(item => {
        console.log(`${item.sku}: ${item.description}`);
        if (item.description_english) {
            console.log(`  (EN: ${item.description_english})`);
        }
    });
}
דוגמת תוצאה
# Output Example
Method: hybrid
AI Provider: google
Items found: 6
Confidence: 92%

  - BLD-001: שקי מלט 50 ק"ג = 900.0
    (EN: Cement bags 50 kg)
  - BLD-002: בלוקים 20x20x40 = 850.0
    (EN: Blocks 20x20x40)
  - PLM-100: צינור PVC 4 אינץ' = 325.0
    (EN: PVC pipe 4 inch)