Ejemplo n.º 1
0
def BottomBox(data):
    return Row(
        width='100%',
        margin=Rect([8, 0, 6, 0]),
        border=Border(
            width=0.5,
            color=Color.BLACK,
        ),
        padding=Rect([2, 8, 4, 8]),
    ).add(
        Column(width='50%').add(
            Text(
                text=boil('status_of_cm_types_of_workers'),
                font_family='Roboto Condensed',
                font_size=8,
                font_weight=Pango.Weight.BOLD,
            ),
            Text(text='{} {}'.format(
                boil('status_of_cm_list_1'),
                boil('status_of_cm_skilled_mason'),
            ),
                 font_family='Roboto Condensed',
                 font_size=8,
                 padding=Rect([2, 0, 2, 0])),
            Text(
                text='{} {}'.format(
                    boil('status_of_cm_list_2'),
                    boil('status_of_cm_labourer'),
                ),
                font_family='Roboto Condensed',
                font_size=8,
            ),
        ),
        Column(width='60%').add(
            Text(
                text=boil('status_of_cm_avg._daily_wage_(nrs.)'),
                width='100%',
                alignment=Text.CENTER,
                font_family='Roboto Condensed',
                font_size=8,
                font_weight=Pango.Weight.BOLD,
            ),
            Text(
                text='%s %s' % (fmt_num(data['avg_wage_1']), '/-'),
                width='65%',
                alignment=Text.RIGHT,
                font_family='Roboto Condensed',
                font_size=8,
                padding=Rect([2, 0, 2, 0]),
            ),
            Text(
                text='%s %s' % (fmt_num(data['avg_wage_2']), '/-'),
                width='65%',
                alignment=Text.RIGHT,
                font_family='Roboto Condensed',
                font_size=8,
                padding=Rect([0, 0, 1, 0]),
            )),
    )
Ejemplo n.º 2
0
def Header(data):
    nm_text = '{} | {}'.format(
        data['rep_data']['dist_nm'],
        data['rep_data']['palika_nm'],
    )

    return Column(
        width='100%',
        margin=Rect([0, 5, 8, 5]),
    ).add(
        Row(height=52, width='10%').add(
            Text(
                text=boil('header_title'),
                font_family='Roboto Condensed',
                font_size=24,
                font_weight=Pango.Weight.BOLD,
                color=Color.PRIMARY,
                height='100%',
                vertical_alignment=Text.BOTTOM,
            ),
            Vr(
                width=2,
                height='100%',
                color=Color.PRIMARY,
                margin=Rect([0, 16, 0, 16]),
                padding=Rect([24, 0, 0, 0]),
            ),
            Column(height='100%', justify='end').add(
                Text(
                    text='{} {}'.format(
                        boil('header_month'),
                        boil('header_year') if isinstance(
                            boil('header_year'), str) else get_lang_num(
                                str(boil('header_year'))),
                    ),
                    font='Roboto Light',
                    font_size=10,
                    color=Color.PRIMARY,
                ),
                Text(
                    text=nm_text,
                    font='Roboto Light',
                    font_size=calc_nm_len(nm_text),
                    color=Color.PRIMARY,
                ))),
        Hr(
            width='100%',
            height=1,
            color=Color.PRIMARY,
            margin=Rect([8, 0, 0, 0]),
        ),
        Hr(
            width='100%',
            height=1.8,
            color=Color.PRIMARY,
            margin=Rect([2, 0, 0, 0]),
        ),
    )
Ejemplo n.º 3
0
def Pop(data):
    for k, v in data.items():
        if not v:
            data[k] = boil('partner_orgs_no_partner_orgs')

    hs = _calc_box_hs([v for v in data.values()])

    return Column(width='100%', height='100%').add(
        Column(
            width='100% - 16',
            height='76%',
            margin=Rect([12, 8, 4, 11]),
        ).add(*[PoGroup(info[0], info[1]) for info in zip(hs, data.items())]))
