Add sales channels (#1103)

- [x] Data model
- [x] Enforce constraint
- [x] Filter order list
- [x] Set channel on created order
- [x] Products API
- [x] Order API
- [x] Tests
- [x] Filter reports
- [x] Resellers
- [ ] deploy plugins
  - [ ] posbackend
  - [ ] resellers
  - [ ] reports
- [x] Ticketlayouts
- [x] Support in pretixPOS
This commit is contained in:
Raphael Michel
2018-11-23 15:35:09 +01:00
committed by GitHub
parent 0f76779fb1
commit b4290384e1
39 changed files with 472 additions and 57 deletions

View File

@@ -0,0 +1,94 @@
from django.core import exceptions
from django.db.models import TextField, lookups as builtin_lookups
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
DELIMITER = "\x1F"
class MultiStringField(TextField):
default_error_messages = {
'delimiter_found': _('No value can contain the delimiter character.')
}
def __init__(self, verbose_name=None, name=None, **kwargs):
super().__init__(verbose_name, name, **kwargs)
def deconstruct(self):
name, path, args, kwargs = super().deconstruct()
return name, path, args, kwargs
def to_python(self, value):
if isinstance(value, (list, tuple)):
return value
elif value:
return [v for v in value.split(DELIMITER) if v]
else:
return []
def get_prep_value(self, value):
if isinstance(value, (list, tuple)):
return DELIMITER + DELIMITER.join(value) + DELIMITER
elif value is None:
return ""
raise TypeError("Invalid data type passed.")
def get_prep_lookup(self, lookup_type, value): # NOQA
raise TypeError('Lookups on multi strings are currently not supported.')
def from_db_value(self, value, expression, connection, context):
if value:
return [v for v in value.split(DELIMITER) if v]
else:
return []
def validate(self, value, model_instance):
super().validate(value, model_instance)
for l in value:
if DELIMITER in l:
raise exceptions.ValidationError(
self.error_messages['delimiter_found'],
code='delimiter_found',
)
def get_lookup(self, lookup_name):
if lookup_name == 'contains':
return MultiStringContains
elif lookup_name == 'icontains':
return MultiStringIContains
raise NotImplementedError(
"Lookup '{}' doesn't work with MultiStringField".format(lookup_name),
)
class MultiStringContains(builtin_lookups.Contains):
def process_rhs(self, qn, connection):
sql, params = super().process_rhs(qn, connection)
params[0] = "%" + DELIMITER + params[0][1:-1] + DELIMITER + "%"
return sql, params
class MultiStringIContains(builtin_lookups.IContains):
def process_rhs(self, qn, connection):
sql, params = super().process_rhs(qn, connection)
params[0] = "%" + DELIMITER + params[0][1:-1] + DELIMITER + "%"
return sql, params
class MultiStringSerializer(serializers.Field):
def __init__(self, **kwargs):
self.allow_blank = kwargs.pop('allow_blank', False)
super().__init__(**kwargs)
def to_representation(self, value):
return value
def to_internal_value(self, data):
if isinstance(data, list):
return data
else:
raise ValidationError('Invalid data type.')
serializers.ModelSerializer.serializer_field_mapping[MultiStringField] = MultiStringSerializer