Skip to content

Commit f55db52

Browse files
authored
v0.7.6 (#257)
* Closing Entry Model and workflow optimization. * Development pre-migration new laptop * v0.7.6 Refactor mixin usage for base views in `django_ledger`. Replaces multiple redundant mixins with unified base view classes (`EntityUnitModelModelBaseView` and `VendorModelModelBaseView`) to streamline inheritance and improve code maintainability. Updated version to `0.7.6` to reflect these changes. * Enhance filtering and account data handling in ledger. Added support for cleared and reconciled transaction filtering in `io_core` based on kwargs with proper validation. Updated `io_context` to include a method for retrieving account data with an optional key function. Also improved form handling for datetime inputs in journal entries. * Refactor transaction queries and add account balance utility Updated transaction filtering methods to validate input types and support AccountModel, UUID, and string formats. Added new utility methods for cleared and reconciled transaction queries. Introduced an account balance retrieval method in the entity model for better account insights. * Add extensibility hooks and method for entity instance name Introduce new template blocks for custom JS/CSS in the header and footer to enhance layout flexibility. Add a method to retrieve the authorized entity instance's name, improving clarity and usability in views. * Add alt_str method and enhance docstrings for properties Introduced the `alt_str` method to provide a concise string representation of accounts. Additionally, improved and detailed the docstrings for `coa_slug` and `entity_slug` properties, ensuring clarity and consistency in code documentation. * Refactor closing entry behavior and enhance ledger locking. Updated ledger locking/unlocking logic to ensure data consistency during posting, unposting, and deletion of closing entries. Adjusted form input attributes and enhanced `mark_as_posted` and `mark_as_unposted` methods for better handling of entity metadata. * Removed experimental swappable model functionality.
1 parent a9b7005 commit f55db52

31 files changed

+254
-171
lines changed

dev_env/settings.py

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -154,47 +154,3 @@
154154
# }
155155
# }
156156
# }
157-
158-
# DJANGO_LEDGER_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.AccountModel')
159-
# DJANGO_LEDGER_CHART_OF_ACCOUNTS_MODEL = getattr(settings, 'DJANGO_LEDGER_ACCOUNT_MODEL', 'django_ledger.ChartOfAccountModel')
160-
# DJANGO_LEDGER_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_TRANSACTION_MODEL', 'django_ledger.TransactionModel')
161-
# DJANGO_LEDGER_JOURNAL_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_JOURNAL_ENTRY_MODEL', 'django_ledger.JournalEntryModel')
162-
# DJANGO_LEDGER_LEDGER_MODEL = getattr(settings, 'DJANGO_LEDGER_LEDGER_MODEL', 'django_ledger.LedgerModel')
163-
# DJANGO_LEDGER_ENTITY_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_MODEL', 'django_ledger.EntityModel')
164-
# DJANGO_LEDGER_ENTITY_STATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_STATE_MODEL', 'django_ledger.EntityStateModel')
165-
# DJANGO_LEDGER_ENTITY_UNIT_MODEL = getattr(settings, 'DJANGO_LEDGER_ENTITY_UNIT_MODEL', 'django_ledger.EntityUnitModel')
166-
# DJANGO_LEDGER_ESTIMATE_MODEL = getattr(settings, 'DJANGO_LEDGER_ESTIMATE_MODEL', 'django_ledger.EstimateModel')
167-
# DJANGO_LEDGER_BILL_MODEL = getattr(settings, 'DJANGO_LEDGER_BILL_MODEL', 'django_ledger.BillModel')
168-
# DJANGO_LEDGER_INVOICE_MODEL = getattr(settings, 'DJANGO_LEDGER_INVOICE_MODEL', 'django_ledger.InvoiceModel')
169-
# DJANGO_LEDGER_PURCHASE_ORDER_MODEL = getattr(settings, 'DJANGO_LEDGER_PURCHASE_ORDER_MODEL', 'django_ledger.PurchaseOrderModel')
170-
# DJANGO_LEDGER_CUSTOMER_MODEL = getattr(settings, 'DJANGO_LEDGER_CUSTOMER_MODEL', 'django_ledger.CustomerModel')
171-
# DJANGO_LEDGER_VENDOR_MODEL = getattr(settings, 'DJANGO_LEDGER_VENDOR_MODEL', 'django_ledger.VendorModel')
172-
# DJANGO_LEDGER_BANK_ACCOUNT_MODEL = getattr(settings, 'DJANGO_LEDGER_BANK_ACCOUNT_MODEL', 'django_ledger.BankAccountModel')
173-
# DJANGO_LEDGER_CLOSING_ENTRY_MODEL = getattr(settings, 'DJANGO_LEDGER_CLOSING_ENTRY_MODEL', 'django_ledger.ClosingEntryModel')
174-
# DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL = getattr(settings, 'DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL', 'django_ledger.UnitOfMeasureModel')
175-
# DJANGO_LEDGER_ITEM_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_TRANSACTION_MODEL', 'django_ledger.ItemTransactionModel')
176-
# DJANGO_LEDGER_ITEM_MODEL = getattr(settings, 'DJANGO_LEDGER_ITEM_MODEL', 'django_ledger.ItemModel')
177-
# DJANGO_LEDGER_STAGED_TRANSACTION_MODEL = getattr(settings, 'DJANGO_LEDGER_STAGED_TRANSACTION_MODEL', 'django_ledger.StagedTransactionModel')
178-
# DJANGO_LEDGER_IMPORT_JOB_MODEL = getattr(settings, 'DJANGO_LEDGER_IMPORT_JOB_MODEL', 'django_ledger.ImportJobModel')
179-
180-
DJANGO_LEDGER_ACCOUNT_MODEL = 'django_ledger.AccountModel'
181-
DJANGO_LEDGER_CHART_OF_ACCOUNTS_MODEL = 'django_ledger.ChartOfAccountModel'
182-
DJANGO_LEDGER_TRANSACTION_MODEL = 'django_ledger.TransactionModel'
183-
DJANGO_LEDGER_JOURNAL_ENTRY_MODEL = 'django_ledger.JournalEntryModel'
184-
DJANGO_LEDGER_LEDGER_MODEL = 'django_ledger.LedgerModel'
185-
DJANGO_LEDGER_ENTITY_MODEL = 'django_ledger.EntityModel'
186-
DJANGO_LEDGER_ENTITY_STATE_MODEL = 'django_ledger.EntityStateModel'
187-
DJANGO_LEDGER_ENTITY_UNIT_MODEL = 'django_ledger.EntityUnitModel'
188-
DJANGO_LEDGER_ESTIMATE_MODEL = 'django_ledger.EstimateModel'
189-
DJANGO_LEDGER_BILL_MODEL = 'django_ledger.BillModel'
190-
DJANGO_LEDGER_INVOICE_MODEL = 'django_ledger.InvoiceModel'
191-
DJANGO_LEDGER_PURCHASE_ORDER_MODEL = 'django_ledger.PurchaseOrderModel'
192-
DJANGO_LEDGER_CUSTOMER_MODEL = 'django_ledger.CustomerModel'
193-
DJANGO_LEDGER_VENDOR_MODEL = 'django_ledger.VendorModel'
194-
DJANGO_LEDGER_BANK_ACCOUNT_MODEL = 'django_ledger.BankAccountModel'
195-
DJANGO_LEDGER_CLOSING_ENTRY_MODEL = 'django_ledger.ClosingEntryModel'
196-
DJANGO_LEDGER_UNIT_OF_MEASURE_MODEL = 'django_ledger.UnitOfMeasureModel'
197-
DJANGO_LEDGER_ITEM_TRANSACTION_MODEL = 'django_ledger.ItemTransactionModel'
198-
DJANGO_LEDGER_ITEM_MODEL = 'django_ledger.ItemModel'
199-
DJANGO_LEDGER_STAGED_TRANSACTION_MODEL = 'django_ledger.StagedTransactionModel'
200-
DJANGO_LEDGER_IMPORT_JOB_MODEL = 'django_ledger.ImportJobModel'

django_ledger/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
default_app_config = 'django_ledger.apps.DjangoLedgerConfig'
77

88
"""Django Ledger"""
9-
__version__ = '0.7.5.2'
9+
__version__ = '0.7.6'
1010
__license__ = 'GPLv3 License'
1111

1212
__author__ = 'Miguel Sanda'

django_ledger/forms/closing_entry.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class Meta:
2626
'closing_date': DateInput(attrs={
2727
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
2828
'placeholder': _('Closing Date (YYYY-MM-DD)...'),
29-
'id': 'djl-datepicker'
29+
'id': 'djl-datepicker',
30+
'type': 'date'
3031
})
3132
}
3233
labels = {

django_ledger/forms/journal_entry.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class Meta:
5353
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
5454
}),
5555
'timestamp': DateTimeInput(attrs={
56+
'type': 'datetime-local',
5657
'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
5758
}),
5859
'description': Textarea(attrs={

django_ledger/io/io_context.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,16 @@ def is_by_period(self) -> bool:
8989
def is_by_activity(self) -> bool:
9090
return self.IO_DATA['by_activity']
9191

92+
# Account Information
93+
def get_account_data(self, key_func=None) -> Dict:
94+
if key_func:
95+
return {
96+
key_func(acc): acc for acc in self.IO_DATA['accounts']
97+
}
98+
return {
99+
acc['account_uuid']: acc for acc in self.IO_DATA['accounts']
100+
}
101+
92102
# Balance Sheet Data...
93103
def has_balance_sheet(self) -> bool:
94104
return 'balance_sheet' in self.IO_DATA

django_ledger/io/io_core.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,28 @@ def database_digest(self,
847847
if role:
848848
txs_queryset = txs_queryset.for_roles(role_list=role)
849849

850+
# Cleared transaction filter via KWARGS....
851+
cleared_filter = kwargs.get('cleared')
852+
if cleared_filter is not None:
853+
if cleared_filter in [True, False]:
854+
txs_queryset = txs_queryset.is_cleared() if cleared_filter else txs_queryset.not_cleared()
855+
else:
856+
raise IOValidationError(
857+
message=f'Invalid value for cleared filter: {cleared_filter}. '
858+
f'Valid values are True, False'
859+
)
860+
861+
# Reconciled transaction filter via KWARGS....
862+
reconciled_filter = kwargs.get('reconciled')
863+
if reconciled_filter is not None:
864+
if reconciled_filter in [True, False]:
865+
txs_queryset = txs_queryset.is_reconciled() if reconciled_filter else txs_queryset.not_reconciled()
866+
else:
867+
raise IOValidationError(
868+
message=f'Invalid value for reconciled filter: {reconciled_filter}. '
869+
f'Valid values are True, False'
870+
)
871+
850872
if io_result.is_bounded:
851873
txs_queryset = txs_queryset.annotate(
852874
amount_io=Case(

django_ledger/models/accounts.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,15 +472,55 @@ def __str__(self):
472472
x5=self.code
473473
)
474474

475+
def alt_str(self):
476+
"""
477+
Returns a formatted string representation of the object.
478+
479+
The formatted string includes the code, name, role, and balance type
480+
of the object. The role is converted to uppercase for consistency,
481+
and the balance type is displayed as is. This method provides a
482+
concise textual representation for quick identification or display.
483+
484+
Returns:
485+
str: A formatted string in the format 'code: name (ROLE/BALANCE_TYPE)'.
486+
"""
487+
return f'{self.code}: {self.name} ({self.role.upper()}/{self.balance_type})'
488+
475489
@property
476490
def coa_slug(self):
491+
"""
492+
Property that retrieves the `coa_slug` attribute from the object. If the attribute
493+
is not found, it fetches the `slug` attribute from the `coa_model`.
494+
495+
Attributes:
496+
_coa_slug (str): Cached value of the `coa_slug` if it exists.
497+
coa_model (Any): Object containing the `slug` attribute that serves
498+
as a fallback when `_coa_slug` is not present.
499+
500+
Returns:
501+
str: The value of `_coa_slug` if defined, or the `slug` attribute from
502+
`coa_model` if `_coa_slug` is not available.
503+
"""
477504
try:
478505
return getattr(self, '_coa_slug')
479506
except AttributeError:
480507
return self.coa_model.slug
481508

482509
@property
483510
def entity_slug(self):
511+
"""
512+
Retrieve the slug value associated with the entity.
513+
514+
This property method returns the value of the private attribute
515+
'_entity_slug' for the current instance. The purpose of the
516+
slug is typically to provide a URL-friendly string representing
517+
the entity.
518+
519+
Returns
520+
-------
521+
Any
522+
The value of the '_entity_slug' attribute.
523+
"""
484524
return getattr(self, '_entity_slug')
485525

486526
@classmethod
@@ -1059,7 +1099,6 @@ class AccountModel(AccountModelAbstract):
10591099
"""
10601100

10611101
class Meta(AccountModelAbstract.Meta):
1062-
swappable = 'DJANGO_LEDGER_ACCOUNT_MODEL'
10631102
abstract = False
10641103

10651104

django_ledger/models/bank_account.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,5 +213,4 @@ class BankAccountModel(BankAccountModelAbstract):
213213
"""
214214

215215
class Meta(BankAccountModelAbstract.Meta):
216-
swappable = 'DJANGO_LEDGER_BANK_ACCOUNT_MODEL'
217216
abstract = False

django_ledger/models/bill.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,6 @@ class BillModel(BillModelAbstract):
19201920
"""
19211921

19221922
class Meta(BillModelAbstract.Meta):
1923-
swappable = 'DJANGO_LEDGER_BILL_MODEL'
19241923
abstract = False
19251924

19261925

django_ledger/models/chart_of_accounts.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,6 @@ class ChartOfAccountModel(ChartOfAccountModelAbstract):
840840
Base ChartOfAccounts Model
841841
"""
842842
class Meta(ChartOfAccountModelAbstract.Meta):
843-
swappable = 'DJANGO_LEDGER_CHART_OF_ACCOUNTS_MODEL'
844843
abstract = False
845844

846845

0 commit comments

Comments
 (0)