Advertisement
sak1b

target-bulk-mutation-25-march.py

Mar 25th, 2021
575
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 19.74 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.             target_user_objects_cache = {}
  262.             partner_target_sales_cache = {}
  263.  
  264.             all_agents = User.objects.filter(groups__name='agent')
  265.             all_partners = Partner.objects.all()
  266.  
  267.             for agent in all_agents:
  268.                 agents[agent.email] = agent
  269.  
  270.             for partner in all_partners:
  271.                 partners[partner.partner_id] = partner
  272.  
  273.             # print(agents)
  274.             # print(partners)
  275.  
  276.             target_user_list = []
  277.             partner_target_sales_list_new = []
  278.             partner_target_sales_list_existing = []
  279.  
  280.             partner_target_sales_hash_new = {}
  281.             partner_target_sales_hash_existing = {}
  282.             raw_data = []
  283.  
  284.             for row in csv_reader:
  285.                 raw_data.append(
  286.                     {
  287.                         'row': row,
  288.                         'target_user_objects_list_new': [],
  289.                         'target_user_objects_list_existing': [],
  290.  
  291.                     }
  292.                 )
  293.  
  294.             # toDo 1: target_user bulk create
  295.             print("\n\n====================Zero phase==================================\n\n")
  296.             # tu = TargetUser.objects.all()
  297.             print("\n\n====================First phase==================================\n\n")
  298.             for item in raw_data:
  299.                 print('\n\n\n')
  300.                 print(item['row'][0])
  301.                 email = item['row'][0]
  302.                 month = item['row'][1] # toDo change date to 1
  303.                 agent = agents.get(email, None)
  304.  
  305.                 if agent is None:
  306.                     pass
  307.                     # riase exception here
  308.  
  309.                 # target_user_item = TargetUser(
  310.                 #     user=agent,
  311.                 #     month=month
  312.                 # )
  313.                 #
  314.                 # target_user_list.append(target_user_item)
  315.                 # item['target_user_objects_list_new'].append(target_user_item)
  316.  
  317.                 parents_list = cls.get_parents_list(agent.id)
  318.                 parents_list.append(agent.id) #to do cheeky fix
  319.  
  320.                 for parent_id in parents_list:
  321.                     hash_val = str(parent_id) + "-" + str(month)
  322.                     target_user_item = target_user_objects_cache.get(hash_val, None)
  323.                     if target_user_item is None:
  324.                         target_user_item = TargetUser.objects.filter(user_id=parent_id, month=month).first()
  325.  
  326.                         if target_user_item:
  327.                             item['target_user_objects_list_existing'].append(target_user_item)
  328.                         else:
  329.                             target_user_item = TargetUser(
  330.                                 user_id=parent_id,
  331.                                 month=month
  332.                             )
  333.                             target_user_list.append(target_user_item)
  334.                             item['target_user_objects_list_new'].append(target_user_item)
  335.  
  336.                         target_user_objects_cache[hash_val] = target_user_item # added in cache
  337.                     else:
  338.                         if target_user_item.id is None:
  339.                             item['target_user_objects_list_new'].append(target_user_item)
  340.                         else:
  341.                             item['target_user_objects_list_existing'].append(target_user_item)
  342.  
  343.                 # print(item['target_user_objects_list_new'])
  344.                 # print(item['target_user_objects_list_existing'])
  345.  
  346.             TargetUser.objects.bulk_create(target_user_list)
  347.  
  348.             # toDo 2: partner_target_sales bulk create
  349.             print("\n\n====================Second phase==================================\n\n")
  350.             pts = PartnerTargetSales.objects.all()
  351.             for item in pts:
  352.                 hash_val = str(item.target_user_id) + "-" + str(item.partner_id)
  353.                 item.target_sales = item.target_sales + 0
  354.                 partner_target_sales_cache[hash_val] = item
  355.                 # print(item.id)
  356.             print("\n\n====================Third phase==================================\n\n")
  357.  
  358.             for item in raw_data:
  359.                 target_user_objects_list_new = item['target_user_objects_list_new']
  360.                 target_user_objects_list_existing = item['target_user_objects_list_existing']
  361.                 # print(item['row'][0])
  362.                 # print('new: ')
  363.                 # print(target_user_objects_list_new)
  364.                 # print('existing: ')
  365.                 # print(target_user_objects_list_existing)
  366.                 if len(target_user_objects_list_new) > 0:
  367.                     for target_user_obj in target_user_objects_list_new:
  368.                         index = 2
  369.                         while index + 1 < no_of_columns:
  370.                             if len(item['row'][index]) == 0:
  371.                                 index += 2
  372.                                 continue
  373.  
  374.                             partner_id = item['row'][index]
  375.                             target_sales = int(item['row'][index + 1])
  376.  
  377.                             partner_obj = partners.get(partner_id, None)
  378.  
  379.                             if partner_obj is None:
  380.                                 pass
  381.  
  382.                             hash_val = str(target_user_obj.id) + "-" + str(partner_obj.id)
  383.                             partner_target_sales_item = partner_target_sales_cache.get(hash_val, None)
  384.  
  385.                             if partner_target_sales_item is None:
  386.                                 # partner_target_sales_item = PartnerTargetSales.objects.filter(
  387.                                 #     target_user=target_user_obj,
  388.                                 #     partner=partner_obj
  389.                                 # ).first()
  390.  
  391.                                 if partner_target_sales_item:
  392.                                     partner_target_sales_item.target_sales = partner_target_sales_item.target_sales \
  393.                                         + target_sales
  394.                                     partner_target_sales_hash_existing[hash_val] = partner_target_sales_item
  395.                                 else:
  396.                                     partner_target_sales_item = PartnerTargetSales(
  397.                                         target_user=target_user_obj,
  398.                                         partner=partner_obj,
  399.                                         target_sales=target_sales
  400.                                     )
  401.                                     partner_target_sales_hash_new[hash_val] = partner_target_sales_item
  402.                                 partner_target_sales_cache[str(target_user_obj.id) + "-" + str(partner_obj.id)] = \
  403.                                     partner_target_sales_item
  404.  
  405.                             else:
  406.                                 partner_target_sales_item.target_sales = partner_target_sales_item.target_sales \
  407.                                     + target_sales
  408.  
  409.                                 if partner_target_sales_item.id is None:
  410.                                     partner_target_sales_hash_new[hash_val] = partner_target_sales_item
  411.                                 else:
  412.                                     partner_target_sales_hash_existing[hash_val] = partner_target_sales_item
  413.  
  414.                             # partner_target_sales_list.append(partner_target_sales_item)
  415.  
  416.                             index += 2
  417.  
  418.                 if len(target_user_objects_list_existing) > 0:
  419.                     for target_user_obj in target_user_objects_list_existing:
  420.                         index = 2
  421.                         while index + 1 < no_of_columns:
  422.                             if len(item['row'][index]) == 0:
  423.                                 index += 2
  424.                                 continue
  425.  
  426.                             partner_id = item['row'][index]
  427.                             target_sales = int(item['row'][index + 1])
  428.  
  429.                             partner_obj = partners.get(partner_id, None)
  430.  
  431.                             if partner_obj is None:
  432.                                 pass
  433.  
  434.                             hash_val = str(target_user_obj.id) + "-" + str(partner_obj.id)
  435.                             partner_target_sales_item = partner_target_sales_cache.get(hash_val, None)
  436.  
  437.                             if partner_target_sales_item is None:
  438.                                 # partner_target_sales_item = PartnerTargetSales.objects.filter(
  439.                                 #     target_user=target_user_obj,
  440.                                 #     partner=partner_obj
  441.                                 # ).first()
  442.  
  443.                                 if partner_target_sales_item:
  444.                                     partner_target_sales_item.target_sales = partner_target_sales_item.target_sales \
  445.                                                                              + target_sales
  446.                                     partner_target_sales_hash_existing[hash_val] = partner_target_sales_item
  447.                                 else:
  448.                                     partner_target_sales_item = PartnerTargetSales(
  449.                                         target_user=target_user_obj,
  450.                                         partner=partner_obj,
  451.                                         target_sales=target_sales
  452.                                     )
  453.                                     partner_target_sales_hash_new[hash_val] = partner_target_sales_item
  454.  
  455.                                 partner_target_sales_cache[str(target_user_obj.id) + "-" + str(partner_obj.id)] = \
  456.                                     partner_target_sales_item
  457.  
  458.                             else:
  459.                                 partner_target_sales_item.target_sales = partner_target_sales_item.target_sales \
  460.                                                                          + target_sales
  461.  
  462.                                 if partner_target_sales_item.id is None:
  463.                                     partner_target_sales_hash_new[hash_val] = partner_target_sales_item
  464.                                 else:
  465.                                     partner_target_sales_hash_existing[hash_val] = partner_target_sales_item
  466.  
  467.                             # partner_target_sales_list.append(partner_target_sales_item)
  468.  
  469.                             index += 2
  470.             print('\n\nLast============================\n\n')
  471.             # print(partner_target_sales_list)
  472.             for key, val in partner_target_sales_hash_new.items():
  473.                 partner_target_sales_list_new.append(val)
  474.  
  475.             for key, val in partner_target_sales_hash_existing.items():
  476.                 partner_target_sales_list_existing.append(val)
  477.  
  478.             PartnerTargetSales.objects.bulk_create(partner_target_sales_list_new)
  479.             PartnerTargetSales.objects.bulk_update(partner_target_sales_list_existing, ['target_sales'])
  480.             data1 = "yyyyeeeeeeeeesssssssssssss"
  481.         except Exception as e:
  482.             print(e)
  483.             print('Did not work')
  484.             data1 = "Did not work"
  485.  
  486.         print("\n\n------DONE---------------------------------------------------------------------------------\n\n\n\n")
  487.  
  488.         return CreateTargetsInBulk(data1=data1)
  489.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement