You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

forms.py 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import re
  2. from django import forms
  3. from django.db.models import Q
  4. from django.utils.translation import ugettext_lazy as _
  5. from oscar.core.loading import get_model
  6. Product = get_model('catalogue', 'Product')
  7. Range = get_model('offer', 'Range')
  8. class RangeForm(forms.ModelForm):
  9. class Meta:
  10. model = Range
  11. exclude = ('included_products', 'slug', 'excluded_products', 'classes',
  12. 'proxy_class')
  13. class RangeProductForm(forms.Form):
  14. query = forms.CharField(
  15. max_length=1024, label=_("Product SKUs or UPCs"),
  16. widget=forms.Textarea, required=False,
  17. help_text=_("You can paste in a selection of SKUs or UPCs"))
  18. file_upload = forms.FileField(
  19. label=_("File of SKUs or UPCs"), required=False, max_length=255,
  20. help_text=_('Either comma-separated, or one identifier per line'))
  21. def __init__(self, range, *args, **kwargs):
  22. self.range = range
  23. super(RangeProductForm, self).__init__(*args, **kwargs)
  24. def clean(self):
  25. clean_data = super(RangeProductForm, self).clean()
  26. if not clean_data.get('query') and not clean_data.get('file_upload'):
  27. raise forms.ValidationError(
  28. _("You must submit either a list of SKU/UPCs or a file"))
  29. return clean_data
  30. def clean_query(self):
  31. raw = self.cleaned_data['query']
  32. if not raw:
  33. return raw
  34. # Check that the search matches some products
  35. ids = set(re.compile(r'[\w-]+').findall(raw))
  36. products = self.range.included_products.all()
  37. existing_skus = set(products.values_list(
  38. 'stockrecords__partner_sku', flat=True))
  39. existing_upcs = set(products.values_list('upc', flat=True))
  40. existing_ids = existing_skus.union(existing_upcs)
  41. new_ids = ids - existing_ids
  42. if len(new_ids) == 0:
  43. raise forms.ValidationError(
  44. _("The products with SKUs or UPCs matching %s are already in"
  45. " this range") % (', '.join(ids)))
  46. self.products = Product._default_manager.filter(
  47. Q(stockrecords__partner_sku__in=new_ids) |
  48. Q(upc__in=new_ids))
  49. if len(self.products) == 0:
  50. raise forms.ValidationError(
  51. _("No products exist with a SKU or UPC matching %s")
  52. % ", ".join(ids))
  53. found_skus = set(self.products.values_list(
  54. 'stockrecords__partner_sku', flat=True))
  55. found_upcs = set(self.products.values_list('upc', flat=True))
  56. found_ids = found_skus.union(found_upcs)
  57. self.missing_skus = new_ids - found_ids
  58. self.duplicate_skus = existing_ids.intersection(ids)
  59. return raw
  60. def get_products(self):
  61. return self.products if hasattr(self, 'products') else []
  62. def get_missing_skus(self):
  63. return self.missing_skus
  64. def get_duplicate_skus(self):
  65. return self.duplicate_skus