예제 #1
0
파일: idcards.py 프로젝트: flavour/aidiq
    def draw(self):
        """
            Draw the card (one side)

            Instance attributes (NB draw-function should not modify them):
            - self.canv...............the canvas (provides the drawing methods)
            - self.resource...........the resource
            - self.item...............the data item (dict)
            - self.labels.............the field labels (dict)
            - self.backside...........this instance should render the backside
                                      of a card
            - self.multiple...........there are multiple cards per page
            - self.width..............the width of the card (in points)
            - self.height.............the height of the card (in points)

            NB Canvas coordinates are relative to the lower left corner of the
               card's frame, drawing must not overshoot self.width/self.height
        """

        T = current.T

        c = self.canv
        w = self.width
        #h = self.height
        common = self.common

        orange = HexColor(0xEE4229)

        item = self.item
        raw = item["_row"]

        # Get the org logo
        logos = common.get("logos")
        if logos:
            root_org = raw["org_organisation.root_organisation"]
            logo = logos.get(root_org)
        else:
            logo = None

        if not self.backside:

            draw_field = self.draw_field
            draw_value = self.draw_value
            draw_label = self.draw_label

            # Horizontal alignments
            LEFT = w / 4 - 5
            CENTER = w / 2 - 5
            RIGHT = w * 3 / 4 - 5

            # Vertical alignments
            TOP = 200
            LOWER = [76, 58, 40]
            BOTTOM = 16

            # Org Logo
            if logo:
                self.draw_image(logo, LEFT, TOP, width=60, height=60, valign="middle", halign="center")

            # Get the profile picture
            pictures = common.get("pictures")
            if pictures:
                picture = pictures.get(raw["pr_person.pe_id"])
                if picture:
                    self.draw_image(picture, RIGHT, TOP, width=60, height=60, valign="middle", halign="center")

            # Center fields in reverse order so that vertical positions
            # can be adjusted for very long and hence wrapping strings
            y = 98

            # Organisation/Branch
            org_name = s3_str(item.get("org_organisation.name"))
            aH = draw_value(CENTER, y, org_name, height=16, size=8)
            draw_label(CENTER, y, "hrm_human_resource.organisation_id")

            # Job Title
            y += aH + 12
            job_title = s3_str(item.get("hrm_human_resource.job_title_id"))
            aH = draw_value(CENTER, y, job_title, height=16, size=8)
            draw_label(CENTER, y, "hrm_human_resource.job_title_id")

            # Name
            y += aH + 12
            name = s3_format_fullname(fname = raw["pr_person.first_name"],
                                      mname = raw["pr_person.middle_name"],
                                      lname = raw["pr_person.last_name"],
                                      truncate = False,
                                      )
            draw_value(CENTER, y, name, height=24, size=10)
            draw_label(CENTER, y, None, T("Name"))

            # IDs
            draw_field(LEFT, LOWER[0], "pr_national_id_identity.value")
            draw_label(LEFT, LOWER[0], None, T("ID"))
            # TODO only volunteers can have this? (Adjust label by HR type?)
            draw_field(RIGHT, LOWER[0], "hrm_human_resource.code")
            draw_label(RIGHT, LOWER[0], None, T("Volunteer ID"))

            # Medical Details
            draw_field(LEFT, LOWER[1], "pr_physical_description.blood_type")
            draw_label(LEFT, LOWER[1], None, T("Blood Type"))
            draw_field(RIGHT, LOWER[1], "pr_physical_description.allergic")
            draw_label(RIGHT, LOWER[1], None, T("Allergic"))

            # Issuing/Expirey Dates
            # TODO adjust interval per org (org_idcard)
            today = current.request.now.date()
            format_date = current.calendar.format_date
            issued_on = format_date(today)
            expires_on = format_date(today + relativedelta(months=24))

            c.setFont(BOLD, 7)
            c.drawCentredString(LEFT, LOWER[2], issued_on)
            draw_label(LEFT, LOWER[2], None, T("Issued on"))
            c.setFont(BOLD, 7)
            c.drawCentredString(RIGHT, LOWER[2], expires_on)
            draw_label(RIGHT, LOWER[2], None, T("Expires on"))

            # Barcode
            code = raw["hrm_human_resource.code"]
            if code:
                self.draw_barcode(s3_str(code), CENTER, BOTTOM, height=12, halign="center")

            # Graphics
            c.setFillColor(orange)
            c.rect(0, 0, w, 12, fill=1, stroke=0)
            c.rect(w - 12, 0, 12, 154, fill=1, stroke=0)

            # Add a utting line with multiple cards per page
            if self.multiple:
                c.setDash(1, 2)
                self.draw_outline()
        else:
            # Horizontal alignments
            CENTER = w / 2

            # Vertical alignments
            TOP = 200
            BOTTOM = 16

            # TODO Mission statement

            # TODO IFRC membership statement

            # TODO Signature and caption

            # Barcode
            code = raw["hrm_human_resource.code"]
            if code:
                self.draw_barcode(s3_str(code), CENTER, BOTTOM, height=12, halign="center")

            # Graphics
            if logo:
                self.draw_image(logo, CENTER, TOP, width=60, height=60, valign="middle", halign="center")
            c.setFillColor(orange)
            c.rect(0, 0, w, 10, fill=1, stroke=0)
