django-ledger 0.7.11__py3-none-any.whl → 0.8.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.
- django_ledger/__init__.py +1 -1
- django_ledger/context.py +12 -0
- django_ledger/forms/account.py +45 -46
- django_ledger/forms/bill.py +0 -4
- django_ledger/forms/closing_entry.py +13 -1
- django_ledger/forms/data_import.py +182 -63
- django_ledger/forms/estimate.py +3 -6
- django_ledger/forms/invoice.py +3 -7
- django_ledger/forms/item.py +10 -18
- django_ledger/forms/purchase_order.py +2 -4
- django_ledger/io/io_core.py +515 -400
- django_ledger/io/io_generator.py +7 -6
- django_ledger/io/io_library.py +1 -2
- django_ledger/migrations/0025_alter_billmodel_cash_account_and_more.py +70 -0
- django_ledger/migrations/0026_stagedtransactionmodel_customer_model_and_more.py +56 -0
- django_ledger/models/__init__.py +2 -1
- django_ledger/models/accounts.py +109 -69
- django_ledger/models/bank_account.py +40 -23
- django_ledger/models/bill.py +386 -333
- django_ledger/models/chart_of_accounts.py +173 -105
- django_ledger/models/closing_entry.py +99 -48
- django_ledger/models/customer.py +100 -66
- django_ledger/models/data_import.py +818 -323
- django_ledger/models/deprecations.py +61 -0
- django_ledger/models/entity.py +891 -644
- django_ledger/models/estimate.py +57 -28
- django_ledger/models/invoice.py +46 -26
- django_ledger/models/items.py +503 -142
- django_ledger/models/journal_entry.py +61 -47
- django_ledger/models/ledger.py +106 -42
- django_ledger/models/mixins.py +424 -281
- django_ledger/models/purchase_order.py +39 -17
- django_ledger/models/receipt.py +1083 -0
- django_ledger/models/transactions.py +242 -139
- django_ledger/models/unit.py +93 -54
- django_ledger/models/utils.py +12 -2
- django_ledger/models/vendor.py +121 -70
- django_ledger/report/core.py +2 -14
- django_ledger/settings.py +57 -71
- django_ledger/static/django_ledger/bundle/djetler.bundle.js +1 -1
- django_ledger/static/django_ledger/bundle/djetler.bundle.js.LICENSE.txt +25 -0
- django_ledger/static/django_ledger/bundle/styles.bundle.js +1 -1
- django_ledger/static/django_ledger/css/djl_styles.css +273 -0
- django_ledger/templates/django_ledger/bills/includes/card_bill.html +2 -2
- django_ledger/templates/django_ledger/components/menu.html +41 -26
- django_ledger/templates/django_ledger/components/period_navigator.html +5 -3
- django_ledger/templates/django_ledger/customer/customer_detail.html +87 -0
- django_ledger/templates/django_ledger/customer/customer_list.html +0 -1
- django_ledger/templates/django_ledger/customer/tags/customer_table.html +8 -6
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_imported.html +24 -3
- django_ledger/templates/django_ledger/data_import/tags/data_import_job_txs_table.html +26 -10
- django_ledger/templates/django_ledger/entity/entity_dashboard.html +2 -2
- django_ledger/templates/django_ledger/entity/includes/card_entity.html +12 -6
- django_ledger/templates/django_ledger/financial_statements/balance_sheet.html +1 -1
- django_ledger/templates/django_ledger/financial_statements/cash_flow.html +4 -1
- django_ledger/templates/django_ledger/financial_statements/income_statement.html +4 -1
- django_ledger/templates/django_ledger/financial_statements/tags/balance_sheet_statement.html +27 -3
- django_ledger/templates/django_ledger/financial_statements/tags/cash_flow_statement.html +16 -4
- django_ledger/templates/django_ledger/financial_statements/tags/income_statement.html +73 -18
- django_ledger/templates/django_ledger/includes/widget_ratios.html +18 -24
- django_ledger/templates/django_ledger/invoice/includes/card_invoice.html +3 -3
- django_ledger/templates/django_ledger/layouts/base.html +7 -2
- django_ledger/templates/django_ledger/layouts/content_layout_1.html +1 -1
- django_ledger/templates/django_ledger/receipt/customer_receipt_report.html +115 -0
- django_ledger/templates/django_ledger/receipt/receipt_delete.html +30 -0
- django_ledger/templates/django_ledger/receipt/receipt_detail.html +89 -0
- django_ledger/templates/django_ledger/receipt/receipt_list.html +134 -0
- django_ledger/templates/django_ledger/receipt/vendor_receipt_report.html +115 -0
- django_ledger/templates/django_ledger/vendor/tags/vendor_table.html +12 -7
- django_ledger/templates/django_ledger/vendor/vendor_detail.html +86 -0
- django_ledger/templatetags/django_ledger.py +338 -191
- django_ledger/tests/test_accounts.py +1 -2
- django_ledger/tests/test_io.py +17 -0
- django_ledger/tests/test_purchase_order.py +3 -3
- django_ledger/tests/test_transactions.py +1 -2
- django_ledger/urls/__init__.py +1 -4
- django_ledger/urls/customer.py +3 -0
- django_ledger/urls/data_import.py +3 -0
- django_ledger/urls/receipt.py +102 -0
- django_ledger/urls/vendor.py +1 -0
- django_ledger/views/__init__.py +1 -0
- django_ledger/views/bill.py +8 -11
- django_ledger/views/chart_of_accounts.py +6 -4
- django_ledger/views/closing_entry.py +11 -7
- django_ledger/views/customer.py +68 -30
- django_ledger/views/data_import.py +120 -66
- django_ledger/views/djl_api.py +3 -5
- django_ledger/views/entity.py +2 -4
- django_ledger/views/estimate.py +3 -7
- django_ledger/views/inventory.py +3 -5
- django_ledger/views/invoice.py +4 -6
- django_ledger/views/item.py +7 -11
- django_ledger/views/journal_entry.py +1 -2
- django_ledger/views/mixins.py +125 -93
- django_ledger/views/purchase_order.py +24 -35
- django_ledger/views/receipt.py +294 -0
- django_ledger/views/unit.py +1 -2
- django_ledger/views/vendor.py +54 -16
- {django_ledger-0.7.11.dist-info → django_ledger-0.8.1.dist-info}/METADATA +43 -75
- {django_ledger-0.7.11.dist-info → django_ledger-0.8.1.dist-info}/RECORD +104 -122
- {django_ledger-0.7.11.dist-info → django_ledger-0.8.1.dist-info}/WHEEL +1 -1
- django_ledger-0.8.1.dist-info/top_level.txt +1 -0
- django_ledger/contrib/django_ledger_graphene/__init__.py +0 -0
- django_ledger/contrib/django_ledger_graphene/accounts/schema.py +0 -33
- django_ledger/contrib/django_ledger_graphene/api.py +0 -42
- django_ledger/contrib/django_ledger_graphene/apps.py +0 -6
- django_ledger/contrib/django_ledger_graphene/auth/mutations.py +0 -49
- django_ledger/contrib/django_ledger_graphene/auth/schema.py +0 -6
- django_ledger/contrib/django_ledger_graphene/bank_account/mutations.py +0 -61
- django_ledger/contrib/django_ledger_graphene/bank_account/schema.py +0 -34
- django_ledger/contrib/django_ledger_graphene/bill/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/bill/schema.py +0 -34
- django_ledger/contrib/django_ledger_graphene/coa/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/coa/schema.py +0 -30
- django_ledger/contrib/django_ledger_graphene/customers/__init__.py +0 -0
- django_ledger/contrib/django_ledger_graphene/customers/mutations.py +0 -71
- django_ledger/contrib/django_ledger_graphene/customers/schema.py +0 -43
- django_ledger/contrib/django_ledger_graphene/data_import/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/data_import/schema.py +0 -0
- django_ledger/contrib/django_ledger_graphene/entity/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/entity/schema.py +0 -94
- django_ledger/contrib/django_ledger_graphene/item/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/item/schema.py +0 -31
- django_ledger/contrib/django_ledger_graphene/journal_entry/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/journal_entry/schema.py +0 -35
- django_ledger/contrib/django_ledger_graphene/ledger/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/ledger/schema.py +0 -32
- django_ledger/contrib/django_ledger_graphene/purchase_order/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/purchase_order/schema.py +0 -31
- django_ledger/contrib/django_ledger_graphene/transaction/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/transaction/schema.py +0 -36
- django_ledger/contrib/django_ledger_graphene/unit/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/unit/schema.py +0 -27
- django_ledger/contrib/django_ledger_graphene/vendor/mutations.py +0 -0
- django_ledger/contrib/django_ledger_graphene/vendor/schema.py +0 -37
- django_ledger/contrib/django_ledger_graphene/views.py +0 -12
- django_ledger-0.7.11.dist-info/top_level.txt +0 -4
- {django_ledger-0.7.11.dist-info → django_ledger-0.8.1.dist-info/licenses}/AUTHORS.md +0 -0
- {django_ledger-0.7.11.dist-info → django_ledger-0.8.1.dist-info/licenses}/LICENSE +0 -0
django_ledger/models/customer.py
CHANGED
|
@@ -7,17 +7,27 @@ created before it can be assigned to the InvoiceModel. Only customers who are ac
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
import os
|
|
10
|
-
|
|
10
|
+
import warnings
|
|
11
|
+
from uuid import UUID, uuid4
|
|
11
12
|
|
|
12
|
-
from django.core.exceptions import ObjectDoesNotExist
|
|
13
|
-
from django.db import models, transaction
|
|
14
|
-
from django.db.models import
|
|
13
|
+
from django.core.exceptions import ObjectDoesNotExist, ValidationError
|
|
14
|
+
from django.db import IntegrityError, models, transaction
|
|
15
|
+
from django.db.models import F, Manager, Q, QuerySet
|
|
15
16
|
from django.utils.text import slugify
|
|
16
17
|
from django.utils.translation import gettext_lazy as _
|
|
17
18
|
|
|
18
|
-
from django_ledger.models.
|
|
19
|
+
from django_ledger.models.deprecations import deprecated_entity_slug_behavior
|
|
20
|
+
from django_ledger.models.mixins import (
|
|
21
|
+
ContactInfoMixIn,
|
|
22
|
+
CreateUpdateMixIn,
|
|
23
|
+
TaxCollectionMixIn,
|
|
24
|
+
)
|
|
19
25
|
from django_ledger.models.utils import lazy_loader
|
|
20
|
-
from django_ledger.settings import
|
|
26
|
+
from django_ledger.settings import (
|
|
27
|
+
DJANGO_LEDGER_CUSTOMER_NUMBER_PREFIX,
|
|
28
|
+
DJANGO_LEDGER_DOCUMENT_NUMBER_PADDING,
|
|
29
|
+
DJANGO_LEDGER_USE_DEPRECATED_BEHAVIOR,
|
|
30
|
+
)
|
|
21
31
|
|
|
22
32
|
|
|
23
33
|
def customer_picture_upload_to(instance, filename):
|
|
@@ -32,6 +42,10 @@ def customer_picture_upload_to(instance, filename):
|
|
|
32
42
|
return f'customer_pictures/{customer_number}/{safe_name}{ext.lower()}'
|
|
33
43
|
|
|
34
44
|
|
|
45
|
+
class CustomerModelValidationError(ValidationError):
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
|
|
35
49
|
class CustomerModelQueryset(QuerySet):
|
|
36
50
|
"""
|
|
37
51
|
A custom defined QuerySet for the CustomerModel. This implements multiple methods or queries needed to get a
|
|
@@ -40,6 +54,27 @@ class CustomerModelQueryset(QuerySet):
|
|
|
40
54
|
reports.
|
|
41
55
|
"""
|
|
42
56
|
|
|
57
|
+
def for_user(self, user_model):
|
|
58
|
+
"""
|
|
59
|
+
Fetches a QuerySet of BillModels that the UserModel as access to.
|
|
60
|
+
May include BillModels from multiple Entities.
|
|
61
|
+
|
|
62
|
+
The user has access to bills if:
|
|
63
|
+
1. Is listed as Manager of Entity.
|
|
64
|
+
2. Is the Admin of the Entity.
|
|
65
|
+
|
|
66
|
+
Parameters
|
|
67
|
+
__________
|
|
68
|
+
user_model
|
|
69
|
+
Logged in and authenticated django UserModel instance.
|
|
70
|
+
"""
|
|
71
|
+
if user_model.is_superuser:
|
|
72
|
+
return self
|
|
73
|
+
return self.filter(
|
|
74
|
+
Q(entity_model__admin=user_model)
|
|
75
|
+
| Q(entity_model__managers__in=[user_model])
|
|
76
|
+
)
|
|
77
|
+
|
|
43
78
|
def active(self) -> QuerySet:
|
|
44
79
|
"""
|
|
45
80
|
Active customers can be assigned to new Invoices and show on dropdown menus and views.
|
|
@@ -86,66 +121,56 @@ class CustomerModelQueryset(QuerySet):
|
|
|
86
121
|
CustomerModelQueryset
|
|
87
122
|
A QuerySet of visible Customers.
|
|
88
123
|
"""
|
|
89
|
-
return self.filter(
|
|
90
|
-
Q(hidden=False) & Q(active=True)
|
|
91
|
-
)
|
|
124
|
+
return self.filter(Q(hidden=False) & Q(active=True))
|
|
92
125
|
|
|
93
126
|
|
|
94
127
|
class CustomerModelManager(Manager):
|
|
95
128
|
"""
|
|
96
|
-
A custom
|
|
129
|
+
A custom-defined CustomerModelManager that will act as an interface to handling the DB queries to the
|
|
97
130
|
CustomerModel.
|
|
98
131
|
"""
|
|
99
132
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
The user has access to bills if:
|
|
106
|
-
1. Is listed as Manager of Entity.
|
|
107
|
-
2. Is the Admin of the Entity.
|
|
108
|
-
|
|
109
|
-
Parameters
|
|
110
|
-
__________
|
|
111
|
-
user_model
|
|
112
|
-
Logged in and authenticated django UserModel instance.
|
|
113
|
-
"""
|
|
114
|
-
qs = self.get_queryset()
|
|
115
|
-
if user_model.is_superuser:
|
|
116
|
-
return qs
|
|
117
|
-
return qs.filter(
|
|
118
|
-
Q(entity_model__admin=user_model) |
|
|
119
|
-
Q(entity_model__managers__in=[user_model])
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
def for_entity(self, entity_slug, user_model) -> CustomerModelQueryset:
|
|
133
|
+
@deprecated_entity_slug_behavior
|
|
134
|
+
def for_entity(
|
|
135
|
+
self, entity_model: 'EntityModel | str | UUID' = None, **kwargs
|
|
136
|
+
) -> CustomerModelQueryset:
|
|
123
137
|
"""
|
|
124
138
|
Fetches a QuerySet of CustomerModel associated with a specific EntityModel & UserModel.
|
|
125
139
|
May pass an instance of EntityModel or a String representing the EntityModel slug.
|
|
126
140
|
|
|
127
141
|
Parameters
|
|
128
142
|
__________
|
|
129
|
-
|
|
143
|
+
entity_model: str or EntityModel
|
|
130
144
|
The entity slug or EntityModel used for filtering the QuerySet.
|
|
131
|
-
user_model
|
|
132
|
-
Logged in and authenticated django UserModel instance.
|
|
133
|
-
|
|
134
145
|
|
|
135
146
|
Returns
|
|
136
147
|
-------
|
|
137
148
|
CustomerModelQueryset
|
|
138
149
|
A filtered CustomerModel QuerySet.
|
|
139
150
|
"""
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
EntityModel = lazy_loader.get_entity_model()
|
|
152
|
+
qs = self.get_queryset()
|
|
153
|
+
if 'user_model' in kwargs:
|
|
154
|
+
warnings.warn(
|
|
155
|
+
'user_model parameter is deprecated and will be removed in a future release. '
|
|
156
|
+
'Use for_user(user_model).for_entity(entity_model) instead to keep current behavior.',
|
|
157
|
+
DeprecationWarning,
|
|
158
|
+
stacklevel=2,
|
|
145
159
|
)
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
160
|
+
if DJANGO_LEDGER_USE_DEPRECATED_BEHAVIOR:
|
|
161
|
+
qs = qs.for_user(kwargs['user_model'])
|
|
162
|
+
|
|
163
|
+
if isinstance(entity_model, EntityModel):
|
|
164
|
+
qs = qs.filter(entity_model=entity_model)
|
|
165
|
+
elif isinstance(entity_model, str):
|
|
166
|
+
qs = qs.filter(entity_model__slug__exact=entity_model)
|
|
167
|
+
elif isinstance(entity_model, UUID):
|
|
168
|
+
qs = qs.filter(entity_model_id=entity_model)
|
|
169
|
+
else:
|
|
170
|
+
raise CustomerModelValidationError(
|
|
171
|
+
message='Must pass EntityModel, slug or EntityModel UUID',
|
|
172
|
+
)
|
|
173
|
+
return qs
|
|
149
174
|
|
|
150
175
|
|
|
151
176
|
class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMixIn):
|
|
@@ -155,7 +180,7 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
155
180
|
|
|
156
181
|
1. :func:`ContactInfoMixIn <django_ledger.models.mixins.ContactInfoMixIn>`
|
|
157
182
|
2. :func:`CreateUpdateMixIn <django_ledger.models.mixins.CreateUpdateMixIn>`
|
|
158
|
-
|
|
183
|
+
|
|
159
184
|
Attributes
|
|
160
185
|
__________
|
|
161
186
|
uuid : UUID
|
|
@@ -189,19 +214,27 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
189
214
|
unique=True,
|
|
190
215
|
null=True,
|
|
191
216
|
blank=True,
|
|
192
|
-
verbose_name='User defined customer code'
|
|
217
|
+
verbose_name='User defined customer code',
|
|
193
218
|
)
|
|
194
219
|
customer_name = models.CharField(max_length=100)
|
|
195
|
-
customer_number = models.CharField(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
220
|
+
customer_number = models.CharField(
|
|
221
|
+
max_length=30,
|
|
222
|
+
editable=False,
|
|
223
|
+
verbose_name=_('Customer Number'),
|
|
224
|
+
help_text='System generated customer number.',
|
|
225
|
+
)
|
|
226
|
+
entity_model = models.ForeignKey(
|
|
227
|
+
'django_ledger.EntityModel',
|
|
228
|
+
editable=False,
|
|
229
|
+
on_delete=models.CASCADE,
|
|
230
|
+
verbose_name=_('Customer Entity'),
|
|
231
|
+
)
|
|
201
232
|
description = models.TextField()
|
|
202
233
|
active = models.BooleanField(default=True)
|
|
203
234
|
hidden = models.BooleanField(default=False)
|
|
204
|
-
picture = models.ImageField(
|
|
235
|
+
picture = models.ImageField(
|
|
236
|
+
upload_to=customer_picture_upload_to, null=True, blank=True
|
|
237
|
+
)
|
|
205
238
|
|
|
206
239
|
additional_info = models.JSONField(null=True, blank=True, default=dict)
|
|
207
240
|
|
|
@@ -217,9 +250,7 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
217
250
|
models.Index(fields=['active']),
|
|
218
251
|
models.Index(fields=['hidden']),
|
|
219
252
|
]
|
|
220
|
-
unique_together = [
|
|
221
|
-
('entity_model', 'customer_number')
|
|
222
|
-
]
|
|
253
|
+
unique_together = [('entity_model', 'customer_number')]
|
|
223
254
|
|
|
224
255
|
def __str__(self):
|
|
225
256
|
if not self.customer_number:
|
|
@@ -236,10 +267,7 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
236
267
|
bool
|
|
237
268
|
True if customer model can be generated, else False.
|
|
238
269
|
"""
|
|
239
|
-
return all([
|
|
240
|
-
self.entity_model_id,
|
|
241
|
-
not self.customer_number
|
|
242
|
-
])
|
|
270
|
+
return all([self.entity_model_id, not self.customer_number])
|
|
243
271
|
|
|
244
272
|
def _get_next_state_model(self, raise_exception: bool = True):
|
|
245
273
|
"""
|
|
@@ -261,10 +289,12 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
261
289
|
try:
|
|
262
290
|
LOOKUP = {
|
|
263
291
|
'entity_model_id__exact': self.entity_model_id,
|
|
264
|
-
'key__exact': EntityStateModel.KEY_CUSTOMER
|
|
292
|
+
'key__exact': EntityStateModel.KEY_CUSTOMER,
|
|
265
293
|
}
|
|
266
294
|
|
|
267
|
-
state_model_qs = EntityStateModel.objects.filter(
|
|
295
|
+
state_model_qs = EntityStateModel.objects.filter(
|
|
296
|
+
**LOOKUP
|
|
297
|
+
).select_for_update()
|
|
268
298
|
state_model = state_model_qs.get()
|
|
269
299
|
state_model.sequence = F('sequence') + 1
|
|
270
300
|
state_model.save()
|
|
@@ -272,13 +302,12 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
272
302
|
|
|
273
303
|
return state_model
|
|
274
304
|
except ObjectDoesNotExist:
|
|
275
|
-
|
|
276
305
|
LOOKUP = {
|
|
277
306
|
'entity_model_id': self.entity_model_id,
|
|
278
307
|
'entity_unit_id': None,
|
|
279
308
|
'fiscal_year': None,
|
|
280
309
|
'key': EntityStateModel.KEY_CUSTOMER,
|
|
281
|
-
'sequence': 1
|
|
310
|
+
'sequence': 1,
|
|
282
311
|
}
|
|
283
312
|
state_model = EntityStateModel.objects.create(**LOOKUP)
|
|
284
313
|
return state_model
|
|
@@ -303,7 +332,6 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
303
332
|
"""
|
|
304
333
|
if self.can_generate_customer_number():
|
|
305
334
|
with transaction.atomic(durable=True):
|
|
306
|
-
|
|
307
335
|
state_model = None
|
|
308
336
|
while not state_model:
|
|
309
337
|
state_model = self._get_next_state_model(raise_exception=False)
|
|
@@ -316,6 +344,12 @@ class CustomerModelAbstract(ContactInfoMixIn, TaxCollectionMixIn, CreateUpdateMi
|
|
|
316
344
|
|
|
317
345
|
return self.customer_number
|
|
318
346
|
|
|
347
|
+
def validate_for_entity(self, entity_model: 'EntityModel'):
|
|
348
|
+
if entity_model.uuid != self.entity_model_id:
|
|
349
|
+
raise CustomerModelValidationError(
|
|
350
|
+
'EntityModel does not belong to this Vendor'
|
|
351
|
+
)
|
|
352
|
+
|
|
319
353
|
def clean(self):
|
|
320
354
|
"""
|
|
321
355
|
Custom defined clean method that fetches the next customer number if not yet fetched.
|