Changeset - 4483d769996a
[Not reviewed]
0 2 0
Brett Smith - 4 years ago 2020-07-17 13:58:18
brettcsmith@brettcsmith.org
data: Add Account.is_open_on_date() method.
2 files changed with 62 insertions and 2 deletions:
0 comments (0 inline, 0 general)
conservancy_beancount/data.py
Show inline comments
...
 
@@ -250,6 +250,22 @@ class Account(str):
 
    def is_credit_card(self) -> bool:
 
        return self.is_under('Liabilities:CreditCard') is not None
 

	
 
    def is_open_on_date(self, date: datetime.date) -> Optional[bool]:
 
        """Return true if this account is open on the given date.
 

	
 
        This method considers the dates on the account's open and close
 
        directives. If there is no close directive, it just checks the date is
 
        on or after the opening date. If neither exists, returns None.
 
        """
 
        try:
 
            meta = self.meta
 
        except KeyError:
 
            return None
 
        close_date = meta.close_date
 
        if close_date is None:
 
            close_date = date + datetime.timedelta(days=1)
 
        return meta.open_date <= date < close_date
 

	
 
    def is_opening_equity(self) -> bool:
 
        return self.is_under('Equity:Funds', 'Equity:OpeningBalance') is not None
 

	
tests/test_data_account.py
Show inline comments
...
 
@@ -14,17 +14,17 @@
 
# You should have received a copy of the GNU Affero General Public License
 
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
 

	
 
import datetime
 
import pytest
 

	
 
from . import testutil
 

	
 
from datetime import date as Date
 

	
 
from beancount.core.data import Open, Close, Booking
 
from beancount.parser import options as bc_options
 

	
 
from conservancy_beancount import data
 

	
 
Date = datetime.date
 
clean_account_meta = pytest.fixture()(testutil.clean_account_meta)
 

	
 
@pytest.fixture
...
 
@@ -160,6 +160,50 @@ def test_is_credit_card(acct_name, expected):
 
def test_is_opening_equity(acct_name, expected):
 
    assert data.Account(acct_name).is_opening_equity() == expected
 

	
 
@pytest.mark.parametrize('date', [
 
    testutil.PAST_DATE,
 
    testutil.FY_START_DATE,
 
    testutil.FY_MID_DATE,
 
    testutil.FUTURE_DATE,
 
])
 
def test_is_open_on_date_without_opening(date):
 
    account = data.Account('Assets:Cash')
 
    assert account.is_open_on_date(date) is None
 

	
 
@pytest.mark.parametrize('days_diff', range(-2, 3))
 
def test_is_open_on_date_without_closing(clean_account_meta, days_diff):
 
    open_date = testutil.FY_START_DATE
 
    acct_name = 'Assets:Checking'
 
    data.Account.load_opening(Open({}, open_date, acct_name, None, None))
 
    account = data.Account(acct_name)
 
    check_date = open_date + datetime.timedelta(days=days_diff)
 
    assert account.is_open_on_date(check_date) == (days_diff >= 0)
 

	
 
@pytest.mark.parametrize('close_diff,check_diff', [
 
    (30, -30),
 
    (30, -1),
 
    (30, 0),
 
    (30, 1),
 
    (30, 29),
 
    (30, 30),
 
    (30, 60),
 
    (60, 30),
 
    (60, 59),
 
    (60, 60),
 
    (60, 90),
 
    (60, -60),
 
])
 
def test_is_open_on_date_with_closing(clean_account_meta, close_diff, check_diff):
 
    open_date = testutil.FY_START_DATE
 
    acct_name = 'Assets:Savings'
 
    data.Account.load_opening(Open({}, open_date, acct_name, None, None))
 
    close_date = open_date + datetime.timedelta(days=close_diff)
 
    data.Account.load_closing(Close({}, close_date, acct_name))
 
    account = data.Account(acct_name)
 
    check_date = open_date + datetime.timedelta(days=check_diff)
 
    expected = (0 <= check_diff < close_diff)
 
    assert account.is_open_on_date(check_date) == expected
 

	
 
@pytest.mark.parametrize('acct_name', [
 
    'Assets:Cash',
 
    'Assets:Prepaid:Expenses',
0 comments (0 inline, 0 general)