def update_controller_field(cls, **kwargs): """This can be used to make the controller optional (i.e. whether the :attr:`owner` field may be NULL). Example:: class MyModel(Controllable): .... MyModel.update_controller_field(blank=False, null=False) """ dd.update_field(cls, 'owner_id', **kwargs) dd.update_field(cls, 'owner_type', **kwargs)
def update_controller_field(cls, verbose_name=None, **kwargs): """Update attributes of the :attr:`owner` field and its underlying fields :attr:`owner_id` and :attr:`owner_type`. This can be used to make the controller optional (i.e. specify whether the :attr:`owner` field may be NULL). Example:: class MyModel(Controllable): .... MyModel.update_controller_field(blank=False, null=False) When `verbose_name` is specified, all three fields will be updated, appending " (object)" and " (type)" to :attr:`owner_id` and :attr:`owner_type` respectively. """ if verbose_name is not None: dd.update_field(cls, 'owner', verbose_name=verbose_name) kwargs.update( verbose_name=string_concat(verbose_name, ' ', _('(object)'))) dd.update_field(cls, 'owner_id', **kwargs) if verbose_name is not None: kwargs.update( verbose_name=string_concat(verbose_name, ' ', _('(type)'))) dd.update_field(cls, 'owner_type', **kwargs)
def update_controller_field(cls, verbose_name=None, **kwargs): """Update attributes of the :attr:`owner` field and its underlying fields :attr:`owner_id` and :attr:`owner_type`. This can be used to make the controller optional (i.e. specify whether the :attr:`owner` field may be NULL). Example:: class MyModel(Controllable): .... MyModel.update_controller_field(blank=False, null=False) When `verbose_name` is specified, all three fields will be updated, appending " (object)" and " (type)" to :attr:`owner_id` and :attr:`owner_type` respectively. """ if verbose_name is not None: dd.update_field(cls, 'owner', verbose_name=verbose_name) kwargs.update( verbose_name=string_concat( verbose_name, ' ', _('(object)'))) dd.update_field(cls, 'owner_id', **kwargs) if verbose_name is not None: kwargs.update( verbose_name=string_concat( verbose_name, ' ', _('(type)'))) dd.update_field(cls, 'owner_type', **kwargs)
def update_controller_field(cls, verbose_name=None, **kwargs): if verbose_name is not None: dd.update_field(cls, 'owner', verbose_name=verbose_name) kwargs.update( verbose_name=format_lazy(u"{} {}", verbose_name, _('(object)'))) dd.update_field(cls, 'owner_id', **kwargs) if verbose_name is not None: kwargs.update( verbose_name=format_lazy(u"{} {}", verbose_name, _('(type)'))) dd.update_field(cls, 'owner_type', **kwargs)
return u'%s #%s' % (self._meta.verbose_name, self.pk) def as_li(self, ar): """Return this comment as a list item. If `bleach <http://bleach.readthedocs.org/en/latest/>`_ is installed, all tags except some will be removed when """ txt = ar.parse_memo(self.short_text) if bleach is None: chunks = [txt] else: chunks = [bleach.clean( txt, tags=self.ALLOWED_TAGS, strip=True)] by = _("{0} by {1}").format( naturaltime(self.created), unicode(self.user)), chunks += [ " (", E.tostring(ar.obj2html(self, by)), ")" ] if self.more_text: chunks.append(" (...)") html = ''.join(chunks) return "<li>" + html + "</li>" dd.update_field(Comment, 'user', editable=False) from .ui import *
else: class ExcerptDetail(dd.DetailLayout): # window_size = (80, 20) window_size = (80, 'auto') main = """ id excerpt_type:25 project user:10 build_method company contact_person language owner build_time # outbox.MailsByController """ if dd.is_installed('contacts'): dd.update_field(Excerpt, 'company', verbose_name=_("Recipient (Organization)")) dd.update_field(Excerpt, 'contact_person', verbose_name=_("Recipient (Person)")) class Excerpts(dd.Table): # label = _("Excerpts history") icon_name = 'script' required_roles = dd.login_required((ExcerptsUser, OfficeOperator)) model = 'excerpts.Excerpt' detail_layout = ExcerptDetail() insert_layout = """ excerpt_type project company contact_person """
"Controller %r has no method `get_target_url`." % self.owner) super(Attachment, self).save(*args, **kw) def summary_row(self, ar, **kw): url = self.owner.get_target_url() #~ url = ui.build_url(*parts) text = url.split('/')[-1] return [ar.renderer.href(url, text)] class Attachments(dd.Table): required_roles = dd.login_required(OfficeStaff) model = Attachment #~ window_size = (400,500) #~ detail_layout = """ #~ mail owner #~ """ class AttachmentsByMail(Attachments): required_roles = dd.login_required(OfficeUser) master_key = 'mail' display_mode = 'summary' class AttachmentsByController(Attachments): master_key = 'owner' dd.update_field(Mail, 'user', verbose_name=_("Sender"))
def about_me(self, ar): return self.remarks # def get_default_table(self, ar): # tbl = super(User, self).get_default_table(ar) # return rt.actors.users.OtherUsers # def __str__(self): # s = self.get_full_name() # if self.callme_mode: # if self.tel: # s += " ({})".format(self.tel) # return s dd.update_field('users.User', 'remarks', verbose_name=_("About me")) class UserDetail(UserDetail): """Layout of User Detail in Lino Noi.""" main = "general contact dashboard.WidgetsByUser" general = dd.Panel(""" box1:45 clocking:15 topics.InterestsByPartner faculties.CompetencesByUser """, label=_("General")) clocking = dd.Panel(""" open_session_on_new_ticket timezone """, label=_("Clocking"), required_roles=dd.required(Worker))
# return self.client def get_notify_owner(self, ar): return self.client def get_change_observers(self): return self.client.get_change_observers() # def get_notify_observers(self): # yield self.user # for u in settings.SITE.user_model.objects.filter( # coaching_supervisor=True).exclude(email=''): # yield u dd.update_field(Coaching, 'start_date', verbose_name=_("Coached from")) dd.update_field(Coaching, 'end_date', verbose_name=_("until")) class Coachings(dd.Table): required_roles = dd.required(SocialStaff) help_text = _("Liste des accompagnements.") model = 'pcsw.Coaching' parameters = mixins.ObservedPeriod( coached_by=models.ForeignKey( 'users.User', blank=True, null=True, verbose_name=_("Coached by"), help_text="""Nur Begleitungen dieses Benutzers."""), and_coached_by=models.ForeignKey(
weight = models.IntegerField( _("Work effort"), # Arbeitsaufwand blank=True, help_text=u"""\ Wieviel Aufwand mir persönlich ein Neuantrag in diesem Fachbereich verursacht (0 = gar kein Aufwand, %d = maximaler Aufwand).""" % MAX_WEIGHT) def full_clean(self, *args, **kw): if self.weight is None: self.weight = self.faculty.weight super(Competence, self).full_clean(*args, **kw) def __str__(self): return u'%s #%s' % (self._meta.verbose_name, self.pk) dd.update_field(Competence, 'user', verbose_name=_("User")) class Competences(dd.Table): required_roles = dd.required(SocialStaff) model = 'newcomers.Competence' column_names = 'id user faculty weight *' order_by = ["id"] class CompetencesByUser(Competences): required_roles = dd.required() master_key = 'user' column_names = 'seqno faculty weight *' order_by = ["seqno"]
Represents a physical person. """ class Meta(Person.Meta): verbose_name = _("Person") verbose_name_plural = _("Persons") #~ ordering = ['last_name','first_name'] def get_queryset(self, ar): return self.model.objects.select_related('country', 'city') def get_print_language(self): "Used by DirectPrintAction" return self.language dd.update_field(Person, 'first_name', blank=False) dd.update_field(Person, 'last_name', blank=False) class PersonDetail(PersonDetail): main = "general contact misc" general = dd.Panel(""" overview:20 general2:40 general3:40 contacts.RolesByPerson:20 households.MembersByPerson:40 \ humanlinks.LinksByHuman """, label=_("General")) general2 = """
verbose_name=_("Start time")) end_time = dd.TimeField( blank=True, null=True, verbose_name=_("End time")) def get_weekly_chunks(obj, ar, qs, current_week_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) link = str(current_week_day.day) \ if current_week_day != dd.today() \ else E.b(str(current_week_day.day)) link = E.p(*gen_insert_button( ar.actor, [link], rt.models.cal.Event, ar, current_week_day), align="center") else: link = '' chunks = [e.obj2href(ar, e.colored_calendar_fmt(ar.param_values)) for e in qs] return [link] + chunks dd.update_field(DailyPlannerRow, 'overview', verbose_name=_("Time range")) from .ui import *
master_instance=self, param_values=dict(sheet_type=SheetTypes.results))) # for st in SheetTypes.get_list_items(): # balances.append(ar.spawn( # ItemEntriesByReport, # master_instance=self, # param_values=dict(sheet_type=st))) if True: for sar in balances: # if header: # yield header(str(sar.get_title())) yield sar dd.update_field(Report, 'start_period', null=True) # class Entry(SimpleSummary): # class Meta: # app_label = 'sheets' # abstract = dd.is_abstract_model(__name__, 'Entry') # verbose_name = _("Sheet entry") # verbose_name_plural = _("Sheet entries") # show_in_site_search = False # master = dd.ForeignKey('ledger.FiscalYear') # item = dd.ForeignKey('sheets.Item') # value = dd.PriceField(_("Value"))
# @dd.virtualfield(dd.HtmlBox(_("Presences"))) # def presences_box(self, ar): # # not finished # if ar is None: # return '' # pv = ar.param_values # # if not pv.start_date or not pv.end_date: # # return '' # events = self.events_by_course().order_by('start_date') # events = rt.models.system.PeriodEvents.started.add_filter(events, pv) # return "TODO: copy logic from presence_sheet.wk.html" # we want to use default values from the activity line dd.update_field(Course, 'every_unit', default=models.NOT_PROVIDED) dd.update_field(Course, 'every', default=models.NOT_PROVIDED) if FILL_EVENT_GUESTS: @dd.receiver(dd.post_save, sender=cal.Event, dispatch_uid="fill_event_guests_from_course") def fill_event_guests_from_course(sender=None, instance=None, **kw): #~ logger.info("20130528 fill_event_guests_from_course") if settings.SITE.loading_from_dump: return event = instance if event.is_user_modified(): return if event.is_fixed_state():
def save(self, *args, **kw): ct = CALENDAR_DICT.get(self.type) ct.validate_calendar(self) super(RemoteCalendar, self).save(*args, **kw) class Room(mixins.BabelNamed, ContactRelated, Colored): class Meta: app_label = 'cal' abstract = dd.is_abstract_model(__name__, 'Room') verbose_name = _("Room") verbose_name_plural = _("Rooms") description = dd.RichTextField(_("Description"), blank=True) dd.update_field( Room, 'company', verbose_name=_("Responsible")) dd.update_field( Room, 'contact_person', verbose_name=_("Contact person")) # class Priority(mixins.BabelNamed): # class Meta: # app_label = 'cal' # verbose_name = _("Priority") # verbose_name_plural = _('Priorities') # ref = models.CharField(max_length=1) # class EventType(mixins.BabelNamed, Referrable, mixins.Sequenced, MailableType): templates_group = 'cal/Event' ref_max_length = 4
verbose_name = _("Plausibility problem") verbose_name_plural = _("Plausibility problems") ordering = ['owner_type', 'owner_id', 'checker'] # problem_type = ProblemTypes.field() checker = Checkers.field() # severity = Severities.field() # feedback = Feedbacks.field(blank=True) message = models.CharField(_("Message"), max_length=250) # fixable = models.BooleanField(_("Fixable"), default=False) update_problem = UpdateProblem() fix_problem = FixProblem() dd.update_field(Problem, 'user', verbose_name=_("Responsible")) Problem.set_widget_options('checker', width=10) Problem.set_widget_options('user', width=10) Problem.set_widget_options('message', width=50) class Problems(dd.Table): "The base table for :class:`Problem` objects." model = 'plausibility.Problem' column_names = "user owner message #fixable checker *" auto_fit_column_widths = True editable = False cell_edit = False parameters = dict( user=models.ForeignKey( 'users.User',
""" ut = self.type if not ut or not ut.warn_expiry_unit: return if not self.needed: return update_reminder( 1, self, self.user, self.end_date, _("%s expires") % unicode(ut), ut.warn_expiry_value, ut.warn_expiry_unit) dd.update_field( Upload, 'company', verbose_name=_("Issued by (Organization)")) dd.update_field( Upload, 'contact_person', verbose_name=_("Issued by (Person)")) dd.update_field(Upload, 'start_date', verbose_name=_("Valid from")) dd.update_field(Upload, 'end_date', verbose_name=_("Valid until")) # dd.update_field( # Upload, 'upload_area', default=UploadAreas.job_search.as_callable) class UploadDetail(dd.FormLayout): "The Detail layout for Upload" main = """ user project id type description start_date end_date needed
verbose_name = _("Authority") verbose_name_plural = _("Authorities") authorized = dd.ForeignKey(settings.SITE.user_model) @dd.chooser() def authorized_choices(cls, user): qs = settings.SITE.user_model.objects.exclude(user_type=None) #~ user_type=UserTypes.blank_item) 20120829 if user is not None: qs = qs.exclude(id=user.id) #~ .exclude(level__gte=UserLevels.admin) return qs dd.update_field(Authority, 'user', null=False) @dd.receiver(dd.pre_startup) def inject_partner_field(sender=None, **kwargs): User = sender.models.users.User if dd.is_installed('contacts'): Partner = sender.models.contacts.Partner if not issubclass(User, Partner): dd.inject_field( User, 'partner', dd.ForeignKey('contacts.Partner', blank=True, null=True,
Represents a physical person. """ class Meta(Person.Meta): verbose_name = _("Person") verbose_name_plural = _("Persons") #~ ordering = ['last_name','first_name'] def get_queryset(self, ar): return self.model.objects.select_related('country', 'city') def get_print_language(self): "Used by DirectPrintAction" return self.language dd.update_field(Person, 'first_name', blank=False) dd.update_field(Person, 'last_name', blank=False) class PersonDetail(PersonDetail): main = "general contact misc" general = dd.Panel(""" overview:20 general2:40 general3:40 contacts.RolesByPerson:20 households.MembersByPerson:40 \ humanlinks.LinksByHuman """, label=_("General")) general2 = """ title first_name:15 middle_name:15
""" if not self.state: if ar.get_user() == self.user: self.state = VoteStates.watching else: self.state = VoteStates.invited super(Vote, self).on_create(ar) # def get_author(self): def get_row_permission(self, ar, state, ba): # we bypass the author check because return dd.Model.get_row_permission(self, ar, state, ba) dd.update_field(Vote, 'user', verbose_name=_("Voter")) class Votes(dd.Table): """Table parameters: .. attribute:: observed_event There are two class attributes for defining a filter conditions which canot be removed by the user: .. attribute:: filter_vote_states A set of vote states to require (i.e. to filter upon). This must resolve using :meth:`resolve_states <lino.core.model.Model.resolve_states>`.
@dd.chooser() def type_choices(self, upload_area): M = dd.resolve_model('uploads.UploadType') logger.info("20140430 type_choices %s", upload_area) if upload_area is None: return M.objects.all() return M.objects.filter(upload_area=upload_area) def save(self, *args, **kw): if self.type is not None: self.upload_area = self.type.upload_area super(Upload, self).save(*args, **kw) dd.update_field(Upload, 'user', verbose_name=_("Uploaded by")) class Uploads(dd.Table): "Shows all Uploads" model = 'uploads.Upload' required_roles = dd.login_required((OfficeUser, OfficeOperator)) column_names = "file type user owner description *" order_by = ['-id'] detail_layout = dd.DetailLayout(""" file user upload_area type description owner """, window_size=(80, 'auto'))
"requiring this skill." "A number between -{0} and +{0}.").format(MAX_WEIGHT)) skill_type = dd.ForeignKey( 'skills.SkillType', null=True, blank=True) remarks = dd.RichTextField(_("Remarks"), blank=True) # topic_group = dd.ForeignKey( # 'topics.TopicGroup', blank=True, null=True, # verbose_name=_("Options category"), # help_text=_("The topic group to use for " # "specifying additional options.")) dd.update_field(Skill, 'parent', verbose_name=_("Parent skill")) class Competence(UserAuthored, Sequenced): """A **skill offer** is when a given *user* is declared to have a given *skill*. .. attribute:: user .. attribute:: end_user .. attribute:: faculty .. attribute:: affinity """ allow_cascaded_delete = "end_user user"
#~ flt = flt & models.Q(type__gte=PlaceTypes.get_by_value('50')) flt = flt & models.Q(type__in=types) #~ flt = flt | models.Q(type=PlaceTypes.blank_item) return cls.objects.filter(flt).order_by('name') #~ if country is not None: #~ cd = getattr(CountryDrivers,country.isocode,None) #~ if cd: #~ return Place.objects.filter( #~ country=country, #~ type__in=cd.city_types).order_by('name') #~ return country.place_set.order_by('name') #~ return cls.city.field.rel.model.objects.order_by('name') dd.update_field(Place, 'parent', verbose_name=_("Part of")) class Places(dd.Table): model = 'countries.Place' required_roles = dd.login_required(ContactsStaff) order_by = "country name".split() column_names = "country name type zip_code parent *" detail_layout = """ name country type parent zip_code id PlacesByPlace """ insert_layout = """ name
def update_cal_event_type(self): return self.event_type def update_cal_summary(self, i): return six.text_type(self) def care_about_conflicts(self, we): """Recurrent events don't care about conflicts. A holiday won't move just because some other event has been created before on that date. """ return False dd.update_field( RecurrentEvent, 'every_unit', default=Recurrencies.yearly.as_callable, blank=False, null=False) class UpdateGuests(dd.MultipleRowAction): """Decide whether it is time to add Guest instances for this event, and if yes, call :meth:`suggest_guests` to instantiate them. - No guests must be added when loading from dump - The Event must be in a state which allows editing the guests - If there are already at least one guest, no guests will be added """ label = _('Update Guests') # icon_name = 'lightning'
#~ register_action = None #~ deregister_action = None def before_state_change(self, ar, old, new): if new.name == 'registered': if self.get_existing_auto_events().count() == 0: #~ ar.confirm("Booking has no events! Are you sure?") raise Warning("Booking has no events!") def after_ui_save(self, ar, cw): super(Booking, self).after_ui_save(ar, cw) if self.state.is_editable: self.update_reminders(ar) dd.update_field(Booking, 'contact_person', verbose_name=_("Contact person")) dd.update_field(Booking, 'company', verbose_name=_("Organizer")) dd.update_field(Booking, 'every_unit', default=Recurrencies.as_callable('once')) dd.update_field(Booking, 'every', default=1) class BookingDetail(dd.DetailLayout): #~ start = "start_date start_time" #~ end = "end_date end_time" #~ freq = "every every_unit" #~ start end freq main = "general invoicing.InvoicingsByGenerator" general = dd.Panel(""" start_date start_time end_date end_time room event_type workflow_buttons
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 mail.full_clean() mail.save() if mails: logger.info("got {} from mailbox: {}".format(mails,mb))
class VatAccountInvoice(VatVoucher, Matching): class Meta: verbose_name = _("Invoice") verbose_name_plural = _("Invoices") # Override the field to change the text for the purchase invoice. your_ref = models.CharField(_("Provider's invoice number"), max_length=200, blank=True) # show_items = dd.ShowSlaveTable('vat.ItemsByInvoice', show_in_workflow=True) dd.update_field(VatAccountInvoice, 'total_vat', editable=False) dd.update_field(VatAccountInvoice, 'total_base', editable=False) class InvoiceItem(AccountVoucherItem, VatItemBase): class Meta: verbose_name = _("Account invoice item") verbose_name_plural = _("Account invoice items") voucher = dd.ForeignKey('vat.VatAccountInvoice', related_name='items') title = models.CharField(_("Description"), max_length=200, blank=True) def account_changed(self, ar): if self.account and self.account.vat_class: self.vat_class = self.account.vat_class
@dd.virtualfield(dd.HtmlBox(_("Presences"))) def presences_box(self, ar): # not finished if ar is None: return '' pv = ar.param_values # if not pv.start_date or not pv.end_date: # return '' events = self.events_by_course.order_by('start_date') events = rt.modules.system.PeriodEvents.started.add_filter(events, pv) return "TODO: copy logic from presence_sheet.wk.html" # customize fields coming from mixins to override their inherited # default verbose_names dd.update_field(Course, 'every_unit', default=models.NOT_PROVIDED) dd.update_field(Course, 'every', default=models.NOT_PROVIDED) if FILL_EVENT_GUESTS: @dd.receiver(dd.post_save, sender=cal.Event, dispatch_uid="fill_event_guests_from_course") def fill_event_guests_from_course(sender=None, instance=None, **kw): #~ logger.info("20130528 fill_event_guests_from_course") if settings.SITE.loading_from_dump: return event = instance if event.is_user_modified(): return if event.is_fixed_state():
""", size=(60, 'auto')) rt.models.countries.Places.detail_layout = """ name country type parent zip_code id PlacesByPlace contacts.PartnersByCity """ rt.models.courses.AllEnrolments.column_names = \ 'id #request_date #start_date #end_date #user course \ pupil__birth_date pupil__age pupil__country pupil__city \ pupil__gender state' dd.update_field(rt.models.contacts.Partner, 'language', verbose_name=_("Contact language")) # rt.models.cv.LanguageKnowledgesByPerson.display_mode = 'grid' from lino_avanti.lib.avanti.roles import ClientsUser if dd.is_installed('calview'): rt.models.calview.CalendarView.required_roles = dd.login_required( ClientsUser) rt.models.calview.DailySlaveBase.required_roles = dd.login_required( ClientsUser) if dd.is_installed('extensible'): rt.models.extensible.CalendarPanel.required_roles = dd.login_required( ClientsUser)
@dd.chooser() def type_choices(self, upload_area): M = dd.resolve_model('uploads.UploadType') # logger.info("20140430 type_choices %s", upload_area) if upload_area is None: return M.objects.all() return M.objects.filter(upload_area=upload_area) def save(self, *args, **kw): if self.type is not None: self.upload_area = self.type.upload_area super(Upload, self).save(*args, **kw) dd.update_field(Upload, 'user', verbose_name=_("Uploaded by")) class Uploads(dd.Table): model = 'uploads.Upload' required_roles = dd.login_required((OfficeUser, OfficeOperator)) column_names = "file type user owner description *" order_by = ['-id'] detail_layout = dd.DetailLayout(""" file user volume:10 library_file:40 upload_area type description owner """, window_size=(80, 'auto'))
"created": self.created.strftime("%a %d %b %Y %H:%M"), } # Encode and send that message to the whole channels Group for our # Websocket. Note how you can send to a channel or Group from any part # of Django, not just inside a consumer. from channels import Group Group(user.username).send({ # WebSocket text frame, with JSON content "text": json.dumps(message), }) return dd.update_field(Message, 'user', verbose_name=_("Recipient"), editable=False) # Message.update_controller_field( # null=True, blank=True, verbose_name=_("About")) dd.inject_field('users.User', 'notify_myself', models.BooleanField(_('Notify myself'), default=False)) dd.inject_field( 'users.User', 'mail_mode', MailModes.field(_('Email notification mode'), default=MailModes.often.as_callable)) class Messages(dd.Table): "Base for all tables of messages." model = 'notify.Message'
fields.update(start_date=models.DateField( _("Period from"), blank=True, null=True, help_text=_("Start date of observed period"))) fields.update(end_date=models.DateField( _("until"), blank=True, null=True, help_text=_("End date of observed period"))) # fields.update( # show_published=dd.YesNo.field(_("Published"), blank=True)) super(Comment, cls).setup_parameters(fields) @classmethod def get_request_queryset(cls, ar, **filter): qs = super(Comment, cls).get_request_queryset(ar, **filter) pv = ar.param_values if pv.observed_event: qs = pv.observed_event.add_filter(qs, pv) # if pv.show_published == dd.YesNo.yes: # qs = qs.filter(published__isnull=False) # elif pv.show_published == dd.YesNo.no: # qs = qs.filter(published__isnull=True) return qs dd.update_field(Comment, 'user', editable=False) from .ui import *
if a is not None: return a if self.callme_mode: a = rt.models.users.OtherUsers.detail_action if a is not None and a.get_view_permission(ar.get_user().user_type): return a @dd.htmlbox(_("About me")) def about_me(self, ar): return self.remarks @classmethod def get_simple_parameters(cls): s = list(super(User, cls).get_simple_parameters()) s.append('user_state') return s # def get_default_table(self, ar): # tbl = super(User, self).get_default_table(ar) # return rt.models.users.OtherUsers # def __str__(self): # s = self.get_full_name() # if self.callme_mode: # if self.tel: # s += " ({})".format(self.tel) # return s dd.update_field('users.User', 'remarks', verbose_name=_("About me"))
class Meta: app_label = 'cal' abstract = dd.is_abstract_model(__name__, 'PlannerRow') verbose_name = _("Planner row") verbose_name_plural = _("Planner rows") ordering = ['seqno'] start_time = dd.TimeField( blank=True, null=True, verbose_name=_("Start time")) end_time = dd.TimeField( blank=True, null=True, verbose_name=_("End time")) dd.update_field(DailyPlannerRow, 'overview', verbose_name=_("Time range")) class RemoteCalendar(mixins.Sequenced): class Meta: app_label = 'cal' abstract = dd.is_abstract_model(__name__, 'RemoteCalendar') verbose_name = _("Remote Calendar") verbose_name_plural = _("Remote Calendars") ordering = ['seqno'] type = models.CharField(_("Type"), max_length=20, default='local', choices=CALENDAR_CHOICES) url_template = models.CharField(_("URL template"), max_length=200, blank=True) # ,null=True)
""" if not self.state: if ar.get_user() == self.user: self.state = VoteStates.watching else: self.state = VoteStates.invited super(Vote, self).on_create(ar) # def get_author(self): def get_row_permission(self, ar, state, ba): # we bypass the author check because return dd.Model.get_row_permission(self,ar, state, ba) dd.update_field(Vote, 'user', verbose_name=_("Voter")) class Votes(dd.Table): """Table parameters: .. attribute:: observed_event There are two class attributes for defining a filter conditions which canot be removed by the user: .. attribute:: filter_vote_states A set of vote states to require (i.e. to filter upon). This must resolve using :meth:`resolve_states <lino.core.model.Model.resolve_states>`.
def __str__(self): return "%s / %s" % (self.order, self.worker) def get_print_language(self): return self.worker.language def get_body_template(self): """Overrides :meth:`lino.core.model.Model.get_body_template`.""" return self.order.body_template def get_excerpt_title(self): return self.order.get_excerpt_title() dd.update_field( Enrolment, 'overview', verbose_name=Order._meta.verbose_name) dd.update_field(Enrolment, 'order', blank=True) @dd.receiver(dd.post_startup) def setup_memo_commands(sender=None, **kwargs): # See :doc:`/specs/memo` if not sender.is_installed('memo'): return Order = sender.models.orders.Order def cmd(parser, s): pk = s
def __str__(self): return "%s / %s" % (self.order, self.worker) def get_print_language(self): return self.worker.language def get_body_template(self): """Overrides :meth:`lino.core.model.Model.get_body_template`.""" return self.order.body_template def get_excerpt_title(self): return self.order.get_excerpt_title() dd.update_field( Enrolment, 'overview', verbose_name=Order._meta.verbose_name) dd.update_field(Enrolment, 'order', blank=True) @dd.receiver(dd.post_startup) def setup_memo_commands(sender=None, **kwargs): # See :doc:`/specs/memo` Order = sender.models.orders.Order def cmd(parser, s): pk = s txt = None
for coaching in qs: if coaching.type and coaching.type.eval_guestrole: u = coaching.user if u != event.user and u.partner is not None: yield Guest(event=event, partner=u.partner, role=coaching.type.eval_guestrole) @classmethod def get_printable_demo_objects(cls, excerpt_type): """All contracts of a demo project are being printed. Overrides :meth:`lino_xl.lib.excerpts.mixins.Certifiable.get_printable_demo_objects`. """ return cls.objects.all() dd.update_field(ContractBase, 'signer1', default=default_signer1) dd.update_field(ContractBase, 'signer2', default=default_signer2) class ContractBaseTable(dd.Table): """Base for contract tables. Defines the following parameter fields: .. attribute:: user .. attribute:: observed_event .. attribute:: ending Show only contracts with the specified :class:`ContractEnding <lino_welfare.modlib.isip.models.ContractEnding>`.
found = 0 for other in qs: found += 1 if limit is not None and found > limit: return ok = False for w in other.get_dupable_words(other.last_name): if w in last_name_words: ok = True break if ok: yield other dd.update_field(Client, 'user', verbose_name=_("Primary coach")) dd.update_field(Client, 'ref', verbose_name=_("Legacy file number")) class ClientDetail(dd.DetailLayout): main = "general person contact courses_tab family \ notes career trends #polls #courses misc db_tab" general = dd.Panel(""" general1:30 general2:40 image:15 cal.EntriesByProject cal.GuestsByPartner """, label=_("General"))
# # yield w(None, _("N/A")) # yield w(TOTAL_KEY, _("Total")) # # # class DayDetail(dd.DetailLayout): # main = "working.MySessionsByDay cal.PlannerByDay" # # class Event(Event, ContactRelated): class Meta: app_label = 'cal' abstract = dd.is_abstract_model(__name__, 'Event') dd.update_field(Event, 'user', verbose_name=_("Author")) dd.update_field(Event, 'company', verbose_name=_("Organizer")) dd.update_field(Event, 'contact_person', verbose_name=_("Contact person")) class RoomDetail(dd.DetailLayout): main = """ id name company contact_person description cal.EntriesByRoom """ Rooms.set_detail_layout(RoomDetail()) class EventDetail(EventDetail):
#~ description = dd.BabelTextField(format='plain',blank=True) url = models.URLField(blank=True) class Stage(mixins.Sequenced): event = dd.ForeignKey('events.Event', related_name="stages") city = dd.ForeignKey('countries.Place', related_name="stages") def __str__(self): return str(self.city) def get_siblings(self): return self.event.stages.all() dd.update_field(Event, 'name', blank=True) class StagesByEvent(dd.Table): model = Stage # Event.cities.through master_key = 'event' class FeaturesByEvent(dd.Table): model = Event.features.through master_key = 'event' class Events(dd.Table): model = Event order_by = ['date']
class Board(mixins.BabelNamed, mixins.DatePeriod): class Meta(object): verbose_name = _("Board") verbose_name_plural = _("Boards") def full_clean(self, *args, **kw): if not self.start_date: self.start_date = dd.today() super(Board, self).full_clean(*args, **kw) dd.update_field( Board, 'start_date', verbose_name=_("Works since"), null=False) dd.update_field(Board, 'end_date', verbose_name=_("Worked until")) class Boards(dd.Table): model = 'boards.Board' required_roles = dd.required(dd.SiteStaff, OfficeUser) column_names = 'name *' order_by = ["name"] insert_layout = """ name """ detail_layout = """
""" if bleach is None: chunks = [self.short_text] else: chunks = [bleach.clean(self.short_text, tags=self.ALLOWED_TAGS, strip=True)] by = (_("{0} by {1}").format(naturaltime(self.created), unicode(self.user)),) chunks += [" (", E.tostring(ar.obj2html(self, by)), ")"] if self.more_text: chunks.append(" (...)") html = "".join(chunks) return "<li>" + html + "</li>" dd.update_field(Comment, "user", editable=False) class Comments(dd.Table): required_roles = dd.required(dd.SiteStaff) slave_grid_format = "summary" model = "comments.Comment" insert_layout = dd.FormLayout( """ short_text """, window_size=(40, 10), )
# if qty is None: # qty = Duration(1) kw['product'] = product kw['qty'] = qty return super(SalesDocument, self).add_voucher_item(**kw) def get_excerpt_templates(self, bm): # Overrides lino_xl.lib.excerpts.mixins.Certifiable.get_excerpt_templates pt = self.paper_type or get_paper_type(self.partner) if pt and pt.template: # print(20190506, pt.template) return [pt.template] dd.update_field(SalesDocument, 'total_base', editable=False) dd.update_field(SalesDocument, 'total_vat', editable=False) dd.update_field(SalesDocument, 'total_incl', editable=False) def get_paper_type(obj): sr = getattr(obj, 'salesrule', None) if sr: return sr.paper_type class ProductDocItem(QtyVatItemBase): class Meta: abstract = True product = dd.ForeignKey('products.Product', blank=True, null=True)
# ~ description = dd.BabelTextField(format='plain',blank=True) url = models.URLField(blank=True) class Stage(mixins.Sequenced): event = dd.ForeignKey("events.Event", related_name="stages") city = dd.ForeignKey("countries.Place", related_name="stages") def __unicode__(self): return unicode(self.city) def get_siblings(self): return self.event.stages.order_by("seqno") dd.update_field(Event, "name", blank=True) class StagesByEvent(dd.Table): model = Stage # Event.cities.through master_key = "event" class FeaturesByEvent(dd.Table): model = Event.features.through master_key = "event" class Events(dd.Table): model = Event order_by = ["date"]
signer1_function = dd.ForeignKey( "contacts.RoleType", blank=True, null=True, verbose_name=_("First signer function"), help_text=_("""Contact function to designate the secretary."""), related_name="%(app_label)s_%(class)s_set_by_signer1") signer2_function = dd.ForeignKey( "contacts.RoleType", blank=True, null=True, verbose_name=_("Second signer function"), help_text=_( "Contact function to designate the president."), related_name="%(app_label)s_%(class)s_set_by_signer2") dd.update_field(SiteConfig, 'signer1', blank=True, null=True) dd.update_field(SiteConfig, 'signer2', blank=True, null=True) class SiteConfigDetail(dd.FormLayout): main = "general constants cbss" general = dd.Panel( """ site_company next_partner_id:10 job_office master_budget signer1 signer2 signer1_function signer2_function """, label=_("General"))
@classmethod def add_param_filter(cls, qs, lookup_prefix='', company=None, **kwargs): qs = super(Person, cls).add_param_filter(qs, **kwargs) if company: fkw = dict() wanted = company.whole_clan() fkw[lookup_prefix + 'rolesbyperson__company__in'] = wanted qs = qs.filter(**fkw) return qs # We use the `overview` field only in detail forms, and we # don't want it to have a label "Description": dd.update_field(Person, 'overview', verbose_name=None) class Company(Company, Hierarchical, Commentable): class Meta(Company.Meta): app_label = 'contacts' abstract = dd.is_abstract_model(__name__, 'Company') def get_overview_elems(self, ar): elems = super(Company, self).get_overview_elems(ar) elems += ContactDetailsOwner.get_overview_elems(self, ar) return elems class PersonDetail(PersonDetail):
#~ register_action = None #~ deregister_action = None def before_state_change(self, ar, old, new): if new.name == 'registered': if self.get_existing_auto_events().count() == 0: #~ ar.confirm("Booking has no events! Are you sure?") raise Warning("Booking has no events!") def after_ui_save(self, ar, cw): super(Booking, self).after_ui_save(ar, cw) if self.state.editable: self.update_reminders(ar) dd.update_field(Booking, 'contact_person', verbose_name=_("Contact person")) dd.update_field(Booking, 'company', verbose_name=_("Organizer")) dd.update_field(Booking, 'every_unit', default=Recurrencies.once.as_callable) dd.update_field(Booking, 'every', default=1) class BookingDetail(dd.FormLayout): #~ start = "start_date start_time" #~ end = "end_date end_time" #~ freq = "every every_unit" #~ start end freq main = "general sales.InvoicingsByInvoiceable" general = dd.Panel(""" start_date start_time end_date end_time room event_type workflow_buttons max_events max_date every_unit every
#~ description = dd.BabelTextField(format='plain',blank=True) url = models.URLField(blank=True) @dd.python_2_unicode_compatible class Stage(mixins.Sequenced): event = dd.ForeignKey('events.Event', related_name="stages") city = dd.ForeignKey('countries.Place', related_name="stages") def __str__(self): return str(self.city) def get_siblings(self): return self.event.stages.all() dd.update_field(Event, 'name', blank=True) class StagesByEvent(dd.Table): model = Stage # Event.cities.through master_key = 'event' class FeaturesByEvent(dd.Table): model = Event.features.through master_key = 'event' class Events(dd.Table): model = Event order_by = ['date']
class Meta: app_label = 'groups' abstract = dd.is_abstract_model(__name__, 'Membership') verbose_name = _("Group membership") verbose_name_plural = _("Group memberships") group = dd.ForeignKey('groups.Group', related_name="members") remark = models.CharField(_("Remark"), max_length=200, blank=True) allow_cascaded_delete = ['site', 'user','group'] def __str__(self): return _('{} in {}').format(self.user, self.group) dd.update_field(Membership, "user", verbose_name=_("User")) class Memberships(dd.Table): model = 'groups.Membership' insert_layout = dd.InsertLayout(""" user group remark """, window_size=(60, 'auto')) detail_layout = dd.DetailLayout(""" user group remark """, window_size=(60, 'auto'))
verbose_name_plural = _("Authorities") authorized = dd.ForeignKey(settings.SITE.user_model) @dd.chooser() def authorized_choices(cls, user): qs = settings.SITE.user_model.objects.exclude( user_type=None) #~ user_type=UserTypes.blank_item) 20120829 if user is not None: qs = qs.exclude(id=user.id) #~ .exclude(level__gte=UserLevels.admin) return qs dd.update_field(Authority, 'user', null=False) @dd.receiver(dd.pre_startup) def inject_partner_field(sender=None, **kwargs): User = sender.models.users.User if dd.is_installed('contacts'): Partner = sender.models.contacts.Partner if not issubclass(User, Partner): dd.inject_field(User, 'partner', dd.ForeignKey( 'contacts.Partner', blank=True, null=True, related_name='users_by_partner', on_delete=models.PROTECT)) # a related_name is needed so that Avanti can have aClient # who inherits from both Partner and UserAuthored
- :attr:`user` - :attr:`summary` - :attr:`start_date`, NB: also :attr:`start_time` :attr:`end_date`, :attr:`end_time`? """ if self.end_date and self.end_date != self.start_date: duration = self.end_date - self.start_date event.end_date = event.start_date + duration # if "Weekends" in str(event.owner): # dd.logger.info("20180321 %s", self.end_date) else: event.end_date = None dd.update_field(RecurrenceSet, 'start_date', default=dd.today) from lino.core.workflows import Workflow class ReservationStates(Workflow): is_editable = models.BooleanField(_("Editable"), default=True) class Reservation(RecurrenceSet, EventGenerator, mixins.Registrable, UserAuthored): class Meta: abstract = True room = dd.ForeignKey('cal.Room', blank=True, null=True) max_date = models.DateField(
fkw = dict() wanted = topic.whole_clan() fkw[lookup_prefix + 'interest_set__topic__in'] = wanted return qs # @classmethod # def get_request_queryset(cls, ar): # qs = super(Person, cls).get_request_queryset(ar) # pv = ar.param_values # if pv.skill: # return qs # We use the `overview` field only in detail forms, and we # don't want it to have a label "Description": dd.update_field(Person, 'overview', verbose_name=None) class Company(Company, Hierarchical, Commentable): class Meta(Company.Meta): app_label = 'contacts' abstract = dd.is_abstract_model(__name__, 'Company') # def get_overview_elems(self, ar): # elems = super(Company, self).get_overview_elems(ar) # # elems += AddressOwner.get_overview_elems(self, ar) # elems += ContactDetailsOwner.get_overview_elems(self, ar) # return elems class PersonDetail(PersonDetail):
def presences_box(self, ar): # not finished if ar is None: return '' pv = ar.param_values # if not pv.start_date or not pv.end_date: # return '' events = self.events_by_course().order_by('start_date') events = rt.models.system.PeriodEvents.started.add_filter(events, pv) return "TODO: copy logic from presence_sheet.wk.html" # customize fields coming from mixins to override their inherited # default verbose_names dd.update_field(Course, 'every_unit', default=models.NOT_PROVIDED) dd.update_field(Course, 'every', default=models.NOT_PROVIDED) if FILL_EVENT_GUESTS: @dd.receiver(dd.post_save, sender=cal.Event, dispatch_uid="fill_event_guests_from_course") def fill_event_guests_from_course(sender=None, instance=None, **kw): #~ logger.info("20130528 fill_event_guests_from_course") if settings.SITE.loading_from_dump: return event = instance if event.is_user_modified(): return if event.is_fixed_state():
#~ s = contacts.ContactDocument.summary_row(self,ui,rr) if self.subject: s += [' ', self.subject] return s def get_mailable_type(self): return self.type def get_print_language(self): return self.language if dd.is_installed('contacts'): dd.update_field(Note, 'company', verbose_name=_("Recipient (Organization)")) dd.update_field(Note, 'contact_person', verbose_name=_("Recipient (Person)")) # def html_text(s): # return '<div class="htmlText">' + s + '</div>' class NoteDetail(dd.DetailLayout): main = """ date:10 time event_type:25 type:25 subject project company contact_person contact_role id user:10 language:8 build_time
return cls.for_master_model(master_model, **kw) def after_ui_create(self, ar): #Needed for when creating Tickets for other Users on a table-view. self.create_children(ar) super(Star, self).after_ui_create(ar) @dd.displayfield(_("Stared Because")) def master_owner(self, ar): if ar is None: return None return ar.obj2html(self.master.owner) if self.master is not None else "" def __str__(self): return _("{} starring {}").format(self.user, self.owner) dd.update_field(Star, 'user', verbose_name=_("User"), blank=False, null=False) dd.update_field(Star, 'owner', verbose_name=_("Starred object")) Star.update_controller_field(blank=False, null=False) class Stars(dd.Table): model = 'stars.Star' column_names = "id owner user nickname master_owner *" parameters = dict( type=dd.ForeignKey(ContentType, blank=True, null=True), inherited_stars=dd.YesNo.field(_("inherited stars"), blank=True, null=True) ) # params_layout = """""" @classmethod
def summary_row(self, ar, **kw): # ~ s = super(Note,self).summary_row(ui,rr) s = super(Note, self).summary_row(ar) # ~ s = contacts.ContactDocument.summary_row(self,ui,rr) if self.subject: s += [" ", self.subject] return s def get_mailable_type(self): return self.type def get_print_language(self): return self.language dd.update_field(Note, "company", verbose_name=_("Recipient (Organization)")) dd.update_field(Note, "contact_person", verbose_name=_("Recipient (Person)")) def html_text(s): return '<div class="htmlText">' + s + "</div>" class NoteDetail(dd.FormLayout): main = """ date:10 time event_type:25 type:25 subject project company contact_person contact_role id user:10 language:8 build_time body:40 outbox.MailsByController:40 """
#~ flt = flt | models.Q(type=PlaceTypes.blank_item) return cls.objects.filter(flt).order_by('name') #~ if country is not None: #~ cd = getattr(CountryDrivers,country.isocode,None) #~ if cd: #~ return Place.objects.filter( #~ country=country, #~ type__in=cd.city_types).order_by('name') #~ return country.place_set.order_by('name') #~ return cls.city.field.rel.model.objects.order_by('name') dd.update_field(Place, 'parent', verbose_name=_("Part of"), help_text=_("The superordinate geographic place " "of which this place is a part.")) class Places(dd.Table): help_text = _(""" The table of known geographical places. A geographical place can be a city, a town, a suburb, a province, a lake... any named geographic entity, except for countries because these have their own table. """) model = 'countries.Place' required_roles = dd.login_required(ContactsStaff) order_by = "country name".split()
related_name="%(app_label)s_%(class)s_set_by_type") goal = dd.ForeignKey("immersion.Goal", related_name="trainings") reference_person = models.CharField( _("reference person"), max_length=200, blank=True) responsibilities = dd.RichTextField( _("responsibilities"), blank=True, null=True, format='html') remark = models.TextField(_("Remark"), blank=True) # @dd.chooser() # def company_choices(cls): # return rt.modules.jobs.JobProvider.objects.all() @classmethod def get_certifiable_fields(cls): return ( 'client company contact_person contact_role type ' 'applies_from applies_until ' 'language ' 'reference_person responsibilities ' 'user user_asd exam_policy ' 'date_decided date_issued ') dd.update_field(Contract, 'user', verbose_name=_("responsible (IS)")) dd.update_field(Contract, 'company', blank=False, null=False) from .ui import *
#~ flt = flt & models.Q(type__gte=PlaceTypes.get_by_value('50')) flt = flt & models.Q(type__in=types) #~ flt = flt | models.Q(type=PlaceTypes.blank_item) return cls.objects.filter(flt).order_by('name') #~ if country is not None: #~ cd = getattr(CountryDrivers,country.isocode,None) #~ if cd: #~ return Place.objects.filter( #~ country=country, #~ type__in=cd.city_types).order_by('name') #~ return country.place_set.order_by('name') #~ return cls.city.field.rel.model.objects.order_by('name') dd.update_field( Place, 'parent', verbose_name=_("Part of"), help_text=_("The superordinate geographic place " "of which this place is a part.")) class Places(dd.Table): help_text = _(""" The table of known geographical places. A geographical place can be a city, a town, a suburb, a province, a lake... any named geographic entity, except for countries because these have their own table. """) model = 'countries.Place' required_roles = dd.login_required(ContactsStaff) order_by = "country name".split() column_names = "country name type zip_code parent *"