[IMP] [FIX] [ADD] website_sale, website_sale_delivery: delivery + ecommerce code cleaning

- added a website_order_line on sale.order model, that are the lines to display
and use in the front-end. This allows to display only products (and not delivery
costs), and to have a correct badge for the number od products.
- cleaned ecommerce website code and method name. Still some cleaning to do
I think.
- fixed some issues in partner and shipping info management, now using CheckoutInfo
more cleanly
- fixed the process of choosing the carrier

bzr revid: tde@openerp.com-20131218132150-f4br0099p2caf43i
This commit is contained in:
Thibault Delavallée 2013-12-18 14:21:50 +01:00
parent e883b15c48
commit 7a564f261e
12 changed files with 233 additions and 167 deletions

View File

@ -1 +1,2 @@
import event
import website

View File

@ -139,11 +139,3 @@ class sale_order_line(osv.osv):
res.update({'price_unit': order_line.event_ticket_id.price})
return res
class Website(orm.Model):
_inherit = 'website'
def get_website_sale_domain(self):
# remove product event from the website content grid and list view (not removed in detail view)
return super(Website, self).get_website_sale_domain() + [('event_ok', '=', False)]

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from openerp.osv import orm
class Website(orm.Model):
_inherit = 'website'
def ecommerce_get_product_domain(self):
# remove product event from the website content grid and list view (not removed in detail view)
return ['&'] + super(Website, self).ecommerce_get_product_domain() + [('event_ok', '=', False)]

View File

