예제 #1
0
 def _send_mail(self, subject, ctx):
     # Don't go to the work unless we have a place to send it
     emails = utils.get_setting('TIMEPIECE_ACCOUNTING_EMAILS')
     if not emails:
         return
     from_email = utils.get_setting('DEFAULT_FROM_EMAIL')
     msg = render_to_string('timepiece/contract/hours_email.txt', ctx)
     send_mail(subject=subject,
               message=msg,
               from_email=from_email,
               recipient_list=emails)
예제 #2
0
 def _send_mail(self, subject, ctx):
     # Don't go to the work unless we have a place to send it
     emails = utils.get_setting('TIMEPIECE_ACCOUNTING_EMAILS')
     if not emails:
         return
     from_email = utils.get_setting('DEFAULT_FROM_EMAIL')
     msg = render_to_string('timepiece/contract/hours_email.txt', ctx)
     send_mail(
         subject=subject,
         message=msg,
         from_email=from_email,
         recipient_list=emails
     )
예제 #3
0
 def delete(self, *args, **kwargs):
     # Note: this gets called when you delete a single item using the red
     # Delete button at the bottom while editing it in the admin - but not
     # when you delete one or more from the change list using the admin
     # action.
     super(ContractHour, self).delete(*args, **kwargs)
     # If we have an email address to send to, and this record was in
     # pending status, we'll send an email about the change.
     if ContractHour.PENDING_STATUS in (self.status,
                                        self._original['status']):
         domain = Site.objects.get_current().domain
         method = 'https' if utils.get_setting('TIMEPIECE_EMAILS_USE_HTTPS')\
             else 'http'
         url = self.contract.get_absolute_url()
         ctx = {
             'deleted': True,
             'new': False,
             'changed': False,
             'previous': self._original,
             'link': '%s://%s%s' % (method, domain, url)
         }
         contract = self._original['contract']
         name = self._meta.verbose_name
         subject = "Deleted pending %s for %s" % (name, contract)
         self._send_mail(subject, ctx)
예제 #4
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        self.active = kwargs.pop('active', None)

        initial = kwargs.get('initial', {})
        default_loc = utils.get_setting('TIMEPIECE_DEFAULT_LOCATION_SLUG')
        if default_loc:
            try:
                loc = Location.objects.get(slug=default_loc)
            except Location.DoesNotExist:
                loc = None
            if loc:
                initial['location'] = loc.pk
        project = initial.get('project', None)
        try:
            last_project_entry = Entry.objects.filter(
                user=self.user, project=project).order_by('-end_time')[0]
        except IndexError:
            initial['activity'] = None
        else:
            initial['activity'] = last_project_entry.activity.pk

        super(ClockInForm, self).__init__(*args, **kwargs)

        self.fields['start_time'].initial = datetime.datetime.now()
        self.fields['project'].queryset = Project.trackable.filter(
            users=self.user)
        if not self.active:
            self.fields.pop('active_comment')
        else:
            self.fields['active_comment'].initial = self.active.comments
        self.instance.user = self.user
예제 #5
0
def quick_clock_in(request):
    user = request.user
    work_projects = []
    leave_projects = []

    if user.is_authenticated() and user.is_active:
        # Display all active paid leave projects that the user is assigned to.
        leave_ids = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS').values()
        lq = Q(users=user) & Q(id__in=leave_ids)
        leave_projects = Project.trackable.filter(lq).order_by('name')

        # Get all projects this user has clocked in to.
        entries = Entry.objects.filter(user=user)
        project_ids = list(entries.values_list('project', flat=True))

        # Narrow to projects which can still be clocked in to.
        pq = Q(id__in=project_ids)
        valid_projects = Project.trackable.filter(pq).exclude(id__in=leave_ids)
        valid_ids = list(valid_projects.values_list('id', flat=True))

        # Display the 10 projects this user most recently clocked into.
        work_ids = []
        for i in project_ids:
            if len(work_ids) > 10:
                break
            if i in valid_ids and i not in work_ids:
                work_ids.append(i)
        work_projects = [valid_projects.get(pk=i) for i in work_ids]

    return {
        'leave_projects': leave_projects,
        'work_projects': work_projects,
    }
