Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.5.6.1 - USE_TZ Setting Not Required & Bugfixes #182

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion django_ledger/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
default_app_config = 'django_ledger.apps.DjangoLedgerConfig'

"""Django Ledger"""
__version__ = '0.5.6.0'
__version__ = '0.5.6.1'
__license__ = 'GPLv3 License'

__author__ = 'Miguel Sanda'
Expand Down
11 changes: 6 additions & 5 deletions django_ledger/admin/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
from django.forms import BaseInlineFormSet
from django.urls import reverse
from django.utils.html import format_html
from django.utils.timezone import localtime

from django_ledger.admin.coa import ChartOfAccountsInLine
from django_ledger.models import EntityUnitModel, ItemTransactionModel, TransactionModel
from django_ledger.io.io_core import get_localtime
from django_ledger.models import EntityUnitModel
from django_ledger.models.entity import EntityModel, EntityManagementModel


Expand Down Expand Up @@ -167,16 +167,17 @@ def cash_flow_statement_link(self, obj: EntityModel):
cash_flow_statement_link.short_description = 'Cash Flow'

def add_code_of_accounts(self, request, queryset):
lt = get_localtime().isoformat()
for entity_model in queryset:
entity_model.create_chart_of_accounts(
coa_name=f'{entity_model.name} CoA {localtime().isoformat()}',
coa_name=f'{entity_model.name} CoA {lt}',
commit=True,
assign_as_default=False
)

def populate_random_data(self, request, queryset):
for entity_model in queryset:
start_date = localtime() - timedelta(days=180)
start_date = get_localtime() - timedelta(days=180)
entity_model.populate_random_data(
start_date=start_date,
days_forward=180,
Expand All @@ -196,4 +197,4 @@ def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)

def has_delete_permission(self, request, obj=None):
return False
return False
7 changes: 3 additions & 4 deletions django_ledger/forms/closing_entry.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
from django.forms import DateInput, ValidationError, ModelForm, Textarea
from django import forms
from django.utils.timezone import localdate
from django.utils.translation import gettext_lazy as _

from django_ledger.io.io_core import get_localdate
from django_ledger.models.closing_entry import ClosingEntryModel
from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES
from django.utils.translation import gettext_lazy as _


class ClosingEntryCreateForm(ModelForm):

def clean_closing_date(self):
closing_date = self.cleaned_data['closing_date']
if closing_date > localdate():
if closing_date > get_localdate():
raise ValidationError(
message=_('Cannot create a closing entry with a future date.'), code='invalid_date'
)
Expand Down
42 changes: 39 additions & 3 deletions django_ledger/io/io_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@
from django.db.models.functions import TruncMonth
from django.http import Http404
from django.utils.dateparse import parse_date, parse_datetime
from django.utils.timezone import make_aware, is_naive, localtime
from django.utils.timezone import make_aware, is_naive, localtime, localdate
from django.utils.translation import gettext_lazy as _

from django_ledger import settings
from django_ledger.exceptions import InvalidDateInputError, TransactionNotInBalanceError
from django_ledger.io import roles as roles_module
from django_ledger.io.io_digest import IODigestContextManager
from django_ledger.io.io_middleware import (
AccountRoleIOMiddleware, AccountGroupIOMiddleware, JEActivityIOMiddleware,
BalanceSheetIOMiddleware, IncomeStatementIOMiddleware,
CashFlowStatementIOMiddleware
)
from django_ledger.io.io_digest import IODigestContextManager
from django_ledger.io.ratios import FinancialRatioManager
from django_ledger.models.utils import lazy_loader
from django_ledger.settings import DJANGO_LEDGER_PDF_SUPPORT_ENABLED
Expand Down Expand Up @@ -111,6 +111,37 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
return True


def get_localtime(tz=None) -> datetime:
"""
Convenience function to retrieve the localtime of the current system based on the USE_TZ django setting.

Parameters
----------
tz: ZoneInfo
Optional timezone to use, otherwise the system timezone is used.

Returns
-------
datetime
"""
if global_settings.USE_TZ:
return localtime(timezone=tz)
return datetime.now(tz=tz)


def get_localdate() -> date:
"""
Convenience function to retrieve the local date of the current system based on the USE_TZ django setting.

Returns
-------
date
"""
if global_settings.USE_TZ:
return localdate()
return datetime.today()


def validate_io_date(
dt: Union[str, date, datetime],
no_parse_localdate: bool = True) -> Optional[Union[datetime, date]]:
Expand Down Expand Up @@ -140,7 +171,12 @@ def validate_io_date(
)
elif is_naive(fdt):
fdt = make_aware(fdt)
return fdt
if global_settings.USE_TZ:
return make_aware(
datetime.combine(
fdt, datetime.min.time(),
))
return datetime.combine(fdt, datetime.min.time())

