internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: django-oscar/django-oscar

Issue:
date_from and date_to should be required=False
These fields:
https://github.com/django-oscar/django-oscar/blob/1.0.1/oscar/apps/dashboard/reports/forms.py#L22

should be set to `required=False`

Because the base `ReportGenerator` class is capable of handling form submissions without a date range by checking if `self.date_range_field_name` is set to `None`. 
https://github.com/django-oscar/django-oscar/blob/1.0.1/oscar/apps/dashboard/reports/reports.py#L56



Discussion:
Sorry. I would send a pull request. But to be honest, I have to look up how to do that--and it's 1:00am in my timezone. :(


Resolving patch:
diff --git a/src/oscar/apps/dashboard/reports/forms.py b/src/oscar/apps/dashboard/reports/forms.py
--- a/src/oscar/apps/dashboard/reports/forms.py
+++ b/src/oscar/apps/dashboard/reports/forms.py
@@ -19,10 +19,11 @@ class ReportForm(forms.Form):
                                                 " reports use the selected"
                                                 " date range"))
 
-    date_from = forms.DateField(label=_("Date from"))
+    date_from = forms.DateField(label=_("Date from"), required=False)
     date_to = forms.DateField(label=_("Date to"),
                               help_text=_("The report is inclusive of this"
-                                          " date"))
+                                          " date"),
+                              required=False)
     download = forms.BooleanField(label=_("Download"), required=False)
 
     def clean(self):


Test patch:
Repository: django-oscar/django-oscar

Issue:
Postcode field raises ValidationError even if set as not required
I've set up

<pre>
OSCAR_REQUIRED_ADDRESS_FIELDS = ('first_name', 'last_name', 'line4', 'line1', 'country')
</pre>

but form does not validates empty postcode field. Seems like _ensure_postcode_is_valid_for_country_ [1] method doesnt know anything about this feature.

[1] https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/address/abstract_models.py#L262



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/address/abstract_models.py b/src/oscar/apps/address/abstract_models.py
--- a/src/oscar/apps/address/abstract_models.py
+++ b/src/oscar/apps/address/abstract_models.py
@@ -1,6 +1,7 @@
 import re
 import zlib
 
+from django.conf import settings
 from django.db import models
 from django.utils.encoding import python_2_unicode_compatible
 from django.utils.translation import ugettext_lazy as _, pgettext_lazy
@@ -10,7 +11,6 @@
 from oscar.models.fields import UppercaseCharField, PhoneNumberField
 from django.utils.six.moves import filter
 