예제 #6
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        self.active = kwargs.pop('active', None)

        initial = kwargs.get('initial', {})
        default_loc = utils.get_setting('TIMEPIECE_DEFAULT_LOCATION_SLUG')
        if default_loc:
            try:
                loc = Location.objects.get(slug=default_loc)
            except Location.DoesNotExist:
                loc = None
            if loc:
                initial['location'] = loc.pk
        project = initial.get('project', None)
        try:
            last_project_entry = Entry.objects.filter(
                user=self.user, project=project).order_by('-end_time')[0]
        except IndexError:
            initial['activity'] = None
        else:
            initial['activity'] = last_project_entry.activity.pk

        super(ClockInForm, self).__init__(*args, **kwargs)

        self.fields['start_time'].required = False
        self.fields['start_time'].initial = datetime.datetime.now()
        self.fields['start_time'].widget = TimepieceSplitDateTimeWidget()
        self.fields['project'].queryset = Project.trackable.filter(
            users=self.user)
        if not self.active:
            self.fields.pop('active_comment')
        else:
            self.fields['active_comment'].initial = self.active.comments
        self.instance.user = self.user
예제 #7
0
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop("user")
        self.active = kwargs.pop("active", None)

        initial = kwargs.get("initial", {})
        default_loc = utils.get_setting("TIMEPIECE_DEFAULT_LOCATION_SLUG")
        if default_loc:
            try:
                loc = Location.objects.get(slug=default_loc)
            except Location.DoesNotExist:
                loc = None
            if loc:
                initial["location"] = loc.pk
        project = initial.get("project", None)
        try:
            last_project_entry = Entry.objects.filter(user=self.user, project=project).order_by("-end_time")[0]
        except IndexError:
            initial["activity"] = None
        else:
            initial["activity"] = last_project_entry.activity.pk

        super(ClockInForm, self).__init__(*args, **kwargs)

        self.fields["start_time"].required = False
        self.fields["start_time"].initial = datetime.datetime.now()
        self.fields["start_time"].widget = TimepieceSplitDateTimeWidget()
        self.fields["project"].queryset = Project.trackable.filter(users=self.user)
        if not self.active:
            self.fields.pop("active_comment")
        else:
            self.fields["active_comment"].initial = self.active.comments
        self.instance.user = self.user
예제 #8
0
    def save(self, *args, **kwargs):
        # Let the date_approved default to today if it's been set approved
        # and doesn't have one
        if self.status == self.APPROVED_STATUS and not self.date_approved:
            self.date_approved = datetime.date.today()

        # If we have an email address to send to, and this record was
        # or is in pending status, we'll send an email about the change.
        if ContractHour.PENDING_STATUS in (self.status, self._original['status']):
            is_new = self.pk is None
        super(ContractHour, self).save(*args, **kwargs)
        if ContractHour.PENDING_STATUS in (self.status, self._original['status']):
            domain = Site.objects.get_current().domain
            method = 'https' if utils.get_setting('TIMEPIECE_EMAILS_USE_HTTPS')\
                else 'http'
            url = self.contract.get_absolute_url()
            ctx = {
                'new': is_new,
                'changed': not is_new,
                'deleted': False,
                'current': self,
                'previous': self._original,
                'link': '%s://%s%s' % (method, domain, url)
            }
            prefix = "New" if is_new else "Changed"
            name = self._meta.verbose_name
            subject = "%s pending %s for %s" % (prefix, name, self.contract)
            self._send_mail(subject, ctx)