예제 #2
0
파일: idcards.py 프로젝트: nursix/eden
    def draw(self):
        """
            Draw the card (one side)

            Instance attributes (NB draw-function should not modify them):
            - self.canv...............the canvas (provides the drawing methods)
            - self.resource...........the resource
            - self.item...............the data item (dict)
            - self.labels.............the field labels (dict)
            - self.backside...........this instance should render the backside
                                      of a card
            - self.multiple...........there are multiple cards per page
            - self.width..............the width of the card (in points)
            - self.height.............the height of the card (in points)

            NB Canvas coordinates are relative to the lower left corner of the
               card's frame, drawing must not overshoot self.width/self.height
        """

        T = current.T

        c = self.canv
        w = self.width
        #h = self.height
        common = self.common

        blue = HexColor(0x27548F)

        item = self.item
        raw = item["_row"]

        root_org = raw["org_organisation.root_organisation"]

        # Get the localized root org name
        org_names = common.get("root_org_names")
        if org_names:
            root_org_name = org_names.get(root_org)

        #draw_field = self.draw_field
        draw_value = self.draw_value
        draw_label = self.draw_label

        code = raw["pr_person.pe_label"]

        if not self.backside:

            # Horizontal alignments
            LEFT = w / 4 - 5
            CENTER = w / 2 - 5
            RIGHT = w * 3 / 4 - 5

            # Vertical alignments
            TOP = 200
            #LOWER = [76, 58, 40]
            BOTTOM = 16

            # Organisation name
            if root_org_name:
                draw_value(LEFT, TOP, root_org_name,
                           width = 55,
                           height = 55,
                           size = 10,
                           valign = "middle",
                           )

            # Get the profile picture
            pictures = common.get("pictures")
            if pictures:
                picture = pictures.get(raw["pr_person.pe_id"])
                if picture:
                    self.draw_image(picture, RIGHT, TOP,
                                    width = 60,
                                    height = 55,
                                    valign = "middle",
                                    halign = "center",
                                    )

            # Center fields in reverse order so that vertical positions
            # can be adjusted for very long and hence wrapping strings
            y = 98

            # ID
            ah = draw_value(CENTER, y, code, height=24, size=8)
            draw_label(CENTER, y, None, T("ID Number"))

            # Name
            y += ah + 12
            name = s3_format_fullname(fname = raw["pr_person.first_name"],
                                      mname = raw["pr_person.middle_name"],
                                      lname = raw["pr_person.last_name"],
                                      truncate = False,
                                      )
            draw_value(CENTER, y, name, height=24, size=10)
            draw_label(CENTER, y, None, T("Name"))

            # Barcode
            if code:
                self.draw_barcode(s3_str(code), CENTER, BOTTOM,
                                  height = 12,
                                  halign = "center",
                                  maxwidth = w - 15,
                                  )

            # Graphics
            c.setFillColor(blue)
            c.rect(0, 0, w, 12, fill=1, stroke=0)
            c.rect(w - 12, 0, 12, 154, fill=1, stroke=0)

            # Add a utting line with multiple cards per page
            if self.multiple:
                c.setDash(1, 2)
                self.draw_outline()
        else:
            # Horizontal alignments
            CENTER = w / 2

            # Vertical alignments
            TOP = 200
            MIDDLE = 85
            BOTTOM = 16

            # QR Code
            if code:
                identity = "%s//%s:%s:%s" % (code,
                                             raw["pr_person.first_name"] or "",
                                             raw["pr_person.middle_name"] or "",
                                             raw["pr_person.last_name"] or "",
                                             )
                self.draw_qrcode(identity, CENTER, MIDDLE,
                                 size=60, halign="center", valign="center")
            # Barcode
            if code:
                self.draw_barcode(s3_str(code), CENTER, BOTTOM,
                                  height = 12,
                                  halign = "center",
                                  maxwidth = w - 15
                                  )

            # Graphics
            c.setFillColor(blue)
            c.rect(0, 0, w, 10, fill=1, stroke=0)
