class OrderItemSerializer(serializers.ModelSerializer): """ Serializer for order item. """ product = serializers.JSONField(source='product_data', read_only=True) unit_price = PriceField(read_only=True) subtotal = PriceField(read_only=True) total = PriceField(read_only=True) extra = serializers.JSONField(read_only=True) class Meta: model = OrderItem fields = [ 'id', 'product_type', 'product_id', 'product', 'unit_price', 'quantity', 'subtotal', 'extra_rows', 'total', 'extra', ] read_only_fields = fields
class BasketItemSerializer(serializers.ModelSerializer): """ Serializer for basket item. """ url = serializers.SerializerMethodField() product_type = serializers.CharField(source='product._meta.label', read_only=True) product = ProductField(read_only=True) quantity = serializers.IntegerField(min_value=1) unit_price = PriceField(read_only=True) subtotal = PriceField(read_only=True) total = PriceField(read_only=True) extra = serializers.JSONField( required=False, help_text=_("Extra is updated and null values are removed.")) extra_rows = ExtraRowsField(read_only=True) class Meta: model = BasketItem fields = [ 'url', 'ref', 'product_type', 'product_id', 'product', 'unit_price', 'quantity', 'subtotal', 'extra_rows', 'total', 'extra', ] read_only_fields = fields def get_url(self, obj): request = self.context.get('request', None) url = reverse('salesman-basket-detail', args=[obj.ref]) return request.build_absolute_uri(url) if request else url def validate_extra(self, value): # Update basket `extra` instead of replacing it, remove null values. extra = self.instance.extra if self.instance else {} if value: extra.update(value) extra = {k: v for k, v in extra.items() if v is not None} # Validate using extra validator. context = self.context.copy() context['basket_item'] = self.instance return app_settings.SALESMAN_EXTRA_VALIDATOR(extra, context=context) def to_representation(self, item): item.update(self.context['request']) return super().to_representation(item)
class OrderSerializer(serializers.ModelSerializer): """ Serializer for order. """ url = serializers.SerializerMethodField() subtotal = PriceField(read_only=True) total = PriceField(read_only=True) amount_paid = PriceField(read_only=True) amount_outstanding = PriceField(read_only=True) extra = serializers.JSONField(read_only=True) items = OrderItemSerializer(many=True, read_only=True) payments = OrderPaymentSerializer(many=True, read_only=True) notes = serializers.SerializerMethodField() class Meta: model = Order fields = [ 'id', 'url', 'ref', 'token', 'status', 'status_display', 'date_created', 'date_updated', 'is_paid', 'user', 'email', 'billing_address', 'shipping_address', 'subtotal', 'extra_rows', 'total', 'amount_paid', 'amount_outstanding', 'extra', 'items', 'payments', 'notes', ] read_only_fields = fields prefetched_fields = ['items', 'payments', 'notes'] def get_url(self, obj): request = self.context.get('request', None) url = reverse('salesman-order-detail', args=[obj.ref]) return request.build_absolute_uri(url) if request else url def get_notes(self, obj): notes = [x for x in obj.notes.all() if x.public] return OrderNoteSerializer(notes, many=True).data
class ExtraRowSerializer(serializers.Serializer): """ Extra row serializer used for adding extra data to ``extra_rows`` dict on both the basket and basket item model. Mostly used when processing basket modifiers. """ label = serializers.CharField(read_only=True, default="") amount = PriceField(read_only=True, default=0) extra = serializers.DictField(read_only=True, default={})
class BasketSerializer(serializers.ModelSerializer): """ Serializer for basket. """ items = BasketItemSerializer(source='get_items', many=True, read_only=True) subtotal = PriceField(read_only=True) total = PriceField(read_only=True) extra = serializers.JSONField(read_only=True) extra_rows = ExtraRowsField(read_only=True) class Meta: model = Basket fields = ['id', 'items', 'subtotal', 'total', 'extra', 'extra_rows'] def to_representation(self, basket): basket.update(self.context['request']) return super().to_representation(basket)
class OrderPaymentSerializer(serializers.ModelSerializer): """ Serializer for order payment. """ amount = PriceField(read_only=True) class Meta: model = OrderPayment fields = ['amount', 'transaction_id', 'payment_method', 'date_created'] read_only_fields = fields