예제 #9
0
    def save(self, *args, **kwargs):
        # Let the date_approved default to today if it's been set approved
        # and doesn't have one
        if self.status == self.APPROVED_STATUS and not self.date_approved:
            self.date_approved = datetime.date.today()

        # If we have an email address to send to, and this record was
        # or is in pending status, we'll send an email about the change.
        if ContractHour.PENDING_STATUS in (self.status,
                                           self._original['status']):
            is_new = self.pk is None
        super(ContractHour, self).save(*args, **kwargs)
        if ContractHour.PENDING_STATUS in (self.status,
                                           self._original['status']):
            domain = Site.objects.get_current().domain
            method = 'https' if utils.get_setting('TIMEPIECE_EMAILS_USE_HTTPS')\
                else 'http'
            url = self.contract.get_absolute_url()
            ctx = {
                'new': is_new,
                'changed': not is_new,
                'deleted': False,
                'current': self,
                'previous': self._original,
                'link': '%s://%s%s' % (method, domain, url)
            }
            prefix = "New" if is_new else "Changed"
            name = self._meta.verbose_name
            subject = "%s pending %s for %s" % (prefix, name, self.contract)
            self._send_mail(subject, ctx)
예제 #10
0
 def get_entries_data(self):
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     # Account for the day added by the form
     query = Q(end_time__gt=utils.get_week_start(self.from_date),
               end_time__lt=self.to_date + relativedelta(days=1))
     query &= ~Q(project__in=projects.values())
     entries = timepiece.Entry.objects.date_trunc(
         'week', extra_values=('activity', 'project__status')).filter(query)
     return entries
예제 #11
0
 def get_entries_data(self):
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     # Account for the day added by the form
     query = Q(end_time__gt=utils.get_week_start(self.from_date),
         end_time__lt=self.to_date + relativedelta(days=1))
     query &= ~Q(project__in=projects.values())
     entries = timepiece.Entry.objects.date_trunc('week',
         extra_values=('activity', 'project__status')).filter(query)
     return entries
예제 #12
0
def report_payroll_summary(request):
    date = timezone.now() - relativedelta(months=1)
    from_date = utils.get_month_start(date).date()
    to_date = from_date + relativedelta(months=1)

    year_month_form = PayrollSummaryReportForm(request.GET or None,
                                               initial={
                                                   'month': from_date.month,
                                                   'year': from_date.year
                                               })

    if year_month_form.is_valid():
        from_date, to_date = year_month_form.save()
    last_billable = utils.get_last_billable_day(from_date)
    projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
    weekQ = Q(end_time__gt=utils.get_week_start(from_date),
              end_time__lt=last_billable + relativedelta(days=1))
    monthQ = Q(end_time__gt=from_date, end_time__lt=to_date)
    workQ = ~Q(project__in=projects.values())
    statusQ = Q(status=Entry.INVOICED) | Q(status=Entry.APPROVED)
    # Weekly totals
    week_entries = Entry.objects.date_trunc('week').filter(
        weekQ, statusQ, workQ)
    date_headers = generate_dates(from_date, last_billable, by='week')
    weekly_totals = list(
        get_project_totals(week_entries, date_headers, 'total', overtime=True))
    # Monthly totals
    leave = Entry.objects.filter(monthQ,
                                 ~workQ).values('user', 'hours',
                                                'project__name')
    extra_values = ('project__type__label', )
    month_entries = Entry.objects.date_trunc('month', extra_values)
    month_entries_valid = month_entries.filter(monthQ, statusQ, workQ)
    labels, monthly_totals = get_payroll_totals(month_entries_valid, leave)
    # Unapproved and unverified hours
    entries = Entry.objects.filter(monthQ).order_by()  # No ordering
    user_values = ['user__pk', 'user__first_name', 'user__last_name']
    unverified = entries.filter(status=Entry.UNVERIFIED, user__is_active=True) \
                        .values_list(*user_values).distinct()
    unapproved = entries.filter(status=Entry.VERIFIED) \
                        .values_list(*user_values).distinct()
    return render(
        request, 'timepiece/reports/payroll_summary.html', {
            'from_date': from_date,
            'year_month_form': year_month_form,
            'date_headers': date_headers,
            'weekly_totals': weekly_totals,
            'monthly_totals': monthly_totals,
            'unverified': unverified,
            'unapproved': unapproved,
            'labels': labels,
        })
예제 #13
0
def report_payroll_summary(request):
    date = timezone.now() - relativedelta(months=1)
    from_date = utils.get_month_start(date).date()
    to_date = from_date + relativedelta(months=1)

    year_month_form = PayrollSummaryReportForm(request.GET or None, initial={
        'month': from_date.month,
        'year': from_date.year,
    })

    if year_month_form.is_valid():
        from_date, to_date = year_month_form.save()
    last_billable = utils.get_last_billable_day(from_date)
    projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
    weekQ = Q(end_time__gt=utils.get_week_start(from_date),
              end_time__lt=last_billable + relativedelta(days=1))
    monthQ = Q(end_time__gt=from_date, end_time__lt=to_date)
    workQ = ~Q(project__in=projects.values())
    statusQ = Q(status=Entry.INVOICED) | Q(status=Entry.APPROVED)
    # Weekly totals
    week_entries = Entry.objects.date_trunc('week').filter(
        weekQ, statusQ, workQ
    )
    date_headers = generate_dates(from_date, last_billable, by='week')
    weekly_totals = list(get_project_totals(week_entries, date_headers,
                                            'total', overtime=True))
    # Monthly totals
    leave = Entry.objects.filter(monthQ, ~workQ)
    leave = leave.values('user', 'hours', 'project__name')
    extra_values = ('project__type__label',)
    month_entries = Entry.objects.date_trunc('month', extra_values)
    month_entries_valid = month_entries.filter(monthQ, statusQ, workQ)
    labels, monthly_totals = get_payroll_totals(month_entries_valid, leave)
    # Unapproved and unverified hours
    entries = Entry.objects.filter(monthQ).order_by()  # No ordering
    user_values = ['user__pk', 'user__first_name', 'user__last_name']
    unverified = entries.filter(status=Entry.UNVERIFIED, user__is_active=True) \
                        .values_list(*user_values).distinct()
    unapproved = entries.filter(status=Entry.VERIFIED) \
                        .values_list(*user_values).distinct()
    return render(request, 'timepiece/reports/payroll_summary.html', {
        'from_date': from_date,
        'year_month_form': year_month_form,
        'date_headers': date_headers,
        'weekly_totals': weekly_totals,
        'monthly_totals': monthly_totals,
        'unverified': unverified,
        'unapproved': unapproved,
        'labels': labels,
    })
예제 #14
0
    def get_entry_query(self, start, end, data):
        """Builds Entry query from form data."""
        # Entry types.
        incl_billable = data.get('billable', True)
        incl_nonbillable = data.get('non_billable', True)
        incl_leave = data.get('paid_leave', True)

        # If no types are selected, shortcut & return nothing.
        if not any((incl_billable, incl_nonbillable, incl_leave)):
            return None

        # All entries must meet time period requirements.
        basicQ = Q(end_time__gte=start, end_time__lt=end)

        # Filter by project for HourlyReport.
        projects = data.get('projects', None)
        basicQ &= Q(project__in=projects) if projects else Q()

        # Filter by user, activity, and project type for BillableReport.
        if 'users' in data:
            basicQ &= Q(user__in=data.get('users'))
        if 'activities' in data:
            basicQ &= Q(activity__in=data.get('activities'))
        if 'project_types' in data:
            basicQ &= Q(project__type__in=data.get('project_types'))

        # If all types are selected, no further filtering is required.
        if all((incl_billable, incl_nonbillable, incl_leave)):
            return basicQ

        # Filter by whether a project is billable or non-billable.
        billableQ = None
        if incl_billable and not incl_nonbillable:
            billableQ = Q(activity__billable=True,
                          project__type__billable=True)
        if incl_nonbillable and not incl_billable:
            billableQ = Q(activity__billable=False) |\
                    Q(project__type__billable=False)

        # Filter by whether the entry is paid leave.
        leave_ids = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS').values()
        leaveQ = Q(project__in=leave_ids)
        if incl_leave:
            extraQ = (leaveQ | billableQ) if billableQ else leaveQ
        else:
            extraQ = (~leaveQ & billableQ) if billableQ else ~leaveQ

        return basicQ & extraQ
