diff --git a/InvenTree/InvenTree/version.py b/InvenTree/InvenTree/version.py index c2548fb4b6..f913678a9b 100644 --- a/InvenTree/InvenTree/version.py +++ b/InvenTree/InvenTree/version.py @@ -8,7 +8,7 @@ import re import common.models -INVENTREE_SW_VERSION = "0.5.2" +INVENTREE_SW_VERSION = "0.5.3" # InvenTree API version INVENTREE_API_VERSION = 12 diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 40cb2ddd5c..d3c4325105 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -670,6 +670,18 @@ class InvenTreeSetting(BaseInvenTreeSetting): 'validator': bool, }, + # 2021-10-08 + # This setting exists as an interim solution for https://github.com/inventree/InvenTree/issues/2042 + # The BOM API can be extremely slow when calculating pricing information "on the fly" + # A future solution will solve this properly, + # but as an interim step we provide a global to enable / disable BOM pricing + 'PART_SHOW_PRICE_IN_BOM': { + 'name': _('Show Price in BOM'), + 'description': _('Include pricing information in BOM tables'), + 'default': True, + 'validator': bool, + }, + 'PART_SHOW_RELATED': { 'name': _('Show related parts'), 'description': _('Display related parts for a part'), diff --git a/InvenTree/part/api.py b/InvenTree/part/api.py index 34441286ff..de37d4ea52 100644 --- a/InvenTree/part/api.py +++ b/InvenTree/part/api.py @@ -1100,6 +1100,12 @@ class BomList(generics.ListCreateAPIView): except AttributeError: pass + try: + # Include or exclude pricing information in the serialized data + kwargs['include_pricing'] = str2bool(self.request.GET.get('include_pricing', True)) + except AttributeError: + pass + # Ensure the request context is passed through! kwargs['context'] = self.get_serializer_context() @@ -1141,6 +1147,18 @@ class BomList(generics.ListCreateAPIView): except (ValueError, Part.DoesNotExist): pass + include_pricing = str2bool(params.get('include_pricing', True)) + + if include_pricing: + queryset = self.annotate_pricing(queryset) + + return queryset + + def annotate_pricing(self, queryset): + """ + Add part pricing information to the queryset + """ + # Annotate with purchase prices queryset = queryset.annotate( purchase_price_min=Min('sub_part__stock_items__purchase_price'), diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index 060faf8b0d..90dfecf26a 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -418,6 +418,7 @@ class BomItemSerializer(InvenTreeModelSerializer): part_detail = kwargs.pop('part_detail', False) sub_part_detail = kwargs.pop('sub_part_detail', False) + include_pricing = kwargs.pop('include_pricing', False) super(BomItemSerializer, self).__init__(*args, **kwargs) @@ -427,6 +428,14 @@ class BomItemSerializer(InvenTreeModelSerializer): if sub_part_detail is not True: self.fields.pop('sub_part_detail') + if not include_pricing: + # Remove all pricing related fields + self.fields.pop('price_range') + self.fields.pop('purchase_price_min') + self.fields.pop('purchase_price_max') + self.fields.pop('purchase_price_avg') + self.fields.pop('purchase_price_range') + @staticmethod def setup_eager_loading(queryset): queryset = queryset.prefetch_related('part') diff --git a/InvenTree/templates/InvenTree/settings/part.html b/InvenTree/templates/InvenTree/settings/part.html index 14a18a1aa5..ee662d6905 100644 --- a/InvenTree/templates/InvenTree/settings/part.html +++ b/InvenTree/templates/InvenTree/settings/part.html @@ -19,6 +19,7 @@ {% include "InvenTree/settings/setting.html" with key="PART_ALLOW_EDIT_IPN" %} {% include "InvenTree/settings/setting.html" with key="PART_SHOW_QUANTITY_IN_FORMS" icon="fa-hashtag" %} {% include "InvenTree/settings/setting.html" with key="PART_SHOW_PRICE_IN_FORMS" icon="fa-dollar-sign" %} + {% include "InvenTree/settings/setting.html" with key="PART_SHOW_PRICE_IN_BOM" icon="fa-dollar-sign" %} {% include "InvenTree/settings/setting.html" with key="PART_SHOW_RELATED" icon="fa-random" %} {% include "InvenTree/settings/setting.html" with key="PART_CREATE_INITIAL" icon="fa-boxes" %}