Beispiel #1
0
def setup_client_workflow(sender=None, **kw):
    """Set up workflow for :class:`ClientStates
    <lino_welfare.modlib.pcsw.choicelists.ClientStates>`.

    """
    # ClientStates.refused.add_transition(RefuseClient)
    # ClientStates.former.add_transition(MarkClientFormer)
    ClientStates.newcomer.add_transition(
        required_states='former',
        required_roles=dd.required(NewcomersAgent))
Beispiel #2
0
    courses.CourseRequestsByPerson
    """, label=_("Languages"))

    competences = dd.Panel("""
    cv.SkillsByPerson cv.SoftSkillsByPerson skills
    cv.ObstaclesByPerson obstacles badges.AwardsByHolder
    """, label=_("Competences"), required_roles=dd.required(IntegrationAgent))

    contracts = dd.Panel("""
    isip.ContractsByClient
    jobs.CandidaturesByPerson
    jobs.ContractsByClient
    """, label=_("Contracts"))

if settings.SITE.is_installed('cbss'):
    ClientDetail.main += ' cbss'
    ClientDetail.cbss = dd.Panel("""
cbss_identify_person cbss_manage_access cbss_retrieve_ti_groups
cbss_summary
    """, label=_("CBSS"), required_roles=dd.required(SocialAgent))


Clients.detail_layout = ClientDetail()

ClientContactTypes.detail_layout = """
id name can_refund is_bailiff
contacts.PartnersByClientContactType
pcsw.ClientContactsByType
"""
ClientContactTypes.column_names = "id name can_refund is_bailiff"
Beispiel #3
0
class PropTypes(dd.Table):
    required_roles = dd.required(dd.SiteStaff)
    model = PropType
    detail_layout = """
Beispiel #4
0
class MyComments(My, Comments):
    required_roles = dd.required(OfficeUser)
    auto_fit_column_widths = True
    order_by = ["modified"]
    column_names = "modified short_text owner *"
Beispiel #5
0
class CommentsByX(Comments):
    required_roles = dd.required(OfficeUser)
    order_by = ["-created"]
Beispiel #6
0
class AllExcerpts(Excerpts):
    required_roles = dd.required(SiteAdmin, OfficeStaff)
    column_names = ("id excerpt_type owner project "
                    "company language build_time *")
Beispiel #7
0
class Languages(dd.Table):
    model = 'languages.Language'
    required_roles = dd.required(OfficeUser)
Beispiel #8
0
class DebtorsCreditors(dd.VirtualTable):
    """
    Abstract base class for different tables showing a list of
    partners with the following columns:

      partner due_date balance actions


    """
    required_roles = dd.required(AccountingReader)
    auto_fit_column_widths = True
    column_names = "age due_date partner partner_id balance vouchers"
    slave_grid_format = 'html'
    abstract = True

    parameters = mixins.Today()
    # params_layout = "today"

    d_or_c = NotImplementedError

    @classmethod
    def rowmvtfilter(self, row):
        raise NotImplementedError()

    @classmethod
    def get_data_rows(self, ar):
        rows = []
        mi = ar.master_instance
        if mi is None:  # called directly from main menu
            if ar.param_values is None:
                return rows
            end_date = ar.param_values.today
        else:  # called from Situation report
            end_date = mi.today

        qs = rt.modules.contacts.Partner.objects.order_by('name')
        for row in qs:
            row._balance = ZERO
            row._due_date = None
            row._expected = tuple(
                get_due_movements(self.d_or_c,
                                  partner=row,
                                  value_date__lte=end_date))
            for dm in row._expected:
                row._balance += dm.balance
                if dm.due_date is not None:
                    if row._due_date is None or row._due_date > dm.due_date:
                        row._due_date = dm.due_date
                # logger.info("20140105 %s %s", row, dm)

            if row._balance > ZERO:
                rows.append(row)

        def k(a):
            return a._due_date

        rows.sort(key=k)
        return rows

    # @dd.displayfield(_("Partner"))
    # def partner(self, row, ar):
    #     return ar.obj2html(row)

    @dd.virtualfield(models.ForeignKey('contacts.Partner'))
    def partner(self, row, ar):
        return row

    @dd.virtualfield(models.IntegerField(_("ID")))
    def partner_id(self, row, ar):
        return row.pk

    @dd.virtualfield(dd.PriceField(_("Balance")))
    def balance(self, row, ar):
        return row._balance

    @dd.virtualfield(models.DateField(_("Due date")))
    def due_date(self, row, ar):
        return row._due_date

    @dd.virtualfield(models.IntegerField(_("Age")))
    def age(self, row, ar):
        dd = ar.param_values.today - row._due_date
        return dd.days

    @dd.displayfield(_("Vouchers"))
    def vouchers(self, row, ar):
        matches = [dm.match for dm in row._expected]
        return E.span(', '.join(matches))
