Skip to content

Commit f8f4e8f

Browse files
elarrobapablokillinstreakshucontech
authored
v0.7.11 (#281)
* v.0.7.7 * Enhance account list views and update icon styles. Implemented dynamic page titles and subtitles for account pages by overriding `get_context_data`. Updated template text and classes for greater consistency, including standardizing icon colors for active, locked, and default roles. * Adding TransactionModel attributes during commit_txs. * Fixed a couple of hard coded dollar "$" symbols and changed them with `{% currency_symbol %}` tag to render the correct symbol when `DJANGO_LEDGER_CURRENCY_SYMBOL` is other than default ("$"). (#265) * Dependency update * Update contribution guidelines in README and Contribute.md Clarified the types of pull requests that are encouraged, emphasizing those that address bug fixes, enhancements, or valuable additions. Added a note discouraging submissions focused only on cosmetic changes like linting or refactoring. * Update ManyToManyField configurations and bump version to 0.7.8 Adjusted `ManyToManyField` relationships in `BillModel`, `InvoiceModel`, and `PurchaseOrderModel` to include `through` and `through_fields` for `ItemTransactionModel`. Incremented package version to `0.7.8`. * Add support for bank account type validation and retrieval based on OFX standards - Introduced `bank_account_type` field in `BankAccountModel` with predefined choices. - Added methods to retrieve routing number, account type, and account type validation in `OFXImport` class. - Enhanced account queries with a new `.cash()` method to filter accounts with `ASSET_CA_CASH` role. - Updated indexing and unique constraints for `BankAccountModel`. * Migration Update * Refactor bank account type handling and account type mapping logic - Replaced `BankAccountModel.BANK_ACCOUNT_TYPES` with explicit OFX types. - Renamed `ACCOUNT_TYPE_ROLE_MAPPING` to `ACCOUNT_TYPE_DEFAULT_ROLE_MAPPING`. - Centralized OFX type mappings in `ACCOUNT_TYPE_OFX_MAPPING`. - Removed `bank_account_type` field from `BankAccountModel`. - Added `get_account_type_from_ofx` method for retrieving account type from OFX data. * Add financial institution field and utility methods to account models - Introduced `financial_institution` field in account mixin for storing bank details. - Added `get_account_last_digits` utility for partial account number retrieval. - Implemented `can_hide` and `can_unhide` methods in `BankAccountModel`. * Refactor account handling and enhance validation methods - Renamed `get_account_type` to `get_ofx_account_type` for clarity in OFX implementation. - Added `get_account_type` method to map OFX account types to internal account types. - Introduced `get_routing_last_digits` method for masked routing number retrieval. - Improved handling of missing account and routing numbers in utility methods. * Sort node issue fix * Update chart_of_accounts.py * Bump version to 0.7.9 and update `for_entity` method to accept `EntityModel` instances. * V0.7.10 (#279) * Add customer and vendor code fields, picture upload functionality, and UI improvements - Introduced `customer_code` and `vendor_code` fields for user-defined unique codes in `CustomerModel` and `VendorModel`. - Added support for customer and vendor picture uploads with specified upload paths. - Updated migration `0023` to reflect the new fields and modifications. - Improved UI consistency in templates and added icons for enhanced usability. - Updated `pyproject.toml` to bump version to `0.7.10`. * Bump version to 0.7.10. * v0.7.11 - IO Core Bugfixes. - BillModel and InvoiceModel now have a ForeignKey to EntityModel for easier access to EntityModel. - pre_save hook has been implemented to populate field from associated ledger model. --------- Co-authored-by: Pablo Santa Cruz <[email protected]> Co-authored-by: killinstreak <[email protected]> Co-authored-by: Shucon Tech <[email protected]>
1 parent 9b4d020 commit f8f4e8f

File tree

8 files changed

+76
-19
lines changed

8 files changed

+76
-19
lines changed

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.10'
9+
__version__ = '0.7.11'
1010
__license__ = 'GPLv3 License'
1111

1212
__author__ = 'Miguel Sanda'

django_ledger/io/io_core.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -224,18 +224,29 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
224224

225225
while not is_valid:
226226
tx_type_choice = choice([DEBIT, CREDIT])
227-
txs_candidates = list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice)
227+
228+
if IS_TX_MODEL:
229+
txs_candidates = list(tx for tx in tx_data if tx.tx_type == tx_type_choice)
230+
else:
231+
txs_candidates = list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice)
232+
228233
if len(txs_candidates) > 0:
229-
tx = choice(list(tx for tx in tx_data if tx['tx_type'] == tx_type_choice))
230-
if any([diff > 0 and tx_type_choice == DEBIT,
231-
diff < 0 and tx_type_choice == CREDIT]):
234+
235+
tx = choice(txs_candidates)
236+
237+
if any([
238+
diff > 0 and tx_type_choice == DEBIT,
239+
diff < 0 and tx_type_choice == CREDIT
240+
]):
232241
if IS_TX_MODEL:
233242
tx.amount += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
234243
else:
235244
tx['amount'] += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
236245

