complete first version of main proccess

This commit is contained in:
aminhashemi92 2025-08-27 07:11:26 +03:30
parent 6ff4740d04
commit f2fc2362a7
61 changed files with 3280 additions and 28 deletions

111
installations/models.py Normal file
View file

@ -0,0 +1,111 @@
from django.db import models
from django.contrib.auth import get_user_model
from django.utils import timezone
from common.models import BaseModel
User = get_user_model()
class InstallationAssignment(BaseModel):
"""انتخاب نصاب و زمان مراجعه برای یک درخواست"""
process_instance = models.ForeignKey(
'processes.ProcessInstance', on_delete=models.CASCADE,
related_name='installation_assignments', verbose_name='نمونه فرآیند'
)
installer = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, blank=True,
related_name='assigned_installations', verbose_name='نصاب'
)
scheduled_date = models.DateField(null=True, blank=True, verbose_name='تاریخ مراجعه')
notes = models.TextField(blank=True, verbose_name='یادداشت')
assigned_by = models.ForeignKey(
User, on_delete=models.SET_NULL, null=True, blank=True,
related_name='assigner_installations', verbose_name='اختصاص‌دهنده'
)
class Meta:
verbose_name = 'اختصاص نصاب'
verbose_name_plural = 'اختصاص‌های نصاب'
ordering = ['-created']
def __str__(self):
return f"Assignment for {self.process_instance.code} to {getattr(self.installer, 'username', '-') }"
class InstallationReport(BaseModel):
"""گزارش نصب توسط نصاب"""
assignment = models.ForeignKey(
InstallationAssignment, on_delete=models.CASCADE,
related_name='reports', verbose_name='اختصاص'
)
visited_date = models.DateField(null=True, blank=True, verbose_name='تاریخ مراجعه')
new_water_meter_serial = models.CharField(max_length=50, null=True, blank=True, verbose_name='سریال کنتور جدید')
seal_number = models.CharField(max_length=50, null=True, blank=True, verbose_name='شماره پلمپ')
is_meter_suspicious = models.BooleanField(default=False, verbose_name='کنتور مشکوک است؟')
utm_x = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True, verbose_name='UTM X')
utm_y = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True, verbose_name='UTM Y')
description = models.TextField(blank=True, verbose_name='توضیحات')
created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='ایجادکننده')
approved = models.BooleanField(default=False, verbose_name='تایید شده')
approved_at = models.DateTimeField(null=True, blank=True, verbose_name='تاریخ تایید')
class Meta:
verbose_name = 'گزارش نصب'
verbose_name_plural = 'گزارش‌های نصب'
ordering = ['-created']
def __str__(self):
return f"Report for {self.assignment.process_instance.code}"
def save(self, *args, **kwargs):
# set approved time
if self.approved and self.approved_at is None:
self.approved_at = timezone.now()
super().save(*args, **kwargs)
# if approved, propagate UTM to well
try:
if self.approved and self.assignment and self.assignment.process_instance and self.assignment.process_instance.well:
well = self.assignment.process_instance.well
changed = False
if self.utm_x is not None:
well.utm_x = self.utm_x
changed = True
if self.utm_y is not None:
well.utm_y = self.utm_y
changed = True
if changed:
well.save()
except Exception:
pass
class InstallationPhoto(BaseModel):
report = models.ForeignKey(InstallationReport, on_delete=models.CASCADE, related_name='photos', verbose_name='گزارش')
image = models.ImageField(upload_to='installations/photos/%Y/%m/%d/', verbose_name='عکس')
class Meta:
verbose_name = 'عکس نصب'
verbose_name_plural = 'عکس‌های نصب'
ordering = ['created']
class InstallationItemChange(BaseModel):
"""تغییرات اقلام در مرحله نصب (افزودن/حذف نسبت به اقلام مرحله ۱)"""
CHANGE_CHOICES = [
('add', 'افزودن'),
('remove', 'حذف'),
]
report = models.ForeignKey(InstallationReport, on_delete=models.CASCADE, related_name='item_changes', verbose_name='گزارش')
item = models.ForeignKey('invoices.Item', on_delete=models.CASCADE, verbose_name='آیتم')
change_type = models.CharField(max_length=6, choices=CHANGE_CHOICES, verbose_name='نوع تغییر')
quantity = models.PositiveIntegerField(verbose_name='تعداد')
unit_price = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='قیمت واحد', null=True, blank=True)
total_price = models.DecimalField(max_digits=15, decimal_places=2, verbose_name='قیمت کل', null=True, blank=True)
notes = models.TextField(blank=True, verbose_name='یادداشت')
class Meta:
verbose_name = 'تغییر آیتم نصب'
verbose_name_plural = 'تغییرات آیتم‌های نصب'
ordering = ['created']