예제 #3
0
파일: siglist.py 프로젝트: waidyanatha/eden
    def pdf(self, r, **attr):
        """
            Generate the PDF

            @param r: the S3Request instance
            @param attr: controller attributes
        """

        T = current.T

        db = current.db
        s3db = current.s3db

        # Look up the report organisation
        logo = None
        org_id, org_label = self.get_report_organisation(r)
        if org_id:
            # Look up the root organisation's logo
            otable = s3db.org_organisation
            rotable = otable.with_alias("root_organisation")
            join = rotable.on(rotable.id == otable.root_organisation)
            field = rotable.logo
            row = db(otable.id == org_id).select(field,
                                                 join = join,
                                                 limitby = (0, 1),
                                                 ).first()
            if row and row.logo:
                if field.uploadfolder:
                    path = field.uploadfolder
                else:
                    path = os.path.join(current.request.folder, 'uploads')
                logo = os.path.join(path, row.logo)

        # Look up the report programme
        prog_id, prog_label = self.get_report_programme(r)

        # Extract the HR records
        data, pictures = self.extract(r.resource)

        # Construct the header
        title = T("Official Volunteer List")
        header = TABLE(_class = "no-grid",
                       )
        trow = TR()
        if logo:
            trow.append(TD(IMG(_src=logo, _width="80"),
                           _rowspan = 3 if prog_id else 2,
                           ))
        trow.append(TD(H4(title), _colspan = 3))
        header.append(trow)
        if org_id:
            header.append(TR(TD(H5(org_label), _colspan = 3)))
        if prog_id:
            header.append(TR(TD(prog_label, _colspan = 3)))
        header.append(TR(TD()))

        # Should we show the branch column?
        branches = set(row["_row"]["hrm_human_resource.organisation_id"] for row in data.rows)
        if org_id:
            show_branch = len(branches) > 1
            org_repr = s3db.org_OrganisationRepresent(show_link = False,
                                                      parent = False,
                                                      acronym = True,
                                                      )
        else:
            show_branch = True
            org_repr = r.table.organisation_id.represent
        org_repr.bulk(list(branches))

        # Construct the table header
        labels = TR(TH(T("Picture")),
                    TH(T("Name")),
                    TH(T("Last Name")),
                    TH(T("National ID")),
                    TH(T("Volunteer ID")),
                    TH(T("Signature")),
                    )
        if not prog_id:
            labels.insert(1, TH(T("Program")))
        if show_branch:
            labels.insert(1, TH(T("Branch")))

        # Build the table
        body = TABLE(labels, _class="repeat-header shrink-to-fit")

        # Add the data rows
        for row in data.rows:

            raw = row._row

            # Picture
            picture = pictures.get(raw["pr_person.pe_id"])
            if picture:
                picture = IMG(_src=picture,
                              _width=80,
                              )
            else:
                picture = ""

            # Name
            name = s3_format_fullname(fname = raw["pr_person.first_name"],
                                      mname = raw["pr_person.middle_name"],
                                      lname = "",
                                      truncate = False,
                                      )

            # Build the row
            trow = TR(TD(picture),
                      TD(name),
                      TD(row["pr_person.last_name"]),
                      TD(row["pr_national_id_identity.value"]),
                      TD(row["hrm_human_resource.code"]),
                      TD(),
                      )
            if not prog_id:
                trow.insert(1, TD(row["hrm_programme_hours.programme_id"]))
            if show_branch:
                trow.insert(1, TD(org_repr(raw["hrm_human_resource.organisation_id"])))
            body.append(trow)

        footer = DIV()

        from s3.codecs.pdf import EdenDocTemplate, S3RL_PDF

        doc = EdenDocTemplate(title=title)
        printable_width = doc.printable_width

        get_html_flowable = S3RL_PDF().get_html_flowable

        header_flowable = get_html_flowable(header, printable_width)
        body_flowable = get_html_flowable(body, printable_width)
        footer_flowable = get_html_flowable(footer, printable_width)

        # Build the PDF
        doc.build(header_flowable,
                  body_flowable,
                  footer_flowable,
                  )
        filename = "siglist.pdf"

        # Return the generated PDF
        response = current.response
        response.headers["Content-Type"] = contenttype(".pdf")
        disposition = "attachment; filename=\"%s\"" % filename
        response.headers["Content-disposition"] = disposition

        return doc.output.getvalue()
