django-ledger 0.8.2.1__py3-none-any.whl → 0.8.2.2__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.8.2.1'
9
+ __version__ = '0.8.2.2'
10
10
  __license__ = 'GPLv3 License'
11
11
 
12
12
  __author__ = 'Miguel Sanda'
@@ -11,7 +11,7 @@ from django.forms import (
11
11
  )
12
12
  from django.utils.translation import gettext_lazy as _
13
13
 
14
- from django_ledger.io import GROUP_EXPENSES, GROUP_INCOME
14
+ from django_ledger.io import GROUP_EXPENSES, GROUP_INCOME, GROUP_TRANSFERS, GROUP_DEBT_PAYMENT
15
15
  from django_ledger.models import (
16
16
  StagedTransactionModel,
17
17
  ImportJobModel,
@@ -24,9 +24,7 @@ class ImportJobModelCreateForm(ModelForm):
24
24
  def __init__(self, entity_model: EntityModel, *args, **kwargs):
25
25
  super().__init__(*args, **kwargs)
26
26
  self.ENTITY_MODEL: EntityModel = entity_model
27
- self.fields[
28
- 'bank_account_model'
29
- ].queryset = self.ENTITY_MODEL.bankaccountmodel_set.all().active()
27
+ self.fields['bank_account_model'].queryset = self.ENTITY_MODEL.bankaccountmodel_set.all().active()
30
28
 
31
29
  ofx_file = forms.FileField(
32
30
  label='Select File...',
@@ -54,9 +52,7 @@ class ImportJobModelCreateForm(ModelForm):
54
52
  ),
55
53
  }
56
54
  help_texts = {
57
- 'bank_account_model': _(
58
- 'Select the bank account to import transactions from.'
59
- ),
55
+ 'bank_account_model': _('Select the bank account to import transactions from.'),
60
56
  }
61
57
 
62
58
 
@@ -64,9 +60,7 @@ class ImportJobModelUpdateForm(ModelForm):
64
60
  class Meta:
65
61
  model = ImportJobModel
66
62
  fields = ['description']
67
- widgets = {
68
- 'description': TextInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES})
69
- }
63
+ widgets = {'description': TextInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES})}
70
64
 
71
65
 
72
66
  class StagedTransactionModelForm(ModelForm):
@@ -75,59 +69,49 @@ class StagedTransactionModelForm(ModelForm):
75
69
 
76
70
  def __init__(self, base_formset_instance, *args, **kwargs):
77
71
  super().__init__(*args, **kwargs)
78
- self.BASE_FORMSET_INSTANCE: 'BaseStagedTransactionModelFormSet' = (
79
- base_formset_instance
80
- )
72
+ self.BASE_FORMSET_INSTANCE: 'BaseStagedTransactionModelFormSet' = base_formset_instance
81
73
  self.VENDOR_CHOICES = self.BASE_FORMSET_INSTANCE.VENDOR_CHOICES
82
74
  self.VENDOR_MAP = self.BASE_FORMSET_INSTANCE.VENDOR_MAP
83
75
 
84
76
  self.CUSTOMER_CHOICES = self.BASE_FORMSET_INSTANCE.CUSTOMER_CHOICES
85
77
  self.CUSTOMER_MAP = self.BASE_FORMSET_INSTANCE.CUSTOMER_MAP
86
78
 
87
- self.EXPENSE_ACCOUNT_CHOICES = (
88
- self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_EXPENSES_CHOICES
89
- )
90
- self.SALES_ACCOUNT_CHOICES = (
91
- self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_SALES_CHOICES
92
- )
93
- self.SHOW_VENDOR_FIELD: bool = False
94
- self.SHOW_CUSTOMER_FIELD: bool = False
79
+ self.EXPENSE_ACCOUNT_CHOICES = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_EXPENSES_CHOICES
80
+ self.SALES_ACCOUNT_CHOICES = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_SALES_CHOICES
81
+ self.TRANSFER_ACCOUNT_CHOICES = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_TRANSFERS_CHOICES
82
+ self.CC_PAYMENT_ACCOUNT_CHOICES = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_TRANSFERS_CC_PAYMENT
95
83
 
96
84
  staged_tx_model: StagedTransactionModel = getattr(self, 'instance', None)
97
85
 
98
- if staged_tx_model.can_migrate_receipt():
99
- if staged_tx_model.is_expense():
100
- self.fields['customer_model'].widget = forms.HiddenInput()
101
- self.fields['vendor_model'].choices = self.VENDOR_CHOICES
102
- self.fields['account_model'].choices = self.EXPENSE_ACCOUNT_CHOICES
103
- self.SHOW_VENDOR_FIELD = True
104
- elif staged_tx_model.is_sales():
105
- self.fields['vendor_model'].widget = forms.HiddenInput()
106
- self.fields['customer_model'].choices = self.CUSTOMER_CHOICES
107
- self.fields['account_model'].choices = self.SALES_ACCOUNT_CHOICES
108
- self.SHOW_CUSTOMER_FIELD = True
109
- else:
110
- self.fields['customer_model'].widget = forms.HiddenInput()
111
- self.fields['vendor_model'].widget = forms.HiddenInput()
112
- # avoids multiple DB queries rendering the formset...
113
- self.fields[
114
- 'account_model'
115
- ].choices = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_CHOICES
86
+ self.fields['vendor_model'].choices = self.VENDOR_CHOICES
87
+ self.fields['customer_model'].choices = self.CUSTOMER_CHOICES
88
+ self.fields['account_model'].choices = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_CHOICES
116
89
 
