Use delegated events for 'disable-on-click' button handler
There's a button handler that disables the button to help against duplicate
submissions. But in the previous form, the event handler got assigned
when the page was ready and would only work for buttons that were
present at that time.
Now, it uses jQuery's delegated events to ensure that even if a form
gets reloaded via AJAX, it works as expected.
Closes #1039.
Streamline Benefit and Condition name and description handling
This commit was triggered by a recursion problem mentioned here:
8199da2100 (commitcomment-7387486)
It now unifies handling for name and description across both conditions
and benefits:
* Declaring a name property is required for any proxy class. A few
classes had a description declared, but no name. But given that the
description is the more verbose version, and is allowed to include
HTML, it makes sense to still require a name. The declared
descriptions in the models that only had one property are better
suited for @name anyway.
* It drops the max_unaffected_items logic for Benefits. That was only
applied if calling via the non-proxy class, and feels more like it
should be a description anyway.
* __str__ always returns self.name. Anything more complex with that
means we might run into problems with the python_2_unicode_compatible
decorator.
I also added tests for the changes, and verified the tests fail without
my changes.
The previous implementation was too tightly coupled to the actual search
process, and rather verbose. It also had issues for translators in the
case of searching for both UPC and title.
This commit simplifies the description handling and provides a hook to
plug in more advanced descriptions. But I think a visual indication of
"those results are filtered" is a lot more useful than any description,
no matter how detailed.
Furthermore, this commit swaps out the "Create product" and "Search
products" sections to visually tie the search and search results closer
together.
Remove recently edited section on dashboard product list
The same thing can be achived by using the sorting function of the
regular product listings. In fact, I think sorting by recently edited
makes so much sense, that after an ad-hoc consultation in my coworking
office, I've decided to make it the new default.
My argument would be that one either searches for a specific product
that hasn't been touched in a while, or will want to amend a change one
recently did.
Fixes #1454.
Fixes #1460.
bdeb882 limited the dashboard's product list to parent and stand-alone
products, and did away with separate columns for parents and children.
After merging master, the dashboard product table was replaced by
a table generated by tables2. This commit redoes the part of bdeb882 to
replace the separate columns by a "variants" column that's more
informative.
While at it, I also added translatable names for the other columns.
If a child product did not define a title, the success message for the
updating the child product and the message for it's parent were
identical, as get_title() would just use the parent's title. That can be
a bit confusing, and has been addressed in this commit.
The block "error_message" was erroneously referred to as
"explanation". As a result, the `login_forbidden.html` template
displayed the generic 403 error message.
This change:
- Alters the logical flow so the deletion of products takes place in the
`delete` method rather than `get_success_url`. As per SRP, I don't
think the `get_success_url` method should write to the DB.
- Fixes a logical error around child product deletions. We need to test
if the product being deleted is a last child *before* deleting it as
this changes the result.
Adjust URL for creating variant product in dashboard
Why?
- s/_/-/
- I try and follow a RESTy approach to URLs where the parent identifier
is to the left of any action or subordinates resources. (I'm sure
there are other examples in Oscar where we don't follow this).
This also selects the inputs that should have the date picker in a more
reliable fasion. The custom widget adds a data-oscarWidget attribute that
is used to select the elements to apply the widget to.
Replace timepicker with the time part of the datetime picker
One shortcoming is that the widget now shows the time in american format in
the header. (The format used in the input field is not affected and works
as we need it, supporting different formats.)
with https://github.com/smalot/bootstrap-datetimepicker
revision a68df42162
In all our tests the time sliders under the calendar were always ignored.
Also this datetimepicker looks bootstrap and thus fits visually much more
into the rest of the dashboard.
with http://jdewit.github.io/bootstrap-timepicker/
revision f6cef44b5a
The timepicker with sliders for hour and minute were just totally unusable
in our tests with customers.
This timepicker has some shortcomings though:
- it doesn't support time formats. 24-hour hh:mm ought to be enough for
everyone!
- the maintainer stopped maintaining it
I included both the minified and non-minified files for convenience.
This fixes two issues:
1) The code didn't take into account that self.format will be ignored by
Django if USE_L10N=True, unless a format was specified when constructing
the Widget. Remedied by moving the code to render because the current
language is determined at request time, not at object construction time,
and looking up the correct format there.
2) The code couldn't handle date formats that include dots, like
31.12.2014.
Fixes #1440.
We have differing logic on how to check the referrer for safety, which
should be bundled in one place. Plus it's annoying to have to remember
the typo in REFERER.
@aaugustin helpfully pointed us towards is_safe_url(), so that's the
best thing to use anyway.
Fixes #1221.
Update handling of child product for product ranges
This commit addresses issue #1253.
Currently, the offers app doesn't really consider child products;
behaviour is undefined. This commit addresses the fact: for now, we
assume that child and parent products are tightly coupled, and forbid
child products in a range. You can only add the parent product (and
with it all children).
This requirement might be lifted in the future, but that will mean
additional complexity and we will see if it's necessary.
Closes #1253.
create_range method doesn't ignore existing ranges again
The functionality to have it fetch an existing range instead of loudly
complaining when a range already exists has been added as part of #1053.
But @codeinthehole and I agree that a method called create_range
shouldn't silently ignore an existing range, and can't think of a use
case anymore.
* Removed unused _save method. It's not called anywhere.
* Simplified comment and logic for display_order
* Reordered imports
* Used items() instead of six.iteritems() because create_range does not
get complex kwargs
* Removed a duplicate test
* Test for the correct exception
Ensure offers consider parent categories for child products
A variant (child) product should not have categories. We need a new method
to get product categories, either for a product or for a parent product
if the parent is set.
This wrapper method is used when testing if product belongs to a range by
category.
Fixes #1218.
Explain why we can't move Abstract[Shipping|Billing]Address
Technically, they belong into the order app, and AbstractPartnerAddress
belongs into the partner app. I think they're in there because
AbstractUserAddress depends on AbstractShippingAddress. And maybe also
because trying to move them creates a rabbit hole of circular import
issues, which is why I gave up.
Similarily to benefits, conditions either need a custom proxy class or
have a type, range and value defined. This wasn't clear from the
documentation and the fact that the proxy() method happily returned
self.
This was raised in #1401.
We only needed it because Django 1.4 shipped with a pretty old version
of six. Support for that has been removed, and Django 1.5 ships with six
1.6.1, which is more current than we required.
This nicely avoids an issue with django-extra-views pinning a six
version which caused the sandbox build to fail:
https://travis-ci.org/tangentlabs/django-oscar/jobs/32223978#L971
Django's admin interface is not supported; the Oscar dashboard should be
used. It is still provided with the sandbox because it is convenient for
developers, but any code that goes beyond basic ModelAdmin syntax is a
maintenance burden.
Closes #1215.
Fix duplicate communication events created for orders
As reported in #1437, when a communication event type for code
ORDER_PLACED is in the database, both the OrderPlacementMixin and the
dispatcher create a CommunicationEvent. That's no good.
This fix diverges from the suggestion in #1437, because conceptually,
communication events are created for audit purposes and the creation
belongs more into the dispatcher than the view mixin.
Fixes #147.
Use plain textarea widget for email template editing
The dashboard communications app allows editing database-backed email
templates. The HTML body part had TinyMCE enabled, but I could not find
evidence that TinyMCE supports Django's template syntax. It definitely
caused an issue as reported in #1356.
Also use "fields" instead of "exclude" because that's good practice.
Closes #1356.
Update documentation to include all shipping methods, fix typo on configure shipping page
Add docstrings to the following classes in 'oscar.apps.shipping.methods':
* Free
* FixedPrice
* TaxExclusiveOfferDiscount
* TaxInclusiveOfferDiscount
Fix typo in 'docs/source/howto/how_to_configure_shipping.rst':
* Change 'shipping.addr' to 'shipping_addr'
It only prevents adding a product to a range; offers can be applied
nonetheless (despite the docs saying otherwise). The same functionality
can be achieved by overriding get_is_discountable, so it can be safely
removed.
Issue #855 is caused when deleting the middle of three product images in
the dashboard. A quick workaround is to renumber the image order values
when deleting an image. Eventually, this should be readressed as part of
issue #856.
This commit is the squashed version of #1429.
Overide delete() on AbstractProductImage.
Ensures the display order is always in consecutive order.
Cleans up after TestProductImages is run.
Fixes #855.
Closes #1429.
Django stores the class name of the auth backend used to authenticate a
user. The simple assignment before meant that the new name was stored in
the session data, but it might not be in the available auth backends.
Hence logging in would fail as reported in #1432.
Inheriting from the new backend fixes the issue; logging in with the
deprecated name now works.
Fixes #1432.
From #1435:
CommunicationEventType.category is used also to "detect" order-related
emails, in which case when previewing that email Oscar will put a
user-supplied order in the context for the email template.
This doesn't always work because the string that's saved in category
is localized.
Using choices remedies the problem. I don't think this feature is
commonly used, so no attempt at backwards-compatibility for
non-English setups is made.
South doesn't create a migration for this change.
Fixes #1435.