@ -11,13 +11,15 @@ from openerp.addons.website.models import website
PPG = 20 # Products Per Page
PPR = 4 # Products Per Row
class CheckoutInfo(object):
mandatory_billing_fields = ["name", "phone", "email", "street", "city", "country_id", "zip"]
optional_billing_fields = ["company", "state_id"]
string_billing_fields = ["name", "phone", "email", "street", "city", "zip"]
mandatory_shipping_fields = ["shipping_name", "shipping_phone", "shipping_street", "shipping_city", "shipping_country_id", "shipping_zip"]
string_shipping_fields = ["shipping_name", "shipping_phone", "shipping_street", "shipping_city", "shipping_zip"]
optional_shipping_field = ["shipping_state_id"]
string_shipping_fields = ["shipping_name", "shipping_phone", "shipping_street", "shipping_city", "shipping_zip"]
def mandatory_fields(self):
return self.mandatory_billing_fields + self.mandatory_shipping_fields
@ -31,11 +33,16 @@ class CheckoutInfo(object):
def empty(self):
return dict.fromkeys(self.all_fields(), '')
def from_partner(self, partner):
result = dict((field_name, getattr(partner, field_name)) for field_name in self.string_billing_fields if getattr(partner, field_name))
result['state_id'] = partner.state_id and partner.state_id.id or ''
result['country_id'] = partner.country_id and partner.country_id.id or ''
result['company'] = partner.parent_id and partner.parent_id.name or ''
def from_partner(self, partner, address_type='billing'):
assert address_type in ('billing', 'shipping')
if address_type == 'billing':
prefix = ''
else:
prefix = 'shipping_'
result = dict((prefix + field_name, getattr(partner, field_name)) for field_name in self.string_billing_fields if getattr(partner, field_name))
result[prefix + 'state_id'] = partner.state_id and partner.state_id.id or ''
result[prefix + 'country_id'] = partner.country_id and partner.country_id.id or ''
result[prefix + 'company'] = partner.parent_id and partner.parent_id.name or ''
return result
def from_post(self, post):
@ -101,17 +108,23 @@ class table_compute(object):
rows[col] = map(lambda x: x[1], cols)
return filter(bool, rows)
class Ecommerce(http.Controller):
_order = 'website_published desc, website_sequence desc'
def get_attribute_ids(self):
attributes_obj = request.registry.get('product.attribute')
attributes_obj = request.registry['product.attribute']
attributes_ids = attributes_obj.search(request.cr, request.uid, [], context=request.context)
return attributes_obj.browse(request.cr, request.uid, attributes_ids, context=request.context)
def get_pricelist(self):
return request.registry.get('website').get_pricelist_id(request.cr, request.uid, None, context=request.context)
""" Shortcut to get the pricelist from the website model """
return request.registry['website'].ecommerce_get_pricelist_id(request.cr, request.uid, None, context=request.context)
def get_order(self):
""" Shortcut to get the current ecommerce quotation from the website model """
return request.registry['website'].ecommerce_get_current_order(request.cr, request.uid, context=request.context)
def get_products(self, product_ids):
product_obj = request.registry.get('product.template')
@ -179,7 +192,7 @@ class Ecommerce(http.Controller):
@website.route(['/shop/pricelist'], type='http', auth="public", multilang=True)
def shop_promo(self, code, **post):
assert code, 'No pricelist code provided'
request.registry.get('website').change_pricelist_id(request.cr, request.uid, code, context=request.context)
request.registry['website']._ecommerce_change_pricelist(request.cr, request.uid, code=code, context=request.context)
return request.redirect("/shop")
@website.route([
@ -191,7 +204,7 @@ class Ecommerce(http.Controller):
def shop(self, category=0, page=0, filters='', search='', **post):
cr, uid, context = request.cr, request.uid, request.context
product_obj = request.registry.get('product.template')
domain = request.registry.get('website').get_website_sale_domain()
domain = request.registry.get('website').ecommerce_get_product_domain()
if search:
domain += ['|',
('name', 'ilike', "%%%s%%" % search),
@ -286,9 +299,9 @@ class Ecommerce(http.Controller):
order_line_obj = request.registry.get('sale.order.line')
order_obj = request.registry.get('sale.order')
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if not order:
order = request.registry['website']._get_order(request.cr, request.uid, context=request.context)
order = request.registry['website'].ecommerce_get_new_order(request.cr, request.uid, context=request.context)
request.context = dict(request.context, pricelist=self.get_pricelist())
@ -300,8 +313,9 @@ class Ecommerce(http.Controller):
else:
order_line_id = None
else:
order_line_ids = order_line_obj.search(request.cr, SUPERUSER_ID,
[('order_id', '=', order.id),('product_id', '=', product_id)], context=request.context)
order_line_ids = order_line_obj.search(
request.cr, SUPERUSER_ID,
[('order_id', '=', order.id), ('product_id', '=', product_id)], context=request.context)
if order_line_ids:
order_line_id = order_line_ids[0]
@ -349,7 +363,7 @@ class Ecommerce(http.Controller):
prod_obj = request.registry.get('product.product')
# must have a draft sale order with lines at this point, otherwise reset
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if order and order.state != 'draft':
request.registry['website'].sale_reset_order(cr, uid, context=context)
return request.redirect('/shop/')
@ -396,7 +410,7 @@ class Ecommerce(http.Controller):
@website.route(['/shop/add_cart_json/'], type='json', auth="public")
def add_cart_json(self, product_id=None, order_line_id=None, remove=None):
quantity = self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, number=(remove and -1 or 1))
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
return [quantity,
order.get_total_quantity(),
order.amount_total,
@ -411,15 +425,15 @@ class Ecommerce(http.Controller):
cr, uid, context, registry = request.cr, request.uid, request.context, request.registry
# must have a draft sale order with lines at this point, otherwise reset
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if not order or order.state != 'draft' or not order.order_line:
request.registry['website'].sale_reset_order(cr, uid, context=context)
request.registry['website'].ecommerce_reset(cr, uid, context=context)
return request.redirect('/shop/')
# if transaction pending / done: redirect to confirmation
tx = context.get('website_sale_transaction')
if tx and tx.state != 'draft':
return request.redirect('/shop/payment/confirmation/%s' % order.id)
self.get_pricelist()
orm_partner = registry.get('res.partner')
@ -452,17 +466,11 @@ class Ecommerce(http.Controller):
if partner:
partner_info = info.from_partner(partner)
checkout.update(partner_info)
shipping_ids = orm_partner.search(cr, SUPERUSER_ID, [("parent_id", "=", partner.id), ('type', "=", 'delivery')], context=context)
shipping_ids = orm_partner.search(cr, SUPERUSER_ID, [("parent_id", "=", partner.id), ('type', "=", 'delivery')], limit=1, context=context)
if shipping_ids:
values['shipping'] = "true"
shipping_partner = orm_partner.browse(cr, SUPERUSER_ID, shipping_ids[0], context)
checkout['shipping_name'] = getattr(shipping_partner, 'name')
checkout['shipping_phone'] = getattr(shipping_partner, 'phone')
checkout['shipping_street'] = getattr(shipping_partner, 'street')
checkout['shipping_zip'] = getattr(shipping_partner, 'zip')
checkout['shipping_city'] = getattr(shipping_partner, 'city')
checkout['shipping_country_id'] = getattr(shipping_partner, 'country_id')
checkout['shipping_state_id'] = getattr(shipping_partner, 'state_id')
checkout.update(info.from_partner(shipping_partner, address_type='shipping'))
for field_name in info.mandatory_fields():
if not checkout[field_name]:
@ -476,9 +484,9 @@ class Ecommerce(http.Controller):
order_line_obj = request.registry.get('sale.order')
# must have a draft sale order with lines at this point, otherwise redirect to shop
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if not order or order.state != 'draft' or not order.order_line:
request.registry['website'].sale_reset_order(cr, uid, context=context)
request.registry['website'].ecommerce_reset(cr, uid, context=context)
return request.redirect('/shop/')
# if transaction pending / done: redirect to confirmation
tx = context.get('website_sale_transaction')
@ -533,6 +541,7 @@ class Ecommerce(http.Controller):
shipping_id = None
if post.get('shipping_different'):
print post
shipping_info = {
'phone': post['shipping_phone'],
'zip': post['shipping_zip'],
@ -547,6 +556,7 @@ class Ecommerce(http.Controller):
}
domain = [(key, '_id' in key and '=' or 'ilike', '_id' in key and value and int(value) or False)
for key, value in shipping_info.items() if key in info.mandatory_billing_fields + ["type", "parent_id"]]
print domain
shipping_ids = orm_parter.search(cr, SUPERUSER_ID, domain, context=context)
if shipping_ids:
@ -582,9 +592,9 @@ class Ecommerce(http.Controller):
payment_obj = request.registry.get('payment.acquirer')
# if no sale order at this stage: back to checkout beginning
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if not order or not order.state == 'draft' or not order.order_line:
request.registry['website'].sale_reset_order(cr, uid, context=context)
request.registry['website'].ecommerce_reset(cr, uid, context=context)
return request.redirect("/shop/")
# alread a transaction: forward to confirmation
tx = context.get('website_sale_transaction')
@ -644,7 +654,7 @@ class Ecommerce(http.Controller):
cr, uid, context = request.cr, request.uid, request.context
payment_obj = request.registry.get('payment.acquirer')
transaction_obj = request.registry.get('payment.transaction')
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
if not order or not order.order_line or acquirer_id is None:
return request.redirect("/shop/checkout/")
@ -711,7 +721,7 @@ class Ecommerce(http.Controller):
tx = request.registry['payment.transaction'].browse(cr, uid, transaction_id, context=context)
if sale_order_id is None:
order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context)
order = self.get_order()
else:
order = request.registry['sale.order'].browse(cr, uid, sale_order_id, context=context)
@ -733,7 +743,7 @@ class Ecommerce(http.Controller):
request.registry['mail.compose.message'].send_mail(cr, uid, [compose_id], context=create_ctx)
# clean context and session, then redirect to the confirmation page
request.registry['website'].sale_reset_order(cr, uid, context=context)
request.registry['website'].ecommerce_reset(cr, uid, context=context)
return request.redirect('/shop/confirmation/%s' % order.id)

View File

@ -1,24 +1,4 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C)-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
@ -28,6 +8,11 @@ class SaleOrder(osv.Model):
_columns = {
'website_session_id': fields.char('Session UUID4'),
'website_order_line': fields.one2many(
'sale.order.line', 'order_id',
string='Order Lines displayed on Website', readonly=True,
help='Order Lines to be displayed on the website. They should not be used for computation purpose.',
),
}
def _get_website_data(self, cr, uid, order, context):
@ -36,9 +21,9 @@ class SaleOrder(osv.Model):
'order': order
}
def get_total_quantity(self, cr, uid, ids, context=None):
def get_number_of_products(self, cr, uid, ids, context=None):
order = self.browse(cr, uid, ids[0], context=context)
return int(sum(l.product_uom_qty for l in (order.order_line or [])))
return int(sum(l.product_uom_qty for l in (order.website_order_line or [])))
class SaleOrderLine(osv.Model):

