Advertisement
sak1b

create-bulk-target-latest

Mar 21st, 2021
1,184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.80 KB | None | 0 0
  1. import csv
  2. import io
  3. from collections import defaultdict, deque
  4. from csv import DictReader
  5.  
  6. import graphene
  7. from graphene.types import InputObjectType
  8. from django.core.exceptions import ValidationError
  9.  
  10. from ...core.mutations import ModelMutation, BaseMutation
  11. from ...core.types import Upload
  12. from ...core.types.common import TargetError
  13. from ....account.models import User
  14. from ....core.permissions import TargetPermissions
  15. from ....partner.models import Partner
  16. from ....target import models
  17. from ....target.error_codes import TargetErrorCode
  18. from dateutil import parser, relativedelta
  19. from datetime import datetime as dt
  20.  
  21. from ....target.models import Achievement, TargetUser, PartnerTargetSales
  22. from ...utils import check_if_attempted_from_valid_parent
  23.  
  24.  
  25. class CreateTargetInput(InputObjectType):
  26.     user = graphene.ID(description="ID of the Agent.", name="user", required=True)
  27.     month = graphene.Date(required=True, description="Target month(YYYY-MM)")
  28.     target_orders = graphene.Int(
  29.         description="Number of orders for the target.", required=True
  30.     )
  31.     target_sales = graphene.Int(
  32.         description="Amount of sales for the target.", required=True
  33.     )
  34.  
  35.  
  36. class CreateTarget(ModelMutation):
  37.     class Arguments:
  38.         input = CreateTargetInput(
  39.             required=True, description="Fields required to create a target."
  40.         )
  41.  
  42.     class Meta:
  43.         description = "Creates a new target of an agent."
  44.         model = models.Target
  45.         permissions = (TargetPermissions.MANAGE_TARGETS,)
  46.         error_type_class = TargetError
  47.         error_type_field = "target_errors"
  48.  
  49.     @classmethod
  50.     def clean_input(cls, info, instance, data):
  51.         user = cls.get_node_or_error(info, data["user"])
  52.         requestor = info.context.user
  53.         if requestor.groups.first().name in ["dco", "dcm", "cm"]:
  54.             check_if_attempted_from_valid_parent(requestor, user)
  55.  
  56.         cleaned_input = super().clean_input(info, instance, data)
  57.         if cleaned_input['target_orders'] < 1:
  58.             raise ValidationError(
  59.                 {
  60.                     "target_orders": ValidationError(
  61.                         "Target order should be positive number",
  62.                         code=TargetErrorCode.INVALID,
  63.                     )
  64.                 }
  65.             )
  66.  
  67.         if cleaned_input['target_sales'] < 1:
  68.             raise ValidationError(
  69.                 {
  70.                     "target_sales": ValidationError(
  71.                         "Target sales should be positive number",
  72.                         code=TargetErrorCode.INVALID,
  73.                     )
  74.                 }
  75.             )
  76.  
  77.         user = cleaned_input['user']
  78.         month = parser.parse(str(cleaned_input['month'])).replace(day=1)
  79.         cleaned_input['month'] = month
  80.         target = models.Target.objects.filter(user=user, month=month)
  81.  
  82.         if target:
  83.             raise ValidationError(
  84.                 {
  85.                     "month": ValidationError(
  86.                         "Target for specified month already exists.",
  87.                         code=TargetErrorCode.ALREADY_EXISTS,
  88.                     )
  89.                 }
  90.             )
  91.  
  92.         return cleaned_input
  93.  
  94.     @classmethod
  95.     def save(cls, info, instance, cleaned_input):
  96.         instance.save()
  97.         user = cleaned_input['user']
  98.         month = cleaned_input['month']
  99.         achievement = Achievement.objects.filter(user=user, month=month).first()
  100.         if achievement:
  101.             achievement.target = instance
  102.             achievement.save()
  103.  
  104.  
  105. class UpdateTargetInput(graphene.InputObjectType):
  106.     target_orders = graphene.Int(
  107.         description="Number of orders for the target.", required=False
  108.     )
  109.     target_sales = graphene.Int(
  110.         description="Amount of sales for the target.", required=False
  111.     )
  112.  
  113.  
  114. class UpdateTarget(ModelMutation):
  115.     class Arguments:
  116.         id = graphene.ID(required=True, description="ID of a target to update.")
  117.         input = UpdateTargetInput(
  118.             required=True, description="Fields required to update a target."
  119.         )
  120.  
  121.     class Meta:
  122.         description = "Updates a new target of an agent."
  123.         model = models.Target
  124.         permissions = (TargetPermissions.MANAGE_TARGETS,)
  125.         error_type_class = TargetError
  126.         error_type_field = "target_errors"
  127.  
  128.     @classmethod
  129.     def clean_input(cls, info, instance, data):
  130.         target_month = instance.month.strftime("%Y-%m")
  131.         current_month = dt.now().date().strftime("%Y-%m")
  132.         if target_month < current_month:
  133.             raise ValidationError(
  134.                 {
  135.                     "id": ValidationError(
  136.                         "This item can not be modified.",
  137.                         code=TargetErrorCode.INVALID
  138.                     )
  139.                 }
  140.             )
  141.         target_orders = data.get("target_orders")
  142.         target_sales = data.get("target_sales")
  143.  
  144.         if not target_sales and not target_orders:
  145.             raise ValidationError(
  146.                 {
  147.                     "target_sales": ValidationError(
  148.                         "Target sales can not be empty",
  149.                         code=TargetErrorCode.INVALID
  150.                     ),
  151.                     "target_orders": ValidationError(
  152.                         "Target orders can not be empty",
  153.                         code=TargetErrorCode.INVALID
  154.                     )
  155.                 }
  156.             )
  157.  
  158.         if target_orders < 1:
  159.             raise ValidationError(
  160.                 {
  161.                     "target_orders": ValidationError(
  162.                         "Target order should be positive number",
  163.                         code=TargetErrorCode.INVALID
  164.                     )
  165.                 }
  166.             )
  167.  
  168.         if target_sales < 1:
  169.             raise ValidationError(
  170.                 {
  171.                     "target_sales": ValidationError(
  172.                         "Target sales should be positive number",
  173.                         code=TargetErrorCode.INVALID,
  174.                     )
  175.                 }
  176.             )
  177.  
  178.         return super().clean_input(info, instance, data)
  179.  
  180.  
  181. class CreateTargetsInBulk(BaseMutation):
  182.     data1 = graphene.String()
  183.     graph = defaultdict(list)
  184.  
  185.     class Arguments:
  186.         file = Upload(
  187.             required=True,
  188.             description="A file.... later",
  189.         )
  190.         # file_tag = graphene.String("Tag name of the file.", required=True)
  191.  
  192.     class Meta:
  193.         description = "Upload file(csv) to create targets in bulk."
  194.         error_type_class = TargetError
  195.         error_type_field = "target_errors"
  196.         permissions = (TargetPermissions.MANAGE_TARGETS,)
  197.  
  198.     # @classmethod
  199.     # def clean_system_file(cls, instance, file_tag):
  200.     #     files = instance.documents.filter(file_tag=file_tag)
  201.     #     if files:
  202.     #         for file in files:
  203.     #             file.content_file.delete()
  204.     #         files.delete()
  205.     @classmethod
  206.     def get_parents_list(self, source):
  207.  
  208.         if len(self.graph) == 0:
  209.             all_users = User.objects.all()
  210.             for user in all_users:
  211.                 if user.parent_id:
  212.                     self.graph[user.id].append(user.parent_id)
  213.  
  214.         parents_list = []
  215.         visited = set()
  216.         queue = deque()
  217.  
  218.         visited.add(source)
  219.         queue.append(source)
  220.  
  221.         while queue:
  222.             s = queue.popleft()
  223.             for neighbour in self.graph[s]:
  224.                 if neighbour not in visited:
  225.                     parents_list.append(neighbour)
  226.                     visited.add(neighbour)
  227.                     queue.append(neighbour)
  228.  
  229.         return parents_list
  230.  
  231.     @classmethod
  232.     def perform_mutation(cls, _root, info, file):
  233.         # user = info.context.user
  234.         # image_data = info.context.FILES.get(image)
  235.         # validate_image_file(image_data, "image")
  236.         #
  237.         # cls.clean_system_file(user, file_tag)
  238.         # the_image_file = models.Document.objects.create(
  239.         #     content_file=image_data,
  240.         #     mimetype=image_data.content_type,
  241.         #     file_tag=file_tag
  242.         # )
  243.         # user.documents.add(the_image_file)
  244.  
  245.         print("\n\n--------------\n\n")
  246.         try:
  247.             csv_file = info.context.FILES.get(file)
  248.  
  249.             if not csv_file.name.endswith(".csv"):
  250.                 print('add exception here!')
  251.  
  252.             data_set = csv_file.read().decode("UTF-8")
  253.             io_string = io.StringIO(data_set)
  254.  
  255.             csv_reader = csv.reader(io_string, delimiter=',')
  256.             header = next(csv_reader)
  257.             no_of_columns = len(header)
  258.  
  259.             agents = {}
  260.             partners = {}
  261.  
  262.             all_agents = User.objects.filter(groups__name='agent')
  263.             all_partners = Partner.objects.all()
  264.  
  265.             for agent in all_agents:
  266.                 agents[agent.email] = agent
  267.  
  268.             for partner in all_partners:
  269.                 partners[partner.partner_id] = partner
  270.  
  271.             # print(agents)
  272.             # print(partners)
  273.  
  274.             target_user_list = []
  275.             partner_target_sales_list = []
  276.             raw_data = []
  277.  
  278.             for row in csv_reader:
  279.                 raw_data.append({'row': row, 'target_user_objects_list': []})
  280.  
  281.             # toDo 1: target_user bulk create
  282.             for item in raw_data:
  283.                 # print(row)
  284.                 email = item['row'][0]
  285.                 month = item['row'][1]
  286.                 agent = agents.get(email, None)
  287.  
  288.                 if agent is None:
  289.                     pass
  290.                     # riase exception here
  291.  
  292.                 target_user_item = TargetUser(
  293.                     user=agent,
  294.                     month=month
  295.                 )
  296.  
  297.                 target_user_list.append(target_user_item)
  298.                 item['target_user_objects_list'].append(target_user_item)
  299.  
  300.                 parents_list = cls.get_parents_list(agent.id)
  301.  
  302.                 for parent_id in parents_list:
  303.                     target_user_item = TargetUser(
  304.                         user_id=parent_id,
  305.                         month=month
  306.                     )
  307.                     target_user_list.append(target_user_item)
  308.                     item['target_user_objects_list'].append(target_user_item)
  309.  
  310.                 # target_user_list.append(target_user_item)
  311.                 item['target_obj'] = target_user_item
  312.  
  313.             TargetUser.objects.bulk_create(target_user_list)
  314.  
  315.             # toDo 2: partner_target_sales bulk create
  316.             for item in raw_data:
  317.                 target_user_objects_list = item['target_user_objects_list']
  318.                 for target_user_obj in target_user_objects_list:
  319.                     index = 2
  320.                     while index + 1 < no_of_columns:
  321.                         if len(item['row'][index]) == 0:
  322.                             index += 2
  323.                             continue
  324.  
  325.                         partner_id = item['row'][index]
  326.                         target_sales = item['row'][index + 1]
  327.  
  328.                         partner_obj = partners.get(partner_id, None)
  329.  
  330.                         if partner_obj is None:
  331.                             pass
  332.  
  333.                         partner_target_sales_item = PartnerTargetSales(
  334.                             target_user=target_user_obj,
  335.                             partner=partner_obj,
  336.                             target_sales=target_sales
  337.                         )
  338.  
  339.                         partner_target_sales_list.append(partner_target_sales_item)
  340.  
  341.                         index += 2
  342.  
  343.             PartnerTargetSales.objects.bulk_create(partner_target_sales_list)
  344.  
  345.         except Exception as e:
  346.             print(e)
  347.             print('Did not work')
  348.  
  349.         print("\n\n--------------\n\n")
  350.         data1 = "uploading functionality is working"
  351.  
  352.         return CreateTargetsInBulk(data1=data1)
  353.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement