Beispiel #1
0
def inject_summary_fields(sender, **kw):
    SiteSummary = rt.models.working.SiteSummary
    UserSummary = rt.models.working.UserSummary
    WorkSite = rt.models.tickets.Site
    Ticket = dd.plugins.working.ticket_model
    for t in ReportingTypes.get_list_items():
        k = t.name + '_hours'
        dd.inject_field(SiteSummary, k,
                        dd.DurationField(t.text, null=True, blank=True))
        dd.inject_field(UserSummary, k,
                        dd.DurationField(t.text, null=True, blank=True))
        dd.inject_field(Ticket, k,
                        dd.DurationField(t.text, null=True, blank=True))

        def make_getter(t):
            k = t.name + '_hours'

            def getter(obj, ar):
                qs = SiteSummary.objects.filter(master=obj, year__isnull=True)
                d = qs.aggregate(**{k: models.Sum(k)})
                n = d[k]
                return n

            return getter

        dd.inject_field(
            WorkSite, k,
            dd.VirtualField(dd.DurationField(t.text), make_getter(t)))

    if False:  # removed 20181211 because useless
        for ts in TicketStates.get_list_items():
            k = ts.get_summary_field()
            if k is not None:
                dd.inject_field(SiteSummary, k, models.IntegerField(ts.text))

                def make_getter(ts):
                    k = ts.get_summary_field()

                    def getter(obj, ar):
                        if ar is None:
                            return ''
                        qs = SiteSummary.objects.filter(master=obj)
                        d = qs.aggregate(**{k: models.Sum(k)})
                        n = d[k]
                        if n == 0:
                            return ''
                        sar = rt.models.tickets.TicketsBySite.request(
                            obj, param_values=dict(state=ts, show_active=None))
                        # n = sar.get_total_count()
                        url = ar.renderer.request_handler(sar)
                        if url is None:
                            return str(n)
                        return E.a(str(n), href='javascript:' + url)

                    return getter

                dd.inject_field(
                    WorkSite, k,
                    dd.VirtualField(dd.DisplayField(ts.text), make_getter(ts)))
Beispiel #2
0
    def get_daily_field(cls, pc):
        Event = rt.models.cal.Event

        def func(fld, obj, ar):
            # obj is a DailyPlannerRow instance
            mi = ar.master_instance
            if mi is None:  # e.g. when using DailySlave from dashboard.
                mi = cls.calendar_view.get_row_by_pk(ar, 0)
            qs = cls.get_calendar_entries(ar, obj)
            qs = qs.filter(event_type__planner_column=pc)
            qs = qs.filter(start_date=mi.date)
            # pv = ar.param_values
            # qs = Event.calendar_param_filter(qs, pv)
            # current_day = pv.get('date', dd.today())
            # if current_day:
            #     qs = qs.filter(start_date=current_day)
            # if obj is cls.model.HEADER_ROW:
            #     qs = qs.filter(start_time__isnull=True)
            # else:
            #     get_plannable_entries
            #     if obj.start_time:
            #         qs = qs.filter(start_time__gte=obj.start_time,
            #                        start_time__isnull=False)
            #     if obj.end_time:
            #         qs = qs.filter(start_time__lt=obj.end_time,
            #                        start_time__isnull=False)
            qs = qs.order_by('start_time')
            chunks = [e.obj2href(ar, cls.get_calview_div(e, ar)) for e in qs]
            return E.p(*join_elems(chunks))

        return dd.VirtualField(dd.HtmlBox(pc.text), func)
Beispiel #3
0
    def on_analyze(cls, site):
        super(TrendObservable, cls).on_analyze(site)
        TrendEvent = rt.models.trends.TrendEvent

        def w(ts):
            # return a getter function that returns the date of the first event
            # of the given trend stage.
            def func(obj, ar):
                qs = TrendEvent.objects.filter(subject=obj, trend_stage=ts)
                te = qs.order_by('event_date').first()
                if te is not None:
                    return te.event_date

            return func

        try:
            for ts in rt.models.trends.TrendStage.objects.filter(
                    subject_column=True):
                name = "trend_date_" + str(ts.id)
                vf = dd.VirtualField(dd.DateField(str(ts)),
                                     w(ts),
                                     wildcard_data_elem=True)
                cls.define_action(**{name: vf})
        except OperationalError:
            pass