View File

@ -10,7 +10,7 @@ class Website(orm.Model):
def _get_pricelist(self, cr, uid, ids, field_name, arg, context=None):
# FIXME: oh god kill me now
pricelist_id = self.get_pricelist_id(cr, uid, ids, context=context)
pricelist_id = self.ecommerce_get_pricelist_id(cr, uid, ids, context=context)
return dict.fromkeys(
ids, self.pool['product.pricelist'].browse(
cr, uid, pricelist_id, context=context))
@ -20,86 +20,16 @@ class Website(orm.Model):
_get_pricelist, type='many2one', obj='product.pricelist')
}
def _get_order(self, cr, uid, order_id=None, context=None):
order_obj = self.pool.get('sale.order')
# check if order allready exists and have access
if order_id:
if not order_id in order_obj.exists(cr, uid, [order_id], context=context):
return False
try:
order = order_obj.browse(cr, uid, order_id, context=context)
if order:
return order
except:
return False
# ************************************************************
# Ecommerce pricelist management
# ***********************************************************
fields = [k for k, v in order_obj._columns.items()]
order_value = order_obj.default_get(cr, SUPERUSER_ID, fields, context=context)
if request.httprequest.session.get('ecommerce_pricelist'):
order_value['pricelist_id'] = request.httprequest.session['ecommerce_pricelist']
order_value['partner_id'] = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
order_value.update(order_obj.onchange_partner_id(cr, SUPERUSER_ID, [], order_value['partner_id'], context=context)['value'])
# add website_session_id key for access rules
if not request.httprequest.session.get('website_session_id'):
request.httprequest.session['website_session_id'] = str(uuid.uuid4())
order_value["website_session_id"] = request.httprequest.session['website_session_id']
order_id = order_obj.create(cr, SUPERUSER_ID, order_value, context=context)
order = order_obj.browse(cr, SUPERUSER_ID, order_id, context=context)
request.httprequest.session['ecommerce_order_id'] = order.id
return order_obj.browse(cr, uid, order_id,
context=dict(request.context, pricelist=order.pricelist_id.id))
def get_current_order(self, cr, uid, context=None):
if request.httprequest.session.get('ecommerce_order_id'):
order = self._get_order(cr, uid, order_id=request.httprequest.session['ecommerce_order_id'], context=context)
if not order:
request.httprequest.session['ecommerce_order_id'] = False
return order
return False
def _get_transaction(self, cr, uid, tx_id=None, context=None):
transaction_obj = self.pool.get('payment.transaction')
if tx_id:
tx_ids = transaction_obj.search(cr, uid, [('id', '=', tx_id), ('state', 'not in', ['cancel'])], context=context)
if tx_ids:
return transaction_obj.browse(cr, uid, tx_ids[0], context=context)
return False
def get_current_transaction(self, cr, uid, context=None):
if request.httprequest.session.get('website_sale_transaction_id'):
tx = self._get_transaction(cr, uid, tx_id=request.httprequest.session['website_sale_transaction_id'], context=context)
if not tx:
request.httprequest.session['website_sale_transaction_id'] = False
return tx
return False
def sale_reset_order(self, cr, uid, context=None):
request.httprequest.session.update({
'ecommerce_order_id': False,
'ecommerce_pricelist': False,
'website_sale_transaction_id': False,
})
request.context.update({
'website_sale_order': False,
'website_sale_transaction': False,
})
def preprocess_request(self, cr, uid, ids, request, context=None):
request.context.update({
'website_sale_order': self.get_current_order(cr, uid, context=context),
'website_sale_transaction': self.get_current_transaction(cr, uid, context=context)
})
return super(Website, self).preprocess_request(cr, uid, ids, request, context=None)
def get_pricelist_id(self, cr, uid, ids, context=None):
def ecommerce_get_pricelist_id(self, cr, uid, ids, context=None):
if not request.httprequest.session.get('ecommerce_pricelist'):
self.change_pricelist_id(cr, uid, None, context=context)
self._ecommerce_change_pricelist(cr, uid, None, context=context)
return request.httprequest.session.get('ecommerce_pricelist')
def change_pricelist_id(self, cr, uid, code=False, context=None):
def _ecommerce_change_pricelist(self, cr, uid, code=None, context=None):
request.httprequest.session.setdefault('ecommerce_pricelist', False)
pricelist_id = False
@ -115,7 +45,7 @@ class Website(orm.Model):
request.httprequest.session['ecommerce_pricelist'] = pricelist_id
order = self.get_current_order(cr, uid, context=context)
order = self.ecommerce_get_current_order(cr, uid, context=context)
if order:
values = {'pricelist_id': pricelist_id}
values.update(order.onchange_pricelist_id(pricelist_id, None)['value'])
@ -123,6 +53,95 @@ class Website(orm.Model):
for line in order.order_line:
self.add_product_to_cart(order_line_id=line.id, number=0)
# ************************************************************
# Ecommerce quotation management
# ************************************************************
def get_website_sale_domain(self):
def _ecommerce_get_quotation_values(self, cr, uid, context=None):
""" Generate the values for a new ecommerce quotation. """
SaleOrder = self.pool.get('sale.order')
fields = [k for k, v in SaleOrder._columns.items()]
values = SaleOrder.default_get(cr, SUPERUSER_ID, fields, context=context)
if request.httprequest.session.get('ecommerce_pricelist'):
values['pricelist_id'] = request.httprequest.session['ecommerce_pricelist']
values['partner_id'] = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
values.update(SaleOrder.onchange_partner_id(cr, SUPERUSER_ID, [], values['partner_id'], context=context)['value'])
values['website_session_id'] = request.httprequest.session['website_session_id']
return values
def _ecommerce_create_quotation(self, cr, uid, context=None):
""" Create a new quotation used in the ecommerce (event, sale) """
SaleOrder = self.pool.get('sale.order')
quotation_values = self._ecommerce_get_quotation_values(cr, uid, context=context)
return SaleOrder.create(cr, SUPERUSER_ID, quotation_values, context=context)
def ecommerce_get_new_order(self, cr, uid, context=None):
""" Create a new quotation for the ecommerce and update the session
accordingly: website_session_id if not set, ecommerce_order_id """
SaleOrder = self.pool.get('sale.order')
# add website_session_id key for access rules
if not request.httprequest.session.get('website_session_id'):
request.httprequest.session['website_session_id'] = str(uuid.uuid4())
order_id = self._ecommerce_create_quotation(cr, uid, context=context)
request.httprequest.session['ecommerce_order_id'] = order_id
order = SaleOrder.browse(cr, SUPERUSER_ID, order_id, context=context)
return SaleOrder.browse(cr, uid, order_id, context=dict(request.context, pricelist=order.pricelist_id.id))
def ecommerce_get_current_order(self, cr, uid, context=None):
SaleOrder = self.pool.get('sale.order')
order_id = request.httprequest.session.get('ecommerce_order_id')
if not order_id:
request.httprequest.session['ecommerce_order_id'] = False
return False
if not order_id in SaleOrder.exists(cr, uid, [order_id], context=context):
request.httprequest.session['ecommerce_order_id'] = False
return False
try:
order = SaleOrder.browse(cr, uid, order_id, context=context)
return order
except:
request.httprequest.session['ecommerce_order_id'] = False
return False
# ************************************************************
# Ecommerce transaction management
# ************************************************************
def _get_transaction(self, cr, uid, tx_id=None, context=None):
transaction_obj = self.pool.get('payment.transaction')
if tx_id:
tx_ids = transaction_obj.search(cr, uid, [('id', '=', tx_id), ('state', 'not in', ['cancel'])], context=context)
if tx_ids:
return transaction_obj.browse(cr, uid, tx_ids[0], context=context)
return False
def ecommerce_get_current_transaction(self, cr, uid, context=None):
if request.httprequest.session.get('website_sale_transaction_id'):
tx = self._get_transaction(cr, uid, tx_id=request.httprequest.session['website_sale_transaction_id'], context=context)
if not tx:
request.httprequest.session['website_sale_transaction_id'] = False
return tx
return False
def ecommerce_reset(self, cr, uid, context=None):
request.httprequest.session.update({
'ecommerce_order_id': False,
'ecommerce_pricelist': False,
'website_sale_transaction_id': False,
})
request.context.update({
'website_sale_order': False,
'website_sale_transaction': False,
})
def preprocess_request(self, cr, uid, ids, request, context=None):
request.context.update({
'website_sale_order': self.ecommerce_get_current_order(cr, uid, context=context),
'website_sale_transaction': self.ecommerce_get_current_transaction(cr, uid, context=context)
})
return super(Website, self).preprocess_request(cr, uid, ids, request, context=None)
def ecommerce_get_product_domain(self):
return [("sale_ok", "=", True)]