Beispiel #9
0
class ExpectedMovements(dd.VirtualTable):
    """
    A virtual table of :class:`DueMovement` rows, showing
    all "expected" "movements (payments)".

    Subclassed by :class:`lino_cosi.lib.finan.models.SuggestionsByVoucher`.


    """
    row_height = 4
    required_roles = dd.required(AccountingReader)
    label = _("Debts")
    icon_name = 'book_link'
    #~ column_names = 'match due_date debts payments balance'
    column_names = 'due_date:15 balance debts payments'
    auto_fit_column_widths = True
    # variable_row_height = True
    parameters = dd.ParameterPanel(
        date_until=models.DateField(_("Date until"), blank=True, null=True),
        trade_type=TradeTypes.field(blank=True),
        from_journal=dd.ForeignKey('ledger.Journal', blank=True),
        for_journal=dd.ForeignKey('ledger.Journal',
                                  blank=True,
                                  verbose_name=_("Clearable by")),
        account=dd.ForeignKey('accounts.Account', blank=True),
        partner=dd.ForeignKey('contacts.Partner', blank=True),
        project=dd.ForeignKey(dd.plugins.ledger.project_model, blank=True),
    )
    params_layout = "trade_type date_until from_journal " \
                    "for_journal project partner account"

    @classmethod
    def get_dc(cls, ar=None):
        return DEBIT

    @classmethod
    def get_data_rows(cls, ar, **flt):
        #~ if ar.param_values.journal:
        #~ pass
        pv = ar.param_values
        # if pv is None:
        #     raise Exception("No pv in %s" % ar)
        if pv.trade_type:
            flt.update(account=pv.trade_type.get_partner_account())
        if pv.partner:
            flt.update(partner=pv.partner)
        if pv.account:
            flt.update(account=pv.account)
        if pv.project:
            flt.update(project=pv.project)
        if pv.date_until is not None:
            flt.update(value_date__lte=pv.date_until)
        if pv.for_journal is not None:
            accounts = rt.modules.accounts.Account.objects.filter(
                matchrule__journal=pv.for_journal).distinct()
            flt.update(account__in=accounts)
        if pv.from_journal is not None:
            flt.update(voucher__journal=pv.from_journal)
        return get_due_movements(cls.get_dc(ar), **flt)

    @classmethod
    def get_pk_field(self):
        return rt.modules.ledger.Movement._meta.pk

    @classmethod
    def get_row_by_pk(cls, ar, pk):
        # for i in ar.data_iterator:
        #     if i.id == pk:
        #         return i
        # raise Exception("Not found: %s in %s" % (pk, ar))
        mvt = rt.modules.ledger.Movement.objects.get(pk=pk)
        dm = DueMovement(cls.get_dc(ar), mvt)
        dm.collect_all()
        return dm

    @dd.displayfield(_("Info"))
    def info(self, row, ar):
        elems = []
        if row.project:
            elems.append(ar.obj2html(row.project))
        if row.partner:
            elems.append(ar.obj2html(row.partner))
            # elems.append(row.partner.address)
        if row.bank_account:
            elems.append(ar.obj2html(row.bank_account))
        if row.account:
            elems.append(ar.obj2html(row.account))
        # return E.span(*join_elems(elems, ' / '))
        return E.span(*join_elems(elems, E.br))
        # return E.span(*elems)

    @dd.displayfield(_("Match"))
    def match(self, row, ar):
        return row.match

    @dd.virtualfield(
        models.DateField(
            _("Due date"),
            help_text=_("Due date of the eldest debt in this match group")))
    def due_date(self, row, ar):
        return row.due_date

    @dd.displayfield(_("Debts"),
                     help_text=_("List of invoices in this match group"))
    def debts(self, row, ar):
        return E.span(*join_elems([  # E.p(...) until 20150128
            ar.obj2html(i.voucher.get_mti_leaf()) for i in row.debts
        ]))

    @dd.displayfield(_("Payments"),
                     help_text=_("List of payments in this match group"))
    def payments(self, row, ar):
        return E.span(*join_elems([  # E.p(...) until 20150128
            ar.obj2html(i.voucher.get_mti_leaf()) for i in row.payments
        ]))

    @dd.virtualfield(dd.PriceField(_("Balance")))
    def balance(self, row, ar):
        return row.balance

    @dd.virtualfield(dd.ForeignKey('contacts.Partner'))
    def partner(self, row, ar):
        return row.partner

    @dd.virtualfield(dd.ForeignKey(dd.plugins.ledger.project_model))
    def project(self, row, ar):
        return row.project

    @dd.virtualfield(dd.ForeignKey('accounts.Account'))
    def account(self, row, ar):
        return row.account

    @dd.virtualfield(
        dd.ForeignKey('sepa.Account', verbose_name=_("Bank account")))
    def bank_account(self, row, ar):
        return row.bank_account