237-
elif any([diff < 0 and tx_type_choice == DEBIT,
238-
diff > 0 and tx_type_choice == CREDIT]):
246+
elif any([
247+
diff < 0 and tx_type_choice == DEBIT,
248+
diff > 0 and tx_type_choice == CREDIT
249+
]):
239250
if IS_TX_MODEL:
240251
tx.amount -= settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
241252
else:
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Generated by Django 5.2.1 on 2025-08-26 12:40
2+
3+
import django.db.models.deletion
4+
from django.db import migrations, models
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('django_ledger', '0023_customermodel_customer_code_customermodel_picture_and_more'),
11+
]
12+
13+
operations = [
14+
migrations.AddField(
15+
model_name='billmodel',
16+
name='entity_model',
17+
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel'),
18+
),
19+
migrations.AddField(
20+
model_name='invoicemodel',
21+
name='entity_model',
22+
field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel'),
23+
),
24+
]

django_ledger/models/bill.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,13 @@ class BillModelAbstract(
353353

354354
# todo: implement Void Bill (& Invoice)....
355355
uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True)
356+
entity_model = models.ForeignKey(
357+
'django_ledger.EntityModel',
358+
on_delete=models.CASCADE,
359+
null=True,
360+
blank=True,
361+
editable=False
362+
)
356363
bill_number = models.SlugField(max_length=20, verbose_name=_('Bill Number'), editable=False)
357364
bill_status = models.CharField(max_length=10,
358365
choices=BILL_STATUS,
@@ -1927,5 +1934,8 @@ def billmodel_presave(instance: BillModel, **kwargs):
19271934
if instance.can_generate_bill_number():
19281935
instance.generate_bill_number(commit=False)
19291936

1937+
if not instance.entity_model_id:
1938+
instance.entity_model = instance.ledger.entity
1939+
19301940

19311941
pre_save.connect(receiver=billmodel_presave, sender=BillModel)

django_ledger/models/invoice.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ class InvoiceModelAbstract(
309309
"""
310310

311311
uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True)
312+
entity_model = models.ForeignKey('django_ledger.EntityModel',
313+
on_delete=models.CASCADE,
314+
null=True,
315+
blank=True,
316+
editable=False)
312317
invoice_number = models.SlugField(max_length=20,
313318
editable=False,
314319
verbose_name=_('Invoice Number'))
@@ -567,7 +572,8 @@ def get_migrate_state_desc(self):
567572
"""
568573
return f'Invoice {self.invoice_number} account adjustment.'
569574

570-
def get_migration_data(self, queryset: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
575+
def get_migration_data(self,
576+
queryset: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
571577

572578
"""
573579
Fetches necessary item transaction data to perform a migration into the LedgerModel.
@@ -600,7 +606,8 @@ def get_migration_data(self, queryset: Optional[ItemTransactionModelQuerySet] =
600606
'total_amount').annotate(
601607
account_unit_total=Sum('total_amount'))
602608

603-
def update_amount_due(self, itemtxs_qs: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
609+
def update_amount_due(self,
610+
itemtxs_qs: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
604611
"""
605612
Updates the InvoiceModel amount due.
606613
@@ -1835,5 +1842,8 @@ def invoicemodel_presave(instance: InvoiceModel, **kwargs):
18351842
if instance.can_generate_invoice_number():
18361843
instance.generate_invoice_number(commit=False)
18371844

1845+
if not instance.entity_model_id:
1846+
instance.entity_model = instance.ledger.entity
1847+
18381848

18391849
pre_save.connect(receiver=invoicemodel_presave, sender=InvoiceModel)

django_ledger/models/mixins.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ def migrate_state(self,
787787
check_tx_balance(tx_data=[tx for ui, tx in txs_list if uid == ui], perform_correction=True)
788788

789789
# validates all txs as a whole (for safety)...
790-
txs = [tx for ui, tx in txs_list]
790+
txs = [tx for _, tx in txs_list]
791791
check_tx_balance(tx_data=txs, perform_correction=True)
792792
TransactionModel.objects.bulk_create(txs)
793793

@@ -1065,14 +1065,18 @@ def net_due_group(self):
10651065
return self.TERMS_NET_90
10661066
return self.TERMS_NET_90_PLUS
10671067

1068+
def set_due_date(self, force_update: bool = False):
1069+
if self.date_due is None or force_update:
1070+
terms_start_date = self.get_terms_start_date()
1071+
if terms_start_date:
1072+
if self.terms != self.TERMS_ON_RECEIPT:
1073+
self.date_due = terms_start_date + self.get_terms_timedelta()
1074+
else:
1075+
self.date_due = terms_start_date
1076+
10681077
def clean(self):
10691078
super().clean()
1070-
terms_start_date = self.get_terms_start_date()
1071-
if terms_start_date:
1072-
if self.terms != self.TERMS_ON_RECEIPT:
1073-
self.date_due = terms_start_date + self.get_terms_timedelta()
1074-
else:
1075-
self.date_due = terms_start_date
1079+
self.set_due_date()
10761080

10771081

10781082
class MarkdownNotesMixIn(models.Model):

django_ledger/views/bill.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,8 +253,6 @@ def get_context_data(self, *, object_list=None, **kwargs):
253253
title = f'Bill {bill_model.bill_number}'
254254
context['page_title'] = title
255255
context['header_title'] = title
256-
257-
bill_model: BillModel = self.object
258256
bill_items_qs, item_data = bill_model.get_itemtxs_data()
259257
context['itemtxs_qs'] = bill_items_qs
260258
context['total_amount__sum'] = item_data['total_amount__sum']

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "django-ledger"
3-
version = "0.7.10"
3+
version = "0.7.11"
44
readme = "README.md"
55
requires-python = ">=3.10"
66
description = "Double entry accounting system built on the Django Web Framework."

0 commit comments

Comments
 (0)