django-ledger 0.6.0.2__py3-none-any.whl → 0.6.1__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.

File without changes
django_ledger/__init__.py CHANGED
@@ -9,7 +9,7 @@ Contributions to this module:
9
9
  default_app_config = 'django_ledger.apps.DjangoLedgerConfig'
10
10
 
11
11
  """Django Ledger"""
12
- __version__ = '0.6.0.2'
12
+ __version__ = '0.6.1'
13
13
  __license__ = 'GPLv3 License'
14
14
 
15
15
  __author__ = 'Miguel Sanda'
@@ -6,9 +6,7 @@ Contributions to this module:
6
6
  Miguel Sanda <msanda@arrobalytics.com>
7
7
  """
8
8
 
9
- from django_ledger.io.io_digest import *
9
+ from django_ledger.io.io_context import *
10
10
  from django_ledger.io.io_middleware import *
11
11
  from django_ledger.io.ratios import *
12
12
  from django_ledger.io.roles import *
13
- # due to circular import
14
- # from django_ledger.io.io_library import IOLibrary
@@ -38,6 +38,10 @@ class IODigestContextManager:
38
38
  def get_strftime_format(self):
39
39
  return self.STRFTIME_FORMAT
40
40
 
41
+ @property
42
+ def from_datetime(self):
43
+ return self.get_from_datetime()
44
+
41
45
  def get_from_datetime(self, as_str: bool = False, fmt=None) -> Optional[datetime]:
42
46
  from_date = self.IO_DATA['from_date']
43
47
  if from_date:
@@ -47,6 +51,10 @@ class IODigestContextManager:
47
51
  return from_date.strftime(fmt)
48
52
  return from_date
49
53
 
54
+ @property
55
+ def to_datetime(self):
56
+ return self.get_to_datetime()
57
+
50
58
  def get_to_datetime(self, as_str: bool = False, fmt=None) -> datetime:
51
59
  if as_str:
52
60
  if not fmt:
@@ -36,7 +36,7 @@ from django.utils.translation import gettext_lazy as _
36
36
  from django_ledger import settings
37
37
  from django_ledger.exceptions import InvalidDateInputError, TransactionNotInBalanceError
38
38
  from django_ledger.io import roles as roles_module
39
- from django_ledger.io.io_digest import IODigestContextManager
39
+ from django_ledger.io.io_context import IODigestContextManager
40
40
  from django_ledger.io.io_middleware import (
41
41
  AccountRoleIOMiddleware,
42
42
  AccountGroupIOMiddleware,
@@ -116,7 +116,7 @@ class EntityModelManager(MP_NodeManager):
116
116
  qs = EntityModelQuerySet(self.model, using=self._db).order_by('path')
117
117
  return qs.order_by('path').select_related('admin', 'default_coa')
118
118
 
119
- def for_user(self, user_model):
119
+ def for_user(self, user_model, authorized_superuser: bool = False):
120
120
  """
121
121
  This QuerySet guarantees that Users do not access or operate on EntityModels that don't have access to.
122
122
  This is the recommended initial QuerySet.
@@ -125,6 +125,8 @@ class EntityModelManager(MP_NodeManager):
125
125
  ----------
126
126
  user_model
127
127
  The Django User Model making the request.
128
+ authorized_superuser
129
+ Allows any superuser to access the EntityModel. Default is False.
128
130
 
129
131
  Returns
130
132
  -------
@@ -134,7 +136,7 @@ class EntityModelManager(MP_NodeManager):
134
136
  2. Is a manager.
