Ejemplo n.º 1
0
def show_excerpts(severe=True):
    ses = rt.login()
    # dd.logger.info("20141029 %s", settings.SITE)
    coll = {}
    
    def collect(obj):
        l = coll.setdefault(obj.excerpt_type, [])
        if len(l) > 2:
            return
        try:
            rv = ses.run(obj.do_print)
        except Warning as e:
            return
        if rv['success']:
            pass
            # print("\n\n%s\n\n" % rv['open_url'])
        else:
            if severe:
                raise Exception("Oops: %s" % rv['message'])
            else:
                return
        if not 'open_url' in rv:
            if severe:
                raise Exception("Oops: %s" % rv['message'])
            else:
                return
            
        # tmppath = settings.SITE.project_dir + rv['open_url']
        tmppath = settings.SITE.cache_dir
        if not 'media' in rv['open_url']:
        # if not tmppath.endswith('media'):
            tmppath = tmppath.child('media')
        tmppath += rv['open_url']
        head, tail = os.path.split(tmppath)
        # tail = 'tested/' + tail
        tail = 'dl/excerpts/' + tail
        kw = dict(tail=tail)
        kw.update(type=obj.excerpt_type)
        kw.update(owner=obj.owner)
        try:
            # dd.logger.info("20141029 copy %s to %s", tmppath, tail)
            shutil.copyfile(tmppath, tail)
        except IOError as e:
            kw.update(error=str(e))
            msg = "%(type)s %(owner)s %(tail)s Oops: %(error)s" % kw
            # raise Exception(msg)
            kw.update(owner=msg)

        l.append(kw)

    for o in rt.models.excerpts.Excerpt.objects.order_by('excerpt_type'):
        collect(o)

    def asli(et, items):
        s = str(et)
        s += " : " + ', '.join(
            "`%(owner)s <../%(tail)s>`__" % kw % kw for kw in items)
        return s

    return rstgen.ul([asli(k, v) for k, v in coll.items()])
Ejemplo n.º 2
0
 def handle(self, *args, **options):
     settings.SITE.startup()
     ar = rt.login()
     # fn = rt.find_config_file("status.jinja.rst", "jinja")
     fn = "jinja/status.jinja.rst"
     context = ar.get_printable_context()
     print(dd.plugins.jinja.render_jinja(ar, fn, context))
Ejemplo n.º 3
0
def show_excerpts(severe=True):
    ses = rt.login()
    # dd.logger.info("20141029 %s", settings.SITE)
    coll = {}

    def collect(obj):
        l = coll.setdefault(obj.excerpt_type, [])
        if len(l) > 2:
            return
        try:
            rv = ses.run(obj.do_print)
        except Warning as e:
            return
        if rv['success']:
            pass
            # print("\n\n%s\n\n" % rv['open_url'])
        else:
            if severe:
                raise Exception("Oops: %s" % rv['message'])
            else:
                return
        if not 'open_url' in rv:
            if severe:
                raise Exception("Oops: %s" % rv['message'])
            else:
                return

        # tmppath = settings.SITE.project_dir + rv['open_url']
        tmppath = settings.SITE.cache_dir
        if not 'media' in rv['open_url']:
            # if not tmppath.endswith('media'):
            tmppath = tmppath.child('media')
        tmppath += rv['open_url']
        head, tail = os.path.split(tmppath)
        # tail = 'tested/' + tail
        tail = 'dl/excerpts/' + tail
        kw = dict(tail=tail)
        kw.update(type=obj.excerpt_type)
        kw.update(owner=obj.owner)
        try:
            # dd.logger.info("20141029 copy %s to %s", tmppath, tail)
            shutil.copyfile(tmppath, tail)
        except IOError as e:
            kw.update(error=str(e))
            msg = "%(type)s %(owner)s %(tail)s Oops: %(error)s" % kw
            # raise Exception(msg)
            kw.update(owner=msg)

        l.append(kw)

    for o in rt.models.excerpts.Excerpt.objects.order_by('excerpt_type'):
        collect(o)

    def asli(et, items):
        s = str(et)
        s += " : " + ', '.join("`%(owner)s <../%(tail)s>`__" % kw % kw
                               for kw in items)
        return s

    return rstgen.ul([asli(k, v) for k, v in coll.items()])
Ejemplo n.º 4
0
 def send_summary_emails(cls, mm):
     qs = cls.objects.filter(sent__isnull=True)
     qs = qs.exclude(user__email='')
     qs = qs.filter(mail_mode=mm).order_by('user')
     if qs.count() == 0:
         return
     from lino.core.renderer import MailRenderer
     ar = rt.login(renderer=MailRenderer())
     context = ar.get_printable_context()
     sender = settings.SERVER_EMAIL
     template = rt.get_template('notify/summary.eml')
     users = dict()
     for obj in qs:
         lst = users.setdefault(obj.user, [])
         lst.append(obj)
     dd.logger.debug(
         "Send out %s summaries for %d users.", mm, len(users))
     for user, messages in users.items():
         with translation.override(user.language):
             if len(messages) == 1:
                 subject = messages[0].subject
             else:
                 subject = _("{} notifications").format(len(messages))
             subject = settings.EMAIL_SUBJECT_PREFIX + subject
             context.update(user=user, messages=messages)
             body = template.render(**context)
             # dd.logger.debug("20170112 %s", body)
             rt.send_email(subject, sender, body, [user.email])
             for msg in messages:
                 msg.sent = timezone.now()
                 msg.save()
Ejemplo n.º 5
0
def objects():

    ses = rt.login('wilfried')
    dd.plugins.b2c.import_statements_path = HERE
    settings.SITE.site_config.import_b2c(ses)

    # That file contains a few dozen of accounts which are now
    # "orphaned".  We are now going to assign theses accounts to a
    # random partner TODO: find a more realistic rule for selecting
    # the candidates. The filter might be a plugin attribute.

    IA = rt.modules.b2c.Account
    SA = rt.modules.sepa.Account
    PARTNERS = Cycler(rt.modules.contacts.Partner.objects.all())

    count = 0
    for ia in IA.objects.all():
        try:
            SA.objects.get(iban=ia.iban)
        except SA.DoesNotExist:
            yield SA(partner=PARTNERS.pop(), iban=ia.iban)
            count += 1
    if count == 0:
        dd.logger.info("%d statements",
                       rt.modules.b2c.Statement.objects.count())
        raise Exception(
            "There's something wrong: no accounts have been imported")
Ejemplo n.º 6
0
def objects():
    ExcerptType = rt.modules.excerpts.ExcerptType
    Excerpt = rt.modules.excerpts.Excerpt

    if not dd.plugins.excerpts.responsible_user:
        return

    ses = rt.login(dd.plugins.excerpts.responsible_user)

    for et in ExcerptType.objects.all():
        model = et.content_type.model_class()
        if issubclass(model, Certifiable):
            qs = model.get_printable_demo_objects(et)
        else:
            qs = model.objects.all()
            if qs.count() > 0:
                qs = [qs[0]]

        for obj in qs:
            ses.selected_rows = [obj]
            yield et.get_or_create_excerpt(ses)
        # qs2 = Excerpt.objects.filter(excerpt_type=et)
        # if qs2.count() == 0:
        #     if qs.count() > 0:
        #         ses.selected_rows = [qs[0]]
        #         yield et.get_or_create_excerpt(ses)

    for obj in Excerpt.objects.all():
        # dd.logger.info("20150526 rendering %s", obj)
        rv = ses.run(obj.do_print)
        assert rv['success']
Ejemplo n.º 7
0
def objects():
    # vt = dd.plugins.invoicing.get_voucher_type()
    # jnl_list = vt.get_journals()
    # if len(jnl_list) == 0:
    #     return
    from lino_cosi.lib.ledger.roles import LedgerStaff
    accountants = LedgerStaff.get_user_profiles()
    users = rt.models.users.User.objects.filter(
        language=dd.get_default_language(), profile__in=accountants)
    if users.count() == 0:
        return
    ses = rt.login(users[0].username)
    Plan = rt.modules.invoicing.Plan

    # we don't write invoices the last two months because we want to
    # have something in our invoicing plan.
    today = datetime.date(dd.plugins.ledger.start_year, 1, 1)
    while today < dd.demo_date(-60):
        plan = Plan.start_plan(ses.get_user(), today=today)
        yield plan
        plan.fill_plan(ses)
        # for i in plan.items.all()[:9]:
        for i in plan.items.all():
            obj = i.create_invoice(ses)
            assert obj is not None
            yield obj
        today = DurationUnits.months.add_duration(today, 1)
Ejemplo n.º 8
0
def objects():

    ses = rt.login('wilfried')
    dd.plugins.b2c.import_statements_path = HERE
    settings.SITE.site_config.import_b2c(ses)

    # That file contains a few dozen of accounts which are now
    # "orphaned".  We are now going to assign theses accounts to a
    # random partner TODO: find a more realistic rule for selecting
    # the candidates. The filter might be a plugin attribute.

    IA = rt.modules.b2c.Account
    SA = rt.modules.sepa.Account
    PARTNERS = Cycler(rt.modules.contacts.Partner.objects.all())

    count = 0
    for ia in IA.objects.all():
        try:
            SA.objects.get(iban=ia.iban)
        except SA.DoesNotExist:
            yield SA(partner=PARTNERS.pop(), iban=ia.iban)
            count += 1
    if count == 0:
        dd.logger.info(
            "%d statements", rt.modules.b2c.Statement.objects.count())
        raise Exception(
            "There's something wrong: no accounts have been imported")
Ejemplo n.º 9
0
def objects():
    # vt = dd.plugins.invoicing.get_voucher_type()
    # jnl_list = vt.get_journals()
    # if len(jnl_list) == 0:
    #     return
    from lino_xl.lib.ledger.roles import LedgerStaff
    accountants = LedgerStaff.get_user_profiles()
    users = rt.models.users.User.objects.filter(
        language=dd.get_default_language(), user_type__in=accountants)
    if users.count() == 0:
        return
    ses = rt.login(users.first().username)

    for area in Area.objects.all():
        today = datetime.date(dd.plugins.ledger.start_year, 1, 1)
        while today < dd.demo_date(-60):
            plan = Plan.run_start_plan(ses.get_user(), today=today, area=area)
            yield plan
            plan.fill_plan(ses)
            # for i in plan.items.all()[:9]:
            for i in plan.items.all():
                obj = i.create_invoice(ses)
                if obj is not None:
                    yield obj
                else:
                    msg = "create_invoice failed for {}".format(i)
                    raise Exception(msg)
                    # dd.logger.warning(msg)
                    # return
            today = DurationUnits.months.add_duration(today, 1)
Ejemplo n.º 10
0
    def send_summary_emails(cls, mm):
        """Send summary emails for all pending notifications with the given
        mail_mode `mm`.

        """
        qs = cls.objects.filter(sent__isnull=True)
        qs = qs.exclude(user__email='')
        qs = qs.filter(mail_mode=mm).order_by('user')
        if qs.count() == 0:
            return
        from lino.core.renderer import MailRenderer
        ar = rt.login(renderer=MailRenderer())
        context = ar.get_printable_context()
        sender = settings.SERVER_EMAIL
        template = rt.get_template('notify/summary.eml')
        users = dict()
        for obj in qs:
            lst = users.setdefault(obj.user, [])
            lst.append(obj)
        dd.logger.debug("Send out %s summaries for %d users.", mm, len(users))
        for user, messages in users.items():
            with translation.override(user.language):
                if len(messages) == 1:
                    subject = messages[0].subject
                else:
                    subject = _("{} notifications").format(len(messages))
                subject = settings.EMAIL_SUBJECT_PREFIX + subject
                context.update(user=user, messages=messages)
                body = template.render(**context)
                # dd.logger.debug("20170112 %s", body)
                rt.send_email(subject, sender, body, [user.email])
                for msg in messages:
                    msg.sent = timezone.now()
                    msg.save()
Ejemplo n.º 11
0
Archivo: demo.py Proyecto: DarioGT/lino
def objects():

    Member = rt.modules.households.Member
    MemberRoles = rt.modules.households.MemberRoles
    # Household = resolve_model('households.Household')
    Person = resolve_model(dd.plugins.households.person_model)
    Type = resolve_model('households.Type')

    MEN = Cycler(Person.objects.filter(gender=dd.Genders.male).order_by('-id'))
    WOMEN = Cycler(
        Person.objects.filter(gender=dd.Genders.female).order_by('-id'))
    TYPES = Cycler(Type.objects.all())

    ses = rt.login()
    for i in range(5):
        pv = dict(head=MEN.pop(), partner=WOMEN.pop(), type=TYPES.pop())
        ses.run(Person.create_household, action_param_values=pv)
        # yield ses.response['data_record']
        # he = MEN.pop()
        # she = WOMEN.pop()

        # fam = Household(name=he.last_name + "-" + she.last_name, type_id=3)
        # yield fam
        # yield Member(household=fam, person=he, role=Role.objects.get(pk=1))
        # yield Member(household=fam, person=she, role=Role.objects.get(pk=2))

    i = 0
    for m in Member.objects.filter(role=MemberRoles.head):
        i += 1
        if i % 3 == 0:
            m.end_date = i2d(20020304)
            yield m

            pv = dict(head=m.person, partner=WOMEN.pop(), type=TYPES.pop())
            ses.run(Person.create_household, action_param_values=pv)
Ejemplo n.º 12
0
    def test_create_entry(self):
        """# cal.MyEntries.insert({'requesting_panel': u'ext-comp-3913',
'user': u'luc'})

        """

        ses = rt.login("robin", renderer=dd.plugins.extjs.renderer)
        ba = rt.models.cal.MyEntries.get_action_by_name('submit_insert')
        # a = rt.models.cal.MyEntries.submit_insert
        # ba = rt.models.cal.MyEntries.insert_action
        pv = dict(user=ses.get_user())
        resp = ses.run(ba, param_values=pv)
        # ba.request_from(ses).run_from_ui(ses)
        self.assertEqual(sorted(resp.keys()), [
            'close_window', 'data_record', 'detail_handler_name',
            'info_message', 'message', 'refresh_all', 'rows', 'success'])

        # self.assertEqual(resp['data_record'].keys(), None)

        # The return message is of style 'Event "Event #69 (23.10.2014
        # 15:42)" has been created.'  The start_time is the real time
        # runtime and thus not predictable.  So we retrieve the
        # created object and use it to build that message:

        pk = resp['data_record']['id']
        obj = rt.models.cal.Event.objects.get(pk=pk)
        msg = 'Calendar entry "{0}" has been created.'.format(obj)
        self.assertEqual(resp['message'], msg)
Ejemplo n.º 13
0
def objects():
    # vt = dd.plugins.invoicing.get_voucher_type()
    # jnl_list = vt.get_journals()
    # if len(jnl_list) == 0:
    #     return
    from lino_xl.lib.ledger.roles import LedgerStaff
    accountants = LedgerStaff.get_user_profiles()
    users = rt.models.users.User.objects.filter(
        language=dd.get_default_language(), user_type__in=accountants)
    if users.count() == 0:
        return
    ses = rt.login(users[0].username)
    Plan = rt.models.invoicing.Plan

    # we don't write invoices the last two months because we want to
    # have something in our invoicing plan.
    today = datetime.date(dd.plugins.ledger.start_year, 1, 1)
    while today < dd.demo_date(-60):
        plan = Plan.start_plan(ses.get_user(), today=today)
        yield plan
        plan.fill_plan(ses)
        # for i in plan.items.all()[:9]:
        for i in plan.items.all():
            obj = i.create_invoice(ses)
            if obj is not None:
                yield obj
            else:
                msg = "create_invoice failed for {}".format(i)
                raise Exception(msg)
                # dd.logger.warning(msg)
                # return
        today = DurationUnits.months.add_duration(today, 1)
Ejemplo n.º 14
0
    def test_dupable_hidden(self):
        """Since `dupable_clients` is hidden, we can create duplicate partners
        without warning.

        """
        Client = rt.models.pcsw.Client
        User = settings.SITE.user_model

        User(username='******', user_type=UserTypes.admin).save()

        Client(first_name="First", last_name="Last").save()

        data = dict(an="submit_insert")
        data.update(first_name="First")
        data.update(last_name="Last")
        data.update(genderHidden="M")
        data.update(gender="Male")
        self.client.force_login(rt.login("robin").user)
        response = self.client.post('/api/pcsw/Clients',
                                    data=data,
                                    REMOTE_USER="******")
        result = self.check_json_result(
            response, "detail_handler_name data_record rows "
            "close_window success message navinfo")
        self.assertEqual(result['success'], True)
        self.assertEqual(
            result['message'],
            'B\xe9n\xe9ficiaire "LAST First (101)" a \xe9t\xe9 cr\xe9\xe9')