-
 @python_2_unicode_compatible
 class AbstractAddress(models.Model):
     """
@@ -27,7 +27,9 @@ class AbstractAddress(models.Model):
         (MS, _("Ms")),
         (DR, _("Dr")),
     )
-
+    
+    POSTCODE_REQUIRED = 'postcode' in settings.OSCAR_REQUIRED_ADDRESS_FIELDS
+    
     # Regex for each country. Not listed countries don't use postcodes
     # Based on http://en.wikipedia.org/wiki/List_of_postal_codes
     POSTCODES_REGEX = {
@@ -263,7 +265,7 @@ def ensure_postcode_is_valid_for_country(self):
         """
         Validate postcode given the country
         """
-        if not self.postcode and self.country_id:
+        if not self.postcode and self.POSTCODE_REQUIRED and self.country_id:
             country_code = self.country.iso_3166_1_a2
             regex = self.POSTCODES_REGEX.get(country_code, None)
             if regex:


Test patch:
Repository: django-oscar/django-oscar

Issue:
Shipping dashboard not in OSCAR_CORE_APPS
Assuming this is not intentional, `OSCAR_CORE_APPS` is missing `oscar.apps.dashboard.shipping`.

Including a manually overridden shipping dashboard app in `get_core_apps` override won't work. This is not a "real" problem since putting this app directly inside Django's `INSTALLED_APPS` will do the trick, and `oscar.core.loading.get_class` will find overridden classes as expected.

Anyway, `oscar_fork_app` management command doesn't work for this app, since it's not found here: https://github.com/lucaippo/django-oscar/blob/master/src/oscar/core/customisation.py#L67-L71



Discussion:

Resolving patch:
diff --git a/src/oscar/__init__.py b/src/oscar/__init__.py
--- a/src/oscar/__init__.py
+++ b/src/oscar/__init__.py
@@ -58,6 +58,7 @@ def get_version():
     'oscar.apps.dashboard.reviews',
     'oscar.apps.dashboard.vouchers',
     'oscar.apps.dashboard.communications',
+    'oscar.apps.dashboard.shipping',
     # 3rd-party apps that oscar depends on
     'haystack',
     'treebeard',


Test patch:
Repository: django-oscar/django-oscar

Issue:
In cases where the stock is lower than the number of allocated products incorrect message appears
To reproduce:
1. Add 2 products to basket
2. On one of them set num of allocated products as 1 and stock as 0.
3. On the basket page try to do an operation on the one that is still in stock. The message that appears is "a maximum of -1 can be bought" instead of the "no stock available" message



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/partner/availability.py b/src/oscar/apps/partner/availability.py
--- a/src/oscar/apps/partner/availability.py
+++ b/src/oscar/apps/partner/availability.py
@@ -83,7 +83,7 @@ def __init__(self, num_available):
         self.num_available = num_available
 
     def is_purchase_permitted(self, quantity):
-        if self.num_available == 0:
+        if self.num_available <= 0:
             return False, _("no stock available")
         if quantity > self.num_available:
             msg = _("a maximum of %(max)d can be bought") % {


Test patch:
diff --git a/tests/unit/partner/availability_tests.py b/tests/unit/partner/availability_tests.py
--- a/tests/unit/partner/availability_tests.py
+++ b/tests/unit/partner/availability_tests.py
@@ -51,8 +51,9 @@ def test_permits_purchases_up_to_stock_level(self):
             self.assertTrue(is_permitted)
 
     def test_forbids_purchases_over_stock_level(self):
-        is_permitted, __ = self.availability.is_purchase_permitted(7)
+        is_permitted, msg = self.availability.is_purchase_permitted(7)
         self.assertFalse(is_permitted)
+        self.assertEqual(msg, "a maximum of 5 can be bought")
 
     def test_returns_correct_code(self):
         self.assertEqual('instock', self.availability.code)
@@ -60,6 +61,13 @@ def test_returns_correct_code(self):
     def test_returns_correct_message(self):
         self.assertEqual('In stock (5 available)', self.availability.message)
 
+    def test_returns_correct_message_when_allocation_higher_than_stock(self):
+        # this is the value passed when stock lower than allocation by 1
+        self.availability.num_available = -1
+        is_permitted, msg = self.availability.is_purchase_permitted(1)
+        self.assertFalse(is_permitted)
+        self.assertEqual(msg, "no stock available")
+
 
 class TestStockRequiredWrapperForRecordWithoutStock(TestCase):
Repository: django-oscar/django-oscar

Issue:
Dashboard email preview crashes on email templates with hyphen in code
To reproduce, add a `CommunicationEventType` instance through the admin page with a hyphen in its code field (e.g. `TEST-DASH`). Open the dashboard and navigate to Content > Email Templates; an internal server error occurs.

Probably a good fix would be to add validation to the `code` field to ensure that it matches `\w+` as the regular expression in https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/dashboard/communications/app.py#L17 suggests.



Discussion:
Thanks for the report - I'll take a butchers.


Resolving patch:
diff --git a/src/oscar/apps/customer/abstract_models.py b/src/oscar/apps/customer/abstract_models.py
--- a/src/oscar/apps/customer/abstract_models.py
+++ b/src/oscar/apps/customer/abstract_models.py
@@ -5,6 +5,7 @@
 from django.conf import settings
 from django.contrib.auth import models as auth_models
 from django.core.urlresolvers import reverse
+from django.core.validators import RegexValidator
 from django.db import models
 from django.template import Template, Context, TemplateDoesNotExist
 from django.template.loader import get_template
@@ -141,6 +142,12 @@ class AbstractCommunicationEventType(models.Model):
     code = AutoSlugField(
         _('Code'), max_length=128, unique=True, populate_from='name',
         separator=six.u("_"), uppercase=True, editable=True,
+        validators=[
+            RegexValidator(
+                regex=r'^[a-zA-Z_][0-9a-zA-Z_]*$',
+                message=_(
+                    "Code can only contain the letters a-z, A-Z, digits, "
+                    "and underscores, and can't start with a digit."))],
         help_text=_("Code used for looking up this event programmatically"))
 
     #: Name is the friendly description of an event for use in the admin


Test patch:
diff --git a/tests/unit/customer/test_models.py b/tests/unit/customer/test_models.py
new file mode 100644
--- /dev/null
+++ b/tests/unit/customer/test_models.py
@@ -0,0 +1,10 @@
+import pytest
+from django.core import exceptions
+
+from oscar.apps.customer import models
+
+
+def test_communication_event_type_code_forbids_hyphens():
+    ctype = models.CommunicationEventType(code="A-B")
+    with pytest.raises(exceptions.ValidationError):
+        ctype.full_clean()
Repository: django-oscar/django-oscar

Issue:
Create template tag for reviews
See https://github.com/tangentlabs/django-oscar/commit/6029026b7585f14bd88bfe33d4b4b296f3f7d14b#commitcomment-2209224

It makes more sense to have reviews loaded via a templatetag rather than in the `get_context_data` method.



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/catalogue/views.py b/src/oscar/apps/catalogue/views.py
--- a/src/oscar/apps/catalogue/views.py
+++ b/src/oscar/apps/catalogue/views.py
@@ -12,7 +12,6 @@
 from oscar.core.loading import get_class, get_model
 
 Product = get_model('catalogue', 'product')
-ProductReview = get_model('reviews', 'ProductReview')
 Category = get_model('catalogue', 'category')
 ProductAlert = get_model('customer', 'ProductAlert')
 ProductAlertForm = get_class('customer.forms', 'ProductAlertForm')
@@ -65,7 +64,6 @@ def redirect_if_necessary(self, current_path, product):
 
     def get_context_data(self, **kwargs):
         ctx = super(ProductDetailView, self).get_context_data(**kwargs)
-        ctx['reviews'] = self.get_reviews()
         ctx['alert_form'] = self.get_alert_form()
         ctx['has_active_alert'] = self.get_alert_status()
         return ctx
@@ -84,9 +82,6 @@ def get_alert_form(self):
         return ProductAlertForm(
             user=self.request.user, product=self.object)
 
-    def get_reviews(self):
-        return self.object.reviews.filter(status=ProductReview.APPROVED)
-
     def send_signal(self, request, response, product):
         self.view_signal.send(
             sender=self, product=product, user=request.user, request=request,


Test patch:
Repository: django-oscar/django-oscar

Issue:
Drop jQuery UI and jquery-ui-datepicker
#1457 replaced the dashboard's datetimepicker with a much nicer Bootstrap-themed one. While reviewing that, I realised that the customer order list page in the frontend also uses the replaced `jquery-ui-datepicker`. If I'm not mistaken, that is also the only reason we keep the `jquery-mousewheel` and jQuery UI dependencies.

We should move the order list page to use the new datetime picker, and drop all unneeded dependencies.



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/customer/forms.py b/src/oscar/apps/customer/forms.py
--- a/src/oscar/apps/customer/forms.py
+++ b/src/oscar/apps/customer/forms.py
@@ -11,11 +11,12 @@
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import pgettext_lazy
 
+
+from oscar.apps.customer.utils import get_password_reset_url, normalise_email
 from oscar.core.loading import get_profile_class, get_class, get_model
 from oscar.core.compat import get_user_model, existing_user_fields
-from oscar.apps.customer.utils import get_password_reset_url, normalise_email
 from oscar.core.validators import password_validators
-
+from oscar.forms import widgets
 
 Dispatcher = get_class('customer.utils', 'Dispatcher')
 CommunicationEventType = get_model('customer', 'communicationeventtype')
@@ -186,9 +187,11 @@ def save(self, commit=True):
 
 class OrderSearchForm(forms.Form):
     date_from = forms.DateField(
-        required=False, label=pgettext_lazy("start date", "From"))
+        required=False, label=pgettext_lazy("start date", "From"),
+        widget=widgets.DatePickerInput())
     date_to = forms.DateField(
-        required=False, label=pgettext_lazy("end date", "To"))
+        required=False, label=pgettext_lazy("end date", "To"),
+        widget=widgets.DatePickerInput())
     order_number = forms.CharField(required=False, label=_("Order number"))
 
     def clean(self):


Test patch:
Repository: django-oscar/django-oscar

Issue:
Vouchers are rejected as 'expired' if added before their validity
If a voucher is added to the basket _before_ its `start_datetime`, the error message says `The voucher has expired`, which is not the case.



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/basket/views.py b/src/oscar/apps/basket/views.py
--- a/src/oscar/apps/basket/views.py
+++ b/src/oscar/apps/basket/views.py
@@ -362,13 +362,20 @@ def get(self, request, *args, **kwargs):
         return redirect('basket:summary')
 
     def apply_voucher_to_basket(self, voucher):
-        if not voucher.is_active():
+        if voucher.is_expired():
             messages.error(
                 self.request,
                 _("The '%(code)s' voucher has expired") % {
                     'code': voucher.code})
             return
 
+        if not voucher.is_active():
+            messages.error(
+                self.request,
+                _("The '%(code)s' voucher is not active") % {
+                    'code': voucher.code})
+            return
+
         is_available, message = voucher.is_available_to_user(self.request.user)
         if not is_available:
             messages.error(self.request, message)
diff --git a/src/oscar/apps/voucher/abstract_models.py b/src/oscar/apps/voucher/abstract_models.py
--- a/src/oscar/apps/voucher/abstract_models.py
+++ b/src/oscar/apps/voucher/abstract_models.py
@@ -80,6 +80,13 @@ def is_active(self, test_datetime=None):
         test_datetime = test_datetime or timezone.now()
         return self.start_datetime <= test_datetime <= self.end_datetime
 
+    def is_expired(self):
+        """
+        Test whether this voucher has passed its expiration date
+        """
+        now = timezone.now()
+        return self.end_datetime < now
+
     def is_available_to_user(self, user=None):
         """
         Test whether this voucher is available to the passed user.


