143 lines
7.9 KiB
Python
143 lines
7.9 KiB
Python
from django.db import models
|
||
from django.contrib.auth import get_user_model
|
||
from django.utils import timezone
|
||
from django.core.validators import MinValueValidator
|
||
from decimal import Decimal
|
||
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 = [
|
||
('direct', 'مستقیم'),
|
||
('indirect', 'غیرمستقیم'),
|
||
]
|
||
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='سایز کنتور')
|
||
meter_reading = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='عدد کنتور (متر مکعب)')
|
||
meter_charge = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='شارژ کنتور (متر مکعب)')
|
||
meter_charge_expiration_date = models.DateField(null=True, blank=True, verbose_name='تاریخ پایان اعتبار شارژ')
|
||
is_panel_sealed = models.BooleanField(default=False, verbose_name='پلمپ تابلو')
|
||
is_panel_cut = models.BooleanField(default=False, verbose_name='تابلو قطع')
|
||
is_disconnection_done = models.BooleanField(default=False, verbose_name='انجام عملیات قطع')
|
||
discharge_pipe_diameter = models.DecimalField(max_digits=10, decimal_places=4, 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.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(کیلووات ساعت) قدرت موتور')
|
||
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']
|
||
|
||
|