View File

@ -13,11 +13,11 @@
<template id="header" inherit_id="website.layout" name="Header Shop My Cart Link">
<xpath expr="//header//ul[@id='top_menu']/li" position="before">
<li t-att-class="(not website_sale_order or not website_sale_order.get_total_quantity()) and 'hidden' or ''">
<li t-att-class="(not website_sale_order or not website_sale_order.get_number_of_products()) and 'hidden' or ''">
<a href="/shop/mycart/">
<i class="fa fa-shopping-cart"></i>
My cart <sup t-attf-class="my_cart_quantity label label-primary"
t-esc="website_sale_order and website_sale_order.get_total_quantity() or ''"/>
t-esc="website_sale_order and website_sale_order.get_number_of_products() or ''"/>
</a>
</li>
</xpath>
@ -396,10 +396,10 @@
<h1 class="mb32">Shopping Cart</h1>
<div class="row">
<div class="col-md-8 col-sm-9 oe_mycart">
<div t-if="not website_sale_order or not website_sale_order.order_line" class="well well-lg">
<div t-if="not website_sale_order or not website_sale_order.website_order_line" class="well well-lg">
Your cart is empty!
</div>
<table class='table table-striped table-condensed' id="mycart_products" t-if="website_sale_order and website_sale_order.order_line">
<table class='table table-striped table-condensed' id="mycart_products" t-if="website_sale_order and website_sale_order.website_order_line">
<colgroup>
<col width="100"/>
<col/>
@ -414,7 +414,7 @@
</tr>
</thead>
<tbody>
<tr t-foreach="website_sale_order.order_line" t-as="line">
<tr t-foreach="website_sale_order.website_order_line" t-as="line">
<td colspan="2" t-if="not line.product_id.product_tmpl_id"></td>
<td align="center" t-if="line.product_id.product_tmpl_id">
<span t-field="line.product_id.image_small"
@ -486,7 +486,7 @@
</table>
<div class="clearfix"/>
<a href="/shop" class="btn btn-default mb32"><span class="fa fa-long-arrow-left"/> Continue Shopping</a>
<a t-if="website_sale_order and website_sale_order.order_line" href="/shop/checkout/" class="btn btn-primary pull-right mb32">Process Checkout <span class="fa fa-long-arrow-right"/></a>
<a t-if="website_sale_order and website_sale_order.website_order_line" href="/shop/checkout/" class="btn btn-primary pull-right mb32">Process Checkout <span class="fa fa-long-arrow-right"/></a>
<div class="oe_structure"/>
</div>
<div class="col-lg-3 col-lg-offset-1 col-sm-3 text-muted" id="right_column">
@ -626,7 +626,7 @@
<p>
Have a coupon code? Fill in this field and apply.
</p>
<form t-if="website_sale_order and website_sale_order.order_line" action="/shop/mycart/" method="post" class="mb32">
<form t-if="website_sale_order and website_sale_order.website_order_line" action="/shop/mycart/" method="post" class="mb32">
<div class="input-group">
<input name="promo" class='form-control' type="text" placeholder="code..." t-att-value="website_sale_order.pricelist_id.code or ''"/>
<div class="input-group-btn">
@ -821,7 +821,7 @@
<h1 class="mb32">Validate Order</h1>
<div class="row">
<div class="col-lg-8 col-sm-9 oe_mycart">
<table class='table table-striped table-condensed' id="mycart_products" t-if="website_sale_order and website_sale_order.order_line">
<table class='table table-striped table-condensed' id="mycart_products" t-if="website_sale_order and website_sale_order.website_order_line">
<colgroup>
<col width="80"/>
<col/>
@ -836,7 +836,7 @@
</tr>
</thead>
<tbody>
<tr t-foreach="website_sale_order.order_line" t-as="line">
<tr t-foreach="website_sale_order.website_order_line" t-as="line">
<td colspan="2" t-if="not line.product_id.product_tmpl_id"></td>
<td t-if="line.product_id.product_tmpl_id">
<a t-href="/shop/product/#{ slug(line.product_id.product_tmpl_id) }/">