Beispiel #10
0
class MyTextFieldTemplates(TextFieldTemplates, ByUser):
    required_roles = dd.required(OfficeUser)
Beispiel #11
0
class CivilStates(dd.ChoiceList):
    """The global list of **civil states** that a client can have.  This
    is the list of choices for the :attr:`civil_state
    <lino_welfare.modlib.pcsw.models.Client.civil_state>` field of a
    :class:`Client <lino_welfare.modlib.pcsw.models.Client>`.

    **The four official civil states** according to Belgian law are:

    .. attribute:: single

        célibataire : vous n’avez pas de partenaire auquel vous êtes
        officiellement lié

    .. attribute:: married

        marié(e) : vous êtes légalement marié

    .. attribute:: widowed

        veuf (veuve) / Verwitwet : vous êtes légalement marié mais
        votre partenaire est décédé

    .. attribute:: divorced

        divorcé(e) (Geschieden) : votre mariage a été juridiquement dissolu

    **Some institutions define additional civil states** for people
    who are officially still married but at different degrees of
    separation:

    .. attribute:: de_facto_separated

        De facto separated (Séparé de fait, faktisch getrennt)

        Des conjoints sont séparés de fait lorsqu'ils ne respectent
        plus le devoir de cohabitation. Leur mariage n'est cependant
        pas dissous.

        La notion de séparation de fait n'est pas définie par la
        loi. Toutefois, le droit en tient compte dans différents
        domaines, par exemple en matière fiscale ou en matière de
        sécurité sociale (assurance maladie invalidité, allocations
        familiales, chômage, pension, accidents du travail, maladies
        professionnelles).

    .. attribute:: separated

        Legally separated, aka "Separated as to property" (Séparé de
        corps et de biens, Getrennt von Tisch und Bett)

        La séparation de corps et de biens est une procédure
        judiciaire qui, sans dissoudre le mariage, réduit les droits
        et devoirs réciproques des conjoints.  Le devoir de
        cohabitation est supprimé.  Les biens sont séparés.  Les
        impôts sont perçus de la même manière que dans le cas d'un
        divorce. Cette procédure est devenue très rare.

    **Another unofficial civil state** (but relevant in certain
    situations) is:

    .. attribute:: cohabitating

        Cohabitating (cohabitant, zusammenlebend)

        Vous habitez avec votre partenaire et c’est
        reconnu légalement.

    Sources for above: `belgium.be
    <http://www.belgium.be/fr/famille/couple/divorce_et_separation/separation_de_fait/>`__,
    `gouv.qc.ca
    <http://www4.gouv.qc.ca/EN/Portail/Citoyens/Evenements/separation-divorce/Pages/separation-fait.aspx>`__,
    `wikipedia.org <https://en.wikipedia.org/wiki/Cohabitation>`__

    """
    required_roles = dd.required(dd.SiteStaff)
    verbose_name = _("Civil state")
    verbose_name_plural = _("Civil states")

    @classmethod
    def old2new(cls, old):
        """
        **Migration rules** (October 2015) to remove some obsolete choices:

        - 13 (Single cohabitating) becomes :attr:`cohabitating`
        - 18 (Single with child) becomes :attr:`single`
        - 21 (Married (living alone)) becomes :attr:`separated_de_facto`
        - 22 (Married (living with another partner)) becomes :attr:`separated_de_facto`
        - 33 (Widow cohabitating) becomes :attr:`widowed`

        """
        if old == '13':
            return cls.cohabitating
        if old == '18':
            return cls.single
        if old == '21':
            return cls.separated_de_facto
        if old == '22':
            return cls.separated_de_facto
        if old == '33':
            return cls.widowed
        return cls.get_by_value(old)

    @classmethod
    def to_python(cls, value):
        """This will call :meth:`old2new` when loading data from previous
        version. Can be removed when all production sites have been
        migrated.

        """
        if value:
            return cls.old2new(value)
        return None
Beispiel #12
0
class UploadAreas(dd.ChoiceList):
    required_roles = dd.required(OfficeStaff)
    verbose_name = _("Upload Area")
    verbose_name_plural = _("Upload Areas")