Beispiel #4
0
    def setup_columns(cls):
        def w(ut):
            def func(fld, obj, ar):
                if isinstance(ut.role, obj):
                    return "☑"
                return ""

            return func

        names = []
        for ut in UserTypes.get_list_items():
            name = "ut" + ut.value
            # vf = dd.VirtualField(
            #     models.BooleanField(str(ut.value)), w(ut))
            vf = dd.VirtualField(dd.DisplayField(str(ut.value)), w(ut))
            cls.add_virtual_field(name, vf)
            names.append(name + ":3")
        # cls.column_names = "name:20 description:40 " + ' '.join(names)
        cls.column_names = "name:20 " + ' '.join(names)
Beispiel #5
0
    def get_weekly_field(cls, week_day):
        def func(fld, obj, ar):
            # obj is a Plannable instance
            qs = cls.get_calendar_entries(ar, obj)
            delta_days = int(ar.rqdata.get('mk', 0)
                             or 0) if ar.rqdata else ar.master_instance.pk
            # current_day = dd.today() + timedelta(days=delta_days)
            delta_days += int(week_day.value) - dd.today().weekday() - 1
            today = dd.today(delta_days)
            # current_week_day = current_day + \
            #     timedelta(days=int(week_day.value) - current_day.weekday() - 1)
            qs = qs.filter(start_date=today)
            qs = qs.order_by('start_time')
            if obj is cls.model.HEADER_ROW:
                chunks = obj.get_header_chunks(ar, qs, today)
            else:
                chunks = obj.get_weekly_chunks(ar, qs, today)
            return E.table(E.tr(E.td(E.div(*join_elems(chunks)))),
                           CLASS="fixed-table")

        return dd.VirtualField(dd.HtmlBox(week_day.text), func)
Beispiel #6
0
    def get_weekday_field(cls, week_day):

        Event = rt.models.cal.Event

        def func(fld, obj, ar):
            # obj is a Plannable instance
            qs = Event.objects.all()
            qs = Event.calendar_param_filter(qs, ar.param_values)
            delta_days = int(ar.rqdata.get('mk', 0)
                             or 0) if ar.rqdata else ar.master_instance.pk
            # current_day = dd.today() + timedelta(days=delta_days)
            current_day = dd.today(delta_days)
            current_week_day = current_day + \
                timedelta(days=int(week_day.value) - current_day.weekday() - 1)
            qs = qs.filter(start_date=current_week_day)
            qs = qs.order_by('start_time')
            chunks = obj.get_weekly_chunks(ar, qs, current_week_day)
            return E.table(E.tr(E.td(E.div(*join_elems(chunks)))),
                           CLASS="fixed-table")

        return dd.VirtualField(dd.HtmlBox(week_day.text), func)
Beispiel #7
0
        def w(pc):
            verbose_name = pc.text

            def func(fld, week, ar):
                pv = ar.param_values
                if pv is None:
                    return
                qs = Event.objects.all()
                qs = Event.calendar_param_filter(qs, pv)
                offset = int(ar.rqdata.get('mk', 0)
                             or 0) if ar.rqdata else ar.master_instance.pk
                today = dd.today()
                current_date = dd.today(offset)
                target_day = week[int(pc.value) - 1]
                qs = qs.filter(start_date=target_day)
                qs = qs.order_by('start_time')
                chunks = [
                    E.p(e.obj2href(ar, e.colored_calendar_fmt(pv))) for e in qs
                ]

                pk = date2pk(target_day)
                daily, weekly, monthly = make_link_funcs(ar)
                daily_link = daily(Day(pk), str(target_day.day))
                if target_day == today:
                    daily_link = E.b(daily_link)

                header_items = [daily_link]
                header_items = gen_insert_button(cls, header_items, Event, ar,
                                                 target_day)

                header = E.div(*header_items, align="center", CLASS="header")
                return E.table(
                    E.tr(E.td(*[header, E.div(*join_elems(chunks))])),
                    CLASS="fixed-table cal-month-cell {} {} {}".format(
                        "current-month" if current_date.month
                        == target_day.month else "other-month",
                        "current-day" if target_day == today else "",
                        "cal-in-past" if target_day < today else ""))

            return dd.VirtualField(dd.HtmlBox(verbose_name), func)
