From 7abca243de6f0723e3e146402bb330b2c4c75811 Mon Sep 17 00:00:00 2001 From: Eugen Ciur Date: Wed, 27 Nov 2024 08:19:44 +0100 Subject: [PATCH] ip --- papermerge/core/features/document/db/api.py | 4 ++- .../core/features/document/db/selectors.py | 1 + .../features/document/tests/test_selectors.py | 25 ++++++++++++++++++ papermerge/core/tests/test_misc_utils.py | 26 +++++++++++++++++++ papermerge/core/utils/misc.py | 23 ++++++++++++++-- .../components/customFields/YearMonth.tsx | 2 ++ 6 files changed, 78 insertions(+), 3 deletions(-) diff --git a/papermerge/core/features/document/db/api.py b/papermerge/core/features/document/db/api.py index 8b46a902e..f214e7780 100644 --- a/papermerge/core/features/document/db/api.py +++ b/papermerge/core/features/document/db/api.py @@ -22,7 +22,7 @@ from papermerge.core.features.document_types.db.api import document_type_cf_count from papermerge.core.types import OrderEnum, CFVValueColumn from papermerge.core.db.common import get_ancestors -from papermerge.core.utils.misc import str2date, str2float +from papermerge.core.utils.misc import str2date, str2float, float2str from papermerge.core.pathlib import ( abs_docver_path, ) @@ -64,6 +64,8 @@ def get_doc_cfv(session: Session, document_id: uuid.UUID) -> list[schema.CFV]: for row in session.execute(stmt): if row.cf_type == "date": value = str2date(row.cf_value) + elif row.cf_type == "yearmonth": + value = float2str(row.cf_value) else: value = row.cf_value diff --git a/papermerge/core/features/document/db/selectors.py b/papermerge/core/features/document/db/selectors.py index a56837c63..169e18956 100644 --- a/papermerge/core/features/document/db/selectors.py +++ b/papermerge/core/features/document/db/selectors.py @@ -75,6 +75,7 @@ def select_doc_cfv(document_id: uuid.UUID) -> Select: (cf.c.type == 'text', func.cast(cfv.value_text, VARCHAR)), (cf.c.type == 'date', func.substr(func.cast(cfv.value_date, VARCHAR), 0, DATE_LEN)), (cf.c.type == 'boolean', func.cast(cfv.value_boolean, VARCHAR)), + (cf.c.type == 'yearmonth', func.cast(cfv.value_yearmonth, VARCHAR)), ).label("cf_value") ).select_from(doc).join( assoc, diff --git a/papermerge/core/features/document/tests/test_selectors.py b/papermerge/core/features/document/tests/test_selectors.py index 5c3ec4bf6..f6f97a6ae 100644 --- a/papermerge/core/features/document/tests/test_selectors.py +++ b/papermerge/core/features/document/tests/test_selectors.py @@ -107,6 +107,31 @@ def test_select_doc_cfv_with_date_non_empty( } == set(cf_names) +@pytest.mark.parametrize( + "salary_month_input", + ["2024-10-28", "2024-10-28 00:00:00", "2024-10-28 00", "2024-10-28 anything here"], +) +def test_select_doc_cfv_with_yearmonth_non_empty( + salary_month_input, make_document_salary, user, db_session +): + doc = make_document_salary(title="salary.pdf", user=user) + + selector = selectors.select_doc_cfv(document_id=doc.id) + cf = {"Month": salary_month_input} + + dbapi.update_doc_cfv(db_session, document_id=doc.id, custom_fields=cf) + + rows = db_session.execute(selector) + cf_names = list((row.cf_name, row.cf_value) for row in rows) + + assert len(cf_names) == 3 + assert { + ("Company", None), + ("Month", "2024-10"), + ("Total", None), + } == set(cf_names) + + def test_select_doc_type_cfv(make_document_receipt, user, db_session): doc1: orm.Document = make_document_receipt(title="receipt1.pdf", user=user) doc2 = make_document_receipt(title="receipt2.pdf", user=user) diff --git a/papermerge/core/tests/test_misc_utils.py b/papermerge/core/tests/test_misc_utils.py index 17387f390..fca542734 100644 --- a/papermerge/core/tests/test_misc_utils.py +++ b/papermerge/core/tests/test_misc_utils.py @@ -13,3 +13,29 @@ def test_str2float(): assert misc.str2float("2024-03-25") == 2024.03 assert misc.str2float("2024-03-22") == 2024.03 assert misc.str2float("2024-03-01") == 2024.03 + + +def test_float2str_with_float_as_input(): + assert misc.float2str(2024.01) == "2024-01" + assert misc.float2str(2024.03) == "2024-03" + assert misc.float2str(2024.09) == "2024-09" + assert misc.float2str(2024.1) == "2024-10" + assert misc.float2str(2024.10) == "2024-10" + assert misc.float2str(2024.11) == "2024-11" + assert misc.float2str(2024.12) == "2024-12" + + assert misc.float2str(2018.12) == "2018-12" + assert misc.float2str(1983.06) == "1983-06" + + +def test_float2str_with_str_as_input(): + assert misc.float2str("2024.01") == "2024-01" + assert misc.float2str("2024.03") == "2024-03" + assert misc.float2str("2024.09") == "2024-09" + assert misc.float2str("2024.1") == "2024-10" + assert misc.float2str("2024.10") == "2024-10" + assert misc.float2str("2024.11") == "2024-11" + assert misc.float2str("2024.12") == "2024-12" + + assert misc.float2str("2018.12") == "2018-12" + assert misc.float2str("1983.06") == "1983-06" diff --git a/papermerge/core/utils/misc.py b/papermerge/core/utils/misc.py index fe570a782..82c1d3e13 100644 --- a/papermerge/core/utils/misc.py +++ b/papermerge/core/utils/misc.py @@ -1,13 +1,13 @@ -import decimal import io import logging +import math import os import shutil from pathlib import Path from datetime import datetime from typing import Optional from uuid import UUID -from decimal import Decimal + from papermerge.core import constants from papermerge.core.exceptions import InvalidDateFormat @@ -92,6 +92,25 @@ def str2float(value: str | None) -> Optional[float]: return year + month / 100 +def float2str(value: float | str | None) -> Optional[str]: + """ + 2024.01 -> "2024-01" + 2018.09 -> "2018-09" + """ + if value is None: + return None + + value = float(value) + year = int(value) + fraction = value - year + if fraction in (0.1, 0.11, 0.12): + month = math.ceil(fraction * 10) + else: + month = math.ceil(fraction * 100) + + return f"{year}-{month:02d}" + + def copy_file(src: Path | io.BytesIO | bytes, dst: Path): """Copy source file to destination""" logger.debug(f"copying {src} to {dst}") diff --git a/ui2/src/features/document/components/customFields/YearMonth.tsx b/ui2/src/features/document/components/customFields/YearMonth.tsx index 54a8bc44a..0f5153363 100644 --- a/ui2/src/features/document/components/customFields/YearMonth.tsx +++ b/ui2/src/features/document/components/customFields/YearMonth.tsx @@ -29,6 +29,8 @@ export default function CustomFieldYearMonth({ } }, [customField.value]) + console.log(`customField.value=${customField.value}`) + const onLocalChange = (value: DateValue) => { if (value) { const d = dayjs(value)