117
90
  # avoids multiple DB queries rendering the formset...
118
- self.fields[
119
- 'unit_model'
120
- ].choices = self.BASE_FORMSET_INSTANCE.UNIT_MODEL_CHOICES
91
+ self.fields['unit_model'].choices = self.BASE_FORMSET_INSTANCE.UNIT_MODEL_CHOICES
121
92
 
122
93
  if staged_tx_model:
123
- if not staged_tx_model.is_children():
94
+ if staged_tx_model.is_sales():
95
+ self.fields['account_model'].choices = self.SALES_ACCOUNT_CHOICES
96
+
97
+ if staged_tx_model.is_expense():
98
+ self.fields['account_model'].choices = self.EXPENSE_ACCOUNT_CHOICES
99
+
100
+ if staged_tx_model.is_transfer():
101
+ self.fields['account_model'].choices = self.TRANSFER_ACCOUNT_CHOICES
102
+
103
+ if staged_tx_model.is_debt_payment():
104
+ self.fields['account_model'].choices = self.CC_PAYMENT_ACCOUNT_CHOICES
105
+
106
+ if not staged_tx_model.can_have_amount_split():
124
107
  self.fields['amount_split'].widget = HiddenInput()
125
108
  self.fields['amount_split'].disabled = True
126
- else:
109
+
110
+ if not staged_tx_model.can_have_bundle_split():
127
111
  self.fields['bundle_split'].widget = HiddenInput()
128
112
  self.fields['bundle_split'].disabled = True
129
113
 
130
- if staged_tx_model.has_children():
114
+ if not staged_tx_model.can_have_receipt():
131
115
  self.fields['receipt_type'].widget = HiddenInput()
132
116
  self.fields['receipt_type'].disabled = True
133
117
 
@@ -139,22 +123,15 @@ class StagedTransactionModelForm(ModelForm):
139
123
  self.fields['unit_model'].widget = HiddenInput()
140
124
  self.fields['unit_model'].disabled = True
141
125
 
142
- # receipt-related field visibility: not allowed for children rows
143
- if staged_tx_model.is_children():
144
- for f in [
145
- 'receipt_type',
146
- 'vendor_model',
147
- 'customer_model',
148
- 'bundle_split',
149
- ]:
150
- self.fields[f].widget = HiddenInput()
151
- self.fields[f].disabled = True
152
-
153
- if staged_tx_model.is_single():
154
- self.fields['bundle_split'].widget = HiddenInput()
155
- self.fields['bundle_split'].disabled = True
126
+ if not staged_tx_model.can_have_vendor():
127
+ self.fields['vendor_model'].widget = HiddenInput()
128
+ self.fields['vendor_model'].disabled = True
156
129
 
157
- if not staged_tx_model.can_migrate():
130
+ if not staged_tx_model.can_have_customer():
131
+ self.fields['customer_model'].widget = HiddenInput()
132
+ self.fields['customer_model'].disabled = True
133
+
134
+ if not staged_tx_model.can_import():
158
135
  self.fields['tx_import'].widget = HiddenInput()
159
136
  self.fields['tx_import'].disabled = True
160
137
 
@@ -162,6 +139,10 @@ class StagedTransactionModelForm(ModelForm):
162
139
  self.fields['tx_split'].widget = HiddenInput()
163
140
  self.fields['tx_split'].disabled = True
164
141
 
142
+ if not staged_tx_model.can_unbundle():
143
+ # self.fields['bundle_split'].widget = HiddenInput()
144
+ self.fields['bundle_split'].disabled = True
145
+
165
146
  def clean_account_model(self):
166
147
  staged_txs_model: StagedTransactionModel = self.instance
167
148
  if staged_txs_model.has_children():
@@ -186,20 +167,6 @@ class StagedTransactionModelForm(ModelForm):
186
167
  if self.cleaned_data['tx_import'] and self.cleaned_data['tx_split']:
187
168
  raise ValidationError(message=_('Cannot import and split at the same time'))
188
169
 
189
- staged_txs_model: StagedTransactionModel = self.instance
190
- if all(
191
- [
192
- staged_txs_model.has_children(),
193
- staged_txs_model.has_receipt(),
194
- not staged_txs_model.bundle_split,
195
- ]
196
- ):
197
- raise ValidationError(
198
- message=_(
199
- 'Receipt transactions cannot be split into multiple receipts.'
200
- )
201
- )
202
-
203
170
  class Meta:
204
171
  model = StagedTransactionModel
