[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:
parent
e883b15c48
commit
7a564f261e
|
@ -1 +1,2 @@
|
|||
import event
|
||||
import website
|
||||
|
|
|
@ -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)]
|
|
@ -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)]
|
|
@ -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,9 +425,9 @@ 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')
|
||||
|
@ -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)
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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) }/">
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import main
|
|
@ -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
|
|
@ -1 +1,2 @@
|
|||
import sale_order
|
||||
import website
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue