Esempio n. 1
0
 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
Esempio n. 2
0
 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)
Esempio n. 3
0
 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)
Esempio n. 4
0
 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)
Esempio n. 5
0
 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)
Esempio n. 6
0
 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)
Esempio n. 7
0
 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)
Esempio n. 8
0
    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)
Esempio n. 9
0
    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)
Esempio n. 10
0
 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)
Esempio n. 11
0
    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)
Esempio n. 12
0
    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
Esempio n. 13
0
    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)
Esempio n. 14
0
    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)
Esempio n. 15
0
    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