diff --git a/api/migrations/0001_initial.py b/api/migrations/0001_initial.py index e24aeb44..7441cd65 100644 --- a/api/migrations/0001_initial.py +++ b/api/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.7 on 2025-05-04 16:07 +# Generated by Django 5.2.1 on 2025-05-25 23:01 from django.db import migrations, models diff --git a/car_inventory/urls.py b/car_inventory/urls.py index cb957b7a..400f33c0 100644 --- a/car_inventory/urls.py +++ b/car_inventory/urls.py @@ -24,7 +24,7 @@ urlpatterns += i18n_patterns( # path('prometheus/', include('django_prometheus.urls')), path('', include('inventory.urls')), path('ledger/', include('django_ledger.urls', namespace='django_ledger')), - # path("haikalbot/", include("haikalbot.urls")), + path("haikalbot/", include("haikalbot.urls")), path('appointment/', include('appointment.urls')), path('plans/', include('plans.urls')), path("schema/", Schema.as_view()), diff --git a/haikalbot.zip b/haikalbot.zip new file mode 100644 index 00000000..ffb7f462 Binary files /dev/null and b/haikalbot.zip differ diff --git a/haikalbot/Optimizing Qwen3-8B for Arabic Language Support in Django AI Analyst.md b/haikalbot/Optimizing Qwen3-8B for Arabic Language Support in Django AI Analyst.md new file mode 100644 index 00000000..72a67c0d --- /dev/null +++ b/haikalbot/Optimizing Qwen3-8B for Arabic Language Support in Django AI Analyst.md @@ -0,0 +1,204 @@ +# Optimizing Qwen3-8B for Arabic Language Support in Django AI Analyst + +This guide provides specific recommendations for using Qwen3-8B with your Django AI Analyst application for Arabic language support. + +## Qwen3-8B Overview + +Qwen3-8B is a powerful multilingual large language model developed by Alibaba Cloud. It offers several advantages for Arabic language processing: + +- **Strong multilingual capabilities**: Trained on diverse multilingual data including Arabic +- **Efficient performance**: 8B parameter size balances capability and resource requirements +- **Instruction following**: Excellent at following structured instructions in multiple languages +- **Context understanding**: Good comprehension of Arabic context and nuances +- **JSON formatting**: Reliable at generating structured JSON outputs + +## Configuration Settings for Qwen3-8B + +Update your Django settings to use Qwen3-8B: + +```python +# In settings.py +OLLAMA_BASE_URL = "http://10.10.1.132:11434" +OLLAMA_MODEL = "qwen3:8b" +OLLAMA_TIMEOUT = 120 # Seconds +``` + +## Optimized Parameters for Arabic + +When initializing the Ollama LLM with Qwen3-8B for Arabic, use these optimized parameters: + +```python +def get_ollama_llm(): + """ + Initialize and return an Ollama LLM instance configured for Arabic support with Qwen3-8B. + """ + try: + # Get settings from Django settings or use defaults + base_url = getattr(settings, 'OLLAMA_BASE_URL', 'http://10.10.1.132:11434') + model = getattr(settings, 'OLLAMA_MODEL', 'qwen3:8b') + timeout = getattr(settings, 'OLLAMA_TIMEOUT', 120) + + # Configure Ollama with parameters optimized for Qwen3-8B with Arabic + return Ollama( + base_url=base_url, + model=model, + timeout=timeout, + # Parameters optimized for Qwen3-8B with Arabic + parameters={ + "temperature": 0.2, # Lower temperature for more deterministic outputs + "top_p": 0.8, # Slightly reduced for more focused responses + "top_k": 40, # Standard value works well with Qwen3 + "num_ctx": 4096, # Qwen3 supports larger context windows + "num_predict": 2048, # Maximum tokens to generate + "stop": ["```", ""], # Stop sequences for JSON generation + "repeat_penalty": 1.1 # Slight penalty to avoid repetition + } + ) + except Exception as e: + logger.error(f"Error initializing Ollama LLM: {str(e)}") + return None +``` + +## Prompt Template Optimization for Qwen3-8B + +Qwen3-8B responds well to clear, structured prompts. For Arabic analysis, use this optimized template: + +```python +def create_prompt_analyzer_chain(language='ar'): + """ + Create a LangChain for analyzing prompts in Arabic with Qwen3-8B. + """ + llm = get_ollama_llm() + if not llm: + return None + + # Define the prompt template optimized for Qwen3-8B + if language == 'ar': + template = """ + أنت مساعد ذكي متخصص في تحليل نماذج Django. مهمتك هي تحليل الاستعلام التالي وتحديد: + 1. نوع التحليل المطلوب + 2. نماذج البيانات المستهدفة + 3. أي معلمات استعلام + + الاستعلام: {prompt} + + قم بتقديم إجابتك بتنسيق JSON فقط، بدون أي نص إضافي، كما يلي: + ```json + {{ + "analysis_type": "count" أو "relationship" أو "performance" أو "statistics" أو "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {{"field1": "value1", "field2": "value2"}} + }} + ``` + """ + else: + template = """ + You are an intelligent assistant specialized in analyzing Django models. Your task is to analyze the following prompt and determine: + 1. The type of analysis required + 2. Target data models + 3. Any query parameters + + Prompt: {prompt} + + Provide your answer in JSON format only, without any additional text, as follows: + ```json + { + "analysis_type": "count" or "relationship" or "performance" or "statistics" or "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {"field1": "value1", "field2": "value2"} + } + ``` + """ + + # Create the prompt template + prompt_template = PromptTemplate( + input_variables=["prompt"], + template=template + ) + + # Create and return the LLM chain + return LLMChain(llm=llm, prompt=prompt_template) +``` + +## Improved JSON Parsing for Qwen3-8B Responses + +Qwen3-8B sometimes includes markdown formatting in its JSON responses. Use this improved parsing function: + +```python +def _parse_llm_json_response(result): + """ + Parse JSON from Qwen3-8B response, handling markdown formatting. + """ + try: + # First try to extract JSON from markdown code blocks + json_match = re.search(r'```(?:json)?\s*([\s\S]*?)\s*```', result) + if json_match: + json_str = json_match.group(1).strip() + return json.loads(json_str) + + # If no markdown blocks, try to find JSON object directly + json_match = re.search(r'({[\s\S]*})', result) + if json_match: + json_str = json_match.group(1).strip() + return json.loads(json_str) + + # If still no match, try to parse the entire response as JSON + return json.loads(result.strip()) + except Exception as e: + logger.warning(f"Failed to parse JSON from LLM response: {str(e)}") + return None +``` + +## Performance Considerations for Qwen3-8B + +- **Memory Usage**: Qwen3-8B typically requires 8-16GB of RAM when running on Ollama +- **First Request Latency**: The first request may take 5-10 seconds as the model loads +- **Subsequent Requests**: Typically respond within 1-3 seconds +- **Batch Processing**: Consider batching multiple analyses for efficiency + +## Handling Arabic-Specific Challenges with Qwen3-8B + +1. **Diacritics**: Qwen3-8B handles Arabic diacritics well, but for consistency, consider normalizing input by removing diacritics + +2. **Text Direction**: When displaying results in frontend, ensure proper RTL (right-to-left) support + +3. **Dialectal Variations**: Qwen3-8B performs best with Modern Standard Arabic (MSA), but has reasonable support for major dialects + +4. **Technical Terms**: For Django-specific technical terms, consider providing a glossary in both English and Arabic + +## Example Arabic Prompts Optimized for Qwen3-8B + +``` +# Count query +كم عدد السيارات المتوفرة في النظام؟ + +# Relationship analysis +ما هي العلاقة بين نموذج المستخدم ونموذج الطلب؟ + +# Performance analysis +حدد مشاكل الأداء المحتملة في نموذج المنتج + +# Statistical analysis +ما هو متوسط سعر السيارات المتوفرة؟ +``` + +## Troubleshooting Qwen3-8B Specific Issues + +1. **Incomplete JSON**: If Qwen3-8B returns incomplete JSON, try: + - Reducing the complexity of your prompt + - Lowering the temperature parameter to 0.1 + - Adding explicit JSON formatting instructions + +2. **Arabic Character Encoding**: If you see garbled Arabic text, ensure: + - Your database uses UTF-8 encoding + - All HTTP responses include proper content-type headers + - Frontend properly handles Arabic character rendering + +3. **Slow Response Times**: If responses are slow: + - Consider using the quantized version: `qwen3:8b-q4_0` + - Reduce context window size if full 4096 context isn't needed + - Implement more aggressive caching + +## Conclusion + +Qwen3-8B is an excellent choice for Arabic language support in your Django AI Analyst application. With these optimized settings and techniques, you'll get reliable performance for analyzing Django models through Arabic natural language prompts. diff --git a/haikalbot/README.md b/haikalbot/README.md new file mode 100644 index 00000000..c670987d --- /dev/null +++ b/haikalbot/README.md @@ -0,0 +1,163 @@ +# Django AI Analyst - README + +This package provides a Django application that enables AI-powered analysis of Django models through natural language prompts. The AI agent can analyze model structures, relationships, and data to provide insights in JSON format. + +## Features + +- Natural language prompt processing for model analysis +- Support for various types of insights: + - Count queries (e.g., "How many cars do we have?") + - Relationship analysis between models + - Performance optimization suggestions + - Statistical analysis of model fields + - General model structure analysis +- Dealer-specific data access controls +- Caching mechanism for improved performance +- Visualization data generation for frontend display +- Comprehensive test suite + +## Installation + +1. Add 'ai_analyst' to your INSTALLED_APPS setting: + +```python +INSTALLED_APPS = [ + ... + 'ai_analyst', +] +``` + +2. Include the ai_analyst URLconf in your project urls.py: + +```python +path('api/ai/', include('ai_analyst.urls')), +``` + +3. Run migrations to create the AnalysisCache model: + +```bash +python manage.py makemigrations ai_analyst +python manage.py migrate +``` + +## Usage + +Send POST requests to the `/api/ai/analyze/` endpoint with a JSON body containing: + +```json +{ + "prompt": "How many cars do we have?", + "dealer_id": 1 // Optional, for dealer-specific queries +} +``` + +The response will be a JSON object with insights based on the prompt: + +```json +{ + "status": "success", + "request_id": "a1b2c3d4", + "timestamp": "2025-05-25T23:21:56Z", + "prompt": "How many cars do we have?", + "insights": [ + { + "type": "count_analysis", + "results": [ + { + "model": "Car", + "count": 42, + "filters_applied": {} + } + ], + "visualization_data": { + "chart_type": "bar", + "labels": ["Car"], + "data": [42] + } + } + ] +} +``` + +## Customization + +### Cache Duration + +You can customize the cache duration by setting the `CACHE_DURATION` class variable in the `ModelAnalystView` class: + +```python +# In your settings.py +AI_ANALYST_CACHE_DURATION = 7200 # 2 hours in seconds + +# Then in views.py +class ModelAnalystView(View): + CACHE_DURATION = getattr(settings, 'AI_ANALYST_CACHE_DURATION', 3600) + # ... +``` + +### Permission Logic + +The `_check_permissions` method in `ModelAnalystView` can be customized to match your application's permission model: + +```python +def _check_permissions(self, user, dealer_id): + # Your custom permission logic here + return user.has_perm('ai_analyst.can_analyze_models') +``` + +## Example Prompts + +- "How many cars do we have?" +- "Show relationship between User and Order" +- "What is the average price of products?" +- "Count active users" +- "Identify performance issues in the Order model" +- "Show maximum age of customers" + +## Frontend Integration + +The JSON responses include visualization_data that can be used with charting libraries like Chart.js: + +```javascript +// Example with Chart.js +fetch('/api/ai/analyze/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + prompt: 'How many cars do we have?', + dealer_id: 1 + }), +}) +.then(response => response.json()) +.then(data => { + if (data.status === 'success' && data.insights.length > 0) { + const insight = data.insights[0]; + const vizData = insight.visualization_data; + + const ctx = document.getElementById('insightChart').getContext('2d'); + new Chart(ctx, { + type: vizData.chart_type, + data: { + labels: vizData.labels, + datasets: [{ + label: insight.type, + data: vizData.data, + backgroundColor: [ + 'rgba(255, 99, 132, 0.2)', + 'rgba(54, 162, 235, 0.2)', + 'rgba(255, 206, 86, 0.2)' + ], + borderColor: [ + 'rgba(255, 99, 132, 1)', + 'rgba(54, 162, 235, 1)', + 'rgba(255, 206, 86, 1)' + ], + borderWidth: 1 + }] + } + }); + } +}); +``` diff --git a/haikalbot/admin.py b/haikalbot/admin.py index b97a94f6..5acba54b 100644 --- a/haikalbot/admin.py +++ b/haikalbot/admin.py @@ -1,2 +1,15 @@ +from django.contrib import admin +from .models import AnalysisCache -# Register your models here. + +@admin.register(AnalysisCache) +class AnalysisCacheAdmin(admin.ModelAdmin): + list_display = ('prompt_hash', 'dealer_id', 'created_at', 'expires_at', 'is_expired') + list_filter = ('dealer_id', 'created_at') + search_fields = ('prompt_hash',) + readonly_fields = ('prompt_hash', 'created_at', 'updated_at') + + def is_expired(self, obj): + return obj.is_expired() + + is_expired.boolean = True diff --git a/haikalbot/analysis_utils.py b/haikalbot/analysis_utils.py new file mode 100644 index 00000000..b3a0a8d4 --- /dev/null +++ b/haikalbot/analysis_utils.py @@ -0,0 +1,231 @@ +from django.db.models import Avg, Sum, Max, Min, ForeignKey, OneToOneField +import inspect +from django.db import models +from django.utils.translation import gettext_lazy as _ + + +def _localized_keys(language): + if language == 'ar': + return { + 'type': 'نوع', 'model': 'النموذج', 'count': 'العدد', 'filters': 'الفلاتر_المطبقة', + 'error': 'خطأ', 'chart_type': 'نوع_الرسم_البياني', 'labels': 'التسميات', 'data': 'البيانات', + 'visualization_data': 'بيانات_الرسم_البياني', 'field': 'الحقل', 'value': 'القيمة', + 'statistic_type': 'نوع_الإحصاء', 'results': 'النتائج', 'title': 'العنوان' + } + else: + return { + 'type': 'type', 'model': 'model', 'count': 'count', 'filters': 'filters_applied', + 'error': 'error', 'chart_type': 'chart_type', 'labels': 'labels', 'data': 'data', + 'visualization_data': 'visualization_data', 'field': 'field', 'value': 'value', + 'statistic_type': 'statistic_type', 'results': 'results', 'title': 'title' + } + + +def generate_count_insight(models, query_params, dealer_id=None, language='ar'): + keys = _localized_keys(language) + results = [] + + for model in models: + try: + queryset = model.objects.all() + + if dealer_id: + if hasattr(model, 'dealer_id'): + queryset = queryset.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + queryset = queryset.filter(dealer=dealer_id) + + filters = {} + for key, value in query_params.items(): + if key not in ['field', 'operation'] and hasattr(model, key): + try: + field = model._meta.get_field(key) + if isinstance(field, models.IntegerField): + value = int(value) + elif isinstance(field, models.BooleanField): + value = value.lower() in ('true', '1', 'yes') + except Exception: + pass + filters[key] = value + + if filters: + queryset = queryset.filter(**filters) + + results.append({ + keys['model']: model.__name__, + keys['count']: queryset.count(), + keys['filters']: filters + }) + + except Exception as e: + results.append({ + keys['model']: model.__name__, + keys['error']: str(e) + }) + + return { + 'type': keys['type'] + '_analysis', + keys['results']: results, + keys['visualization_data']: { + keys['chart_type']: 'bar', + keys['labels']: [r[keys['model']] for r in results if keys['count'] in r], + keys['data']: [r[keys['count']] for r in results if keys['count'] in r] + } + } + + +def generate_statistics_insight(models, query_params, dealer_id=None, language='ar'): + keys = _localized_keys(language) + results = [] + field = query_params.get('field') + operation = query_params.get('operation', 'average') + + for model in models: + try: + if not field or not hasattr(model, field): + continue + + queryset = model.objects.all() + if dealer_id: + if hasattr(model, 'dealer_id'): + queryset = queryset.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + queryset = queryset.filter(dealer=dealer_id) + + filters = {} + for k, v in query_params.items(): + if k not in ['field', 'operation'] and hasattr(model, k): + filters[k] = v + + if filters: + queryset = queryset.filter(**filters) + + stat_map = { + 'average': Avg, + 'sum': Sum, + 'max': Max, + 'min': Min + } + + if operation in stat_map: + agg = queryset.aggregate(val=stat_map[operation](field))['val'] + value = agg + else: + value = queryset.count() + + results.append({ + keys['model']: model.__name__, + keys['field']: field, + keys['statistic_type']: operation, + keys['value']: value, + keys['filters']: filters + }) + + except Exception as e: + results.append({keys['model']: model.__name__, keys['error']: str(e)}) + + return { + 'type': keys['type'] + '_analysis', + keys['results']: results, + keys['visualization_data']: { + keys['chart_type']: 'bar', + keys['labels']: [f"{r[keys['model']]}.{r[keys['field']]}" for r in results if keys['value'] in r], + keys['data']: [r[keys['value']] for r in results if keys['value'] in r], + keys['title']: f"{operation} of {field}" if language != 'ar' else f"{field} ({operation})" + } + } + + +def generate_recommendations(model_classes, analysis_type, language='ar'): + recs = [] + for model in model_classes: + for field in model._meta.fields: + if isinstance(field, ForeignKey) and not field.db_index: + msg = f"أضف db_index=True إلى {model.__name__}.{field.name}" if language == 'ar' else f"Add db_index=True to {model.__name__}.{field.name}" + recs.append(msg) + if isinstance(field, models.CharField) and not field.db_index and field.name in ['name', 'title', 'description', 'text']: + msg = f"فكر في فهرسة الحقل النصي {model.__name__}.{field.name}" if language == 'ar' else f"Consider indexing the text field {model.__name__}.{field.name}" + recs.append(msg) + return recs[:5] + + +def generate_model_insight(model, dealer_id=None, language='ar'): + keys = _localized_keys(language) + fields_info = [ + { + 'name': f.name, + 'type': f.__class__.__name__, + 'null': f.null, + 'blank': f.blank, + 'unique': f.unique, + 'pk': f.primary_key + } for f in model._meta.fields + ] + + try: + qs = model.objects.all() + if dealer_id: + if hasattr(model, 'dealer_id'): + qs = qs.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + qs = qs.filter(dealer=dealer_id) + count = qs.count() + except Exception: + count = "error" + + return { + 'type': keys['type'] + '_analysis', + keys['model']: model.__name__, + 'fields': fields_info, + 'count': count + } + + +def generate_relationship_insight(models, query_params=None, dealer_id=None, language='ar'): + from_ = "من" if language == 'ar' else "from" + to_ = "إلى" if language == 'ar' else "to" + rel_type = "نوع" if language == 'ar' else "type" + relationships = [] + + for model in models: + for field in model._meta.fields: + if isinstance(field, (ForeignKey, OneToOneField)): + relationships.append({ + from_: model.__name__, + to_: field.related_model.__name__, + rel_type: field.__class__.__name__ + }) + for field in model._meta.many_to_many: + relationships.append({ + from_: model.__name__, + to_: field.related_model.__name__, + rel_type: 'ManyToManyField' + }) + + return { + 'type': 'تحليل_العلاقات' if language == 'ar' else 'relationship_analysis', + 'relationships': relationships + } + + +def generate_performance_insight(models, query_params=None, dealer_id=None, language='ar'): + issues = [] + for model in models: + for field in model._meta.fields: + if isinstance(field, ForeignKey) and not field.db_index: + issues.append({ + 'model': model.__name__, + 'field': field.name, + 'issue': 'Missing index on ForeignKey' + }) + if isinstance(field, models.CharField) and not field.db_index and field.name in ['name', 'title']: + issues.append({ + 'model': model.__name__, + 'field': field.name, + 'issue': 'Unindexed CharField used in filtering' + }) + + return { + 'type': 'تحليل_الأداء' if language == 'ar' else 'performance_analysis', + 'issues': issues + } diff --git a/haikalbot/chatbot_logic.py b/haikalbot/chatbot_logic.py index 15390ce0..f493274f 100644 --- a/haikalbot/chatbot_logic.py +++ b/haikalbot/chatbot_logic.py @@ -3,20 +3,7 @@ from inventory import models from car_inventory import settings def fetch_data(dealer): - """ - Fetches the total number of cars in the inventory for the specified dealer. If no cars are - found, returns a message indicating that fact. If an error occurs during the operation, - it returns an error message with details. - :param dealer: The dealer object for which the inventory information is required. - The dealer object must be an instance of a model that includes a - `get_local_name` method for formatting localized dealer names. - :type dealer: Dealer - :return: A string indicating either the total number of cars in the dealer's inventory, - that no cars exist in the inventory, or an error message detailing what went - wrong during the operation. - :rtype: str - """ try: # Annotate total cars by make, model, and trim cars = models.Car.objects.filter(dealer=dealer).count() diff --git a/haikalbot/haikalbot_01.png b/haikalbot/haikalbot_01.png new file mode 100644 index 00000000..7b921365 Binary files /dev/null and b/haikalbot/haikalbot_01.png differ diff --git a/haikalbot/langchain_ollama_integration_guide.md b/haikalbot/langchain_ollama_integration_guide.md new file mode 100644 index 00000000..5631e8f9 --- /dev/null +++ b/haikalbot/langchain_ollama_integration_guide.md @@ -0,0 +1,312 @@ +# Integrating Ollama with LangChain for Django AI Analyst + +This guide provides step-by-step instructions for integrating Ollama with LangChain in your Django AI Analyst application, with specific focus on Arabic language support. + +## Prerequisites + +1. Ollama installed on your system +2. An Ollama model with Arabic support (preferably Jais-13B as recommended) +3. Django project with the AI Analyst application + +## Installation Steps + +### 1. Install Required Python Packages + +```bash +pip install langchain langchain-community +``` + +### 2. Configure Django Settings + +Add the following to your Django settings.py file: + +```python +# Ollama and LangChain settings +OLLAMA_BASE_URL = "http://10.10.1.132:11434" # Default Ollama API URL +OLLAMA_MODEL = "qwen3:6b" # Or your preferred model +OLLAMA_TIMEOUT = 120 # Seconds +``` + +### 3. Create a LangChain Utility Module + +Create a new file `ai_analyst/langchain_utils.py`: + +```python +from langchain.llms import Ollama +from langchain.chains import LLMChain +from langchain.prompts import PromptTemplate +from django.conf import settings +import logging + +logger = logging.getLogger(__name__) + +def get_ollama_llm(): + """ + Initialize and return an Ollama LLM instance configured for Arabic support. + """ + try: + # Get settings from Django settings or use defaults + base_url = getattr(settings, 'OLLAMA_BASE_URL', 'http://10.10.1.132:11434') + model = getattr(settings, 'OLLAMA_MODEL', 'qwen3:8b') + timeout = getattr(settings, 'OLLAMA_TIMEOUT', 120) + + # Configure Ollama with appropriate parameters for Arabic + return Ollama( + base_url=base_url, + model=model, + timeout=timeout, + # Parameters to improve Arabic language generation + parameters={ + "temperature": 0.7, + "top_p": 0.9, + "top_k": 40, + "num_ctx": 2048, # Context window size + } + ) + except Exception as e: + logger.error(f"Error initializing Ollama LLM: {str(e)}") + return None + +def create_prompt_analyzer_chain(language='ar'): + """ + Create a LangChain for analyzing prompts in Arabic or English. + """ + llm = get_ollama_llm() + if not llm: + return None + + # Define the prompt template based on language + if language == 'ar': + template = """ + قم بتحليل الاستعلام التالي وتحديد نوع التحليل المطلوب ونماذج البيانات المستهدفة وأي معلمات استعلام. + + الاستعلام: {prompt} + + قم بتقديم إجابتك بتنسيق JSON كما يلي: + {{ + "analysis_type": "count" أو "relationship" أو "performance" أو "statistics" أو "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {{"field1": "value1", "field2": "value2"}} + }} + """ + else: + template = """ + Analyze the following prompt and determine the type of analysis required, target data models, and any query parameters. + + Prompt: {prompt} + + Provide your answer in JSON format as follows: + { + "analysis_type": "count" or "relationship" or "performance" or "statistics" or "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {"field1": "value1", "field2": "value2"} + } + """ + + # Create the prompt template + prompt_template = PromptTemplate( + input_variables=["prompt"], + template=template + ) + + # Create and return the LLM chain + return LLMChain(llm=llm, prompt=prompt_template) +``` + +### 4. Update Your View to Use LangChain + +Modify your `ModelAnalystView` class to use the LangChain utilities: + +```python +from .langchain_utils import create_prompt_analyzer_chain +import json +import re + +class ModelAnalystView(View): + # ... existing code ... + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + # We'll initialize chains on demand to avoid startup issues + self.prompt_analyzer_chains = {} + + def _get_prompt_analyzer_chain(self, language='ar'): + """ + Get or create a prompt analyzer chain for the specified language. + """ + if language not in self.prompt_analyzer_chains: + self.prompt_analyzer_chains[language] = create_prompt_analyzer_chain(language) + return self.prompt_analyzer_chains[language] + + def _analyze_prompt_with_llm(self, prompt, language='ar'): + """ + Use LangChain and Ollama to analyze the prompt. + """ + try: + # Get the appropriate chain for the language + chain = self._get_prompt_analyzer_chain(language) + if not chain: + # Fallback to rule-based analysis if chain creation failed + return self._analyze_prompt_rule_based(prompt, language) + + # Run the chain + result = chain.run(prompt=prompt) + + # Parse the JSON result + # Find JSON content within the response (in case the LLM adds extra text) + json_match = re.search(r'({.*})', result.replace('\n', ' '), re.DOTALL) + if json_match: + json_str = json_match.group(1) + return json.loads(json_str) + else: + # Fallback to rule-based analysis + return self._analyze_prompt_rule_based(prompt, language) + + except Exception as e: + logger.error(f"Error in LLM prompt analysis: {str(e)}") + # Fallback to rule-based analysis + return self._analyze_prompt_rule_based(prompt, language) + + def _analyze_prompt_rule_based(self, prompt, language='ar'): + """ + Rule-based fallback for prompt analysis. + """ + analysis_type, target_models, query_params = self._analyze_prompt(prompt, language) + return { + "analysis_type": analysis_type, + "target_models": target_models, + "query_params": query_params + } + + def _process_prompt(self, prompt, user, dealer_id, language='ar'): + """ + Process the natural language prompt and generate insights. + """ + # ... existing code ... + + # Use LLM for prompt analysis + analysis_result = self._analyze_prompt_with_llm(prompt, language) + analysis_type = analysis_result.get('analysis_type', 'general') + target_models = analysis_result.get('target_models', []) + query_params = analysis_result.get('query_params', {}) + + # ... rest of the method ... +``` + +## Testing the Integration + +Create a test script to verify the Ollama and LangChain integration: + +```python +# test_ollama.py +import os +import sys +import django + +# Set up Django environment +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings') +django.setup() + +from ai_analyst.langchain_utils import get_ollama_llm, create_prompt_analyzer_chain + +def test_ollama_connection(): + """Test basic Ollama connection and response.""" + llm = get_ollama_llm() + if not llm: + print("Failed to initialize Ollama LLM") + return + + # Test with Arabic prompt + arabic_prompt = "مرحبا، كيف حالك؟" + print(f"Testing Arabic prompt: {arabic_prompt}") + try: + response = llm.invoke(arabic_prompt) + print(f"Response: {response}") + print("Ollama connection successful!") + except Exception as e: + print(f"Error: {str(e)}") + +def test_prompt_analysis(): + """Test the prompt analyzer chain.""" + chain = create_prompt_analyzer_chain('ar') + if not chain: + print("Failed to create prompt analyzer chain") + return + + # Test with an Arabic analysis prompt + analysis_prompt = "كم عدد السيارات التي لدينا؟" + print(f"Testing analysis prompt: {analysis_prompt}") + try: + result = chain.run(prompt=analysis_prompt) + print(f"Analysis result: {result}") + except Exception as e: + print(f"Error: {str(e)}") + +if __name__ == "__main__": + print("Testing Ollama and LangChain integration...") + test_ollama_connection() + print("\n---\n") + test_prompt_analysis() +``` + +Run the test script: + +```bash +python test_ollama.py +``` + +## Troubleshooting + +### Common Issues and Solutions + +1. **Ollama Connection Error** + - Ensure Ollama is running: `ollama serve` + - Check if the model is downloaded: `ollama list` + - Verify the base URL in settings + +2. **Model Not Found** + - Download the model: `ollama pull jais:13b` + - Check model name spelling in settings + +3. **Timeout Errors** + - Increase the timeout setting for complex queries + - Consider using a smaller model if your hardware is limited + +4. **Poor Arabic Analysis** + - Ensure you're using an Arabic-capable model like Jais-13B + - Check that your prompts are properly formatted in Arabic + - Adjust temperature and other parameters for better results + +5. **JSON Parsing Errors** + - Improve the prompt template to emphasize strict JSON formatting + - Implement more robust JSON extraction from LLM responses + +## Performance Optimization + +For production use, consider these optimizations: + +1. **Caching LLM Responses** + - Implement Redis or another caching system for LLM responses + - Cache common analysis patterns to reduce API calls + +2. **Batch Processing** + - For bulk analysis, use batch processing to reduce overhead + +3. **Model Quantization** + - If performance is slow, consider using a quantized version of the model + - Example: `ollama pull jais:13b-q4_0` for a 4-bit quantized version + +4. **Asynchronous Processing** + - For long-running analyses, implement asynchronous processing with Celery + +## Advanced Usage: Fine-tuning for Domain-Specific Analysis + +For improved performance on your specific domain: + +1. Create a dataset of example prompts and expected analyses +2. Use Ollama's fine-tuning capabilities to adapt the model +3. Update your application to use the fine-tuned model + +## Conclusion + +This integration enables your Django AI Analyst to leverage Ollama's powerful language models through LangChain, with specific optimizations for Arabic language support. The fallback to rule-based analysis ensures robustness, while the LLM-based approach provides more natural language understanding capabilities. diff --git a/haikalbot/migrations/0001_initial.py b/haikalbot/migrations/0001_initial.py index a801e7ea..61850a1a 100644 --- a/haikalbot/migrations/0001_initial.py +++ b/haikalbot/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.7 on 2025-05-04 16:07 +# Generated by Django 5.2.1 on 2025-05-25 23:01 from django.db import migrations, models diff --git a/haikalbot/migrations/0002_initial.py b/haikalbot/migrations/0002_initial.py index 67dffe26..d8b26a8e 100644 --- a/haikalbot/migrations/0002_initial.py +++ b/haikalbot/migrations/0002_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.7 on 2025-05-04 16:07 +# Generated by Django 5.2.1 on 2025-05-25 23:01 import django.db.models.deletion from django.db import migrations, models diff --git a/haikalbot/migrations/0003_analysiscache.py b/haikalbot/migrations/0003_analysiscache.py new file mode 100644 index 00000000..5d94804a --- /dev/null +++ b/haikalbot/migrations/0003_analysiscache.py @@ -0,0 +1,33 @@ +# Generated by Django 5.2.1 on 2025-05-26 00:28 + +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('haikalbot', '0002_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='AnalysisCache', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('prompt_hash', models.CharField(db_index=True, max_length=64)), + ('dealer_id', models.IntegerField(blank=True, db_index=True, null=True)), + ('created_at', models.DateTimeField(default=django.utils.timezone.now)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('expires_at', models.DateTimeField()), + ('result', models.JSONField()), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'indexes': [models.Index(fields=['prompt_hash', 'dealer_id'], name='haikalbot_a_prompt__b98e1e_idx'), models.Index(fields=['expires_at'], name='haikalbot_a_expires_e790cd_idx')], + }, + ), + ] diff --git a/haikalbot/migrations/0004_alter_analysiscache_options_alter_chatlog_options_and_more.py b/haikalbot/migrations/0004_alter_analysiscache_options_alter_chatlog_options_and_more.py new file mode 100644 index 00000000..c61771dd --- /dev/null +++ b/haikalbot/migrations/0004_alter_analysiscache_options_alter_chatlog_options_and_more.py @@ -0,0 +1,36 @@ +# Generated by Django 5.2.1 on 2025-05-26 08:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('haikalbot', '0003_analysiscache'), + ('inventory', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='analysiscache', + options={'verbose_name_plural': 'Analysis caches'}, + ), + migrations.AlterModelOptions( + name='chatlog', + options={'ordering': ['-timestamp']}, + ), + migrations.AlterField( + model_name='analysiscache', + name='expires_at', + field=models.DateTimeField(db_index=True), + ), + migrations.AlterField( + model_name='chatlog', + name='timestamp', + field=models.DateTimeField(auto_now_add=True, db_index=True), + ), + migrations.AddIndex( + model_name='chatlog', + index=models.Index(fields=['dealer', 'timestamp'], name='haikalbot_c_dealer__6f8d63_idx'), + ), + ] diff --git a/haikalbot/models.py b/haikalbot/models.py index 1853a4be..fed58f8e 100644 --- a/haikalbot/models.py +++ b/haikalbot/models.py @@ -1,5 +1,8 @@ from django.db import models from inventory.models import Dealer +from django.contrib.auth.models import User +from django.conf import settings +from django.utils import timezone class ChatLog(models.Model): @@ -21,10 +24,67 @@ class ChatLog(models.Model): :ivar timestamp: The date and time when the chat log entry was created. :type timestamp: datetime """ - dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name='chatlogs') + dealer = models.ForeignKey(Dealer, on_delete=models.CASCADE, related_name='chatlogs', db_index=True) user_message = models.TextField() chatbot_response = models.TextField() - timestamp = models.DateTimeField(auto_now_add=True) + timestamp = models.DateTimeField(auto_now_add=True, db_index=True) + + class Meta: + ordering = ['-timestamp'] + indexes = [ + models.Index(fields=['dealer', 'timestamp']), + ] def __str__(self): - return self.user_message \ No newline at end of file + return f"{self.dealer.name}: {self.user_message[:50]}..." + + +class AnalysisCache(models.Model): + """ + Model to cache analysis results for performance optimization. + + This model stores cached results of model analysis operations to improve + performance for repeated queries. It includes a hash of the prompt, user + information, dealer ID, timestamps, and the cached result in JSON format. + + :ivar prompt_hash: MD5 hash of the prompt + dealer_id + language + :type prompt_hash: str + :ivar user: The user who made the request (optional) + :type user: User + :ivar dealer_id: ID of the dealer associated with this cache entry + :type dealer_id: int + :ivar created_at: When the cache entry was created + :type created_at: datetime + :ivar updated_at: When the cache entry was last updated + :type updated_at: datetime + :ivar expires_at: When the cache entry expires + :type expires_at: datetime + :ivar result: The cached analysis result + :type result: dict + """ + prompt_hash = models.CharField(max_length=64, db_index=True) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True) + dealer_id = models.IntegerField(null=True, blank=True, db_index=True) + created_at = models.DateTimeField(default=timezone.now) + updated_at = models.DateTimeField(auto_now=True) + expires_at = models.DateTimeField(db_index=True) + result = models.JSONField() + + class Meta: + indexes = [ + models.Index(fields=['prompt_hash', 'dealer_id']), + models.Index(fields=['expires_at']), + ] + verbose_name_plural = "Analysis caches" + + def is_expired(self): + """ + Check if the cache entry has expired. + + :return: True if the cache entry has expired, False otherwise + :rtype: bool + """ + return timezone.now() > self.expires_at + + def __str__(self): + return f"Cache: {self.prompt_hash[:10]}... (Dealer: {self.dealer_id})" diff --git a/haikalbot/ollama_model_recommendations.md b/haikalbot/ollama_model_recommendations.md new file mode 100644 index 00000000..070451dc --- /dev/null +++ b/haikalbot/ollama_model_recommendations.md @@ -0,0 +1,76 @@ +# Recommended Ollama Models for Arabic Language Support + +## Top Recommendations + +1. **Jais-13B** (Recommended) + - **Size**: 13 billion parameters + - **Strengths**: Specifically trained on Arabic content, excellent understanding of Arabic context and nuances + - **Command**: `ollama pull jais:13b` + - **Best for**: Production-quality Arabic language understanding and generation + +2. **BLOOM-7B** + - **Size**: 7 billion parameters + - **Strengths**: Trained on 46 languages including Arabic, good multilingual capabilities + - **Command**: `ollama pull bloom:7b` + - **Best for**: Multilingual applications where Arabic is one of several languages + +3. **Mistral-7B-Instruct** + - **Size**: 7 billion parameters + - **Strengths**: Strong general performance, good instruction following, reasonable Arabic support + - **Command**: `ollama pull mistral:7b-instruct` + - **Best for**: General purpose applications with moderate Arabic requirements + +4. **Qwen2-7B** + - **Size**: 7 billion parameters + - **Strengths**: Good multilingual capabilities including Arabic + - **Command**: `ollama pull qwen2:7b` + - **Best for**: Applications requiring both Chinese and Arabic support + +## Comparison Table + +| Model | Size | Arabic Support | Instruction Following | Resource Requirements | Command | +|-------|------|---------------|----------------------|----------------------|---------| +| Jais-13B | 13B | Excellent | Very Good | High (16GB+ RAM) | `ollama pull jais:13b` | +| BLOOM-7B | 7B | Good | Good | Medium (8GB+ RAM) | `ollama pull bloom:7b` | +| Mistral-7B-Instruct | 7B | Moderate | Excellent | Medium (8GB+ RAM) | `ollama pull mistral:7b-instruct` | +| Qwen2-7B | 7B | Good | Very Good | Medium (8GB+ RAM) | `ollama pull qwen2:7b` | + +## Justification for Jais-13B Recommendation + +Jais-13B is specifically recommended for your Django AI Analyst application because: + +1. **Arabic-First Design**: Unlike most models that treat Arabic as one of many languages, Jais was specifically designed for Arabic language understanding and generation. + +2. **Cultural Context**: The model has better understanding of Arabic cultural contexts and nuances, which is important for analyzing domain-specific queries about your data models. + +3. **Technical Terminology**: Better handling of technical terms in Arabic, which is crucial for a model analyzing Django models and database structures. + +4. **Instruction Following**: Good ability to follow complex instructions in Arabic, which is essential for your prompt-based analysis system. + +5. **Performance on Analytical Tasks**: Superior performance on analytical and reasoning tasks in Arabic compared to general multilingual models. + +If your system has limited resources (less than 12GB RAM), Mistral-7B-Instruct would be the next best alternative, offering a good balance between performance and resource requirements. + +## Installation Instructions + +To install the recommended Jais-13B model: + +```bash +ollama pull jais:13b +``` + +For systems with limited resources, install Mistral-7B-Instruct instead: + +```bash +ollama pull mistral:7b-instruct +``` + +After installation, update the `OLLAMA_MODEL` setting in your Django view: + +```python +# For Jais-13B +OLLAMA_MODEL = 'jais:13b' + +# OR for Mistral-7B-Instruct if resources are limited +# OLLAMA_MODEL = 'mistral:7b-instruct' +``` diff --git a/haikalbot/services/analysis_service.py b/haikalbot/services/analysis_service.py new file mode 100644 index 00000000..10081ef5 --- /dev/null +++ b/haikalbot/services/analysis_service.py @@ -0,0 +1,227 @@ +import inspect +import hashlib +from django.db import models +from django.db.models import Avg, Sum, Max, Min, ForeignKey, OneToOneField, Count +from django.utils.translation import gettext_lazy as _ +from django.utils import timezone + + +def _localized_keys(language): + return { + 'type': 'نوع' if language == 'ar' else 'type', + 'model': 'النموذج' if language == 'ar' else 'model', + 'count': 'العدد' if language == 'ar' else 'count', + 'filters': 'الفلاتر_المطبقة' if language == 'ar' else 'filters_applied', + 'error': 'خطأ' if language == 'ar' else 'error', + 'chart_type': 'نوع_الرسم_البياني' if language == 'ar' else 'chart_type', + 'labels': 'التسميات' if language == 'ar' else 'labels', + 'data': 'البيانات' if language == 'ar' else 'data', + 'visualization_data': 'بيانات_الرسم_البياني' if language == 'ar' else 'visualization_data', + 'field': 'الحقل' if language == 'ar' else 'field', + 'value': 'القيمة' if language == 'ar' else 'value', + 'statistic_type': 'نوع_الإحصاء' if language == 'ar' else 'statistic_type', + 'results': 'النتائج' if language == 'ar' else 'results', + 'title': 'العنوان' if language == 'ar' else 'title', + } + + +def generate_count_insight(models, query_params, dealer_id=None, language='en'): + keys = _localized_keys(language) + results = [] + + for model in models: + try: + queryset = model.objects.all() + + if dealer_id: + if hasattr(model, 'dealer_id'): + queryset = queryset.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + queryset = queryset.filter(dealer=dealer_id) + + filters = {} + for key, value in query_params.items(): + if key in ['field', 'operation']: + continue + if hasattr(model, key): + try: + field = model._meta.get_field(key) + if isinstance(field, models.IntegerField): + value = int(value) + elif isinstance(field, models.BooleanField): + value = value.lower() in ('true', '1', 'yes') + except Exception: + pass + filters[key] = value + + if filters: + queryset = queryset.filter(**filters) + + results.append({ + keys['model']: model.__name__, + keys['count']: queryset.count(), + keys['filters']: filters, + }) + except Exception as e: + results.append({ + keys['model']: model.__name__, + keys['error']: str(e), + }) + + return { + keys['type']: keys['type'] + '_analysis', + keys['results']: results, + keys['visualization_data']: { + keys['chart_type']: 'bar', + keys['labels']: [r[keys['model']] for r in results if keys['count'] in r], + keys['data']: [r[keys['count']] for r in results if keys['count'] in r], + } + } + + +def generate_statistics_insight(models, query_params, dealer_id=None, language='en'): + keys = _localized_keys(language) + results = [] + field = query_params.get('field') + operation = query_params.get('operation', 'average') + stat_map = {'average': Avg, 'sum': Sum, 'max': Max, 'min': Min} + + for model in models: + try: + if not field or not hasattr(model, field): + continue + + queryset = model.objects.all() + if dealer_id: + if hasattr(model, 'dealer_id'): + queryset = queryset.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + queryset = queryset.filter(dealer=dealer_id) + + filters = { + k: v for k, v in query_params.items() + if k not in ['field', 'operation'] and hasattr(model, k) + } + + if filters: + queryset = queryset.filter(**filters) + + value = queryset.aggregate(val=stat_map.get(operation, Count)(field))['val'] + + results.append({ + keys['model']: model.__name__, + keys['field']: field, + keys['statistic_type']: operation, + keys['value']: value, + keys['filters']: filters, + }) + except Exception as e: + results.append({ + keys['model']: model.__name__, + keys['error']: str(e), + }) + + return { + keys['type']: keys['type'] + '_analysis', + keys['results']: results, + keys['visualization_data']: { + keys['chart_type']: 'bar', + keys['labels']: [f"{r[keys['model']]}.{r[keys['field']]}" for r in results if keys['value'] in r], + keys['data']: [r[keys['value']] for r in results if keys['value'] in r], + keys['title']: f"{operation} of {field}" if language != 'ar' else f"{field} ({operation})" + } + } + + +def generate_recommendations(model_classes, analysis_type, language='en'): + recs = [] + for model in model_classes: + for field in model._meta.fields: + if isinstance(field, ForeignKey) and not field.db_index: + msg = f"أضف db_index=True إلى {model.__name__}.{field.name}" if language == 'ar' else f"Add db_index=True to {model.__name__}.{field.name}" + recs.append(msg) + if isinstance(field, models.CharField) and not field.db_index and field.name in ['name', 'title', 'description', 'text']: + msg = f"فكر في فهرسة الحقل النصي {model.__name__}.{field.name}" if language == 'ar' else f"Consider indexing the text field {model.__name__}.{field.name}" + recs.append(msg) + return recs[:5] + + +def generate_model_insight(model, dealer_id=None, language='en'): + keys = _localized_keys(language) + fields_info = [{ + 'name': f.name, + 'type': f.__class__.__name__, + 'null': f.null, + 'blank': f.blank, + 'unique': f.unique, + 'pk': f.primary_key + } for f in model._meta.fields] + + try: + qs = model.objects.all() + if dealer_id: + if hasattr(model, 'dealer'): + qs = qs.filter(dealer_id=dealer_id) + elif hasattr(model, 'dealer'): + qs = qs.filter(dealer=dealer_id) + count = qs.count() + except Exception: + count = "error" + + return { + keys['type']: keys['type'] + '_analysis', + keys['model']: model.__name__, + 'fields': fields_info, + 'count': count + } + + +def generate_relationship_insight(models, query_params=None, dealer_id=None, language='en'): + from_ = "من" if language == 'ar' else "from" + to_ = "إلى" if language == 'ar' else "to" + rel_type = "نوع" if language == 'ar' else "type" + relationships = [] + + for model in models: + for field in model._meta.fields: + if isinstance(field, (ForeignKey, OneToOneField)): + relationships.append({ + from_: model.__name__, + to_: field.related_model.__name__, + rel_type: field.__class__.__name__, + }) + for field in model._meta.many_to_many: + relationships.append({ + from_: model.__name__, + to_: field.related_model.__name__, + rel_type: 'ManyToManyField' + }) + + return { + 'type': 'تحليل_العلاقات' if language == 'ar' else 'relationship_analysis', + 'relationships': relationships + } + + +def generate_performance_insight(models, query_params=None, dealer_id=None, language='en'): + issues = [] + + for model in models: + for field in model._meta.fields: + if isinstance(field, ForeignKey) and not field.db_index: + issues.append({ + # 'model': model.__name__, + 'field': field.name, + 'issue': 'Missing index on ForeignKey' + }) + # if isinstance(field, models.CharField) and not field.db_index and field.name in ['name', 'title']: + # issues.append({ + # 'model': model.__name__, + # 'field': field.name, + # 'issue': 'Unindexed CharField used in filtering' + # }) + + return { + 'type': 'تحليل_الأداء' if language == 'ar' else 'performance_analysis', + 'issues': issues + } \ No newline at end of file diff --git a/haikalbot/services/cache_service.py b/haikalbot/services/cache_service.py new file mode 100644 index 00000000..6c80f725 --- /dev/null +++ b/haikalbot/services/cache_service.py @@ -0,0 +1,61 @@ +import hashlib +import logging +from django.utils import timezone +from django.db import models +from ..models import AnalysisCache + +logger = logging.getLogger(__name__) + + +class CacheService: + def generate_hash(self, prompt, dealer_id, language): + """ + Generate a unique MD5 hash based on the prompt, dealer ID, and language. + """ + key = f"{prompt}:{dealer_id or 'all'}:{language}" + return hashlib.md5(key.encode()).hexdigest() + + def get_cached_result(self, prompt_hash, user, dealer_id): + """ + Retrieve a cached analysis result based on hash, dealer, and optionally user. + """ + try: + # Check for user-specific cache if authenticated + if user and user.is_authenticated: + user_cache = AnalysisCache.objects.filter( + prompt_hash=prompt_hash, + user=user, + expires_at__gt=timezone.now() + ).first() + if user_cache: + return user_cache.result + + # Otherwise check for dealer-wide cache + dealer_cache = AnalysisCache.objects.filter( + prompt_hash=prompt_hash, + dealer_id=dealer_id, + expires_at__gt=timezone.now() + ).first() + + return dealer_cache.result if dealer_cache else None + except Exception as e: + logger.warning(f"Cache retrieval failed: {str(e)}") + return None + + def cache_result(self, prompt_hash, result, user, dealer_id, duration=3600): + """ + Save or update a cached result with an expiration timestamp. + """ + try: + expires_at = timezone.now() + timezone.timedelta(seconds=duration) + AnalysisCache.objects.update_or_create( + prompt_hash=prompt_hash, + user=user if user and user.is_authenticated else None, + dealer_id=dealer_id, + defaults={ + 'result': result, + 'expires_at': expires_at + } + ) + except Exception as e: + logger.warning(f"Cache saving failed: {str(e)}") \ No newline at end of file diff --git a/haikalbot/services/llm_service.py b/haikalbot/services/llm_service.py new file mode 100644 index 00000000..32109991 --- /dev/null +++ b/haikalbot/services/llm_service.py @@ -0,0 +1,150 @@ +import json +import logging +from django.apps import apps +from django.http import JsonResponse +from django.db.models import Count, Avg, Max, Min +from langchain_ollama import OllamaLLM +from langchain.chains import LLMChain +from langchain.prompts import PromptTemplate +from django.conf import settings + +logger = logging.getLogger(__name__) + + +def get_llm_instance(): + try: + base_url = getattr(settings, 'OLLAMA_BASE_URL', 'http://10.10.1.132:11434') + model = getattr(settings, 'OLLAMA_MODEL', 'qwen3:8b') + temperature = getattr(settings, 'OLLAMA_TEMPERATURE', 0.2) + top_p = getattr(settings, 'OLLAMA_TOP_P', 0.8) + top_k = getattr(settings, 'OLLAMA_TOP_K', 40) + num_ctx = getattr(settings, 'OLLAMA_NUM_CTX', 4096) + num_predict = getattr(settings, 'OLLAMA_NUM_PREDICT', 2048) + + return OllamaLLM( + base_url=base_url, + model=model, + temperature=temperature, + top_p=top_p, + top_k=top_k, + num_ctx=num_ctx, + num_predict=num_predict, + stop=["```", ""], + repeat_penalty=1.1, + ) + except Exception as e: + logger.error(f"Error initializing Ollama LLM: {str(e)}") + return None + + +def get_llm_chain(language='en'): + llm = get_llm_instance() + if not llm: + return None + + if language == 'ar': + template = """ + قم بتحليل الاستعلام التالي وتحديد نوع التحليل المطلوب ونماذج البيانات المستهدفة وأي معلمات استعلام. + + الاستعلام: {prompt} + + قم بتقديم إجابتك بتنسيق JSON كما يلي: + {{ + "analysis_type": "count" أو "relationship" أو "performance" أو "statistics" أو "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {{"field1": "value1", "field2": "value2"}} + }} + """ + else: + template = """ + Analyze the following prompt and determine the type of analysis required, target data models, and any query parameters. + + Prompt: {prompt} + + Provide your answer in JSON format as follows: + { + "analysis_type": "count" or "relationship" or "performance" or "statistics" or "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {"field1": "value1", "field2": "value2"} + } + """ + + prompt_template = PromptTemplate( + input_variables=["prompt"], + template=template + ) + + return prompt_template | llm + + +def analyze_models_with_orm(analysis_type, target_models, query_params): + results = {} + + for model_name in target_models: + try: + model = apps.get_model('your_app_name', model_name) + except LookupError: + results[model_name] = {"error": f"Model '{model_name}' not found"} + continue + + try: + queryset = model.objects.filter(**query_params) + + if analysis_type == 'count': + results[model_name] = {'count': queryset.count()} + + elif analysis_type == 'statistics': + numeric_fields = [f.name for f in model._meta.fields if f.get_internal_type() in ['IntegerField', 'FloatField', 'DecimalField']] + stats = {} + for field in numeric_fields: + stats[field] = { + 'avg': queryset.aggregate(avg=Avg(field))['avg'], + 'max': queryset.aggregate(max=Max(field))['max'], + 'min': queryset.aggregate(min=Min(field))['min'] + } + results[model_name] = stats + + elif analysis_type == 'relationship': + related = {} + for field in model._meta.get_fields(): + if field.is_relation and field.many_to_one: + related[field.name] = queryset.values(field.name).annotate(count=Count(field.name)).count() + results[model_name] = related + + elif analysis_type == 'performance': + results[model_name] = {'note': 'Performance analysis logic not implemented.'} + + else: + results[model_name] = list(queryset.values()) + + except Exception as e: + results[model_name] = {'error': str(e)} + + return results + + +def analyze_prompt_and_return_json(request): + try: + prompt = request.POST.get('prompt') + language = request.POST.get('language', 'en') + + chain = get_llm_chain(language) + if not chain: + return JsonResponse({'success': False, 'error': 'LLM not initialized'}) + + result = chain.invoke({'prompt': prompt}) + parsed = json.loads(result) + + analysis_type = parsed.get('analysis_type') + target_models = parsed.get('target_models', []) + query_params = parsed.get('query_params', {}) + + if not analysis_type or not target_models: + return JsonResponse({'success': False, 'error': 'Incomplete analysis instruction returned by LLM'}) + + orm_results = analyze_models_with_orm(analysis_type, target_models, query_params) + + return JsonResponse({'success': True, 'data': orm_results}) + + except Exception as e: + return JsonResponse({'success': False, 'error': str(e)}) \ No newline at end of file diff --git a/haikalbot/temp.txt b/haikalbot/temp.txt new file mode 100644 index 00000000..ba64182e --- /dev/null +++ b/haikalbot/temp.txt @@ -0,0 +1,80 @@ +from langchain_ollama import OllamaLLM + +from langchain.chains import LLMChain +from langchain.prompts import PromptTemplate +from django.conf import settings +import logging + +logger = logging.getLogger(__name__) + + +def get_ollama_llm(): + """ + Initialize and return an Ollama LLM instance configured for Arabic support. + """ + try: + # Get settings from Django settings or use defaults + base_url = getattr(settings, 'OLLAMA_BASE_URL', 'http://localhost:11434') + model = getattr(settings, 'OLLAMA_MODEL', 'qwen3:8b') + # timeout = getattr(settings, 'OLLAMA_TIMEOUT', 120) + + return OllamaLLM( + base_url=base_url, + model=model, + temperature= 0.2, + top_p= 0.8, + top_k= 40, + num_ctx= 4096, + num_predict= 2048, + stop= ["```", ""], + repeat_penalty= 1.1, + ) + except Exception as e: + logger.error(f"Error initializing Ollama LLM: {str(e)}") + return None + + +def create_prompt_analyzer_chain(language='ar'): + """ + Create a LangChain for analyzing prompts in Arabic or English. + """ + llm = get_ollama_llm() + if not llm: + return None + + # Define the prompt template based on language + if language == 'ar': + template = """ + قم بتحليل الاستعلام التالي وتحديد نوع التحليل المطلوب ونماذج البيانات المستهدفة وأي معلمات استعلام. + + الاستعلام: {prompt} + + قم بتقديم إجابتك بتنسيق JSON كما يلي: + {{ + "analysis_type": "count" أو "relationship" أو "performance" أو "statistics" أو "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {{"field1": "value1", "field2": "value2"}} + }} + """ + else: + template = """ + Analyze the following prompt and determine the type of analysis required, target data models, and any query parameters. + + Prompt: {prompt} + + Provide your answer in JSON format as follows: + { + "analysis_type": "count" or "relationship" or "performance" or "statistics" or "general", + "target_models": ["ModelName1", "ModelName2"], + "query_params": {"field1": "value1", "field2": "value2"} + } + """ + + # Create the prompt template + prompt_template = PromptTemplate( + input_variables=["prompt"], + template=template + ) + + # Create and return the LLM chain + return prompt_template | llm \ No newline at end of file diff --git a/haikalbot/training_prompt.md b/haikalbot/training_prompt.md new file mode 100644 index 00000000..ee381661 --- /dev/null +++ b/haikalbot/training_prompt.md @@ -0,0 +1,161 @@ +# Training Prompt for Django Model Analyst AI Agent + +## Agent Purpose +You are a specialized AI agent designed to analyze Django models and provide insightful information to users. Your primary function is to interpret Django model structures, relationships, and metadata to generate meaningful insights that help developers and stakeholders understand their data models better. + +## Core Capabilities +1. Parse and understand Django model definitions +2. Identify relationships between models (ForeignKey, ManyToMany, OneToOne) +3. Analyze model fields, types, constraints, and metadata +4. Generate statistics and insights about model usage and structure +5. Provide recommendations for model optimization +6. Respond to natural language queries about models +7. Format responses as structured JSON for integration with frontend applications + +## Input Processing +You will receive inputs in the following format: +1. Django model code or references to model files +2. A natural language prompt specifying the type of analysis or insights requested +3. Optional context about the project or specific concerns + +## Output Requirements +Your responses must: +1. Be formatted as valid JSON +2. Include a "status" field indicating success or failure +3. Provide an "insights" array containing the requested analysis +4. Include metadata about the analysis performed +5. Be structured in a way that's easy to parse and display in a frontend + +## Analysis Types +You should be able to perform the following types of analysis: + +### Structural Analysis +- Model count and complexity metrics +- Field type distribution +- Relationship mapping and visualization data +- Inheritance patterns +- Abstract models usage + +### Performance Analysis +- Potential query bottlenecks +- Missing index recommendations +- Relationship optimization suggestions +- N+1 query vulnerability detection + +### Security Analysis +- Sensitive field detection +- Permission model recommendations +- Data exposure risk assessment + +### Data Integrity Analysis +- Constraint analysis +- Validation rule assessment +- Data consistency recommendations + +## Example Interactions + +### Example 1: Basic Model Analysis +**Input Prompt:** +"Analyze the User and Profile models and show me their relationship structure." + +**Expected Response:** +```json +{ + "status": "success", + "request_id": "a1b2c3d4", + "timestamp": "2025-05-25T23:21:56Z", + "insights": [ + { + "type": "relationship_analysis", + "models": ["User", "Profile"], + "relationships": [ + { + "from": "Profile", + "to": "User", + "type": "OneToOne", + "field": "user", + "related_name": "profile", + "on_delete": "CASCADE" + } + ], + "visualization_data": { + "nodes": [...], + "edges": [...] + } + } + ], + "recommendations": [ + "Consider adding an index to Profile.user for faster lookups" + ] +} +``` + +### Example 2: Query Performance Analysis +**Input Prompt:** +"Identify potential performance issues in the Order and OrderItem models." + +**Expected Response:** +```json +{ + "status": "success", + "request_id": "e5f6g7h8", + "timestamp": "2025-05-25T23:22:30Z", + "insights": [ + { + "type": "performance_analysis", + "models": ["Order", "OrderItem"], + "issues": [ + { + "severity": "high", + "model": "OrderItem", + "field": "order", + "issue": "Missing database index on ForeignKey", + "impact": "Slow queries when filtering OrderItems by Order", + "solution": "Add db_index=True to order field" + }, + { + "severity": "medium", + "model": "Order", + "issue": "No select_related in common queries", + "impact": "Potential N+1 query problems", + "solution": "Use select_related when querying Orders with OrderItems" + } + ] + } + ], + "code_suggestions": [ + { + "model": "OrderItem", + "current": "order = models.ForeignKey(Order, on_delete=models.CASCADE)", + "suggested": "order = models.ForeignKey(Order, on_delete=models.CASCADE, db_index=True)" + } + ] +} +``` + +## Limitations and Boundaries +1. You should not modify or execute code unless explicitly requested +2. You should indicate when you need additional information to provide accurate insights +3. You should acknowledge when a requested analysis is beyond your capabilities +4. You should not make assumptions about implementation details not present in the provided models +5. You should clearly distinguish between factual observations and recommendations + +## Learning and Improvement +You should continuously improve your analysis capabilities by: +1. Learning from user feedback +2. Staying updated on Django best practices +3. Expanding your understanding of common model patterns +4. Refining your insight generation to be more relevant and actionable + +## Ethical Considerations +1. Respect data privacy by not suggesting exposing sensitive information +2. Provide balanced recommendations that consider security, performance, and usability +3. Be transparent about the limitations of your analysis +4. Avoid making judgments about the quality of code beyond objective metrics + +## Technical Integration +You will be integrated into a Django application as a service that: +1. Receives requests through a REST API +2. Has access to model definitions through Django's introspection capabilities +3. Returns JSON responses that can be directly used by frontend components +4. Maintains context across multiple related queries when session information is provided diff --git a/haikalbot/training_prompt_arabic.md b/haikalbot/training_prompt_arabic.md new file mode 100644 index 00000000..2d32829b --- /dev/null +++ b/haikalbot/training_prompt_arabic.md @@ -0,0 +1,161 @@ +# تدريب وكيل محلل نماذج Django بالعربية + +## هدف الوكيل +أنت وكيل ذكاء اصطناعي متخصص مصمم لتحليل نماذج Django وتقديم معلومات مفيدة للمستخدمين. وظيفتك الأساسية هي تفسير هياكل نماذج Django والعلاقات والبيانات الوصفية لتوليد رؤى ذات معنى تساعد المطورين وأصحاب المصلحة على فهم نماذج البيانات الخاصة بهم بشكل أفضل. + +## القدرات الأساسية +1. تحليل وفهم تعريفات نماذج Django +2. تحديد العلاقات بين النماذج (ForeignKey, ManyToMany, OneToOne) +3. تحليل حقول النموذج وأنواعها والقيود والبيانات الوصفية +4. توليد إحصائيات ورؤى حول استخدام النموذج وهيكله +5. تقديم توصيات لتحسين النموذج +6. الاستجابة للاستعلامات باللغة الطبيعية حول النماذج +7. تنسيق الردود كـ JSON منظم للتكامل مع تطبيقات الواجهة الأمامية + +## معالجة المدخلات +ستتلقى المدخلات بالتنسيق التالي: +1. كود نموذج Django أو مراجع لملفات النموذج +2. استعلام باللغة الطبيعية يحدد نوع التحليل أو الرؤى المطلوبة +3. سياق اختياري حول المشروع أو مخاوف محددة + +## متطلبات المخرجات +يجب أن تكون ردودك: +1. منسقة كـ JSON صالح +2. تتضمن حقل "status" يشير إلى النجاح أو الفشل +3. توفر مصفوفة "insights" تحتوي على التحليل المطلوب +4. تتضمن بيانات وصفية حول التحليل الذي تم إجراؤه +5. منظمة بطريقة يسهل تحليلها وعرضها في واجهة أمامية + +## أنواع التحليل +يجب أن تكون قادرًا على إجراء الأنواع التالية من التحليل: + +### التحليل الهيكلي +- عدد النماذج ومقاييس التعقيد +- توزيع أنواع الحقول +- رسم خرائط العلاقات وبيانات التصور +- أنماط الوراثة +- استخدام النماذج المجردة + +### تحليل الأداء +- اختناقات الاستعلام المحتملة +- توصيات الفهرس المفقود +- اقتراحات تحسين العلاقة +- كشف ضعف استعلام N+1 + +### تحليل الأمان +- كشف الحقول الحساسة +- توصيات نموذج الإذن +- تقييم مخاطر التعرض للبيانات + +### تحليل سلامة البيانات +- تحليل القيود +- تقييم قواعد التحقق +- توصيات اتساق البيانات + +## أمثلة على التفاعلات + +### مثال 1: تحليل النموذج الأساسي +**استعلام المدخلات:** +"قم بتحليل نماذج المستخدم والملف الشخصي وأظهر لي هيكل العلاقة بينهما." + +**الرد المتوقع:** +```json +{ + "status": "نجاح", + "request_id": "a1b2c3d4", + "timestamp": "2025-05-25T23:21:56Z", + "insights": [ + { + "type": "تحليل_العلاقات", + "models": ["User", "Profile"], + "relationships": [ + { + "from": "Profile", + "to": "User", + "type": "OneToOne", + "field": "user", + "related_name": "profile", + "on_delete": "CASCADE" + } + ], + "visualization_data": { + "nodes": [...], + "edges": [...] + } + } + ], + "recommendations": [ + "فكر في إضافة فهرس إلى Profile.user للبحث الأسرع" + ] +} +``` + +### مثال 2: تحليل أداء الاستعلام +**استعلام المدخلات:** +"حدد مشاكل الأداء المحتملة في نماذج الطلب وعناصر الطلب." + +**الرد المتوقع:** +```json +{ + "status": "نجاح", + "request_id": "e5f6g7h8", + "timestamp": "2025-05-25T23:22:30Z", + "insights": [ + { + "type": "تحليل_الأداء", + "models": ["Order", "OrderItem"], + "issues": [ + { + "severity": "عالية", + "model": "OrderItem", + "field": "order", + "issue": "فهرس قاعدة بيانات مفقود على ForeignKey", + "impact": "استعلامات بطيئة عند تصفية OrderItems حسب Order", + "solution": "أضف db_index=True إلى حقل order" + }, + { + "severity": "متوسطة", + "model": "Order", + "issue": "لا يوجد select_related في الاستعلامات الشائعة", + "impact": "مشاكل استعلام N+1 محتملة", + "solution": "استخدم select_related عند الاستعلام عن Orders مع OrderItems" + } + ] + } + ], + "code_suggestions": [ + { + "model": "OrderItem", + "current": "order = models.ForeignKey(Order, on_delete=models.CASCADE)", + "suggested": "order = models.ForeignKey(Order, on_delete=models.CASCADE, db_index=True)" + } + ] +} +``` + +## القيود والحدود +1. لا يجب عليك تعديل أو تنفيذ التعليمات البرمجية ما لم يُطلب منك ذلك صراحةً +2. يجب أن تشير عندما تحتاج إلى معلومات إضافية لتقديم رؤى دقيقة +3. يجب أن تعترف عندما يكون التحليل المطلوب خارج قدراتك +4. لا يجب أن تفترض تفاصيل التنفيذ غير الموجودة في النماذج المقدمة +5. يجب أن تميز بوضوح بين الملاحظات الواقعية والتوصيات + +## التعلم والتحسين +يجب أن تحسن باستمرار قدرات التحليل الخاصة بك من خلال: +1. التعلم من تعليقات المستخدم +2. البقاء على اطلاع بأفضل ممارسات Django +3. توسيع فهمك لأنماط النموذج الشائعة +4. تحسين توليد الرؤى لتكون أكثر صلة وقابلية للتنفيذ + +## الاعتبارات الأخلاقية +1. احترام خصوصية البيانات من خلال عدم اقتراح كشف المعلومات الحساسة +2. تقديم توصيات متوازنة تراعي الأمان والأداء وسهولة الاستخدام +3. الشفافية بشأن حدود تحليلك +4. تجنب إصدار أحكام حول جودة الكود بما يتجاوز المقاييس الموضوعية + +## التكامل التقني +سيتم دمجك في تطبيق Django كخدمة: +1. تتلقى الطلبات من خلال واجهة برمجة تطبيقات REST +2. لديها إمكانية الوصول إلى تعريفات النموذج من خلال قدرات التفتيش الذاتي لـ Django +3. تعيد استجابات JSON التي يمكن استخدامها مباشرة بواسطة مكونات الواجهة الأمامية +4. تحافظ على السياق عبر استعلامات متعددة ذات صلة عند توفير معلومات الجلسة diff --git a/haikalbot/urls.py b/haikalbot/urls.py index 71915fe7..ddd4713a 100644 --- a/haikalbot/urls.py +++ b/haikalbot/urls.py @@ -1,7 +1,8 @@ from django.urls import path from . import views +app_name = "haikalbot" urlpatterns = [ - path("", views.ChatbotView.as_view(), name="chatbot"), + path("analyze/", views.ModelAnalystView.as_view(), name="haikalbot"), ] diff --git a/haikalbot/utils/response_formatter.py b/haikalbot/utils/response_formatter.py new file mode 100644 index 00000000..ea9e6ea1 --- /dev/null +++ b/haikalbot/utils/response_formatter.py @@ -0,0 +1,119 @@ +def format_response(prompt, language, request_id, timestamp): + """ + Format a standardized response structure based on language. + + This utility creates a consistent response structure with the appropriate + keys based on the specified language. + + :param prompt: The original user prompt + :type prompt: str + :param language: Language code ('en' or 'ar') + :type language: str + :param request_id: Unique identifier for the request + :type request_id: str + :param timestamp: ISO-formatted timestamp + :type timestamp: str + :return: Formatted response structure + :rtype: dict + """ + if language == 'ar': + return { + 'حالة': "نجاح", + 'معرف_الطلب': request_id, + 'الطابع_الزمني': timestamp, + 'الاستعلام': prompt, + 'التحليلات': [] + } + else: + return { + 'status': "success", + 'request_id': request_id, + 'timestamp': timestamp, + 'prompt': prompt, + 'insights': [] + } + + +def format_error_response(message, status_code, language='en'): + """ + Format a standardized error response. + + :param message: Error message + :type message: str + :param status_code: HTTP status code + :type status_code: int + :param language: Language code ('en' or 'ar') + :type language: str + :return: Formatted error response + :rtype: dict + """ + if language == 'ar': + return { + 'حالة': "خطأ", + 'رسالة': message, + 'رمز_الحالة': status_code + } + else: + return { + 'status': "error", + 'message': message, + 'status_code': status_code + } + + +def format_insights_for_display(insights, language='en'): + """ + Format insights for human-readable display. + + :param insights: Raw insights data + :type insights: dict + :param language: Language code ('en' or 'ar') + :type language: str + :return: Human-readable formatted insights + :rtype: str + """ + formatted_text = "" + + # Determine keys based on language + insights_key = 'التحليلات' if language == 'ar' else 'insights' + recs_key = 'التوصيات' if language == 'ar' else 'recommendations' + + # Format insights + if insights_key in insights and insights[insights_key]: + header = "## نتائج التحليل\n\n" if language == 'ar' else "## Analysis Results\n\n" + formatted_text += header + + for insight in insights[insights_key]: + if isinstance(insight, dict): + # Add insight type as header + if 'type' in insight or 'نوع' in insight: + type_key = 'نوع' if language == 'ar' else 'type' + insight_type = insight.get(type_key, insight.get('type', insight.get('نوع', ''))) + formatted_text += f"### {insight_type}\n\n" + + # Format results if present + results_key = 'النتائج' if language == 'ar' else 'results' + if results_key in insight: + for result in insight[results_key]: + model_key = 'النموذج' if language == 'ar' else 'model' + error_key = 'خطأ' if language == 'ar' else 'error' + count_key = 'العدد' if language == 'ar' else 'count' + + model_name = result.get(model_key, result.get('model', '')) + + if error_key in result: + formatted_text += f"- **{model_name}**: {result[error_key]}\n" + elif count_key in result: + formatted_text += f"- **{model_name}**: {result[count_key]}\n" + + formatted_text += "\n" + + # Format recommendations + if recs_key in insights and insights[recs_key]: + header = "## التوصيات\n\n" if language == 'ar' else "## Recommendations\n\n" + formatted_text += header + + for rec in insights[recs_key]: + formatted_text += f"- {rec}\n" + + return formatted_text diff --git a/haikalbot/views.py b/haikalbot/views.py index 9420f4a2..b685bbf8 100644 --- a/haikalbot/views.py +++ b/haikalbot/views.py @@ -1,38 +1,253 @@ from django.contrib.auth.mixins import LoginRequiredMixin -from django.views import View from django.shortcuts import render +from django.views.decorators.csrf import csrf_exempt +from django.utils.decorators import method_decorator +from django.views import View from django.http import JsonResponse -from .chatbot_logic import get_gpt4_response +from django.apps import apps +from django.db import models +from django.conf import settings +from django.utils import timezone +from datetime import timedelta import json +import hashlib +import logging +import uuid +import re -class ChatbotView(LoginRequiredMixin, View): +from inventory import models as inventory_models +from inventory.utils import get_user_type +from .models import AnalysisCache +from .services.llm_service import get_llm_chain +from .services.analysis_service import ( + generate_model_insight, + generate_count_insight, + generate_relationship_insight, + generate_performance_insight, + generate_statistics_insight, + generate_recommendations +) +from .services.cache_service import CacheService +from .utils.response_formatter import format_response + +logger = logging.getLogger(__name__) + + +@method_decorator(csrf_exempt, name='dispatch') +class ModelAnalystView(View): """ - Represents a view for handling chatbot interactions. + View for handling model analysis requests and rendering the chatbot interface. - This class handles GET and POST requests for a chatbot interface. It leverages - `LoginRequiredMixin` to ensure that only authenticated users can access it. On GET - requests, it renders the chatbot interface, while on POST requests, it interacts - with a chatbot backend to process user messages and return responses. + This view provides both GET and POST methods: + - GET: Renders the chatbot interface + - POST: Processes analysis requests and returns JSON responses - :ivar request: The HTTP request object, providing metadata about the - current session and user. - :type request: HttpRequest + The view includes caching, permission checking, and multilingual support. """ - def get(self, request): - return render(request, "haikalbot/chatbot.html") + # Configuration settings (can be moved to Django settings) + CACHE_DURATION = getattr(settings, 'ANALYSIS_CACHE_DURATION', 3600) + DEFAULT_LANGUAGE = getattr(settings, 'DEFAULT_LANGUAGE', 'en') - def post(self, request): - dealer = request.user.dealer + def get(self, request, *args, **kwargs): + """ + Render the chatbot interface. + :param request: The HTTP request + :return: Rendered chatbot.html template + """ + context = { + 'dark_mode': request.session.get('dark_mode', False) + } + return render(request, "haikalbot/chatbot.html", context) + + def post(self, request, *args, **kwargs): + """ + Process analysis requests and return JSON responses. + + :param request: The HTTP request containing the prompt + :return: JsonResponse with analysis results + """ try: + # Parse request data data = json.loads(request.body) - user_message = data.get("message", "").strip() + prompt = data.get('prompt') + language = data.get('language', self.DEFAULT_LANGUAGE) + dealer = get_user_type(request) - if not user_message: - return JsonResponse({"error": "Message cannot be empty."}, status=400) + # Validate request + if not prompt: + error_msg = "الاستعلام مطلوب" if language == 'ar' else "Prompt is required" + return self._error_response(error_msg, 400) - chatbot_response = get_gpt4_response(user_message, dealer) + if not self._check_permissions(dealer.id): + error_msg = "تم رفض الإذن" if language == 'ar' else "Permission denied" + return self._error_response(error_msg, 403) + + # Check cache + cache_service = CacheService() + prompt_hash = cache_service.generate_hash(prompt, dealer.id, language) + cached_result = cache_service.get_cached_result(prompt_hash, request.user, dealer.id) + + if cached_result: + return JsonResponse(cached_result) + + # Process prompt and generate insights + insights = self._process_prompt(prompt, dealer, language) + + # Cache results + cache_service.cache_result( + prompt_hash, + insights, + request.user, + dealer.id, + self.CACHE_DURATION + ) + + return JsonResponse(insights) - return JsonResponse({"response": chatbot_response}, status=200) except json.JSONDecodeError: - return JsonResponse({"error": "Invalid JSON format."}, status=400) \ No newline at end of file + error_msg = "بيانات JSON غير صالحة في نص الطلب" if language == 'ar' else "Invalid JSON in request body" + return self._error_response(error_msg, 400) + except Exception as e: + logger.exception("Error processing model analysis request") + error_msg = f"حدث خطأ: {str(e)}" if language == 'ar' else f"An error occurred: {str(e)}" + return self._error_response(error_msg, 500) + + def _error_response(self, message, status): + """ + Create a standardized error response. + + :param message: Error message + :param status: HTTP status code + :return: JsonResponse with error details + """ + return JsonResponse({"status": "error", "message": message}, status=status) + + def _check_permissions(self, dealer_id): + """ + Check if the dealer has permissions to access the analysis. + + :param dealer_id: ID of the dealer + :return: True if dealer has permissions, False otherwise + """ + try: + return inventory_models.Dealer.objects.filter(id=dealer_id).exists() + except Exception: + logger.exception("Error checking permissions") + return False + + def _process_prompt(self, prompt, dealer, language): + """ + Process the prompt and generate insights. + + :param prompt: User's prompt text + :param dealer: Dealer object + :param language: Language code (e.g., 'en', 'ar') + :return: Dictionary with analysis results + """ + # Initialize response structure + response = format_response( + prompt=prompt, + language=language, + request_id=str(uuid.uuid4()), + timestamp=timezone.now().isoformat() + ) + + # Get LLM chain for prompt analysis + chain = get_llm_chain(language=language) + + # Parse prompt using LLM + if chain: + try: + result = chain.invoke({"prompt": prompt}) + json_match = re.search(r'({.*})', result.replace('\n', ' '), re.DOTALL) + result = json.loads(json_match.group(1)) if json_match else {} + except Exception as e: + logger.error(f"LLM error fallback: {e}") + result = {} + else: + result = {} + + # Extract analysis parameters + analysis_type = result.get('analysis_type', 'general') + target_models = result.get('target_models', []) + query_params = result.get('query_params', {}) + + # Get models to analyze + all_models = list(apps.get_models()) + models_to_analyze = self._filter_models(all_models, target_models) + if dealer: + models_to_analyze = self._filter_by_dealer(models_to_analyze, dealer.id) + + # Select analysis method based on type + analysis_method = { + 'count': generate_count_insight, + 'relationship': generate_relationship_insight, + 'performance': generate_performance_insight, + 'statistics': generate_statistics_insight + }.get(analysis_type, self._generate_model_insight_all) + + # Generate insights + insights = analysis_method(models_to_analyze, query_params, dealer.id if dealer else None, language) + + # Add insights to response + insights_key = "التحليلات" if language == 'ar' else "insights" + if isinstance(insights, list): + response[insights_key].extend(insights) + else: + response[insights_key].append(insights) + + # Generate recommendations + recommendations = generate_recommendations(models_to_analyze, analysis_type, language) + if recommendations: + recs_key = "التوصيات" if language == 'ar' else "recommendations" + response[recs_key] = recommendations + + # Add plain text summary for response + summary_lines = [] + for insight in response[insights_key]: + if isinstance(insight, dict): + summary_lines.append(insight.get('type', 'Insight')) + else: + summary_lines.append(str(insight)) + + response['response'] = "\n".join(summary_lines) + + return response + + def _filter_models(self, all_models, target_models): + """ + Filter models based on target model names. + + :param all_models: List of all available models + :param target_models: List of target model names + :return: Filtered list of models + """ + if not target_models: + return all_models + return [m for m in all_models if m.__name__ in target_models or + m.__name__.lower() in [t.lower() for t in target_models]] + + def _filter_by_dealer(self, models, dealer_id): + """ + Filter models that are relevant to the dealer. + + :param models: List of models + :param dealer_id: ID of the dealer + :return: Filtered list of models + """ + dealer_models = [m for m in models if any(f.name in ('dealer', 'dealer_id') + for f in m._meta.fields)] + return dealer_models if dealer_models else models + + def _generate_model_insight_all(self, models, query_params, dealer_id, language): + """ + Generate insights for all models. + + :param models: List of models + :param query_params: Query parameters + :param dealer_id: ID of the dealer + :param language: Language code + :return: List of insights + """ + return [generate_model_insight(m, dealer_id, language) for m in models] diff --git a/install_marwan.sh b/install_marwan.sh new file mode 100755 index 00000000..6c2ae0be --- /dev/null +++ b/install_marwan.sh @@ -0,0 +1,8 @@ +#!/bin/bash + + +#sudo brew update && sudo brew install libgl1 libglib2.0-dev libzbar0 cmake build-essential xmlsec1 libxmlsec1-dev pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl libssl-dev -y +pip install --upgrade pip +pip install -r requirements.txt +./apply_initial_migrations.sh +./load_initial_data_marwan.sh \ No newline at end of file diff --git a/inventory/migrations/0001_initial.py b/inventory/migrations/0001_initial.py index a19bf46f..cf6476e4 100644 --- a/inventory/migrations/0001_initial.py +++ b/inventory/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.7 on 2025-05-19 11:40 +# Generated by Django 5.2.1 on 2025-05-25 23:01 import datetime import django.core.validators @@ -21,32 +21,11 @@ class Migration(migrations.Migration): ('appointment', '0001_initial'), ('auth', '0012_alter_user_first_name_max_length'), ('contenttypes', '0002_remove_content_type_name'), - ('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'), + ('django_ledger', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ - migrations.CreateModel( - name='Car', - fields=[ - ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True, verbose_name='Primary Key')), - ('slug', models.SlugField(blank=True, help_text='Slug for the object. If not provided, it will be generated automatically.', null=True, unique=True, verbose_name='Slug')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), - ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), - ('vin', models.CharField(max_length=17, unique=True, verbose_name='VIN')), - ('year', models.IntegerField(verbose_name='Year')), - ('status', models.CharField(choices=[('available', 'Available'), ('sold', 'Sold'), ('hold', 'Hold'), ('damaged', 'Damaged'), ('reserved', 'Reserved'), ('transfer', 'Transfer')], default='available', max_length=10, verbose_name='Status')), - ('stock_type', models.CharField(choices=[('new', 'New'), ('used', 'Used')], default='new', max_length=10, verbose_name='Stock Type')), - ('remarks', models.TextField(blank=True, null=True, verbose_name='Remarks')), - ('mileage', models.IntegerField(blank=True, null=True, verbose_name='Mileage')), - ('receiving_date', models.DateTimeField(verbose_name='Receiving Date')), - ('hash', models.CharField(blank=True, max_length=64, null=True, verbose_name='Hash')), - ], - options={ - 'verbose_name': 'Car', - 'verbose_name_plural': 'Cars', - }, - ), migrations.CreateModel( name='CarEquipment', fields=[ @@ -146,6 +125,29 @@ class Migration(migrations.Migration): }, bases=(models.Model, inventory.mixins.LocalizedNameMixin), ), + migrations.CreateModel( + name='Car', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True, verbose_name='Primary Key')), + ('slug', models.SlugField(blank=True, help_text='Slug for the object. If not provided, it will be generated automatically.', null=True, unique=True, verbose_name='Slug')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), + ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), + ('vin', models.CharField(max_length=17, unique=True, verbose_name='VIN')), + ('year', models.IntegerField(verbose_name='Year')), + ('status', models.CharField(choices=[('available', 'Available'), ('sold', 'Sold'), ('hold', 'Hold'), ('damaged', 'Damaged'), ('reserved', 'Reserved'), ('transfer', 'Transfer')], default='available', max_length=10, verbose_name='Status')), + ('stock_type', models.CharField(choices=[('new', 'New'), ('used', 'Used')], default='new', max_length=10, verbose_name='Stock Type')), + ('remarks', models.TextField(blank=True, null=True, verbose_name='Remarks')), + ('mileage', models.IntegerField(blank=True, null=True, verbose_name='Mileage')), + ('receiving_date', models.DateTimeField(verbose_name='Receiving Date')), + ('hash', models.CharField(blank=True, max_length=64, null=True, verbose_name='Hash')), + ('item_model', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='django_ledger.itemmodel', verbose_name='Item Model')), + ('id_car_make', models.ForeignKey(blank=True, db_column='id_car_make', null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmake', verbose_name='Make')), + ], + options={ + 'verbose_name': 'Car', + 'verbose_name_plural': 'Cars', + }, + ), migrations.CreateModel( name='CarFinance', fields=[ @@ -161,11 +163,6 @@ class Migration(migrations.Migration): 'verbose_name_plural': 'Car Financial Details', }, ), - migrations.AddField( - model_name='car', - name='id_car_make', - field=models.ForeignKey(blank=True, db_column='id_car_make', null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='inventory.carmake', verbose_name='Make'), - ), migrations.CreateModel( name='CarModel', fields=[ @@ -488,6 +485,7 @@ class Migration(migrations.Migration): ('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')), ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')), ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, related_name='notes_created', to=settings.AUTH_USER_MODEL)), + ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='inventory.dealer')), ], options={ 'verbose_name': 'Note', @@ -524,6 +522,7 @@ class Migration(migrations.Migration): ('active', models.BooleanField(default=True, verbose_name='Active')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')), + ('slug', models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True)), ('customer_model', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='django_ledger.customermodel')), ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='organizations', to='inventory.dealer')), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='organization_profile', to=settings.AUTH_USER_MODEL)), @@ -555,6 +554,7 @@ class Migration(migrations.Migration): ('next_action_date', models.DateTimeField(blank=True, null=True, verbose_name='Next Action Date')), ('is_converted', models.BooleanField(default=False)), ('converted_at', models.DateTimeField(blank=True, null=True)), + ('salary', models.PositiveIntegerField(blank=True, null=True, verbose_name='Salary')), ('created', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='Created')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')), ('slug', models.SlugField(blank=True, null=True, unique=True)), @@ -645,8 +645,10 @@ class Migration(migrations.Migration): ('arabic_name', models.CharField(max_length=255, verbose_name='Arabic Name')), ('phone_number', phonenumber_field.modelfields.PhoneNumberField(max_length=128, region='SA', verbose_name='Phone Number')), ('staff_type', models.CharField(choices=[('inventory', 'Inventory'), ('accountant', 'Accountant'), ('sales', 'Sales')], max_length=255, verbose_name='Staff Type')), + ('active', models.BooleanField(default=True, verbose_name='Active')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')), + ('slug', models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True)), ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='inventory.dealer')), ('staff_member', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='staff', to='appointment.staffmember')), ], @@ -670,8 +672,9 @@ class Migration(migrations.Migration): ('closing_date', models.DateField(blank=True, null=True, verbose_name='Closing Date')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Created')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Updated')), + ('slug', models.SlugField(blank=True, help_text='Unique slug for the opportunity.', null=True, unique=True, verbose_name='Slug')), ('car', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.car', verbose_name='Car')), - ('customer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to='django_ledger.customermodel')), + ('customer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to='inventory.customer')), ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to='inventory.dealer')), ('estimate', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='opportunity', to='django_ledger.estimatemodel')), ('lead', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunity', to='inventory.lead')), @@ -750,6 +753,7 @@ class Migration(migrations.Migration): ('email', models.EmailField(max_length=255, verbose_name='Email Address')), ('address', models.CharField(max_length=200, verbose_name='Address')), ('logo', models.ImageField(blank=True, null=True, upload_to='logos/vendors', verbose_name='Logo')), + ('active', models.BooleanField(default=True, verbose_name='Active')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('slug', models.SlugField(blank=True, max_length=255, null=True, unique=True, verbose_name='Slug')), ('dealer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vendors', to='inventory.dealer')), diff --git a/inventory/migrations/0012_carfinance_is_sold.py b/inventory/migrations/0002_carfinance_is_sold.py similarity index 86% rename from inventory/migrations/0012_carfinance_is_sold.py rename to inventory/migrations/0002_carfinance_is_sold.py index 24d73328..63ced651 100644 --- a/inventory/migrations/0012_carfinance_is_sold.py +++ b/inventory/migrations/0002_carfinance_is_sold.py @@ -6,7 +6,7 @@ from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('inventory', '0011_alter_car_item_model'), + ('inventory', '0001_initial'), ] operations = [ diff --git a/inventory/migrations/0002_vendor_active.py b/inventory/migrations/0002_vendor_active.py deleted file mode 100644 index 2118e3e2..00000000 --- a/inventory/migrations/0002_vendor_active.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-20 12:00 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='vendor', - name='active', - field=models.BooleanField(default=True, verbose_name='Active'), - ), - ] diff --git a/inventory/migrations/0003_alter_opportunity_customer.py b/inventory/migrations/0003_alter_opportunity_customer.py deleted file mode 100644 index 0e399ba7..00000000 --- a/inventory/migrations/0003_alter_opportunity_customer.py +++ /dev/null @@ -1,19 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-20 12:45 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0002_vendor_active'), - ] - - operations = [ - migrations.AlterField( - model_name='opportunity', - name='customer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='opportunities', to='inventory.customer'), - ), - ] diff --git a/inventory/migrations/0004_opportunity_slug.py b/inventory/migrations/0004_opportunity_slug.py deleted file mode 100644 index 69b4d398..00000000 --- a/inventory/migrations/0004_opportunity_slug.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-20 12:49 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0003_alter_opportunity_customer'), - ] - - operations = [ - migrations.AddField( - model_name='opportunity', - name='slug', - field=models.SlugField(blank=True, help_text='Unique slug for the opportunity.', null=True, unique=True, verbose_name='Slug'), - ), - ] diff --git a/inventory/migrations/0005_notes_dealer.py b/inventory/migrations/0005_notes_dealer.py deleted file mode 100644 index 63b30675..00000000 --- a/inventory/migrations/0005_notes_dealer.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-20 13:45 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0004_opportunity_slug'), - ] - - operations = [ - migrations.AddField( - model_name='notes', - name='dealer', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='notes', to='inventory.dealer'), - preserve_default=False, - ), - ] diff --git a/inventory/migrations/0006_organization_slug.py b/inventory/migrations/0006_organization_slug.py deleted file mode 100644 index 91b349cf..00000000 --- a/inventory/migrations/0006_organization_slug.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-21 10:54 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0005_notes_dealer'), - ] - - operations = [ - migrations.AddField( - model_name='organization', - name='slug', - field=models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True), - ), - ] diff --git a/inventory/migrations/0007_staff_active_staff_slug.py b/inventory/migrations/0007_staff_active_staff_slug.py deleted file mode 100644 index 704dddbf..00000000 --- a/inventory/migrations/0007_staff_active_staff_slug.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-21 13:32 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0006_organization_slug'), - ] - - operations = [ - migrations.AddField( - model_name='staff', - name='active', - field=models.BooleanField(default=True, verbose_name='Active'), - ), - migrations.AddField( - model_name='staff', - name='slug', - field=models.SlugField(blank=True, editable=False, max_length=255, null=True, unique=True), - ), - ] diff --git a/inventory/migrations/0008_lead_salary.py b/inventory/migrations/0008_lead_salary.py deleted file mode 100644 index ea22048f..00000000 --- a/inventory/migrations/0008_lead_salary.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-21 15:26 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('inventory', '0007_staff_active_staff_slug'), - ] - - operations = [ - migrations.AddField( - model_name='lead', - name='salary', - field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Salary'), - ), - ] diff --git a/inventory/migrations/0009_car_item_model.py b/inventory/migrations/0009_car_item_model.py deleted file mode 100644 index 58d54a1f..00000000 --- a/inventory/migrations/0009_car_item_model.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-25 11:41 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'), - ('inventory', '0008_lead_salary'), - ] - - operations = [ - migrations.AddField( - model_name='car', - name='item_model', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='cars', to='django_ledger.itemmodel', verbose_name='Item Model'), - ), - ] diff --git a/inventory/migrations/0010_alter_car_item_model.py b/inventory/migrations/0010_alter_car_item_model.py deleted file mode 100644 index af7fbfd8..00000000 --- a/inventory/migrations/0010_alter_car_item_model.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-25 11:43 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'), - ('inventory', '0009_car_item_model'), - ] - - operations = [ - migrations.AlterField( - model_name='car', - name='item_model', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='cars', to='django_ledger.itemmodel', verbose_name='Item Model'), - ), - ] diff --git a/inventory/migrations/0011_alter_car_item_model.py b/inventory/migrations/0011_alter_car_item_model.py deleted file mode 100644 index 6a077ec0..00000000 --- a/inventory/migrations/0011_alter_car_item_model.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 5.1.7 on 2025-05-25 11:44 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('django_ledger', '0021_alter_bankaccountmodel_account_model_and_more'), - ('inventory', '0010_alter_car_item_model'), - ] - - operations = [ - migrations.AlterField( - model_name='car', - name='item_model', - field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='django_ledger.itemmodel', verbose_name='Item Model'), - ), - ] diff --git a/inventory/signals.py b/inventory/signals.py index 76a98af7..24a28a6a 100644 --- a/inventory/signals.py +++ b/inventory/signals.py @@ -404,7 +404,7 @@ def create_item_service(sender, instance, created, **kwargs): if created: entity = instance.dealer.entity uom = entity.get_uom_all().get(unit_abbr=instance.uom) - cogs = entity.get_all_accounts().get(role=roles.COGS) + cogs = entity.get_all_accounts().filter(role=roles.COGS,active=True,role_default=True).first() service_model = ItemModel.objects.create( name=instance.name, diff --git a/inventory/urls.py b/inventory/urls.py index 9824c840..0adbc6c5 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -45,6 +45,7 @@ urlpatterns = [ # Tasks path('tasks/', views.task_list, name='task_list'), + path('legal/', views.terms_and_privacy, name='terms_and_privacy'), # path('tasks//detail/', views.task_detail, name='task_detail'), # Dashboards # path("user//settings/", views.UserSettingsView.as_view(), name="user_settings"), diff --git a/inventory/views.py b/inventory/views.py index 37f78936..00c71a87 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -510,6 +510,10 @@ class SalesDashboard(LoginRequiredMixin, TemplateView): return context +def terms_and_privacy(request): + return render(request, 'terms_and_privacy.html') + + class WelcomeView(TemplateView): """ Handles the rendering and context data for the Welcome view. diff --git a/load_initial_data_marwan.sh b/load_initial_data_marwan.sh new file mode 100755 index 00000000..d1d35bcd --- /dev/null +++ b/load_initial_data_marwan.sh @@ -0,0 +1,46 @@ +#!/bin/bash +echo "Loading initial data" + +echo "Loading carmake" +python manage.py loaddata carmake_with_slugs.json + +echo "Loading carmodel" +python manage.py loaddata carmodel_with_slugs.json + +echo "Loading carserie" +python manage.py loaddata carserie_with_slugs.json + +echo "Loading cartrim" +python manage.py loaddata cartrim_with_slugs.json + +echo "Loading carequipment" +python manage.py loaddata carequipment_with_slugs.json + +echo "Loading carspecification" +python manage.py loaddata carspecification.json + +echo "Loading carspecificationvalue" +python manage.py loaddata carspecificationvalue.json + +echo "Loading caroption" +python manage.py loaddata caroption_with_slugs.json + +echo "Loading caroptionvalue" +python manage.py loaddata caroptionvalue.json + + +echo "Populating colors" +python manage.py populate_colors + +echo "Populating Plans" +python manage.py loaddata plan.json +python manage.py loaddata pricing.json +python manage.py loaddata planpricing.json +python manage.py loaddata quota.json +python manage.py loaddata planquota.json + +python manage.py set_vat + +python manage.py initial_services_offered + +echo "Done" \ No newline at end of file diff --git a/locale/ar/LC_MESSAGES/django.mo b/locale/ar/LC_MESSAGES/django.mo index adfbd03a..902a838e 100644 Binary files a/locale/ar/LC_MESSAGES/django.mo and b/locale/ar/LC_MESSAGES/django.mo differ diff --git a/locale/ar/LC_MESSAGES/django.po b/locale/ar/LC_MESSAGES/django.po index e5f314c8..210f2d5f 100644 --- a/locale/ar/LC_MESSAGES/django.po +++ b/locale/ar/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-05-07 15:44+0300\n" +"POT-Creation-Date: 2025-05-26 15:53+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -19,14 +19,14 @@ msgstr "" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: api/models.py:6 inventory/models.py:373 inventory/tables.py:51 -#: templates/inventory/car_detail.html:59 templates/inventory/car_form.html:42 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:31 -#: templates/inventory/car_inventory.html:53 -#: templates/inventory/car_list.html:67 templates/inventory/car_list.html:69 -#: templates/inventory/car_list_view.html:108 -#: templates/inventory/cars_list_api.html:31 -#: templates/inventory/transfer_details.html:69 +#: api/models.py:6 inventory/models.py:468 inventory/tables.py:51 +#: templates/inventory/car_detail.html:76 templates/inventory/car_form.html:48 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:30 +#: templates/inventory/car_inventory.html:65 +#: templates/inventory/car_list.html:71 templates/inventory/car_list.html:77 +#: templates/inventory/car_list_view.html:162 +#: templates/inventory/cars_list_api.html:32 +#: templates/inventory/transfer_details.html:87 #: templates/sales/estimates/estimate_detail.html:194 #: templates/sales/estimates/sale_order_form.html:122 #: templates/sales/estimates/sale_order_preview.html:178 @@ -35,7 +35,15 @@ msgstr "" msgid "VIN" msgstr "رقم الهيكل" -#: car_inventory/settings.py:169 car_inventory/settings.py:334 +#: api/views.py:146 inventory/views.py:654 +msgid "Invalid VIN number provided" +msgstr "تم تقديم رقم تعريف مركبة (VIN) غير صالح" + +#: api/views.py:154 +msgid "VIN not found in any source" +msgstr "لم يتم العثور على رقم الهيكل (VIN) في أي مصدر" + +#: car_inventory/settings.py:170 car_inventory/settings.py:334 msgid "SAR" msgstr "ريال" @@ -48,25 +56,32 @@ msgstr "الإنجليزية" msgid "Arabic" msgstr "العربية" -#: car_inventory/settings.py:356 templates/header.html:342 +#: car_inventory/settings.py:356 templates/header.html:358 #: templates/welcome-temp.html:57 templates/welcome_header.html:7 msgid "Haikal" msgstr "هيكل" -#: inventory/forms.py:110 inventory/forms.py:1596 inventory/models.py:975 -#: inventory/models.py:1005 inventory/models.py:1058 inventory/models.py:1158 -#: inventory/models.py:1260 inventory/models.py:1408 inventory/models.py:1543 +#: inventory/forms.py:105 inventory/forms.py:1631 inventory/models.py:1108 +#: inventory/models.py:1137 inventory/models.py:1198 inventory/models.py:1324 +#: inventory/models.py:1453 inventory/models.py:1646 inventory/models.py:1809 #: templates/account/login.html:29 templates/account/login.html:31 +#: templates/admin_management/user_management.html:21 +#: templates/admin_management/user_management.html:85 +#: templates/admin_management/user_management.html:149 +#: templates/admin_management/user_management.html:213 #: templates/administration/display_appointment.html:49 #: templates/administration/manage_staff_personal_info.html:29 #: templates/administration/staff_list.html:35 #: templates/administration/user_profile.html:25 #: templates/appointment/appointment_client_information.html:45 -#: templates/crm/leads/lead_detail.html:82 -#: templates/crm/opportunities/opportunity_detail.html:200 -#: templates/customers/view_customer.html:74 -#: templates/dealers/dealer_detail.html:78 -#: templates/groups/group_detail.html:61 templates/pricing_page.html:187 +#: templates/components/activity_modal.html:18 +#: templates/crm/leads/lead_detail.html:72 +#: templates/crm/leads/lead_detail.html:163 +#: templates/crm/leads/lead_list.html:39 +#: templates/crm/opportunities/opportunity_detail.html:202 +#: templates/customers/view_customer.html:78 +#: templates/dealers/dealer_detail.html:84 +#: templates/groups/group_detail.html:61 templates/pricing_page.html:186 #: templates/sales/estimates/estimate_detail.html:158 #: templates/sales/estimates/sale_order_form.html:56 #: templates/sales/estimates/sale_order_preview.html:168 @@ -79,112 +94,115 @@ msgstr "هيكل" msgid "Email" msgstr "البريد الإلكتروني" -#: inventory/forms.py:115 +#: inventory/forms.py:110 msgid "Services Offered" msgstr "الخدمات المقدمة" -#: inventory/forms.py:123 inventory/forms.py:126 inventory/forms.py:158 -#: inventory/forms.py:173 inventory/forms.py:261 inventory/forms.py:509 -#: inventory/forms.py:596 inventory/forms.py:816 inventory/forms.py:1013 -#: inventory/forms.py:1602 inventory/models.py:822 inventory/models.py:909 -#: inventory/models.py:1063 inventory/models.py:1159 inventory/models.py:1241 -#: inventory/models.py:1261 inventory/models.py:1604 +#: inventory/forms.py:118 inventory/forms.py:121 inventory/forms.py:153 +#: inventory/forms.py:168 inventory/forms.py:267 inventory/forms.py:515 +#: inventory/forms.py:602 inventory/forms.py:822 inventory/forms.py:1019 +#: inventory/forms.py:1637 inventory/models.py:928 inventory/models.py:1015 +#: inventory/models.py:1203 inventory/models.py:1325 inventory/models.py:1434 +#: inventory/models.py:1454 inventory/models.py:1878 #: templates/administration/staff_index.html:123 -#: templates/crm/leads/lead_list.html:47 -#: templates/crm/opportunities/opportunity_detail.html:190 +#: templates/crm/leads/lead_list.html:103 +#: templates/crm/opportunities/opportunity_detail.html:192 #: templates/customers/customer_list.html:41 -#: templates/customers/view_customer.html:76 templates/pricing_page.html:114 -#: templates/pricing_page.html:117 templates/users/user_detail.html:51 +#: templates/customers/view_customer.html:80 templates/pricing_page.html:113 +#: templates/pricing_page.html:116 templates/users/user_detail.html:20 #: templates/vendors/view_vendor.html:20 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_index.html:369 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:114 msgid "Phone Number" msgstr "رقم الهاتف" -#: inventory/forms.py:460 inventory/models.py:728 -#: templates/inventory/car_detail.html:122 +#: inventory/forms.py:466 inventory/models.py:834 +#: templates/inventory/car_detail.html:143 msgid "Custom Date" msgstr "تاريخ البطاقة الجمركية" -#: inventory/forms.py:510 inventory/models.py:1603 +#: inventory/forms.py:516 inventory/models.py:1877 #: templates/vendors/view_vendor.html:17 msgid "Contact Person" msgstr "الشخص المسؤول" -#: inventory/forms.py:575 +#: inventory/forms.py:581 msgid "Both exterior and interior colors must be selected." msgstr "يجب اختيار اللونين الخارجي والداخلي." -#: inventory/forms.py:671 inventory/forms.py:1599 inventory/models.py:1242 -#: inventory/models.py:1605 templates/account/email_change.html:5 -#: templates/account/email_change.html:9 templates/pricing_page.html:107 +#: inventory/forms.py:677 inventory/forms.py:1634 inventory/models.py:1435 +#: inventory/models.py:1879 templates/account/email_change.html:5 +#: templates/account/email_change.html:9 templates/pricing_page.html:106 msgid "Email Address" msgstr "عنوان البريد الإلكتروني" -#: inventory/forms.py:675 +#: inventory/forms.py:681 #: venv/lib/python3.11/site-packages/appointment/views.py:424 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1915 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1920 msgid "Email address" msgstr "عنوان البريد الإلكتروني" -#: inventory/forms.py:676 templates/crm/leads/lead_list.html:41 -#: templates/customers/customer_list.html:36 templates/users/user_list.html:26 -#: templates/vendors/vendors_list.html:49 +#: inventory/forms.py:682 templates/crm/leads/lead_list.html:97 +#: templates/customers/customer_list.html:36 templates/users/user_list.html:33 +#: templates/vendors/vendors_list.html:35 msgid "email" msgstr "البريد الإلكتروني" -#: inventory/forms.py:682 +#: inventory/forms.py:688 msgid "You must add an email." msgstr "يجب إضافة بريد إلكتروني." -#: inventory/forms.py:687 inventory/forms.py:691 +#: inventory/forms.py:693 inventory/forms.py:697 #: templates/account/login.html:36 templates/account/login.html:38 #: venv/lib/python3.11/site-packages/django_ledger/forms/auth.py:15 msgid "Password" msgstr "كلمة المرور" -#: inventory/forms.py:698 inventory/forms.py:715 inventory/forms.py:851 -#: inventory/forms.py:869 inventory/forms.py:884 +#: inventory/forms.py:704 inventory/forms.py:721 inventory/forms.py:857 +#: inventory/forms.py:875 inventory/forms.py:890 #: venv/lib/python3.11/site-packages/django/forms/fields.py:95 msgid "This field is required." msgstr "هذا الحقل مطلوب." -#: inventory/forms.py:704 inventory/forms.py:708 +#: inventory/forms.py:710 inventory/forms.py:714 msgid "Confirm Password" msgstr "تأكيد كلمة المرور" -#: inventory/forms.py:721 +#: inventory/forms.py:727 msgid "I accept the Terms and Privacy Policy" msgstr "أوافق على الشروط وسياسة الخصوصية" -#: inventory/forms.py:730 +#: inventory/forms.py:736 msgid "You must accept the terms and privacy policy." msgstr "يجب أن تقبل الشروط وسياسة الخصوصية." -#: inventory/forms.py:740 +#: inventory/forms.py:746 msgid "An account with this email already exists." msgstr "يوجد بالفعل حساب بهذا البريد الإلكتروني." -#: inventory/forms.py:748 +#: inventory/forms.py:754 msgid "Passwords do not match." msgstr "كلمات المرور غير متطابقة." -#: inventory/forms.py:775 inventory/models.py:328 inventory/models.py:677 -#: inventory/models.py:690 inventory/models.py:907 inventory/models.py:1152 -#: inventory/models.py:1236 templates/administration/manage_service.html:22 +#: inventory/forms.py:781 inventory/models.py:416 inventory/models.py:783 +#: inventory/models.py:796 inventory/models.py:1013 inventory/models.py:1318 +#: inventory/models.py:1429 templates/admin_management/user_management.html:83 +#: templates/admin_management/user_management.html:147 +#: templates/admin_management/user_management.html:211 +#: templates/administration/manage_service.html:22 #: templates/administration/service_list.html:23 #: templates/administration/staff_list.html:34 #: templates/administration/user_profile.html:242 #: templates/customers/customer_list.html:33 #: templates/groups/group_detail.html:47 templates/groups/group_detail.html:60 -#: templates/items/expenses/expenses_list.html:20 +#: templates/items/expenses/expenses_list.html:21 #: templates/items/service/service_list.html:20 -#: templates/ledger/bank_accounts/bank_account_list.html:18 +#: templates/ledger/bank_accounts/bank_account_list.html:19 #: templates/organizations/organization_list.html:45 -#: templates/plans/order_detail_table.html:8 templates/plans/order_list.html:21 -#: templates/pricing_page.html:186 +#: templates/plans/order_detail_table.html:8 templates/plans/order_list.html:19 +#: templates/pricing_page.html:185 #: templates/representatives/representative_list.html:17 -#: templates/users/user_detail.html:47 templates/vendors/vendors_list.html:46 +#: templates/users/user_detail.html:16 templates/vendors/vendors_list.html:26 #: templates/vendors/view_vendor.html:14 #: venv/lib/python3.11/site-packages/appointment/templates/administration/service_list.html:28 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_list.html:38 @@ -194,71 +212,74 @@ msgstr "كلمات المرور غير متطابقة." msgid "Name" msgstr "الاسم" -#: inventory/forms.py:779 inventory/models.py:821 inventory/models.py:1602 +#: inventory/forms.py:785 inventory/models.py:927 inventory/models.py:1876 msgid "English Name" msgstr "الاسم بالإنجليزية" -#: inventory/forms.py:784 +#: inventory/forms.py:790 msgid "Please enter an English Name." msgstr "يرجى إدخال اسم باللغة الإنجليزية." -#: inventory/forms.py:789 inventory/forms.py:793 inventory/models.py:329 -#: inventory/models.py:678 inventory/models.py:691 inventory/models.py:820 -#: inventory/models.py:908 inventory/models.py:1153 inventory/models.py:1237 -#: inventory/models.py:1601 templates/users/user_detail.html:48 +#: inventory/forms.py:795 inventory/forms.py:799 inventory/models.py:417 +#: inventory/models.py:784 inventory/models.py:797 inventory/models.py:926 +#: inventory/models.py:1014 inventory/models.py:1319 inventory/models.py:1430 +#: inventory/models.py:1875 templates/admin_management/user_management.html:84 +#: templates/admin_management/user_management.html:148 +#: templates/admin_management/user_management.html:212 +#: templates/users/user_detail.html:17 msgid "Arabic Name" msgstr "الاسم بالعربية" -#: inventory/forms.py:798 +#: inventory/forms.py:804 msgid "Please enter an Arabic name." msgstr "يرجى إدخال اسم باللغة العربية." -#: inventory/forms.py:840 templates/organizations/organization_detail.html:8 +#: inventory/forms.py:846 templates/organizations/organization_detail.html:8 #: templates/organizations/organization_list.html:50 msgid "CRN" msgstr "رقم السجل التجاري" -#: inventory/forms.py:844 inventory/models.py:813 inventory/models.py:1155 -#: inventory/models.py:1296 inventory/models.py:1593 +#: inventory/forms.py:850 inventory/models.py:919 inventory/models.py:1321 +#: inventory/models.py:1490 inventory/models.py:1867 msgid "Commercial Registration Number" msgstr "رقم السجل التجاري" -#: inventory/forms.py:852 +#: inventory/forms.py:858 msgid "Commercial Registration Number must be 10 characters" msgstr "رقم السجل التجاري يجب أن يتكون من 10 أرقام" -#: inventory/forms.py:858 templates/organizations/organization_detail.html:9 +#: inventory/forms.py:864 templates/organizations/organization_detail.html:9 #: templates/organizations/organization_list.html:57 msgid "VRN" msgstr "الرقم الضريبي" -#: inventory/forms.py:862 inventory/models.py:818 inventory/models.py:1157 -#: inventory/models.py:1299 inventory/models.py:1596 +#: inventory/forms.py:868 inventory/models.py:924 inventory/models.py:1323 +#: inventory/models.py:1493 inventory/models.py:1870 msgid "VAT Registration Number" msgstr "رقم التسجيل في ضريبة القيمة المضافة" -#: inventory/forms.py:870 +#: inventory/forms.py:876 msgid "VAT Registration Number must be 15 characters." msgstr "يجب أن يكون رقم التسجيل الضريبي مكونًا من 15 حرفًا." -#: inventory/forms.py:875 inventory/models.py:824 inventory/models.py:1066 -#: inventory/models.py:1161 inventory/models.py:1244 inventory/models.py:1607 -#: templates/crm/leads/lead_detail.html:118 +#: inventory/forms.py:881 inventory/models.py:930 inventory/models.py:1206 +#: inventory/models.py:1327 inventory/models.py:1437 inventory/models.py:1881 +#: templates/crm/leads/lead_detail.html:199 #: templates/customers/customer_list.html:51 -#: templates/customers/view_customer.html:71 -#: templates/dealers/dealer_detail.html:68 +#: templates/customers/view_customer.html:75 +#: templates/dealers/dealer_detail.html:74 #: templates/organizations/organization_detail.html:11 #: templates/organizations/organization_list.html:71 #: templates/representatives/representative_detail.html:10 #: templates/sales/estimates/sale_order_form.html:70 -#: templates/vendors/vendors_list.html:64 templates/vendors/view_vendor.html:26 +#: templates/vendors/vendors_list.html:69 templates/vendors/view_vendor.html:26 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/tags/customer_table.html:10 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/vendor/tags/vendor_table.html:11 msgid "Address" msgstr "العنوان" -#: inventory/forms.py:905 inventory/models.py:346 -#: templates/inventory/transfer_preview.html:229 +#: inventory/forms.py:911 inventory/models.py:434 +#: templates/inventory/transfer_preview.html:285 #: templates/ledger/bills/bill_detail.html:213 #: templates/ledger/ledger/ledger_detail.html:81 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:94 @@ -277,8 +298,8 @@ msgstr "العنوان" msgid "Item" msgstr "العنصر" -#: inventory/forms.py:909 inventory/models.py:540 -#: templates/inventory/transfer_preview.html:230 +#: inventory/forms.py:915 inventory/models.py:644 +#: templates/inventory/transfer_preview.html:286 #: templates/ledger/bills/bill_detail.html:214 #: templates/ledger/ledger/ledger_detail.html:83 #: templates/plans/invoices/layout.html:104 @@ -297,90 +318,90 @@ msgstr "العنصر" msgid "Quantity" msgstr "الكمية" -#: inventory/forms.py:934 inventory/models.py:1743 -#: templates/customers/view_customer.html:150 +#: inventory/forms.py:940 inventory/models.py:2035 +#: templates/customers/view_customer.html:154 #: templates/ledger/journal_entry/includes/card_invoice.html:10 #: templates/plans/create_order.html:29 templates/plans/invoices/layout.html:11 #: templates/sales/invoices/invoice_create.html:5 #: templates/sales/invoices/invoice_detail.html:69 #: templates/sales/payments/payment_list.html:21 #: templates/sales/sales_list.html:118 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3159 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3172 #: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:361 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:10 msgid "Invoice" msgstr "فاتورة" -#: inventory/forms.py:938 templates/ledger/bills/bill_detail.html:61 +#: inventory/forms.py:944 templates/ledger/bills/bill_detail.html:61 #: templates/ledger/bills/bill_update_form.html:4 #: templates/ledger/bills/bill_update_form.html:7 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:392 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3158 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3171 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:11 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:61 msgid "Bill" msgstr "الفاتورة" -#: inventory/forms.py:940 +#: inventory/forms.py:946 #: templates/ledger/bank_accounts/bank_account_detail.html:50 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:447 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:471 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:22 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/tags/po_item_table.html:11 msgid "Amount" msgstr "المبلغ" -#: inventory/forms.py:943 inventory/models.py:1674 +#: inventory/forms.py:949 inventory/models.py:1966 msgid "cash" msgstr "نقداً" -#: inventory/forms.py:944 inventory/models.py:1675 +#: inventory/forms.py:950 inventory/models.py:1967 msgid "credit" msgstr "دائن" -#: inventory/forms.py:945 inventory/models.py:1676 -#: templates/inventory/car_detail.html:164 -#: templates/inventory/transfer_car.html:23 +#: inventory/forms.py:951 inventory/models.py:1968 +#: templates/inventory/car_detail.html:191 +#: templates/inventory/transfer_car.html:18 msgid "transfer" msgstr "نقل" -#: inventory/forms.py:946 inventory/models.py:1677 +#: inventory/forms.py:952 inventory/models.py:1969 msgid "debit" msgstr "مدين" -#: inventory/forms.py:947 inventory/models.py:1678 inventory/models.py:1753 +#: inventory/forms.py:953 inventory/models.py:1970 inventory/models.py:2045 msgid "SADAD" msgstr "سداد" -#: inventory/forms.py:949 templates/sales/estimates/sale_order_form.html:177 +#: inventory/forms.py:955 templates/sales/estimates/sale_order_form.html:177 msgid "Payment Method" msgstr "طريقة الدفع" -#: inventory/forms.py:953 +#: inventory/forms.py:959 msgid "Payment Date" msgstr "تاريخ الدفع" -#: inventory/forms.py:962 inventory/forms.py:968 +#: inventory/forms.py:968 inventory/forms.py:974 msgid "Payment amount is greater than amount due" msgstr "مبلغ الدفع أكبر من المبلغ المستحق" -#: inventory/forms.py:964 +#: inventory/forms.py:970 msgid "Payment amount must be greater than 0" msgstr "يجب أن يكون مبلغ الدفع أكبر من 0" -#: inventory/forms.py:966 +#: inventory/forms.py:972 msgid "Invoice is already paid" msgstr "تم دفع الفاتورة بالفعل" -#: inventory/forms.py:994 templates/inventory/transfer_details.html:61 -#: templates/inventory/transfer_preview.html:221 +#: inventory/forms.py:1000 templates/inventory/transfer_details.html:79 +#: templates/inventory/transfer_preview.html:277 msgid "To" msgstr "إلى" -#: inventory/forms.py:1016 inventory/models.py:174 inventory/models.py:390 -#: inventory/models.py:1277 inventory/tables.py:52 -#: templates/inventory/car_list_view.html:64 -#: templates/inventory/car_list_view.html:109 -#: templates/inventory/cars_list_api.html:32 +#: inventory/forms.py:1022 inventory/models.py:203 inventory/models.py:485 +#: inventory/models.py:1471 inventory/tables.py:52 +#: templates/inventory/car_list_view.html:103 +#: templates/inventory/car_list_view.html:163 +#: templates/inventory/cars_list_api.html:33 #: templates/sales/estimates/estimate_detail.html:191 #: templates/sales/estimates/sale_order_form.html:124 #: templates/sales/estimates/sale_order_preview.html:179 @@ -389,11 +410,11 @@ msgstr "إلى" msgid "Make" msgstr "الصانع" -#: inventory/forms.py:1033 inventory/models.py:187 inventory/models.py:398 -#: inventory/models.py:1284 inventory/tables.py:53 -#: templates/inventory/car_list_view.html:73 -#: templates/inventory/car_list_view.html:110 -#: templates/inventory/cars_list_api.html:33 +#: inventory/forms.py:1039 inventory/models.py:226 inventory/models.py:493 +#: inventory/models.py:1478 inventory/tables.py:53 +#: templates/inventory/car_list_view.html:117 +#: templates/inventory/car_list_view.html:164 +#: templates/inventory/cars_list_api.html:34 #: templates/sales/estimates/estimate_detail.html:192 #: templates/sales/estimates/sale_order_form.html:126 #: templates/sales/estimates/sale_order_preview.html:180 @@ -402,17 +423,28 @@ msgstr "الصانع" msgid "Model" msgstr "الموديل" -#: inventory/forms.py:1312 inventory/models.py:421 inventory/models.py:1319 -#: inventory/models.py:1484 inventory/models.py:1535 inventory/tables.py:62 -#: templates/crm/leads/lead_detail.html:51 -#: templates/crm/opportunities/opportunity_detail.html:88 -#: templates/inventory/car_detail.html:83 -#: templates/inventory/car_detail.html:368 -#: templates/inventory/car_inventory.html:58 -#: templates/inventory/car_list.html:163 -#: templates/inventory/car_list_view.html:115 -#: templates/inventory/cars_list_api.html:18 -#: templates/inventory/cars_list_api.html:34 templates/plans/current.html:24 +#: inventory/forms.py:1153 +msgid "Expected Closing Date" +msgstr "تاريخ الإغلاق المتوقع" + +#: inventory/forms.py:1158 +msgid "Probability (%)" +msgstr "الاحتمالية (%)" + +#: inventory/forms.py:1347 inventory/models.py:516 inventory/models.py:1513 +#: inventory/models.py:1801 inventory/tables.py:62 +#: templates/admin_management/user_management.html:22 +#: templates/admin_management/user_management.html:86 +#: templates/admin_management/user_management.html:150 +#: templates/admin_management/user_management.html:214 +#: templates/crm/leads/lead_detail.html:130 +#: templates/inventory/car_detail.html:100 +#: templates/inventory/car_detail.html:399 +#: templates/inventory/car_inventory.html:78 +#: templates/inventory/car_list.html:172 +#: templates/inventory/car_list_view.html:169 +#: templates/inventory/cars_list_api.html:19 +#: templates/inventory/cars_list_api.html:35 templates/plans/current.html:24 #: templates/sales/estimates/estimate_list.html:16 #: templates/sales/invoices/invoice_list.html:17 #: templates/sales/journals/journal_list.html:17 @@ -426,178 +458,195 @@ msgstr "الموديل" msgid "Status" msgstr "الحالة" -#: inventory/forms.py:1328 inventory/models.py:1479 -#: templates/crm/leads/lead_list.html:77 -#: templates/crm/opportunities/opportunity_detail.html:95 -#: templates/crm/opportunities/opportunity_form.html:48 +#: inventory/forms.py:1363 inventory/models.py:1717 msgid "Stage" msgstr "المرحلة" -#: inventory/forms.py:1457 +#: inventory/forms.py:1492 msgid "Select Car Makes" msgstr "اختر ماركات السيارات" -#: inventory/forms.py:1517 +#: inventory/forms.py:1552 msgid "Please enter a valid credit card number" msgstr "يرجى إدخال رقم بطاقة ائتمان صالح" -#: inventory/forms.py:1547 +#: inventory/forms.py:1582 msgid "Please enter a valid month (01-12)" msgstr "يرجى إدخال شهر صالح (01-12)" -#: inventory/forms.py:1554 +#: inventory/forms.py:1589 msgid "This card appears to be expired" msgstr "يبدو أن هذه البطاقة منتهية الصلاحية" -#: inventory/forms.py:1557 +#: inventory/forms.py:1592 msgid "Please enter a valid expiry date in MM/YY format" msgstr "يرجى إدخال تاريخ انتهاء صلاحية صحيح بصيغة MM/YY" -#: inventory/forms.py:1566 +#: inventory/forms.py:1601 msgid "CVV must contain only digits" msgstr "يجب أن يحتوي رمز التحقق (CVV) على أرقام فقط" -#: inventory/forms.py:1568 +#: inventory/forms.py:1603 msgid "CVV must be 3 or 4 digits" msgstr "يجب أن يكون رمز التحقق (CVV) مكونًا من 3 أو 4 أرقام" -#: inventory/forms.py:1577 inventory/forms.py:1580 inventory/models.py:1047 -#: inventory/models.py:1258 +#: inventory/forms.py:1612 inventory/forms.py:1615 inventory/models.py:1187 +#: inventory/models.py:1451 templates/admin_management/user_management.html:19 #: templates/administration/manage_staff_personal_info.html:18 -#: templates/pricing_page.html:93 templates/pricing_page.html:96 +#: templates/pricing_page.html:92 templates/pricing_page.html:95 msgid "First Name" msgstr "الاسم الأول" -#: inventory/forms.py:1587 inventory/forms.py:1590 inventory/models.py:1051 -#: inventory/models.py:1259 +#: inventory/forms.py:1622 inventory/forms.py:1625 inventory/models.py:1191 +#: inventory/models.py:1452 templates/admin_management/user_management.html:20 #: templates/administration/manage_staff_personal_info.html:24 -#: templates/pricing_page.html:100 templates/pricing_page.html:103 +#: templates/pricing_page.html:99 templates/pricing_page.html:102 msgid "Last Name" msgstr "اسم العائلة" -#: inventory/forms.py:1613 templates/pricing_page.html:143 -#: templates/pricing_page.html:146 templates/pricing_page.html:193 +#: inventory/forms.py:1648 templates/pricing_page.html:142 +#: templates/pricing_page.html:145 templates/pricing_page.html:192 msgid "Card Number" msgstr "رقم البطاقة" -#: inventory/forms.py:1624 +#: inventory/forms.py:1659 msgid "Expiration Date" msgstr "تاريخ الانتهاء" -#: inventory/forms.py:1635 +#: inventory/forms.py:1670 msgid "Security Code (CVV)" msgstr "رمز الأمان (CVV)" -#: inventory/forms.py:1647 +#: inventory/forms.py:1682 msgid "Name on Card" msgstr "الاسم على البطاقة" -#: inventory/forms.py:1657 +#: inventory/forms.py:1692 msgid "I agree to the Terms and Conditions" msgstr "أوافق على الشروط وسياسة الخصوصية" -#: inventory/forms.py:1659 +#: inventory/forms.py:1694 msgid "You must accept the terms and conditions" msgstr "يجب أن تقبل الشروط وسياسة الخصوصية." -#: inventory/models.py:147 inventory/models.py:440 inventory/models.py:523 -#: inventory/models.py:568 inventory/models.py:725 inventory/models.py:740 -#: inventory/models.py:784 inventory/models.py:1476 -#: templates/crm/leads/lead_list.html:35 -#: templates/crm/opportunities/opportunity_form.html:35 -#: templates/dashboards/manager.html:52 -#: templates/inventory/transfer_details.html:70 +#: inventory/models.py:36 +msgid "Primary Key" +msgstr "المفتاح الأساسي" + +#: inventory/models.py:37 inventory/models.py:1735 inventory/models.py:1888 +msgid "Slug" +msgstr "المُعرّف الفريد (Slug)" + +#: inventory/models.py:38 +msgid "" +"Slug for the object. If not provided, it will be generated automatically." +msgstr "المُعرّف الفريد للكائن. إذا لم يتم توفيره، فسيتم إنشاؤه تلقائيًا." + +#: inventory/models.py:39 inventory/models.py:653 inventory/models.py:868 +#: inventory/models.py:1887 +msgid "Created At" +msgstr "تاريخ الإنشاء" + +#: inventory/models.py:40 inventory/models.py:654 inventory/models.py:939 +msgid "Updated At" +msgstr "تم التحديث" + +#: inventory/models.py:165 inventory/models.py:536 inventory/models.py:627 +#: inventory/models.py:672 inventory/models.py:831 inventory/models.py:846 +#: inventory/models.py:890 inventory/models.py:1714 +#: templates/crm/leads/lead_list.html:91 templates/dashboards/manager.html:52 +#: templates/inventory/transfer_details.html:88 msgid "Car" msgstr "سيارة" -#: inventory/models.py:148 +#: inventory/models.py:166 msgid "Light Commercial" msgstr "مركبات تجارية خفيفة" -#: inventory/models.py:149 +#: inventory/models.py:167 msgid "Heavy-Duty Tractors" msgstr "جرارات ثقيلة" -#: inventory/models.py:150 +#: inventory/models.py:168 msgid "Trailers" msgstr "مقطورات" -#: inventory/models.py:151 +#: inventory/models.py:169 msgid "Medium Trucks" msgstr "شاحنات متوسطة" -#: inventory/models.py:152 +#: inventory/models.py:170 msgid "Buses" msgstr "حافلات" -#: inventory/models.py:153 +#: inventory/models.py:171 msgid "Motorcycles" msgstr "دراجات نارية" -#: inventory/models.py:154 +#: inventory/models.py:172 msgid "Buggy" msgstr "باجي" -#: inventory/models.py:155 +#: inventory/models.py:173 msgid "Moto ATV" msgstr "موتو ATV" -#: inventory/models.py:156 +#: inventory/models.py:174 msgid "Scooters" msgstr "دراجات سكوتر" -#: inventory/models.py:157 +#: inventory/models.py:175 msgid "Karting" msgstr "كارتينج" -#: inventory/models.py:158 +#: inventory/models.py:176 msgid "ATV" msgstr "مركبات ATV" -#: inventory/models.py:159 +#: inventory/models.py:177 msgid "Snowmobiles" msgstr "دراجات الثلج" -#: inventory/models.py:166 +#: inventory/models.py:185 msgid "logo" msgstr "الشعار" -#: inventory/models.py:205 inventory/models.py:407 inventory/tables.py:55 -#: templates/inventory/car_form.html:75 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:121 +#: inventory/models.py:255 inventory/models.py:502 inventory/tables.py:55 +#: templates/inventory/car_form.html:82 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:100 msgid "Series" msgstr "السلسلة" -#: inventory/models.py:222 inventory/models.py:415 inventory/tables.py:56 -#: templates/inventory/car_list_view.html:112 +#: inventory/models.py:283 inventory/models.py:510 inventory/tables.py:56 +#: templates/inventory/car_list_view.html:166 #: templates/sales/sales_list.html:115 msgid "Trim" msgstr "الفئة" -#: inventory/models.py:236 +#: inventory/models.py:302 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:455 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:541 #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:509 msgid "Equipment" msgstr "المعدات" -#: inventory/models.py:251 +#: inventory/models.py:328 msgid "Specification" msgstr "المواصفة" -#: inventory/models.py:267 +#: inventory/models.py:344 msgid "Specification Value" msgstr "قيمة المواصفة" -#: inventory/models.py:282 +#: inventory/models.py:370 msgid "Option" msgstr "الخيار" -#: inventory/models.py:301 +#: inventory/models.py:389 msgid "Option Value" msgstr "قيمة الخيار" -#: inventory/models.py:305 templates/ledger/bills/bill_detail.html:191 +#: inventory/models.py:393 templates/ledger/bills/bill_detail.html:191 #: templates/sales/estimates/estimate_detail.html:82 #: templates/sales/estimates/estimate_detail.html:169 #: templates/sales/estimates/estimate_list.html:29 @@ -611,7 +660,7 @@ msgstr "قيمة الخيار" msgid "Draft" msgstr "مسودة" -#: inventory/models.py:306 templates/ledger/bills/bill_detail.html:195 +#: inventory/models.py:394 templates/ledger/bills/bill_detail.html:195 #: templates/sales/estimates/estimate_detail.html:86 #: templates/sales/estimates/estimate_detail.html:173 #: templates/sales/estimates/estimate_list.html:33 @@ -626,107 +675,105 @@ msgstr "مسودة" msgid "Approved" msgstr "تمت الموافقة" -#: inventory/models.py:307 inventory/models.py:981 -#: templates/crm/leads/lead_detail.html:55 -#: templates/crm/leads/lead_list.html:123 test.txt:46 +#: inventory/models.py:395 templates/crm/leads/lead_list.html:167 test.txt:46 msgid "Pending" msgstr "قيد الانتظار" -#: inventory/models.py:308 +#: inventory/models.py:396 msgid "Accepted" msgstr "تم القبول" -#: inventory/models.py:309 templates/administration/staff_index.html:83 +#: inventory/models.py:397 templates/administration/staff_index.html:83 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_index.html:329 msgid "Success" msgstr "ناجحة" -#: inventory/models.py:310 +#: inventory/models.py:398 msgid "Reject" msgstr "رفض" -#: inventory/models.py:311 +#: inventory/models.py:399 msgid "Cancelled" msgstr "ملغى" -#: inventory/models.py:315 templates/dashboards/manager.html:103 +#: inventory/models.py:403 templates/dashboards/manager.html:103 #: templates/dashboards/manager.html:235 templates/dashboards/sales.html:20 #: templates/dashboards/sales.html:332 -#: templates/inventory/car_inventory.html:99 -#: templates/inventory/car_list_view.html:38 -#: templates/inventory/car_list_view.html:86 -#: templates/inventory/car_list_view.html:154 -#: templates/inventory/cars_list_api.html:19 +#: templates/inventory/car_inventory.html:131 +#: templates/inventory/car_list_view.html:45 +#: templates/inventory/car_list_view.html:130 +#: templates/inventory/car_list_view.html:210 +#: templates/inventory/cars_list_api.html:20 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_item_formset.html:21 msgid "Available" msgstr "متاح" -#: inventory/models.py:316 templates/dashboards/manager.html:109 +#: inventory/models.py:404 templates/dashboards/manager.html:109 #: templates/dashboards/manager.html:236 templates/dashboards/sales.html:26 #: templates/dashboards/sales.html:333 -#: templates/inventory/car_inventory.html:101 -#: templates/inventory/car_list_view.html:41 -#: templates/inventory/car_list_view.html:88 -#: templates/inventory/car_list_view.html:158 -#: templates/inventory/cars_list_api.html:21 +#: templates/inventory/car_inventory.html:133 +#: templates/inventory/car_list_view.html:56 +#: templates/inventory/car_list_view.html:132 +#: templates/inventory/car_list_view.html:214 +#: templates/inventory/cars_list_api.html:22 msgid "Sold" msgstr "تم البيع" -#: inventory/models.py:317 templates/dashboards/manager.html:127 +#: inventory/models.py:405 templates/dashboards/manager.html:127 #: templates/dashboards/manager.html:239 templates/dashboards/sales.html:44 #: templates/dashboards/sales.html:336 -#: templates/inventory/car_inventory.html:103 +#: templates/inventory/car_inventory.html:135 msgid "Hold" msgstr "في الانتظار" -#: inventory/models.py:318 templates/dashboards/manager.html:133 +#: inventory/models.py:406 templates/dashboards/manager.html:133 #: templates/dashboards/manager.html:240 templates/dashboards/sales.html:50 #: templates/dashboards/sales.html:337 -#: templates/inventory/car_inventory.html:107 -#: templates/inventory/cars_list_api.html:23 +#: templates/inventory/car_inventory.html:142 +#: templates/inventory/cars_list_api.html:24 msgid "Damaged" msgstr "تالف" -#: inventory/models.py:319 templates/dashboards/manager.html:115 +#: inventory/models.py:407 templates/dashboards/manager.html:115 #: templates/dashboards/manager.html:237 templates/dashboards/sales.html:32 #: templates/dashboards/sales.html:334 -#: templates/inventory/car_inventory.html:105 -#: templates/inventory/car_list_view.html:39 -#: templates/inventory/car_list_view.html:87 -#: templates/inventory/car_list_view.html:156 -#: templates/inventory/cars_list_api.html:20 +#: templates/inventory/car_inventory.html:140 +#: templates/inventory/car_list_view.html:49 +#: templates/inventory/car_list_view.html:131 +#: templates/inventory/car_list_view.html:212 +#: templates/inventory/cars_list_api.html:21 msgid "Reserved" msgstr "محجوزة" -#: inventory/models.py:320 templates/dashboards/manager.html:121 -#: templates/dashboards/manager.html:238 templates/dashboards/sales.html:38 -#: templates/dashboards/sales.html:335 -#: templates/inventory/car_list_view.html:40 -#: templates/inventory/car_list_view.html:89 -#: templates/inventory/car_list_view.html:160 -#: templates/inventory/cars_list_api.html:22 -#: templates/inventory/transfer_preview.html:213 +#: inventory/models.py:408 inventory/models.py:1147 +#: templates/dashboards/manager.html:121 templates/dashboards/manager.html:238 +#: templates/dashboards/sales.html:38 templates/dashboards/sales.html:335 +#: templates/inventory/car_list_view.html:53 +#: templates/inventory/car_list_view.html:133 +#: templates/inventory/car_list_view.html:216 +#: templates/inventory/cars_list_api.html:23 +#: templates/inventory/transfer_preview.html:264 msgid "Transfer" msgstr "نقل" -#: inventory/models.py:323 inventory/models.py:980 -#: templates/crm/leads/lead_detail.html:53 -#: templates/crm/leads/lead_list.html:121 -#: templates/inventory/car_inventory.html:68 test.txt:33 +#: inventory/models.py:411 inventory/models.py:1113 +#: templates/crm/leads/lead_detail.html:132 +#: templates/crm/leads/lead_list.html:165 +#: templates/inventory/car_inventory.html:90 test.txt:33 msgid "New" msgstr "جديد" -#: inventory/models.py:324 templates/inventory/car_inventory.html:70 +#: inventory/models.py:412 templates/inventory/car_inventory.html:92 msgid "Used" msgstr "مستعمل" -#: inventory/models.py:330 inventory/models.py:759 +#: inventory/models.py:418 inventory/models.py:865 inventory/models.py:1774 #: templates/administration/manage_day_off.html:63 #: templates/administration/manage_service.html:33 #: templates/administration/user_profile.html:93 #: templates/administration/user_profile.html:243 -#: templates/ledger/coa_accounts/account_detail.html:67 -#: templates/ledger/journal_entry/journal_entry_list.html:65 +#: templates/ledger/coa_accounts/account_detail.html:70 +#: templates/ledger/journal_entry/journal_entry_list.html:51 #: templates/ledger/journal_entry/journal_entry_transactions.html:23 #: templates/ledger/reports/tags/income_statement.html:9 #: templates/plans/invoices/layout.html:102 @@ -749,41 +796,46 @@ msgstr "مستعمل" msgid "Description" msgstr "الوصف" -#: inventory/models.py:332 inventory/tables.py:58 +#: inventory/models.py:420 inventory/tables.py:58 #: templates/administration/manage_service.html:55 #: templates/administration/service_list.html:25 #: templates/administration/user_profile.html:245 -#: templates/inventory/transfer_details.html:72 templates/pricing_page.html:180 +#: templates/inventory/transfer_details.html:89 templates/pricing_page.html:179 #: templates/sales/sales_list.html:116 #: venv/lib/python3.11/site-packages/appointment/templates/administration/service_list.html:30 #: venv/lib/python3.11/site-packages/appointment/templates/administration/user_profile.html:237 msgid "Price" msgstr "السعر" -#: inventory/models.py:334 +#: inventory/models.py:422 msgid "taxable" msgstr "خاضع للضريبة" -#: inventory/models.py:338 +#: inventory/models.py:426 msgid "Unit of Measurement" msgstr "وحدة القياس" -#: inventory/models.py:341 inventory/models.py:375 inventory/models.py:884 +#: inventory/models.py:429 inventory/models.py:470 inventory/models.py:990 msgid "Dealer" msgstr "المعرض" -#: inventory/models.py:365 inventory/models.py:366 +#: inventory/models.py:453 inventory/models.py:454 #: templates/sales/estimates/estimate_detail.html:227 #: templates/sales/estimates/sale_order_preview.html:206 #: templates/sales/invoices/invoice_detail.html:273 msgid "Additional Services" msgstr "الخدمات الإضافية" -#: inventory/models.py:382 inventory/models.py:1615 -#: templates/inventory/car_detail.html:100 -#: templates/inventory/car_form.html:144 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:166 -#: templates/ledger/bills/bill_list.html:51 +#: inventory/models.py:464 +#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1053 +msgid "Item Model" +msgstr "نموذج العنصر" + +#: inventory/models.py:477 inventory/models.py:1901 +#: templates/inventory/car_detail.html:117 +#: templates/inventory/car_form.html:147 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:136 +#: templates/ledger/bills/bill_list.html:52 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:364 #: venv/lib/python3.11/site-packages/django_ledger/models/vendor.py:191 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_table.html:12 @@ -791,12 +843,12 @@ msgstr "الخدمات الإضافية" msgid "Vendor" msgstr "المورد" -#: inventory/models.py:400 inventory/models.py:1287 inventory/tables.py:54 -#: templates/inventory/car_form.html:65 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:61 -#: templates/inventory/car_inventory.html:54 -#: templates/inventory/car_list_view.html:79 -#: templates/inventory/car_list_view.html:111 +#: inventory/models.py:495 inventory/models.py:1481 inventory/tables.py:54 +#: templates/inventory/car_form.html:72 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:55 +#: templates/inventory/car_inventory.html:67 +#: templates/inventory/car_list_view.html:123 +#: templates/inventory/car_list_view.html:165 #: templates/ledger/reports/components/period_navigator.html:21 #: templates/sales/estimates/estimate_detail.html:193 #: templates/sales/estimates/sale_order_form.html:128 @@ -805,214 +857,205 @@ msgstr "المورد" msgid "Year" msgstr "السنة" -#: inventory/models.py:427 inventory/tables.py:50 -#: templates/inventory/car_detail.html:87 templates/inventory/car_form.html:157 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:183 -#: templates/inventory/car_list.html:177 +#: inventory/models.py:522 inventory/tables.py:50 +#: templates/inventory/car_detail.html:104 +#: templates/inventory/car_form.html:158 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:147 +#: templates/inventory/car_list.html:184 msgid "Stock Type" msgstr "نوع المخزون" -#: inventory/models.py:429 inventory/models.py:541 -#: templates/inventory/car_detail.html:105 -#: templates/inventory/car_form.html:195 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:232 -#: templates/inventory/car_list.html:200 +#: inventory/models.py:524 inventory/models.py:645 +#: templates/inventory/car_detail.html:122 +#: templates/inventory/car_form.html:191 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:181 +#: templates/inventory/car_list.html:210 msgid "Remarks" msgstr "ملاحظات" -#: inventory/models.py:430 inventory/tables.py:57 -#: templates/inventory/car_detail.html:91 templates/inventory/car_form.html:169 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:198 -#: templates/inventory/car_list.html:191 templates/inventory/car_list.html:192 +#: inventory/models.py:525 inventory/tables.py:57 +#: templates/inventory/car_detail.html:108 +#: templates/inventory/car_form.html:169 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:157 +#: templates/inventory/car_list.html:196 templates/inventory/car_list.html:202 msgid "Mileage" msgstr "عدد الكيلومترات" -#: inventory/models.py:431 templates/inventory/car_detail.html:95 -#: templates/inventory/car_form.html:182 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:215 +#: inventory/models.py:526 templates/inventory/car_detail.html:112 +#: templates/inventory/car_form.html:180 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:168 msgid "Receiving Date" msgstr "تاريخ الاستلام" -#: inventory/models.py:432 +#: inventory/models.py:527 msgid "Hash" msgstr "رمز" -#: inventory/models.py:441 templates/header.html:36 +#: inventory/models.py:537 templates/header.html:36 #: templates/sales/estimates/estimate_form.html:38 msgid "Cars" msgstr "السيارات" -#: inventory/models.py:488 -msgid "Car Sold" -msgstr "تم بيع السيارة" - -#: inventory/models.py:529 +#: inventory/models.py:633 msgid "From Dealer" msgstr "من معرض" -#: inventory/models.py:535 +#: inventory/models.py:639 msgid "To Dealer" msgstr "الى معرض" -#: inventory/models.py:538 +#: inventory/models.py:642 msgid "Transfer Date" msgstr "تاريخ النقل" -#: inventory/models.py:549 inventory/models.py:762 inventory/models.py:1612 -msgid "Created At" -msgstr "تاريخ الإنشاء" - -#: inventory/models.py:550 inventory/models.py:833 -msgid "Updated At" -msgstr "تم التحديث" - -#: inventory/models.py:556 +#: inventory/models.py:660 msgid "Car Transfer Log" msgstr "سجل نقل السيارة" -#: inventory/models.py:557 +#: inventory/models.py:661 msgid "Car Transfer Logs" msgstr "سجلات نقل السيارات" -#: inventory/models.py:574 templates/inventory/car_detail.html:311 +#: inventory/models.py:678 templates/inventory/car_detail.html:334 msgid "Reserved By" msgstr "محجوز بواسطة" -#: inventory/models.py:582 +#: inventory/models.py:686 msgid "Reserved At" msgstr "تاريخ الحجز" -#: inventory/models.py:583 +#: inventory/models.py:687 msgid "Reserved Until" msgstr "محجوز حتى" -#: inventory/models.py:593 templates/inventory/car_detail.html:451 +#: inventory/models.py:697 templates/inventory/car_detail.html:499 msgid "Car Reservation" msgstr "حجز السيارة" -#: inventory/models.py:594 +#: inventory/models.py:698 msgid "Car Reservations" msgstr "حجوزات السيارات" -#: inventory/models.py:604 templates/inventory/car_detail.html:201 +#: inventory/models.py:708 templates/inventory/car_detail.html:229 msgid "Cost Price" msgstr "سعر التكلفة" -#: inventory/models.py:607 templates/inventory/car_detail.html:206 +#: inventory/models.py:711 templates/inventory/car_detail.html:234 msgid "Selling Price" msgstr "سعر البيع" -#: inventory/models.py:612 templates/inventory/car_detail.html:210 +#: inventory/models.py:716 templates/inventory/car_detail.html:238 #: templates/sales/estimates/estimate_detail.html:221 #: templates/sales/invoices/invoice_detail.html:261 msgid "Discount Amount" msgstr "مبلغ الخصم" -#: inventory/models.py:672 inventory/models.py:673 +#: inventory/models.py:778 inventory/models.py:779 msgid "Car Financial Details" msgstr "تفاصيل المالية للسيارة" -#: inventory/models.py:679 inventory/models.py:692 +#: inventory/models.py:785 inventory/models.py:798 msgid "RGB" msgstr "آر جي بي" -#: inventory/models.py:682 inventory/models.py:683 +#: inventory/models.py:788 inventory/models.py:789 #: templates/inventory/add_colors.html:13 msgid "Exterior Colors" msgstr "الألوان الخارجية" -#: inventory/models.py:695 inventory/models.py:696 +#: inventory/models.py:801 inventory/models.py:802 #: templates/inventory/add_colors.html:33 msgid "Interior Colors" msgstr "الألوان الداخلية" -#: inventory/models.py:712 templates/inventory/car_list_view.html:113 +#: inventory/models.py:818 templates/inventory/car_list_view.html:167 msgid "Color" msgstr "اللون" -#: inventory/models.py:713 +#: inventory/models.py:819 msgid "Colors" msgstr "الألوان" -#: inventory/models.py:727 templates/inventory/car_detail.html:118 +#: inventory/models.py:833 templates/inventory/car_detail.html:139 msgid "Custom Number" msgstr "رقم البطاقة الجمركية" -#: inventory/models.py:731 templates/inventory/car_detail.html:127 -#: templates/inventory/car_detail.html:421 +#: inventory/models.py:837 templates/inventory/car_detail.html:148 +#: templates/inventory/car_detail.html:457 msgid "Custom Card" msgstr "البطاقة الجمركية" -#: inventory/models.py:732 +#: inventory/models.py:838 msgid "Custom Cards" msgstr "البطاقات الجمركية" -#: inventory/models.py:746 inventory/models.py:1492 +#: inventory/models.py:852 inventory/models.py:1724 msgid "Owner" msgstr "المالك" -#: inventory/models.py:747 +#: inventory/models.py:853 msgid "Dealer who owns the car." msgstr "التاجر الذي يمتلك السيارة." -#: inventory/models.py:753 inventory/models.py:960 +#: inventory/models.py:859 inventory/models.py:1093 msgid "Showroom" msgstr "صالة العرض" -#: inventory/models.py:754 +#: inventory/models.py:860 msgid "Dealer where the car is displayed (can be the owner)." msgstr "التاجر الذي تُعرض السيارة في صالته (يمكن أن يكون المالك)." -#: inventory/models.py:760 +#: inventory/models.py:866 msgid "Optional description about the showroom placement." msgstr "وصف اختياري حول وضع السيارة في صالة العرض." -#: inventory/models.py:763 +#: inventory/models.py:869 msgid "Last Updated" msgstr "آخر تحديث" -#: inventory/models.py:766 +#: inventory/models.py:872 msgid "Car Location" msgstr "موقع السيارة" -#: inventory/models.py:767 +#: inventory/models.py:873 msgid "Car Locations" msgstr "مواقف السيارات" -#: inventory/models.py:786 +#: inventory/models.py:892 msgid "Plate Number" msgstr "رقم اللوحة" -#: inventory/models.py:787 +#: inventory/models.py:893 msgid "Text 1" msgstr "النص 1" -#: inventory/models.py:788 +#: inventory/models.py:894 msgid "Text 2" msgstr "النص 2" -#: inventory/models.py:789 +#: inventory/models.py:895 msgid "Text 3" msgstr "النص 3" -#: inventory/models.py:790 templates/inventory/car_detail.html:143 +#: inventory/models.py:896 templates/inventory/car_detail.html:165 msgid "Registration Date" msgstr "تاريخ التسجيل" -#: inventory/models.py:793 templates/inventory/car_detail.html:137 -#: templates/inventory/car_detail.html:149 -#: templates/inventory/car_detail.html:436 +#: inventory/models.py:899 templates/inventory/car_detail.html:159 +#: templates/inventory/car_detail.html:170 +#: templates/inventory/car_detail.html:478 msgid "Registration" msgstr "التسجيل" -#: inventory/models.py:794 +#: inventory/models.py:900 msgid "Registrations" msgstr "تسجيل السيارات" -#: inventory/models.py:802 inventory/models.py:911 inventory/models.py:1072 -#: inventory/models.py:1167 inventory/models.py:1324 inventory/models.py:1497 -#: inventory/models.py:1517 inventory/models.py:1539 inventory/models.py:1562 -#: inventory/models.py:1579 templates/crm/leads/lead_detail.html:100 +#: inventory/models.py:908 inventory/models.py:1018 inventory/models.py:1212 +#: inventory/models.py:1333 inventory/models.py:1532 inventory/models.py:1732 +#: inventory/models.py:1758 inventory/models.py:1783 inventory/models.py:1805 +#: inventory/models.py:1828 inventory/models.py:1845 +#: templates/crm/leads/lead_detail.html:181 #: templates/sales/estimates/estimate_list.html:18 #: templates/sales/invoices/invoice_list.html:19 #: templates/sales/journals/journal_list.html:19 @@ -1022,26 +1065,27 @@ msgstr "تسجيل السيارات" msgid "Created" msgstr "تاريخ الإنشاء" -#: inventory/models.py:803 inventory/models.py:912 inventory/models.py:1073 -#: inventory/models.py:1168 inventory/models.py:1326 inventory/models.py:1498 -#: inventory/models.py:1518 inventory/models.py:1540 inventory/models.py:1563 +#: inventory/models.py:909 inventory/models.py:1019 inventory/models.py:1213 +#: inventory/models.py:1334 inventory/models.py:1534 inventory/models.py:1733 +#: inventory/models.py:1759 inventory/models.py:1784 inventory/models.py:1806 +#: inventory/models.py:1829 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html:41 msgid "Updated" msgstr "تم التحديث" -#: inventory/models.py:827 inventory/models.py:1164 inventory/models.py:1610 +#: inventory/models.py:933 inventory/models.py:1330 inventory/models.py:1884 msgid "Logo" msgstr "الشعار" -#: inventory/models.py:832 +#: inventory/models.py:938 msgid "Joined At" msgstr "انضم في" -#: inventory/models.py:885 +#: inventory/models.py:991 msgid "Dealers" msgstr "المعارض" -#: inventory/models.py:896 inventory/tasks.py:63 templates/header.html:17 +#: inventory/models.py:1002 inventory/tasks.py:62 templates/header.html:17 #: templates/header.html:22 templates/welcome.html:27 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:440 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:526 @@ -1050,281 +1094,27 @@ msgstr "المعارض" msgid "Inventory" msgstr "المخزن" -#: inventory/models.py:897 +#: inventory/models.py:1003 msgid "Accountant" msgstr "محاسب" -#: inventory/models.py:898 templates/header.html:110 +#: inventory/models.py:1004 templates/header.html:110 msgid "Sales" msgstr "المبيعات" -#: inventory/models.py:910 +#: inventory/models.py:1016 msgid "Staff Type" msgstr "نوع الموظف" -#: inventory/models.py:949 inventory/models.py:950 -#: templates/crm/opportunities/opportunity_detail.html:231 -#: templates/crm/opportunities/opportunity_form.html:70 -#: templates/dashboards/manager.html:16 templates/users/user_form.html:4 -#: templates/users/user_list.html:5 -msgid "Staff" -msgstr "الموظفون" - -#: inventory/models.py:958 -msgid "Referrals" -msgstr "إحالات" - -#: inventory/models.py:959 inventory/models.py:1006 -msgid "WhatsApp" -msgstr "واتساب" - -#: inventory/models.py:961 -msgid "TikTok" -msgstr "تيك توك" - -#: inventory/models.py:962 -msgid "Instagram" -msgstr "إنستغرام" - -#: inventory/models.py:963 -msgid "X" -msgstr "إكس" - -#: inventory/models.py:964 -msgid "Facebook" -msgstr "فيسبوك" - -#: inventory/models.py:965 -msgid "Motory" -msgstr "موتري" - -#: inventory/models.py:966 -msgid "Influencers" -msgstr "المؤثرون" - -#: inventory/models.py:967 -msgid "Youtube" -msgstr "يوتيوب" - -#: inventory/models.py:968 -msgid "Campaign" -msgstr "حملة" - -#: inventory/models.py:972 -msgid "Walk In" -msgstr "زيارة مباشرة" - -#: inventory/models.py:973 -msgid "Toll Free" -msgstr "رقم مجاني" - -#: inventory/models.py:974 -#: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:113 -msgid "Website" -msgstr "الموقع الإلكتروني" - -#: inventory/models.py:976 -msgid "Form" -msgstr "نموذج" - -#: inventory/models.py:982 templates/crm/leads/lead_detail.html:57 -#: templates/crm/leads/lead_list.html:125 -msgid "In Progress" -msgstr "قيد التنفيذ" - -#: inventory/models.py:983 templates/crm/leads/lead_detail.html:59 -#: templates/crm/leads/lead_list.html:127 -msgid "Qualified" -msgstr "مؤهل" - -#: inventory/models.py:984 templates/crm/leads/lead_list.html:129 -msgid "Contacted" -msgstr "تم الاتصال" - -#: inventory/models.py:985 -msgid "Converted" -msgstr "تم التحويل" - -#: inventory/models.py:986 inventory/models.py:1413 -#: templates/crm/leads/lead_detail.html:61 -#: templates/crm/leads/lead_list.html:131 -#: templates/sales/estimates/estimate_detail.html:90 -#: templates/sales/estimates/estimate_detail.html:177 -#: templates/sales/estimates/estimate_list.html:37 -#: templates/sales/invoices/invoice_list.html:34 test.txt:59 -#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:347 -#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:228 -#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:305 -#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1042 -#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:196 -msgid "Canceled" -msgstr "ملغى" - -#: inventory/models.py:990 -msgid "Mr" -msgstr "السيد" - -#: inventory/models.py:991 -msgid "Mrs" -msgstr "السيدة" - -#: inventory/models.py:992 -msgid "Ms" -msgstr "الآنسة" - -#: inventory/models.py:993 -msgid "Miss" -msgstr "الآنسة" - -#: inventory/models.py:994 -msgid "Dr" -msgstr "الدكتور" - -#: inventory/models.py:995 -msgid "Prof" -msgstr "الأستاذ" - -#: inventory/models.py:996 -msgid "Prince" -msgstr "الأمير" - -#: inventory/models.py:997 -msgid "Princess" -msgstr "الأميرة" - -#: inventory/models.py:998 templates/pricing_page.html:121 -#: templates/pricing_page.html:124 templates/pricing_page.html:188 -msgid "Company" -msgstr "الشركة" - -#: inventory/models.py:999 -msgid "N/A" -msgstr "غير متوفر" - -#: inventory/models.py:1003 inventory/models.py:1406 -msgid "Call" -msgstr "مكالمة" - -#: inventory/models.py:1004 -msgid "SMS" -msgstr "رسالة نصية" - -#: inventory/models.py:1007 -msgid "Visit" -msgstr "زيارة" - -#: inventory/models.py:1008 templates/inventory/car_form.html:33 -msgid "Add Car" -msgstr "إضافة سيارة" - -#: inventory/models.py:1009 -msgid "Sale Car" -msgstr "بيع سيارة" - -#: inventory/models.py:1010 templates/inventory/reserve_car.html:6 -#: templates/inventory/reserve_car.html:9 -msgid "Reserve Car" -msgstr "حجز السيارة" - -#: inventory/models.py:1011 templates/inventory/transfer_car.html:4 -msgid "Transfer Car" -msgstr "نقل السيارة" - -#: inventory/models.py:1012 -msgid "Remove Car" -msgstr "إزالة السيارة" - -#: inventory/models.py:1013 -#: templates/crm/opportunities/opportunity_detail.html:18 -#: templates/sales/estimates/estimate_form.html:5 -#: templates/sales/estimates/estimate_form.html:32 -msgid "Create Quotation" -msgstr "إنشاء عرض" - -#: inventory/models.py:1014 -msgid "Cancel Quotation" -msgstr "إلغاء العرض" - -#: inventory/models.py:1015 -msgid "Create Order" -msgstr "إنشاء طلب" - -#: inventory/models.py:1016 -msgid "Cancel Order" -msgstr "إلغاء الطلب" - -#: inventory/models.py:1017 templates/sales/estimates/estimate_detail.html:108 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_create.html:24 -#: venv/lib/python3.11/site-packages/django_ledger/views/invoice.py:68 -msgid "Create Invoice" -msgstr "إنشاء فاتورة" - -#: inventory/models.py:1018 -msgid "Cancel Invoice" -msgstr "إلغاء الفاتورة" - -#: inventory/models.py:1022 -msgid "Prospect" -msgstr "العميل المحتمل" - -#: inventory/models.py:1023 -msgid "Proposal" -msgstr "عرض" - -#: inventory/models.py:1024 -msgid "Negotiation" -msgstr "مفاوضات" - -#: inventory/models.py:1025 -msgid "Closed Won" -msgstr "مغلقة - ناجحة" - -#: inventory/models.py:1026 -msgid "Closed Lost" -msgstr "مغلقة - خسارة" - -#: inventory/models.py:1030 -msgid "Low" -msgstr "منخفض" - -#: inventory/models.py:1031 -msgid "Medium" -msgstr "متوسط" - -#: inventory/models.py:1032 -msgid "High" -msgstr "مرتفع" - -#: inventory/models.py:1045 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:11 -msgid "Title" -msgstr "العنوان" - -#: inventory/models.py:1053 -msgid "Male" -msgstr "ذكر" - -#: inventory/models.py:1053 -msgid "Female" -msgstr "أنثى" - -#: inventory/models.py:1055 -msgid "Gender" -msgstr "الجنس" - -#: inventory/models.py:1057 -msgid "Date of Birth" -msgstr "تاريخ الميلاد" - -#: inventory/models.py:1060 templates/customers/customer_list.html:46 -msgid "National ID" -msgstr "رقم الهوية الوطنية" - -#: inventory/models.py:1068 inventory/models.py:1166 +#: inventory/models.py:1017 inventory/models.py:1208 inventory/models.py:1332 +#: inventory/models.py:1886 templates/admin_management/user_management.html:35 +#: templates/admin_management/user_management.html:99 +#: templates/admin_management/user_management.html:163 +#: templates/admin_management/user_management.html:227 #: templates/customers/customer_list.html:56 -#: templates/dealers/dealer_detail.html:105 +#: templates/dealers/dealer_detail.html:111 #: templates/ledger/coa_accounts/account_detail.html:55 -#: templates/ledger/coa_accounts/account_list.html:52 +#: templates/ledger/coa_accounts/account_list.html:28 #: templates/plans/current.html:26 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:433 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:27 @@ -1334,13 +1124,287 @@ msgstr "رقم الهوية الوطنية" msgid "Active" msgstr "نشط" -#: inventory/models.py:1070 templates/administration/manage_service.html:76 +#: inventory/models.py:1082 inventory/models.py:1083 +#: templates/admin_management/user_management.html:206 +#: templates/crm/opportunities/opportunity_detail.html:233 +#: templates/dashboards/manager.html:16 templates/users/user_form.html:4 +#: templates/users/user_list.html:5 +msgid "Staff" +msgstr "الموظفون" + +#: inventory/models.py:1091 +msgid "Referrals" +msgstr "إحالات" + +#: inventory/models.py:1092 inventory/models.py:1139 +msgid "WhatsApp" +msgstr "واتساب" + +#: inventory/models.py:1094 +msgid "TikTok" +msgstr "تيك توك" + +#: inventory/models.py:1095 +msgid "Instagram" +msgstr "إنستغرام" + +#: inventory/models.py:1096 +msgid "X" +msgstr "إكس" + +#: inventory/models.py:1097 +msgid "Facebook" +msgstr "فيسبوك" + +#: inventory/models.py:1098 +msgid "Motory" +msgstr "موتري" + +#: inventory/models.py:1099 +msgid "Influencers" +msgstr "المؤثرون" + +#: inventory/models.py:1100 +msgid "Youtube" +msgstr "يوتيوب" + +#: inventory/models.py:1101 +msgid "Campaign" +msgstr "حملة" + +#: inventory/models.py:1105 +msgid "Walk In" +msgstr "زيارة مباشرة" + +#: inventory/models.py:1106 +msgid "Toll Free" +msgstr "رقم مجاني" + +#: inventory/models.py:1107 +#: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:113 +msgid "Website" +msgstr "الموقع الإلكتروني" + +#: inventory/models.py:1109 +msgid "Form" +msgstr "نموذج" + +#: inventory/models.py:1114 +msgid "Follow-up" +msgstr "متابعة" + +#: inventory/models.py:1115 inventory/models.py:1141 inventory/models.py:1164 +#: templates/crm/leads/lead_detail.html:58 +#: templates/crm/leads/lead_detail.html:136 +#: templates/crm/leads/lead_list.html:28 +#: templates/crm/leads/lead_tracking.html:104 +msgid "Negotiation" +msgstr "مفاوضات" + +#: inventory/models.py:1116 inventory/models.py:1143 +#: templates/crm/leads/lead_detail.html:59 +#: templates/crm/leads/lead_detail.html:138 +#: templates/crm/leads/lead_tracking.html:120 +msgid "Won" +msgstr "تم الفوز" + +#: inventory/models.py:1117 inventory/models.py:1144 +#: templates/crm/leads/lead_detail.html:60 +#: templates/crm/leads/lead_detail.html:140 +#: templates/crm/leads/lead_tracking.html:136 +msgid "Lost" +msgstr "تم الفقد" + +#: inventory/models.py:1118 inventory/models.py:1145 +#: templates/crm/leads/lead_detail.html:61 +#: templates/crm/leads/lead_detail.html:142 +#: templates/crm/leads/lead_list.html:29 +msgid "Closed" +msgstr "مغلقة" + +#: inventory/models.py:1122 +msgid "Mr" +msgstr "السيد" + +#: inventory/models.py:1123 +msgid "Mrs" +msgstr "السيدة" + +#: inventory/models.py:1124 +msgid "Ms" +msgstr "الآنسة" + +#: inventory/models.py:1125 +msgid "Miss" +msgstr "الآنسة" + +#: inventory/models.py:1126 +msgid "Dr" +msgstr "الدكتور" + +#: inventory/models.py:1127 +msgid "Prof" +msgstr "الأستاذ" + +#: inventory/models.py:1128 +msgid "Prince" +msgstr "الأمير" + +#: inventory/models.py:1129 +msgid "Princess" +msgstr "الأميرة" + +#: inventory/models.py:1130 templates/pricing_page.html:120 +#: templates/pricing_page.html:123 templates/pricing_page.html:187 +msgid "Company" +msgstr "الشركة" + +#: inventory/models.py:1131 +msgid "N/A" +msgstr "غير متوفر" + +#: inventory/models.py:1135 inventory/models.py:1644 +#: templates/components/activity_modal.html:17 +#: templates/crm/leads/lead_detail.html:70 +#: templates/crm/leads/lead_list.html:37 +msgid "Call" +msgstr "مكالمة" + +#: inventory/models.py:1136 +msgid "SMS" +msgstr "رسالة نصية" + +#: inventory/models.py:1138 inventory/models.py:1645 +#: templates/components/activity_modal.html:19 +#: templates/crm/leads/lead_detail.html:71 +#: templates/crm/leads/lead_list.html:38 +msgid "Meeting" +msgstr "اجتماع" + +#: inventory/models.py:1140 +msgid "Visit" +msgstr "زيارة" + +#: inventory/models.py:1142 templates/crm/leads/lead_detail.html:57 +#: templates/crm/leads/lead_detail.html:134 +#: templates/crm/leads/lead_list.html:26 templates/crm/leads/lead_list.html:41 +msgid "Follow Up" +msgstr "متابعة" + +#: inventory/models.py:1146 +msgid "Converted" +msgstr "تم التحويل" + +#: inventory/models.py:1148 templates/inventory/car_form.html:37 +#: templates/sales/estimates/estimate_form.html:20 +msgid "Add Car" +msgstr "إضافة سيارة" + +#: inventory/models.py:1149 +msgid "Sale Car" +msgstr "بيع سيارة" + +#: inventory/models.py:1150 templates/inventory/reserve_car.html:5 +#: templates/inventory/reserve_car.html:8 +msgid "Reserve Car" +msgstr "حجز السيارة" + +#: inventory/models.py:1151 templates/inventory/transfer_car.html:4 +msgid "Transfer Car" +msgstr "نقل السيارة" + +#: inventory/models.py:1152 +msgid "Remove Car" +msgstr "إزالة السيارة" + +#: inventory/models.py:1153 +#: templates/crm/opportunities/opportunity_detail.html:18 +#: templates/sales/estimates/estimate_form.html:5 +#: templates/sales/estimates/estimate_form.html:32 +msgid "Create Quotation" +msgstr "إنشاء عرض" + +#: inventory/models.py:1154 +msgid "Cancel Quotation" +msgstr "إلغاء العرض" + +#: inventory/models.py:1155 +msgid "Create Order" +msgstr "إنشاء طلب" + +#: inventory/models.py:1156 +msgid "Cancel Order" +msgstr "إلغاء الطلب" + +#: inventory/models.py:1157 templates/sales/estimates/estimate_detail.html:108 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_create.html:24 +#: venv/lib/python3.11/site-packages/django_ledger/views/invoice.py:68 +msgid "Create Invoice" +msgstr "إنشاء فاتورة" + +#: inventory/models.py:1158 +msgid "Cancel Invoice" +msgstr "إلغاء الفاتورة" + +#: inventory/models.py:1162 +msgid "Discovery" +msgstr "الاكتشاف" + +#: inventory/models.py:1163 +msgid "Proposal" +msgstr "عرض" + +#: inventory/models.py:1165 +msgid "Closed Won" +msgstr "مغلقة - ناجحة" + +#: inventory/models.py:1166 +msgid "Closed Lost" +msgstr "مغلقة - خسارة" + +#: inventory/models.py:1170 +msgid "Low" +msgstr "منخفض" + +#: inventory/models.py:1171 +msgid "Medium" +msgstr "متوسط" + +#: inventory/models.py:1172 +msgid "High" +msgstr "مرتفع" + +#: inventory/models.py:1185 inventory/models.py:1773 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:11 +msgid "Title" +msgstr "العنوان" + +#: inventory/models.py:1193 +msgid "Male" +msgstr "ذكر" + +#: inventory/models.py:1193 +msgid "Female" +msgstr "أنثى" + +#: inventory/models.py:1195 +msgid "Gender" +msgstr "الجنس" + +#: inventory/models.py:1197 +msgid "Date of Birth" +msgstr "تاريخ الميلاد" + +#: inventory/models.py:1200 templates/customers/customer_list.html:46 +msgid "National ID" +msgstr "رقم الهوية الوطنية" + +#: inventory/models.py:1210 templates/administration/manage_service.html:76 #: venv/lib/python3.11/site-packages/django/db/models/fields/files.py:420 msgid "Image" msgstr "الصورة" -#: inventory/models.py:1076 inventory/models.py:1263 -#: templates/crm/opportunities/opportunity_form.html:22 +#: inventory/models.py:1228 inventory/models.py:1456 #: templates/sales/estimates/estimate_detail.html:154 #: templates/sales/estimates/estimate_list.html:15 #: templates/sales/estimates/sale_order_preview.html:167 @@ -1355,7 +1419,8 @@ msgstr "الصورة" msgid "Customer" msgstr "العميل" -#: inventory/models.py:1077 templates/customers/customer_form.html:4 +#: inventory/models.py:1229 templates/admin_management/user_management.html:14 +#: templates/customers/customer_form.html:4 #: templates/customers/customer_list.html:4 #: templates/customers/customer_list.html:5 #: templates/customers/customer_list.html:9 @@ -1363,203 +1428,262 @@ msgstr "العميل" msgid "Customers" msgstr "العملاء" -#: inventory/models.py:1171 inventory/models.py:1263 +#: inventory/models.py:1349 inventory/models.py:1456 msgid "Organization" msgstr "شركة" -#: inventory/models.py:1172 templates/header.html:151 -#: templates/organizations/organization_list.html:5 +#: inventory/models.py:1350 templates/admin_management/user_management.html:78 +#: templates/header.html:165 templates/organizations/organization_list.html:5 #: templates/organizations/organization_list.html:8 #: templates/organizations/organization_list.html:14 msgid "Organizations" msgstr "الشركات" -#: inventory/models.py:1239 +#: inventory/models.py:1432 #: templates/representatives/representative_detail.html:8 #: templates/representatives/representative_list.html:18 msgid "ID Number" msgstr "رقم الهوية" -#: inventory/models.py:1249 +#: inventory/models.py:1442 msgid "Representative" msgstr "ممثل شركة" -#: inventory/models.py:1250 +#: inventory/models.py:1443 #: templates/representatives/representative_list.html:3 #: templates/representatives/representative_list.html:6 msgid "Representatives" msgstr "ممثلي الشركات" -#: inventory/models.py:1263 +#: inventory/models.py:1456 msgid "Lead Type" msgstr "نوع العميل المتوقع" -#: inventory/models.py:1290 templates/crm/leads/lead_list.html:65 +#: inventory/models.py:1484 msgid "Source" msgstr "المصدر" -#: inventory/models.py:1293 templates/crm/leads/lead_list.html:71 +#: inventory/models.py:1487 msgid "Channel" msgstr "القناة" -#: inventory/models.py:1301 +#: inventory/models.py:1495 msgid "address" msgstr "العنوان" -#: inventory/models.py:1308 +#: inventory/models.py:1502 msgid "Assigned" msgstr "مُعين" -#: inventory/models.py:1314 +#: inventory/models.py:1508 msgid "Priority" msgstr "الأولوية" -#: inventory/models.py:1329 +#: inventory/models.py:1519 templates/crm/leads/lead_detail.html:66 +#: templates/crm/leads/lead_detail.html:218 +#: templates/crm/leads/lead_list.html:34 +msgid "Next Action" +msgstr "الإجراء التالي" + +#: inventory/models.py:1524 templates/crm/leads/lead_detail.html:77 +#: templates/crm/leads/lead_list.html:46 +msgid "Next Action Date" +msgstr "تاريخ الإجراء التالي" + +#: inventory/models.py:1530 templates/crm/leads/lead_detail.html:175 +msgid "Salary" +msgstr "الراتب" + +#: inventory/models.py:1538 msgid "Lead" msgstr "فرصة" -#: inventory/models.py:1330 templates/crm/leads/lead_list.html:3 +#: inventory/models.py:1539 templates/crm/leads/lead_list.html:3 #: templates/crm/leads/lead_list.html:7 templates/crm/leads/lead_send.html:5 +#: templates/crm/leads/lead_tracking.html:3 #: templates/dashboards/manager.html:21 test.txt:21 msgid "Leads" msgstr "الفرص" -#: inventory/models.py:1398 +#: inventory/models.py:1636 msgid "Product Demo" msgstr "عرض توضيحي للمنتج" -#: inventory/models.py:1399 +#: inventory/models.py:1637 msgid "Follow-Up Call" msgstr "مكالمة متابعة" -#: inventory/models.py:1400 +#: inventory/models.py:1638 msgid "Contract Discussion" msgstr "مناقشة العقد" -#: inventory/models.py:1401 +#: inventory/models.py:1639 msgid "Sales Meeting" msgstr "اجتماع مبيعات" -#: inventory/models.py:1402 +#: inventory/models.py:1640 msgid "Support Call" msgstr "مكالمة دعم" -#: inventory/models.py:1403 +#: inventory/models.py:1641 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:240 #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:511 msgid "Other" msgstr "أخرى" -#: inventory/models.py:1407 -msgid "Meeting" -msgstr "اجتماع" - -#: inventory/models.py:1411 +#: inventory/models.py:1649 msgid "Scheduled" msgstr "مجدول" -#: inventory/models.py:1412 templates/sales/estimates/estimate_detail.html:88 +#: inventory/models.py:1650 inventory/models.py:1776 +#: templates/sales/estimates/estimate_detail.html:88 #: templates/sales/estimates/estimate_detail.html:175 #: templates/sales/estimates/estimate_list.html:39 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:226 msgid "Completed" msgstr "مكتمل" -#: inventory/models.py:1445 +#: inventory/models.py:1651 templates/crm/leads/lead_list.html:175 +#: templates/sales/estimates/estimate_detail.html:90 +#: templates/sales/estimates/estimate_detail.html:177 +#: templates/sales/estimates/estimate_list.html:37 +#: templates/sales/invoices/invoice_list.html:34 test.txt:59 +#: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:347 +#: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:228 +#: venv/lib/python3.11/site-packages/django_ledger/models/invoice.py:305 +#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1042 +#: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:196 +msgid "Canceled" +msgstr "ملغى" + +#: inventory/models.py:1683 msgid "Old Status" msgstr "الحالة القديمة" -#: inventory/models.py:1448 +#: inventory/models.py:1686 msgid "New Status" msgstr "الحالة الجديدة" -#: inventory/models.py:1453 +#: inventory/models.py:1691 msgid "Changed At" msgstr "تم التغيير في" -#: inventory/models.py:1456 +#: inventory/models.py:1694 msgid "Lead Status History" msgstr "تاريخ حالة العميل المحتمل" -#: inventory/models.py:1457 +#: inventory/models.py:1695 msgid "Lead Status Histories" msgstr "تواريخ حالات العملاء المحتملين" -#: inventory/models.py:1465 +#: inventory/models.py:1703 msgid "Probability must be between 0 and 100." msgstr "يجب أن تكون الاحتمالية بين 0 و 100." -#: inventory/models.py:1496 -#: templates/crm/opportunities/opportunity_detail.html:264 -#: templates/crm/opportunities/opportunity_form.html:79 +#: inventory/models.py:1729 +#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:78 +#: templates/crm/opportunities/partials/opportunity_grid.html:60 +msgid "Expected Revenue" +msgstr "الإيرادات المتوقعة" + +#: inventory/models.py:1731 +#: templates/crm/opportunities/opportunity_detail.html:266 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:100 -#: templates/crm/opportunities/opportunity_list.html:94 -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:71 +#: templates/crm/opportunities/partials/opportunity_grid.html:72 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:75 msgid "Closing Date" msgstr "تاريخ الإغلاق" -#: inventory/models.py:1499 -msgid "Closed" -msgstr "مغلقة" +#: inventory/models.py:1736 +msgid "Unique slug for the opportunity." +msgstr "المُعرّف الفريد للفرصة (slug)." -#: inventory/models.py:1502 +#: inventory/models.py:1742 templates/crm/leads/lead_list.html:128 +#: templates/header.html:148 msgid "Opportunity" msgstr "فرصة" -#: inventory/models.py:1503 +#: inventory/models.py:1743 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:8 #: templates/crm/opportunities/opportunity_list.html:8 msgid "Opportunities" msgstr "الفرص" -#: inventory/models.py:1513 inventory/models.py:1521 +#: inventory/models.py:1754 inventory/models.py:1762 #: templates/account/snippets/already_logged_in.html:8 -#: templates/crm/leads/lead_detail.html:226 -#: templates/customers/view_customer.html:91 +#: templates/crm/leads/lead_detail.html:314 +#: templates/crm/leads/lead_detail.html:592 +#: templates/customers/view_customer.html:95 msgid "Note" msgstr "ملاحظة" -#: inventory/models.py:1522 inventory/models.py:1558 -#: templates/crm/leads/lead_detail.html:137 -#: templates/crm/leads/lead_detail.html:213 -#: templates/crm/leads/lead_detail.html:387 -#: templates/customers/view_customer.html:188 +#: inventory/models.py:1763 inventory/models.py:1824 +#: templates/crm/leads/lead_detail.html:82 +#: templates/crm/leads/lead_detail.html:222 +#: templates/crm/leads/lead_detail.html:305 +#: templates/crm/leads/lead_list.html:51 +#: templates/customers/view_customer.html:192 #: templates/plans/invoices/layout.html:175 #: venv/lib/python3.11/site-packages/django_ledger/forms/bill.py:154 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/includes/card_markdown.html:9 msgid "Notes" msgstr "ملاحظات" -#: inventory/models.py:1531 +#: inventory/models.py:1775 +#: templates/ledger/journal_entry/includes/card_invoice.html:52 +#: templates/ledger/journal_entry/includes/card_invoice.html:63 +#: templates/ledger/journal_entry/includes/card_invoice.html:77 +#: templates/plans/invoices/layout.html:161 +#: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:976 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:72 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:89 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:110 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:63 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:80 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:101 +msgid "Due Date" +msgstr "تاريخ الاستحقاق" + +#: inventory/models.py:1787 templates/crm/leads/lead_detail.html:572 +msgid "Task" +msgstr "مهمة" + +#: inventory/models.py:1788 templates/crm/leads/lead_detail.html:224 +#: templates/crm/leads/lead_detail.html:485 +msgid "Tasks" +msgstr "مهام" + +#: inventory/models.py:1797 msgid "From Email" msgstr "من البريد الإلكتروني" -#: inventory/models.py:1532 +#: inventory/models.py:1798 msgid "To Email" msgstr "إلى البريد الإلكتروني" -#: inventory/models.py:1533 +#: inventory/models.py:1799 msgid "Subject" msgstr "الموضوع" -#: inventory/models.py:1534 inventory/models.py:1577 +#: inventory/models.py:1800 inventory/models.py:1843 msgid "Message" msgstr "رسالة" -#: inventory/models.py:1544 templates/crm/leads/lead_detail.html:138 -#: templates/crm/leads/lead_detail.html:265 +#: inventory/models.py:1810 templates/crm/leads/lead_detail.html:223 +#: templates/crm/leads/lead_detail.html:362 msgid "Emails" msgstr "رسائل البريد الإلكتروني" -#: inventory/models.py:1556 +#: inventory/models.py:1822 msgid "Activity Type" msgstr "نوع النشاط" -#: inventory/models.py:1566 templates/crm/leads/lead_detail.html:136 +#: inventory/models.py:1832 templates/components/activity_modal.html:7 +#: templates/crm/leads/lead_detail.html:221 #: templates/dealers/activity_log.html:11 #: templates/ledger/journal_entry/includes/card_journal_entry.html:32 -#: templates/ledger/journal_entry/journal_entry_list.html:64 -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:384 +#: templates/ledger/journal_entry/journal_entry_list.html:50 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:396 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:388 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_txs_table.html:10 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:33 @@ -1567,376 +1691,375 @@ msgstr "نوع النشاط" msgid "Activity" msgstr "النشاط" -#: inventory/models.py:1567 templates/crm/leads/lead_detail.html:166 -#: templates/header.html:418 +#: inventory/models.py:1833 templates/crm/leads/lead_detail.html:257 +#: templates/header.html:434 msgid "Activities" msgstr "الأنشطة" -#: inventory/models.py:1578 +#: inventory/models.py:1844 msgid "Is Read" msgstr "تمت قراءته" -#: inventory/models.py:1582 +#: inventory/models.py:1848 msgid "Notification" msgstr "إشعار" -#: inventory/models.py:1583 templates/crm/notifications_history.html:6 -#: templates/notifications.html:13 +#: inventory/models.py:1849 templates/crm/notifications_history.html:6 +#: templates/notifications-copy.html:13 templates/notifications.html:23 msgid "Notifications" msgstr "الإشعارات" -#: inventory/models.py:1599 +#: inventory/models.py:1873 msgid "Vendor Model" msgstr "نموذج المورد" -#: inventory/models.py:1616 templates/vendors/vendor_form.html:4 -#: templates/vendors/vendors_list.html:4 templates/vendors/vendors_list.html:5 -#: templates/vendors/vendors_list.html:12 +#: inventory/models.py:1902 templates/admin_management/user_management.html:142 +#: templates/vendors/vendor_form.html:4 templates/vendors/vendors_list.html:5 +#: templates/vendors/vendors_list.html:7 templates/vendors/vendors_list.html:12 msgid "Vendors" msgstr "الموردين" -#: inventory/models.py:1682 inventory/models.py:1706 +#: inventory/models.py:1974 inventory/models.py:1998 msgid "amount" msgstr "المبلغ" -#: inventory/models.py:1685 +#: inventory/models.py:1977 msgid "method" msgstr "طريقة" -#: inventory/models.py:1688 +#: inventory/models.py:1980 msgid "reference number" msgstr "رقم المرجع" -#: inventory/models.py:1690 +#: inventory/models.py:1982 msgid "date" msgstr "التاريخ" -#: inventory/models.py:1694 +#: inventory/models.py:1986 msgid "payment" msgstr "الدفعة" -#: inventory/models.py:1695 templates/header.html:102 +#: inventory/models.py:1987 templates/header.html:102 msgid "payments" msgstr "المدفوعات" -#: inventory/models.py:1708 +#: inventory/models.py:2000 msgid "reason" msgstr "السبب" -#: inventory/models.py:1709 +#: inventory/models.py:2001 msgid "refund date" msgstr "تاريخ الاسترداد" -#: inventory/models.py:1712 +#: inventory/models.py:2004 msgid "refund" msgstr "استرداد" -#: inventory/models.py:1713 +#: inventory/models.py:2005 msgid "refunds" msgstr "استردادات" -#: inventory/models.py:1725 +#: inventory/models.py:2017 msgid "User Activity Log" msgstr "سجل نشاط المستخدم" -#: inventory/models.py:1726 +#: inventory/models.py:2018 msgid "User Activity Logs" msgstr "سجلات نشاط المستخدم" -#: inventory/models.py:1737 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3160 +#: inventory/models.py:2029 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3173 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/card_estimate.html:9 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:9 msgid "Estimate" msgstr "تقدير" -#: inventory/models.py:1748 inventory/tasks.py:39 +#: inventory/models.py:2040 inventory/tasks.py:38 #: templates/ledger/reports/dashboard.html:32 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/includes/widget_bs.html:14 msgid "Cash" msgstr "نقداً" -#: inventory/models.py:1749 +#: inventory/models.py:2041 msgid "Finance" msgstr "تمويل" -#: inventory/models.py:1750 +#: inventory/models.py:2042 msgid "Lease" msgstr "تأجير" -#: inventory/models.py:1751 +#: inventory/models.py:2043 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:1139 msgid "Credit Card" msgstr "بطاقة ائتمان" -#: inventory/models.py:1752 +#: inventory/models.py:2044 msgid "Bank Transfer" msgstr "تحويل بنكي" -#: inventory/models.py:1796 templates/groups/group_form.html:4 +#: inventory/models.py:2088 templates/groups/group_form.html:4 #: templates/groups/group_list.html:5 templates/users/user_group_form.html:4 msgid "Group" msgstr "مجموعة" -#: inventory/models.py:1963 +#: inventory/models.py:2255 msgid "Payment History" msgstr "سجل الدفع" -#: inventory/models.py:1964 +#: inventory/models.py:2256 msgid "Payment Histories" msgstr "سجلات الدفع" -#: inventory/tables.py:59 templates/inventory/car_inventory.html:55 +#: inventory/tables.py:59 templates/inventory/car_inventory.html:70 msgid "Exterior Color" msgstr "اللون الخارجي" -#: inventory/tables.py:60 templates/inventory/car_inventory.html:56 +#: inventory/tables.py:60 templates/inventory/car_inventory.html:73 msgid "Interior Color" msgstr "اللون الداخلي" -#: inventory/tables.py:61 templates/inventory/car_inventory.html:59 -#: templates/inventory/car_list_view.html:114 +#: inventory/tables.py:61 templates/inventory/car_inventory.html:81 msgid "Age" msgstr "العمر" -#: inventory/tasks.py:51 templates/ledger/ledger/ledger_detail.html:38 +#: inventory/tasks.py:50 templates/ledger/ledger/ledger_detail.html:38 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_detail.html:41 msgid "Accounts Receivable" msgstr "الحسابات المدينة" -#: inventory/tasks.py:76 +#: inventory/tasks.py:75 msgid "Prepaid Expenses" msgstr "المصروفات المدفوعة مقدمًا" -#: inventory/tasks.py:88 +#: inventory/tasks.py:87 msgid "Employee Advance" msgstr "سلفة الموظف" -#: inventory/tasks.py:99 +#: inventory/tasks.py:98 msgid "VAT Receivable" msgstr "ضريبة القيمة المضافة المستحقة" -#: inventory/tasks.py:109 +#: inventory/tasks.py:108 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:452 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:538 msgid "Buildings - Accum. Depreciation" msgstr "المباني - الإهلاك المتراكم" -#: inventory/tasks.py:121 +#: inventory/tasks.py:120 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:459 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:545 msgid "Intangible Assets" msgstr "الأصول غير الملموسة" -#: inventory/tasks.py:133 +#: inventory/tasks.py:132 msgid "Investments" msgstr "الاستثمارات" -#: inventory/tasks.py:170 +#: inventory/tasks.py:169 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:451 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:537 msgid "Buildings" msgstr "المباني" -#: inventory/tasks.py:184 +#: inventory/tasks.py:183 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:466 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:552 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:52 msgid "Accounts Payable" msgstr "الحسابات الدائنة" -#: inventory/tasks.py:196 templates/ledger/ledger/ledger_detail.html:46 +#: inventory/tasks.py:195 templates/ledger/ledger/ledger_detail.html:46 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:472 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:558 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/invoice_detail.html:51 msgid "Deferred Revenue" msgstr "الإيرادات المؤجلة" -#: inventory/tasks.py:208 +#: inventory/tasks.py:207 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:467 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:553 msgid "Wages Payable" msgstr "الأجور المستحقة الدفع" -#: inventory/tasks.py:220 +#: inventory/tasks.py:219 msgid "Long-Term Notes Payable" msgstr "أوراق الدفع طويلة الأجل" -#: inventory/tasks.py:232 +#: inventory/tasks.py:231 msgid "VAT Payable" msgstr "ضريبة القيمة المضافة المستحقة الدفع" -#: inventory/tasks.py:242 +#: inventory/tasks.py:241 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:469 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:555 msgid "Taxes Payable" msgstr "الضرائب المستحقة الدفع" -#: inventory/tasks.py:252 +#: inventory/tasks.py:251 msgid "Social Insurance Payable" msgstr "التأمينات الاجتماعية المستحقة الدفع" -#: inventory/tasks.py:258 +#: inventory/tasks.py:257 msgid "End of Service Benefits" msgstr "مكافأة نهاية الخدمة" -#: inventory/tasks.py:265 +#: inventory/tasks.py:264 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:478 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:564 msgid "Mortgage Payable" msgstr "الرهن المستحق الدفع" -#: inventory/tasks.py:273 +#: inventory/tasks.py:272 msgid "Registered Capital" msgstr "رأس المال المسجل" -#: inventory/tasks.py:276 +#: inventory/tasks.py:275 msgid "Additional Paid-In Capital" msgstr "رأس المال المدفوع الإضافي" -#: inventory/tasks.py:279 +#: inventory/tasks.py:278 msgid "Opening Balances" msgstr "الأرصدة الافتتاحية" -#: inventory/tasks.py:284 +#: inventory/tasks.py:283 msgid "Statutory Reserve" msgstr "الاحتياطي النظامي" -#: inventory/tasks.py:287 +#: inventory/tasks.py:286 msgid "Foreign Currency Translation Reserve" msgstr "احتياطي تحويل العملات الأجنبية" -#: inventory/tasks.py:294 +#: inventory/tasks.py:293 msgid "Operating Profits and Losses" msgstr "الأرباح والخسائر التشغيلية" -#: inventory/tasks.py:305 +#: inventory/tasks.py:304 msgid "Retained Earnings (or Losses)" msgstr "الأرباح المحتجزة (أو الخسائر)" -#: inventory/tasks.py:315 +#: inventory/tasks.py:314 msgid "Sales Revenue" msgstr "إيرادات المبيعات" -#: inventory/tasks.py:327 +#: inventory/tasks.py:326 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:492 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:580 msgid "Interest Income" msgstr "دخل الفائدة" -#: inventory/tasks.py:339 +#: inventory/tasks.py:338 msgid "Unearned Income" msgstr "الدخل غير المكتسب" -#: inventory/tasks.py:345 +#: inventory/tasks.py:344 msgid "Sales/Service Revenue" msgstr "إيرادات المبيعات/الخدمات" -#: inventory/tasks.py:348 +#: inventory/tasks.py:347 msgid "Non-Operating Revenues" msgstr "الإيرادات غير التشغيلية" -#: inventory/tasks.py:356 inventory/tasks.py:537 +#: inventory/tasks.py:355 inventory/tasks.py:536 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:497 #: venv/lib/python3.11/site-packages/django_ledger/io/roles.py:587 msgid "Cost of Goods Sold" msgstr "تكلفة البضائع المباعة" -#: inventory/tasks.py:369 +#: inventory/tasks.py:368 msgid "Accrued Expenses" msgstr "المصروفات المستحقة" -#: inventory/tasks.py:379 +#: inventory/tasks.py:378 msgid "Accrued Salaries" msgstr "الرواتب المستحقة" -#: inventory/tasks.py:389 +#: inventory/tasks.py:388 msgid "Rent Expense" msgstr "مصروف الإيجار" -#: inventory/tasks.py:401 +#: inventory/tasks.py:400 msgid "Salaries and Administrative Fees" msgstr "الرواتب والرسوم الإدارية" -#: inventory/tasks.py:411 +#: inventory/tasks.py:410 msgid "Medical Insurance" msgstr "التأمين الطبي" -#: inventory/tasks.py:421 +#: inventory/tasks.py:420 msgid "Marketing and Advertising Expenses" msgstr "مصروفات التسويق والإعلان" -#: inventory/tasks.py:431 +#: inventory/tasks.py:430 msgid "Commissions and Incentives" msgstr "العمولات والحوافز" -#: inventory/tasks.py:441 +#: inventory/tasks.py:440 msgid "Travel Tickets" msgstr "تذاكر السفر" -#: inventory/tasks.py:451 +#: inventory/tasks.py:450 msgid "Social Insurance" msgstr "التأمينات الاجتماعية" -#: inventory/tasks.py:461 +#: inventory/tasks.py:460 msgid "Government Fees" msgstr "الرسوم الحكومية" -#: inventory/tasks.py:471 +#: inventory/tasks.py:470 msgid "Fees and Subscriptions" msgstr "الرسوم والاشتراكات" -#: inventory/tasks.py:481 +#: inventory/tasks.py:480 msgid "Office Services Expenses" msgstr "مصروفات خدمات المكتب" -#: inventory/tasks.py:491 +#: inventory/tasks.py:490 msgid "Office Supplies and Printing" msgstr "اللوازم المكتبية والطباعة" -#: inventory/tasks.py:501 +#: inventory/tasks.py:500 msgid "Hospitality Expenses" msgstr "مصروفات الضيافة" -#: inventory/tasks.py:511 +#: inventory/tasks.py:510 msgid "Bank Commissions" msgstr "عمولات البنوك" -#: inventory/tasks.py:521 +#: inventory/tasks.py:520 #: templates/ledger/reports/tags/income_statement.html:223 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:291 msgid "Other Expenses" msgstr "مصروفات أخرى" -#: inventory/tasks.py:531 +#: inventory/tasks.py:530 msgid "Transportation Expenses" msgstr "مصروفات النقل" -#: inventory/tasks.py:538 +#: inventory/tasks.py:537 msgid "Salaries and Wages" msgstr "الرواتب والأجور" -#: inventory/tasks.py:539 +#: inventory/tasks.py:538 msgid "Sales Commissions" msgstr "عمولات المبيعات" -#: inventory/tasks.py:540 +#: inventory/tasks.py:539 msgid "Shipping and Customs Clearance" msgstr "الشحن والتخليص الجمركي" -#: inventory/tasks.py:543 +#: inventory/tasks.py:542 msgid "Zakat" msgstr "الزكاة" -#: inventory/tasks.py:544 +#: inventory/tasks.py:543 msgid "Taxes" msgstr "الضرائب" -#: inventory/tasks.py:545 +#: inventory/tasks.py:544 msgid "Foreign Currency Translation" msgstr "تحويل العملات الأجنبية" -#: inventory/tasks.py:546 +#: inventory/tasks.py:545 msgid "Interest Expenses" msgstr "مصروفات الفائدة" @@ -1944,8 +2067,8 @@ msgstr "مصروفات الفائدة" msgid "success" msgstr "ناجحة" -#: inventory/utils.py:75 templates/inventory/car_form.html:383 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:427 +#: inventory/utils.py:75 templates/inventory/car_form.html:386 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:381 msgid "error" msgstr "خطأ" @@ -1962,93 +2085,89 @@ msgstr "تم حجز السيارة بنجاح." msgid "Enter a valid Saudi phone number (05XXXXXXXX or +9665XXXXXXXX)" msgstr "أدخل رقم جوال سعودي صحيح 05XXXXXXXX" -#: inventory/views.py:293 +#: inventory/views.py:270 msgid "Passwords do not match" msgstr "كلمات المرور غير متطابقة." -#: inventory/views.py:297 inventory/views.py:2596 +#: inventory/views.py:275 inventory/views.py:2641 msgid "User created successfully" msgstr "تم إنشاء المستخدم بنجاح." -#: inventory/views.py:595 +#: inventory/views.py:578 msgid "Car saved successfully" msgstr "تم حفظ السيارة بنجاح" -#: inventory/views.py:665 +#: inventory/views.py:650 msgid "VIN number exists" msgstr "رقم الهيكل موجود مسبقاً" -#: inventory/views.py:669 -msgid "Invalid VIN number provided" -msgstr "تم تقديم رقم تعريف مركبة (VIN) غير صالح" - -#: inventory/views.py:678 +#: inventory/views.py:664 msgid "VIN not found in all sources" msgstr "لم يتم العثور على رقم التعريف (VIN) في جميع المصادر" -#: inventory/views.py:691 +#: inventory/views.py:680 msgid "Manufacturer not found in the database" msgstr "لم يتم العثور على الشركة المصنعة في قاعدة البيانات" -#: inventory/views.py:731 +#: inventory/views.py:721 msgid "Server error occurred" msgstr "حدث خطأ في الخادم" -#: inventory/views.py:841 +#: inventory/views.py:819 msgid "No image provided" msgstr "لم يتم تقديم صورة" -#: inventory/views.py:853 +#: inventory/views.py:832 msgid "No QR/Barcode detected" msgstr "لم يتم اكتشاف رمز QR أو الباركود" -#: inventory/views.py:895 templates/dashboards/manager.html:48 -#: templates/dashboards/sales.html:112 templates/inventory/car_inventory.html:5 -#: templates/inventory/inventory_stats.html:5 +#: inventory/views.py:878 templates/dashboards/manager.html:48 +#: templates/dashboards/sales.html:112 templates/inventory/car_inventory.html:4 +#: templates/inventory/inventory_stats.html:4 msgid "inventory" msgstr "المخزون" -#: inventory/views.py:1224 +#: inventory/views.py:1214 msgid "Car finance details saved successfully" msgstr "تم حفظ تفاصيل المالية للسيارة بنجاح." -#: inventory/views.py:1270 +#: inventory/views.py:1261 msgid "Car finance details updated successfully" msgstr "تم تحديث تفاصيل المالية للسيارة بنجاح." -#: inventory/views.py:1322 +#: inventory/views.py:1314 msgid "Car updated successfully" msgstr "تم تحديث السيارة بنجاح" -#: inventory/views.py:1360 +#: inventory/views.py:1354 msgid "Car deleted successfully" msgstr "تم حذف السيارة بنجاح." -#: inventory/views.py:1396 +#: inventory/views.py:1391 msgid "Location saved successfully" msgstr "تم حفظ يوم الإجازة بنجاح." -#: inventory/views.py:1434 +#: inventory/views.py:1430 msgid "Location updated successfully" msgstr "تم تحديث البريد الإلكتروني بنجاح!" -#: inventory/views.py:1539 +#: inventory/views.py:1537 msgid "Car transfer canceled successfully" msgstr "تم إلغاء نقل السيارة بنجاح." -#: inventory/views.py:1556 +#: inventory/views.py:1554 msgid "Car transfer approved successfully" msgstr "تمت الموافقة على نقل السيارة بنجاح." -#: inventory/views.py:1581 +#: inventory/views.py:1579 msgid "Car transfer rejected successfully" msgstr "تم رفض نقل السيارة بنجاح." -#: inventory/views.py:1593 +#: inventory/views.py:1591 msgid "Car Transfer Completed successfully." msgstr "تم إكمال نقل السيارة بنجاح." -#: inventory/views.py:1662 +#: inventory/views.py:1661 msgid "Custom Card added successfully" msgstr "تم إضافة البطاقة الجمركية بنجاح." @@ -2076,310 +2195,370 @@ msgstr "إجراء غير صالح." msgid "Invalid request method" msgstr "طريقة الطلب غير صالحة" -#: inventory/views.py:1855 +#: inventory/views.py:1857 msgid "Dealer updated successfully" msgstr "تم تحديث المعرض بنجاح." -#: inventory/views.py:1888 templates/header.html:143 +#: inventory/views.py:1891 templates/header.html:157 msgid "customers" msgstr "العملاء" -#: inventory/views.py:2105 +#: inventory/views.py:2052 +msgid "Customer Account with this email is Deactivated,Please Contact Admin" +msgstr "" +"تم تعطيل حساب العميل المرتبط بهذا البريد الإلكتروني، يرجى التواصل مع المسؤول" + +#: inventory/views.py:2057 +msgid "Customer with this email already exists" +msgstr "يوجد عميل مسجل مسبقًا بهذا البريد الإلكتروني" + +#: inventory/views.py:2127 msgid "Customer deactivated successfully" -msgstr "تم إلغاء تفعيل العميل بنجاح" +msgstr "تم تعطيل حساب العميل بنجاح" -#: inventory/views.py:2197 +#: inventory/views.py:2222 msgid "Vendor created successfully" -msgstr "تم إنشاء المورد بنجاح." +msgstr "تم إنشاء المورد بنجاح" -#: inventory/views.py:2235 +#: inventory/views.py:2230 +msgid "Vendor Account with this email is Deactivated,Please Contact Admin" +msgstr "" +"تم تعطيل حساب المورد المرتبط بهذا البريد الإلكتروني، يرجى التواصل مع المسؤول" + +#: inventory/views.py:2234 +msgid "Vendor with this email already exists" +msgstr "يوجد مورد مسجل مسبقًا بهذا البريد الإلكتروني" + +#: inventory/views.py:2273 msgid "Vendor updated successfully" msgstr "تم تحديث المورد بنجاح" -#: inventory/views.py:2278 +#: inventory/views.py:2316 msgid "Vendor deleted successfully" msgstr "تم حذف المورد بنجاح." -#: inventory/views.py:2363 +#: inventory/views.py:2404 msgid "Group created successfully" msgstr "تم إنشاء المجموعة بنجاح." -#: inventory/views.py:2405 +#: inventory/views.py:2447 msgid "Group updated successfully" msgstr "تم تحديث المجموعة بنجاح." -#: inventory/views.py:2432 +#: inventory/views.py:2474 msgid "Group deleted successfully" msgstr "تم حذف المجموعة بنجاح." -#: inventory/views.py:2466 +#: inventory/views.py:2508 msgid "Permission added successfully" msgstr "تمت إضافة الإذن بنجاح." -#: inventory/views.py:2502 +#: inventory/views.py:2544 msgid "Group added successfully" msgstr "تمت إضافة المجموعة بنجاح." -#: inventory/views.py:2608 +#: inventory/views.py:2656 msgid "" "You have reached the maximum number of staff users allowed for your plan" msgstr "لقد وصلت إلى الحد الأقصى لعدد أعضاء الفريق المسموح به في خطتك." -#: inventory/views.py:2662 +#: inventory/views.py:2713 msgid "User updated successfully" msgstr "تم تحديث المستخدم بنجاح" -#: inventory/views.py:2714 +#: inventory/views.py:2764 msgid "User deleted successfully" msgstr "تم حذف المستخدم بنجاح." -#: inventory/views.py:2851 +#: inventory/views.py:2856 +msgid "" +"Organization Account with this email is Deactivated,Please Contact Admin" +msgstr "" +"تم تعطيل حساب المؤسسة المرتبط بهذا البريد الإلكتروني، يرجى التواصل مع المسؤول" + +#: inventory/views.py:2861 +msgid "Organization with this email already exists" +msgstr "يوجد مؤسسة مسجلة مسبقًا بهذا البريد الإلكتروني" + +#: inventory/views.py:2922 msgid "Organization Deactivated successfully" msgstr "تم إلغاء تفعيل المؤسسة بنجاح" -#: inventory/views.py:2933 +#: inventory/views.py:3007 msgid "Representative created successfully" msgstr "تم إنشاء الخدمة بنجاح." -#: inventory/views.py:2975 +#: inventory/views.py:3050 msgid "Representative updated successfully" msgstr "تم تحديث الخدمة بنجاح." -#: inventory/views.py:2999 +#: inventory/views.py:3075 msgid "Representative deleted successfully" msgstr "تم حذف الخدمة بنجاح!" -#: inventory/views.py:3070 +#: inventory/views.py:3148 msgid "Bank account created successfully" msgstr "تم إنشاء المنظمة بنجاح." -#: inventory/views.py:3141 +#: inventory/views.py:3221 msgid "Bank account updated successfully" msgstr "تم تحديث المجموعة بنجاح." -#: inventory/views.py:3177 +#: inventory/views.py:3257 msgid "Bank account deleted successfully" msgstr "تم حذف الملاحظة بنجاح." -#: inventory/views.py:3263 +#: inventory/views.py:3345 msgid "Account created successfully" msgstr "تم إنشاء المجموعة بنجاح." -#: inventory/views.py:3378 +#: inventory/views.py:3459 msgid "Account updated successfully" msgstr "تم تحديث المجموعة بنجاح." -#: inventory/views.py:3406 +#: inventory/views.py:3487 msgid "Account deleted successfully" msgstr "تم حذف الملاحظة بنجاح." -#: inventory/views.py:3519 inventory/views.py:5886 +#: inventory/views.py:3601 inventory/views.py:6168 msgid "Items and Quantities are required" msgstr "المنتجات والكميات مطلوبة" -#: inventory/views.py:3526 inventory/views.py:3531 inventory/views.py:5892 -#: inventory/views.py:5897 +#: inventory/views.py:3610 inventory/views.py:3618 inventory/views.py:6176 +#: inventory/views.py:6184 msgid "Quantity must be greater than zero" msgstr "يجب أن تكون مدة الفاصل الزمني أكبر من 0." -#: inventory/views.py:3540 inventory/views.py:3548 +#: inventory/views.py:3631 inventory/views.py:3644 msgid "Quantity must be less than or equal to the number of cars in stock" msgstr "يجب أن تكون الكمية أقل من أو تساوي عدد السيارات المتوفرة في المخزون" -#: inventory/views.py:3640 +#: inventory/views.py:3760 msgid "Quotation created successfully" msgstr "تم إنشاء عرض السعر بنجاح" -#: inventory/views.py:3891 +#: inventory/views.py:4037 msgid "Quotation is not ready for review" msgstr "العرض غير جاهز للمراجعة." -#: inventory/views.py:3897 +#: inventory/views.py:4043 msgid "Quotation is not ready for approval" msgstr "العرض غير جاهز للموافقة." -#: inventory/views.py:3900 +#: inventory/views.py:4046 msgid "Quotation approved successfully" msgstr "تمت الموافقة على العرض بنجاح." -#: inventory/views.py:3903 +#: inventory/views.py:4049 msgid "Quotation is not ready for rejection" msgstr "العرض غير جاهز للرفض." -#: inventory/views.py:3906 inventory/views.py:3924 +#: inventory/views.py:4052 inventory/views.py:4070 msgid "Quotation canceled successfully" msgstr "تم إلغاء الحجز بنجاح." -#: inventory/views.py:3909 +#: inventory/views.py:4055 msgid "Quotation is not ready for completion" msgstr "العرض غير جاهز للإكمال." -#: inventory/views.py:3913 +#: inventory/views.py:4059 msgid "Quotation is not ready for cancellation" msgstr "العرض غير جاهز للإلغاء." -#: inventory/views.py:3926 +#: inventory/views.py:4072 msgid "Quotation marked as " msgstr "تم وضع علامة على عرض السعر كـ" -#: inventory/views.py:4340 +#: inventory/views.py:4492 msgid "fully paid" msgstr "مدفوع بالكامل" -#: inventory/views.py:4343 +#: inventory/views.py:4495 msgid "Amount exceeds due amount" msgstr "المبلغ يتجاوز المبلغ المستحق" -#: inventory/views.py:4351 inventory/views.py:4461 +#: inventory/views.py:4503 inventory/views.py:4621 msgid "Payment created successfully" msgstr "تم إنشاء الدفعة بنجاح" -#: inventory/views.py:4465 +#: inventory/views.py:4625 msgid "Invoice is not fully paid, Payment cannot be marked as paid" msgstr "لم يتم دفع الفاتورة بالكامل، لا يمكن وضع علامة مدفوعة على الدفعة" -#: inventory/views.py:4663 +#: inventory/views.py:4830 msgid "Lead created successfully" msgstr "تم إنشاء العميل المتوقع بنجاح" -#: inventory/views.py:4728 +#: inventory/views.py:4985 msgid "Lead deleted successfully" msgstr "تم حذف العميل المتوقع بنجاح" -#: inventory/views.py:4757 inventory/views.py:4786 +#: inventory/views.py:5014 inventory/views.py:5045 inventory/views.py:8076 msgid "Note added successfully" msgstr "تمت إضافة الملاحظة بنجاح" -#: inventory/views.py:4783 +#: inventory/views.py:5040 msgid "Notes field is required" msgstr "حقل الملاحظات مطلوب" -#: inventory/views.py:4819 -msgid "Note updated successfully" -msgstr "تم تحديث الملاحظة بنجاح" - -#: inventory/views.py:4845 +#: inventory/views.py:5068 msgid "Note deleted successfully." msgstr "تم حذف الملاحظة بنجاح." -#: inventory/views.py:4871 +#: inventory/views.py:5094 msgid "Lead is already converted to customer" msgstr "تم تحويل العميل المتوقع بالفعل إلى عميل" -#: inventory/views.py:4875 +#: inventory/views.py:5105 msgid "Lead converted to customer successfully" msgstr "تم تحويل العميل المتوقع إلى عميل بنجاح" -#: inventory/views.py:4900 +#: inventory/views.py:5131 msgid "You do not have permission to schedule lead" msgstr "ليست لديك صلاحية جدولة هذا العميل المتوقع" -#: inventory/views.py:4941 +#: inventory/views.py:5175 msgid "Lead scheduled and appointment created successfully" msgstr "تمت جدولة العميل المتوقع وإنشاء الموعد بنجاح" -#: inventory/views.py:4971 +#: inventory/views.py:5206 msgid "Lead transferred successfully" msgstr "تم نقل العميل المتوقع بنجاح" -#: inventory/views.py:5004 +#: inventory/views.py:5253 msgid "Email Draft successfully" msgstr "تم إنشاء مسودة البريد الإلكتروني بنجاح" -#: inventory/views.py:5037 inventory/views.py:6098 +#: inventory/views.py:5288 inventory/views.py:6388 msgid "Email sent successfully" msgstr "تم إرسال البريد الإلكتروني بنجاح!" -#: inventory/views.py:5266 +#: inventory/views.py:5537 msgid "Opportunity deleted successfully" msgstr "تم حذف الفرصة بنجاح." -#: inventory/views.py:5304 +#: inventory/views.py:5575 msgid "Opportunity status updated successfully" msgstr "تم تحديث حالة الفرصة بنجاح" -#: inventory/views.py:5361 -msgid "Notification marked as read" -msgstr "تم تعليم الإشعار كمقروء" - -#: inventory/views.py:5418 +#: inventory/views.py:5691 msgid "Service created successfully" msgstr "تم إنشاء الخدمة بنجاح" -#: inventory/views.py:5462 +#: inventory/views.py:5736 msgid "Service updated successfully" msgstr "تم تحديث الخدمة بنجاح" -#: inventory/views.py:5718 inventory/views.py:5770 +#: inventory/views.py:5999 inventory/views.py:6052 msgid "Bill updated successfully" msgstr "تم تحديث الفاتورة بنجاح." -#: inventory/views.py:5811 +#: inventory/views.py:6093 msgid "Bill is already approved" msgstr "تمت الموافقة على الفاتورة مسبقًا." -#: inventory/views.py:5815 +#: inventory/views.py:6097 msgid "Bill marked as approved successfully" msgstr "تم تحديد الفاتورة كموافقة بنجاح." -#: inventory/views.py:5842 +#: inventory/views.py:6124 msgid "Bill is already paid" msgstr "تم دفع الفاتورة مسبقًا." -#: inventory/views.py:5851 +#: inventory/views.py:6133 msgid "Bill marked as paid successfully" msgstr "تم تحديد الفاتورة كمدفوعة بنجاح." -#: inventory/views.py:5853 +#: inventory/views.py:6135 msgid "Amount paid is not equal to amount due" msgstr "المبلغ المدفوع لا يساوي المبلغ المستحق." -#: inventory/views.py:5958 +#: inventory/views.py:6246 msgid "Bill created successfully" msgstr "تم تحديث الفاتورة بنجاح." -#: inventory/views.py:6059 +#: inventory/views.py:6349 msgid "Quotation has no items" msgstr "عرض السعر لا يحتوي على أي عناصر" -#: inventory/views.py:6607 +#: inventory/views.py:6905 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/unit/unit_detail.html:23 #: venv/lib/python3.11/site-packages/django_ledger/views/entity.py:210 msgid "Dashboard" msgstr "لوحة القيادة" -#: inventory/views.py:6762 inventory/views.py:6796 inventory/views.py:6856 +#: inventory/views.py:7060 inventory/views.py:7093 inventory/views.py:7152 msgid "Unauthorized" msgstr "غير مصرح" -#: inventory/views.py:6982 +#: inventory/views.py:7278 msgid "Settings updated" msgstr "تم تحديث الإعدادات" -#: inventory/views.py:7308 +#: inventory/views.py:7618 msgid "Journal Entry created" msgstr "تم إنشاء قيد اليومية" -#: inventory/views.py:7349 +#: inventory/views.py:7659 msgid "Journal Entry cannot be deleted" msgstr "لا يمكن حذف قيد اليومية" -#: inventory/views.py:7422 +#: inventory/views.py:7733 msgid "Ledger is already locked" msgstr "دفتر الأستاذ مقفل بالفعل" -#: inventory/views.py:7449 +#: inventory/views.py:7760 msgid "Ledger is already Unlocked" msgstr "دفتر الأستاذ غير مقفل بالفعل" -#: inventory/views.py:7478 +#: inventory/views.py:7789 msgid "Ledger is already posted" msgstr "دفتر الأستاذ تم ترحيله بالفعل" -#: inventory/views.py:7508 +#: inventory/views.py:7819 msgid "Ledger is already Unposted" msgstr "دفتر الأستاذ لم يتم ترحيله بعد" +#: inventory/views.py:8011 +msgid "Activity added successfully" +msgstr "تمت إضافة النشاط بنجاح" + +#: inventory/views.py:8013 +msgid "Activity form is not valid" +msgstr "نموذج النشاط غير صالح" + +#: inventory/views.py:8035 +msgid "Task added successfully" +msgstr "تمت إضافة المهمة بنجاح" + +#: inventory/views.py:8038 inventory/views.py:8051 +msgid "Task form is not valid" +msgstr "نموذج المهمة غير صالح" + +#: inventory/views.py:8049 +msgid "Task updated successfully" +msgstr "تم تحديث المهمة بنجاح" + +#: inventory/views.py:8079 inventory/views.py:8093 +msgid "Note form is not valid" +msgstr "نموذج الملاحظة غير صالح" + +#: inventory/views.py:8090 +msgid "Note updated successfully" +msgstr "تم تحديث الملاحظة بنجاح" + +#: inventory/views.py:8126 +msgid "Account activated successfully" +msgstr "تم تفعيل الحساب بنجاح" + +#: inventory/views.py:8143 +msgid "Account Deleted successfully" +msgstr "تم حذف الحساب بنجاح" + +#: inventory/views.py:8147 +msgid "You cannot delete this account,it is related to another account" +msgstr "لا يمكنك حذف هذا الحساب، لأنه مرتبط بحساب آخر" + #: templates/account/account_inactive.html:5 #: templates/account/account_inactive.html:9 msgid "Account Inactive" @@ -2412,11 +2591,11 @@ msgstr "" #: templates/account/confirm_email_verification_code.html:27 #: templates/account/email_confirm.html:35 #: templates/account/reauthenticate.html:18 -#: templates/inventory/transfer_details.html:27 +#: templates/inventory/transfer_details.html:34 #: templates/ledger/bills/bill_detail.html:11 #: templates/ledger/bills/bill_detail.html:36 #: templates/ledger/journal_entry/journal_entry_list.html:13 -#: templates/plans/billing_info_delete.html:13 templates/pricing_page.html:202 +#: templates/plans/billing_info_delete.html:13 templates/pricing_page.html:201 #: templates/sales/estimates/estimate_detail.html:52 #: templates/sales/invoices/invoice_detail.html:19 #: templates/sales/invoices/invoice_detail.html:43 @@ -2427,40 +2606,41 @@ msgstr "تأكيد" #: templates/account/confirm_email_verification_code.html:31 #: templates/account/confirm_email_verification_code.html:35 #: templates/account/confirm_login_code..html:38 -#: templates/crm/leads/lead_form.html:16 +#: templates/crm/leads/lead_form.html:32 #: templates/crm/leads/schedule_lead.html:18 -#: templates/crm/opportunities/opportunity_detail.html:58 -#: templates/crm/opportunities/opportunity_form.html:89 +#: templates/crm/opportunities/opportunity_detail.html:59 #: templates/customers/customer_form.html:33 -#: templates/dealers/dealer_form.html:22 templates/groups/group_form.html:35 +#: templates/dealers/dealer_form.html:21 templates/groups/group_form.html:35 #: templates/groups/group_permission_form.html:35 -#: templates/inventory/add_colors.html:57 -#: templates/inventory/add_custom_card.html:12 -#: templates/inventory/car_confirm_delete.html:14 -#: templates/inventory/car_detail.html:330 -#: templates/inventory/car_finance_form.html:41 -#: templates/inventory/car_registration_form.html:13 -#: templates/inventory/color_palette.html:107 -#: templates/inventory/reserve_car.html:30 -#: templates/inventory/transfer_preview.html:181 -#: templates/inventory/transfer_preview.html:200 -#: templates/ledger/bank_accounts/bank_account_form.html:33 -#: templates/ledger/bills/bill_form.html:42 +#: templates/inventory/add_colors.html:74 +#: templates/inventory/add_custom_card.html:13 +#: templates/inventory/car_confirm_delete.html:11 +#: templates/inventory/car_detail.html:359 +#: templates/inventory/car_finance_form.html:46 +#: templates/inventory/car_registration_form.html:14 +#: templates/inventory/color_palette.html:108 +#: templates/inventory/reserve_car.html:23 +#: templates/inventory/transfer_preview.html:222 +#: templates/inventory/transfer_preview.html:246 +#: templates/items/expenses/expense_create.html:22 +#: templates/items/service/service_create.html:24 +#: templates/ledger/bank_accounts/bank_account_form.html:34 +#: templates/ledger/bills/bill_form.html:43 #: templates/ledger/bills/bill_update_form.html:18 -#: templates/ledger/coa_accounts/account_form.html:32 +#: templates/ledger/coa_accounts/account_form.html:35 #: templates/ledger/journal_entry/includes/card_invoice.html:134 #: templates/ledger/journal_entry/journal_entry_form.html:17 -#: templates/ledger/ledger/ledger_form.html:17 +#: templates/ledger/ledger/ledger_form.html:23 #: templates/modal/event_details_modal.html:24 -#: templates/organizations/organization_form.html:20 +#: templates/organizations/organization_form.html:16 #: templates/representatives/representative_form.html:12 #: templates/sales/estimates/estimate_detail.html:120 -#: templates/sales/estimates/estimate_form.html:66 +#: templates/sales/estimates/estimate_form.html:77 #: templates/sales/estimates/estimate_send.html:26 #: templates/sales/journals/journal_form.html:19 #: templates/two_factor/_wizard_actions.html:5 -#: templates/users/user_form.html:41 templates/users/user_group_form.html:28 -#: templates/vendors/vendor_form.html:38 +#: templates/users/user_form.html:41 templates/users/user_group_form.html:24 +#: templates/vendors/vendor_form.html:42 #: venv/lib/python3.11/site-packages/appointment/templates/modal/event_details_modal.html:22 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_create.html:37 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:205 @@ -2476,7 +2656,7 @@ msgstr "إلغاء" #: templates/account/confirm_login_code..html:35 templates/account/login.html:6 #: templates/account/login.html:22 templates/account/login.html:46 #: templates/account/request_login_code.html:5 templates/account/signup.html:80 -#: templates/header.html:447 templates/welcome-temp.html:77 +#: templates/header.html:468 templates/welcome-temp.html:77 msgid "Sign In" msgstr "تسجيل الدخول" @@ -2506,6 +2686,7 @@ msgstr "تسجيل الدخول" #: templates/account/verification_sent.html:14 #: templates/account/verified_email_required.html:13 #: templates/account/verified_email_required.html:14 +#: templates/haikalbot/chatbot.html:62 templates/haikalbot/chatbot.html:63 #: templates/otp/verify_otp.html:11 templates/otp/verify_otp.html:12 msgid "home" msgstr "الرئيسية" @@ -2544,7 +2725,7 @@ msgstr "إعادة إرسال التحقق" #: templates/account/email.html:51 templates/administration/staff_list.html:48 #: templates/sales/estimates/estimate_form.html:53 -#: templates/sales/estimates/estimate_form.html:103 +#: templates/sales/estimates/estimate_form.html:117 #: templates/sales/sales_list.html:208 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_list.html:52 msgid "Remove" @@ -2833,7 +3014,7 @@ msgstr "إذا لم تقم بإنشاء حساب بعد، يرجى التسجي #: templates/account/login.html:56 templates/account/signup-wizard.html:18 #: templates/account/signup.html:5 templates/account/signup.html:79 -#: templates/header.html:450 templates/welcome-temp.html:78 +#: templates/header.html:471 templates/welcome-temp.html:78 #: templates/welcome_header.html:36 msgid "Sign Up" msgstr "إنشاء حساب" @@ -2847,7 +3028,7 @@ msgid "Mail me a sign-in code" msgstr "أرسل لي رمز تسجيل الدخول عبر البريد الإلكتروني" #: templates/account/logout.html:3 templates/account/logout.html:11 -#: templates/account/logout.html:20 templates/header.html:440 +#: templates/account/logout.html:20 templates/header.html:461 msgid "Sign Out" msgstr "تسجيل الخروج" @@ -2932,7 +3113,7 @@ msgstr "لم تستلم الرمز؟" #: templates/account/password_reset_from_key.html:40 #: templates/account/password_reset_from_key_done.html:5 #: templates/account/password_reset_from_key_done.html:20 -#: templates/dealers/dealer_detail.html:10 +#: templates/dealers/dealer_detail.html:16 msgid "Change Password" msgstr "تغيير كلمة المرور" @@ -3013,7 +3194,7 @@ msgstr "الوصول" #: templates/account/signup-wizard.html:29 #: templates/items/service/service_list.html:23 templates/plans/current.html:17 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:443 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:439 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:463 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/bank_account_update.html:13 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_txs_table.html:8 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:9 @@ -3033,23 +3214,27 @@ msgstr "إضافي" msgid "Done" msgstr "تم" -#: templates/account/signup-wizard.html:63 +#: templates/account/signup-wizard.html:44 +msgid "Read Terms of Service and Privacy Policy" +msgstr "اقرأ شروط الخدمة وسياسة الخصوصية" + +#: templates/account/signup-wizard.html:64 msgid "You are all set!" msgstr "كل شيء جاهز!" -#: templates/account/signup-wizard.html:64 +#: templates/account/signup-wizard.html:65 msgid "Now you can access your account" msgstr "الآن يمكنك الوصول إلى حسابك" -#: templates/account/signup-wizard.html:64 +#: templates/account/signup-wizard.html:65 msgid "anytime" msgstr "في أي وقت" -#: templates/account/signup-wizard.html:64 +#: templates/account/signup-wizard.html:65 msgid "anywhere" msgstr "في أي مكان" -#: templates/account/signup-wizard.html:64 +#: templates/account/signup-wizard.html:65 #: templates/administration/email_change_verification_code.html:25 #: templates/administration/manage_day_off.html:69 #: templates/appointment/enter_verification_code.html:24 @@ -3061,37 +3246,37 @@ msgstr "في أي مكان" msgid "Submit" msgstr "إرسال" -#: templates/account/signup-wizard.html:73 templates/pricing_page.html:200 +#: templates/account/signup-wizard.html:74 templates/pricing_page.html:199 #: venv/lib/python3.11/site-packages/alabaster/relations.html:9 msgid "Previous" msgstr "السابق" -#: templates/account/signup-wizard.html:75 -#: templates/appointment/appointments.html:86 templates/pricing_page.html:201 +#: templates/account/signup-wizard.html:76 +#: templates/appointment/appointments.html:86 templates/pricing_page.html:200 #: templates/two_factor/_wizard_actions.html:14 #: venv/lib/python3.11/site-packages/alabaster/relations.html:13 #: venv/lib/python3.11/site-packages/appointment/templates/appointment/appointments.html:85 msgid "Next" msgstr "التالي" -#: templates/account/signup-wizard.html:107 -#: templates/account/signup-wizard.html:112 +#: templates/account/signup-wizard.html:108 +#: templates/account/signup-wizard.html:113 msgid "Please enter a valid phone number" msgstr "يرجى إدخال رقم هاتف صالح" -#: templates/account/signup-wizard.html:143 +#: templates/account/signup-wizard.html:144 msgid "Password does not match" msgstr "كلمة المرور غير متطابقة" -#: templates/account/signup-wizard.html:251 -#: templates/inventory/car_form.html:614 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:654 +#: templates/account/signup-wizard.html:252 +#: templates/inventory/car_form.html:617 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:608 msgid "Please Wait" msgstr "الرجاء الإنتظار" -#: templates/account/signup-wizard.html:252 -#: templates/inventory/car_form.html:615 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:655 +#: templates/account/signup-wizard.html:253 +#: templates/inventory/car_form.html:618 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:609 msgid "Loading" msgstr "تحميل" @@ -3149,21 +3334,35 @@ msgstr "" "خلال بضع دقائق." #: templates/account/verified_email_required.html:23 +#, fuzzy +#| msgid "" +#| "This part of the site requires us to verify that\n" +#| "you are who you claim to be. For this purpose, we require that you\n" +#| "verify ownership of your email address. " msgid "" "This part of the site requires us to verify that\n" -"you are who you claim to be. For this purpose, we require that you\n" -"verify ownership of your email address. " +" you are who you claim to be. For this purpose, we " +"require that you\n" +" verify ownership of your email address. " msgstr "" "يتطلب هذا الجزء من الموقع التحقق من أنك الشخص الذي تدّعي أنه أنت. لهذا السبب، " "نطلب منك تأكيد ملكية عنوان بريدك الإلكتروني." #: templates/account/verified_email_required.html:28 +#, fuzzy +#| msgid "" +#| "We have sent an email to you for\n" +#| "verification. Please click on the link inside that email. If you do not " +#| "see the verification email in your main inbox, check your spam folder. " +#| "Otherwise\n" +#| "contact us if you do not receive it within a few minutes." msgid "" "We have sent an email to you for\n" -"verification. Please click on the link inside that email. If you do not see " -"the verification email in your main inbox, check your spam folder. " -"Otherwise\n" -"contact us if you do not receive it within a few minutes." +" verification. Please click on the link inside that " +"email. If you do not see the verification email in your main inbox, check " +"your spam folder. Otherwise\n" +" contact us if you do not receive it within a few " +"minutes." msgstr "" "لقد أرسلنا لك بريدًا إلكترونيًا للتحقق. يرجى النقر على الرابط الموجود داخل " "البريد الإلكتروني. إذا لم تجد البريد الإلكتروني للتحقق في صندوق الوارد " @@ -3179,16 +3378,107 @@ msgstr "" "ملاحظة: لا يزال بإمكانك تغيير " "عنوان بريدك الإلكتروني." +#: templates/admin_management/user_management.html:5 +#: templates/admin_management/user_management.html:11 +msgid "User Management" +msgstr "إدارة المستخدمين" + +#: templates/admin_management/user_management.html:23 +msgid "Created date" +msgstr "تاريخ الإنشاء" + +#: templates/admin_management/user_management.html:24 +#: templates/admin_management/user_management.html:88 +#: templates/admin_management/user_management.html:152 +#: templates/admin_management/user_management.html:216 +#: templates/inventory/car_detail.html:336 +#: templates/ledger/coa_accounts/account_detail.html:71 +#: templates/representatives/representative_list.html:20 +#: templates/sales/estimates/estimate_list.html:19 +#: templates/sales/invoices/invoice_list.html:20 +#: templates/sales/journals/journal_list.html:20 +#: templates/sales/payments/payment_list.html:24 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/account_txs_table.html:29 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:30 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:89 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html:39 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_table.html:16 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:13 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:36 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/tags/customer_table.html:13 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/data_import/tags/data_import_job_list_table.html:38 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:16 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:38 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html:13 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html:27 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html:57 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:15 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:51 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:112 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:186 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:260 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:321 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_table.html:39 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:16 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:16 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:95 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/product/tags/product_table.html:15 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/service/tags/services_table.html:15 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/uom/tags/uom_table.html:11 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/uom/tags/uom_table.html:33 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/vendor/tags/vendor_table.html:14 +msgid "Actions" +msgstr "الإجراءات" + +#: templates/admin_management/user_management.html:37 +#: templates/admin_management/user_management.html:101 +#: templates/admin_management/user_management.html:165 +#: templates/admin_management/user_management.html:229 +msgid "Inactive" +msgstr "غير نشط" + +#: templates/admin_management/user_management.html:54 +#: templates/admin_management/user_management.html:118 +#: templates/admin_management/user_management.html:182 +#: templates/admin_management/user_management.html:246 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:101 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html:52 +msgid "Activate" +msgstr "تفعيل" + +#: templates/admin_management/user_management.html:56 +#: templates/admin_management/user_management.html:120 +#: templates/admin_management/user_management.html:184 +#: templates/admin_management/user_management.html:248 +msgid "Permenantly Delete" +msgstr "حذف نهائي" + +#: templates/admin_management/user_management.html:62 +#: templates/admin_management/user_management.html:126 +#: templates/admin_management/user_management.html:190 +#: templates/admin_management/user_management.html:254 +msgid "No data available in table" +msgstr "لا توجد بيانات في الجدول" + +#: templates/admin_management/user_management.html:87 +#: templates/admin_management/user_management.html:151 +#: templates/admin_management/user_management.html:215 +#: templates/customers/customer_list.html:60 +#: templates/organizations/organization_list.html:74 +#: templates/vendors/vendors_list.html:75 +msgid "Create date" +msgstr "تاريخ الإنشاء" + #: templates/administration/display_appointment.html:19 -#: templates/customers/view_customer.html:92 -#: templates/customers/view_customer.html:119 +#: templates/customers/view_customer.html:96 +#: templates/customers/view_customer.html:123 #: templates/email_sender/reminder_email.html:80 #: templates/email_sender/reschedule_email.html:64 #: templates/email_sender/reschedule_email.html:69 -#: templates/inventory/car_detail.html:371 -#: templates/inventory/transfer_details.html:59 -#: templates/inventory/transfer_preview.html:219 -#: templates/ledger/coa_accounts/account_detail.html:64 +#: templates/inventory/car_detail.html:402 +#: templates/inventory/transfer_details.html:73 +#: templates/inventory/transfer_preview.html:271 +#: templates/ledger/coa_accounts/account_detail.html:67 #: templates/ledger/journal_entry/includes/card_journal_entry.html:15 #: templates/sales/estimates/sale_order_preview.html:166 #: venv/lib/python3.11/site-packages/appointment/templates/administration/display_appointment.html:25 @@ -3240,14 +3530,14 @@ msgstr "العميل" #: templates/administration/display_appointment.html:55 #: templates/appointment/appointment_client_information.html:57 -#: templates/crm/leads/lead_detail.html:88 -#: templates/dealers/dealer_detail.html:84 +#: templates/crm/leads/lead_detail.html:169 +#: templates/dealers/dealer_detail.html:90 #: templates/organizations/organization_detail.html:10 #: templates/organizations/organization_list.html:64 -#: templates/pricing_page.html:189 +#: templates/pricing_page.html:188 #: templates/representatives/representative_detail.html:9 #: templates/representatives/representative_list.html:19 -#: templates/vendors/vendors_list.html:54 +#: templates/vendors/vendors_list.html:47 #: venv/lib/python3.11/site-packages/appointment/templates/administration/display_appointment.html:49 #: venv/lib/python3.11/site-packages/appointment/templates/appointment/appointment_client_information.html:64 msgid "Phone" @@ -3310,7 +3600,7 @@ msgstr "لقد أرسلنا رمز التحقق إلى بريدك الإلكتر #: templates/administration/email_change_verification_code.html:22 #: templates/appointment/enter_verification_code.html:21 -#: templates/ledger/coa_accounts/account_list.html:50 +#: templates/ledger/coa_accounts/account_list.html:26 #: venv/lib/python3.11/site-packages/appointment/templates/administration/email_change_verification_code.html:22 #: venv/lib/python3.11/site-packages/appointment/templates/appointment/enter_verification_code.html:21 msgid "Code" @@ -3358,25 +3648,26 @@ msgstr "تأكيد الحذف" #: templates/administration/service_list.html:13 #: templates/administration/staff_index.html:79 #: templates/administration/user_profile.html:18 -#: templates/crm/leads/lead_list.html:99 templates/crm/leads/lead_list.html:232 +#: templates/crm/leads/lead_list.html:142 +#: templates/crm/leads/lead_list.html:279 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:28 #: templates/customers/view_customer.html:23 #: templates/groups/group_detail.html:109 #: templates/ledger/bank_accounts/bank_account_detail.html:63 -#: templates/ledger/coa_accounts/account_detail.html:118 -#: templates/ledger/coa_accounts/account_list.html:119 +#: templates/ledger/coa_accounts/account_detail.html:144 +#: templates/ledger/coa_accounts/account_list.html:100 #: templates/ledger/journal_entry/journal_entry_delete.html:19 -#: templates/ledger/journal_entry/journal_entry_list.html:116 +#: templates/ledger/journal_entry/journal_entry_list.html:102 #: templates/ledger/ledger/ledger_delete.html:19 -#: templates/ledger/ledger/ledger_list.html:108 +#: templates/ledger/ledger/ledger_list.html:110 #: templates/modal/delete_modal.html:12 templates/modal/delete_modal.html:26 #: templates/modal/event_details_modal.html:33 #: templates/organizations/organization_detail.html:19 -#: templates/organizations/organization_list.html:126 +#: templates/organizations/organization_list.html:123 #: templates/plans/billing_info_create_or_update.html:14 #: templates/representatives/representative_detail.html:16 #: templates/sales/estimates/estimate_detail.html:29 -#: templates/users/user_detail.html:90 templates/vendors/vendors_list.html:112 +#: templates/users/user_detail.html:60 templates/vendors/vendors_list.html:131 #: templates/vendors/view_vendor.html:39 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_index.html:325 #: venv/lib/python3.11/site-packages/appointment/templates/administration/user_profile.html:33 @@ -3418,7 +3709,7 @@ msgstr "حذف" #: venv/lib/python3.11/site-packages/appointment/templates/administration/user_profile.html:236 #: venv/lib/python3.11/site-packages/appointment/templates/appointment/default_thank_you.html:23 #: venv/lib/python3.11/site-packages/appointment/views.py:421 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1863 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1868 msgid "Duration" msgstr "المدة" @@ -3461,35 +3752,38 @@ msgstr "" "خيار." #: templates/administration/manage_staff_member.html:70 -#: templates/crm/leads/lead_form.html:13 +#: templates/components/activity_modal.html:25 +#: templates/crm/leads/lead_detail.html:581 +#: templates/crm/leads/lead_detail.html:601 +#: templates/crm/leads/lead_form.html:30 #: templates/crm/leads/schedule_lead.html:15 -#: templates/crm/opportunities/opportunity_detail.html:59 -#: templates/crm/opportunities/opportunity_form.html:88 -#: templates/customers/customer_form.html:30 -#: templates/dealers/assign_car_makes.html:23 +#: templates/crm/opportunities/opportunity_detail.html:60 +#: templates/customers/customer_form.html:31 +#: templates/dealers/assign_car_makes.html:88 #: templates/dealers/dealer_form.html:19 templates/groups/group_form.html:38 #: templates/groups/group_permission_form.html:38 -#: templates/inventory/add_colors.html:56 -#: templates/inventory/add_custom_card.html:17 -#: templates/inventory/car_edit.html:12 -#: templates/inventory/car_finance_form.html:40 -#: templates/inventory/car_location_form.html:13 -#: templates/inventory/car_registration_form.html:18 +#: templates/inventory/add_colors.html:72 +#: templates/inventory/add_custom_card.html:18 +#: templates/inventory/car_edit.html:18 +#: templates/inventory/car_finance_form.html:44 +#: templates/inventory/car_location_form.html:14 +#: templates/inventory/car_registration_form.html:19 #: templates/inventory/color_palette.html:106 #: templates/items/expenses/expense_create.html:16 +#: templates/items/expenses/expense_create.html:21 #: templates/items/expenses/expense_update.html:16 -#: templates/items/service/service_create.html:22 -#: templates/ledger/bank_accounts/bank_account_form.html:31 -#: templates/ledger/bills/bill_form.html:41 +#: templates/items/service/service_create.html:23 +#: templates/ledger/bank_accounts/bank_account_form.html:32 +#: templates/ledger/bills/bill_form.html:42 #: templates/ledger/bills/bill_update_form.html:15 -#: templates/ledger/coa_accounts/account_form.html:30 +#: templates/ledger/coa_accounts/account_form.html:32 #: templates/ledger/journal_entry/journal_entry_form.html:16 #: templates/ledger/journal_entry/journal_entry_txs.html:62 -#: templates/ledger/ledger/ledger_form.html:16 -#: templates/organizations/organization_form.html:17 +#: templates/ledger/ledger/ledger_form.html:22 +#: templates/organizations/organization_form.html:15 #: templates/plans/billing_info_create_or_update.html:17 #: templates/representatives/representative_form.html:11 -#: templates/sales/estimates/estimate_form.html:65 +#: templates/sales/estimates/estimate_form.html:74 #: templates/sales/estimates/sale_order_form.html:194 #: templates/sales/invoices/approved_invoice_update.html:16 #: templates/sales/invoices/draft_invoice_update.html:16 @@ -3497,8 +3791,8 @@ msgstr "" #: templates/sales/invoices/paid_invoice_update.html:16 #: templates/sales/journals/journal_form.html:18 #: templates/sales/payments/payment_create.html:16 -#: templates/users/user_form.html:44 templates/users/user_group_form.html:31 -#: templates/vendors/vendor_form.html:41 +#: templates/users/user_form.html:44 templates/users/user_group_form.html:27 +#: templates/vendors/vendor_form.html:40 #: venv/lib/python3.11/site-packages/appointment/templates/administration/manage_staff_member.html:70 #: venv/lib/python3.11/site-packages/appointment/views_admin.py:464 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_item_formset.html:81 @@ -3539,12 +3833,14 @@ msgstr "قائمة الخدمات" #: templates/administration/service_list.html:26 #: templates/administration/user_profile.html:94 #: templates/administration/user_profile.html:162 -#: templates/groups/group_detail.html:83 -#: templates/inventory/car_detail.html:367 -#: templates/items/expenses/expenses_list.html:22 +#: templates/crm/leads/lead_list.html:115 +#: templates/crm/leads/lead_list.html:132 templates/groups/group_detail.html:83 +#: templates/inventory/car_detail.html:398 +#: templates/items/expenses/expenses_list.html:23 #: templates/items/service/service_list.html:24 -#: templates/ledger/bank_accounts/bank_account_list.html:21 -#: templates/ledger/journal_entry/journal_entry_list.html:69 +#: templates/ledger/bank_accounts/bank_account_list.html:22 +#: templates/ledger/bills/bill_list.html:53 +#: templates/ledger/journal_entry/journal_entry_list.html:55 #: templates/ledger/ledger/ledger_list.html:25 #: templates/modal/confirm_modal.html:21 #: venv/lib/python3.11/site-packages/appointment/templates/administration/service_list.html:31 @@ -3655,22 +3951,20 @@ msgstr "قائمة جميع أعضاء الفريق" msgid "Staff Members" msgstr "أعضاء الفريق" -#: templates/administration/staff_list.html:25 -#: templates/crm/leads/lead_detail.html:216 templates/crm/note_form.html:15 +#: templates/administration/staff_list.html:25 templates/crm/note_form.html:15 #: templates/customers/note_form.html:6 -#: templates/customers/view_customer.html:84 -#: templates/inventory/car_detail.html:130 -#: templates/inventory/car_detail.html:152 -#: templates/inventory/car_detail.html:168 -#: templates/inventory/car_detail.html:246 -#: templates/inventory/car_detail.html:292 +#: templates/customers/view_customer.html:88 +#: templates/inventory/car_detail.html:153 +#: templates/inventory/car_detail.html:175 +#: templates/inventory/car_detail.html:196 +#: templates/inventory/car_detail.html:273 +#: templates/inventory/car_detail.html:316 #: venv/lib/python3.11/site-packages/appointment/services.py:170 msgid "Add" msgstr "إضافة" #: templates/administration/staff_list.html:36 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:71 -#: templates/crm/opportunities/opportunity_list.html:65 #: templates/inventory/car_form.html:228 #: templates/inventory/inventory_stats.html:63 #: venv/lib/python3.11/site-packages/appointment/templates/administration/staff_list.html:40 @@ -3934,20 +4228,20 @@ msgid "Payment Details" msgstr "تفاصيل الدفع" #: templates/appointment/appointment_client_information.html:96 -#: templates/customers/view_customer.html:117 -#: templates/inventory/car_detail.html:230 -#: templates/inventory/inventory_stats.html:72 -#: templates/inventory/transfer_details.html:74 -#: templates/inventory/transfer_preview.html:232 +#: templates/customers/view_customer.html:121 +#: templates/inventory/car_detail.html:258 +#: templates/inventory/inventory_stats.html:70 +#: templates/inventory/transfer_details.html:91 +#: templates/inventory/transfer_preview.html:288 #: templates/ledger/bills/bill_detail.html:216 -#: templates/ledger/coa_accounts/account_detail.html:100 +#: templates/ledger/coa_accounts/account_detail.html:114 #: templates/ledger/ledger/ledger_detail.html:84 #: templates/ledger/ledger/ledger_detail.html:100 #: templates/ledger/reports/tags/balance_sheet_statement.html:55 #: templates/ledger/reports/tags/cash_flow_statement.html:11 #: templates/plans/invoices/layout.html:112 #: templates/plans/invoices/layout.html:133 -#: templates/plans/order_detail_table.html:12 templates/pricing_page.html:183 +#: templates/plans/order_detail_table.html:12 templates/pricing_page.html:182 #: templates/sales/estimates/estimate_detail.html:197 #: templates/sales/estimates/sale_order_preview.html:184 #: templates/sales/invoices/invoice_detail.html:244 @@ -4122,71 +4416,133 @@ msgstr "هيكل" msgid "Select Date" msgstr "اختر التاريخ" -#: templates/crm/leads/lead_detail.html:18 -#: templates/crm/leads/lead_detail.html:35 +#: templates/crm/leads/lead_detail.html:45 +#: templates/crm/leads/lead_list.html:13 +msgid "Update Lead Actions" +msgstr "تحديث إجراءات العميل المحتمل" + +#: templates/crm/leads/lead_detail.html:54 +#: templates/crm/leads/lead_list.html:22 +msgid "Current Action" +msgstr "الإجراء الحالي" + +#: templates/crm/leads/lead_detail.html:56 +#: templates/crm/leads/lead_list.html:24 +msgid "Select Action" +msgstr "اختر إجراء" + +#: templates/crm/leads/lead_detail.html:68 +#: templates/crm/leads/lead_list.html:36 +msgid "Select Next Action" +msgstr "اختر الإجراء التالي" + +#: templates/crm/leads/lead_detail.html:69 +msgid "No Action" +msgstr "لا يوجد إجراء" + +#: templates/crm/leads/lead_detail.html:87 +#: templates/crm/leads/lead_list.html:56 templates/inventory/car_form.html:239 +#: templates/inventory/car_form.html:258 templates/inventory/car_form.html:276 +#: templates/inventory/car_form.html:293 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:229 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:235 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:252 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:270 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:287 +#: templates/modal/confirm_modal.html:11 templates/modal/confirm_modal.html:20 +#: templates/modal/error_modal.html:17 +#: templates/modal/event_details_modal.html:21 +#: templates/partials/scanner_modal.html:6 +#: templates/partials/specifications_modal.html:8 +#: venv/lib/python3.11/site-packages/appointment/templates/modal/confirm_modal.html:18 +#: venv/lib/python3.11/site-packages/appointment/templates/modal/error_modal.html:17 +#: venv/lib/python3.11/site-packages/appointment/templates/modal/event_details_modal.html:19 +msgid "Close" +msgstr "إغلاق" + +#: templates/crm/leads/lead_detail.html:88 +#: templates/crm/leads/lead_list.html:57 +msgid "Save Changes" +msgstr "حفظ التغييرات" + +#: templates/crm/leads/lead_detail.html:97 +#: templates/crm/leads/lead_detail.html:114 msgid "Lead Details" msgstr "تفاصيل العميل المحتمل" -#: templates/crm/leads/lead_detail.html:44 +#: templates/crm/leads/lead_detail.html:123 msgid "Assigned to" msgstr "مُعين إلى" -#: templates/crm/leads/lead_detail.html:46 +#: templates/crm/leads/lead_detail.html:125 msgid "Not Assigned" msgstr "غير معين" -#: templates/crm/leads/lead_detail.html:72 +#: templates/crm/leads/lead_detail.html:153 msgid "Car Requested" msgstr "السيارة المطلوبة" -#: templates/crm/leads/lead_detail.html:94 -msgid "Salary" -msgstr "الراتب" - -#: templates/crm/leads/lead_detail.html:106 +#: templates/crm/leads/lead_detail.html:187 msgid "Lead Source" msgstr "مصدر العميل المحتمل" -#: templates/crm/leads/lead_detail.html:112 +#: templates/crm/leads/lead_detail.html:193 msgid "Lead Channel" msgstr "قناة العميل المحتمل" -#: templates/crm/leads/lead_detail.html:124 +#: templates/crm/leads/lead_detail.html:205 #: venv/lib/python3.11/site-packages/django_ledger/forms/entity.py:82 #: venv/lib/python3.11/site-packages/django_ledger/forms/entity.py:159 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:108 msgid "City" msgstr "المدينة" -#: templates/crm/leads/lead_detail.html:201 -msgid "by" -msgstr "بواسطة" +#: templates/crm/leads/lead_detail.html:217 +msgid "Current Stage" +msgstr "المرحلة الحالية" -#: templates/crm/leads/lead_detail.html:218 -#: templates/customers/view_customer.html:86 +#: templates/crm/leads/lead_detail.html:230 +#: templates/crm/leads/lead_list.html:270 +msgid "Update Actions" +msgstr "تحديث الإجراءات" + +#: templates/crm/leads/lead_detail.html:258 +#: templates/crm/opportunities/opportunity_detail.html:303 +msgid "Add Activity" +msgstr "إضافة نشاط" + +#: templates/crm/leads/lead_detail.html:293 +msgid "created by" +msgstr "تم الإنشاء بواسطة" + +#: templates/crm/leads/lead_detail.html:306 +#: templates/customers/view_customer.html:90 msgid "Add Note" msgstr "إضافة ملاحظة" -#: templates/crm/leads/lead_detail.html:227 +#: templates/crm/leads/lead_detail.html:315 msgid "Created By" msgstr "تم الإنشاء بواسطة" -#: templates/crm/leads/lead_detail.html:228 +#: templates/crm/leads/lead_detail.html:316 msgid "Created On" msgstr "تم الإنشاء في" -#: templates/crm/leads/lead_detail.html:245 -#: templates/crm/leads/lead_form.html:6 +#: templates/crm/leads/lead_detail.html:342 +#: templates/crm/leads/lead_detail.html:343 +#: templates/crm/leads/lead_form.html:20 #: templates/crm/leads/schedule_lead.html:5 templates/crm/note_form.html:13 +#: templates/crm/opportunities/opportunity_form.html:142 +#: templates/crm/opportunities/partials/opportunity_grid.html:103 #: templates/customers/view_customer.html:30 -#: templates/items/expenses/expenses_list.html:34 -#: templates/items/service/service_list.html:44 -#: templates/ledger/bank_accounts/bank_account_list.html:33 +#: templates/items/expenses/expenses_list.html:44 +#: templates/items/service/service_list.html:55 +#: templates/ledger/bank_accounts/bank_account_list.html:41 #: templates/ledger/journal_entry/includes/card_invoice.html:34 #: venv/lib/python3.11/site-packages/appointment/services.py:170 #: venv/lib/python3.11/site-packages/appointment/views_admin.py:374 #: venv/lib/python3.11/site-packages/appointment/views_admin.py:471 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:102 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:98 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/bank_account_update.html:23 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html:49 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:46 @@ -4223,14 +4579,18 @@ msgstr "تم الإنشاء في" msgid "Update" msgstr "تحديث" -#: templates/crm/leads/lead_detail.html:417 -#: templates/customers/view_customer.html:219 -#: templates/inventory/car_detail.html:536 -msgid "Error loading form. Please try again later" -msgstr "حدث خطأ أثناء تحميل النموذج. يرجى المحاولة مرة أخرى لاحقًا." +#: templates/crm/leads/lead_detail.html:366 +#: templates/crm/leads/lead_list.html:272 +msgid "Send Email" +msgstr "إرسال البريد الإلكتروني" -#: templates/crm/leads/lead_form.html:6 +#: templates/crm/leads/lead_detail.html:486 +msgid "Add Task" +msgstr "إضافة مهمة" + +#: templates/crm/leads/lead_form.html:20 #: templates/crm/leads/schedule_lead.html:5 +#: templates/crm/opportunities/opportunity_form.html:144 #: venv/lib/python3.11/site-packages/appointment/views_admin.py:429 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/bank_account_create.html:22 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_create.html:33 @@ -4246,48 +4606,49 @@ msgstr "حدث خطأ أثناء تحميل النموذج. يرجى المحا msgid "Create" msgstr "إنشاء" -#: templates/crm/leads/lead_list.html:13 +#: templates/crm/leads/lead_list.html:25 templates/crm/leads/lead_list.html:173 +msgid "Contacted" +msgstr "تم الاتصال" + +#: templates/crm/leads/lead_list.html:27 +msgid "Proposal Sent" +msgstr "تم إرسال العرض" + +#: templates/crm/leads/lead_list.html:40 +msgid "Send Proposal" +msgstr "إرسال العرض" + +#: templates/crm/leads/lead_list.html:69 msgid "Add Lead" msgstr "إضافة عميل محتمل" -#: templates/crm/leads/lead_list.html:31 +#: templates/crm/leads/lead_list.html:87 msgid "Lead Name" msgstr "اسم العميل المحتمل" -#: templates/crm/leads/lead_list.html:53 +#: templates/crm/leads/lead_list.html:109 msgid "Schedule" msgstr "الجدولة" -#: templates/crm/leads/lead_list.html:59 +#: templates/crm/leads/lead_list.html:121 msgid "Assigned To" msgstr "مُعين إلى" -#: templates/crm/leads/lead_list.html:83 -msgid "Is Opportunity" -msgstr "هل هي فرصة" - -#: templates/crm/leads/lead_list.html:87 -#: templates/customers/customer_list.html:60 -#: templates/organizations/organization_list.html:74 -#: templates/vendors/vendors_list.html:68 -msgid "Create date" -msgstr "تاريخ الإنشاء" - -#: templates/crm/leads/lead_list.html:103 +#: templates/crm/leads/lead_list.html:146 msgid "Are you sure you want to delete this lead?" msgstr "هل أنت متأكد أنك تريد حذف هذا العميل المحتمل؟" -#: templates/crm/leads/lead_list.html:107 +#: templates/crm/leads/lead_list.html:150 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:158 #: templates/groups/group_detail.html:32 -#: templates/inventory/car_detail.html:472 -#: templates/inventory/transfer_details.html:47 +#: templates/inventory/car_detail.html:519 +#: templates/inventory/transfer_details.html:62 #: templates/ledger/bank_accounts/bank_account_detail.html:31 #: templates/ledger/bills/bill_detail.html:24 #: templates/ledger/bills/bill_detail.html:49 #: templates/ledger/bills/bill_detail.html:121 #: templates/ledger/coa_accounts/account_detail.html:22 -#: templates/ledger/coa_accounts/account_list.html:86 +#: templates/ledger/coa_accounts/account_list.html:60 #: templates/ledger/journal_entry/journal_entry_list.html:25 #: templates/organizations/organization_list.html:96 #: templates/sales/estimates/estimate_detail.html:37 @@ -4295,50 +4656,32 @@ msgstr "هل أنت متأكد أنك تريد حذف هذا العميل الم #: templates/sales/invoices/invoice_detail.html:31 #: templates/sales/invoices/invoice_detail.html:56 #: templates/sales/invoices/invoice_detail.html:142 -#: templates/users/user_detail.html:32 #: venv/lib/python3.11/site-packages/appointment/models.py:530 -#: venv/lib/python3.11/site-packages/django/forms/widgets.py:801 +#: venv/lib/python3.11/site-packages/django/forms/widgets.py:867 msgid "Yes" msgstr "نعم" -#: templates/crm/leads/lead_list.html:205 -#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:155 -#: templates/groups/group_detail.html:27 -#: templates/inventory/car_detail.html:467 -#: templates/inventory/transfer_details.html:24 -#: templates/inventory/transfer_details.html:46 -#: templates/ledger/bank_accounts/bank_account_detail.html:26 -#: templates/ledger/bills/bill_detail.html:20 -#: templates/ledger/bills/bill_detail.html:45 -#: templates/ledger/bills/bill_detail.html:123 -#: templates/ledger/coa_accounts/account_detail.html:18 -#: templates/ledger/coa_accounts/account_list.html:83 -#: templates/ledger/journal_entry/journal_entry_list.html:24 -#: templates/organizations/organization_list.html:95 -#: templates/sales/estimates/estimate_detail.html:63 -#: templates/sales/invoices/invoice_detail.html:27 -#: templates/sales/invoices/invoice_detail.html:52 -#: templates/sales/invoices/invoice_detail.html:144 -#: templates/users/user_detail.html:27 -#: venv/lib/python3.11/site-packages/appointment/models.py:530 -#: venv/lib/python3.11/site-packages/appointment/tests/models/test_appointment.py:62 -#: venv/lib/python3.11/site-packages/django/forms/widgets.py:802 -msgid "No" -msgstr "لا" +#: templates/crm/leads/lead_list.html:169 +msgid "In Progress" +msgstr "قيد التنفيذ" -#: templates/crm/leads/lead_list.html:223 +#: templates/crm/leads/lead_list.html:171 +msgid "Qualified" +msgstr "مؤهل" + +#: templates/crm/leads/lead_list.html:267 #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:27 -#: templates/dealers/dealer_detail.html:13 +#: templates/dealers/dealer_detail.html:19 #: templates/groups/group_detail.html:103 -#: templates/inventory/car_detail.html:179 -#: templates/inventory/car_detail.html:237 +#: templates/inventory/car_detail.html:207 +#: templates/inventory/car_detail.html:265 #: templates/ledger/bank_accounts/bank_account_detail.html:57 -#: templates/ledger/coa_accounts/account_detail.html:114 +#: templates/ledger/coa_accounts/account_detail.html:140 #: templates/modal/event_details_modal.html:27 #: templates/organizations/organization_detail.html:14 -#: templates/organizations/organization_list.html:124 +#: templates/organizations/organization_list.html:121 #: templates/representatives/representative_detail.html:13 -#: templates/users/user_detail.html:84 templates/vendors/vendors_list.html:105 +#: templates/users/user_detail.html:52 templates/vendors/vendors_list.html:125 #: templates/vendors/view_vendor.html:32 #: venv/lib/python3.11/site-packages/appointment/templates/modal/event_details_modal.html:25 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/includes/card_customer.html:28 @@ -4348,17 +4691,25 @@ msgstr "لا" msgid "Edit" msgstr "تحديث" -#: templates/crm/leads/lead_list.html:225 -msgid "Send Email" -msgstr "إرسال البريد الإلكتروني" - -#: templates/crm/leads/lead_list.html:226 +#: templates/crm/leads/lead_list.html:273 msgid "Schedule Event" msgstr "جدولة الحدث" -#: templates/crm/leads/lead_list.html:228 -msgid "Convert" -msgstr "تحويل" +#: templates/crm/leads/lead_list.html:275 +msgid "Convert to Opportunity" +msgstr "تحويل إلى فرصة" + +#: templates/crm/leads/lead_tracking.html:65 +msgid "Lead Tracking" +msgstr "تتبع العملاء المحتملين" + +#: templates/crm/leads/lead_tracking.html:72 templates/dashboards/sales.html:91 +msgid "New Leads" +msgstr "عملاء محتملون جدد" + +#: templates/crm/leads/lead_tracking.html:88 +msgid "Follow Ups" +msgstr "متابعات" #: templates/crm/notifications.html:16 #: templates/crm/notifications_history.html:14 @@ -4378,65 +4729,66 @@ msgstr "تفاصيل الفرصة" msgid "View Quotation" msgstr "مشاهدة عرض السعر" -#: templates/crm/opportunities/opportunity_detail.html:83 -msgid "Other Information" -msgstr "معلومات أخرى" - -#: templates/crm/opportunities/opportunity_detail.html:89 -msgid "Update Status" -msgstr "تحديث الحالة" - -#: templates/crm/opportunities/opportunity_detail.html:96 -msgid "Update Stage" -msgstr "تحديث المرحلة" - -#: templates/crm/opportunities/opportunity_detail.html:114 +#: templates/crm/opportunities/opportunity_detail.html:116 msgid "Quotation Amount" msgstr "مبلغ عرض السعر" -#: templates/crm/opportunities/opportunity_detail.html:169 +#: templates/crm/opportunities/opportunity_detail.html:171 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/card_estimate.html:14 msgid "Estimated Revenue" msgstr "الإيرادات المقدرة" -#: templates/crm/opportunities/opportunity_detail.html:219 +#: templates/crm/opportunities/opportunity_detail.html:221 msgid "Contact Name" msgstr "اسم جهة الاتصال" -#: templates/crm/opportunities/opportunity_detail.html:252 +#: templates/crm/opportunities/opportunity_detail.html:254 msgid "Create Date" msgstr "تاريخ الإنشاء" -#: templates/crm/opportunities/opportunity_form.html:8 +#: templates/crm/opportunities/opportunity_form.html:10 msgid "Edit Opportunity" msgstr "تعديل الفرصة" -#: templates/crm/opportunities/opportunity_form.html:8 -msgid "Add New Opportunity" -msgstr "إضافة فرصة جديدة" +#: templates/crm/opportunities/opportunity_form.html:12 +msgid "Create New Opportunity" +msgstr "إنشاء فرصة جديدة" -#: templates/crm/opportunities/opportunity_form.html:56 -msgid "Enter probability" -msgstr "أدخل الاحتمالية" +#: templates/crm/opportunities/opportunity_form.html:18 +msgid "Back to list" +msgstr "العودة إلى القائمة" -#: templates/crm/opportunities/opportunity_form.html:57 -#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:110 -#: templates/crm/opportunities/opportunity_list.html:104 -msgid "Probability" -msgstr "الاحتمالية" +#: templates/crm/opportunities/opportunity_form.html:138 +msgid "Reset" +msgstr "إعادة تعيين" + +#: templates/crm/opportunities/opportunity_form.html:155 +msgid "Opportunity Guidelines" +msgstr "إرشادات الفرص" + +#: templates/crm/opportunities/opportunity_form.html:160 +msgid "Probability indicates conversion chance" +msgstr "تشير النسبة المئوية إلى فرصة التحويل" + +#: templates/crm/opportunities/opportunity_form.html:166 +msgid "Update stage as deal progresses" +msgstr "تحديث المرحلة مع تقدم الصفقة" + +#: templates/crm/opportunities/opportunity_form.html:172 +msgid "Set realistic closing dates" +msgstr "تحديد تواريخ إغلاق واقعية" #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:11 -#: templates/crm/opportunities/opportunity_list.html:11 +#: templates/crm/opportunities/opportunity_list.html:83 msgid "Add Opportunity" msgstr "إضافة فرصة" #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:55 -#: templates/crm/opportunities/opportunity_list.html:49 -#: templates/inventory/car_list_view.html:167 -#: templates/ledger/bills/bill_list.html:80 -#: templates/ledger/coa_accounts/account_list.html:117 +#: templates/inventory/car_list_view.html:231 +#: templates/ledger/bills/bill_list.html:84 +#: templates/ledger/coa_accounts/account_list.html:98 #: templates/ledger/journal_entry/includes/card_invoice.html:33 -#: templates/ledger/journal_entry/journal_entry_list.html:113 +#: templates/ledger/journal_entry/journal_entry_list.html:99 #: templates/sales/invoices/invoice_list.html:61 #: templates/sales/sales_list.html:207 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:44 @@ -4448,16 +4800,15 @@ msgstr "إضافة فرصة" msgid "View" msgstr "عرض" -#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:78 -#: templates/crm/opportunities/opportunity_list.html:72 -msgid "Expected Revenue" -msgstr "الإيرادات المتوقعة" - #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:89 -#: templates/crm/opportunities/opportunity_list.html:83 msgid "Contact" msgstr "جهة الاتصال" +#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:110 +#: templates/crm/opportunities/partials/opportunity_grid.html:81 +msgid "Probability" +msgstr "الاحتمالية" + #: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:145 msgid "Delete Opportunity" msgstr "حذف الفرصة" @@ -4466,12 +4817,60 @@ msgstr "حذف الفرصة" msgid "Are you sure you want to delete this opportunity?" msgstr "هل أنت متأكد أنك تريد حذف هذه الفرصة؟" +#: ⁨templates/crm/opportunities/opportunity_list copy.html⁩:155 +#: templates/groups/group_detail.html:27 +#: templates/inventory/car_detail.html:514 +#: templates/inventory/transfer_details.html:29 +#: templates/inventory/transfer_details.html:58 +#: templates/ledger/bank_accounts/bank_account_detail.html:26 +#: templates/ledger/bills/bill_detail.html:20 +#: templates/ledger/bills/bill_detail.html:45 +#: templates/ledger/bills/bill_detail.html:123 +#: templates/ledger/coa_accounts/account_detail.html:18 +#: templates/ledger/coa_accounts/account_list.html:57 +#: templates/ledger/journal_entry/journal_entry_list.html:24 +#: templates/organizations/organization_list.html:95 +#: templates/sales/estimates/estimate_detail.html:63 +#: templates/sales/invoices/invoice_detail.html:27 +#: templates/sales/invoices/invoice_detail.html:52 +#: templates/sales/invoices/invoice_detail.html:144 +#: venv/lib/python3.11/site-packages/appointment/models.py:530 +#: venv/lib/python3.11/site-packages/appointment/tests/models/test_appointment.py:62 +#: venv/lib/python3.11/site-packages/django/forms/widgets.py:868 +msgid "No" +msgstr "لا" + +#: templates/crm/opportunities/opportunity_list.html:20 +msgid "Search opportunities..." +msgstr "ابحث في الفرص..." + +#: templates/crm/opportunities/opportunity_list.html:46 +msgid "All Stages" +msgstr "جميع المراحل" + +#: templates/crm/opportunities/opportunity_list.html:68 +msgid "Newest First" +msgstr "الأحدث أولاً" + +#: templates/crm/opportunities/opportunity_list.html:71 +msgid "Highest Value" +msgstr "أعلى قيمة" + +#: templates/crm/opportunities/opportunity_list.html:74 +msgid "Earliest Close Date" +msgstr "أقرب تاريخ إغلاق" + +#: templates/crm/opportunities/partials/opportunity_grid.html:100 +msgid "View Details" +msgstr "عرض التفاصيل" + #: templates/customers/customer_form.html:15 msgid "Edit Customer" msgstr "تحديث العميل" #: templates/customers/customer_form.html:17 #: templates/customers/customer_list.html:15 +#: templates/sales/estimates/estimate_form.html:27 msgid "Add Customer" msgstr "إضافة عميل" @@ -4487,7 +4886,7 @@ msgstr "عرض العميل" msgid "Customer details" msgstr "تفاصيل العميل" -#: templates/customers/view_customer.html:53 +#: templates/customers/view_customer.html:57 #: templates/dashboards/manager.html:31 #: templates/sales/invoices/invoice_list.html:4 #: templates/sales/invoices/invoice_list.html:9 @@ -4499,35 +4898,35 @@ msgstr "تفاصيل العميل" msgid "Invoices" msgstr "الفواتير" -#: templates/customers/view_customer.html:57 +#: templates/customers/view_customer.html:61 #: templates/dashboards/manager.html:36 #: templates/sales/estimates/estimate_list.html:4 #: templates/sales/estimates/estimate_list.html:8 msgid "Quotations" msgstr "العروض" -#: templates/customers/view_customer.html:68 -#: templates/dealers/dealer_detail.html:63 +#: templates/customers/view_customer.html:72 +#: templates/dealers/dealer_detail.html:69 msgid "Default Address" msgstr "العنوان الافتراضي" -#: templates/customers/view_customer.html:110 +#: templates/customers/view_customer.html:114 msgid "Related" msgstr "مرتبط" -#: templates/customers/view_customer.html:116 -#: templates/ledger/bank_accounts/bank_account_list.html:20 -#: templates/ledger/coa_accounts/account_list.html:48 +#: templates/customers/view_customer.html:120 +#: templates/ledger/bank_accounts/bank_account_list.html:21 +#: templates/ledger/coa_accounts/account_list.html:24 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/product/tags/product_table.html:8 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/service/tags/services_table.html:8 msgid "Type" msgstr "النوع" -#: templates/customers/view_customer.html:118 +#: templates/customers/view_customer.html:122 msgid "Payment Status" msgstr "حالة الدفع" -#: templates/customers/view_customer.html:128 +#: templates/customers/view_customer.html:132 #: templates/sales/estimates/estimate_detail.html:79 #: templates/sales/estimates/estimate_send.html:5 #: templates/sales/estimates/sale_order_form.html:171 @@ -4535,7 +4934,7 @@ msgstr "حالة الدفع" msgid "Quotation" msgstr "عرض سعر" -#: templates/customers/view_customer.html:156 +#: templates/customers/view_customer.html:160 #: templates/ledger/bills/bill_detail.html:199 #: templates/sales/invoices/invoice_detail.html:80 #: templates/sales/invoices/invoice_detail.html:224 @@ -4545,6 +4944,11 @@ msgstr "عرض سعر" msgid "Paid" msgstr "مدفوع" +#: templates/customers/view_customer.html:223 +#: templates/inventory/car_detail.html:588 +msgid "Error loading form. Please try again later" +msgstr "حدث خطأ أثناء تحميل النموذج. يرجى المحاولة مرة أخرى لاحقًا." + #: templates/dashboards/manager.html:9 templates/dashboards/sales.html:119 msgid "As of" msgstr "حتى" @@ -4578,10 +4982,6 @@ msgstr "تم استلام الدفع عبر جميع القنوات." msgid "New Customers" msgstr "عملاء جدد." -#: templates/dashboards/sales.html:91 -msgid "New Leads" -msgstr "فرص جديدة." - #: templates/dashboards/sales.html:154 msgid "Canceled Invoices" msgstr "الفواتير الملغاة." @@ -4596,7 +4996,7 @@ msgstr "من الشهر الماضي." msgid "Gross Profit" msgstr "الربح الإجمالي" -#: templates/dealers/assign_car_makes.html:16 +#: templates/dealers/assign_car_makes.html:59 msgid "Select Car Makes You Sell" msgstr "اختر ماركات السيارات التي تبيعها" @@ -4604,64 +5004,74 @@ msgstr "اختر ماركات السيارات التي تبيعها" msgid "Profile" msgstr "الملف الشخصي" -#: templates/dealers/dealer_detail.html:37 +#: templates/dealers/dealer_detail.html:10 +#: templates/sales/orders/order_list.html:4 +#: templates/sales/orders/order_list.html:8 +msgid "Orders" +msgstr "طلبات" + +#: templates/dealers/dealer_detail.html:13 +msgid "Billing Information" +msgstr "معلومات الفوترة" + +#: templates/dealers/dealer_detail.html:43 msgid "Joined" msgstr "انضم" -#: templates/dealers/dealer_detail.html:37 +#: templates/dealers/dealer_detail.html:43 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html:41 msgid "ago" msgstr "منذ" -#: templates/dealers/dealer_detail.html:44 +#: templates/dealers/dealer_detail.html:50 msgid "last login" msgstr "آخر تسجيل دخول" -#: templates/dealers/dealer_detail.html:48 +#: templates/dealers/dealer_detail.html:54 msgid "Total users" msgstr "إجمالي المستخدمين" -#: templates/dealers/dealer_detail.html:52 +#: templates/dealers/dealer_detail.html:58 msgid "Total cars" msgstr "إجمالي السيارات" -#: templates/dealers/dealer_detail.html:107 -#: templates/inventory/car_detail.html:336 templates/plans/current.html:28 +#: templates/dealers/dealer_detail.html:113 +#: templates/inventory/car_detail.html:364 templates/plans/current.html:28 msgid "Expired" msgstr "منتهي الصلاحية" -#: templates/dealers/dealer_detail.html:108 -#: templates/inventory/car_detail.html:327 +#: templates/dealers/dealer_detail.html:114 +#: templates/inventory/car_detail.html:353 msgid "Renew" msgstr "تجديد" -#: templates/dealers/dealer_detail.html:111 templates/plans/current.html:46 +#: templates/dealers/dealer_detail.html:117 templates/plans/current.html:46 msgid "Upgrade" msgstr "ترقية" -#: templates/dealers/dealer_detail.html:114 +#: templates/dealers/dealer_detail.html:120 #: templates/subscriptions/subscription_plan.html:85 msgid "Subscribe" msgstr "الاشتراك" -#: templates/dealers/dealer_detail.html:118 templates/plans/current.html:35 +#: templates/dealers/dealer_detail.html:124 templates/plans/current.html:35 msgid "Active until" msgstr "نشط حتى" -#: templates/dealers/dealer_detail.html:118 +#: templates/dealers/dealer_detail.html:124 msgid "Days left" msgstr "الأيام المتبقية" -#: templates/dealers/dealer_detail.html:121 +#: templates/dealers/dealer_detail.html:127 #: templates/subscriptions/subscription_plan.html:42 templates/welcome.html:107 msgid "Per month" msgstr "شهريًا" -#: templates/dealers/dealer_detail.html:151 +#: templates/dealers/dealer_detail.html:157 msgid "Makes you are selling" msgstr "الماركات التي تبيعها" -#: templates/dealers/dealer_detail.html:166 +#: templates/dealers/dealer_detail.html:172 msgid "Select Makes" msgstr "اختر العلامات التجارية" @@ -4701,7 +5111,7 @@ msgstr "الخدمة المطلوبة" #: venv/lib/python3.11/site-packages/appointment/templates/email_sender/reminder_email.html:138 #: venv/lib/python3.11/site-packages/appointment/templates/email_sender/reschedule_email.html:65 #: venv/lib/python3.11/site-packages/appointment/templates/email_sender/reschedule_email.html:70 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2529 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2534 msgid "Time" msgstr "الوقت" @@ -4754,7 +5164,7 @@ msgid "This is a reminder for your upcoming appointment." msgstr "هذه تذكرة بموعدك القادم." #: templates/email_sender/reminder_email.html:83 -#: templates/inventory/car_detail.html:159 +#: templates/inventory/car_detail.html:180 #: venv/lib/python3.11/site-packages/appointment/templates/email_sender/reminder_email.html:142 msgid "Location" msgstr "الموقع" @@ -4887,17 +5297,25 @@ msgid "Account Activation" msgstr "تفعيل الحساب" #: templates/email_sender/thank_you_email.html:185 -#: venv/lib/python3.11/site-packages/appointment/templates/email_sender/thank_you_email.html:185 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "\n" +#| " To activate your account and set " +#| "your password, please use the following secure\n" +#| " link: Set Your Password. Please\n" +#| " note that this link will expire " +#| "in 2 days for your security.\n" +#| " " msgid "" "\n" -" To activate your account and set " -"your password, please use the following secure\n" -" link: Set Your Password. Please\n" -" note that this link will expire in 2 " -"days for your security.\n" -" " +" note that this link will " +"expire in 2 days for your security.\n" +" " msgstr "" "\n" " لتفعيل حسابك وتعيين كلمة المرور، " @@ -4939,13 +5357,19 @@ msgid "Support" msgstr "الدعم" #: templates/email_sender/thank_you_email.html:246 -#: venv/lib/python3.11/site-packages/appointment/templates/email_sender/thank_you_email.html:246 +#, fuzzy +#| msgid "" +#| "\n" +#| " Should you have any inquiries or require " +#| "further assistance, our support team is here to\n" +#| " help. You can reach us anytime.\n" +#| " " msgid "" "\n" -" Should you have any inquiries or require " -"further assistance, our support team is here to\n" -" help. You can reach us anytime.\n" -" " +" Should you have any inquiries or " +"require further assistance, our support team is here to\n" +" help. You can reach us anytime.\n" +" " msgstr "" "\n" " إذا كان لديك أي استفسارات أو كنت بحاجة إلى " @@ -5034,19 +5458,19 @@ msgid "Users" msgstr "المستخدمون" #: templates/groups/group_detail.html:65 templates/groups/group_detail.html:94 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3219 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3231 msgid "No Permissions" msgstr "بدون أذونات" #: templates/groups/group_detail.html:82 templates/groups/group_list.html:24 -#: templates/users/user_detail.html:65 templates/users/user_list.html:24 +#: templates/users/user_detail.html:34 templates/users/user_list.html:32 msgid "name" msgstr "الاسم" #: templates/groups/group_detail.html:114 #: templates/ledger/bank_accounts/bank_account_detail.html:68 -#: templates/ledger/coa_accounts/account_detail.html:122 -#: templates/users/user_detail.html:95 +#: templates/ledger/coa_accounts/account_detail.html:148 +#: templates/users/user_detail.html:65 msgid "Back to List" msgstr "العودة إلى القائمة" @@ -5066,17 +5490,17 @@ msgstr "إجمالي المستخدمين" msgid "total permission" msgstr "إجمالي الأذونات" -#: templates/groups/group_list.html:27 templates/users/user_list.html:30 +#: templates/groups/group_list.html:27 templates/users/user_list.html:36 msgid "actions" msgstr "الإجراءات" -#: templates/groups/group_list.html:40 templates/inventory/car_detail.html:112 -#: templates/inventory/car_inventory.html:114 -#: templates/ledger/coa_accounts/account_detail.html:92 +#: templates/groups/group_list.html:40 templates/inventory/car_detail.html:133 +#: templates/inventory/car_inventory.html:150 +#: templates/ledger/coa_accounts/account_detail.html:102 #: templates/representatives/representative_list.html:30 #: templates/sales/estimates/estimate_list.html:50 #: templates/sales/journals/journal_list.html:34 -#: templates/users/user_list.html:52 +#: templates/users/user_list.html:58 msgid "view" msgstr "عرض" @@ -5092,33 +5516,35 @@ msgstr "تحرير الإذن" msgid "Add Permission" msgstr "إضافة إذن" -#: templates/haikalbot/chatbot.html:4 templates/haikalbot/chatbot.html:22 -#: templates/haikalbot/chatbot.html:27 templates/haikalbot/chatbot.html:78 -msgid "HaikalBot" +#: templates/haikalbot/chatbot.html:5 +msgid "Haikalbot" msgstr "هيكل بوت" -#: templates/haikalbot/chatbot.html:27 -msgid "Hello! How can I assist you today?" -msgstr "مرحبًا! كيف يمكنني مساعدتك اليوم؟" +#: templates/haikalbot/chatbot.html:78 +msgid "How many cars are in inventory" +msgstr "كم عدد السيارات في المخزون" -#: templates/haikalbot/chatbot.html:32 -msgid "Type your message here..." -msgstr "اكتب رسالتك هنا..." +#: templates/haikalbot/chatbot.html:79 +msgid "Show me sales analysis" +msgstr "اعرض لي تحليل المبيعات" -#: templates/haikalbot/chatbot.html:33 -#: templates/sales/estimates/estimate_send.html:27 -msgid "Send" -msgstr "إرسال" +#: templates/haikalbot/chatbot.html:80 +msgid "What are the best-selling cars" +msgstr "ما هي السيارات الأكثر مبيعًا" -#: templates/haikalbot/chatbot.html:77 -msgid "You" -msgstr "أنت" +#: templates/haikalbot/chatbot.html:85 +msgid "Type your message here" +msgstr "اكتب رسالتك هنا" + +#: templates/haikalbot/chatbot.html:346 +msgid "Copy" +msgstr "نسخ" #: templates/header.html:27 msgid "add car" msgstr "إضافة سيارة" -#: templates/header.html:43 templates/inventory/car_inventory.html:52 +#: templates/header.html:43 templates/inventory/car_inventory.html:62 msgid "Stock" msgstr "المخزون" @@ -5150,62 +5576,66 @@ msgstr "إدارة علاقات العملاء" msgid "leads" msgstr "الفرص" -#: templates/header.html:181 templates/header.html:186 +#: templates/header.html:141 +msgid "leads Tracking" +msgstr "متابعة العملاء المحتملين" + +#: templates/header.html:195 templates/header.html:200 msgid "Financials" msgstr "البيانات المالية" -#: templates/header.html:191 +#: templates/header.html:205 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:436 #: venv/lib/python3.11/site-packages/django_ledger/models/chart_of_accounts.py:192 msgid "Chart of Accounts" msgstr "قائمة الحسابات" -#: templates/header.html:200 +#: templates/header.html:214 #: templates/ledger/bank_accounts/bank_account_list.html:4 #: templates/ledger/bank_accounts/bank_account_list.html:10 #: venv/lib/python3.11/site-packages/django_ledger/views/bank_account.py:33 msgid "Bank Accounts" msgstr "الحسابات المصرفية" -#: templates/header.html:209 +#: templates/header.html:223 #: venv/lib/python3.11/site-packages/django_ledger/models/ledger.py:214 msgid "Ledgers" msgstr "دفاتر الأستاذ" -#: templates/header.html:217 templates/items/service/service_list.html:10 +#: templates/header.html:231 templates/items/service/service_list.html:4 +#: templates/items/service/service_list.html:10 #: venv/lib/python3.11/site-packages/django_ledger/views/item.py:297 msgid "Services" msgstr "الخدمات" -#: templates/header.html:225 templates/items/expenses/expense_create.html:5 +#: templates/header.html:239 templates/items/expenses/expense_create.html:5 #: templates/items/expenses/expense_update.html:5 #: templates/items/expenses/expenses_list.html:4 -#: templates/items/expenses/expenses_list.html:10 -#: templates/items/service/service_list.html:4 +#: templates/items/expenses/expenses_list.html:11 #: templates/ledger/reports/dashboard.html:48 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/includes/widget_ic.html:8 msgid "Expenses" msgstr "المصروفات" -#: templates/header.html:234 +#: templates/header.html:248 msgid "vendors" msgstr "الموردين" -#: templates/header.html:243 +#: templates/header.html:257 msgid "bills" msgstr "الفواتير" -#: templates/header.html:255 +#: templates/header.html:269 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:11 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:42 msgid "Reports" msgstr "التقارير" -#: templates/header.html:282 +#: templates/header.html:297 msgid "Cash Flow" msgstr "التدفق النقدي" -#: templates/header.html:293 templates/ledger/ledger/ledger_detail.html:117 +#: templates/header.html:308 templates/ledger/ledger/ledger_detail.html:117 #: templates/ledger/reports/income_statement.html:31 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:146 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_update.html:71 @@ -5217,7 +5647,7 @@ msgstr "التدفق النقدي" msgid "Income Statement" msgstr "بيان الدخل" -#: templates/header.html:304 templates/ledger/ledger/ledger_detail.html:115 +#: templates/header.html:319 templates/ledger/ledger/ledger_detail.html:115 #: templates/ledger/reports/balance_sheet.html:36 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:144 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_update.html:66 @@ -5230,37 +5660,41 @@ msgstr "بيان الدخل" msgid "Balance Sheet" msgstr "الميزانية العمومية" -#: templates/header.html:351 templates/header.html:352 +#: templates/header.html:367 templates/header.html:368 #: templates/welcome_header.html:13 templates/welcome_header.html:14 msgid "Switch theme" msgstr "تبديل النمط" -#: templates/header.html:406 templates/header.html:410 +#: templates/header.html:422 templates/header.html:426 msgid "profile" msgstr "الملف الشخصي" -#: templates/header.html:415 +#: templates/header.html:431 msgid "Staff & Groups" msgstr "الموظفون والمجموعات" -#: templates/header.html:423 +#: templates/header.html:439 msgid "Settings" msgstr "الإعدادات" +#: templates/header.html:444 +msgid "Admin Managemnet" +msgstr "xxxxxxxxxxxxxxx" + #: templates/inventory/add_colors.html:5 msgid "Add Colors" msgstr "إضافة لون" -#: templates/inventory/add_colors.html:6 +#: templates/inventory/add_colors.html:7 msgid "Select exterior and interior colors for" msgstr "اختر الألوان الخارجية والداخلية لـ" -#: templates/inventory/car_detail.html:3 templates/inventory/car_detail.html:54 -#: templates/inventory/car_history.html:4 +#: templates/inventory/car_detail.html:3 templates/inventory/car_detail.html:71 +#: templates/inventory/car_history.html:3 msgid "Car Details" msgstr "تفاصيل السيارة" -#: templates/inventory/car_detail.html:23 +#: templates/inventory/car_detail.html:24 msgid "" "This car information is not complete , please add colors and finances before " "making it ready for sale ." @@ -5268,192 +5702,157 @@ msgstr "" "معلومات هذه السيارة غير مكتملة، يرجى إضافة الألوان المعلومات المالية قبل " "تجهيزها للبيع." -#: templates/inventory/car_detail.html:30 +#: templates/inventory/car_detail.html:25 +msgid "Add Color" +msgstr "إضافة لون" + +#: templates/inventory/car_detail.html:37 msgid "Action Required , Please Approved The Tranfer Request Of This Car ." msgstr "الإجراء مطلوب، يرجى الموافقة على طلب نقل هذه السيارة." -#: templates/inventory/car_detail.html:37 +#: templates/inventory/car_detail.html:48 msgid "" "Car Is In Transfer Process To Another Dealer, Please Wait For The " "Acceptance ." msgstr "السيارة قيد عملية النقل إلى تاجر آخر، يرجى انتظار القبول." -#: templates/inventory/car_detail.html:44 +#: templates/inventory/car_detail.html:59 msgid "This car is reserved until " msgstr "هذه السيارة محجوزة حتى " -#: templates/inventory/car_detail.html:63 templates/inventory/car_list.html:119 +#: templates/inventory/car_detail.html:80 templates/inventory/car_list.html:128 msgid "year" msgstr "السنة" -#: templates/inventory/car_detail.html:67 templates/inventory/car_form.html:84 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:82 -#: templates/inventory/car_list.html:79 +#: templates/inventory/car_detail.html:84 templates/inventory/car_form.html:91 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:70 +#: templates/inventory/car_list.html:88 msgid "make" msgstr "الصانع" -#: templates/inventory/car_detail.html:71 templates/inventory/car_form.html:107 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:99 -#: templates/inventory/car_list.html:97 +#: templates/inventory/car_detail.html:88 templates/inventory/car_form.html:114 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:83 +#: templates/inventory/car_list.html:106 msgid "model" msgstr "الموديل" -#: templates/inventory/car_detail.html:75 templates/inventory/car_list.html:130 +#: templates/inventory/car_detail.html:92 templates/inventory/car_list.html:139 msgid "series" msgstr "السلسلة" -#: templates/inventory/car_detail.html:79 templates/inventory/car_form.html:94 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:143 -#: templates/inventory/car_list.html:141 +#: templates/inventory/car_detail.html:96 templates/inventory/car_form.html:101 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:117 +#: templates/inventory/car_list.html:150 msgid "trim" msgstr "الفئة" -#: templates/inventory/car_detail.html:109 -#: templates/inventory/car_detail.html:485 -#: templates/inventory/car_form.html:118 templates/inventory/car_form.html:228 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:252 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:279 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:299 -#: templates/inventory/car_list.html:47 templates/inventory/car_list.html:221 +#: templates/inventory/car_detail.html:126 +#: templates/inventory/car_detail.html:536 +#: templates/inventory/car_form.html:125 templates/inventory/car_form.html:228 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:196 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:225 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:248 +#: templates/inventory/car_list.html:48 templates/inventory/car_list.html:234 msgid "specifications" msgstr "المواصفات" -#: templates/inventory/car_detail.html:162 -#: templates/inventory/car_inventory.html:92 +#: templates/inventory/car_detail.html:185 +#: templates/inventory/car_inventory.html:124 msgid "Our Showroom" msgstr "معرضنا" -#: templates/inventory/car_detail.html:166 +#: templates/inventory/car_detail.html:194 msgid "No location available." msgstr "لا يوجد موقع متاح." -#: templates/inventory/car_detail.html:181 +#: templates/inventory/car_detail.html:210 msgid "Sell to another dealer" msgstr "بيع السيارة لمعرض آخر" -#: templates/inventory/car_detail.html:185 -#: templates/inventory/car_detail.html:240 +#: templates/inventory/car_detail.html:214 +#: templates/inventory/car_detail.html:267 msgid "Cannot Edit, Car in Transfer." msgstr "لا يمكن التعديل، السيارة قيد النقل." -#: templates/inventory/car_detail.html:193 +#: templates/inventory/car_detail.html:222 msgid "Financial Details" msgstr "التفاصيل المالية" -#: templates/inventory/car_detail.html:214 +#: templates/inventory/car_detail.html:242 msgid "Additional Fee" msgstr "رسوم إضافية" -#: templates/inventory/car_detail.html:226 +#: templates/inventory/car_detail.html:254 #: templates/plans/invoices/layout.html:111 msgid "VAT Amount" msgstr "مبلغ ضريبة القيمة المضافة" -#: templates/inventory/car_detail.html:243 +#: templates/inventory/car_detail.html:270 msgid "No finance details available." msgstr "لا توجد تفاصيل مالية متاحة." -#: templates/inventory/car_detail.html:257 +#: templates/inventory/car_detail.html:283 msgid "Colors Details" msgstr "تفاصيل الألوان" -#: templates/inventory/car_detail.html:264 +#: templates/inventory/car_detail.html:289 msgid "Exterior" msgstr "الخارجي" -#: templates/inventory/car_detail.html:273 +#: templates/inventory/car_detail.html:299 msgid "Interior" msgstr "الداخلي" -#: templates/inventory/car_detail.html:285 +#: templates/inventory/car_detail.html:310 msgid "No colors available for this car." msgstr "لا تتوفر ألوان لهذه السيارة." -#: templates/inventory/car_detail.html:304 +#: templates/inventory/car_detail.html:327 msgid "Reservations Details" msgstr "تفاصيل الحجز" -#: templates/inventory/car_detail.html:312 +#: templates/inventory/car_detail.html:335 msgid "Expires At" msgstr "ينتهي في" -#: templates/inventory/car_detail.html:313 -#: templates/ledger/coa_accounts/account_detail.html:69 -#: templates/representatives/representative_list.html:20 -#: templates/sales/estimates/estimate_list.html:19 -#: templates/sales/invoices/invoice_list.html:20 -#: templates/sales/journals/journal_list.html:20 -#: templates/sales/payments/payment_list.html:24 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/account_txs_table.html:29 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:30 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:93 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html:39 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/tags/bill_table.html:16 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:13 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:36 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/customer/tags/customer_table.html:13 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/data_import/tags/data_import_job_list_table.html:38 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:16 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_table.html:38 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/expense/tags/expense_item_table.html:13 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html:27 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html:57 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:15 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:51 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:112 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:186 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:260 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:321 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/tags/invoice_table.html:39 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:16 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:16 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:95 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/product/tags/product_table.html:15 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/service/tags/services_table.html:15 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/uom/tags/uom_table.html:11 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/uom/tags/uom_table.html:33 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/vendor/tags/vendor_table.html:14 -msgid "Actions" -msgstr "الإجراءات" - -#: templates/inventory/car_detail.html:346 -#: templates/inventory/reserve_car.html:29 +#: templates/inventory/car_detail.html:377 +#: templates/inventory/reserve_car.html:22 msgid "Reserve" msgstr "حجز" -#: templates/inventory/car_detail.html:361 -#: templates/inventory/transfer_details.html:57 +#: templates/inventory/car_detail.html:392 +#: templates/inventory/transfer_details.html:70 msgid "Transfer Details" msgstr "تفاصيل النقل" -#: templates/inventory/car_detail.html:369 +#: templates/inventory/car_detail.html:400 msgid "From Showroom" msgstr "من صالة العرض" -#: templates/inventory/car_detail.html:370 +#: templates/inventory/car_detail.html:401 msgid "To Showroom" msgstr "إلى صالة العرض" -#: templates/inventory/car_detail.html:455 +#: templates/inventory/car_detail.html:505 msgid "Are you sure you want to reserve this car?" msgstr "هل أنت متأكد أنك تريد حجز هذه السيارة؟" -#: templates/inventory/car_detail.html:599 -#: templates/inventory/car_list.html:542 +#: templates/inventory/car_detail.html:651 +#: templates/inventory/car_list.html:548 #: templates/partials/specifications_modal.html:11 msgid "No specifications available." msgstr "لا توجد مواصفات متاحة." -#: templates/inventory/car_detail.html:603 -#: templates/inventory/car_list.html:546 +#: templates/inventory/car_detail.html:655 +#: templates/inventory/car_list.html:552 msgid "Error loading specifications." msgstr "حدث خطأ أثناء تحميل المواصفات." -#: templates/inventory/car_edit.html:1 templates/inventory/car_edit.html:4 +#: templates/inventory/car_edit.html:6 templates/inventory/car_edit.html:11 msgid "Edit Car" msgstr "تعديل السيارة" -#: templates/inventory/car_edit.html:10 +#: templates/inventory/car_edit.html:17 #: templates/two_factor/_wizard_actions.html:10 #: templates/two_factor/_wizard_actions.html:12 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/bank_account_create.html:25 @@ -5481,193 +5880,179 @@ msgstr "عودة" msgid "Car Finance Details" msgstr "التفاصيل المالية السيارة" -#: templates/inventory/car_finance_form.html:10 +#: templates/inventory/car_finance_form.html:11 msgid "Finance Details for" msgstr "التفاصيل المالية لـ" -#: templates/inventory/car_form.html:22 +#: templates/inventory/car_form.html:23 msgid "Please Add A Vendor, Before Adding A Car ." msgstr "يرجى إضافة مورد قبل إضافة السيارة." -#: templates/inventory/car_form.html:73 templates/inventory/car_form.html:92 -#: templates/inventory/car_form.html:105 templates/inventory/car_form.html:269 -#: templates/inventory/car_form.html:454 templates/inventory/car_form.html:471 -#: templates/inventory/car_form.html:472 templates/inventory/car_form.html:494 -#: templates/inventory/car_form.html:513 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:105 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:126 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:148 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:313 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:497 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:514 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:515 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:535 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:554 +#: templates/inventory/car_form.html:23 templates/vendors/vendor_form.html:20 +#: templates/vendors/vendors_list.html:15 +msgid "Add Vendor" +msgstr "إضافة مورد" + +#: templates/inventory/car_form.html:80 templates/inventory/car_form.html:99 +#: templates/inventory/car_form.html:112 templates/inventory/car_form.html:268 +#: templates/inventory/car_form.html:457 templates/inventory/car_form.html:474 +#: templates/inventory/car_form.html:475 templates/inventory/car_form.html:497 +#: templates/inventory/car_form.html:516 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:88 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:104 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:121 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:262 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:451 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:468 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:469 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:489 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:508 #: templates/plans/plan_table.html:120 msgid "Select" msgstr "اختيار" -#: templates/inventory/car_form.html:125 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:259 -#: templates/inventory/car_list.html:27 templates/inventory/car_list.html:214 +#: templates/inventory/car_form.html:131 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:202 +#: templates/inventory/car_list.html:25 templates/inventory/car_list.html:228 msgid "options" msgstr "الخيارات" -#: templates/inventory/car_form.html:205 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:262 +#: templates/inventory/car_form.html:203 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:206 msgid "Save and Add Another" msgstr "حفظ وإضافة آخر" -#: templates/inventory/car_form.html:208 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:265 +#: templates/inventory/car_form.html:209 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:210 msgid "Save and Go to Inventory" msgstr "حفظ والانتقال إلى المخزون" -#: templates/inventory/car_form.html:238 templates/inventory/car_form.html:257 -#: templates/inventory/car_form.html:277 templates/inventory/car_form.html:289 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:281 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:287 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:301 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:321 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:333 -#: templates/modal/confirm_modal.html:11 templates/modal/confirm_modal.html:20 -#: templates/modal/error_modal.html:17 -#: templates/modal/event_details_modal.html:21 -#: templates/partials/scanner_modal.html:6 -#: templates/partials/specifications_modal.html:8 -#: venv/lib/python3.11/site-packages/appointment/templates/modal/confirm_modal.html:18 -#: venv/lib/python3.11/site-packages/appointment/templates/modal/error_modal.html:17 -#: venv/lib/python3.11/site-packages/appointment/templates/modal/event_details_modal.html:19 -msgid "Close" -msgstr "إغلاق" - -#: templates/inventory/car_form.html:255 -#: venv/lib/python3.11/site-packages/click/core.py:1396 +#: templates/inventory/car_form.html:254 +#: venv/lib/python3.11/site-packages/click/core.py:1140 msgid "Options" msgstr "الخيارات" #: templates/inventory/car_form.html:264 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:308 -#: templates/inventory/car_list.html:152 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:258 +#: templates/inventory/car_list.html:161 msgid "equipment" msgstr "التجهيزات" -#: templates/inventory/car_form.html:288 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:332 +#: templates/inventory/car_form.html:289 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:283 msgid "scanner" msgstr "الماسح الضوئي" -#: templates/inventory/car_form.html:293 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:337 +#: templates/inventory/car_form.html:298 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:292 #: templates/partials/scanner_modal.html:10 msgid "VIN will appear here." msgstr "رقم الهيكل سيظهر هنا." -#: templates/inventory/car_form.html:294 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:338 +#: templates/inventory/car_form.html:299 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:293 #: templates/partials/scanner_modal.html:11 msgid "Use OCR Fallback" msgstr "التعرف الآلي على الحروف" -#: templates/inventory/car_form.html:365 templates/inventory/car_form.html:366 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:409 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:410 +#: templates/inventory/car_form.html:368 templates/inventory/car_form.html:369 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:363 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:364 msgid "Please enter a valid VIN." msgstr "الرجاء إدخال رقم هيكل صالح مكون من 17 حرفًا." -#: templates/inventory/car_form.html:388 -#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:432 +#: templates/inventory/car_form.html:391 +#: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:386 msgid "An error occurred while decoding the VIN." msgstr "حدث خطأ أثناء فك تشفير الهيكل" #: ⁨templates/inventory/car_form_qabl alfalsafa.html⁩:45 -#: templates/inventory/car_list_view.html:93 -#: templates/inventory/scan_vin.html:15 templates/partials/search_box.html:4 +#: templates/inventory/car_list_view.html:144 +#: templates/inventory/scan_vin.html:13 templates/partials/search_box.html:4 #: templates/representatives/representative_list.html:9 #: templates/representatives/representative_list.html:10 #: templates/sales/sales_list.html:50 msgid "Search" msgstr "بحث" -#: templates/inventory/car_history.html:17 +#: templates/inventory/car_history.html:24 msgid "History" msgstr "التاريخ" -#: templates/inventory/car_inventory.html:57 +#: templates/inventory/car_inventory.html:76 msgid "Showroom Location" msgstr "موقع صالة العرض" -#: templates/inventory/car_inventory.html:87 -#: templates/inventory/car_inventory.html:88 +#: templates/inventory/car_inventory.html:116 +#: templates/inventory/car_inventory.html:119 msgid "No Color" msgstr "بدون لون" -#: templates/inventory/car_inventory.html:120 +#: templates/inventory/car_inventory.html:156 msgid "No cars available." msgstr "لا توجد سيارات متاحة." -#: templates/inventory/car_inventory.html:121 +#: templates/inventory/car_inventory.html:157 msgid "Add a Car" msgstr "إضافة سيارة" -#: templates/inventory/car_list.html:70 -#: templates/ledger/bills/bill_list.html:27 -#: templates/ledger/coa_accounts/account_list.html:25 +#: templates/inventory/car_list.html:79 +#: templates/ledger/bills/bill_list.html:26 msgid "search" msgstr "بحث" -#: templates/inventory/car_list.html:81 templates/inventory/car_list.html:99 -#: templates/inventory/car_list.html:110 templates/inventory/car_list.html:121 -#: templates/inventory/car_list.html:132 templates/inventory/car_list.html:143 -#: templates/inventory/car_list.html:154 templates/inventory/car_list.html:165 -#: templates/inventory/car_list.html:179 templates/inventory/car_list.html:273 -#: templates/inventory/car_list.html:274 templates/inventory/car_list.html:275 -#: templates/inventory/car_list.html:276 templates/inventory/car_list.html:277 -#: templates/inventory/car_list.html:278 templates/inventory/car_list.html:378 -#: templates/inventory/car_list.html:379 templates/inventory/car_list.html:380 -#: templates/inventory/car_list.html:381 templates/inventory/car_list.html:382 -#: templates/inventory/car_list.html:407 templates/inventory/car_list.html:408 -#: templates/inventory/car_list.html:409 templates/inventory/car_list.html:410 -#: templates/inventory/car_list.html:436 templates/inventory/car_list.html:437 -#: templates/inventory/car_list.html:438 templates/inventory/car_list.html:463 -#: templates/inventory/car_list.html:464 templates/inventory/car_list.html:488 +#: templates/inventory/car_list.html:90 templates/inventory/car_list.html:108 +#: templates/inventory/car_list.html:119 templates/inventory/car_list.html:130 +#: templates/inventory/car_list.html:141 templates/inventory/car_list.html:152 +#: templates/inventory/car_list.html:163 templates/inventory/car_list.html:174 +#: templates/inventory/car_list.html:186 templates/inventory/car_list.html:279 +#: templates/inventory/car_list.html:280 templates/inventory/car_list.html:281 +#: templates/inventory/car_list.html:282 templates/inventory/car_list.html:283 +#: templates/inventory/car_list.html:284 templates/inventory/car_list.html:384 +#: templates/inventory/car_list.html:385 templates/inventory/car_list.html:386 +#: templates/inventory/car_list.html:387 templates/inventory/car_list.html:388 +#: templates/inventory/car_list.html:413 templates/inventory/car_list.html:414 +#: templates/inventory/car_list.html:415 templates/inventory/car_list.html:416 +#: templates/inventory/car_list.html:442 templates/inventory/car_list.html:443 +#: templates/inventory/car_list.html:444 templates/inventory/car_list.html:469 +#: templates/inventory/car_list.html:470 templates/inventory/car_list.html:494 msgid "select" msgstr "اختيار" -#: templates/inventory/car_list.html:108 +#: templates/inventory/car_list.html:117 msgid "generation" msgstr "الجيل" -#: templates/inventory/car_list.html:201 +#: templates/inventory/car_list.html:215 msgid "Enter remarks" msgstr "أدخل الملاحظات" -#: templates/inventory/car_list.html:225 +#: templates/inventory/car_list.html:235 msgid "save" msgstr "حفظ" -#: templates/inventory/car_list.html:345 +#: templates/inventory/car_list.html:351 msgid "Make not found for the decoded VIN." msgstr "لم يتم العثور على الشركة الصانعة الخاصة برقم الهيكل المدخل." -#: templates/inventory/car_list.html:353 +#: templates/inventory/car_list.html:359 msgid "Please enter a valid 17-character VIN number." msgstr "الرجاء إدخال رقم هيكل صالح مكون من 17 حرفًا." -#: templates/inventory/car_list.html:587 +#: templates/inventory/car_list.html:593 msgid "No options available." msgstr "لا توجد سيارات متاحة." -#: templates/inventory/car_list.html:591 +#: templates/inventory/car_list.html:597 msgid "Error loading options." msgstr "خطأ في تحميل الخيارات." -#: templates/inventory/car_list_table.html:13 +#: templates/inventory/car_list_table.html:10 msgid "Excel" msgstr "إكسل" -#: templates/inventory/car_list_view.html:37 -#: templates/inventory/car_list_view.html:85 +#: templates/inventory/car_list_view.html:41 +#: templates/inventory/car_list_view.html:129 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_list.html:98 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_list.html:110 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/closing_entry_list.html:76 @@ -5685,41 +6070,45 @@ msgstr "إكسل" msgid "All" msgstr "الكل" -#: templates/inventory/car_list_view.html:42 +#: templates/inventory/car_list_view.html:61 msgid "Filter" msgstr "تصفية" #: templates/inventory/car_list_view.html:168 +msgid "Date Received" +msgstr "تاريخ الاستلام" + +#: templates/inventory/car_list_view.html:232 #: templates/sales/sales_list.html:207 msgid "Export" msgstr "تصدير" -#: templates/inventory/car_location_form.html:4 -#: templates/inventory/car_location_form.html:8 +#: templates/inventory/car_location_form.html:5 +#: templates/inventory/car_location_form.html:9 msgid "Manage Car Location" msgstr "إدارة موقع السيارة" -#: templates/inventory/car_transfer_form.html:4 +#: templates/inventory/car_transfer_form.html:5 msgid "Car Transfer" msgstr "نقل السيارة" -#: templates/inventory/car_transfer_form.html:8 +#: templates/inventory/car_transfer_form.html:9 msgid "Sell car to another dealer" msgstr "بيع السيارة لتاجر آخر" -#: templates/inventory/car_transfer_form.html:13 +#: templates/inventory/car_transfer_form.html:14 msgid "Sell" msgstr "بيع" -#: templates/inventory/color_palette.html:74 +#: templates/inventory/color_palette.html:72 msgid "Update Color" msgstr "تحديث اللون" -#: templates/inventory/color_palette.html:77 +#: templates/inventory/color_palette.html:75 msgid "Add Color for" msgstr "إضافة لون الى" -#: templates/inventory/color_palette.html:83 +#: templates/inventory/color_palette.html:81 msgid "Color Type" msgstr "نوع اللون" @@ -5731,137 +6120,137 @@ msgstr "الموديلات" msgid "Trims" msgstr "الفئات" -#: templates/inventory/inventory_stats.html:75 +#: templates/inventory/inventory_stats.html:74 msgid "No trims available" msgstr "لا يوجد فئات متاحة." -#: templates/inventory/inventory_stats.html:81 +#: templates/inventory/inventory_stats.html:80 msgid "No models available." msgstr "لا توجد موديلات متاحة." -#: templates/inventory/reserve_car.html:11 +#: templates/inventory/reserve_car.html:9 msgid "You are reserving" msgstr "أنت تحجز" -#: templates/inventory/reserve_car.html:16 +#: templates/inventory/reserve_car.html:13 msgid "Reservation Start Time" msgstr "وقت بدء الحجز" -#: templates/inventory/reserve_car.html:23 +#: templates/inventory/reserve_car.html:18 msgid "Reservation End Time" msgstr "وقت انتهاء الحجز" -#: templates/inventory/scan_vin.html:6 +#: templates/inventory/scan_vin.html:5 msgid "Scan Vehicle Code" msgstr "مسح رمز السيارة" -#: templates/inventory/scan_vin.html:10 +#: templates/inventory/scan_vin.html:8 msgid "VIN / Barcode / QR Code" msgstr "رمز VIN / الباركود / رمز QR" -#: templates/inventory/scan_vin.html:14 +#: templates/inventory/scan_vin.html:12 msgid "Start Scanning" msgstr "ابدأ المسح" -#: templates/inventory/scan_vin.html:22 +#: templates/inventory/scan_vin.html:20 msgid "Switch Camera" msgstr "تبديل الكاميرا" -#: templates/inventory/scan_vin.html:23 +#: templates/inventory/scan_vin.html:21 msgid "Scan" msgstr "مسح" -#: templates/inventory/transfer_car.html:6 +#: templates/inventory/transfer_car.html:7 msgid "transfer car" msgstr "نقل السيارة" -#: templates/inventory/transfer_details.html:8 +#: templates/inventory/transfer_details.html:7 msgid "Car Transfer Details" msgstr "تفاصيل نقل السيارة" -#: templates/inventory/transfer_details.html:17 +#: templates/inventory/transfer_details.html:19 msgid "Car Transfer Approve" msgstr "الموافقة على نقل السيارة" -#: templates/inventory/transfer_details.html:21 +#: templates/inventory/transfer_details.html:25 #: templates/two_factor/profile/profile.html:21 msgid "Are you sure?" msgstr "هل أنت متأكد؟" -#: templates/inventory/transfer_details.html:38 -#: templates/inventory/transfer_details.html:109 +#: templates/inventory/transfer_details.html:49 +#: templates/inventory/transfer_details.html:135 msgid "Cancel Transfer" msgstr "إلغاء النقل" -#: templates/inventory/transfer_details.html:42 +#: templates/inventory/transfer_details.html:55 #: templates/ledger/bills/bill_detail.html:15 #: templates/ledger/bills/bill_detail.html:40 msgid "Are you sure" msgstr "هل أنت متأكد" -#: templates/inventory/transfer_details.html:60 -#: templates/inventory/transfer_preview.html:220 +#: templates/inventory/transfer_details.html:76 +#: templates/inventory/transfer_preview.html:274 msgid "From" msgstr "من" -#: templates/inventory/transfer_details.html:73 +#: templates/inventory/transfer_details.html:90 #: templates/plans/invoices/layout.html:110 -#: templates/plans/order_detail_table.html:10 templates/pricing_page.html:181 +#: templates/plans/order_detail_table.html:10 templates/pricing_page.html:180 #: templates/sales/estimates/sale_order_preview.html:205 #: templates/sales/invoices/invoice_detail.html:267 msgid "VAT" msgstr "ضريبة القيمة المضافة" -#: templates/inventory/transfer_details.html:92 -#: templates/inventory/transfer_preview.html:249 +#: templates/inventory/transfer_details.html:114 +#: templates/inventory/transfer_preview.html:304 #: templates/sales/estimates/sale_order_form.html:98 #: templates/sales/estimates/sale_order_preview.html:216 msgid "Total Amount" msgstr "المبلغ الإجمالي" -#: templates/inventory/transfer_details.html:93 +#: templates/inventory/transfer_details.html:117 msgid "Total Amount written" msgstr "المبلغ بالحروف" -#: templates/inventory/transfer_details.html:93 +#: templates/inventory/transfer_details.html:117 msgid "only" msgstr "فقط لا غير" -#: templates/inventory/transfer_details.html:105 +#: templates/inventory/transfer_details.html:130 #: templates/ledger/journal_entry/includes/card_invoice.html:116 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/card_estimate.html:80 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:161 msgid "Approve" msgstr "الموافقة" -#: templates/inventory/transfer_preview.html:159 +#: templates/inventory/transfer_preview.html:190 msgid "Download transfer" msgstr "تحميل النقل" -#: templates/inventory/transfer_preview.html:162 -#: templates/inventory/transfer_preview.html:174 +#: templates/inventory/transfer_preview.html:196 +#: templates/inventory/transfer_preview.html:214 msgid "Accept transfer" msgstr "قبول النقل" -#: templates/inventory/transfer_preview.html:165 -#: templates/inventory/transfer_preview.html:193 +#: templates/inventory/transfer_preview.html:202 +#: templates/inventory/transfer_preview.html:238 msgid "Reject transfer" msgstr "رفض النقل" -#: templates/inventory/transfer_preview.html:178 +#: templates/inventory/transfer_preview.html:220 msgid "Are you sure you want to accept this transfer?" msgstr "هل أنت متأكد أنك تريد قبول هذا النقل؟" -#: templates/inventory/transfer_preview.html:197 +#: templates/inventory/transfer_preview.html:244 msgid "Are you sure you want to reject this transfer?" msgstr "هل أنت متأكد أنك تريد رفض هذا النقل؟" -#: templates/inventory/transfer_preview.html:214 +#: templates/inventory/transfer_preview.html:266 #: templates/sales/estimates/sale_order_preview.html:160 msgid "Thank you for choosing us. We appreciate your business" msgstr "شكرًا لاختيارك لنا. نحن نقدر عملك معنا." -#: templates/inventory/transfer_preview.html:231 +#: templates/inventory/transfer_preview.html:287 #: templates/ledger/bills/bill_detail.html:215 #: templates/plans/invoices/layout.html:103 #: templates/sales/estimates/estimate_detail.html:196 @@ -5871,19 +6260,19 @@ msgstr "شكرًا لاختيارك لنا. نحن نقدر عملك معنا." msgid "Unit Price" msgstr "سعر الوحدة" -#: templates/inventory/transfer_preview.html:254 +#: templates/inventory/transfer_preview.html:310 #: templates/sales/estimates/sale_order_preview.html:221 msgid "If you have any questions, feel free to contact us at" msgstr "إذا كان لديك أي أسئلة، يرجى التواصل معنا على" -#: templates/inventory/transfer_preview.html:255 +#: templates/inventory/transfer_preview.html:312 #: templates/plans/invoices/layout.html:195 #: templates/sales/estimates/sale_order_preview.html:222 msgid "Thank you for your business" msgstr "شكراً لتعاملك معنا" #: templates/items/expenses/expense_create.html:11 -#: templates/items/expenses/expenses_list.html:11 +#: templates/items/expenses/expenses_list.html:12 msgid "Add Expense" msgstr "إضافة مصروف" @@ -5891,7 +6280,7 @@ msgstr "إضافة مصروف" msgid "Update Expense" msgstr "تحديث المصروف" -#: templates/items/expenses/expenses_list.html:19 +#: templates/items/expenses/expenses_list.html:20 #: templates/items/service/service_list.html:19 #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:530 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/product/tags/product_table.html:9 @@ -5899,17 +6288,19 @@ msgstr "تحديث المصروف" msgid "Item Number" msgstr "رقم العنصر" -#: templates/items/expenses/expenses_list.html:21 +#: templates/items/expenses/expenses_list.html:22 #: templates/items/service/service_list.html:21 #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:535 msgid "Unit of Measure" msgstr "وحدة القياس" -#: templates/items/expenses/expenses_list.html:40 -#: templates/items/service/service_list.html:50 -#: templates/sales/invoices/invoice_list.html:67 -msgid "No Invoice Found" -msgstr "لم يتم العثور على فاتورة" +#: templates/items/expenses/expenses_list.html:58 +#: templates/items/service/service_list.html:63 +#: templates/ledger/bank_accounts/bank_account_list.html:48 +#: templates/ledger/coa_accounts/account_list.html:107 +#: templates/vendors/vendors_list.html:138 +msgid "No Accounts Found" +msgstr "لم يتم العثور على أي حسابات" #: templates/items/service/service_create.html:13 #: venv/lib/python3.11/site-packages/appointment/views_admin.py:472 @@ -5956,16 +6347,16 @@ msgstr "حساب نقدي" msgid "bank account" msgstr "الحساب المصرفي" -#: templates/ledger/bank_accounts/bank_account_form.html:14 +#: templates/ledger/bank_accounts/bank_account_form.html:15 msgid "Edit Bank Account" msgstr "تحديث الحساب المصرفي" -#: templates/ledger/bank_accounts/bank_account_form.html:17 +#: templates/ledger/bank_accounts/bank_account_form.html:18 #: templates/ledger/bank_accounts/bank_account_list.html:11 msgid "Add Bank Account" msgstr "إضافة حساب بنكي" -#: templates/ledger/bank_accounts/bank_account_list.html:19 +#: templates/ledger/bank_accounts/bank_account_list.html:20 #: templates/ledger/reports/tags/income_statement.html:8 #: venv/lib/python3.11/site-packages/django_ledger/forms/bank_account.py:87 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:1148 @@ -5973,12 +6364,6 @@ msgstr "إضافة حساب بنكي" msgid "Account Number" msgstr "رقم الحساب" -#: templates/ledger/bank_accounts/bank_account_list.html:39 -#: templates/ledger/journal_entry/journal_entry_list.html:124 -#: templates/ledger/ledger/ledger_list.html:116 -msgid "No Bank Accounts Found" -msgstr "لم يتم العثور على أي حساب بنكي." - #: templates/ledger/bills/bill_detail.html:4 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/purchase_order/includes/po_item_formset.html:61 msgid "View Bill" @@ -6044,7 +6429,7 @@ msgid "Due Amount" msgstr "المبلغ الكلي" #: templates/ledger/bills/bill_detail.html:158 -#: templates/ledger/bills/bill_list.html:45 +#: templates/ledger/bills/bill_list.html:50 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:356 msgid "Bill Number" msgstr "رقم الفاتورة" @@ -6105,6 +6490,7 @@ msgstr "إنشاء فاتورة" #: templates/ledger/bills/bill_list.html:4 #: templates/ledger/bills/bill_list.html:8 +#: templates/ledger/bills/bill_list.html:16 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:393 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/estimate_detail.html:84 msgid "Bills" @@ -6115,26 +6501,24 @@ msgstr "الفواتير" msgid "New Bill" msgstr "فاتورة جديدة" -#: templates/ledger/bills/bill_list.html:28 +#: templates/ledger/bills/bill_list.html:32 msgid "Search bills..." msgstr "ابحث عن الفواتير ..." -#: templates/ledger/bills/bill_list.html:48 +#: templates/ledger/bills/bill_list.html:51 #: venv/lib/python3.11/site-packages/django_ledger/models/bill.py:360 msgid "Bill Status" msgstr "حالة الفاتورة" -#: templates/ledger/bills/bill_list.html:88 +#: templates/ledger/bills/bill_list.html:92 msgid "No bill found." msgstr "لم يتم العثور على فاتورة." -#: templates/ledger/bills/bill_list.html:97 -#: templates/ledger/coa_accounts/account_list.html:136 +#: templates/ledger/bills/bill_list.html:99 msgid "to" msgstr "إلى" -#: templates/ledger/bills/bill_list.html:97 -#: templates/ledger/coa_accounts/account_list.html:136 +#: templates/ledger/bills/bill_list.html:99 msgid "Items of" msgstr "عناصر" @@ -6147,7 +6531,7 @@ msgid "Are you sure you want to delete this account?" msgstr "هل أنت متأكد أنك تريد حذف هذا الحساب؟" #: templates/ledger/coa_accounts/account_detail.html:39 -#: templates/ledger/coa_accounts/account_list.html:49 +#: templates/ledger/coa_accounts/account_list.html:25 #: templates/ledger/journal_entry/journal_entry_transactions.html:19 #: templates/ledger/reports/tags/balance_sheet_statement.html:14 #: templates/sales/payments/payment_details.html:16 @@ -6173,7 +6557,7 @@ msgstr "رمز الحساب" #: templates/ledger/coa_accounts/account_detail.html:48 #: templates/ledger/coa_accounts/account_detail.html:50 -#: templates/ledger/coa_accounts/account_list.html:51 +#: templates/ledger/coa_accounts/account_list.html:27 #: templates/ledger/reports/tags/balance_sheet_statement.html:18 #: templates/ledger/reports/tags/income_statement.html:13 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:26 @@ -6183,12 +6567,12 @@ msgid "Balance Type" msgstr "نوع الرصيد" #: templates/ledger/coa_accounts/account_detail.html:48 -#: templates/ledger/coa_accounts/account_detail.html:65 -#: templates/ledger/coa_accounts/account_list.html:101 +#: templates/ledger/coa_accounts/account_detail.html:68 +#: templates/ledger/coa_accounts/account_list.html:82 #: templates/ledger/journal_entry/journal_entry_transactions.html:21 #: templates/sales/payments/payment_details.html:18 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:423 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:424 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:448 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:13 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:48 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/transactions/tags/txs_table.html:13 @@ -6197,12 +6581,12 @@ msgid "Debit" msgstr "مدين" #: templates/ledger/coa_accounts/account_detail.html:50 -#: templates/ledger/coa_accounts/account_detail.html:66 -#: templates/ledger/coa_accounts/account_list.html:103 +#: templates/ledger/coa_accounts/account_detail.html:69 +#: templates/ledger/coa_accounts/account_list.html:84 #: templates/ledger/journal_entry/journal_entry_transactions.html:22 #: templates/sales/payments/payment_details.html:19 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:422 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:423 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:447 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:12 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_txs_table.html:47 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/transactions/tags/txs_table.html:12 @@ -6210,7 +6594,7 @@ msgstr "مدين" msgid "Credit" msgstr "دائن" -#: templates/ledger/coa_accounts/account_detail.html:63 +#: templates/ledger/coa_accounts/account_detail.html:66 msgid "JE Number" msgstr "رقم القيد المحاسبي" @@ -6229,32 +6613,24 @@ msgstr "إضافة حساب" #: templates/ledger/coa_accounts/account_list.html:3 #: templates/ledger/coa_accounts/account_list.html:6 -#: templates/ledger/coa_accounts/account_list.html:20 +#: templates/ledger/coa_accounts/account_list.html:14 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:444 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/chart_of_accounts/includes/coa_card.html:54 msgid "Accounts" msgstr "الحسابات" -#: templates/ledger/coa_accounts/account_list.html:17 +#: templates/ledger/coa_accounts/account_list.html:15 msgid "New Account" msgstr "حساب جديد" -#: templates/ledger/coa_accounts/account_list.html:31 -msgid "Search accounts..." -msgstr "ابحث عن الحسابات..." - -#: templates/ledger/coa_accounts/account_list.html:72 +#: templates/ledger/coa_accounts/account_list.html:46 msgid "Delete Account" msgstr "حذف الحساب" -#: templates/ledger/coa_accounts/account_list.html:79 +#: templates/ledger/coa_accounts/account_list.html:53 msgid "Are you sure you want to delete this Account?" msgstr "هل أنت متأكد أنك تريد حذف هذا الحساب؟" -#: templates/ledger/coa_accounts/account_list.html:128 -msgid "No account found." -msgstr "لم يتم العثور على حساب." - #: templates/ledger/journal_entry/includes/card_invoice.html:15 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:16 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:14 @@ -6291,20 +6667,6 @@ msgstr "هذه الفاتورة هي" msgid "Amount Due" msgstr "المبلغ المستحق" -#: templates/ledger/journal_entry/includes/card_invoice.html:52 -#: templates/ledger/journal_entry/includes/card_invoice.html:63 -#: templates/ledger/journal_entry/includes/card_invoice.html:77 -#: templates/plans/invoices/layout.html:161 -#: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:976 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:72 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:89 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/includes/card_bill.html:110 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:63 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:80 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/invoice/includes/card_invoice.html:101 -msgid "Due Date" -msgstr "تاريخ الاستحقاق" - #: templates/ledger/journal_entry/includes/card_invoice.html:53 #: templates/ledger/journal_entry/includes/card_invoice.html:64 #: templates/ledger/journal_entry/includes/card_invoice.html:78 @@ -6390,7 +6752,7 @@ msgid "Journal Entry Detail" msgstr "تفاصيل إدخال اليومية" #: templates/ledger/journal_entry/includes/card_journal_entry.html:17 -#: templates/ledger/journal_entry/journal_entry_list.html:66 +#: templates/ledger/journal_entry/journal_entry_list.html:52 #: templates/ledger/ledger/ledger_list.html:23 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:391 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:18 @@ -6400,7 +6762,7 @@ msgid "Posted" msgstr "تم النشر" #: templates/ledger/journal_entry/includes/card_journal_entry.html:24 -#: templates/ledger/journal_entry/journal_entry_list.html:67 +#: templates/ledger/journal_entry/journal_entry_list.html:53 #: templates/ledger/ledger/ledger_list.html:24 #: venv/lib/python3.11/site-packages/django_ledger/models/accounts.py:432 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:392 @@ -6413,8 +6775,8 @@ msgstr "مقفل" #: templates/ledger/journal_entry/includes/card_journal_entry.html:42 #: templates/ledger/journal_entry/journal_entry_txs.html:71 -#: templates/ledger/ledger/ledger_list.html:82 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:113 +#: templates/ledger/ledger/ledger_list.html:84 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:109 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:43 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_detail_txs.html:64 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:76 @@ -6424,7 +6786,7 @@ msgstr "قفل" #: templates/ledger/journal_entry/includes/card_journal_entry.html:46 #: templates/ledger/journal_entry/journal_entry_txs.html:77 -#: templates/ledger/ledger/ledger_list.html:86 +#: templates/ledger/ledger/ledger_list.html:88 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:47 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_detail_txs.html:70 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:109 @@ -6433,7 +6795,7 @@ msgstr "إلغاء القفل" #: templates/ledger/journal_entry/includes/card_journal_entry.html:50 #: templates/ledger/journal_entry/journal_entry_txs.html:83 -#: templates/ledger/ledger/ledger_list.html:90 +#: templates/ledger/ledger/ledger_list.html:92 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/includes/card_closing_entry.html:28 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:51 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_detail_txs.html:76 @@ -6444,7 +6806,7 @@ msgstr "نشر" #: templates/ledger/journal_entry/includes/card_journal_entry.html:54 #: templates/ledger/journal_entry/journal_entry_txs.html:89 -#: templates/ledger/ledger/ledger_list.html:94 +#: templates/ledger/ledger/ledger_list.html:96 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/includes/card_closing_entry.html:46 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/includes/card_journal_entry.html:55 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_detail_txs.html:82 @@ -6461,9 +6823,9 @@ msgid "Create Journal Entry" msgstr "إنشاء إدخال يومية" #: templates/ledger/journal_entry/journal_entry_list.html:4 -#: templates/ledger/journal_entry/journal_entry_list.html:36 +#: templates/ledger/journal_entry/journal_entry_list.html:38 #: templates/ledger/ledger/ledger_list.html:21 -#: templates/ledger/ledger/ledger_list.html:46 +#: templates/ledger/ledger/ledger_list.html:48 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:408 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_list.html:19 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:10 @@ -6479,16 +6841,16 @@ msgstr "إدخالات دفتر اليومية" msgid "Are you sure ?" msgstr "هل أنت متأكد؟" -#: templates/ledger/journal_entry/journal_entry_list.html:53 +#: templates/ledger/journal_entry/journal_entry_list.html:39 msgid "Add Journal Entry" msgstr "إضافة قيد يومية" -#: templates/ledger/journal_entry/journal_entry_list.html:62 +#: templates/ledger/journal_entry/journal_entry_list.html:48 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:8 msgid "Document Number" msgstr "رقم المستند" -#: templates/ledger/journal_entry/journal_entry_list.html:63 +#: templates/ledger/journal_entry/journal_entry_list.html:49 #: templates/ledger/journal_entry/journal_entry_transactions.html:18 #: templates/sales/payments/payment_details.html:15 #: templates/sales/payments/payment_list.html:22 @@ -6499,20 +6861,24 @@ msgstr "رقم المستند" msgid "Timestamp" msgstr "الطابع الزمني" -#: templates/ledger/journal_entry/journal_entry_list.html:68 +#: templates/ledger/journal_entry/journal_entry_list.html:54 msgid "Transaction Count" msgstr "عدد المعاملات" -#: templates/ledger/journal_entry/journal_entry_list.html:114 +#: templates/ledger/journal_entry/journal_entry_list.html:100 #: templates/ledger/journal_entry/journal_entry_transactions.html:4 #: templates/ledger/journal_entry/journal_entry_transactions.html:11 #: templates/sales/payments/payment_details.html:4 #: templates/sales/payments/payment_details.html:8 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:466 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:490 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:91 msgid "Transactions" msgstr "المعاملات" +#: templates/ledger/journal_entry/journal_entry_list.html:110 +msgid "No Bank Accounts Found" +msgstr "لم يتم العثور على أي حساب بنكي." + #: templates/ledger/journal_entry/journal_entry_transactions.html:17 #: templates/sales/payments/payment_details.html:14 msgid "#" @@ -6585,13 +6951,13 @@ msgstr "معاملات الفاتورة" #: templates/ledger/ledger/ledger_form.html:5 #: templates/ledger/ledger/ledger_form.html:9 -#: templates/ledger/ledger/ledger_list.html:14 +#: templates/ledger/ledger/ledger_list.html:13 #: venv/lib/python3.11/site-packages/django_ledger/views/ledger.py:95 msgid "Create Ledger" msgstr "إنشاء دفتر الأستاذ" #: templates/ledger/ledger/ledger_list.html:4 -#: templates/ledger/ledger/ledger_list.html:9 +#: templates/ledger/ledger/ledger_list.html:12 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:396 #: venv/lib/python3.11/site-packages/django_ledger/models/ledger.py:213 #: venv/lib/python3.11/site-packages/django_ledger/models/mixins.py:217 @@ -6608,16 +6974,20 @@ msgstr "اسم دفتر الأستاذ" msgid "Created Date" msgstr "تاريخ الإنشاء" -#: templates/ledger/ledger/ledger_list.html:99 +#: templates/ledger/ledger/ledger_list.html:101 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:122 msgid "Hide" msgstr "إخفاء" -#: templates/ledger/ledger/ledger_list.html:103 +#: templates/ledger/ledger/ledger_list.html:105 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/ledger/tags/ledgers_table.html:126 msgid "UnHide" msgstr "إلغاء الإخفاء" +#: templates/ledger/ledger/ledger_list.html:118 +msgid "No Entries found" +msgstr "لم يتم العثور على أي مدخلات" + #: templates/ledger/reports/balance_sheet.html:38 #: templates/ledger/reports/cash_flow_statement.html:33 #: templates/ledger/reports/income_statement.html:28 @@ -6642,7 +7012,7 @@ msgstr "الوحدة" #: templates/ledger/reports/cash_flow_statement.html:38 #: templates/ledger/reports/components/period_navigator.html:11 #: templates/ledger/reports/income_statement.html:35 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3173 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3186 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/balance_sheet.html:37 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/cash_flow.html:38 msgid "Fiscal Year" @@ -7044,7 +7414,7 @@ msgstr[5] "سينتهي حسابك %(user)s خلال %(days)s أيام." msgid "Go" msgstr "اذهب" -#: templates/notifications.html:14 +#: templates/notifications-copy.html:14 templates/notifications.html:24 msgid "Mark all as read" msgstr "وضع علامة مقروء على الكل" @@ -7187,10 +7557,15 @@ msgid "Continue" msgstr "متابعة" #: templates/plans/create_order.html:34 +#, fuzzy +#| msgid "" +#| "\n" +#| " Invoice for this order will be issued for:\n" +#| " " msgid "" "\n" -" Invoice for this order will be issued for:\n" -" " +" Invoice for this order will be issued for:\n" +" " msgstr "" "\n" " سيتم إصدار فاتورة لهذا الطلب لـ:\n" @@ -7202,13 +7577,19 @@ msgid "VAT ID" msgstr "رقم ضريبة القيمة المضافة" #: templates/plans/create_order.html:49 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "\n" +#| " If this data is not correct please edit billing data before\n" +#| " making an order.\n" +#| " " msgid "" "\n" -" If this data is not correct please edit billing data before\n" -" making an order.\n" -" " +" making an order.\n" +" " msgstr "" "\n" " إذا كانت هذه البيانات غير صحيحة، يرجى not be issued. If you need an " +#| "invoice please provide\n" +#| " billing data " +#| "before making an order.\n" +#| " " msgid "" "\n" -" Invoice will not be issued. If you need an " -"invoice please provide\n" -" billing data " -"before making an order.\n" -" " +" Invoice will not be issued. If you " +"need an invoice please provide\n" +" billing " +"data before making an order.\n" +" " msgstr "" "\n" " لن يتم إصدار فاتورة. إذا كنت بحاجة إلى فاتورة، يرجى " @@ -7238,7 +7626,7 @@ msgid "Your Account" msgstr "حسابك" #: templates/plans/current.html:42 templates/plans/extend.html:24 -#: templates/pricing_page.html:179 +#: templates/pricing_page.html:178 msgid "Plan" msgstr "الخطة" @@ -7247,22 +7635,31 @@ msgid "Plan Details" msgstr "تفاصيل الخطة" #: templates/plans/expiration_messages.html:7 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "Your account has expired.\n" +#| " Please extend your account." msgid "" "Your account has expired.\n" -" Please extend your account." +" Please extend your account." msgstr "" "لقد انتهت صلاحية حسابك.\n" " يرجى تمديد حسابك." #: templates/plans/expiration_messages.html:14 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "\n" +#| " Your account is not active. Possibly you are over some " +#| "limits.\n" +#| " Try to activate your account.\n" +#| " " msgid "" "\n" -" Your account is not active. Possibly you are over some " +" Your account is not active. Possibly you are over some " "limits.\n" -" Try to activate your account.\n" -" " +" Try to activate your account.\n" +" " msgstr "" "\n" " حسابك غير نشط. ربما تجاوزت بعض الحدود.\n" @@ -7270,13 +7667,21 @@ msgstr "" " " #: templates/plans/expiration_messages.html:23 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "\n" +#| " Your account will expire soon (in %(days_to_expire)s " +#| "days).\n" +#| " We recommend to extend your " +#| "account now.\n" +#| " " msgid "" "\n" -" Your account will expire soon (in %(days_to_expire)s days).\n" -" We recommend to extend your " +" Your account will expire soon (in %(days_to_expire)s " +"days).\n" +" We recommend to extend your " "account now.\n" -" " +" " msgstr "" "\n" " سينتهي حسابك قريبًا (خلال %(days_to_expire)s أيام).\n" @@ -7300,17 +7705,23 @@ msgid "Pricings" msgstr "السعر" #: templates/plans/extend.html:44 templates/plans/plan_table.html:95 -#: templates/pricing_page.html:68 +#: templates/pricing_page.html:67 msgid "days" msgstr "أيام" #: templates/plans/extend.html:54 -#, python-format +#, fuzzy, python-format +#| msgid "" +#| "\n" +#| " Unfortunately your current plan is not available any " +#| "more. You need to upgrade your plan.\n" +#| " " msgid "" "\n" -" Unfortunately your current plan is not available any more. " -"You need to upgrade your plan.\n" -" " +" Unfortunately your current plan is not " +"available any more. You need to upgrade your " +"plan.\n" +" " msgstr "" "\n" " للأسف، خطتك الحالية لم تعد متاحة. تحتاج إلى This plan is no longer " +"

This plan is no longer " "available.

\n" -"
Upgrade to current plans →\n" -" " +" Upgrade to current plans →\n" +" " msgstr "" "\n" " هذه الخطة لم تعد متاحة ولا يمكن تمديدها." @@ -7579,47 +7990,47 @@ msgstr "اختر الخطة" msgid "Choose Your Plan" msgstr "اختر خطتك" -#: templates/pricing_page.html:58 +#: templates/pricing_page.html:57 msgid "Select a Plan" msgstr "اختر خطة" -#: templates/pricing_page.html:69 templates/welcome.html:109 +#: templates/pricing_page.html:68 templates/welcome.html:109 msgid "Included" msgstr "متضمن" -#: templates/pricing_page.html:90 +#: templates/pricing_page.html:89 msgid "Enter Your Information" msgstr "أدخل معلوماتك" -#: templates/pricing_page.html:135 templates/pricing_page.html:138 +#: templates/pricing_page.html:134 templates/pricing_page.html:137 msgid "Cardholder Name" msgstr "اسم حامل البطاقة" -#: templates/pricing_page.html:153 templates/pricing_page.html:156 +#: templates/pricing_page.html:152 templates/pricing_page.html:155 msgid "Expiry Date" msgstr "تاريخ الانتهاء" -#: templates/pricing_page.html:163 templates/pricing_page.html:166 +#: templates/pricing_page.html:162 templates/pricing_page.html:165 msgid "CVV" msgstr "رمز الأمان (CVV)" -#: templates/pricing_page.html:176 +#: templates/pricing_page.html:175 msgid "Confirm Your Information" msgstr "تأكيد معلوماتك" -#: templates/pricing_page.html:178 +#: templates/pricing_page.html:177 msgid "Order Summary" msgstr "ملخص الطلب" -#: templates/pricing_page.html:185 +#: templates/pricing_page.html:184 msgid "User Information" msgstr "معلومات المستخدم" -#: templates/pricing_page.html:192 +#: templates/pricing_page.html:191 msgid "Cardholder" msgstr "حامل البطاقة" -#: templates/pricing_page.html:194 +#: templates/pricing_page.html:193 msgid "Expiry" msgstr "الانتهاء" @@ -7717,10 +8128,14 @@ msgstr "تاريخ الحالة" #: templates/sales/estimates/estimate_list.html:56 #: templates/sales/journals/journal_list.html:40 -#: templates/sales/orders/order_list.html:41 +#: templates/sales/orders/order_list.html:34 msgid "No Quotations Found" msgstr "لم يتم العثور على عروض" +#: templates/sales/estimates/estimate_send.html:27 +msgid "Send" +msgstr "إرسال" + #: templates/sales/estimates/sale_order_form.html:5 #: templates/sales/estimates/sale_order_preview.html:159 msgid "Sale Order" @@ -7803,16 +8218,15 @@ msgstr "حالة الفاتورة" msgid "Past Due" msgstr "مستحق" +#: templates/sales/invoices/invoice_list.html:68 +msgid "No Invoice Found" +msgstr "لم يتم العثور على فاتورة" + #: templates/sales/journals/journal_form.html:5 #: templates/sales/journals/journal_form.html:9 msgid "Create Payment" msgstr "إجراء الدفع" -#: templates/sales/orders/order_list.html:4 -#: templates/sales/orders/order_list.html:8 -msgid "Orders" -msgstr "طلبات" - #: templates/sales/orders/order_list.html:14 msgid "Order Number" msgstr "رقم الطلب" @@ -7826,7 +8240,7 @@ msgid "Print" msgstr "طباعة" #: templates/sales/orders/purchase_order.html:45 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3157 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3170 msgid "Purchase Order" msgstr "أمر شراء" @@ -7887,6 +8301,10 @@ msgstr "حجم المخزون" msgid "Now" msgstr "الآن" +#: templates/terms_and_privacy.html:4 +msgid "Terms of use and privacy policy" +msgstr "شروط الاستخدام وسياسة الخصوصية" + #: templates/two_factor/core/backup_tokens.html:5 #: templates/two_factor/profile/profile.html:34 msgid "Backup Tokens" @@ -8183,22 +8601,22 @@ msgstr "" msgid "View Staff" msgstr "عرض الموظفين" -#: templates/users/user_detail.html:20 -msgid "Are you sure you want to delete this user?" -msgstr "هل أنت متأكد أنك تريد حذف هذا المستخدم؟" - -#: templates/users/user_detail.html:42 +#: templates/users/user_detail.html:11 msgid "User Details" msgstr "تفاصيل المستخدم" -#: templates/users/user_detail.html:52 +#: templates/users/user_detail.html:21 msgid "Role" msgstr "الدور" -#: templates/users/user_detail.html:75 +#: templates/users/user_detail.html:44 msgid "No Group" msgstr "لا يوجد مجموعة" +#: templates/users/user_detail.html:58 +msgid "Are you sure you want to delete this user?" +msgstr "هل أنت متأكد أنك تريد حذف هذا المستخدم؟" + #: templates/users/user_form.html:17 msgid "Edit Staff" msgstr "تعديل الموظف" @@ -8207,51 +8625,39 @@ msgstr "تعديل الموظف" msgid "Add Staff" msgstr "إضافة موظف" -#: templates/users/user_group_form.html:13 +#: templates/users/user_group_form.html:10 msgid "Manage Groups" msgstr "إدارة المجموعات" -#: templates/users/user_list.html:14 +#: templates/users/user_list.html:15 msgid "Add New Staff" msgstr "إضافة موظف جديد" -#: templates/users/user_list.html:15 +#: templates/users/user_list.html:16 msgid "Manage Groups & Permissions" msgstr "إدارة المجموعات والأذونات" -#: templates/users/user_list.html:25 -msgid "arabic name" -msgstr "الاسم بالعربية" +#: templates/users/user_list.html:20 +msgid "No Active Subscription,please activate your subscription." +msgstr "لا يوجد اشتراك نشط، يرجى تفعيل اشتراكك." -#: templates/users/user_list.html:27 +#: templates/users/user_list.html:34 msgid "phone number" msgstr "رقم الهاتف" -#: templates/users/user_list.html:28 +#: templates/users/user_list.html:35 msgid "role" msgstr "الدور" -#: templates/users/user_list.html:29 -msgid "groups" -msgstr "المجموعات" - #: templates/vendors/vendor_form.html:17 msgid "Edit Vendor" msgstr "تعديل مورد" -#: templates/vendors/vendor_form.html:20 templates/vendors/vendors_list.html:18 -msgid "Add Vendor" -msgstr "إضافة مورد" - -#: templates/vendors/vendors_list.html:27 -msgid "Enter vendor name" -msgstr "أدخل اسم المورد" - -#: templates/vendors/vendors_list.html:59 +#: templates/vendors/vendors_list.html:58 msgid "Contact name" msgstr "اسم جهة الاتصال" -#: templates/vendors/vendors_list.html:110 +#: templates/vendors/vendors_list.html:129 #: templates/vendors/view_vendor.html:37 msgid "Are you sure you want to delete this vendor" msgstr "هل أنت متأكد أنك تريد حذف هذا المورد" @@ -8802,6 +9208,40 @@ msgstr "يرجى التأكد من أن" msgid "reviews this appointment request and takes the necessary action." msgstr "يقوم بمراجعة طلب الموعد هذا واتخاذ الإجراءات اللازمة." +#: venv/lib/python3.11/site-packages/appointment/templates/email_sender/thank_you_email.html:185 +#, python-format +msgid "" +"\n" +" To activate your account and set " +"your password, please use the following secure\n" +" link: Set Your Password. Please\n" +" note that this link will expire in 2 " +"days for your security.\n" +" " +msgstr "" +"\n" +" لتفعيل حسابك وتعيين كلمة المرور، " +"يرجى استخدام الرابط الآمن التالي: تعيين كلمة المرور. يرجى\n" +" ملاحظة أن هذا الرابط سينتهي صلاحيته " +"خلال يومين لضمان الأمان.\n" +" " + +#: venv/lib/python3.11/site-packages/appointment/templates/email_sender/thank_you_email.html:246 +msgid "" +"\n" +" Should you have any inquiries or require " +"further assistance, our support team is here to\n" +" help. You can reach us anytime.\n" +" " +msgstr "" +"\n" +" إذا كان لديك أي استفسارات أو كنت بحاجة إلى " +"مزيد من المساعدة، فإن فريق الدعم لدينا هنا\n" +" لمساعدتك. يمكنك التواصل معنا في أي وقت.\n" +" " + #: venv/lib/python3.11/site-packages/appointment/templates/error_pages/304_already_submitted.html:11 #: venv/lib/python3.11/site-packages/appointment/templates/error_pages/403_forbidden_rescheduling.html:100 msgid "Not authorized!" @@ -9208,27 +9648,77 @@ msgstr "المستخدم هو مشرف عام." msgid "French" msgstr "الفرنسية" -#: venv/lib/python3.11/site-packages/click/_termui_impl.py:556 +#: venv/lib/python3.11/site-packages/ckeditor_uploader/forms.py:6 +msgid "Search files" +msgstr "البحث في الملفات" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:5 +msgid "Select an image to embed" +msgstr "اختر صورة لإدراجها" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:27 +msgid "Browse for the image you want, then click 'Embed Image' to continue..." +msgstr "" +"تصفح للعثور على الصورة المطلوبة، ثم انقر على 'إدراج الصورة' للمتابعة..." + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:29 +msgid "" +"No images found. Upload images using the 'Image Button' dialog's 'Upload' " +"tab." +msgstr "" +"لم يتم العثور على صور. قم بتحميل الصور باستخدام تبويب 'تحميل' في مربع حوار " +"'زر الصورة'." + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:50 +msgid "Images in: " +msgstr "الصور في: " + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:62 +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:80 +msgid "Embed Image" +msgstr "إدراج الصورة" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:146 +msgid "Play Slideshow" +msgstr "تشغيل عرض الشرائح" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:147 +msgid "Pause Slideshow" +msgstr "إيقاف عرض الشرائح مؤقتاً" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:148 +msgid "‹ Previous Photo" +msgstr "‹ الصورة السابقة" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:149 +msgid "Next Photo ›" +msgstr "الصورة التالية ›" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:150 +msgid "Next ›" +msgstr "التالي ›" + +#: venv/lib/python3.11/site-packages/ckeditor_uploader/templates/ckeditor/browse.html:151 +msgid "‹ Prev" +msgstr "‹ السابق" + +#: venv/lib/python3.11/site-packages/click/_termui_impl.py:600 #, python-brace-format msgid "{editor}: Editing failed" msgstr "{editor}: فشل التحرير" -#: venv/lib/python3.11/site-packages/click/_termui_impl.py:560 +#: venv/lib/python3.11/site-packages/click/_termui_impl.py:604 #, python-brace-format msgid "{editor}: Editing failed: {e}" msgstr "{editor}: فشل التحرير: {e}" -#: venv/lib/python3.11/site-packages/click/core.py:1124 -msgid "Aborted!" -msgstr "تم الإلغاء!" - -#: venv/lib/python3.11/site-packages/click/core.py:1349 -#: venv/lib/python3.11/site-packages/click/core.py:1379 +#: venv/lib/python3.11/site-packages/click/core.py:1084 +#: venv/lib/python3.11/site-packages/click/core.py:1121 #, python-brace-format -msgid "(Deprecated) {text}" -msgstr "(مهمل) {text}" +msgid "{text} {deprecated_message}" +msgstr "" -#: venv/lib/python3.11/site-packages/click/core.py:1422 +#: venv/lib/python3.11/site-packages/click/core.py:1202 #, python-brace-format msgid "Got unexpected extra argument ({args})" msgid_plural "Got unexpected extra arguments ({args})" @@ -9239,27 +9729,33 @@ msgstr[3] "تم الحصول على أربعة وسائط إضافية غير م msgstr[4] "تم الحصول على خمسة وسائط إضافية غير متوقعة ({args})" msgstr[5] "تم الحصول على عدد كبير من الوسائط الإضافية غير المتوقعة ({args})" -#: venv/lib/python3.11/site-packages/click/core.py:1438 -msgid "DeprecationWarning: The command {name!r} is deprecated." +#: venv/lib/python3.11/site-packages/click/core.py:1221 +#, fuzzy +#| msgid "DeprecationWarning: The command {name!r} is deprecated." +msgid "DeprecationWarning: The command {name!r} is deprecated.{extra_message}" msgstr "تحذير إهمال: الأمر {name!r} مهمل." -#: venv/lib/python3.11/site-packages/click/core.py:1645 +#: venv/lib/python3.11/site-packages/click/core.py:1405 +msgid "Aborted!" +msgstr "تم الإلغاء!" + +#: venv/lib/python3.11/site-packages/click/core.py:1779 msgid "Commands" msgstr "الأوامر" -#: venv/lib/python3.11/site-packages/click/core.py:1677 +#: venv/lib/python3.11/site-packages/click/core.py:1810 msgid "Missing command." msgstr "الأمر مفقود." -#: venv/lib/python3.11/site-packages/click/core.py:1755 +#: venv/lib/python3.11/site-packages/click/core.py:1888 msgid "No such command {name!r}." msgstr "لا يوجد أمر باسم {name!r}." -#: venv/lib/python3.11/site-packages/click/core.py:2313 +#: venv/lib/python3.11/site-packages/click/core.py:2303 msgid "Value must be an iterable." msgstr "يجب أن تكون القيمة قابلة للتكرار." -#: venv/lib/python3.11/site-packages/click/core.py:2334 +#: venv/lib/python3.11/site-packages/click/core.py:2324 #, python-brace-format msgid "Takes {nargs} values but 1 was given." msgid_plural "Takes {nargs} values but {len} were given." @@ -9270,86 +9766,89 @@ msgstr[3] "" msgstr[4] "" msgstr[5] "" -#: venv/lib/python3.11/site-packages/click/core.py:2783 +#: venv/lib/python3.11/site-packages/click/core.py:2404 +#, fuzzy +#| msgid "DeprecationWarning: The command {name!r} is deprecated." +msgid "" +"DeprecationWarning: The {param_type} {name!r} is deprecated.{extra_message}" +msgstr "تحذير إهمال: الأمر {name!r} مهمل." + +#: venv/lib/python3.11/site-packages/click/core.py:2807 #, python-brace-format msgid "env var: {var}" msgstr "متغير البيئة: {var}" -#: venv/lib/python3.11/site-packages/click/core.py:2813 -msgid "(dynamic)" -msgstr "(ديناميكي)" - -#: venv/lib/python3.11/site-packages/click/core.py:2828 +#: venv/lib/python3.11/site-packages/click/core.py:2810 #, python-brace-format msgid "default: {default}" msgstr "القيمة الافتراضية: {default}" -#: venv/lib/python3.11/site-packages/click/core.py:2841 -msgid "required" -msgstr "مطلوب" +#: venv/lib/python3.11/site-packages/click/core.py:2870 +msgid "(dynamic)" +msgstr "(ديناميكي)" -#: venv/lib/python3.11/site-packages/click/decorators.py:457 +#: venv/lib/python3.11/site-packages/click/decorators.py:465 #, python-format msgid "%(prog)s, version %(version)s" msgstr "%(prog)s، الإصدار %(version)s" -#: venv/lib/python3.11/site-packages/click/decorators.py:520 +#: venv/lib/python3.11/site-packages/click/decorators.py:522 msgid "Show the version and exit." msgstr "عرض الإصدار والخروج." -#: venv/lib/python3.11/site-packages/click/decorators.py:541 +#: venv/lib/python3.11/site-packages/click/decorators.py:548 msgid "Show this message and exit." msgstr "إظهار رسالة المساعدة هذه والخروج" -#: venv/lib/python3.11/site-packages/click/exceptions.py:49 -#: venv/lib/python3.11/site-packages/click/exceptions.py:88 +#: venv/lib/python3.11/site-packages/click/exceptions.py:50 +#: venv/lib/python3.11/site-packages/click/exceptions.py:89 #, python-brace-format msgid "Error: {message}" msgstr "خطأ: {message}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:80 +#: venv/lib/python3.11/site-packages/click/exceptions.py:81 #, python-brace-format msgid "Try '{command} {option}' for help." msgstr "حاول '{command} {option}' للحصول على المساعدة." -#: venv/lib/python3.11/site-packages/click/exceptions.py:129 +#: venv/lib/python3.11/site-packages/click/exceptions.py:130 #, python-brace-format msgid "Invalid value: {message}" msgstr "قيمة غير صالحة: {message}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:131 +#: venv/lib/python3.11/site-packages/click/exceptions.py:132 #, python-brace-format msgid "Invalid value for {param_hint}: {message}" msgstr "قيمة غير صالحة لـ {param_hint}: {message}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:187 +#: venv/lib/python3.11/site-packages/click/exceptions.py:190 msgid "Missing argument" msgstr "الوسيطة مفقودة" -#: venv/lib/python3.11/site-packages/click/exceptions.py:189 +#: venv/lib/python3.11/site-packages/click/exceptions.py:192 msgid "Missing option" msgstr "الخيار مفقود" -#: venv/lib/python3.11/site-packages/click/exceptions.py:191 +#: venv/lib/python3.11/site-packages/click/exceptions.py:194 msgid "Missing parameter" msgstr "المعلمة مفقودة" -#: venv/lib/python3.11/site-packages/click/exceptions.py:193 +#: venv/lib/python3.11/site-packages/click/exceptions.py:196 #, python-brace-format msgid "Missing {param_type}" msgstr "مفقود {param_type}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:200 +#: venv/lib/python3.11/site-packages/click/exceptions.py:203 #, python-brace-format msgid "Missing parameter: {param_name}" msgstr "المعلمة مفقودة: {param_name}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:220 +#: venv/lib/python3.11/site-packages/click/exceptions.py:223 #, python-brace-format msgid "No such option: {name}" msgstr "لا يوجد خيار باسم: {name}" -#: venv/lib/python3.11/site-packages/click/exceptions.py:232 +#: venv/lib/python3.11/site-packages/click/exceptions.py:235 #, python-brace-format msgid "Did you mean {possibility}?" msgid_plural "(Possible options: {possibilities})" @@ -9360,11 +9859,11 @@ msgstr[3] "" msgstr[4] "" msgstr[5] "" -#: venv/lib/python3.11/site-packages/click/exceptions.py:270 +#: venv/lib/python3.11/site-packages/click/exceptions.py:282 msgid "unknown error" msgstr "خطأ غير معروف" -#: venv/lib/python3.11/site-packages/click/exceptions.py:277 +#: venv/lib/python3.11/site-packages/click/exceptions.py:289 msgid "Could not open file {filename!r}: {message}" msgstr "تعذر فتح الملف {filename!r}: {message}" @@ -9372,15 +9871,15 @@ msgstr "تعذر فتح الملف {filename!r}: {message}" msgid "Usage:" msgstr "الاستخدام:" -#: venv/lib/python3.11/site-packages/click/parser.py:233 +#: venv/lib/python3.11/site-packages/click/parser.py:200 msgid "Argument {name!r} takes {nargs} values." msgstr "الوسيطة {name!r} تتطلب {nargs} قيمة." -#: venv/lib/python3.11/site-packages/click/parser.py:415 +#: venv/lib/python3.11/site-packages/click/parser.py:383 msgid "Option {name!r} does not take a value." msgstr "الخيار {name!r} لا يأخذ قيمة." -#: venv/lib/python3.11/site-packages/click/parser.py:476 +#: venv/lib/python3.11/site-packages/click/parser.py:444 msgid "Option {name!r} requires an argument." msgid_plural "Option {name!r} requires {nargs} arguments." msgstr[0] "الخيار {name!r} يتطلب وسيطة." @@ -9398,32 +9897,32 @@ msgstr "إكمال الأوامر في القشرة غير مدعوم للإصد msgid "Couldn't detect Bash version, shell completion is not supported." msgstr "تعذر اكتشاف إصدار Bash، إكمال الأوامر غير مدعوم." -#: venv/lib/python3.11/site-packages/click/termui.py:158 +#: venv/lib/python3.11/site-packages/click/termui.py:162 msgid "Repeat for confirmation" msgstr "أعد المحاولة للتأكيد" -#: venv/lib/python3.11/site-packages/click/termui.py:174 +#: venv/lib/python3.11/site-packages/click/termui.py:178 msgid "Error: The value you entered was invalid." msgstr "خطأ: القيمة التي أدخلتها غير صالحة." -#: venv/lib/python3.11/site-packages/click/termui.py:176 +#: venv/lib/python3.11/site-packages/click/termui.py:180 #, python-brace-format msgid "Error: {e.message}" msgstr "خطأ: {e.message}" -#: venv/lib/python3.11/site-packages/click/termui.py:187 +#: venv/lib/python3.11/site-packages/click/termui.py:191 msgid "Error: The two entered values do not match." msgstr "خطأ: القيمتان المدخلتان لا تتطابقان." -#: venv/lib/python3.11/site-packages/click/termui.py:243 +#: venv/lib/python3.11/site-packages/click/termui.py:247 msgid "Error: invalid input" msgstr "خطأ: إدخال غير صالح" -#: venv/lib/python3.11/site-packages/click/termui.py:773 +#: venv/lib/python3.11/site-packages/click/termui.py:866 msgid "Press any key to continue..." msgstr "اضغط أي مفتاح للمتابعة..." -#: venv/lib/python3.11/site-packages/click/types.py:267 +#: venv/lib/python3.11/site-packages/click/types.py:332 #, python-brace-format msgid "" "Choose from:\n" @@ -9432,7 +9931,7 @@ msgstr "" "اختر من:\n" "\t{choices}" -#: venv/lib/python3.11/site-packages/click/types.py:299 +#: venv/lib/python3.11/site-packages/click/types.py:369 msgid "{value!r} is not {choice}." msgid_plural "{value!r} is not one of {choices}." msgstr[0] "القيمة %(value)r ليست خياراً صالحاً." @@ -9442,7 +9941,7 @@ msgstr[3] "القيمة %(value)r ليست خياراً صالحاً." msgstr[4] "القيمة %(value)r ليست خياراً صالحاً." msgstr[5] "القيمة %(value)r ليست خياراً صالحاً." -#: venv/lib/python3.11/site-packages/click/types.py:393 +#: venv/lib/python3.11/site-packages/click/types.py:460 msgid "{value!r} does not match the format {format}." msgid_plural "{value!r} does not match the formats {formats}." msgstr[0] "" @@ -9452,60 +9951,60 @@ msgstr[3] "" msgstr[4] "" msgstr[5] "" -#: venv/lib/python3.11/site-packages/click/types.py:415 +#: venv/lib/python3.11/site-packages/click/types.py:482 msgid "{value!r} is not a valid {number_type}." msgstr "القيمة %(value)r ليست خياراً صالحاً." -#: venv/lib/python3.11/site-packages/click/types.py:471 +#: venv/lib/python3.11/site-packages/click/types.py:538 #, python-brace-format msgid "{value} is not in the range {range}." msgstr "" -#: venv/lib/python3.11/site-packages/click/types.py:612 +#: venv/lib/python3.11/site-packages/click/types.py:679 msgid "{value!r} is not a valid boolean." msgstr "القيمة %(value)r ليست خياراً صالحاً." -#: venv/lib/python3.11/site-packages/click/types.py:636 +#: venv/lib/python3.11/site-packages/click/types.py:703 msgid "{value!r} is not a valid UUID." msgstr "القيمة “%(value)s” ليست UUID صالح." -#: venv/lib/python3.11/site-packages/click/types.py:826 +#: venv/lib/python3.11/site-packages/click/types.py:893 msgid "file" msgstr "ملف" -#: venv/lib/python3.11/site-packages/click/types.py:828 +#: venv/lib/python3.11/site-packages/click/types.py:895 msgid "directory" msgstr "مجلد" -#: venv/lib/python3.11/site-packages/click/types.py:830 +#: venv/lib/python3.11/site-packages/click/types.py:897 msgid "path" msgstr "مسار" -#: venv/lib/python3.11/site-packages/click/types.py:881 +#: venv/lib/python3.11/site-packages/click/types.py:944 msgid "{name} {filename!r} does not exist." msgstr "{name} {filename!r} غير موجود." -#: venv/lib/python3.11/site-packages/click/types.py:890 +#: venv/lib/python3.11/site-packages/click/types.py:953 msgid "{name} {filename!r} is a file." msgstr "{name} {filename!r} هو ملف." -#: venv/lib/python3.11/site-packages/click/types.py:898 +#: venv/lib/python3.11/site-packages/click/types.py:961 msgid "{name} {filename!r} is a directory." msgstr "{name} '{filename}' هو دليل." -#: venv/lib/python3.11/site-packages/click/types.py:907 +#: venv/lib/python3.11/site-packages/click/types.py:970 msgid "{name} {filename!r} is not readable." msgstr "{name} {filename!r} غير قابل للقراءة." -#: venv/lib/python3.11/site-packages/click/types.py:916 +#: venv/lib/python3.11/site-packages/click/types.py:979 msgid "{name} {filename!r} is not writable." msgstr "{name} {filename!r} غير قابل للكتابة." -#: venv/lib/python3.11/site-packages/click/types.py:925 +#: venv/lib/python3.11/site-packages/click/types.py:988 msgid "{name} {filename!r} is not executable." msgstr "{name} {filename!r} غير قابل للتنفيذ." -#: venv/lib/python3.11/site-packages/click/types.py:992 +#: venv/lib/python3.11/site-packages/click/types.py:1055 #, python-brace-format msgid "{len_type} values are required, but {len_value} was given." msgid_plural "{len_type} values are required, but {len_value} were given." @@ -9566,86 +10065,86 @@ msgstr "أدخل قيمة صالحة." msgid "Enter a valid domain name." msgstr "أدخل اسم نطاق صالح." -#: venv/lib/python3.11/site-packages/django/core/validators.py:155 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:768 +#: venv/lib/python3.11/site-packages/django/core/validators.py:153 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:775 msgid "Enter a valid URL." msgstr "أدخل رابط URL صالحاً." -#: venv/lib/python3.11/site-packages/django/core/validators.py:216 +#: venv/lib/python3.11/site-packages/django/core/validators.py:200 msgid "Enter a valid integer." msgstr "أدخل عدداً صحيحاً صالحاً." -#: venv/lib/python3.11/site-packages/django/core/validators.py:227 +#: venv/lib/python3.11/site-packages/django/core/validators.py:211 msgid "Enter a valid email address." msgstr "أدخل عنوان بريد إلكتروني صالح." #. Translators: "letters" means latin letters: a-z and A-Z. -#: venv/lib/python3.11/site-packages/django/core/validators.py:310 +#: venv/lib/python3.11/site-packages/django/core/validators.py:289 msgid "" "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens." msgstr "أدخل “Slug” صالح يتكون من أحرف وأرقام وتسطيرات سفلية أو واصلات." -#: venv/lib/python3.11/site-packages/django/core/validators.py:318 +#: venv/lib/python3.11/site-packages/django/core/validators.py:297 msgid "" "Enter a valid “slug” consisting of Unicode letters, numbers, underscores, or " "hyphens." msgstr "أدخل “Slug” صالح يتكون من أحرف يونكود وأرقام وتسطيرات سفلية أو واصلات." -#: venv/lib/python3.11/site-packages/django/core/validators.py:330 -#: venv/lib/python3.11/site-packages/django/core/validators.py:339 -#: venv/lib/python3.11/site-packages/django/core/validators.py:353 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2215 +#: venv/lib/python3.11/site-packages/django/core/validators.py:309 +#: venv/lib/python3.11/site-packages/django/core/validators.py:318 +#: venv/lib/python3.11/site-packages/django/core/validators.py:332 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2220 #, python-format msgid "Enter a valid %(protocol)s address." msgstr "أدخل عنوان %(protocol)s صالحًا." -#: venv/lib/python3.11/site-packages/django/core/validators.py:332 +#: venv/lib/python3.11/site-packages/django/core/validators.py:311 msgid "IPv4" msgstr "IPv4" -#: venv/lib/python3.11/site-packages/django/core/validators.py:341 +#: venv/lib/python3.11/site-packages/django/core/validators.py:320 #: venv/lib/python3.11/site-packages/django/utils/ipv6.py:43 msgid "IPv6" msgstr "IPv6" -#: venv/lib/python3.11/site-packages/django/core/validators.py:355 +#: venv/lib/python3.11/site-packages/django/core/validators.py:334 msgid "IPv4 or IPv6" msgstr "IPv4 or IPv6" -#: venv/lib/python3.11/site-packages/django/core/validators.py:396 +#: venv/lib/python3.11/site-packages/django/core/validators.py:375 msgid "Enter only digits separated by commas." msgstr "أدخل أرقاماً فقط مفصولة بفواصل." -#: venv/lib/python3.11/site-packages/django/core/validators.py:402 +#: venv/lib/python3.11/site-packages/django/core/validators.py:381 #, python-format msgid "Ensure this value is %(limit_value)s (it is %(show_value)s)." msgstr "تأكد من أن هذه القيمة هي %(limit_value)s (هي %(show_value)s)." -#: venv/lib/python3.11/site-packages/django/core/validators.py:437 +#: venv/lib/python3.11/site-packages/django/core/validators.py:416 #: venv/lib/python3.11/site-packages/djmoney/models/validators.py:51 #, python-format msgid "Ensure this value is less than or equal to %(limit_value)s." msgstr "تأكد من أن هذه القيمة أقل من أو تساوي %(limit_value)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:446 +#: venv/lib/python3.11/site-packages/django/core/validators.py:425 #: venv/lib/python3.11/site-packages/djmoney/models/validators.py:43 #, python-format msgid "Ensure this value is greater than or equal to %(limit_value)s." msgstr "تأكد من أن هذه القيمة أكبر من أو تساوي %(limit_value)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:455 +#: venv/lib/python3.11/site-packages/django/core/validators.py:434 #, python-format msgid "Ensure this value is a multiple of step size %(limit_value)s." msgstr "تأكد من أن هذه القيمة هي مضاعف لخطوة الحجم %(limit_value)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:462 +#: venv/lib/python3.11/site-packages/django/core/validators.py:441 #, python-format msgid "" "Ensure this value is a multiple of step size %(limit_value)s, starting from " "%(offset)s, e.g. %(offset)s, %(valid_value1)s, %(valid_value2)s, and so on." msgstr "" -#: venv/lib/python3.11/site-packages/django/core/validators.py:494 +#: venv/lib/python3.11/site-packages/django/core/validators.py:473 #, python-format msgid "" "Ensure this value has at least %(limit_value)d character (it has " @@ -9660,7 +10159,7 @@ msgstr[1] "" "تأكد من أن هذه القيمة تحتوي على الأقل على %(limit_value)d أحرف (تحتوي على " "%(show_value)d)." -#: venv/lib/python3.11/site-packages/django/core/validators.py:512 +#: venv/lib/python3.11/site-packages/django/core/validators.py:491 #, python-format msgid "" "Ensure this value has at most %(limit_value)d character (it has " @@ -9675,27 +10174,27 @@ msgstr[1] "" "تأكد من أن هذه القيمة تحتوي على الأكثر على %(limit_value)d أحرف (تحتوي على " "%(show_value)d)." -#: venv/lib/python3.11/site-packages/django/core/validators.py:535 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:359 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:398 +#: venv/lib/python3.11/site-packages/django/core/validators.py:514 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:366 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:405 msgid "Enter a number." msgstr "أدخل رقماً." -#: venv/lib/python3.11/site-packages/django/core/validators.py:537 +#: venv/lib/python3.11/site-packages/django/core/validators.py:516 #, python-format msgid "Ensure that there are no more than %(max)s digit in total." msgid_plural "Ensure that there are no more than %(max)s digits in total." msgstr[0] "تأكد من أن العدد الإجمالي للأرقام لا يتجاوز %(max)s رقم." msgstr[1] "تأكد من أن العدد الإجمالي للأرقام لا يتجاوز %(max)s أرقام." -#: venv/lib/python3.11/site-packages/django/core/validators.py:542 +#: venv/lib/python3.11/site-packages/django/core/validators.py:521 #, python-format msgid "Ensure that there are no more than %(max)s decimal place." msgid_plural "Ensure that there are no more than %(max)s decimal places." msgstr[0] "تأكد من أن العدد الإجمالي للأماكن العشرية لا يتجاوز %(max)s." msgstr[1] "تأكد من أن العدد الإجمالي للأماكن العشرية لا يتجاوز %(max)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:547 +#: venv/lib/python3.11/site-packages/django/core/validators.py:526 #, python-format msgid "" "Ensure that there are no more than %(max)s digit before the decimal point." @@ -9706,7 +10205,7 @@ msgstr[0] "" msgstr[1] "" "تأكد من أن العدد الإجمالي للأرقام قبل العلامة العشرية لا يتجاوز %(max)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:618 +#: venv/lib/python3.11/site-packages/django/core/validators.py:597 #, python-format msgid "" "File extension “%(extension)s” is not allowed. Allowed extensions are: " @@ -9715,16 +10214,16 @@ msgstr "" "امتداد الملف “%(extension)s” غير مسموح به. الامتدادات المسموح بها هي: " "%(allowed_extensions)s." -#: venv/lib/python3.11/site-packages/django/core/validators.py:680 +#: venv/lib/python3.11/site-packages/django/core/validators.py:659 msgid "Null characters are not allowed." msgstr "الأحرف الفارغة غير مسموح بها." -#: venv/lib/python3.11/site-packages/django/db/models/base.py:1572 +#: venv/lib/python3.11/site-packages/django/db/models/base.py:1600 #: venv/lib/python3.11/site-packages/django/forms/models.py:908 msgid "and" msgstr "و" -#: venv/lib/python3.11/site-packages/django/db/models/base.py:1574 +#: venv/lib/python3.11/site-packages/django/db/models/base.py:1602 #, python-format msgid "%(model_name)s with this %(field_labels)s already exists." msgstr "%(model_name)s مع %(field_labels)s هذا موجود بالفعل." @@ -9766,34 +10265,34 @@ msgstr "" msgid "Field of type: %(field_type)s" msgstr "حقل من النوع: %(field_type)s" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1156 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1162 #, python-format msgid "“%(value)s” value must be either True or False." msgstr "القيمة “%(value)s” يجب أن تكون إما True أو False." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1157 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1163 #, python-format msgid "“%(value)s” value must be either True, False, or None." msgstr "القيمة “%(value)s” يجب أن تكون إما True، False، أو None." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1159 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1165 msgid "Boolean (Either True or False)" msgstr "قيمة منطقية (إما True أو False)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1209 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1215 #, python-format msgid "String (up to %(max_length)s)" msgstr "نص (حتى %(max_length)s)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1211 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1217 msgid "String (unlimited)" msgstr "نص (غير محدود)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1320 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1326 msgid "Comma-separated integers" msgstr "أرقام مفصولة بفواصل" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1421 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1427 #, python-format msgid "" "“%(value)s” value has an invalid date format. It must be in YYYY-MM-DD " @@ -9802,8 +10301,8 @@ msgstr "" "القيمة “%(value)s” تحتوي على تنسيق تاريخ غير صالح. يجب أن تكون بالتنسيق YYYY-" "MM-DD." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1425 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1560 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1431 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1566 #, python-format msgid "" "“%(value)s” value has the correct format (YYYY-MM-DD) but it is an invalid " @@ -9812,11 +10311,11 @@ msgstr "" "القيمة “%(value)s” تحتوي على التنسيق الصحيح (YYYY-MM-DD) لكنها تاريخ غير " "صالح." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1429 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1435 msgid "Date (without time)" msgstr "تاريخ (بدون وقت)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1556 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1562 #, python-format msgid "" "“%(value)s” value has an invalid format. It must be in YYYY-MM-DD " @@ -9825,7 +10324,7 @@ msgstr "" "القيمة “%(value)s” تحتوي على تنسيق غير صالح. يجب أن تكون بالتنسيق YYYY-MM-DD " "HH:MM[:ss[.uuuuuu]][TZ]." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1564 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1570 #, python-format msgid "" "“%(value)s” value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]" @@ -9834,20 +10333,20 @@ msgstr "" "القيمة “%(value)s” تحتوي على التنسيق الصحيح (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]" "[TZ]) لكنها تاريخ/وقت غير صالح." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1569 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1575 msgid "Date (with time)" msgstr "تاريخ (مع الوقت)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1696 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1702 #, python-format msgid "“%(value)s” value must be a decimal number." msgstr "القيمة “%(value)s” يجب أن تكون رقماً عشرياً." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1698 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1704 msgid "Decimal number" msgstr "رقم عشري" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1859 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1864 #, python-format msgid "" "“%(value)s” value has an invalid format. It must be in [DD] " @@ -9856,76 +10355,76 @@ msgstr "" "القيمة “%(value)s” تحتوي على تنسيق غير صالح. يجب أن تكون بالتنسيق [DD] " "[[HH:]MM:]ss[.uuuuuu]." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1940 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:1945 msgid "File path" msgstr "مسار الملف" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2018 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2023 #, python-format msgid "“%(value)s” value must be a float." msgstr "القيمة “%(value)s” يجب أن تكون عدداً عشرياً." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2020 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2025 msgid "Floating point number" msgstr "عدد عشري" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2060 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2065 #, python-format msgid "“%(value)s” value must be an integer." msgstr "القيمة “%(value)s” يجب أن تكون عدداً صحيحاً." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2062 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2067 msgid "Integer" msgstr "عدد صحيح" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2158 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2163 msgid "Big (8 byte) integer" msgstr "عدد صحيح كبير (8 بايت)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2175 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2180 msgid "Small integer" msgstr "عدد صحيح صغير" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2183 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2188 msgid "IPv4 address" msgstr "عنوان IPv4" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2214 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2219 msgid "IP address" msgstr "عنوان IP" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2305 -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2306 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2310 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2311 #, python-format msgid "“%(value)s” value must be either None, True or False." msgstr "القيمة “%(value)s” يجب أن تكون إما None، True أو False." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2308 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2313 msgid "Boolean (Either True, False or None)" msgstr "قيمة منطقية (إما True أو False أو None)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2359 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2364 msgid "Positive big integer" msgstr "عدد صحيح موجب كبير" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2374 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2379 msgid "Positive integer" msgstr "عدد صحيح موجب" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2389 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2394 msgid "Positive small integer" msgstr "عدد صحيح موجب صغير" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2405 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2410 #, python-format msgid "Slug (up to %(max_length)s)" msgstr "Slug (حتى %(max_length)s)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2441 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2446 msgid "Text" msgstr "النص" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2521 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2526 #, python-format msgid "" "“%(value)s” value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] " @@ -9934,7 +10433,7 @@ msgstr "" "القيمة “%(value)s” تحتوي على تنسيق غير صالح. يجب أن تكون بالتنسيق " "HH:MM[:ss[.uuuuuu]]." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2525 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2530 #, python-format msgid "" "“%(value)s” value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an " @@ -9943,20 +10442,20 @@ msgstr "" "القيمة “%(value)s” تحتوي على التنسيق الصحيح (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]" "[TZ]) لكنها تاريخ/وقت غير صالح." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2637 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2642 msgid "URL" msgstr "رابط URL" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2661 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2666 msgid "Raw binary data" msgstr "بيانات ثنائية خام" -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2726 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2731 #, python-format msgid "“%(value)s” is not a valid UUID." msgstr "القيمة “%(value)s” ليست UUID صالح." -#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2728 +#: venv/lib/python3.11/site-packages/django/db/models/fields/__init__.py:2733 msgid "Universally unique identifier" msgstr "معرّف فريد عالمي" @@ -9972,30 +10471,31 @@ msgstr "كائن JSON" msgid "Value must be valid JSON." msgstr "يجب أن تكون القيمة JSON صالح." -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:932 -#, python-format -msgid "%(model)s instance with %(field)s %(value)r does not exist." +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:978 +#, fuzzy, python-format +#| msgid "%(model)s instance with %(field)s %(value)r does not exist." +msgid "%(model)s instance with %(field)s %(value)r is not a valid choice." msgstr "المثال %(model)s مع %(field)s %(value)r غير موجود." -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:934 +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:981 msgid "Foreign Key (type determined by related field)" msgstr "مفتاح أجنبي (يحدد النوع حسب الحقل المرتبط)" -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1228 +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1275 msgid "One-to-one relationship" msgstr "علاقة واحد لواحد" -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1285 +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1332 #, python-format msgid "%(from)s-%(to)s relationship" msgstr "علاقة %(from)s-%(to)s" -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1287 +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1334 #, python-format msgid "%(from)s-%(to)s relationships" msgstr "علاقات %(from)s-%(to)s" -#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1335 +#: venv/lib/python3.11/site-packages/django/db/models/fields/related.py:1382 msgid "Many-to-many relationship" msgstr "علاقة متعدد لمتعدد" @@ -10005,46 +10505,46 @@ msgstr "علاقة متعدد لمتعدد" msgid ":?.!" msgstr ":؟.!" -#: venv/lib/python3.11/site-packages/django/forms/fields.py:308 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:315 msgid "Enter a whole number." msgstr "أدخل عدداً صحيحاً." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:479 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1260 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:486 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1267 msgid "Enter a valid date." msgstr "أدخل تاريخاً صالحاً." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:502 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1261 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:509 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1268 msgid "Enter a valid time." msgstr "أدخل وقتاً صالحاً." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:529 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:536 msgid "Enter a valid date/time." msgstr "أدخل تاريخاً/وقتاً صالحاً." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:563 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:570 msgid "Enter a valid duration." msgstr "أدخل مدة صالحة." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:564 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:571 #, python-brace-format msgid "The number of days must be between {min_days} and {max_days}." msgstr "يجب أن يكون عدد الأيام بين {min_days} و {max_days}." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:633 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:640 msgid "No file was submitted. Check the encoding type on the form." msgstr "لم يتم تقديم ملف. تحقق من نوع الترميز في النموذج." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:634 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:641 msgid "No file was submitted." msgstr "لم يتم تقديم أي ملف." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:635 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:642 msgid "The submitted file is empty." msgstr "الملف المقدم فارغ." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:637 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:644 #, python-format msgid "Ensure this filename has at most %(max)d character (it has %(length)d)." msgid_plural "" @@ -10054,48 +10554,48 @@ msgstr[0] "" msgstr[1] "" "تأكد من أن اسم الملف يحتوي على %(max)d أحرف كحد أقصى (يحتوي على %(length)d)." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:642 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:649 msgid "Please either submit a file or check the clear checkbox, not both." msgstr "يرجى إما تقديم ملف أو تحديد خانة الإزالة، وليس كليهما." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:710 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:717 msgid "" "Upload a valid image. The file you uploaded was either not an image or a " "corrupted image." msgstr "" "قم بتحميل صورة صالحة. الملف الذي قمت بتحميله إما ليس صورة أو صورة تالفة." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:882 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:968 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:889 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:975 #: venv/lib/python3.11/site-packages/django/forms/models.py:1592 #, python-format msgid "Select a valid choice. %(value)s is not one of the available choices." msgstr "اختر خياراً صالحاً. %(value)s ليس أحد الخيارات المتاحة." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:970 -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1089 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:977 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1096 #: venv/lib/python3.11/site-packages/django/forms/models.py:1590 msgid "Enter a list of values." msgstr "أدخل قائمة بالقيم." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1090 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1097 msgid "Enter a complete value." msgstr "أدخل قيمة كاملة." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1332 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1339 msgid "Enter a valid UUID." msgstr "أدخل UUID صالحاً." -#: venv/lib/python3.11/site-packages/django/forms/fields.py:1362 +#: venv/lib/python3.11/site-packages/django/forms/fields.py:1369 msgid "Enter a valid JSON." msgstr "أدخل JSON صالحاً." #. Translators: This is the default suffix added to form field labels -#: venv/lib/python3.11/site-packages/django/forms/forms.py:94 +#: venv/lib/python3.11/site-packages/django/forms/forms.py:97 msgid ":" msgstr ":" -#: venv/lib/python3.11/site-packages/django/forms/forms.py:230 +#: venv/lib/python3.11/site-packages/django/forms/forms.py:239 #, python-format msgid "(Hidden field %(name)s) %(error)s" msgstr "(الحقل المخفي %(name)s) %(error)s" @@ -10159,7 +10659,7 @@ msgstr "اختر خياراً صالحاً. هذا الخيار ليس من ال msgid "“%(pk)s” is not a valid value." msgstr "“%(pk)s” ليست قيمة صالحة." -#: venv/lib/python3.11/site-packages/django/forms/utils.py:227 +#: venv/lib/python3.11/site-packages/django/forms/utils.py:229 #, python-format msgid "" "%(datetime)s couldn’t be interpreted in time zone %(current_timezone)s; it " @@ -10168,15 +10668,15 @@ msgstr "" "لم يتم تفسير %(datetime)s في المنطقة الزمنية %(current_timezone)s؛ قد يكون " "غامضاً أو قد لا يكون موجوداً." -#: venv/lib/python3.11/site-packages/django/forms/widgets.py:461 +#: venv/lib/python3.11/site-packages/django/forms/widgets.py:527 msgid "Clear" msgstr "مسح" -#: venv/lib/python3.11/site-packages/django/forms/widgets.py:462 +#: venv/lib/python3.11/site-packages/django/forms/widgets.py:528 msgid "Currently" msgstr "حالياً" -#: venv/lib/python3.11/site-packages/django/forms/widgets.py:800 +#: venv/lib/python3.11/site-packages/django/forms/widgets.py:866 msgid "Unknown" msgstr "غير معروف" @@ -10502,18 +11002,18 @@ msgstr "ديسمبر" msgid "This is not a valid IPv6 address." msgstr "هذا ليس عنوان IPv6 صالحاً." -#: venv/lib/python3.11/site-packages/django/utils/text.py:67 +#: venv/lib/python3.11/site-packages/django/utils/text.py:76 #, python-format msgctxt "String to return when truncating text" msgid "%(truncated_text)s…" msgstr "%(truncated_text)s…" -#: venv/lib/python3.11/site-packages/django/utils/text.py:278 +#: venv/lib/python3.11/site-packages/django/utils/text.py:287 msgid "or" msgstr "أو" #. Translators: This string is used as a separator between list elements -#: venv/lib/python3.11/site-packages/django/utils/text.py:297 +#: venv/lib/python3.11/site-packages/django/utils/text.py:306 #: venv/lib/python3.11/site-packages/django/utils/timesince.py:135 msgid ", " msgstr "، " @@ -10646,13 +11146,13 @@ msgstr "لم يتم تحديد اليوم" msgid "No week specified" msgstr "لم يتم تحديد الأسبوع" -#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:349 -#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:380 +#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:353 +#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:384 #, python-format msgid "No %(verbose_name_plural)s available" msgstr "لا توجد %(verbose_name_plural)s متاحة" -#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:652 +#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:680 #, python-format msgid "" "Future %(verbose_name_plural)s not available because " @@ -10661,7 +11161,7 @@ msgstr "" "%(verbose_name_plural)s المستقبلية غير متاحة لأن %(class_name)s. الخاصية " "allow_future هي False." -#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:692 +#: venv/lib/python3.11/site-packages/django/views/generic/dates.py:720 #, python-format msgid "Invalid date string “%(datestr)s” given format “%(format)s”" msgstr "سلسلة التاريخ غير صالحة “%(datestr)s” بالصيغة “%(format)s”" @@ -10680,7 +11180,7 @@ msgstr "الصفحة ليست “الأخيرة”، ولا يمكن تحويل msgid "Invalid page (%(page_number)s): %(message)s" msgstr "صفحة غير صالحة (%(page_number)s): %(message)s" -#: venv/lib/python3.11/site-packages/django/views/generic/list.py:169 +#: venv/lib/python3.11/site-packages/django/views/generic/list.py:173 #, python-format msgid "Empty list and “%(class_name)s.allow_empty” is False." msgstr "قائمة فارغة والخاصية “%(class_name)s.allow_empty” هي False." @@ -10858,11 +11358,11 @@ msgstr "لا يمكن إنشاء إدخال إغلاق بتاريخ مستقبل msgid "Closing Date (YYYY-MM-DD)..." msgstr "تاريخ الإغلاق (YYYY-MM-DD)..." -#: venv/lib/python3.11/site-packages/django_ledger/forms/closing_entry.py:33 +#: venv/lib/python3.11/site-packages/django_ledger/forms/closing_entry.py:34 msgid "Select a Closing Date" msgstr "اختر تاريخ الإغلاق" -#: venv/lib/python3.11/site-packages/django_ledger/forms/closing_entry.py:50 +#: venv/lib/python3.11/site-packages/django_ledger/forms/closing_entry.py:51 msgid "Closing Entry Notes" msgstr "ملاحظات إدخال الإغلاق" @@ -11070,8 +11570,8 @@ msgstr "اسم المخزون" msgid "Cannot create new Journal Entries on a locked Ledger." msgstr "لا يمكن إنشاء إدخالات يومية جديدة على دفتر حسابات مقفل." -#: venv/lib/python3.11/site-packages/django_ledger/forms/journal_entry.py:63 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3169 +#: venv/lib/python3.11/site-packages/django_ledger/forms/journal_entry.py:64 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3182 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bills/bill_detail.html:95 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/estimate/includes/estimate_item_table.html:9 msgid "Entity Unit" @@ -11114,14 +11614,14 @@ msgstr "يجب أن يتكون اسم الوحدة من 10 أحرف على ال msgid "Must provide all City/State/Zip/Country" msgstr "يجب توفير جميع المعلومات: المدينة/الولاية/الرمز البريدي/الدولة" -#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1357 +#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1379 msgid "Cannot commit on locked ledger" msgstr "لا يمكن تأكيد المعاملات على دفتر حسابات مقفل" -#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1566 -#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1695 -#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1812 -#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1936 +#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1592 +#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1721 +#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1838 +#: venv/lib/python3.11/site-packages/django_ledger/io/io_core.py:1962 msgid "PDF support not enabled. Install PDF support from Pipfile." msgstr "دعم PDF غير ممكّن. قم بتثبيت دعم PDF من Pipfile." @@ -11349,9 +11849,9 @@ msgid "Only one default account for role permitted." msgstr "يُسمح بحساب افتراضي واحد فقط للدور." #: venv/lib/python3.11/site-packages/django_ledger/models/bank_account.py:128 -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:69 -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:378 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3166 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:73 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:390 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3179 #: venv/lib/python3.11/site-packages/django_ledger/models/estimate.py:251 msgid "Entity Model" msgstr "نموذج الكيان" @@ -11453,7 +11953,7 @@ msgstr "هل تريد وضع الفاتورة %s كملغاة؟" #: venv/lib/python3.11/site-packages/django_ledger/models/chart_of_accounts.py:182 #: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:795 -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3225 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3237 #: venv/lib/python3.11/site-packages/django_ledger/models/purchase_order.py:217 msgid "Entity" msgstr "الكيان" @@ -11483,51 +11983,51 @@ msgstr "قائمة الحسابات نشطة حاليًا." msgid "The Chart of Accounts is currently not active." msgstr "قائمة الحسابات غير نشطة حاليًا." -#: venv/lib/python3.11/site-packages/django_ledger/models/chart_of_accounts.py:852 +#: venv/lib/python3.11/site-packages/django_ledger/models/chart_of_accounts.py:851 msgid "Default Chart of Accounts cannot be deactivated." msgstr "لا يمكن إلغاء تنشيط قائمة الحسابات الافتراضية." -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:72 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:76 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/tags/closing_entry_table.html:10 msgid "Is Posted" msgstr "تم النشر" -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:84 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:88 msgid "Only one Closing Entry for Date Allowed." msgstr "مسموح بإدخال إغلاق واحد فقط لكل تاريخ." -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:273 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:286 msgid "Cannot update transactions of a posted Closing Entry." msgstr "لا يمكن تحديث المعاملات لإدخال إغلاق تم نشره." -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:287 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:300 msgid "" "This action will delete existing closing entry transactions and create new " "ones." msgstr "سيؤدي هذا الإجراء إلى حذف قيود الإغلاق الحالية وإنشاء قيود جديدة." -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:305 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:318 msgid "Cannot delete a posted Closing Entry" msgstr "لا يمكن حذف إدخال إغلاق تم نشره" -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:319 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:334 msgid "This action cannot be undone." msgstr "لا يمكن التراجع عن هذا الإجراء." -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:373 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:385 msgid "Account Model" msgstr "نموذج الحساب" -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:387 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:428 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:399 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:452 msgid "Transaction Type" msgstr "نوع المعاملة" -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:388 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:400 msgid "Closing Entry Balance" msgstr "رصيد إدخال الإغلاق" -#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:398 +#: venv/lib/python3.11/site-packages/django_ledger/models/closing_entry.py:410 msgid "Closing Entry Model" msgstr "نموذج إدخال الإغلاق" @@ -11581,7 +12081,7 @@ msgstr "نموذج وحدة الكيان" msgid "Staged Transaction Model" msgstr "نموذج المعاملة المتدرجة" -#: venv/lib/python3.11/site-packages/django_ledger/models/data_import.py:1187 +#: venv/lib/python3.11/site-packages/django_ledger/models/data_import.py:1186 msgid "Invalid Bank Account for LedgerModel. No matching Entity Model found." msgstr "" "حساب مصرفي غير صالح لنموذج دفتر الحسابات. لم يتم العثور على نموذج كيان مطابق." @@ -11628,7 +12128,7 @@ msgstr "مسموح فقط بالمعرف، UUID أو نموذج الكيان." msgid "No default_coa found." msgstr "لم يتم العثور على قائمة حسابات افتراضية." -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:2830 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:2844 msgid "" "Closing books must be called by providing closing_date or " "closing_entry_model, not both." @@ -11636,32 +12136,32 @@ msgstr "" "يجب استدعاء إغلاق الدفاتر إما بتحديد تاريخ الإغلاق أو نموذج إدخال الإغلاق، " "وليس كليهما." -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:2834 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:2848 msgid "" "Closing books must be called by providing closing_date or " "closing_entry_model." msgstr "" "يجب استدعاء إغلاق الدفاتر إما بتحديد تاريخ الإغلاق أو نموذج إدخال الإغلاق." -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3156 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3169 #: venv/lib/python3.11/site-packages/django_ledger/models/journal_entry.py:407 -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:433 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:457 msgid "Journal Entry" msgstr "إدخال دفتر اليومية" -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3217 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3229 msgid "Read Permissions" msgstr "أذونات القراءة" -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3218 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3230 msgid "Read/Write Permissions" msgstr "أذونات القراءة/الكتابة" -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3229 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3241 msgid "Manager" msgstr "مدير" -#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3234 +#: venv/lib/python3.11/site-packages/django_ledger/models/entity.py:3246 msgid "Permission Level" msgstr "مستوى الأذونات" @@ -12013,10 +12513,6 @@ msgstr "تم الاستلام" msgid "Associated Entity Unit" msgstr "وحدة الكيان المرتبطة" -#: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1053 -msgid "Item Model" -msgstr "نموذج العنصر" - #: venv/lib/python3.11/site-packages/django_ledger/models/items.py:1058 msgid "Bill Model" msgstr "نموذج الفاتورة" @@ -12304,43 +12800,51 @@ msgstr "هل تريد وضع أمر الشراء %s على أنه تم التن msgid "Do you want to mark Purchase Order %s as Void?" msgstr "هل تريد إبطال أمر الشراء %s؟" -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:434 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:88 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:97 +msgid "" +"Account list must be a list of AccountModel, UUID or str objects (codes)." +msgstr "" +"يجب أن تكون قائمة الحسابات عبارة عن قائمة من كائنات AccountModel أو UUID أو " +"كائنات نصية (رموز)." + +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:458 msgid "Journal Entry to be associated with this transaction." msgstr "إدخال دفتر اليومية المرتبط بهذه المعاملة." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:440 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:464 msgid "Account from Chart of Accounts to be associated with this transaction." msgstr "الحساب من مخطط الحسابات المرتبط بهذه المعاملة." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:448 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:472 msgid "Amount of the transaction." msgstr "مبلغ المعاملة." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:455 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:479 msgid "Transaction Description" msgstr "وصف المعاملة" -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:456 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:480 msgid "A description to be included with this individual transaction." msgstr "وصف يتم تضمينه مع هذه المعاملة الفردية." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:458 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:482 msgid "Cleared" msgstr "تمت التسوية" -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:459 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:483 msgid "Reconciled" msgstr "تمت المطابقة" -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:465 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:489 msgid "Transaction" msgstr "معاملة" -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:574 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:597 msgid "Transactions cannot be linked to root accounts." msgstr "لا يمكن ربط المعاملات بالحسابات الجذرية." -#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:586 +#: venv/lib/python3.11/site-packages/django_ledger/models/transactions.py:609 msgid "Cannot modify transactions on locked journal entries." msgstr "لا يمكن تعديل المعاملات على إدخالات دفتر اليومية المقفلة." @@ -12358,7 +12862,7 @@ msgstr "كيان المورد" #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/account_create.html:10 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/account_list.html:19 -#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:98 +#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:107 msgid "Create Account" msgstr "إنشاء حساب" @@ -12367,8 +12871,8 @@ msgid "Account Transaction List Report" msgstr "تقرير قائمة معاملات الحساب" #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/account_list.html:10 -msgid "Accounts List" -msgstr "قائمة الحسابات" +msgid "CoA Account List" +msgstr "قائمة حسابات دليل الحسابات" #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/account_list.html:21 msgid "Back to CoA List" @@ -12382,7 +12886,7 @@ msgstr "مخطط الحسابات" msgid "CoA Role Default" msgstr "الدور الافتراضي لمخطط الحسابات" -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:100 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:96 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html:64 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:58 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html:119 @@ -12393,15 +12897,10 @@ msgid "Detail" msgstr "التفاصيل" #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:105 -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/bank_account/tags/bank_accounts_table.html:52 -msgid "Activate" -msgstr "تفعيل" - -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:109 msgid "Deactivate" msgstr "إلغاء التفعيل" -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:117 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/account/tags/accounts_table.html:113 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/je_detail.html:29 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/journal_entry/tags/je_table.html:80 msgid "Unlock" @@ -12614,7 +13113,7 @@ msgstr "وضع كنشط" #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/closing_entry_create.html:9 #: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/closing_entry/closing_entry_create.html:20 -#: venv/lib/python3.11/site-packages/django_ledger/views/closing_entry.py:76 +#: venv/lib/python3.11/site-packages/django_ledger/views/closing_entry.py:72 msgid "Create Closing Entry" msgstr "إنشاء إدخال إغلاق" @@ -12750,7 +13249,7 @@ msgstr "قائمة مهام الاستيراد" msgid "Manage" msgstr "إدارة" -#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html:32 +#: venv/lib/python3.11/site-packages/django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html:33 msgid "View JE" msgstr "عرض إدخال الدفتر" @@ -13168,11 +13667,11 @@ msgstr "تحديث المورد" msgid "Entity Accounts" msgstr "حسابات الكيان" -#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:91 +#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:100 msgid "WARNING: The chart of accounts list is inactive." msgstr "تحذير: قائمة دليل الحسابات غير نشطة." -#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:144 +#: venv/lib/python3.11/site-packages/django_ledger/views/account.py:153 msgid "Update Account" msgstr "تحديث الحساب" @@ -13188,10 +13687,14 @@ msgstr "إنشاء دليل الحسابات" msgid "Successfully updated {} Default Chart of Account to " msgstr "تم تحديث دليل الحسابات الافتراضي {} بنجاح إلى" -#: venv/lib/python3.11/site-packages/django_ledger/views/closing_entry.py:50 +#: venv/lib/python3.11/site-packages/django_ledger/views/closing_entry.py:48 msgid "Closing Entry List" msgstr "قائمة إدخال الإغلاق" +#: venv/lib/python3.11/site-packages/django_ledger/views/closing_entry.py:169 +msgid "Delete Closing Entry" +msgstr "حذف القيد الختامي" + #: venv/lib/python3.11/site-packages/django_ledger/views/customer.py:35 msgid "Customer List" msgstr "قائمة العملاء" @@ -13409,100 +13912,119 @@ msgstr "تحديث وحدة الكيان" msgid "Vendor List" msgstr "قائمة الموردين" -#: venv/lib/python3.11/site-packages/django_ledger/views/vendor.py:44 +#: venv/lib/python3.11/site-packages/django_ledger/views/vendor.py:50 msgid "Create New Vendor" msgstr "إنشاء مورد جديد" -#: venv/lib/python3.11/site-packages/django_ledger/views/vendor.py:71 +#: venv/lib/python3.11/site-packages/django_ledger/views/vendor.py:77 msgid "Vendor Update" msgstr "تحديث المورد" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:27 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:34 #, python-format msgid "%(value)s is not a valid hex color. Format should be #RRGGBB or #RGB" msgstr "%(value)s ليس لون سداسي عشري صالح. يجب أن يكون التنسيق #RRGGBB أو #RGB" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:66 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:73 msgid "Name of this configuration" msgstr "اسم هذا التكوين" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:70 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:77 msgid "Only one configuration can be active at a time" msgstr "يمكن أن يكون هناك تكوين نشط واحد فقط في كل مرة" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:78 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:85 msgid "Select the page size for the PDF" msgstr "اختر حجم الصفحة لملف PDF" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:83 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:90 msgid "Number of items to display per page" msgstr "عدد العناصر التي سيتم عرضها لكل صفحة" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:88 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:95 msgid "Page margin in millimeters" msgstr "هامش الصفحة بالمليمترات" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:96 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:103 msgid "Select font from available system fonts" msgstr "حدد الخط من الخطوط المتاحة في النظام" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:101 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:108 msgid "Font size for headers" msgstr "حجم الخط للعناوين" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:106 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:113 msgid "Font size for table content" msgstr "حجم الخط لمحتوى الجدول" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:112 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:119 msgid "Logo to display on PDF" msgstr "الشعار المعروض في ملف PDF" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:118 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:125 msgid "Header background color (hex format, e.g. #F0F0F0)" msgstr "لون خلفية العنوان (تنسيق سداسي عشري، مثل #F0F0F0)" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:122 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:129 msgid "Grid line color (hex format, e.g. #000000)" msgstr "لون خطوط الشبكة (تنسيق سداسي عشري، مثل #000000)" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:127 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:134 msgid "Grid line width in points" msgstr "عرض خطوط الشبكة بالنقاط" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:133 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:140 msgid "Display the header with model name" msgstr "عرض العنوان مع اسم النموذج" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:137 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:144 msgid "Display the logo in the PDF" msgstr "عرض الشعار في ملف PDF" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:141 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:148 msgid "Display export timestamp" msgstr "عرض الطابع الزمني للتصدير" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:145 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:152 msgid "Display page numbers" msgstr "عرض أرقام الصفحات" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:152 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:156 +msgid "" +"Enable right-to-left (RTL) text support for Arabic and other RTL languages" +msgstr "" +"تمكين دعم النص من اليمين إلى اليسار (RTL) للغة العربية واللغات الأخرى التي " +"تُكتب من اليمين إلى اليسار" + +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:162 +msgid "Text alignment for table content" +msgstr "محاذاة النص لمحتوى الجدول" + +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:168 +msgid "Text alignment for table headers" +msgstr "محاذاة النص لعناوين الجدول" + +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:174 +msgid "Text alignment for the title" +msgstr "محاذاة النص لعنوان التقرير" + +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:181 msgid "Spacing between table cells in millimeters" msgstr "المسافة بين خلايا الجدول بالمليمترات" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:157 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:186 msgid "Maximum characters per line before wrapping" msgstr "الحد الأقصى لعدد الأحرف في السطر قبل الانتقال إلى سطر جديد" -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:171 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:200 msgid "" "There can only be one active configuration. Please deactivate the current " "active configuration first." msgstr "" "يمكن أن يكون هناك تكوين نشط واحد فقط. يرجى إلغاء تنشيط التكوين الحالي أولاً." -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:175 -#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:176 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:204 +#: venv/lib/python3.11/site-packages/django_pdf_actions/models.py:205 msgid "Export PDF Settings" msgstr "إعدادات تصدير PDF" @@ -13520,10 +14042,10 @@ msgid "" "Message Django's middlewares" msgstr "" -#: venv/lib/python3.11/site-packages/sympy/solvers/simplex.py:564 +#: venv/lib/python3.11/site-packages/sympy/solvers/simplex.py:563 msgid "x" msgstr "س" -#: venv/lib/python3.11/site-packages/sympy/solvers/simplex.py:565 +#: venv/lib/python3.11/site-packages/sympy/solvers/simplex.py:564 msgid "y" msgstr "ص" diff --git a/plan.json b/plan.json new file mode 100644 index 00000000..65f58260 --- /dev/null +++ b/plan.json @@ -0,0 +1,50 @@ +[ +{ + "model": "plans.plan", + "pk": 1, + "fields": { + "order": 0, + "created": "2025-05-03T16:27:13.240Z", + "updated_at": "2025-05-03T16:27:13.240Z", + "name": "الأساسية", + "description": "مثالية لوكالات السيارات الصغيرة أو الأفراد الذين يديرون عددًا محدودًا من السيارات\r\nتتيح الخطة إدارة ما يصل إلى 3 مستخدمين\r\nتتيح الخطة إدارة ما يصل إلى 100 مركبة\r\nتوفر ميزات أساسية لمتابعة المبيعات والمخزون بسهولة دون تكلفة مرتفعة", + "default": null, + "available": true, + "visible": true, + "customized": null, + "url": "" + } +}, +{ + "model": "plans.plan", + "pk": 2, + "fields": { + "order": 1, + "created": "2025-05-03T16:29:17.050Z", + "updated_at": "2025-05-03T16:29:17.050Z", + "name": "المتقدمة", + "description": "مصممة للوكالات المتوسطة الحجم التي تحتاج إلى إدارة عدد أكبر من المستخدمين والمخزون\r\nتدعم 6 مستخدمين\r\nوما يصل إلى 300 مركبة في المخزون\r\nتشمل أدوات إضافية لتحليل الأداء وتتبع المبيعات وإدارة المعاملات بسهولة.", + "default": null, + "available": true, + "visible": true, + "customized": null, + "url": "" + } +}, +{ + "model": "plans.plan", + "pk": 3, + "fields": { + "order": 2, + "created": "2025-05-03T16:30:47.026Z", + "updated_at": "2025-05-03T16:30:47.026Z", + "name": "البلاتينيوم", + "description": "الخيار الأمثل للوكالات الكبيرة التي تتعامل مع حجم عملاء كبير ومخزون واسع\r\nتدعم 12 مستخدمًا\r\nوما يصل إلى 1000 مركبة في المخزون\r\nتوفر ميزات متقدمة لتحسين الكفاءة مثل التحليلات المخصصة، ودعم العملاء المتميز، وإدارة العقود والمستندات", + "default": null, + "available": true, + "visible": true, + "customized": null, + "url": "" + } +} +] diff --git a/planpricing.json b/planpricing.json new file mode 100644 index 00000000..e9d4d947 --- /dev/null +++ b/planpricing.json @@ -0,0 +1,86 @@ +[ +{ + "model": "plans.planpricing", + "pk": 1, + "fields": { + "created": "2025-05-03T16:27:13.240Z", + "updated_at": "2025-05-03T16:27:13.240Z", + "plan": 1, + "pricing": 1, + "price": "600.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +}, +{ + "model": "plans.planpricing", + "pk": 2, + "fields": { + "created": "2025-05-03T16:27:13.241Z", + "updated_at": "2025-05-03T16:27:13.241Z", + "plan": 1, + "pricing": 2, + "price": "6480.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +}, +{ + "model": "plans.planpricing", + "pk": 3, + "fields": { + "created": "2025-05-03T16:29:17.051Z", + "updated_at": "2025-05-03T16:29:17.051Z", + "plan": 2, + "pricing": 1, + "price": "900.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +}, +{ + "model": "plans.planpricing", + "pk": 4, + "fields": { + "created": "2025-05-03T16:29:17.051Z", + "updated_at": "2025-05-03T16:29:17.051Z", + "plan": 2, + "pricing": 2, + "price": "9720.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +}, +{ + "model": "plans.planpricing", + "pk": 5, + "fields": { + "created": "2025-05-03T16:30:47.026Z", + "updated_at": "2025-05-03T16:30:47.026Z", + "plan": 3, + "pricing": 1, + "price": "1300.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +}, +{ + "model": "plans.planpricing", + "pk": 6, + "fields": { + "created": "2025-05-03T16:30:47.027Z", + "updated_at": "2025-05-03T16:30:47.027Z", + "plan": 3, + "pricing": 2, + "price": "14040.00", + "order": 0, + "has_automatic_renewal": false, + "visible": true + } +} +] diff --git a/planquota.json b/planquota.json new file mode 100644 index 00000000..71fc0ab5 --- /dev/null +++ b/planquota.json @@ -0,0 +1,68 @@ +[ +{ + "model": "plans.planquota", + "pk": 1, + "fields": { + "created": "2025-05-03T16:27:13.241Z", + "updated_at": "2025-05-03T16:27:13.241Z", + "plan": 1, + "quota": 1, + "value": 3 + } +}, +{ + "model": "plans.planquota", + "pk": 2, + "fields": { + "created": "2025-05-03T16:27:13.241Z", + "updated_at": "2025-05-03T16:27:13.241Z", + "plan": 1, + "quota": 2, + "value": 100 + } +}, +{ + "model": "plans.planquota", + "pk": 3, + "fields": { + "created": "2025-05-03T16:29:17.051Z", + "updated_at": "2025-05-03T16:29:17.051Z", + "plan": 2, + "quota": 1, + "value": 6 + } +}, +{ + "model": "plans.planquota", + "pk": 4, + "fields": { + "created": "2025-05-03T16:29:17.052Z", + "updated_at": "2025-05-03T16:29:17.052Z", + "plan": 2, + "quota": 2, + "value": 300 + } +}, +{ + "model": "plans.planquota", + "pk": 5, + "fields": { + "created": "2025-05-03T16:30:47.027Z", + "updated_at": "2025-05-03T16:30:47.027Z", + "plan": 3, + "quota": 1, + "value": 12 + } +}, +{ + "model": "plans.planquota", + "pk": 6, + "fields": { + "created": "2025-05-03T16:30:47.027Z", + "updated_at": "2025-05-03T16:30:47.027Z", + "plan": 3, + "quota": 2, + "value": 1000 + } +} +] diff --git a/pricing.json b/pricing.json new file mode 100644 index 00000000..31c66042 --- /dev/null +++ b/pricing.json @@ -0,0 +1,24 @@ +[ +{ + "model": "plans.pricing", + "pk": 1, + "fields": { + "created": "2025-05-03T16:25:31.501Z", + "updated_at": "2025-05-03T16:25:31.501Z", + "name": "شهري", + "period": 30, + "url": "" + } +}, +{ + "model": "plans.pricing", + "pk": 2, + "fields": { + "created": "2025-05-03T16:25:45.320Z", + "updated_at": "2025-05-03T16:25:45.320Z", + "name": "سنوي", + "period": 365, + "url": "" + } +} +] diff --git a/quota.json b/quota.json new file mode 100644 index 00000000..d7128b4c --- /dev/null +++ b/quota.json @@ -0,0 +1,32 @@ +[ +{ + "model": "plans.quota", + "pk": 1, + "fields": { + "order": 0, + "created": "2025-05-03T16:26:49.537Z", + "updated_at": "2025-05-03T16:26:49.537Z", + "codename": "Users", + "name": "مستخدم", + "unit": "", + "description": "", + "is_boolean": false, + "url": "" + } +}, +{ + "model": "plans.quota", + "pk": 2, + "fields": { + "order": 1, + "created": "2025-05-03T16:27:03.802Z", + "updated_at": "2025-05-03T16:27:03.802Z", + "codename": "Cars", + "name": "سيارات", + "unit": "", + "description": "", + "is_boolean": false, + "url": "" + } +} +] diff --git a/requirements.txt b/requirements.txt index d60b3bf9..e39311be 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,14 @@ aiohappyeyeballs==2.6.1 -aiohttp==3.11.18 +aiohttp==3.12.0 aiohttp-retry==2.9.1 aiosignal==1.3.2 alabaster==1.0.0 albucore==0.0.24 -albumentations==2.0.6 +albumentations==2.0.7 annotated-types==0.7.0 anyio==4.9.0 arabic-reshaper==3.0.0 +arrow==1.3.0 asgiref==3.8.1 astor==0.8.1 astroid==3.3.10 @@ -16,6 +17,7 @@ autopep8==2.3.2 Babel==2.15.0 beautifulsoup4==4.13.4 bleach==6.2.0 +blessed==1.21.0 blinker==1.9.0 Brotli==1.1.0 cattrs==24.1.3 @@ -23,16 +25,17 @@ certifi==2025.4.26 cffi==1.17.1 chardet==5.2.0 charset-normalizer==3.4.2 -click==8.2.0 +click==8.2.1 colorama==0.4.6 commonmark==0.9.1 contourpy==1.3.2 crispy-bootstrap5==2025.4 -cryptography==44.0.3 +cryptography==45.0.3 cssselect2==0.8.0 ctranslate2==4.6.0 cycler==0.12.1 -Cython==3.1.0 +Cython==3.1.1 +dataclasses-json==0.6.7 decorator==5.2.1 defusedxml==0.7.1 desert==2020.11.18 @@ -40,13 +43,13 @@ diff-match-patch==20241021 dill==0.4.0 distro==1.9.0 dj-rest-auth==7.0.1 -dj-shop-cart==8.0.0a2 Django==5.2.1 -django-allauth==65.8.0 +django-allauth==65.8.1 django-appointment==3.8.0 django-autoslug==1.9.9 django-background-tasks==1.2.8 django-bootstrap5==25.1 +django-ckeditor==6.7.2 django-classy-tags==4.1.0 django-cors-headers==4.7.0 django-countries==7.6.1 @@ -56,6 +59,7 @@ django-extensions==4.1 django-filter==25.1 django-formtools==2.5.1 django-import-export==4.3.7 +django-js-asset==3.1.2 django-ledger==0.7.7 django-model-utils==5.0.0 django-money==3.5.4 @@ -64,7 +68,7 @@ django-nine==0.2.7 django-nonefield==0.4 django-ordered-model==3.7.4 django-pdf-actions==0.1.49 -django-phonenumber-field==8.1.0 +django-phonenumber-field==8.0.0 django-picklefield==3.3 django-plans==2.0.0 django-prometheus==2.3.1 @@ -79,23 +83,25 @@ django-sslserver==0.22 django-tables2==2.7.5 django-treebeard==4.7.1 django-view-breadcrumbs==2.5.1 +django-widget-tweaks==1.5.0 djangocms-admin-style==3.3.1 djangorestframework==3.16.0 djangorestframework_simplejwt==5.5.0 djangoviz==0.1.1 +djhtml==3.0.8 docopt==0.6.2 docutils==0.21.2 easy-thumbnails==2.10 emoji==2.14.1 et_xmlfile==2.0.0 -Faker==37.1.0 +Faker==37.3.0 filelock==3.18.0 fire==0.7.0 -Flask==3.1.0 fonttools==4.58.0 +fpdf==1.7.2 fpdf2==2.8.3 frozenlist==1.6.0 -fsspec==2025.3.2 +fsspec==2025.5.1 gprof2dot==2025.4.14 graphqlclient==0.2.4 greenlet==3.2.2 @@ -105,8 +111,9 @@ hpack==4.1.0 hstspreload==2025.1.1 httpcore==1.0.9 httpx==0.28.1 +httpx-sse==0.4.0 hyperframe==6.1.0 -icalendar==6.2.0 +icalendar==6.3.1 idna==3.10 imageio==2.37.0 imagesize==1.4.1 @@ -116,9 +123,17 @@ isodate==0.7.2 isort==6.0.1 itsdangerous==2.2.0 Jinja2==3.1.6 -jiter==0.9.0 -joblib==1.5.0 +jiter==0.10.0 +joblib==1.5.1 +jsonpatch==1.33 +jsonpointer==3.0.0 +jwt==1.3.1 kiwisolver==1.4.8 +langchain==0.3.25 +langchain-community==0.3.24 +langchain-core==0.3.61 +langchain-text-splitters==0.3.8 +langsmith==0.3.42 lazy_loader==0.4 ledger==1.0.1 libretranslatepy==2.1.4 @@ -128,54 +143,56 @@ lxml==5.4.0 Markdown==3.8 markdown-it-py==3.0.0 MarkupSafe==3.0.2 -marshmallow==4.0.0 +marshmallow==3.26.1 matplotlib==3.10.3 mccabe==0.7.0 mdurl==0.1.2 MouseInfo==0.1.3 mpmath==1.3.0 -multidict==6.4.3 +multidict==6.4.4 mypy_extensions==1.1.0 networkx==3.4.2 -newrelic==10.11.0 +newrelic==10.12.0 nltk==3.9.1 num2words==0.5.14 -numpy==2.2.5 +numpy==2.2.6 oauthlib==3.2.2 ofxtools==0.9.5 -openai==1.78.1 +openai==1.82.0 opencv-contrib-python==4.11.0.86 opencv-python==4.11.0.86 opencv-python-headless==4.11.0.86 openpyxl==3.1.5 opt_einsum==3.4.0 +orjson==3.10.18 outcome==1.3.0.post0 -packaging==25.0 +packaging==24.2 pandas==2.2.3 pango==0.0.1 pdfkit==1.0.0 phonenumbers==8.13.42 pillow==10.4.0 platformdirs==4.3.8 -prometheus_client==0.21.1 +prometheus_client==0.22.0 propcache==0.3.1 -protobuf==6.30.2 -psycopg==3.2.8 -psycopg-binary==3.2.8 -psycopg-c==3.2.8 +protobuf==6.31.0 +psycopg==3.2.9 +psycopg-binary==3.2.9 +psycopg-c==3.2.9 psycopg2-binary==2.9.10 py-moneyed==3.0 PyAutoGUI==0.9.54 pyclipper==1.3.0.post6 pycodestyle==2.13.0 pycparser==2.22 -pydantic==2.11.4 +pydantic==2.11.5 +pydantic-settings==2.9.1 pydantic_core==2.33.2 pydotplus==2.0.2 pydyf==0.11.0 PyGetWindow==0.0.9 Pygments==2.19.1 -PyJWT==2.9.0 +PyJWT==2.10.1 pylint==3.3.7 PyMsgBox==1.0.9 PyMySQL==1.1.1 @@ -184,7 +201,6 @@ pyobjc-framework-Cocoa==11.0 pyobjc-framework-Quartz==11.0 pyparsing==3.2.3 pypdf==5.5.0 -PyPDF2==3.0.1 pyperclip==1.9.0 pyphen==0.17.2 pypng==0.20220715.0 @@ -197,22 +213,25 @@ python-dateutil==2.9.0.post0 python-docx==1.1.2 python-dotenv==1.1.0 python-openid==2.2.5 -python-stdnum==2.0 +python-slugify==8.0.4 +python-stdnum==2.1 python3-saml==1.16.0 pytweening==1.2.0 pytz==2025.2 pyvin==0.0.2 -pywa==2.9.0 +pywa==2.10.0 pywhat==5.1.0 pywhatkit==5.4 PyYAML==6.0.2 pyzbar==0.1.9 qrcode==8.2 RapidFuzz==3.13.0 +redis==6.1.0 regex==2024.11.6 -reportlab==4.4.0 +reportlab==4.4.1 requests==2.32.3 requests-oauthlib==2.0.0 +requests-toolbelt==1.0.0 rfc3986==2.0.0 rich==14.0.0 rubicon-objc==0.5.0 @@ -220,16 +239,17 @@ sacremoses==0.1.1 scikit-image==0.25.2 scikit-learn==1.6.1 scipy==1.15.3 -selenium==4.32.0 +selenium==4.33.0 sentencepiece==0.2.0 -shapely==2.1.0 +shapely==2.1.1 simsimd==6.2.1 six==1.17.0 +slugify==0.0.1 sniffio==1.3.1 snowballstemmer==3.0.1 sortedcontainers==2.4.0 soupsieve==2.7 -SQLAlchemy==2.0.40 +SQLAlchemy==2.0.41 sqlparse==0.5.3 stanza==1.10.1 stringzilla==3.12.5 @@ -237,9 +257,11 @@ suds==1.2.0 swapper==1.3.0 sympy==1.14.0 tablib==3.8.0 +tenacity==9.1.2 termcolor==3.1.0 +text-unidecode==1.3 threadpoolctl==3.6.0 -tifffile==2025.5.10 +tifffile==2025.5.24 tinycss2==1.4.0 tinyhtml5==2.0.0 tomli==2.2.1 @@ -248,9 +270,10 @@ torch==2.7.0 tqdm==4.67.1 trio==0.30.0 trio-websocket==0.12.2 -twilio==9.6.0 +twilio==9.6.1 +types-python-dateutil==2.9.0.20250516 typing-inspect==0.9.0 -typing-inspection==0.4.0 +typing-inspection==0.4.1 typing_extensions==4.13.2 tzdata==2025.2 Unidecode==1.4.0 @@ -260,6 +283,7 @@ vin==0.6.2 vininfo==1.8.0 vishap==0.1.5 vpic-api==0.7.4 +wcwidth==0.2.13 weasyprint==65.1 webencodings==0.5.1 websocket-client==1.8.0 @@ -269,3 +293,4 @@ wsproto==1.2.0 xmlsec==1.3.15 yarl==1.20.0 zopfli==0.2.3.post1 +zstandard==0.23.0 diff --git a/requirements_dev.txt b/requirements_dev.txt index a27310b3..fd0f3c41 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -92,3 +92,5 @@ typing_extensions==4.13.0 tzdata==2025.2 urllib3==2.3.0 wcwidth==0.2.13 +langchain +langchain_ollama diff --git a/static/images/favicons/haikalbot_v1.png b/static/images/favicons/haikalbot_v1.png new file mode 100644 index 00000000..361b5247 Binary files /dev/null and b/static/images/favicons/haikalbot_v1.png differ diff --git a/static/images/favicons/haikalbot_v2.png b/static/images/favicons/haikalbot_v2.png new file mode 100644 index 00000000..cab82cbb Binary files /dev/null and b/static/images/favicons/haikalbot_v2.png differ diff --git a/templates/account/signup-wizard.html b/templates/account/signup-wizard.html index 740d64e4..206bc605 100644 --- a/templates/account/signup-wizard.html +++ b/templates/account/signup-wizard.html @@ -41,6 +41,7 @@
diff --git a/templates/crm/leads/lead_tracking.html b/templates/crm/leads/lead_tracking.html index 5b470d0f..939b8bd3 100644 --- a/templates/crm/leads/lead_tracking.html +++ b/templates/crm/leads/lead_tracking.html @@ -5,14 +5,12 @@ {% block customCSS %} +{% endblock customCSS %} {% block content %} - + addMessage(botResponse, false); + scrollToBottom(); + } -
-
-
-

{% trans 'HaikalBot' %}

+ function hasInsightsData(response) { + return response.insights || response['التحليلات'] || + response.recommendations || response['التوصيات']; + } + + function handleRequestError(error) { + hideTypingIndicator(); + const errorMsg = isArabic ? + 'عذرًا، حدث خطأ أثناء معالجة طلبك. يرجى المحاولة مرة أخرى.' : + 'Sorry, an error occurred while processing your request. Please try again.'; + addMessage(errorMsg, false); + console.error('API Error:', error); + } + + // Chat management + function clearChat() { + if (confirm(isArabic ? + 'هل أنت متأكد من أنك تريد مسح المحادثة؟' : + 'Are you sure you want to clear the chat?')) { + const welcomeMessage = chatMessages.children().first(); + chatMessages.empty().append(welcomeMessage); + } + } + + function exportChat() { + let chatContent = ''; + $('.message').each(function() { + const isUser = $(this).hasClass('user-message'); + const sender = isUser ? + (isArabic ? 'أنت' : 'You') : + (isArabic ? 'المساعد الذكي' : 'AI Assistant'); + const text = $(this).find('.chat-message').text().trim(); + const time = $(this).find('.text-400').text().trim(); + + chatContent += `${sender} (${time}):\n${text}\n\n`; + }); + + downloadTextFile(chatContent, 'chat-export-' + new Date().toISOString().slice(0, 10) + '.txt'); + } + + function downloadTextFile(content, filename) { + const blob = new Blob([content], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(url); + } + + // Message display functions + function addMessage(text, isUser) { + const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + const messageClass = isUser ? 'user-message justify-content-between' : ''; + + const avatarHtml = getAvatarHtml(isUser); + const messageHtml = getMessageHtml(text, isUser, time); + + const fullMessageHtml = ` +
+ ${avatarHtml} + ${messageHtml}
-
+ `; -
-

{% trans 'HaikalBot' %}: {% trans 'Hello! How can I assist you today?' %}

+ chatMessages.append(fullMessageHtml); + scrollToBottom(); + } + + function getAvatarHtml(isUser) { + if (isUser) { + return ` +
+
+ +
+
+ `; + } + return ` +
+
+ +
- - -
-
+ `; + } - - + }); + } + // Process recommendations + if (recommendationsData.length > 0) { + formattedResponse += isArabic ? '## التوصيات\n\n' : '## Recommendations\n\n'; + recommendationsData.forEach(rec => { + formattedResponse += `- ${rec}\n`; + }); + } -
-{% endblock content %} + return formattedResponse.trim() || + (isArabic ? 'تم تحليل البيانات بنجاح ولكن لا توجد نتائج للعرض.' : 'Data analyzed successfully but no results to display.'); + } + + function getLocalizedValue(obj, englishKey, arabicKey) { + return isArabic ? (obj[arabicKey] || obj[englishKey] || '') : (obj[englishKey] || obj[arabicKey] || ''); + } + + // Copy message functionality + $(document).on('click', '.copy-btn', function() { + const text = $(this).closest('.d-flex').find('.chat-message').text().trim(); + navigator.clipboard.writeText(text).then(() => { + showCopySuccess($(this)); + }); + }); + + function showCopySuccess(button) { + const originalIcon = button.html(); + button.html(''); + setTimeout(() => { + button.html(originalIcon); + }, 1500); + } + + // Initialize + scrollToBottom(); +}); + +{% endblock content %} \ No newline at end of file diff --git a/templates/header.html b/templates/header.html index 82f80f6a..498d15f0 100644 --- a/templates/header.html +++ b/templates/header.html @@ -268,6 +268,7 @@ {% trans 'Reports' %}
+ {% if request.user.dealer.entity %} {% if perms.django_ledger.view_accountmodel %}
{% endif %} + {% endif %}
{% endif %} diff --git a/templates/terms_and_privacy.html b/templates/terms_and_privacy.html new file mode 100644 index 00000000..09177017 --- /dev/null +++ b/templates/terms_and_privacy.html @@ -0,0 +1,271 @@ +{% extends 'base.html' %} +{% load static i18n %} + +{% block title %}{{ _("Terms of use and privacy policy")}}{% endblock title %} +{% block content %} + + +
+
+
+ +

Date: 1/1/2025

+
+

Terms of Service

+

Welcome to Haikal, an advanced car inventory management platform owned and operated by Tenhal Information Technology Company ("we", "our", "us"). By accessing or using the Haikal system ("the Service"), you agree to be legally bound by the terms outlined below.

+

1. Acceptance of Terms

+

By using the Service, you confirm that you are authorized to act on behalf of a business entity, agree to these Terms of Service, and comply with all applicable laws and regulations.

+ +

2. Description of Service

+

Haikal provides car dealers and authorized users with tools for managing car inventory, sales, branches, financial transactions, and analytics. Additional services may include integration with government systems, API access, and reporting modules.

+ +

3. Account Registration & Security

+
    +
  • You must register and maintain a secure account with accurate information.
  • +
  • You are solely responsible for any activity under your account.
  • +
  • You must notify us immediately if you suspect unauthorized access or breach of your account.
  • +
+ +

4. License and Restrictions

+
    +
  • We grant you a non-exclusive, non-transferable, revocable license to use the Service in accordance with these terms.
  • +
  • You may not copy, modify, distribute, resell, reverse-engineer, or decompile any part of the Service.
  • +
+ +

5. User Obligations

+
    +
  • You agree not to upload illegal, harmful, or offensive data to the system.
  • +
  • You are responsible for maintaining compliance with data privacy regulations when inputting customer data.
  • +
  • You must not attempt to access systems or data not explicitly made available to you.
  • +
+ +

6. Intellectual Property

+

All content, software, user interface designs, databases, and trademarks within Haikal are the intellectual property of Tenhal Information Technology Company and are protected under local and international IP laws.

+ +

7. Service Availability & Modifications

+
    +
  • We aim to provide 99.9% uptime but do not guarantee uninterrupted access.
  • +
  • We may modify or discontinue parts of the service at any time with or without notice.
  • +
+ +

8. Third-Party Integrations

+

We may integrate with external services such as VIN databases, payment processors, or government systems. Use of those services is subject to their own terms and privacy policies.

+ +

9. Limitation of Liability

+

To the fullest extent permitted by law, Tenhal is not liable for indirect, incidental, punitive, or consequential damages resulting from your use of the Service. Our total liability is limited to the amount you paid us in the last 12 months.

+ +

10. Termination

+

We may suspend or terminate your access if you violate these terms. Upon termination, your access to the Service and associated data may be revoked or deleted.

+ +

11. Governing Law

+

These terms are governed by the laws of the Kingdom of Saudi Arabia. Any disputes will be resolved exclusively in courts located in Riyadh.

+
+ +
+ +
+

Privacy Policy

+ +

We value your privacy and are committed to protecting your personal and business data. This Privacy Policy explains how we collect, use, and protect your information when you use Haikal.

+ +

1. Information We Collect

+
    +
  • Account Information: Name, email, phone number, user role, and login credentials.
  • +
  • Business Data: Inventory details, financial transactions, customer and supplier records.
  • +
  • Technical Data: IP addresses, browser types, login timestamps, session logs, device identifiers.
  • +
+ +

2. How We Use Your Information

+
    +
  • To operate and improve the Service.
  • +
  • To secure accounts and prevent misuse or fraud.
  • +
  • To provide customer support and respond to inquiries.
  • +
  • To comply with legal obligations and cooperate with regulators when required.
  • +
+ +

3. Data Sharing

+
    +
  • We do not sell your information to third parties.
  • +
  • We may share data with trusted processors (e.g., hosting, support tools) under strict confidentiality terms.
  • +
  • We may disclose data to authorities when legally required.
  • +
+ +

4. Data Storage and Security

+
    +
  • Your data is stored securely on encrypted servers with access control policies in place.
  • +
  • We apply firewalls, intrusion detection, and regular audits to safeguard information.
  • +
+ +

5. Your Rights

+
    +
  • You have the right to access, correct, or request deletion of your data.
  • +
  • You may contact us to object to processing or request data portability.
  • +
+ +

6. Data Retention

+

We retain data as long as necessary to provide the service, comply with legal obligations, or enforce agreements. Upon request, we may anonymize or delete your data.

+ +

7. Cookies and Tracking

+

We may use cookies to enhance your experience. These may include session cookies, authentication tokens, and analytics tools.

+ +

8. International Data Transfers

+

If data is processed outside of Saudi Arabia, we ensure adequate protection via agreements and security standards aligned with applicable laws.

+ +

9. Changes to this Policy

+

We may revise this Privacy Policy from time to time. Updates will be posted here with a revised effective date.

+
+ + + +
+
+

التاريخ: ١/١/٢٠٢٥

+ +
+

شروط الخدمة

+

مرحبًا بك في هيكل، منصة متقدمة لإدارة مخزون السيارات، مملوكة وتديرها شركة تنحل لتقنية المعلومات ("نحن"، "خاصتنا"). باستخدامك لنظام هيكل، فإنك توافق على الالتزام القانوني بالشروط التالية:

+ +

١. قبول الشروط

+

باستخدامك للخدمة، فإنك تؤكد أنك مفوض بالتصرف نيابة عن كيان تجاري، وتوافق على شروط الخدمة هذه، وتلتزم بجميع القوانين والأنظمة المعمول بها.

+ +

٢. وصف الخدمة

+

يوفر هيكل أدوات لتجار السيارات والمستخدمين المخولين لإدارة المخزون، المبيعات، الفروع، المعاملات المالية، والتحليلات. تشمل الخدمات الإضافية تكاملات مع أنظمة حكومية، وصول API، وتقارير.

+ +

٣. التسجيل والحماية

+
    +
  • يجب تسجيل حساب دقيق وآمن.
  • +
  • أنت مسؤول عن كل نشاط يتم عبر حسابك.
  • +
  • يجب إبلاغنا فورًا عند الاشتباه في اختراق الحساب.
  • +
+ +

٤. الترخيص والقيود

+
    +
  • نمنحك ترخيصًا غير حصري وقابل للإلغاء لاستخدام الخدمة.
  • +
  • لا يحق لك نسخ، تعديل، توزيع، أو عكس هندسة أي جزء من الخدمة.
  • +
+ +

٥. التزامات المستخدم

+
    +
  • عدم تحميل بيانات غير قانونية أو ضارة.
  • +
  • أنت مسؤول عن الامتثال لقوانين خصوصية البيانات.
  • +
  • لا تحاول الوصول لبيانات أو أنظمة غير مصرّح بها.
  • +
+ +

٦. الملكية الفكرية

+

جميع المحتويات، البرمجيات، قواعد البيانات، والتصاميم تخص تنحل وتخضع للقوانين المحلية والدولية.

+ +

٧. توفر الخدمة والتعديلات

+
    +
  • نهدف لتوفير الخدمة بنسبة تشغيل 99.9٪ ولكن لا نضمن عدم الانقطاع.
  • +
  • قد نقوم بتحديث أو تعديل أو إيقاف الخدمة في أي وقت.
  • +
+ +

٨. تكامل الأطراف الخارجية

+

قد نتكامل مع خدمات خارجية مثل قواعد بيانات VIN، ومعالجات الدفع، والأنظمة الحكومية. يخضع استخدام هذه الخدمات لشروطها الخاصة.

+ +

٩. حدود المسؤولية

+

أقصى مسؤولية لنا عن أي ضرر غير مباشر أو عرضي تقتصر على ما دفعته خلال الـ 12 شهرًا الماضية.

+ +

١٠. الإنهاء

+

يجوز لنا إنهاء أو تعليق حسابك إذا انتهكت هذه الشروط. وقد يتم حذف بياناتك بعد الإنهاء.

+ +

١١. القانون الحاكم

+

تخضع هذه الشروط لقوانين المملكة العربية السعودية، ويكون الاختصاص القضائي لمحاكم الرياض فقط.

+
+ +
+ +
+

سياسة الخصوصية

+ +

نحن نهتم بخصوصيتك وملتزمون بحماية بياناتك الشخصية والتجارية. توضح هذه السياسة كيفية جمع واستخدام وحماية بياناتك عند استخدام نظام هيكل.

+ +

١. المعلومات التي نجمعها

+
    +
  • بيانات الحساب: الاسم، البريد الإلكتروني، الهاتف، الدور، بيانات تسجيل الدخول.
  • +
  • بيانات الأعمال: تفاصيل السيارات، المعاملات المالية، سجلات العملاء والموردين.
  • +
  • بيانات تقنية: عناوين IP، أنواع المتصفحات، أوقات الدخول، سجلات الجلسات، معرفات الأجهزة.
  • +
+ +

٢. استخدام البيانات

+
    +
  • لتشغيل الخدمة وتحسينها.
  • +
  • لحماية الحسابات ومنع الاحتيال.
  • +
  • لدعم العملاء والاستجابة للاستفسارات.
  • +
  • للالتزام بالقوانين والتعاون مع الجهات التنظيمية.
  • +
+ +

٣. مشاركة البيانات

+
    +
  • لا نبيع بياناتك لأي طرف ثالث.
  • +
  • قد نشارك البيانات مع مزودين موثوقين بموجب اتفاقيات سرية.
  • +
  • قد نكشف عن البيانات للجهات المختصة عند الطلب القانوني.
  • +
+ +

٤. التخزين والحماية

+
    +
  • تُخزن البيانات على خوادم مشفرة مع سياسات وصول صارمة.
  • +
  • نطبق جدران حماية، واكتشاف التسلل، ومراجعات دورية.
  • +
+ +

٥. حقوقك

+
    +
  • لك الحق في الوصول إلى بياناتك أو تعديلها أو طلب حذفها.
  • +
  • يمكنك الاعتراض على المعالجة أو طلب نقل البيانات.
  • +
+ +

٦. الاحتفاظ بالبيانات

+

نحتفظ بالبيانات طالما كانت ضرورية لتقديم الخدمة أو للامتثال للأنظمة. يمكننا إزالتها أو إخفاؤها حسب الطلب.

+ +

٧. الكوكيز والتتبع

+

قد نستخدم الكوكيز لتحسين تجربتك، بما في ذلك جلسات التوثيق والتحليلات.

+ +

٨. نقل البيانات خارجياً

+

إذا تم نقل البيانات خارج السعودية، نضمن حمايتها وفق اتفاقيات ومعايير قانونية مناسبة.

+ +

٩. التحديثات

+

قد نُجري تغييرات على هذه السياسة، وسيتم نشر التعديلات مع تاريخ سريان جديد.

+
+ +
+
+
+
+
+

Contact Information

+

If you have any questions or concerns about these Terms or Privacy practices, please contact us:

+

+ Tenhal Information Technology Company
+ Riyadh, Saudi Arabia
+ 📧 info@tenhal.sa
+ 🌐 www.tenhal.sa +

+
+
+
+
+

معلومات التواصل

+

لأي استفسار حول هذه الشروط أو سياسة الخصوصية، يرجى التواصل معنا:

+

+ شركة تنحل لتقنية المعلومات
+ الرياض، المملكة العربية السعودية
+ 📧 info@tenhal.sa
+ 🌐 tenhal.sa +

+
+
+
+
+ + + + + +{% endblock content %} \ No newline at end of file diff --git a/test.txt b/test.txt index 83f97a67..fe076804 100644 --- a/test.txt +++ b/test.txt @@ -250,3 +250,36 @@ send_mail( "OPC minivan 5-doors": "ميني فان OPC 5 أبواب", "Hardtop 2-doors": "Hardtop 2 أبواب", "JP-spec Sedan 4-doors": "جي بي مواصفات سيدان 4 أبواب", + + + +python manage.py dumpdata inventory.CarMake --indent 4 > carmake.json +python manage.py dumpdata inventory.CarModel --indent 4 > carmodel.json +python manage.py dumpdata inventory.CarSerie --indent 4 > carserie.json +python manage.py dumpdata inventory.CarTrim --indent 4 > cartrim.json +python manage.py dumpdata inventory.CarEquipment --indent 4 > carequipment.json +python manage.py dumpdata inventory.CarSpecification --indent 4 > carspecification.json +python manage.py dumpdata inventory.CarSpecificationValue --indent 4 > carspecificationvalue.json +python manage.py dumpdata inventory.CarOption --indent 4 > caroption.json +python manage.py dumpdata inventory.CarOptionValue --indent 4 > caroptionvalue.json +python manage.py dumpdata plans.Plan --indent 4 > plan.json +python manage.py dumpdata plans.Pricing --indent 4 > pricing.json +python manage.py dumpdata plans.PlanPricing --indent 4 > planpricing.json +python manage.py dumpdata plans.Quota --indent 4 > quota.json +python manage.py dumpdata plans.PlanQuota --indent 4 > planquota.json + + +python manage.py loaddata carmake.json +python manage.py loaddata carmodel.json +python manage.py loaddata carserie.json +python manage.py loaddata cartrim.json +python manage.py loaddata carequipment.json +python manage.py loaddata carspecification.json +python manage.py loaddata carspecificationvalue.json +python manage.py loaddata caroption.json +python manage.py loaddata caroptionvalue.json +python manage.py loaddata plan.json +python manage.py loaddata pricing.json +python manage.py loaddata planpricing.json +python manage.py loaddata quota.json +python manage.py loaddata planquota.json diff --git a/test_ollama.py b/test_ollama.py new file mode 100644 index 00000000..c1cd8e01 --- /dev/null +++ b/test_ollama.py @@ -0,0 +1,194 @@ +import os +import django + + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "car_inventory.settings") +django.setup() + +from django.test import TestCase, RequestFactory +from django.contrib.auth.models import User +from django.http import JsonResponse +import json + +from unittest.mock import patch, MagicMock +from haikalbot.views import ModelAnalystView +from haikalbot.models import AnalysisCache + + + + + +class ModelAnalystViewTest(TestCase): + def setUp(self): + self.factory = RequestFactory() + self.user = User.objects.create_user( + username='testuser', email='test@example.com', password='testpass' + ) + self.superuser = User.objects.create_superuser( + username='admin', email='admin@example.com', password='adminpass' + ) + self.view = ModelAnalystView() + + def test_post_without_prompt(self): + """Test that the view returns an error when no prompt is provided.""" + request = self.factory.post( + '/analyze/', + data=json.dumps({}), + content_type='application/json' + ) + request.user = self.user + + response = self.view.post(request) + + self.assertEqual(response.status_code, 400) + content = json.loads(response.content) + self.assertEqual(content['status'], 'error') + self.assertEqual(content['message'], 'Prompt is required') + + def test_post_with_invalid_json(self): + """Test that the view handles invalid JSON properly.""" + request = self.factory.post( + '/analyze/', + data='invalid json', + content_type='application/json' + ) + request.user = self.user + + response = self.view.post(request) + + self.assertEqual(response.status_code, 400) + content = json.loads(response.content) + self.assertEqual(content['status'], 'error') + self.assertEqual(content['message'], 'Invalid JSON in request body') + + @patch('ai_analyst.views.ModelAnalystView._process_prompt') + @patch('ai_analyst.views.ModelAnalystView._check_permissions') + @patch('ai_analyst.views.ModelAnalystView._generate_hash') + @patch('ai_analyst.views.ModelAnalystView._get_cached_result') + @patch('ai_analyst.views.ModelAnalystView._cache_result') + def test_post_with_valid_prompt(self, mock_cache_result, mock_get_cached, + mock_generate_hash, mock_check_permissions, + mock_process_prompt): + """Test that the view processes a valid prompt correctly.""" + # Setup mocks + mock_check_permissions.return_value = True + mock_generate_hash.return_value = 'test_hash' + mock_get_cached.return_value = None + mock_process_prompt.return_value = { + 'status': 'success', + 'insights': [{'type': 'test_insight'}] + } + + # Create request + request = self.factory.post( + '/analyze/', + data=json.dumps({'prompt': 'How many cars do we have?', 'dealer_id': 1}), + content_type='application/json' + ) + request.user = self.user + + # Call view + response = self.view.post(request) + + # Assertions + self.assertEqual(response.status_code, 200) + content = json.loads(response.content) + self.assertEqual(content['status'], 'success') + self.assertEqual(len(content['insights']), 1) + + # Verify function calls + mock_check_permissions.assert_called_once_with(self.user, 1) + mock_generate_hash.assert_called_once_with('How many cars do we have?', 1) + mock_get_cached.assert_called_once_with('test_hash', self.user, 1) + mock_process_prompt.assert_called_once_with('How many cars do we have?', self.user, 1) + mock_cache_result.assert_called_once() + + @patch('ai_analyst.views.ModelAnalystView._get_cached_result') + @patch('ai_analyst.views.ModelAnalystView._check_permissions') + @patch('ai_analyst.views.ModelAnalystView._generate_hash') + def test_post_with_cached_result(self, mock_generate_hash, mock_check_permissions, mock_get_cached): + """Test that the view returns cached results when available.""" + # Setup mocks + mock_check_permissions.return_value = True + mock_generate_hash.return_value = 'test_hash' + mock_get_cached.return_value = { + 'status': 'success', + 'insights': [{'type': 'cached_insight'}], + 'cached': True + } + + # Create request + request = self.factory.post( + '/analyze/', + data=json.dumps({'prompt': 'How many cars do we have?', 'dealer_id': 1}), + content_type='application/json' + ) + request.user = self.user + + # Call view + response = self.view.post(request) + + # Assertions + self.assertEqual(response.status_code, 200) + content = json.loads(response.content) + self.assertEqual(content['status'], 'success') + self.assertEqual(content['cached'], True) + + # Verify function calls + mock_check_permissions.assert_called_once_with(self.user, 1) + mock_generate_hash.assert_called_once_with('How many cars do we have?', 1) + mock_get_cached.assert_called_once_with('test_hash', self.user, 1) + + def test_check_permissions_superuser(self): + """Test that superusers have permission to access any dealer data.""" + result = self.view._check_permissions(self.superuser, 1) + self.assertTrue(result) + + result = self.view._check_permissions(self.superuser, None) + self.assertTrue(result) + + def test_analyze_prompt_count(self): + """Test that the prompt analyzer correctly identifies count queries.""" + analysis_type, target_models, query_params = self.view._analyze_prompt("How many cars do we have?") + self.assertEqual(analysis_type, 'count') + self.assertEqual(target_models, ['Car']) + self.assertEqual(query_params, {}) + + analysis_type, target_models, query_params = self.view._analyze_prompt( + "Count the number of users with active status") + self.assertEqual(analysis_type, 'count') + self.assertEqual(target_models, ['User']) + self.assertTrue('active' in query_params or 'status' in query_params) + + def test_analyze_prompt_relationship(self): + """Test that the prompt analyzer correctly identifies relationship queries.""" + analysis_type, target_models, query_params = self.view._analyze_prompt( + "Show relationship between User and Profile") + self.assertEqual(analysis_type, 'relationship') + self.assertTrue('User' in target_models and 'Profile' in target_models) + + analysis_type, target_models, query_params = self.view._analyze_prompt( + "What is the User to Order relationship?") + self.assertEqual(analysis_type, 'relationship') + self.assertTrue('User' in target_models and 'Order' in target_models) + + def test_analyze_prompt_statistics(self): + """Test that the prompt analyzer correctly identifies statistics queries.""" + analysis_type, target_models, query_params = self.view._analyze_prompt("What is the average price of cars?") + self.assertEqual(analysis_type, 'statistics') + self.assertEqual(target_models, ['Car']) + self.assertEqual(query_params['field'], 'price') + self.assertEqual(query_params['operation'], 'average') + + analysis_type, target_models, query_params = self.view._analyze_prompt("Show maximum age of users") + self.assertEqual(analysis_type, 'statistics') + self.assertEqual(target_models, ['User']) + self.assertEqual(query_params['field'], 'age') + self.assertEqual(query_params['operation'], 'maximum') + + def test_normalize_model_name(self): + """Test that model names are correctly normalized.""" + self.assertEqual(self.view._normalize_model_name('users'), 'User') + self.assertEqual(self.view._normalize_model_name('car'), 'Car') + self.assertEqual(self.view._normalize_model_name('orderItems'), + 'OrderItem') # This would actually need more logic to handle camelCase