Beispiel #8
0
        def w(pc, verbose_name):
            def func(fld, obj, ar):
                # obj is the DailyPlannerRow instance
                pv = ar.param_values
                qs = Event.objects.filter(event_type__planner_column=pc)
                qs = Event.calendar_param_filter(qs, pv)
                current_day = pv.get('date', dd.today())
                if current_day:
                    qs = qs.filter(start_date=current_day)
                if obj.start_time:
                    qs = qs.filter(start_time__gte=obj.start_time,
                                   start_time__isnull=False)
                if obj.end_time:
                    qs = qs.filter(start_time__lt=obj.end_time,
                                   start_time__isnull=False)
                if not obj.start_time and not obj.end_time:
                    qs = qs.filter(start_time__isnull=True)
                qs = qs.order_by('start_time')
                chunks = [
                    e.obj2href(ar, e.colored_calendar_fmt(pv)) for e in qs
                ]
                return E.p(*join_elems(chunks))

            return dd.VirtualField(dd.HtmlBox(verbose_name), func)
Beispiel #9
0
        def w(rpttype, verbose_name):
            def func(fld, obj, ar):
                return obj._root2tot.get(rpttype, None)

            return dd.VirtualField(dd.DurationField(verbose_name), func)
Beispiel #10
0
def rpttype2vf(func, rpttype, verbose_name):
    return dd.VirtualField(dd.DurationField(verbose_name), func)
Beispiel #11
0
def set_upload_shortcuts(sender, **kw):
    """This is the successor for `quick_upload_buttons`."""

    # remember that models might have been overridden.
    UploadType = sender.modules.uploads.UploadType

    for i in Shortcuts.items():

        def f(obj, ar):
            if obj is None or ar is None:
                return E.div()
            try:
                utype = UploadType.objects.get(shortcut=i)
            except UploadType.DoesNotExist:
                return E.div()
            items = []
            target = sender.modules.resolve(i.target)
            sar = ar.spawn_request(actor=target,
                                   master_instance=obj,
                                   known_values=dict(type=utype))
            # param_values=dict(pupload_type=et))
            n = sar.get_total_count()
            if n == 0:
                iar = target.insert_action.request_from(sar,
                                                        master_instance=obj)
                btn = iar.ar2button(
                    None,
                    _("Upload"),
                    icon_name="page_add",
                    title=_("Upload a file from your PC to the server."))
                items.append(btn)
            elif n == 1:
                after_show = ar.get_status()
                obj = sar.data_iterator[0]
                items.append(
                    sar.renderer.href_button(dd.build_media_url(obj.file.name),
                                             _("show"),
                                             target='_blank',
                                             icon_name='page_go',
                                             style="vertical-align:-30%;",
                                             title=_(
                                                 "Open the uploaded file in a "
                                                 "new browser window")))
                after_show.update(record_id=obj.pk)
                items.append(
                    sar.window_action_button(
                        sar.ah.actor.detail_action,
                        after_show,
                        _("Edit"),
                        icon_name='application_form',
                        title=_("Edit metadata of the uploaded file.")))
            else:
                obj = sar.sliced_data_iterator[0]
                items.append(
                    ar.obj2html(obj, pgettext("uploaded file", "Last")))

                btn = sar.renderer.action_button(obj,
                                                 sar,
                                                 sar.bound_action,
                                                 _("All {0} files").format(n),
                                                 icon_name=None)
                items.append(btn)

            return E.div(*join_elems(items, ', '))

        vf = dd.VirtualField(dd.DisplayField(i.text), f)
        dd.inject_field(i.model_spec, i.name, vf)