Ejemplo n.º 4
0
def ReconstructionAndRetrofit(data):
    return Row(width='100%', padding=Rect(8)).add(
        Column(width='50%', padding=Rect([3, 8, 0, 2])).add(
            ReconstructionStatus(data['reconstruction_status']),
            Houses(data['houses']),
        ),
        Column(width='50%', padding=Rect([3, 2, 0, 8])).add(
            RetrofitStatus(data['retrofitting_status']),
            Row(width='100%').add(
                Grievances(data['grievances']),
                NonCompliance(data['non_compliances']),
            ),
        ))
Ejemplo n.º 5
0
def Page(data):
    return Column(width='100%', relative=True).add(
        Row(width='100%').add(
            Panel(
                title=boil('facts_and_figures_panel_title'),
                height=148,
                width='50% - 5',
            ).add(FF(data['facts_and_figures'])),
            Panel(
                title=boil('typologies_panel_title'),
                height=148,
                width='50% - 5',
            ).add(Typologies(data['housing_typologies'])),
        ),
        Row(width='100%').add(
            Panel(
                title=boil('recon_&_retrofit_panel_title'),
                width='100%',
                right_footer=ReconstructionAndRetrofitFooter,
                footer_data=data['reconstruction_retrofit_updates']
                ['recon_footer_date'],
            ).add(
                ReconstructionAndRetrofit(
                    data['reconstruction_retrofit_updates']), ), ),
        Row(width='100%').add(
            Column(width='50%', height='100%').add(
                Panel(
                    title=boil('po_presence_pos_presence_title'),
                    height='45% - 20',
                    width='100% - 10',
                ).add(Pop(data['pos_presence'])),
                Panel(
                    title=boil('other_sectors_panel_title'),
                    height='55% - 20',
                    width='100% - 10',
                ).add(OtherSectors(data['other_sectors'])),
            ),
            Panel(
                title=boil('status_of_cm_panel_title'),
                width='50%',
            ).add(CMTable(data['construction_materials'], data['work_wage'])),
        ),
        Panel(
            title=boil('key_contacts_panel_title'),
            width='100%',
            left_footer=LeftFootNotes,
            right_footer=RightFootNotes,
        ).add(KeyContacts(data['key_contacts']), ),
        Sidebar(bottom=0, left=-12),
    )
Ejemplo n.º 6
0
def Contact(it, title, contact):

    for k, v in contact.items():
        # TODO: fix 'none'
        if not v or v == 'None':
            contact[k] = '-'

    return Column(width='33%', padding=Rect([0, 8, 0, 8])).add(
        Text(
            text=title,
            font_family="Roboto Condensed",
            font_size=9,
            font_weight=Text.BOLD,
        ),
        Text(
            text=contact['name'] if contact['name'] != ZERO_DEFAULT else '',
            font_family="Roboto Condensed",
            font_size=7,
        ),
        Text(
            text=contact['title'] if contact['title'] != ZERO_DEFAULT else '',
            font_family="Roboto Condensed",
            font_size=7,
        ),
        Text(
            text=get_lang_num(contact['contact'])
            if contact['contact'] != ZERO_DEFAULT else '',
            font_family="Roboto Condensed",
            font_size=7,
        ))
Ejemplo n.º 7
0
def Sector(label, items, icon):
    return Column(
        width='50%',
        height='100%',
        justify='center',
        align='center',
    ).add(
        Canvas(
            width=56,
            height=56,
            renderer=IconRenderer(filename=icon),
        ),
        Text(
            text=label,
            color=Color.ACCENT,
            margin=Rect(4),
            font_family='Roboto Condensed',
            font_size=8,
            font_weight=Pango.Weight.BOLD,
        ), *[
            Row().add(
                Text(
                    text='{}: '.format(key),
                    font_family='Roboto Condensed',
                    font_size=8,
                    font_weight=Pango.Weight.BOLD,
                ),
                Text(
                    text=value,
                    font_family='Roboto Condensed',
                    font_size=8,
                )) for key, value in items.items()
        ])
