[IMP] website_sale_options
This commit is contained in:
parent
1d68662fb9
commit
204a62499a
|
@ -62,7 +62,7 @@ class ir_http(orm.AbstractModel):
|
|||
self.geo_ip_resolver = GeoIP.open('/usr/share/GeoIP/GeoIP.dat', GeoIP.GEOIP_STANDARD)
|
||||
except ImportError:
|
||||
self.geo_ip_resolver = False
|
||||
if self.geo_ip_resolver:
|
||||
if self.geo_ip_resolver and request.httprequest.remote_addr:
|
||||
record = self.geo_ip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
|
||||
request.session['geoip'] = record
|
||||
|
||||
|
|
|
@ -98,17 +98,17 @@ class QueryURL(object):
|
|||
return path
|
||||
|
||||
|
||||
class website_sale(http.Controller):
|
||||
def get_pricelist():
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
sale_order = context.get('sale_order')
|
||||
if sale_order:
|
||||
pricelist = sale_order.pricelist_id
|
||||
else:
|
||||
partner = pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
|
||||
pricelist = partner.property_product_pricelist
|
||||
return pricelist
|
||||
|
||||
def get_pricelist(self):
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
sale_order = context.get('sale_order')
|
||||
if sale_order:
|
||||
pricelist = sale_order.pricelist_id
|
||||
else:
|
||||
partner = pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
|
||||
pricelist = partner.property_product_pricelist
|
||||
return pricelist
|
||||
class website_sale(http.Controller):
|
||||
|
||||
@http.route(['/shop',
|
||||
'/shop/page/<int:page>',
|
||||
|
@ -215,11 +215,6 @@ class website_sale(http.Controller):
|
|||
context['pricelist'] = int(self.get_pricelist())
|
||||
product = template_obj.browse(cr, uid, int(product), context=context)
|
||||
|
||||
optional_product_ids = []
|
||||
for p in product.optional_product_ids:
|
||||
ctx = dict(context, active_id=p.id)
|
||||
optional_product_ids.append(template_obj.browse(cr, uid, p.id, context=ctx))
|
||||
|
||||
attribute_value_ids = []
|
||||
if request.website.company_pricelist_id.id != context['pricelist']:
|
||||
company_currency_id = request.website.company_currency_id.id
|
||||
|
@ -240,7 +235,6 @@ class website_sale(http.Controller):
|
|||
'category_list': category_list,
|
||||
'main_object': product,
|
||||
'product': product,
|
||||
'optional_product_ids': optional_product_ids,
|
||||
'attribute_value_ids': attribute_value_ids
|
||||
}
|
||||
return request.website.render("website_sale.product", values)
|
||||
|
@ -282,24 +276,13 @@ class website_sale(http.Controller):
|
|||
@http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True)
|
||||
def cart_update(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
order = request.website.sale_get_order(force_create=1)
|
||||
prod_obj = pool['product.product']
|
||||
|
||||
optional_product_ids = []
|
||||
for k, v in kw.items():
|
||||
if "optional-product-" in k and int(kw.get(k.replace("product", "quantity"))):
|
||||
optional_product_ids.append(int(v))
|
||||
if add_qty or set_qty:
|
||||
line_id, quantity, option_ids = order._cart_update(product_id=int(product_id),
|
||||
add_qty=int(add_qty), set_qty=int(set_qty),
|
||||
optional_product_ids=optional_product_ids)
|
||||
# options have all time the same quantity
|
||||
for option_id in optional_product_ids:
|
||||
order._cart_update(product_id=option_id, set_qty=quantity, linked_line_id=line_id)
|
||||
order = request.website.sale_get_order(force_create=1)
|
||||
line_id, quantity = order._cart_update(product_id=int(product_id), add_qty=int(add_qty), set_qty=int(set_qty))
|
||||
|
||||
if goto_shop:
|
||||
attrib_list = request.httprequest.args.getlist('attrib')
|
||||
keep = QueryURL('/shop', category=kw.get('category'), search=kw.get('search'), attrib=attrib_list)
|
||||
return request.redirect( keep() )
|
||||
return request.redirect("/shop/product/%s" % slug(prod_obj.browse(cr, uid, product_id).product_tmpl_id))
|
||||
else:
|
||||
return request.redirect("/shop/cart")
|
||||
|
||||
|
|
|
@ -6,58 +6,6 @@
|
|||
<field name="image" type="base64" file="website/static/description/website_edit.png"/>
|
||||
</record>
|
||||
|
||||
<!-- add Warranty to ipad -->
|
||||
|
||||
<record id="product_attribute_1" model="product.attribute">
|
||||
<field name="name">Duration</field>
|
||||
<field name="type">hidden</field>
|
||||
</record>
|
||||
<record id="product_attribute_value_1" model="product.attribute.value">
|
||||
<field name="name">1 year</field>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
</record>
|
||||
<record id="product_attribute_value_2" model="product.attribute.value">
|
||||
<field name="name">2 year</field>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
</record>
|
||||
|
||||
<record id="product_product_1" model="product.product">
|
||||
<field name="name">Warranty</field>
|
||||
<field name="list_price">20.0</field>
|
||||
<field name="website_sequence">1000</field>
|
||||
<field name="website_published" eval="True"/>
|
||||
<field name="type">service</field>
|
||||
<field name="uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="uom_po_id" ref="product.product_uom_unit"/>
|
||||
<field name="description_sale">Warranty, issued to the purchaser of an article by its manufacturer, promising to repair or replace it if necessary within a specified period of time.</field>
|
||||
<field name="default_code">W0001</field>
|
||||
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_1')])]"/>
|
||||
</record>
|
||||
<record id="product_product_1b" model="product.product">
|
||||
<field name="default_code">W0002</field>
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_2')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="product_attribute_line_1" model="product.attribute.line">
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
<field name="value_ids" eval="[(6,0,[ref('product_attribute_value_1'), ref('product_attribute_value_2')])]"/>
|
||||
</record>
|
||||
<record id="product_product_1_product_template" model="product.template">
|
||||
<field name="attribute_line_ids" eval="[(6,0,[ref('product_attribute_line_1')])]"/>
|
||||
</record>
|
||||
<record id="product.product_product_4_product_template" model="product.template">
|
||||
<field name="optional_product_ids" eval="[(6,0,[ref('product_product_1_product_template')])]"/>
|
||||
</record>
|
||||
<record id="product_attribute_price_1" model="product.attribute.price">
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="value_id" ref="product_attribute_value_2"/>
|
||||
<field name="price_extra">18.00</field>
|
||||
</record>
|
||||
|
||||
<!-- -->
|
||||
|
||||
<record id="product.product_attribute_2" model="product.attribute">
|
||||
<field name="type">color</field>
|
||||
</record>
|
||||
|
|
|
@ -51,20 +51,14 @@ class sale_order(osv.Model):
|
|||
'order': order
|
||||
}
|
||||
|
||||
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, linked_line_id=None, optional_product_ids=None, context=None):
|
||||
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None):
|
||||
for so in self.browse(cr, uid, ids, context=context):
|
||||
order_line_id = None
|
||||
|
||||
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
|
||||
if line_id:
|
||||
domain += [('id', '=', line_id)]
|
||||
domain += linked_line_id and [('linked_line_id', '=', linked_line_id)] or [('linked_line_id', '=', False)]
|
||||
if not line_id:
|
||||
if optional_product_ids:
|
||||
domain += [('option_line_ids.product_id', '=', pid) for pid in optional_product_ids]
|
||||
else:
|
||||
domain += [('option_line_ids', '=', False)]
|
||||
|
||||
order_line_id = None
|
||||
order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
|
||||
if order_line_ids:
|
||||
order_line_id = order_line_ids[0]
|
||||
|
@ -99,15 +93,11 @@ class sale_order(osv.Model):
|
|||
|
||||
quantity = 0
|
||||
for so in self.browse(cr, uid, ids, context=context):
|
||||
line_id = so._cart_find_product_line(product_id, line_id, linked_line_id, optional_product_ids, context=context)
|
||||
line_id = so._cart_find_product_line(product_id, line_id, context=context)
|
||||
|
||||
# Create line if no line with product_id can be located
|
||||
if not line_id:
|
||||
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, context=context)
|
||||
if linked_line_id and linked_line_id in map(int,so.order_line):
|
||||
values["linked_line_id"] = linked_line_id
|
||||
linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
|
||||
values["name"] = _("%s\nLinked to: %s") % (values["name"], linked.product_id.name_get()[0][1])
|
||||
line_id = sol.create(cr, SUPERUSER_ID, values, context=context)
|
||||
if add_qty:
|
||||
add_qty -= 1
|
||||
|
@ -118,23 +108,16 @@ class sale_order(osv.Model):
|
|||
elif add_qty != None:
|
||||
quantity = sol.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)
|
||||
|
||||
# select linked product
|
||||
option_ids = [line.id for line in so.order_line if line.linked_line_id.id == line_id]
|
||||
|
||||
# Remove zero of negative lines
|
||||
if quantity <= 0:
|
||||
sol.unlink(cr, SUPERUSER_ID, [line_id] + option_ids, context=context)
|
||||
sol.unlink(cr, SUPERUSER_ID, [line_id], context=context)
|
||||
else:
|
||||
# update line
|
||||
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, line_id, context=context)
|
||||
values['product_uom_qty'] = quantity
|
||||
sol.write(cr, SUPERUSER_ID, [line_id], values, context=context)
|
||||
|
||||
# change quantity of linked product
|
||||
if option_ids:
|
||||
sol.write(cr, SUPERUSER_ID, option_ids, {'product_uom_qty': quantity}, context=context)
|
||||
|
||||
return (line_id, quantity, option_ids)
|
||||
return (line_id, quantity)
|
||||
|
||||
def _cart_accessories(self, cr, uid, ids, context=None):
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -143,28 +126,6 @@ class sale_order(osv.Model):
|
|||
product_ids = random.sample(s, min(len(s),3))
|
||||
return self.pool['product.product'].browse(cr, uid, product_ids, context=context)
|
||||
|
||||
def _cart_optional_products(self, cr, uid, ids, context=None):
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
products = {}
|
||||
for l in order.website_order_line:
|
||||
opt = {}
|
||||
for o in l.product_id.optional_product_ids:
|
||||
if not opt.get(o.product_tmpl_id.id):
|
||||
opt[o.product_tmpl_id.id] = {
|
||||
'product_tmpl_id': o.product_tmpl_id,
|
||||
'product_ids': []
|
||||
}
|
||||
if o not in opt[o.product_tmpl_id.id]:
|
||||
opt[o.product_tmpl_id.id]['product_ids'].append(o)
|
||||
|
||||
if opt:
|
||||
products[l.id] = {
|
||||
'order_line_id': l,
|
||||
'optional_product_tmpl': opt
|
||||
}
|
||||
|
||||
return products
|
||||
|
||||
class website(orm.Model):
|
||||
_inherit = 'website'
|
||||
|
||||
|
|
|
@ -393,13 +393,10 @@
|
|||
<t t-call="website_sale.product_price"/>
|
||||
<p t-if="len(product.product_variant_ids) > 1" class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
|
||||
|
||||
<t t-placeholder="button">
|
||||
<a t-if="not optional_product_ids" class="btn btn-primary btn-lg mt8 a-submit js_check_product">Add to Cart</a>
|
||||
<a t-if="optional_product_ids" class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
|
||||
</t>
|
||||
<a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
|
||||
</div>
|
||||
|
||||
<div t-if="optional_product_ids" id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
|
@ -407,7 +404,6 @@
|
|||
<h4 class="modal-title" id="myModalLabel">Product to add in your shopping cart</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<table class="table table-striped table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -426,7 +422,7 @@
|
|||
<strong t-field="product.name"/>
|
||||
<div class="text-muted">
|
||||
<div t-field="product.description_sale"/>
|
||||
<div class="js_attributes"></div>
|
||||
<div class="js_attributes"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
|
@ -461,51 +457,6 @@
|
|||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
|
||||
<t t-set="option_inc" t-value="0"/>
|
||||
<tr class="js_product" t-foreach="optional_product_ids" t-as="product">
|
||||
<td width="100">
|
||||
<input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
|
||||
<span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-left">
|
||||
<strong class="media-heading" t-field="product.name"/>
|
||||
<div class="text-muted" t-field="product.description_sale"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-right">
|
||||
<t t-call="website_sale.variants"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="(website.compute_curency(product.lst_price) - product.price) > 0.1">
|
||||
<span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
|
||||
t-field="product.lst_price"
|
||||
t-field-options='{
|
||||
"widget": "monetary",
|
||||
"from_currency": "website.company_currency_id",
|
||||
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
|
||||
}'/><br/>
|
||||
</t>
|
||||
<span class="oe_price" style="white-space: nowrap;"
|
||||
t-field="product.price"
|
||||
t-field-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
|
||||
}'/>
|
||||
<p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
|
||||
<a href="#" class="js_add"><strong>Add to Cart</strong></a>
|
||||
<span class="js_remove hidden">
|
||||
<span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
|
||||
<a href="#" class="js_remove"><small>Remove from cart</small></a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -536,19 +487,8 @@
|
|||
</t>
|
||||
</template>
|
||||
|
||||
<template id="product_confirmation" inherit_id="website_sale.product" optional="disabled" name="Confirm: Add To Cart">
|
||||
<xpath expr="//div[@id='modal_optional_products']" position="attributes">
|
||||
<attribute name="t-if">True</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-placeholder='button']" position="replace">
|
||||
<t t-placeholder="button">
|
||||
<a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="product_quantity" inherit_id="website_sale.product" optional="enabled" name="Select Quantity">
|
||||
<xpath expr="//t[@t-placeholder='button']" position="before">
|
||||
<xpath expr="//a[@data-target='#modal_optional_products']" position="before">
|
||||
<div class="css_quantity input-group" style="width: 108px;">
|
||||
<span class="input-group-addon">
|
||||
<a t-attf-href="#" class="mb8 js_add_cart_json">
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
<field name="website_published" class="pull-right" widget="website_button"/>
|
||||
<field name="alternative_product_ids" widget="many2many_tags"/>
|
||||
<field name="accessory_product_ids" widget="many2many_tags"/>
|
||||
<field name="optional_product_ids" widget="many2many_tags"/>
|
||||
<field name="website_style_ids" widget="many2many_tags"/>
|
||||
<field name="website_sequence"/>
|
||||
</group>
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
import controllers
|
||||
import models
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
'name': 'eCommerce Optional Products',
|
||||
'category': 'Website',
|
||||
'version': '1.0',
|
||||
'description': """
|
||||
OpenERP E-Commerce
|
||||
==================
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['website_sale'],
|
||||
'data': [
|
||||
'views/views.xml',
|
||||
'views/templates.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/demo.xml',
|
||||
],
|
||||
'qweb': ['static/src/xml/*.xml'],
|
||||
'installable': True,
|
||||
'application': True,
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
import main
|
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website.models.website import slug
|
||||
from openerp.addons.website_sale.controllers.main import QueryURL
|
||||
from openerp.addons.website_sale.controllers.main import website_sale
|
||||
|
||||
class website_sale_options(website_sale):
|
||||
|
||||
def product(self, product, category='', search='', **kwargs):
|
||||
r = super(website_sale_options, self)
|
||||
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
template_obj = pool['product.template']
|
||||
|
||||
optional_product_ids = []
|
||||
for p in product.optional_product_ids:
|
||||
ctx = dict(context, active_id=p.id)
|
||||
optional_product_ids.append(template_obj.browse(cr, uid, p.id, context=ctx))
|
||||
|
||||
r.qcontext['optional_product_ids'] = optional_product_ids
|
||||
return r
|
||||
|
||||
def cart_update(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
order = request.website.sale_get_order(force_create=1)
|
||||
prod_obj = pool['product.product']
|
||||
|
||||
optional_product_ids = []
|
||||
for k, v in kw.items():
|
||||
if "optional-product-" in k and int(kw.get(k.replace("product", "quantity"))):
|
||||
optional_product_ids.append(int(v))
|
||||
if add_qty or set_qty:
|
||||
line_id, quantity = order._cart_update(product_id=int(product_id),
|
||||
add_qty=int(add_qty), set_qty=int(set_qty),
|
||||
optional_product_ids=optional_product_ids)
|
||||
# options have all time the same quantity
|
||||
for option_id in optional_product_ids:
|
||||
order._cart_update(product_id=option_id, set_qty=value.get('quantity'), linked_line_id=value.get('line_id'))
|
||||
|
||||
if goto_shop:
|
||||
return request.redirect("/shop/product/%s" % slug(prod_obj.browse(cr, uid, product_id).product_tmpl_id))
|
||||
else:
|
||||
return request.redirect("/shop/cart")
|
|
@ -0,0 +1,58 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- add Warranty to ipad -->
|
||||
|
||||
<record id="product_attribute_1" model="product.attribute">
|
||||
<field name="name">Duration</field>
|
||||
<field name="type">hidden</field>
|
||||
</record>
|
||||
<record id="product_attribute_value_1" model="product.attribute.value">
|
||||
<field name="name">1 year</field>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
</record>
|
||||
<record id="product_attribute_value_2" model="product.attribute.value">
|
||||
<field name="name">2 year</field>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
</record>
|
||||
|
||||
<record id="product_product_1" model="product.product">
|
||||
<field name="name">Warranty</field>
|
||||
<field name="list_price">20.0</field>
|
||||
<field name="website_sequence">-1</field>
|
||||
<field name="website_published" eval="True"/>
|
||||
<field name="type">service</field>
|
||||
<field name="uom_id" ref="product.product_uom_unit"/>
|
||||
<field name="uom_po_id" ref="product.product_uom_unit"/>
|
||||
<field name="description_sale">Warranty, issued to the purchaser of an article by its manufacturer, promising to repair or replace it if necessary within a specified period of time.</field>
|
||||
<field name="default_code">W0001</field>
|
||||
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_1')])]"/>
|
||||
</record>
|
||||
<record id="product_product_1b" model="product.product">
|
||||
<field name="default_code">W0002</field>
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_2')])]"/>
|
||||
</record>
|
||||
|
||||
<record id="product_attribute_line_1" model="product.attribute.line">
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="attribute_id" ref="product_attribute_1"/>
|
||||
<field name="value_ids" eval="[(6,0,[ref('product_attribute_value_1'), ref('product_attribute_value_2')])]"/>
|
||||
</record>
|
||||
<record id="product_product_1_product_template" model="product.template">
|
||||
<field name="attribute_line_ids" eval="[(6,0,[ref('product_attribute_line_1')])]"/>
|
||||
</record>
|
||||
<record id="product.product_product_4_product_template" model="product.template">
|
||||
<field name="optional_product_ids" eval="[(6,0,[ref('product_product_1_product_template')])]"/>
|
||||
</record>
|
||||
<record id="product_attribute_price_1" model="product.attribute.price">
|
||||
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
|
||||
<field name="value_id" ref="product_attribute_value_2"/>
|
||||
<field name="price_extra">18.00</field>
|
||||
</record>
|
||||
|
||||
<!-- -->
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1 @@
|
|||
import sale_order
|
|
@ -0,0 +1,72 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv, orm, fields
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.tools.translate import _
|
||||
|
||||
|
||||
class sale_order(osv.Model):
|
||||
_inherit = "sale.order"
|
||||
|
||||
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, linked_line_id=None, optional_product_ids=None, context=None):
|
||||
for so in self.browse(cr, uid, ids, context=context):
|
||||
|
||||
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
|
||||
if line_id:
|
||||
domain += [('id', '=', line_id)]
|
||||
domain += linked_line_id and [('linked_line_id', '=', linked_line_id)] or [('linked_line_id', '=', False)]
|
||||
if not line_id:
|
||||
if optional_product_ids:
|
||||
domain += [('option_line_ids.product_id', '=', pid) for pid in optional_product_ids]
|
||||
else:
|
||||
domain += [('option_line_ids', '=', False)]
|
||||
|
||||
order_line_id = None
|
||||
order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
|
||||
if order_line_ids:
|
||||
order_line_id = order_line_ids[0]
|
||||
return order_line_id
|
||||
|
||||
def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, linked_line_id=None, optional_product_ids=None, context=None):
|
||||
""" Add or set product quantity, add_qty can be negative """
|
||||
sol = self.pool.get('sale.order.line')
|
||||
|
||||
quantity = 0
|
||||
for so in self.browse(cr, uid, ids, context=context):
|
||||
line_id = so._cart_find_product_line(product_id, line_id, linked_line_id, optional_product_ids, context=context)
|
||||
|
||||
# Create line if no line with product_id can be located
|
||||
if not line_id:
|
||||
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, context=context)
|
||||
if linked_line_id and linked_line_id in map(int,so.order_line):
|
||||
values["linked_line_id"] = linked_line_id
|
||||
linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
|
||||
values["name"] = _("%s\nLinked to: %s") % (values["name"], linked.product_id.name_get()[0][1])
|
||||
line_id = sol.create(cr, SUPERUSER_ID, values, context=context)
|
||||
if add_qty:
|
||||
add_qty -= 1
|
||||
|
||||
# compute new quantity
|
||||
if set_qty:
|
||||
quantity = set_qty
|
||||
elif add_qty != None:
|
||||
quantity = sol.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)
|
||||
|
||||
# select linked product
|
||||
option_ids = [line.id for line in so.order_line if line.linked_line_id.id == line_id]
|
||||
|
||||
# Remove zero of negative lines
|
||||
if quantity <= 0:
|
||||
sol.unlink(cr, SUPERUSER_ID, [line_id] + option_ids, context=context)
|
||||
else:
|
||||
# update line
|
||||
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, line_id, context=context)
|
||||
values['product_uom_qty'] = quantity
|
||||
sol.write(cr, SUPERUSER_ID, [line_id], values, context=context)
|
||||
|
||||
# change quantity of linked product
|
||||
if option_ids:
|
||||
sol.write(cr, SUPERUSER_ID, option_ids, {'product_uom_qty': quantity}, context=context)
|
||||
|
||||
return (line_id, quantity)
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="optional_products" inherit_id="website_sale.product" name="Optional Products">
|
||||
<xpath expr="//tr[@id='product_confirmation']" position="after">
|
||||
<tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
|
||||
<t t-set="option_inc" t-value="0"/>
|
||||
<tr class="js_product" t-foreach="optional_product_ids" t-as="product">
|
||||
<td width="100">
|
||||
<input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
|
||||
<span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-left">
|
||||
<strong class="media-heading" t-field="product.name"/>
|
||||
<div class="text-muted" t-field="product.description_sale"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-right">
|
||||
<t t-call="website_sale.variants"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="(website.compute_curency(product.lst_price) - product.price) > 0.1">
|
||||
<span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
|
||||
t-field="product.lst_price"
|
||||
t-field-options='{
|
||||
"widget": "monetary",
|
||||
"from_currency": "website.company_currency_id",
|
||||
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
|
||||
}'/><br/>
|
||||
</t>
|
||||
<span class="oe_price" style="white-space: nowrap;"
|
||||
t-field="product.price"
|
||||
t-field-options='{
|
||||
"widget": "monetary",
|
||||
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
|
||||
}'/>
|
||||
<p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
|
||||
<a href="#" class="js_add"><strong>Add to Cart</strong></a>
|
||||
<span class="js_remove hidden">
|
||||
<span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
|
||||
<a href="#" class="js_remove"><small>Remove from cart</small></a>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_form_view">
|
||||
<field name="name">product.template.product.website.form</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="website_sale.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="accessory_product_ids" position="after">
|
||||
<field name="optional_product_ids" widget="many2many_tags"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
Loading…
Reference in New Issue