mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-27 19:16:44 +00:00
Schema: (Redo) Remove hardcoded enum values from customizable fields (#9452)
* Remove hardcoded currency enum from schema * Convert schema custom key enums to int to allow customized keys to validate * Convert stock status key enums to int to allow customizations to validate in schema * api version bump * Restore enumerated help text for currencies * Remove commented block of old code * Restore custom key enumerated values to schema documentation * Restore status key enumeration to schema documentation
This commit is contained in:
parent
f541d76cd1
commit
f87f4387ed
@ -1,12 +1,16 @@
|
||||
"""InvenTree API version information."""
|
||||
|
||||
# InvenTree API version
|
||||
INVENTREE_API_VERSION = 332
|
||||
INVENTREE_API_VERSION = 333
|
||||
|
||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||
|
||||
|
||||
INVENTREE_API_TEXT = """
|
||||
v333 - 2025-04-03 : https://github.com/inventree/InvenTree/pull/9452
|
||||
- Currency string is no longer restricted to a hardcoded enum
|
||||
- Customizable status keys are no longer hardcoded enum values
|
||||
|
||||
v332 - 2025-04-02 : https://github.com/inventree/InvenTree/pull/9393
|
||||
- Adds 'search_notes' parameter to all searchable API endpoints
|
||||
|
||||
|
@ -13,6 +13,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
from djmoney.contrib.django_rest_framework.fields import MoneyField
|
||||
from djmoney.money import Money
|
||||
from djmoney.utils import MONEY_CLASSES, get_currency_field_name
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import empty
|
||||
@ -86,6 +87,7 @@ class InvenTreeMoneySerializer(MoneyField):
|
||||
return amount
|
||||
|
||||
|
||||
@extend_schema_field(serializers.CharField())
|
||||
class InvenTreeCurrencySerializer(serializers.ChoiceField):
|
||||
"""Custom serializers for selecting currency option."""
|
||||
|
||||
@ -111,6 +113,14 @@ class InvenTreeCurrencySerializer(serializers.ChoiceField):
|
||||
if 'help_text' not in kwargs:
|
||||
kwargs['help_text'] = _('Select currency from available options')
|
||||
|
||||
if InvenTree.ready.isGeneratingSchema():
|
||||
kwargs['help_text'] = (
|
||||
kwargs['help_text']
|
||||
+ '\n\n'
|
||||
+ '\n'.join(f'* `{value}` - {label}' for value, label in choices)
|
||||
+ "\n\nOther valid currencies may be found in the 'CURRENCY_CODES' global setting."
|
||||
)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
|
@ -40,7 +40,11 @@ from InvenTree.serializers import (
|
||||
)
|
||||
from stock.generators import generate_batch_code
|
||||
from stock.models import StockItem, StockLocation
|
||||
from stock.serializers import LocationBriefSerializer, StockItemSerializerBrief
|
||||
from stock.serializers import (
|
||||
LocationBriefSerializer,
|
||||
StockItemSerializerBrief,
|
||||
StockStatusCustomSerializer,
|
||||
)
|
||||
from stock.status_codes import StockStatus
|
||||
from users.serializers import OwnerSerializer, UserSerializer
|
||||
|
||||
@ -581,11 +585,7 @@ class BuildOutputCompleteSerializer(serializers.Serializer):
|
||||
help_text=_('Location for completed build outputs'),
|
||||
)
|
||||
|
||||
status_custom_key = serializers.ChoiceField(
|
||||
choices=StockStatus.items(custom=True),
|
||||
default=StockStatus.OK.value,
|
||||
label=_('Status'),
|
||||
)
|
||||
status_custom_key = StockStatusCustomSerializer(default=StockStatus.OK.value)
|
||||
|
||||
accept_incomplete_allocation = serializers.BooleanField(
|
||||
default=False,
|
||||
|
@ -8,9 +8,13 @@ from django.db import models
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
from rest_framework.fields import ChoiceField
|
||||
|
||||
import InvenTree.ready
|
||||
|
||||
from .custom import get_logical_value
|
||||
|
||||
|
||||
@ -73,6 +77,7 @@ class CustomChoiceField(serializers.ChoiceField):
|
||||
return field_info
|
||||
|
||||
|
||||
@extend_schema_field(OpenApiTypes.INT)
|
||||
class ExtraCustomChoiceField(CustomChoiceField):
|
||||
"""Custom Choice Field that returns value of status if empty.
|
||||
|
||||
@ -138,14 +143,27 @@ class InvenTreeCustomStatusModelField(models.PositiveIntegerField):
|
||||
if self.status_class:
|
||||
validators.append(CustomStatusCodeValidator(status_class=self.status_class))
|
||||
|
||||
help_text = _('Additional status information for this item')
|
||||
if InvenTree.ready.isGeneratingSchema():
|
||||
help_text = (
|
||||
help_text
|
||||
+ '\n\n'
|
||||
+ '\n'.join(
|
||||
f'* `{value}` - {label}'
|
||||
for value, label in self.status_class.items(custom=True)
|
||||
)
|
||||
+ "\n\nAdditional custom status keys may be retrieved from the corresponding 'status_retrieve' call."
|
||||
)
|
||||
|
||||
custom_key_field = ExtraInvenTreeCustomStatusModelField(
|
||||
default=None,
|
||||
verbose_name=_('Custom status key'),
|
||||
help_text=_('Additional status information for this item'),
|
||||
help_text=help_text,
|
||||
validators=validators,
|
||||
blank=True,
|
||||
null=True,
|
||||
)
|
||||
|
||||
cls.add_to_class(f'{name}_custom_key', custom_key_field)
|
||||
self._custom_key_field = custom_key_field
|
||||
|
||||
|
@ -795,11 +795,7 @@ class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer):
|
||||
allow_blank=True,
|
||||
)
|
||||
|
||||
status = serializers.ChoiceField(
|
||||
choices=StockStatus.items(custom=True),
|
||||
default=StockStatus.OK.value,
|
||||
label=_('Status'),
|
||||
)
|
||||
status = stock.serializers.StockStatusCustomSerializer(default=StockStatus.OK.value)
|
||||
|
||||
packaging = serializers.CharField(
|
||||
label=_('Packaging'),
|
||||
@ -1981,13 +1977,8 @@ class ReturnOrderLineItemReceiveSerializer(serializers.Serializer):
|
||||
label=_('Return order line item'),
|
||||
)
|
||||
|
||||
status = serializers.ChoiceField(
|
||||
choices=stock.status_codes.StockStatus.items(custom=True),
|
||||
default=None,
|
||||
label=_('Status'),
|
||||
help_text=_('Stock item status code'),
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
status = stock.serializers.StockStatusCustomSerializer(
|
||||
default=None, required=False, allow_blank=True
|
||||
)
|
||||
|
||||
def validate_line_item(self, item):
|
||||
|
@ -16,6 +16,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
import structlog
|
||||
from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
from djmoney.contrib.exchange.models import convert_money
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
from sql_util.utils import SubqueryCount, SubquerySum
|
||||
from taggit.serializers import TagListSerializerField
|
||||
@ -1300,6 +1301,21 @@ class PartStocktakeReportGenerateSerializer(serializers.Serializer):
|
||||
)
|
||||
|
||||
|
||||
@extend_schema_field(
|
||||
serializers.CharField(
|
||||
help_text=_('Select currency from available options')
|
||||
+ '\n\n'
|
||||
+ '\n'.join(
|
||||
f'* `{value}` - {label}'
|
||||
for value, label in common.currency.currency_code_mappings()
|
||||
)
|
||||
+ "\n\nOther valid currencies may be found in the 'CURRENCY_CODES' global setting."
|
||||
)
|
||||
)
|
||||
class PartPricingCurrencySerializer(serializers.ChoiceField):
|
||||
"""Serializer to allow annotating the schema to use String on currency fields."""
|
||||
|
||||
|
||||
class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||
"""Serializer for Part pricing information."""
|
||||
|
||||
@ -1384,7 +1400,7 @@ class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||
required=False,
|
||||
)
|
||||
|
||||
override_min_currency = serializers.ChoiceField(
|
||||
override_min_currency = PartPricingCurrencySerializer(
|
||||
label=_('Minimum price currency'),
|
||||
read_only=False,
|
||||
required=False,
|
||||
@ -1399,7 +1415,7 @@ class PartPricingSerializer(InvenTree.serializers.InvenTreeModelSerializer):
|
||||
required=False,
|
||||
)
|
||||
|
||||
override_max_currency = serializers.ChoiceField(
|
||||
override_max_currency = PartPricingCurrencySerializer(
|
||||
label=_('Maximum price currency'),
|
||||
read_only=False,
|
||||
required=False,
|
||||
|
@ -10,6 +10,7 @@ from django.db.models.functions import Coalesce
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
import structlog
|
||||
from drf_spectacular.utils import extend_schema_field
|
||||
from rest_framework import serializers
|
||||
from rest_framework.serializers import ValidationError
|
||||
from sql_util.utils import SubqueryCount, SubquerySum
|
||||
@ -984,6 +985,38 @@ class ConvertStockItemSerializer(serializers.Serializer):
|
||||
stock_item.convert_to_variant(part, request.user)
|
||||
|
||||
|
||||
@extend_schema_field(
|
||||
serializers.IntegerField(
|
||||
help_text='Status key, chosen from the list of StockStatus keys'
|
||||
)
|
||||
)
|
||||
class StockStatusCustomSerializer(serializers.ChoiceField):
|
||||
"""Serializer to allow annotating the schema to use int where custom values may be entered."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the status selector."""
|
||||
if 'choices' not in kwargs:
|
||||
kwargs['choices'] = stock.status_codes.StockStatus.items(custom=True)
|
||||
|
||||
if 'label' not in kwargs:
|
||||
kwargs['label'] = _('Status')
|
||||
|
||||
if 'help_text' not in kwargs:
|
||||
kwargs['help_text'] = _('Stock item status code')
|
||||
|
||||
if InvenTree.ready.isGeneratingSchema():
|
||||
kwargs['help_text'] = (
|
||||
kwargs['help_text']
|
||||
+ '\n\n'
|
||||
+ '\n'.join(
|
||||
f'* `{value}` - {label}' for value, label in kwargs['choices']
|
||||
)
|
||||
+ "\n\nAdditional custom status keys may be retrieved from the 'stock_status_retrieve' call."
|
||||
)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class ReturnStockItemSerializer(serializers.Serializer):
|
||||
"""DRF serializer for returning a stock item from a customer."""
|
||||
|
||||
@ -1001,14 +1034,7 @@ class ReturnStockItemSerializer(serializers.Serializer):
|
||||
help_text=_('Destination location for returned item'),
|
||||
)
|
||||
|
||||
status = serializers.ChoiceField(
|
||||
choices=stock.status_codes.StockStatus.items(custom=True),
|
||||
default=None,
|
||||
label=_('Status'),
|
||||
help_text=_('Stock item status code'),
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
status = StockStatusCustomSerializer(default=None, required=False, allow_blank=True)
|
||||
|
||||
notes = serializers.CharField(
|
||||
label=_('Notes'),
|
||||
@ -1058,10 +1084,8 @@ class StockChangeStatusSerializer(serializers.Serializer):
|
||||
|
||||
return items
|
||||
|
||||
status = serializers.ChoiceField(
|
||||
choices=stock.status_codes.StockStatus.items(custom=True),
|
||||
default=stock.status_codes.StockStatus.OK.value,
|
||||
label=_('Status'),
|
||||
status = StockStatusCustomSerializer(
|
||||
default=stock.status_codes.StockStatus.OK.value
|
||||
)
|
||||
|
||||
note = serializers.CharField(
|
||||
@ -1620,11 +1644,9 @@ class StockAdjustmentItemSerializer(serializers.Serializer):
|
||||
help_text=_('Batch code for this stock item'),
|
||||
)
|
||||
|
||||
status = serializers.ChoiceField(
|
||||
status = StockStatusCustomSerializer(
|
||||
choices=stock_item_adjust_status_options(),
|
||||
default=None,
|
||||
label=_('Status'),
|
||||
help_text=_('Stock item status code'),
|
||||
required=False,
|
||||
allow_blank=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user