Ejemplo n.º 8
0
def NonCompliance(data):
    return Column(width='50%').add(
        Text(
            text=boil('recon_&_retrofit_non-compliances_title'),
            color=Color.ACCENT,
            font_family="Roboto Condensed",
            font_size=9,
            font_weight=Text.BOLD,
            margin=Rect([3.2, 0, 5, 0]),
        ),
        Text(markup='<b>{}:</b> {}'.format(
            boil('recon_&_retrofit_registered_(both)'),
            fmt_num(data['registered']),
        ),
             font_family="Roboto Condensed",
             font_size=7.5,
             margin=Rect([0, 0, 3, 0])),
        Text(
            markup='<b>{}:</b> {}'.format(
                boil('recon_&_retrofit_addressed_(both)'),
                fmt_num(data['addressed']),
            ),
            font_family="Roboto Condensed",
            font_size=7.5,
        ),
    )
Ejemplo n.º 9
0
def RetrofitStatus(data):
    rows = [
        TwoValueLineChart(datum, bar_color=Color.ACCENT2) for datum in data
    ]

    return Column(width='100%').add(
        Text(
            text=boil('recon_&_retrofit_retrofitting_status_title'),
            font_family="Roboto Condensed",
            font_size=9,
            font_weight=Text.BOLD,
            color=Color.ACCENT,
        ),
        Hr(
            width='100%',
            height=1,
            margin=Rect([3, 0, 3, 0]),
            dash=[3],
            color=Color.PRIMARY,
        ),
        *rows,
        Hr(
            width='100%',
            height=1,
            margin=Rect([3, 0, 3, 0]),
            dash=[3],
            color=Color.PRIMARY,
        ),
    )
Ejemplo n.º 10
0
def Houses(data):
    return Column(width='100%').add(
        Text(text=boil('recon_&_retrofit_houses_title'),
             font_family="Roboto Condensed",
             font_size=9,
             font_weight=Text.BOLD,
             color=Color.ACCENT,
             margin=Rect([0, 0, 2, 0])),
        Row(
            width='100%',
            justify='space-between',
            margin=Rect([0, 0, 3, 0]),
        ).add(
            Text(
                markup='<b>{}</b>: {}'.format(
                    boil('recon_&_retrofit_under_construction'),
                    fmt_num(data['under_construction'], )),
                font_family="Roboto Condensed",
                font_size=7.5,
            ),
            Text(
                markup='<b>{}</b>: {}'.format(
                    boil('recon_&_retrofit_completed'),
                    fmt_num(data['completed'], )),
                font_family="Roboto Condensed",
                font_size=7.5,
            )),
    )
Ejemplo n.º 11
0
def FurtherInfoNotes(data, **kwargs):
    # TODO: check nans before entering

    return Row(**kwargs, width='100%', height=16).add(
        Text(
            text=boil('page_2_futher_information'),
            font_family='Roboto Condensed',
            font_size=7,
            font_weight=Pango.Weight.BOLD,
            padding=Rect([12.5, 0, 0, 5]),
        ), *[
            Column(padding=Rect(8)).add(
                Text(
                    text='{}. {} ({})'.format(
                        get_lang_num(i + 1),
                        contact['name'] if contact['name']
                        and contact['name'] != 'None' else '',
                        contact['title'] if contact['title']
                        and contact['title'] != 'None' else '',
                    ),
                    font_family='Roboto Condensed',
                    font_size=7,
                    padding=Rect([5, 0, 0, 0]),
                ),
                Text(
                    text='     {}'.format(
                        get_lang_num(contact['phone']) if contact['phone']
                        and contact['phone'] != 'None' else ''),
                    font_family='Roboto Condensed',
                    font_size=7,
                ),
            ) for i, contact in enumerate(data)
            if not all([is_nan(v) for v in contact.values()])
        ])
Ejemplo n.º 12
0
def PoGroup(h, pos):
    #TODO: set global val for what blank is
    label = pos[0]
    pos_list = pos[1]

    return Column(
        width='98%',
        height='{}%'.format(h + 4),
        border=Border(
            width=0.5,
            color=Color.BLACK,
        ),
    ).add(
        Text(
            width='98%',
            height='{}%'.format(h + 4),
            # markup='{}'.format('hello '*60),
            markup='<b>{}:</b> {}'.format(boil(label), pos_list),
            color=Color.BLACK,
            font_family="Roboto Condensed",
            font_size=7,
            #TODO: fix bug where row cuts off early
            auto_scale_height=False,
            padding=Rect([1, 0, 5, 3]),
        ), )