135
137
  """
136
138
  qs = self.get_queryset()
137
- if user_model.is_superuser:
139
+ if user_model.is_superuser and authorized_superuser:
138
140
  return qs
139
141
  return qs.filter(
140
142
  Q(admin=user_model) |
@@ -881,8 +881,6 @@ class ItemTransactionModelManager(models.Manager):
881
881
 
882
882
  def for_user(self, user_model):
883
883
  qs = self.get_queryset()
884
- if user_model.is_superuser:
885
- return qs
886
884
  return qs.filter(
887
885
  Q(item_model__entity__admin=user_model) |
888
886
  Q(item_model__entity__managers__in=[user_model])
@@ -891,7 +889,7 @@ class ItemTransactionModelManager(models.Manager):
891
889
  def for_entity(self, user_model, entity_slug):
892
890
  qs = self.for_user(user_model)
893
891
  if isinstance(entity_slug, lazy_loader.get_entity_model()):
894
- qs.filter(
892
+ return qs.filter(
895
893
  Q(item_model__entity=entity_slug)
896
894
  )
897
895
  return qs.filter(
@@ -226,7 +226,6 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
226
226
  ledger_str = f'LedgerModel: {self.uuid}'
227
227
  return f'{ledger_str} | Posted: {self.posted} | Locked: {self.locked}'
228
228
 
229
-
230
229
  def has_wrapped_model_info(self):
231
230
  if self.additional_info is not None:
232
231
  return self._WRAPPED_MODEL_KEY in self.additional_info
@@ -523,7 +522,7 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
523
522
  je_model_qs.bulk_update(objs=je_model_qs, fields=['locked', 'updated'])
524
523
  return je_model_qs
525
524
 
526
- def unlock(self, commit: bool = False, **kwargs):
525
+ def unlock(self, commit: bool = False, raise_exception: bool = True, **kwargs):
527
526
  """
528
527
  Un-locks the LedgerModel.
529
528
 
@@ -532,13 +531,19 @@ class LedgerModelAbstract(CreateUpdateMixIn, IOMixIn):
532
531
  commit: bool
533
532
  If True, saves the LedgerModel instance instantly. Defaults to False.
534
533
  """
535
- if self.can_unlock():
536
- self.locked = False
537
- if commit:
538
- self.save(update_fields=[
539
- 'locked',
540
- 'updated'
541
- ])
534
+ if not self.can_unlock():
535
+ if raise_exception:
536
+ raise LedgerModelValidationError(
537
+ message=_(f'Ledger {self.name} cannot be un-locked. UUID: {self.uuid}')
538
+ )
539
+ return
540
+
541
+ self.locked = False
542
+ if commit:
543
+ self.save(update_fields=[
544
+ 'locked',
545
+ 'updated'
546
+ ])
542
547
 
543
548
  def hide(self, commit: bool = False, raise_exception: bool = True, **kwargs):
544
549
  if not self.can_hide():
@@ -487,7 +487,8 @@ class AccrualMixIn(models.Model):
487
487
  if ledger_model.locked:
488
488
  if raise_exception:
489
489
  raise ValidationError(f'Bill ledger {ledger_model.name} is already locked...')
490
- ledger_model.lock(commit)
490
+ return
491
+ ledger_model.lock(commit, raise_exception=raise_exception)
491
492
 
492
493
  def unlock_ledger(self, commit: bool = False, raise_exception: bool = True, **kwargs):
493
494
  """
@@ -501,10 +502,11 @@ class AccrualMixIn(models.Model):
501
502
  If True, raises ValidationError if LedgerModel already locked.
502
503
  """
503
504
  ledger_model = self.ledger
504
- if not ledger_model.locked:
505
+ if not ledger_model.is_locked():
505
506
  if raise_exception:
506
507
  raise ValidationError(f'Bill ledger {ledger_model.name} is already unlocked...')
507
- ledger_model.unlock(commit)
508
+ return
509
+ ledger_model.unlock(commit, raise_exception=raise_exception)
508
510
 
509
511
  # POST/UNPOST Ledger...
510
512
  def post_ledger(self, commit: bool = False, raise_exception: bool = True, **kwargs):
@@ -522,7 +524,8 @@ class AccrualMixIn(models.Model):
522
524
  if ledger_model.posted:
523
525
  if raise_exception:
524
526
  raise ValidationError(f'Bill ledger {ledger_model.name} is already posted...')
525
- ledger_model.post(commit)
527
+ return
528
+ ledger_model.post(commit, raise_exception=raise_exception)
526
529
 
527
530
  def unpost_ledger(self, commit: bool = False, raise_exception: bool = True, **kwargs):
528
531
  """