예제 #4
0
파일: siglist.py 프로젝트: sahana/eden
    def pdf(self, r, **attr):
        """
            Generate the PDF

            Args:
                r: the S3Request instance
                attr: controller attributes
        """

        T = current.T

        db = current.db
        s3db = current.s3db

        # Look up the report organisation
        logo = None
        org_id, org_label = self.get_report_organisation(r)
        if org_id:
            # Look up the root organisation's logo
            otable = s3db.org_organisation
            rotable = otable.with_alias("root_organisation")
            join = rotable.on(rotable.id == otable.root_organisation)
            field = rotable.logo
            row = db(otable.id == org_id).select(
                field,
                join=join,
                limitby=(0, 1),
            ).first()
            if row and row.logo:
                if field.uploadfolder:
                    path = field.uploadfolder
                else:
                    path = os.path.join(current.request.folder, 'uploads')
                logo = os.path.join(path, row.logo)

        # Look up the report programme
        prog_id, prog_label = self.get_report_programme(r)

        # Extract the HR records
        data, pictures = self.extract(r.resource)

        # Construct the header
        title = T("Official Volunteer List")
        header = TABLE(_class="no-grid", )
        trow = TR()
        if logo:
            trow.append(
                TD(
                    IMG(_src=logo, _width="80"),
                    _rowspan=3 if prog_id else 2,
                ))
        trow.append(TD(H4(title), _colspan=3))
        header.append(trow)
        if org_id:
            header.append(TR(TD(H5(org_label), _colspan=3)))
        if prog_id:
            header.append(TR(TD(prog_label, _colspan=3)))
        header.append(TR(TD()))

        # Should we show the branch column?
        branches = set(row["_row"]["hrm_human_resource.organisation_id"]
                       for row in data.rows)
        if org_id:
            show_branch = len(branches) > 1
            org_repr = s3db.org_OrganisationRepresent(
                show_link=False,
                parent=False,
                acronym=True,
            )
        else:
            show_branch = True
            org_repr = r.table.organisation_id.represent
        org_repr.bulk(list(branches))

        # Construct the table header
        labels = TR(
            TH(T("Picture")),
            TH(T("Name")),
            TH(T("Last Name")),
            TH(T("National ID")),
            TH(T("Volunteer ID")),
            TH(T("Signature")),
        )
        if not prog_id:
            labels.insert(1, TH(T("Program")))
        if show_branch:
            labels.insert(1, TH(T("Branch")))

        # Build the table
        body = TABLE(labels, _class="repeat-header shrink-to-fit")

        # Add the data rows
        for row in data.rows:

            raw = row._row

            # Picture
            picture = pictures.get(raw["pr_person.pe_id"])
            if picture:
                picture = IMG(
                    _src=picture,
                    _width=80,
                )
            else:
                picture = ""

            # Name
            name = s3_format_fullname(
                fname=raw["pr_person.first_name"],
                mname=raw["pr_person.middle_name"],
                lname="",
                truncate=False,
            )

            # Build the row
            trow = TR(
                TD(picture),
                TD(name),
                TD(row["pr_person.last_name"]),
                TD(row["pr_national_id_identity.value"]),
                TD(row["hrm_human_resource.code"]),
                TD(),
            )
            if not prog_id:
                trow.insert(1, TD(row["hrm_programme_hours.programme_id"]))
            if show_branch:
                trow.insert(
                    1, TD(org_repr(raw["hrm_human_resource.organisation_id"])))
            body.append(trow)

        footer = DIV()

        from s3.codecs.pdf import EdenDocTemplate, S3RL_PDF

        doc = EdenDocTemplate(title=title)
        printable_width = doc.printable_width

        get_html_flowable = S3RL_PDF().get_html_flowable

        header_flowable = get_html_flowable(header, printable_width)
        body_flowable = get_html_flowable(body, printable_width)
        footer_flowable = get_html_flowable(footer, printable_width)

        # Build the PDF
        doc.build(
            header_flowable,
            body_flowable,
            footer_flowable,
        )
        filename = "siglist.pdf"

        # Return the generated PDF
        response = current.response
        response.headers["Content-Type"] = contenttype(".pdf")
        disposition = "attachment; filename=\"%s\"" % filename
        response.headers["Content-disposition"] = disposition

        return doc.output.getvalue()
