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.

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