Ejemplo n.º 13
0
def Page2(data, LANG):
    set_lang(LANG)
    return Column(
        width=WIDTH,
        height=HEIGHT,
        bg_color=Color.WHITE,
        padding=Rect(32),
    ).add(Page2Content(data), )
Ejemplo n.º 14
0
def Footer(data):
    faq_blocks = []
    for it, item in enumerate(data):
        question = Text(
            width='100%',
            text='{}: {}'.format(boil('faq_q'), item['q']),
            font_family='Roboto Condensed',
            font_size=8.5,
            font_weight=Pango.Weight.BOLD,
        )
        answer = Text(
            width='100%',
            text='{}: {}'.format(boil('faq_a'), item['a']),
            font_family='Roboto Condensed',
            font_size=8,
            padding=Rect([0, 0, 8, 0]) if it == 0 else Rect(0),
        )
        faq_blocks.append(question)
        faq_blocks.append(answer)

    return Column(
        width='100%',
        padding=Rect([10, 16, 6, 16]),
    ).add(*faq_blocks, )
Ejemplo n.º 15
0
def Page(data):
    return Column(width='100%', relative=True).add(
        Panel(
            title=boil('land_issues_panel_title'),
            width='100% - 10',
        ).add(HH(data['hhs'])),
        Row(width='100%').add(
            Panel(
                title=boil('tech_staff_panel_title'),
                height='100% - 20',
                width='50% - 10',
                right_footer=TechnicalStaffFooter,
            ).add(
                TechnicalStaff(
                    data['technical_staff'],
                    data['technical_staff_masons'],
                )),
            Panel(
                title=boil('training_panel_title'),
                height='100% - 20',
                width='50% - 10',
                right_footer=TrainingsFooter,
            ).add(Trainings(data['trainings'])),
        ),
        Panel(
            title=boil('map_panel_title'),
            width='100% - 10',
        ).add(Map(data['map'])),
        Panel(
            title=boil('faq_panel_title'),
            width='100% - 10',
            left_footer=FurtherInfoNotes,
            footer_data=data['further_info'],
        ).add(Footer(data['faq'])),
        Sidebar(bottom=0, right=-12),
    )
Ejemplo n.º 16
0
def KeyContacts(data):
    titles = [boil('key_contacts_municipal_office_title')] * 4 + [
        boil('key_contacts_gmali/nra_title'),
        boil('key_contacts_dlpiu-building_title'),
    ]

    return Column(
        width='100%',
        margin=Rect([0, 5, 0, 0]),
    ).add(
        Row(
            width='100%',
            padding=Rect([15, 0, 20, 0]),
        ).add(*[
            Contact(i, titles[i], contact)
            for i, contact in enumerate(data[:3])
        ])).add(
            Row(
                width='100%',
                padding=Rect([0, 0, 12, 0]),
            ).add(*[
                Contact(i + 3, titles[i + 3], contact)
                for i, contact in enumerate(data[3:])
            ]))
