136 lines
		
	
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
	
		
			7.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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='کنتور مشکوک است؟')
 | 
						||
    METER_TYPE_CHOICES = [
 | 
						||
        ('smart', 'هوشمند (آبی/برق)'),
 | 
						||
        ('volumetric', 'حجمی'),
 | 
						||
    ]
 | 
						||
    meter_type = models.CharField(max_length=20, choices=METER_TYPE_CHOICES, null=True, blank=True, verbose_name='نوع کنتور')
 | 
						||
    METER_MODEL_CHOICES = [
 | 
						||
        ('A', 'A'),
 | 
						||
        ('B', 'B'),
 | 
						||
    ]
 | 
						||
    meter_model = models.CharField(max_length=20, choices=METER_MODEL_CHOICES, null=True, blank=True, verbose_name='مدل کنتور')
 | 
						||
    meter_size = models.CharField(max_length=50, null=True, blank=True, verbose_name='سایز کنتور')
 | 
						||
    discharge_pipe_diameter = models.PositiveIntegerField(null=True, blank=True, verbose_name='قطر لوله آبده (اینچ)')
 | 
						||
    USAGE_TYPE_CHOICES = [
 | 
						||
        ('domestic', 'شرب و خدمات'),
 | 
						||
        ('agriculture', 'کشاورزی'),
 | 
						||
        ('industrial', 'صنعتی'),
 | 
						||
    ]
 | 
						||
    usage_type = models.CharField(max_length=20, choices=USAGE_TYPE_CHOICES, null=True, verbose_name='نوع مصرف')
 | 
						||
    exploitation_license_number = models.CharField(max_length=50, verbose_name='شماره پروانه بهرهبرداری چاه')
 | 
						||
    motor_power = models.PositiveIntegerField(null=True, blank=True, verbose_name='(کیلووات ساعت) قدرت موتور')
 | 
						||
    pre_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی قبل از کالیبراسیون')
 | 
						||
    post_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی بعد از کالیبراسیون')
 | 
						||
    water_meter_manufacturer = models.ForeignKey('wells.WaterMeterManufacturer', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='شرکت سازنده کنتور آب')
 | 
						||
    sim_number = models.CharField(max_length=20, null=True, blank=True, verbose_name='شماره سیمکارت')
 | 
						||
    driving_force = models.CharField(max_length=50, null=True, blank=True, verbose_name='نیرو محرکه چاه')
 | 
						||
    utm_x = models.DecimalField(max_digits=10, decimal_places=0, null=True, blank=True, verbose_name='UTM X')
 | 
						||
    utm_y = models.DecimalField(max_digits=10, decimal_places=0, 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']
 | 
						||
 | 
						||
 |