def update_helper_result_table(competition_id, update=False, participant_id=None): # Delete duplicate HelperResults if any. cursor = connection.cursor() cursor.execute("Select participant_id, count(*) from results_helperresults where competition_id=%s group by participant_id having count(*)>1", [competition_id]) for participant_id, _ in cursor.fetchall(): HelperResults.objects.filter(competition_id=competition_id, participant_id=participant_id)[0].delete() # END Delete duplicate competition = Competition.objects.get(id=competition_id) participants = Participant.objects.filter(is_participating=True).order_by('distance', 'registration_dt') if competition.is_individual: participants = participants.filter(competition=competition) else: participants = participants.filter(competition_id__in=competition.get_ids()) if not update: participants = participants.extra( where=[ "(Select hr1.calculated_total from results_helperresults hr1 where hr1.participant_id=registration_participant.id and hr1.competition_id = %s) is null" ], params=[competition_id, ],) if participant_id: participants = participants.filter(id=participant_id) if participants: class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) competition_class.create_helper_results(participants)
def post(self, request, *args, **kwargs): application = Application.objects.get(code=kwargs.get('slug')) discount_code = request.POST.get("discount_code", "") ret = {"fee": None, "insurance": None} if discount_code: try: discount_code = DiscountCode.objects.get(code=discount_code, campaign_id__competition_id=application.competition_id) _class = load_class(discount_code.campaign.discount_kind) discount = _class(application=application) usage_times = discount.get_usage_count() if discount_code.usage_times_left and discount_code.usage_times_left - usage_times >= 0 and discount_code.is_active: price = discount.get_final_price_for_application() if isinstance(price, float): ret['fee'] = {"new_total": price} application.discount_code = discount_code application.save() else: ret["error"] = price if not discount_code.usage_times_left or discount_code.usage_times_left-usage_times < 0: ret["error"] = _("Code already used for this competition") except: ret["error"] = _("Entered code is invalid") return JsonResponse(ret)
def filter_queryset(self, term, queryset=None, context=None): if queryset is None: queryset = self.get_queryset() distance_id = gender = bday = None if context: competition_id, distance_id, gender, bday = context.split("~~~") else: # Something wrong. We shouldn't show any numbers competition_id = -1 group = None if distance_id: distance = Distance.objects.get(id=distance_id) class_ = load_class(distance.competition.processing_class) processing_class = class_(distance.competition.id) group = processing_class.get_group_for_number_search(distance.id, gender, bday) queryset = queryset.filter(participant_slug='') if competition_id: competition = Competition.objects.get(id=competition_id) queryset = queryset.filter(distance__competition_id__in=competition.get_ids()) if distance_id: queryset = queryset.filter(distance_id=distance_id) if group: queryset = queryset.filter(group=group) if term == '': return queryset else: return super().filter_queryset(term, queryset)
def fetch_results(_id): url_data = UrlSync.objects.get(id=_id) processed_line = url_data.current_line class_ = load_class(url_data.competition.processing_class) processing_class = class_(url_data.competition.id) try: resp = requests.get(url_data.url) if resp.status_code != 200: return buf = StringIO(resp.text) file_lines = tuple(buf.readlines()) lines_to_process = file_lines[processed_line:] for line in lines_to_process: print(line) if len(line.strip()) == 0: print('empty line') continue number, time_text = line.strip().split(',') if number == '0': print('skipping 0 number') continue scan, created = ChipScan.objects.get_or_create( competition=url_data.competition, nr_text=number, time_text=time_text, url_sync=url_data) scan.time = time_text try: scan.nr = Number.objects.get( competition_id__in=url_data.competition.get_ids(), number=number, group='') except: print('number not found') continue finally: scan.save() process_chip_result.delay(scan.id) # processing_class.process_chip_result(scan.id) url_data.current_line = len(file_lines) url_data.save() # TODO: This should be removed after process review processing_class.recalculate_all_standings() send_smses() except: error = traceback.format_exc() Log.objects.create(content_object=url_data, action="Error processing file", params={ 'error': error, }) raise Exception('Error processing external chip file')
def recalculate_standing_for_result(competition_id, _id): competition = Competition.objects.get(id=competition_id) result = Result.objects.get(id=_id) class_ = load_class(competition.processing_class) processing_class = class_(competition.id) processing_class.recalculate_standing_for_result(result)
def set_final_price(self): if self.discount_code: _class = load_class(self.discount_code.campaign.discount_kind) discount = _class(application=self) price = discount.get_final_price_for_application() self.final_price = price + float(self.donation) else: self.final_price = float(self.total_entry_fee) + float(self.total_insurance_fee) + float(self.donation)
def process_chip_result(_id): scan = ChipScan.objects.select_related('competition').get(id=_id) class_ = load_class(scan.competition.processing_class) processing_class = class_(scan.competition.id) if not scan.is_processed: if scan.competition.processing_class: processing_class.process_chip_result(scan.id)
def result_process(competition_id, action, user_id): competition = Competition.objects.get(id=competition_id) class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) if action == 'process_unprocessed': for chip in competition.chipscan_set.filter(is_processed=False).order_by('time'): competition_class.process_chip_result(chip.id) return True return False
def sitetrees_build(lang): items = [] for competition in Competition.objects.filter(is_in_menu=True): children = [] if competition.processing_class: _class = load_class(competition.processing_class) processing = _class(competition=competition) items.append(processing.build_menu(lang)) else: items.append(item(str(competition), '#', url_as_pattern=False, children=children)) return tree('dynamic_competition', items=items),
def result_process(competition_id, action, user_id): competition = Competition.objects.get(id=competition_id) class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) if action == 'process_unprocessed': for chip in competition.chipscan_set.filter( is_processed=False).order_by('time'): competition_class.process_chip_result(chip.id) return True return False
def sitetrees_build(): activate("lv") items = [] for competition in Competition.objects.filter(is_in_menu=True): children = [] if competition.processing_class: _class = load_class(competition.processing_class) processing = _class(competition=competition) items.append(processing.build_manager_menu()) else: items.append(item(str(competition), '#', url_as_pattern=False, children=children, access_loggedin=True)) return (tree('dynamic_competition_manager', items=items),)
def get(self, *args, **kwargs): self.object = self.get_object() if self.object.competition.processing_class: _class = load_class(self.object.competition.processing_class) else: raise Http404 processing_class = _class(self.object.competition_id) file_obj = processing_class.number_pdf(participant_id=self.object.id) response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=%s.pdf' % self.object.slug response.write(file_obj.getvalue()) file_obj.close() return response
def fetch_results(_id): url_data = UrlSync.objects.get(id=_id) processed_line = url_data.current_line class_ = load_class(url_data.competition.processing_class) processing_class = class_(url_data.competition.id) try: resp = requests.get(url_data.url) if resp.status_code != 200: return buf = StringIO(resp.text) file_lines = tuple(buf.readlines()) lines_to_process = file_lines[processed_line:] for line in lines_to_process: print(line) if len(line.strip()) == 0: print('empty line') continue number, time_text = line.strip().split(',') if number == '0': print('skipping 0 number') continue scan, created = ChipScan.objects.get_or_create(competition=url_data.competition, nr_text=number, time_text=time_text, url_sync=url_data) scan.time = time_text try: scan.nr = Number.objects.get(competition_id__in=url_data.competition.get_ids(), number=number, group='') except: print('number not found') continue finally: scan.save() process_chip_result.delay(scan.id) # processing_class.process_chip_result(scan.id) url_data.current_line = len(file_lines) url_data.save() # TODO: This should be removed after process review processing_class.recalculate_all_standings() send_smses() except: error = traceback.format_exc() Log.objects.create(content_object=url_data, action="Error processing file", params={ 'error': error, }) raise Exception('Error processing external chip file')
def sitetrees_build(lang): items = [] for competition in Competition.objects.filter(is_in_menu=True): children = [] if competition.processing_class: _class = load_class(competition.processing_class) processing = _class(competition=competition) items.append(processing.build_menu(lang)) else: items.append( item(str(competition), '#', url_as_pattern=False, children=children)) return tree('dynamic_competition', items=items),
def match_participant_to_applied(participant): results = participant.result_set.all() for result in results: ma = MemberApplication.objects.filter(competition=result.competition, participant=None, member__slug=participant.slug) if ma: ma1 = ma.get() ma1.participant = participant ma1.save() participant.team = ma1.member.team participant.save() # Recalculate points class_ = load_class(result.competition.processing_class) _competition_class = class_(result.competition.id) _competition_class.recalculate_team_result(team=ma1.member.team)
def update_results_for_result(result): """ Full result recalculation in case points have changed for participant. """ class_ = load_class(result.competition.processing_class) competition_class = class_(competition=result.competition) updated = result.set_all() if updated: print('points have been updated.') result.save() competition_class.assign_result_place() competition_class.recalculate_standing_for_result(result) competition_class.assign_standing_places() if result.participant.team: competition_class.recalculate_team_result(team=result.participant.team)
def update_results_for_result(result): """ Full result recalculation in case points have changed for participant. """ class_ = load_class(result.competition.processing_class) competition_class = class_(competition=result.competition) updated = result.set_all() if updated: print('points have been updated.') result.save() competition_class.assign_result_place() competition_class.recalculate_standing_for_result(result) competition_class.assign_standing_places() if result.participant.team: competition_class.recalculate_team_result( team=result.participant.team)
def merge_standings(competition_id): """ Function searches for double created standings in provided competition. Such cases could appear if user had grammar error in his name and is fixed after standing has been created. This function is invoked from Participant model on save method if participant slug has been changed. :param competition_id: competition id that should be searched and merged :return: Nothing is being returned """ competition = Competition.objects.get(id=competition_id) doubles = competition.sebstandings_set.order_by( 'distance', 'participant_slug').values('distance', 'participant_slug').annotate( count=Count('participant_slug')).filter(count__gt=1) if not doubles: return if competition.processing_class: class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) for double in doubles: print(double) standings = list( competition.sebstandings_set.filter( distance_id=double.get('distance'), participant_slug=double.get('participant_slug')).order_by( '-distance_total')) standing = standings.pop(0) for st in standings: for _ in range(1, 8): if getattr(st, "distance_points%s" % _) > getattr( standing, "distance_points%s" % _): setattr(standing, "distance_points%s" % _, getattr(st, "distance_points%s" % _)) setattr(standing, "group_points%s" % _, getattr(st, "group_points%s" % _)) for result in st.results: result.standings_object = standing result.save() st.delete() if competition.processing_class: competition_class.recalculate_standing_points(standing) standing.save()
def update_helper_result_table(competition_id, update=False, participant_id=None): # Delete duplicate HelperResults if any. cursor = connection.cursor() cursor.execute( "Select participant_id, count(*) from results_helperresults where competition_id=%s group by participant_id having count(*)>1", [competition_id]) for participant_id, _ in cursor.fetchall(): HelperResults.objects.filter( competition_id=competition_id, participant_id=participant_id)[0].delete() # END Delete duplicate competition = Competition.objects.get(id=competition_id) participants = Participant.objects.filter(is_participating=True).order_by( 'distance', 'registration_dt') if competition.is_individual: participants = participants.filter(competition=competition) else: participants = participants.filter( competition_id__in=competition.get_ids()) if not update: participants = participants.extra( where=[ "(Select hr1.calculated_total from results_helperresults hr1 where hr1.participant_id=registration_participant.id and hr1.competition_id = %s) is null" ], params=[ competition_id, ], ) if participant_id: participants = participants.filter(id=participant_id) if participants: class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) competition_class.create_helper_results(participants)
def get(self, *args, **kwargs): self.object = self.get_object() if not self.object.participant.is_shown_public: raise Http404("Anonymous participant cannot get diploma.") if self.object.competition.processing_class: _class = load_class(self.object.competition.processing_class) else: raise Http404 try: processing_class = _class(self.object.competition_id) file_obj = processing_class.generate_diploma(self.object) except: raise Http404 response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=%s.pdf' % self.object.participant.slug response.write(file_obj.read()) file_obj.close() return response
def __init__(self, competition=None, competition_id=None): activate('lv') if not competition and not competition_id: raise Exception('Expected at least one variable') if not competition: self.competition = Competition.objects.get(id=competition_id) else: self.competition = competition if self.competition.level == 2: self.primary_competition = self.competition.parent else: self.primary_competition = self.competition self.output = BytesIO() self.doc = SimpleDocTemplate(self.output, pagesize=A4, topMargin=0.2 * inch, bottomMargin=0.8 * inch, leftMargin=0.2 * inch, rightMargin=0.2 * inch, showBoundary=0) class_ = load_class(self.competition.processing_class) self.processing_class = class_(self.competition.id) self.elements = []
def get(self, *args, **kwargs): self.object = self.get_object() if not self.object.participant.is_shown_public: raise Http404("Anonymous participant cannot get diploma.") if self.object.competition.processing_class: _class = load_class(self.object.competition.processing_class) else: raise Http404 try: processing_class = _class(self.object.competition_id) file_obj = processing_class.generate_diploma(self.object) except: raise Http404 response = HttpResponse(content_type='application/pdf') response[ 'Content-Disposition'] = 'attachment; filename=%s.pdf' % self.object.participant.slug response.write(file_obj.read()) file_obj.close() return response
def generate_thumbnails(pk, field, model_class=None): model = load_class(model_class) instance = model._default_manager.get(pk=pk) fieldfile = getattr(instance, field) # optimize file call(["/usr/bin/jpegoptim", fieldfile.path]) generate_all_aliases(fieldfile, include_global=True) try: if model.__name__ == 'Photo': instance.is_processed = True instance.save() album = instance.album if not album.photo_set.filter(is_processed=False).count(): album.is_processed = True album.save() except: pass
def merge_standings(competition_id): """ Function searches for double created standings in provided competition. Such cases could appear if user had grammar error in his name and is fixed after standing has been created. This function is invoked from Participant model on save method if participant slug has been changed. :param competition_id: competition id that should be searched and merged :return: Nothing is being returned """ competition = Competition.objects.get(id=competition_id) doubles = competition.sebstandings_set.order_by('distance', 'participant_slug').values('distance', 'participant_slug').annotate(count=Count('participant_slug')).filter(count__gt=1) if not doubles: return if competition.processing_class: class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) for double in doubles: print(double) standings = list(competition.sebstandings_set.filter(distance_id=double.get('distance'), participant_slug=double.get('participant_slug')).order_by('-distance_total')) standing = standings.pop(0) for st in standings: for _ in range(1, 8): if getattr(st, "distance_points%s" % _) > getattr(standing, "distance_points%s" % _): setattr(standing, "distance_points%s" % _, getattr(st, "distance_points%s" % _)) setattr(standing, "group_points%s" % _, getattr(st, "group_points%s" % _)) for result in st.results: result.standings_object = standing result.save() st.delete() if competition.processing_class: competition_class.recalculate_standing_points(standing) standing.save()
def recalculate_all_points(competition_id): competition = Competition.objects.get(id=competition_id) class_ = load_class(competition.processing_class) competition_class = class_(competition=competition) competition_class.recalculate_all_points()
def get_competition_class(self): if not self._competition_class: class_ = load_class(self.competition.processing_class) self._competition_class = class_(self.competition.id) return self._competition_class
def __init__(self, *args, **kwargs): self.participants = kwargs.pop('participants', None) super(ApplicationPayUpdateForm, self).__init__(*args, **kwargs) insured_participants = self.participants.exclude(insurance=None) if insured_participants: self.fields['accept_insurance'].required = True insurance_company = insured_participants[ 0].insurance.insurance_company terms_doc = "<a href='%s' target='_blank'>%s</a>" % ( insurance_company.terms_doc.url, _("Regulation")) if insurance_company.terms_doc else "" self.fields['accept_insurance'].label = mark_safe( "%s %s" % (insurance_company.term, terms_doc)) else: self.fields['accept_insurance'].widget = forms.HiddenInput() now = timezone.now() competition = self.instance.competition checkboxes = ( 'accept_terms', 'accept_inform_participants', 'accept_insurance', ) if competition.processing_class: _class = load_class(competition.processing_class) processing = _class(competition=competition) if hasattr(processing, 'payment_additional_checkboxes'): for key, field in processing.payment_additional_checkboxes( application=self.instance): self.fields[key] = field checkboxes += (key, ) payments = competition.activepaymentchannel_set.filter( from_date__lte=now, till_date__gte=now).select_related('payment_channel') # If user have already requested bill, then we are not showing possibility to request one more. if self.instance.invoice: payments = payments.filter(payment_channel__is_bill=False) if self.instance.final_price == 0: self.fields['payment_type'].required = False self.fields['payment_type'].widget = forms.HiddenInput() else: self.fields['payment_type'].choices = [(obj.id, obj) for obj in payments] if self.instance.discount_code: self.initial['discount_code'] = self.instance.discount_code.code self.fields['donation'].required = False self.helper = FormHelper() self.helper.form_tag = False self.helper.layout = Layout( *checkboxes, Div( Div(Div( Field("discount_code", css_class= "input-field if--50 if--dark js-placeholder-up"), ), css_class= "input-wrap w100 bottom-margin--15 col-s-24 col-m-12 col-l-12 col-xl-12" ), css_class="input-wrap w100 bottom-margin--15", ), Div(Div(css_class="w100 bottom-margin--30", ), Div(Div( HTML(_("Payment method")) if self.instance.final_price > 0 else HTML(""), css_class="fs14 fw700 uppercase w100 bottom-margin--30"), Div(Div(Field('payment_type', wrapper_class="row row--gutters-20"), css_class="w100"), css_class="input-wrap w100"), css_class="inner no-padding--560"), css_class="w100 border-top"), Div( Div( # company_name Div(Div(Field( "company_name", css_class= "input-field if--50 if--dark js-placeholder-up", ), css_class="input-wrap w100 bottom-margin--15"), css_class="col-xl-8 col-m-12 col-s-24"), # company_vat Div(Div( Field("company_vat", css_class= "input-field if--50 if--dark js-placeholder-up"), css_class="input-wrap w100 bottom-margin--15"), css_class="col-xl-8 col-m-12 col-s-24"), # company_regnr Div(Div( Field("company_regnr", css_class= "input-field if--50 if--dark js-placeholder-up"), css_class="input-wrap w100 bottom-margin--15"), css_class="col-xl-8 col-m-12 col-s-24"), # company_address Div(Div( Field("company_address", css_class= "input-field if--50 if--dark js-placeholder-up"), css_class="input-wrap w100 bottom-margin--15"), css_class="col-xl-8 col-m-12 col-s-24"), # company_juridical_address Div(Div( Field("company_juridical_address", css_class= "input-field if--50 if--dark js-placeholder-up"), css_class="input-wrap w100 bottom-margin--15"), css_class="col-xl-8 col-m-12 col-s-24"), 'invoice_show_names', css_class=""), css_class="invoice_fields"))
def save(self, *args, **kwargs): prev_participant = None if self.pk: prev_participant = Participant.objects.get(id=self.pk) self.full_name = '%s %s' % (self.first_name, self.last_name) # Full name always should be based on first_name and last_name fields self.team_name_slug = slugify(self.team_name.replace(' ', '')) # In case first name, last name or birthday is changed, then slug changes as well. old_slug = self.slug self.set_slug() if old_slug != self.slug and self.is_participating: Log.objects.create(content_object=self, action="Changed SLUG", message="Changing on number model", params={'old_slug':old_slug, 'new_slug': self.slug}) self.numbers(slug=old_slug).update(participant_slug=self.slug) # We update number slugs to match new slug if self.team: team = self.team self.team = None # Remove connection to existing team member. # Because of slug change connection to team is disconnected. # After disconnection team points are recalculated on every stage team have participated. try: member = team.member_set.get(slug=old_slug) for appl in member.memberapplication_set.all(): class_ = load_class(appl.competition.processing_class) processing_class = class_(competition=appl.competition) processing_class.recalculate_team_result(team=team) appl.participant = None appl.participant_unpaid = None appl.participant_potential = None appl.save() except: pass sebs = self.primary_sebstandings_set.filter(competition_id__in=self.competition.get_ids()) if sebs: sebs.update(participant_slug=self.slug) # Check if there are double standings that should be merged from velo.results.tasks import merge_standings merge_standings.delay(self.competition.parent_id if self.competition.level == 2 else self.competition_id) self.set_group() if not self.primary_number and self.is_participating: numbers = self.numbers().order_by('-number') if numbers: self.primary_number = numbers[0] if not self.registration_dt: self.registration_dt = timezone.now() # Recalculate totals. # TODO: This should be done when creating payment, not on any save. recalculate_participant(self, commit=False) obj = super(Participant, self).save(*args, **kwargs) if not self.code_short and self.id: hashids = Hashids(salt=settings.SECRET_KEY, min_length=7, alphabet=settings.HASH_ALPHABET) self.code_short = hashids.encode(self.id) self.save() if self.is_participating and (not prev_participant or not prev_participant.is_participating): from velo.results.tasks import master_update_helper_result_table master_update_helper_result_table.delay(participant_id=self.id) if old_slug != self.slug and self.is_participating: from velo.team.utils import match_participant_to_applied match_participant_to_applied(self) return obj