Ejemplo n.º 17
0
def HH(data):
    """for showing the HH bar. logic:
            if 0 values: show message that there are no reported issues
            if 1 value: do something #TODO
            else: show bar
            """

    # info f.e type
    items = [
        {
            'key': 'landless',
            'label': boil('land_issues_landless'),
            'color': hx('#ff6117'),
        },
        {
            'key': 'no_land_certificates',
            'label': boil('land_issues_no_land_certificates'),
            'color': hx('#bf053d'),
        },
        {
            'key': 'right_of_way',
            'label': boil('land_issues_right_of_way'),
            'color': hx('#7d0547'),
        },
        {
            'key': 'affected_by_hep',
            'label': boil('land_issues_affected_by_hep'),
            'color': hx('#1e7a8c'),
        },
        {
            'key': 'smallplots',
            'label': boil('land_issues_small_plots'),
            'color': hx('#abd1b5'),
        },
        {
            'key': 'guthi_land',
            'label': boil('land_issues_guthi_land'),
            'color': hx('#ffc202'),
        },
    ]

    # add val and drop item if it's zero or invalid
    items = _filter_items(items, data)

    wdz = _get_widths(items)

    bars = []
    labels = []
    if wdz:
        for item in wdz:
            color = item['color']

            bar = Text(
                bg_color=color,
                height=20,
                width='{}%'.format(item['w']),
                alignment=Text.CENTER,
                vertical_alignment=Text.MIDDLE,
                text=fmt_num(item['val']),
                color=Color.WHITE,
                font_family='Roboto Condensed',
                font_size=11,
                font_weight=Pango.Weight.BOLD,
            )
            bars.append(bar)

            label = Label(
                label=item['label'],
                color=color,
            )
            labels.append(label)

        return Column(
            width='100%',
            padding=Rect([16, 16, 8, 16]),
        ).add(
            Row(width='100%').add(*bars),
            Row(
                width='100%',
                justify='space-between' if len(labels) > 1 else None,
            ).add(*labels)
        )

    else:
        return Column(width='100%', height='100%').add(
            Text(
                height='100%',
                width='100%',
                alignment=Text.CENTER,
                vertical_alignment=Text.MIDDLE,
                text=boil('land_issues_no_information'),
                color=Color.GRAY,
                font_family='Roboto Condensed',
                font_size=18,
                font_weight=Pango.Weight.BOLD,
                margin=Rect([0, 0, 43, 0]),
            )
        )
Ejemplo n.º 18
0
def Trainings(data):
    short = data['short']
    vocational = data['vocational']

    short_training = [
        {'value': short['reached'], 'color': Color.ACCENT},
        {'value': _calc_reached(short['reqd'], short['reached']), 'color': Color.GRAY},
    ]
    vocational_training = [
        {'value': vocational['reached'], 'color': Color.ACCENT},
        {'value': _calc_reached(vocational['reqd'], vocational['reached']), 'color': Color.GRAY},
    ]

    items = [
        {'label': boil('training_reached'), 'color': Color.ACCENT},
        {'label': boil('training_remaining'), 'color': Color.GRAY},
    ]

    return Column(
        width='100%',
        height='100%',
        padding=Rect([10, 10, 4, 10]),
    ).add(
        Text(
            height=13,
            text=boil('training_sub_title'),
            color=Color.PRIMARY,
            font_family='Roboto Condensed',
            font_size=8,
            font_weight=Pango.Weight.BOLD,
        ),
        Row(width='100%', height='100% - 32', padding=Rect(4)).add(
            Canvas(
                width='50%',
                height='100%',
                renderer=PieChart(
                    items=short_training,
                    label=boil('training_short_training'),
                )
            ),
            Canvas(
                width='50%',
                height='100%',
                renderer=PieChart(
                    items=vocational_training,
                    label=boil('training_vocational_training'),
                )
            ),
        ),
        Row(
            width='100%',
            height=16,
            justify='center',
            align='center',
        ).add(
            *[
                Label(
                    label=item['label'],
                    color=item['color'],
                ) for item in items
            ]
        ),
    )
