django-ledger 0.7.9__py3-none-any.whl → 0.7.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-ledger might be problematic. Click here for more details.

django_ledger/__init__.py CHANGED
@@ -6,7 +6,7 @@ Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
6
6
  default_app_config = 'django_ledger.apps.DjangoLedgerConfig'
7
7
 
8
8
  """Django Ledger"""
9
- __version__ = '0.7.9'
9
+ __version__ = '0.7.11'
10
10
  __license__ = 'GPLv3 License'
11
11
 
12
12
  __author__ = 'Miguel Sanda'
@@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _
13
13
  from treebeard.forms import MoveNodeForm
14
14
 
15
15
  from django_ledger.io import ACCOUNT_CHOICES_NO_ROOT
16
- from django_ledger.models import ChartOfAccountModel, EntityModel
16
+ from django_ledger.models import ChartOfAccountModel
17
17
  from django_ledger.models.accounts import AccountModel
18
18
  from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES
19
19
 
@@ -24,8 +24,6 @@ class AccountModelCreateForm(ModelForm):
24
24
 
25
25
  Attributes
26
26
  ----------
27
- ENTITY_MODEL : Model
28
- The entity model being used in the form.
29
27
  COA_MODEL : Model
30
28
  The Chart of Account Model being used in the form.
31
29
  """
@@ -23,6 +23,7 @@ class CustomerModelForm(ModelForm):
23
23
  model = CustomerModel
24
24
  fields = [
25
25
  'customer_name',
26
+ 'customer_code',
26
27
  'address_1',
27
28
  'address_2',
28
29
  'city',
@@ -43,6 +44,10 @@ class CustomerModelForm(ModelForm):
43
44
  'customer_name': TextInput(attrs={
44
45
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
45
46
  }),
47
+ 'customer_code': TextInput(attrs={
48
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
49
+ 'placeholder': 'Ex: CDR-78987-2025...'
50
+ }),
46
51
  'address_1': TextInput(attrs={
47
52
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
48
53
  }),
@@ -22,6 +22,7 @@ class VendorModelForm(ModelForm):
22
22
  model = VendorModel
23
23
  fields = [
24
24
  'vendor_name',
25
+ 'vendor_code',
25
26
  'address_1',
26
27
  'address_2',
27
28
  'city',
@@ -39,6 +40,10 @@ class VendorModelForm(ModelForm):
39
40
  'vendor_name': TextInput(attrs={
40
41
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
41
42
  }),
43
+ 'vendor_code': TextInput(attrs={
44
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
45
+ 'placeholder': 'Ex: GRB-67987-2025...'
46
+ }),
42
47
  'address_1': TextInput(attrs={
43
48
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
44
49
  }),
@@ -224,18 +224,29 @@ def check_tx_balance(tx_data: list, perform_correction: bool = False) -> bool:
224
224
 
225
225
  while not is_valid:
226
226
  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
+
228
233
  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
+ ]):
232
241
  if IS_TX_MODEL:
233
242
  tx.amount += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
234
243
  else:
235
244
  tx['amount'] += settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
236
245
 
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
+ ]):
239
250
  if IS_TX_MODEL:
240
251
  tx.amount -= settings.DJANGO_LEDGER_TRANSACTION_CORRECTION
241
252
  else:
@@ -0,0 +1,51 @@
1
+ # Generated by Django 5.2.1 on 2025-08-22 19:05
2
+
3
+ import django.db.models.deletion
4
+ import django_ledger.models.customer
5
+ import django_ledger.models.vendor
6
+ from django.db import migrations, models
7
+
8
+
9
+ class Migration(migrations.Migration):
10
+
11
+ dependencies = [
12
+ ('django_ledger', '0022_bankaccountmodel_financial_institution_and_more'),
13
+ ]
14
+
15
+ operations = [
16
+ migrations.AddField(
17
+ model_name='customermodel',
18
+ name='customer_code',
19
+ field=models.SlugField(blank=True, null=True, unique=True, verbose_name='User defined customer code'),
20
+ ),
21
+ migrations.AddField(
22
+ model_name='customermodel',
23
+ name='picture',
24
+ field=models.ImageField(blank=True, null=True, upload_to=django_ledger.models.customer.customer_picture_upload_to),
25
+ ),
26
+ migrations.AddField(
27
+ model_name='vendormodel',
28
+ name='picture',
29
+ field=models.ImageField(blank=True, null=True, upload_to=django_ledger.models.vendor.vendor_picture_upload_to),
30
+ ),
31
+ migrations.AddField(
32
+ model_name='vendormodel',
33
+ name='vendor_code',
34
+ field=models.SlugField(blank=True, null=True, verbose_name='User defined vendor code.'),
35
+ ),
36
+ migrations.AlterField(
37
+ model_name='customermodel',
38
+ name='customer_number',
39
+ field=models.CharField(editable=False, help_text='System generated customer number.', max_length=30, verbose_name='Customer Number'),
40
+ ),
41
+ migrations.AlterField(
42
+ model_name='vendormodel',
43
+ name='entity_model',
44
+ field=models.ForeignKey(editable=False, on_delete=django.db.models.deletion.CASCADE, to='django_ledger.entitymodel', verbose_name='Vendor Entity'),
45
+ ),
46
+ migrations.AlterField(
47
+ model_name='vendormodel',
48
+ name='vendor_number',
49
+ field=models.CharField(blank=True, editable=False, help_text='System generated vendor number.', max_length=30, null=True, verbose_name='Vendor Number'),
50
+ ),
51
+ ]
@@ -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
+ ]
@@ -353,6 +353,13 @@ class BillModelAbstract(
353
353
 
354
354
  # todo: implement Void Bill (& Invoice)....
355
355
  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
+ )
356
363
  bill_number = models.SlugField(max_length=20, verbose_name=_('Bill Number'), editable=False)
357
364
  bill_status = models.CharField(max_length=10,
358
365
  choices=BILL_STATUS,
@@ -1927,5 +1934,8 @@ def billmodel_presave(instance: BillModel, **kwargs):
1927
1934
  if instance.can_generate_bill_number():
1928
1935
  instance.generate_bill_number(commit=False)
1929
1936
 
1937
+ if not instance.entity_model_id:
1938
+ instance.entity_model = instance.ledger.entity
1939
+
1930
1940
 
1931
1941
  pre_save.connect(receiver=billmodel_presave, sender=BillModel)
@@ -6,11 +6,13 @@ A Customer refers to the person or entity that buys product and services. When i
6
6
  created before it can be assigned to the InvoiceModel. Only customers who are active can be assigned to new Invoices.
7
7
  """
8
8
 
9
+ import os
9
10
  from uuid import uuid4
10
11
 
11
12
  from django.core.exceptions import ObjectDoesNotExist
12
13
  from django.db import models, transaction, IntegrityError
13
14
  from django.db.models import Q, F, QuerySet, Manager
