Changeset - 72f58d80d735
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2020-06-15 18:09:42
brettcsmith@brettcsmith.org
reports: BaseODS.currency_cell() sets default style.

It'll be rare we don't want this.
2 files changed with 15 insertions and 0 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/reports/core.py
Show inline comments
...
 
@@ -877,96 +877,98 @@ class BaseODS(BaseSpreadsheet[RT, ST], metaclass=abc.ABCMeta):
 
                styles, odf.style.Style, name=f'{textalign.title()}Text',
 
            )
 
            aligned_style.setAttribute('family', 'table-cell')
 
            aligned_style.addElement(odf.style.ParagraphProperties(textalign=textalign))
 
            setattr(self, f'style_{textalign}text', aligned_style)
 

	
 
        self.style_col1: odf.style.Style
 
        self.style_col1_25: odf.style.Style
 
        self.style_col1_5: odf.style.Style
 
        self.style_col1_75: odf.style.Style
 
        self.style_col2: odf.style.Style
 
        for width in ['1', '1.25', '1.5', '1.75', '2']:
 
            width_name = width.replace('.', '_')
 
            column_style = self.replace_child(
 
                self.document.automaticstyles, odf.style.Style, name=f'col_{width_name}',
 
            )
 
            column_style.setAttribute('family', 'table-column')
 
            column_style.addElement(odf.style.TableColumnProperties(columnwidth=f'{width}in'))
 
            setattr(self, f'style_col{width_name}', column_style)
 

	
 
    ### Rows and cells
 

	
 
    def add_row(self, *cells: odf.table.TableCell, **attrs: Any) -> odf.table.TableRow:
 
        row = odf.table.TableRow(**attrs)
 
        for cell in cells:
 
            row.addElement(cell)
 
        self.sheet.addElement(row)
 
        return row
 

	
 
    def balance_cell(self, balance: Balance, **attrs: Any) -> odf.table.TableCell:
 
        if balance.is_zero():
 
            return self.float_cell(0, **attrs)
 
        elif len(balance) == 1:
 
            amount = next(iter(balance.values()))
 
            attrs['stylename'] = self.merge_styles(
 
                attrs.get('stylename'), self.currency_style(amount.currency),
 
            )
 
            return self.currency_cell(amount, **attrs)
 
        else:
 
            lines = [babel.numbers.format_currency(
 
                number, currency, locale=self.locale, format_type=self.currency_fmt_key,
 
            ) for number, currency in balance.values()]
 
            attrs['stylename'] = self.merge_styles(
 
                attrs.get('stylename'), self.style_endtext,
 
            )
 
            return self.multiline_cell(lines, **attrs)
 

	
 
    def currency_cell(self, amount: data.Amount, **attrs: Any) -> odf.table.TableCell:
 
        if 'stylename' not in attrs:
 
            attrs['stylename'] = self.currency_style(amount.currency)
 
        number, currency = amount
 
        cell = odf.table.TableCell(valuetype='currency', value=number, **attrs)
 
        cell.addElement(odf.text.P(text=babel.numbers.format_currency(
 
            number, currency, locale=self.locale, format_type=self.currency_fmt_key,
 
        )))
 
        return cell
 

	
 
    def date_cell(self, date: datetime.date, **attrs: Any) -> odf.table.TableCell:
 
        attrs.setdefault('stylename', self.style_date)
 
        cell = odf.table.TableCell(valuetype='date', datevalue=date, **attrs)
 
        cell.addElement(odf.text.P(text=date.isoformat()))
 
        return cell
 

	
 
    def float_cell(self, value: Union[int, float, Decimal], **attrs: Any) -> odf.table.TableCell:
 
        cell = odf.table.TableCell(valuetype='float', value=value, **attrs)
 
        cell.addElement(odf.text.P(text=str(value)))
 
        return cell
 

	
 
    def _meta_link_pairs(self, links: Iterable[Optional[str]]) -> Iterator[Tuple[str, str]]:
 
        for href in links:
 
            if href is None:
 
                continue
 
            elif self.rt_wrapper is not None:
 
                rt_ids = self.rt_wrapper.parse(href)
 
                rt_href = rt_ids and self.rt_wrapper.url(*rt_ids)
 
            else:
 
                rt_ids = None
 
                rt_href = None
 
            if rt_ids is None or rt_href is None:
 
                # '..' pops the ODS filename off the link path. In other words,
 
                # make the link relative to the directory the ODS is in.
 
                href_path = Path('..', href)
 
                href = str(href_path)
 
                text = href_path.name
 
            else:
 
                rt_path = urlparse.urlparse(rt_href).path
 
                if rt_path.endswith('/Ticket/Display.html'):
 
                    text = rtutil.RT.unparse(*rt_ids)
 
                else:
 
                    text = urlparse.unquote(Path(rt_path).name)
 
                href = rt_href
 
            yield (href, text)
 

	
 
    def meta_links_cell(self, links: Iterable[Optional[str]], **attrs: Any) -> odf.table.TableCell:
 
        return self.multilink_cell(self._meta_link_pairs(links), **attrs)
 

	
 
    def multiline_cell(self, lines: Iterable[Any], **attrs: Any) -> odf.table.TableCell:
 
        cell = odf.table.TableCell(valuetype='string', **attrs)
tests/test_reports_spreadsheet.py
Show inline comments
...
 