Ejemplo n.º 19
0
def CMTable(top_data, bot_data):
    materials = [{
        'label': boil('status_of_cm_stone'),
        'key': 'stone',
        'icon': 'stone.png',
        'unit': boil('status_of_cm_cubic_metre_measurement'),
    }, {
        'label': boil('status_of_cm_aggregate'),
        'key': 'aggregate',
        'icon': 'aggregate.png',
        'unit': boil('status_of_cm_cubic_metre_measurement'),
    }, {
        'label': boil('status_of_cm_sand'),
        'key': 'sand',
        'icon': 'sand.png',
        'unit': boil('status_of_cm_cubic_metre_measurement'),
    }, {
        'label': boil('status_of_cm_timber'),
        'key': 'timber',
        'icon': 'timber.png',
        'unit': boil('status_of_cm_cubic_feet_measurement'),
    }, {
        'label': boil('status_of_cm_cement_(ppc)'),
        'key': 'cement_ppc',
        'icon': 'cement.png',
        'unit': boil('status_of_cm_sack_measurement'),
    }, {
        'label': boil('status_of_cm_cement_(opc)'),
        'key': 'cement_opc',
        'icon': 'cement.png',
        'unit': boil('status_of_cm_sack_measurement'),
    }, {
        'label': boil('status_of_cm_rebars'),
        'key': 'rebar',
        'icon': 'rebar.png',
        'unit': boil('status_of_cm_kg_plural_measurement'),
    }, {
        'label': boil('status_of_cm_tin'),
        'key': 'tin',
        'icon': 'tin.png',
        'unit': boil('status_of_cm_bundle_measurement'),
    }, {
        'label': boil('status_of_cm_bricks'),
        'key': 'bricks',
        'icon': 'bricks.png',
        'unit': boil('status_of_cm_pieces_measurement'),
    }]

    rows = []
    for material in materials:
        key = material['key']
        datum = top_data[key]
        label = material['label']

        if datum['ava'] is None:
            datum['ava'] = ZERO_DEFAULT

        rows.append([
            {
                'text': label,
                'icon': material.get('icon')
            },
            {
                'text': material['unit']
            },
            {
                'text': fmt_num(datum['req_quantity'])
            },
            {
                'text': datum['ava']
            },
            {
                'text': fmt_num(datum['cost'])
            },
        ])

    headers = [
        '<b>{}</b>'.format(boil(k)) for k in [
            'status_of_cm_materials_header',
            'status_of_cm_unit_header',
            'status_of_cm_req._quantity*_header',
            'status_of_cm_ava._header',
            'status_of_cm_cost_(nrs.)**_header',
        ]
    ]

    widths = ['28%', '12%', '25%', '10%', '25%']
    return Column(width='100%', padding=Rect([16, 14, 0, 14])).add(
        TR_Text(widths=widths, items=headers),
        *[TR(widths=widths, items=row) for row in rows],
        BottomBox(bot_data),
    )
Ejemplo n.º 20
0
def Typologies(data):
    widths = ['60%', '20%', '20%']
    headers = [
        boil('typologies_typology'),
        boil('typologies_municipal'),
        boil('typologies_district')
    ]

    if get_lang() == 'np':
        row_seperator_padding = [3.5, 0, 4.5, 0]
    else:
        row_seperator_padding = [4.5, 0, 4.5, 0]

    # flatten and add dict
    # TODO: assert that we don't have duplicate keys? (exclude blanks))
    rows = get_list_typo(OrderedDict((boil(k), v) for k, v in data.items()), 5)

    return Column(
        width='100%',
        padding=Rect(12),
    ).add(
        Row(width='100%').add(*[
            Text(
                width=widths[i],
                text=header,
                font_family="Roboto Condensed",
                font_size=9,
                font_weight=Text.BOLD,
                color=Color.ACCENT,
                alignment=Text.LEFT if i == 0 else Text.RIGHT,
            ) for i, header in enumerate(headers)
        ]),
        Hr(
            width='100%',
            height=1,
            color=Color.PRIMARY,
            dash=[3],
            margin=Rect([3, 0, 3, 0]),
        ),
        *[
            Row(width='100%').add(*[
                Item(
                    width=widths[i],
                    text=k if i == 0 else fmt_pct(
                        list(d_v.items())[i - 1][1],
                        pts=2,
                    ),
                    index=i,
                    padding=Rect(row_seperator_padding),
                ) for i in range(NUM_COLS)
            ]) for k, d_v in rows.items()
        ],
        *[
            Row(width='100%').add(*[
                Item(
                    width=widths[i],
                    text=' ',
                    index=i,
                    padding=Rect(row_seperator_padding),
                ) for i in range(NUM_COLS)
            ]) for v in range(NUM_ROWS - len(rows))
        ],
        Text(width='100%',
             text=boil('typologies_cbs_footer'),
             font_family="Roboto Light",
             font_size=6,
             alignment=Text.RIGHT,
             color=Color.DARK_GRAY,
             padding=Rect([0, 0, 10, 0])),
    )