예제 #15
0
    def get_entry_query(self, start, end, data):
        """Builds Entry query from form data."""
        # Entry types.
        incl_billable = data.get('billable', True)
        incl_nonbillable = data.get('non_billable', True)
        incl_leave = data.get('paid_leave', True)

        # If no types are selected, shortcut & return nothing.
        if not any((incl_billable, incl_nonbillable, incl_leave)):
            return None

        # All entries must meet time period requirements.
        basicQ = Q(end_time__gte=start, end_time__lt=end)

        # Filter by project for HourlyReport.
        projects = data.get('projects', None)
        basicQ &= Q(project__in=projects) if projects else Q()

        # Filter by user, activity, and project type for BillableReport.
        if 'users' in data:
            basicQ &= Q(user__in=data.get('users'))
        if 'activities' in data:
            basicQ &= Q(activity__in=data.get('activities'))
        if 'project_types' in data:
            basicQ &= Q(project__type__in=data.get('project_types'))

        # If all types are selected, no further filtering is required.
        if all((incl_billable, incl_nonbillable, incl_leave)):
            return basicQ

        # Filter by whether a project is billable or non-billable.
        billableQ = None
        if incl_billable and not incl_nonbillable:
            billableQ = Q(activity__billable=True,
                    project__type__billable=True)
        if incl_nonbillable and not incl_billable:
            billableQ = Q(activity__billable=False) |\
                    Q(project__type__billable=False)

        # Filter by whether the entry is paid leave.
        leave_ids = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS').values()
        leaveQ = Q(project__in=leave_ids)
        if incl_leave:
            extraQ = (leaveQ | billableQ) if billableQ else leaveQ
        else:
            extraQ = (~leaveQ & billableQ) if billableQ else ~leaveQ

        return basicQ & extraQ
예제 #16
0
 def summary(user, date, end_date):
     """
     Returns a summary of hours worked in the given time frame, for this
     user.  The setting TIMEPIECE_PAID_LEAVE_PROJECTS can be used to
     separate out hours for paid leave that should not be included in the
     total worked (e.g., sick time, vacation time, etc.).  Those hours will
     be added to the summary separately using the dictionary key set in
     TIMEPIECE_PAID_LEAVE_PROJECTS.
     """
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     entries = user.timepiece_entries.filter(end_time__gt=date,
                                             end_time__lt=end_date)
     data = {
         'billable': Decimal('0'),
         'non_billable': Decimal('0'),
         'invoiced': Decimal('0'),
         'uninvoiced': Decimal('0'),
         'total': Decimal('0')
     }
     invoiced = entries.filter(status='invoiced').aggregate(
         i=Sum('hours'))['i']
     uninvoiced = entries.exclude(status='invoiced').aggregate(
         uninv=Sum('hours'))['uninv']
     total = entries.aggregate(s=Sum('hours'))['s']
     if invoiced:
         data['invoiced'] = invoiced
     if uninvoiced:
         data['uninvoiced'] = uninvoiced
     if total:
         data['total'] = total
     billable = entries.exclude(project__in=projects.values())
     billable = billable.values('billable', ).annotate(s=Sum('hours'))
     for row in billable:
         if row['billable']:
             data['billable'] += row['s']
         else:
             data['non_billable'] += row['s']
     data['total_worked'] = data['billable'] + data['non_billable']
     data['paid_leave'] = {}
     for name, pk in projects.iteritems():
         qs = entries.filter(project=projects[name])
         data['paid_leave'][name] = qs.aggregate(s=Sum('hours'))['s']
     return data