@@ -425,96 +425,109 @@ def test_ods_writer_add_row_empty(ods_writer):
 
    row = ods_writer.add_row(stylename='blank')
 
    assert ods_writer.sheet.lastChild is row
 
    assert row.firstChild is None
 
    assert row.getAttribute('stylename') == 'blank'
 

	
 
def test_ods_writer_balance_cell_empty(ods_writer):
 
    balance = core.Balance()
 
    cell = ods_writer.balance_cell(balance)
 
    assert cell.value_type != 'string'
 
    assert float(cell.value) == 0
 

	
 
def test_ods_writer_balance_cell_single_currency(ods_writer):
 
    number = 250
 
    currency = 'EUR'
 
    balance = core.Balance([testutil.Amount(number, currency)])
 
    cell = ods_writer.balance_cell(balance)
 
    assert cell.value_type == 'currency'
 
    assert Decimal(cell.value) == number
 
    assert cell.text == babel.numbers.format_currency(
 
        number, currency, locale=EN_US, format_type='accounting',
 
    )
 

	
 
def test_ods_writer_balance_cell_multi_currency(ods_writer):
 
    amounts = [testutil.Amount(num, code) for num, code in [
 
        (2500, 'RUB'),
 
        (3500, 'BRL'),
 
    ]]
 
    balance = core.Balance(amounts)
 
    cell = ods_writer.balance_cell(balance)
 
    assert cell.text == '\0'.join(babel.numbers.format_currency(
 
        number, currency, locale=EN_US, format_type='accounting',
 
    ) for number, currency in amounts)
 

	
 
@pytest.mark.parametrize('cell_source,style_name', testutil.combine_values(
 
    CURRENCY_CELL_DATA,
 
    XML_NAMES,
 
))
 
def test_ods_writer_currency_cell(ods_writer, cell_source, style_name):
 
    cell = ods_writer.currency_cell(cell_source, stylename=style_name)
 
    number, currency = cell_source
 
    assert cell.getAttribute('valuetype') == 'currency'
 
    assert cell.getAttribute('value') == str(number)
 
    assert cell.getAttribute('stylename') == style_name
 
    expected = babel.numbers.format_currency(
 
        number, currency, locale=EN_US, format_type='accounting',
 
    )
 
    assert get_text(cell) == expected
 

	
 
@pytest.mark.parametrize('currency', [
 
    'EUR',
 
    'CHF',
 
    'GBP',
 
])
 
def test_ods_writer_currency_cell_default_style(ods_writer, currency):
 
    amount = testutil.Amount(1000, currency)
 
    expected_stylename = ods_writer.currency_style(currency).getAttribute('name')
 
    cell = ods_writer.currency_cell(amount)
 
    assert cell.getAttribute('valuetype') == 'currency'
 
    assert cell.getAttribute('value') == '1000'
 
    assert cell.getAttribute('stylename') == expected_stylename
 

	
 
@pytest.mark.parametrize('date,style_name', testutil.combine_values(
 
    [datetime.date(1980, 2, 5), datetime.date(2030, 10, 30)],
 
    XML_NAMES_LIST,
 
))
 
def test_ods_writer_date_cell(ods_writer, date, style_name):
 
    if style_name is None:
 
        expect_style = ods_writer.style_date.getAttribute('name')
 
        cell = ods_writer.date_cell(date)
 
    else:
 
        expect_style = style_name
 
        cell = ods_writer.date_cell(date, stylename=style_name)
 
    date_s = date.isoformat()
 
    assert cell.getAttribute('valuetype') == 'date'
 
    assert cell.getAttribute('datevalue') == date_s
 
    assert cell.getAttribute('stylename') == expect_style
 
    assert get_text(cell) == date_s
 

	
 
@pytest.mark.parametrize('cell_source,style_name', testutil.combine_values(
 
    NUMERIC_CELL_DATA,
 
    XML_NAMES,
 
))
 
def test_ods_writer_float_cell(ods_writer, cell_source, style_name):
 
    cell = ods_writer.float_cell(cell_source, stylename=style_name)
 
    assert cell.getAttribute('valuetype') == 'float'
 
    assert cell.getAttribute('stylename') == style_name
 
    expected = str(cell_source)
 
    assert cell.getAttribute('value') == expected
 
    assert get_text(cell) == expected
 

	
 
def test_ods_writer_meta_links_cell(ods_writer):
 
    rt_client = testutil.RTClient()
 
    ods_writer.rt_wrapper = rtutil.RT(rt_client)
 
    rt_url = rt_client.DEFAULT_URL[:-10]
 
    meta_links = [
 
        'rt://ticket/1',
 
        'rt://ticket/2/attachments/9',
 
        'rt:1/5',
 
        'Invoices/0123.pdf',
 
    ]
 
    cell = ods_writer.meta_links_cell(meta_links, stylename='meta1')
 
    assert cell.getAttribute('valuetype') == 'string'
 
    assert cell.getAttribute('stylename') == 'meta1'
 
    children = iter(get_children(cell, odf.text.A))
 
    child = next(children)
 
    assert child.getAttribute('type') == 'simple'
 
    expect_url = f'{rt_url}/Ticket/Display.html?id=1'
 
    assert child.getAttribute('href') == expect_url
 
    assert get_text(child) == 'rt:1'
0 comments (0 inline, 0 general)