fix --> sync livestocks with table ExcelLivestocks

This commit is contained in:
2026-02-10 12:30:41 +03:30
parent 67fa1e23e7
commit 1e773ef53d
4 changed files with 191 additions and 22 deletions

View File

@@ -0,0 +1,144 @@
from datetime import datetime
import jdatetime
from django.core.management.base import BaseCommand
from django.db import transaction
from django.utils import timezone
from apps.herd.models import Herd
from apps.livestock.models import (
LiveStock,
LiveStockSpecies,
ExcelLiveStocks
)
BATCH_SIZE = 100
class Command(BaseCommand):
help = "Import livestock from ExcelLiveStocks into LiveStock using bulk_create"
def normalize_herd_code(self, value, length=10):
if value is None:
return None
return str(value).strip().zfill(length)
def parse_jalali_datetime(self, date_str: str):
if not date_str:
return None
year, month, day = map(int, date_str.split('/'))
# jalali → gregorian (date)
g_date = jdatetime.date(year, month, day).togregorian()
# date → naive datetime
naive_dt = datetime.combine(g_date, datetime.min.time())
# naive → aware (VERY IMPORTANT)
return timezone.make_aware(naive_dt)
def handle(self, *args, **options):
qs = ExcelLiveStocks.objects.all()
if not qs.exists():
self.stdout.write(self.style.WARNING("No records to import"))
return
# ---------- preload lookups ----------
herd_map = {
h.code: h
for h in Herd.objects.all()
}
species_map = {
s.name.strip(): s
for s in LiveStockSpecies.objects.all()
}
livestocks_to_create = []
processed_ids = []
created_count = 0
skipped = 0
self.stdout.write("Starting import...")
with transaction.atomic():
for row in qs.iterator(chunk_size=BATCH_SIZE):
herd = herd_map.get(self.normalize_herd_code(row.herd_code))
# print(self.normalize_herd_code(row.herd_code))
if not herd:
# print("herd")
skipped += 1
continue
# species cache / create
species_name = (row.species or "").strip()
if not species_name:
# print("species")
skipped += 1
continue
species = species_map.get(species_name)
if not species:
species = LiveStockSpecies.objects.create(
name=species_name
)
species_map[species_name] = species
livestocks_to_create.append(
LiveStock(
herd=herd,
species=species,
gender=self.map_gender(row.gender),
birthdate=self.parse_jalali_datetime(row.birthdate),
)
)
processed_ids.append(row.id)
if len(livestocks_to_create) >= BATCH_SIZE:
print("-----------------------------CREATE------------------------------------")
print(livestocks_to_create)
LiveStock.objects.bulk_create(
livestocks_to_create,
batch_size=BATCH_SIZE
)
created_count += len(livestocks_to_create)
livestocks_to_create.clear()
break
# flush remaining
if livestocks_to_create:
LiveStock.objects.bulk_create(
livestocks_to_create,
batch_size=BATCH_SIZE
)
created_count += len(livestocks_to_create)
# mark excel rows as archived
# ExcelLiveStocks.objects.filter(
# id__in=processed_ids
# ).update(archive=True)
self.stdout.write(self.style.SUCCESS(
f"Import finished. Created: {created_count}, Skipped: {skipped}"
))
@staticmethod
def map_gender(value):
if not value:
return 1
value = value.strip().lower()
if value in ['female', 'f', 'ماده']:
return 2
return 1
@staticmethod
def parse_date(value):
if not value:
return None
try:
return datetime.strptime(value, '%Y/%m/%d')
except Exception:
return None

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0 on 2026-02-10 08:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('livestock', '0019_excellivestocks'),
]
operations = [
migrations.AddField(
model_name='excellivestocks',
name='sync_status',
field=models.CharField(max_length=50, null=True),
),
]

View File

@@ -110,6 +110,7 @@ class ExcelLiveStocks(BaseModel):
birthdate = models.CharField(max_length=150, null=True)
gender = models.CharField(max_length=150, null=True)
agent_code = models.CharField(max_length=150, null=True)
sync_status = models.CharField(max_length=50, null=True)
class TemporaryLiveStock(BaseModel):