[MERGE] trunk-website-al
bzr revid: ddm@openerp.com-20131002085338-8jw3dkqtq842nwhe
@@ -68,8 +68,10 @@
|
||||
<field name="event_id" ref="event.event_0"/>
|
||||
<field name="product_id" ref="event_0_product"/>
|
||||
<field name="deadline" eval="(DateTime.today() + timedelta(60)).strftime('%Y-%m-%d')"/>
|
||||
<field name="price">5000.0</field>
|
||||
<field name="price">1500.0</field>
|
||||
<field name="register_max">10</field>
|
||||
<field name="description_sale">Cathering for breakfast and lunch
|
||||
VIP Parking access</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -97,8 +99,10 @@
|
||||
<field name="event_id" ref="event.event_2"/>
|
||||
<field name="product_id" ref="event_2_product"/>
|
||||
<field name="deadline" eval="(DateTime.today() + timedelta(60)).strftime('%Y-%m-%d')"/>
|
||||
<field name="price">5000.0</field>
|
||||
<field name="price">1500.0</field>
|
||||
<field name="register_max">5</field>
|
||||
<field name="description_sale">Cathering for breakfast and lunch
|
||||
VIP Parking access</field>
|
||||
</record>
|
||||
|
||||
<record id="event_3_ticket_1" model="event.event.ticket">
|
||||
@@ -115,8 +119,10 @@
|
||||
<field name="event_id" ref="event.event_3"/>
|
||||
<field name="product_id" ref="event_3_product"/>
|
||||
<field name="deadline" eval="(DateTime.today() + timedelta(60)).strftime('%Y-%m-%d')"/>
|
||||
<field name="price">5000.0</field>
|
||||
<field name="price">1500.0</field>
|
||||
<field name="register_max">5</field>
|
||||
<field name="description_sale">Cathering for breakfast and lunch
|
||||
VIP Parking access</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import controllers
|
||||
import res_config
|
||||
|
||||
import website
|
||||
import view
|
||||
import models
|
||||
|
||||
@@ -14,7 +14,7 @@ import werkzeug.wrappers
|
||||
from PIL import Image
|
||||
|
||||
import openerp
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import ir_fields
|
||||
import res_config
|
||||
import view
|
||||
import website
|
||||
@@ -0,0 +1,87 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from lxml import etree, html
|
||||
|
||||
from openerp.osv import orm, fields
|
||||
from openerp.tools import ustr
|
||||
|
||||
class converter(orm.Model):
|
||||
_inherit = 'ir.fields.converter'
|
||||
|
||||
def _html_to_integer(self, cr, uid, model, column, value, context=None):
|
||||
return int(value.text_content().strip()), []
|
||||
|
||||
def _html_to_float(self, cr, uid, model, column, value, context=None):
|
||||
return float(value.text_content().strip()), []
|
||||
|
||||
def _html_to_passthrough(self, cr, uid, model, column, value, context=None):
|
||||
return value.text_content().strip(), []
|
||||
|
||||
_html_to_char = _html_to_date = _html_to_datetime = _html_to_passthrough
|
||||
|
||||
def _html_to_text(self, cr, uid, model, column, value, context=None):
|
||||
return value.text_content(), []
|
||||
|
||||
def _html_to_selection(self, cr, uid, model, column, value, context=None):
|
||||
text = value.text_content().strip()
|
||||
|
||||
selection = column.reify(cr, uid, model, column, context=context)
|
||||
for k, v in selection:
|
||||
if isinstance(v, str):
|
||||
v = ustr(v)
|
||||
if text == v:
|
||||
return k, []
|
||||
|
||||
warning = u"No value found for label %s in selection %s" % (text, selection)
|
||||
# FIXME: ?
|
||||
return False, [Warning(warning.encode('utf-8'))]
|
||||
|
||||
def _html_to_many2one(self, cr, uid, model, column, value, context=None):
|
||||
matches = self.pool[column._obj].name_search(
|
||||
cr, uid, name=value.text_content().strip(), context=context)
|
||||
# FIXME: more than one match, error reporting
|
||||
return matches[0][0], []
|
||||
|
||||
def _html_to_html(self, cr, uid, model, column, value, context=None):
|
||||
content = []
|
||||
if value.text: content.append(value.text)
|
||||
content.extend(html.tostring(child)
|
||||
for child in value.iterchildren(tag=etree.Element))
|
||||
return '\n'.join(content), []
|
||||
|
||||
|
||||
class test_converter(orm.Model):
|
||||
_name = 'website.converter.test'
|
||||
|
||||
_columns = {
|
||||
'char': fields.char(),
|
||||
'integer': fields.integer(),
|
||||
'float': fields.float(),
|
||||
'numeric': fields.float(digits=(16, 2)),
|
||||
'many2one': fields.many2one('website.converter.test.sub'),
|
||||
'binary': fields.binary(),
|
||||
'date': fields.date(),
|
||||
'datetime': fields.datetime(),
|
||||
'selection': fields.selection([
|
||||
(1, "réponse A"),
|
||||
(2, "réponse B"),
|
||||
(3, "réponse C"),
|
||||
(4, "réponse D"),
|
||||
]),
|
||||
'selection_str': fields.selection([
|
||||
('A', "Qu'il n'est pas arrivé à Toronto"),
|
||||
('B', "Qu'il était supposé arriver à Toronto"),
|
||||
('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
|
||||
('D', "La réponse D"),
|
||||
], string="Lorsqu'un pancake prend l'avion à destination de Toronto et "
|
||||
"qu'il fait une escale technique à St Claude, on dit:"),
|
||||
'html': fields.html(),
|
||||
'text': fields.text(),
|
||||
}
|
||||
|
||||
|
||||
class test_converter_sub(orm.Model):
|
||||
_name = 'website.converter.test.sub'
|
||||
|
||||
_columns = {
|
||||
'name': fields.char(),
|
||||
}
|
||||
@@ -55,57 +55,19 @@ class view(osv.osv):
|
||||
def extract_embedded_fields(self, cr, uid, arch, context=None):
|
||||
return arch.xpath('//*[@data-oe-model != "ir.ui.view"]')
|
||||
|
||||
def convert_embedded_field(self, cr, uid, el, column,
|
||||
type_override=None, context=None):
|
||||
""" Converts the content of an embedded field to a value acceptable
|
||||
for writing in the column
|
||||
|
||||
:param etree._Element el: embedded field being saved
|
||||
:param fields._column column: column object corresponding to the field
|
||||
:param type type_override: column type to dispatch on instead of the
|
||||
column's actual type (for proxy column types
|
||||
e.g. relateds)
|
||||
:return: converted value
|
||||
"""
|
||||
column_type = type_override or type(column)
|
||||
|
||||
if issubclass(column_type, fields.html):
|
||||
content = []
|
||||
if el.text: content.append(el.text)
|
||||
content.extend(html.tostring(child)
|
||||
for child in el.iterchildren(tag=etree.Element))
|
||||
return '\n'.join(content)
|
||||
elif issubclass(column_type, fields.integer):
|
||||
return int(el.text_content())
|
||||
elif issubclass(column_type, fields.float):
|
||||
return float(el.text_content())
|
||||
elif issubclass(column_type, (fields.char, fields.text,
|
||||
fields.date, fields.datetime)):
|
||||
return el.text_content()
|
||||
# TODO: fields.selection
|
||||
elif issubclass(column_type, fields.many2one):
|
||||
matches = self.pool[column._obj].name_search(
|
||||
cr, uid, name=el.text_content().strip(), context=context)
|
||||
# FIXME: more than one match, error reporting
|
||||
return matches[0][0]
|
||||
elif issubclass(column_type, fields.function):
|
||||
# FIXME: special-case selection as in get_pg_type?
|
||||
return self.convert_embedded_field(
|
||||
cr, uid, el, column,
|
||||
type_override=getattr(fields, column._type),
|
||||
context=context)
|
||||
# TODO?: fields.many2many, fields.one2many
|
||||
# TODO?: fields.reference
|
||||
else:
|
||||
raise TypeError("Un-convertable column type %s" % column_type)
|
||||
|
||||
def save_embedded_field(self, cr, uid, el, context=None):
|
||||
Model = self.pool[el.get('data-oe-model')]
|
||||
field = el.get('data-oe-field')
|
||||
|
||||
column = Model._all_columns[field].column
|
||||
convert = self.pool['ir.fields.converter'].to_field(
|
||||
cr, uid, Model, column, fromtype="html", context=context)
|
||||
value, warnings = convert(el)
|
||||
# FIXME: report error
|
||||
if warnings: return
|
||||
|
||||
Model.write(cr, uid, [int(el.get('data-oe-id'))], {
|
||||
field: self.convert_embedded_field(cr, uid, el, column, context=context)
|
||||
field: value
|
||||
}, context=context)
|
||||
|
||||
def to_field_ref(self, cr, uid, el, context=None):
|
||||
@@ -137,7 +99,8 @@ class view(osv.osv):
|
||||
"""
|
||||
res_id = int(res_id)
|
||||
|
||||
arch_section = html.fromstring(value)
|
||||
arch_section = html.fromstring(
|
||||
value, parser=html.HTMLParser(encoding='utf-8'))
|
||||
|
||||
if xpath is None:
|
||||
# value is an embedded field on its own, not a view section
|
||||
@@ -1,4 +1,4 @@
|
||||
@charset "utf-8";
|
||||
@charset "UTF-8";
|
||||
/* ---- CKEditor Minimal Reset ---- */
|
||||
.navbar.navbar-inverse .cke_chrome {
|
||||
border: none;
|
||||
@@ -167,7 +167,6 @@ table.editorbar-panel td.selected {
|
||||
box-shadow: 0px 10px 10px -10px black inset;
|
||||
z-index: 1010;
|
||||
overflow: hidden;
|
||||
height: 110px;
|
||||
}
|
||||
#oe_snippets:hover {
|
||||
height: auto;
|
||||
@@ -177,16 +176,13 @@ table.editorbar-panel td.selected {
|
||||
overflow-y: auto;
|
||||
}
|
||||
#oe_snippets .nav {
|
||||
padding: 3px 15px;
|
||||
width: 162px;
|
||||
background: #444444;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
height: 108px;
|
||||
}
|
||||
#oe_snippets .nav > li {
|
||||
display: block;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
font-size: 13px;
|
||||
}
|
||||
#oe_snippets .nav > li > a {
|
||||
padding: 2px 10px !important;
|
||||
@@ -194,13 +190,14 @@ table.editorbar-panel td.selected {
|
||||
display: block;
|
||||
}
|
||||
#oe_snippets .pill-content {
|
||||
margin-top: 24px;
|
||||
display: inline-block;
|
||||
height: 110px;
|
||||
white-space: nowrap;
|
||||
padding-left: 166px;
|
||||
}
|
||||
#oe_snippets .pill-content > div {
|
||||
display: inline-block;
|
||||
background: black;
|
||||
padding: 5px;
|
||||
}
|
||||
#oe_snippets .pill-content > div label {
|
||||
width: 44px;
|
||||
@@ -211,23 +208,23 @@ table.editorbar-panel td.selected {
|
||||
#oe_snippets .pill-content > div label div {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
-webkit-transform: translate(-39px, 44px) rotate(-90deg);
|
||||
-moz-transform: translate(-39px, 44px) rotate(-90deg);
|
||||
-o-transform: translate(-39px, 44px) rotate(-90deg);
|
||||
transform: translate(-39px, 44px) rotate(-90deg);
|
||||
-webkit-transform-origin: 50% 50%;
|
||||
-moz-transform-origin: 50% 50%;
|
||||
-ms-transform-origin: 50% 50%;
|
||||
-o-transform-origin: 50% 50%;
|
||||
transform-origin: 50% 50%;
|
||||
-webkit-transform: translate(-39px, 44px);
|
||||
-moz-transform: translate(-39px, 44px);
|
||||
-ms-transform: translate(-39px, 44px);
|
||||
-o-transform: translate(-39px, 44px);
|
||||
transform: translate(-39px, 44px);
|
||||
-webkit-transform-origin: 50% 50% 50%;
|
||||
-moz-transform-origin: 50% 50% 50%;
|
||||
-ms-transform-origin: 50% 50% 50%;
|
||||
-o-transform-origin: 50% 50% 50%;
|
||||
transform-origin: 50% 50% 50%;
|
||||
}
|
||||
|
||||
.oe_snippet {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 108px;
|
||||
height: 108px;
|
||||
border-radius: 3px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin: 1px;
|
||||
margin-top: 0px;
|
||||
position: relative;
|
||||
@@ -243,9 +240,15 @@ table.editorbar-panel td.selected {
|
||||
height: 100%;
|
||||
background: transparent;
|
||||
color: white;
|
||||
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.95);
|
||||
position: relative;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_title {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_img {
|
||||
box-shadow: inset 0px 0px 0px 3px #333333;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail span, .oe_snippet .oe_snippet_thumbnail div {
|
||||
line-height: 18px;
|
||||
}
|
||||
@@ -256,7 +259,6 @@ table.editorbar-panel td.selected {
|
||||
#oe_snippets .oe_snippet_thumbnail {
|
||||
background: #747474;
|
||||
background-image: radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
|
||||
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.07) inset;
|
||||
}
|
||||
|
||||
/* ---- SNIPPETS DROP ZONES ---- */
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
@charset "utf-8"
|
||||
|
||||
@import "compass/css3"
|
||||
|
||||
/* ---- CKEditor Minimal Reset ---- */
|
||||
|
||||
.navbar.navbar-inverse .cke_chrome
|
||||
@@ -145,33 +147,30 @@ table.editorbar-panel
|
||||
box-shadow: 0px 10px 10px -10px black inset
|
||||
z-index: 1010
|
||||
overflow: hidden
|
||||
height: 110px
|
||||
&:hover
|
||||
height: auto
|
||||
.scroll
|
||||
white-space: nowrap
|
||||
overflow-y: auto
|
||||
.nav
|
||||
padding: 3px 15px
|
||||
width: 162px
|
||||
background: #444444
|
||||
> li
|
||||
display: block
|
||||
display: inline-block
|
||||
float: none
|
||||
font-size: 13px
|
||||
> a
|
||||
padding: 2px 10px !important
|
||||
width: 100%
|
||||
display: block
|
||||
position: fixed
|
||||
z-index: 1
|
||||
height: 108px
|
||||
.pill-content
|
||||
margin-top: 24px
|
||||
display: inline-block
|
||||
height: 110px
|
||||
white-space: nowrap
|
||||
padding-left: 166px
|
||||
> div
|
||||
display: inline-block
|
||||
background: rgb(0,0,0)
|
||||
padding: 5px
|
||||
label
|
||||
width: 44px
|
||||
height: 100%
|
||||
@@ -180,22 +179,14 @@ table.editorbar-panel
|
||||
div
|
||||
width: 100px
|
||||
text-align: center
|
||||
-webkit-transform: translate(-39px, 44px) rotate(-90deg)
|
||||
-moz-transform: translate(-39px, 44px) rotate(-90deg)
|
||||
-o-transform: translate(-39px, 44px) rotate(-90deg)
|
||||
transform: translate(-39px, 44px) rotate(-90deg)
|
||||
-webkit-transform-origin: 50% 50%
|
||||
-moz-transform-origin: 50% 50%
|
||||
-ms-transform-origin: 50% 50%
|
||||
-o-transform-origin: 50% 50%
|
||||
transform-origin: 50% 50%
|
||||
@include transform( translate(-39px, 44px) , rotate(-90deg) )
|
||||
@include transform-origin(50% 50%)
|
||||
|
||||
.oe_snippet
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
width: 108px
|
||||
height: 108px
|
||||
border-radius: 3px
|
||||
width: 100px
|
||||
height: 100px
|
||||
margin: 1px
|
||||
margin-top: 0px
|
||||
position: relative
|
||||
@@ -204,15 +195,18 @@ table.editorbar-panel
|
||||
user-select: none
|
||||
cursor: move
|
||||
pointer-events: none
|
||||
|
||||
.oe_snippet_thumbnail
|
||||
pointer-events: auto
|
||||
text-align: center
|
||||
height: 100%
|
||||
background: transparent
|
||||
color: white
|
||||
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.95)
|
||||
position: relative
|
||||
.oe_snippet_thumbnail_title
|
||||
font-size: 12px
|
||||
display: block
|
||||
.oe_snippet_thumbnail_img
|
||||
box-shadow: inset 0px 0px 0px 3px #333333
|
||||
span, div
|
||||
line-height: 18px
|
||||
& > :not(.oe_snippet_thumbnail)
|
||||
@@ -221,7 +215,6 @@ table.editorbar-panel
|
||||
#oe_snippets .oe_snippet_thumbnail
|
||||
background: rgb(116, 116, 116)
|
||||
background-image: radial-gradient(rgba(0,0,0,0.25),rgba(0,0,0,0.4))
|
||||
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.07) inset
|
||||
|
||||
/* ---- SNIPPETS DROP ZONES ---- */
|
||||
|
||||
|
||||
@@ -367,6 +367,25 @@ ul.nav-stacked > li > a {
|
||||
}
|
||||
|
||||
/* ---- PUBLISH ---- */
|
||||
a[data-publish] {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
a[data-publish] .css_unpublish, a[data-publish] .css_publish, a[data-publish] .css_unpublished, a[data-publish] .css_published {
|
||||
display: none;
|
||||
}
|
||||
a[data-publish][data-publish='off'] .css_unpublished, a[data-publish][data-publish='off']:hover .css_publish {
|
||||
display: inline;
|
||||
}
|
||||
a[data-publish][data-publish='off']:hover .css_unpublished {
|
||||
display: none;
|
||||
}
|
||||
a[data-publish][data-publish='on'] .css_published, a[data-publish][data-publish='on']:hover .css_unpublish {
|
||||
display: inline;
|
||||
}
|
||||
a[data-publish][data-publish='on']:hover .css_published {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropdown .css_unpublish, .dropdown .css_publish {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -283,6 +283,20 @@ ul.nav-stacked > li > a
|
||||
text-transform: uppercase
|
||||
|
||||
/* ---- PUBLISH ---- */
|
||||
a[data-publish]
|
||||
text-decoration: none !important
|
||||
.css_unpublish, .css_publish, .css_unpublished, .css_published
|
||||
display: none
|
||||
&[data-publish='off']
|
||||
.css_unpublished, &:hover .css_publish
|
||||
display: inline
|
||||
&:hover .css_unpublished
|
||||
display: none
|
||||
&[data-publish='on']
|
||||
.css_published, &:hover .css_unpublish
|
||||
display: inline
|
||||
&:hover .css_published
|
||||
display: none
|
||||
|
||||
.dropdown .css_unpublish, .dropdown .css_publish
|
||||
display: none
|
||||
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 26 KiB |
@@ -18,7 +18,7 @@
|
||||
return new website.editor.LinkDialog(editor).appendTo(document.body);
|
||||
}
|
||||
function image_dialog(editor) {
|
||||
return new website.editor.ImageDialog(editor).appendTo(document.body);
|
||||
return new website.editor.RTEImageDialog(editor).appendTo(document.body);
|
||||
}
|
||||
|
||||
if (website.is_editable) {
|
||||
@@ -673,6 +673,23 @@
|
||||
});
|
||||
},
|
||||
});
|
||||
/**
|
||||
* ImageDialog widget. Lets users change an image, including uploading a
|
||||
* new image in OpenERP or selecting the image style (if supported by
|
||||
* the caller).
|
||||
*
|
||||
* Initialized as usual, but the caller can hook into two events:
|
||||
*
|
||||
* @event start({url, style}) called during dialog initialization and
|
||||
* opening, the handler can *set* the ``url``
|
||||
* and ``style`` properties on its parameter
|
||||
* to provide these as default values to the
|
||||
* dialog
|
||||
* @event save({url, style}) called during dialog finalization, the handler
|
||||
* is provided with the image url and style
|
||||
* selected by the users (or possibly the ones
|
||||
* originally passed in)
|
||||
*/
|
||||
website.editor.ImageDialog = website.editor.Dialog.extend({
|
||||
template: 'website.editor.dialog.image',
|
||||
events: _.extend({}, website.editor.Dialog.prototype.events, {
|
||||
@@ -685,47 +702,30 @@
|
||||
'click a[href=#existing]': 'browse_existing',
|
||||
'change select.image-style': 'preview_image',
|
||||
}),
|
||||
start: function () {
|
||||
var selection = this.editor.getSelection();
|
||||
var el = selection && selection.getSelectedElement();
|
||||
this.element = null;
|
||||
|
||||
var $select = this.$('.image-style');
|
||||
var $options = $select.children();
|
||||
start: function () {
|
||||
var $options = this.$('.image-style').children();
|
||||
this.image_styles = $options.map(function () { return this.value; }).get();
|
||||
|
||||
if (el && el.is('img')) {
|
||||
this.element = el;
|
||||
_(this.image_styles).each(function (style) {
|
||||
if (el.hasClass(style)) {
|
||||
$select.val(style);
|
||||
}
|
||||
});
|
||||
// set_image must follow setup of image style
|
||||
this.set_image(el.getAttribute('src'));
|
||||
var o = { url: null, style: null, };
|
||||
// avoid typos, prevent addition of new properties to the object
|
||||
Object.preventExtensions(o);
|
||||
this.trigger('start', o);
|
||||
|
||||
if (o.url) {
|
||||
if (o.style) {
|
||||
this.$('.image-style').val(o.style);
|
||||
}
|
||||
this.set_image(o.url);
|
||||
}
|
||||
|
||||
return this._super();
|
||||
},
|
||||
save: function () {
|
||||
var url = this.$('input.url').val();
|
||||
var style = this.$('.image-style').val();
|
||||
var element, editor = this.editor;
|
||||
if (!(element = this.element)) {
|
||||
element = editor.document.createElement('img');
|
||||
// focus event handler interactions between bootstrap (modal)
|
||||
// and ckeditor (RTE) lead to blowing the stack in Safari and
|
||||
// Chrome (but not FF) when this is done synchronously =>
|
||||
// defer insertion so modal has been hidden & destroyed before
|
||||
// it happens
|
||||
setTimeout(function () {
|
||||
editor.insertElement(element);
|
||||
}, 0);
|
||||
}
|
||||
element.setAttribute('src', url);
|
||||
$(element.$).removeClass(this.image_styles.join(' '));
|
||||
if (style) { element.addClass(style); }
|
||||
|
||||
this.trigger('save', {
|
||||
url: this.$('input.url').val(),
|
||||
style: this.$('.image-style').val(),
|
||||
});
|
||||
return this._super();
|
||||
},
|
||||
|
||||
@@ -769,12 +769,53 @@
|
||||
.removeClass(this.image_styles.join(' '))
|
||||
.addClass(this.$('select.image-style').val());
|
||||
},
|
||||
|
||||
browse_existing: function (e) {
|
||||
e.preventDefault();
|
||||
new website.editor.ExistingImageDialog(this).appendTo(document.body);
|
||||
},
|
||||
});
|
||||
website.editor.RTEImageDialog = website.editor.ImageDialog.extend({
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.on('start', this, this.proxy('started'));
|
||||
this.on('save', this, this.proxy('saved'));
|
||||
},
|
||||
started: function (holder) {
|
||||
var selection = this.editor.getSelection();
|
||||
var el = selection && selection.getSelectedElement();
|
||||
this.element = null;
|
||||
|
||||
if (el && el.is('img')) {
|
||||
this.element = el;
|
||||
_(this.image_styles).each(function (style) {
|
||||
if (el.hasClass(style)) {
|
||||
holder.style = style;
|
||||
}
|
||||
});
|
||||
holder.url = el.getAttribute('src');
|
||||
}
|
||||
},
|
||||
saved: function (data) {
|
||||
var element, editor = this.editor;
|
||||
if (!(element = this.element)) {
|
||||
element = editor.document.createElement('img');
|
||||
// focus event handler interactions between bootstrap (modal)
|
||||
// and ckeditor (RTE) lead to blowing the stack in Safari and
|
||||
// Chrome (but not FF) when this is done synchronously =>
|
||||
// defer insertion so modal has been hidden & destroyed before
|
||||
// it happens
|
||||
setTimeout(function () {
|
||||
editor.insertElement(element);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
var style = data.style;
|
||||
element.setAttribute('src', data.url);
|
||||
$(element.$).removeClass(this.image_styles.join(' '));
|
||||
if (style) { element.addClass(style); }
|
||||
},
|
||||
});
|
||||
|
||||
var IMAGES_PER_ROW = 6;
|
||||
var IMAGES_ROWS = 4;
|
||||
@@ -893,7 +934,7 @@
|
||||
if (m.attributeName !== 'class') { return true; }
|
||||
|
||||
// find out what classes were added or removed
|
||||
var oldClasses = m.oldValue.split(/\s+/);
|
||||
var oldClasses = (m.oldValue || '').split(/\s+/);
|
||||
var newClasses = m.target.className.split(/\s+/);
|
||||
var change = _.union(_.difference(oldClasses, newClasses),
|
||||
_.difference(newClasses, oldClasses));
|
||||
@@ -911,6 +952,7 @@
|
||||
while (node && !$(node).hasClass('oe_editable')) {
|
||||
node = node.parentNode;
|
||||
}
|
||||
$(m.target).trigger('node_changed');
|
||||
return node;
|
||||
})
|
||||
.compact()
|
||||
|
||||
@@ -117,9 +117,29 @@
|
||||
};
|
||||
|
||||
dom_ready.then(function () {
|
||||
|
||||
/* ----- PUBLISHING STUFF ---- */
|
||||
$('[data-publish]:has(.js_publish)').each(function () {
|
||||
var $pub = $("[data-publish]", this);
|
||||
if($pub.size())
|
||||
$(this).attr("data-publish", $pub.attr("data-publish"));
|
||||
else
|
||||
$(this).removeAttr("data-publish");
|
||||
});
|
||||
|
||||
$('[data-publish]:has(.js_publish_management)').each(function () {
|
||||
$(this).attr("data-publish", $(".js_publish_management .btn-success", this).size() ? "on" : 'off');
|
||||
$(this).attr("data-publish", $(".js_publish_management .btn-success", this).size() ? "on" : 'off');
|
||||
});
|
||||
|
||||
$(document).on('click', '.js_publish', function (e) {
|
||||
e.preventDefault();
|
||||
var $data = $(":first", this).parents("[data-publish]");
|
||||
$data.attr("data-publish", $data.first().attr("data-publish") == 'off' ? 'on' : 'off');
|
||||
openerp.jsonRpc('/website/publish', 'call', {'id': $(this).data('id'), 'object': $(this).data('object')})
|
||||
.then(function (result) {
|
||||
$data.attr("data-publish", +result ? 'on' : 'off');
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.js_publish_management .js_publish_btn', function (e) {
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
start: function () {
|
||||
var self = this;
|
||||
$("[data-oe-model]").on('click', function (event) {
|
||||
var tag = event.srcElement.tagName.toLowerCase();
|
||||
var $this = $(event.srcElement);
|
||||
var tag = $this[0].tagName.toLowerCase();
|
||||
if (!(tag === 'a' || tag === "button") && !$this.parents("a, button").length) {
|
||||
self.$('[data-action="edit"]').parent().effect('bounce', {distance: 18, times: 5}, 250);
|
||||
}
|
||||
@@ -158,23 +158,29 @@
|
||||
var $pill = self.$(".pill-content");
|
||||
var padding = parseInt($pill.css("padding-left"));
|
||||
var $scroll = this.$(".scroll");
|
||||
|
||||
$scroll.scroll(function () {
|
||||
|
||||
$scroll.scroll(function () {
|
||||
$pill.find("> div").each(function () {
|
||||
/*
|
||||
if ($(this).position().left <= padding) {
|
||||
$ul.find("> li").removeClass('active');
|
||||
$ul.find("a[href='#" + $(this).attr("id") + "']").parent("li").addClass('active');
|
||||
}
|
||||
}*/
|
||||
});
|
||||
});
|
||||
|
||||
$ul.find("a").click(function (event) {
|
||||
event.preventDefault();
|
||||
$scroll.scrollLeft( $scroll.scrollLeft() + $($(event.currentTarget).attr("href")).position().left - padding );
|
||||
$pill.find("> div").hide();
|
||||
$pill.find( $(event.currentTarget).attr('href')).show();
|
||||
$ul.find('> li').removeClass('active');
|
||||
$(event.currentTarget).parent().addClass('active');
|
||||
return false;
|
||||
});
|
||||
|
||||
$pill.css("padding-right", self.$el.outerWidth() - padding + 10 - $pill.find("> div:last").outerWidth());
|
||||
// $pill.css("padding-right", self.$el.outerWidth() - padding + 10 - $pill.find("> div:last").outerWidth());
|
||||
$pill.find("> div").hide();
|
||||
$pill.find("div:first").show();
|
||||
$ul.find("> li:first").addClass('active');
|
||||
},
|
||||
cover_target: function ($el, $target){
|
||||
@@ -389,7 +395,7 @@
|
||||
},
|
||||
stop: function(){
|
||||
$('.oe_drop_zone').droppable('destroy').remove();
|
||||
if (!dropped) {
|
||||
if (!dropped && self.$modal.find('input:not(:checked)').length) {
|
||||
self.$modal.modal('toggle');
|
||||
}
|
||||
},
|
||||
@@ -573,7 +579,6 @@
|
||||
onBlurEdit : function () {},
|
||||
});
|
||||
|
||||
|
||||
website.snippet.editorRegistry = {};
|
||||
website.snippet.Editor = openerp.Class.extend({
|
||||
init: function (parent, dom) {
|
||||
@@ -700,6 +705,7 @@
|
||||
this.$overlay.on('click', '.oe_snippet_clone', function () {
|
||||
var $clone = self.$target.clone(false);
|
||||
self.$target.after($clone);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
@@ -793,6 +799,50 @@
|
||||
onBlur : function () {
|
||||
this.$overlay.removeClass('oe_active');
|
||||
},
|
||||
|
||||
change_background: function (bg, ul_options) {
|
||||
var self = this;
|
||||
var $ul = this.$editor.find(ul_options);
|
||||
var bg_value = (typeof bg == 'string' ? self.$target.find(bg) : $(bg)).css("background-image").replace(/url\(['"]*|['"]*\)/g, "");
|
||||
|
||||
// select in ul options
|
||||
$ul.find("li").removeClass("active");
|
||||
var selected = $ul.find('[data-value="' + bg_value + '"], [data-value="' + bg_value.replace(/.*:\/\/[^\/]+/, '') + '"]');
|
||||
selected.addClass('active');
|
||||
if (!selected.length) {
|
||||
$ul.find('.oe_custom_bg b').html(bg_value);
|
||||
}
|
||||
|
||||
// bind envent on options
|
||||
var $li = $ul.find("li");
|
||||
$li.on('click', function (event) {
|
||||
if ($(this).data("value")) {
|
||||
$li.removeClass("active");
|
||||
$(this).addClass("active");
|
||||
self.$editor.find('input').val("");
|
||||
} else {
|
||||
var editor = new website.editor.ImageDialog();
|
||||
editor.on('start', self, function (o) {o.url = bg_value;});
|
||||
editor.on('save', self, function (o) {
|
||||
var $bg = typeof bg == 'string' ? self.$target.find(bg) : $(bg);
|
||||
$bg.css("background-image", "url(" + o.url + ")");
|
||||
});
|
||||
editor.appendTo($('body'));
|
||||
}
|
||||
})
|
||||
.on('mouseover', function (event) {
|
||||
if ($(this).data("value")) {
|
||||
var src = $(this).data("value");
|
||||
var $bg = typeof bg == 'string' ? self.$target.find(bg) : $(bg);
|
||||
$bg.css("background-image", "url(" + src + ")");
|
||||
}
|
||||
})
|
||||
.on('mouseout', function (event) {
|
||||
var src = $ul.find('li.active').data("value");
|
||||
var $bg = typeof bg == 'string' ? self.$target.find(bg) : $(bg);
|
||||
$bg.css("background-image", "url(" + src + ")");
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -863,13 +913,13 @@
|
||||
|
||||
var change = false;
|
||||
if (dd > (2*resize[1][next] + resize[1][current])/3) {
|
||||
self.$target.attr("class",self.$target.attr("class").replace(regClass, ''));
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][next]);
|
||||
current = next;
|
||||
change = true;
|
||||
}
|
||||
if (prev != current && dd < (2*resize[1][prev] + resize[1][current])/3) {
|
||||
self.$target.attr("class",self.$target.attr("class").replace(regClass, ''));
|
||||
self.$target.attr("class", (self.$target.attr("class")||'').replace(regClass, ''));
|
||||
self.$target.addClass(resize[0][prev]);
|
||||
current = prev;
|
||||
change = true;
|
||||
@@ -991,8 +1041,9 @@
|
||||
this.$editor.find(".js_add").on('click', _.bind(this.on_add, this));
|
||||
this.$editor.find(".js_remove").on('click', _.bind(this.on_remove, this));
|
||||
|
||||
this.change_background();
|
||||
this.change_background(".item.active", 'ul[name="carousel-background"]');
|
||||
this.change_style();
|
||||
this.set_options_style();
|
||||
this.change_size();
|
||||
},
|
||||
on_add: function (e) {
|
||||
@@ -1014,48 +1065,12 @@
|
||||
.find('.item.active').remove().end()
|
||||
.find('.item:first').addClass('active');
|
||||
this.$target.carousel(0);
|
||||
this.set_options_background();
|
||||
this.set_options_style();
|
||||
}
|
||||
if (nb <= 1) {
|
||||
this.$target.find('.carousel-control').addClass("hidden");
|
||||
}
|
||||
},
|
||||
onFocus: function () {
|
||||
this.set_options_background();
|
||||
this.set_options_style();
|
||||
this._super();
|
||||
},
|
||||
set_options_background: function () {
|
||||
var $image = this.$target.find('.carousel-inner .item.active > img');
|
||||
var bg = $image.attr('src');
|
||||
var $ul = this.$editor.find('ul[name="carousel-background"]');
|
||||
$ul.find("li").removeClass("active");
|
||||
var selected = $ul.find('[data-value="' + bg + '"], [data-value="' + bg.replace(/.*:\/\/[^\/]+/, '') + '"]')
|
||||
.addClass('active').length;
|
||||
this.$editor.find('.oe_custom_bg b').html(selected ? "" : bg);
|
||||
},
|
||||
change_background: function () {
|
||||
var self = this;
|
||||
var $ul = this.$editor.find('ul[name="carousel-background"]');
|
||||
var $li = $ul.find("li");
|
||||
|
||||
$li.on('click', function (event) {
|
||||
$li.removeClass("active");
|
||||
$(this).addClass("active");
|
||||
self.$editor.find('input').val("");
|
||||
})
|
||||
.on('mouseover', function (event) {
|
||||
if ($(this).data("value")) {
|
||||
self.$target.find('.carousel-inner .item.active > img')
|
||||
.attr('src', $(this).data("value"));
|
||||
}
|
||||
})
|
||||
.on('mouseout', function (event) {
|
||||
self.$target.find('.carousel-inner .item.active > img')
|
||||
.attr('src', $ul.find('li.active').data("value"));
|
||||
});
|
||||
},
|
||||
set_options_style: function () {
|
||||
var style = false;
|
||||
var $el = this.$target.find('.carousel-inner .item.active');
|
||||
@@ -1124,50 +1139,7 @@
|
||||
website.snippet.editorRegistry.parallax = website.snippet.editorRegistry.resize.extend({
|
||||
start : function () {
|
||||
this._super();
|
||||
this.change_background();
|
||||
},
|
||||
onFocus: function () {
|
||||
this.$imagebg = $("<img/>");
|
||||
this.$imagebg.prependTo(this.$target);
|
||||
this.set_options_background();
|
||||
this._super();
|
||||
},
|
||||
onBlur : function () {
|
||||
this._super();
|
||||
this.$imagebg.remove();
|
||||
},
|
||||
set_options_background: function () {
|
||||
var bg = this.$target.css("background-image").replace(/url\(|\)/g, "");
|
||||
this.$imagebg.attr("src", bg);
|
||||
|
||||
var $ul = this.$editor.find('ul[name="parallax-background"]');
|
||||
$ul.find("li").removeClass("active");
|
||||
var selected = $ul.find('[data-value="' + bg + '"], [data-value="' + bg.replace(/.*:\/\/[^\/]+/, '') + '"]')
|
||||
.addClass('active').length;
|
||||
this.$editor.find('.oe_custom_bg b').html(selected ? "" : bg);
|
||||
},
|
||||
change_background: function () {
|
||||
var self = this;
|
||||
var $ul = this.$editor.find('ul[name="parallax-background"]');
|
||||
var $li = $ul.find("li");
|
||||
|
||||
$li.on('click', function (event) {
|
||||
$li.removeClass("active");
|
||||
$(this).addClass("active");
|
||||
self.$editor.find('input').val("");
|
||||
})
|
||||
.on('mouseover', function (event) {
|
||||
if ($(this).data("value")) {
|
||||
var src = $(this).data("value");
|
||||
self.$imagebg.attr('src', src);
|
||||
self.$target.css("background-image", "url(" + src + ")");
|
||||
}
|
||||
})
|
||||
.on('mouseout', function (event) {
|
||||
var src = $ul.find('li.active').data("value");
|
||||
self.$imagebg.attr('src', src);
|
||||
self.$target.css("background-image", "url(" + src + ")");
|
||||
});
|
||||
this.change_background(this.$target, 'ul[name="parallax-background"]');
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -63,10 +63,10 @@
|
||||
<li><a href="#snippet_effect">Effects</a></li>
|
||||
</ul>
|
||||
<div class="pill-content">
|
||||
<div id="snippet_structure"><label><div>Structure</div></label></div>
|
||||
<div id="snippet_content"><label><div>Content</div></label></div>
|
||||
<div id="snippet_business"><label><div>Business</div></label></div>
|
||||
<div id="snippet_effect"><label><div>Effects</div></label></div>
|
||||
<div id="snippet_structure"></div>
|
||||
<div id="snippet_content"></div>
|
||||
<div id="snippet_business"></div>
|
||||
<div id="snippet_effect"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -160,17 +160,14 @@
|
||||
|
||||
<!-- thumbnail to display inside the bottom widget list editor -->
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img src="/website/static/src/img/banner/color_splash.jpg" style="position: absolute; left: 0; top: 40px; max-width: 100%"/>
|
||||
<img src="/website/static/src/img/banner/banner_picture.png" style="position: absolute; left: 10px; top: 52px; max-width: 25%"/>
|
||||
<span style="position: absolute; top: 50px; right: 10px;">Banner</span>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_banner.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Banner</span>
|
||||
</div>
|
||||
|
||||
<!-- body to insert after drag and drop thumbnail -->
|
||||
<div id="myCarousel" class="oe_snippet_body carousel slide oe_medium mb32" data-interval="10000">
|
||||
<!-- Carousel items -->
|
||||
<div class="carousel-inner">
|
||||
<div class="item image_text active">
|
||||
<img src="/website/static/src/img/banner/color_splash.jpg" width="100%" height="100%"/>
|
||||
<div class="item image_text active" style="background-image: url('/website/static/src/img/banner/color_splash.jpg')">
|
||||
<div class="container">
|
||||
<div class="carousel-caption content">
|
||||
<h2>Set Your Banner Title</h2>
|
||||
@@ -197,7 +194,9 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.well" data-snippet-id='well' data-category='content' data-selector-siblings='p, h1, h2, h3, blockquote'>
|
||||
<div class='oe_snippet_thumbnail'>Well</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<span class="oe_snippet_thumbnail_title">Well</span>
|
||||
</div>
|
||||
<div class="oe_snippet_body well">
|
||||
Manage your sales funnel with no effort with OpenERP CRM. Attract
|
||||
leads, follow-up on phone calls and meetings. Analyse the quality
|
||||
@@ -206,7 +205,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.quote" data-snippet-id='quote' data-category='content' data-selector-siblings='p, h1, h2, h3, blockquote'>
|
||||
<div class='oe_snippet_thumbnail'>Quote</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quote.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Quote</span>
|
||||
</div>
|
||||
<blockquote class="oe_snippet_body">
|
||||
<p>
|
||||
OpenERP provides essential platform for our project management.
|
||||
@@ -217,7 +219,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.panel" data-snippet-id='panel' data-category='content' data-selector-siblings='p, h1, h2, h3, blockquote'>
|
||||
<div class='oe_snippet_thumbnail'>Panel</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_panel.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Panel</span>
|
||||
</div>
|
||||
<div class="oe_snippet_body panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">OpenERP Features</h3>
|
||||
@@ -233,13 +238,16 @@
|
||||
|
||||
<div t-name="website.snippets.surprise" data-snippet-id='vomify' data-category='content' data-selector-children='.oe_structure'>
|
||||
<div class="oe_snippet_body" style="height: 0; position: absolute;"></div>
|
||||
<div class='oe_snippet_thumbnail' style='background-image:radial-gradient(red,orange,yellow,green,blue);'>Surprise!</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_surprise.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Surprise!</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.text-image" data-snippet-id='text-image' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<span style="position: absolute; top: 50px; left: 5px;">Text-Image</span>
|
||||
<img src="/website/static/src/img/banner/banner_picture.png" style="position: absolute; right: 5px; top: 50px; max-width: 28%"/>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text-Image</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
@@ -268,8 +276,8 @@
|
||||
|
||||
<div t-name="website.snippets.image-text" data-snippet-id='image-text' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img src="/website/static/src/img/banner/banner_picture.png" style="position: absolute; left: 5px; top: 50px; max-width: 28%"/>
|
||||
<span style="position: absolute; top: 50px; right: 5px;">Image-Text</span>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_text.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Image-Text</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
@@ -297,15 +305,8 @@
|
||||
|
||||
<div t-name="website.snippets.jumbotron" data-snippet-id='jumbotron' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<div style="position: absolute; top: 30px; background-color: #eee; width: 100%; padding: 8px 0 6px 4px;">
|
||||
<div style="color: #000; display: block; text-align: left;">
|
||||
Jumbotron
|
||||
<div style="font-size: 9px; line-height: 9px; text-shadow: none;">
|
||||
Jumbotron Sub-title
|
||||
<br/><span class="label label-primary">Contact us</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Jumbotron</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body jumbotron mt16 mb16">
|
||||
<div class="container">
|
||||
@@ -324,21 +325,8 @@
|
||||
|
||||
<div t-name="website.snippets.text-block" data-snippet-id='text-block' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<div style="position: absolute; top: 26px; left: 5px; width: 94%;">
|
||||
<div style="display: block;">
|
||||
Text Block
|
||||
<div style="text-shadow: none;font-size: 9px; line-height: 9px; color: #bbb;margin-bottom: 5px;">
|
||||
Jumbotron Sub-title
|
||||
</div>
|
||||
<div style="text-shadow: none;font-size: 6px; line-height: 6px; text-align: left;">
|
||||
Organize projects around your own processes. Work
|
||||
on tasks and issues using the kanban view, schedule
|
||||
tasks using the gantt chart and control deadlines
|
||||
in the calendar view. Every project may have it's
|
||||
own stages allowing teams to optimize their job.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_block.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Text Block</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body mt16 mb16">
|
||||
<div class="container">
|
||||
@@ -370,7 +358,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.title" data-snippet-id='title' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class="oe_snippet_thumbnail">Title</div>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_title.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Title</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@@ -385,8 +376,8 @@
|
||||
|
||||
<div t-name="website.snippets.hr" data-snippet-id='hr' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<hr style="position: absolute;top: 61px;margin: 0;width: 100%;border-color: #888;"/>
|
||||
<div style="position: absolute;width: 100%;top: 51px;">Separator</div>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Separator</span>
|
||||
</div>
|
||||
<hr class="oe_snippet_body"/>
|
||||
</div>
|
||||
@@ -394,17 +385,8 @@
|
||||
|
||||
<div t-name="website.snippets.big-picture" data-snippet-id='big-picture' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<div style="position: absolute; top: 8px; left: 5px; width: 94%;">
|
||||
<div style="display: block;">
|
||||
Big Picture
|
||||
<img src="/website/static/src/img/big_picture.png" style="max-width: 100%"/>
|
||||
<div style="text-shadow: none;font-size: 6px; line-height: 6px; margin: 5px 10px">
|
||||
OpenERP's Point of Sale introduces a super clean
|
||||
interface with no installation required.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_big_picture.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Big Picture</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body dark mt16 mb16">
|
||||
<div class="container">
|
||||
@@ -436,23 +418,8 @@
|
||||
|
||||
<div t-name="website.snippets.three-columns" data-snippet-id='three-columns' data-category='structure' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class="oe_snippet_thumbnail">
|
||||
<div style="padding-top: 22px;">
|
||||
Three Columns
|
||||
<div class="clearfix" style="font-size: 6px;text-shadow: none;">
|
||||
<div class="pull-left" style="width: 33%;line-height: 6px;">
|
||||
<img src="/website/static/src/img/china_thumb.jpg" style="max-width: 90%;"/>
|
||||
Post job offers and keep track of each application received.
|
||||
</div>
|
||||
<div class="pull-left" style="width: 33%;line-height: 6px;">
|
||||
<img src="/website/static/src/img/desert_thumb.jpg" style="max-width: 90%;"/>
|
||||
Break down information silos. Share knowledge and best practices amongst all employees.
|
||||
</div>
|
||||
<div class="pull-left" style="width: 33%; line-height: 6px;">
|
||||
<img src="/website/static/src/img/deers_thumb.jpg" style="max-width: 90%;"/>
|
||||
The agenda of each employee is updated accordingly.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_three_columns.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Three Columns</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body mt16 mb16">
|
||||
<div class="container">
|
||||
@@ -503,7 +470,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.portfolio" data-snippet-id='portfolio' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>Portfolio</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_portfolio.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Portfolio</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@@ -533,21 +503,8 @@
|
||||
|
||||
<div t-name="website.snippets.image-gallery" data-snippet-id='image-gallery' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<div style="padding-top: 22px;">
|
||||
Image Gallery
|
||||
<div class="clearfix">
|
||||
<div style="float: right; width: 56px;height: 30px;">
|
||||
<img src="/website/static/src/img/china_thumb.jpg" style="max-width: 24px;"/>
|
||||
<img src="/website/static/src/img/deers_thumb.jpg" style="max-width: 24px;"/>
|
||||
<img src="/website/static/src/img/desert_thumb.jpg" style="max-width: 24px;"/>
|
||||
<img src="/website/static/src/img/china_thumb.jpg" style="max-width: 24px;"/>
|
||||
</div>
|
||||
<img src="/website/static/src/img/desert.jpg" style="float-left; width: 50px;height: 31px;margin-top: 4px;"/>
|
||||
<img src="/website/static/src/img/deers_thumb.jpg" style="float-left; max-width: 24px;"/>
|
||||
<img src="/website/static/src/img/landscape.jpg" style="float-left; max-width: 50px;"/>
|
||||
<img src="/website/static/src/img/china_thumb.jpg" style="max-width: 24px;"/>
|
||||
</div>
|
||||
</div>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_image_gallery.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Image Gallery</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
@@ -586,7 +543,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.pricing" data-snippet-id='pricing' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>Comparisons</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_comparison.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Comparisons</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@@ -688,7 +648,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.cta" data-snippet-id='cta' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>Buttons</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_button.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Button</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body dark">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@@ -702,7 +665,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.faq" data-snippet-id='faq' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>FAQ</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_faq.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">FAQ</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body">
|
||||
<div class="container">
|
||||
<h2 class="page-header">
|
||||
@@ -745,7 +711,10 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.references" data-snippet-id='references' data-category='business' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>References</div>
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_references.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">References</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body mb32 mt16">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@@ -796,25 +765,11 @@
|
||||
</div>
|
||||
|
||||
<div t-name="website.snippets.parallax" data-snippet-id='parallax' data-category='effect' data-selector-children='.oe_structure, [data-oe-type=html]'>
|
||||
<div class='oe_snippet_thumbnail'>Parallax</div>
|
||||
|
||||
<li class="oe_snippet_options dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Background</a>
|
||||
<ul class="dropdown-menu" name="parallax-background">
|
||||
<li data-value="/website/static/src/img/parallax/parallax_bg.jpg"><a>Parallax</a></li>
|
||||
<li data-value="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-value="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-value="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-value="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-value="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
<li data-value="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-value="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-value="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li class="oe_custom_bg"><b></b></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<section class="oe_snippet_body parallax_full oe_structure" style="background-image: url(/website/static/src/img/parallax/parallax_bg.jpg)">
|
||||
<div class='oe_snippet_thumbnail'>
|
||||
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_parallax.png"/>
|
||||
<span class="oe_snippet_thumbnail_title">Parallax</span>
|
||||
</div>
|
||||
<section class="oe_snippet_body parallax_full oe_structure">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12 mt128 mb32">
|
||||
@@ -828,7 +783,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</templates>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import test_views
|
||||
import test_views, test_converter
|
||||
|
||||
checks = [ test_views ]
|
||||
checks = [ test_views, test_converter, ]
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from collections import namedtuple
|
||||
from functools import partial
|
||||
from xml.dom.minidom import getDOMImplementation
|
||||
|
||||
from lxml import etree, html
|
||||
|
||||
from openerp.tests import common
|
||||
from openerp.tools import qweb
|
||||
import unittest2
|
||||
|
||||
renderer = qweb.QWebXml()
|
||||
impl = getDOMImplementation()
|
||||
document = impl.createDocument(None, None, None)
|
||||
|
||||
Request = namedtuple('Request', 'cr uid registry')
|
||||
class RegistryProxy(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
def __getitem__(self, name):
|
||||
return self.func(name)
|
||||
|
||||
class TestConvertBack(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestConvertBack, self).setUp()
|
||||
|
||||
self.Converter = self.registry('ir.fields.converter')
|
||||
|
||||
def field_rountrip_result(self, field, value, expected):
|
||||
model = 'website.converter.test'
|
||||
Model = self.registry(model)
|
||||
id = Model.create(
|
||||
self.cr, self.uid, {
|
||||
field: value
|
||||
})
|
||||
[record] = Model.browse(self.cr, self.uid, [id])
|
||||
|
||||
e = document.createElement('span')
|
||||
field_value = 'record.%s' % field
|
||||
e.setAttribute('t-field', field_value)
|
||||
|
||||
rendered = renderer.render_tag_field(
|
||||
e, {'field': field_value}, '', {
|
||||
'record': record,
|
||||
'request': Request(self.cr, self.uid, RegistryProxy( self.registry)),
|
||||
})
|
||||
element = html.fromstring(
|
||||
rendered, parser=html.HTMLParser(encoding='utf-8'))
|
||||
|
||||
column = Model._all_columns[field].column
|
||||
|
||||
from_html = self.Converter.to_field(
|
||||
self.cr, self.uid, model, column, 'html')
|
||||
|
||||
value_back, warnings = from_html(element)
|
||||
self.assertEqual(warnings, [])
|
||||
|
||||
if isinstance(expected, str):
|
||||
expected = expected.decode('utf-8')
|
||||
self.assertEqual(value_back, expected)
|
||||
|
||||
def field_roundtrip(self, field, value):
|
||||
self.field_rountrip_result(field, value, value)
|
||||
|
||||
def test_integer(self):
|
||||
self.field_roundtrip('integer', 42)
|
||||
|
||||
def test_float(self):
|
||||
self.field_roundtrip('float', 42.567890)
|
||||
|
||||
def test_numeric(self):
|
||||
self.field_roundtrip('numeric', 42.77)
|
||||
|
||||
def test_char(self):
|
||||
self.field_roundtrip('char', "foo bar")
|
||||
|
||||
self.field_roundtrip('char', "ⒸⓄⓇⒼⒺ")
|
||||
|
||||
def test_m2o(self):
|
||||
Sub = self.registry('website.converter.test.sub')
|
||||
sub = partial(Sub.create, self.cr, self.uid)
|
||||
ids = [
|
||||
sub({'name': "Foo"}),
|
||||
sub({'name': "Bar"}),
|
||||
sub({'name': "Baz"}),
|
||||
]
|
||||
|
||||
self.field_rountrip_result(
|
||||
'many2one',
|
||||
ids[2],
|
||||
ids[2])
|
||||
|
||||
def test_selection(self):
|
||||
self.field_roundtrip('selection', 3)
|
||||
|
||||
def test_selection_str(self):
|
||||
self.field_roundtrip('selection_str', 'B')
|
||||
|
||||
def test_text(self):
|
||||
self.field_roundtrip('text', """
|
||||
You must obey the dance commander
|
||||
Givin' out the order for fun
|
||||
You must obey the dance commander
|
||||
You know that he's the only one
|
||||
Who gives the orders here,
|
||||
Alright
|
||||
Who gives the orders here,
|
||||
Alright
|
||||
|
||||
It would be awesome
|
||||
If we could dance-a
|
||||
It would be awesome, yeah
|
||||
Let's take the chance-a
|
||||
It would be awesome, yeah
|
||||
Let's start the show
|
||||
Because you never know
|
||||
You never know
|
||||
You never know until you go
|
||||
""")
|
||||
@@ -364,22 +364,37 @@
|
||||
<template id="publish_management">
|
||||
<t t-if="editable" t-ignore="true">
|
||||
<div t-attf-class="dropdown js_publish_management pull-right #{object.id and object.website_published and 'css_publish' or 'css_unpublish'}" t-att-data-id="object.id" t-att-data-object="object._name">
|
||||
<a t-attf-class="btn btn-sm btn-#{object.id and object.website_published and 'success' or 'default'}" t-att-id="'dopprod-%s' % object.id" role="button" data-toggle="dropdown">Options <span class="caret"></span></a>
|
||||
<a t-attf-class="btn btn-xs btn-#{object.id and object.website_published and 'success' or 'default'}" t-att-id="'dopprod-%s' % object.id" role="button" data-toggle="dropdown">Options <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % object.id">
|
||||
<t t-raw="0"/>
|
||||
<li>
|
||||
<a href="#" class="js_publish_btn css_unpublish">Unpublish</a>
|
||||
<a href="#" class="js_publish_btn css_publish">Publish</a>
|
||||
</li>
|
||||
<li class="divider"/>
|
||||
<li>
|
||||
<a t-att-href="'/admin/#model=%s&id=%s' % (object._name, object.id)">Edit</a>
|
||||
</li>
|
||||
<t t-if="publish_edit">
|
||||
<li class="divider"/>
|
||||
<li>
|
||||
<a t-att-href="'/admin/#model=%s&id=%s' % (object._name, object.id)">Edit</a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="publish_short">
|
||||
<t t-if="editable" t-ignore="true">
|
||||
<a href="#" t-att-data-id="object.id" t-att-data-object="object._name"
|
||||
t-att-data-publish="object.id and object.website_published and 'on' or 'off'"
|
||||
class="pull-right js_publish">
|
||||
<span t-attf-class="text-success css_publish glyphicon glyphicon-ok"></span>
|
||||
<span t-attf-class="text-danger css_unpublish glyphicon glyphicon-remove-circle"></span>
|
||||
<span t-attf-class="text-muted css_published glyphicon glyphicon-ok"></span>
|
||||
<span t-attf-class="text-muted css_unpublished glyphicon glyphicon-remove-circle"></span>
|
||||
</a>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="kanban">
|
||||
<t t-set="step"><t t-esc="step or 0"/></t>
|
||||
<t t-set="scope"><t t-esc="scope or 0"/></t>
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
</group>
|
||||
<group string="Others Info">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="default_lang_id" widget="selection"/>
|
||||
<field name="language_ids" widget="many2many_tags"/>
|
||||
<field name="default_lang_id" widget="selection"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
from openerp.tools.translate import _
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
|
||||
@@ -29,7 +29,7 @@ import simplejson
|
||||
import werkzeug
|
||||
|
||||
|
||||
class website_mail(http.Controller):
|
||||
class WebsiteBlog(http.Controller):
|
||||
_category_post_per_page = 6
|
||||
_post_comment_per_page = 6
|
||||
|
||||
@@ -75,7 +75,8 @@ class website_mail(http.Controller):
|
||||
blog_post_obj = request.registry['blog.post']
|
||||
tag_obj = request.registry['blog.tag']
|
||||
category_obj = request.registry['blog.category']
|
||||
user_obj = request.registry['res.users']
|
||||
|
||||
current_user = request.registry['res.users'].browse(cr, uid, uid, context=context)
|
||||
|
||||
tag = None
|
||||
category = None
|
||||
@@ -103,6 +104,9 @@ class website_mail(http.Controller):
|
||||
blog_posts = category.blog_post_ids
|
||||
elif tag:
|
||||
blog_posts = tag.blog_post_ids
|
||||
else:
|
||||
blog_post_ids = blog_post_obj.search(cr, uid, [], context=context)
|
||||
blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context)
|
||||
|
||||
if blog_posts:
|
||||
pager = request.website.pager(
|
||||
@@ -143,6 +147,7 @@ class website_mail(http.Controller):
|
||||
'blog_posts': blog_posts,
|
||||
'pager': pager,
|
||||
'nav_list': nav,
|
||||
'current_user': current_user,
|
||||
'unable_editor': post.get('unable_editor')
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,27 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Options: Blog Post Summary: hide author -->
|
||||
<template id="view_blog_post_short_author" inherit_option_id="website_blog.view_blog_post_short" name="Hide Authors">
|
||||
<xpath expr="//span[@class='icon-user']" position="attributes">
|
||||
<attribute name="class">hidden</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Options: Blog Post Summary: show category -->
|
||||
<template id="view_blog_post_short_category" inherit_option_id="website_blog.view_blog_post_short" name="Show Blog Name">
|
||||
<xpath expr="//span[@class='icon-user']" position="after">
|
||||
<span class="icon-folder-open"> In <span t-field="blog_post.category_id"/> &nbsp;</span>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Blog Post Complete -->
|
||||
<template id="view_blog_post" name="Blog Post">
|
||||
<div>
|
||||
<t t-call="website.publish_management"><t t-set="object" t-value="blog_post"/></t>
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="blog_post"/>
|
||||
<t t-set="publish_edit" t-value="true"/>
|
||||
</t>
|
||||
</div><div class="clearfix"/>
|
||||
|
||||
<h1 class="text-center" t-field="blog_post.name"/>
|
||||
@@ -75,9 +86,11 @@
|
||||
<ul class="media-list">
|
||||
<li t-foreach="blog_post.website_message_ids" t-as="message" class="media">
|
||||
<div class="media-body">
|
||||
<img class="media-object pull-left" t-att-src="'/website/image?model=res.users&field=image_small&id='+str(message.author_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||
<img class="media-object pull-left" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(message.author_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||
<div class="media-body">
|
||||
<t t-call="website.publish_management"><t t-set="object" t-value="message"/></t>
|
||||
<t t-call="website.publish_short">
|
||||
<t t-set="object" t-value="message"/>
|
||||
</t>
|
||||
<h5 class="media-heading">
|
||||
<span t-field="message.author_id"/> <small>on <span t-field="message.date"/></small>
|
||||
</h5>
|
||||
@@ -87,12 +100,11 @@
|
||||
</li>
|
||||
</ul>
|
||||
<section groups="group_website_blog_reply" class="mb32">
|
||||
<t t-call="website_mail.follow"><t t-set="object" t-value="blog_post"/></t>
|
||||
<h4>Leave a Comment</h4>
|
||||
<form id="comment" t-attf-action="/blog/#{blog_post.category_id.id}/#{blog_post.id}/post#post"
|
||||
method="POST">
|
||||
<img class="img pull-left img-rounded" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(user_id.partner_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||
<div class="pull-left" style="width: 75%%">
|
||||
<div class="pull-left mb32" style="width: 75%%">
|
||||
<textarea rows="3" class="form-control" placeholder="Write a comment..."></textarea>
|
||||
<button type="submit" class="btn btn-danger mt8">Post</button>
|
||||
</div>
|
||||
@@ -100,12 +112,19 @@
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<!-- Options: Blog Post: hide author -->
|
||||
<template id="view_blog_post_author" inherit_option_id="website_blog.view_blog_post" name="Hide Authors">
|
||||
<xpath expr="//span[@class='icon-user']" position="attributes">
|
||||
<attribute name="class">hidden</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Options: Blog Post: show category -->
|
||||
<template id="view_blog_post_show_category" inherit_option_id="website_blog.view_blog_post" name="Show Blog Name">
|
||||
<xpath expr="//span[@class='icon-user']" position="after">
|
||||
<span class="icon-folder-open"> In <span t-field="blog_post.category_id"/> &nbsp;</span>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Page -->
|
||||
<template id="index" name="Blogs" page="True">
|
||||
@@ -135,6 +154,7 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Option: right column -->
|
||||
<template id="blog_right_column" inherit_id="website_blog.index" inherit_option_id="website_blog.index" name="Right Column">
|
||||
<xpath expr="//div[@class='row']" position="inside">
|
||||
<div class="col-sm-3 hidden-xs col-lg-offset-1 mb32" id="right_column">
|
||||
@@ -146,7 +166,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option: archives -->
|
||||
<!-- Option: Right Column: archives -->
|
||||
<template id="blog_history" inherit_id="website_blog.blog_right_column" inherit_option_id="website_blog.blog_right_column" name="Archives">
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<section>
|
||||
@@ -168,6 +188,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option: Right Column: about us -->
|
||||
<template id="blog_aboutus" inherit_option_id="website_blog.blog_right_column" inherit_id="website_blog.blog_right_column" name="About" priority="4">
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<section class="mb16">
|
||||
@@ -183,26 +204,36 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option: Right Column: follow us -->
|
||||
<template id="blog_followus" inherit_option_id="website_blog.blog_right_column" inherit_id="website_blog.blog_right_column" name="Follow us" priority="2">
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<section class="mb16">
|
||||
<h4>Follow us</h4>
|
||||
<p class="text-muted">
|
||||
Participate on our social stream.
|
||||
</p>
|
||||
<t t-call="website_mail.follow"><t t-set="object" t-value="category"/></t>
|
||||
<h2>
|
||||
<a t-att-href="website.social_facebook" t-if="website.social_facebook"><i class="icon-facebook-sign"/></a>
|
||||
<a t-att-href="website.social_twitter" t-if="website.social_twitter"><i class="icon-twitter-sign"/></a>
|
||||
<a t-att-href="website.social_linkedin" t-if="website.social_linkedin"><i class="icon-linkedin-sign"/></a>
|
||||
<a t-att-href="website.social_youtube" t-if="website.social_youtube"><i class="icon-youtube-sign"/></a>
|
||||
<a t-att-href="website.social_googleplus" t-if="website.social_googleplus"><i class="icon-google-plus-sign"/></a>
|
||||
<a t-att-href="website.social_github" t-if="website.social_github"><i class="icon-github-sign"/></a>
|
||||
</h2>
|
||||
<h4>Follow us</h4>
|
||||
<t t-if="category">
|
||||
<p class="text-muted">
|
||||
Be notified of new blog posts in <t t-esc="category.name"/>
|
||||
</p>
|
||||
<t t-call="website_mail.follow">
|
||||
<t t-set="email" t-value="current_user.email"/>
|
||||
<t t-set="object" t-value="category"/>
|
||||
</t>
|
||||
</t>
|
||||
<p class="text-muted">
|
||||
Participate on our social stream.
|
||||
</p>
|
||||
<h2>
|
||||
<a t-att-href="website.social_facebook" t-if="website.social_facebook"><i class="icon-facebook-sign"/></a>
|
||||
<a t-att-href="website.social_twitter" t-if="website.social_twitter"><i class="icon-twitter-sign"/></a>
|
||||
<a t-att-href="website.social_linkedin" t-if="website.social_linkedin"><i class="icon-linkedin-sign"/></a>
|
||||
<a t-att-href="website.social_youtube" t-if="website.social_youtube"><i class="icon-youtube-sign"/></a>
|
||||
<a t-att-href="website.social_googleplus" t-if="website.social_googleplus"><i class="icon-google-plus-sign"/></a>
|
||||
<a t-att-href="website.social_github" t-if="website.social_github"><i class="icon-github-sign"/></a>
|
||||
</h2>
|
||||
</section>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option: Right Column: categories + category in blog post -->
|
||||
<template id="blog_categories" inherit_option_id="website_blog.blog_right_column" name="Other Blogs" priority="6">
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<section class="mb16">
|
||||
|
||||
@@ -76,9 +76,14 @@ class BlogPost(osv.Model):
|
||||
shorten=True,
|
||||
max_length=self._shorten_max_char,
|
||||
expand_options={
|
||||
'oe_expand_href': '/blog/%d/%d' % (page.category_id.id, page.id),
|
||||
'oe_expand_a_class': 'oe_mail_expand btn btn-info'
|
||||
}, br=True
|
||||
'oe_expand_container_tag': 'div',
|
||||
'oe_expand_container_class': 'oe_mail_expand text-center',
|
||||
'oe_expand_container_content': '',
|
||||
'oe_expand_a_href': '/blog/%d/%d' % (page.category_id.id, page.id),
|
||||
'oe_expand_a_class': 'oe_mail_expand btn btn-info',
|
||||
'oe_expand_separator_node': 'br',
|
||||
},
|
||||
protect_sections=True,
|
||||
)
|
||||
except Exception:
|
||||
body_short = False
|
||||
|
||||
@@ -4,7 +4,7 @@ import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
import urllib
|
||||
|
||||
class website_contract(http.Controller):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
|
||||
from urllib import quote_plus
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
import urllib
|
||||
|
||||
class website_crm_partner_assign(http.Controller):
|
||||
|
||||
@@ -24,7 +24,7 @@ from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons import website_sale
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
@@ -64,7 +64,7 @@ class event(osv.osv):
|
||||
class sale_order_line(osv.osv):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
def _recalculate_product_values(self, cr, uid, ids, product_id=None, context=None):
|
||||
def _recalculate_product_values(self, cr, uid, ids, product_id=0, context=None):
|
||||
if not ids:
|
||||
return super(sale_order_line, self)._recalculate_product_values(cr, uid, ids, product_id, context=context)
|
||||
|
||||
|
||||
@@ -13,14 +13,6 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="event_website_sale_mycart" inherit_id="website_sale.mycart">
|
||||
<xpath expr="//small[@class='text-error']" position="replace">
|
||||
<t t-if="(not line.event_id or line.event_ticket_id and line.event_ticket_id.price == line.product_id.lst_price)">
|
||||
<small class="text-error" style="text-decoration: line-through;"><t t-esc="line.product_id.lst_price" /> €</small>
|
||||
</t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Page -->
|
||||
<template id="index" name="Events" page="True">
|
||||
<t t-call="website.layout">
|
||||
@@ -156,15 +148,18 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ticket Type</th>
|
||||
<th>Sales End</th>
|
||||
<th>Price</th>
|
||||
<th style="min-width: 100px">Sales End</th>
|
||||
<th style="min-width: 100px">Price</th>
|
||||
<th></th>
|
||||
<th>Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="event_id.event_ticket_ids" t-as="ticket">
|
||||
<td><span t-field="ticket.name"/></td>
|
||||
<td>
|
||||
<div t-field="ticket.name"/>
|
||||
<div><small t-field="ticket.product_id.description_sale"/></div>
|
||||
</td>
|
||||
<td><span t-field="ticket.deadline"/></td>
|
||||
<td><span t-field="ticket.price"/></td>
|
||||
<td>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
from datetime import datetime
|
||||
|
||||
class google_map(http.Controller):
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
|
||||
class website_hr(http.Controller):
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
|
||||
|
||||
class WebsiteMail(http.Controller):
|
||||
@@ -32,10 +32,10 @@ class WebsiteMail(http.Controller):
|
||||
partner_obj = request.registry['res.partner']
|
||||
user_obj = request.registry['res.users']
|
||||
partner_ids = []
|
||||
if request.context['is_public_user'] and email:
|
||||
if request.context['is_public_user'] and email and email != u'false': # post contains stringified booleans
|
||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", email)], context=request.context)
|
||||
if not partner_ids:
|
||||
partner_ids = [partner_obj.create(request.cr, SUPERUSER_ID, {"email": email, "name": email}, request.context)]
|
||||
partner_ids = [partner_obj.name_create(request.cr, SUPERUSER_ID, email, request.context)]
|
||||
else:
|
||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id]
|
||||
return partner_ids
|
||||
|
||||
@@ -32,6 +32,10 @@ class MailMessage(osv.Model):
|
||||
),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'website_published': True,
|
||||
}
|
||||
|
||||
def _search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False, access_rights_uid=None):
|
||||
""" Override that adds specific access rights of mail.message, to restrict
|
||||
|
||||
@@ -12,12 +12,14 @@ $(document).ready(function () {
|
||||
$(document).on('click', '.js_follow', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $data = $(":first", this).parents("[data-follow]");
|
||||
var $email = $data.first().siblings(".js_follow_email");
|
||||
var message_is_follower = $data.first().attr("data-follow");
|
||||
$data.attr("data-follow", message_is_follower == 'off' ? 'on' : 'off');
|
||||
$.post('/website_mail/follow', {
|
||||
'id': $(this).data('id'),
|
||||
'object': $(this).data('object'),
|
||||
'message_is_follower': message_is_follower,
|
||||
'email': $email && $email.val() || false,
|
||||
}, function (result) {
|
||||
$data.attr("data-follow", + result ? 'on' : 'off');
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.website_blog.tests import test_controllers
|
||||
from openerp.addons.website_mail.tests import test_controllers
|
||||
|
||||
checks = [
|
||||
test_controllers,
|
||||
|
||||
@@ -20,10 +20,23 @@
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.mail.tests.test_mail_base import TestMailBase
|
||||
from openerp.addons.website_mail.controllers.main import WebsiteMail
|
||||
from openerp.tools import mute_logger, email_split
|
||||
|
||||
|
||||
class TestControllers(TestMailBase):
|
||||
|
||||
def test_00(self):
|
||||
def test_00_subscribe(self):
|
||||
# from openerp.addons.web.http import request
|
||||
# print request
|
||||
|
||||
cr, uid = self.cr, self.uid
|
||||
# context = {
|
||||
# 'is_public_user': True,
|
||||
# }
|
||||
# email = 'Marcel Dupuis <marcel.dupuis@example.com>'
|
||||
# website_mail = WebsiteMail()
|
||||
|
||||
# pid = website_mail._find_or_create_partner(email, context)
|
||||
# partner = self.res_partner.browse(cr, uid, pid)
|
||||
# print partner.name, partner.email
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
<a href="#" t-att-data-id="object.id" t-att-data-object="object._name" t-att-data-follow="object.id and object.message_is_follower and 'on' or 'off'" class="pull-right js_follow" t-if="editable" t-ignore="true">
|
||||
<span t-attf-class="label label-success css_follow">Follow</span>
|
||||
<span t-attf-class="label label-danger css_unfollow">Unfollow</span>
|
||||
<span t-attf-class="label label-success css_followed">Followed</span>
|
||||
<span t-attf-class="label label-danger css_unfollowed">Unfollowed</span>
|
||||
<span t-attf-class="label label-success css_followed">Following</span>
|
||||
<span t-attf-class="label label-danger css_unfollowed">Not Following</span>
|
||||
</a>
|
||||
<input type="email" name="email" class="js_follow_email css_unfollowed_email"
|
||||
t-att-value="email"
|
||||
t-att-placeholder="email or 'Email Address'"/>
|
||||
</template>
|
||||
|
||||
<template id="website.layout" inherit_id="website.layout">
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
import controllers
|
||||
import website_membership
|
||||
import models
|
||||
@@ -4,7 +4,7 @@ import openerp
|
||||
from openerp.addons.web import http
|
||||
from openerp.tools.translate import _
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
import urllib
|
||||
|
||||
class website_crm_partner_assign(http.Controller):
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
import res_partner
|
||||
@@ -2,9 +2,13 @@
|
||||
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
class res_partner(osv.osv):
|
||||
|
||||
class WebsiteResPartner(osv.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
_columns = {
|
||||
'website_published': fields.boolean(
|
||||
'Publish', help="Publish on the website"),
|
||||
'website_description': fields.html('Description for the website'),
|
||||
'website_short_description': fields.text('Sort description for the website'),
|
||||
}
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
from openerp.osv import osv
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website import website
|
||||
from openerp.addons.website.models import website
|
||||
import random
|
||||
|
||||
def get_order(order_id=None):
|
||||
@@ -12,19 +12,19 @@ def get_order(order_id=None):
|
||||
# check if order allready exists
|
||||
if order_id:
|
||||
try:
|
||||
order = order_obj.browse(request.cr, SUPERUSER_ID, order_id, request.context)
|
||||
order = order_obj.browse(request.cr, SUPERUSER_ID, order_id, context=request.context)
|
||||
order.pricelist_id
|
||||
except:
|
||||
order_id = None
|
||||
if not order_id:
|
||||
fields = [k for k, v in order_obj._columns.items()]
|
||||
order_value = order_obj.default_get(request.cr, SUPERUSER_ID, fields, request.context)
|
||||
order_value = order_obj.default_get(request.cr, SUPERUSER_ID, fields, context=request.context)
|
||||
if request.httprequest.session.get('ecommerce_pricelist'):
|
||||
order_value['pricelist_id'] = request.httprequest.session['ecommerce_pricelist']
|
||||
order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, SUPERUSER_ID, request.uid, request.context).partner_id.id
|
||||
order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, SUPERUSER_ID, request.uid, context=request.context).partner_id.id
|
||||
order_value.update(order_obj.onchange_partner_id(request.cr, SUPERUSER_ID, [], order_value['partner_id'], context=request.context)['value'])
|
||||
order_id = order_obj.create(request.cr, SUPERUSER_ID, order_value, request.context)
|
||||
order = order_obj.browse(request.cr, SUPERUSER_ID, order_id, request.context)
|
||||
order_id = order_obj.create(request.cr, SUPERUSER_ID, order_value, context=request.context)
|
||||
order = order_obj.browse(request.cr, SUPERUSER_ID, order_id, context=request.context)
|
||||
request.httprequest.session['ecommerce_order_id'] = order.id
|
||||
|
||||
return order_obj.browse(request.cr, SUPERUSER_ID, order_id,
|
||||
@@ -176,7 +176,7 @@ class Ecommerce(http.Controller):
|
||||
fill_hole_products = []
|
||||
# search for checking of access rules and keep order
|
||||
fill_hole = [id for id in fill_hole if id in product_obj.search(request.cr, request.uid, [("id", 'in', fill_hole)], context=request.context)]
|
||||
for product in product_obj.browse(request.cr, SUPERUSER_ID, fill_hole, context=request.context):
|
||||
for product in product_obj.browse(request.cr, request.uid, fill_hole, context=request.context):
|
||||
fill_hole_products.append(product)
|
||||
fill_hole_products.reverse()
|
||||
|
||||
@@ -200,7 +200,7 @@ class Ecommerce(http.Controller):
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
# search for checking of access rules and keep order
|
||||
product_ids = [id for id in product_ids if id in product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context)]
|
||||
return product_obj.browse(request.cr, SUPERUSER_ID, product_ids, context=request.context)
|
||||
return product_obj.browse(request.cr, request.uid, product_ids, context=request.context)
|
||||
|
||||
@website.route(['/shop/', '/shop/category/<cat_id>/', '/shop/category/<cat_id>/page/<int:page>/', '/shop/page/<int:page>/'], type='http', auth="public", multilang=True)
|
||||
def category(self, cat_id=0, page=0, **post):
|
||||
@@ -250,26 +250,24 @@ class Ecommerce(http.Controller):
|
||||
}
|
||||
return request.website.render("website_sale.products", values)
|
||||
|
||||
@website.route(['/shop/product/<product_id>/'], type='http', auth="public", multilang=True)
|
||||
@website.route(['/shop/product/<int:product_id>/'], type='http', auth="public", multilang=True)
|
||||
def product(self, cat_id=0, product_id=0, **post):
|
||||
|
||||
if 'promo' in post:
|
||||
self.change_pricelist(post.get('promo'))
|
||||
|
||||
product_id = product_id and int(product_id) or 0
|
||||
product_obj = request.registry.get('product.template')
|
||||
category_obj = request.registry.get('product.public.category')
|
||||
|
||||
category_ids = category_obj.search(request.cr, request.uid, [(1, '=', 1)], context=request.context)
|
||||
category_list = category_obj.name_get(request.cr, request.uid, category_ids, request.context)
|
||||
category_list = category_obj.name_get(request.cr, request.uid, category_ids, context=request.context)
|
||||
category_list = sorted(category_list, key=lambda category: category[1])
|
||||
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
|
||||
category = None
|
||||
if post.get('category_id') and int(post.get('category_id')):
|
||||
category = category_obj.browse(request.cr, request.uid, int(post.get('category_id')), context=request.context)
|
||||
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
product = product_obj.browse(request.cr, request.uid, product_id, context=request.context)
|
||||
|
||||
values = {
|
||||
@@ -282,7 +280,7 @@ class Ecommerce(http.Controller):
|
||||
}
|
||||
return request.website.render("website_sale.product", values)
|
||||
|
||||
@website.route(['/shop/add_product/', '/shop/category/<cat_id>/add_product/'], type='http', auth="public", multilang=True)
|
||||
@website.route(['/shop/add_product/', '/shop/category/<int:cat_id>/add_product/'], type='http', auth="public", multilang=True)
|
||||
def add_product(self, cat_id=0, **post):
|
||||
product_id = request.registry.get('product.product').create(request.cr, request.uid,
|
||||
{'name': 'New Product', 'public_categ_id': cat_id}, request.context)
|
||||
@@ -320,13 +318,11 @@ class Ecommerce(http.Controller):
|
||||
def add_product_to_cart(self, product_id=0, order_line_id=0, number=1, set_number=-1):
|
||||
order_line_obj = request.registry.get('sale.order.line')
|
||||
|
||||
product_id = product_id and int(product_id) or 0
|
||||
|
||||
order = get_current_order()
|
||||
if not order:
|
||||
order = get_order()
|
||||
|
||||
context = dict(request.context, pricelist=self.get_pricelist())
|
||||
request.context = dict(request.context, pricelist=self.get_pricelist())
|
||||
|
||||
quantity = 0
|
||||
|
||||
@@ -339,9 +335,9 @@ class Ecommerce(http.Controller):
|
||||
else:
|
||||
domain += [('product_id', '=', product_id)]
|
||||
|
||||
order_line_ids = order_line_obj.search(request.cr, SUPERUSER_ID, domain, context=context)
|
||||
order_line_ids = order_line_obj.search(request.cr, SUPERUSER_ID, domain, context=request.context)
|
||||
if order_line_ids:
|
||||
order_line = order_line_obj.read(request.cr, SUPERUSER_ID, order_line_ids, [], context=context)[0]
|
||||
order_line = order_line_obj.read(request.cr, SUPERUSER_ID, order_line_ids, [], context=request.context)[0]
|
||||
if not product_id:
|
||||
product_id = order_line['product_id'][0]
|
||||
if set_number >= 0:
|
||||
@@ -352,11 +348,11 @@ class Ecommerce(http.Controller):
|
||||
quantity = 0
|
||||
else:
|
||||
fields = [k for k, v in order_line_obj._columns.items()]
|
||||
values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields, context=context)
|
||||
values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields, context=request.context)
|
||||
quantity = 1
|
||||
|
||||
# change and record value
|
||||
vals = order_line_obj._recalculate_product_values(request.cr, request.uid, order_line_ids, product_id, context=context)
|
||||
vals = order_line_obj._recalculate_product_values(request.cr, request.uid, order_line_ids, product_id, context=request.context)
|
||||
values.update(vals)
|
||||
|
||||
values['product_uom_qty'] = quantity
|
||||
@@ -364,13 +360,13 @@ class Ecommerce(http.Controller):
|
||||
values['order_id'] = order.id
|
||||
|
||||
if order_line_ids:
|
||||
order_line_obj.write(request.cr, SUPERUSER_ID, order_line_ids, values, context=context)
|
||||
order_line_obj.write(request.cr, SUPERUSER_ID, order_line_ids, values, context=request.context)
|
||||
if not quantity:
|
||||
order_line_obj.unlink(request.cr, SUPERUSER_ID, order_line_ids, context=context)
|
||||
order_line_obj.unlink(request.cr, SUPERUSER_ID, order_line_ids, context=request.context)
|
||||
else:
|
||||
#values['name'] = "website order"
|
||||
order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, values, context=context)
|
||||
order.write({'order_line': [(4, order_line_id)]}, context=context)
|
||||
order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, values, context=request.context)
|
||||
order.write({'order_line': [(4, order_line_id)]}, context=request.context)
|
||||
|
||||
return [quantity, order.get_total_quantity()]
|
||||
|
||||
@@ -395,6 +391,7 @@ class Ecommerce(http.Controller):
|
||||
suggested_products.append(suggested_ids.pop(index))
|
||||
|
||||
values = {
|
||||
'int': int,
|
||||
'get_categories': self.get_categories,
|
||||
'suggested_products': prod_obj.browse(request.cr, request.uid, suggested_products, request.context),
|
||||
}
|
||||
@@ -402,7 +399,7 @@ class Ecommerce(http.Controller):
|
||||
|
||||
@website.route(['/shop/<path:path>/add_cart/', '/shop/add_cart/'], type='http', auth="public", multilang=True)
|
||||
def add_cart(self, path=None, product_id=None, order_line_id=None, remove=None, **kw):
|
||||
self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, number=(remove and -1 or 1))
|
||||
self.add_product_to_cart(product_id=product_id and int(product_id), order_line_id=order_line_id and int(order_line_id), number=(remove and -1 or 1))
|
||||
return request.redirect("/shop/mycart/")
|
||||
|
||||
@website.route(['/shop/add_cart_json/'], type='json', auth="public")
|
||||
@@ -415,7 +412,7 @@ class Ecommerce(http.Controller):
|
||||
|
||||
@website.route(['/shop/checkout/'], type='http', auth="public", multilang=True)
|
||||
def checkout(self, **post):
|
||||
classic_fields = ["name", "phone", "fax", "email", "street", "city", "state_id", "zip"]
|
||||
classic_fields = ["name", "phone", "email", "street", "city", "state_id", "zip"]
|
||||
rel_fields = ['country_id', 'state_id']
|
||||
|
||||
order = get_current_order()
|
||||
@@ -488,7 +485,6 @@ class Ecommerce(http.Controller):
|
||||
company_id = partner_obj.create(request.cr, SUPERUSER_ID, {'name': post['company'], 'is_company': True}, request.context)
|
||||
|
||||
partner_value = {
|
||||
'fax': post['fax'],
|
||||
'phone': post['phone'],
|
||||
'zip': post['zip'],
|
||||
'email': post['email'],
|
||||
@@ -508,7 +504,6 @@ class Ecommerce(http.Controller):
|
||||
shipping_id = None
|
||||
if post.get('shipping_different'):
|
||||
shipping_value = {
|
||||
'fax': post['shipping_fax'],
|
||||
'phone': post['shipping_phone'],
|
||||
'zip': post['shipping_zip'],
|
||||
'street': post['shipping_street'],
|
||||
@@ -570,14 +565,14 @@ class Ecommerce(http.Controller):
|
||||
def change_sequence(self, id, top):
|
||||
product_obj = request.registry.get('product.template')
|
||||
if top:
|
||||
product_obj.set_sequence_top(request.cr, request.uid, [id], request.context)
|
||||
product_obj.set_sequence_top(request.cr, request.uid, [id], context=request.context)
|
||||
else:
|
||||
product_obj.set_sequence_bottom(request.cr, request.uid, [id], request.context)
|
||||
product_obj.set_sequence_bottom(request.cr, request.uid, [id], context=request.context)
|
||||
|
||||
@website.route(['/shop/change_styles/'], type='json', auth="public")
|
||||
def change_styles(self, id, style_id):
|
||||
product_obj = request.registry.get('product.template')
|
||||
product = product_obj.browse(request.cr, request.uid, id, request.context)
|
||||
product = product_obj.browse(request.cr, request.uid, id, context=request.context)
|
||||
|
||||
remove = []
|
||||
active = False
|
||||
@@ -587,14 +582,11 @@ class Ecommerce(http.Controller):
|
||||
active = True
|
||||
break
|
||||
|
||||
style = request.registry.get('website.product.style').browse(request.cr, request.uid, style_id, request.context)
|
||||
style = request.registry.get('website.product.style').browse(request.cr, request.uid, style_id, context=request.context)
|
||||
|
||||
if remove:
|
||||
print "remove", remove
|
||||
product.write({'website_style_ids': [(3, rid) for rid in remove]})
|
||||
|
||||
if not active:
|
||||
print "add", style.id
|
||||
product.write({'website_style_ids': [(4, style.id)]})
|
||||
|
||||
return not active
|
||||
@@ -602,7 +594,7 @@ class Ecommerce(http.Controller):
|
||||
@website.route(['/shop/change_size/'], type='json', auth="public")
|
||||
def change_size(self, id, x, y):
|
||||
product_obj = request.registry.get('product.template')
|
||||
product = product_obj.browse(request.cr, request.uid, id, request.context)
|
||||
product = product_obj.browse(request.cr, request.uid, id, context=request.context)
|
||||
return product.write({'website_size_x': x, 'website_size_y': y})
|
||||
|
||||
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_product_product_public,product.product.public,product.model_product_product,base.group_public,1,0,0,0
|
||||
access_product_template_public,product.template.public,product.model_product_template,base.group_public,1,0,0,0
|
||||
access_point_of_sale_category_public,product.category.public,product.model_product_public_category,base.group_public,1,0,0,0
|
||||
access_product_category_,product.category,product.model_product_category,base.group_public,1,0,0,0
|
||||
access_product_category_public,product.category.public,product.model_product_public_category,base.group_public,1,0,0,0
|
||||
access_product_pricelist_version_public,product.pricelist.version,product.model_product_pricelist_version,base.group_public,1,0,0,0
|
||||
access_product_product_price_type_public,product.price.type,product.model_product_price_type,base.group_public,1,0,0,0
|
||||
|
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 138 KiB |
@@ -15,8 +15,11 @@
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
OpenERP e-Commerce is unlike anything you have ever seen before.
|
||||
It's at the same time full-featured, integrated with your
|
||||
management software, fully customizable and super easy.
|
||||
Get an awesome catalog of products and great product description
|
||||
pages.
|
||||
</p><p>
|
||||
It's full-featured, integrated with your management software,
|
||||
fully customizable and super easy.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start?app=website_sale" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> online store</a>
|
||||
@@ -43,7 +46,7 @@
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img oe_centered">
|
||||
<img class="oe_picture" src="website_sale_product.png">
|
||||
<img class="oe_picture oe_screenshot" src="website_sale_product.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,18 +57,18 @@
|
||||
<h2 class="oe_slogan">Increase Your Revenue Per Order</h2>
|
||||
<h3 class="oe_slogan">Do you want fries with that?</h3>
|
||||
<div class="oe_span6">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="suggested.png">
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Use the built-in cross-selling feature helps you offer extra
|
||||
The built-in cross-selling feature helps you offer extra
|
||||
products related to what the shopper put in his cart. (e.g.
|
||||
accessories)
|
||||
</p><p>
|
||||
OpenERP's upselling algorythm allows you to show visitors
|
||||
similar but more expensive products than the one in view, with
|
||||
incentives like customer ratings. (social validation)
|
||||
</p><p>
|
||||
incentives.
|
||||
</p><p>
|
||||
The inline editing feature allows you to easily change a price,
|
||||
launch a promotion or fine tune the description of a product,
|
||||
in a just a click.
|
||||
@@ -85,11 +88,11 @@
|
||||
events related to shopping carts, call-to-actions, etc.
|
||||
</p><p>
|
||||
As OpenERP marketing tools (mass mailing, campaigns, etc) are also
|
||||
linked with Google Analytics, you get a 360° view of your business.
|
||||
linked with Google Analytics, you get a complete view of your business.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="analytics.png">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -100,7 +103,7 @@
|
||||
<h3 class="oe_slogan">Multi-languages Without Pain</h3>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture" src="">
|
||||
<img class="oe_picture oe_screenshot" src="openerp_translation_tool.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
@@ -121,22 +124,21 @@
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Designer-Friendly Themes</h2>
|
||||
<h3 class="oe_slogan">Designers love working on OpenERP</h3>
|
||||
<h2 class="oe_slogan">Fine Tune Your Catalog</h2>
|
||||
<h3 class="oe_slogan">Boost Sales by Emphasazing Best Products</h3>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Themes are awesome and easy to design. You don't need to develop
|
||||
to create new pages, themes or building blocks. We use a clean
|
||||
HTML structure, a <a href="http://getbootstrap.com/">bootstrap</a>
|
||||
CSS and our modularity allows to distribute your themes easily.
|
||||
Get a full control on how you display your products in
|
||||
the catalog page: promotional ribbons, related sized of products,
|
||||
discounts, variants, grid/list view, etc.
|
||||
</p><p>
|
||||
The building block approach allows the website to remain clean
|
||||
after the end-users start creating new contents.
|
||||
Edit any product inline to make your website evolve with
|
||||
your customer need.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture" src="">
|
||||
<img class="oe_picture oe_screenshot" src="ribbon.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -148,7 +150,7 @@
|
||||
<h3 class="oe_slogan">SEO tools at your finger tips</h3>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="website_seo.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
@@ -178,7 +180,7 @@
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="website_edit.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -187,11 +189,11 @@
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Manage a Resellers Network</h2>
|
||||
<h2 class="oe_slogan">Manage a Reseller Network</h2>
|
||||
<h3 class="oe_slogan">Referencing, Lead Forward, Pricelists</h3>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="reseller.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
@@ -228,7 +230,7 @@
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img oe_centered">
|
||||
<img class="oe_picture" src="">
|
||||
<img class="oe_picture" src="warehouse_illu_01.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,6 +238,28 @@
|
||||
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">A Clean Checkout Process</h2>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Convert most visitor interests into real orders with a
|
||||
clean checkout process with a minimal number of steps
|
||||
and a great useability on every page.
|
||||
</p><p>
|
||||
Customize your checkout process to fit your business needs:
|
||||
payment modes, delivery methods, cross-selling, special conditions, etc.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="checkout.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">And much more...</h2>
|
||||
<div class="oe_span4">
|
||||
@@ -246,6 +270,7 @@
|
||||
<li>Flexible pricelists</li>
|
||||
<li>Product multi-variants</li>
|
||||
<li>Multiple stores</li>
|
||||
<li>Great checkout process</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="oe_span4">
|
||||
@@ -279,7 +304,7 @@
|
||||
<a href="/apps/website">
|
||||
<h3>CMS</h3>
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="website_home.png">
|
||||
</div>
|
||||
</a>
|
||||
<p>
|
||||
@@ -301,7 +326,7 @@
|
||||
<a href="/apps/website_event">
|
||||
<h3>Online Events</h3>
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
<img class="oe_picture oe_screenshot" src="event_top.png">
|
||||
</div>
|
||||
</a>
|
||||
<p>
|
||||
|
||||
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 56 KiB |
@@ -1,5 +1,20 @@
|
||||
@charset "utf-8";
|
||||
/* ---- Default Styles Description ---- */
|
||||
/* ---- Default Styles ---- */
|
||||
.oe_product {
|
||||
border: 1px solid rgba(100, 100, 100, 0.2);
|
||||
}
|
||||
|
||||
.oe_product_description {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
padding: 5px 0 5px 0;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.oe_subdescription {
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.oe_product_image {
|
||||
position: absolute;
|
||||
}
|
||||
@@ -12,8 +27,16 @@
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.oe_product .oe_product_cart {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* ---- Default Styles Description ---- */
|
||||
.oe_product .oe_product_image {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
@@ -30,6 +53,11 @@
|
||||
border-top: 1px solid #dddddd;
|
||||
}
|
||||
|
||||
.oe_mycart .input-group-addon {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px;
|
||||
}
|
||||
|
||||
.oe_shop_top .oe_product_description {
|
||||
top: 0;
|
||||
bottom: auto;
|
||||
@@ -53,28 +81,6 @@
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* ---- Default Styles ---- */
|
||||
.oe_product {
|
||||
border: 1px solid rgba(100, 100, 100, 0.2);
|
||||
}
|
||||
|
||||
.oe_product .oe_product_image img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.oe_product_description {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
padding: 5px 0 5px 0;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.oe_subdescription {
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
/* ---- Grid Style ---- */
|
||||
.style1 .oe_product .oe_product_image {
|
||||
position: absolute;
|
||||
@@ -91,12 +97,15 @@
|
||||
.col-md-12 .oe-height-2 {
|
||||
height: 150px;
|
||||
}
|
||||
.col-md-12 .oe-height-3 {
|
||||
height: 225px;
|
||||
}
|
||||
.col-md-12 .oe-height-4 {
|
||||
height: 300px;
|
||||
}
|
||||
.col-md-12 .oe-height-6 {
|
||||
height: 450px;
|
||||
}
|
||||
.col-md-12 .oe-height-8 {
|
||||
height: 600px;
|
||||
}
|
||||
|
||||
.col-md-9 .oe-height-1 {
|
||||
height: 70px;
|
||||
@@ -104,12 +113,15 @@
|
||||
.col-md-9 .oe-height-2 {
|
||||
height: 140px;
|
||||
}
|
||||
.col-md-9 .oe-height-3 {
|
||||
height: 210px;
|
||||
}
|
||||
.col-md-9 .oe-height-4 {
|
||||
height: 280px;
|
||||
}
|
||||
.col-md-9 .oe-height-6 {
|
||||
height: 420px;
|
||||
}
|
||||
.col-md-9 .oe-height-8 {
|
||||
height: 560px;
|
||||
}
|
||||
|
||||
@media (max-width: 728px) {
|
||||
.oe_product {
|
||||
@@ -135,12 +147,15 @@
|
||||
.col-md-12 .oe-height-2 {
|
||||
height: 190px;
|
||||
}
|
||||
.col-md-12 .oe-height-3 {
|
||||
height: 285px;
|
||||
}
|
||||
.col-md-12 .oe-height-4 {
|
||||
height: 380px;
|
||||
}
|
||||
.col-md-12 .oe-height-6 {
|
||||
height: 570px;
|
||||
}
|
||||
.col-md-12 .oe-height-8 {
|
||||
height: 760px;
|
||||
}
|
||||
|
||||
.col-md-9 .oe-height-1 {
|
||||
height: 72px;
|
||||
@@ -148,12 +163,15 @@
|
||||
.col-md-9 .oe-height-2 {
|
||||
height: 144px;
|
||||
}
|
||||
.col-md-9 .oe-height-3 {
|
||||
height: 216px;
|
||||
}
|
||||
.col-md-9 .oe-height-4 {
|
||||
height: 288px;
|
||||
}
|
||||
.col-md-9 .oe-height-6 {
|
||||
height: 432px;
|
||||
}
|
||||
.col-md-9 .oe-height-8 {
|
||||
height: 576px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1200px) {
|
||||
.col-md-12 .oe-height-1 {
|
||||
@@ -162,11 +180,14 @@
|
||||
.col-md-12 .oe-height-2 {
|
||||
height: 250px;
|
||||
}
|
||||
.col-md-12 .oe-height-3 {
|
||||
height: 375px;
|
||||
}
|
||||
.col-md-12 .oe-height-4 {
|
||||
height: 499.9px;
|
||||
height: 500px;
|
||||
}
|
||||
.col-md-12 .oe-height-6 {
|
||||
height: 750px;
|
||||
}
|
||||
.col-md-12 .oe-height-8 {
|
||||
height: 1000px;
|
||||
}
|
||||
|
||||
.col-md-9 .oe-height-1 {
|
||||
@@ -175,12 +196,15 @@
|
||||
.col-md-9 .oe-height-2 {
|
||||
height: 190px;
|
||||
}
|
||||
.col-md-9 .oe-height-3 {
|
||||
height: 285px;
|
||||
}
|
||||
.col-md-9 .oe-height-4 {
|
||||
height: 380px;
|
||||
}
|
||||
.col-md-9 .oe-height-6 {
|
||||
height: 570px;
|
||||
}
|
||||
.col-md-9 .oe-height-8 {
|
||||
height: 760px;
|
||||
}
|
||||
}
|
||||
/* ---- Product list style ---- */
|
||||
.oe_list_products {
|
||||
@@ -233,14 +257,17 @@
|
||||
border: 1px #dddddd solid;
|
||||
cursor: pointer;
|
||||
}
|
||||
#products_grid .css_options .dropdown [name="size"] td.selected, #products_grid .css_options .dropdown [name="size"] td.select {
|
||||
#products_grid .css_options .dropdown [name="size"] td.selected {
|
||||
background-color: #b1d4f1;
|
||||
}
|
||||
#products_grid .css_options .dropdown [name="size"] table.oe_hover td.selected:not(.select) {
|
||||
#products_grid .css_options .dropdown [name="size"] table.oe_hover td.selected {
|
||||
background-color: transparent;
|
||||
}
|
||||
#products_grid .css_options .dropdown [name="size"] table.oe_hover td.select {
|
||||
background-color: #b1d4f1;
|
||||
}
|
||||
|
||||
.cke_editable #products_grid td:hover > .css_options {
|
||||
.cke_editable #products_grid .oe_product_cart:hover > .css_options {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@@ -284,3 +311,69 @@
|
||||
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* Wizard */
|
||||
ul.wizard {
|
||||
padding: 0;
|
||||
margin-top: 20px;
|
||||
list-style: none outside none;
|
||||
border: 1px solid #d4d4d4;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065);
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065);
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065);
|
||||
}
|
||||
|
||||
ul.wizard li {
|
||||
position: relative;
|
||||
float: left;
|
||||
padding: 0 10px 0 20px;
|
||||
margin: 0;
|
||||
line-height: 38px;
|
||||
background: #fbfbfb;
|
||||
}
|
||||
|
||||
ul.wizard li .chevron {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -10px;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
border: 20px solid transparent;
|
||||
border-right: 0;
|
||||
border-left: 10px solid #d4d4d4;
|
||||
}
|
||||
|
||||
ul.wizard li .chevron:before {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 1px;
|
||||
display: block;
|
||||
border: 20px solid transparent;
|
||||
border-right: 0;
|
||||
border-left: 10px solid #fbfbfb;
|
||||
content: "";
|
||||
}
|
||||
|
||||
ul.wizard li.text-success {
|
||||
background: #f3f4f5;
|
||||
}
|
||||
|
||||
ul.wizard li.text-success .chevron:before {
|
||||
border-left: 10px solid whitesmoke;
|
||||
}
|
||||
|
||||
ul.wizard li.text-primary {
|
||||
background: #f1f6fc;
|
||||
}
|
||||
|
||||
ul.wizard li.text-primary .chevron:before {
|
||||
border-left: 10px solid #f1f6fc;
|
||||
}
|
||||
|
||||
ul.wizard li:first-child {
|
||||
padding-left: 15px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
@charset "utf-8"
|
||||
|
||||
/* ---- Default Styles Description ---- */
|
||||
/* ---- Default Styles ---- */
|
||||
|
||||
.oe_product
|
||||
border: 1px solid rgba(100,100,100,0.2)
|
||||
|
||||
.oe_product_description
|
||||
background: rgba(255,255, 255, 0.8)
|
||||
padding: 5px 0 5px 0
|
||||
z-index: 5
|
||||
|
||||
.oe_subdescription
|
||||
line-height: 1.2
|
||||
margin-bottom: 4px
|
||||
|
||||
.oe_product_image
|
||||
position: absolute
|
||||
@@ -13,6 +25,15 @@
|
||||
left: 0
|
||||
bottom: 0
|
||||
right: 0
|
||||
z-index: 4
|
||||
|
||||
.oe_product
|
||||
.oe_product_cart
|
||||
position: relative
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
/* ---- Default Styles Description ---- */
|
||||
|
||||
.oe_product
|
||||
.oe_product_image
|
||||
@@ -29,6 +50,11 @@
|
||||
right: 15px
|
||||
border-top: 1px solid #dddddd
|
||||
|
||||
.oe_mycart
|
||||
.input-group-addon
|
||||
padding-left: 6px
|
||||
padding-right: 6px
|
||||
|
||||
|
||||
.oe_shop_top /* Option 1 */
|
||||
.oe_product_description
|
||||
@@ -53,26 +79,6 @@
|
||||
top: 0
|
||||
bottom: 0
|
||||
|
||||
/* ---- Default Styles ---- */
|
||||
|
||||
.oe_product
|
||||
border: 1px solid rgba(100,100,100,0.2)
|
||||
|
||||
.oe_product .oe_product_image img
|
||||
max-width: 100%
|
||||
max-height: 100%
|
||||
z-index: 4
|
||||
|
||||
.oe_product_description
|
||||
background: rgba(255,255, 255, 0.8)
|
||||
padding: 5px 0 5px 0
|
||||
z-index: 5
|
||||
|
||||
.oe_subdescription
|
||||
line-height: 1.2
|
||||
margin-bottom: 4px
|
||||
|
||||
|
||||
/* ---- Grid Style ---- */
|
||||
|
||||
.style1
|
||||
@@ -89,19 +95,23 @@
|
||||
height: 75px
|
||||
.oe-height-2
|
||||
height: 150px
|
||||
.oe-height-3
|
||||
height: 225px
|
||||
.oe-height-4
|
||||
height: 300px
|
||||
.oe-height-6
|
||||
height: 450px
|
||||
.oe-height-8
|
||||
height: 600px
|
||||
.col-md-9
|
||||
.oe-height-1
|
||||
height: 70px
|
||||
.oe-height-2
|
||||
height: 140px
|
||||
.oe-height-3
|
||||
height: 210px
|
||||
.oe-height-4
|
||||
height: 280px
|
||||
.oe-height-6
|
||||
height: 420px
|
||||
.oe-height-8
|
||||
height: 560px
|
||||
|
||||
@media (max-width: 728px)
|
||||
.oe_product
|
||||
@@ -123,19 +133,23 @@
|
||||
height: 95px
|
||||
.oe-height-2
|
||||
height: 190px
|
||||
.oe-height-3
|
||||
height: 285px
|
||||
.oe-height-4
|
||||
height: 380px
|
||||
.oe-height-6
|
||||
height: 570px
|
||||
.oe-height-8
|
||||
height: 760px
|
||||
.col-md-9
|
||||
.oe-height-1
|
||||
height: 72px
|
||||
.oe-height-2
|
||||
height: 144px
|
||||
.oe-height-3
|
||||
height: 216px
|
||||
.oe-height-4
|
||||
height: 288px
|
||||
.oe-height-6
|
||||
height: 432px
|
||||
.oe-height-8
|
||||
height: 576px
|
||||
|
||||
@media (min-width: 1200px)
|
||||
.col-md-12
|
||||
@@ -143,19 +157,23 @@
|
||||
height: 125px
|
||||
.oe-height-2
|
||||
height: 250px
|
||||
.oe-height-3
|
||||
height: 375px
|
||||
.oe-height-4
|
||||
height: 499.9px
|
||||
height: 500px
|
||||
.oe-height-6
|
||||
height: 750px
|
||||
.oe-height-8
|
||||
height: 1000px
|
||||
.col-md-9
|
||||
.oe-height-1
|
||||
height: 95px
|
||||
.oe-height-2
|
||||
height: 190px
|
||||
.oe-height-3
|
||||
height: 285px
|
||||
.oe-height-4
|
||||
height: 380px
|
||||
.oe-height-6
|
||||
height: 570px
|
||||
.oe-height-8
|
||||
height: 760px
|
||||
|
||||
/* ---- Product list style ---- */
|
||||
.oe_list_products
|
||||
@@ -202,13 +220,15 @@
|
||||
height: 20px
|
||||
border: 1px #dddddd solid
|
||||
cursor: pointer
|
||||
&.selected, &.select
|
||||
&.selected
|
||||
background-color: #B1D4F1
|
||||
table.oe_hover td.selected:not(.select)
|
||||
table.oe_hover td.selected
|
||||
background-color: transparent
|
||||
table.oe_hover td.select
|
||||
background-color: #B1D4F1
|
||||
|
||||
.cke_editable
|
||||
#products_grid td:hover > .css_options
|
||||
#products_grid .oe_product_cart:hover > .css_options
|
||||
display: block
|
||||
|
||||
/* Ribbon for promotionso on products */
|
||||
@@ -250,3 +270,64 @@
|
||||
-webkit-box-shadow: 0px 0px 3px rgba(0,0,0,0.3)
|
||||
-moz-box-shadow: 0px 0px 3px rgba(0,0,0,0.3)
|
||||
box-shadow: 0px 0px 3px rgba(0,0,0,0.3)
|
||||
|
||||
|
||||
/* Wizard */
|
||||
|
||||
|
||||
ul.wizard
|
||||
padding: 0
|
||||
margin-top: 20px
|
||||
list-style: none outside none
|
||||
border: 1px solid #d4d4d4
|
||||
-webkit-border-radius: 4px
|
||||
-moz-border-radius: 4px
|
||||
border-radius: 4px
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065)
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065)
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.065)
|
||||
|
||||
ul.wizard li
|
||||
position: relative
|
||||
float: left
|
||||
padding: 0 10px 0 20px
|
||||
margin: 0
|
||||
line-height: 38px
|
||||
background: #fbfbfb
|
||||
|
||||
ul.wizard li .chevron
|
||||
position: absolute
|
||||
top: 0
|
||||
right: -10px
|
||||
z-index: 1
|
||||
display: block
|
||||
border: 20px solid transparent
|
||||
border-right: 0
|
||||
border-left: 10px solid #d4d4d4
|
||||
|
||||
ul.wizard li .chevron:before
|
||||
position: absolute
|
||||
top: -20px
|
||||
right: 1px
|
||||
display: block
|
||||
border: 20px solid transparent
|
||||
border-right: 0
|
||||
border-left: 10px solid #fbfbfb
|
||||
content: ""
|
||||
|
||||
ul.wizard li.text-success
|
||||
background: #f3f4f5
|
||||
|
||||
ul.wizard li.text-success .chevron:before
|
||||
border-left: 10px solid #f5f5f5
|
||||
|
||||
ul.wizard li.text-primary
|
||||
background: #f1f6fc
|
||||
|
||||
ul.wizard li.text-primary .chevron:before
|
||||
border-left: 10px solid #f1f6fc
|
||||
|
||||
ul.wizard li:first-child
|
||||
padding-left: 15px
|
||||
border-radius: 4px 0 0 4px
|
||||
|
||||
|
||||
@@ -36,20 +36,18 @@ $(document).ready(function () {
|
||||
});
|
||||
|
||||
// hack to add and rome from cart with json
|
||||
$('.oe_website_sale a[href*="/add_cart/"], a[href*="/remove_cart/"]').on('click', function (ev) {
|
||||
$('.oe_website_sale a[href*="/add_cart/"],.oe_website_sale a[href*="/remove_cart/"]').on('click', function (ev) {
|
||||
ev.preventDefault();
|
||||
var $link = $(ev.currentTarget);
|
||||
var product_id = $link.attr("href").match(/product_id=([0-9]+)/)[1];
|
||||
if (product_id) {
|
||||
product_id = +product_id;
|
||||
}
|
||||
var product = $link.attr("href").match(/product_id=([0-9]+)/);
|
||||
var product_id = product ? +product[1] : 0;
|
||||
openerp.jsonRpc("/shop/add_cart_json/", 'call', {'product_id': product_id, 'order_line_id': $link.data('id'), 'remove': $link.is('[href*="/remove_cart/"]')})
|
||||
.then(function (data) {
|
||||
if (!data[0]) {
|
||||
location.reload();
|
||||
}
|
||||
set_my_cart_quantity(data[1]);
|
||||
$link.parent().find(".js_quantity").val(data[0]);
|
||||
$link.parents(".input-group:first").find(".js_quantity").val(data[0]);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -49,17 +49,7 @@
|
||||
<li>
|
||||
<a t-href="/shop/mycart/">
|
||||
<i class="icon-shopping-cart"></i>
|
||||
My cart <span t-attf-class="my_cart_quantity badge #{(not website_sale_order or not website_sale_order.get_total_quantity()) and 'hidden' or ''}"
|
||||
t-esc="website_sale_order and website_sale_order.get_total_quantity() or ''"/>
|
||||
</a>
|
||||
</li>
|
||||
</xpath>
|
||||
<xpath expr="//footer//ul[@name='products']" position="inside">
|
||||
<li><a t-href="/shop/">Shop</a></li>
|
||||
<li>
|
||||
<a t-href="/shop/mycart/">
|
||||
<i class="icon-shopping-cart"></i>
|
||||
My cart <span t-attf-class="my_cart_quantity badge #{(not website_sale_order or not website_sale_order.get_total_quantity()) and 'hidden' or ''}"
|
||||
My cart <sup t-attf-class="my_cart_quantity label label-primary #{(not website_sale_order or not website_sale_order.get_total_quantity()) and 'hidden' or ''}"
|
||||
t-esc="website_sale_order and website_sale_order.get_total_quantity() or ''"/>
|
||||
</a>
|
||||
</li>
|
||||
@@ -141,7 +131,6 @@
|
||||
<div class="col-md-12" id="products_grid">
|
||||
<table width="100%">
|
||||
<colgroup>
|
||||
<col style="width: 1px; margin-right: -1px;" />
|
||||
<col class="col-md-3" />
|
||||
<col class="col-md-3" />
|
||||
<col class="col-md-3" />
|
||||
@@ -150,65 +139,67 @@
|
||||
<tbody>
|
||||
<t t-set="table_products" t-value="get_bin_packing_products(product_ids, product_ids_for_holes, 4)"/>
|
||||
<tr t-foreach="table_products" t-as="tr_product">
|
||||
<td class="oe-height-2"></td>
|
||||
<t t-foreach="tr_product" t-as="td_product">
|
||||
<t t-if="td_product">
|
||||
<t t-set="product" t-value="td_product['product']"/>
|
||||
<td t-att-colspan="td_product['x']"
|
||||
t-att-rowspan="td_product['y']"
|
||||
t-attf-class="oe_product #{ td_product['class'] }"
|
||||
t-att-data-publish="product.website_published and 'on' or 'off'">
|
||||
t-attf-class="oe_product oe-height-#{td_product['y']*2} #{ td_product['class'] }">
|
||||
|
||||
<div class="css_options" t-ignore="true">
|
||||
<div t-attf-class="dropdown js_options" t-att-data-id="product.id">
|
||||
<a class="btn btn-default" t-att-id="'dopprod-%s' % product.id" role="button" data-toggle="dropdown">Options <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % product.id">
|
||||
<li class='dropdown-submenu'>
|
||||
<a tabindex="-1" href="#">Size</a>
|
||||
<ul class="dropdown-menu" name="size">
|
||||
<li><a href="#">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="selected"></td>
|
||||
<td t-att-class="product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 3 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class='dropdown-submenu'>
|
||||
<a tabindex="-1" href="#">Styles</a>
|
||||
<ul class="dropdown-menu" name="style">
|
||||
<t t-foreach="styles" t-as="style">
|
||||
<li t-att-class="style.id in [s.id for s in product.website_style_ids] and 'active' or ''"><a href="#" t-att-data-id="style.id" t-att-data-class="style.html_class"><t t-esc="style.name"/></a></li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="oe_product_cart" t-att-data-publish="product.website_published and 'on' or 'off'">
|
||||
|
||||
<div class="css_options" t-ignore="true" t-if="editable">
|
||||
<div t-attf-class="dropdown js_options" t-att-data-id="product.id">
|
||||
<a class="btn btn-default" t-att-id="'dopprod-%s' % product.id" role="button" data-toggle="dropdown">Options <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu" t-att-aria-labelledby="'dopprod-%s' % product.id">
|
||||
<li class='dropdown-submenu'>
|
||||
<a tabindex="-1" href="#">Size</a>
|
||||
<ul class="dropdown-menu" name="size">
|
||||
<li><a href="#">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="selected"></td>
|
||||
<td t-att-class="product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 1 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 2 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td t-att-class="product.website_size_y > 3 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 1 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 2 and 'selected'"></td>
|
||||
<td t-att-class="product.website_size_y > 3 and product.website_size_x > 3 and 'selected'"></td>
|
||||
</tr>
|
||||
</table>
|
||||
</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class='dropdown-submenu'>
|
||||
<a tabindex="-1" href="#">Styles</a>
|
||||
<ul class="dropdown-menu" name="style">
|
||||
<t t-foreach="styles" t-as="style">
|
||||
<li t-att-class="style.id in [s.id for s in product.website_style_ids] and 'active' or ''"><a href="#" t-att-data-id="style.id" t-att-data-class="style.html_class"><t t-esc="style.name"/></a></li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<t t-call="website_sale.products_cart"/>
|
||||
</div>
|
||||
|
||||
<t t-call="website_sale.products_cart"/>
|
||||
</td>
|
||||
</t>
|
||||
<td t-if="td_product == None"/>
|
||||
@@ -322,14 +313,16 @@
|
||||
</label>
|
||||
<br/>
|
||||
</t>
|
||||
<div>
|
||||
<t t-if="product.product_variant_ids[0].lst_price != product.product_variant_ids[0].price">
|
||||
<h5 class="text-danger" style="text-decoration: line-through;" title="Price without reduction"><span t-field="product.product_variant_ids[0].lst_price" /> €</h5>
|
||||
<h4><t t-esc="product.product_variant_ids[0].price" /> €</h4>
|
||||
</t>
|
||||
<h4 t-if="product.product_variant_ids[0].lst_price == product.product_variant_ids[0].price">
|
||||
<b><span t-field="product.product_variant_ids[0].lst_price" /> €</b>
|
||||
</h4>
|
||||
|
||||
<div class="product_price">
|
||||
<b>
|
||||
<t t-if="product.product_variant_ids[0].lst_price != product.product_variant_ids[0].price">
|
||||
<span class="text-danger" style="text-decoration: line-through;">
|
||||
<t t-esc="product.product_variant_ids[0].lst_price" /> €
|
||||
</span>&nbsp;
|
||||
</t>
|
||||
<h4><b><t t-esc="product.product_variant_ids[0].price" /> €</b></h4>
|
||||
</b>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-lg mt8">Add to Cart</button>
|
||||
<hr t-if="product.description_sale"/>
|
||||
@@ -379,19 +372,32 @@
|
||||
<t t-call="website.layout">
|
||||
<t t-set="head">
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.js"></script>
|
||||
<link rel='stylesheet' href='/website_sale/static/src/css/website_sale.css'/>
|
||||
<t t-raw="head or ''"/>
|
||||
</t>
|
||||
<t t-set="title">Your Cart</t>
|
||||
<div id="wrap">
|
||||
<div class="container oe_website_sale">
|
||||
<div class="col-md-12 oe_mycart">
|
||||
<h1>My Shopping Cart</h1>
|
||||
<table class='table' id="mycart_products">
|
||||
|
||||
<ul class="wizard pull-right">
|
||||
<li class="text-primary">Review Order<span class="chevron"></span></li>
|
||||
<li class="text-muted">Shipping & Billing<span class="chevron"></span></li>
|
||||
<li class="text-muted">Payment<span class="chevron"></span></li>
|
||||
<li class="text-muted">Confirmation<span class="chevron"></span></li>
|
||||
</ul>
|
||||
<h1 class="mb32">Your Cart</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8 oe_mycart">
|
||||
<div t-if="not website_sale_order or not website_sale_order.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">
|
||||
<colgroup>
|
||||
<col width="80"/>
|
||||
<col/>
|
||||
<col width="80"/>
|
||||
<col width="160"/>
|
||||
<col width="100"/>
|
||||
<col width="120"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -400,52 +406,84 @@
|
||||
<th>Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody t-if="not website_sale_order or not website_sale_order.order_line">
|
||||
<tr><td colspan="4"><h3>Your cart is empty</h3></td></tr>
|
||||
</tbody>
|
||||
<tbody t-if="website_sale_order and website_sale_order.order_line">
|
||||
<t t-foreach="website_sale_order.order_line" t-as="line">
|
||||
<tr>
|
||||
<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/#{ line.product_id.product_tmpl_id.id }/"><img class="img-rounded" t-att-src="line.product_id.img('image_small')"/></a>
|
||||
</td>
|
||||
<td t-if="line.product_id.product_tmpl_id">
|
||||
<a t-href="/shop/product/#{ line.product_id.product_tmpl_id.id }/"><span t-field="line.name"/></a><br/>
|
||||
<small t-field="line.product_id.description_sale"/>
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="line.product_id.product_tmpl_id and line.product_id.lst_price != line.price_unit">
|
||||
<small class="text-error" style="text-decoration: line-through;"><t t-esc="line.product_id.lst_price" /> €</small>
|
||||
</t>
|
||||
<span t-field="line.price_unit"></span> €
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-right">
|
||||
<input type="text" class="js_quantity input-sm col-md-5" t-att-data-id="line.id" t-att-value="line.product_uom_qty"/>
|
||||
<a t-href="./remove_cart/?order_line_id=#{ line.id }" t-att-data-id="line.id" class="btn btn-default mb8 btn-sm btn-inverse">-</a>
|
||||
<a t-href="./add_cart/?order_line_id=#{ line.id }" t-att-data-id="line.id" class="btn btn-default mb8 btn-sm btn-success">+</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<tbody>
|
||||
<tr t-foreach="website_sale_order.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/#{ line.product_id.product_tmpl_id.id }/"><img class="img-rounded" t-att-src="line.product_id.img('image_small')"/></a>
|
||||
</td>
|
||||
<td t-if="line.product_id.product_tmpl_id">
|
||||
<div>
|
||||
<a t-href="/shop/product/#{ line.product_id.product_tmpl_id.id }/">
|
||||
<strong t-field="line.product_id.name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-muted" t-field="line.product_id.description_sale"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<div class="text-danger" style="text-decoration: line-through;" t-if="line.product_id.lst_price > line.price_unit">
|
||||
<t t-esc="line.product_id.lst_price" /> €
|
||||
</div>
|
||||
<span t-field="line.price_unit"></span> €
|
||||
</td>
|
||||
<td>
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<a t-href="./remove_cart/?order_line_id=#{ line.id }" t-att-data-id="line.id" class="mb8">
|
||||
<span class="icon-minus"/>
|
||||
</a>
|
||||
</span>
|
||||
<input type="text" class="js_quantity form-control"
|
||||
t-att-data-id="line.id" t-att-value="int(line.product_uom_qty)"/>
|
||||
<span class="input-group-addon">
|
||||
<a t-href="./add_cart/?order_line_id=#{ line.id }" t-att-data-id="line.id" class="mb8 float_left">
|
||||
<span class="icon-plus"/>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class='table table-hover table-condensed' id="mycart_total">
|
||||
<table class='pull-right mb16' id="mycart_total">
|
||||
<colgroup>
|
||||
<col width="80"/>
|
||||
<col/>
|
||||
<col width="80"/>
|
||||
<col width="160"/>
|
||||
<col width="100"/>
|
||||
<col width="120"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr> <th colspan="3">Subtotal </th> <th><t t-esc="website_sale_order and website_sale_order.amount_untaxed or 0"/> €</th></tr>
|
||||
<tr> <th colspan="3">Taxes </th> <th><t t-esc="website_sale_order and website_sale_order.amount_tax or 0"/> €</th></tr>
|
||||
<tr> <th colspan="3"><h4>Total</h4></th> <th><h4><t t-esc="website_sale_order and website_sale_order.amount_total or 0"/> €</h4></th></tr>
|
||||
<tr style="border-top: 1px solid #000">
|
||||
<th><h3>Total:</h3></th>
|
||||
<th class="text-right"><h3><t t-esc="website_sale_order and website_sale_order.amount_total or 0"/> €</h3></th>
|
||||
</tr>
|
||||
<tr class="text-muted">
|
||||
<td><abbr title="Taxes may be updated after providing shipping address">Incl. Taxes:</abbr></td>
|
||||
<td class="text-right"><t t-esc="website_sale_order and website_sale_order.amount_tax or 0"/> €</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<a t-if="website_sale_order and website_sale_order.order_line" t-href="/shop/checkout/" class="btn btn-success">Proceed To Payment</a>
|
||||
<div class="clearfix"/>
|
||||
|
||||
<a t-href="/shop" class="btn btn-default"><span class="icon-long-arrow-left"/> Continue Shopping</a>
|
||||
<a t-if="website_sale_order and website_sale_order.order_line" t-href="/shop/checkout/" class="btn btn-primary pull-right mb32">Process Checkout <span class="icon-long-arrow-right"/></a>
|
||||
<div class="oe_structure"/>
|
||||
</div>
|
||||
<div class="col-md-3 col-md-offset-1 text-muted" id="right_column">
|
||||
<h4>Policies</h4>
|
||||
<ul class="list-unstyled mb32">
|
||||
<li><span class="icon-check"/> 30-days money-back guarantee</li>
|
||||
<li><span class="icon-check"/> Invoice sent by e-Mail</li>
|
||||
</ul>
|
||||
|
||||
<h4>Secure Payment</h4>
|
||||
<ul class="list-unstyled mb32">
|
||||
<li><span class="icon-lock"/> Transation 256bit encrypted</li>
|
||||
<li><span class="icon-check"/> Processed by Ogone</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="oe_structure"/>
|
||||
</div>
|
||||
@@ -474,66 +512,59 @@
|
||||
|
||||
<template id="suggested_products_list" inherit_id="website_sale.mycart" inherit_option_id="website_sale.mycart" name="Suggested Products in list view">
|
||||
<xpath expr="//table[@id='mycart_products']" position="after">
|
||||
<table t-if="suggested_products" class='table table-hover table-condensed'>
|
||||
<table t-if="suggested_products" class='table table-striped table-condensed'>
|
||||
<colgroup>
|
||||
<col/>
|
||||
<col width="80"/>
|
||||
<col width="160"/>
|
||||
<col/>
|
||||
<col width="100"/>
|
||||
<col width="120"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Suggested products</th>
|
||||
<th colspan="2">Suggested products</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="suggested_products" t-as="product">
|
||||
<tr>
|
||||
<td>
|
||||
<a t-href="/shop/product/#{ product.id }/"><span t-field="product.name"/></a><br/>
|
||||
<small t-field="product.description_sale"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="product.list_price"></span>€
|
||||
</td>
|
||||
<td>
|
||||
<div class="pull-right">
|
||||
<a t-href="./add_cart/?product_id=#{ product.id }" class="btn btn-sm btn-success">+</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr t-foreach="suggested_products" t-as="product">
|
||||
|
||||
<td>
|
||||
<a t-href="/shop/product/#{ product.product_tmpl_id.id }/">
|
||||
<img class="img-rounded" t-att-src="product.img('image_small')"/>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
<a t-href="/shop/product/#{ product.product_tmpl_id.id }/">
|
||||
<strong t-field="product.name"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-muted" t-field="product.description_sale"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="product.lst_price"></span> €
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a t-href="./add_cart/?product_id=#{ product.id }"><strong>Add to Cart</strong></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="suggested_products_cell" inherit_option_id="website_sale.mycart" name="Suggested Products in card view">
|
||||
<xpath expr="//table[@id='mycart_products']" position="after">
|
||||
<div class="mt16 mb32" t-if="suggested_products">
|
||||
<h4>Suggested products</h4>
|
||||
<div class='row mt16'>
|
||||
<t t-foreach="suggested_products" t-as="product">
|
||||
<div class='col-md-2 thumbnail'>
|
||||
<div class='mt16 text-center'>
|
||||
<a t-href="/shop/product/#{ product.id }/">
|
||||
<img t-att-src="product.img('image_small')"/>
|
||||
</a>
|
||||
<h5>
|
||||
<a t-href="/shop/product/#{ product.id }/" style="display: block;">
|
||||
<span t-field="product.name"/>
|
||||
</a>
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="reduction_code" inherit_option_id="website_sale.mycart" name="Reduction Code">
|
||||
<xpath expr="//table[@id='mycart_total']" position="after">
|
||||
<form t-if="website_sale_order and website_sale_order.order_line" class="well" t-action="/shop/mycart/" method="post">
|
||||
<input name="promo" class='input' type="text" placeholder="Reduction Code..." t-att-value="website_sale_order.pricelist_id.code or ''"/>
|
||||
<button class="btn">Apply Code</button>
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<h4>Coupon Code</h4>
|
||||
<p>
|
||||
Have a coupon code? Fill in this field and apply.
|
||||
</p>
|
||||
<form t-if="website_sale_order and website_sale_order.order_line" t-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">
|
||||
<button class="btn btn-default">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</xpath>
|
||||
</template>
|
||||
@@ -545,244 +576,263 @@
|
||||
<t t-call="website.layout">
|
||||
<t t-set="head">
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.js"></script>
|
||||
<link rel='stylesheet' href='/website_sale/static/src/css/website_sale.css'/>
|
||||
<t t-raw="head or ''"/>
|
||||
</t>
|
||||
<t t-set="title">Shop - Checkout</t>
|
||||
<div id="wrap">
|
||||
<div class="container oe_website_sale">
|
||||
<ul class="wizard pull-right">
|
||||
<li><a href="/shop/mycart" class="text-success">Review Order<span class="chevron"></span></a></li>
|
||||
<li class="text-primary">Shipping & Billing<span class="chevron"></span></li>
|
||||
<li class="text-muted">Payment<span class="chevron"></span></li>
|
||||
<li class="text-muted">Confirmation<span class="chevron"></span></li>
|
||||
</ul>
|
||||
<h1>Your Address</h1>
|
||||
<form t-action="/shop/confirm_order/" method="post">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<th>Price</th>
|
||||
<th>Qty.</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody t-if="website_sale_order.order_line">
|
||||
<t t-foreach="website_sale_order.order_line" t-as="line">
|
||||
<tr>
|
||||
<td><t t-esc="line.name"/></td>
|
||||
<td><t t-esc="line.product_uom_qty"/></td>
|
||||
<td><t t-esc="line.price_unit"/> €</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><th>Untaxed Amount</th><td></td><td><t t-esc="website_sale_order.amount_untaxed"/> €</td></tr>
|
||||
<tr><th>Taxes</th><td></td><td><t t-esc="website_sale_order.amount_tax"/> €</td></tr>
|
||||
<tr><th>Total</th><td></td><td><t t-esc="website_sale_order.amount_total"/> €</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
<div class="col-md-8 oe_mycart">
|
||||
<h3 class="page-header mt16">Set Billing Information
|
||||
<small t-if="user_id.id == website.public_user.id"> or
|
||||
<a t-if="not partner" t-attf-href="/admin#action=redirect&url=#{ request.httprequest.host_url }/shop/checkout/">sign in</a>
|
||||
</small>
|
||||
</h3>
|
||||
<div class="row">
|
||||
<div t-attf-class="form-group #{error.get('name') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Your Name</label>
|
||||
<input type="text" name="name" class="form-control" t-att-value="checkout.get('name')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('company') and 'has-error' or ''} col-lg-6">
|
||||
<label for="company">Your Company</label>
|
||||
<input type="text" name="company" class="form-control" t-att-value="checkout.get('company')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('email') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Email</label>
|
||||
<input type="email" name="email" class="form-control" t-att-value="checkout.get('email')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{ error.get('phone') and 'has-error' or ''} col-lg-6">
|
||||
<label for="phone">Telephone</label>
|
||||
<input type="tel" name="phone" class="form-control" t-att-value="checkout.get('phone')"/>
|
||||
</div>
|
||||
|
||||
<div t-attf-class="form-group #{error.get('street') and 'has-error' or ''} col-lg-6">
|
||||
<label for="street">Street</label>
|
||||
<input type="text" name="street" class="form-control" t-att-value="checkout.get('street')"/>
|
||||
</div>
|
||||
<div class="clearfix"/>
|
||||
|
||||
<div t-attf-class="form-group #{error.get('city') and 'has-error' or ''} col-lg-6">
|
||||
<label for="city">City</label>
|
||||
<input type="text" name="city" class="form-control" t-att-value="checkout.get('city')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('zip') and 'has-error' or ''} col-lg-6">
|
||||
<label for="zip">Zip / Postal Code</label>
|
||||
<input type="text" name="zip" class="form-control" t-att-value="checkout.get('zip')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('state_id') and 'has-error' or ''} col-lg-6">
|
||||
<label for="state_id">State / Province</label>
|
||||
<select name="state_id" class="form-control">
|
||||
<option value="">select...</option>
|
||||
<t t-foreach="states or []" t-as="state">
|
||||
<option t-att-value="state.id" t-att-selected="state.id == checkout.get('state_id')"><t t-esc="state.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('country_id') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Country</label>
|
||||
<select name="country_id" class="form-control">
|
||||
<option value="">Country...</option>
|
||||
<t t-foreach="countries or []" t-as="country">
|
||||
<option t-att-value="country.id" t-att-selected="country.id == checkout.get('country_id')"><t t-esc="country.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"/>
|
||||
|
||||
<div class="form-group col-lg-6">
|
||||
<label>
|
||||
<input t-if="not shipping" type="checkbox" name="shipping_different"/>
|
||||
<input t-if="shipping" type="checkbox" name="shipping_different" checked="1"/>
|
||||
Ship to a different address
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="js_shipping row mb16" t-att-style="not shipping and 'display:none' or ''">
|
||||
<h3 class="oe_shipping col-lg-12 mt16">Shipping Information</h3>
|
||||
|
||||
<div t-attf-class="form-group #{error.get('shipping_name') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Name (Shipping)</label>
|
||||
<input type="text" name="shipping_name" class="form-control" t-att-value="checkout.get('shipping_name', '')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_phone') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Telephone</label>
|
||||
<input type="tel" name="shipping_phone" class="form-control" t-att-value="checkout.get('shipping_phone', '')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_street') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Street</label>
|
||||
<input type="text" name="shipping_street" class="form-control" t-att-value="checkout.get('shipping_street', '')"/>
|
||||
</div>
|
||||
<div class="clearfix"/>
|
||||
<div t-attf-class="form-group #{error.get('shipping_city') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">City</label>
|
||||
<input type="text" name="shipping_city" class="form-control" t-att-value="checkout.get('shipping_city', '')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_zip') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Zip / Postal Code</label>
|
||||
<input type="text" name="shipping_zip" class="form-control" t-att-value="checkout.get('shipping_zip', '')"/>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_state_id') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">State / Province</label>
|
||||
<select name="shipping_state_id" class="form-control">
|
||||
<option value="">State / Province...</option>
|
||||
<t t-foreach="states or []" t-as="state">
|
||||
<option t-att-value="state.id" t-att-selected="state.id == checkout.get('shipping_state_id')"><t t-esc="state.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_country_id') and 'has-error' or ''} col-lg-6">
|
||||
<label for="contact_name">Country</label>
|
||||
<select name="shipping_country_id" class="form-control">
|
||||
<option value="">Country...</option>
|
||||
<t t-foreach="countries or []" t-as="country">
|
||||
<option t-att-value="country.id" t-att-selected="country.id == checkout.get('shipping_country_id')"><t t-esc="country.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default btn-primary pull-right mb32">Confirm <span class="icon-long-arrow-right"/></button>
|
||||
</div>
|
||||
<div class="col-lg-offset-1 col-lg-3 text-muted">
|
||||
<h3 class="page-header mt16">Your Order <small><a href="/shop/mycart"><span class="icon-arrow-right"/> change</a></small></h3>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-right">Subtotal:</div>
|
||||
<div class="col-sm-6"><t t-esc="website_sale_order.amount_untaxed or 0"/> €</div>
|
||||
<div class="col-sm-6 text-right">Taxes:</div>
|
||||
<div class="col-sm-6"><t t-esc="website_sale_order.amount_tax or 0"/> €</div>
|
||||
<div class="col-sm-6 text-right"><h4>Total To Pay:</h4></div>
|
||||
<div class="col-sm-6"><h4><t t-esc="website_sale_order.amount_total or 0"/> €</h4></div>
|
||||
</div>
|
||||
<form class="col-md-8 form-horizontal" t-action="/shop/confirm_order/" method="post">
|
||||
<div class=" row">
|
||||
<a t-if="not partner" t-attf-href="/admin#action=redirect&url=#{ request.httprequest.host_url }/shop/checkout/" class="btn btn-primary">Log me, I have an account</a>
|
||||
<h3 class="col-md-10">Billing Information</h3>
|
||||
<div t-attf-class="form-group #{error.get('name') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Name and firstname</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="name" class="form-control" t-att-value="checkout['name']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{ error.get('phone') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Telephone</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="tel" name="phone" class="form-control" t-att-value="checkout['phone']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('fax') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Fax</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="tel" name="fax" class="form-control" t-att-value="checkout['fax']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('company') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Company</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="company" class="form-control" t-att-value="checkout['company']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('email') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Email address</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="email" name="email" class="form-control" t-att-value="checkout['email']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('street') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Street</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="street" class="form-control" t-att-value="checkout['street']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('city') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">City</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="city" class="form-control" t-att-value="checkout['city']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('state_id') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">State / Province</label>
|
||||
<div class="col-lg-4">
|
||||
<select name="state_id" class="form-control">
|
||||
<option value="">State / Province...</option>
|
||||
<t t-foreach="states or []" t-as="state">
|
||||
<option t-att-value="state.id" t-att-selected="state.id == checkout['state_id']"><t t-esc="state.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('zip') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Zip / Postal Code</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="zip" class="form-control" t-att-value="checkout['zip']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('country_id') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Country</label>
|
||||
<div class="col-lg-4">
|
||||
<select name="country_id" class="form-control">
|
||||
<option value="">Country...</option>
|
||||
<t t-foreach="countries or []" t-as="country">
|
||||
<option t-att-value="country.id" t-att-selected="country.id == checkout['country_id']"><t t-esc="country.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group checkbox">
|
||||
<div class="col-lg-7 col-md-offset-3">
|
||||
<label>
|
||||
<input t-if="not shipping" type="checkbox" name="shipping_different"/>
|
||||
<input t-if="shipping" type="checkbox" name="shipping_different" checked="1"/>
|
||||
Ship to different address
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="js_shipping row" t-att-style="not shipping and 'display:none' or ''">
|
||||
<h3 class="col-md-12 oe_shipping">Shipping Information</h3>
|
||||
<div t-attf-class="form-group #{error.get('shipping_name') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Name and firstname</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="shipping_name" class="form-control" t-att-value="checkout.get('shipping_name', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_phone') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Telephone</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="tel" name="shipping_phone" class="form-control" t-att-value="checkout.get('shipping_phone', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_fax') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Fax</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="tel" name="shipping_fax" class="form-control" t-att-value="checkout.get('shipping_fax', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_street') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Street</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="shipping_street" class="form-control" t-att-value="checkout.get('shipping_street', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_city') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">City</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="shipping_city" class="form-control" t-att-value="checkout.get('shipping_city', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_state_id') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">State / Province</label>
|
||||
<div class="col-lg-4">
|
||||
<select name="shipping_state_id" class="form-control">
|
||||
<option value="">State / Province...</option>
|
||||
<t t-foreach="states or []" t-as="state">
|
||||
<option t-att-value="state.id" t-att-selected="state.id == checkout.get('shipping_state_id')"><t t-esc="state.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_zip') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Zip / Postal Code</label>
|
||||
<div class="col-lg-4">
|
||||
<input type="text" name="shipping_zip" class="form-control" t-att-value="checkout.get('shipping_zip', '')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('shipping_country_id') and 'has-error' or ''}">
|
||||
<label class="col-lg-3 control-label" for="contact_name">Country</label>
|
||||
<div class="col-lg-4">
|
||||
<select name="shipping_country_id" class="form-control">
|
||||
<option value="">Country...</option>
|
||||
<t t-foreach="countries or []" t-as="country">
|
||||
<option t-att-value="country.id" t-att-selected="country.id == checkout.get('shipping_country_id')"><t t-esc="country.name"/></option>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default">Confirm</button>
|
||||
</form>
|
||||
<button type="submit" class="btn btn-default btn-primary pull-right mt16" t-if="user_id.id != website.public_user.id">
|
||||
Confirm <span class="icon-long-arrow-right"/>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="payment">
|
||||
<t t-call="website.layout">
|
||||
<t t-set="head">
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.js"></script>
|
||||
<t t-raw="head or ''"/>
|
||||
</t>
|
||||
<t t-set="title">Shop - Payment</t>
|
||||
<div id="wrap">
|
||||
<div class="container oe_website_sale">
|
||||
<t t-set="head">
|
||||
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.js"></script>
|
||||
<link rel='stylesheet' href='/website_sale/static/src/css/website_sale.css'/>
|
||||
<t t-raw="head or ''"/>
|
||||
</t>
|
||||
<t t-set="title">Select Payment Mode</t>
|
||||
<div id="wrap">
|
||||
<div class="container oe_website_sale">
|
||||
|
||||
<ul class="wizard pull-right">
|
||||
<li><a href="/shop/mycart" class="text-success">Review Order<span class="chevron"></span></a></li>
|
||||
<li><a href="/shop/checkout" class="text-success">Shipping & Billing<span class="chevron"></span></a></li>
|
||||
<li class="text-primary">Payment<span class="chevron"></span></li>
|
||||
<li class="text-muted">Confirmation<span class="chevron"></span></li>
|
||||
</ul>
|
||||
<h1 class="mb32">Validate Order</h1>
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<table class="table table-condensed" t-if="order">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<th>Price</th>
|
||||
<th>Qty.</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody t-if="website_sale_order.order_line">
|
||||
<t t-foreach="website_sale_order.order_line" t-as="line">
|
||||
<tr>
|
||||
<td><t t-esc="line.name"/></td>
|
||||
<td><t t-esc="line.product_uom_qty"/></td>
|
||||
<td><t t-esc="line.price_unit"/> €</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><th>Untaxed Amount</th><td></td><td><t t-esc="website_sale_order.amount_untaxed"/> €</td></tr>
|
||||
<tr><th>Taxes</th><td></td><td><t t-esc="website_sale_order.amount_tax"/> €</td></tr>
|
||||
<tr><th>Total</th><td></td><td><t t-esc="website_sale_order.amount_total"/> €</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="js_payment row">
|
||||
<h3 class="col-md-12">Click on your payment method</h3>
|
||||
<div class="col-md-2">
|
||||
<t t-foreach="payments or []" t-as="payment">
|
||||
<label>
|
||||
<input t-att-value="payment.id" type="radio" name="payment_type"/> <t t-esc="payment.name"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
<t t-foreach="payments or []" t-as="payment">
|
||||
<div t-att-data-id="payment.id" t-raw="payment._content" class="hidden col-md-6"/>
|
||||
</t>
|
||||
<a t-href="/shop/payment_validate/" class="hidden btn btn-default">I validate my payment</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 oe_mycart">
|
||||
<table class='table table-striped table-condensed' id="mycart_products" t-if="website_sale_order and website_sale_order.order_line">
|
||||
<colgroup>
|
||||
<col width="80"/>
|
||||
<col/>
|
||||
<col width="100"/>
|
||||
<col width="120"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="2">Product</th>
|
||||
<th>Price</th>
|
||||
<th>Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="website_sale_order.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/#{ line.product_id.product_tmpl_id.id }/"><img class="img-rounded" t-att-src="line.product_id.img('image_small')"/></a>
|
||||
</td>
|
||||
<td t-if="line.product_id.product_tmpl_id">
|
||||
<strong t-field="line.product_id.name"/>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<span t-field="line.price_unit"></span> €
|
||||
</td>
|
||||
<td>
|
||||
<div t-esc="line.product_uom_qty"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class='pull-right mb16' id="mycart_total">
|
||||
<colgroup>
|
||||
<col width="100"/>
|
||||
<col width="120"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr style="border-top: 1px solid #000">
|
||||
<th><h3>Total:</h3></th>
|
||||
<th class="text-right"><h3><t t-esc="website_sale_order and website_sale_order.amount_total or 0"/> €</h3></th>
|
||||
</tr>
|
||||
<tr class="text-muted">
|
||||
<td><abbr title="Taxes may be updated after providing shipping address">Incl. Taxes:</abbr></td>
|
||||
<td class="text-right"><t t-esc="website_sale_order and website_sale_order.amount_tax or 0"/> €</td>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
<div class="clearfix"/>
|
||||
<div class="oe_structure"/>
|
||||
</div>
|
||||
<div class="col-md-3 col-md-offset-1 text-muted" id="right_column">
|
||||
<h4>Bill To:</h4>
|
||||
<div t-field="website_sale_order.partner_invoice_id"/>
|
||||
<div>
|
||||
<a href="/shop/checkout"><span class="icon-arrow-right"/> Change Address</a>
|
||||
</div>
|
||||
|
||||
<h4 class="mt32">Ship To:</h4>
|
||||
<div t-field="website_sale_order.partner_shipping_id"/>
|
||||
<div>
|
||||
<a href="/shop/checkout"><span class="icon-arrow-right"/> Change Address</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="js_payment mb64">
|
||||
<p>Select your payment method:</p>
|
||||
<div>
|
||||
<t t-foreach="payments or []" t-as="payment">
|
||||
<label>
|
||||
<input t-att-value="payment.id" type="radio" name="payment_type"/> <t t-esc="payment.name"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
<t t-foreach="payments or []" t-as="payment">
|
||||
<div t-att-data-id="payment.id" t-raw="payment._content" class="hidden"/>
|
||||
</t>
|
||||
<a t-href="/shop/payment_validate/" class="btn btn-primary mt16">Validate & Pay <span class="icon-long-arrow-right"/></a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="oe_structure"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
|
||||
@@ -34,13 +34,15 @@ class sale_order(osv.Model):
|
||||
class sale_order_line(osv.Model):
|
||||
_inherit = "sale.order.line"
|
||||
|
||||
def _recalculate_product_values(self, cr, uid, ids, product_id=None, context=None):
|
||||
def _recalculate_product_values(self, cr, uid, ids, product_id=0, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
user_obj = self.pool.get('res.users')
|
||||
product_id = product_id or ids and self.browse(cr, uid, ids[0], context=context).product_id.id
|
||||
product_id = product_id and int(product_id) or \
|
||||
ids and self.browse(cr, uid, ids[0], context=context).product_id.id
|
||||
|
||||
return self.product_id_change(
|
||||
cr, SUPERUSER_ID, [],
|
||||
cr, SUPERUSER_ID, ids,
|
||||
pricelist=context.pop('pricelist'),
|
||||
product=product_id,
|
||||
partner_id=user_obj.browse(cr, SUPERUSER_ID, uid).partner_id.id,
|
||||
|
||||