Ejemplo n.º 15
0
Archivo: utils.py Proyecto: khchine5/xl
    def finalize(self):
        if len(self.duplicate_zip_codes):
            for country, codes in self.duplicate_zip_codes.items():
                dd.logger.warning(
                    "%d duplicate zip codes in %s : %s",
                    len(codes), country, ', '.join(codes))

        if self.ROOT is None:
            return
        
        ses = rt.login(self.ROOT.username)

        Journal = rt.models.ledger.Journal
        dd.logger.info("Register %d vouchers", len(self.must_register))
        failures = 0
        for doc in progress.bar(self.must_register):
            # puts("Registering {0}".format(doc))
            try:
                doc.register(ses)
            except Exception as e:
                dd.logger.warning("Failed to register %s : %s ", doc, e)
                failures += 1
                if failures > 100:
                    dd.logger.warning("Abandoned after 100 failures.")
                    break

        # Given a string `ms` of type 'VKR940095', locate the corresponding
        # movement.
        dd.logger.info("Resolving %d matches", len(self.must_match))
        for ms, lst in self.must_match.items():
            for (voucher, matching) in lst:
                if matching.pk is None:
                    dd.logger.warning("Ignored match %s in %s (pk is None)" % (
                        ms, matching))
                    continue
                idjnl, iddoc = ms[:3], ms[3:]
                try:
                    year, num = year_num(iddoc)
                except ValueError as e:
                    dd.logger.warning("Ignored match %s in %s (%s)" % (
                        ms, matching, e))
                try:
                    jnl = Journal.objects.get(ref=idjnl)
                except Journal.DoesNotExist:
                    dd.logger.warning("Ignored match %s in %s (invalid JNL)" % (
                        ms, matching))
                    continue
                qs = Movement.objects.filter(
                    voucher__journal=jnl, voucher__number=num,
                    voucher__year=year, partner__isnull=False)
                if qs.count() == 0:
                    dd.logger.warning("Ignored match %s in %s (no movement)" % (
                        ms, matching))
                    continue
                matching.match = qs[0]
                matching.save()
                voucher.deregister(ses)
                voucher.register(ses)
Ejemplo n.º 16
0
    def finalize(self):
        if len(self.duplicate_zip_codes):
            for country, codes in self.duplicate_zip_codes.items():
                dd.logger.warning("%d duplicate zip codes in %s : %s",
                                  len(codes), country, ', '.join(codes))

        if self.ROOT is None:
            return

        ses = rt.login(self.ROOT.username)

        Journal = rt.models.ledger.Journal
        dd.logger.info("Register %d vouchers", len(self.must_register))
        failures = 0
        for doc in progress.bar(self.must_register):
            # puts("Registering {0}".format(doc))
            try:
                doc.register(ses)
            except Exception as e:
                dd.logger.warning("Failed to register %s : %s ", doc, e)
                failures += 1
                if failures > 100:
                    dd.logger.warning("Abandoned after 100 failures.")
                    break

        # Given a string `ms` of type 'VKR940095', locate the corresponding
        # movement.
        dd.logger.info("Resolving %d matches", len(self.must_match))
        for ms, lst in self.must_match.items():
            for (voucher, matching) in lst:
                if matching.pk is None:
                    dd.logger.warning("Ignored match %s in %s (pk is None)" %
                                      (ms, matching))
                    continue
                idjnl, iddoc = ms[:3], ms[3:]
                try:
                    year, num = year_num(iddoc)
                except ValueError as e:
                    dd.logger.warning("Ignored match %s in %s (%s)" %
                                      (ms, matching, e))
                try:
                    jnl = Journal.objects.get(ref=idjnl)
                except Journal.DoesNotExist:
                    dd.logger.warning("Ignored match %s in %s (invalid JNL)" %
                                      (ms, matching))
                    continue
                qs = Movement.objects.filter(voucher__journal=jnl,
                                             voucher__number=num,
                                             voucher__year=year,
                                             partner__isnull=False)
                if qs.count() == 0:
                    dd.logger.warning("Ignored match %s in %s (no movement)" %
                                      (ms, matching))
                    continue
                matching.match = qs[0]
                matching.save()
                voucher.deregister(ses)
                voucher.register(ses)
Ejemplo n.º 17
0
    def test_makecopy(self):
        UserTypes = rt.models.users.UserTypes
        Partner = rt.models.contacts.Partner
        Account = rt.models.ledger.Account
        AnaAccountInvoice = rt.models.ana.AnaAccountInvoice
        jnl = rt.models.ledger.Journal.objects.get(ref="PRC")
        # acc = rt.models.ledger.Account.objects.get(ref="PRC")
        user = create_row(rt.models.users.User,
                          username="******",
                          user_type=UserTypes.admin)
        ses = rt.login('robin', renderer=TestRenderer())
        partner = create_row(Partner, name="Foo")
        self.assertEqual(AnaAccountInvoice.objects.count(), 0)
        invoice = jnl.create_voucher(partner=partner, user=user)
        self.assertEqual(invoice.__class__, AnaAccountInvoice)
        invoice.full_clean()
        invoice.save()
        ga = Account.objects.filter(
            needs_ana=True, ana_account__isnull=False).order_by('ref')[0]
        for n in range(3):
            i = invoice.add_voucher_item(
                account=ga,
                seqno=3 - n,  # enter them in reverse order to reproduce
                # #2470
                total_incl=123 + n)
            i.full_clean()
            i.save()

        s = ses.show('ana.ItemsByInvoice',
                     invoice,
                     column_names="seqno account total_incl")
        # print(s)
        expected = """\
==================== ============================= =================
 No.                  Account                       Total incl. VAT
-------------------- ----------------------------- -----------------
 1                    (6010) Purchase of services   125,00
 2                    (6010) Purchase of services   124,00
 3                    (6010) Purchase of services   123,00
 **Total (3 rows)**                                 **372,00**
==================== ============================= =================
"""
        self.assertEqual(s, expected)
        self.assertEqual(AnaAccountInvoice.objects.count(), 1)
        self.assertEqual(invoice.number, 1)

        invoice.make_copy.run_from_session(ses)
        self.assertEqual(AnaAccountInvoice.objects.count(), 2)

        invoice = AnaAccountInvoice.objects.get(number=2)

        s = ses.show('ana.ItemsByInvoice',
                     invoice,
                     column_names="seqno account total_incl")
        # print(s)
        self.assertEqual(s, expected)
Ejemplo n.º 18
0
def objects():
    ses = rt.login()
    Client = rt.modules.pcsw.Client
    CLIENTS = Cycler(Client.objects.all())
    for obj in lino_objects():
        if obj.__class__.__name__ == "Event":
            if obj.event_type.invite_client:
                obj.project = CLIENTS.pop()
        yield obj
        obj.update_guests.run_from_code(ses)
Ejemplo n.º 19
0
    def test_makecopy(self):
        UserTypes = rt.models.users.UserTypes
        Partner = rt.models.contacts.Partner
        Account = rt.models.ledger.Account
        AnaAccountInvoice = rt.models.ana.AnaAccountInvoice
        jnl = rt.models.ledger.Journal.objects.get(ref="PRC")
        # acc = rt.models.ledger.Account.objects.get(ref="PRC")
        user = create_row(rt.models.users.User,
            username="******", user_type=UserTypes.admin)
        ses = rt.login('robin', renderer=TestRenderer())
        partner = create_row(Partner, name="Foo")
        self.assertEqual(AnaAccountInvoice.objects.count(), 0)
        invoice = jnl.create_voucher(partner=partner, user=user)
        self.assertEqual(
            invoice.__class__, AnaAccountInvoice)
        invoice.full_clean()
        invoice.save()
        ga = Account.objects.filter(
            needs_ana=True, ana_account__isnull=False).order_by('ref')[0]
        for n in range(3):
            i = invoice.add_voucher_item(
                account=ga,
                seqno=3-n,  # enter them in reverse order to reproduce
                            # #2470
                total_incl=123+n)
            i.full_clean()
            i.save()
        
        s = ses.show('ana.ItemsByInvoice', invoice,
                     column_names="seqno account total_incl")
        # print(s)
        expected = """\
==================== ============================= =================
 No.                  Account                       Total incl. VAT
-------------------- ----------------------------- -----------------
 1                    (6010) Purchase of services   125,00
 2                    (6010) Purchase of services   124,00
 3                    (6010) Purchase of services   123,00
 **Total (3 rows)**                                 **372,00**
==================== ============================= =================
"""
        self.assertEqual(s, expected)
        self.assertEqual(AnaAccountInvoice.objects.count(), 1)
        self.assertEqual(invoice.number, 1)

        invoice.make_copy.run_from_session(ses)
        self.assertEqual(AnaAccountInvoice.objects.count(), 2)

        invoice = AnaAccountInvoice.objects.get(number=2)

        s = ses.show('ana.ItemsByInvoice', invoice,
                     column_names="seqno account total_incl")
        # print(s)
        self.assertEqual(s, expected)
Ejemplo n.º 20
0
def objects():
    
    yield rt.login('alicia').get_user()

    if False:  # done in lino_welfare/modlib/integ/fixtures/

        TT = Cycler(rt.modules.immersion.ContractType.objects.all())
        TG = Cycler(rt.modules.immersion.Goal.objects.all())
        Training = rt.modules.immersion.Contract

        alicia = rt.login('alicia').get_user()
        selected_clients = (131, 149, 161)
        for i, pk in enumerate(selected_clients):
            kw = dict(client_id=pk)
            kw.update(type=TT.pop())
            kw.update(user=alicia)
            kw.update(goal=TG.pop())
            kw.update(applies_from=dd.demo_date(i*30))
            kw.update(applies_until=dd.demo_date(i*30+60*(i+1)))
            yield Training(**kw)
Ejemplo n.º 21
0
def objects():

    yield lib_objects()

    SECTIONS = Cycler(rt.models.courses.Sections.objects())

    for obj in rt.models.courses.Pupil.objects.order_by('id'):
        if obj.id % 5 == 0:
            obj.is_lfv = True
        if obj.id % 6 == 0:
            obj.is_ckk = True
        if obj.id % 4 == 0:
            obj.section = SECTIONS.pop()
        elif obj.id % 10 != 0:
            obj.member_until = dd.demo_date().replace(month=12, day=31)
        yield obj

    fee_account = rt.models.accounts.Account(
        ref=dd.plugins.courses.membership_fee_account,
        type=rt.models.accounts.AccountTypes.incomes,
        default_amount=15,
        **dd.str2kw('name', _("Membership fee")))
    yield fee_account

    Journal = rt.models.ledger.Journal
    USERS = Cycler(rt.models.users.User.objects.all())
    MEMBERS = Cycler(rt.models.courses.Pupil.objects.all())

    jnl = Journal.objects.get(ref='CSH')
    membership_payments = [
        (1, 3),
        (2, 1),
        (10, 2),
        (11, 4),
        (12, 5),
    ]
    REQUEST = rt.login()

    for month, number in membership_payments:
        date = dd.demo_date().replace(month=month)
        voucher = jnl.create_voucher(
            user=USERS.pop(),
            voucher_date=date)
        yield voucher
        for i in range(number):
            M = jnl.voucher_type.get_items_model()
            kw = dict(voucher=voucher)
            kw.update(partner=MEMBERS.pop(), date=date, account=fee_account)
            kw.update(
                amount=fee_account.default_amount, dc=fee_account.type.dc)
            yield M(**kw)
        voucher.register(REQUEST)
        voucher.save()
Ejemplo n.º 22
0
    def test02(self):
        # This case demonstratest that ordering does not ignore case, at
        # least in sqlite. we would prefer to have `['adams', 'Zybulka']`,
        # but we get `['Zybulka', 'adams']`.

        contacts = rt.modules.contacts
        contacts.Partner(name="Zybulka").save()
        contacts.Partner(name="adams").save()
        ar = rt.login().spawn(contacts.Partners)
        l = [p.name for p in ar]
        expected = ['Zybulka', 'adams']
        self.assertEqual(l, expected)
Ejemplo n.º 23
0
    def test02(self):
        # This case demonstrates that ordering does not ignore case, at
        # least in sqlite. we would prefer to have `['adams', 'Zybulka']`,
        # but we get `['Zybulka', 'adams']`.

        contacts = rt.models.contacts
        contacts.Partner(name="Zybulka").save()
        contacts.Partner(name="adams").save()
        ar = rt.login().spawn(contacts.Partners)
        l = [p.name for p in ar]
        expected = ['Zybulka', 'adams']
        self.assertEqual(l, expected)
Ejemplo n.º 24
0
Archivo: demo.py Proyecto: TonisPiip/xl
def objects():

    Member = rt.modules.households.Member
    MemberRoles = rt.modules.households.MemberRoles
    # Household = resolve_model('households.Household')
    Person = dd.plugins.households.person_model
    Type = resolve_model('households.Type')

    men = Person.objects.filter(gender=dd.Genders.male).order_by('-id')
    women = Person.objects.filter(gender=dd.Genders.female).order_by('-id')
    # avoid interference with persons created by humanlinks demo
    # because these have already their households:
    men = men.filter(household_members__isnull=True)
    men = men.filter(humanlinks_children__isnull=True)
    men = men.filter(humanlinks_parents__isnull=True)
    women = women.filter(humanlinks_children__isnull=True)
    women = women.filter(humanlinks_parents__isnull=True)
    women = women.filter(household_members__isnull=True)

    MEN = Cycler(men)
    WOMEN = Cycler(women)
    TYPES = Cycler(Type.objects.all())

    if not len(MEN) or not len(WOMEN):
        raise Exception("Not enough persons in {} and {} (all: {})".format(
            men, women, Person.objects.all()))

    # avoid automatic creation of children
    # loading_from_dump = settings.SITE.loading_from_dump
    # settings.SITE.loading_from_dump = True
    ses = rt.login()
    for i in range(5):
        pv = dict(head=MEN.pop(), partner=WOMEN.pop(), type=TYPES.pop())
        ses.run(Person.create_household, action_param_values=pv)
        # yield ses.response['data_record']
        # he = MEN.pop()
        # she = WOMEN.pop()

        # fam = Household(name=he.last_name + "-" + she.last_name, type_id=3)
        # yield fam
        # yield Member(household=fam, person=he, role=Role.objects.get(pk=1))
        # yield Member(household=fam, person=she, role=Role.objects.get(pk=2))

    i = 0
    for m in Member.objects.filter(role=MemberRoles.head):
        i += 1
        if i % 3 == 0:
            m.end_date = i2d(20020304)
            yield m

            pv = dict(head=m.person, partner=WOMEN.pop(), type=TYPES.pop())
            ses.run(Person.create_household, action_param_values=pv)
Ejemplo n.º 25
0
    def objects(self):

        self.ignored_journals = set()
        self.ignored_accounts = set()
        self.ignored_bank_accounts = set()
        self.undefined_bank_accounts = set()
        self.unknown_users = set()
        self.missing_partners = set()
        self.missing_clients = set()
        self.rows_by_year = SumCollector()
        self.ignored_matches = SumCollector()
        self.ignored_partners = SumCollector()

        yield wanted_accounts()

        # self.group = accounts.Group(name="Imported from TIM")
        # self.group.full_clean()
        # self.group.save()

        # yield self.load_dbf('BUD')

        # # self.after_gen_load()

        # yield self.load_dbf('JNL')

        # from lino_cosi.lib.vat.fixtures import euvatrates
        # yield euvatrates.objects()

        settings.SITE.loading_from_dump = True
        yield self.load_dbf('IML')
        yield self.load_dbf('IMP')
        # yield self.load_dbf('MVI')
        settings.SITE.loading_from_dump = False

        if len(self.must_register) == 0:
            return

        ses = rt.login('roger')

        dd.logger.info("Register %d vouchers", len(self.must_register))
        failures = 0
        for doc in progress.bar(self.must_register):
            # puts("Registering {0}".format(doc))
            try:
                doc.register(ses)
            except Exception as e:
                dd.logger.warning("Failed to register %s : %s ", doc, e)
                failures += 1
                if failures > 100:
                    dd.logger.warning("Abandoned after 100 failures.")
                    break
Ejemplo n.º 26
0
def objects():
    # dd.logger.info(
    #     "sheets %s %s",
    #     dd.plugins.ledger.start_year, dd.today().year+1)
    from datetime import date
    Report = rt.models.sheets.Report
    AccountingPeriod = rt.models.ledger.AccountingPeriod
    ses = rt.login("robin")
    for year in range(dd.plugins.ledger.start_year, dd.today().year+1):
        sp = AccountingPeriod.get_default_for_date(date(year, 1, 1))
        ep = AccountingPeriod.get_default_for_date(date(year, 12, 31))
        obj = Report(start_period=sp, end_period=ep, user=ses.get_user())
        yield obj
        obj.run_update_plan(ses)