205
172
  fields = [
@@ -223,18 +190,10 @@ class StagedTransactionModelForm(ModelForm):
223
190
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small',
224
191
  }
225
192
  ),
226
- 'amount_split': NumberInput(
227
- attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}
228
- ),
229
- 'vendor_model': Select(
230
- attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}
231
- ),
232
- 'customer_model': Select(
233
- attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}
234
- ),
235
- 'receipt_type': Select(
236
- attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}
237
- ),
193
+ 'amount_split': NumberInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}),
194
+ 'vendor_model': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}),
195
+ 'customer_model': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}),
196
+ 'receipt_type': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'}),
238
197
  }
239
198
 
240
199
 
@@ -250,29 +209,23 @@ class BaseStagedTransactionModelFormSet(BaseModelFormSet):
250
209
 
251
210
  # validates that the job import model belongs to the entity model...
252
211
  if import_job_model.entity_uuid != entity_model.uuid:
253
- raise ValidationError(
254
- message=_('Import job does not belong to this entity')
255
- )
212
+ raise ValidationError(message=_('Import job does not belong to this entity'))
256
213
 
257
214
  self.ENTITY_MODEL = entity_model
258
215
  self.IMPORT_JOB_MODEL: ImportJobModel = import_job_model
259
216
 
260
217
  self.queryset = (
261
- self.IMPORT_JOB_MODEL.stagedtransactionmodel_set.all().is_pending()
218
+ StagedTransactionModel.objects.for_entity(entity_model=entity_model)
219
+ .for_import_job(import_job_model=import_job_model)
220
+ .is_pending()
262
221
  )
263
222
 
264
- self.MAPPED_ACCOUNT_MODEL = (
265
- self.IMPORT_JOB_MODEL.bank_account_model.account_model
266
- )
223
+ self.MAPPED_ACCOUNT_MODEL = self.IMPORT_JOB_MODEL.bank_account_model.account_model
267
224
 
268
225
  self.account_model_qs = (
269
- entity_model.get_coa_accounts()
270
- .available()
271
- .exclude(uuid__exact=self.MAPPED_ACCOUNT_MODEL.uuid)
226
+ entity_model.get_coa_accounts().available().exclude(uuid__exact=self.MAPPED_ACCOUNT_MODEL.uuid)
272
227
  )
273
- self.ACCOUNT_MODEL_CHOICES = [(None, '----')] + [
274
- (a.uuid, a) for a in self.account_model_qs
275
- ]
228
+ self.ACCOUNT_MODEL_CHOICES = [(None, '----')] + [(a.uuid, a) for a in self.account_model_qs]
276
229
  self.ACCOUNT_MODEL_EXPENSES_CHOICES = [(None, '----')] + [
277
230
  (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_EXPENSES
278
231
  ]
@@ -280,22 +233,22 @@ class BaseStagedTransactionModelFormSet(BaseModelFormSet):
280
233
  (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_INCOME
281
234
  ]
282
235
 
283
- self.unit_model_qs = entity_model.entityunitmodel_set.all()
284
- self.UNIT_MODEL_CHOICES = [(None, '----')] + [
285
- (u.uuid, u) for i, u in enumerate(self.unit_model_qs)
236
+ self.ACCOUNT_MODEL_TRANSFERS_CHOICES = [(None, '----')] + [
237
+ (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_TRANSFERS
238
+ ]
239
+
240
+ self.ACCOUNT_MODEL_TRANSFERS_CC_PAYMENT = [(None, '----')] + [
241
+ (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_DEBT_PAYMENT
286
242
  ]
287
243
 
244
+ self.unit_model_qs = entity_model.entityunitmodel_set.all()
245
+ self.UNIT_MODEL_CHOICES = [(None, '----')] + [(u.uuid, u) for i, u in enumerate(self.unit_model_qs)]
246
+
288
247
  self.VENDOR_MODEL_QS = entity_model.vendormodel_set.visible()
289
- len(self.VENDOR_MODEL_QS)
290
248
  self.CUSTOMER_MODEL_QS = entity_model.customermodel_set.visible()
291
- len(self.CUSTOMER_MODEL_QS)
292
249
 
293
- self.VENDOR_CHOICES = [(None, '-----')] + [
294
- (str(v.uuid), v) for v in self.VENDOR_MODEL_QS
295
- ]
296
- self.CUSTOMER_CHOICES = [(None, '-----')] + [
297
- (str(c.uuid), c) for c in self.CUSTOMER_MODEL_QS
298
- ]
250
+ self.VENDOR_CHOICES = [(None, '-----')] + [(str(v.uuid), v) for v in self.VENDOR_MODEL_QS]
251
+ self.CUSTOMER_CHOICES = [(None, '-----')] + [(str(c.uuid), c) for c in self.CUSTOMER_MODEL_QS]
299
252
 
300
253
  self.VENDOR_MAP = dict(self.VENDOR_CHOICES)
301
254
  self.CUSTOMER_MAP = dict(self.CUSTOMER_CHOICES)