예제 #5
0
파일: idcards.py 프로젝트: sahana/eden
    def draw(self):
        """
            Draw the card (one side)

            Instance attributes (NB draw-function should not modify them):
            - self.canv...............the canvas (provides the drawing methods)
            - self.resource...........the resource
            - self.item...............the data item (dict)
            - self.labels.............the field labels (dict)
            - self.backside...........this instance should render the backside
                                      of a card
            - self.multiple...........there are multiple cards per page
            - self.width..............the width of the card (in points)
            - self.height.............the height of the card (in points)

            NB Canvas coordinates are relative to the lower left corner of the
               card's frame, drawing must not overshoot self.width/self.height
        """

        T = current.T

        c = self.canv
        w = self.width
        #h = self.height
        common = self.common

        orange = HexColor(0xEE4229)

        item = self.item
        raw = item["_row"]

        root_org = raw["org_organisation.root_organisation"]

        # Get the org logo
        logos = common.get("logos")
        if logos:
            logo = logos.get(root_org)
        else:
            logo = None

        # Get the root org's card configuration
        configs = common.get("configs")
        if configs:
            config = configs.get(root_org)
        else:
            config = None

        # Get the localized root org name
        org_names = common.get("root_org_names")
        if org_names:
            root_org_name = org_names.get(root_org)

        draw_field = self.draw_field
        draw_value = self.draw_value
        draw_label = self.draw_label

        if not self.backside:

            # Horizontal alignments
            LEFT = w / 4 - 5
            CENTER = w / 2 - 5
            RIGHT = w * 3 / 4 - 5

            # Vertical alignments
            TOP = 200
            LOWER = [76, 58, 40]
            BOTTOM = 16

            # Org Logo
            if logo:
                self.draw_image(
                    logo,
                    LEFT,
                    TOP,
                    width=55,
                    height=55,
                    valign="middle",
                    halign="center",
                )
            elif root_org_name:
                draw_value(
                    LEFT,
                    TOP,
                    root_org_name,
                    width=55,
                    height=55,
                    size=10,
                    valign="middle",
                )

            # Get the profile picture
            pictures = common.get("pictures")
            if pictures:
                picture = pictures.get(raw["pr_person.pe_id"])
                if picture:
                    self.draw_image(
                        picture,
                        RIGHT,
                        TOP,
                        width=60,
                        height=55,
                        valign="middle",
                        halign="center",
                    )

            # Center fields in reverse order so that vertical positions
            # can be adjusted for very long and hence wrapping strings
            y = 98

            # Organisation/Branch
            org_name = s3_str(item.get("org_organisation.name"))
            aH = draw_value(CENTER, y, org_name, height=16, size=8)
            draw_label(CENTER, y, "hrm_human_resource.organisation_id")

            # Job Title
            y += aH + 12
            job_title = s3_str(item.get("hrm_human_resource.job_title_id"))
            aH = draw_value(CENTER, y, job_title, height=16, size=8)
            draw_label(CENTER, y, "hrm_human_resource.job_title_id")

            # Name
            y += aH + 12
            name = s3_format_fullname(
                fname=raw["pr_person.first_name"],
                mname=raw["pr_person.middle_name"],
                lname=raw["pr_person.last_name"],
                truncate=False,
            )
            draw_value(CENTER, y, name, height=24, size=10)
            draw_label(CENTER, y, None, T("Name"))

            # IDs
            draw_field(LEFT, LOWER[0], "pr_national_id_identity.value")
            draw_label(LEFT, LOWER[0], None, T("ID"))
            # TODO only volunteers can have this? (Adjust label by HR type?)
            draw_field(RIGHT, LOWER[0], "hrm_human_resource.code")
            draw_label(RIGHT, LOWER[0], None, T("Volunteer ID"))

            # Medical Details
            draw_field(LEFT, LOWER[1], "pr_physical_description.blood_type")
            draw_label(LEFT, LOWER[1], None, T("Blood Type"))
            draw_field(RIGHT, LOWER[1], "pr_physical_description.allergic")
            draw_label(RIGHT, LOWER[1], None, T("Allergic"))

            # Issuing/Expirey Dates
            vp = config.get("validity_period", 24) if config else 24
            today = current.request.now.date()
            format_date = current.calendar.format_date
            issued_on = format_date(today)
            expires_on = format_date(today + relativedelta(months=vp))

            c.setFont(BOLD, 7)
            c.drawCentredString(LEFT, LOWER[2], issued_on)
            draw_label(LEFT, LOWER[2], None, T("Issued on"))
            c.setFont(BOLD, 7)
            c.drawCentredString(RIGHT, LOWER[2], expires_on)
            draw_label(RIGHT, LOWER[2], None, T("Expires on"))

            # Barcode
            code = raw["hrm_human_resource.code"]
            if code:
                self.draw_barcode(
                    s3_str(code),
                    CENTER,
                    BOTTOM,
                    height=12,
                    halign="center",
                    maxwidth=w - 15,
                )

            # Graphics
            c.setFillColor(orange)
            c.rect(0, 0, w, 12, fill=1, stroke=0)
            c.rect(w - 12, 0, 12, 154, fill=1, stroke=0)

            # Add a utting line with multiple cards per page
            if self.multiple:
                c.setDash(1, 2)
                self.draw_outline()
        else:
            # Horizontal alignments
            CENTER = w / 2

            # Vertical alignments
            TOP = 200
            MIDDLE = 85
            BOTTOM = 16

            if config:
                # Organisation Statement
                org_statement = config.get("org_statement")
                if org_statement:
                    aH = draw_value(
                        CENTER,
                        MIDDLE,
                        org_statement,
                        height=40,
                        size=6,
                    )

                # Authority Statement
                authority_statement = config.get("authority_statement")
                if authority_statement:
                    draw_value(
                        CENTER,
                        MIDDLE + aH + 10,
                        authority_statement,
                        height=40,
                        size=7,
                        bold=False,
                    )

                # Signature
                signature = config.get("signature")
                if signature:
                    field = current.s3db.doc_card_config.signature
                    path = field.uploadfolder
                    if not path:
                        path = os.path.join(current.request.folder, "uploads")
                    self.draw_image(
                        os.path.join(path, signature),
                        CENTER,
                        MIDDLE - 25,
                        height=40,
                        width=60,
                        valign="middle",
                        halign="center",
                    )

                # Signature Text
                signature_text = config.get("signature_text")
                if signature_text:
                    draw_value(
                        CENTER,
                        MIDDLE - (50 if signature else 25),
                        signature_text,
                        height=20,
                        size=5,
                        bold=False,
                    )

            # Barcode
            code = raw["hrm_human_resource.code"]
            if code:
                self.draw_barcode(s3_str(code),
                                  CENTER,
                                  BOTTOM,
                                  height=12,
                                  halign="center",
                                  maxwidth=w - 15)

            # Graphics
            if logo:
                self.draw_image(logo,
                                CENTER,
                                TOP,
                                width=60,
                                height=60,
                                valign="middle",
                                halign="center")
            c.setFillColor(orange)
            c.rect(0, 0, w, 10, fill=1, stroke=0)