Ejemplo n.º 27
0
    def test01(self):
        from lino.modlib.users.choicelists import UserTypes
        User = rt.models.users.User
        Account = rt.models.accounts.Account
        AccountTypes = rt.models.accounts.AccountTypes
        
        Journal = rt.models.ledger.Journal
        Partner = rt.models.contacts.Partner
        Person = rt.models.contacts.Person
        Company = rt.models.contacts.Company
        Role = rt.models.contacts.Role
        # Account = rt.models.sepa.Account
        Invoice = rt.models.vat.VatAccountInvoice
        VoucherTypes = rt.models.ledger.VoucherTypes
        JournalGroups = rt.models.ledger.JournalGroups

        robin = create_row(
            User, username='******',
            user_type=UserTypes.admin, language="en")
        ar = rt.login('robin')
        
        a = create_row(Account, name="A", type=AccountTypes.expenses)
        b = create_row(Account, name="B", type=AccountTypes.expenses)
        c = create_row(Account, name="C", type=AccountTypes.expenses)
        d = create_row(Account, name="D", type=AccountTypes.expenses)

        lst = [i.seqno for i in Account.objects.order_by('name')]
        self.assertEqual(lst, [1, 2, 3, 4])
        
        self.assertEqual(a.seqno, 1)
        self.assertEqual(b.seqno, 2)
        self.assertEqual(c.seqno, 3)
        self.assertEqual(d.seqno, 4)

        a.move_down(ar)
        
        self.assertEqual(ar.response, {
            'message': 'Renumbered 1 of 3 siblings.',
            'success': True,
            'refresh_all': True})

        # NOTE that a, b, c and d are invalid now
        a = b = c = d = None

        lst = [i.seqno for i in Account.objects.order_by('name')]
        self.assertEqual(lst, [2, 1, 3, 4])
        
        lst = [i.name for i in Account.objects.order_by('seqno')]
        self.assertEqual(''.join(lst), "BACD")
Ejemplo n.º 28
0
    def test01(self):
        from lino.modlib.users.choicelists import UserTypes
        User = rt.models.users.User
        Account = rt.models.ledger.Account
        
        Journal = rt.models.ledger.Journal
        Partner = rt.models.contacts.Partner
        Person = rt.models.contacts.Person
        Company = rt.models.contacts.Company
        Role = rt.models.contacts.Role
        # Account = rt.models.sepa.Account
        Invoice = rt.models.vat.VatAccountInvoice
        VoucherTypes = rt.models.ledger.VoucherTypes
        JournalGroups = rt.models.ledger.JournalGroups

        robin = create_row(
            User, username='******',
            user_type=UserTypes.admin, language="en")
        ar = rt.login('robin')
        
        a = create_row(Account, name="A")
        b = create_row(Account, name="B")
        c = create_row(Account, name="C")
        d = create_row(Account, name="D")

        lst = [i.seqno for i in Account.objects.order_by('name')]
        self.assertEqual(lst, [1, 2, 3, 4])
        
        self.assertEqual(a.seqno, 1)
        self.assertEqual(b.seqno, 2)
        self.assertEqual(c.seqno, 3)
        self.assertEqual(d.seqno, 4)

        response = a.move_down()
        
        self.assertEqual(response, {
            'message': 'Renumbered 1 of 3 siblings.',
            'success': True,
            'refresh_all': True})

        # NOTE that a, b, c and d are invalid now
        a = b = c = d = None

        lst = [i.seqno for i in Account.objects.order_by('name')]
        self.assertEqual(lst, [2, 1, 3, 4])
        
        lst = [i.name for i in Account.objects.order_by('seqno')]
        self.assertEqual(''.join(lst), "BACD")
Ejemplo n.º 29
0
def objects():

    Member = rt.modules.households.Member
    MemberRoles = rt.modules.households.MemberRoles
    # Household = resolve_model('households.Household')
    Person = resolve_model(dd.plugins.households.person_model)
    Type = resolve_model('households.Type')

    MEN = Cycler(Person.objects.filter(gender=dd.Genders.male)
                 .order_by('-id'))
    WOMEN = Cycler(Person.objects.filter(gender=dd.Genders.female)
                   .order_by('-id'))
    TYPES = Cycler(Type.objects.all())

    ses = rt.login()
    for i in range(5):
        pv = dict(
            head=MEN.pop(), partner=WOMEN.pop(),
            type=TYPES.pop())
        ses.run(
            Person.create_household,
            action_param_values=pv)
        # yield ses.response['data_record']
        # he = MEN.pop()
        # she = WOMEN.pop()
        
        # fam = Household(name=he.last_name + "-" + she.last_name, type_id=3)
        # yield fam
        # yield Member(household=fam, person=he, role=Role.objects.get(pk=1))
        # yield Member(household=fam, person=she, role=Role.objects.get(pk=2))

    i = 0
    for m in Member.objects.filter(role=MemberRoles.head):
        i += 1
        if i % 3 == 0:
            m.end_date = i2d(20020304)
            yield m

            pv = dict(
                head=m.person, partner=WOMEN.pop(),
                type=TYPES.pop())
            ses.run(
                Person.create_household,
                action_param_values=pv)
Ejemplo n.º 30
0
def objects():

    Company = rt.models.contacts.Company
    
    ar = rt.login(request=PseudoRequest("robin"))

    obj = Company(name="My pub")
    obj.full_clean()
    obj.save_new_instance(ar)
    
    cw = ChangeWatcher(obj)
    obj.name = "Our pub"
    obj.save_watched_instance(ar, cw)

    obj.delete_instance(ar)

    # this is a special fixture : it creates objects as a side effect
    # but does not yield them.
    return []
Ejemplo n.º 31
0
def objects():

    Company = rt.models.contacts.Company

    ar = rt.login(request=PseudoRequest("robin"))

    obj = Company(name="My pub")
    obj.full_clean()
    obj.save_new_instance(ar)

    cw = ChangeWatcher(obj)
    obj.name = "Our pub"
    obj.save_watched_instance(ar, cw)

    obj.delete_instance(ar)

    # this is a special fixture : it creates objects as a side effect
    # but does not yield them.
    return []
Ejemplo n.º 32
0
def objects():
    ExcerptType = rt.models.excerpts.ExcerptType
    Excerpt = rt.models.excerpts.Excerpt

    if not dd.plugins.excerpts.responsible_user:
        return

    ses = rt.login(dd.plugins.excerpts.responsible_user)

    for et in ExcerptType.objects.all():
        model = et.content_type.model_class()
        qs = model.get_printable_demo_objects()
        # if issubclass(model, Certifiable):
        #     qs = model.get_printable_demo_objects(et)
        # else:
        #     qs = model.objects.all()
        #     if qs.count() > 0:
        #         qs = [qs[0]]
        # if et.certifying:
        for obj in qs:
            ses.selected_rows = [obj]
            yield et.get_or_create_excerpt(ses)
        # qs2 = Excerpt.objects.filter(excerpt_type=et)
        # if qs2.count() == 0:
        #     if qs.count() > 0:
        #         ses.selected_rows = [qs[0]]
        #         yield et.get_or_create_excerpt(ses)

    for obj in Excerpt.objects.all():
        # dd.logger.info("20150526 rendering %s", obj)
        try:
            rv = ses.run(obj.do_print)
            assert rv['success']
        except Warning as e:
            dd.logger.warning(
                "Failed to render %s : %s", obj, e)
        except Exception as e:
            if SEVERE:
                raise
            else:
                traceback.print_exc()
                dd.logger.warning(
                    "20160311 failed to render %s : %s", obj, e)
Ejemplo n.º 33
0
def objects():
    ExcerptType = rt.models.excerpts.ExcerptType
    Excerpt = rt.models.excerpts.Excerpt

    if not dd.plugins.excerpts.responsible_user:
        return

    ses = rt.login(dd.plugins.excerpts.responsible_user)

    for et in ExcerptType.objects.all().order_by('id'):
        model = et.content_type.model_class()
        qs = model.get_printable_demo_objects()
        # if issubclass(model, Certifiable):
        #     qs = model.get_printable_demo_objects(et)
        # else:
        #     qs = model.objects.all()
        #     if qs.count() > 0:
        #         qs = [qs[0]]
        # if et.certifying:
        for obj in qs:
            ses.selected_rows = [obj]
            yield et.get_or_create_excerpt(ses)
        # qs2 = Excerpt.objects.filter(excerpt_type=et)
        # if qs2.count() == 0:
        #     if qs.count() > 0:
        #         ses.selected_rows = [qs[0]]
        #         yield et.get_or_create_excerpt(ses)

    for obj in Excerpt.objects.all():
        # dd.logger.info("20150526 rendering %s", obj)
        try:
            rv = ses.run(obj.do_print)
            assert rv['success']
        except Warning as e:
            dd.logger.warning("Failed to render %s : %s", obj, e)
        except Exception as e:
            if SEVERE:
                raise
            else:
                traceback.print_exc()
                dd.logger.warning("20160311 failed to render %s : %s", obj, e)
Ejemplo n.º 34
0
    def test_create_entry(self):
        """# cal.MyEvents.insert({'requesting_panel': u'ext-comp-3913',
'user': u'luc'})

        """

        ses = rt.login("robin")
        ba = rt.modules.cal.MyEvents.get_action_by_name("submit_insert")
        # a = rt.modules.cal.MyEvents.submit_insert
        # ba = rt.modules.cal.MyEvents.insert_action
        pv = dict(user=ses.get_user())
        resp = ses.run(ba, param_values=pv)
        # ba.request_from(ses).run_from_ui(ses)
        self.assertEqual(
            sorted(resp.keys()),
            [
                "close_window",
                "data_record",
                "detail_handler_name",
                "info_message",
                "message",
                "refresh_all",
                "rows",
                "success",
            ],
        )

        # self.assertEqual(resp['data_record'].keys(), None)

        # The return message is of style 'Event "Event #69 (23.10.2014
        # 15:42)" has been created.'  The start_time is the real time
        # runtime and thus not predictable.  So we retrieve the
        # created object and use it to build that message:

        pk = resp["data_record"]["id"]
        obj = rt.modules.cal.Event.objects.get(pk=pk)
        msg = 'Event "{0}" has been created.'.format(obj)
        self.assertEqual(resp["message"], msg)
Ejemplo n.º 35
0
def show_excerpts(severe=True):
    ses = rt.login()
    # dd.logger.info("20141029 %s", settings.SITE)
    coll = {}

    def collect(obj):
        l = coll.setdefault(obj.excerpt_type, [])
        mf = obj.build_method.get_target(None, obj)
        tmppath = Path(mf.name)
        if tmppath.exists():
            tail = tmppath.name
            tail = 'dl/excerpts/' + tail
            kw = dict(tail=tail)
            kw.update(type=obj.excerpt_type)
            kw.update(owner=obj.owner)
            try:
                # dd.logger.info("20141029 copy %s to %s", tmppath, tail)
                shutil.copyfile(tmppath, tail)
            except IOError as e:
                kw.update(error=str(e))
                msg = "%(type)s %(owner)s %(tail)s Oops: %(error)s" % kw
                # raise Exception(msg)
                kw.update(owner=msg)

            l.append(kw)

    for o in rt.models.excerpts.Excerpt.objects.order_by('excerpt_type'):
        collect(o)

    def asli(et, items):
        s = str(et)
        s += " : " + ', '.join("`%(owner)s <../%(tail)s>`__" % kw % kw
                               for kw in items)
        return s

    return rstgen.ul([asli(k, v) for k, v in coll.items()])
Ejemplo n.º 36
0
def objects(refs="PMO BNK"):  # welfare calls it with customized refs.

    Journal = rt.models.ledger.Journal
    Company = rt.models.contacts.Company
    Movement = rt.models.ledger.Movement

    USERS = Cycler(settings.SITE.user_model.objects.all())
    OFFSETS = Cycler(12, 20, 28)

    START_YEAR = dd.plugins.ledger.start_year
    end_date = settings.SITE.demo_date(-30)
    site_company = settings.SITE.site_config.site_company

    ses = rt.login('robin')

    qs = Company.objects.filter(country__isnull=False)
    # if qs.count() < 10:
    #     raise Exception("20171009")
    for p in qs:
        if Movement.objects.filter(partner=p, cleared=False).count():
            add_demo_account(p)

    if dd.is_installed("vat") and dd.plugins.vat.declaration_plugin is None:
        dd.logger.warning("No demo payments because declaration_plugin is None")
        return

    for ref in refs.split():
        # if ref == 'BNK':
        #     continue  # temp 20171007
        jnl = Journal.objects.get(ref=ref)
        sug_table = jnl.voucher_type.table_class.suggestions_table
        do_fill = sug_table.get_action_by_name('do_fill')
        if ref == 'PMO':
            assert site_company is not None
            if site_company.country is None:
                raise Exception(
                    "Oops, site company {} has no country".format(
                        site_company))

            acct = add_demo_account(site_company)
            jnl.sepa_account = acct
            yield jnl

        offset = OFFSETS.pop()
        date = datetime.date(START_YEAR, 1, 1)
        while date < end_date:
            voucher = jnl.create_voucher(
                user=USERS.pop(),
                entry_date=date + delta(days=offset))
            yield voucher
            # print("20201009", voucher)
            # start action request for do_fill:
            ar = do_fill.request(master_instance=voucher)
            # select all rows:
            suggestions = sug_table.request(voucher)
            ar.selected_rows = list(suggestions)
            # run the action:
            ar.run()

            # manually introduce some payment differences:
            if ref == 'BNK':
                for item in voucher.items.all():
                    pd = PAYMENT_DIFFS.pop()
                    if pd:
                        pd = Decimal(pd)
                        item.amount += item.amount * pd
                        if item.amount:
                            item.save()
                        else:
                            item.delete()
            # if no items have been created (or if they have been
            # deleted by PAYMENT_DIFFS), remove the empty voucher:
            if voucher.items.count() == 0:
                voucher.delete()
            else:
                # if ref == 'PMO':
                #     voucher.execution_date = voucher.entry_date
                #     assert voucher.execution_date is not None
                voucher.register(REQUEST)
                # voucher.full_clean()
                # voucher.save()

                # for i in voucher.items.all():
                #     if i.partner:
                #         yield add_demo_account(i.partner)

                # For payment orders we also write the XML file
                if ref == 'PMO':
                    rv = voucher.write_xml.run_from_session(ses)
                    if not rv['success']:
                        raise Exception("20170630")
                    if False:
                        # not needed here because write_xml validates
                        fn = Path(settings.SITE.cache_dir + rv['open_url'])
                        if not fn.exists():
                            raise Exception("20170630")
                        validate_pain001(fn)

            date += delta(months=1)
Ejemplo n.º 37
0
    def test01(self):
        from lino.modlib.users.choicelists import UserTypes
        Ticket = rt.models.tickets.Ticket
        # Project = rt.models.tickets.Project
        # Line = rt.models.courses.Line
        # Activity = rt.models.courses.Course
        # Enrolment = rt.models.courses.Enrolment
        # Meeting = rt.models.meetings.Meeting
        Change = rt.models.changes.Change
        User = rt.models.users.User
        # Vote = rt.models.votes.Vote
        # VoteStates = rt.models.votes.VoteStates
        # VotesByVotable = rt.models.votes.VotesByVotable
        # ContentType = rt.models.contenttypes.ContentType
        # ct_Ticket = ContentType.objects.get_for_model(Ticket)

        # create(Project, name='project')

        robin = create(User, username='******',
                       first_name="Robin",
                       user_type=UserTypes.admin,
                       language="en")
        anna = create(User, username='******',
                      first_name="Anna",
                      user_type=UserTypes.user,
                      language="en")
        berta = create(User, username='******',
                       first_name="Berta",
                       user_type=UserTypes.user,
                       language="en")
        # meeting = create(Meeting, name="Test")
        # sprints = create(Line, name="Sprints")
        # sprint = create(Activity, line=sprints)
        #
        # Enrolment(course=sprint, pupil=robin)
        
        ses = rt.login('robin')
        
        ticket = create(Ticket, summary="First", user=robin)
        ticket.after_ui_save(ses, None)
        # vote = Vote.objects.get(votable=ticket)
        # self.assertEqual(vote.user, robin)
        # self.assertEqual(vote.state, VoteStates.author)
        
        def check_success(ia, **kwargs):
            rv = ia.run_from_session(ses, **kwargs)
            self.assertEqual(rv, {'success': True, 'refresh': True})

        check_success(ticket.mark_talk)
        check_success(ticket.mark_started)
        check_success(ticket.mark_refused)
        check_success(ticket.mark_closed)
        check_success(ticket.mark_refused)
        
        # Vote.objects.all().delete()
        Ticket.objects.all().delete()
        
        # self.assertEqual(Vote.objects.count(), 0)

        ticket = create(
            Ticket, summary="Second", user=robin, end_user=anna)
        ticket.after_ui_save(ses, None)