@@ -536,13 +539,14 @@ class AccrualMixIn(models.Model):
536
539
  If True, raises ValidationError if LedgerModel already locked.
537
540
  """
538
541
  ledger_model = self.ledger
539
- if not ledger_model.posted:
542
+ if not ledger_model.is_posted():
540
543
  if raise_exception:
541
544
  raise ValidationError(f'Bill ledger {ledger_model.name} is not posted...')
542
- ledger_model.post(commit)
545
+ return
546
+ ledger_model.post(commit, raise_exception=raise_exception)
543
547
 
544
548
  def migrate_state(self,
545
- # todo: remove usermodel param...
549
+ # todo: remove usermodel param...?
546
550
  user_model,
547
551
  entity_slug: str,
548
552
  itemtxs_qs: Optional[QuerySet] = None,
@@ -49,35 +49,6 @@ class TransactionModelQuerySet(QuerySet):
49
49
  """
50
50
  A custom QuerySet class for TransactionModels implementing methods to effectively and safely read
51
51
  TransactionModels from the database.
52
-
53
- Methods
54
- -------
55
- posted() -> TransactionModelQuerySet:
56
- Fetches a QuerySet of posted transactions only.
57
-
58
- for_accounts(account_list: List[str or AccountModel]) -> TransactionModelQuerySet:
59
- Fetches a QuerySet of TransactionModels which AccountModel has a specific role.
60
-
61
- for_roles(role_list: Union[str, List[str]]) -> TransactionModelQuerySet:
62
- Fetches a QuerySet of TransactionModels which AccountModel has a specific role.
63
-
64
- for_unit(unit_slug: Union[str, EntityUnitModel]) -> TransactionModelQuerySet:
65
- Fetches a QuerySet of TransactionModels associated with a specific EntityUnitModel.
66
-
67
- for_activity(activity_list: Union[str, List[str]]) -> TransactionModelQuerySet:
68
- Fetches a QuerySet of TransactionModels associated with a specific activity or list of activities.
69
-
70
- to_date(to_date: Union[str, date, datetime]) -> TransactionModelQuerySet:
71
- Fetches a QuerySet of TransactionModels associated with a maximum date or timestamp filter.
72
-
73
- from_date(from_date: Union[str, date, datetime]) -> TransactionModelQuerySet:
74
- Fetches a QuerySet of TransactionModels associated with a minimum date or timestamp filter.
75
-
76
- not_closing_entry() -> TransactionModelQuerySet:
77
- Fetches a QuerySet of TransactionModels that are not part of a closing entry.
78
-
79
- is_closing_entry() -> TransactionModelQuerySet:
80
- Fetches a QuerySet of TransactionModels that are part of a closing entry.
81
52
  """
82
53
 
83
54
  def posted(self) -> QuerySet:
@@ -111,7 +82,7 @@ class TransactionModelQuerySet(QuerySet):
111
82
  TransactionModelQuerySet
112
83
  Returns a TransactionModelQuerySet with applied filters.
113
84
  """
114
- if len(account_list) > 0 and isinstance(account_list[0], str):
85
+ if isinstance(account_list, list) > 0 and isinstance(account_list[0], str):
115
86
  return self.filter(account__code__in=account_list)
116
87
  return self.filter(account__in=account_list)
117
88
 
@@ -276,8 +247,6 @@ class TransactionModelManager(models.Manager):
276
247
  ledger or the user is one of the managers of the entity associated with the transaction's ledger.