15
+ from django.utils.text import slugify
14
16
  from django.utils.translation import gettext_lazy as _
15
17
 
16
18
  from django_ledger.models.mixins import ContactInfoMixIn, CreateUpdateMixIn, TaxCollectionMixIn
@@ -18,6 +20,18 @@ from django_ledger.models.utils import lazy_loader
18
20
  from django_ledger.settings import DJANGO_LEDGER_DOCUMENT_NUMBER_PADDING, DJANGO_LEDGER_CUSTOMER_NUMBER_PREFIX
19
21
 
20
22
 
23
+ def customer_picture_upload_to(instance, filename):
24
+ """
25
+ Stores pictures under: customer_pictures/<customer_number>/<sanitized-filename>.<ext>
26
+ """
27
+ if not instance.customer_number:
28
+ instance.generate_customer_number(commit=False)
29
+ customer_number = instance.customer_number
30
+ name, ext = os.path.splitext(filename)
31
+ safe_name = slugify(name)
32
+ return f'customer_pictures/{customer_number}/{safe_name}{ext.lower()}'
33
+
34
+
21
35
  class CustomerModelQueryset(QuerySet):
22
36
  """
23
37
  A custom defined QuerySet for the CustomerModel. This implements multiple methods or queries needed to get a
@@ -170,8 +184,16 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
170
184
  """
171
185
 
172
186
  uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True)
187
+ customer_code = models.SlugField(
188
+ max_length=50,
189
+ unique=True,
190
+ null=True,
191
+ blank=True,
192
+ verbose_name='User defined customer code'
193
+ )
173
194
  customer_name = models.CharField(max_length=100)