예제 #17
0
 def summary(user, date, end_date):
     """
     Returns a summary of hours worked in the given time frame, for this
     user.  The setting TIMEPIECE_PAID_LEAVE_PROJECTS can be used to
     separate out hours for paid leave that should not be included in the
     total worked (e.g., sick time, vacation time, etc.).  Those hours will
     be added to the summary separately using the dictionary key set in
     TIMEPIECE_PAID_LEAVE_PROJECTS.
     """
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     entries = user.timepiece_entries.filter(
         end_time__gt=date, end_time__lt=end_date)
     data = {
         'billable': Decimal('0'), 'non_billable': Decimal('0'),
         'invoiced': Decimal('0'), 'uninvoiced': Decimal('0'),
         'total': Decimal('0')
         }
     invoiced = entries.filter(
         status=Entry.INVOICED).aggregate(i=Sum('hours'))['i']
     uninvoiced = entries.exclude(
         status=Entry.INVOICED).aggregate(uninv=Sum('hours'))['uninv']
     total = entries.aggregate(s=Sum('hours'))['s']
     if invoiced:
         data['invoiced'] = invoiced
     if uninvoiced:
         data['uninvoiced'] = uninvoiced
     if total:
         data['total'] = total
     billable = entries.exclude(project__in=projects.values())
     billable = billable.values(
         'billable',
     ).annotate(s=Sum('hours'))
     for row in billable:
         if row['billable']:
             data['billable'] += row['s']
         else:
             data['non_billable'] += row['s']
     data['total_worked'] = data['billable'] + data['non_billable']
     data['paid_leave'] = {}
     for name, pk in projects.iteritems():
         qs = entries.filter(project=projects[name])
         data['paid_leave'][name] = qs.aggregate(s=Sum('hours'))['s']
     return data
예제 #18
0
 def summary(user, date, end_date):
     """
     Returns a summary of hours worked in the given time frame, for this
     user.  The setting TIMEPIECE_PAID_LEAVE_PROJECTS can be used to
     separate out hours for paid leave that should not be included in the
     total worked (e.g., sick time, vacation time, etc.).  Those hours will
     be added to the summary separately using the dictionary key set in
     TIMEPIECE_PAID_LEAVE_PROJECTS.
     """
     projects = utils.get_setting("TIMEPIECE_PAID_LEAVE_PROJECTS")
     entries = user.timepiece_entries.filter(end_time__gt=date, end_time__lt=end_date)
     data = {
         "billable": Decimal("0"),
         "non_billable": Decimal("0"),
         "invoiced": Decimal("0"),
         "uninvoiced": Decimal("0"),
         "total": Decimal("0"),
     }
     invoiced = entries.filter(status=Entry.INVOICED).aggregate(i=Sum("hours"))["i"]
     uninvoiced = entries.exclude(status=Entry.INVOICED).aggregate(uninv=Sum("hours"))["uninv"]
     total = entries.aggregate(s=Sum("hours"))["s"]
     if invoiced:
         data["invoiced"] = invoiced
     if uninvoiced:
         data["uninvoiced"] = uninvoiced
     if total:
         data["total"] = total
     billable = entries.exclude(project__in=projects.values())
     billable = billable.values("billable").annotate(s=Sum("hours"))
     for row in billable:
         if row["billable"]:
             data["billable"] += row["s"]
         else:
             data["non_billable"] += row["s"]
     data["total_worked"] = data["billable"] + data["non_billable"]
     data["paid_leave"] = {}
     for name, pk in projects.iteritems():
         qs = entries.filter(project=projects[name])
         data["paid_leave"][name] = qs.aggregate(s=Sum("hours"))["s"]
     return data
예제 #19
0
class PermissionsRequiredMixin(object):
    # Required.
    permissions = None

    # Optional.
    raise_exception = False
    login_url = utils.get_setting('LOGIN_URL')
    redirect_field_name = REDIRECT_FIELD_NAME

    def dispatch(self, request, *args, **kwargs):
        if getattr(self, 'permissions', None) is None:
            raise ImproperlyConfigured('Class must define the permissions '
                                       'attribute')

        if not request.user.has_perms(self.permissions):
            if self.raise_exception:
                raise PermissionDenied
            return redirect_to_login(request.get_full_path(), self.login_url,
                                     self.redirect_field_name)

        return super(PermissionsRequiredMixin,
                     self).dispatch(request, *args, **kwargs)