277
248
  """
278
249
  qs = self.get_queryset()
279
- if user_model.is_superuser:
280
- return qs
281
250
  return qs.filter(
282
251
  Q(journal_entry__ledger__entity__admin=user_model) |
283
252
  Q(journal_entry__ledger__entity__managers__in=[user_model])
@@ -311,25 +311,20 @@ class DjangoLedgerSecurityMixIn(LoginRequiredMixin, PermissionRequiredMixin):
311
311
  )
312
312
  return self.ENTITY_SLUG_URL_KWARG
313
313
 
314
+ def get_superuser_authorization(self):
315
+ return self.AUTHORIZE_SUPERUSER
316
+
314
317
  def has_permission(self):
318
+ has_perm = super().has_permission()
319
+ if not has_perm:
320
+ return False
321
+
315
322
  entity_slug_kwarg = self.get_entity_slug_kwarg()
316
- if self.request.user.is_superuser:
317
- if not self.AUTHORIZE_SUPERUSER:
318
- return False
319
- if entity_slug_kwarg in self.kwargs:
320
- try:
321
- entity_model_qs = self.get_authorized_entity_queryset()
322
- self.AUTHORIZED_ENTITY_MODEL = entity_model_qs.get(slug__exact=self.kwargs[entity_slug_kwarg])
323
- except ObjectDoesNotExist:
324
- return False
325
- return True
326
- elif self.request.user.is_authenticated:
327
- has_perm = super().has_permission()
328
- if not has_perm:
329
- return False
323
+ entity_model_qs = self.get_authorized_entity_queryset()
324
+
325
+ if self.request.user.is_authenticated:
330
326
  if entity_slug_kwarg in self.kwargs:
331
327
  try:
332
- entity_model_qs = self.get_authorized_entity_queryset()
333
328
  self.AUTHORIZED_ENTITY_MODEL = entity_model_qs.get(slug__exact=self.kwargs[entity_slug_kwarg])
334
329
  except ObjectDoesNotExist:
335
330
  return False
@@ -338,7 +333,9 @@ class DjangoLedgerSecurityMixIn(LoginRequiredMixin, PermissionRequiredMixin):
338
333
 
339
334
  def get_authorized_entity_queryset(self):
340
335
  return EntityModel.objects.for_user(
341
- user_model=self.request.user).only(
336
+ user_model=self.request.user,
337
+ authorized_superuser=self.get_superuser_authorization(),
338
+ ).only(
342
339
  'uuid', 'slug', 'name', 'default_coa', 'admin')
343
340
 
344
341
  def get_authorized_entity_instance(self) -> Optional[EntityModel]:
@@ -372,8 +369,26 @@ class EntityUnitMixIn:
372
369
 
373
370
 
374
371
  class DigestContextMixIn:
375
- IO_DIGEST = False
376
- IO_DIGEST_EQUITY = False
372
+ IO_DIGEST_UNBOUNDED = False
373
+ IO_DIGEST_BOUNDED = False
374
+
375
+ IO_DIGEST_UNBOUNDED_CONTEXT_NAME = 'tx_digest'
376
+ IO_MANAGER_UNBOUNDED_CONTEXT_NAME = 'tx_digest_context'
377
+
378
+ IO_DIGEST_BOUNDED_CONTEXT_NAME = 'equity_digest'
379
+ IO_MANAGER_BOUNDED_CONTEXT_NAME = 'equity_digest_context'
380
+
381
+ def get_io_digest_unbounded_context_name(self):
382
+ return self.IO_DIGEST_UNBOUNDED_CONTEXT_NAME
383
+
384
+ def get_io_manager_unbounded_context_name(self):
385
+ return self.IO_MANAGER_UNBOUNDED_CONTEXT_NAME
386
+
387
+ def get_io_digest_bounded_context_name(self):
388
+ return self.IO_DIGEST_BOUNDED_CONTEXT_NAME
389
+
390
+ def get_io_manager_bounded_context_name(self):
391
+ return self.IO_MANAGER_BOUNDED_CONTEXT_NAME
377
392
 
378
393
  def get_context_data(self, **kwargs):
379
394
  context = super(DigestContextMixIn, self).get_context_data(**kwargs)
@@ -385,8 +400,8 @@ class DigestContextMixIn:
385
400
  to_date=None,
386
401
  **kwargs):
387
402
 
388
- if any([self.IO_DIGEST,
389
- self.IO_DIGEST_EQUITY]):
403
+ if any([self.IO_DIGEST_UNBOUNDED,
404
+ self.IO_DIGEST_BOUNDED]):
390
405
 
391
406
  by_period = self.request.GET.get('by_period')
392
407
  entity_model: EntityModel = self.object
@@ -401,7 +416,7 @@ class DigestContextMixIn:
401
416
  else:
402
417
  unit_slug = None
403
418
 
404
- if self.IO_DIGEST:
419
+ if self.IO_DIGEST_UNBOUNDED:
405
420
  io_digest = entity_model.digest(user_model=self.request.user,
406
421
  to_date=to_date,
407
422
  unit_slug=unit_slug,
@@ -410,10 +425,10 @@ class DigestContextMixIn:
410
425
  process_roles=True,
411
426
  process_groups=True)
412
427
 
413
- context['tx_digest_context'] = io_digest
414
- context['tx_digest'] = io_digest.get_io_data()
428
+ context[self.get_io_manager_unbounded_context_name()] = io_digest
429
+ context[self.get_io_digest_unbounded_context_name()] = io_digest.get_io_data()
415
430
 
416
- if self.IO_DIGEST_EQUITY:
431
+ if self.IO_DIGEST_BOUNDED:
417
432
  io_digest_equity = entity_model.digest(user_model=self.request.user,
418
433
  equity_only=True,
419
434
  to_date=to_date,
@@ -424,8 +439,8 @@ class DigestContextMixIn:
424
439
  process_roles=False,
425
440
  process_groups=True)
426
441
 
427
- context['equity_digest_context'] = io_digest_equity
428
- context['equity_digest'] = io_digest_equity.get_io_data()
442
+ context[self.get_io_manager_bounded_context_name()] = io_digest_equity
443
+ context[self.get_io_digest_bounded_context_name()] = io_digest_equity.get_io_data()
429
444
 
430
445
  # todo: how is this used??....
431
446
  context['date_filter'] = to_date
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-ledger
3
- Version: 0.6.0.2
3
+ Version: 0.6.1
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>
@@ -48,7 +48,7 @@ assets/node_modules/node-gyp/gyp/tools/pretty_gyp.py,sha256=2ZCRPW-MZfK7gdnCIaqh
48
48
  assets/node_modules/node-gyp/gyp/tools/pretty_sln.py,sha256=b_Fxm-SXUCPL3Tix4EyNwZNmQ-zkeRIFFmuL0R5wFhw,5482
49
49
  assets/node_modules/node-gyp/gyp/tools/pretty_vcproj.py,sha256=AwQrxK1F-jhjsbbT35XQjrvWNbc3IBFaKXoJogqMh_o,10633
50
50
  assets/node_modules/node-gyp/test/fixtures/test-charmap.py,sha256=5raXzaQnO2eJnrlFtlDtWftryhZX7Fj0amFW3hdSnhE,547
51
- django_ledger/__init__.py,sha256=c-3dvReg1GgIIrDElZzpUfB38BXg2TAKf5d9uhe5WMQ,458
51
+ django_ledger/__init__.py,sha256=zjhbT65sw3hTpJoAXAnUS_CQxh530bsWRh9Lcro2CeQ,456
52
52
  django_ledger/apps.py,sha256=H-zEWUjKGakgSDSZmLIoXChZ2h6e0dth0ZO5SpoT-8U,163
53
53
  django_ledger/exceptions.py,sha256=rML8sQQ0Hq-DYMLZ76dfw2RYSAsXWUoyHuyC_yP9o1o,491
54
54
  django_ledger/settings.py,sha256=bZyPKgjmRcO_Rj7hDi4gGlW0VFr_LP2yKeUVIkmWgQM,6321
@@ -114,9 +114,9 @@ django_ledger/forms/transactions.py,sha256=DD2TJthArTKTuzd4A43ZbugepcB8iuJ4Q_PSR
114
114
  django_ledger/forms/unit.py,sha256=rXUefjpuAmUU0vPOqu1ObO4k-bN-_Q6kOqHJ4kp_Vlg,1131
115
115
  django_ledger/forms/utils.py,sha256=sgkwBZs15_rZ5NT7h-8Z7wi3-ItM1E1sqoVDo3NQ5Jc,513
116
116
  django_ledger/forms/vendor.py,sha256=Nuh8MmSpz4ycMZwiVe--U9Ec6ezIsfACHDkhA2SyiZ4,2215
117
- django_ledger/io/__init__.py,sha256=Y9R-mY4peg8EpxmlXKaBER1IHMU-Nos8_dII41Kj0Ho,445
118
- django_ledger/io/io_core.py,sha256=Cutbj5WQQ0Mrja2_kLw02KL6_JygDdJvDp7JF5KzWJU,46923
119
- django_ledger/io/io_digest.py,sha256=W_bCH6JxGw6eASDb1k43JuGAejvOVfyA7WkCS7AEqDQ,4280
117
+ django_ledger/io/__init__.py,sha256=8m5AoBRiG2ymrX0Y4LVjq0275i7I5Sk7YRa1BTzVofI,369
118
+ django_ledger/io/io_context.py,sha256=xgykRoB6hVSN2q20f62j_4zbOeAHU5ZgbZaSwRaSkOU,4444
119
+ django_ledger/io/io_core.py,sha256=ktyTd_r6fZBSvGsXR-6J-vzwsdzAAyu3lnMWsVaFInk,46924
120
120
  django_ledger/io/io_generator.py,sha256=JF4plsABUkCIrtI2X-YD7o5eNghRIgLUseNcBIGOj3U,34613
121
121
  django_ledger/io/io_library.py,sha256=vvQm3IQRLFdH7HS_DYX46Xe-U9IvgZ6MQnHjy0-fyjk,22480
122
122
  django_ledger/io/io_middleware.py,sha256=c-vwpcjg2HbYbb4O36fdf6011dFOnoNsDHOAQXmJgB8,20052
@@ -152,15 +152,15 @@ django_ledger/models/coa.py,sha256=o-VM2XK64djM3px6pJlGrUVTXu5qNb4ENESS70I___0,2
152
152
  django_ledger/models/coa_default.py,sha256=4Zj8OMhgBiYuREjM82cFfyGWd8uCAeqggVkeNhg4SLU,27338
153
153
  django_ledger/models/customer.py,sha256=JQOktcYKUlENJv4frek9rAW6sRerrQ0xXHlC5KPmhWk,11807
154
154
  django_ledger/models/data_import.py,sha256=2H-4oTVLa7qXq03m9fd7T5zSQLkZKOAn2OAeOQBzMPA,19477
155
- django_ledger/models/entity.py,sha256=YYcgiVsC4aDl-htStJRQ6_1Hdmw5oHK4mBP2L0XanwI,121708
155
+ django_ledger/models/entity.py,sha256=VFknz-7FQZu_gVDb5RWqPoCb3eXVzIMgmr4hatUlzBI,121876
156
156
  django_ledger/models/estimate.py,sha256=-qB5t2cEdyYpFUq7tOUQnFqvE6EDUiVdTtzjEbESwEQ,55829
157
157
  django_ledger/models/invoice.py,sha256=h5Jh5KOfYr31Eu9gFW1mdoGoVzx7nW8qBdx7vyiXnZU,61568
158
- django_ledger/models/items.py,sha256=O9ujsut2jiISwKEmYcCTdUdsFywm0S-RKUDPCeXvPgY,55093
158
+ django_ledger/models/items.py,sha256=Wh_zPBnYCdI393nHafT6xd4aSutKBQPwKSjDtXTTPNQ,55042
159
159
  django_ledger/models/journal_entry.py,sha256=VfXXvm3tUFuy2Z6j3PLlDk9ndHqsZgn_PuhrxTNqaiY,50918
160
- django_ledger/models/ledger.py,sha256=q6yWf9jGK05kah_19Cbijc8HZErPM1koPejKO3ZbYXI,23382
161
- django_ledger/models/mixins.py,sha256=SBcSMfFuFzLqFQv298aDOfAJrF5kT91oXyo384auKqc,51903
160
+ django_ledger/models/ledger.py,sha256=kPxyKo5u0-2viifCY87Ms3xglmgrfiDAg0oJgsOrDwc,23603
161
+ django_ledger/models/mixins.py,sha256=s8ZjEjYQfmU88cLyFNKoiFi79_g1rTe1knEccV2WUXw,52122
162
162
  django_ledger/models/purchase_order.py,sha256=CDibi90e7Yhpv_UiyP32mMcsQ0EUElXJ2r8pLzuS7yE,42729
163
- django_ledger/models/transactions.py,sha256=aRZuP-zg-ZrxBi6rt3wx2ELXhsRC-BS9NtNUDCU2DV0,24236
163
+ django_ledger/models/transactions.py,sha256=kOL7s-hiRc6iqS7J62bVJY6ikja9Q8WdkRq0FT0zO2U,22722
164
164
  django_ledger/models/unit.py,sha256=x5FFJXgOi1OdajQejIakW6wGY4DjrJhL3S0Pm5OimMk,8074
165
165
  django_ledger/models/utils.py,sha256=3gkdCrfJp9qwN3Sf8R96AliilzwcKBm31UEao4WJO9o,8436
166
166
  django_ledger/models/vendor.py,sha256=akJCO86GIwjlZ_jPUZCDXlMeuJe-8zKTm-52aJXGFpg,11320
@@ -411,14 +411,14 @@ django_ledger/views/invoice.py,sha256=iUzTG-EbdYqNX-eYwHBnQRUD_1wTOGutw0BfDMKcI6
411
411
  django_ledger/views/item.py,sha256=FY53vk_giTRgvJ47FRqChQ8vyDYPDp4DGTvVhGAb36E,21347
412
412
  django_ledger/views/journal_entry.py,sha256=21kuiRBlhlkgv8xZKM4mj9djv0Fu0BhB80QOEOHCa-w,12135
413
413
  django_ledger/views/ledger.py,sha256=Yk6uDoYhJs5vf5JRqsy8n0nUNDEHk7NzjR1PglyqaAM,12647
414
- django_ledger/views/mixins.py,sha256=pXiEEen4rKrAluaROMAZC7nLR967LUV5fOiOAfq22tY,21966
414
+ django_ledger/views/mixins.py,sha256=0hbpYeXAXQd1PoHetJjBcpie2AYkS_8eteVLfszQFT4,22410
415
415
  django_ledger/views/purchase_order.py,sha256=1J3u4QnCkM7z1Y6DePijVdM67x4CQgfmQJcs3Y4kclU,21082
416
416
  django_ledger/views/transactions.py,sha256=5taQRGLSMkM_N8paQJ07HMspI_Nl7PawF8OohCiRmao,206
417
417
  django_ledger/views/unit.py,sha256=_RgPJO9mR6v5ohBXlnL3T8nTWgS1lwlCvERQcHk0wHE,10232
418
418
  django_ledger/views/vendor.py,sha256=gUdBPTFLeSwlNfdHSA1KFdE_y3QpwpkFhEB0r3-UYdI,3461
419
- django_ledger-0.6.0.2.dist-info/AUTHORS.md,sha256=SRM2cynD89ZfEsL09zrbUVeO17r9zE2ZM7y6ReMqVRo,713
420
- django_ledger-0.6.0.2.dist-info/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
421
- django_ledger-0.6.0.2.dist-info/METADATA,sha256=lx74R33LSCnxzSR4EcoICDKCz8vpi04rr1d31KbzoVg,9643
422
- django_ledger-0.6.0.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
423
- django_ledger-0.6.0.2.dist-info/top_level.txt,sha256=0U3SjF63ND36grQNWDONVe-T9-T07lFl5e6QkG7bR2E,44
424
- django_ledger-0.6.0.2.dist-info/RECORD,,
419
+ django_ledger-0.6.1.dist-info/AUTHORS.md,sha256=SRM2cynD89ZfEsL09zrbUVeO17r9zE2ZM7y6ReMqVRo,713
420
+ django_ledger-0.6.1.dist-info/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
421
+ django_ledger-0.6.1.dist-info/METADATA,sha256=eHzjHHjGze0fWBZszdinvMyE4tx-9EcYrzrGuDL2Yhg,9641
422
+ django_ledger-0.6.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
423
+ django_ledger-0.6.1.dist-info/top_level.txt,sha256=0U3SjF63ND36grQNWDONVe-T9-T07lFl5e6QkG7bR2E,44
424
+ django_ledger-0.6.1.dist-info/RECORD,,