change on broker (organization type) - some changes on livestock & herd
This commit is contained in:
94
apps/herd/management/commands/import_ranchers.py
Normal file
94
apps/herd/management/commands/import_ranchers.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import pandas as pd
|
||||
from django.core.management.base import BaseCommand
|
||||
from apps.herd.models import Rancher
|
||||
from apps.herd.models import Herd
|
||||
from apps.authentication.models import Province, City, Organization
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Import Rancher and Herd data from Excel"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('excel_path', type=str)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
path = options['excel_path']
|
||||
df = pd.read_excel(path)
|
||||
records = df.to_dict(orient='records')
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f"{len(records)} records loaded."))
|
||||
|
||||
ranchers_to_create = []
|
||||
herds_to_create = []
|
||||
|
||||
province_cache = {p.id: p for p in Province.objects.all()}
|
||||
city_cache = {c.id: c for c in City.objects.all()}
|
||||
org_cache = {o.id: o for o in Organization.objects.all()}
|
||||
|
||||
for r in records:
|
||||
full_name = str(r.get("fullname") or "").strip()
|
||||
first_name = full_name.split(" ")[0] if full_name else ""
|
||||
last_name = " ".join(full_name.split(" ")[1:]) if len(full_name.split(" ")) > 1 else ""
|
||||
|
||||
# province = province_cache.get((Province.objects.get(name=r.get("province"))).id)
|
||||
province = Province.objects.get(id=1)
|
||||
city = City.objects.get(id=1)
|
||||
|
||||
rancher = Rancher(
|
||||
first_name=first_name,
|
||||
last_name=last_name,
|
||||
mobile=r.get("mobile"),
|
||||
national_code=r.get("national_id"),
|
||||
address="",
|
||||
province=province,
|
||||
city=city,
|
||||
without_herd=not bool(r.get("herd_code"))
|
||||
)
|
||||
ranchers_to_create.append(rancher)
|
||||
|
||||
# ذخیرهی دامداران
|
||||
Rancher.objects.bulk_create(ranchers_to_create, batch_size=10000)
|
||||
self.stdout.write(self.style.SUCCESS(f"✅ Created {len(ranchers_to_create)} ranchers."))
|
||||
|
||||
# بازیابی مجدد همهی دامداران برای نگاشت herd
|
||||
rancher_cache = {r.national_code: r for r in Rancher.objects.all()}
|
||||
|
||||
for r in records:
|
||||
if not r.get("herd_code"):
|
||||
print("not herd code")
|
||||
continue
|
||||
|
||||
province = Province.objects.get(id=1)
|
||||
city = City.objects.get(id=1)
|
||||
coop = Organization.objects.get(id=1)
|
||||
print(f"province {province}")
|
||||
print(f"city {city}")
|
||||
print(f"coop {coop}")
|
||||
|
||||
key = r.get("national_id")
|
||||
print(f'key {key}')
|
||||
rancher = Rancher.objects.get(national_code=key)
|
||||
print(f'ranchers {rancher}')
|
||||
if not rancher:
|
||||
print("not rancher")
|
||||
continue
|
||||
|
||||
herd = Herd(
|
||||
code=r.get("herd_code"),
|
||||
name=r.get("herd_name"),
|
||||
rancher=rancher,
|
||||
province=province,
|
||||
city=city,
|
||||
postal=r.get("postal_code"),
|
||||
institution=r.get("unit_id"),
|
||||
epidemiologic=r.get("epidemiological_code"),
|
||||
cooperative=coop,
|
||||
heavy_livestock_number=r.get("heavy_livestock") or 0,
|
||||
light_livestock_number=r.get("light_livestock") or 0,
|
||||
)
|
||||
print(herd)
|
||||
herds_to_create.append(herd)
|
||||
print(herds_to_create)
|
||||
|
||||
Herd.objects.bulk_create(herds_to_create, batch_size=10000)
|
||||
self.stdout.write(self.style.SUCCESS(f"✅ Created {len(herds_to_create)} herds."))
|
||||
@@ -151,7 +151,7 @@ class RancherViewSet(viewsets.ModelViewSet, DynamicSearchMixin):
|
||||
""" list of rancher herds """
|
||||
|
||||
rancher = self.get_object()
|
||||
queryset = rancher.herd.all() # get rancher herds
|
||||
queryset = rancher.herd.all().order_by('-modify_date') # get rancher herds
|
||||
|
||||
# paginate queryset
|
||||
page = self.paginate_queryset(queryset)
|
||||
|
||||
86
apps/livestock/management/commands/import_livestock.py
Normal file
86
apps/livestock/management/commands/import_livestock.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import pandas as pd
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils.dateparse import parse_datetime
|
||||
from apps.livestock.models import LiveStock, LiveStockType, LiveStockSpecies
|
||||
from apps.herd.models import Herd
|
||||
from apps.tag.models import Tag
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Import livestock data from Excel"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('excel_path', type=str)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
path = options['excel_path']
|
||||
df = pd.read_excel(path)
|
||||
records = df.to_dict(orient='records')
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f"{len(records)} records loaded."))
|
||||
|
||||
herd_cache = {h.code: h for h in Herd.objects.all()}
|
||||
type_cache = {t.name.strip(): t for t in LiveStockType.objects.all()}
|
||||
species_male = LiveStockSpecies.objects.filter(name__icontains='نر').first()
|
||||
species_female = LiveStockSpecies.objects.filter(name__icontains='ماده').first()
|
||||
|
||||
livestocks_to_create = []
|
||||
skipped = 0
|
||||
|
||||
for r in records:
|
||||
try:
|
||||
herd_code = str(r.get('herd_code')).strip()
|
||||
if not herd_code:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
herd = herd_cache.get(herd_code)
|
||||
if not herd:
|
||||
herd = Herd.objects.create(
|
||||
code=herd_code,
|
||||
name=f"گله {herd_code}",
|
||||
province_id=int(r.get('province_id')) if r.get('province_id') else None,
|
||||
city_id=int(r.get('city_id')) if r.get('city_id') else None,
|
||||
cooperative_id=int(r.get('cooperative_id')) if r.get('cooperative_id') else None,
|
||||
)
|
||||
herd_cache[herd_code] = herd
|
||||
|
||||
tag_code = r.get('national_id_livestock_code')
|
||||
tag = Tag.objects.filter(code=tag_code).first()
|
||||
if not tag:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
type_name = str(r.get('type')).strip()
|
||||
livestock_type = type_cache.get(type_name)
|
||||
if not livestock_type:
|
||||
skipped += 1
|
||||
continue
|
||||
|
||||
gender_str = str(r.get('gender')).strip()
|
||||
gender = 1 if gender_str == 'نر' else 2 if gender_str == 'ماده' else None
|
||||
species = species_male if gender == 1 else species_female
|
||||
|
||||
birthdate = parse_datetime(str(r.get('birth_day_gh'))) if r.get('birth_day_gh') else None
|
||||
weight_type = 'H' if type_name == 'گاو' else 'L'
|
||||
|
||||
livestocks_to_create.append(LiveStock(
|
||||
herd=herd,
|
||||
tag=tag,
|
||||
type=livestock_type,
|
||||
use_type=None,
|
||||
species=species,
|
||||
weight_type=weight_type,
|
||||
gender=gender,
|
||||
birthdate=birthdate
|
||||
))
|
||||
|
||||
except Exception as e:
|
||||
skipped += 1
|
||||
print(e)
|
||||
continue
|
||||
|
||||
LiveStock.objects.bulk_create(livestocks_to_create, batch_size=10000)
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f"✅ Created {len(livestocks_to_create)} records."))
|
||||
self.stdout.write(self.style.WARNING(f"⚠️ Skipped {skipped} records due to missing/invalid data."))
|
||||
@@ -1,9 +1,11 @@
|
||||
from rest_framework import viewsets
|
||||
from apps.livestock import models as livestock_models
|
||||
from apps.tag.web.api.v1.api import TagViewSet
|
||||
from . import serializers as livestock_serializers
|
||||
from rest_framework.exceptions import APIException
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from common.tools import CustomOperations
|
||||
from django.db import transaction
|
||||
from rest_framework import status
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0 on 2025-08-05 12:38
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pos_device', '0027_alter_deviceactivationcode_expires_at'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deviceactivationcode',
|
||||
name='expires_at',
|
||||
field=models.DateTimeField(default=datetime.datetime(2025, 8, 5, 16, 8, 12, 82964)),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,19 @@
|
||||
# Generated by Django 5.0 on 2025-08-05 12:40
|
||||
|
||||
import datetime
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pos_device', '0028_alter_deviceactivationcode_expires_at'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='deviceactivationcode',
|
||||
name='expires_at',
|
||||
field=models.DateTimeField(default=datetime.datetime(2025, 8, 5, 16, 10, 58, 428777)),
|
||||
),
|
||||
]
|
||||
17
apps/product/migrations/0066_remove_broker_organization.py
Normal file
17
apps/product/migrations/0066_remove_broker_organization.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0 on 2025-08-05 12:38
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('product', '0065_productstats_given_distribution_number'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='broker',
|
||||
name='organization',
|
||||
),
|
||||
]
|
||||
20
apps/product/migrations/0067_broker_organization_type.py
Normal file
20
apps/product/migrations/0067_broker_organization_type.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.0 on 2025-08-05 12:40
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('authentication', '0027_remove_organizationstats_total_buyers_and_more'),
|
||||
('product', '0066_remove_broker_organization'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='broker',
|
||||
name='organization_type',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_organization', to='authentication.organizationtype'),
|
||||
),
|
||||
]
|
||||
@@ -3,7 +3,7 @@ from simple_history.models import HistoricalRecords
|
||||
from django.db import models
|
||||
from apps.core.models import BaseModel
|
||||
from apps.authorization.models import UserRelations
|
||||
from apps.authentication.models import Organization
|
||||
from apps.authentication.models import OrganizationType, Organization
|
||||
from django.contrib.postgres.fields import ArrayField
|
||||
from apps.livestock.models import LiveStockType
|
||||
from datetime import datetime
|
||||
@@ -238,8 +238,8 @@ class Broker(BaseModel):
|
||||
related_name='product_broker',
|
||||
null=True
|
||||
)
|
||||
organization = models.ForeignKey(
|
||||
Organization,
|
||||
organization_type = models.ForeignKey(
|
||||
OrganizationType,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='product_organization',
|
||||
null=True
|
||||
|
||||
@@ -19,6 +19,11 @@ class TagSerializer(serializers.ModelSerializer):
|
||||
'organization',
|
||||
'status',
|
||||
]
|
||||
extra_kwargs = {
|
||||
'serial': {
|
||||
'required': False
|
||||
}
|
||||
}
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
""" update tag information """
|
||||
|
||||
@@ -48,6 +48,7 @@ pyOpenSSL
|
||||
pyparsing
|
||||
python-dateutil
|
||||
pytz
|
||||
pandas
|
||||
redis
|
||||
requests
|
||||
rsa==4.8
|
||||
|
||||
Reference in New Issue
Block a user