Skip to content

Commit 2fe0eef

Browse files
Adds "active" field for Company model (inventree#7024)
* Add "active" field to Company model * Expose 'active' parameter to API * Fix default value * Add 'active' column to PUI * Update PUI table * Update company detail pages * Update API filters for SupplierPart and ManufacturerPart * Bump API version * Update order forms * Add edit action to SalesOrderDetail page * Enable editing of ReturnOrder * Typo fix * Adds explicit "active" field to SupplierPart model * More updates - Add "inactive" badge to SupplierPart page - Update SupplierPartTable - Update backend API fields * Update ReturnOrderTable - Also some refactoring * Impove usePurchaseOrderLineItemFields hook * Cleanup * Implement duplicate action for SupplierPart * Fix for ApiForm - Only override initialValues for specified fields * Allow edit and duplicate of StockItem * Fix for ApiForm - Default values were overriding initial data * Add duplicate part option * Cleanup ApiForm - Cache props.fields * Fix unused import * More fixes * Add unit tests * Allow ordering company by 'active' status * Update docs * Merge migrations * Fix for serializers.py * Force new form value * Remove debug call * Further unit test fixes * Update default CSRF_TRUSTED_ORIGINS values * Reduce debug output
1 parent 2632bcf commit 2fe0eef

41 files changed

Lines changed: 927 additions & 390 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ Run the following commands from the top-level project directory:
1212

1313
```
1414
$ git clone https://github.com/inventree/inventree
15-
$ cd inventree/docs
16-
$ pip install -r requirements.txt
15+
$ pip install -r docs/requirements.txt
1716
```
1817

1918
## Serve Locally
27.7 KB
Loading
55.5 KB
Loading
26.5 KB
Loading

docs/docs/order/company.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ External companies are represented by the *Company* database model. Each company
1111
- [Manufacturer](#manufacturers)
1212

1313
!!! tip Multi Purpose
14-
A company may be allocated to multiple categories
14+
A company may be allocated to multiple categories, for example, a company may be both a supplier and a customer.
1515

1616
### Edit Company
1717

@@ -20,6 +20,20 @@ To edit a company, click on the <span class='fas fa-edit'>Edit Company</span> ic
2020
!!! warning "Permission Required"
2121
The edit button will not be available to users who do not have the required permissions to edit the company
2222

23+
### Disable Company
24+
25+
Rather than deleting a company, it is possible to disable it. This will prevent the company from being used in new orders, but will not remove it from the database. Additionally, any existing orders associated with the company (and other linked items such as supplier parts, for a supplier) will remain intact. Unless the company is re-enabled, it will not be available for selection in new orders.
26+
27+
It is recommended to disable a company rather than deleting it, as this will preserve the integrity of historical data.
28+
29+
To disable a company, simply edit the company details and set the `active` attribute to `False`:
30+
31+
{% with id="company_disable", url="order/company_disable.png", description="Disable Company" %}
32+
{% include "img.html" %}
33+
{% endwith %}
34+
35+
To re-enable a company, simply follow the same process and set the `active` attribute to `True`.
36+
2337
### Delete Company
2438

2539
To delete a company, click on the <span class='fas fa-trash-alt'></span> icon under the actions menu. Confirm the deletion using the checkbox then click on <span class="badge inventree confirm">Submit</span>
@@ -193,6 +207,24 @@ To edit a supplier part, first access the supplier part detail page with one of
193207

194208
After the supplier part details are loaded, click on the <span class='fas fa-edit'></span> icon next to the supplier part image. Edit the supplier part information then click on <span class="badge inventree confirm">Submit</span>
195209

210+
#### Disable Supplier Part
211+
212+
Supplier parts can be individually disabled - for example, if a supplier part is no longer available for purchase. By disabling the part in the InvenTree system, it will no longer be available for selection in new purchase orders. However, any existing purchase orders which reference the supplier part will remain intact.
213+
214+
The "active" status of a supplier part is clearly visible within the user interface:
215+
216+
{% with id="supplier_part_disable", url="order/disable_supplier_part.png", description="Disable Supplier Part" %}
217+
{% include "img.html" %}
218+
{% endwith %}
219+
220+
To change the "active" status of a supplier part, simply edit the supplier part details and set the `active` attribute:
221+
222+
{% with id="supplier_part_disable_edit", url="order/disable_supplier_part_edit.png", description="Disable Supplier Part" %}
223+
{% include "img.html" %}
224+
{% endwith %}
225+
226+
It is recommended to disable a supplier part rather than deleting it, as this will preserve the integrity of historical data.
227+
196228
#### Delete Supplier Part
197229

198230
To delete a supplier part, first access the supplier part detail page like in the [Edit Supplier Part](#edit-supplier-part) section.

src/backend/InvenTree/InvenTree/api_version.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
"""InvenTree API version information."""
22

33
# InvenTree API version
4-
INVENTREE_API_VERSION = 189
4+
INVENTREE_API_VERSION = 190
55
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
66

77
INVENTREE_API_TEXT = """
88
9+
v190 - 2024-04-19 : https://github.com/inventree/InvenTree/pull/7024
10+
- Adds "active" field to the Company API endpoints
11+
- Allow company list to be filtered by "active" status
12+
913
v189 - 2024-04-19 : https://github.com/inventree/InvenTree/pull/7066
1014
- Adds "currency" field to CompanyBriefSerializer class
1115

src/backend/InvenTree/InvenTree/settings.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,14 +1087,17 @@
10871087
if SITE_URL and SITE_URL not in CSRF_TRUSTED_ORIGINS:
10881088
CSRF_TRUSTED_ORIGINS.append(SITE_URL)
10891089

1090-
if not TESTING and len(CSRF_TRUSTED_ORIGINS) == 0:
1091-
if DEBUG:
1092-
logger.warning(
1093-
'No CSRF_TRUSTED_ORIGINS specified. Defaulting to http://* for debug mode. This is not recommended for production use'
1094-
)
1095-
CSRF_TRUSTED_ORIGINS = ['http://*']
1090+
if DEBUG:
1091+
for origin in [
1092+
'http://localhost',
1093+
'http://*.localhost' 'http://*localhost:8000',
1094+
'http://*localhost:5173',
1095+
]:
1096+
if origin not in CSRF_TRUSTED_ORIGINS:
1097+
CSRF_TRUSTED_ORIGINS.append(origin)
10961098

1097-
elif isInMainThread():
1099+
if not TESTING and len(CSRF_TRUSTED_ORIGINS) == 0:
1100+
if isInMainThread():
10981101
# Server thread cannot run without CSRF_TRUSTED_ORIGINS
10991102
logger.error(
11001103
'No CSRF_TRUSTED_ORIGINS specified. Please provide a list of trusted origins, or specify INVENTREE_SITE_URL'

src/backend/InvenTree/company/api.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from django.db.models import Q
44
from django.urls import include, path, re_path
5+
from django.utils.translation import gettext_lazy as _
56

67
from django_filters import rest_framework as rest_filters
78

@@ -58,11 +59,17 @@ def get_queryset(self):
5859

5960
filter_backends = SEARCH_ORDER_FILTER
6061

61-
filterset_fields = ['is_customer', 'is_manufacturer', 'is_supplier', 'name']
62+
filterset_fields = [
63+
'is_customer',
64+
'is_manufacturer',
65+
'is_supplier',
66+
'name',
67+
'active',
68+
]
6269

6370
search_fields = ['name', 'description', 'website']
6471

65-
ordering_fields = ['name', 'parts_supplied', 'parts_manufactured']
72+
ordering_fields = ['active', 'name', 'parts_supplied', 'parts_manufactured']
6673

6774
ordering = 'name'
6875

@@ -153,7 +160,13 @@ class Meta:
153160
fields = ['manufacturer', 'MPN', 'part', 'tags__name', 'tags__slug']
154161

155162
# Filter by 'active' status of linked part
156-
active = rest_filters.BooleanFilter(field_name='part__active')
163+
part_active = rest_filters.BooleanFilter(
164+
field_name='part__active', label=_('Part is Active')
165+
)
166+
167+
manufacturer_active = rest_filters.BooleanFilter(
168+
field_name='manufacturer__active', label=_('Manufacturer is Active')
169+
)
157170

158171

159172
class ManufacturerPartList(ListCreateDestroyAPIView):
@@ -301,8 +314,16 @@ class Meta:
301314
'tags__slug',
302315
]
303316

317+
active = rest_filters.BooleanFilter(label=_('Supplier Part is Active'))
318+
304319
# Filter by 'active' status of linked part
305-
active = rest_filters.BooleanFilter(field_name='part__active')
320+
part_active = rest_filters.BooleanFilter(
321+
field_name='part__active', label=_('Internal Part is Active')
322+
)
323+
324+
supplier_active = rest_filters.BooleanFilter(
325+
field_name='supplier__active', label=_('Supplier is Active')
326+
)
306327

307328
# Filter by the 'MPN' of linked manufacturer part
308329
MPN = rest_filters.CharFilter(
@@ -378,6 +399,7 @@ def get_serializer(self, *args, **kwargs):
378399
'part',
379400
'supplier',
380401
'manufacturer',
402+
'active',
381403
'MPN',
382404
'packaging',
383405
'pack_quantity',
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Generated by Django 4.2.11 on 2024-04-15 14:42
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('company', '0068_auto_20231120_1108'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='company',
15+
name='active',
16+
field=models.BooleanField(default=True, help_text='Is this company active?', verbose_name='Active'),
17+
),
18+
migrations.AddField(
19+
model_name='supplierpart',
20+
name='active',
21+
field=models.BooleanField(default=True, help_text='Is this supplier part active?', verbose_name='Active'),
22+
),
23+
]

src/backend/InvenTree/company/models.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class Company(
8181
link: Secondary URL e.g. for link to internal Wiki page
8282
image: Company image / logo
8383
notes: Extra notes about the company
84+
active: boolean value, is this company active
8485
is_customer: boolean value, is this company a customer
8586
is_supplier: boolean value, is this company a supplier
8687
is_manufacturer: boolean value, is this company a manufacturer
@@ -155,6 +156,10 @@ def get_api_url():
155156
verbose_name=_('Image'),
156157
)
157158

159+
active = models.BooleanField(
160+
default=True, verbose_name=_('Active'), help_text=_('Is this company active?')
161+
)
162+
158163
is_customer = models.BooleanField(
159164
default=False,
160165
verbose_name=_('is customer'),
@@ -654,6 +659,7 @@ class SupplierPart(
654659
part: Link to the master Part (Obsolete)
655660
source_item: The sourcing item linked to this SupplierPart instance
656661
supplier: Company that supplies this SupplierPart object
662+
active: Boolean value, is this supplier part active
657663
SKU: Stock keeping unit (supplier part number)
658664
link: Link to external website for this supplier part
659665
description: Descriptive notes field
@@ -802,6 +808,12 @@ def save(self, *args, **kwargs):
802808
help_text=_('Supplier stock keeping unit'),
803809
)
804810

811+
active = models.BooleanField(
812+
default=True,
813+
verbose_name=_('Active'),
814+
help_text=_('Is this supplier part active?'),
815+
)
816+
805817
manufacturer_part = models.ForeignKey(
806818
ManufacturerPart,
807819
on_delete=models.CASCADE,

0 commit comments

Comments
 (0)