:date: 2017-04-01 15:14

=======================
Saturday, April 1, 2017
=======================

Inviting others to vote
=======================

Lino can now automatically create "vote invitations" (i.e. votes
having a new state "invited").  I added two other new vote states
"pro" and "con".  And we have a new table "My vote invitations" which
basically asks the user to choose one of four options:

- Cancelled : not interested. You declare that you don't want to be
  bothered with this ticket.
- Watching : You are interested, you are neutral and did not
  yet declare your opinion. You want to be notified when
  something happens in this ticket.
- Pro : optimistically watching. You declare that you want this ticket
  to get *done*. You support this ticket.
- Con : skeptically watching. You declare that you want this ticket to
  get *refused*.

The pro and con states are not yet used, but I plan to also make the
number of pro, con and watching votes visible in the WishesByMilestone
view. So you can do polls in Noi by formulating your questions as
tickets, creating an activity and adding them as tickets, and then
adding enrolments to your activity. The participants will
automatically be invited to vote. Note that you must click the Save
button of the activity for Lino to create vote invitations.

I updated the specs about this: :ref:`specs.noi.votes`.


- I added a new method :meth:`Commentable.on_commented
  <lino.modlib.comments.mixins.Commentable.on_commented>`.  And
  :class:`Votable <lino_xl.lib.votes.mixins.Votable>` now invites the
  comment's author to vote on this votable.

- Similar system for :meth:`Workable.on_worked
  <lino_xl.lib.clocking.mixins.Workable.on_worked>`.

- I changed the label of the ticket state "Cancelled" to "Refused".

- The label of a :class:`lino.core.workflows.ChangeStateAction` is now
  being inherited from its :attr:`target_state`. Don't ask me why I
  didn't see this earlier.


Vocabulary and translations
===========================

I did a series of renames, without (yet) changing any model names.

Especially in the :mod:`lino_xl.lib.cal` plugin I started to tidy up
with the obsolete term "calendar event". This word is still being used
in many places for what should actually be called a "calendar
entry". For example::

    MyEvents -> MyEntries
    AllEvents  -> AllEntries
    PublicEvents -> PublicEntries
    EventsByRoom -> EntriesByRoom
    Events -> Entries
    EventsByDay -> EntriesByDay

    EventStates -> CalendarEntryStates

    MoveEventNext -> MoveEntryNext

    ConflictingEvents -> ConflictingEntries

    EventChecker -> EntryChecker

I also changed some translatable messages::

    Calendar Event Types -> Calendar entry types
    Event label -> Entry label

    Event Policy -> Recurrency policy
    Recurrent event rule -> Recurring event


And then our :mod:`lino_xl.lib.courses` plugin. The name "courses" is
really wrong because already :ref:`voga` uses the :class:`Course`
model also for "travels" and "hikes". They use the word "activities"
(Aktivitäten) as the general term. In :ref:`cpaschatelet` they use almost
the same thing and call it "workshops" (ateliers). Lino Noi uses it to
organize sprints and meetings. Meanwhile I think that the best general
term is "Events" (Veranstaltungen, Évènements, Üritused). I am now
trying to evolve step by step towards my final goal which is to have
"events" which generate "calendar entries". All in all it is still a
big chaos, but only for the developer.


How to disable all fields except some::


    class Message(dd.Model):

        _disabled_fields = set('body sender subject ...'.split())

        def disabled_fields(self, ar):
            # fields = super(Message, self).disabled_fields(ar)
            # fields |= self._disabled_fields
            return self._disabled_fields



Today I discovered a cool thing: I can override the label of a remote
field using update_field. sed for `Session.ticket__id`.