def clean(self): data = super().clean() errors = {} if self.project.closed_on: if self.project.closed_on < in_days(-14): errors["__all__"] = _( "This project has been closed too long ago.") else: self.add_warning(_("This project has been closed recently."), code="project-closed") if self.instance.invoice_service: self.add_warning(_("This entry is already part of an invoice."), code="part-of-invoice") if data.get("are_expenses") and not data.get("third_party_costs"): errors["third_party_costs"] = ( _("Providing third party costs is necessary for expenses."), ) if data.get("cost") and data.get("third_party_costs") is not None: if data["cost"] < data["third_party_costs"]: self.add_warning( _("Third party costs shouldn't be higher than costs."), code="third-party-costs-higher", ) if data.get("rendered_on") and data["rendered_on"] > in_days(7): errors["rendered_on"] = _("That's too far in the future.") raise_if_errors(errors) return data
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.offer and self.offer.project_id != self.project_id: errors["offer"] = _( "The offer must belong to the same project as the service.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.closed_on and self.closed_on > dt.date.today(): errors["closed_on"] = _( "Leave this empty if you do not want to close the project yet." ) raise_if_errors(errors)
def clean_fields(self, exclude): super().clean_fields(exclude) errors = {} if self.starts_on and self.ends_on: if self.ends_on < self.starts_on: errors["ends_on"] = _("Absences cannot end before they began.") if self.starts_on.year != self.ends_on.year: errors["ends_on"] = _("Start and end must be in the same year.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude): super().clean_fields(exclude) errors = {} if (self.hourly_labor_costs is None) != (self.green_hours_target is None): errors["__all__"] = _("Either provide both hourly labor costs" " and green hours target or none.") if self.date_from and self.date_until and self.date_from > self.date_until: errors["date_until"] = _( "Employments cannot end before they began.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude): super().clean_fields(exclude) errors = {} effort = (self.effort_type != "", self.effort_rate is not None) if any(effort) and not all(effort): if self.effort_type == "": errors["effort_type"] = _("Either fill in all fields or none.") if self.effort_rate is None: errors["effort_rate"] = _("Either fill in all fields or none.") if self.third_party_costs is not None and self.cost is None: errors["cost"] = _("Cannot be empty if third party costs is set.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude): super().clean_fields(exclude) errors = {} expense = (self.expense_currency != "", self.expense_cost is not None) if any(expense) and not all(expense): if self.expense_currency == "": errors["expense_currency"] = _( "Either fill in all fields or none.") if self.expense_cost is None: errors["expense_cost"] = _( "Either fill in all fields or none.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.weeks: no_mondays = [day for day in self.weeks if day.weekday() != 0] if no_mondays: errors["weeks"] = _( "Only mondays allowed, but field contains %s.") % ( ", ".join( local_date_format(day) for day in no_mondays), ) raise_if_errors(errors, exclude)
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.starts_at and self.ends_at: if self.starts_at.date() != self.ends_at.date(): errors["ends_at"] = _( "Breaks must start and end on the same day.") if self.starts_at >= self.ends_at: errors["ends_at"] = _( "Breaks should end later than they begin.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude): super().clean_fields(exclude) errors = {} try: number = phonenumbers.parse(self.phone_number, "CH") except phonenumbers.NumberParseException as exc: errors["phone_number"] = str(exc) else: if phonenumbers.is_valid_number(number): self.phone_number = phonenumbers.format_number( number, phonenumbers.PhoneNumberFormat.E164) else: errors["phone_number"] = _("Phone number invalid.") raise_if_errors(errors, exclude)
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.earliest_start_on.weekday() != 0: errors["earliest_start_on"] = _("Only mondays allowed.") if self.completion_requested_on.weekday() != 0: errors["completion_requested_on"] = _("Only mondays allowed.") if self.completion_requested_on <= self.earliest_start_on: errors["completion_requested_on"] = _( "Allow at least one week for the work please.") raise_if_errors(errors, exclude)
def clean(self): data = super().clean() errors = {} if data.get("day"): if data["day"] < logbook_lock() - dt.timedelta(days=7): errors["day"] = _("Breaks have to be logged promptly.") elif data["day"] > in_days(7): errors["day"] = _("That's too far in the future.") raise_if_errors(errors) if all(data.get(f) for f in ("day", "starts_at", "ends_at")): data["starts_at"] = timezone.make_aware( dt.datetime.combine(data["day"], data["starts_at"])) data["ends_at"] = timezone.make_aware( dt.datetime.combine(data["day"], data["ends_at"])) return data
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.status in (self.OFFERED, self.ACCEPTED, self.DECLINED): if not self.offered_on: errors.setdefault("offered_on", []).append( _("Offered on date missing for selected state.")) if not self.valid_until: errors.setdefault("valid_until", []).append( _("Valid until date missing for selected state.")) if self.offered_on and self.valid_until: if self.offered_on > self.valid_until: errors["valid_until"] = _( "Valid until date has to be after offered on date.") if self.status >= self.ACCEPTED and not self.closed_on: self.closed_on = dt.date.today() elif self.status < self.ACCEPTED and self.closed_on: self.closed_on = None raise_if_errors(errors)
def clean_fields(self, exclude=None): super().clean_fields(exclude=exclude) errors = {} if self.status >= self.SENT: if not self.invoiced_on or not self.due_on: errors["status"] = _( "Invoice and/or due date missing for selected state.") if self.status <= self.SENT and self.closed_on: errors["status"] = _( "Invalid status when closed on is already set.") if self.invoiced_on and self.due_on: if self.invoiced_on > self.due_on: errors["due_on"] = _("Due date has to be after invoice date.") if self.type in (self.SERVICES, self.DOWN_PAYMENT) and not self.project: errors["__all__"] = _( "Invoices of type %(type)s require a project.") % { "type": self.get_type_display() } if self.status == Invoice.CANCELED and not self.payment_notice: errors["payment_notice"] = _( "Please provide a short reason for the invoice cancellation.") if bool(self.service_period_from) != bool(self.service_period_until): errors["service_period_from"] = errors["service_period_until"] = _( "Either fill in both fields or none.") if (self.service_period_from and self.service_period_until and self.service_period_from > self.service_period_until): errors["service_period_until"] = _( "Until date has to be after from date.") raise_if_errors(errors, exclude)
def clean(self): data = super().clean() errors = {} if not data.get("service") and not data.get("service_title"): errors["service"] = _( "This field is required unless you create a new service.") elif data.get("service") and data.get("service_title"): errors["service"] = _( "Deselect the existing service if you want to create a new service." ) if self.project.closed_on: if self.project.is_logbook_locked: errors["__all__"] = _( "This project has been closed too long ago.") else: self.add_warning(_("This project has been closed recently."), code="project-closed") if self.instance.invoice_service: self.add_warning(_("This entry is already part of an invoice."), code="part-of-invoice") if data.get("service_title") and not is_title_specific( data["service_title"]): self.add_warning( _("This title seems awfully unspecific." " Please use specific titles for services."), code="unspecific-service", ) if (data.get("service_title") and self.request.user.features[FEATURES.GLASSFROG] and not data.get("service_role")): self.add_error("service_role", _("This field is required.")) if all(f in self.fields and data.get(f) for f in ["rendered_by", "rendered_on"]) and ( not self.instance.pk or ("rendered_on" in self.changed_data)): if data["rendered_by"].features[FEATURES.LATE_LOGGING]: # Fine pass elif data["rendered_on"] < logbook_lock(): errors["rendered_on"] = _( "Hours have to be logged in the same week.") elif data["rendered_on"] > in_days(7): errors["rendered_on"] = _("That's too far in the future.") if (all(data.get(f) for f in ["rendered_by", "rendered_on", "hours"]) and not self.instance.pk): msg = data["rendered_by"].take_a_break_warning( day=data["rendered_on"], add=data["hours"]) if msg: self.add_warning(msg, code="take-a-break") try: latest = LoggedHours.objects.filter( Q(rendered_by=self.request.user), ~Q(id=self.instance.id)).latest("pk") except LoggedHours.DoesNotExist: pass else: fields = [ "rendered_by", "rendered_on", "service", "hours", "description" ] for field in fields: if data.get(field) != getattr(latest, field): break else: self.add_warning(_("This seems to be a duplicate. Is it?"), code="maybe-duplicate") raise_if_errors(errors) return data