[FIX] website_sale*: not possible to process order if no delivery methods available

bzr revid: dle@openerp.com-20140402144520-ulfex2r3q9wwd3ig
This commit is contained in:
Denis Ledoux 2014-04-02 16:45:20 +02:00
parent 9553c48a8b
commit ad680380b8
6 changed files with 86 additions and 71 deletions

View File

@ -584,6 +584,7 @@ class Ecommerce(http.Controller):
"""
cr, uid, context = request.cr, request.uid, request.context
payment_obj = request.registry.get('payment.acquirer')
sale_order_obj = request.registry['sale.order']
# if no sale order at this stage: back to checkout beginning
order = self.get_order()
@ -603,29 +604,31 @@ class Ecommerce(http.Controller):
shipping_partner_id = order.partner_invoice_id.id
values = {
'order': request.registry['sale.order'].browse(cr, SUPERUSER_ID, order.id, context=context)
'order': sale_order_obj.browse(cr, SUPERUSER_ID, order.id, context=context)
}
values.update(request.registry.get('sale.order')._get_website_data(cr, uid, order, context))
values['errors'] = sale_order_obj._get_errors(cr, uid, order, context=context)
values.update(sale_order_obj._get_website_data(cr, uid, order, context=context))
# fetch all registered payment means
if tx:
acquirer_ids = [tx.acquirer_id.id]
else:
acquirer_ids = payment_obj.search(cr, SUPERUSER_ID, [('website_published', '=', True), '|', ('company_id', '=', order.company_id.id), ('company_id', '=', False)], context=context)
values['acquirers'] = payment_obj.browse(cr, uid, acquirer_ids, context=context)
render_ctx = dict(context, submit_class='btn btn-primary', submit_txt='Pay Now')
for acquirer in values['acquirers']:
render_ctx['tx_url'] = '/shop/payment/transaction/%s' % acquirer.id
acquirer.button = payment_obj.render(
cr, SUPERUSER_ID, acquirer.id,
order.name,
order.amount_total,
order.pricelist_id.currency_id.id,
partner_id=shipping_partner_id,
tx_values={
'return_url': '/shop/payment/validate',
},
context=render_ctx)
if not values['errors']:
# fetch all registered payment means
if tx:
acquirer_ids = [tx.acquirer_id.id]
else:
acquirer_ids = payment_obj.search(cr, SUPERUSER_ID, [('website_published', '=', True), '|', ('company_id', '=', order.company_id.id), ('company_id', '=', False)], context=context)
values['acquirers'] = payment_obj.browse(cr, uid, acquirer_ids, context=context)
render_ctx = dict(context, submit_class='btn btn-primary', submit_txt='Pay Now')
for acquirer in values['acquirers']:
render_ctx['tx_url'] = '/shop/payment/transaction/%s' % acquirer.id
acquirer.button = payment_obj.render(
cr, SUPERUSER_ID, acquirer.id,
order.name,
order.amount_total,
order.pricelist_id.currency_id.id,
partner_id=shipping_partner_id,
tx_values={
'return_url': '/shop/payment/validate',
},
context=render_ctx)
return request.website.render("website_sale.payment", values)

View File

@ -16,6 +16,9 @@ class SaleOrder(osv.Model):
),
}
def _get_errors(self, cr, uid, order, context=None):
return []
def _get_website_data(self, cr, uid, order, context):
return {
'partner': order.partner_id.id,

View File

@ -883,6 +883,12 @@
<li class="text-muted">Confirmation<span class="chevron"></span></li>
</ul>
<h1 class="mb32">Validate Order</h1>
<t t-foreach="errors" t-as="error">
<div class="alert alert-danger" t-if="error">
<h3><t t-esc="error[0]"/></h3>
<t t-esc="error[1]"/>
</div>
</t>
<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.website_order_line">
@ -970,7 +976,7 @@
</t>
</div>
</div>
<div class="js_payment mb64 row" t-if="not website_sale_order.amount_total" id="payment_method">
<div class="js_payment mb64 row" t-if="not website_sale_order.amount_total and not errors" id="payment_method">
<div class="col-lg-8 col-sm-8">
<form target="_self" action="/shop/payment/validate/" method="post" class="pull-right">
<a style="width:100px;" class="btn btn-primary a-submit">

View File

@ -10,13 +10,13 @@ class Ecommerce(Ecommerce):
@http.route(['/shop/payment/'], type='http', auth="public", website=True, multilang=True)
def payment(self, **post):
cr, uid, context = request.cr, request.uid, request.context
carrier_obj = request.registry.get('delivery.carrier')
order = self.get_order()
carrier_id = post.get('carrier_id')
if carrier_id:
carrier_id = int(carrier_id)
if order and carrier_id or not carrier_obj.grid_get(cr, uid, [order.carrier_id.id], order.partner_shipping_id.id):
# recompute delivery costs
request.registry['website']._check_carrier_quotation(cr,uid,order,carrier_id,context=context)
request.registry['sale.order']._check_carrier_quotation(cr, uid, order, force_carrier_id=carrier_id, context=context)
if order and carrier_id:
return request.redirect("/shop/payment/")
res = super(Ecommerce, self).payment(**post)

View File

@ -56,6 +56,50 @@ class SaleOrder(orm.Model):
),
}
def _check_carrier_quotation(self, cr, uid, order, force_carrier_id=None, context=None):
carrier_obj = self.pool.get('delivery.carrier')
# check to add or remove carrier_id
if all(line.product_id.type == "service" for line in order.website_order_line):
order.write({'carrier_id': None}, context=context)
self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context)
return True
else:
carrier_id = force_carrier_id or order.carrier_id.id
if force_carrier_id or not carrier_id or not carrier_id in self._get_delivery_methods(cr, uid, order, context=context):
self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context)
carrier_ids = self.pool.get('delivery.carrier').search(cr, uid, [('website_published','=',True)], context=context)
if force_carrier_id:
carrier_ids.insert(0, force_carrier_id)
for delivery_id in carrier_ids:
grid_id = carrier_obj.grid_get(cr, uid, [delivery_id], order.partner_shipping_id.id)
if grid_id:
carrier_id = delivery_id
break
order.write({'carrier_id': carrier_id}, context=context)
if carrier_id:
order.delivery_set(context=context)
return bool(carrier_id)
def _get_delivery_methods(self, cr, uid, order, context=None):
carrier_obj = self.pool.get('delivery.carrier')
delivery_ids = carrier_obj.search(cr, uid, [('website_published','=',True)], context=context)
# Following loop is done to avoid displaying delivery methods who are not available for this order
# This can surely be done in a more efficient way, but at the moment, it mimics the way it's
# done in delivery_set method of sale.py, from delivery module
for delivery_id in list(delivery_ids):
grid_id = carrier_obj.grid_get(cr, uid, [delivery_id], order.partner_shipping_id.id)
if not grid_id:
delivery_ids.remove(delivery_id)
return delivery_ids
def _get_errors(self, cr, uid, order, context=None):
errors = super(SaleOrder, self)._get_errors(cr, uid, order, context=context)
if not self._get_delivery_methods(cr, uid, order, context=context):
errors.append(('No delivery method available', 'There is no available delivery method for your order'))
return errors
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)
@ -69,14 +113,7 @@ class SaleOrder(orm.Model):
delivery_ctx = dict(context, order_id=order.id)
DeliveryCarrier = self.pool.get('delivery.carrier')
carrier_obj = self.pool.get('delivery.carrier')
delivery_ids = DeliveryCarrier.search(cr, uid, [('website_published','=',True)], context=context)
# Following loop is done to avoid displaying delivery methods who are not available for this order
# This can surely be done in a more efficient way, but at the moment, it mimics the way it's
# done in delivery_set method of sale.py, from delivery module
for delivery_id in delivery_ids:
grid_id = carrier_obj.grid_get(cr, uid, [delivery_id], order.partner_shipping_id.id)
if not grid_id:
delivery_ids.remove(delivery_id)
delivery_ids = self._get_delivery_methods(cr, uid, order, context=context)
values['deliveries'] = DeliveryCarrier.browse(cr, SUPERUSER_ID, delivery_ids, context=delivery_ctx)
return values

View File

@ -9,7 +9,7 @@ class Website(orm.Model):
def _ecommerce_create_quotation(self, cr, uid, context=None):
order_id = super(Website, self)._ecommerce_create_quotation(cr, uid, context=context)
order = self.pool['sale.order'].browse(cr, SUPERUSER_ID, order_id, context=context)
self._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context)
self.pool['sale.order']._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context)
return order_id
def _ecommerce_add_product_to_cart(self, cr, uid, product_id=0, order_line_id=0, number=1, set_number=-1, context=None):
@ -17,38 +17,4 @@ class Website(orm.Model):
product_id=product_id, order_line_id=order_line_id, number=number, set_number=set_number,
context=context)
order = self.ecommerce_get_current_order(cr, uid, context=context)
return self._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context) and quantity or None
def _check_carrier_quotation(self, cr, uid, order, force_carrier_id=None, context=None):
# check to add or remove carrier_id
carrier_obj = self.pool.get('delivery.carrier')
carrier_id = False
for line in order.website_order_line:
if line.product_id.type != "service":
carrier_id = True
break
if not carrier_id:
order.write({'carrier_id': None}, context=context)
self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context)
return True
else:
if order.carrier_id:
self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context)
carrier_ids = self.pool.get('delivery.carrier').search(cr, uid, [('website_published','=',True)], context=context)
if force_carrier_id:
carrier_ids.insert(0, force_carrier_id)
for delivery_id in set(carrier_ids):
grid_id = carrier_obj.grid_get(cr, uid, [delivery_id], order.partner_shipping_id.id)
if grid_id:
carrier_id = delivery_id
break
order.write({'carrier_id': carrier_id}, context=context)
#If carrier_id have no grid, we don't have delivery !
if carrier_id:
order.delivery_set(context=context)
else:
self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context)
return bool(carrier_id)
return self.pool['sale.order']._check_carrier_quotation(cr, uid, order, force_carrier_id=None, context=context) and quantity or None