예제 #20
0
 def __init__(self, *args, **kwargs):
     self.user = kwargs.pop('user')
     self.active = kwargs.pop('active', None)
     initial = kwargs.get('initial', {})
     default_loc = utils.get_setting('TIMEPIECE_DEFAULT_LOCATION_SLUG')
     if default_loc:
         try:
             loc = timepiece.Location.objects.get(slug=default_loc)
         except timepiece.Location.DoesNotExist:
             loc = None
         if loc:
             initial['location'] = loc.pk
     project = initial.get('project')
     try:
         last_project_entry = timepiece.Entry.objects.filter(
             user=self.user, project=project).order_by('-end_time')[0]
     except IndexError:
         initial['activity'] = None
     else:
         initial['activity'] = last_project_entry.activity.id
     super(ClockInForm, self).__init__(*args, **kwargs)
     self.fields['start_time'].required = False
     self.fields['start_time'].initial = datetime.now()
     self.fields['start_time'].widget = forms.SplitDateTimeWidget(
         attrs={'class': 'timepiece-time'},
         date_format='%m/%d/%Y',
     )
     self.fields['project'].queryset = timepiece.Project.objects.filter(
         users=self.user,
         status__enable_timetracking=True,
         type__enable_timetracking=True)
     if not self.active:
         self.fields.pop('active_comment')
     else:
         self.fields['active_comment'].initial = self.active.comments
     self.instance.user = self.user
예제 #21
0
 def delete(self, *args, **kwargs):
     # Note: this gets called when you delete a single item using the red
     # Delete button at the bottom while editing it in the admin - but not
     # when you delete one or more from the change list using the admin
     # action.
     super(ContractHour, self).delete(*args, **kwargs)
     # If we have an email address to send to, and this record was in
     # pending status, we'll send an email about the change.
     if ContractHour.PENDING_STATUS in (self.status, self._original['status']):
         domain = Site.objects.get_current().domain
         method = 'https' if utils.get_setting('TIMEPIECE_EMAILS_USE_HTTPS')\
             else 'http'
         url = self.contract.get_absolute_url()
         ctx = {
             'deleted': True,
             'new': False,
             'changed': False,
             'previous': self._original,
             'link': '%s://%s%s' % (method, domain, url)
         }
         contract = self._original['contract']
         name = self._meta.verbose_name
         subject = "Deleted pending %s for %s" % (name, contract)
         self._send_mail(subject, ctx)
예제 #22
0
파일: forms.py 프로젝트: DarioGT/schedulall
 def __init__(self, *args, **kwargs):
     self.user = kwargs.pop('user')
     self.active = kwargs.pop('active', None)
     initial = kwargs.get('initial', {})
     default_loc = utils.get_setting('TIMEPIECE_DEFAULT_LOCATION_SLUG')
     if default_loc:
         try:
             loc = timepiece.Location.objects.get(slug=default_loc)
         except timepiece.Location.DoesNotExist:
             loc = None
         if loc:
             initial['location'] = loc.pk
     project = initial.get('project')
     try:
         last_project_entry = timepiece.Entry.objects.filter(
             user=self.user, project=project).order_by('-end_time')[0]
     except IndexError:
         initial['activity'] = None
     else:
         initial['activity'] = last_project_entry.activity.id
     super(ClockInForm, self).__init__(*args, **kwargs)
     self.fields['start_time'].required = False
     self.fields['start_time'].initial = datetime.now()
     self.fields['start_time'].widget = forms.SplitDateTimeWidget(
         attrs={'class': 'timepiece-time'},
         date_format='%m/%d/%Y',
     )
     self.fields['project'].queryset = timepiece.Project.objects.filter(
         users=self.user, status__enable_timetracking=True,
         type__enable_timetracking=True
     )
     if not self.active:
         self.fields.pop('active_comment')
     else:
         self.fields['active_comment'].initial = self.active.comments
     self.instance.user = self.user
예제 #23
0
 def get_query_set(self):
     qs = EntryQuerySet(self.model)
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     return qs.exclude(project__in=projects.values())
def extra_nav(request):
    return {
        'timepiece_extra_nav': utils.get_setting('TIMEPIECE_EXTRA_NAV'),
    }
def extra_nav(request):
    return {
        'timepiece_extra_nav': utils.get_setting('TIMEPIECE_EXTRA_NAV'),
    }
예제 #26
0
 def get_query_set(self):
     qs = EntryQuerySet(self.model)
     projects = utils.get_setting('TIMEPIECE_PAID_LEAVE_PROJECTS')
     return qs.exclude(project__in=projects.values())