예제 #6
0
    def invite(self, r, **attr):
        """
            Prepare and process invitation form

            @param r: the S3Request instance
            @param attr: controller attributes
        """

        T = current.T

        db = current.db
        s3db = current.s3db

        response = current.response
        request = current.request
        session = current.session

        settings = current.deployment_settings
        auth = current.auth
        auth_settings = auth.settings
        auth_messages = auth.messages

        output = {
            "title": T("Invite Organisation"),
        }

        # Get all accounts that are linked to this org
        utable = auth_settings.table_user
        oltable = s3db.org_organisation_user
        pltable = s3db.pr_person_user

        organisation_id = r.record.id
        join = oltable.on((oltable.user_id == utable.id) & \
                          (oltable.deleted == False))
        left = pltable.on((pltable.user_id == utable.id) & \
                          (pltable.deleted == False))
        query = (oltable.organisation_id == organisation_id)
        rows = db(query).select(
            utable.id,
            utable.first_name,
            utable.last_name,
            utable.email,
            utable.registration_key,
            pltable.pe_id,
            join=join,
            left=left,
        )

        active, disabled, invited = [], [], []
        for row in rows:
            user = row[utable]
            person_link = row.pr_person_user
            if person_link.pe_id:
                if user.registration_key:
                    disabled.append(user)
                else:
                    active.append(user)
            else:
                invited.append(user)

        if active or disabled:
            response.error = T(
                "There are already user accounts registered for this organization"
            )

            from gluon import UL, LI, H4, DIV
            from s3 import s3_format_fullname

            fullname = lambda user: s3_format_fullname(
                fname=user.first_name,
                lname=user.last_name,
                truncate=False,
            )
            account_list = DIV(_class="org-account-list")
            if active:
                account_list.append(H4(T("Active Accounts")))
                accounts = UL()
                for user in active:
                    accounts.append(
                        LI("%s <%s>" % (fullname(user), user.email)))
                account_list.append(accounts)
            if disabled:
                account_list.append(H4(T("Disabled Accounts")))
                accounts = UL()
                for user in disabled:
                    accounts.append(
                        LI("%s <%s>" % (fullname(user), user.email)))
                account_list.append(accounts)

            output["item"] = account_list
            response.view = self._view(r, "display.html")
            return output

        account = invited[0] if invited else None

        # Look up existing invite-account
        email = None
        if account:
            email = account.email
        else:
            ctable = s3db.pr_contact
            query = (ctable.pe_id == r.record.pe_id) & \
                    (ctable.contact_method == "EMAIL") & \
                    (ctable.deleted == False)
            contact = db(query).select(
                ctable.value,
                orderby=ctable.priority,
                limitby=(0, 1),
            ).first()
            if contact:
                email = contact.value

        # Form Fields
        dbset = db(utable.id != account.id) if account else db
        formfields = [
            Field("email",
                  default=email,
                  requires=[
                      IS_EMAIL(error_message=auth_messages.invalid_email),
                      IS_LOWER(),
                      IS_NOT_IN_DB(
                          dbset,
                          "%s.email" % utable._tablename,
                          error_message=auth_messages.duplicate_email,
                      ),
                  ]),
        ]

        # Generate labels (and mark required fields in the process)
        labels, has_required = s3_mark_required(formfields, )
        response.s3.has_required = has_required

        # Form buttons
        SEND_INVITATION = T("Send New Invitation") if account else T(
            "Send Invitation")
        buttons = [
            INPUT(
                _type="submit",
                _value=SEND_INVITATION,
            ),
            # TODO cancel-button?
        ]

        # Construct the form
        response.form_label_separator = ""
        form = SQLFORM.factory(
            table_name="invite",
            record=None,
            hidden={"_next": request.vars._next},
            labels=labels,
            separator="",
            showid=False,
            submit_button=SEND_INVITATION,
            #delete_label = auth_messages.delete_label,
            formstyle=settings.get_ui_formstyle(),
            buttons=buttons,
            *formfields)

        # Identify form for CSS & JS Validation
        form.add_class("send_invitation")

        if form.accepts(
                request.vars,
                session,
                formname="invite",
                #onvalidation = auth_settings.register_onvalidation,
        ):

            error = self.invite_account(r.record,
                                        form.vars.email,
                                        account=account)
            if error:
                response.error = T(
                    "Could not send invitation (%(reason)s)") % {
                        "reason": error
                    }
            else:
                response.confirmation = T("Invitation sent")
        else:
            if account:
                response.warning = T(
                    "This organisation has been invited before!")

        output["form"] = form

        response.view = self._view(r, "update.html")

        return output
