Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: django-oscar/django-oscar
...
head fork: django-oscar/django-oscar
  • 4 commits
  • 14 files changed
  • 0 commit comments
  • 1 contributor
Commits on Aug 24, 2012
@codeinthehole codeinthehole Improve django admin for basket app 7ddb7f3
@codeinthehole codeinthehole Update order creator to create payment event quantity objects
This fixes an issue with payment events not having any lines set.  Also
includes some admin improvements.
f7c20f9
@codeinthehole codeinthehole Amend demo site to have a custom checkout app
It only creates a payment event at the moment but it will do more.  Oh
yes.
446585d
@codeinthehole codeinthehole Altered default partner wrapper to not specify a dispatch date
Turns out this is a bit confusing.  Better for it to do nothing by
default and this behaviour can be enabled when it is needed.
3507b07
View
11 oscar/apps/basket/abstract_models.py
@@ -112,7 +112,8 @@ def add_product(self, product, quantity=1, options=None):
# product (eg T-shirts with different personalisations)
line_ref = self._create_line_reference(product, options)
- # Determine price to store (if one exists)
+ # Determine price to store (if one exists). It is only stored for audit
+ # and sometimes caching.
price = None
if product.has_stockrecord:
stockrecord = product.stockrecord
@@ -366,6 +367,10 @@ def time_since_creation(self, test_datetime=None):
test_datetime = datetime.datetime.now()
return test_datetime - self.date_created
+ @property
+ def contains_a_voucher(self):
+ return self.vouchers.all().count() > 0
+
def contains_voucher(self, code):
"""
Test whether the basket contains a voucher with a given code
@@ -392,6 +397,10 @@ class AbstractLine(models.Model):
product = models.ForeignKey('catalogue.Product', related_name='basket_lines')
quantity = models.PositiveIntegerField(_('Quantity'), default=1)
+
+ # We store the unit price incl tax of the product when it is first added to
+ # the basket. This allows us to tell if a product has changed price since a
+ # person first added it to their basket.
price_incl_tax = models.DecimalField(_('Price incl. Tax'), decimal_places=2, max_digits=12,
null=True)
View
12 oscar/apps/basket/admin.py
@@ -1,11 +1,21 @@
from django.contrib import admin
from django.db.models import get_model
+Line = get_model('basket', 'line')
+
+
+class LineInline(admin.TabularInline):
+ model = Line
+
class BasketAdmin(admin.ModelAdmin):
+ list_display = ('id', 'owner', 'status', 'num_lines', 'total_incl_tax',
+ 'contains_a_voucher', 'date_created', 'date_submitted',
+ 'time_before_submit')
read_only_fields = ('date_merged', 'date_submitted')
+ inlines = [LineInline]
admin.site.register(get_model('basket', 'basket'), BasketAdmin)
-admin.site.register(get_model('basket', 'line'))
+admin.site.register(Line)
admin.site.register(get_model('basket', 'LineAttribute'))
View
9 oscar/apps/checkout/mixins.py
@@ -15,6 +15,7 @@
CommunicationEvent = get_model('order', 'CommunicationEvent')
PaymentEventType = get_model('order', 'PaymentEventType')
PaymentEvent = get_model('order', 'PaymentEvent')
+PaymentEventQuantity = get_model('order', 'PaymentEventQuantity')
UserAddress = get_model('address', 'UserAddress')
Basket = get_model('basket', 'Basket')
CommunicationEventType = get_model('customer', 'CommunicationEventType')
@@ -56,7 +57,7 @@ def add_payment_source(self, source):
self._payment_sources.append(source)
def add_payment_event(self, event_type_name, amount):
- event_type, n = PaymentEventType.objects.get_or_create(name=event_type_name)
+ event_type, __ = PaymentEventType.objects.get_or_create(name=event_type_name)
if self._payment_events is None:
self._payment_events = []
event = PaymentEvent(event_type=event_type, amount=amount)
@@ -196,6 +197,12 @@ def save_payment_events(self, order):
for event in self._payment_events:
event.order = order
event.save()
+ # We assume all lines are involved in the initial payment event
+ for line in order.lines.all():
+ PaymentEventQuantity.objects.create(
+ event=event,
+ line=line,
+ quantity=line.quantity)
def save_payment_sources(self, order):
"""
View
3  oscar/apps/order/abstract_models.py
@@ -528,6 +528,9 @@ class Meta:
def __unicode__(self):
return _("Payment event for order %s") % self.order
+ def num_affected_lines(self):
+ return self.lines.all().count()
+
class PaymentEventQuantity(models.Model):
"""
View
35 oscar/apps/order/admin.py
@@ -12,14 +12,21 @@
ShippingEventType = get_model('order', 'ShippingEventType')
PaymentEvent = get_model('order', 'PaymentEvent')
PaymentEventType = get_model('order', 'PaymentEventType')
+PaymentEventQuantity = get_model('order', 'PaymentEventQuantity')
LineAttribute = get_model('order', 'LineAttribute')
OrderDiscount = get_model('order', 'OrderDiscount')
+class LineInline(admin.TabularInline):
+ model = Line
+ extra = 0
+
+
class OrderAdmin(admin.ModelAdmin):
raw_id_fields = ['user','billing_address','shipping_address', ]
list_display = ('number', 'total_incl_tax', 'site', 'user', 'billing_address', 'date_placed')
readonly_fields = ('number', 'total_incl_tax', 'total_excl_tax', 'shipping_incl_tax', 'shipping_excl_tax')
+ inlines = [LineInline]
class LineAdmin(admin.ModelAdmin):
@@ -33,25 +40,35 @@ class LinePriceAdmin(admin.ModelAdmin):
class ShippingEventTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'is_required', 'sequence_number')
exclude = ('code',)
-
-
+
+
+class PaymentEventQuantityInline(admin.TabularInline):
+ model = PaymentEventQuantity
+ extra = 0
+
+
+class PaymentEventAdmin(admin.ModelAdmin):
+ list_display = 'order', 'event_type', 'amount', 'num_affected_lines', 'date'
+ inlines = [PaymentEventQuantityInline]
+
+
class PaymentEventTypeAdmin(admin.ModelAdmin):
exclude = ('code',)
-
-
+
+
class OrderNoteAdmin(admin.ModelAdmin):
exclude = ('user',)
-
+
def save_model(self, request, obj, form, change):
if not change:
obj.user = request.user
obj.save()
-
-
+
+
class OrderDiscountAdmin(admin.ModelAdmin):
readonly_fields = ('order' ,'offer_id', 'voucher_id', 'voucher_code', 'amount')
list_display = ('order', 'offer', 'voucher', 'voucher_code', 'amount')
-
+
admin.site.register(Order, OrderAdmin)
admin.site.register(OrderNote, OrderNoteAdmin)
@@ -60,7 +77,7 @@ class OrderDiscountAdmin(admin.ModelAdmin):
admin.site.register(LinePrice, LinePriceAdmin)
admin.site.register(ShippingEvent)
admin.site.register(ShippingEventType, ShippingEventTypeAdmin)
-admin.site.register(PaymentEvent)
+admin.site.register(PaymentEvent, PaymentEventAdmin)
admin.site.register(PaymentEventType, PaymentEventTypeAdmin)
admin.site.register(LineAttribute)
admin.site.register(OrderDiscount, OrderDiscountAdmin)
View
17 oscar/apps/partner/wrappers.py
@@ -1,4 +1,3 @@
-import datetime
from decimal import Decimal as D
from django.utils.translation import ugettext_lazy as _
@@ -8,7 +7,7 @@ class DefaultWrapper(object):
"""
Default stockrecord wrapper
"""
-
+
def is_available_to_buy(self, stockrecord):
"""
Test whether a product is available to buy.
@@ -56,7 +55,7 @@ def availability_code(self, stockrecord):
if self.is_available_to_buy(stockrecord):
return 'available'
return 'outofstock'
-
+
def availability(self, stockrecord):
"""
Return an availability message for the passed stockrecord.
@@ -68,16 +67,12 @@ def availability(self, stockrecord):
if self.is_available_to_buy(stockrecord):
return _('Available')
return _("Not available")
-
+
def dispatch_date(self, stockrecord):
- if stockrecord.net_stock_level:
- # Assume next day for in-stock items
- return datetime.date.today() + datetime.timedelta(days=1)
- # Assume one week for out-of-stock items
- return datetime.date.today() + datetime.timedelta(days=7)
-
+ return None
+
def lead_time(self, stockrecord):
return 1
-
+
def calculate_tax(self, stockrecord):
return D('0.00')
View
1  oscar/apps/payment/admin.py
@@ -1,5 +1,6 @@
from django.contrib import admin
from django.db.models import get_model
+
Source = get_model('payment', 'Source')
Transaction = get_model('payment', 'Transaction')
SourceType = get_model('payment', 'SourceType')
View
11 sites/demo/apps/app.py
@@ -0,0 +1,11 @@
+from oscar.app import Shop
+
+from apps.checkout.app import application as checkout_app
+
+
+class Application(Shop):
+ # Use local checkout app so we can mess with the view classes
+ checkout_app = checkout_app
+
+
+application = Application()
View
0  sites/demo/apps/checkout/__init__.py
No changes.
View
11 sites/demo/apps/checkout/app.py
@@ -0,0 +1,11 @@
+from oscar.apps.checkout import app
+
+from apps.checkout import views
+
+
+class CheckoutApplication(app.CheckoutApplication):
+ # Replace the payment details view with our own
+ payment_details_view = views.PaymentDetailsView
+
+
+application = CheckoutApplication()
View
8 sites/demo/apps/checkout/views.py
@@ -0,0 +1,8 @@
+from oscar.apps.checkout import views
+
+
+class PaymentDetailsView(views.PaymentDetailsView):
+
+ def handle_payment(self, order_number, total_incl_tax, **kwargs):
+ # Create a payment event
+ self.add_payment_event('Authorize', total_incl_tax)
View
8 sites/demo/urls.py
@@ -1,18 +1,20 @@
-from django.conf.urls.defaults import *
+from django.conf.urls.defaults import patterns, url, include
from django.conf import settings
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf.urls.static import static
from django.views.generic import TemplateView
-from oscar.app import shop
+from apps.app import application
+
+# These need to be imported into this namespace
from oscar.views import handler500, handler404
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
- (r'', include(shop.urls)),
+ (r'', include(application.urls)),
)
if settings.DEBUG:
View
6 tests/unit/partner/model_tests.py
@@ -81,13 +81,11 @@ def test_default_wrapper_for_out_of_stock(self):
def test_dispatch_date_for_in_stock(self):
product = create_product(price=D('10.00'), partner="Acme", num_in_stock=1)
- tomorrow = datetime.date.today() + datetime.timedelta(days=1)
- self.assertEquals(tomorrow, product.stockrecord.dispatch_date)
+ self.assertIsNone(product.stockrecord.dispatch_date)
def test_dispatch_date_for_out_of_stock(self):
product = create_product(price=D('10.00'), partner="Acme", num_in_stock=0)
- date = datetime.date.today() + datetime.timedelta(days=7)
- self.assertEquals(date, product.stockrecord.dispatch_date)
+ self.assertIsNone(product.stockrecord.dispatch_date)
class CustomWrapperTests(TestCase):
View
10 tests/unit/partner/wrapper_tests.py
@@ -75,13 +75,3 @@ def test_backorder_purchase_is_permitted(self):
m.return_value = None
result, reason = self.wrapper.is_purchase_permitted(record)
self.assertTrue(result)
-
- def test_dispatch_date_for_in_stock(self):
- tomorrow = datetime.date.today() + datetime.timedelta(days=1)
- record = StockRecord(product=self.product, num_in_stock=4)
- self.assertEquals(tomorrow, self.wrapper.dispatch_date(record))
-
- def test_dispatch_date_for_out_of_stock(self):
- date = datetime.date.today() + datetime.timedelta(days=7)
- record = StockRecord(product=self.product)
- self.assertEquals(date, self.wrapper.dispatch_date(record))

No commit comments for this range

Something went wrong with that request. Please try again.