Test patch:
Repository: django-oscar/django-oscar

Issue:
ShippingAddressView.get_initial <Country: XXX> is not JSON serializable
If you are to return back to the shipping address after you've reached further into the checkout process and you selected a country from the list, doing a GET request to the address /checkout/shipping-address/ would result in the following error:

`TypeError at /shop/checkout/shipping-address/ <Country: XXXXX> is not JSON serializable`

The issue is in here https://github.com/django-oscar/django-oscar/blob/master/src/oscar/apps/checkout/views.py#L140

Modifying the initial dictionary in this function modifies the same reference that is going to be stored in the session.



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/checkout/views.py b/src/oscar/apps/checkout/views.py
--- a/src/oscar/apps/checkout/views.py
+++ b/src/oscar/apps/checkout/views.py
@@ -140,6 +140,7 @@ class ShippingAddressView(CheckoutSessionMixin, generic.FormView):
     def get_initial(self):
         initial = self.checkout_session.new_shipping_address_fields()
         if initial:
+            initial = initial.copy()
             # Convert the primary key stored in the session into a Country
             # instance
             try:


Test patch:
Repository: django-oscar/django-oscar

Issue:
Exceptions when price_excl_tax is unset
The Oscar product admin allows the `price_excl_tax` field to be left unset, however an exception occurs when adding a product to the basket if this field is empty.

