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)
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)
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()
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()
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)
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
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)