83 lines
3.4 KiB
Python
83 lines
3.4 KiB
Python
from django.core.management.base import BaseCommand, CommandError
|
|
from products.models import *
|
|
from django.db import transaction
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Manage serial code in batch'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument('--tenant-id', '-t', required=True, type=int)
|
|
parser.add_argument('--job', '-j', type=int)
|
|
parser.add_argument('--all', '-A', action="store_true", help="apply to all code")
|
|
parser.add_argument('--seq-range', "-r", help="code by seq range")
|
|
parser.add_argument('--code-file', "-f", help="code list from file")
|
|
parser.add_argument('--activate', "-a", action="store_true", help="activate code")
|
|
parser.add_argument('--deactivate', "-d", action="store_true", help="deactivate code")
|
|
parser.add_argument('--bind-product', "-b", type=int, help="bind to product by id")
|
|
parser.add_argument('--unbind-product', "-u", action="store_true", help="unbind product")
|
|
|
|
def handle(self, *args, **options):
|
|
if options.get('job'):
|
|
job = Job.objects.get(pk=options['job'])
|
|
else:
|
|
job = Job.objects.create(name='bind-batch.%d' % options.get('batch'))
|
|
try:
|
|
job.update('running', 0.0)
|
|
tenant = Tenant.objects.get(pk=options['tenant_id'])
|
|
|
|
query = self.build_query(options)
|
|
total = query.count()
|
|
done = 0
|
|
prod = None
|
|
if options.get("bind_product"):
|
|
prod = Product.objects.get(tenant=tenant, pk=options['bind_product'])
|
|
for batch_ids in self.iterate_batches(query, 10000):
|
|
uq = SerialCode.objects.filter(pk__in=batch_ids)
|
|
if options.get("activate"):
|
|
uq.update(is_active=True)
|
|
elif options.get("deactivate"):
|
|
uq.update(is_active=False)
|
|
elif options.get("unbind_product"):
|
|
uq.update(product=None)
|
|
elif options.get("bind_product"):
|
|
uq.update(product=prod)
|
|
|
|
transaction.commit()
|
|
done += len(batch_ids)
|
|
|
|
print("code batch op", done, total)
|
|
perc = done * 100.0 / total
|
|
job.update('running', perc)
|
|
|
|
job.update('done', 100.0)
|
|
except Exception as e:
|
|
job.update('error', message=str(e))
|
|
raise
|
|
|
|
def iterate_batches(self, query, batchsize):
|
|
total = query.count()
|
|
cur = 0
|
|
while cur < total:
|
|
yield [x.pk for x in query[cur : cur + batchsize]]
|
|
cur += batchsize
|
|
|
|
def build_query(self, options):
|
|
tenant = Tenant.objects.get(pk=options['tenant_id'])
|
|
query = SerialCode.objects.filter(tenant=tenant).order_by('pk')
|
|
if options.get("seq_range"):
|
|
begin, end = options['seq_range'].split(',', maxsplit=1)
|
|
query = query.filter(seq_num__gte=int(begin),
|
|
seq_num__lte=int(end))
|
|
elif options.get("code_file"):
|
|
codes = self.read_code_file(options['code_file'])
|
|
query = query.filter(code__in=codes)
|
|
elif options.get("all"):
|
|
pass
|
|
else:
|
|
raise Exception("Code not specified")
|
|
return query
|
|
|
|
def read_code_file(self, cf):
|
|
with open(cf, 'r') as f:
|
|
return [x for x in f.read().splitlines() if not x.strip().startswith('#')]
|