예제 #7
0
    def draw(self):
        """
            Draw the card (one side)

            Instance attributes (NB draw-function should not modify them):
            - self.canv...............the canvas (provides the drawing methods)
            - self.resource...........the resource
            - self.item...............the data item (dict)
            - self.labels.............the field labels (dict)
            - self.backside...........this instance should render the backside
                                      of a card
            - self.multiple...........there are multiple cards per page
            - self.width..............the width of the card (in points)
            - self.height.............the height of the card (in points)

            NB Canvas coordinates are relative to the lower left corner of the
               card's frame, drawing must not overshoot self.width/self.height
        """

        T = current.T

        c = self.canv
        w = self.width
        #h = self.height
        common = self.common

        blue = HexColor(0x27548F)

        item = self.item
        raw = item["_row"]

        root_org = raw["org_organisation.root_organisation"]

        # Get the localized root org name
        org_names = common.get("root_org_names")
        if org_names:
            root_org_name = org_names.get(root_org)

        #draw_field = self.draw_field
        draw_value = self.draw_value
        draw_label = self.draw_label

        code = raw["pr_person.pe_label"]

        if not self.backside:

            # Horizontal alignments
            LEFT = w / 4 - 5
            CENTER = w / 2 - 5
            RIGHT = w * 3 / 4 - 5

            # Vertical alignments
            TOP = 200
            #LOWER = [76, 58, 40]
            BOTTOM = 16

            # Organisation name
            if root_org_name:
                draw_value(
                    LEFT,
                    TOP,
                    root_org_name,
                    width=55,
                    height=55,
                    size=10,
                    valign="middle",
                )

            # Get the profile picture
            pictures = common.get("pictures")
            if pictures:
                picture = pictures.get(raw["pr_person.pe_id"])
                if picture:
                    self.draw_image(
                        picture,
                        RIGHT,
                        TOP,
                        width=60,
                        height=55,
                        valign="middle",
                        halign="center",
                    )

            # Center fields in reverse order so that vertical positions
            # can be adjusted for very long and hence wrapping strings
            y = 98

            # ID
            ah = draw_value(CENTER, y, code, height=24, size=8)
            draw_label(CENTER, y, None, T("ID Number"))

            # Name
            y += ah + 12
            name = s3_format_fullname(
                fname=raw["pr_person.first_name"],
                mname=raw["pr_person.middle_name"],
                lname=raw["pr_person.last_name"],
                truncate=False,
            )
            draw_value(CENTER, y, name, height=24, size=10)
            draw_label(CENTER, y, None, T("Name"))

            # Barcode
            if code:
                self.draw_barcode(
                    s3_str(code),
                    CENTER,
                    BOTTOM,
                    height=12,
                    halign="center",
                    maxwidth=w - 15,
                )

            # Graphics
            c.setFillColor(blue)
            c.rect(0, 0, w, 12, fill=1, stroke=0)
            c.rect(w - 12, 0, 12, 154, fill=1, stroke=0)

            # Add a utting line with multiple cards per page
            if self.multiple:
                c.setDash(1, 2)
                self.draw_outline()
        else:
            # Horizontal alignments
            CENTER = w / 2

            # Vertical alignments
            TOP = 200
            MIDDLE = 85
            BOTTOM = 16

            # QR Code
            if code:
                identity = "%s//%s:%s:%s" % (
                    code,
                    raw["pr_person.first_name"] or "",
                    raw["pr_person.middle_name"] or "",
                    raw["pr_person.last_name"] or "",
                )
                self.draw_qrcode(identity,
                                 CENTER,
                                 MIDDLE,
                                 size=60,
                                 halign="center",
                                 valign="center")
            # Barcode
            if code:
                self.draw_barcode(s3_str(code),
                                  CENTER,
                                  BOTTOM,
                                  height=12,
                                  halign="center",
                                  maxwidth=w - 15)

            # Graphics
            c.setFillColor(blue)
            c.rect(0, 0, w, 10, fill=1, stroke=0)