Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but 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
David Winterbottom codeinthehole Improve django admin for basket app 7ddb7f3
David Winterbottom 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
David Winterbottom 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
David Winterbottom 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
11 oscar/apps/basket/abstract_models.py
View
@@ -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)
12 oscar/apps/basket/admin.py
View
@@ -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'))
9 oscar/apps/checkout/mixins.py
View
@@ -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):
"""
3  oscar/apps/order/abstract_models.py
View
@@ -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):
"""
35 oscar/apps/order/admin.py
View
@@ -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)
17 oscar/apps/partner/wrappers.py
View
@@ -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')
1  oscar/apps/payment/admin.py
View
@@ -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')
11 sites/demo/apps/app.py
View
@@ -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()
0  sites/demo/apps/checkout/__init__.py
View
No changes.
11 sites/demo/apps/checkout/app.py
View
@@ -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()
8 sites/demo/apps/checkout/views.py
View
@@ -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)
8 sites/demo/urls.py
View
@@ -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:
6 tests/unit/partner/model_tests.py
View
@@ -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):
10 tests/unit/partner/wrapper_tests.py
View
@@ -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.