Ejemplo n.º 38
0
def objects():
    Granting = rt.modules.aids.Granting
    AidType = rt.modules.aids.AidType
    Person = rt.modules.contacts.Person
    Client = rt.modules.pcsw.Client
    ClientStates = rt.modules.pcsw.ClientStates
    ClientContactType = rt.modules.pcsw.ClientContactType
    Board = rt.modules.boards.Board
    ExcerptType = rt.modules.excerpts.ExcerptType
    ConfirmationStates = rt.modules.aids.ConfirmationStates

    Project = resolve_model('pcsw.Client')
    qs = Project.objects.filter(client_state=ClientStates.coached)
    # if qs.count() > 10:
    #     qs = qs[:10]
    PROJECTS = Cycler(qs)

    l = []
    qs = ClientContactType.objects.filter(can_refund=True)
    for cct in qs:
        qs2 = Person.objects.filter(client_contact_type=cct)
        if qs2.count():
            i = (cct, Cycler(qs2))
            l.append(i)
    PARTNERS = Cycler(l)

    BOARDS = Cycler(Board.objects.all())
    CONFIRMSTATES = Cycler(ConfirmationStates.objects())

    DURATIONS = Cycler(None, 1, 1, 30, 0, None, 365)

    fkw = dd.str2kw('name', _("Pharmacy"))  # Apotheke
    pharmacy_type = rt.modules.pcsw.ClientContactType.objects.get(**fkw)
    PHARMACIES = Cycler(rt.modules.contacts.Company.objects.filter(
        client_contact_type=pharmacy_type))

    for i, at in enumerate(AidType.objects.all()):
        for j in range(2):
            sd = dd.demo_date(days=i)
            kw = dict(start_date=sd,
                      board=BOARDS.pop(),
                      decision_date=dd.demo_date(days=i-1),
                      aid_type=at)

            kw.update(client=PROJECTS.pop())
            duration = DURATIONS.pop()
            if duration is not None:
                kw.update(end_date=sd+datetime.timedelta(days=duration))
            g = Granting(**kw)
            # g.after_ui_create(None)
            g.full_clean()
            if g.signer is not None:
                g.state = CONFIRMSTATES.pop()
            yield g

    # ConfirmationTypes = rt.modules.aids.ConfirmationTypes
    RefundConfirmation = rt.modules.aids.RefundConfirmation
    IncomeConfirmation = rt.modules.aids.IncomeConfirmation
    ClientContact = rt.modules.pcsw.ClientContact

    COACHES = Cycler(rt.modules.users.User.objects.filter(
        coaching_type__isnull=False))

    AMOUNTS = Cycler(123, 234, 345, 456, 678)
    CATEGORIES = Cycler(rt.modules.aids.Category.objects.all())

    # create 1 or 2 confirmations per granting
    urgent_aid_generated = 0
    for i, g in enumerate(Granting.objects.filter(aid_type__isnull=False)):
        ct = g.aid_type.confirmation_type
        num = i % 2 + 1
        if ct.model is RefundConfirmation:
            num = 3  # always create 3 confirmations per refund granting
        if g.aid_type.pharmacy_type == pharmacy_type:
            pharmacy = PHARMACIES.pop()
            yield ClientContact(
                type=pharmacy_type,
                company=pharmacy, client=g.client)
        for j in range(num):
            kw = dict(granting=g, client=g.client)
            kw.update(user=COACHES.pop())
            kw.update(start_date=g.start_date)
            kw.update(end_date=g.end_date)
            if g.signer is not None:
                kw.update(state=CONFIRMSTATES.pop())
                kw.update(signer=g.signer)
            if ct.model is IncomeConfirmation:
                kw.update(category=CATEGORIES.pop())
                kw.update(amount=AMOUNTS.pop())
            if ct.model is RefundConfirmation:
                doctor_type, doctor_cycler = PARTNERS.pop()
                doctor = doctor_cycler.pop()
                kw.update(doctor_type=doctor_type)
                kw.update(doctor=doctor)
                yield ClientContact(
                    type=doctor_type,
                    contact_person=doctor, client=g.client)
                # only the first confirmation has a pharmacy
                if g.aid_type.pharmacy_type == pharmacy_type and j == 0:
                    kw.update(pharmacy=pharmacy)

            yield ct.model(**kw)

        # for two refund grantings, create the corresponding
        # additional granting of urgent medical help
        if ct.model is RefundConfirmation and urgent_aid_generated < 2:
            kw = dict()
            kw.update(client=g.client)
            kw.update(start_date=g.start_date)
            kw.update(end_date=g.end_date)
            kw.update(aid_type=AidType.objects.get(short_name="DMH"))
            yield Granting(**kw)
            urgent_aid_generated += 1

    if False:  # no need to print them all.
               # lino_welfare.modlib.welfare.fixtures.demo2 is enough.
        ses = rt.login('theresia')
        for at in rt.modules.aids.AidType.objects.exclude(
                confirmation_type=''):
            M = at.confirmation_type.model
            et = ExcerptType.get_for_model(M)
            qs = M.objects.filter(granting__aid_type=at)
            for obj in qs:
                ses.selected_rows = [obj]
                yield et.get_or_create_excerpt(ses)
            
    def person2client(f, l):
        obj = Person.objects.get(first_name=f, last_name=l)
        mti.insert_child(obj, Client)

    person2client("Paul", "Frisch")
    person2client("Bruno", "Braun")

    # create a clothing_refund granting and excerpt for Paul Frisch:
    ses = rt.login("alicia")
    obj = Client.objects.get(name="Frisch Paul")
    at = AidType.objects.get(
        body_template='clothing_bank.body.html')
    g = Granting(aid_type=at, client=obj)
    g.full_clean()
    yield g
    M = at.confirmation_type.model
    conf = M(client=obj, granting=g)
    conf.full_clean()
    conf.on_create(ses)
    yield conf
    et = ExcerptType.get_for_model(M)
    ses.selected_rows = [conf]
    yield et.get_or_create_excerpt(ses)
Ejemplo n.º 39
0
def checksummaries():
    rt.login().run(settings.SITE.site_config.check_all_summaries)
Ejemplo n.º 40
0
    def test_suggest_cal_guests(self):
        """Tests a bugfix in :meth:`suggest_cal_guests
        <lino_xl.lib.courses.Course.suggest_cal_guests>`.

        """
        User = settings.SITE.user_model
        Guest = rt.models.cal.Guest
        Event = rt.models.cal.Event
        EventType = rt.models.cal.EventType
        GuestRole = rt.models.cal.GuestRole
        Recurrencies = rt.models.cal.Recurrencies
        Room = rt.models.cal.Room
        Enrolment = rt.models.courses.Enrolment
        Course = rt.models.courses.Course
        Line = rt.models.courses.Line
        EnrolmentStates = rt.models.courses.EnrolmentStates
        Pupil = rt.models.pcsw.Client

        robin = User(username='******', user_type=UserTypes.admin)
        robin.save()
        ar = rt.login('robin')
        settings.SITE.verbose_client_info_message = False

        pupil = Pupil(first_name="First", last_name="Pupil")
        pupil.save()

        pupil2 = Pupil(first_name="Second", last_name="Pupil")
        pupil2.save()

        et = EventType(name="lesson")
        et.full_clean()
        et.save()

        gr = GuestRole(name="pupil")
        gr.save()

        room = Room(name="classroom")
        room.save()

        line = Line(name="Test",
                    guest_role=gr,
                    event_type=et,
                    every_unit=Recurrencies.weekly)
        line.full_clean()
        line.save()
        course = Course(max_events=4,
                        line=line,
                        start_date=i2d(20150409),
                        user=robin,
                        monday=True,
                        room=room)
        course.full_clean()
        course.save()

        # Two enrolments, one is requested, the other confirmed. Only
        # the confirmed enrolments will be inserted as guests.

        self.create_obj(Enrolment,
                        course=course,
                        state=EnrolmentStates.requested,
                        pupil=pupil2)

        self.create_obj(Enrolment,
                        course=course,
                        state=EnrolmentStates.confirmed,
                        pupil=pupil)

        wanted, unwanted = course.get_wanted_auto_events(ar)
        self.assertEqual(
            ar.response['info_message'],
            'Generating events between 2015-04-13 and 2019-05-22 (max. 4).')
        self.assertEqual(len(wanted), 4)

        course.do_update_events.run_from_ui(ar)
        self.assertEqual(ar.response['success'], True)
        self.assertEqual(Event.objects.all().count(), 4)
        self.assertEqual(Guest.objects.all().count(), 4)
        # self.assertEqual(ar.response['info_message'], '')

        try:
            self.create_obj(Enrolment,
                            course=course,
                            state=EnrolmentStates.confirmed,
                            pupil=pupil)
            self.fail("Expected ValidationError")
        except ValidationError as e:
            if six.PY2:
                expected = "{'__all__': [u'Un object Inscription avec ces " \
                           "champs Atelier et B\\xe9n\\xe9ficiaire existe " \
                           "d\\xe9j\\xe0.']}"
            else:
                expected = "{'__all__': ['Un object Inscription avec ces champs Atelier et Bénéficiaire existe déjà.']}"
            self.assertEqual(str(e), expected)
Ejemplo n.º 41
0
    def test_checkin_guest(self):
        """Test whether notifications are being emitted.

        - when a visitor checks in
        - when a client is modified
        - when a coaching is created or modified
        - when a note is created or modified

        """
        User = settings.SITE.user_model
        Message = rt.models.notify.Message
        Note = rt.models.notes.Note
        NoteType = rt.models.notes.EventType
        Guest = rt.models.cal.Guest
        Event = rt.models.cal.Event
        EventType = rt.models.cal.EventType
        Client = rt.models.pcsw.Client
        ClientStates = rt.models.pcsw.ClientStates
        Coaching = rt.models.coachings.Coaching
        ContentType = rt.models.contenttypes.ContentType

        self.assertEqual(settings.SITE.use_websockets, False)

        robin = self.create_obj(User,
                                username='******',
                                user_type=UserTypes.admin,
                                language="en")
        caroline = self.create_obj(User,
                                   username='******',
                                   user_type='200',
                                   language="fr")
        alicia = self.create_obj(User,
                                 username='******',
                                 first_name="Alicia",
                                 user_type='120',
                                 language="fr")
        roger = self.create_obj(User,
                                username='******',
                                user_type='420',
                                language="en")

        ses = rt.login('robin')
        translation.activate('fr')

        first = self.create_obj(Client,
                                first_name="First",
                                last_name="Gérard",
                                client_state=ClientStates.coached)

        second = self.create_obj(Client,
                                 first_name="Second",
                                 last_name="Gérard",
                                 client_state=ClientStates.coached)
        self.create_obj(Coaching,
                        client=second,
                        start_date=i2d(20130501),
                        end_date=i2d(20140501),
                        user=caroline)
        second_roger = self.create_obj(Coaching,
                                       client=second,
                                       start_date=i2d(20140501),
                                       user=roger)
        self.create_obj(Coaching,
                        client=second,
                        start_date=i2d(20140520),
                        user=alicia)

        nt = self.create_obj(NoteType, name="System note")
        settings.SITE.site_config.update(system_note_type=nt)

        consultation = self.create_obj(EventType, name="consultation")

        # gr = self.create_obj(GuestRole, name="client")

        event = self.create_obj(Event, event_type=consultation, user=caroline)
        guest = self.create_obj(Guest, event=event, partner=first)

        self.assertEqual(str(guest), 'Présence #1 (22.05.2014)')

        # Checkin a guest

        res = ses.run(guest.checkin)
        # 'GÉRARD First (100) has started waiting for caroline'
        self.assertEqual(
            res, {
                'message': "GÉRARD First (100) a commencé d'attendre caróline",
                'success': True,
                'refresh': True
            })

        # it has caused a notification message:
        self.assertEqual(Message.objects.count(), 1)
        msg = Message.objects.all()[0]
        self.assertEqual(msg.user.username, 'caróline')

        self.assertEqual(msg.subject,
                         "GÉRARD First (100) a commencé d'attendre caróline")

        # it does *not* cause a system note:
        self.assertEqual(Note.objects.count(), 0)

        # When a client is modified, all active coaches get a
        # notification.
        # Note that Caroline doesn't get a notification because her
        # coaching is not active.
        # Alicia doesn't get a notification because she did it herself.
        # Roger doesn't get notified because he is user_type 420

        data = dict(first_name="Seconda", an="submit_detail")
        kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/pcsw/Clients/{}'.format(second.pk)
        self.client.force_login(alicia)
        res = self.client.put(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        # self.assertEqual(Message.objects.count(), 2)
        # self.check_notifications()
        self.check_notifications("""
=================================================== ======= ==============
 Sujet                                               Lié à   Destinataire
--------------------------------------------------- ------- --------------
 GÉRARD First (100) a commencé d'attendre caróline           caróline
=================================================== ======= ==============
""")

        # When a coaching is modified, all active coaches of that
        # client get a notification.

        Message.objects.all().delete()
        data = dict(start_date="02.05.2014", an="grid_put")
        data.update(mt=51)
        data.update(mk=second.pk)
        kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(robin)
        url = '/api/coachings/CoachingsByClient/{}'.format(second_roger.pk)
        res = self.client.put(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        # self.check_notifications()
        self.check_notifications("""
================================== ==================== ===========
 Subject                            Controlled by        Recipient
---------------------------------- -------------------- -----------
 robin a modifié róger / Gérard S   *róger / Gérard S*   Alicia
================================== ==================== ===========
""")

        # AssignCoach. we are going to Assign caroline as coach for
        # first client.

        # Request URL:http://127.0.0.1:8000/api/newcomers/AvailableCoachesByClient/5?_dc=1469707129689&fv=EVERS%20Eberhart%20(127)%20assigned%20to%20Hubert%20Huppertz%20&fv=EVERS%20Eberhart%20(127)%20is%20now%20coached%20by%20Hubert%20Huppertz%20for%20Laufende%20Beihilfe.&fv=false&mt=48&mk=127&an=assign_coach&sr=5
        # Request Method:GET

        # fv:EVERS Eberhart (127) assigned to Hubert Huppertz
        # fv:EVERS Eberhart (127) is now coached by Hubert Huppertz for Laufende Beihilfe.
        # fv:false
        # mt:48
        # mk:127
        # an:assign_coach
        # sr:5

        Message.objects.all().delete()
        # self.assertEqual(Coaching.objects.count(), 1)
        # self.check_coachings()
        self.check_coachings("""
==== ====================== ============== ============ ========== =========
 ID   Client                 Coached from   until        Coach      Primary
---- ---------------------- -------------- ------------ ---------- ---------
 1    GÉRARD Seconda (101)   01/05/2013     01/05/2014   caróline   No
 2    GÉRARD Seconda (101)   02/05/2014                  róger      No
 3    GÉRARD Seconda (101)   20/05/2014                  Alicia     No
==== ====================== ============== ============ ========== =========
""")

        self.assertEqual(Note.objects.count(), 0)

        data = dict(fv=["First GÉRARD assigned to caróline", "Body", 'false'],
                    an="assign_coach")
        data.update(mt=ContentType.objects.get_for_model(Client).pk)
        data.update(mk=first.pk)
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/api/newcomers/AvailableCoachesByClient/{}'.format(caroline.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        self.check_notifications("""
=================================== ======= ==============
 Sujet                               Lié à   Destinataire
----------------------------------- ------- --------------
 First GÉRARD assigned to caróline           caróline
=================================== ======= ==============
""")

        # self.check_coachings("")
        self.check_coachings("""
==== ====================== ======================== ============ ============= ==========
 ID   Bénéficiaire           En intervention depuis   au           Intervenant   Primaire
---- ---------------------- ------------------------ ------------ ------------- ----------
 1    GÉRARD Seconda (101)   01/05/2013               01/05/2014   caróline      Non
 2    GÉRARD Seconda (101)   02/05/2014                            róger         Non
 3    GÉRARD Seconda (101)   20/05/2014                            Alicia        Non
 4    GÉRARD First (100)     22/05/2014                            caróline      Oui
==== ====================== ======================== ============ ============= ==========
""")

        self.check_notes("""
==== ======== ==================== ===================================
 ID   Auteur   Bénéficiaire         Sujet
---- -------- -------------------- -----------------------------------
 1    Alicia   GÉRARD First (100)   First GÉRARD assigned to caróline
==== ======== ==================== ===================================
""")

        # Mark client as former

        # Request URL:http://127.0.0.1:8000/api/pcsw/Clients/181?_dc=1469714189945&an=mark_former&sr=181
        # Request Method:GET
        # an:mark_former

        Message.objects.all().delete()
        Note.objects.all().delete()

        data = dict(an="mark_former")
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/api/pcsw/Clients/{}'.format(second.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        res = AttrDict(json.loads(res.content))
        self.assertEqual(res.message,
                         'This will end 2 coachings of GÉRARD Seconda (101).')

        self.assertEqual(res.xcallback['title'], "Confirmation")
        kwargs = dict()
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/callbacks/{}/yes'.format(res.xcallback['id'])
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        res = AttrDict(json.loads(res.content))
        self.assertEqual(
            res.message,
            'Alicia a classé GÉRARD Seconda (101) comme <b>Ancien</b>.')
        self.assertTrue(res.success)

        self.check_notifications("""
=========================================================== ======================== ==============
 Sujet                                                       Lié à                    Destinataire
----------------------------------------------------------- ------------------------ --------------
 Alicia a classé GÉRARD Seconda (101) comme <b>Ancien</b>.   *GÉRARD Seconda (101)*   róger
=========================================================== ======================== ==============
""")

        # check two coachings have now an end_date set:
        # self.check_coachings()
        self.check_coachings("""
==== ====================== ======================== ============ ============= ==========
 ID   Bénéficiaire           En intervention depuis   au           Intervenant   Primaire
---- ---------------------- ------------------------ ------------ ------------- ----------
 1    GÉRARD Seconda (101)   01/05/2013               01/05/2014   caróline      Non
 2    GÉRARD Seconda (101)   02/05/2014               22/05/2014   róger         Non
 3    GÉRARD Seconda (101)   20/05/2014               22/05/2014   Alicia        Non
 4    GÉRARD First (100)     22/05/2014                            caróline      Oui
==== ====================== ======================== ============ ============= ==========
""")
        # self.check_notes()
        self.check_notes("""
==== ======== ====================== ===========================================================
 ID   Auteur   Bénéficiaire           Sujet
---- -------- ---------------------- -----------------------------------------------------------
 2    Alicia   GÉRARD Seconda (101)   Alicia a classé GÉRARD Seconda (101) comme <b>Ancien</b>.
==== ======== ====================== ===========================================================
""")

        #
        # RefuseClient
        #

        Message.objects.all().delete()
        Note.objects.all().delete()

        self.create_obj(Coaching,
                        client=first,
                        start_date=i2d(20130501),
                        user=roger)

        first.client_state = ClientStates.newcomer
        first.save()

        data = dict(fv=["20", ""], an="refuse_client")
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/api/pcsw/Clients/{}'.format(first.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        # self.check_notifications("")
        #if six.PY2:
        self.check_notifications("""
========================================================= ====================== ==============
Sujet                                                     Lié à                  Destinataire
--------------------------------------------------------- ---------------------- --------------
Alicia a classé GÉRARD First (100) comme <b>Refusé</b>.   *GÉRARD First (100)*   caróline
Alicia a classé GÉRARD First (100) comme <b>Refusé</b>.   *GÉRARD First (100)*   róger
========================================================= ====================== ==============
""")
        # self.check_notes()
        self.check_notes("""
==== ======== ==================== =========================================================
 ID   Auteur   Bénéficiaire         Sujet
---- -------- -------------------- ---------------------------------------------------------
 3    Alicia   GÉRARD First (100)   Alicia a classé GÉRARD First (100) comme <b>Refusé</b>.
==== ======== ==================== =========================================================
""")

        # When a note is created, all active coaches of that
        # client get a notification.

        Message.objects.all().delete()
        data = dict()
        data.update(mt=51)
        data.update(mk=second.pk)
        data.update(an='submit_insert')
        data.update(subject="test", projectHidden=second.pk)

        kwargs = dict(data=data)
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/api/notes/NotesByProject/{}'.format(second.pk)
        res = self.client.post(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        res = AttrDict(json.loads(res.content))
        self.assertEqual(res.data_record['id'], 4)
        new_note_pk = res.data_record['id']

        # self.check_notifications()
        self.check_notifications("""
============================== ================== ==============
 Sujet                          Lié à              Destinataire
------------------------------ ------------------ --------------
 Alicia created Event/Note #4   *Observation #4*   róger
============================== ================== ==============
""")

        Message.objects.all().delete()
        data = dict()
        data.update(mt=51)
        data.update(mk=second.pk)
        data.update(an='submit_detail')
        data.update(subject="test 2",
                    body="<p>Bla bla bla</p>",
                    projectHidden=second.pk)

        kwargs = dict(data=urlencode(data))
        # kwargs = dict(data=data)
        kwargs['REMOTE_USER'] = '******'
        self.client.force_login(alicia)
        url = '/api/notes/NotesByProject/{}'.format(new_note_pk)
        res = self.client.put(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        # self.check_notifications()
        # self.check_notifications("Aucun enregistrement")
        self.check_notifications("""
=============================== ================== ==============
 Sujet                           Lié à              Destinataire
------------------------------- ------------------ --------------
 Alicia modified Event/Note #4   *Observation #4*   róger
=============================== ================== ==============
""")

        self.assertEqual(Message.objects.count(), 1)
        msg = Message.objects.all()[0]
        # print msg.body
        self.assertEquivalent(
            msg.body, """
<div><p>Subject: test 2<br/>Client: [client 101] (Seconda GÉRARD)</p><p>Alicia modified [note 4] (test 2):</p><ul><li><b>Body</b> : 1 lines added</li><li><b>Subject</b> : test --&gt; test 2</li></ul></div>
""")
Ejemplo n.º 42
0
Archivo: demo.py Proyecto: DarioGT/lino
def objects():

    Person = dd.resolve_model(dd.apps.humanlinks.person_model)
    Link = rt.modules.humanlinks.Link
    LinkTypes = rt.modules.humanlinks.LinkTypes
    ar = rt.login()

    households = dd.resolve_app('households')
    if households:
        married = households.Type.objects.get(
            **dd.str2kw('name', _("Married")))
        divorced = households.Type.objects.get(
            **dd.str2kw('name', _("Divorced")))

    ig = InstanceGenerator()
    ig.add_instantiator(
        'person', Person, 'first_name last_name gender birth_date')
    ig.add_instantiator(
        'link', Link, 'parent child type')

    NAME1 = "Frisch"

    opa = ig.person("Hubert", NAME1, 'M', '1933-07-21')
    oma = ig.person("Gaby", "Frogemuth", 'F', '1934-08-04')

    P = ig.person("Paul", NAME1, 'M', '1967-06-19')
    L = ig.person("Ludwig", NAME1, 'M', '1968-06-01')
    A = ig.person("Alice", NAME1, 'F', '1969-12-19')
    B = ig.person("Bernd", NAME1, 'M', '1971-09-10')

    P1 = ig.person("Paula", "Einzig", 'F', '1968-12-19')
    P1A = ig.person("Peter", NAME1, 'M', '1987-06-19')
    P2 = ig.person("Petra", "Zweith", 'F', '1968-12-19')
    P2A = ig.person("Philippe", NAME1, 'M', '1997-06-19')
    P2B = ig.person("Clara", NAME1, 'F', '1999-06-19')
    P3 = ig.person("Dora", "Drosson", 'F', '1971-12-19')
    P3A = ig.person("Dennis", NAME1, 'M', '2001-06-19')

    L1 = ig.person("Laura", "Loslever", 'F', '1968-04-27')
    L1A = ig.person("Melba", NAME1, 'F', '2002-04-05')
    L1B = ig.person("Irma", NAME1, 'F', '2008-03-24')

    yield ig.flush()

    ig.link(opa, oma, LinkTypes.spouse)

    for i in (P, L, A, B):
        ig.link(opa, i, LinkTypes.parent)
        ig.link(oma, i, LinkTypes.parent)

    ig.link(P, P1A, LinkTypes.parent)
    ig.link(P1, P1A, LinkTypes.parent)

    ig.link(P, P2A, LinkTypes.parent)
    ig.link(P2, P2A, LinkTypes.parent)

    ig.link(P, P2B, LinkTypes.parent)
    ig.link(P2, P2B, LinkTypes.parent)

    ig.link(P, P3A, LinkTypes.parent)
    ig.link(P3, P3A, LinkTypes.parent)

    ig.link(P, P2, LinkTypes.spouse)

    ig.link(L, L1, LinkTypes.spouse)

    for i in (L1A, L1B):
        ig.link(L, i, LinkTypes.parent)
        ig.link(L1, i, LinkTypes.parent)

    yield ig.flush()

    if households:
        households.Household.create_household(ar, opa, oma, married)

        households.Household.create_household(ar, P, P1, divorced)
        hh = households.Household.create_household(ar, P, P2, married)
        hh.members_by_role('head')[0].set_primary(ar)
        hh.members_by_role('partner')[0].set_primary(ar)

        households.Household.create_household(ar, L, L1, married)

    A = ig.person("Albert", "Adam", 'M', '1973-07-21')
    B = ig.person("Bruno", "Braun", 'M', '1973-07-22')

    E = ig.person("Eveline", "Evrard", 'F', '1974-08-21')
    F = ig.person("Françoise", "Freisen", 'F', '1974-08-22')

    I = ig.person("Ilja", "Adam", 'M', '1994-08-22')
    J = ig.person("Jan", "Braun", 'M', '1996-08-22')
    K = ig.person("Kevin", "Braun", 'M', '1998-08-22')
    L = ig.person("Lars", "Braun", 'M', '1998-08-22')

    M = ig.person("Monique", "Braun", 'F', '2000-08-22')
    N = ig.person("Noémie", "Adam", 'F', '2002-08-22')
    O = ig.person("Odette", "Adam", 'F', '2004-08-22')
    P = ig.person("Pascale", "Adam", 'F', '2004-08-22')

    yield ig.flush()

    ig.link(A, I, LinkTypes.parent)
    ig.link(A, N, LinkTypes.parent)
    ig.link(A, O, LinkTypes.parent)
    ig.link(A, P, LinkTypes.parent)

    ig.link(B, J, LinkTypes.parent)
    ig.link(B, K, LinkTypes.parent)
    ig.link(B, L, LinkTypes.parent)
    ig.link(B, M, LinkTypes.parent)

    ig.link(E, I, LinkTypes.parent)
    ig.link(E, J, LinkTypes.parent)
    ig.link(E, K, LinkTypes.parent)
    ig.link(E, L, LinkTypes.parent)

    ig.link(F, M, LinkTypes.parent)
    ig.link(F, N, LinkTypes.parent)
    ig.link(F, O, LinkTypes.parent)
    ig.link(F, P, LinkTypes.parent)

    ig.link(A, F, LinkTypes.spouse)
    ig.link(B, E, LinkTypes.spouse)

    yield ig.flush()

    if households:
        households.Household.create_household(ar, A, E, married)
        households.Household.create_household(ar, A, F, divorced)
        households.Household.create_household(ar, B, E, divorced)
        households.Household.create_household(ar, B, F, married)
Ejemplo n.º 43
0
    def test01(self):
        # print("20180502 test_debts.test01()")

        # Member = rt.models.households.Member
        Household = rt.models.households.Household
        Person = rt.models.contacts.Person
        Genders = rt.models.system.Genders
        Budget = rt.models.debts.Budget
        Actor = rt.models.debts.Actor
        Entry = rt.models.debts.Entry
        
        def check_count(b, a, e):
            self.assertEqual(Budget.objects.count(), b)
            self.assertEqual(Actor.objects.count(), a)
            self.assertEqual(Entry.objects.count(), e)
        
        

        u = users.User(username='******',
                       user_type=UserTypes.admin,
                       language="en")
        u.save()
        # be = countries.Country(name="Belgium", isocode="BE")
        # be.save()
        # kw = dict()
        # # kw.update(card_number="123456789")
        # # kw.update(national_id="680601 053-29")
        # kw.update(id=116)
        # kw.update(first_name="Jean")
        # kw.update(middle_name="Jacques")
        # kw.update(last_name="Jeffin")
        # obj = pcsw.Client(**kw)
        # obj.full_clean()
        # obj.save()

        from lino_welfare.modlib.debts.fixtures.minimal import objects
        for o in objects():
            o.save()
        # from lino_xl.lib.households.fixtures.std import objects
        # for o in objects():
        #     o.save()

        # Reproduce ticket #521
        ar = rt.login('root')
        
        p1 = Person(first_name="A", last_name="A", gender=Genders.male)
        p1.save()
        p2 = Person(first_name="B", last_name="B", gender=Genders.female)
        p2.save()
        h = Household.create_household(ar, p1, p2, None)

        # The household has for whatever reason an empty member
        # entry. Lino should ignore this entry.
        h.add_member(None)

        check_count(0, 0, 0)
        
        b = Budget(partner=h, user=u)
        b.save()
        b.fill_defaults()
        # from django.utils.encoding import force_text
        # s = ' & '.join([force_text(a) for a in b.get_actors()])
        # s = '{0} & {1}'.format(*b.get_actors())
        # self.assertEqual(s, "Mr. & Mrs.")

        ##
        ## Reproduce ticket #159 ('NoneType' object is not iterable
        ## (after duplicating a budget)) and verify ticket #471
        ## (Become the author after duplicating a budget).
        ##
        
        self.assertEqual(b.user.username, 'root')
        self.assertEqual(b.id, 1)

        ou = users.User(username='******',
                        user_type=UserTypes.admin,
                        language="en")
        ou.save()
        ar = rt.login('other')

        check_count(1, 2, 44)
        
        new = b.duplicate.run_from_code(ar)
        self.assertEqual(new.user.username, 'other')
        self.assertEqual(new.id, 2)
        
        check_count(2, 4, 88)
        new = Budget.objects.get(pk=2)
        self.assertEqual(new.user.username, 'other')
       
        url = "/api/debts/Budgets/1?&an=duplicate&sr=1"
        dlg = []
        dlg.append((
            "This will create a copy of Budget 1 for A & B A-B Are you sure?",
            'yes'))
        dlg.append((
            'Duplicated Budget 1 for A & B A-B to Budget 3 for A & B A-B.',
            None))
        self.check_callback_dialog(self.client.get, 'other', url, dlg)

        check_count(3, 6, 132)

        new = Budget.objects.get(pk=3)
        self.assertEqual(new.user.username, 'other')
Ejemplo n.º 44
0
    def test_comment(self, logger):
        """Test what happens when a comment is posted on a ticket with
        watchers.

        """
        ContentType = rt.models.contenttypes.ContentType
        Comment = rt.models.comments.Comment
        Ticket = rt.models.tickets.Ticket
        Project = rt.models.tickets.Project
        Vote = rt.models.votes.Vote
        Message = rt.models.notify.Message
        User = settings.SITE.user_model
        create(Project, name="Project")
        robin = create(
            User, username='******',
            first_name="Robin",
            user_type=UserTypes.admin)
        aline = create(
            User, username='******',
            first_name="Aline",
            email="*****@*****.**", language='fr')
        obj = create(
            Ticket, summary="Save the world, après moi le déluge",
            user=robin)
        create(Vote, votable=obj, user=aline)
        
        self.assertEqual(Message.objects.count(), 0)
        
        url = "/api/comments/CommentsByRFC"
        post_data = dict()
        post_data[constants.URL_PARAM_ACTION_NAME] = 'submit_insert'
        post_data.update(short_text="I don't agree.")
        post_data[constants.URL_PARAM_MASTER_PK] = obj.pk
        ct = ContentType.objects.get_for_model(Ticket)
        post_data[constants.URL_PARAM_MASTER_TYPE] = ct.id
        # post_data[constants.URL_PARAM_REQUESTING_PANEL] = '123'
        response = self.client.post(
            url, post_data,
            REMOTE_USER='******',
            HTTP_ACCEPT_LANGUAGE='en')
        result = self.check_json_result(
            response, 'rows success message close_window')
        self.assertEqual(result['success'], True)
        self.assertEqual(
            result['message'],
            """Comment "Comment #1" has been created.""")

        self.assertEqual(Message.objects.count(), 1)
        msg = Message.objects.all()[0]
        # self.assertEqual(msg.message_type)
        self.assertEqual(msg.seen, None)
        self.assertEqual(msg.user, aline)
        expected = """Robin a commenté [ticket 1] (Save the world, """\
                   """après moi le déluge): I don't agree."""
        self.assertEqual(expected, msg.body)
        
        # manually set created timestamp so we can test on it later.
        now = datetime.datetime(2016, 12, 22, 19, 45, 55)
        if settings.USE_TZ:
            now = make_aware(now)
        msg.created = now
        msg.save()
        
        settings.SERVER_EMAIL = '*****@*****.**'
        
        with capture_stdout() as out:
            send_pending_emails_often()
            
        out = out.getvalue().strip()
        print(out)

        expected = """send email
Sender: [email protected]
To: [email protected]
Subject: [Django] Robin a comment? #1 (? Save the world, apr?s moi le d?luge)
<body>
(22/12/2016 19:45)
Robin a comment? <a href="http://127.0.0.1:8000/api/tickets/Ticket/1" title="Save the world, apr&#232;s moi le d&#233;luge">#1</a> (Save the world, apr?s moi le d?luge): I don't agree.
</body>
"""        
        self.assertEquivalent(expected, out)
        
        self.assertEqual(logger.debug.call_count, 1)
        logger.debug.assert_called_with(
            'Send out %s summaries for %d users.',
            MailModes.often, 1)
        # logger.info.assert_called_with(
        #     'Notify %s users about %s', 1, 'Change by robin')

        Message.objects.all().delete()
        self.assertEqual(Message.objects.count(), 0)
        
        ar = rt.login('robin')
        cw = ChangeWatcher(obj)
        obj.priority = 200
        obj.save_watched_instance(ar, cw)


        with capture_stdout() as out:
            send_pending_emails_often()
            
        out = out.getvalue().strip()
        # print(out)
        expected = ""
        # self.assertEquivalent(expected, out)
        
        # we do not test the output because the datetime changes. But
        # we actually just wanted to see if there is no
        # UnicodeException. We capture it in order to hide it from
        # test runner output.
        
        self.assertEqual(logger.debug.call_count, 2)
        logger.debug.assert_called_with(
            'Send out %s summaries for %d users.',
            MailModes.often, 1)
Ejemplo n.º 45
0
def objects():
    yield lib_objects()

    Client = rt.modules.pcsw.Client
    ClientStates = rt.modules.pcsw.ClientStates
    Company = rt.modules.contacts.Company
    Journal = rt.modules.ledger.Journal
    AccountInvoice = rt.modules.vatless.AccountInvoice
    InvoiceItem = rt.modules.vatless.InvoiceItem
    Account = rt.modules.accounts.Account
    AccountTypes = rt.modules.accounts.AccountTypes
    PaymentOrder = rt.modules.finan.PaymentOrder
    PaymentOrderItem = rt.modules.finan.PaymentOrderItem

    CLIENTS = Cycler(Client.objects.filter(client_state=ClientStates.coached)[:5])
    if len(CLIENTS) == 0:
        raise Exception("Oops, no CLIENTS in %s" % CLIENTS)
    qs = Company.objects.filter(sepa_accounts__iban__gt="").distinct()
    # RECIPIENTS = Cycler(qs[:5])
    RECIPIENTS = Cycler(qs)
    if len(RECIPIENTS) == 0:
        raise Exception("Oops, no recipients in %s" % qs)
    ACCOUNTS = Cycler(Account.objects.filter(type=AccountTypes.expenses))
    if len(ACCOUNTS) == 0:
        raise Exception("Oops, no ACCOUNTS in %s" % ACCOUNTS)
    AMOUNTS = Cycler(10, "12.50", 25, "29.95", 120, "5.33")
    ITEMNUMS = Cycler(1, 5, 1, 1, 7, 1)

    ses = rt.login("wilfried")
    REG = Journal.get_by_ref("REG")
    SREG = Journal.get_by_ref("SREG")
    for i in range(30):
        kw = dict()
        kw.update(partner=RECIPIENTS.pop())
        # if i % 9 != 0:
        #     kw.update(project=CLIENTS.pop())
        kw.update(entry_date=dd.today(-5 * i))
        kw.update(voucher_date=dd.today(-5 * i - 1))
        kw.update(due_date=dd.today(30 - 5 * i))
        kw.update(user=ses.get_user())
        itemnum = ITEMNUMS.pop()
        acc = ACCOUNTS.pop()
        prj = CLIENTS.pop()
        if itemnum == 1:
            kw.update(journal=REG)
            kw.update(project=prj)
        else:
            kw.update(journal=SREG)
        obj = AccountInvoice(**kw)
        yield obj
        for j in range(itemnum):
            yield InvoiceItem(voucher=obj, amount=AMOUNTS.pop(), project=prj, account=acc)
            prj = CLIENTS.pop()
        obj.register(ses)
        obj.save()

    refs = ("832/3331/01", "832/330/01", "832/330/03F", "832/330/03", "832/3343/21", "832/334/27")
    ACCOUNTS = list(rt.modules.accounts.Account.objects.filter(ref__in=refs))
    AMOUNTS = Cycler("648.91", "817.36", "544.91", "800.08")
    jnl = Journal.get_by_ref("AAW")
    for i in range(3):
        kw = dict()
        kw.update(entry_date=dd.today(-30 * i))
        kw.update(voucher_date=dd.today(-30 * i))
        kw.update(journal=jnl)
        kw.update(user=ses.get_user())
        for acc in ACCOUNTS:
            kw.update(narration=acc.name)
            kw.update(item_account=acc)
            obj = PaymentOrder(**kw)
            yield obj
            for j in range(5):
                cli = CLIENTS.pop()
                yield PaymentOrderItem(seqno=j + 1, voucher=obj, amount=AMOUNTS.pop(), project=cli)
            # this is especially slow in a sqlite :memory: databae
            # dd.logger.info(
            #     "20151211 Gonna register PaymentOrder %s %s %s",
            #     dd.fds(obj.entry_date), obj, obj.narration)
            obj.register(ses)
            obj.save()
Ejemplo n.º 46
0
def objects():

    Line = rt.models.courses.Line
    Teacher = dd.plugins.courses.teacher_model
    Course = rt.models.courses.Course
    Topic = rt.models.courses.Topic
    Enrolment = rt.models.courses.Enrolment
    User = rt.models.users.User
    EventType = rt.models.cal.EventType
    Guest = rt.models.cal.Guest
    GuestRole = rt.models.cal.GuestRole
    GuestStates = rt.models.cal.GuestStates
    EntryStates = rt.models.cal.EntryStates
    Event = rt.models.cal.Event
    Person = rt.models.contacts.Person
    CommentType = rt.models.comments.CommentType
    TrendStage = rt.models.trends.TrendStage
    TrendArea = rt.models.trends.TrendArea

    for area, stages in trends_config:
        ta = named(TrendArea, area)
        yield ta
        for stage in stages:
            yield named(TrendStage, stage, trend_area=ta)
    
    yield EventType(**dd.str2kw('name', _("First contact")))
    
    kw = dd.str2kw('name', _("Lesson"))
    kw.update(dd.str2kw('event_label', _("Lesson")))
    event_type = EventType(**kw)
    yield event_type

    pupil = named(GuestRole, _("Pupil"))
    yield pupil
    yield named(GuestRole, _("Assistant"))

    topic_citizen = named(Topic, _("Citizen course"))
    yield topic_citizen
    
    topic_lang = named(Topic, _("Language courses"))
    yield topic_lang
    
    kw.update(topic=topic_citizen)
    kw = dict(event_type=event_type, guest_role=pupil)
    yield named(Line, _("Citizen course"), **kw)
    
    kw.update(topic=topic_lang)
    alpha = named(Line, _("Alphabetisation"), **kw)
    yield alpha
    yield named(Line, _("German for beginners"), **kw)
    yield named(Line, _("German A1+"), **kw)
    yield named(Line, _("German A2"), **kw)
    yield named(Line, _("German A2 (women)"), **kw)
        
    yield named(CommentType, _("Phone call"))
    yield named(CommentType, _("Visit"))
    yield named(CommentType, _("Individual consultation"))
    yield named(CommentType, _("Internal meeting"))
    yield named(CommentType, _("Meeting with partners"))
    
    laura = Teacher(first_name="Laura", last_name="Lieblig")
    yield laura
    yield User(username="******", user_type=UserTypes.teacher,
               partner=laura)
    
    yield User(username="******", user_type=UserTypes.user)
    yield User(username="******", user_type=UserTypes.auditor)
    yield User(username="******", user_type=UserTypes.coordinator)
    yield User(username="******", user_type=UserTypes.secretary)

    USERS = Cycler(User.objects.exclude(
        user_type__in=(UserTypes.auditor, UserTypes.admin)))
    
    kw = dict(monday=True, tuesday=True, thursday=True, friday=True)
    kw.update(
        line=alpha,
        start_date=dd.demo_date(-30),
        start_time="9:00", end_time="12:00",
        max_date=dd.demo_date(10),
        every_unit=Recurrencies.daily,
        user=USERS.pop(),
        teacher=laura,
        max_places=5)
    
    yield Course(**kw)

    kw.update(start_time="14:00", end_time="17:00", user=USERS.pop())
    yield Course(**kw)

    
    PUPILS = Cycler(dd.plugins.courses.pupil_model.objects.all())
    # print(20170302, dd.plugins.courses.pupil_model.objects.all())
    COURSES = Cycler(Course.objects.all())
    STATES = Cycler(EnrolmentStates.objects())

    def fits(course, pupil):
        if course.max_places and course.get_free_places() == 0:
            return False
        if Enrolment.objects.filter(course=course, pupil=pupil).count():
            return False
        return True
    for i in range(10):
        course = COURSES.pop()
        pupil = PUPILS.pop()
        while not fits(course, pupil):
            course = COURSES.pop()
        kw = dict(user=USERS.pop(), course=course, pupil=pupil)
        kw.update(request_date=dd.demo_date(-i))
        kw.update(state=STATES.pop())
        yield Enrolment(**kw)


    ar = rt.login('robin')
    for obj in Course.objects.all():
        obj.update_auto_events(ar)
        
    # Suggested calendar entries older than 7 days should be marked as
    # either took_place or cancelled. 
    qs = Event.objects.filter(
        start_date__lte=dd.demo_date(-7),
        state=EntryStates.suggested)
    for i, obj in enumerate(qs):
        if i % 9:
            obj.state = EntryStates.took_place
        else:
            obj.state = EntryStates.cancelled
        obj.full_clean()
        obj.save()

    # participants of events which took place should be marked as
    # either absent or present or excused:
    qs = Guest.objects.filter(
        event__start_date__lte=dd.demo_date(-7),
        event__state=EntryStates.took_place)
    for i, obj in enumerate(qs):
        if i % 9:
            obj.state = GuestStates.present
        elif i % 3:
            obj.state = GuestStates.absent
        else:
            obj.state = GuestStates.excused
        obj.full_clean()
        obj.save()
Ejemplo n.º 47
0
    def test_create_entry(self):
        ses = rt.login()

        Person = rt.models.app.Person
        Restaurant = rt.models.app.Restaurant
        Place = rt.models.app.Place
        Visit = rt.models.app.Visit
        Meal = rt.models.app.Meal

        # Create some initial data:

        Person(name="Alfred").save()
        Person(name="Bert").save()
        Person(name="Claude").save()
        Person(name="Dirk").save()
        r = Restaurant(id=1, name="First")
        r.save()
        for i in 1, 2:
            r.owners.add(Person.objects.get(pk=i))
        for i in 3, 4:
            r.cooks.add(Person.objects.get(pk=i))

        # Here is our data:

        lst = list(Person.objects.all())
        self.assertEqual(str(lst), "[<Person: Alfred>, <Person: Bert>, <Person: Claude>, <Person: Dirk>]")

        lst = list(Restaurant.objects.all())
        self.assertEqual(
            str(lst),
            "[Restaurant #1 ('First (owners=Alfred, Bert, cooks=Claude, Dirk)')]")
        
        x = list(Place.objects.all())
        self.assertEqual(
            str(x),
            "[Place #1 ('First (owners=Alfred, Bert)')]")


        """
        The :func:`delete_child` function
        ---------------------------------

        Imagine that a user of our application discovers that Restaurant #1
        isn't actually a `Restaurant`, it's just a `Place`.  They would like
        to "remove it's Restaurant data" from the database, but keep the
        `Place` data.  Especially the primary key (#1) and the related objects
        (the owners) should remain unchanged. But the cooks must be deleted
        since they exist only for restaurants.

        It seems that this is not trivial in Django (`How do you delete child
        class object without deleting parent class object?
        <http://stackoverflow.com/questions/9439730>`__).  That's why we wrote
        the :func:`delete_child` function.
        Here is how to "reduce" a Restaurant to a `Place` by 
        calling the :func:`delete_child` function:

        """

        from lino.utils.mti import delete_child

        p = Place.objects.get(id=1)
        delete_child(p, Restaurant)

        # The Place still exists, but no longer as a Restaurant:

        x = Place.objects.get(pk=1)
        self.assertEqual(
            str(x),
            "First (owners=Alfred, Bert)")

        try:
            list(Restaurant.objects.get(pk=1))
            self.fail("Expected DoesNotExist")
        except Restaurant.DoesNotExist:
            pass
            # Traceback (most recent call last):
        # ...
        # DoesNotExist: Restaurant matching query does not exist.

        """

        The :func:`insert_child` function
        ----------------------------------

        The opposite operation, "promoting a simple Place to a Restaurant", 
        is done using :func:`insert_child`.

        from lino.utils.mti import insert_child

        Let's first create a simple Place #2 with a single owner.
        """

        obj = Place(id=2, name="Second")
        obj.save()
        obj.owners.add(Person.objects.get(pk=2))
        obj.save()
        self.assertEqual(
            str(obj),
            "Second (owners=Bert)")

        # Now this Place becomes a Restaurant and hires 2 cooks:

        obj = insert_child(obj, Restaurant)
        for i in 3, 4:
            obj.cooks.add(Person.objects.get(pk=i))
        self.assertEqual(
            str(obj),
            "Second (owners=Bert, cooks=Claude, Dirk)")

        # If you try to promote a Person to a Restaurant, you'll get an exception:

        person = Person.objects.get(pk=2)
        try:
            insert_child(person, Restaurant).save()
            self.fail("Expected ValidationError")
        except ValidationError as e:
            self.assertEqual(
                str(e), "['A Person cannot be parent for a Restaurant']")

        """
        The :class:`EnableChild` virtual field 
        --------------------------------------

        This section shows how the :class:`EnableChild` virtual field is being 
        used by Lino, and thus is Lino-specific.


        After the above examples our database looks like this:

        """
         
        x = list(Person.objects.all())
        self.assertEqual(
            str(x),
            "[<Person: Alfred>, <Person: Bert>, <Person: Claude>, <Person: Dirk>]")
        x = list(Place.objects.all())
        self.assertEqual(
            str(x),
            "[Place #1 ('First (owners=Alfred, Bert)'), Place #2 ('Second (owners=Bert)')]")
        x = list(Restaurant.objects.all())
        self.assertEqual(
            str(x),
            "[Restaurant #2 ('Second (owners=Bert, cooks=Claude, Dirk)')]")

        # Let's take Place #1 and look at it.

        obj = Place.objects.get(pk=1)
        self.assertEqual(
            str(obj), "First (owners=Alfred, Bert)")

        # How to see whether a given Place is a Restaurant?

        x  = ""
        for i in Place.objects.all():
            x += "{0} -> {1}\n".format(i, i.get_mti_child('restaurant'))
        self.assertEqual(
            x, """\
First (owners=Alfred, Bert) -> None
Second (owners=Bert) -> Second (owners=Bert, cooks=Claude, Dirk)
""")

        # Let's promote First (currently a simple Place) to a Restaurant:

        x = insert_child(obj, Restaurant)
        # Restaurant #1 ('#1 (name=First, owners=Alfred, Bert, cooks=)')


        # And Second stops being a Restaurant:

        second = Place.objects.get(pk=2)
        delete_child(second, Restaurant)

        # This operation has removed the related Restaurant instance:

        try:
            Restaurant.objects.get(pk=2)
            self.fail("Expected DoesNotExist")
        except Restaurant.DoesNotExist:
            pass

        # And finally, rather to explain why Restaurants sometimes 
        # close and later reopen:

        bert = Person.objects.get(pk=2)
        second = Place.objects.get(pk=2)
        insert_child(second, Restaurant)
        # Restaurant #2 ('#2 (name=Second, owners=Bert, cooks=)')

        # Now we can see this place again as a Restaurant

        second = Restaurant.objects.get(pk=2)

        # And engage for example a new cook:

        second.cooks.add(bert)
        # second
        # Restaurant #2 ('#2 (name=Second, owners=Bert, cooks=Bert)')



        # Related objects
        # ---------------

        # Now let's have a more detailed look at what happens to the related 
        # objects (Person, Visit and Meal).

        # Bert, the owner of Restaurant #2 does two visits:

        second = Restaurant.objects.get(pk=2)
        Visit(purpose="Say hello", person=bert, place=second).save()
        Visit(purpose="Hang around", person=bert, place=second).save()
        x = list(second.visit_set.all())
        self.assertEqual(
            str(x),
            "[<Visit: Say hello visit by Bert at Second>, <Visit: Hang around visit by Bert at Second>]")

        # Claude and Dirk, now workless, still go to eat in restaurants:

        Meal(what="Fish",person=Person.objects.get(pk=3),restaurant=second).save()
        Meal(what="Meat",person=Person.objects.get(pk=4),restaurant=second).save()
        x = list(second.meal_set.all())
        self.assertEqual(
            str(x),
            "[<Meal: Claude eats Fish at Second>, <Meal: Dirk eats Meat at Second>]")

        # Now we reduce Second to a Place:

        second = Place.objects.get(pk=2)
        delete_child(second, Restaurant)

        # Restaurant #2 no longer exists:

        try:
            Restaurant.objects.get(pk=2)
            self.fail("Expected DoesNotExist")
        except Restaurant.DoesNotExist:
            pass
        
        # Note that `Meal` has :attr:`allow_cascaded_delete
        # <lino.core.model.Model.allow_cascaded_delete>` set to
        # `['restaurant']`, otherwise the above code would have raised a
        # ValidationError :message:`Cannot delete #2
        # (name=Second,owners=Bert,cooks=Bert) because 2 meals refer to it.` But
        # the meals have been deleted:

        self.assertEqual(Meal.objects.count(), 0)

        # Of course, #2 remains as a Place
        # The owner and visits have been taken over:

        second = Place.objects.get(pk=2)
        x = list(second.visit_set.all())
        self.assertEqual(
            str(x),
            "[<Visit: Say hello visit by Bert at Second>, <Visit: Hang around visit by Bert at Second>]")


        # The :func:`create_mti_child` function
        # -------------------------------------

        # This function is for rather internal use.  :ref:`Python dumps <dpy>`
        # generated by :class:`lino.utils.dpy.Serializer` use this function for
        # creating MTI children instances without having to lookup their parent.

        # .. currentmodule:: lino.utils.dpy

        # In a Python dump we are in a special situation: All Place instances
        # are being generated first, and in another step we are going to create
        # all the Restaurant instances.  So how can we create a Restaurant whose
        # Place already exists *without first having to do a lookup of the Place
        # record*?  That's why :func:`create_mti_child` was written for.

        obj = Place(id=3, name="Third")
        obj.save()
        obj.owners.add(Person.objects.get(pk=2))
        obj.save()
        self.assertEqual(
            str(obj),
            "Third (owners=Bert)")

        from lino.utils.dpy import create_mti_child
        obj = create_mti_child(Place, 3, Restaurant)

        # The return value is technically a normal model instance,
        # but whose `save` and `full_clean` methods have been 
        # patched: `full_clean` is overridden to do nothing, 
        # and `save` will call a "raw" save to avoid the 
        # need of a proper Place instance for that Restaurant.
        # The only thing you can do with it is to save it:

        obj.save()

        # The `save` and `full_clean` methods are the only methods that 
        # will be called by 
        # :class:`lino.utils.dpy.Deserializer`.

        # To test whether :func:`create_mti_child` did her job, 
        # we must re-read an instance:

        obj = Restaurant.objects.get(pk=3)
        self.assertEqual(
            str(obj),
            "Third (owners=Bert, cooks=)")

        # Note that :func:`create_mti_child` supports changing the
        # `name` although that field is defined in the Place model,
        # not in Restaurant. This feature was added 20170626 (#1926,
        # #1923). Before that date Lino raised an exception when you
        # specified a field of the parent model.  And before *that*
        # (until 20120930) this case was silently ignored for
        # backwards compatibility (`/blog/2011/1210`).

        obj = Place(id=4, name="Fourth")
        obj.save()
        ow = create_mti_child(Place, 4, Restaurant, name="A new name")
        ow.full_clean()
        ow.save()
        obj = Restaurant.objects.get(id=4)
        self.assertEqual(obj.name, "A new name")
Ejemplo n.º 48
0
    def test01(self):

        u = users.User(username='******',
                       profile=UserTypes.admin,
                       language="en")
        u.save()
        # be = countries.Country(name="Belgium", isocode="BE")
        # be.save()
        # kw = dict()
        # # kw.update(card_number="123456789")
        # # kw.update(national_id="680601 053-29")
        # kw.update(id=116)
        # kw.update(first_name="Jean")
        # kw.update(middle_name="Jacques")
        # kw.update(last_name="Jeffin")
        # obj = pcsw.Client(**kw)
        # obj.full_clean()
        # obj.save()

        from lino_welfare.modlib.debts.fixtures.minimal import objects
        for o in objects():
            o.save()
        # from lino_xl.lib.households.fixtures.std import objects
        # for o in objects():
        #     o.save()

        # Reproduce ticket #521
        ar = rt.login('root')
        # Member = rt.modules.households.Member
        Household = rt.modules.households.Household
        Person = rt.modules.contacts.Person
        Genders = rt.modules.system.Genders
        Budget = rt.modules.debts.Budget
        
        p1 = Person(first_name="A", last_name="A", gender=Genders.male)
        p1.save()
        p2 = Person(first_name="B", last_name="B", gender=Genders.female)
        p2.save()
        h = Household.create_household(ar, p1, p2, None)

        # The household has for whatever reason an empty member
        # entry. Lino should ignore this entry.
        h.add_member(None)

        b = Budget(partner=h, user=u)
        b.save()
        b.fill_defaults()
        # from django.utils.encoding import force_text
        # s = ' & '.join([force_text(a) for a in b.get_actors()])
        # s = '{0} & {1}'.format(*b.get_actors())
        # self.assertEqual(s, "Mr. & Mrs.")

        ##
        ## Reproduce ticket #159 ('NoneType' object is not iterable
        ## (after duplicating a budget)) and verify ticket #471
        ## (Become the author after duplicating a budget).
        ##
        
        self.assertEqual(b.user.username, 'root')
        self.assertEqual(b.id, 1)

        ou = users.User(username='******',
                        profile=UserTypes.admin,
                        language="en")
        ou.save()
        ar = rt.login('other')
        new = b.duplicate.run_from_code(ar)
        self.assertEqual(new.user.username, 'other')
        self.assertEqual(new.id, 2)
        # new.save()  # must save after on_duplicate
        new = rt.modules.debts.Budget.objects.get(pk=2)
        self.assertEqual(new.user.username, 'other')

        url = "/api/debts/Budgets/1?&an=duplicate&sr=1"
        res = test_client.get(url, REMOTE_USER='******')
        rv = json.loads(res.content)
        self.assertEqual(
            rv['message'],
            u'Duplicated Budget 1 for A-B to Budget 3 for A-B.')
        new = rt.modules.debts.Budget.objects.get(pk=3)

        self.assertEqual(new.user.username, 'other')
Ejemplo n.º 49
0
    def test01(self):
        from lino.modlib.users.choicelists import UserTypes
        Ticket = rt.models.tickets.Ticket
        # Project = rt.models.tickets.Project
        # Line = rt.models.courses.Line
        # Activity = rt.models.courses.Course
        # Enrolment = rt.models.courses.Enrolment
        Meeting = rt.models.meetings.Meeting
        Change = rt.models.changes.Change
        User = rt.models.users.User
        Vote = rt.models.votes.Vote
        VoteStates = rt.models.votes.VoteStates
        VotesByVotable = rt.models.votes.VotesByVotable
        # ContentType = rt.models.contenttypes.ContentType
        # ct_Ticket = ContentType.objects.get_for_model(Ticket)

        # create(Project, name='project')

        robin = create(User, username='******',
                       first_name="Robin",
                       user_type=UserTypes.admin,
                       language="en")
        anna = create(User, username='******',
                      first_name="Anna",
                      user_type=UserTypes.user,
                      language="en")
        berta = create(User, username='******',
                       first_name="Berta",
                       user_type=UserTypes.user,
                       language="en")
        meeting = create(Meeting, name="Test")
        # sprints = create(Line, name="Sprints")
        # sprint = create(Activity, line=sprints)
        #
        # Enrolment(course=sprint, pupil=robin)
        
        ses = rt.login('robin')
        
        ticket = create(Ticket, summary="First", user=robin)
        ticket.after_ui_save(ses, None)
        vote = Vote.objects.get(votable=ticket)
        self.assertEqual(vote.user, robin)
        self.assertEqual(vote.state, VoteStates.author)
        
        def check_success(ia, **kwargs):
            rv = ia.run_from_session(ses, **kwargs)
            self.assertEqual(rv, {'success': True, 'refresh': True})

        check_success(ticket.mark_talk)
        check_success(ticket.mark_started)
        check_success(ticket.mark_refused)
        check_success(ticket.mark_closed)
        check_success(ticket.mark_refused)
        
        Vote.objects.all().delete()
        Ticket.objects.all().delete()
        
        self.assertEqual(Vote.objects.count(), 0)

        ticket = create(
            Ticket, summary="Second", user=robin, end_user=anna)
        ticket.after_ui_save(ses, None)
        self.assertEqual(Vote.objects.count(), 2)
        
        vote = Vote.objects.get(votable=ticket, user=anna)
        self.assertEqual(vote.state, VoteStates.author)

        
        # manually creating a vote will make the vote invited:
        vote = create(
            Vote, votable=ticket, user=berta)
        # vote.after_ui_save(ses, None)
        self.assertEqual(vote.state, VoteStates.invited)
Ejemplo n.º 50
0
 def handle(self, *args, **options):
     ses = rt.login()
     ses.run(settings.SITE.site_config.check_all_summaries)
Ejemplo n.º 51
0
Archivo: demo.py Proyecto: forexblog/xl
def objects():

    Member = rt.models.households.Member
    MemberRoles = rt.models.households.MemberRoles
    Person = dd.plugins.households.person_model
    Type = rt.models.households.Type
    Household = rt.models.households.Household

    men = Person.objects.filter(gender=dd.Genders.male).order_by('-id')
    women = Person.objects.filter(gender=dd.Genders.female).order_by('-id')
    if dd.is_installed('humanlinks'):
        # avoid interference with persons created by humanlinks demo
        # because these have already their households:
        men = men.filter(household_members__isnull=True)
        men = men.filter(humanlinks_children__isnull=True)
        men = men.filter(humanlinks_parents__isnull=True)
        women = women.filter(humanlinks_children__isnull=True)
        women = women.filter(humanlinks_parents__isnull=True)
        women = women.filter(household_members__isnull=True)
    
    MEN = Cycler(men)
    WOMEN = Cycler(women)
    TYPES = Cycler(Type.objects.all())

    if not len(MEN) or not len(WOMEN):
        raise Exception(
            "Not enough persons in {} and {} (all: {})".format(
                men, women, Person.objects.all()))

    # avoid automatic creation of children
    # loading_from_dump = settings.SITE.loading_from_dump
    # settings.SITE.loading_from_dump = True
    ses = rt.login()
    for i in range(5):
        pv = dict(
            head=MEN.pop(), partner=WOMEN.pop(),
            type=TYPES.pop())
        ses.run(
            Person.create_household,
            action_param_values=pv)
        # yield ses.response['data_record']
        # he = MEN.pop()
        # she = WOMEN.pop()
        
        # fam = Household(name=he.last_name + "-" + she.last_name, type_id=3)
        # yield fam
        # yield Member(household=fam, person=he, role=Role.objects.get(pk=1))
        # yield Member(household=fam, person=she, role=Role.objects.get(pk=2))

    i = 0
    for m in Member.objects.filter(role=MemberRoles.head):
        i += 1
        if i % 3 == 0:
            m.end_date = i2d(20020304)
            yield m

            pv = dict(
                head=m.person, partner=WOMEN.pop(),
                type=TYPES.pop())
            ses.run(
                Person.create_household,
                action_param_values=pv)
            
    if False:  # dd.is_installed('addresses'):
        Address = rt.models.addresses.Address
        children = set()
        
        for h in Household.objects.all():
            for m in Member.objects.filter(household=h, primary=True):
                addr = Address.objects.get(
                    partner=m.person, primary=True)
                if m.role == MemberRoles.head:
                    addr.partner = h
                    addr.full_clean()
                    addr.save()
                else:
                    addr.delete()
                    children.add(m.person)
            
            h.sync_primary_address_()
            
        for p in children:
            p.sync_primary_address_()
Ejemplo n.º 52
0
def objects():

    Line = rt.models.courses.Line
    Teacher = dd.plugins.courses.teacher_model
    Course = rt.models.courses.Course
    Topic = rt.models.courses.Topic
    Enrolment = rt.models.courses.Enrolment
    CourseStates = rt.models.courses.CourseStates
    User = rt.models.users.User
    EventType = rt.models.cal.EventType
    Guest = rt.models.cal.Guest
    GuestRole = rt.models.cal.GuestRole
    GuestStates = rt.models.cal.GuestStates
    EntryStates = rt.models.cal.EntryStates
    Event = rt.models.cal.Event
    Person = rt.models.contacts.Person
    CommentType = rt.models.comments.CommentType
    TrendStage = rt.models.trends.TrendStage
    TrendArea = rt.models.trends.TrendArea

    for area, stages in trends_config:
        ta = named(TrendArea, area)
        yield ta
        for stage in stages:
            kw = dict(trend_area=ta)
            if stage[0] == "!":
                stage = stage[1:]
                kw.update(subject_column=True)
            yield named(TrendStage, stage, **kw)

    yield EventType(**dd.str2kw('name', _("First contact")))

    kw = dd.str2kw('name', _("Lesson"))
    kw.update(dd.str2kw('event_label', _("Lesson")))
    event_type = EventType(**kw)
    yield event_type

    pupil = named(GuestRole, _("Pupil"))
    yield pupil
    yield named(GuestRole, _("Assistant"))

    topic_citizen = named(Topic, _("Citizen course"))
    yield topic_citizen

    topic_lang = named(Topic, _("Language courses"))
    yield topic_lang

    kw.update(topic=topic_citizen)
    kw = dict(event_type=event_type, guest_role=pupil)
    yield named(Line, _("Citizen course"), **kw)

    kw.update(topic=topic_lang)
    alpha = named(Line, _("Alphabetisation"), **kw)
    yield alpha
    yield named(Line, _("German for beginners"), **kw)
    yield named(Line, _("German A1+"), **kw)
    yield named(Line, _("German A2"), **kw)
    yield named(Line, _("German A2 (women)"), **kw)

    yield named(CommentType, _("Phone call"))
    yield named(CommentType, _("Visit"))
    yield named(CommentType, _("Individual consultation"))
    yield named(CommentType, _("Internal meeting"))
    yield named(CommentType, _("Meeting with partners"))

    laura = Teacher(first_name="Laura", last_name="Lieblig")
    yield laura
    yield User(username="******", user_type=UserTypes.teacher, partner=laura)

    yield User(username="******", user_type=UserTypes.user)
    yield User(username="******", user_type=UserTypes.user)
    yield User(username="******", user_type=UserTypes.auditor)
    yield User(username="******", user_type=UserTypes.coordinator)
    yield User(username="******", user_type=UserTypes.secretary)

    USERS = Cycler(
        User.objects.exclude(user_type__in=(UserTypes.auditor,
                                            UserTypes.admin)))

    kw = dict(monday=True, tuesday=True, thursday=True, friday=True)
    kw.update(line=alpha,
              start_date=dd.demo_date(-30),
              start_time="9:00",
              end_time="12:00",
              max_date=dd.demo_date(10),
              state=CourseStates.active,
              every_unit=Recurrencies.daily,
              user=USERS.pop(),
              teacher=laura,
              max_places=5)

    yield Course(**kw)

    kw.update(start_time="14:00",
              end_time="17:00",
              user=USERS.pop(),
              max_places=15)
    yield Course(**kw)

    kw.update(start_time="18:00",
              end_time="20:00",
              user=USERS.pop(),
              max_places=15)
    yield Course(**kw)

    PUPILS = Cycler(dd.plugins.courses.pupil_model.objects.all())
    # print(20170302, dd.plugins.courses.pupil_model.objects.all())
    COURSES = Cycler(Course.objects.all())
    STATES = Cycler(EnrolmentStates.objects())

    def fits(course, pupil):
        if course.max_places and course.get_free_places() == 0:
            return False
        if Enrolment.objects.filter(course=course, pupil=pupil).count():
            return False
        return True

    def enrol(pupil):
        course = COURSES.pop()
        if fits(course, pupil):
            kw = dict(user=USERS.pop(), course=course, pupil=pupil)
            kw.update(request_date=dd.demo_date(-i))
            kw.update(state=STATES.pop())
            return Enrolment(**kw)

    for i, p in enumerate(
            dd.plugins.courses.pupil_model.objects.order_by('id')):

        yield enrol(p)
        if i % 2 == 0:
            yield enrol(p)
        if i % 3 == 0:
            yield enrol(p)

    ar = rt.login('robin')
    for obj in Course.objects.all():
        obj.update_auto_events(ar)

    # Suggested calendar entries older than 7 days should be marked as
    # either took_place or cancelled.
    qs = Event.objects.filter(start_date__lte=dd.demo_date(-7),
                              state=EntryStates.suggested)
    for i, obj in enumerate(qs):
        if i % 9:
            obj.state = EntryStates.took_place
        else:
            obj.state = EntryStates.cancelled
        obj.full_clean()
        obj.save()

    # participants of events which took place should be marked as
    # either absent or present or excused:
    qs = Guest.objects.filter(
        event__start_date__lte=dd.demo_date(-7),
        event__state=EntryStates.took_place).order_by('id')
    STATES = Cycler(GuestStates.get_list_items())
    for i, obj in enumerate(qs):
        obj.state = STATES.pop()
        # if i % 8:
        #     obj.state = GuestStates.present
        # elif i % 3:
        #     obj.state = GuestStates.missing
        # else:
        #     obj.state = GuestStates.excused
        obj.full_clean()
        obj.save()
Ejemplo n.º 53
0
    def test_checkin_guest(self):
        """Test whether notifications are being emitted.

        - when a visitor checks in
        - when a client is modified
        - when a coaching is modified

        """
        User = settings.SITE.user_model
        Message = rt.models.notify.Message
        Note = rt.models.notes.Note
        NoteType = rt.models.notes.EventType
        Guest = rt.models.cal.Guest
        Event = rt.models.cal.Event
        EventType = rt.models.cal.EventType
        Client = rt.models.pcsw.Client
        Coaching = rt.models.pcsw.Coaching
        ContentType = rt.models.contenttypes.ContentType

        self.create_obj(
            User, username='******', profile=UserTypes.admin)
        caroline = self.create_obj(
            User, username='******', profile='200')
        alicia = self.create_obj(
            User, username='******', first_name="Alicia", profile='100')
        roger = self.create_obj(
            User, username='******', profile='400')

        ses = rt.login('robin')

        first = self.create_obj(
            Client, first_name="First", last_name="Client")

        second = self.create_obj(
            Client, first_name="Second", last_name="Client")
        self.create_obj(
            Coaching, client=second,
            start_date=i2d(20130501),
            end_date=i2d(20140501),
            user=caroline)
        second_roger = self.create_obj(
            Coaching, client=second, start_date=i2d(20140501),
            user=roger)
        self.create_obj(
            Coaching, client=second, start_date=i2d(20140520),
            user=alicia)

        nt = self.create_obj(NoteType, name="System note")
        sc = settings.SITE.site_config
        sc.system_note_type = nt
        sc.save()

        consultation = self.create_obj(EventType, name="consultation")

        # gr = self.create_obj(GuestRole, name="client")

        event = self.create_obj(
            Event, event_type=consultation, user=caroline)
        guest = self.create_obj(Guest, event=event, partner=first)

        self.assertEqual(str(guest), 'Presence #1 (22.05.2014)')

        # Checkin a guest

        res = ses.run(guest.checkin)
        self.assertEqual(res, {
            'message': '', 'success': True, 'refresh': True})

        # it has caused a notification message:
        self.assertEqual(Message.objects.count(), 1)

        # id does *not* cause a system note:
        self.assertEqual(Note.objects.count(), 0)

        # When a client is modified, all active coaches get a
        # notification.
        # Note that Caroline doesn't get a notification because this
        # coaching is not active.
        # Alicia doesn't get a notification because she did it herself.

        data = dict(first_name="Seconda", an="submit_detail")
        kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/pcsw/Clients/{}'.format(second.pk)
        res = self.client.put(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        self.assertEqual(Message.objects.count(), 2)

        # self.check_notifications()
        self.check_notifications("""
+------------------------------------------------------------------------+------------------------+-----------+
| Body                                                                   | Controlled by          | Recipient |
+========================================================================+========================+===========+
|                                                                        |                        | caroline  |
+------------------------------------------------------------------------+------------------------+-----------+
| [CLIENT Seconda (101)](javascript:Lino.pcsw.Clients.detail.run\(null,{ | *CLIENT Seconda (101)* | roger     |
| "record_id": 101 }\)) has been modified by Alicia:                     |                        |           |
|                                                                        |                        |           |
|   * **Name** : 'Client Second' --&gt; 'Client Seconda'                 |                        |           |
|   * **First name** : 'Second' --&gt; 'Seconda'                         |                        |           |
+------------------------------------------------------------------------+------------------------+-----------+
""")

        # When a coaching is modified, all active coaches of that
        # client get a notification.

        Message.objects.all().delete()
        data = dict(start_date="02.05.2014", an="grid_put")
        data.update(mt=51)
        data.update(mk=second.pk)
        kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/pcsw/CoachingsByClient/{}'.format(second_roger.pk)
        res = self.client.put(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        self.check_notifications("""
+-----------------------------------------------------+------------------------+-----------+
| Body                                                | Controlled by          | Recipient |
+=====================================================+========================+===========+
| **roger / Client S** has been modified by Alicia:   | *CLIENT Seconda (101)* | roger     |
|                                                     |                        |           |
|   * **Coached from** : 2014-05-01 --&gt; 2014-05-02 |                        |           |
+-----------------------------------------------------+------------------------+-----------+
""")

        # AssignCoach. we are going to Assign caroline as coach for
        # first client.

        # Request URL:http://127.0.0.1:8000/api/newcomers/AvailableCoachesByClient/5?_dc=1469707129689&fv=EVERS%20Eberhart%20(127)%20assigned%20to%20Hubert%20Huppertz%20&fv=EVERS%20Eberhart%20(127)%20is%20now%20coached%20by%20Hubert%20Huppertz%20for%20Laufende%20Beihilfe.&fv=false&mt=48&mk=127&an=assign_coach&sr=5
        # Request Method:GET

        # fv:EVERS Eberhart (127) assigned to Hubert Huppertz
        # fv:EVERS Eberhart (127) is now coached by Hubert Huppertz for Laufende Beihilfe.
        # fv:false
        # mt:48
        # mk:127
        # an:assign_coach
        # sr:5

        Message.objects.all().delete()
        # self.assertEqual(Coaching.objects.count(), 1)
        self.check_coachings("""
==== ====================== ============== ============ ========== =========
 ID   Client                 Coached from   until        Coach      Primary
---- ---------------------- -------------- ------------ ---------- ---------
 1    CLIENT Seconda (101)   01/05/2013     01/05/2014   caroline   No
 2    CLIENT Seconda (101)   02/05/2014                  roger      No
 3    CLIENT Seconda (101)   20/05/2014                  Alicia     No
==== ====================== ============== ============ ========== =========
""")

        self.assertEqual(Note.objects.count(), 0)

        data = dict(
            fv=["First CLIENT assigned to caroline", "Body", 'false'],
            an="assign_coach")
        data.update(mt=ContentType.objects.get_for_model(Client).pk)
        data.update(mk=first.pk)
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/newcomers/AvailableCoachesByClient/{}'.format(
            caroline.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)

        # self.check_notifications()
        self.check_notifications("""
======================================== =============== ===========
 Body                                     Controlled by   Recipient
---------------------------------------- --------------- -----------
 First CLIENT assigned to caroline Body                   caroline
======================================== =============== ===========
""")

        self.check_coachings("""
==== ====================== ============== ============ ========== =========
 ID   Client                 Coached from   until        Coach      Primary
---- ---------------------- -------------- ------------ ---------- ---------
 1    CLIENT Seconda (101)   01/05/2013     01/05/2014   caroline   No
 2    CLIENT Seconda (101)   02/05/2014                  roger      No
 3    CLIENT Seconda (101)   20/05/2014                  Alicia     No
 4    CLIENT First (100)     22/05/2014                  caroline   No
==== ====================== ============== ============ ========== =========
""")

        self.check_notes("""
==== ======== ==================== ===================================
 ID   Author   Client               Subject
---- -------- -------------------- -----------------------------------
 1    Alicia   CLIENT First (100)   First CLIENT assigned to caroline
==== ======== ==================== ===================================
""")

        # Mark client as former

        # Request URL:http://127.0.0.1:8000/api/pcsw/Clients/181?_dc=1469714189945&an=mark_former&sr=181
        # Request Method:GET
        # an:mark_former

        Message.objects.all().delete()
        Note.objects.all().delete()

        data = dict(an="mark_former")
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/pcsw/Clients/{}'.format(second.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        res = AttrDict(json.loads(res.content))
        self.assertEqual(
            res.message, 'This will end 2 coachings of CLIENT Seconda (101).')

        self.assertEqual(res.xcallback['title'], "Confirmation")
        kwargs = dict()
        kwargs['REMOTE_USER'] = '******'
        url = '/callbacks/{}/yes'.format(res.xcallback['id'])
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        res = AttrDict(json.loads(res.content))
        self.assertEqual(
            res.message,
            'Alicia marked CLIENT Seconda (101) as <b>Former</b>.')
        self.assertTrue(res.success)

        self.check_notifications("""
=================================================== ======================== ===========
 Body                                                Controlled by            Recipient
--------------------------------------------------- ------------------------ -----------
 Alicia marked CLIENT Seconda (101) as **Former**.   *CLIENT Seconda (101)*   roger
=================================================== ======================== ===========
""")

        # check two coachings have now an end_date set:
        self.check_coachings("""
==== ====================== ============== ============ ========== =========
 ID   Client                 Coached from   until        Coach      Primary
---- ---------------------- -------------- ------------ ---------- ---------
 1    CLIENT Seconda (101)   01/05/2013     01/05/2014   caroline   No
 2    CLIENT Seconda (101)   02/05/2014     22/05/2014   roger      No
 3    CLIENT Seconda (101)   20/05/2014     22/05/2014   Alicia     No
 4    CLIENT First (100)     22/05/2014                  caroline   No
==== ====================== ============== ============ ========== =========
""")
        self.check_notes("""
==== ======== ====================== ======================================================
 ID   Author   Client                 Subject
---- -------- ---------------------- ------------------------------------------------------
 2    Alicia   CLIENT Seconda (101)   Alicia marked CLIENT Seconda (101) as <b>Former</b>.
==== ======== ====================== ======================================================
""")

        #
        # RefuseClient
        #

        Message.objects.all().delete()
        Note.objects.all().delete()

        data = dict(fv=["20", ""], an="refuse_client")
        kwargs = dict(data=data)
        # kwargs = dict(data=urlencode(data))
        kwargs['REMOTE_USER'] = '******'
        url = '/api/pcsw/Clients/{}'.format(first.pk)
        res = self.client.get(url, **kwargs)
        self.assertEqual(res.status_code, 200)
        self.check_notifications("""
======================================================================== ====================== ===========
 Body                                                                     Controlled by          Recipient
------------------------------------------------------------------------ ---------------------- -----------
 Alicia marked CLIENT First (100) as **Refused**. PCSW is not competent   *CLIENT First (100)*   caroline
======================================================================== ====================== ===========
""")
        self.check_notes("""
==== ======== ==================== =====================================================
 ID   Author   Client               Subject
---- -------- -------------------- -----------------------------------------------------
 3    Alicia   CLIENT First (100)   Alicia marked CLIENT First (100) as <b>Refused</b>.
==== ======== ==================== =====================================================
""")
Ejemplo n.º 54
0
    def test_this(self):

        from lino.api import rt
        from lino.core.renderer import TestRenderer
        
        UserTypes = rt.models.users.UserTypes        
        rt.models.users.User(
            username="******", user_type=UserTypes.admin).save()
        
        ses = rt.login('robin', renderer=TestRenderer())

        s = ses.show('changes.Changes')
        self.assertEqual(s, "No data to display")


        rr = rt.models.contacts.Companies.required_roles
        self.assertTrue(ses.user.user_type.role.satisfies_requirement(rr))

        # We create a new organization:

        url = '/api/contacts/Companies'
        data = dict(an='submit_insert', name='My pub')
        res = self.post_json_dict('robin', url, data)
        self.assertEqual(
            res.message, 'Organization "My pub" has been created.')

        s = ses.show('changes.Changes',
                     column_names="id type master object diff")
        # print(s)
        expected = """\
==== ============= ========== ===================== ===============================================
 ID   Change Type   Master     Object                Changes
---- ------------- ---------- --------------------- -----------------------------------------------
 1    Create        *My pub*   `My pub <Detail>`__   Company(id=100,name='My pub',partner_ptr=100)
==== ============= ========== ===================== ===============================================
"""
        
        self.assertEqual(s, expected)
        
        url = '/api/contacts/Companies/100'
        data = "an=submit_detail&name=Our%20pub"
        res = self.put_json_dict('robin', url, data)
        self.assertEqual(
            res.message, 'Organization "Our pub" has been updated.')

        output = ses.show('changes.Changes', column_names="id type master object diff")
        # print(output)
        expected = """\
==== ============= =========== ====================== ===============================================
 ID   Change Type   Master      Object                 Changes
---- ------------- ----------- ---------------------- -----------------------------------------------
 2    Update        *Our pub*   `Our pub <Detail>`__   name : 'My pub' --> 'Our pub'
 1    Create        *Our pub*   `Our pub <Detail>`__   Company(id=100,name='My pub',partner_ptr=100)
==== ============= =========== ====================== ===============================================
"""
        self.assertEqual(output, expected)

        # We add an entry:

        url = '/api/entries/Entries'
        data = dict(an='submit_insert', subject='test', companyHidden=100)
        res = self.post_json_dict('robin', url, data)
        if six.PY2:
            self.assertEqual(
                res.message, 'Entry "Entry object" has been created.')
            expected = """\
==== ============= =========== =========================== ===============================================
 ID   Change Type   Master      Object                      Changes
---- ------------- ----------- --------------------------- -----------------------------------------------
 3    Create        *Our pub*   `Entry object <Detail>`__   Entry(id=1,user=1,subject='test',company=100)
 2    Update        *Our pub*   `Our pub <Detail>`__        name : 'My pub' --> 'Our pub'
 1    Create        *Our pub*   `Our pub <Detail>`__        Company(id=100,name='My pub',partner_ptr=100)
==== ============= =========== =========================== ===============================================
"""
        else:
            self.assertEqual(
                res.message, 'Entry "Entry object (1)" has been created.')
            expected = """\
==== ============= =========== =============================== ===============================================
 ID   Change Type   Master      Object                          Changes
---- ------------- ----------- ------------------------------- -----------------------------------------------
 3    Create        *Our pub*   `Entry object (1) <Detail>`__   Entry(id=1,user=1,subject='test',company=100)
 2    Update        *Our pub*   `Our pub <Detail>`__            name : 'My pub' --> 'Our pub'
 1    Create        *Our pub*   `Our pub <Detail>`__            Company(id=100,name='My pub',partner_ptr=100)
==== ============= =========== =============================== ===============================================
"""


        output = ses.show('changes.Changes',
                     column_names="id type master object diff")
        # print(output)
        self.assertEqual(output, expected)
        
        
        # Now we delete the entry:

        url = '/api/entries/Entries/1'
        data = dict(an='delete_selected', sr=1)
        res = self.get_json_dict('robin', url, data)
        if six.PY2:
            self.assertEqual(
            res.message, """\
You are about to delete 1 Entry:
Entry object
Are you sure ?""")
        else:
            self.assertEqual(
                res.message, """\
You are about to delete 1 Entry:
Entry object (1)
Are you sure ?""")

        
        
        # We answer "yes":

        url = "/callbacks/{0}/yes".format(res['xcallback']['id'])
        res = self.get_json_dict('robin', url, {})
        # r = test_client.get(url)
        self.assertEqual(res.success, True)
        self.assertEqual(res.record_deleted, True)
        

        expected = """\
==== ============= =========== ====================== ===============================================
 ID   Change Type   Master      Object                 Changes
---- ------------- ----------- ---------------------- -----------------------------------------------
 4    Delete        *Our pub*                          Entry(id=1,user=1,subject='test',company=100)
 3    Create        *Our pub*                          Entry(id=1,user=1,subject='test',company=100)
 2    Update        *Our pub*   `Our pub <Detail>`__   name : 'My pub' --> 'Our pub'
 1    Create        *Our pub*   `Our pub <Detail>`__   Company(id=100,name='My pub',partner_ptr=100)
==== ============= =========== ====================== ===============================================
"""
        output = ses.show('changes.Changes',
                     column_names="id type master object diff")
        # print(output)
        self.assertEqual(output, expected)

        # Note how the `object` column of the first two rows in above
        # table is empty. That's because the entry object has been
        # deleted, so it does no longer exist in the database and Lino
        # cannot point to it. But note also that `object` is a
        # "nullable Generic ForeignKey", the underlying fields
        # `object_id` and `object_type` still contain their
        # values. Here is the same table with "Object" split into its
        # components:

        expected = """\
==== ============= =========== ============== =========== ===============================================
 ID   Change Type   Master      Object type    object id   Changes
---- ------------- ----------- -------------- ----------- -----------------------------------------------
 4    Delete        *Our pub*   Entry          1           Entry(id=1,user=1,subject='test',company=100)
 3    Create        *Our pub*   Entry          1           Entry(id=1,user=1,subject='test',company=100)
 2    Update        *Our pub*   Organization   100         name : 'My pub' --> 'Our pub'
 1    Create        *Our pub*   Organization   100         Company(id=100,name='My pub',partner_ptr=100)
==== ============= =========== ============== =========== ===============================================
"""
        output = ses.show('changes.Changes',
                     column_names="id type master object_type object_id diff")
        # print(output)
        self.assertEqual(output, expected)


# Until 20150626 only the
# :attr:`object<lino.modlib.changes.models.Change.object>` was nullable,
# not the :attr:`master<lino.modlib.changes.models.Change.master>`.  But
# now you can also delete the master, and all change records will still
# remain:

        url = '/api/contacts/Companies/100'
        data = dict(an='delete_selected', sr=100)
        res = self.get_json_dict('robin', url, data)
        
        url = "/callbacks/{0}/yes".format(res.xcallback['id'])
        self.get_json_dict('robin', url, {})
        
        expected = """\
==== ============= ======== ======== ================================================
 ID   Change Type   Master   Object   Changes
---- ------------- -------- -------- ------------------------------------------------
 5    Delete                          Company(id=100,name='Our pub',partner_ptr=100)
 4    Delete                          Entry(id=1,user=1,subject='test',company=100)
 3    Create                          Entry(id=1,user=1,subject='test',company=100)
 2    Update                          name : 'My pub' --> 'Our pub'
 1    Create                          Company(id=100,name='My pub',partner_ptr=100)
==== ============= ======== ======== ================================================
"""
        output = ses.show('changes.Changes',
                     column_names="id type master object diff")
        # print(output)
        self.assertEqual(output, expected)
        

        # Of course these change records are now considered broken GFKs:

        expected = """\
===================== ================= ============================================================= ========
 Database model        Database object   Message                                                       Action
--------------------- ----------------- ------------------------------------------------------------- --------
 `Change <Detail>`__   `#1 <Detail>`__   Invalid primary key 100 for contacts.Partner in `master_id`   clear
 `Change <Detail>`__   `#2 <Detail>`__   Invalid primary key 100 for contacts.Partner in `master_id`   clear
 `Change <Detail>`__   `#3 <Detail>`__   Invalid primary key 100 for contacts.Partner in `master_id`   clear
 `Change <Detail>`__   `#4 <Detail>`__   Invalid primary key 100 for contacts.Partner in `master_id`   clear
 `Change <Detail>`__   `#5 <Detail>`__   Invalid primary key 100 for contacts.Partner in `master_id`   clear
 `Change <Detail>`__   `#1 <Detail>`__   Invalid primary key 100 for contacts.Company in `object_id`   clear
 `Change <Detail>`__   `#2 <Detail>`__   Invalid primary key 100 for contacts.Company in `object_id`   clear
 `Change <Detail>`__   `#3 <Detail>`__   Invalid primary key 1 for entries.Entry in `object_id`        clear
 `Change <Detail>`__   `#4 <Detail>`__   Invalid primary key 1 for entries.Entry in `object_id`        clear
 `Change <Detail>`__   `#5 <Detail>`__   Invalid primary key 100 for contacts.Company in `object_id`   clear
===================== ================= ============================================================= ========
"""
        output = ses.show('gfks.BrokenGFKs')
        # print(output)
        self.assertEqual(output, expected)