Similarly, if I have a product in my cart, and then clear the `price_excl_tax` field, an exception occurs when I try to view my basket.

Bottom line: `price_excl_tax` needs to be mandatory.



Discussion:
Stock record could import price from external service or etc and that could be the case that price is updated yet - for this case it might be an option to prohibit product adding to busket if `price_excl_tax`.
What do you think @john-parton @mvantellingen ?


Resolving patch:
diff --git a/src/oscar/apps/partner/strategy.py b/src/oscar/apps/partner/strategy.py
--- a/src/oscar/apps/partner/strategy.py
+++ b/src/oscar/apps/partner/strategy.py
@@ -210,7 +210,7 @@ class StockRequired(object):
     """
 
     def availability_policy(self, product, stockrecord):
-        if not stockrecord:
+        if not stockrecord or stockrecord.price_excl_tax is None:
             return Unavailable()
         if not product.get_product_class().track_stock:
             return Available()


Test patch:
diff --git a/tests/integration/basket/test_forms.py b/tests/integration/basket/test_forms.py
--- a/tests/integration/basket/test_forms.py
+++ b/tests/integration/basket/test_forms.py
@@ -175,3 +175,14 @@ def test_mixed_currency_baskets_are_not_permitted(self):
         form = forms.AddToBasketForm(
             basket=basket, product=product, data=data)
         self.assertFalse(form.is_valid())
+
+    def test_for_empty_price_excl_tax(self):
+        basket = factories.BasketFactory()
+        product_class = factories.ProductClassFactory(track_stock=False)
+        product = factories.ProductFactory(product_class=product_class, stockrecords=[])
+        factories.StockRecordFactory.build(price_excl_tax=None, product=product)
+
+        data = {'quantity': 1}
+        form = forms.AddToBasketForm(basket=basket, product=product, data=data)
+        self.assertFalse(form.is_valid())
+        self.assertEqual(form.errors['__all__'][0], 'unavailable')
diff --git a/tests/integration/partner/test_strategy.py b/tests/integration/partner/test_strategy.py
--- a/tests/integration/partner/test_strategy.py
+++ b/tests/integration/partner/test_strategy.py
@@ -47,6 +47,13 @@ def test_free_product_is_available_to_buy(self):
         self.assertTrue(info.availability.is_available_to_buy)
         self.assertTrue(info.price.exists)
 
+    def test_product_with_empty_price(self):
+        product_class = factories.ProductClassFactory(track_stock=False)
+        product = factories.ProductFactory(product_class=product_class, stockrecords=[])
+        factories.StockRecordFactory(price_excl_tax=None, product=product)
+        info = self.strategy.fetch_for_product(product)
+        self.assertFalse(info.availability.is_available_to_buy)
+
 
 class TestDefaultStrategyForParentProductWhoseVariantsHaveNoStockRecords(TestCase):
Repository: django-oscar/django-oscar

Issue:
Multilingual not working on 127.0.0.1:8000/xx-xx/catalogue/category/some-item
I have two languages.
In the settings.py:
`LANGUAGES = (
    ('en', gettext_noop('English')),
    ('zh-cn', gettext_noop('Simplified Chinese')),
)
`
When i go to http://127.0.0.1:8000/zh-cn/catalogue/category/some-item,
the page will redirect to http://127.0.0.1:8000/en/catalogue/category/some-item
And the status code of the request is 301 MOVED PERMANENTLY (from cache)

Everything seems working normally except the category page.
All these pages can display Chinese language.
http://127.0.0.1:8000/zh-cn/offers/
http://127.0.0.1:8000/zh-cn/catalogue/
http://127.0.0.1:8000/zh-cn/catalogue/some-item/
http://127.0.0.1:8000/zh-cn/dashboard/



Discussion:
Yup, can reproduce it here. Thanks for the report

Thanks.
I think i solved this problem by deleting `cache.set(cache_key, url)` in catalogue/abstract_model.py
class AbstractCategory:

```
def get_absolute_url(self):
        """
        Our URL scheme means we have to look up the category's ancestors. As
        that is a bit more expensive, we cache the generated URL. That is
        safe even for a stale cache, as the default implementation of
        ProductCategoryView does the lookup via primary key anyway. But if
        you change that logic, you'll have to reconsider the caching
        approach.
        """
        cache_key = 'CATEGORY_URL_%s' % self.pk
        url = cache.get(cache_key)
        if not url:
            url = reverse(
                'catalogue:category',
                kwargs={'category_slug': self.full_slug, 'pk': self.pk})
            #cache.set(cache_key, url)
        return url
```


Resolving patch:
diff --git a/src/oscar/apps/catalogue/abstract_models.py b/src/oscar/apps/catalogue/abstract_models.py
--- a/src/oscar/apps/catalogue/abstract_models.py
+++ b/src/oscar/apps/catalogue/abstract_models.py
@@ -19,7 +19,8 @@
 from django.utils.html import strip_tags
 from django.utils.safestring import mark_safe
 from django.utils.translation import ugettext_lazy as _
-from django.utils.translation import pgettext_lazy
+from django.utils.translation import get_language, pgettext_lazy
+
 from treebeard.mp_tree import MP_Node
 
 from oscar.core.decorators import deprecated
@@ -194,7 +195,8 @@ def get_absolute_url(self):
         you change that logic, you'll have to reconsider the caching
         approach.
         """
-        cache_key = 'CATEGORY_URL_%s' % self.pk
+        current_locale = get_language()
+        cache_key = 'CATEGORY_URL_%s_%s' % (current_locale, self.pk)
         url = cache.get(cache_key)
         if not url:
             url = reverse(


Test patch:
Repository: django-oscar/django-oscar

Issue:
In shipping address checkout view, "addressbook" should be two words
The shipping_address template has "An address from your addressbook?" as the header above the user's address book. "addressbook" should be changed to "address book".
<img width="985" alt="shipping_address___checkout___flyshop_-_welcome_to_surround_video_" src="https://cloud.githubusercontent.com/assets/15231879/12589909/3ab9d41c-c42e-11e5-9abe-bb627a996f75.png">



Discussion:

Resolving patch:
diff --git a/src/oscar/apps/checkout/utils.py b/src/oscar/apps/checkout/utils.py
--- a/src/oscar/apps/checkout/utils.py
+++ b/src/oscar/apps/checkout/utils.py
@@ -74,7 +74,7 @@ def get_guest_email(self):
     # Options:
     # 1. No shipping required (eg digital products)
     # 2. Ship to new address (entered in a form)
-    # 3. Ship to an addressbook address (address chosen from list)
+    # 3. Ship to an address book address (address chosen from list)
 
     def reset_shipping_data(self):
         self._flush_namespace('shipping')
diff --git a/src/oscar/apps/checkout/views.py b/src/oscar/apps/checkout/views.py
--- a/src/oscar/apps/checkout/views.py
+++ b/src/oscar/apps/checkout/views.py
@@ -217,7 +217,7 @@ def get_success_url(self):
 
 class UserAddressDeleteView(CheckoutSessionMixin, generic.DeleteView):
     """
-    Delete an address from a user's addressbook.
+    Delete an address from a user's address book.
     """
     template_name = 'checkout/user_address_delete.html'
     success_url = reverse_lazy('checkout:shipping-address')


Test patch: