django-ledger 0.8.2.2__py3-none-any.whl → 0.8.2.3__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 +1 -1
- django_ledger/forms/data_import.py +44 -4
- django_ledger/models/__init__.py +1 -0
- django_ledger/models/data_import.py +130 -54
- django_ledger/models/receipt.py +2 -2
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html +8 -6
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html +0 -2
- django_ledger/templates/django_ledger/receipt/receipt_detail.html +4 -2
- django_ledger/views/data_import.py +11 -7
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/METADATA +1 -1
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/RECORD +15 -15
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/WHEEL +0 -0
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/licenses/AUTHORS.md +0 -0
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/licenses/LICENSE +0 -0
- {django_ledger-0.8.2.2.dist-info → django_ledger-0.8.2.3.dist-info}/top_level.txt +0 -0
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.8.2.
|
|
9
|
+
__version__ = '0.8.2.3'
|
|
10
10
|
__license__ = 'GPLv3 License'
|
|
11
11
|
|
|
12
12
|
__author__ = 'Miguel Sanda'
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from itertools import groupby
|
|
2
|
+
|
|
1
3
|
from django import forms
|
|
2
4
|
from django.forms import (
|
|
3
5
|
ModelForm,
|
|
@@ -140,7 +142,7 @@ class StagedTransactionModelForm(ModelForm):
|
|
|
140
142
|
self.fields['tx_split'].disabled = True
|
|
141
143
|
|
|
142
144
|
if not staged_tx_model.can_unbundle():
|
|
143
|
-
|
|
145
|
+
self.fields['bundle_split'].widget = HiddenInput()
|
|
144
146
|
self.fields['bundle_split'].disabled = True
|
|
145
147
|
|
|
146
148
|
def clean_account_model(self):
|
|
@@ -160,13 +162,42 @@ class StagedTransactionModelForm(ModelForm):
|
|
|
160
162
|
def clean_tx_import(self):
|
|
161
163
|
staged_txs_model: StagedTransactionModel = self.instance
|
|
162
164
|
if staged_txs_model.is_children():
|
|
163
|
-
|
|
165
|
+
parent_form = self.BASE_FORMSET_INSTANCE.FORMS_BY_ID[staged_txs_model.parent_id]
|
|
166
|
+
if all(
|
|
167
|
+
[
|
|
168
|
+
any(
|
|
169
|
+
[
|
|
170
|
+
staged_txs_model.is_child_not_bundled_has_receipt(),
|
|
171
|
+
staged_txs_model.is_child_not_bundled_no_receipt(),
|
|
172
|
+
]
|
|
173
|
+
),
|
|
174
|
+
parent_form.cleaned_data['tx_import'] is True,
|
|
175
|
+
]
|
|
176
|
+
):
|
|
177
|
+
return True
|
|
164
178
|
return self.cleaned_data['tx_import']
|
|
165
179
|
|
|
180
|
+
def clean_bundle_split(self):
|
|
181
|
+
staged_txs_model: StagedTransactionModel = self.instance
|
|
182
|
+
if staged_txs_model.is_single():
|
|
183
|
+
return True
|
|
184
|
+
if staged_txs_model.is_children():
|
|
185
|
+
parent_form = self.BASE_FORMSET_INSTANCE.FORMS_BY_ID[staged_txs_model.parent.uuid]
|
|
186
|
+
return parent_form.cleaned_data['bundle_split']
|
|
187
|
+
return self.cleaned_data['bundle_split']
|
|
188
|
+
|
|
166
189
|
def clean(self):
|
|
167
190
|
if self.cleaned_data['tx_import'] and self.cleaned_data['tx_split']:
|
|
168
191
|
raise ValidationError(message=_('Cannot import and split at the same time'))
|
|
169
192
|
|
|
193
|
+
def has_changed(self):
|
|
194
|
+
has_changed = super().has_changed()
|
|
195
|
+
staged_txs_model: StagedTransactionModel = self.instance
|
|
196
|
+
if not has_changed and staged_txs_model.is_children():
|
|
197
|
+
parent_form = self.BASE_FORMSET_INSTANCE.FORMS_BY_ID[staged_txs_model.parent.uuid]
|
|
198
|
+
return parent_form.has_changed()
|
|
199
|
+
return has_changed
|
|
200
|
+
|
|
170
201
|
class Meta:
|
|
171
202
|
model = StagedTransactionModel
|
|
172
203
|
fields = [
|
|
@@ -244,8 +275,8 @@ class BaseStagedTransactionModelFormSet(BaseModelFormSet):
|
|
|
244
275
|
self.unit_model_qs = entity_model.entityunitmodel_set.all()
|
|
245
276
|
self.UNIT_MODEL_CHOICES = [(None, '----')] + [(u.uuid, u) for i, u in enumerate(self.unit_model_qs)]
|
|
246
277
|
|
|
247
|
-
self.VENDOR_MODEL_QS = entity_model.vendormodel_set.visible()
|
|
248
|
-
self.CUSTOMER_MODEL_QS = entity_model.customermodel_set.visible()
|
|
278
|
+
self.VENDOR_MODEL_QS = entity_model.vendormodel_set.visible().order_by('vendor_name')
|
|
279
|
+
self.CUSTOMER_MODEL_QS = entity_model.customermodel_set.visible().order_by('customer_name')
|
|
249
280
|
|
|
250
281
|
self.VENDOR_CHOICES = [(None, '-----')] + [(str(v.uuid), v) for v in self.VENDOR_MODEL_QS]
|
|
251
282
|
self.CUSTOMER_CHOICES = [(None, '-----')] + [(str(c.uuid), c) for c in self.CUSTOMER_MODEL_QS]
|
|
@@ -253,6 +284,15 @@ class BaseStagedTransactionModelFormSet(BaseModelFormSet):
|
|
|
253
284
|
self.VENDOR_MAP = dict(self.VENDOR_CHOICES)
|
|
254
285
|
self.CUSTOMER_MAP = dict(self.CUSTOMER_CHOICES)
|
|
255
286
|
|
|
287
|
+
self.FORMS_BY_ID = {
|
|
288
|
+
f.instance.uuid: f for f in self.forms if getattr(f, 'instance', None) and getattr(f.instance, 'uuid', None)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
form_children = [(f.instance.parent_id, f.instance.uuid) for f in self.forms if f.instance.parent_id]
|
|
292
|
+
form_children.sort(key=lambda f: f[0])
|
|
293
|
+
|
|
294
|
+
self.FORM_CHILDREN = {g: list(j[1] for j in p) for g, p in groupby(form_children, key=lambda i: i[0])}
|
|
295
|
+
|
|
256
296
|
def get_form_kwargs(self, index):
|
|
257
297
|
return {
|
|
258
298
|
'base_formset_instance': self,
|
django_ledger/models/__init__.py
CHANGED
|
@@ -15,5 +15,6 @@ from django_ledger.models.unit import *
|
|
|
15
15
|
from django_ledger.models.purchase_order import *
|
|
16
16
|
from django_ledger.models.closing_entry import *
|
|
17
17
|
from django_ledger.models.entity import *
|
|
18
|
+
|
|
18
19
|
from django_ledger.models.data_import import *
|
|
19
20
|
from django_ledger.models.receipt import *
|
|
@@ -16,7 +16,7 @@ from decimal import Decimal
|
|
|
16
16
|
from typing import Dict, List, Optional, Set, Union
|
|
17
17
|
from uuid import UUID, uuid4
|
|
18
18
|
|
|
19
|
-
from django.core.exceptions import
|
|
19
|
+
from django.core.exceptions import ValidationError
|
|
20
20
|
from django.db import models, transaction
|
|
21
21
|
from django.db.models import (
|
|
22
22
|
BooleanField,
|
|
@@ -432,16 +432,31 @@ class StagedTransactionModelQuerySet(QuerySet):
|
|
|
432
432
|
|
|
433
433
|
This method filters the objects in the queryset to determine whether there
|
|
434
434
|
are any transactions that are pending (i.e., have a null transaction_model).
|
|
435
|
-
|
|
436
|
-
|
|
435
|
+
Additionally, it includes parent transactions (not bundled) that have at least
|
|
436
|
+
one child transaction still pending import.
|
|
437
437
|
|
|
438
438
|
Returns
|
|
439
439
|
-------
|
|
440
440
|
QuerySet
|
|
441
|
-
A QuerySet containing objects with a null `transaction_model
|
|
441
|
+
A QuerySet containing objects with a null `transaction_model`, or parent
|
|
442
|
+
transactions (not bundled) with pending children.
|
|
442
443
|
|
|
443
444
|
"""
|
|
444
|
-
|
|
445
|
+
parents_with_pending_children = Q(
|
|
446
|
+
parent__isnull=True, bundle_split=False, children_mapping_done=False, children_import_pending_count__gt=0
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
return self.filter(
|
|
450
|
+
Q(
|
|
451
|
+
transaction_model__isnull=True,
|
|
452
|
+
)
|
|
453
|
+
| parents_with_pending_children
|
|
454
|
+
).exclude(
|
|
455
|
+
bundle_split=False,
|
|
456
|
+
transaction_model__isnull=True,
|
|
457
|
+
children_count__gt=0,
|
|
458
|
+
children_import_pending_count=0
|
|
459
|
+
)
|
|
445
460
|
|
|
446
461
|
def is_imported(self):
|
|
447
462
|
"""
|
|
@@ -449,13 +464,19 @@ class StagedTransactionModelQuerySet(QuerySet):
|
|
|
449
464
|
related transaction model. This function checks whether the `transaction_model`
|
|
450
465
|
field in the related objects is non-null.
|
|
451
466
|
|
|
467
|
+
Additionally, it includes non-bundled parent transactions only if they have at
|
|
468
|
+
least one imported child (i.e., a child with a non-null `transaction_model`).
|
|
469
|
+
This ensures a parent is not considered imported until at least one child is
|
|
470
|
+
imported.
|
|
471
|
+
|
|
452
472
|
Returns
|
|
453
473
|
-------
|
|
454
474
|
QuerySet
|
|
455
|
-
A filtered queryset containing
|
|
456
|
-
|
|
475
|
+
A filtered queryset containing objects where the `transaction_model` is not
|
|
476
|
+
null, plus non-bundled parents that have at least one imported child.
|
|
457
477
|
"""
|
|
458
|
-
|
|
478
|
+
parents_with_imported_children = Q(parent__isnull=True, bundle_split=False, imported_count__gt=0)
|
|
479
|
+
return self.filter(Q(transaction_model__isnull=False) | parents_with_imported_children)
|
|
459
480
|
|
|
460
481
|
def is_parent(self):
|
|
461
482
|
"""
|
|
@@ -548,6 +569,7 @@ class StagedTransactionModelManager(Manager):
|
|
|
548
569
|
entity_unit=F('transaction_model__journal_entry__entity_unit__name'),
|
|
549
570
|
children_count=Count('split_transaction_set'),
|
|
550
571
|
children_mapped_count=Count('split_transaction_set__account_model__uuid'),
|
|
572
|
+
imported_count=Count('split_transaction_set__transaction_model_id'),
|
|
551
573
|
total_amount_split=Coalesce(
|
|
552
574
|
Sum('split_transaction_set__amount_split'),
|
|
553
575
|
Value(value=0.00, output_field=DecimalField()),
|
|
@@ -560,6 +582,7 @@ class StagedTransactionModelManager(Manager):
|
|
|
560
582
|
)
|
|
561
583
|
.annotate(
|
|
562
584
|
children_mapping_pending_count=F('children_count') - F('children_mapped_count'),
|
|
585
|
+
children_import_pending_count=F('imported_count') - F('children_count'),
|
|
563
586
|
)
|
|
564
587
|
.annotate(
|
|
565
588
|
children_mapping_done=Case(
|
|
@@ -602,7 +625,7 @@ class StagedTransactionModelManager(Manager):
|
|
|
602
625
|
),
|
|
603
626
|
then=True,
|
|
604
627
|
),
|
|
605
|
-
# is
|
|
628
|
+
# is parent, mapped and all parent amount is split...
|
|
606
629
|
When(
|
|
607
630
|
condition=(
|
|
608
631
|
# no receipt type selected...
|
|
@@ -611,12 +634,12 @@ class StagedTransactionModelManager(Manager):
|
|
|
611
634
|
Q(children_count__gt=0)
|
|
612
635
|
& Q(bundle_split=True)
|
|
613
636
|
& Q(receipt_type__isnull=True)
|
|
614
|
-
& Q(
|
|
637
|
+
& Q(children_mapping_done=True)
|
|
615
638
|
& Q(total_amount_split__exact=F('amount'))
|
|
616
639
|
& Q(parent__isnull=True)
|
|
617
640
|
& Q(transaction_model__isnull=True)
|
|
618
641
|
& Q(customer_model__isnull=True)
|
|
619
|
-
& Q(vendor_model__isnull=
|
|
642
|
+
& Q(vendor_model__isnull=True)
|
|
620
643
|
)
|
|
621
644
|
# BUNDLED...
|
|
622
645
|
# a receipt type is assigned... at least a customer or vendor is selected...
|
|
@@ -643,10 +666,19 @@ class StagedTransactionModelManager(Manager):
|
|
|
643
666
|
& Q(receipt_type__isnull=True)
|
|
644
667
|
& Q(vendor_model__isnull=True)
|
|
645
668
|
& Q(customer_model__isnull=True)
|
|
646
|
-
& Q(
|
|
669
|
+
& Q(children_mapping_done=True)
|
|
647
670
|
& Q(total_amount_split__exact=F('amount'))
|
|
648
671
|
& Q(transaction_model__isnull=True)
|
|
649
672
|
)
|
|
673
|
+
| (
|
|
674
|
+
Q(children_count__exact=0)
|
|
675
|
+
& Q(parent__isnull=False)
|
|
676
|
+
& Q(bundle_split=False)
|
|
677
|
+
& Q(receipt_type__isnull=False)
|
|
678
|
+
& (Q(vendor_model__isnull=False) | Q(customer_model__isnull=False))
|
|
679
|
+
& Q(children_mapping_done=True)
|
|
680
|
+
& Q(transaction_model__isnull=True)
|
|
681
|
+
)
|
|
650
682
|
),
|
|
651
683
|
then=True,
|
|
652
684
|
),
|
|
@@ -905,10 +937,12 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
905
937
|
return [
|
|
906
938
|
{
|
|
907
939
|
'account': self.account_model,
|
|
908
|
-
'amount': abs(self.amount),
|
|
909
|
-
'amount_staged': self.amount,
|
|
940
|
+
'amount': abs(self.amount if not self.is_children() else self.amount_split),
|
|
941
|
+
'amount_staged': self.amount if not self.is_children() else self.amount_split,
|
|
910
942
|
'unit_model': self.unit_model,
|
|
911
|
-
'tx_type': CREDIT
|
|
943
|
+
'tx_type': CREDIT
|
|
944
|
+
if not (self.amount if not self.is_children() else self.amount_split) < 0.00
|
|
945
|
+
else DEBIT,
|
|
912
946
|
'description': self.name,
|
|
913
947
|
'staged_tx_model': self,
|
|
914
948
|
}
|
|
@@ -996,34 +1030,57 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
996
1030
|
properly. This method checks whether both `account_model_id` and
|
|
997
1031
|
`transaction_model_id` are set.
|
|
998
1032
|
|
|
1033
|
+
Additionally, a parent transaction that is not bundled will be considered
|
|
1034
|
+
imported for listing purposes if it has at least one child transaction that is
|
|
1035
|
+
still pending import. This allows a parent to appear in both imported and
|
|
1036
|
+
pending states when its children are not fully imported.
|
|
1037
|
+
|
|
999
1038
|
Returns
|
|
1000
1039
|
-------
|
|
1001
1040
|
bool
|
|
1002
1041
|
True if both `account_model_id` and `transaction_model_id` are not None,
|
|
1003
|
-
indicating that the models have been successfully imported
|
|
1042
|
+
indicating that the models have been successfully imported; or if this is a
|
|
1043
|
+
non-bundled parent with at least one pending child. False otherwise.
|
|
1004
1044
|
"""
|
|
1005
|
-
|
|
1045
|
+
own_imported = all(
|
|
1006
1046
|
[
|
|
1007
1047
|
self.account_model_id is not None,
|
|
1008
1048
|
self.transaction_model_id is not None,
|
|
1009
1049
|
]
|
|
1010
1050
|
)
|
|
1051
|
+
parent_with_imported_child = all(
|
|
1052
|
+
[
|
|
1053
|
+
self.is_parent(),
|
|
1054
|
+
not self.is_bundled(),
|
|
1055
|
+
self.split_transaction_set.filter(transaction_model__isnull=False).exists(),
|
|
1056
|
+
]
|
|
1057
|
+
)
|
|
1058
|
+
return own_imported or parent_with_imported_child
|
|
1011
1059
|
|
|
1012
1060
|
def is_pending(self) -> bool:
|
|
1013
1061
|
"""
|
|
1014
1062
|
Determine if the transaction is pending.
|
|
1015
1063
|
|
|
1016
1064
|
A transaction is considered pending if it has not been assigned a
|
|
1017
|
-
`transaction_model_id`.
|
|
1018
|
-
|
|
1065
|
+
`transaction_model_id`. Additionally, a parent transaction that is not
|
|
1066
|
+
bundled is also considered pending if any of its children are still
|
|
1067
|
+
pending import. This allows a parent to be both imported and pending
|
|
1068
|
+
while its children are not fully imported.
|
|
1019
1069
|
|
|
1020
1070
|
Returns
|
|
1021
1071
|
-------
|
|
1022
1072
|
bool
|
|
1023
1073
|
True if the transaction is pending (i.e., `transaction_model_id`
|
|
1024
|
-
is None),
|
|
1074
|
+
is None), or this is a non-bundled parent with at least one pending
|
|
1075
|
+
child. False otherwise.
|
|
1025
1076
|
"""
|
|
1026
|
-
return self.transaction_model_id is None
|
|
1077
|
+
return self.transaction_model_id is None or all(
|
|
1078
|
+
[
|
|
1079
|
+
self.is_parent(),
|
|
1080
|
+
not self.is_bundled(),
|
|
1081
|
+
self.split_transaction_set.filter(transaction_model__isnull=True).exists(),
|
|
1082
|
+
]
|
|
1083
|
+
)
|
|
1027
1084
|
|
|
1028
1085
|
def is_mapped(self) -> bool:
|
|
1029
1086
|
"""
|
|
@@ -1288,8 +1345,6 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1288
1345
|
return False
|
|
1289
1346
|
|
|
1290
1347
|
def has_receipt(self) -> bool:
|
|
1291
|
-
# if self.is_children() and self.is_bundled():
|
|
1292
|
-
# return self.parent.receipt_type is not None
|
|
1293
1348
|
return self.receipt_type is not None
|
|
1294
1349
|
|
|
1295
1350
|
def has_mapped_receipt(self) -> bool:
|
|
@@ -1318,9 +1373,7 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1318
1373
|
return False
|
|
1319
1374
|
|
|
1320
1375
|
def can_unbundle(self) -> bool:
|
|
1321
|
-
if any([
|
|
1322
|
-
not self.is_single()
|
|
1323
|
-
]):
|
|
1376
|
+
if any([not self.is_single()]):
|
|
1324
1377
|
return True
|
|
1325
1378
|
return False
|
|
1326
1379
|
|
|
@@ -1341,7 +1394,8 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1341
1394
|
[
|
|
1342
1395
|
self.is_single(),
|
|
1343
1396
|
self.is_parent_is_bundled_has_receipt(),
|
|
1344
|
-
self.is_parent_is_bundled_no_receipt()
|
|
1397
|
+
self.is_parent_is_bundled_no_receipt(),
|
|
1398
|
+
self.is_parent_not_bundled_no_receipt(),
|
|
1345
1399
|
]
|
|
1346
1400
|
):
|
|
1347
1401
|
return True
|
|
@@ -1454,12 +1508,20 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1454
1508
|
|
|
1455
1509
|
if not ready_to_import:
|
|
1456
1510
|
return False
|
|
1511
|
+
is_role_valid = self.is_role_mapping_valid(raise_exception=False)
|
|
1512
|
+
if not is_role_valid:
|
|
1513
|
+
return False
|
|
1457
1514
|
|
|
1458
|
-
if ready_to_import:
|
|
1459
|
-
|
|
1460
|
-
if is_role_valid:
|
|
1515
|
+
if ready_to_import and is_role_valid:
|
|
1516
|
+
if self.is_bundled():
|
|
1461
1517
|
return True
|
|
1462
1518
|
|
|
1519
|
+
# not bundled....
|
|
1520
|
+
else:
|
|
1521
|
+
if any([self.is_child_not_bundled_no_receipt(), self.is_child_not_bundled_has_receipt()]):
|
|
1522
|
+
return True
|
|
1523
|
+
return False
|
|
1524
|
+
|
|
1463
1525
|
can_split_into_je = getattr(self, 'can_split_into_je')
|
|
1464
1526
|
if can_split_into_je and as_split:
|
|
1465
1527
|
return True
|
|
@@ -1472,10 +1534,13 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1472
1534
|
if ready_to_import:
|
|
1473
1535
|
if self.is_transfer():
|
|
1474
1536
|
return True
|
|
1475
|
-
if any(
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1537
|
+
if any(
|
|
1538
|
+
[
|
|
1539
|
+
self.is_single_has_receipt(),
|
|
1540
|
+
self.is_parent_is_bundled_has_receipt(),
|
|
1541
|
+
self.is_child_not_bundled_has_receipt(),
|
|
1542
|
+
]
|
|
1543
|
+
):
|
|
1479
1544
|
return True
|
|
1480
1545
|
return False
|
|
1481
1546
|
|
|
@@ -1619,10 +1684,15 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1619
1684
|
The journal entry activity if successfully retrieved or updated; otherwise,
|
|
1620
1685
|
returns the existing activity or None if no activity is present.
|
|
1621
1686
|
"""
|
|
1622
|
-
if (
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1687
|
+
if any(
|
|
1688
|
+
[
|
|
1689
|
+
force_update,
|
|
1690
|
+
self.is_single(),
|
|
1691
|
+
self.is_parent_is_bundled_no_receipt(),
|
|
1692
|
+
self.is_parent_is_bundled_has_receipt(),
|
|
1693
|
+
self.is_child_not_bundled_has_receipt(),
|
|
1694
|
+
self.is_child_not_bundled_no_receipt(),
|
|
1695
|
+
]
|
|
1626
1696
|
):
|
|
1627
1697
|
role_set = self.get_import_role_set()
|
|
1628
1698
|
if role_set is not None:
|
|
@@ -1761,14 +1831,11 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1761
1831
|
force_je_retrieval=False,
|
|
1762
1832
|
)
|
|
1763
1833
|
staged_to_save += [i['staged_tx_model'] for i in je_data]
|
|
1764
|
-
# staged_to_save = set(i['staged_tx_model'] for i in je_data)
|
|
1765
|
-
# for i in staged_to_save:
|
|
1766
|
-
# i.save(update_fields=['transaction_model', 'updated'])
|
|
1767
1834
|
staged_to_save = set(staged_to_save)
|
|
1768
1835
|
for i in staged_to_save:
|
|
1769
1836
|
i.save(update_fields=['transaction_model', 'updated'])
|
|
1770
1837
|
|
|
1771
|
-
def migrate_receipt(self, receipt_date: Optional[date | datetime] = None):
|
|
1838
|
+
def migrate_receipt(self, receipt_date: Optional[date | datetime] = None, split_amount: bool = False):
|
|
1772
1839
|
if not self.can_migrate_receipt():
|
|
1773
1840
|
raise StagedTransactionModelValidationError(
|
|
1774
1841
|
'Migrate receipts can only be performed on receipt transactions. Use migrate_transactions() instead.'
|
|
@@ -1778,7 +1845,7 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1778
1845
|
|
|
1779
1846
|
with transaction.atomic():
|
|
1780
1847
|
receipt_model: ReceiptModel = self.generate_receipt_model(receipt_date=receipt_date, commit=True)
|
|
1781
|
-
receipt_model.migrate_receipt()
|
|
1848
|
+
receipt_model.migrate_receipt(split_amount=split_amount)
|
|
1782
1849
|
|
|
1783
1850
|
def generate_receipt_model(self, receipt_date: Optional[date] = None, commit: bool = False) -> ReceiptModel:
|
|
1784
1851
|
if receipt_date:
|
|
@@ -1791,7 +1858,7 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1791
1858
|
receipt_model.configure(
|
|
1792
1859
|
receipt_date=receipt_date,
|
|
1793
1860
|
entity_model=self.entity_slug,
|
|
1794
|
-
amount=abs(self.amount),
|
|
1861
|
+
amount=abs(self.amount_split if self.is_children() else self.amount),
|
|
1795
1862
|
unit_model=self.unit_model,
|
|
1796
1863
|
receipt_type=self.receipt_type,
|
|
1797
1864
|
vendor_model=self.vendor_model if self.is_expense() or self.is_debt_payment() else None,
|
|
@@ -1805,12 +1872,12 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1805
1872
|
return receipt_model
|
|
1806
1873
|
|
|
1807
1874
|
def can_undo_import(self):
|
|
1875
|
+
if self.transaction_model_id is None:
|
|
1876
|
+
return False
|
|
1808
1877
|
if all([self.is_children(), self.is_bundled()]):
|
|
1809
1878
|
return False
|
|
1810
|
-
|
|
1811
1879
|
return True
|
|
1812
1880
|
|
|
1813
|
-
# UNDO
|
|
1814
1881
|
def undo_import(self, raise_exception: bool = True):
|
|
1815
1882
|
"""
|
|
1816
1883
|
Undo import operation for a staged transaction. This method handles the deletion
|
|
@@ -1832,10 +1899,7 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1832
1899
|
|
|
1833
1900
|
with transaction.atomic():
|
|
1834
1901
|
# Receipt import case...
|
|
1835
|
-
|
|
1836
|
-
receipt_model = self.receiptmodel
|
|
1837
|
-
except ObjectDoesNotExist:
|
|
1838
|
-
receipt_model = None
|
|
1902
|
+
receipt_model = getattr(self, 'receiptmodel', None)
|
|
1839
1903
|
|
|
1840
1904
|
if receipt_model is not None:
|
|
1841
1905
|
receipt_model.delete()
|
|
@@ -1850,10 +1914,10 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1850
1914
|
tx_model = self.transaction_model
|
|
1851
1915
|
journal_entry_model = tx_model.journal_entry
|
|
1852
1916
|
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1917
|
+
journal_entry_model.unpost(raise_exception=False)
|
|
1918
|
+
journal_entry_model.unlock(raise_exception=False)
|
|
1919
|
+
|
|
1920
|
+
journal_entry_model.delete()
|
|
1857
1921
|
|
|
1858
1922
|
self.transaction_model = None
|
|
1859
1923
|
self.save(update_fields=['transaction_model', 'updated'])
|
|
@@ -1862,6 +1926,11 @@ class StagedTransactionModelAbstract(CreateUpdateMixIn):
|
|
|
1862
1926
|
if raise_exception:
|
|
1863
1927
|
raise StagedTransactionModelValidationError(message=_('Nothing to undo for this staged transaction.'))
|
|
1864
1928
|
|
|
1929
|
+
def can_delete(self) -> bool:
|
|
1930
|
+
if self.is_children():
|
|
1931
|
+
return True
|
|
1932
|
+
return False
|
|
1933
|
+
|
|
1865
1934
|
def clean(self, verify: bool = False):
|
|
1866
1935
|
if self.has_children():
|
|
1867
1936
|
self.amount_split = None
|
|
@@ -2001,3 +2070,10 @@ def stagedtransactionmodel_presave(instance: StagedTransactionModel, **kwargs):
|
|
|
2001
2070
|
|
|
2002
2071
|
|
|
2003
2072
|
pre_save.connect(stagedtransactionmodel_presave, sender=StagedTransactionModel)
|
|
2073
|
+
|
|
2074
|
+
|
|
2075
|
+
def stagedtransactionmodel_predelete(instance: StagedTransactionModel, **kwargs):
|
|
2076
|
+
if not instance.can_delete():
|
|
2077
|
+
raise StagedTransactionModelValidationError(
|
|
2078
|
+
message=_('Cannot delete parent Staged Transactions.'),
|
|
2079
|
+
)
|
django_ledger/models/receipt.py
CHANGED
|
@@ -825,7 +825,7 @@ class ReceiptModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn, IOMixIn):
|
|
|
825
825
|
]
|
|
826
826
|
)
|
|
827
827
|
|
|
828
|
-
def migrate_receipt(self):
|
|
828
|
+
def migrate_receipt(self, split_amount: bool = False):
|
|
829
829
|
"""Post staged transactions into the ledger as journal entries.
|
|
830
830
|
|
|
831
831
|
This method commits staged transactions linked to the receipt into the
|
|
@@ -846,7 +846,7 @@ class ReceiptModelAbstract(CreateUpdateMixIn, MarkdownNotesMixIn, IOMixIn):
|
|
|
846
846
|
message='Must have VendorModel or CustomerModel, not both.',
|
|
847
847
|
)
|
|
848
848
|
|
|
849
|
-
commit_dict = self.staged_transaction_model.commit_dict(split_txs=
|
|
849
|
+
commit_dict = self.staged_transaction_model.commit_dict(split_txs=split_amount)
|
|
850
850
|
ledger_model = self.ledger_model
|
|
851
851
|
staged_to_save = list()
|
|
852
852
|
for je_data in commit_dict:
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
{{ imported_tx.get_activity_display }}
|
|
51
51
|
{% endif %}</td>
|
|
52
52
|
<td>{% if imported_tx.entity_unit %}{{ imported_tx.entity_unit }}{% endif %}</td>
|
|
53
|
-
<td>{{ imported_tx.account_model }}</td>
|
|
54
|
-
<td>{{ imported_tx.transaction_model }}</td>
|
|
53
|
+
<td>{{ imported_tx.account_model | default:'' }}</td>
|
|
54
|
+
<td>{{ imported_tx.transaction_model | default:'' }}</td>
|
|
55
55
|
<td class="has-text-centered">
|
|
56
56
|
<div class="dropdown is-hoverable is-right">
|
|
57
57
|
<div class="dropdown-trigger">
|
|
@@ -63,9 +63,11 @@
|
|
|
63
63
|
</div>
|
|
64
64
|
<div class="dropdown-menu" id="actions-{{ imported_tx.uuid }}" role="menu">
|
|
65
65
|
<div class="dropdown-content">
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
{% if not imported_tx.is_parent and not imported_tx.is_bundled %}
|
|
67
|
+
<a href="{% url 'django_ledger:je-detail' entity_slug=import_job_model.entity_slug ledger_pk=imported_tx.transaction_model.journal_entry.ledger_id je_pk=imported_tx.transaction_model.journal_entry_id %}"
|
|
68
|
+
class="dropdown-item">{% trans 'View JE' %}</a>
|
|
69
|
+
{% endif %}
|
|
70
|
+
{% if imported_tx.receipt_uuid %}
|
|
69
71
|
<a href="{% url 'django_ledger:receipt-detail' entity_slug=import_job_model.entity_slug receipt_pk=imported_tx.receiptmodel.uuid %}"
|
|
70
72
|
class="dropdown-item">{% trans 'View Receipt' %}</a>
|
|
71
73
|
{% endif %}
|
|
@@ -77,8 +79,8 @@
|
|
|
77
79
|
<button type="submit"
|
|
78
80
|
class="dropdown-item has-text-danger">{% trans 'Undo Import' %}</button>
|
|
79
81
|
</form>
|
|
82
|
+
</div>
|
|
80
83
|
{% endif %}
|
|
81
|
-
</div>
|
|
82
84
|
</div>
|
|
83
85
|
</div>
|
|
84
86
|
</td>
|
|
@@ -78,8 +78,6 @@
|
|
|
78
78
|
<td class="has-text-centered">
|
|
79
79
|
{{ txf.customer_model }}
|
|
80
80
|
{{ txf.vendor_model }}
|
|
81
|
-
{# {{ txf.instance.can_migrate }}#}
|
|
82
|
-
{# {{ txf.instance.ready_to_import }}#}
|
|
83
81
|
</td>
|
|
84
82
|
<td class="has-text-centered">{{ txf.tx_import }}</td>
|
|
85
83
|
<td class="has-text-centered">{{ txf.bundle_split }}</td>
|
|
@@ -58,8 +58,10 @@
|
|
|
58
58
|
<a href="{{ tx.get_journal_entry_detail_url }}">{{ tx.journal_entry.description|default:'—' }}</a>
|
|
59
59
|
</td>
|
|
60
60
|
<td>{{ tx.account.code }} - {{ tx.account.name }}</td>
|
|
61
|
-
<td class="has-text-right">{%
|
|
62
|
-
|
|
61
|
+
<td class="has-text-right">{% currency_symbol %}{% if tx.is_debit %}
|
|
62
|
+
{{ tx.amount | currency_format }}{% endif %}</td>
|
|
63
|
+
<td class="has-text-right">{% currency_symbol %}{% if tx.is_credit %}
|
|
64
|
+
{{ tx.amount | currency_format }}{% endif %}</td>
|
|
63
65
|
<td>{{ tx.journal_entry.entity_unit.name|default:'—' }}</td>
|
|
64
66
|
</tr>
|
|
65
67
|
{% endfor %}
|
|
@@ -210,17 +210,18 @@ class DataImportJobDetailView(ImportJobModelViewBaseView, DetailView):
|
|
|
210
210
|
for tx_form in txs_formset:
|
|
211
211
|
if tx_form.has_changed():
|
|
212
212
|
staged_transaction_model: StagedTransactionModel = tx_form.instance
|
|
213
|
+
|
|
213
214
|
is_split = tx_form.cleaned_data['tx_split'] is True
|
|
215
|
+
is_import = tx_form.cleaned_data['tx_import'] is True
|
|
216
|
+
is_bundled = tx_form.cleaned_data['bundle_split'] is True
|
|
217
|
+
|
|
214
218
|
if is_split:
|
|
215
219
|
staged_transaction_model.add_split()
|
|
216
|
-
|
|
217
|
-
is_import = tx_form.cleaned_data['tx_import']
|
|
218
|
-
if is_import:
|
|
219
|
-
# all entries in split will be going so the same journal entry... (same unit...)
|
|
220
|
-
is_bundled = tx_form.cleaned_data['bundle_split']
|
|
220
|
+
elif is_import:
|
|
221
221
|
if staged_transaction_model.can_migrate_receipt():
|
|
222
222
|
staged_transaction_model.migrate_receipt(
|
|
223
|
-
receipt_date=staged_transaction_model.date_posted
|
|
223
|
+
receipt_date=staged_transaction_model.date_posted,
|
|
224
|
+
split_amount=not is_bundled,
|
|
224
225
|
)
|
|
225
226
|
else:
|
|
226
227
|
staged_transaction_model.migrate_transactions(split_txs=not is_bundled)
|
|
@@ -276,9 +277,12 @@ class ImportJobModelResetView(ImportJobModelViewBaseView, DetailView):
|
|
|
276
277
|
|
|
277
278
|
def post(self, request, **kwargs):
|
|
278
279
|
import_job_model: ImportJobModel = self.get_object()
|
|
279
|
-
imported_staged_txs = import_job_model.stagedtransactionmodel_set.
|
|
280
|
+
imported_staged_txs = import_job_model.stagedtransactionmodel_set.all()
|
|
280
281
|
for staged_tx in imported_staged_txs:
|
|
281
282
|
staged_tx.undo_import(raise_exception=False)
|
|
283
|
+
if staged_tx.is_children():
|
|
284
|
+
staged_tx.delete()
|
|
285
|
+
|
|
282
286
|
|
|
283
287
|
return redirect(
|
|
284
288
|
to=import_job_model.get_data_import_url(),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-ledger
|
|
3
|
-
Version: 0.8.2.
|
|
3
|
+
Version: 0.8.2.3
|
|
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=
|
|
1
|
+
django_ledger/__init__.py,sha256=ZL-fuSwWwUj6jcETC_xzBKG2xCheCQcy4KfU6QD3v-U,382
|
|
2
2
|
django_ledger/apps.py,sha256=H-zEWUjKGakgSDSZmLIoXChZ2h6e0dth0ZO5SpoT-8U,163
|
|
3
3
|
django_ledger/context.py,sha256=OBNHHm6qlt3fBc1_EiOcbzwafsqJBXtdZY5ubW_gga0,301
|
|
4
4
|
django_ledger/exceptions.py,sha256=rML8sQQ0Hq-DYMLZ76dfw2RYSAsXWUoyHuyC_yP9o1o,491
|
|
@@ -18,7 +18,7 @@ django_ledger/forms/bill.py,sha256=u5zJWWq4huEsfqukHCCnlGEcUsArOQmrKyBcRtsSWCU,1
|
|
|
18
18
|
django_ledger/forms/chart_of_accounts.py,sha256=wymLQ8iLNPU_LgS79BOdMUapuLqoTvgqVdAyL1Pw0Ro,2414
|
|
19
19
|
django_ledger/forms/closing_entry.py,sha256=kJQtVqira0rpYvlmMlGAaV5L3Wz3XNXSgrcVfZ2VyLM,1948
|
|
20
20
|
django_ledger/forms/customer.py,sha256=xK1tlA1yYvZM2TWeSumcHOfmw0DiiIzgypOoXDK5fF4,2707
|
|
21
|
-
django_ledger/forms/data_import.py,sha256=
|
|
21
|
+
django_ledger/forms/data_import.py,sha256=4phvkT09Gl9xT6FAj3zdW8w1yvxgjbS3Ua6Eqzqrx0E,12390
|
|
22
22
|
django_ledger/forms/entity.py,sha256=b0QirmsFSnaM8YWDO4V6GQXfFgR_MLmdq27I2q2sGQ0,6880
|
|
23
23
|
django_ledger/forms/estimate.py,sha256=oGx4NbIkySA3a9r4bTNCz7t2swsTQgxuOSOdXIrXcZo,5064
|
|
24
24
|
django_ledger/forms/feedback.py,sha256=WUT-kI4uT6q5aqEYaDYwyIFfhXpmtwMv6qf9BFSYsDo,1850
|
|
@@ -71,7 +71,7 @@ django_ledger/migrations/0025_alter_billmodel_cash_account_and_more.py,sha256=8p
|
|
|
71
71
|
django_ledger/migrations/0026_stagedtransactionmodel_customer_model_and_more.py,sha256=qv2PFWhXgAHWGptb8Xgoq0O4TsGqJelnI0-BRSJqZBE,4470
|
|
72
72
|
django_ledger/migrations/0027_alter_accountmodel_role_alter_receiptmodel_amount_and_more.py,sha256=2lOHxOP6IvizjTwukN4GB0GWrROmDv_mdRM3wf6IXZo,7391
|
|
73
73
|
django_ledger/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
-
django_ledger/models/__init__.py,sha256=
|
|
74
|
+
django_ledger/models/__init__.py,sha256=AJTkUumUJzwg5RnbtuHikD7dqX4KaIYj7B8dZYtRz7E,852
|
|
75
75
|
django_ledger/models/accounts.py,sha256=Y0EuVy1xCELOLhIMXnku6VlWFC33JctK7NsnJ-L62QM,38924
|
|
76
76
|
django_ledger/models/bank_account.py,sha256=P-62wjQ94EneCseewDV2tyRt0ghlaEh1jFIowWJdHCU,8942
|
|
77
77
|
django_ledger/models/bill.py,sha256=a15MHAl5HSu536BsWwbcYnGXL8PGo14ToncVNktME2s,64469
|
|
@@ -79,7 +79,7 @@ django_ledger/models/chart_of_accounts.py,sha256=g7NWRCSoj4YFuOPBGUqgBVekwCU7xPO
|
|
|
79
79
|
django_ledger/models/closing_entry.py,sha256=zxoZOC2ymbrwyPOGPsKXXBwHDGegAtTnqDye0Y-mVAo,20625
|
|
80
80
|
django_ledger/models/coa_default.py,sha256=L3fHc-HvYo_gTvCWv5oZl-rWnH9ZPuloK-bw3_cICo0,27614
|
|
81
81
|
django_ledger/models/customer.py,sha256=JDlCII2r4Ebj08tYc2DfRVBWRb68Nw61ZRDGIEAUjvk,13375
|
|
82
|
-
django_ledger/models/data_import.py,sha256=
|
|
82
|
+
django_ledger/models/data_import.py,sha256=0vB8n9JwwlGCJ5lTsf14LGCru0RDdxFqQX4MPSmxXtY,79393
|
|
83
83
|
django_ledger/models/deprecations.py,sha256=49sLBeVhHMYSf3F3VPCE6_5iNZH1xmElWZsgGIGUErs,2275
|
|
84
84
|
django_ledger/models/entity.py,sha256=SN73ceuj3kNcfWCrLRZVoMUePGBl6j4SABkwr9OZg_Y,122092
|
|
85
85
|
django_ledger/models/estimate.py,sha256=0DmDs7U5WqaQM9xciuXKR29pGHaLT7z_QmlNvvzUy_0,59406
|
|
@@ -89,7 +89,7 @@ django_ledger/models/journal_entry.py,sha256=X3wRhYqOmDGcRZj4WYGCNDQhBBZ1hp5fnCc
|
|
|
89
89
|
django_ledger/models/ledger.py,sha256=hT5u9IHJy5vun9_bzcC5FKN8ocP0OGdR4RDDe3icgzo,29400
|
|
90
90
|
django_ledger/models/mixins.py,sha256=v5m7MwUcsndLctbTrrof-RSlMyc5tcQqRhcmPjJbOk4,54287
|
|
91
91
|
django_ledger/models/purchase_order.py,sha256=X5ZIfwTAMWUbqL79nQCWWltlOiKSEFGocfaWHK3i154,45128
|
|
92
|
-
django_ledger/models/receipt.py,sha256=
|
|
92
|
+
django_ledger/models/receipt.py,sha256=q5yT5v2c55sPyvIpweHoR6LY5hm7PXlybkAilSobWUQ,37352
|
|
93
93
|
django_ledger/models/signals.py,sha256=3cm_8--Jz-Jb0fPgrVmm5xx_jKFARV6_A29VDjqHeIw,1563
|
|
94
94
|
django_ledger/models/transactions.py,sha256=TmHqTVaPx3d0Flaab_cUbKfa7a1hEpkgbsdV6YZlyVc,26431
|
|
95
95
|
django_ledger/models/unit.py,sha256=iP7gMLCPV82uxsDIWa-BhdgLtm8FwGbQ_kOCSC-tJJo,10227
|
|
@@ -217,8 +217,8 @@ django_ledger/templates/django_ledger/data_import/import_job_create.html,sha256=
|
|
|
217
217
|
django_ledger/templates/django_ledger/data_import/import_job_delete.html,sha256=qgobtrI-WNYFqhn8de05mcD-FQ0UGSLT6ZoaBlblXAU,944
|
|
218
218
|
django_ledger/templates/django_ledger/data_import/import_job_update.html,sha256=ZDy391RSOXUq3keUs48QrVrI_ZicdNvDeLT_JacH17M,887
|
|
219
219
|
django_ledger/templates/django_ledger/data_import/tags/data_import_job_list_table.html,sha256=y_U1xixMC9YPR4aq6F_cNpyb-dZ5qcVh9D6HSN9Xpps,2919
|
|
220
|
-
django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html,sha256=
|
|
221
|
-
django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html,sha256=
|
|
220
|
+
django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html,sha256=NYck3UKL5-eLab_PV3wVnZKf0oaPisgha-2YghVrWd0,5416
|
|
221
|
+
django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html,sha256=93Pqi8bvLv_x4-cavBtAa6p7gKDn1_UnUjAvKwaatgY,4718
|
|
222
222
|
django_ledger/templates/django_ledger/entity/entitiy_list.html,sha256=onM9uaWTm2oQ00OPIH5ki2FEfgjx7_EIOT8akuAhQM4,1507
|
|
223
223
|
django_ledger/templates/django_ledger/entity/entity_create.html,sha256=TDayIv2qno7cT3xTCapKV6EZKcTTNfIMxXJFQmHHyz0,1387
|
|
224
224
|
django_ledger/templates/django_ledger/entity/entity_dashboard.html,sha256=7iQYLYsP_Q1S2wGcYcZUn3FWJBNJPxZ4OvGQjfctoiw,5435
|
|
@@ -301,7 +301,7 @@ django_ledger/templates/django_ledger/purchase_order/includes/po_table.html,sha2
|
|
|
301
301
|
django_ledger/templates/django_ledger/purchase_order/tags/po_item_table.html,sha256=2DK0aaqG4R-GsOr_I4mHVEI8O614FuggpEBN6r-jcu4,1998
|
|
302
302
|
django_ledger/templates/django_ledger/receipt/customer_receipt_report.html,sha256=Z2M4JnelzRRscVgA7jA3gWvDWMv9wiz5IiVVubqn98E,5197
|
|
303
303
|
django_ledger/templates/django_ledger/receipt/receipt_delete.html,sha256=yB5jHmFUOc1ZMulSU5uq8oc1jomRmIZA0aK91iF0Oxc,1226
|
|
304
|
-
django_ledger/templates/django_ledger/receipt/receipt_detail.html,sha256=
|
|
304
|
+
django_ledger/templates/django_ledger/receipt/receipt_detail.html,sha256=QITtI2VFa7E1Ub9KAR9ParTIPCxUvQOERuyORMykywo,4917
|
|
305
305
|
django_ledger/templates/django_ledger/receipt/receipt_list.html,sha256=KZSxhgA_uZj015Arx_CM8ghbxTlSLUew6v3NP49AXzM,6810
|
|
306
306
|
django_ledger/templates/django_ledger/receipt/vendor_receipt_report.html,sha256=ySVb7twSChUXEuPSujZZaD8PtNBBsEDLdTKEE8zq4qQ,5149
|
|
307
307
|
django_ledger/templates/django_ledger/service/service_create.html,sha256=kGlqz3-txJojmBEnwXat8V6p4mZ0yozKBYDSlMgGcB8,1431
|
|
@@ -375,7 +375,7 @@ django_ledger/views/bill.py,sha256=dtp8KqyqvDGPy99lB1bz4jHEhHJ_4b87O6jpRFS-oOI,2
|
|
|
375
375
|
django_ledger/views/chart_of_accounts.py,sha256=AlRdX_g-Hjqetv1pVdQRMIYj4D4gnCURUgbAnPt_kpA,5659
|
|
376
376
|
django_ledger/views/closing_entry.py,sha256=JG2uDrqi90S1_Edb6-dsfNgx5xXLQRm6awjf_c8Y8fk,8433
|
|
377
377
|
django_ledger/views/customer.py,sha256=UPdEZ8DJj6FHR-eO2EgqdrYzU6QoAp1QAvPgHK0SXSg,4867
|
|
378
|
-
django_ledger/views/data_import.py,sha256=
|
|
378
|
+
django_ledger/views/data_import.py,sha256=mDQqHj5Z8lAxWwKCSmSkMPHOINm_INPlCy281HkcxlU,10934
|
|
379
379
|
django_ledger/views/djl_api.py,sha256=W4DooOXtTDvcZ6AyBgcwv86CUytQx_KHxxycU6s3e3I,4359
|
|
380
380
|
django_ledger/views/entity.py,sha256=eY7dDY45Mv3M5pdegXtdkbC0TAzJh7LuG0NrZx56lM8,9394
|
|
381
381
|
django_ledger/views/estimate.py,sha256=z5rlNiiXDXR24yPdzCNXVM_yJRDE4CG4ZrItijaXtmY,12648
|
|
@@ -393,9 +393,9 @@ django_ledger/views/receipt.py,sha256=mtiHfk529oVVSIrAR28LgQc696HUVFnV4rYd9HTqoV
|
|
|
393
393
|
django_ledger/views/transactions.py,sha256=3ijtJzdLPFkqG7OYpe-7N4QVjCyR2yl5ht_9RyfquBA,212
|
|
394
394
|
django_ledger/views/unit.py,sha256=IK0KWf_NkTCzJILtA4SDU9tD4OL3kbAktLdvL6fxRhU,10035
|
|
395
395
|
django_ledger/views/vendor.py,sha256=-tUs6-flA_SiXuDWs173Sho4JwQr0zMAhqD_-xM0eeA,4746
|
|
396
|
-
django_ledger-0.8.2.
|
|
397
|
-
django_ledger-0.8.2.
|
|
398
|
-
django_ledger-0.8.2.
|
|
399
|
-
django_ledger-0.8.2.
|
|
400
|
-
django_ledger-0.8.2.
|
|
401
|
-
django_ledger-0.8.2.
|
|
396
|
+
django_ledger-0.8.2.3.dist-info/licenses/AUTHORS.md,sha256=ShPwf-qniJkbjRzX5_lqhmgoLMEYMSHSwKPXHZtWmyk,824
|
|
397
|
+
django_ledger-0.8.2.3.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
398
|
+
django_ledger-0.8.2.3.dist-info/METADATA,sha256=xvPML8oA6ACobgjGWNeEUXjwDgpvNm2pdf1ToEL2Q3Q,8460
|
|
399
|
+
django_ledger-0.8.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
400
|
+
django_ledger-0.8.2.3.dist-info/top_level.txt,sha256=57KG3JBsF9fqPnPGyFfcpKtfFNS9TQONjtfKhUlwiy4,14
|
|
401
|
+
django_ledger-0.8.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|