from datetime import datetime, timedelta import jdatetime from dateutil.relativedelta import relativedelta from django.db.models import Count, Q from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope from rest_framework import viewsets from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.permissions import AllowAny from rest_framework.response import Response from LiveStock.LiveStoksAndPoultry.filterset import LiveStockFilterSet from LiveStock.LiveStoksAndPoultry.serializers import LiveStockSerializer, PosLiveStockSerializer from LiveStock.Rancher.helpers import update_one_rancher from LiveStock.helpers import build_query, CustomPagination, convert_to_miladi from LiveStock.models import LiveStock, Rancher, LiveStockProduct, LiveStockRolseProduct, Cooperative, Union, \ CooperativeProductsShare from authentication.models import SystemUserProfile from panel.models import POSMachine, PosMachineTransactions from panel.validate_headers import PosDeviceValidator class LiveStockViewSet(viewsets.ModelViewSet): queryset = LiveStock.objects.filter(trash=False).order_by('-birth_day_gh') permission_classes = [TokenHasReadWriteScope] serializer_class = LiveStockSerializer filterset_class = LiveStockFilterSet pagination_class = CustomPagination def list(self, request, *args, **kwargs): role = request.GET['role'] user = SystemUserProfile.objects.get(user=request.user, trash=False) type=request.GET.get('type') if type == 'archive': live_stocks=LiveStock.objects.filter(trash=True,archive=True).order_by('-birth_day_gh') else: live_stocks=LiveStock.objects.filter(trash=False).order_by('-birth_day_gh') if role == 'Cooperative': # todo:فعلا چون دامدار تکراری داریم نمیشه از طریق دامدار پیداکرد باید از طریف آدرس بریم cooperative = Cooperative.objects.get(user=user, trash=False) ranchers = Rancher.objects.filter(city=cooperative.address.city.name).values_list('herd_code', flat=True).distinct() live_stocks = live_stocks.filter(herd_code__in=ranchers) date1 = request.GET.get('date1') date2 = request.GET.get('date2') if date1 and date2: date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() live_stocks = live_stocks.filter(birth_day__gte=date1, birth_day__lte=date2) value = request.GET.get('value') search = request.GET.get('search') if value and search == 'filter': if search != 'undefined' and search.strip(): live_stocks = live_stocks.filter( build_query(self.filterset_class.Meta.fields, value) ) page = self.paginate_queryset(live_stocks) if page is not None: serializer = self.serializer_class(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.serializer_class(live_stocks, many=True) return Response(serializer.data, status=status.HTTP_200_OK) def create(self, request, *args, **kwargs): rancher = Rancher.objects.get(key=request.data['rancher_key']) request.data.pop('rancher_key') serializer = self.serializer_class(data=request.data) if serializer.is_valid(): live_stock = serializer.create(validated_data=request.data) live_stock.rancher = rancher live_stock.herd_code = rancher.herd_code live_stock.contractor_code = rancher.contractor_code live_stock.save() return Response({"result": "با موفقیت ثبت شد"}, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def update(self, request, pk=None, *args, **kwargs): user=SystemUserProfile.objects.filter(trash=False,user=request.user).first() filter_kwargs = {'key': request.data['live_stock_key']} if 'return_from_archive' in request.data.keys(): filter_kwargs['trash']=True filter_kwargs['archive']=True else: filter_kwargs['trash'] = False live_stock = LiveStock.objects.get(**filter_kwargs) live_stocks = LiveStock.objects.filter(herd_code=live_stock.herd_code, trash=False) rancher = Rancher.objects.get(herd_code=live_stock.herd_code) request.data.pop('live_stock_key') serializer = self.serializer_class(live_stock) if 'herd_code' in request.data.keys() and request.data['herd_code']: rancher.herd_code = request.data['herd_code'] rancher.save() live_stocks.update(herd_code=request.data['herd_code']) if 'return_from_archive' in request.data.keys(): live_stock.archive = False live_stock.trash = False live_stock.returner_from_archive=user.fullname live_stock.return_from_archive_date=datetime.now() live_stock.save() request.data.pop('return_from_archive') serializer.update(instance=live_stock, validated_data=request.data) return Response(serializer.data, status=status.HTTP_200_OK) def destroy(self, request, *args, **kwargs): user=SystemUserProfile.objects.filter(trash=False,user=request.user).first() live_stock = LiveStock.objects.get(key=request.GET['live_stock_key'], trash=False) if not live_stock.birth_day_gh: year, month, day = map(int, live_stock.birth_day.split('/')) live_stock.birth_day_gh = convert_to_miladi(year, month, day) live_stock.save() live_stock.trash=True live_stock.archive=True live_stock.archiver=user.fullname live_stock.archive_date=datetime.now() live_stock.age_of_archive=(datetime.now().date() - live_stock.birth_day_gh.date()).days live_stock.save() return Response({"result":"با موفقیت بایگانی شد."}, status=status.HTTP_200_OK) class PosLiveStockViewSet(viewsets.ModelViewSet): queryset = Rancher.objects.all() permission_classes = [AllowAny] serializer_class = PosLiveStockSerializer def get_transactions_month(self,natcode): import json transactions = PosMachineTransactions.objects.filter(natcode=natcode,paid=True,live_stock=True, trash=False) has_month_data = False last_month = None earliest_transaction_date = None for transaction in transactions: try: additional_data = json.loads(transaction.additional) if 'month' in additional_data and isinstance(additional_data['month'], list): has_month_data = True for month in additional_data['month']: if last_month is None or month > last_month: last_month = month except (json.JSONDecodeError, AttributeError): pass if hasattr(transaction, 'create_date'): created_date = transaction.create_date if earliest_transaction_date is None or created_date < earliest_transaction_date: earliest_transaction_date = created_date future_months = [] if not transactions: base_date = jdatetime.date.today().togregorian() - relativedelta(months=1) include_current = True elif has_month_data and last_month: year = int(str(last_month)[:4]) month = int(str(last_month)[4:6]) base_date = jdatetime.date(year, month, 1).togregorian() include_current = False else: if earliest_transaction_date: base_date = earliest_transaction_date else: base_date = jdatetime.date.today().togregorian() include_current = False start_offset = 0 if include_current else 1 for i in range(start_offset, start_offset + 6): future_date = base_date + relativedelta(months=i) jd_future = jdatetime.date.fromgregorian(date=future_date) future_months.append(int(f"{jd_future.year}{jd_future.month:02d}")) return future_months def list(self, request, *args, **kwargs): validator = PosDeviceValidator(request) validation_error = validator.validation_version() if validation_error: return validation_error validation_device = validator.validation_device() if not validation_device: return Response({"result": "نشست شما منقضی شده لطفا محدد وارد شوید!"}, status=status.HTTP_401_UNAUTHORIZED) pos = POSMachine.objects.get(pos_id=validation_device) if pos.cooperative is None: return Response({"result": "دستگاه شما برای مدیریت امور دام تعریف نشده است!"}, status=403) if int(validator.device_version) < 218: return Response( {"result": "لطفا جهت بروزرسانی نسخه دستگاه کارت خوان با پشتیبانی دستگاه ارتباط بگیرید!"}, status=status.HTTP_403_FORBIDDEN) if 'nath_id' in request.GET: ranchers = Rancher.objects.filter(national_id=request.GET['nath_id'], trash=False).first() if not ranchers: return Response({"result": "دامدار یافت نشد!"}, status=403) union = Union.objects.filter(trash=False).first() if 'product_key' in request.GET: product = LiveStockRolseProduct.objects.filter(key=request.GET['product_key'], trash=False).select_related( 'parent_product').only('parent_product__price', 'parent_product__name', 'parent_product__image', 'parent_product__light_wight', 'parent_product__heavy_wight', 'parent_product__shipping_price', 'parent_product__union_price', 'parent_product__cooperative_price').first() else: product = LiveStockRolseProduct.objects.filter(cooperative=pos.cooperative, trash=False).select_related( 'parent_product').only('parent_product__price', 'parent_product__name', 'parent_product__image', 'parent_product__light_wight', 'parent_product__heavy_wight', 'parent_product__shipping_price', 'parent_product__union_price', 'parent_product__cooperative_price').first() main_product = product.parent_product share = CooperativeProductsShare.objects.get(product=main_product, cooperative=pos.cooperative, trash=False) if ranchers.type == 'rural': heavy_rate= product.parent_product.heavy_wight light_rate= product.parent_product.light_wight else: heavy_rate= product.parent_product.heavy_wight_industrial light_rate= product.parent_product.light_wight_industrial month_list = self.get_transactions_month(request.GET['nath_id']) shares_list = [] if share.union_price > 0: shares_list.append({ "name":'union', "shaba":union.account, "price":share.union_price, }) if share.company_price > 0: shares_list.append({ "name":'company', "shaba":"IR170150000003100050545702", "price":share.company_price, }) if pos.cooperative.first_sub_cooperative_price > 0: shares_list.append({ "name":'first_sub_cooperative', "shaba":pos.cooperative.first_sub_cooperative_account, "price":pos.cooperative.first_sub_cooperative_price, }) if pos.cooperative.second_sub_cooperative_price > 0: shares_list.append({ "name":'second_sub_cooperative', "shaba":pos.cooperative.second_sub_cooperative_price, "price":pos.cooperative.second_sub_cooperative_price, }) dict1 = { "title": [ {"key": "نام و نام خانوادگی", "value": ranchers.fullname if ranchers.fullname else ranchers.user.fullname}, {"key": "موبایل", "value": ranchers.mobile}, {"key": "وزن کل خریداری شده", "value": str(ranchers.total_weight)} ], "key": ranchers.key, "herd_code": ranchers.herd_code, "national_id": ranchers.national_id, "fullname": ranchers.fullname if ranchers.fullname else ranchers.user.fullname, "type": ranchers.type, "mobile": ranchers.mobile, "allow_buy": ranchers.allow_buy, "more_than_inventory": True, "pos_owners": [], "allow_buy_message": " ", "real_light_livestock": ranchers.light_livestock, # تعداد تعیین شده دام توسط سامانه "real_heavy_livestock": ranchers.heavy_livestock, # تعداد تعیین شده دام توسط سامانه "real_dhi_livestock": 0, # تعداد تعیین شده دام توسط سامانه "weight_quota_heavy": ranchers.weight_quota_heavy, # سهمیه قابل دریافت "weight_quota_light": ranchers.weight_quota_light, # سهمیه قابل دریافت "weight_quota_dhi": ranchers.dhi_amount, # سهمیه قابل دریافت "heavy_rate": heavy_rate, # نرخ تبدیل جهت دریافت سهمیه "light_rate": light_rate, # نرخ تبدیل جهت دریافت سهمیه "dhi_rate": product.parent_product.heavy_wight_dha, # نرخ تبدیل جهت دریافت سهمیه "round_rate": 1, # مضرب رند کردن فروش "total_weight": ranchers.total_weight, # کل خرید دامدار ریم د دمش "product_total_weight": product.total_weight, "product_total_allocated_weight": product.total_allocated_weight, "product_total_remain_weight": product.total_remain_weight, "product_name": product.parent_product.name, "product_image": product.parent_product.image, "product_price": share.price, "cooperative_price_with_shipping": share.price + share.shipping_price + share.cooperative_price, "cooperative_price_without_shipping": share.price + share.cooperative_price, "union_price": share.union_price, "union_shaba": union.account, "shares": shares_list, "cooperative_shaba": pos.cooperative.account, "month_list": month_list, } return Response(dict1, status=status.HTTP_200_OK) return Response({"resut": "کد ملی وارد نشده است!"}, status=status.HTTP_403_FORBIDDEN) # class DashboardLiveStockViewSet(viewsets.ModelViewSet): # queryset = LiveStock.objects.filter(trash=False) # permission_classes = [TokenHasReadWriteScope] # serializer_class = LiveStockSerializer # filterset_class = LiveStockFilterSet # # def list(self, request, *args, **kwargs): # role = request.GET['role'] # user = SystemUserProfile.objects.get(user=request.user, trash=False) # if role == 'Cooperative': # # todo:فعلا چون دامدار تکراری داریم نمیشه از طریق دامدار پیداکرد باید از طریف آدرس بریم # cooperative = Cooperative.objects.get(user=user, trash=False) # ranchers = Rancher.objects.filter(city=cooperative.address.city.name).values_list('herd_code', # flat=True).distinct() # live_stocks = self.queryset.filter(herd_code__in=ranchers) # else: # live_stocks = self.queryset # date1 = request.GET.get('date1') # date2 = request.GET.get('date2') # if date1 and date2: # date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() # date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() # live_stocks = live_stocks.filter(birth_day__gte=date1, birth_day__lte=date2) # # value = request.GET.get('value') # search = request.GET.get('search') # if value and search == 'filter': # if search != 'undefined' and search.strip(): # live_stocks = live_stocks.filter( # build_query(self.filterset_class.Meta.fields, value) # ) # sheep = live_stocks.filter(type='گوسفند').count() # goat = live_stocks.filter(type='بز').count() # cow = live_stocks.filter(type='گاو').count() # horse = live_stocks.filter(type='اسب').count() # camel = live_stocks.filter(type='شتر').count() # light_livestock = live_stocks.filter(type__in=('بز', 'گوسفند')).count() # heavy_livestock = live_stocks.filter(type__in=('گاو', 'اسب', 'شتر')).count() # # dict1={ # 'live_stocks_count':live_stocks.count(), # "sheep":sheep, # "goat":goat, # "cow":cow, # "horse":horse, # "camel":camel, # "light_livestock":light_livestock, # "heavy_livestock":heavy_livestock, # # } # return Response(dict1, status=status.HTTP_200_OK) @api_view(["GET"]) @csrf_exempt @permission_classes([TokenHasReadWriteScope]) def dashboard_live_stock(request): role = request.GET['role'] user = SystemUserProfile.objects.get(user=request.user, trash=False) type = request.GET.get('type') if type == 'archive': live_stocks = LiveStock.objects.filter(trash=True, archive=True).only('type') else: live_stocks = LiveStock.objects.filter(trash=False).only('type') if role == 'Cooperative': cooperative = Cooperative.objects.get(user=user, trash=False) ranchers = Rancher.objects.filter(city=cooperative.address.city.name).values_list('herd_code', flat=True).distinct() live_stocks = live_stocks.filter(herd_code__in=ranchers) date1 = request.GET.get('date1') date2 = request.GET.get('date2') if date1 and date2: date1 = datetime.strptime(str(request.GET['date1']), '%Y-%m-%d').date() date2 = datetime.strptime(str(request.GET['date2']), '%Y-%m-%d').date() live_stocks = live_stocks.filter(birth_day__gte=date1, birth_day__lte=date2) value = request.GET.get('value') search = request.GET.get('search') if value and search == 'filter': if search != 'undefined' and search.strip(): live_stocks = live_stocks.filter( build_query(LiveStockFilterSet.Meta.fields, value) ) counts = live_stocks.values('type').annotate(total=Count('id')) count_dict = {item['type']: item['total'] for item in counts} light_livestock = count_dict.get('بز', 0) + count_dict.get('گوسفند', 0) heavy_livestock = count_dict.get('گاو', 0) + count_dict.get('اسب', 0) + count_dict.get('شتر', 0) result = { 'live_stocks_count': sum(count_dict.values()), "sheep": count_dict.get('گوسفند', 0), "goat": count_dict.get('بز', 0), "cow": count_dict.get('گاو', 0), "horse": count_dict.get('اسب', 0), "camel": count_dict.get('شتر', 0), "light_livestock": light_livestock, "heavy_livestock": heavy_livestock, } return Response(result, status=status.HTTP_200_OK) from datetime import date, timedelta def archive_live_stock(request): today = date.today() archive_msg = 'بایگانی خودکار به علت سن بالا' stocks_to_convert = LiveStock.objects.filter(trash=False, birth_day_gh__isnull=True) for stock in stocks_to_convert: try: year, month, day = map(int, stock.birth_day.split('/')) stock.birth_day_gh = convert_to_miladi(year, month, day) stock.save() except: continue archive_conditions = Q( Q(type__in=['بز', 'گوسفند'], gender='نر') & Q(birth_day_gh__lte=today - timedelta(days=425)) | Q(type__in=['بز', 'گوسفند'], gender='ماده') & Q(birth_day_gh__lte=today - timedelta(days=1825)) | Q(type='گاو') & Q(birth_day_gh__lte=today - timedelta(days=3285)) | Q(type='اسب') & Q(birth_day_gh__lte=today - timedelta(days=4380)) ) archived_count = LiveStock.objects.filter( trash=False, birth_day_gh__isnull=False ).filter(archive_conditions).update( trash=True, archive=True, archiver=archive_msg ) return HttpResponse('ok')