distribution of tags & tag batches

This commit is contained in:
2026-01-27 14:52:50 +03:30
parent da15cb5b99
commit 915b0bf5a1
8 changed files with 100 additions and 7 deletions

View File

@@ -4,3 +4,6 @@ from django.apps import AppConfig
class TagConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.tag'
def ready(self):
import apps.tag.signals.tag_distribution_signals # noqa

View File

@@ -0,0 +1,29 @@
# Generated by Django 5.0 on 2026-01-27 09:18
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tag', '0041_tagbatch_total_remaining_tags'),
]
operations = [
migrations.AddField(
model_name='tagdistribution',
name='parent',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='child', to='tag.tagdistribution'),
),
migrations.AddField(
model_name='tagdistribution',
name='remaining_number',
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name='tagdistribution',
name='total_tag_count',
field=models.IntegerField(default=0),
),
]

View File

@@ -91,6 +91,12 @@ class TagBatch(BaseModel):
class TagDistribution(BaseModel):
parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
related_name='child',
null=True
)
dist_identity = models.CharField(max_length=20, default="0", unique=True, null=True)
batch = models.ForeignKey(
TagBatch,
@@ -112,7 +118,9 @@ class TagDistribution(BaseModel):
null=True
)
species_code = models.IntegerField(default=0)
total_tag_count = models.IntegerField(default=0)
distributed_number = models.IntegerField(default=0)
remaining_number = models.IntegerField(default=0)
is_closed = models.BooleanField(default=False)
def __str__(self):

View File

@@ -17,7 +17,7 @@ class TagDistributionService:
service of distribute tags in organizations
"""
def create_distribution(self, org: Organization = None, data: dict = None):
def create_distribution_from_batch(self, org: Organization = None, data: dict = None):
"""
distribute tags with batch
"""
@@ -57,7 +57,8 @@ class TagDistributionService:
assigner_org=org,
assigned_org=assigned_org,
species_code=distribution.get('species_code'),
distributed_number=distribution.get('count'),
total_tag_count=distribution.get('count'),
remaining_number=distribution.get('count'),
dist_identity=generate_unique_code(f"{random.randint(1000, 9999)}"),
)
@@ -73,6 +74,7 @@ class TagDistributionService:
# create distribution batch
distributions_batch = TagDistributionBatch.objects.create(
parent=TagDistributionBatch.objects.get(id=data.get('parent')) if data.get('parent') else None,
assigner_org=org,
assigned_org=assigned_org,
total_tag_count=total_counted_tags,
@@ -83,7 +85,8 @@ class TagDistributionService:
return {'tag_distributions': distributions, 'distributions_batch': distributions_batch}
def edit_distribution(self, dist_batch: TagDistributionBatch = None, data: dict = None, org: Organization = None):
def edit_distribution_from_batch(self, dist_batch: TagDistributionBatch = None, data: dict = None,
org: Organization = None):
"""
edit record of distributed tags
"""
@@ -130,7 +133,8 @@ class TagDistributionService:
assigner_org=org,
assigned_org=assigned_org,
species_code=distribution.get('species_code'),
distributed_number=distribution.get('count'),
total_tag_count=distribution.get('count'),
remaining_number=distribution.get('count'),
dist_identity=generate_unique_code(f"{random.randint(1000, 9999)}"),
)
@@ -152,6 +156,12 @@ class TagDistributionService:
return {'tag_distributions': distributions, 'distributions_batch': dist_batch}
def create_distribution_from_distribution(self, org: Organization = None, tag_batch: TagDistributionBatch = None):
pass
def edit_distribution_from_distribution(self, org: Organization = None, tag_batch: TagDistributionBatch = None):
pass
def distribution_batch_main_dashboard(self, org: Organization, is_closed: str = 'false'):
"""
distribution batch main page dashboard detail

View File

@@ -62,6 +62,7 @@ class TagService:
species_code=data.get('species_code'),
serial_from=serial_start_range,
serial_to=serial_end_range,
total_remaining_tags=request_number if request_number > 0 else 1,
status='created',
)
@@ -104,6 +105,7 @@ class TagService:
batch.species_code = data.get('species_code')
batch.serial_from = serial_start_range
batch.serial_to = serial_end_range
batch.total_remaining_tags = request_number
batch.save(update_fields=['request_number', 'species_code', 'serial_from', 'serial_to'])
# recreate tags for batch

View File

View File

@@ -0,0 +1,41 @@
from django.db.models.aggregates import Count
from django.db.models.signals import post_save
from django.dispatch import receiver
from apps.tag.models import TagDistribution, TagDistributionBatch
@receiver(post_save, sender=TagDistribution)
def calculate_tag_batch_details(sender, instance: TagDistribution, **kwargs):
"""
calculate distribution & remaining tag count from batch
"""
distributions = TagDistribution.objects.filter(batch=instance.batch)
distributed_tags = distributions.aggregate(count=Count('tag'))['count']
instance.batch.total_distributed_tags = distributed_tags
instance.batch.total_remaining_tags = int(instance.batch.request_number) - distributed_tags
instance.batch.save(update_fields=['total_distributed_tags', 'total_remaining_tags'])
@receiver(post_save, sender=TagDistributionBatch)
def calculate_tag_distribution_detail(sender, instance: TagDistributionBatch, **kwargs):
"""
calculate distribution & remaining distributed tags
"""
if getattr(instance, 'flag', False):
return
tag_dist_batch = instance
if tag_dist_batch.parent:
tag_dist_batch.parent.total_distributed_tag_count += tag_dist_batch.total_tag_count
tag_dist_batch.parent.remaining_tag_count = tag_dist_batch.parent.total_tag_count - tag_dist_batch.total_tag_count
tag_dist_batch.parent.save(update_fields=['total_distributed_tag_count', 'remaining_tag_count'])
tag_dist_batch.remaining_tag_count = tag_dist_batch.total_tag_count
print(tag_dist_batch.remaining_tag_count)
instance.flag = True
tag_dist_batch.save(update_fields=['remaining_tag_count'])

View File

@@ -35,6 +35,7 @@ class TagViewSet(BaseViewSet, TagService, SoftDeleteMixin, DynamicSearchMixin, v
filter_backends = [SearchFilter]
search_fields = [
'serial',
'status',
'tag_code',
'organization__name',
'organization__type__key',
@@ -70,7 +71,6 @@ class TagViewSet(BaseViewSet, TagService, SoftDeleteMixin, DynamicSearchMixin, v
org = get_organization_by_user(request.user) # noqa
serial_start_range, serial_end_range = request.data.pop('serial_range') # serial_range is like [500, 550]
print(serial_start_range, serial_end_range)
data = request.data.copy()
# create tag & batch
@@ -428,7 +428,7 @@ class TagDistributionViewSet(
org = get_organization_by_user(request.user)
data = request.data.copy()
distribution_data = self.create_distribution(
distribution_data = self.create_distribution_from_batch(
org=org,
data=data
)
@@ -445,7 +445,7 @@ class TagDistributionViewSet(
data = request.data.copy()
dist_batch = tag_models.TagDistributionBatch.objects.get(id=pk)
distribution_data = self.edit_distribution(org=org, data=data, dist_batch=dist_batch)
distribution_data = self.edit_distribution_from_batch(org=org, data=data, dist_batch=dist_batch)
serializer = self.serializer_class(distribution_data.get('tag_distributions'), many=True)
return Response(serializer.data, status=status.HTTP_200_OK)