Beispiel #12
0
def set_excerpts_actions(sender, **kw):
    """Installs (1) print management actions on models for which there is
    an excerpt type and (2) the excerpt shortcut fields defined in
    :class:`lino_xl.lib.excerpts.choicelists.Shortcuts`.

    """
    # logger.info("20140401 %s.set_attest_actions()", __name__)

    # in case ExcerptType is overridden
    ExcerptType = sender.modules.excerpts.ExcerptType
    Excerpt = sender.modules.excerpts.Excerpt

    try:
        etypes = [(obj, obj.content_type) for obj in ExcerptType.objects.all()]
    except (OperationalError, ProgrammingError, UnresolvedChoice) as e:
        dd.logger.debug("Failed to set excerpts actions : %s", e)
        # Happens e.g. when the database has not yet been migrated
        etypes = []

    for atype, ct in etypes:
        if ct is not None:
            m = ct.model_class()
            if m is not None:  # e.g. database contains types for
                # models that existed before but have
                # been removed
                an = atype.get_action_name()
                m.define_action(
                    **{an: CreateExcerpt(atype, six.text_type(atype))})
                # dd.logger.info("Added print action to %s", m)

                # if atype.certifying and not issubclass(m, Certifiable):
                #     m.define_action(
                #         clear_printed=ClearCache())

    # An attestable model must also inherit
    # :class:`lino.mixins.printable.BasePrintable` or some subclass
    # thereof.

    for i in Shortcuts.items():

        def f(obj, ar):
            if ar is None:
                return ''
            if obj is None:
                return E.div()
            try:
                et = ExcerptType.objects.get(shortcut=i)
            except ExcerptType.DoesNotExist:
                return E.div()
            items = []
            if True:
                sar = ar.spawn(ExcerptsByOwner,
                               master_instance=obj,
                               param_values=dict(excerpt_type=et))
                n = sar.get_total_count()
                if n > 0:
                    ex = sar.sliced_data_iterator[0]
                    items.append(ar.obj2html(ex, _("Last")))

                    ba = sar.bound_action
                    btn = sar.renderer.action_button(obj,
                                                     sar,
                                                     ba,
                                                     "%s (%d)" % (_("All"), n),
                                                     icon_name=None)
                    items.append(btn)

                ia = getattr(obj, et.get_action_name())
                btn = ar.instance_action_button(ia,
                                                _("Create"),
                                                icon_name=None)
                items.append(btn)

            else:
                ot = ContentType.objects.get_for_model(obj.__class__)
                qs = Excerpt.objects.filter(owner_id=obj.pk,
                                            owner_type=ot,
                                            excerpt_type=et)
                if qs.count() > 0:
                    ex = qs[0]
                    txt = ExcerptsByOwner.format_excerpt(ex)
                    items.append(ar.obj2html(ex, txt))
            return E.div(*join_elems(items, ', '))

        vf = dd.VirtualField(dd.DisplayField(i.text), f)
        dd.inject_field(i.model_spec, i.name, vf)
Beispiel #13
0
class Mail(UserAuthored, Printable, UploadController, mixins.ProjectRelated,
           Controllable):
    class Meta:
        verbose_name = _("Outgoing Mail")
        verbose_name_plural = _("Outgoing Mails")

    send_mail = SendMail()

    date = models.DateField(verbose_name=_("Date"),
                            help_text="""
        The official date to be printed on the document.
        """)

    subject = models.CharField(
        _("Subject"),
        max_length=200,
        blank=True,
        # null=True
    )
    body = dd.RichTextField(_("Body"), blank=True, format='html')

    #~ type = dd.ForeignKey(MailType,null=True,blank=True)

    #~ sender = dd.ForeignKey(settings.SITE.user_model,
    #~ verbose_name=_("Sender"))
    #~ related_name='outmails_by_sender',
    #~ blank=True,null=True)
    sent = models.DateTimeField(null=True, editable=False)

    def on_create(self, ar):
        self.date = settings.SITE.today()
        super(Mail, self).on_create(ar)

    #~ def disabled_fields(self,ar):
    #~ if not self.owner.post_as_attachment:
    #~ return ['body']
    #~ return []
    #~ @classmethod
    #~ def get_model_actions(self,table):
    #~ for x in super(Mail,self).get_model_actions(table): yield x
    #~ yield 'send_mail',SendMail()
    def get_print_language(self):
        if self.user is not None:
            return self.user.language
        return super(Mail, self).get_print_language()

    def __str__(self):
        return u'%s #%s' % (self._meta.verbose_name, self.pk)

    def get_recipients(self, rr):
        #~ recs = []
        recs = [
            str(r) for r in Recipient.objects.filter(mail=self,
                                                     type=RecipientTypes.to)
        ]
        return ', '.join(recs)

    recipients = dd.VirtualField(dd.HtmlBox(_("Recipients")), get_recipients)

    def get_row_permission(self, ar, state, ba):
        """
        Mails may not be edited after they have been sent.
        """
        if self.sent and not ba.action.readonly:
            #~ logger.info("20120920 Mail.get_row_permission()")
            return False
        return super(Mail, self).get_row_permission(ar, state, ba)
