django-ledger 0.8.0__py3-none-any.whl → 0.8.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.

Files changed (56) hide show
  1. django_ledger/__init__.py +1 -1
  2. django_ledger/forms/account.py +45 -46
  3. django_ledger/forms/data_import.py +182 -64
  4. django_ledger/io/io_core.py +507 -374
  5. django_ledger/migrations/0026_stagedtransactionmodel_customer_model_and_more.py +56 -0
  6. django_ledger/models/__init__.py +2 -1
  7. django_ledger/models/bill.py +337 -300
  8. django_ledger/models/customer.py +47 -34
  9. django_ledger/models/data_import.py +770 -289
  10. django_ledger/models/entity.py +882 -637
  11. django_ledger/models/mixins.py +421 -282
  12. django_ledger/models/receipt.py +1083 -0
  13. django_ledger/models/transactions.py +105 -41
  14. django_ledger/models/unit.py +42 -30
  15. django_ledger/models/utils.py +12 -2
  16. django_ledger/models/vendor.py +85 -66
  17. django_ledger/settings.py +1 -0
  18. django_ledger/static/django_ledger/bundle/djetler.bundle.js +1 -1
  19. django_ledger/static/django_ledger/bundle/djetler.bundle.js.LICENSE.txt +1 -13
  20. django_ledger/templates/django_ledger/bills/bill_update.html +1 -1
  21. django_ledger/templates/django_ledger/components/period_navigator.html +5 -3
  22. django_ledger/templates/django_ledger/customer/customer_detail.html +87 -0
  23. django_ledger/templates/django_ledger/customer/customer_list.html +0 -1
  24. django_ledger/templates/django_ledger/customer/tags/customer_table.html +3 -1
  25. django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html +24 -3
  26. django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html +26 -10
  27. django_ledger/templates/django_ledger/entity/entity_dashboard.html +2 -2
  28. django_ledger/templates/django_ledger/invoice/invoice_update.html +1 -1
  29. django_ledger/templates/django_ledger/layouts/base.html +3 -1
  30. django_ledger/templates/django_ledger/layouts/content_layout_1.html +1 -1
  31. django_ledger/templates/django_ledger/receipt/customer_receipt_report.html +115 -0
  32. django_ledger/templates/django_ledger/receipt/receipt_delete.html +30 -0
  33. django_ledger/templates/django_ledger/receipt/receipt_detail.html +89 -0
  34. django_ledger/templates/django_ledger/receipt/receipt_list.html +134 -0
  35. django_ledger/templates/django_ledger/receipt/vendor_receipt_report.html +115 -0
  36. django_ledger/templates/django_ledger/vendor/tags/vendor_table.html +3 -2
  37. django_ledger/templates/django_ledger/vendor/vendor_detail.html +86 -0
  38. django_ledger/templatetags/django_ledger.py +338 -191
  39. django_ledger/urls/__init__.py +1 -0
  40. django_ledger/urls/customer.py +3 -0
  41. django_ledger/urls/data_import.py +3 -0
  42. django_ledger/urls/receipt.py +102 -0
  43. django_ledger/urls/vendor.py +1 -0
  44. django_ledger/views/__init__.py +1 -0
  45. django_ledger/views/customer.py +56 -14
  46. django_ledger/views/data_import.py +119 -66
  47. django_ledger/views/mixins.py +112 -86
  48. django_ledger/views/receipt.py +294 -0
  49. django_ledger/views/vendor.py +53 -14
  50. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.dist-info}/METADATA +1 -1
  51. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.dist-info}/RECORD +55 -45
  52. django_ledger/static/django_ledger/bundle/styles.bundle.js +0 -1
  53. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.dist-info}/WHEEL +0 -0
  54. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.dist-info}/licenses/AUTHORS.md +0 -0
  55. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.dist-info}/licenses/LICENSE +0 -0
  56. {django_ledger-0.8.0.dist-info → django_ledger-0.8.2.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.0'
9
+ __version__ = '0.8.2'
10
10
  __license__ = 'GPLv3 License'
11
11
 
12
12
  __author__ = 'Miguel Sanda'
@@ -5,10 +5,19 @@ Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
5
5
  Contributions to this module:
6
6
  * Miguel Sanda <msanda@arrobalytics.com>
7
7
  """
8
+
8
9
  from random import randint
9
10
  from typing import Optional
10
11
 
11
- from django.forms import TextInput, Select, ModelForm, ChoiceField, ValidationError, CheckboxInput, HiddenInput
12
+ from django.forms import (
13
+ TextInput,
14
+ Select,
15
+ ModelForm,
16
+ ChoiceField,
17
+ ValidationError,
18
+ CheckboxInput,
19
+ HiddenInput,
20
+ )
12
21
  from django.utils.translation import gettext_lazy as _
13
22
  from treebeard.forms import MoveNodeForm
14
23
 
@@ -62,25 +71,27 @@ class AccountModelCreateForm(ModelForm):
62
71
  'balance_type',
63
72
  'active',
64
73
  'active',
65
- 'coa_model'
74
+ 'coa_model',
66
75
  ]
67
76
  widgets = {
68
- 'code': TextInput(attrs={
69
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
70
- 'placeholder': _('Alpha Numeric (auto generated if not provided)...')
71
- }),
72
- 'name': TextInput(attrs={
73
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
74
- 'placeholder': _('Account Name...')
75
- }),
76
- 'role': Select(attrs={
77
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
78
- }),
77
+ 'code': TextInput(
78
+ attrs={
79
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
80
+ 'placeholder': _(
81
+ 'Alpha Numeric (auto generated if not provided)...'
82
+ ),
83
+ }
84
+ ),
85
+ 'name': TextInput(
86
+ attrs={
87
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
88
+ 'placeholder': _('Account Name...'),
89
+ }
90
+ ),
91
+ 'role': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
79
92
  'role_default': CheckboxInput(),
80
- 'balance_type': Select(attrs={
81
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
82
- }),
83
- 'coa_model': HiddenInput()
93
+ 'balance_type': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
94
+ 'coa_model': HiddenInput(),
84
95
  }
85
96
 
86
97
 
@@ -88,7 +99,7 @@ class AccountModelUpdateForm(MoveNodeForm):
88
99
  """
89
100
  AccountModelUpdateForm
90
101
 
91
- A form for updating account model, inheriting from MoveNodeForm.
102
+ A form for updating the account model, inheriting from MoveNodeForm.
92
103
 
93
104
  Attributes
94
105
  ----------
@@ -98,36 +109,32 @@ class AccountModelUpdateForm(MoveNodeForm):
98
109
  An optional choice field for selecting the relative node.
99
110
  """
100
111
 
101
- _position = ChoiceField(required=True,
102
- label=_('Position'),
103
- widget=Select(attrs={
104
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
105
- }))
106
- _ref_node_id = ChoiceField(required=False,
107
- label=_('Relative to'),
108
- widget=Select(attrs={
109
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
110
- }))
111
-
112
+ _position = ChoiceField(
113
+ required=True,
114
+ label=_('Position'),
115
+ widget=Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
116
+ )
117
+ _ref_node_id = ChoiceField(
118
+ required=False,
119
+ label=_('Relative to'),
120
+ widget=Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
121
+ )
112
122
 
113
123
  def __init__(self, *args, **kwargs):
114
124
  super().__init__(*args, **kwargs)
115
125
  self.fields['role'].disabled = True
116
126
  self.fields['coa_model'].disabled = True
117
127
 
118
-
119
128
  @classmethod
120
129
  def mk_dropdown_tree(cls, model, for_node: Optional[AccountModel] = None):
121
- """ Creates a tree-like list of choices """
130
+ """Creates a tree-like list of choices"""
122
131
 
123
132
  if not for_node:
124
133
  raise ValidationError(message='Must provide for_node argument.')
125
134
 
126
135
  qs = for_node.get_account_move_choice_queryset()
127
136
 
128
- return [
129
- (i.uuid, f'{"-" * (i.depth - 1)} {i}') for i in qs
130
- ]
137
+ return [(i.uuid, f'{"-" * (i.depth - 1)} {i}') for i in qs]
131
138
 
132
139
  def clean_role(self):
133
140
  return self.instance.role
@@ -147,17 +154,9 @@ class AccountModelUpdateForm(MoveNodeForm):
147
154
  widgets = {
148
155
  'role': HiddenInput(),
149
156
  'coa_model': HiddenInput(),
150
- 'parent': Select(attrs={
151
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
152
- }),
153
- 'balance_type': Select(attrs={
154
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
155
- }),
156
- 'code': TextInput(attrs={
157
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
158
- }),
159
- 'name': TextInput(attrs={
160
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
161
- }),
157
+ 'parent': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
158
+ 'balance_type': Select(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
159
+ 'code': TextInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
160
+ 'name': TextInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES}),
162
161
  'role_default': CheckboxInput(),
163
162
  }
@@ -1,34 +1,37 @@
1
1
  from django import forms
2
2
  from django.forms import (
3
- ModelForm, BaseModelFormSet, modelformset_factory,
4
- Select, NumberInput, HiddenInput,
5
- TextInput, ValidationError
3
+ ModelForm,
4
+ BaseModelFormSet,
5
+ modelformset_factory,
6
+ Select,
7
+ NumberInput,
8
+ HiddenInput,
9
+ TextInput,
10
+ ValidationError,
6
11
  )
7
12
  from django.utils.translation import gettext_lazy as _
8
13
 
14
+ from django_ledger.io import GROUP_EXPENSES, GROUP_INCOME
9
15
  from django_ledger.models import (
10
16
  StagedTransactionModel,
11
17
  ImportJobModel,
12
- EntityModel
18
+ EntityModel,
13
19
  )
14
20
  from django_ledger.settings import DJANGO_LEDGER_FORM_INPUT_CLASSES
15
21
 
16
22
 
17
23
  class ImportJobModelCreateForm(ModelForm):
18
-
19
24
  def __init__(self, entity_model: EntityModel, *args, **kwargs):
20
25
  super().__init__(*args, **kwargs)
21
26
  self.ENTITY_MODEL: EntityModel = entity_model
22
- self.fields['bank_account_model'].queryset = self.ENTITY_MODEL.bankaccountmodel_set.all().active()
27
+ self.fields[
28
+ 'bank_account_model'
29
+ ].queryset = self.ENTITY_MODEL.bankaccountmodel_set.all().active()
23
30
 
24
31
  ofx_file = forms.FileField(
25
32
  label='Select File...',
26
33
  required=True,
27
- widget=forms.FileInput(
28
- attrs={
29
- 'class': 'file-input',
30
- 'accept': '.ofx,.qfx'
31
- })
34
+ widget=forms.FileInput(attrs={'class': 'file-input', 'accept': '.ofx,.qfx'}),
32
35
  )
33
36
 
34
37
  class Meta:
@@ -38,30 +41,31 @@ class ImportJobModelCreateForm(ModelForm):
38
41
  'description',
39
42
  ]
40
43
  widgets = {
41
- 'description': TextInput(attrs={
42
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
43
- 'placeholder': _('Name this import...')
44
- }),
44
+ 'description': TextInput(
45
+ attrs={
46
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-large',
47
+ 'placeholder': _('Name this import...'),
48
+ }
49
+ ),
45
50
  'bank_account_model': Select(
46
51
  attrs={
47
52
  'class': DJANGO_LEDGER_FORM_INPUT_CLASSES,
48
- }),
53
+ }
54
+ ),
49
55
  }
50
56
  help_texts = {
51
- 'bank_account_model': _('Select the bank account to import transactions from.'),
57
+ 'bank_account_model': _(
58
+ 'Select the bank account to import transactions from.'
59
+ ),
52
60
  }
53
61
 
54
62
 
55
63
  class ImportJobModelUpdateForm(ModelForm):
56
64
  class Meta:
57
65
  model = ImportJobModel
58
- fields = [
59
- 'description'
60
- ]
66
+ fields = ['description']
61
67
  widgets = {
62
- 'description': TextInput(attrs={
63
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES
64
- })
68
+ 'description': TextInput(attrs={'class': DJANGO_LEDGER_FORM_INPUT_CLASSES})
65
69
  }
66
70
 
67
71
 
@@ -71,37 +75,90 @@ class StagedTransactionModelForm(ModelForm):
71
75
 
72
76
  def __init__(self, base_formset_instance, *args, **kwargs):
73
77
  super().__init__(*args, **kwargs)
74
- self.BASE_FORMSET_INSTANCE = base_formset_instance
78
+ self.BASE_FORMSET_INSTANCE: 'BaseStagedTransactionModelFormSet' = (
79
+ base_formset_instance
80
+ )
81
+ self.VENDOR_CHOICES = self.BASE_FORMSET_INSTANCE.VENDOR_CHOICES
82
+ self.VENDOR_MAP = self.BASE_FORMSET_INSTANCE.VENDOR_MAP
75
83
 
76
- # for IDE typing hints...
77
- instance: StagedTransactionModel = getattr(self, 'instance', None)
84
+ self.CUSTOMER_CHOICES = self.BASE_FORMSET_INSTANCE.CUSTOMER_CHOICES
85
+ self.CUSTOMER_MAP = self.BASE_FORMSET_INSTANCE.CUSTOMER_MAP
78
86
 
79
- # avoids multiple DB queries rendering the formset...
80
- self.fields['unit_model'].choices = self.BASE_FORMSET_INSTANCE.UNIT_MODEL_CHOICES
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
95
+
96
+ staged_tx_model: StagedTransactionModel = getattr(self, 'instance', None)
97
+
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
81
116
 
82
117
  # avoids multiple DB queries rendering the formset...
83
- self.fields['account_model'].choices = self.BASE_FORMSET_INSTANCE.ACCOUNT_MODEL_CHOICES
118
+ self.fields[
119
+ 'unit_model'
120
+ ].choices = self.BASE_FORMSET_INSTANCE.UNIT_MODEL_CHOICES
84
121
 
85
- if instance:
86
- if not instance.is_children():
122
+ if staged_tx_model:
123
+ if not staged_tx_model.is_children():
87
124
  self.fields['amount_split'].widget = HiddenInput()
88
125
  self.fields['amount_split'].disabled = True
89
126
  else:
90
127
  self.fields['bundle_split'].widget = HiddenInput()
91
128
  self.fields['bundle_split'].disabled = True
92
129
 
93
- if not instance.can_have_account():
130
+ if staged_tx_model.has_children():
131
+ self.fields['receipt_type'].widget = HiddenInput()
132
+ self.fields['receipt_type'].disabled = True
133
+
134
+ if not staged_tx_model.can_have_account():
94
135
  self.fields['account_model'].widget = HiddenInput()
95
136
  self.fields['account_model'].disabled = True
96
137
 
97
- if not instance.can_have_unit():
138
+ if not staged_tx_model.can_have_unit():
98
139
  self.fields['unit_model'].widget = HiddenInput()
99
140
  self.fields['unit_model'].disabled = True
100
141
 
101
- if not instance.can_import():
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
156
+
157
+ if not staged_tx_model.can_migrate():
102
158
  self.fields['tx_import'].widget = HiddenInput()
103
159
  self.fields['tx_import'].disabled = True
104
- if not instance.can_split():
160
+
161
+ if not staged_tx_model.can_split():
105
162
  self.fields['tx_split'].widget = HiddenInput()
106
163
  self.fields['tx_split'].disabled = True
107
164
 
@@ -114,8 +171,9 @@ class StagedTransactionModelForm(ModelForm):
114
171
  def clean_unit_model(self):
115
172
  staged_txs_model: StagedTransactionModel = self.instance
116
173
  if not staged_txs_model.can_have_unit():
117
- if staged_txs_model.parent_id:
174
+ if staged_txs_model.is_children():
118
175
  return staged_txs_model.parent.unit_model
176
+ return None
119
177
  return self.cleaned_data['unit_model']
120
178
 
121
179
  def clean_tx_import(self):
@@ -125,10 +183,23 @@ class StagedTransactionModelForm(ModelForm):
125
183
  return self.cleaned_data['tx_import']
126
184
 
127
185
  def clean(self):
128
- # cannot import and split at the same time
129
186
  if self.cleaned_data['tx_import'] and self.cleaned_data['tx_split']:
130
187
  raise ValidationError(message=_('Cannot import and split at the same time'))
131
188
 
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
+
132
203
  class Meta:
133
204
  model = StagedTransactionModel
134
205
  fields = [
@@ -136,51 +207,98 @@ class StagedTransactionModelForm(ModelForm):
136
207
  'bundle_split',
137
208
  'amount_split',
138
209
  'account_model',
139
- 'unit_model'
210
+ 'unit_model',
211
+ 'receipt_type',
212
+ 'vendor_model',
213
+ 'customer_model',
140
214
  ]
141
215
  widgets = {
142
- 'account_model': Select(attrs={
143
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small',
144
- }),
145
- 'unit_model': Select(attrs={
146
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small',
147
- }),
148
- 'amount_split': NumberInput(attrs={
149
- 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small'
150
- })
216
+ 'account_model': Select(
217
+ attrs={
218
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small',
219
+ }
220
+ ),
221
+ 'unit_model': Select(
222
+ attrs={
223
+ 'class': DJANGO_LEDGER_FORM_INPUT_CLASSES + ' is-small',
224
+ }
225
+ ),
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
+ ),
151
238
  }
152
239
 
153
240
 
154
241
  class BaseStagedTransactionModelFormSet(BaseModelFormSet):
155
-
156
- def __init__(self, *args,
157
- entity_model: EntityModel,
158
- import_job_model: ImportJobModel,
159
- **kwargs):
242
+ def __init__(
243
+ self,
244
+ *args,
245
+ entity_model: EntityModel,
246
+ import_job_model: ImportJobModel,
247
+ **kwargs,
248
+ ):
160
249
  super().__init__(*args, **kwargs)
161
250
 
162
251
  # validates that the job import model belongs to the entity model...
163
252
  if import_job_model.entity_uuid != entity_model.uuid:
164
- raise ValidationError(message=_('Import job does not belong to this entity'))
253
+ raise ValidationError(
254
+ message=_('Import job does not belong to this entity')
255
+ )
165
256
 
166
257
  self.ENTITY_MODEL = entity_model
167
258
  self.IMPORT_JOB_MODEL: ImportJobModel = import_job_model
168
- self.MAPPED_ACCOUNT_MODEL = self.IMPORT_JOB_MODEL.bank_account_model.account_model
169
259
 
170
- self.account_model_qs = entity_model.get_coa_accounts().available().exclude(
171
- uuid__exact=self.MAPPED_ACCOUNT_MODEL.uuid
260
+ self.queryset = (
261
+ self.IMPORT_JOB_MODEL.stagedtransactionmodel_set.all().is_pending()
262
+ )
263
+
264
+ self.MAPPED_ACCOUNT_MODEL = (
265
+ self.IMPORT_JOB_MODEL.bank_account_model.account_model
266
+ )
267
+
268
+ self.account_model_qs = (
269
+ entity_model.get_coa_accounts()
270
+ .available()
271
+ .exclude(uuid__exact=self.MAPPED_ACCOUNT_MODEL.uuid)
172
272
  )
173
- self.ACCOUNT_MODEL_CHOICES = [
174
- (a.uuid, a) if i > 0 else (None, '----') for i, a in
175
- enumerate(self.account_model_qs)
273
+ self.ACCOUNT_MODEL_CHOICES = [(None, '----')] + [
274
+ (a.uuid, a) for a in self.account_model_qs
275
+ ]
276
+ self.ACCOUNT_MODEL_EXPENSES_CHOICES = [(None, '----')] + [
277
+ (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_EXPENSES
278
+ ]
279
+ self.ACCOUNT_MODEL_SALES_CHOICES = [(None, '----')] + [
280
+ (a.uuid, a) for a in self.account_model_qs if a.role in GROUP_INCOME
176
281
  ]
177
282
 
178
283
  self.unit_model_qs = entity_model.entityunitmodel_set.all()
179
- self.UNIT_MODEL_CHOICES = [
180
- (u.uuid, u) if i > 0 else (None, '----') for i, u in
181
- enumerate(self.unit_model_qs)
284
+ self.UNIT_MODEL_CHOICES = [(None, '----')] + [
285
+ (u.uuid, u) for i, u in enumerate(self.unit_model_qs)
286
+ ]
287
+
288
+ self.VENDOR_MODEL_QS = entity_model.vendormodel_set.visible()
289
+ len(self.VENDOR_MODEL_QS)
290
+ self.CUSTOMER_MODEL_QS = entity_model.customermodel_set.visible()
291
+ len(self.CUSTOMER_MODEL_QS)
292
+
293
+ self.VENDOR_CHOICES = [(None, '-----')] + [
294
+ (str(v.uuid), v) for v in self.VENDOR_MODEL_QS
182
295
  ]
183
- self.queryset = self.IMPORT_JOB_MODEL.stagedtransactionmodel_set.all().is_pending()
296
+ self.CUSTOMER_CHOICES = [(None, '-----')] + [
297
+ (str(c.uuid), c) for c in self.CUSTOMER_MODEL_QS
298
+ ]
299
+
300
+ self.VENDOR_MAP = dict(self.VENDOR_CHOICES)
301
+ self.CUSTOMER_MAP = dict(self.CUSTOMER_CHOICES)
184
302
 
185
303
  def get_form_kwargs(self, index):
186
304
  return {
@@ -194,5 +312,5 @@ StagedTransactionModelFormSet = modelformset_factory(
194
312
  formset=BaseStagedTransactionModelFormSet,
195
313
  can_delete=True,
196
314
  can_order=False,
197
- extra=0
315
+ extra=0,
198
316
  )