|
10 | 10 | whether temporarily or indefinitely may be flagged as inactive (i.e. active is False). Hidden Vendors will not show up |
11 | 11 | as an option in the UI, but can still be used programmatically (via API). |
12 | 12 | """ |
13 | | - |
| 13 | +import os |
14 | 14 | from uuid import uuid4 |
15 | 15 |
|
16 | 16 | from django.core.exceptions import ObjectDoesNotExist, ValidationError |
17 | 17 | from django.db import models, transaction, IntegrityError |
18 | | -from django.db.models import Q, F, QuerySet |
| 18 | +from django.db.models import Q, F, QuerySet, Manager |
| 19 | +from django.utils.text import slugify |
19 | 20 | from django.utils.translation import gettext_lazy as _ |
20 | 21 |
|
21 | 22 | from django_ledger.models.mixins import ContactInfoMixIn, CreateUpdateMixIn, FinancialAccountInfoMixin, TaxInfoMixIn |
22 | 23 | from django_ledger.models.utils import lazy_loader |
23 | 24 | from django_ledger.settings import DJANGO_LEDGER_DOCUMENT_NUMBER_PADDING, DJANGO_LEDGER_VENDOR_NUMBER_PREFIX |
24 | 25 |
|
25 | 26 |
|
| 27 | +def vendor_picture_upload_to(instance, filename): |
| 28 | + if not instance.customer_number: |
| 29 | + instance.generate_customer_number(commit=False) |
| 30 | + vendor_number = instance.customer_number |
| 31 | + name, ext = os.path.splitext(filename) |
| 32 | + safe_name = slugify(name) |
| 33 | + return f'vendor_pictures/{vendor_number}/{safe_name}{ext.lower()}' |
| 34 | + |
| 35 | + |
26 | 36 | class VendorModelValidationError(ValidationError): |
27 | 37 | pass |
28 | 38 |
|
@@ -83,7 +93,7 @@ def visible(self) -> QuerySet: |
83 | 93 | ) |
84 | 94 |
|
85 | 95 |
|
86 | | -class VendorModelManager(models.Manager): |
| 96 | +class VendorModelManager(Manager): |
87 | 97 | """ |
88 | 98 | Custom defined VendorModel Manager, which defines many methods for initial query of the Database. |
89 | 99 | """ |
@@ -173,15 +183,27 @@ class VendorModelAbstract(ContactInfoMixIn, |
173 | 183 |
|
174 | 184 | """ |
175 | 185 | uuid = models.UUIDField(default=uuid4, editable=False, primary_key=True) |
176 | | - vendor_number = models.CharField(max_length=30, null=True, blank=True) |
| 186 | + vendor_code = models.SlugField( |
| 187 | + max_length=50, |
| 188 | + null=True, |
| 189 | + blank=True, |
| 190 | + verbose_name='User defined vendor code.' |
| 191 | + ) |
| 192 | + vendor_number = models.CharField(max_length=30, |
| 193 | + null=True, |
| 194 | + blank=True, |
| 195 | + editable=False, |
| 196 | + verbose_name=_('Vendor Number'), help_text='System generated vendor number.') |
177 | 197 | vendor_name = models.CharField(max_length=100) |
178 | 198 |
|
179 | 199 | entity_model = models.ForeignKey('django_ledger.EntityModel', |
180 | 200 | on_delete=models.CASCADE, |
181 | | - verbose_name=_('Vendor Entity')) |
| 201 | + verbose_name=_('Vendor Entity'), |
| 202 | + editable=False) |
182 | 203 | description = models.TextField() |
183 | 204 | active = models.BooleanField(default=True) |
184 | 205 | hidden = models.BooleanField(default=False) |
| 206 | + picture = models.ImageField(upload_to=vendor_picture_upload_to, null=True, blank=True) |
185 | 207 |
|
186 | 208 | additional_info = models.JSONField(null=True, blank=True, default=dict) |
187 | 209 |
|
@@ -215,7 +237,7 @@ def can_generate_vendor_number(self) -> bool: |
215 | 237 | Returns |
216 | 238 | ------- |
217 | 239 | bool |
218 | | - True if vendor number can be generated, else False. |
| 240 | + True if the vendor number can be generated, else False. |
219 | 241 | """ |
220 | 242 | return all([ |
221 | 243 | self.entity_model_id, |
|
0 commit comments