Beispiel #14
0
#

def preview(obj, ar):
    return obj.html or obj.text

def spam(obj):
    """Checks if the message is spam or not
    """
    if obj.subject.startswith("*****SPAM*****"):
        return True
    else:
        return False


dd.inject_field('django_mailbox.Message', 'preview',
                dd.VirtualField(dd.HtmlBox(_("Preview")), preview))
dd.inject_field('django_mailbox.Message', 'ticket',
                dd.ForeignKey('tickets.Ticket', blank=True, null=True))

dd.update_field('django_mailbox.Message', 'from_header', format="plain")


from .ui import *

@dd.schedule_often(10)
def get_new_mail():
    for mb in rt.models.django_mailbox.Mailbox.objects.filter(active=True):
        mails = mb.get_new_mail()
        for mail in mails:
            if spam(mail):
                mail.spam = True
Beispiel #15
0
    def get_monthly_field(cls, wd):
        Events = rt.models.cal.Events

        def func(fld, obj, ar):
            # obj is the first day of the week to show
            # pv = ar.param_values
            today = dd.today()
            # if pv is None:
            #     return
            qs = cls.get_calendar_entries(ar, None)
            # qs = Event.objects.all()
            # qs = Event.calendar_param_filter(qs, pv)
            mi = ar.master_instance
            if mi is None:
                return
            target_day = cls.get_row_by_pk(ar, obj.pk + int(wd.value) - 1)
            current_month = mi.date.month
            nav = mi.planner

            # offset = ar.master_instance.pk
            # offset = int(ar.rqdata.get('mk', 0) or 0) if ar.rqdata else ar.master_instance.pk
            # current_date = dd.today(offset)
            # pk = offset + int(wd.value) - 1
            # target_day = cls.get_row_by_pk(ar, pk)
            # if target_day is None:
            #     return
            # target_day = week[int(wd.value)-1]
            qs = qs.filter(start_date=target_day.date)
            qs = qs.order_by('start_time')
            chunks = [
                E.p(e.obj2href(ar, cls.get_calview_div(e, ar))) for e in qs
            ]

            # pk = date2pk(target_day)

            # nav.daily_view
            # sar = ar.spawn_request(actor=actor, param_values=ar.param_values)
            # rnd = settings.SITE.kernel.default_renderer
            # def func(day, text):
            #     # day.navigation_mode = actor.navigation_mode
            #     return rnd.ar2button(sar, day, text, style="", icon_name=None, title=str(day))
            #

            daily = nav.daily_button_func(ar)
            daily_link = daily(target_day, str(target_day.date.day))
            if target_day.date == today:
                daily_link = E.b(daily_link)

            # header_items = [daily_link]
            # header_items = Event.gen_insert_button(cls, header_items, ar, target_day)
            header_items = [daily_link]
            btn = ar.gen_insert_button(Events, start_date=target_day.date)
            if btn:
                header_items.append(btn)

            header = E.div(*header_items, align="center", CLASS="header")
            return E.table(
                E.tr(E.td(*[header, E.div(*join_elems(chunks))])),
                CLASS="fixed-table cal-month-cell {} {} {}".format(
                    "current-month" if current_month == target_day.date.month
                    else "other-month",
                    "current-day" if target_day.date == today else "",
                    "cal-in-past" if target_day.date < today else ""))

        return dd.VirtualField(dd.HtmlBox(wd.text), func)