View File

@ -0,0 +1 @@
import main

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from openerp.addons.website_sale.controllers.main import Ecommerce
from openerp.addons.web.http import request
from openerp.addons.website.models import website
class Ecommerce(Ecommerce):
@website.route(['/shop/payment/'], type='http', auth="public", multilang=True)
def payment(self, **post):
cr, uid, context = request.cr, request.uid, request.context
order = self.get_order()
carrier_id = post.get('carrier_id')
if order and carrier_id:
# recompute delivery costs
SaleOrder = request.registry['sale.order']
SaleOrder.write(cr, uid, [order.id], {'carrier_id': carrier_id}, context=context)
SaleOrder.delivery_set(cr, uid, [order.id], context=context)
res = super(Ecommerce, self).payment(**post)
return res

View File

@ -1 +1,2 @@
import sale_order
import website

View File

@ -17,28 +17,32 @@ class delivery_carrier(orm.Model):
class SaleOrder(orm.Model):
_inherit = 'sale.order'
_columns = {
'website_order_line': fields.one2many(
'sale.order.line', 'order_id',
string='Order Lines displayed on Website', readonly=True,
domain=[('is_delivery', '=', False)],
help='Order Lines to be displayed on the website. They should not be used for computation purpose.',
),
}
def _add_delivery(self, cr, uid, order, context=None):
pass
def _get_website_data(self, cr, uid, order, context=None):
""" Override to add delivery-related website data. """
values = super(SaleOrder, self)._get_website_data(cr, uid, order, context=context)
# We need a delivery only if we have stockable products
todo = False
has_stockable_products = False
for line in order.order_line:
if line.product_id.type in ('consu', 'product'):
todo = True
if not todo:
has_stockable_products = True
if not has_stockable_products:
return values
carrier_obj = self.pool.get('delivery.carrier')
dids = carrier_obj.search(cr, uid, [], context=context)
context['order_id'] = order.id
deliveries = carrier_obj.browse(cr, uid, dids, context=context)
# By default, select the first carrier
# if not order.carrier_id and dids:
# self.pool.get('sale.order').write(cr, uid, [order.id], {'carrier_id': dids[0]}, context=context)
# recompute delivery costs
self.pool.get('sale.order').delivery_set(cr, uid, [order.id], context=context)
values['deliveries'] = deliveries
delivery_ctx = dict(context, order_id=order.id)
DeliveryCarrier = self.pool.get('delivery.carrier')
delivery_ids = DeliveryCarrier.search(cr, uid, [], context=context)
values['deliveries'] = DeliveryCarrier.browse(cr, uid, delivery_ids, context=delivery_ctx)
return values

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
from openerp.osv import orm
class Website(orm.Model):
_inherit = 'website'
def _ecommerce_get_quotation_values(self, cr, uid, context=None):
""" Override the quotation values generation to add carrier_id data """
values = super(Website, self)._ecommerce_get_quotation_values(cr, uid, context=context)
DeliveryCarrier = self.pool.get('delivery.carrier')
carrier_ids = DeliveryCarrier.search(cr, uid, [], context=context, limit=1)
# By default, select the first carrier
if carrier_ids:
values['carrier_id'] = carrier_ids[0]
return values
def _ecommerce_create_quotation(self, cr, uid, context=None):
order_id = super(Website, self)._ecommerce_create_quotation(cr, uid, context=context)
self.pool['sale.order'].delivery_set(cr, uid, [order_id], context=context)
return order_id