if no_parse_localdate:
return localtime()
Expand Down
6 changes: 3 additions & 3 deletions django_ledger/io/io_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
from typing import Union, Optional

from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.utils.timezone import localtime, localdate
from django.utils.translation import gettext_lazy as _

from django_ledger.io.io_core import get_localtime, get_localdate
from django_ledger.io.roles import (INCOME_OPERATIONAL, ASSET_CA_INVENTORY, COGS, ASSET_CA_CASH, ASSET_CA_PREPAID,
LIABILITY_CL_DEFERRED_REVENUE, EXPENSE_OPERATIONAL, EQUITY_CAPITAL,
ASSET_CA_RECEIVABLES, LIABILITY_CL_ACC_PAYABLE)
Expand Down Expand Up @@ -94,9 +94,9 @@ def __init__(self,
self.fk.add_provider(bank)

self.start_date: datetime = start_dttm
self.local_date = localdate()
self.local_date = get_localdate()
self.tx_quantity = tx_quantity
self.localtime = localtime()
self.localtime = get_localtime()
self.COUNT_INVENTORY = True
self.DAYS_FORWARD = days_forward

Expand Down
15 changes: 12 additions & 3 deletions django_ledger/io/io_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@
"""
from collections import defaultdict
from dataclasses import dataclass
from datetime import date, datetime
from decimal import Decimal
from itertools import chain
from typing import Union, Dict, Callable, Optional
from uuid import UUID
from datetime import date, datetime

from django.core.exceptions import ValidationError
from django.db.models import Q
from django.utils.timezone import localtime
from django.utils.translation import gettext_lazy as _

from django_ledger.io.io_core import get_localtime
from django_ledger.models.accounts import AccountModel, AccountModelQuerySet, CREDIT, DEBIT
from django_ledger.models.coa import ChartOfAccountModel
from django_ledger.models.entity import EntityModel
Expand Down Expand Up @@ -196,6 +196,15 @@ def commit(self,
posted=post_new_ledgers
)
] = txs

elif isinstance(k, UUID):
try:
self.commit_plan[self.ledger_map[k]] = txs
except KeyError:
raise IOLibraryError(
message=_(f'Ledger UUID {k} not found.')
)

elif isinstance(k, LedgerModel):
self.commit_plan[k] = txs

Expand All @@ -217,7 +226,7 @@ def commit(self,

# where the magic happens...
je, txs_models = ledger_model.commit_txs(
je_timestamp=je_timestamp if je_timestamp else localtime(),
je_timestamp=je_timestamp if je_timestamp else get_localtime(),
je_txs=je_txs,
je_posted=post_journal_entries
)
Expand Down
4 changes: 2 additions & 2 deletions django_ledger/models/accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
from django.db.models import Q
from django.db.models.signals import pre_save
from django.urls import reverse
from django.utils.timezone import localdate
from django.utils.translation import gettext_lazy as _
from treebeard.mp_tree import MP_Node, MP_NodeManager, MP_NodeQuerySet

from django_ledger.io.io_core import get_localdate
from django_ledger.io.roles import (ACCOUNT_ROLE_CHOICES, BS_ROLES, GROUP_INVOICE, GROUP_BILL, validate_roles,
GROUP_ASSETS,
GROUP_LIABILITIES, GROUP_CAPITAL, GROUP_INCOME, GROUP_EXPENSES, GROUP_COGS,
Expand Down Expand Up @@ -706,7 +706,7 @@ def get_absolute_url(self):
kwargs={
'account_pk': self.uuid,
'entity_slug': self.coa_model.entity.slug,
'year': localdate().year
'year': get_localdate().year
}
)

Expand Down
24 changes: 12 additions & 12 deletions django_ledger/models/bill.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
from django.db.models.signals import pre_save
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.timezone import localdate, localtime
from django.utils.translation import gettext_lazy as _

from django_ledger.io import ASSET_CA_CASH, ASSET_CA_PREPAID, LIABILITY_CL_ACC_PAYABLE
from django_ledger.io.io_core import get_localtime, get_localdate
from django_ledger.models.entity import EntityModel
from django_ledger.models.items import ItemTransactionModelQuerySet, ItemTransactionModel, ItemModel, ItemModelQuerySet
from django_ledger.models.mixins import (CreateUpdateMixIn, AccrualMixIn, MarkdownNotesMixIn,
Expand Down Expand Up @@ -151,7 +151,7 @@ def overdue(self):
BillModelQuerySet
Returns a QuerySet of overdue bills only.
"""
return self.filter(date_due__lt=localdate())
return self.filter(date_due__lt=get_localdate())

def unpaid(self):
"""
Expand Down Expand Up @@ -470,7 +470,7 @@ def configure(self,

if date_draft and isinstance(date_draft, datetime):
date_draft = date_draft.date()
self.date_draft = localdate() if not date_draft else date_draft
self.date_draft = get_localdate() if not date_draft else date_draft

LedgerModel = lazy_loader.get_ledger_model()
ledger_model: LedgerModel = LedgerModel(entity=entity_model, posted=ledger_posted)
Expand Down Expand Up @@ -723,7 +723,7 @@ def is_past_due(self) -> bool:
True if BillModel is past due, else False.
"""
if self.date_due and self.is_approved():
return self.date_due < localdate()
return self.date_due < get_localdate()
return False

# Permissions....
Expand Down Expand Up @@ -987,7 +987,7 @@ def make_payment(self,
self.clean()

if not payment_date:
payment_date = localtime()
payment_date = get_localtime()

if commit:
self.migrate_state(
Expand Down Expand Up @@ -1059,7 +1059,7 @@ def mark_as_draft(self, date_draft: Optional[date] = None, commit: bool = False,
elif isinstance(date_draft, date):
self.date_draft = date_draft
else:
self.date_draft = localdate()
self.date_draft = get_localdate()

self.clean()
if commit:
Expand Down Expand Up @@ -1164,7 +1164,7 @@ def mark_as_review(self,
elif isinstance(date_in_review, date):
self.date_in_review = date_in_review
else:
self.date_in_review = localdate()
self.date_in_review = get_localdate()

self.clean()
if commit:
Expand Down Expand Up @@ -1265,7 +1265,7 @@ def mark_as_approved(self,
elif isinstance(date_approved, date):
self.date_approved = date_approved
else:
self.date_approved = localdate()
self.date_approved = get_localdate()

self.get_state(commit=True)
self.clean()
Expand Down Expand Up @@ -1367,12 +1367,12 @@ def mark_as_paid(self,
elif isinstance(date_paid, date):
self.date_paid = date_paid
else:
self.date_paid = localdate()
self.date_paid = get_localdate()

self.progress = Decimal.from_float(1.0)
self.amount_paid = self.amount_due

if self.date_paid > localdate():
if self.date_paid > get_localdate():
raise BillModelValidationError(f'Cannot pay {self.__class__.__name__} in the future.')
if self.date_paid < self.date_approved:
raise BillModelValidationError(
Expand Down Expand Up @@ -1486,7 +1486,7 @@ def mark_as_void(self,
elif isinstance(date_void, date):
self.date_void = date_void
else:
self.date_void = localdate()
self.date_void = get_localdate()

self.bill_status = self.BILL_STATUS_VOID
self.void_state(commit=True)
Expand Down Expand Up @@ -1568,7 +1568,7 @@ def mark_as_canceled(self, date_canceled: Optional[date] = None, commit: bool =
if not self.can_cancel():
raise BillModelValidationError(f'Bill {self.bill_number} cannot be canceled. Must be draft or in review.')

self.date_canceled = localdate() if not date_canceled else date_canceled
self.date_canceled = get_localdate() if not date_canceled else date_canceled
self.bill_status = self.BILL_STATUS_CANCELED
self.clean()
if commit:
Expand Down
7 changes: 3 additions & 4 deletions django_ledger/models/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@
from django.db.models.signals import pre_save
from django.urls import reverse
from django.utils.text import slugify
from django.utils.timezone import localtime, localdate
from django.utils.translation import gettext_lazy as _
from treebeard.mp_tree import MP_Node, MP_NodeManager, MP_NodeQuerySet

from django_ledger.io import roles as roles_module, validate_roles, IODigestContextManager
from django_ledger.io.io_core import IOMixIn
from django_ledger.io.io_core import IOMixIn, get_localtime, get_localdate
from django_ledger.models.accounts import AccountModel, AccountModelQuerySet, DEBIT, CREDIT
from django_ledger.models.bank_account import BankAccountModelQuerySet, BankAccountModel
from django_ledger.models.coa import ChartOfAccountModel, ChartOfAccountModelQuerySet
Expand Down Expand Up @@ -527,7 +526,7 @@ def create_closing_entry_for_date(self,
if closing_entry_model:
self.validate_closing_entry_model(closing_entry_model, closing_date=closing_date)

if closing_date > localdate():
if closing_date > get_localdate():
raise EntityModelValidationError(
message=_(f'Cannot create closing entry with a future date {closing_date}.')
)
Expand Down Expand Up @@ -2590,7 +2589,7 @@ def deposit_capital(self,
capital_account = account_model_qs.filter(role__exact=roles_module.EQUITY_CAPITAL).get()

if not je_timestamp:
je_timestamp = localtime()
je_timestamp = get_localtime()

if not description:
description = f'Capital Deposit on {je_timestamp.isoformat()}...'
Expand Down
Loading