174
- customer_number = models.CharField(max_length=30, editable=False, verbose_name=_('Customer Number'))
195
+ customer_number = models.CharField(max_length=30, editable=False, verbose_name=_('Customer Number'),
196
+ help_text='System generated customer number.')
175
197
  entity_model = models.ForeignKey('django_ledger.EntityModel',
176
198
  editable=False,
177
199
  on_delete=models.CASCADE,
@@ -179,6 +201,7 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
179
201
  description = models.TextField()
180
202
  active = models.BooleanField(default=True)
181
203
  hidden = models.BooleanField(default=False)
204
+ picture = models.ImageField(upload_to=customer_picture_upload_to, null=True, blank=True)
182
205
 
183
206
  additional_info = models.JSONField(null=True, blank=True, default=dict)
184
207
 
@@ -309,6 +309,11 @@ class InvoiceModelAbstract(
309
309
  """
310
310
 
311
311
  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)
312
317
  invoice_number = models.SlugField(max_length=20,
313
318
  editable=False,
314
319
  verbose_name=_('Invoice Number'))
@@ -567,7 +572,8 @@ class InvoiceModelAbstract(
567
572
  """
568
573
  return f'Invoice {self.invoice_number} account adjustment.'
569
574
 
570
- def get_migration_data(self, queryset: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
575
+ def get_migration_data(self,
576
+ queryset: Optional[ItemTransactionModelQuerySet] = None) -> ItemTransactionModelQuerySet:
571
577
 
572
578
  """
573
579
  Fetches necessary item transaction data to perform a migration into the LedgerModel.
@@ -600,7 +606,8 @@ class InvoiceModelAbstract(
600
606
  'total_amount').annotate(
601
607
  account_unit_total=Sum('total_amount'))
602
608
 
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:
604
611
  """
605
612
  Updates the InvoiceModel amount due.
606
613
 
@@ -1835,5 +1842,8 @@ def invoicemodel_presave(instance: InvoiceModel, **kwargs):
1835
1842
  if instance.can_generate_invoice_number():
1836
1843
  instance.generate_invoice_number(commit=False)
1837
1844
 
1845
+ if not instance.entity_model_id:
1846
+ instance.entity_model = instance.ledger.entity
1847
+
1838
1848
 
1839
1849
  pre_save.connect(receiver=invoicemodel_presave, sender=InvoiceModel)
@@ -787,7 +787,7 @@ class AccrualMixIn(models.Model):
787
787
  check_tx_balance(tx_data=[tx for ui, tx in txs_list if uid == ui], perform_correction=True)
788
788
 
789
789
  # 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]
791
791
  check_tx_balance(tx_data=txs, perform_correction=True)
792
792
  TransactionModel.objects.bulk_create(txs)
793
793
 
@@ -1065,14 +1065,18 @@ class PaymentTermsMixIn(models.Model):
1065
1065
  return self.TERMS_NET_90
1066
1066
  return self.TERMS_NET_90_PLUS
1067
1067
 
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
+
1068
1077
  def clean(self):
1069
1078
  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()
1076
1080
 
1077
1081
 
1078
1082
  class MarkdownNotesMixIn(models.Model):
@@ -10,12 +10,13 @@ Vendors can be flagged as active/inactive or hidden. Vendors who no longer condu
10
10
  whether temporarily or indefinitely may be flagged as inactive (i.e. active is False). Hidden Vendors will not show up
11
11
  as an option in the UI, but can still be used programmatically (via API).
12
12
  """
13
-
13
+ import os
14
14
  from uuid import uuid4
15
15
 
16
16
  from django.core.exceptions import ObjectDoesNotExist, ValidationError
17
17
  from django.db import models, transaction, IntegrityError
18
- from django.db.models import Q, F, QuerySet
18
+ from django.db.models import Q, F, QuerySet, Manager
19
+ from django.utils.text import slugify
19
20
  from django.utils.translation import gettext_lazy as _
20
21
 
21
22
  from django_ledger.models.mixins import ContactInfoMixIn, CreateUpdateMixIn, FinancialAccountInfoMixin, TaxInfoMixIn
@@ -23,6 +24,15 @@ from django_ledger.models.utils import lazy_loader
23
24
  from django_ledger.settings import DJANGO_LEDGER_DOCUMENT_NUMBER_PADDING, DJANGO_LEDGER_VENDOR_NUMBER_PREFIX
24
25
 
25
26
 
27
+ def vendor_picture_upload_to(instance, filename):
28
+ if not instance.customer_number:
29
+ instance.generate_customer_number(commit=False)
30
+ vendor_number = instance.customer_number
31
+ name, ext = os.path.splitext(filename)
32
+ safe_name = slugify(name)
33
+ return f'vendor_pictures/{vendor_number}/{safe_name}{ext.lower()}'
34
+
35
+
26
36
  class VendorModelValidationError(ValidationError):
27
37
  pass
28
38
 
@@ -83,7 +93,7 @@ class VendorModelQuerySet(QuerySet):
83
93
  )
84
94
 
85
95
 
86
- class VendorModelManager(models.Manager):
96
+ class VendorModelManager(Manager):
87
97
  """
88
98
  Custom defined VendorModel Manager, which defines many methods for initial query of the Database.
89
99
  """
@@ -173,15 +183,27 @@ class VendorModelAbstract(ContactInfoMixIn,
173
183
 
174
184
  """
175
185
  uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True)
176
- vendor_number = models.CharField(max_length=30, null=True, blank=True)
186
+ vendor_code = models.SlugField(
187
+ max_length=50,
188
+ null=True,
189
+ blank=True,
190
+ verbose_name='User defined vendor code.'
191
+ )
192
+ vendor_number = models.CharField(max_length=30,
193
+ null=True,
194
+ blank=True,
195
+ editable=False,
196
+ verbose_name=_('Vendor Number'), help_text='System generated vendor number.')
177
197
  vendor_name = models.CharField(max_length=100)
178
198
 
179
199
  entity_model = models.ForeignKey('django_ledger.EntityModel',
180
200
  on_delete=models.CASCADE,
181
- verbose_name=_('Vendor Entity'))
201
+ verbose_name=_('Vendor Entity'),
202
+ editable=False)
182
203
  description = models.TextField()
183
204
  active = models.BooleanField(default=True)
184
205
  hidden = models.BooleanField(default=False)
206
+ picture = models.ImageField(upload_to=vendor_picture_upload_to, null=True, blank=True)
185
207
 
186
208
  additional_info = models.JSONField(null=True, blank=True, default=dict)
187
209
 
@@ -215,7 +237,7 @@ class VendorModelAbstract(ContactInfoMixIn,
215
237
  Returns
216
238
  -------
217
239
  bool
218
- True if vendor number can be generated, else False.
240
+ True if the vendor number can be generated, else False.
219
241
  """
220
242
  return all([
221
243
  self.entity_model_id,
@@ -8,6 +8,7 @@
8
8
  <th class="has-text-centered">{% trans 'Customer Number' %}</th>
9
9
  <th class="has-text-centered">{% trans 'Customer' %}</th>
10
10
  <th class="has-text-centered">{% trans 'Address' %}</th>
11
+ <th class="has-text-centered">{% trans 'Customer Code' %}</th>
11
12
  <th class="has-text-centered">{% trans 'Active' %}</th>
12
13
  <th class="has-text-centered">{% trans 'Hidden' %}</th>
13
14
  <th class="has-text-centered">{% trans 'Actions' %}</th>
@@ -19,6 +20,7 @@
19
20
  <td>{{ customer.customer_number }}</td>
20
21
  <td>{{ customer.customer_name }}</td>
21
22
  <td>{{ customer.address_1 }}</td>
23
+ <td>{% if customer.customer_code %}{{ customer.customer_code }}{% endif %}</td>
22
24
  <td>
23
25
  {% if customer.active %}
24
26
  <span class="icon has-text-success-dark">
@@ -47,8 +47,8 @@
47
47
  <section class="hero is-light is-bold is-small">
48
48
  <div class="hero-body">
49
49
  <div class="container">
50
- <h1 class="title">{% trans 'Receivables' %}</h1>
51
- <h2 class="subtitle">
50
+ <h1 class="is-size-2 is-bold">{% trans 'Receivables' %}</h1>
51
+ <h2 class="is-size-5 has-text-weight-light">
52
52
  <span class="icon">{% icon "ic:baseline-business" 16 %}</span>{{ entity.name }}</h2>
53
53
  </div>
54
54
  </div>
@@ -80,8 +80,8 @@
80
80
  <section class="hero is-light is-bold is-small">
81
81
  <div class="hero-body">
82
82
  <div class="container">
83
- <h1 class="title">{% trans 'Payables' %}</h1>
84
- <h2 class="subtitle">
83
+ <h1 class="is-size-2 is-bold">{% trans 'Payables' %}</h1>
84
+ <h2 class="is-size-5 has-text-weight-light">
85
85
  <span class="icon">{% icon "ic:baseline-business" 16 %}</span>{{ entity.name }}</h2>
86
86
  </div>
87
87
  </div>
@@ -19,9 +19,9 @@
19
19
  </div>
20
20
  {% endif %}
21
21
  <div class="column is-9">
22
- <h1 class="title has-text-weight-light">{{ header_title }}</h1>
22
+ <h1 class="is-size-2 is-bold">{{ header_title }}</h1>
23
23
  {% if header_subtitle %}
24
- <h2 class="subtitle">{{ header_subtitle }}</h2>
24
+ <h2 class="is-size-5 has-text-weight-light">{{ header_subtitle }}</h2>
25
25
  {% endif %}
26
26
  </div>
27
27
  </div>
@@ -9,6 +9,7 @@
9
9
  <th class="has-text-centered">{% trans 'Vendor Number' %}</th>
10
10
  <th class="has-text-centered">{% trans 'Vendor' %}</th>
11
11
  <th class="has-text-centered">{% trans 'Address' %}</th>
12
+ <th class="has-text-centered">{% trans 'Code' %}</th>
12
13
  <th class="has-text-centered">{% trans 'Active' %}</th>
13
14
  <th class="has-text-centered">{% trans 'Hidden' %}</th>
14
15
  <th class="has-text-centered">{% trans 'Actions' %}</th>
@@ -20,6 +21,7 @@
20
21
  <td>{{ vendor.vendor_number }}</td>
21
22
  <td>{{ vendor.vendor_name }}</td>
22
23
  <td>{{ vendor.address_1 }}</td>
24
+ <td>{% if vendor.vendor_code %}{{ vendor.vendor_code }}{% endif %}</td>
23
25
  <td>
24
26
  {% if vendor.active %}
25
27
  <span class="icon has-text-success-dark">
@@ -31,6 +33,7 @@
31
33
  </span>
32
34
  {% endif %}
33
35
  </td>
36
+
34
37
  <td>
35
38
  {% if vendor.hidden %}
36
39
  <span class="icon has-text-success-dark">
@@ -23,8 +23,10 @@ from django_ledger.io import ROLES_ORDER_ALL
23
23
  from django_ledger.io.io_core import validate_activity, get_localdate
24
24
  from django_ledger.models import BillModel, InvoiceModel, JournalEntryModel
25
25
  from django_ledger.settings import (
26
- DJANGO_LEDGER_FINANCIAL_ANALYSIS, DJANGO_LEDGER_CURRENCY_SYMBOL,
27
- DJANGO_LEDGER_SPACED_CURRENCY_SYMBOL)
26
+ DJANGO_LEDGER_FINANCIAL_ANALYSIS,
27
+ DJANGO_LEDGER_CURRENCY_SYMBOL,
28
+ DJANGO_LEDGER_SPACED_CURRENCY_SYMBOL
29
+ )
28
30
  from django_ledger.utils import get_default_entity_session_key, get_end_date_from_session
29
31
 
30
32
  register = template.Library()
@@ -613,7 +615,8 @@ def navigation_menu(context, style):
613
615
  {
614
616
  'type': 'link',
615
617
  'title': 'Entity Dashboard',
616
- 'url': reverse('django_ledger:entity-dashboard', kwargs={'entity_slug': ENTITY_SLUG})
618
+ 'url': reverse('django_ledger:entity-dashboard', kwargs={'entity_slug': ENTITY_SLUG}),
619
+ 'icon': 'mdi:view-dashboard'
617
620
  },
618
621
  {
619
622
  'type': 'links',
@@ -622,49 +625,57 @@ def navigation_menu(context, style):
622
625
  {
623
626
  'type': 'link',
624
627
  'title': 'Vendors',
625
- 'url': reverse('django_ledger:vendor-list', kwargs={'entity_slug': ENTITY_SLUG})
628
+ 'url': reverse('django_ledger:vendor-list', kwargs={'entity_slug': ENTITY_SLUG}),
629
+ 'icon': 'mdi:truck'
626
630
  },
627
631
  {
628
632
  'type': 'link',
629
633
  'title': 'Customers',
630
- 'url': reverse('django_ledger:customer-list', kwargs={'entity_slug': ENTITY_SLUG})
634
+ 'url': reverse('django_ledger:customer-list', kwargs={'entity_slug': ENTITY_SLUG}),
635
+ 'icon': 'mdi:account-group'
631
636
  },
632
637
  {
633
638
  'type': 'link',
634
639
  'title': 'Bank Accounts',
635
- 'url': reverse('django_ledger:bank-account-list', kwargs={'entity_slug': ENTITY_SLUG})
640
+ 'url': reverse('django_ledger:bank-account-list', kwargs={'entity_slug': ENTITY_SLUG}),
641
+ 'icon': 'mdi:bank'
636
642
  },
637
643
  {
638
644
  'type': 'link',
639
645
  'title': 'Estimates & Contracts',
640
- 'url': reverse('django_ledger:customer-estimate-list', kwargs={'entity_slug': ENTITY_SLUG})
646
+ 'url': reverse('django_ledger:customer-estimate-list', kwargs={'entity_slug': ENTITY_SLUG}),
647
+ 'icon': 'mdi:clipboard-text'
641
648
  },
642
649
  {
643
650
  'type': 'link',
644
651
  'title': 'Bills',
645
- 'url': reverse('django_ledger:bill-list', kwargs={'entity_slug': ENTITY_SLUG})
652
+ 'url': reverse('django_ledger:bill-list', kwargs={'entity_slug': ENTITY_SLUG}),
653
+ 'icon': 'uil:bill'
646
654
  },
647
655
  {
648
656
  'type': 'link',
649
657
  'title': 'Invoices',
650
- 'url': reverse('django_ledger:invoice-list', kwargs={'entity_slug': ENTITY_SLUG})
658
+ 'url': reverse('django_ledger:invoice-list', kwargs={'entity_slug': ENTITY_SLUG}),
659
+ 'icon': 'mdi:file-document'
651
660
  },
652
661
  {
653
662
  'type': 'link',
654
663
  'title': 'Purchase Orders',
655
- 'url': reverse('django_ledger:po-list', kwargs={'entity_slug': ENTITY_SLUG})
664
+ 'url': reverse('django_ledger:po-list', kwargs={'entity_slug': ENTITY_SLUG}),
665
+ 'icon': 'mdi:cart'
656
666
  },
657
667
  {
658
668
  'type': 'link',
659
669
  'title': 'Inventory',
660
- 'url': reverse('django_ledger:inventory-list', kwargs={'entity_slug': ENTITY_SLUG})
670
+ 'url': reverse('django_ledger:inventory-list', kwargs={'entity_slug': ENTITY_SLUG}),
671
+ 'icon': 'mdi:warehouse'
661
672
  },
662
673
  {
663
674
  'type': 'link',
664
675
  'title': 'Closing Entries',
665
- 'url': reverse('django_ledger:closing-entry-list', kwargs={'entity_slug': ENTITY_SLUG})
676
+ 'url': reverse('django_ledger:closing-entry-list', kwargs={'entity_slug': ENTITY_SLUG}),
677
+ 'icon': 'mdi:book-lock'
666
678
  }
667
-
668
679
  ]
669
680
  },
670
681
  {
@@ -674,32 +685,38 @@ def navigation_menu(context, style):
674
685
  {
675
686
  'type': 'link',
676
687
  'title': 'Entity Units',
677
- 'url': reverse('django_ledger:unit-list', kwargs={'entity_slug': ENTITY_SLUG})
688
+ 'url': reverse('django_ledger:unit-list', kwargs={'entity_slug': ENTITY_SLUG}),
689
+ 'icon': 'mdi:domain'
678
690
  },
679
691
  {
680
692
  'type': 'link',
681
693
  'title': 'Products',
682
- 'url': reverse('django_ledger:product-list', kwargs={'entity_slug': ENTITY_SLUG})
694
+ 'url': reverse('django_ledger:product-list', kwargs={'entity_slug': ENTITY_SLUG}),
695
+ 'icon': 'mdi:package-variant'
683
696
  },
684
697
  {
685
698
  'type': 'link',
686
699
  'title': 'Services',
687
- 'url': reverse('django_ledger:service-list', kwargs={'entity_slug': ENTITY_SLUG})
700
+ 'url': reverse('django_ledger:service-list', kwargs={'entity_slug': ENTITY_SLUG}),
701
+ 'icon': 'mdi:briefcase'
688
702
  },
689
703
  {
690
704
  'type': 'link',
691
705
  'title': 'Business Expenses',
692
- 'url': reverse('django_ledger:expense-list', kwargs={'entity_slug': ENTITY_SLUG})
706
+ 'url': reverse('django_ledger:expense-list', kwargs={'entity_slug': ENTITY_SLUG}),
707
+ 'icon': 'mdi:cash-minus'
693
708
  },
694
709
  {
695
710
  'type': 'link',
696
711
  'title': 'Inventory Items',
697
- 'url': reverse('django_ledger:inventory-item-list', kwargs={'entity_slug': ENTITY_SLUG})
712
+ 'url': reverse('django_ledger:inventory-item-list', kwargs={'entity_slug': ENTITY_SLUG}),
713
+ 'icon': 'mdi:barcode'
698
714
  },
699
715
  {
700
716
  'type': 'link',
701
717
  'title': 'Unit of Measures',
702
- 'url': reverse('django_ledger:uom-list', kwargs={'entity_slug': ENTITY_SLUG})
718
+ 'url': reverse('django_ledger:uom-list', kwargs={'entity_slug': ENTITY_SLUG}),
719
+ 'icon': 'mdi:ruler'
703
720
  },
704
721
  ]
705
722
  },
@@ -710,17 +727,20 @@ def navigation_menu(context, style):
710
727
  {
711
728
  'type': 'link',
712
729
  'title': 'Balance Sheet',
713
- 'url': reverse('django_ledger:entity-bs', kwargs={'entity_slug': ENTITY_SLUG})
730
+ 'url': reverse('django_ledger:entity-bs', kwargs={'entity_slug': ENTITY_SLUG}),
731
+ 'icon': 'clarity:balance-line'
714
732
  },
715
733
  {
716
734
  'type': 'link',
717
735
  'title': 'Income Statement',
718
- 'url': reverse('django_ledger:entity-ic', kwargs={'entity_slug': ENTITY_SLUG})
736
+ 'url': reverse('django_ledger:entity-ic', kwargs={'entity_slug': ENTITY_SLUG}),
737
+ 'icon': 'mdi:chart-line'
719
738
  },
720
739
  {
721
740
  'type': 'link',
722
741
  'title': 'Cash Flow Statement',
723
- 'url': reverse('django_ledger:entity-cf', kwargs={'entity_slug': ENTITY_SLUG})
742
+ 'url': reverse('django_ledger:entity-cf', kwargs={'entity_slug': ENTITY_SLUG}),
743
+ 'icon': 'hugeicons:money-send-flow-02'
724
744
  },
725
745
  ]
726
746
  },
@@ -731,17 +751,20 @@ def navigation_menu(context, style):
731
751
  {
732
752
  'type': 'link',
733
753
  'title': 'Chart of Accounts',
734
- 'url': reverse('django_ledger:coa-list', kwargs={'entity_slug': ENTITY_SLUG})
754
+ 'url': reverse('django_ledger:coa-list', kwargs={'entity_slug': ENTITY_SLUG}),
755
+ 'icon': 'system-uicons:hierarchy'
735
756
  },
736
757
  {
737
758
  'type': 'link',
738
759
  'title': 'Ledgers',
739
- 'url': reverse('django_ledger:ledger-list-visible', kwargs={'entity_slug': ENTITY_SLUG})
760
+ 'url': reverse('django_ledger:ledger-list-visible', kwargs={'entity_slug': ENTITY_SLUG}),
761
+ 'icon': 'mdi:book-open'
740
762
  },
741
763
  {
742
764
  'type': 'link',
743
765
  'title': 'Data Import',
744
- 'url': reverse('django_ledger:data-import-jobs-list', kwargs={'entity_slug': ENTITY_SLUG})
766
+ 'url': reverse('django_ledger:data-import-jobs-list', kwargs={'entity_slug': ENTITY_SLUG}),
767
+ 'icon': 'mdi:database-import'
745
768
  }
746
769
  ]
747
770
  },
@@ -752,12 +775,14 @@ def navigation_menu(context, style):
752
775
  {
753
776
  'type': 'link',
754
777
  'title': 'My Entities',
755
- 'url': reverse('django_ledger:home')
778
+ 'url': reverse('django_ledger:home'),
779
+ 'icon': 'mdi:home-group'
756
780
  },
757
781
  {
758
782
  'type': 'link',
759
783
  'title': 'Entity Settings',
760
- 'url': reverse('django_ledger:entity-update', kwargs={'entity_slug': ENTITY_SLUG})
784
+ 'url': reverse('django_ledger:entity-update', kwargs={'entity_slug': ENTITY_SLUG}),
785
+ 'icon': 'mdi:cog'
761
786
  }
762
787
  ]
763
788
  }
@@ -766,7 +791,6 @@ def navigation_menu(context, style):
766
791
  ctx['request'] = context['request']
767
792
  return ctx
768
793
 
769
-
770
794
  @register.inclusion_tag('django_ledger/product/tags/product_table.html', takes_context=True)
771
795
  def product_table(context, queryset):
772
796
  entity_slug = context['view'].kwargs['entity_slug']
@@ -253,8 +253,6 @@ class BillModelDetailView(BillModelModelBaseView, DetailView):
253
253
  title = f'Bill {bill_model.bill_number}'
254
254
  context['page_title'] = title
255
255
  context['header_title'] = title
256
-
257
- bill_model: BillModel = self.object
258
256
  bill_items_qs, item_data = bill_model.get_itemtxs_data()
259
257
  context['itemtxs_qs'] = bill_items_qs
260
258
  context['total_amount__sum'] = item_data['total_amount__sum']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: django-ledger
3
- Version: 0.7.9
3
+ Version: 0.7.11
4
4
  Summary: Double entry accounting system built on the Django Web Framework.
5
5
  Author-email: Miguel Sanda <msanda@arrobalytics.com>
6
6
  Maintainer-email: Miguel Sanda <msanda@arrobalytics.com>
@@ -1,4 +1,4 @@
1
- django_ledger/__init__.py,sha256=ihK8afW7Z89n0NPbEPgekMNY6Qt6R9NRQIXgrtHZ1SE,380
1
+ django_ledger/__init__.py,sha256=uLgks5A6z1Ujc8_0OaliPLnQX7YQoyMbzdWZ0I1Zxy4,381
2
2
  django_ledger/apps.py,sha256=H-zEWUjKGakgSDSZmLIoXChZ2h6e0dth0ZO5SpoT-8U,163
3
3
  django_ledger/exceptions.py,sha256=rML8sQQ0Hq-DYMLZ76dfw2RYSAsXWUoyHuyC_yP9o1o,491
4
4
  django_ledger/settings.py,sha256=QOMK8mhT8MLrMxVDEzNRJ9W01Pm-Po26y7KaBPLVeNk,8952
@@ -43,14 +43,14 @@ django_ledger/contrib/django_ledger_graphene/unit/schema.py,sha256=orR4tn1ORTfzL
43
43
  django_ledger/contrib/django_ledger_graphene/vendor/mutations.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  django_ledger/contrib/django_ledger_graphene/vendor/schema.py,sha256=Y20FR0gut0yNsROL_f1LSHdzn7wM4_voKQv--evVGG4,1453
45
45
  django_ledger/forms/__init__.py,sha256=N7iaeMO5xTU-q7RXTVYUy-fu8nMZbiIJ9QEtDCjsTdI,205
46
- django_ledger/forms/account.py,sha256=1-L3-fy63sqz_pV1Wd0nxFsFzEW5WLKDAvjGv9aUN4M,5284
46
+ django_ledger/forms/account.py,sha256=2b6m6-o744l5pDJgTDnI_MddyncqYXLJafF6lqY48V0,5197
47
47
  django_ledger/forms/app_filters.py,sha256=fHmftiuR1Ei28LhGuu7LoxS4Q5pVjj1wiT0fF4GUcUI,2293
48
48
  django_ledger/forms/auth.py,sha256=HaJDEIRFoAHEAv-s_ZfTe0rZbhzIQ7GkKnaBX1qiAW4,736
49
49
  django_ledger/forms/bank_account.py,sha256=Ir6eQk4PSL7dii4mYGM895u6twrgvPm8vn3FCozSg8Q,4828
50
50
  django_ledger/forms/bill.py,sha256=vJbLZhHpolhzM0WKZdSAcuBnQAXDGGeKmY3RrswB-ZM,10813
51
51
  django_ledger/forms/chart_of_accounts.py,sha256=wymLQ8iLNPU_LgS79BOdMUapuLqoTvgqVdAyL1Pw0Ro,2414
52
52
  django_ledger/forms/closing_entry.py,sha256=ARKHmwf8n2vLMpLTTven9xuwVBQ7aMBcIUMnnWkbUdw,1526
53
- django_ledger/forms/customer.py,sha256=GrpREV8c3UsNhg5KzwNsofnuW5uv25Ue-Aa-pJeyXUc,2501
53
+ django_ledger/forms/customer.py,sha256=xK1tlA1yYvZM2TWeSumcHOfmw0DiiIzgypOoXDK5fF4,2707
54
54
  django_ledger/forms/data_import.py,sha256=AMb8C867KZ6qxTHtGkpexj7VY1yehPJX0DE0-4pFIcA,6930
55
55
  django_ledger/forms/entity.py,sha256=b0QirmsFSnaM8YWDO4V6GQXfFgR_MLmdq27I2q2sGQ0,6880
56
56
  django_ledger/forms/estimate.py,sha256=0A30F4mosT4uvIde61lAWbPV4JePUQIX87VAcTtby3c,5180
@@ -63,10 +63,10 @@ django_ledger/forms/purchase_order.py,sha256=XIi7v6ZaBd9nYgcWLmgNKm9751XBXpbwmUt
63
63
  django_ledger/forms/transactions.py,sha256=ockQjKihNY07m9NWL9nJtHBQMzROaQQO18QZSuiFn8s,3210
64
64
  django_ledger/forms/unit.py,sha256=rXUefjpuAmUU0vPOqu1ObO4k-bN-_Q6kOqHJ4kp_Vlg,1131
65
65
  django_ledger/forms/utils.py,sha256=sgkwBZs15_rZ5NT7h-8Z7wi3-ItM1E1sqoVDo3NQ5Jc,513
66
- django_ledger/forms/vendor.py,sha256=Nuh8MmSpz4ycMZwiVe--U9Ec6ezIsfACHDkhA2SyiZ4,2215
66
+ django_ledger/forms/vendor.py,sha256=eLCZiWZLVigTyltQZfBfcE35_9Re4hdXisyWOadMS-s,2417
67
67
  django_ledger/io/__init__.py,sha256=8m5AoBRiG2ymrX0Y4LVjq0275i7I5Sk7YRa1BTzVofI,369
68
68
  django_ledger/io/io_context.py,sha256=2AiQyJSTkYUCu09Ig0ZPgYj8PtlvUKNS30KvRp9e7zA,4753
69
- django_ledger/io/io_core.py,sha256=EmW0zu4P38OubxncBbnDdyAfM8X_epoxEc7iK-pApKA,87335
69
+ django_ledger/io/io_core.py,sha256=Sok4OmD_8Wqma7gP2OPLRqfZOgNqb-4ZretC8MGRpJ0,87500
70
70
  django_ledger/io/io_generator.py,sha256=IN_ZuMlPHXgoEffxA7PMN2fyTvWPJktzVR6yIaocsRs,34725
71
71
  django_ledger/io/io_library.py,sha256=CGZABR4P80VfIube4QEryNOi01llrPq0Gh-8vVbtZDY,22496
72
72
  django_ledger/io/io_middleware.py,sha256=vbWIBYA4V9nwoiEtB0W9pq19QIwPmaAyVJlo_1Gg2BY,20284
@@ -98,29 +98,31 @@ django_ledger/migrations/0019_alter_transactionmodel_amount_and_more.py,sha256=F
98
98
  django_ledger/migrations/0020_remove_bankaccountmodel_django_ledg_cash_ac_59a8af_idx_and_more.py,sha256=KFQExX3UVpeI9WlmRl2AZ9Q7k-24YBNf9ij4VU7tq_o,1741
99
99
  django_ledger/migrations/0021_alter_bankaccountmodel_account_model_and_more.py,sha256=b3eJA_QzNzvx7BPSaj2RCPIbsrCkZrpkvk_qN7v-4OA,1101
100
100
  django_ledger/migrations/0022_bankaccountmodel_financial_institution_and_more.py,sha256=MR_E-DYIEsxSfhO5O4iBsShe-tyM3wYZQ4C4_6h1Prw,2959
101
+ django_ledger/migrations/0023_customermodel_customer_code_customermodel_picture_and_more.py,sha256=M2p8Km55aNE-aKX_XWYZKQeh03MPbyoSQ15sOj-B86E,2095
102
+ django_ledger/migrations/0024_billmodel_entity_model_invoicemodel_entity_model.py,sha256=Fq2HiDJGpK7_dXq94INOs63psxf_q29vYZRVOr3qFRs,839
101
103
  django_ledger/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
104
  django_ledger/models/__init__.py,sha256=OesBx4My9GnqU1xB5WXuuGLOnmzgxEJxI-WWxRxi658,807
103
105
  django_ledger/models/accounts.py,sha256=LDbDLUiTkxy0k2Qyrq4N6FvpaffXW4vAuM53v5xveg0,36685
104
106
  django_ledger/models/bank_account.py,sha256=dar6-iOqCBkeqyxwuV8tc2czFZVX9nGRSPvOLxp4m64,8009
105
- django_ledger/models/bill.py,sha256=LCuYvyOtkZ6H-tcV4AYN1GFe_C6s__QxEbR0IcfTak8,65000
107
+ django_ledger/models/bill.py,sha256=LEJJymFBh-U6YcKZC56CnAPSC_2bPuUDptu7QKX131U,65270
106
108
  django_ledger/models/chart_of_accounts.py,sha256=cMHAc0TQdYD1iMan9qbrq2FX3NlmPYI_g1qwXPa4sSU,30308
107
109
  django_ledger/models/closing_entry.py,sha256=ILFNwxvCNvlEKuK2AL8z49izEBtfco-IT_oXcCMcbP8,18294
108
110
  django_ledger/models/coa_default.py,sha256=CK4vOZ73QePciZUL93wigDXpxKamdXAKBaQR7r-G7tk,27482
109
- django_ledger/models/customer.py,sha256=2v6E1Ri9v3yBPMS8wpnqbEdDeLD897DEfR6vSDf2lVY,11336
111
+ django_ledger/models/customer.py,sha256=UUGXXGMilZ4XYdK1Ytu-3IlYhHw-t3_cgh32GbadRxE,12188
110
112
  django_ledger/models/data_import.py,sha256=nffhWbb-EQN3zmFtJ512ix5ExnlJDSNHieOxR4W6OSE,47802
111
113
  django_ledger/models/entity.py,sha256=kiY-VX_ot727sF0VRlfxA7bOVE5aP-hFmDg6TX78msM,124687
112
114
  django_ledger/models/estimate.py,sha256=t3ZSBHZUUOdWP6eMCyQwNgvNSY4myKbkdfaFd9zlpH0,58056
113
- django_ledger/models/invoice.py,sha256=l1yI-kpePNNSp0MfwGeccdPLAmTmvVV4CquNIxMrmc4,63222
115
+ django_ledger/models/invoice.py,sha256=1HdVjm5pmdiDFSonUwEzR-U4aY0OLK3PCKxuk-xaxww,63647
114
116
  django_ledger/models/items.py,sha256=cGv681aocJJxXSbsz9NlLhPp7kJ-gQrtxl7EcsiwULg,55087
115
117
  django_ledger/models/journal_entry.py,sha256=Hqfz7oNUBXt1Vprd5W1adrFmZzCebemc2cvQZTlKVrk,66993
116
118
  django_ledger/models/ledger.py,sha256=ltWmPIzauwxODO-FSupphIOkJYPDGT47-xKOst5DEvQ,26266
117
- django_ledger/models/mixins.py,sha256=Y0uRYZAWUExpHdLZy30XQrmr2t05gMvOuDRKjkoauKk,54213
119
+ django_ledger/models/mixins.py,sha256=jwHepBVjM30iQVuHSg0TMYBvchEWCgpG59B_fKBGyt4,54371
118
120
  django_ledger/models/purchase_order.py,sha256=A0fKA1lU12CYePb43T--wSNqf_d6Vwap1deyNXUoFEg,44140
119
121
  django_ledger/models/signals.py,sha256=3cm_8--Jz-Jb0fPgrVmm5xx_jKFARV6_A29VDjqHeIw,1563
120
122
  django_ledger/models/transactions.py,sha256=b_ChD6FG-ru7FgT7c9D_1ku1YyhCz840wSrnyVQN6AU,24045
121
123
  django_ledger/models/unit.py,sha256=2bH-Tg3OOz7bEcVdB66_CTUhxTY9YP78thwJL5HKC0k,8346
122
124
  django_ledger/models/utils.py,sha256=Weta2Cwsn4wRqvxMecIuD7aHYiiXBwUeMqpUDK4CokE,8360
123
- django_ledger/models/vendor.py,sha256=ha_sTc9BHY7RKk70n50eZ-EvqbKHbDObyf0_khhLWN8,11322
125
+ django_ledger/models/vendor.py,sha256=CSPDEAYmtyv9LHadvplmaG7wz41rNsa_PyYKkdEJjs4,12248
124
126
  django_ledger/models/schemas/__init__.py,sha256=8Tvw33tVJtCvxoXje2lrs9C1bsP_iuGcVi1JqzdPUao,157
125
127
  django_ledger/models/schemas/digest.py,sha256=ME_dJ4g2p3dQ97Skh_RTZMwuNLmwTi19BdLM1G6tyAo,1077
126
128
  django_ledger/models/schemas/net_payable.py,sha256=2FcfLaaJySjZ3Yk_IMu8SxYWNO_sngEtbuFCXInrQUU,958
@@ -234,7 +236,7 @@ django_ledger/templates/django_ledger/customer/customer_create.html,sha256=jHJMo
234
236
  django_ledger/templates/django_ledger/customer/customer_list.html,sha256=zRBHsbYlZH13U1TRkyfKR9VZ6HnLkDGhvejMBBYTqZY,689
235
237
  django_ledger/templates/django_ledger/customer/customer_update.html,sha256=z1rzw_gDp0rPr_dmtlaZZrDavRiy1FVZ3qEuKKKnclk,1354
236
238
  django_ledger/templates/django_ledger/customer/includes/card_customer.html,sha256=z_R_NtbYScvrcuqF-uZggTuPasVS-RXN-4ZHWUVaFxQ,1306
237
- django_ledger/templates/django_ledger/customer/tags/customer_table.html,sha256=gd7_NsxaZk_iG8siYpZWfwyjIiY2HPv6FnJ5kExBOyY,3411
239
+ django_ledger/templates/django_ledger/customer/tags/customer_table.html,sha256=aEPSJ0T-zxVRX-lUJWefpP5Lx8egW3yJEQOQOFLafwI,3582
238
240
  django_ledger/templates/django_ledger/data_import/data_import_job_list.html,sha256=tFb1nX9Ag6g6RhIISFoqC6J7pjKQTOasEUQ5YLtA3SE,592
239
241
  django_ledger/templates/django_ledger/data_import/data_import_job_txs.html,sha256=oxaQnblI7JsBQs8I4U5RK00S3_ONvEPl3UV-wDA3a-M,943
240
242
  django_ledger/templates/django_ledger/data_import/import_job_create.html,sha256=RpCtH7J2lGujC3kTrYDzWf3hw8Z-0G6LjltTbtRK0JY,3205
@@ -245,7 +247,7 @@ django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_impor
245
247
  django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html,sha256=z0wTLneFb9BqYohhD2W6loRc9VpAmuFO93Gy2sFMyPo,3916
246
248
  django_ledger/templates/django_ledger/entity/entitiy_list.html,sha256=onM9uaWTm2oQ00OPIH5ki2FEfgjx7_EIOT8akuAhQM4,1507
247
249
  django_ledger/templates/django_ledger/entity/entity_create.html,sha256=TDayIv2qno7cT3xTCapKV6EZKcTTNfIMxXJFQmHHyz0,1387
248
- django_ledger/templates/django_ledger/entity/entity_dashboard.html,sha256=krofkugevRNaRm-us184gbQph2h8xpV5u8Ww0TVxmho,5365
250
+ django_ledger/templates/django_ledger/entity/entity_dashboard.html,sha256=gX0YXYWh9HKZrAQBCQkjqkpCUDzefV-A9Bw9r6VCugE,5435
249
251
  django_ledger/templates/django_ledger/entity/entity_delete.html,sha256=Kn0a3fff8Jiq4zd4WKqumEqE6PJLa8U3cQ4hSRnR81I,1239
250
252
  django_ledger/templates/django_ledger/entity/entity_update.html,sha256=kB4NGg3ndXauTUyFCmm1jvGFsqs_FeI-mSP-rfz5eq0,1024
251
253
  django_ledger/templates/django_ledger/entity/home.html,sha256=xt7TLtBV2pcFJDUkwrPFnP2Bxi8kreKXISe8GgyVQsI,995
@@ -273,7 +275,7 @@ django_ledger/templates/django_ledger/includes/card_markdown.html,sha256=wKihCko
273
275
  django_ledger/templates/django_ledger/includes/footer.html,sha256=etnULJWQRmSdtMFgxY-vT2-JQYyxxixa7xQ2K6qD1Wo,528
274
276
  django_ledger/templates/django_ledger/includes/messages.html,sha256=N_7BlYw9pJfzsv9gTUE4FFoUppWhbkxShd4UnQ81IfM,322
275
277
  django_ledger/templates/django_ledger/includes/nav.html,sha256=fUFYiJoHV-Mf_fPsGzbLBq5kOnDHGC1XfNA_F5YZ3Kc,2004
276
- django_ledger/templates/django_ledger/includes/page_header.html,sha256=q2tL3SvFebET4CB_gJB_qRocMbDdijrNCoowoHCgthM,2353
278
+ django_ledger/templates/django_ledger/includes/page_header.html,sha256=2xWdfdxAi9bQIku-BaXA5p3OogNBEtYqzMKfnlywXUM,2366
277
279
  django_ledger/templates/django_ledger/includes/widget_bs.html,sha256=UxLVF8rdKwONQaRIE3IrWLYXD0XBs6wEMRGeLevbHwk,949
278
280
  django_ledger/templates/django_ledger/includes/widget_ic.html,sha256=IWSnAcMJMoAg9kf_XCBPBNGYUSXtgGurgPotkdsVrEM,1129
279
281
  django_ledger/templates/django_ledger/includes/widget_ratios.html,sha256=aoMU4luFPAia6lkBJkimu2f3t4a8Y8j2LEf0uSUn9zI,3252
@@ -342,9 +344,9 @@ django_ledger/templates/django_ledger/vendor/vendor_create.html,sha256=EanF0Isff
342
344
  django_ledger/templates/django_ledger/vendor/vendor_list.html,sha256=Jnp_xI76CxrSFEphRLjQKKs2CajyAe3Xy_uQBcjH8lU,672
343
345
  django_ledger/templates/django_ledger/vendor/vendor_update.html,sha256=4kBUlGgrgRFhdwhjQAxJrp0ATsTWQ4kcKLlUqpkjLKo,1341
344
346
  django_ledger/templates/django_ledger/vendor/includes/card_vendor.html,sha256=oCXyuqyF7CnJnDQdK0G0jdYLqtPWYSzwlv8oddyGJg8,1290
345
- django_ledger/templates/django_ledger/vendor/tags/vendor_table.html,sha256=YC-3T5x4oua3VBg1q690CRzoogKL8qFgQRp5jTKLFgk,3400
347
+ django_ledger/templates/django_ledger/vendor/tags/vendor_table.html,sha256=cNbTIZhpKvSxcchFZpZLywJgQl6lCp-YAu9bBdzUij8,3555
346
348
  django_ledger/templatetags/__init__.py,sha256=N7iaeMO5xTU-q7RXTVYUy-fu8nMZbiIJ9QEtDCjsTdI,205
347
- django_ledger/templatetags/django_ledger.py,sha256=KS6Tb5z7IcRW9ddCDfrHeSFz9in3hV2sseqrq3bL9m0,31251
349
+ django_ledger/templatetags/django_ledger.py,sha256=jEez145Hzt_16cubVWEyqGu_EUbnBzu02lJsw6EaLCo,32453
348
350
  django_ledger/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
349
351
  django_ledger/tests/base.py,sha256=ddsMTzv0-17JD1QRobpTN2CVKL1v0lNplo78JaB36oQ,10842
350
352
  django_ledger/tests/test_accounts.py,sha256=bASqtQjp6twya8JrNkBXVMsOnK8E8Hl7B0J6RfDJGB0,6345
@@ -388,7 +390,7 @@ django_ledger/views/__init__.py,sha256=fY9eBoPkx50p-kSalskd4QW1tHm3e64WpwOFuJzn4
388
390
  django_ledger/views/account.py,sha256=fC0PX889DxyKheTF3SIA_aDxermQu8hPhrw5JBwpwS0,9536
389
391
  django_ledger/views/auth.py,sha256=I8Mv_aAfW-8Z5VYPOX7P3IUO4Fp5jJPkSuu1ZSVpWtI,777
390
392
  django_ledger/views/bank_account.py,sha256=MbiVurJTNK-UsDPn17-ai4G8sE3qIMrdmXaWPX-J8n8,5025
391
- django_ledger/views/bill.py,sha256=5tNb3pyh8GQM4hjV0FXqCXrEQF2LwpEWLkOkpknEdjA,22239
393
+ django_ledger/views/bill.py,sha256=eMVthGDkbOrRpVo4qF1jFOXq268YPjcz72P-LMM98U4,22194
392
394
  django_ledger/views/chart_of_accounts.py,sha256=wMdnXRNWzdPgxl1YeHbdAQXbCBU2VkmxVxxtUuk9NAQ,5485
393
395
  django_ledger/views/closing_entry.py,sha256=SbJMyBVG8KTfZ6oo4Gdzx03utKY5CoC7qioU_dm9n5I,8157
394
396
  django_ledger/views/customer.py,sha256=FYnwhRx6JXE4bsjXQqFp8b9H8a4m7zv6ohoSj1OkZD8,3678
@@ -409,9 +411,9 @@ django_ledger/views/purchase_order.py,sha256=CyftKrQWV1SBz7W0CvZOfZ81OPEiBHPD7b9
409
411
  django_ledger/views/transactions.py,sha256=3ijtJzdLPFkqG7OYpe-7N4QVjCyR2yl5ht_9RyfquBA,212
410
412
  django_ledger/views/unit.py,sha256=CarmOKzXANssVD3qMS1oXvJw614Y3rS0QHhSGJC0jBE,10069
411
413
  django_ledger/views/vendor.py,sha256=7gtVK_bgnXxbVwNAHYtI_eNEJPefCz807LgE1vqOov8,3532
412
- django_ledger-0.7.9.dist-info/AUTHORS.md,sha256=ShPwf-qniJkbjRzX5_lqhmgoLMEYMSHSwKPXHZtWmyk,824
413
- django_ledger-0.7.9.dist-info/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
414
- django_ledger-0.7.9.dist-info/METADATA,sha256=Jm46VjpBOjXbwS4omyYP6DCXLXfphxas_poWHhpqLKk,9089
415
- django_ledger-0.7.9.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
416
- django_ledger-0.7.9.dist-info/top_level.txt,sha256=fmHWehb2HfoDncQ3eQtYzeYc-gJMywf6q_ZpKBjwzoQ,38
417
- django_ledger-0.7.9.dist-info/RECORD,,
414
+ django_ledger-0.7.11.dist-info/AUTHORS.md,sha256=ShPwf-qniJkbjRzX5_lqhmgoLMEYMSHSwKPXHZtWmyk,824
415
+ django_ledger-0.7.11.dist-info/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
416
+ django_ledger-0.7.11.dist-info/METADATA,sha256=BGpP8dA2hd3bB1flaeDQrpii0eVK353z9PEGdFnxS_o,9090
417
+ django_ledger-0.7.11.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
418
+ django_ledger-0.7.11.dist-info/top_level.txt,sha256=fmHWehb2HfoDncQ3eQtYzeYc-gJMywf6q_ZpKBjwzoQ,38
419
+ django_ledger-0.7.11.dist-info/RECORD,,