Ejemplo n.º 21
0
def TechnicalStaff(tech_data, mason_data):
    widths = ['35%', '30%', '35%']
    headers = [
        boil('tech_staff_staff_title'),
        boil('tech_staff_available_title'),
        boil('tech_staff_addl_req_title')
    ]

    tech_data = [[
        boil(item['lookup']),
        fmt_num(item['available']),
        fmt_num(item['additional'])
    ] for item in tech_data]

    mason_data = [
        boil(mason_data['lookup']), mason_data['available'],
        mason_data['additional']
    ]

    # mason_data = [mason_data['label'], 100, 300]

    header_row = Row(width='100%').add(*[
        Text(
            border=Border(width=0.5, color=Color.BLACK),
            text=item,
            width=widths[i],
            font_family='Roboto Condensed',
            font_size=7,
            font_weight=Pango.Weight.BOLD,
            padding=Rect(4),
            alignment=(Text.LEFT if i == 0 else Text.CENTER),
        ) for i, item in enumerate(headers)
    ])

    # add non masons
    data_rows = [
        Row(width='100%').add(
            *[
                Text(
                    border=Border(width=0.5, color=Color.BLACK),
                    text=item,
                    width=widths[i],
                    height='15',
                    font_family='Roboto Condensed',
                    font_size=7 if i == 0 else 9,
                    font_weight=Pango.Weight.BOLD if i == 0 else None,
                    padding=Rect([3, 0, 0, 4]),
                    alignment=(Text.LEFT if i == 0 else Text.CENTER),
                ) for i, item in enumerate(row)
            ], ) for row in tech_data
    ]

    # add masons
    data_rows.append(
        Row(width='100%').add(*[
            Text(
                border=Border(width=0.5, color=Color.BLACK),
                text=mason_data[0],
                width=widths[0],
                font_family='Roboto Condensed',
                font_weight=Pango.Weight.BOLD,
                font_size=7,
                padding=Rect(4),
                alignment=Text.LEFT,
            ),
            Column(
                border=Border(width=0.5, color=Color.BLACK),
                height='100%',
                width=widths[1],
            ).add(
                Text(
                    text='{} ({} {})'.format(fmt_num(mason_data[1][0]),
                                             fmt_num(7), boil(
                                                 'tech_staff_days')),
                    font_family='Roboto Condensed',
                    font_size=6,
                    width='100%',
                    alignment=Text.CENTER,
                    padding=Rect([2, 0, 0, 0]),
                )).add(
                    Text(
                        text='{} ({} {})'.format(fmt_num(mason_data[1][1]),
                                                 fmt_num(50),
                                                 boil('tech_staff_days')),
                        font_family='Roboto Condensed',
                        font_size=6,
                        width='100%',
                        alignment=Text.CENTER,
                    )),
            Column(border=Border(width=0.5, color=Color.BLACK),
                   height='100%',
                   width=widths[2]).add(
                       Text(
                           text='{} ({} {})'.format(fmt_num(mason_data[2][0]),
                                                    fmt_num(7),
                                                    boil('tech_staff_days')),
                           font_family='Roboto Condensed',
                           font_size=6,
                           width='100%',
                           alignment=Text.CENTER,
                           padding=Rect([2, 0, 0, 0]),
                       )).add(
                           Text(
                               text='{} ({} {})'.format(
                                   fmt_num(mason_data[2][1]), fmt_num(50),
                                   boil('tech_staff_days')),
                               font_family='Roboto Condensed',
                               font_size=6,
                               width='100%',
                               alignment=Text.CENTER,
                           )),
        ]))
    #
    # Row(width=widths[1],
    #     border=Border(width=0.5, color=Color.BLACK),
    #     height='100%').add(
    #     Row(border=Border(width=0.5, color=Color.BLACK)).add(
    #         Text(
    #             text='xx22',
    #             font='RobotoCondensed bold 6',
    #             font_size='RobotoCondensed bold',
    #             alignment=Text.CENTER,
    #         ),
    #     ).add(Row(border=Border(width=0.5, color=Color.BLACK)).add(
    #         Text(
    #             text='yy',
    #             font='RobotoCondensed 6',
    #         ),
    #     ),
    #     ),

    return Column(
        width='100%',
        padding=Rect(16),
    ).add(
        header_row,
        *data_rows,
    )