[MERGE] upstream

bzr revid: fme@openerp.com-20140115160017-tg0zqbogexo0ybhz
This commit is contained in:
Fabien Meghazi 2014-01-15 17:00:17 +01:00
commit 3755e320a0
45 changed files with 2321 additions and 1405 deletions

View File

@ -35,10 +35,6 @@ to an appropriate local partner, based on the distance and the weight that was a
""",
'author': 'OpenERP SA',
'depends': ['base_geolocalize', 'crm', 'account', 'portal'],
'demo': [
# 'res_partner_demo.xml',
'crm_lead_demo.xml'
],
'data': [
'security/ir.model.access.csv',
'res_partner_view.xml',
@ -50,7 +46,10 @@ to an appropriate local partner, based on the distance and the weight that was a
'portal_data.xml',
'report/crm_lead_report_view.xml',
'report/crm_partner_report_view.xml',
],
'demo': [
'res_partner_demo.xml',
'crm_lead_demo.xml'
],
'js': [
'static/src/js/next.js',

View File

@ -176,7 +176,7 @@ class email_template(osv.osv):
'mail_server_id': fields.many2one('ir.mail_server', 'Outgoing Mail Server', readonly=False,
help="Optional preferred server for outgoing mails. If not set, the highest "
"priority one will be used."),
'body_html': fields.text('Body', translate=True, help="Rich-text/HTML version of the message (placeholders may be used here)"),
'body_html': fields.html('Body', translate=True, help="Rich-text/HTML version of the message (placeholders may be used here)"),
'report_name': fields.char('Report Filename', translate=True,
help="Name to use for the generated report file (may contain placeholders)\n"
"The extension can be omitted and will then come from the report type."),

View File

@ -12,5 +12,9 @@
<field name="journal_id" ref="analytic_journal"/>
</record>
<record id="product.product_product_consultant" model="product.product">
<field name="sale_ok">True</field>
</record>
</data>
</openerp>

View File

@ -198,6 +198,7 @@ parameter) will see those record just disappear.
<field name="name">Service</field>
<field name="categ_id" ref="product.product_category_all"/>
<field name="type">service</field>
<field name="sale_ok">False</field>
</record>
<!-- Product Public Categories -->

View File

@ -400,7 +400,7 @@
<field name="name">product.public.category.form</field>
<field name="model">product.public.category</field>
<field name="arch" type="xml">
<form string="Product Categories" version="7.0">
<form string="Pos/Public Categories" version="7.0">
<sheet>
<field name="image_medium" widget='image' class="oe_avatar oe_right"/>
<div class="oe_left">
@ -426,7 +426,7 @@
</field>
</record>
<record id="product_public_category_action" model="ir.actions.act_window">
<field name="name">Public Categories</field>
<field name="name">Pos/Public Product Categories</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.public.category</field>
<field name="view_type">form</field>
@ -445,7 +445,7 @@
</p>
</field>
</record>
<menuitem action="product_public_category_action" id="menu_product_public_category" parent="base.menu_product" sequence="10" />
<menuitem action="product_public_category_action" id="menu_product_public_category" parent="prod_config_main" sequence="10" />
<!-- END -->
<!-- Unit of Measure -->
@ -802,7 +802,7 @@
<field name="mes_type"/>
</group>
<group colspan="4" string="Product Variants">
<group colspan="4" string="Product Variants" groups="product.group_product_variant">
<field colspan="4" name="product_variant_ids" nolabel="1">
<tree string="Product Variants" editable="bottom">
<field name="active"/>

View File

@ -78,6 +78,9 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
'module_sale_stock': fields.boolean("Trigger delivery orders automatically from sales orders",
help='Allows you to Make Quotation, Sale Order using different Order policy and Manage Related Stock.\n'
'-This installs the module sale_stock.'),
'group_sale_delivery_address': fields.boolean("Allow a different address for delivery and invoicing ",
implied_group='sale.group_delivery_invoice_address',
help="Allows you to specify different delivery and invoice addresses on a sales order."),
}
def default_get(self, cr, uid, fields, context=None):

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_sales_config" model="ir.ui.view">
<field name="name">sale settings</field>
<field name="model">sale.config.settings</field>
@ -41,6 +40,10 @@
<field name="module_warning" class="oe_inline"/>
<label for="module_warning"/>
</div>
<div>
<field name="group_sale_delivery_address" class="oe_inline"/>
<label for="group_sale_delivery_address"/>
</div>
</div>
<group name="Sale" position="before">
<group>
@ -58,7 +61,7 @@
</group>
</group>
<group name="Sale" position="before">
<group>
<group name="Product Features">
<label for="id" string="Product Features"/>
<div>
<div>

View File

@ -28,9 +28,6 @@ class sale_configuration(osv.osv_memory):
_inherit = 'sale.config.settings'
_columns = {
'group_sale_delivery_address': fields.boolean("Allow a different address for delivery and invoicing ",
implied_group='sale.group_delivery_invoice_address',
help="Allows you to specify different delivery and invoice addresses on a sales order."),
'group_invoice_deli_orders': fields.boolean('Generate invoices after and based on delivery orders',
implied_group='sale_stock.group_invoice_deli_orders',
help="To allow your salesman to make invoices for Delivery Orders using the menu 'Deliveries to Invoice'."),

View File

@ -8,12 +8,6 @@
<field name="inherit_id" ref="sale.view_sales_config"/>
<field name="arch" type="xml">
<data>
<xpath expr="//div[@name='Customer Features']" position="inside">
<div>
<field name="group_sale_delivery_address" class="oe_inline"/>
<label for="group_sale_delivery_address"/>
</div>
</xpath>
<xpath expr="//div[@name='group_invoice_so_lines']" position="replace">
<div>
<field name="group_invoice_so_lines" on_change="onchange_invoice_methods(group_invoice_so_lines, group_invoice_deli_orders)" class="oe_inline"/>

View File

@ -135,11 +135,16 @@ class Website(openerp.addons.web.controllers.main.Home):
view_model, view_theme_id = imd.get_object_reference(
request.cr, request.uid, 'website', 'theme')
user = request.registry['res.users'].browse(request.cr, request.uid, request.uid, request.context)
group_ids = [g.id for g in user.groups_id]
view = request.registry.get("ir.ui.view")
views = view._views_get(request.cr, request.uid, xml_id, request.context)
done = {}
result = []
for v in views:
if v.groups_id and [g for g in v.groups_id if g.id not in group_ids]:
continue
if v.inherit_option_id and v.inherit_option_id.id != view_theme_id or not optional:
if v.inherit_option_id.id not in done:
result.append({

View File

@ -1,3 +1,4 @@
sass:
sass -t expanded --compass --unix-newlines --watch website.sass:website.css&
sass -t expanded --compass --unix-newlines --watch editor.sass:editor.css&
sass -t expanded --compass --unix-newlines --watch snippets.sass:snippets.css&

View File

@ -81,6 +81,10 @@
outline: none !important;
}
.css_editable_display {
display: block !important;
}
.css_non_editable_mode_hidden {
display: none;
}
@ -89,18 +93,12 @@
display: none;
}
.oe_carousel_options {
cursor: pointer;
position: absolute;
white-space: nowrap;
z-index: 1;
display: none;
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child {
background-image: url("/website/static/src/img/edit_here.png") !important;
}
.oe_carousel_options > * {
display: inline-block !important;
vertical-align: middle !important;
position: relative !important;
top: 2px;
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before {
content: "Press The Top-Left Edit Button" !important;
}
/* ---- EDITOR BAR ---- {{{ */
@ -236,386 +234,6 @@ ul.oe_menu_editor .disclose {
z-index: 1000;
}
/* ---- SNIPPET EDITOR ---- {{{ */
#oe_snippets {
position: fixed;
left: 0px;
right: 0px;
background: #282828;
-webkit-box-shadow: 0px 10px 10px -10px black inset;
-moz-box-shadow: 0px 10px 10px -10px black inset;
box-shadow: 0px 10px 10px -10px black inset;
z-index: 1010;
overflow: hidden;
}
#oe_snippets:hover {
height: auto;
}
#oe_snippets .scroll {
white-space: nowrap;
overflow-y: none;
}
#oe_snippets .nav {
display: inline-block;
border-bottom: none !important;
vertical-align: middle;
min-width: 120px;
z-index: 1;
}
#oe_snippets .nav > li {
display: block;
float: none;
}
#oe_snippets .nav > li.active {
background: black !important;
}
#oe_snippets .nav > li > a {
padding: 2px 10px !important;
width: 100%;
display: block;
border: 0;
}
#oe_snippets .pill-content {
border: 0;
}
#oe_snippets .tab-content {
display: inline-block;
white-space: nowrap;
background: black;
}
#oe_snippets .tab-content > div {
background: black;
}
#oe_snippets .tab-content > div label {
width: 44px;
color: white;
padding-left: 10px;
}
#oe_snippets .tab-content > div label div {
width: 100px;
text-align: center;
-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 {
float: left;
vertical-align: top;
width: 93px;
margin-left: 1px;
margin-top: 0px;
position: relative;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
cursor: move;
pointer-events: none;
}
.oe_snippet .oe_snippet_thumbnail {
pointer-events: auto;
text-align: center;
height: 100%;
background: transparent;
color: white;
position: relative;
}
.oe_snippet .oe_snippet_thumbnail:hover .oe_snippet_thumbnail_img {
-webkit-transform: scale(0.95, 0.95);
-moz-transform: scale(0.95, 0.95);
-ms-transform: scale(0.95, 0.95);
-o-transform: scale(0.95, 0.95);
transform: scale(0.95, 0.95);
}
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_title {
font-size: 12px;
display: block;
text-shadow: 0 0 2px black;
}
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_img {
height: 74px;
-webkit-transition: all 150ms linear;
-moz-transition: all 150ms linear;
-o-transition: all 150ms linear;
transition: all 150ms linear;
-webkit-box-shadow: inset 0px 0px 0px 3px #333333;
-moz-box-shadow: inset 0px 0px 0px 3px #333333;
box-shadow: inset 0px 0px 0px 3px #333333;
-webkit-transform: scale(1, 1);
-moz-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
.oe_snippet .oe_snippet_thumbnail span, .oe_snippet .oe_snippet_thumbnail div {
line-height: 18px;
}
.oe_snippet > :not(.oe_snippet_thumbnail) {
display: none !important;
}
#oe_snippets .oe_snippet_thumbnail {
background: #747474, -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, rgba(0, 0, 0, 0.25)), color-stop(100%, rgba(0, 0, 0, 0.4)));
background: #747474, -webkit-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, -moz-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, -o-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
}
/* ---- SNIPPETS DROP ZONES ---- {{{ */
.oe_drop_zone.oe_insert {
display: block;
height: 48px;
margin: 0px;
margin-top: -4px;
margin-bottom: -44px;
-webkit-transition: margin 250ms linear;
-moz-transition: margin 250ms linear;
-o-transition: margin 250ms linear;
transition: margin 250ms linear;
width: 100%;
position: absolute;
z-index: 1000;
}
.oe_drop_zone.oe_insert:not(.oe_vertical):before {
content: "";
display: block;
border-top: dashed 2px rgba(209, 178, 255, 0.72);
position: relative;
top: 0px;
}
.oe_drop_zone.oe_insert.oe_hover:before {
border-top: dashed 2px rgba(116, 255, 161, 0.72);
}
.oe_drop_zone.oe_insert.oe_vertical {
width: 48px;
float: left;
position: relative;
margin: 0px -24px !important;
}
.oe_drop_zone.oe_insert.oe_overlay {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: rgba(153, 0, 255, 0.5);
}
.oe_drop_zone, .oe_drop_zone_style {
border: none;
background: rgba(153, 0, 255, 0.3);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
}
.oe_drop_zone.oe_hover, .oe_drop_zone_style.oe_hover {
background: rgba(0, 255, 133, 0.3);
z-index: 1001;
}
.oe_drop_zone_style {
color: white;
height: 48px;
margin-bottom: 32px;
padding-top: 12px;
}
/* ---- SNIPPET MANIPULATOR ---- {{{ */
.resize_editor_busy {
background-color: rgba(0,0,0,0.1);
}
.oe_overlay {
display: none;
position: absolute;
background: transparent;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
-webkit-transition: opacity 100ms linear;
-moz-transition: opacity 100ms linear;
-o-transition: opacity 100ms linear;
transition: opacity 100ms linear;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
pointer-events: none;
}
.oe_overlay.oe_active {
display: block;
border-style: dashed;
border-width: 1px;
-webkit-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
-moz-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
border-color: rgba(0, 0, 0, 0.5);
}
.oe_overlay .oe_handle {
display: block !important;
pointer-events: auto;
position: absolute;
top: 50%;
left: 50%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 12px;
height: 12px;
margin: -2px;
}
.oe_overlay .oe_handle:before {
position: relative;
top: 50%;
left: 50%;
display: block;
background: white;
border: solid 1px rgba(0, 0, 0, 0.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
width: 18px;
height: 18px;
margin: -9px;
padding-left: 1px;
font-size: 14px;
line-height: 14px;
font-family: FontAwesome;
color: rgba(0, 0, 0, 0.5);
-webkit-transition: background 100ms linear;
-moz-transition: background 100ms linear;
-o-transition: background 100ms linear;
transition: background 100ms linear;
}
.oe_overlay .oe_handle:hover:before {
background: rgba(0, 0, 0, 0.5);
color: white;
-webkit-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
}
.oe_overlay .oe_handle.e {
left: auto;
top: 2px;
height: 100%;
right: -4px;
cursor: w-resize;
}
.oe_overlay .oe_handle.e:before {
content: "\F061";
}
.oe_overlay .oe_handle.s, .oe_overlay .oe_handle.size {
top: auto;
left: 2px;
width: 100%;
bottom: -4px;
cursor: n-resize;
}
.oe_overlay .oe_handle.s:before, .oe_overlay .oe_handle.size:before {
content: "\F063";
}
.oe_overlay .oe_handle.size {
border-style: dashed;
border-width: 0 0 1px 0;
border-color: rgba(0, 0, 0, 0.5);
}
.oe_overlay .oe_handle.size:before {
content: "Resize";
width: 64px;
text-align: center;
margin-left: -32px;
margin-top: -4px;
}
.oe_overlay .oe_handle.w {
top: 2px;
height: 100%;
left: -4px;
cursor: e-resize;
}
.oe_overlay .oe_handle.w:before {
content: "\F060";
}
.oe_overlay .oe_handle.n {
left: 2px;
width: 100%;
top: -4px;
cursor: s-resize;
}
.oe_overlay .oe_handle.n:before {
content: "\F062";
}
.oe_overlay .icon.btn {
display: inline-block;
}
.oe_overlay .oe_overlay_options {
position: absolute;
width: 100%;
text-align: center;
top: -11px;
z-index: 1002;
}
.oe_overlay .oe_overlay_options .btn, .oe_overlay .oe_overlay_options a {
pointer-events: auto;
cursor: pointer;
}
.oe_overlay .oe_overlay_options .dropdown {
display: inline-block;
}
.oe_overlay .oe_overlay_options .dropdown-menu {
text-align: left;
min-width: 180px;
}
.oe_overlay .oe_overlay_options .dropdown-menu select, .oe_overlay .oe_overlay_options .dropdown-menu input {
display: block;
}
.oe_handle {
pointer-events: auto;
position: absolute;
top: 50%;
left: 50%;
display: block;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 8px;
height: 8px;
margin: -4px;
}
.s-resize-important, .s-resize-important * {
cursor: s-resize !important;
}
.n-resize-important, .n-resize-important * {
cursor: n-resize !important;
}
.e-resize-important, .e-resize-important * {
cursor: e-resize !important;
}
.w-resize-important, .w-resize-important * {
cursor: w-resize !important;
}
.move-important, .move-important * {
cursor: move !important;
}
/* ---- MOBILE PREVIEW ---- {{{ */
.oe_mobile_preview.modal .modal-content {
height: 660px;

View File

@ -67,23 +67,20 @@
.oe_editable:focus
outline: none !important
.css_editable_display
display: block !important
.css_non_editable_mode_hidden
display: none
.cke_editable .css_editable_mode_hidden
display: none
.oe_carousel_options
cursor: pointer
position: absolute
white-space: nowrap
z-index: 1
display: none
> *
display: inline-block !important
vertical-align: middle !important
position: relative !important
top: +2px
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child
background-image: url('/website/static/src/img/edit_here.png') !important
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
content: 'Press The Top-Left Edit Button' !important
// }}}
@ -207,281 +204,6 @@ ul.oe_menu_editor
// }}}
/* ---- SNIPPET EDITOR ---- {{{ */
#oe_snippets
position: fixed
left: 0px
right: 0px
// top property is set programmatically
background: rgb(40,40,40)
+box-shadow(0px 10px 10px -10px black inset)
z-index: 1010
overflow: hidden
&:hover
height: auto
.scroll
white-space: nowrap
overflow-y: none
.nav
display: inline-block
border-bottom: none !important
vertical-align: middle
min-width: 120px
> li
display: block
float: none
&.active
background: black !important
> a
padding: 2px 10px !important
width: 100%
display: block
border: 0
z-index: 1
.pill-content
border: 0
.tab-content
display: inline-block
white-space: nowrap
background: black
> div
background: rgb(0,0,0)
label
width: 44px
color: #fff
padding-left: 10px
div
width: 100px
text-align: center
@include transform( translate(-39px, 44px) , rotate(-90deg) )
@include transform-origin(50% 50%)
.oe_snippet
float: left
vertical-align: top
width: 93px
margin-left: 1px
margin-top: 0px
position: relative
overflow: hidden
+user-select(none)
cursor: move
pointer-events: none
.oe_snippet_thumbnail
pointer-events: auto
text-align: center
height: 100%
background: transparent
color: white
position: relative
&:hover
.oe_snippet_thumbnail_img
@include transform( scale(.95,.95))
.oe_snippet_thumbnail_title
font-size: 12px
display: block
+text-shadow(0 0 2px rgb(0,0,0))
.oe_snippet_thumbnail_img
height: 74px
@include transition(all 150ms linear)
+box-shadow(inset 0px 0px 0px 3px #333333)
@include transform( scale(1,1))
span, div
line-height: 18px
& > :not(.oe_snippet_thumbnail)
display: none !important
#oe_snippets .oe_snippet_thumbnail
@include background(#747474, radial-gradient(rgba(0,0,0,0.25),rgba(0,0,0,0.4)))
// }}}}
/* ---- SNIPPETS DROP ZONES ---- {{{ */
.oe_drop_zone.oe_insert
display: block
height: 48px
margin: 0px
margin-top: -4px
margin-bottom: -44px
@include transition(margin 250ms linear)
width: 100%
position: absolute
z-index: 1000
&:not(.oe_vertical):before
content: ""
display: block
border-top: dashed 2px rgba(209, 178, 255, 0.72)
position: relative
top: 0px
&.oe_hover:before
border-top: dashed 2px rgba(116, 255, 161, 0.72)
&.oe_vertical
width: 48px
float: left
position: relative
margin: 0px -24px !important
&.oe_overlay
+border-radius(3px)
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
//background-size: 100px 100px
background: rgba(153, 0, 255,.5)
.oe_drop_zone, .oe_drop_zone_style
border: none
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
//background-size: 100px 100px
background: rgba(153, 0, 255, .3)
+border-radius(4px)
&.oe_hover
background: rgba(0, 255, 133, .3)
z-index: 1001
.oe_drop_zone_style
color: white
height: 48px
margin-bottom: 32px
padding-top: 12px
// }}}
/* ---- SNIPPET MANIPULATOR ---- {{{ */
.resize_editor_busy
background-color: rgba(0,0,0,0.3)
.oe_overlay
display: none
position: absolute
background: transparent
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.02) ,rgba(255,255,255,.02) 35px, rgba(0,0,0,.02) 35px, rgba(0,0,0,.02) 75px))
+border-radius(3px)
@include transition(opacity 100ms linear)
+box-sizing(border-box)
pointer-events: none
&.oe_active
display: block
border-style: dashed
border-width: 1px
+box-shadow(0px 0px 0px 1px rgba(255,255,255,0.3), 0px 0px 0px 1px rgba(255,255,255,0.3) inset)
border-color: rgba(0, 0, 0, 0.5)
.oe_handle
display: block !important
pointer-events: auto
position: absolute
top: 50%
left: 50%
+box-sizing(border-box)
width: 12px
height: 12px
margin: -2px
&:before
position: relative
top: 50%
left: 50%
display: block
background: rgba(255, 255, 255, 1)
border: solid 1px rgba(0, 0, 0, .2)
+border-radius(5px)
width: 18px
height: 18px
margin: -9px
padding-left: 1px
font-size: 14px
line-height: 14px
font-family: FontAwesome
color: rgba(0,0,0,.5)
@include transition(background 100ms linear)
&:hover:before
background: rgba(0, 0, 0, .5)
color: #fff
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
.oe_handle.e
left: auto
top: 2px
height: 100%
right: -4px
cursor: w-resize
&:before
content: "\F061"
.oe_handle.s, .oe_handle.size
top: auto
left: 2px
width: 100%
bottom: -4px
cursor: n-resize
&:before
content: "\F063"
.oe_handle.size
border-style: dashed
border-width: 0 0 1px 0
border-color: rgba(0, 0, 0, 0.5)
&:before
content: "Resize"
width: 64px
text-align: center
margin-left: -32px
margin-top: -4px
.oe_handle.w
top: 2px
height: 100%
left: -4px
cursor: e-resize
&:before
content: "\F060"
.oe_handle.n
left: 2px
width: 100%
top: -4px
cursor: s-resize
&:before
content: "\F062"
.icon.btn
display: inline-block
.oe_overlay_options
position: absolute
width: 100%
text-align: center
top: -11px
z-index: 1002
.btn, a
pointer-events: auto
cursor: pointer
.dropdown
display: inline-block
.dropdown-menu
text-align: left
min-width: 180px
.dropdown-menu select,.dropdown-menu input
display: block
.oe_handle
pointer-events: auto
position: absolute
top: 50%
left: 50%
display: block
+box-sizing(border-box)
width: 8px
height: 8px
margin: -4px
.s-resize-important, .s-resize-important *
cursor: s-resize !important
.n-resize-important, .n-resize-important *
cursor: n-resize !important
.e-resize-important, .e-resize-important *
cursor: e-resize !important
.w-resize-important, .w-resize-important *
cursor: w-resize !important
.move-important, .move-important *
cursor: move !important
// }}}
/* ---- MOBILE PREVIEW ---- {{{ */
$mobile_preview_background: #000000

View File

@ -1,220 +1,588 @@
/* ---- SNIPPET EDITOR ---- {{{ */
#oe_snippets {
position: fixed;
left: 0px;
right: 0px;
background: #282828;
-webkit-box-shadow: 0px 10px 10px -10px black inset;
-moz-box-shadow: 0px 10px 10px -10px black inset;
box-shadow: 0px 10px 10px -10px black inset;
z-index: 1010;
overflow: hidden;
}
#oe_snippets:hover {
height: auto;
}
#oe_snippets .scroll {
white-space: nowrap;
overflow-y: none;
}
#oe_snippets .nav {
display: inline-block;
border-bottom: none !important;
vertical-align: middle;
min-width: 120px;
z-index: 1;
}
#oe_snippets .nav > li {
display: block;
float: none;
}
#oe_snippets .nav > li.active {
background: black !important;
}
#oe_snippets .nav > li > a {
padding: 2px 10px !important;
width: 100%;
display: block;
border: 0;
}
#oe_snippets .pill-content {
border: 0;
}
#oe_snippets .tab-content {
display: inline-block;
white-space: nowrap;
background: black;
}
#oe_snippets .tab-content > div {
background: black;
}
#oe_snippets .tab-content > div label {
width: 44px;
color: white;
padding-left: 10px;
}
#oe_snippets .tab-content > div label div {
width: 100px;
text-align: center;
-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 {
float: left;
vertical-align: top;
width: 93px;
margin-left: 1px;
margin-top: 0px;
position: relative;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
cursor: move;
pointer-events: none;
}
.oe_snippet .oe_snippet_thumbnail {
pointer-events: auto;
text-align: center;
height: 100%;
background: transparent;
color: white;
position: relative;
}
.oe_snippet .oe_snippet_thumbnail:hover .oe_snippet_thumbnail_img {
-webkit-transform: scale(0.95, 0.95);
-moz-transform: scale(0.95, 0.95);
-ms-transform: scale(0.95, 0.95);
-o-transform: scale(0.95, 0.95);
transform: scale(0.95, 0.95);
}
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_title {
font-size: 12px;
display: block;
text-shadow: 0 0 2px black;
}
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_img {
height: 74px;
-webkit-transition: all 150ms linear;
-moz-transition: all 150ms linear;
-o-transition: all 150ms linear;
transition: all 150ms linear;
-webkit-box-shadow: inset 0px 0px 0px 3px #333333;
-moz-box-shadow: inset 0px 0px 0px 3px #333333;
box-shadow: inset 0px 0px 0px 3px #333333;
-webkit-transform: scale(1, 1);
-moz-transform: scale(1, 1);
-ms-transform: scale(1, 1);
-o-transform: scale(1, 1);
transform: scale(1, 1);
}
.oe_snippet .oe_snippet_thumbnail span, .oe_snippet .oe_snippet_thumbnail div {
line-height: 18px;
}
.oe_snippet > :not(.oe_snippet_thumbnail) {
display: none !important;
}
#oe_snippets .oe_snippet_thumbnail {
background: #747474, -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, rgba(0, 0, 0, 0.25)), color-stop(100%, rgba(0, 0, 0, 0.4)));
background: #747474, -webkit-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, -moz-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, -o-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
background: #747474, radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
}
/* ---- SNIPPETS DROP ZONES ---- {{{ */
.oe_drop_zone.oe_insert {
display: block;
height: 48px;
margin: 0px;
margin-top: -4px;
margin-bottom: -44px;
-webkit-transition: margin 250ms linear;
-moz-transition: margin 250ms linear;
-o-transition: margin 250ms linear;
transition: margin 250ms linear;
width: 100%;
position: absolute;
z-index: 1000;
}
.oe_drop_zone.oe_insert:not(.oe_vertical):before {
content: "";
display: block;
border-top: dashed 2px rgba(209, 178, 255, 0.72);
position: relative;
top: 0px;
}
.oe_drop_zone.oe_insert.oe_hover:before {
border-top: dashed 2px rgba(116, 255, 161, 0.72);
}
.oe_drop_zone.oe_insert.oe_vertical {
width: 48px;
float: left;
position: relative;
margin: 0px -24px !important;
}
.oe_drop_zone.oe_insert.oe_overlay {
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
background: rgba(153, 0, 255, 0.5);
}
.oe_drop_zone, .oe_drop_zone_style {
border: none;
background: rgba(153, 0, 255, 0.3);
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
}
.oe_drop_zone.oe_hover, .oe_drop_zone_style.oe_hover {
background: rgba(0, 255, 133, 0.3);
z-index: 1001;
}
.oe_drop_zone_style {
color: white;
height: 48px;
margin-bottom: 32px;
padding-top: 12px;
}
/* ---- SNIPPET MANIPULATOR ---- {{{ */
.resize_editor_busy {
background-color: rgba(0, 0, 0, 0.3);
}
.oe_overlay {
display: none;
position: absolute;
background: transparent;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
-ms-border-radius: 3px;
-o-border-radius: 3px;
border-radius: 3px;
-webkit-transition: opacity 100ms linear;
-moz-transition: opacity 100ms linear;
-o-transition: opacity 100ms linear;
transition: opacity 100ms linear;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
pointer-events: none;
}
.oe_overlay.oe_active {
display: block;
border-style: dashed;
border-width: 1px;
-webkit-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
-moz-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
border-color: rgba(0, 0, 0, 0.5);
}
.oe_overlay .oe_handle {
display: block !important;
pointer-events: auto;
position: absolute;
top: 50%;
left: 50%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 16px;
height: 16px;
margin: -2px;
}
.oe_overlay .oe_handle.e:before, .oe_overlay .oe_handle.w:before, .oe_overlay .oe_handle.s:before, .oe_overlay .oe_handle.n:before, .oe_overlay .oe_handle.size .oe_handle_button {
position: relative;
top: 50%;
left: 50%;
display: block;
background: white;
border: solid 1px rgba(0, 0, 0, 0.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
width: 18px;
height: 18px;
margin: -9px;
padding-left: 1px;
font-size: 14px;
line-height: 14px;
font-family: FontAwesome;
color: rgba(0, 0, 0, 0.5);
-webkit-transition: background 100ms linear;
-moz-transition: background 100ms linear;
-o-transition: background 100ms linear;
transition: background 100ms linear;
}
.oe_overlay .oe_handle.e:hover:before, .oe_overlay .oe_handle.w:hover:before, .oe_overlay .oe_handle.s:hover:before, .oe_overlay .oe_handle.n:hover:before {
background: rgba(0, 0, 0, 0.5);
color: white;
-webkit-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
}
.oe_overlay .oe_handle.e {
left: auto;
top: 2px;
height: 100%;
right: -6px;
cursor: w-resize;
}
.oe_overlay .oe_handle.e:before {
content: "\F061";
}
.oe_overlay .oe_handle.s {
top: auto;
left: 2px;
width: 100%;
bottom: -6px;
cursor: n-resize;
}
.oe_overlay .oe_handle.s:before {
z-index: 0;
content: "\F063";
}
.oe_overlay .oe_handle.size {
top: auto;
left: 2px;
width: 100%;
bottom: -6px;
}
.oe_overlay .oe_handle.size .oe_handle_button {
z-index: 1;
content: "Resize";
width: 64px;
text-align: center;
margin-left: -32px;
margin-top: -10px;
cursor: row-resize;
}
.oe_overlay .oe_handle.size .oe_handle_button:hover {
background: rgba(30, 30, 30, 0.8);
color: white;
-webkit-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
}
.oe_overlay .oe_handle.size div {
border-style: dashed;
border-width: 0 0 1px 0;
border-color: rgba(0, 0, 0, 0.5);
position: relative;
top: 8px;
}
.oe_overlay .oe_handle.w {
top: 2px;
height: 100%;
left: -6px;
cursor: e-resize;
}
.oe_overlay .oe_handle.w:before {
content: "\F060";
}
.oe_overlay .oe_handle.n {
left: 2px;
width: 100%;
top: -6px;
cursor: s-resize;
}
.oe_overlay .oe_handle.n:before {
content: "\F062";
}
.oe_overlay .icon.btn {
display: inline-block;
}
.oe_overlay .oe_overlay_options {
position: absolute;
width: 100%;
text-align: center;
top: -11px;
z-index: 1002;
}
.oe_overlay .oe_overlay_options .btn, .oe_overlay .oe_overlay_options a {
pointer-events: auto;
cursor: pointer;
}
.oe_overlay .oe_overlay_options .dropdown {
display: inline-block;
}
.oe_overlay .oe_overlay_options .dropdown-menu {
text-align: left;
min-width: 180px;
}
.oe_overlay .oe_overlay_options .dropdown-menu select, .oe_overlay .oe_overlay_options .dropdown-menu input {
display: block;
}
.s-resize-important, .s-resize-important * {
cursor: s-resize !important;
}
.n-resize-important, .n-resize-important * {
cursor: n-resize !important;
}
.e-resize-important, .e-resize-important * {
cursor: e-resize !important;
}
.w-resize-important, .w-resize-important * {
cursor: w-resize !important;
}
.move-important, .move-important * {
cursor: move !important;
}
/* add CSS for bootstrap dropdown multi level */
.dropdown-submenu{position:relative; z-index: 1000}
.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;}
.dropdown-submenu:hover>.dropdown-menu{display:block;}
.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;}
.dropdown-submenu:hover>a:after{border-left-color:#ffffff;}
.dropdown-submenu.pull-left{float:none;}
.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;}
/*
.oe_snippet_demo .oe_page{
margin-top: 50px;
margin-bottom: 300px;
padding-bottom: 10px;
}
.oe_snippet_demo .oe_page .oe_container{
min-height: 200px;
}
.oe_snippet_demo .oe_page *{
outline: 1px solid transparent;
-webkit-transiton: all 150ms linear;
}
.oe_snippet_demo .oe_page .oe_selected{
position: relative;
outline: 2px dashed rgba(151, 137, 255,0.5) !important;
cursor: pointer;
}
.oe_snippet_demo .oe_page .oe_selected:after{
content:'Insert Snippet Here';
position: absolute;
height:20px; left:-2px; right:-2px; bottom:-10px;
background: rgba(151, 137, 255, 1);
border-radius: 2px;
z-index: 800;
pointer-events :none;
color: white;
text-shadow: none;
font-size: 14px;
line-height: 20px;
text-align: center;
}
.oe_snippet_demo.oe_new .oe_page .oe_selected:after{
content:'';
height:100%;
top:0px; left:0px; right:0px; bottom:0px;
background: rgba(151, 137, 255, 0.2);
}
*/
.oe_snippet_editor{
position: fixed;
z-index: 1000;
bottom: 0;
left: 0;
right: 0;
height: 214px;
background: rgb(160,160,160);
box-shadow: 0 1px 3px rgb(100,100,100) inset;
.dropdown-submenu {
position: relative;
z-index: 1000;
}
.oe_snippet_list{
width: auto;
white-space: nowrap;
margin-left: 20px;
.dropdown-submenu > .dropdown-menu {
top: 0;
left: 100%;
margin-top: -6px;
margin-left: -1px;
-webkit-border-radius: 0 6px 6px 6px;
-moz-border-radius: 0 6px 6px 6px;
border-radius: 0 6px 6px 6px;
}
.oe_snippet_editor .oe_snippet{
box-sizing: border-box;
display: inline-block;
width: 220px;
height: 160px;
border-radius: 3px;
background: white;
margin: 20px 20px 20px 0;
cursor: pointer;
border: 2px solid transparent;
box-shadow: 0 1px 3px rgb(100,100,100);
position: relative;
top: 0;
overflow: hidden;
vertical-align: top;
user-select: none;
white-space: normal;
.dropdown-submenu:hover > .dropdown-menu {
display: block;
}
.dropdown-submenu:hover > a:after {
border-left-color: white;
}
.dropdown-submenu > a:after {
display: block;
content: " ";
float: right;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 5px 0 5px 5px;
border-left-color: #cccccc;
margin-top: 5px;
margin-right: -10px;
}
.dropdown-submenu.pull-left {
float: none;
}
.dropdown-submenu.pull-left > .dropdown-menu {
left: -100%;
margin-left: 10px;
-webkit-border-radius: 6px 0 6px 6px;
-moz-border-radius: 6px 0 6px 6px;
border-radius: 6px 0 6px 6px;
}
.oe_snippet_list {
width: auto;
white-space: nowrap;
margin-left: 20px;
}
.oe_snippet_editor .oe_snippet:after{
content: attr(name);
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
background: rgba(255,255,255,0.8);
text-align: center;
color: black;
padding: 8px;
.oe_snippet_editor {
position: fixed;
z-index: 1000;
bottom: 0;
left: 0;
right: 0;
height: 214px;
background: #a0a0a0;
box-shadow: 0 1px 3px #646464 inset;
}
.oe_snippet_editor .oe_snippet.oe_selected, .oe_snippet_editor .oe_snippet.oe_active{
border: 2px solid rgb(151, 137, 255);
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59);
.oe_snippet_editor .oe_snippet {
box-sizing: border-box;
display: inline-block;
width: 220px;
height: 160px;
border-radius: 3px;
background: white;
margin: 20px 20px 20px 0;
cursor: pointer;
border: 2px solid transparent;
box-shadow: 0 1px 3px #646464;
position: relative;
top: 0;
overflow: hidden;
vertical-align: top;
user-select: none;
white-space: normal;
}
.oe_snippet_editor .oe_snippet > *{
pointer-events: none;
margin-top: 16px;
line-height: 1em;
zoom: 0.6;
.oe_snippet_editor .oe_snippet:after {
content: attr(name);
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
background: rgba(255, 255, 255, 0.8);
text-align: center;
color: black;
padding: 8px;
}
.oe_snippet_editor .oe_snippet > .container{
margin-top: 15px;
zoom: 0.17;
line-height: 0.999em;
line-height: 1em;
.oe_snippet_editor .oe_snippet.oe_selected, .oe_snippet_editor .oe_snippet.oe_active {
border: 2px solid #9789ff;
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59);
}
.oe_snippet_editor .oe_snippet > .row{
margin-top: 0px;
zoom: 0.23;
line-height: 0.999em;
.oe_snippet_editor .oe_snippet > * {
pointer-events: none;
margin-top: 16px;
line-height: 1em;
zoom: 0.6;
}
.oe_snippet_editor .oe_snippet > .span6{
margin-top: 18px;
zoom: 0.34;
.oe_snippet_editor .oe_snippet > .container {
margin-top: 15px;
zoom: 0.17;
line-height: 0.999em;
line-height: 1em;
}
.oe_snippet_editor .oe_snippet > .span12{
margin-top: 16px;
zoom: 0.23;
.oe_snippet_editor .oe_snippet > .row {
margin-top: 0px;
zoom: 0.23;
line-height: 0.999em;
}
.oe_snippet_editor .oe_snippet > p{
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
font-size: 20px;
padding: 16px;
zoom: 1;
margin: 0px;
.oe_snippet_editor .oe_snippet > .span6 {
margin-top: 18px;
zoom: 0.34;
}
.oe_snippet_editor .oe_snippet.oe_new{
background: gray;
box-shadow: 0px 1px 3px rgb(90,90,90) inset;
border: 0px;
.oe_snippet_editor .oe_snippet > .span12 {
margin-top: 16px;
zoom: 0.23;
}
.oe_snippet_editor .oe_snippet.oe_new.oe_selected, .oe_snippet_editor .oe_snippet.oe_new.oe_active{
box-shadow: 0px 2px 0px 0px rgb(151,137,255) inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset;
.oe_snippet_editor .oe_snippet > p {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
font-size: 20px;
padding: 16px;
zoom: 1;
margin: 0px;
}
.oe_snippet_editor .oe_snippet.oe_new > *{
zoom:1;
margin: 0;
line-height: 160px;
text-align: center;
color: white;
font-size: 48px;
.oe_snippet_editor .oe_snippet.oe_new {
background: gray;
box-shadow: 0px 1px 3px #5a5a5a inset;
border: 0px;
}
.oe_snippet_editor .oe_snippet.oe_new:after{
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
background: transparent;
color: white;
text-shadow: 0px 1px 3px black;
line-height: 160px;
padding: 0px;
.oe_snippet_editor .oe_snippet.oe_new.oe_selected, .oe_snippet_editor .oe_snippet.oe_new.oe_active {
box-shadow: 0px 2px 0px 0px #9789ff inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset;
}
.oe_snippet_editor .oe_snippet.oe_new > * {
zoom: 1;
margin: 0;
line-height: 160px;
text-align: center;
color: white;
font-size: 48px;
}
.oe_snippet_editor .oe_snippet.oe_new:after {
position: absolute;
left: 0px;
right: 0px;
top: 0px;
bottom: 0px;
background: transparent;
color: white;
text-shadow: 0px 1px 3px black;
line-height: 160px;
padding: 0px;
}
.oe_snippet_drop {
position: relative;
border: 2px dashed rgb(174, 52, 255);
background: rgba(147, 52, 255, 0.1);
min-height: 28px;
margin: -16px auto;
border-radius: 5px;
max-width: 50%;
position: relative;
border: 2px dashed #ae34ff;
background: rgba(147, 52, 255, 0.1);
min-height: 28px;
margin: -16px auto;
border-radius: 5px;
max-width: 50%;
}
.oe_snippet_drop.oe_accepting {
border: 2px dashed rgb(52, 255, 166);
background: rgba(52, 255, 190, 0.1);
border: 2px dashed #34ffa6;
background: rgba(52, 255, 190, 0.1);
}
/*
[class*="span"]{
margin-left: 0px !important;
}
*/
#website-top-edit li.oe_snippet_editorbar {
padding: 1px 8px 2px;
font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;
float: left;
margin-top: 6px;
border: 1px solid #a6a6a6;
border-bottom-color: #979797;
background: #eeeeee;
border-radius: 3px;
padding: 1px 8px 2px;
font: normal normal normal 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif;
float: left;
margin-top: 6px;
border: 1px solid #a6a6a6;
border-bottom-color: #979797;
background: #eeeeee;
border-radius: 3px;
}
#website-top-edit li.oe_snippet_editorbar > * {
display: inline-block;
height: 22px;
padding: 4px 6px;
outline: 0;
border: 0;
display: inline-block;
height: 22px;
padding: 4px 6px;
outline: 0;
border: 0;
}
#website-top-edit li.oe_snippet_editorbar a.button .icon {
cursor: inherit;
background-repeat: no-repeat;
margin-top: 1px;
width: 16px;
height: 16px;
display: inline-block;
cursor: inherit;
background-repeat: no-repeat;
margin-top: 1px;
width: 16px;
height: 16px;
display: inline-block;
}
[data-snippet-id] {
min-height: 10px;
min-width: 10px;
min-height: 10px;
min-width: 10px;
}

View File

@ -0,0 +1,467 @@
@import "compass/css3"
@import "compass/css3/user-interface"
@import "compass/css3/transition"
/* ---- SNIPPET EDITOR ---- {{{ */
#oe_snippets
position: fixed
left: 0px
right: 0px
// top property is set programmatically
background: rgb(40,40,40)
+box-shadow(0px 10px 10px -10px black inset)
z-index: 1010
overflow: hidden
&:hover
height: auto
.scroll
white-space: nowrap
overflow-y: none
.nav
display: inline-block
border-bottom: none !important
vertical-align: middle
min-width: 120px
> li
display: block
float: none
&.active
background: black !important
> a
padding: 2px 10px !important
width: 100%
display: block
border: 0
z-index: 1
.pill-content
border: 0
.tab-content
display: inline-block
white-space: nowrap
background: black
> div
background: rgb(0,0,0)
label
width: 44px
color: #fff
padding-left: 10px
div
width: 100px
text-align: center
@include transform( translate(-39px, 44px) , rotate(-90deg) )
@include transform-origin(50% 50%)
.oe_snippet
float: left
vertical-align: top
width: 93px
margin-left: 1px
margin-top: 0px
position: relative
overflow: hidden
+user-select(none)
cursor: move
pointer-events: none
.oe_snippet_thumbnail
pointer-events: auto
text-align: center
height: 100%
background: transparent
color: white
position: relative
&:hover
.oe_snippet_thumbnail_img
@include transform( scale(.95,.95))
.oe_snippet_thumbnail_title
font-size: 12px
display: block
+text-shadow(0 0 2px rgb(0,0,0))
.oe_snippet_thumbnail_img
height: 74px
@include transition(all 150ms linear)
+box-shadow(inset 0px 0px 0px 3px #333333)
@include transform( scale(1,1))
span, div
line-height: 18px
& > :not(.oe_snippet_thumbnail)
display: none !important
#oe_snippets .oe_snippet_thumbnail
@include background(#747474, radial-gradient(rgba(0,0,0,0.25),rgba(0,0,0,0.4)))
// }}}}
/* ---- SNIPPETS DROP ZONES ---- {{{ */
.oe_drop_zone.oe_insert
display: block
height: 48px
margin: 0px
margin-top: -4px
margin-bottom: -44px
@include transition(margin 250ms linear)
width: 100%
position: absolute
z-index: 1000
&:not(.oe_vertical):before
content: ""
display: block
border-top: dashed 2px rgba(209, 178, 255, 0.72)
position: relative
top: 0px
&.oe_hover:before
border-top: dashed 2px rgba(116, 255, 161, 0.72)
&.oe_vertical
width: 48px
float: left
position: relative
margin: 0px -24px !important
&.oe_overlay
+border-radius(3px)
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
//background-size: 100px 100px
background: rgba(153, 0, 255,.5)
.oe_drop_zone, .oe_drop_zone_style
border: none
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
//background-size: 100px 100px
background: rgba(153, 0, 255, .3)
+border-radius(4px)
&.oe_hover
background: rgba(0, 255, 133, .3)
z-index: 1001
.oe_drop_zone_style
color: white
height: 48px
margin-bottom: 32px
padding-top: 12px
// }}}
/* ---- SNIPPET MANIPULATOR ---- {{{ */
.resize_editor_busy
background-color: rgba(0,0,0,0.3)
.oe_overlay
display: none
position: absolute
background: transparent
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.02) ,rgba(255,255,255,.02) 35px, rgba(0,0,0,.02) 35px, rgba(0,0,0,.02) 75px))
+border-radius(3px)
@include transition(opacity 100ms linear)
+box-sizing(border-box)
pointer-events: none
&.oe_active
display: block
border-style: dashed
border-width: 1px
+box-shadow(0px 0px 0px 1px rgba(255,255,255,0.3), 0px 0px 0px 1px rgba(255,255,255,0.3) inset)
border-color: rgba(0, 0, 0, 0.5)
.oe_handle
display: block !important
pointer-events: auto
position: absolute
top: 50%
left: 50%
+box-sizing(border-box)
width: 16px
height: 16px
margin: -2px
&.e:before, &.w:before, &.s:before, &.n:before, &.size .oe_handle_button
position: relative
top: 50%
left: 50%
display: block
background: rgba(255, 255, 255, 1)
border: solid 1px rgba(0, 0, 0, .2)
+border-radius(5px)
width: 18px
height: 18px
margin: -9px
padding-left: 1px
font-size: 14px
line-height: 14px
font-family: FontAwesome
color: rgba(0,0,0,.5)
@include transition(background 100ms linear)
&.e, &.w, &.s, &.n
&:hover:before
background: rgba(0, 0, 0, .5)
color: #fff
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
&.e
left: auto
top: 2px
height: 100%
right: -6px
cursor: w-resize
&:before
content: "\F061"
&.s
top: auto
left: 2px
width: 100%
bottom: -6px
cursor: n-resize
&:before
z-index: 0
content: "\F063"
&.size
top: auto
left: 2px
width: 100%
bottom: -6px
.oe_handle_button
z-index: 1
content: "Resize"
width: 64px
text-align: center
margin-left: -32px
margin-top: -10px
cursor: row-resize
&:hover
background: rgba(30, 30, 30, .8)
color: #fff
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
div
border-style: dashed
border-width: 0 0 1px 0
border-color: rgba(0, 0, 0, 0.5)
position: relative
top: 8px
&.w
top: 2px
height: 100%
left: -6px
cursor: e-resize
&:before
content: "\F060"
&.n
left: 2px
width: 100%
top: -6px
cursor: s-resize
&:before
content: "\F062"
.icon.btn
display: inline-block
.oe_overlay_options
position: absolute
width: 100%
text-align: center
top: -11px
z-index: 1002
.btn, a
pointer-events: auto
cursor: pointer
.dropdown
display: inline-block
.dropdown-menu
text-align: left
min-width: 180px
.dropdown-menu select,.dropdown-menu input
display: block
.s-resize-important, .s-resize-important *
cursor: s-resize !important
.n-resize-important, .n-resize-important *
cursor: n-resize !important
.e-resize-important, .e-resize-important *
cursor: e-resize !important
.w-resize-important, .w-resize-important *
cursor: w-resize !important
.move-important, .move-important *
cursor: move !important
// }}}
/* add CSS for bootstrap dropdown multi level */
.dropdown-submenu
position: relative
z-index: 1000
.dropdown-submenu
&>.dropdown-menu
top: 0
left: 100%
margin-top: -6px
margin-left: -1px
-webkit-border-radius: 0 6px 6px 6px
-moz-border-radius: 0 6px 6px 6px
border-radius: 0 6px 6px 6px
&:hover
&>.dropdown-menu
display: block
&>a:after
border-left-color: #ffffff
&>a:after
display: block
content: " "
float: right
width: 0
height: 0
border-color: transparent
border-style: solid
border-width: 5px 0 5px 5px
border-left-color: #cccccc
margin-top: 5px
margin-right: -10px
&.pull-left
float: none
&>.dropdown-menu
left: -100%
margin-left: 10px
-webkit-border-radius: 6px 0 6px 6px
-moz-border-radius: 6px 0 6px 6px
border-radius: 6px 0 6px 6px
.oe_snippet_list
width: auto
white-space: nowrap
margin-left: 20px
.oe_snippet_editor
position: fixed
z-index: 1000
bottom: 0
left: 0
right: 0
height: 214px
background: rgb(160,160,160)
box-shadow: 0 1px 3px rgb(100,100,100) inset
.oe_snippet
box-sizing: border-box
display: inline-block
width: 220px
height: 160px
border-radius: 3px
background: white
margin: 20px 20px 20px 0
cursor: pointer
border: 2px solid transparent
box-shadow: 0 1px 3px rgb(100,100,100)
position: relative
top: 0
overflow: hidden
vertical-align: top
user-select: none
white-space: normal
&:after
content: attr(name)
position: absolute
bottom: 0px
left: 0px
right: 0px
background: rgba(255,255,255,0.8)
text-align: center
color: black
padding: 8px
&.oe_selected, &.oe_active
border: 2px solid rgb(151, 137, 255)
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59)
& > *
pointer-events: none
margin-top: 16px
line-height: 1em
zoom: 0.6
& > .container
margin-top: 15px
zoom: 0.17
line-height: 0.999em
line-height: 1em
& > .row
margin-top: 0px
zoom: 0.23
line-height: 0.999em
& > .span6
margin-top: 18px
zoom: 0.34
& > .span12
margin-top: 16px
zoom: 0.23
& > p
position: absolute
top: 0
right: 0
left: 0
bottom: 0
font-size: 20px
padding: 16px
zoom: 1
margin: 0px
&.oe_new
background: gray
box-shadow: 0px 1px 3px rgb(90,90,90) inset
border: 0px
&.oe_selected, &.oe_active
box-shadow: 0px 2px 0px 0px rgb(151,137,255) inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset
& > *
zoom: 1
margin: 0
line-height: 160px
text-align: center
color: white
font-size: 48px
&:after
position: absolute
left: 0px
right: 0px
top: 0px
bottom: 0px
background: transparent
color: white
text-shadow: 0px 1px 3px black
line-height: 160px
padding: 0px
.oe_snippet_drop
position: relative
border: 2px dashed rgb(174, 52, 255)
background: rgba(147, 52, 255, 0.1)
min-height: 28px
margin: -16px auto
border-radius: 5px
max-width: 50%
&.oe_accepting
border: 2px dashed rgb(52, 255, 166)
background: rgba(52, 255, 190, 0.1)
#website-top-edit
li.oe_snippet_editorbar
padding: 1px 8px 2px
font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif
float: left
margin-top: 6px
border: 1px solid #a6a6a6
border-bottom-color: #979797
background: #eeeeee
border-radius: 3px
& > *
display: inline-block
height: 22px
padding: 4px 6px
outline: 0
border: 0
a.button .icon
cursor: inherit
background-repeat: no-repeat
margin-top: 1px
width: 16px
height: 16px
display: inline-block
[data-snippet-id]
min-height: 10px
min-width: 10px

View File

@ -1,3 +1,4 @@
@charset "utf-8";
/* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
*
* css for editor buttons, openerp widget included in the website and other
@ -78,95 +79,6 @@
margin-bottom: 0px !important;
}
.pt128 {
padding-top: 128px !important;
}
.pt92 {
padding-top: 92px !important;
}
.pt64 {
padding-top: 64px !important;
}
.pt48 {
padding-top: 48px !important;
}
.pt32 {
padding-top: 32px !important;
}
.pt16 {
padding-top: 16px !important;
}
.pt8 {
padding-top: 8px !important;
}
.pt4 {
padding-top: 4px !important;
}
.pt0 {
padding-top: 0px !important;
}
.pb128 {
padding-bottom: 128px !important;
}
.pb92 {
padding-bottom: 92px !important;
}
.pb64 {
padding-bottom: 64px !important;
}
.pb48 {
padding-bottom: 48px !important;
}
.pb32 {
padding-bottom: 32px !important;
}
.pb16 {
padding-bottom: 16px !important;
}
.pb8 {
padding-bottom: 8px !important;
}
.pb4 {
padding-bottom: 4px !important;
}
.pb0 {
padding-bottom: 0px !important;
}
/* Grid of unequally tall elements */
.grid > [class*="col-md"] {
display: inline-block;
float: none;
vertical-align: top;
box-sizing: border-box;
}
.grid > [class*="col-md"].grid-align-top > [class*="col-md"] {
vertical-align: top;
}
.grid > [class*="col-md"].grid-align-middle > [class*="col-md"] {
vertical-align: middle;
}
.grid > [class*="col-md"].grid-align-bottom > [class*="col-md"] {
vertical-align: bottom;
}
/* Extra Styles */
img.shadow {
-webkit-border-radius: 3px;
@ -185,9 +97,14 @@ h1.text-muted, h2.text-muted, h3.text-muted {
}
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
.navbar.navbar-default.navbar-static-top {
.navbar.navbar-static-top {
margin-bottom: 0;
}
.navbar.navbar-static-top ul.nav > li.divider {
margin-top: 15px;
padding-top: 20px;
border-right: 1px solid grey;
}
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
html, body, #wrapwrap {
@ -209,7 +126,7 @@ header, main, footer {
footer {
height: 100%;
background: #eff8f8;
background: rgba(100, 200, 200, 0.1);
background: rgba(200, 200, 200, 0.1);
}
#footer_container {
@ -225,6 +142,7 @@ footer {
.row {
min-height: 32px;
width: 100%;
}
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
@ -233,7 +151,7 @@ footer {
}
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child {
background-image: url("/website/static/src/img/edit_here.png");
background-image: url("/website/static/src/img/under_construction.png");
background-repeat: no-repeat;
background-position: center;
height: 220px !important;
@ -244,7 +162,7 @@ footer {
}
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before {
content: "Press The Top-Left Edit Button";
content: "This page is under construction";
text-align: center;
display: block;
padding-top: 160px;
@ -257,6 +175,10 @@ footer {
content: "Drag Building Blocks Here";
}
.css_editable_display {
display: none;
}
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
.navbar .nav > li > p {
margin-bottom: 0px;
@ -334,10 +256,15 @@ ul.nav-stacked > li > a {
}
/* ---- SNIPPETS --- */
[data-snippet-id],.colmd,.hr,.blockquote {
overflow: hidden;
[data-snippet-id], .colmd, .hr, .blockquote {
overflow: hidden;
}
@media (max-width: 400px) {
[data-snippet-id] {
height: auto !important;
}
}
.carousel-inner {
height: 100%;
}
@ -345,6 +272,7 @@ ul.nav-stacked > li > a {
height: 100%;
background-size: 100%;
}
.carousel .carousel-caption {
left: auto;
right: auto;
@ -398,6 +326,10 @@ ul.nav-stacked > li > a {
right: 10px;
}
.quotecarousel {
padding-bottom: 16px;
}
/* Parallax Theme */
div.carousel[data-snippet-id="slider"] .carousel-indicators li {
border: 1px solid grey;
@ -431,7 +363,7 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
/* Background */
.oe_dark {
background: #eff8f8;
background: rgba(100, 200, 200, 0.14);
background: rgba(200, 200, 200, 0.14);
-webkit-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
-moz-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset;
@ -439,16 +371,55 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
.oe_black {
background-color: rgba(0, 0, 0, 0.9);
color: white;
}
.oe_green {
background-color: rgba(0, 128, 0, 0.8);
background-color: #51d466;
color: white;
}
.oe_green .text-muted {
color: #dddddd;
}
.oe_blue_light {
background-color: #4791d2;
color: white;
}
.oe_blue_light .text-muted {
color: #dddddd;
}
.oe_blue {
background-color: #34495e;
color: white;
}
.oe_orange {
background-color: #e67e22;
color: white;
}
.oe_orange .text-muted {
color: #dddddd;
}
.oe_purple {
background-color: #b163a3;
color: white;
}
.oe_purple .text-muted {
color: #dddddd;
}
.oe_red {
background-color: rgba(255, 0, 0, 0.8);
background-color: #f75353;
color: white;
}
.oe_red .text-muted {
color: #dddddd;
}
/* Misc */
.oe_img_bg {
background-size: 100%;
}
@ -508,45 +479,3 @@ span[data-oe-type="monetary"] {
-o-column-count: 3;
column-count: 3;
}
.bs-callout {
margin: 20px 0;
padding: 20px;
border-left: 3px solid #eeeeee;
}
.bs-callout h4 {
margin-top: 0;
margin-bottom: 5px;
}
.bs-callout p:last-child {
margin-bottom: 0;
}
.bs-callout-danger {
background-color: #fdf7f7;
border-color: #eed3d7;
}
.bs-callout-danger h4 {
color: #b94a48;
}
.bs-callout-warning {
background-color: #faf8f0;
border-color: #faebcc;
}
.bs-callout-warning h4 {
color: #8a6d3b;
}
.bs-callout-info {
background-color: #f4f8fa;
border-color: #bce8f1;
}
.bs-callout-info h4 {
color: #34789a;
}

View File

@ -51,57 +51,6 @@
.mb0
margin-bottom: 0px !important
.pt128
padding-top: 128px !important
.pt92
padding-top: 92px !important
.pt64
padding-top: 64px !important
.pt48
padding-top: 48px !important
.pt32
padding-top: 32px !important
.pt16
padding-top: 16px !important
.pt8
padding-top: 8px !important
.pt4
padding-top: 4px !important
.pt0
padding-top: 0px !important
.pb128
padding-bottom: 128px !important
.pb92
padding-bottom: 92px !important
.pb64
padding-bottom: 64px !important
.pb48
padding-bottom: 48px !important
.pb32
padding-bottom: 32px !important
.pb16
padding-bottom: 16px !important
.pb8
padding-bottom: 8px !important
.pb4
padding-bottom: 4px !important
.pb0
padding-bottom: 0px !important
/* Grid of unequally tall elements */
.grid > [class*="col-md"]
display: inline-block
float: none
vertical-align: top
box-sizing: border-box
&.grid-align-top > [class*="col-md"]
vertical-align: top
&.grid-align-middle > [class*="col-md"]
vertical-align: middle
&.grid-align-bottom > [class*="col-md"]
vertical-align: bottom
/* Extra Styles */
img.shadow
@ -114,8 +63,13 @@ h1.text-muted, h2.text-muted, h3.text-muted
/* ----- BOOTSTRAP HACK FOR HEADER NAV BAR ----- */
.navbar.navbar-default.navbar-static-top
.navbar.navbar-static-top
margin-bottom: 0
ul.nav
> li.divider
margin-top: 15px
padding-top: 20px
border-right: 1px solid grey
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
@ -133,7 +87,7 @@ header, main, footer
footer
height: 100%
background: rgb(239, 248, 248)
background: rgba(100, 200, 200, 0.1)
background: rgba(200, 200, 200, 0.1)
#footer_container
padding-top: 24px
@ -147,6 +101,7 @@ footer
.row
min-height: 32px
width: 100%
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
@ -154,7 +109,7 @@ footer
background-image: url('/website/static/src/img/drag_here.png')
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child
background-image: url('/website/static/src/img/edit_here.png')
background-image: url('/website/static/src/img/under_construction.png')
background-repeat: no-repeat
background-position: center
height: 220px !important
@ -163,7 +118,7 @@ footer
position: static
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
content: 'Press The Top-Left Edit Button'
content: 'This page is under construction'
text-align: center
display: block
padding-top: 160px
@ -174,6 +129,9 @@ footer
.oe_structure.oe_editable.oe_empty:empty:before, .oe_editable[data-oe-type=html]:empty:before, .oe_structure.oe_editable.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
content: 'Drag Building Blocks Here'
.css_editable_display
display: none
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
.navbar .nav > li > p
@ -245,6 +203,10 @@ ul.nav-stacked > li > a
[data-snippet-id],.colmd,.hr,.blockquote
overflow: hidden
@media (max-width: 400px)
[data-snippet-id]
height: auto !important
.carousel-inner
height: 100%
.item
@ -295,6 +257,8 @@ ul.nav-stacked > li > a
&.right span
right: 10px
.quotecarousel
padding-bottom: 16px
/* Parallax Theme */
@ -323,17 +287,52 @@ div.carousel[data-snippet-id="slider"]
padding: 32px 0
/* Background */
.oe_dark
background: #eff8f8
background: rgba(100, 200, 200, 0.14)
background: rgba(200, 200, 200, 0.14)
+box-shadow(0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset)
.oe_black
background-color: rgba(0, 0, 0, 0.9)
color: white
.oe_green
background-color: rgba(0, 128, 0, 0.8)
background-color: #51d466
color: white
.text-muted
color: #ddd
.oe_blue_light
background-color: #4791d2
color: white
.text-muted
color: #ddd
.oe_blue
background-color: #34495e
color: white
.oe_orange
background-color: #e67e22
color: white
.text-muted
color: #ddd
.oe_purple
background-color: #b163a3
color: white
.text-muted
color: #ddd
.oe_red
background-color: rgba(255, 0, 0, 0.8)
background-color: #f75353
color: white
.text-muted
color: #ddd
/* Misc */
.oe_img_bg
background-size: 100%
@ -379,30 +378,3 @@ span[data-oe-type="monetary"]
.oe_template_fallback
@include column-count(3)
// ---- Callouts from bootstrap doc ---- {{{
.bs-callout
margin: 20px 0
padding: 20px
border-left: 3px solid #eee
.bs-callout h4
margin-top: 0
margin-bottom: 5px
.bs-callout p:last-child
margin-bottom: 0
.bs-callout-danger
background-color: #fdf7f7
border-color: #eed3d7
.bs-callout-danger h4
color: #b94a48
.bs-callout-warning
background-color: #faf8f0
border-color: #faebcc
.bs-callout-warning h4
color: #8a6d3b
.bs-callout-info
background-color: #f4f8fa
border-color: #bce8f1
.bs-callout-info h4
color: #34789a
// }}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -49,7 +49,7 @@
function is_editable_node(element) {
return !(element.data('oe-model') === 'ir.ui.view'
|| element.data('cke-realelement')
|| is_editing_host(element)
|| (is_editing_host(element) && element.getAttribute('attributeEditable') !== 'true')
|| element.isReadOnly());
}

View File

@ -148,10 +148,13 @@
});
self.$el.css('top', this.parent.get('height'));
},
_get_snippet_url: function () {
return '/website/snippets';
},
fetch_snippet_templates: function () {
var self = this;
openerp.jsonRpc("/website/snippets", 'call', {})
openerp.jsonRpc(this._get_snippet_url(), 'call', {})
.then(function (html) {
var $html = $(html);
@ -180,11 +183,11 @@
$el.css({
'position': 'absolute',
'width': $target.outerWidth(),
'height': $target.outerHeight() + mt + mb,
'height': $target.outerHeight() + mt + mb+1,
'top': pos.top - mt,
'left': pos.left
});
$el.find(".oe_handle.size").css("bottom", mb+'px');
$el.find(".oe_handle.size").css("bottom", (mb-7)+'px');
},
show: function () {
this.$el.removeClass("hidden");
@ -951,6 +954,8 @@
clean_for_save: function () {
this.$target.removeAttr('contentEditable')
.find('*').removeAttr('contentEditable');
this.$target.removeAttr('attributeEditable')
.find('*').removeAttr('attributeEditable');
},
});
@ -970,7 +975,7 @@
this.$overlay.append($box.find(".oe_handles").html());
this.$overlay.find(".oe_handle").on('mousedown', function (event){
this.$overlay.find(".oe_handle:not(:has(.oe_handle_button)), .oe_handle .oe_handle_button").on('mousedown', function (event){
event.preventDefault();
var $handle = $(this);
@ -1004,7 +1009,6 @@
if (compass === 'size') {
var grid = resize[0];
var offset = self.$target.offset().top;
if (self.$target.css("background").match(/rgba\(0, 0, 0, 0\)/)) {
self.$target.addClass("resize_editor_busy");
@ -1032,10 +1036,10 @@
event.preventDefault();
if (compass === 'size') {
var dy = event.pageY-offset;
dy = dy - dy%resize[0];
if (dy <= 0) dy = resize[0];
dy = dy - dy%resize;
if (dy <= 0) dy = resize;
self.$target.css("height", dy+"px");
self.on_resize(compass, beginClass, current);
self.on_resize(compass, null, dy);
self.parent.cover_target(self.$overlay, self.$target);
return;
}
@ -1080,7 +1084,8 @@
// list of class (Array), grid (Array), default value (INT)
n: [_.map(grid, function (v) {return 'mt'+v;}), grid],
s: [_.map(grid, function (v) {return 'mb'+v;}), grid],
size: [8]
// INT if the user can resize the snippet (resizing per INT px)
size: null
};
return this.grid;
},
@ -1292,6 +1297,11 @@
});
website.snippet.editorRegistry.carousel = website.snippet.editorRegistry.slider.extend({
getSize: function () {
this.grid = this._super();
this.grid.size = 8;
return this.grid;
},
clean_for_save: function () {
this._super();
this.$target.css("background-image", "");
@ -1355,11 +1365,20 @@
self.$target.carousel( $(this).data('slide')); });
this.$target.find('.carousel-image, .content').attr('contentEditable', 'true');
this.$target.find('.carousel-image').attr('attributeEditable', 'true');
this._super();
},
});
website.snippet.editorRegistry.parallax = website.snippet.editorRegistry.resize.extend({
getSize: function () {
this.grid = this._super();
this.grid.size = 8;
return this.grid;
},
on_resize: function (compass, beginClass, current) {
this.$target.data("snippet-view").set_values();
},
start : function () {
var self = this;
this._super();

View File

@ -86,7 +86,7 @@
<div class='oe_handle n'></div>
<div class='oe_handle e'></div>
<div class='oe_handle w'></div>
<div class='oe_handle size'></div>
<div class='oe_handle size'><div class="oe_handle_button size">Resize</div><div class="oe_border"/></div>
<div class='oe_handle s'></div>
</div>
<div class='oe_snippet_thumbnail'>Margin resize</div>

View File

@ -44,6 +44,14 @@ class WebsiteUiSuite(unittest.TestSuite):
self._timeout = timeout
self._options = options
self._test = None
self._ignore_filters = [
# Ignore phantomjs warnings
"*** WARNING:",
# Fixes an issue with PhantomJS 1.9.2 on OS X 10.9 (Mavericks)
# cf. https://github.com/ariya/phantomjs/issues/11418
"CoreText performance note",
]
def __iter__(self):
return iter([self])
@ -97,9 +105,7 @@ class WebsiteUiSuite(unittest.TestSuite):
for stream in ready:
lines = stream.readlines()
if lines is None: # EOF
# Fixes an issue with PhantomJS 1.9.2 on OS X 10.9 (Mavericks)
# cf. https://github.com/ariya/phantomjs/issues/11418
filtered_lines = [line for line in output if "CoreText performance note" not in line]
filtered_lines = [line for line in output if not any(ignore in line for ignore in self._ignore_filters)]
if (filtered_lines):
self.process(filtered_lines, result)
readable.remove(stream)

View File

@ -117,7 +117,7 @@
Write one sentence to convince visitor about your message.
</p>
<p>
<a class="btn btn-primary btn-lg" href="/website.contactus">
<a class="btn btn-primary btn-lg" href="/page/website.contactus">
Contact us
</a>
</p>
@ -277,7 +277,7 @@
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
<span class="oe_snippet_thumbnail_title">Quotes Slider</span>
</div>
<div id="myQuoteCarousel" class="oe_snippet_body carousel slide mb0" style="height: 240px;">
<div id="myQuoteCarousel" class="oe_snippet_body carousel quotecarousel slide mb0">
<!-- Indicators -->
<ol class="carousel-indicators mb0">
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
@ -676,6 +676,118 @@
</section>
</div>
<div data-snippet-id="features" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
<span class="oe_snippet_thumbnail_title">Features</span>
</div>
<section class="oe_snippet_body mb16">
<div class="container">
<div class="row">
<div class="col-md-12 text-center mb16">
<h2>List of Features</h2>
<h4 class="text-muted">Add a great slogan</h4>
</div>
<div class="col-md-3 text-center">
<span class="fa fa-suitcase fa-5x"></span>
<h3 class="mt8 mb0">First Feature</h3>
<p class="text-muted">Tell what's the value for the customer for this feature.</p>
<p><a class="btn btn-primary">Learn More</a></p>
</div>
<div class="col-md-3 text-center">
<span class="fa fa-lock fa-5x"></span>
<h3 class="mt8 mb0">Second Feature</h3>
<p class="text-muted">Talk about what the customer would like to know, not what you want to show.</p>
<p><a class="btn btn-success">Take Tour</a></p>
</div>
<div class="col-md-3 text-center">
<span class="fa fa-heart fa-5x"></span>
<h3 class="mt8 mb0">Third Feature</h3>
<p class="text-muted">A small explanation of this great feature, in clear words.</p>
<p><a class="btn btn-info">Buy Now</a></p>
</div>
<div class="col-md-3 text-center">
<span class="fa fa-credit-card fa-5x"></span>
<h3 class="mt8 mb0">Fourth Feature</h3>
<p class="text-muted">A small explanation of this great feature on two lines.</p>
<p><a class="btn btn-danger">Buy Now</a></p>
</div>
</div>
</div>
</section>
</div>
<div data-snippet-id="features-list" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_features.png"/>
<span class="oe_snippet_thumbnail_title">Feature Grid</span>
</div>
<section class="oe_snippet_body mb16">
<div class="container">
<div class="row">
<div class="col-md-5 text-center mb16">
<h2>List of Features</h2>
<h4 class="text-muted">Add a great slogan</h4>
</div>
<div class="col-md-5 text-center mb16 col-md-offset-2">
<h2>Second List</h2>
<h4 class="text-muted">Add a great slogan</h4>
</div>
</div><div class="row">
<div class="col-md-5">
<ul class="list-unstyled">
<li>
<span style="min-width: 45px" class="fa fa-3x fa-comment pull-left mb16"></span>
<h3 class="mb0">Blog</h3>
<p>OpenERP includes a full features enterprise blog to promote your messages.</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-columns pull-left mb16"></span>
<h3 class="mb0">Pricing Tables</h3>
<p>Use building blocks to use pricing tables to display your products or services.</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-user pull-left mb16"></span>
<h3 class="mb0">Log In &amp; Signup</h3>
<p>Clean &amp; simple Log In, Signup &amp; Forgot Your Password forms.</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-envelope pull-left mb16"></span>
<h3 class="mb0">Contact</h3>
<p>User-friendly contact form with Google Map integration.</p>
</li>
</ul>
</div>
<div class="col-md-5 col-md-offset-2">
<ul class="list-unstyled">
<li>
<span style="min-width: 45px" class="fa fa-3x fa-magic pull-left mb16"></span>
<h3 class="mb0">Bootstrap</h3>
<p>Uses Twitter Bootstrap's sleek, intuitive, and powerful front-end framework.</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-font pull-left mb16"></span>
<h3 class="mb0">Google Web Fonts</h3>
<p>Royalty free, open source fonts for the people, by the people!</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-bolt pull-left mb16"></span>
<h3 class="mb0">Powerful &amp; slick jQuery</h3>
<p>Fantastic jQuery plugins such as Isotope and Bootstrap's inbuilt features.</p>
</li>
<li>
<span style="min-width: 45px" class="fa fa-3x fa-picture-o pull-left mb16"></span>
<h3 class="mb0">Sample images</h3>
<p>Fantastic sample images fully licensed for use.</p>
</li>
</ul>
</div>
</div>
</div>
</section>
</div>
</div>
<div id="snippet_effect" class="tab-pane fade">
@ -713,7 +825,7 @@
data-scroll-background-ratio="0.3">
<div>
<div class="oe_structure">
<div id="myQuoteCarousel" class="carousel slide mb0" style="height: 240px;" data-snippet-id="slider">
<div id="myQuoteCarousel" class="carousel quotecarousel slide mb0" data-snippet-id="slider">
<!-- Indicators -->
<ol class="carousel-indicators mb0">
<li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
@ -796,6 +908,10 @@
<li data-class='oe_dark'><a>Darken</a></li>
<li data-class='oe_green'><a>Green</a></li>
<li data-class='oe_red'><a>Red</a></li>
<li data-class='oe_blue_light'><a>Light Blue</a></li>
<li data-class='oe_blue'><a>Dark Blue</a></li>
<li data-class='oe_orange'><a>Orange</a></li>
<li data-class='oe_purple'><a>Purple</a></li>
<li data-class='oe_black'><a>Black</a></li>
</ul>
</li>

View File

@ -75,7 +75,7 @@
<script type="text/javascript" src="/website/static/src/js/website.js"></script>
<script t-if="not translatable" type="text/javascript" src="/website/static/src/js/website.snippets.animation.js"></script>
<t t-raw="head or ''"/>
<t t-raw="head or ''" name='layout_head'/>
</head>
<body>
<div id="wrapwrap">
@ -96,12 +96,13 @@
<t t-foreach="website.menu_id.child_id" t-as="submenu">
<t t-call="website.submenu"/>
</t>
<li class="divider"/>
<li class="dropdown" t-ignore="true" t-if="user_id.id != website.public_user.id">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="badge">
<b>
<span t-esc="user_id.name"/>
<span class="caret"></span>
</span>
</b>
</a>
<ul class="dropdown-menu js_usermenu" role="menu">
<li><a href="/web" role="menuitem">Administration</a></li>
@ -195,7 +196,7 @@
</template>
<template id="editor_head" inherit_id="website.layout" name="Editor" groups="base.group_website_publisher">
<xpath expr="//head" position="inside">
<xpath expr='//t[@name="layout_head"]' position="before">
<link rel='stylesheet' href='/website/static/src/css/snippets.css'/>
<link rel='stylesheet' href='/website/static/src/css/editor.css'/>
<link rel='stylesheet' href='/website/static/lib/bootstrap-tour/bootstrap-tour.css'/>
@ -235,7 +236,7 @@
<xpath expr="//ul[@id='top_menu']" position="inside">
<li t-if="user_id.id == website.public_user.id">
<a t-attf-href="/web#redirect=#{ quote_plus(url_for('', keep_query='*')) }">
<span class="badge">Sign in</span>
<b>Sign in</b>
</a>
</li>
</xpath>
@ -533,7 +534,7 @@
</div>
<div class="container" t-if="views">
<div class="bs-callout bs-callout-danger" t-if="qweb_template and editable">
<div class="alert alert-danger" t-if="qweb_template and editable">
<h4>Template fallback</h4>
<p>An error occured while rendering the template <code t-esc="qweb_template"/>.</p>
<p>If this error is caused by a change of yours in the templates, you have the possibility to reset one or more templates to their <strong>factory settings</strong>.</p>

View File

@ -15,4 +15,5 @@ OpenERP Contact Form
'views/website_crm.xml',
],
'installable': True,
'auto_install': True,
}

View File

@ -28,7 +28,10 @@
'author': 'OpenERP SA',
'depends': ['website', 'mail'],
'data': [
'views/snippets.xml',
'views/website_mail.xml',
'views/website_email_designer.xml',
'views/email_template_view.xml',
'security/website_mail.xml',
],
'css': [

View File

@ -1 +1,2 @@
import email_designer
import main

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# from openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website.models import website
class WebsiteEmailDesigner(http.Controller):
@website.route('/website_mail/email_designer/<model("email.template"):template>/', type='http', auth="public", multilang=True)
def index(self, template, **kw):
values = {
'template': template,
}
print template
return request.website.render("website_mail.designer_index", values)
@website.route(['/website_mail/snippets'], type='json', auth="public")
def snippets(self):
return request.website._render('website_mail.email_designer_snippets')

View File

@ -1,2 +1,3 @@
import mail_message
import mail_thread
import email_template

View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import lxml
import urlparse
from openerp.osv import osv, fields
from openerp.tools.translate import _
class EmailTemplate(osv.Model):
_inherit = 'email.template'
def _get_website_link(self, cr, uid, ids, name, args, context=None):
return dict((id, _('<a href="website_mail/email_designer/%s">Edit in Website</a>') % id) for id in ids)
_columns = {
'website_link': fields.function(
_get_website_link, type='text',
string='Website Link',
help='Link to the website',
),
}
def _postprocess_html_replace_links(self, cr, uid, body_html, context=None):
""" Post-processing of body_html. Indeed the content generated by the
website builder contains references to local addresses, for example
for images. This method changes those addresses to absolute addresses. """
html = body_html
if not body_html:
return html
# form a tree
root = lxml.html.fromstring(html)
if not len(root) and root.text is None and root.tail is None:
html = '<div>%s</div>' % html
root = lxml.html.fromstring(html)
base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
(base_scheme, base_netloc, bpath, bparams, bquery, bfragment) = urlparse.urlparse(base_url)
def _process_link(url):
new_url = url
(scheme, netloc, path, params, query, fragment) = urlparse.urlparse(url)
if not scheme and not netloc:
new_url = urlparse.urlunparse((base_scheme, base_netloc, path, params, query, fragment))
return new_url
# check all nodes, replace :
# - img src -> check URL
# - a href -> check URL
for node in root.iter():
if node.tag == 'a':
node.set('href', _process_link(node.get('href')))
elif node.tag == 'img' and not node.get('src', 'data').startswith('data'):
node.set('src', _process_link(node.get('src')))
html = lxml.html.tostring(root, pretty_print=False, method='html')
# this is ugly, but lxml/etree tostring want to put everything in a 'div' that breaks the editor -> remove that
if html.startswith('<div>') and html.endswith('</div>'):
html = html[5:-6]
return html
def create(self, cr, uid, values, context=None):
if 'body_html' in values:
values['body_html'] = self._postprocess_html_replace_links(cr, uid, values['body_html'], context=context)
return super(EmailTemplate, self).create(cr, uid, values, context=context)
def write(self, cr, uid, ids, values, context=None):
if 'body_html' in values:
values['body_html'] = self._postprocess_html_replace_links(cr, uid, values['body_html'], context=context)
return super(EmailTemplate, self).write(cr, uid, ids, values, context=context)

View File

@ -0,0 +1,17 @@
(function () {
'use strict';
var website = openerp.website;
website.snippet.BuildingBlock.include({
// init: function (parent) {
// this._super.apply(this, arguments);
// },
_get_snippet_url: function () {
return '/website_mail/snippets';
}
});
})();

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="email_template_form_inherit_website_link">
<field name="name">email.template.form</field>
<field name="model">email.template</field>
<field name="inherit_id" ref="email_template.email_template_form"/>
<field name="arch" type="xml">
<xpath expr="//page[@string='Mailing Template']/group" position="before">
<field name="website_link" widget='html' radonly='1'/>
</xpath>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,459 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="email_designer_snippets">
<div class="scroll" t-ignore="1">
<ul class="nav navbar-nav nav-tabs">
<li class="active"><a href="#snippet_structure" data-toggle="tab">Structure</a></li>
<li><a href="#snippet_content" data-toggle="tab">Content</a></li>
<li><a href="#snippet_feature" data-toggle="tab">Features</a></li>
<li><a href="#snippet_effect" data-toggle="tab">Effects</a></li>
</ul>
<div class="tab-content">
<div id="snippet_structure" class="tab-pane fade in active">
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td style="width:600px" valign="top">
<div style="padding:0px 5px">
<table style="font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top">
<h3 style="text-align: center; padding:0px 5px">A Section Subtitle</h3>
<p style="overflow:hidden; font-size:12px">
Write one or two paragraphs describing your product,
services or a specific feature. To be successful
your content needs to be useful to your readers.
</p><p style="overflow:hidden; font-size:12px">
Start with the customer find out what they want
and give it to them.
</p>
</td>
<td width="10"></td>
<td valign="top" width="290">
<img width="270" style="display:block;border:none;min-height:150px" src="/website/static/src/img/text_image.png"/>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="image-text" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px 5px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td style="width:600px" valign="top">
<div style="padding:0px 5px">
<table style="font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" width="290">
<img width="270" style="display:block;border:none;min-height:150px" alt="" src="/website/static/src/img/image_text.jpg"/>
</td>
<td width="10"></td>
<td valign="top">
<h3 style="text-align: center; padding:0px 5px">A Section Subtitle</h3>
<p style="overflow:hidden; font-size:12px">
Write one or two paragraphs describing your product,
services or a specific feature. To be successful
your content needs to be useful to your readers.
</p><p style="overflow:hidden; font-size:12px">
Start with the customer find out what they want
and give it to them.
</p>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_jumbotron.png"/>
<span class="oe_snippet_thumbnail_title">Big Message</span>
</div>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px 5px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:600px">
<div style="padding:0px 5px">
<h1 style="text-align: center">Sell Online. Easily.</h1>
<p style="overflow:hidden">
Write one sentence to convince visitor about your message.
</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px 5px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:600px">
<h2 style="text-align: center">
A Great Headline
</h2>
<h3 style="text-align: center">
A good subtitle
</h3>
</td>
</tr>
<tr>
<td valign="top" style="width:600px">
<div style="padding:0px 5px">
<p style="overflow:hidden">
A great way to catch your reader's attention is to tell a story.
Everything you consider writing can be told as a story.
</p>
<p style="overflow:hidden">
<strong>Great stories have personality</strong>. Consider telling
a great story that provides personality. Writing a story
with personality for potential clients will asist with
making a relationship connection. This shows up in small
quirks like word choices or phrases. Write from your point
of view, not from someone else's experience.
</p>
<p style="overflow:hidden">
<strong>Great stories are for everyone even when only written for
just one person</strong>. If you try to write with a wide general
audience in mind, your story will ring false and be bland.
No one will be interested. Write for one person. If its genuine
for the one, its genuine for the rest.
</p>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="hr" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_separator.png"/>
<span class="oe_snippet_thumbnail_title">Separator</span>
</div>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:600px">
<div style="padding:0px 5px">
<hr width="100%" style="background-color:rgb(204,204,204);border:medium none;clear:both;display:block;font-size:0px;min-height:1px;line-height:0"/>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="big-picture" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:600px">
<h2 style="text-align: center; padding:0px 5px">A Punchy Headline</h2>
</td>
</tr>
<tr>
<td valign="top" style="width:600px">
<img width="500" style="display:block;border:none;min-height:250px;margin:0 auto;" src="/website/static/src/img/big_picture.png"/>
</td>
</tr>
<tr>
<td valign="top" style="width:600px">
<p style="text-align: center; overflow:hidden">
<h3 style="text-align: center; padding:0px 5px">A Small Subtitle</h3>
</p>
<p style="text-align: center; overflow:hidden">
Choose a vibrant image and write an inspiring paragraph
about it. It does not have to be long, but it should
reinforce your image.
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="three-columns" data-selector-children=".oe_structure, [data-oe-type=html]">
<div class="oe_snippet_thumbnail">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:200px">
<img width="175" style="display:block;border:none;min-height:50px" src="/website/static/src/img/desert_thumb.jpg"/>
</td>
<td valign="top" style="width:200px">
<img width="175" style="display:block;border:none;min-height:50px" src="/website/static/src/img/deers_thumb.jpg"/>
</td>
<td valign="top" style="width:200px">
<img width="175" style="display:block;border:none;min-height:50px" src="/website/static/src/img/china_thumb.jpg"/>
</td>
</tr>
<tr>
<td valign="top" style="width:200px">
<h3 style="text-align: center; padding:0px 5px">Feature One</h3>
<p style="overflow:hidden">
Choose a vibrant image and write an inspiring paragraph
about it. It does not have to be long, but it should
reinforce your image.
</p>
</td>
<td valign="top" style="width:200px">
<h3 style="text-align: center; padding:0px 5px">Feature Two</h3>
<p style="overflow:hidden">
Choose a vibrant image and write an inspiring paragraph
about it. It does not have to be long, but it should
reinforce your image.
</p>
</td>
<td valign="top" style="width:200px">
<h3 style="text-align: center; padding:0px 5px">Feature Three</h3>
<p style="overflow:hidden">
Choose a vibrant image and write an inspiring paragraph
about it. It does not have to be long, but it should
reinforce your image.
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="snippet_feature" class="tab-pane fade">
<div data-snippet-id="pricing" data-selector-children=".oe_structure, [data-oe-type=html]">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<div style="width:600px">
<h2 style="text-align: center">Our Offers</h2>
</div>
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:200px; bgcolor: #bce8f1; background-color: #bce8f1;">
<h2 style="text-align: center">Beginner</h2>
<p style="text-align: center; overflow:hidden">Starter Package</p>
</td>
<td valign="top" style="width:200px; bgcolor: #428bca; background-color: #428bca;">
<h2 style="text-align: center">Professional</h2>
<p style="text-align: center; overflow:hidden">Enterprise package</p>
</td>
<td valign="top" style="width:200px; bgcolor: #bce8f1; background-color: #bce8f1;">
<h2 style="text-align: center">Expert</h2>
<p style="text-align: center; overflow:hidden">The top of the top</p>
</td>
</tr>
<tr>
<td valign="top" style="width:200px">
<h2 style="margin: 0; text-align: center">$<strong style="font-size: 30px">450</strong><small>.00</small></h2>
<p style="text-align: center">per month</p>
</td>
<td valign="top" style="width:200px">
<h2 style="margin: 0; text-align: center">$<strong style="font-size: 30px">590</strong><small>.00</small></h2>
<p style="text-align: center">per month</p>
</td>
<td valign="top" style="width:200px">
<h2 style="margin: 0; text-align: center">$<strong style="font-size: 30px">890</strong><small>.00</small></h2>
<p style="text-align: center">per month</p>
</td>
</tr>
<tr>
<td valign="top" style="width:200px">
<ul>
<li>Battery: 8 hours</li>
<li>Screen: 2.5 inch</li>
<li>Weight: 1.1 ounces</li>
<li>No support</li>
</ul>
</td>
<td valign="top" style="width:200px">
<ul>
<li>Battery: 12 hours</li>
<li>Screen: 2.8 inch</li>
<li>Weight: 1.2 ounces</li>
<li>Limited support</li>
</ul>
</td>
<td valign="top" style="width:200px">
<ul>
<li>Battery: 20 hours</li>
<li>Screen: 2.8 inch</li>
<li>Weight: 1.2 ounces</li>
<li>Unlimited support</li>
</ul>
</td>
</tr>
<tr>
<td valign="top" style="width:200px">
<p style="text-align: center; overflow: hidden">
<i>Free shipping, satisfied or reimbursed.</i><br/>
<a href="/page/website.contactus">Order now</a>
</p>
</td>
<td valign="top" style="width:200px">
<p style="text-align: center; overflow: hidden">
<i>Free shipping, satisfied or reimbursed.</i><br/>
<a href="/page/website.contactus">Order now</a>
</p>
</td>
<td valign="top" style="width:200px">
<p style="text-align: center; overflow: hidden">
<i>Free shipping, satisfied or reimbursed.</i><br/>
<a href="/page/website.contactus">Contact us</a>
</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div data-snippet-id="cta" data-selector-children=".oe_structure, [data-oe-type=html]">
<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>
<div class="oe_snippet_body" style="padding:0px; margin:0px">
<table cellspacing="0" cellpadding="0" style="margin:10px 0px 0px;vertical-align:top;padding:0px;font-family:arial;font-size:12px;color:rgb(51,51,51)">
<tbody>
<tr>
<td valign="top" style="width:200px">
<div style="padding:0px 5px">
<table style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background-color:rgb(153,153,153);border-collapse:collapse;width:70px;font-family:arial;font-size:12px;color:rgb(51,51,51);margin-left:60px" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
</a>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</td>
<td valign="top" style="width:200px">
<div style="padding:0px 5px">
<table style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background-color:rgb(153,153,153);border-collapse:collapse;width:70px;font-family:arial;font-size:12px;color:rgb(51,51,51);margin-left:60px" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
</a>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</td>
<td valign="top" style="width:200px">
<div style="padding:0px 5px">
<table style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;background-color:rgb(153,153,153);border-collapse:collapse;width:70px;font-family:arial;font-size:12px;color:rgb(51,51,51);margin-left:60px" border="0" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td style="border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:4px;border-bottom-left-radius:4px;padding:15px 5px;border-collapse:collapse;background-color:rgb(101,101,101)" align="center" valign="middle">
<a href="http://r.info.openerp.com/3bbh9o3y3tjskrk.html" style="text-decoration:none;border:none rgb(221,221,221);font-weight:bold;line-height:100%;text-align:center;color:rgb(0,136,204);word-wrap:break-word!important;background-color:rgb(101,101,101)" target="_blank">
<span style="color:rgb(255,255,255);font-family:arial;font-size:12px;display:block;width:auto;text-align:center;white-space:nowrap">View Product</span>
</a>
</td>
</tr>
<tr>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="snippet_effect" class="tab-pane fade">
</div>
<div id="snippet_styles" class="hidden">
</div>
</div>
</div>
</template>
</data>
</openerp>

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Email Designer main page -->
<template id="designer_index" name="Email Designer">
<t t-call="website.layout">
<t t-set="head">
<script type="text/javascript" src="/website_mail/static/src/js/website_email_designer.js"></script>
</t>
<div id="wrap">
<div class="container">
<h1 t-field="template.name"/>
<div class="row" style="width: 600px;">
<div class="row">
<div class="col-lg-3"><b>Email From</b></div>
<div class="col-lg-9"><span t-field="template.email_from"/></div>
</div>
<div class="row">
<div class="col-lg-3"><b>To (Email)</b></div>
<div class="col-lg-9"><span t-field="template.email_to"/></div>
</div>
<div class="row">
<div class="col-lg-3"><b>To (Partners)</b></div>
<div class="col-lg-9"><span t-field="template.partner_to"/></div>
</div>
<div class="row">
<div class="col-lg-3"><b>Reply To</b></div>
<div class="col-lg-9"><span t-field="template.reply_to"/></div>
</div>
<div class="row">
<div class="col-lg-3"><b>Subject</b></div>
<div class="col-lg-9"><span t-field="template.subject"/></div>
</div>
<div class="row well">
<div t-field="template.body_html" style="position: relative;"/>
</div>
</div>
</div>
</div>
</t>
<t t-set="website.footer"></t>
</template>
</data>
</openerp>

View File

@ -114,10 +114,10 @@ class Ecommerce(http.Controller):
_order = 'website_published desc, website_sequence desc'
def get_attribute_ids(self):
attributes_obj = request.registry['product.attribute']
attributes_ids = attributes_obj.search(request.cr, request.uid, [], context=request.context)
return attributes_obj.browse(request.cr, request.uid, attributes_ids, context=request.context)
def get_characteristic_ids(self):
characteristics_obj = request.registry['product.characteristic']
characteristics_ids = characteristics_obj.search(request.cr, request.uid, [], context=request.context)
return characteristics_obj.browse(request.cr, request.uid, characteristics_ids, context=request.context)
def get_pricelist(self):
""" Shortcut to get the pricelist from the website model """
@ -134,13 +134,13 @@ class Ecommerce(http.Controller):
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, request.uid, product_ids, context=request.context)
def has_search_filter(self, attribute_id, value_id=None):
def has_search_filter(self, characteristic_id, value_id=None):
if request.httprequest.args.get('filters'):
filters = simplejson.loads(request.httprequest.args['filters'])
else:
filters = []
for key_val in filters:
if key_val[0] == attribute_id and (not value_id or value_id in key_val[1:]):
if key_val[0] == characteristic_id and (not value_id or value_id in key_val[1:]):
return key_val
return False
@ -176,11 +176,11 @@ class Ecommerce(http.Controller):
post.get("category") and ("&category=%s" % post.get("category")) or ""
))
def attributes_to_ids(self, attributes):
obj = request.registry.get('product.attribute.product')
def characteristics_to_ids(self, characteristics):
obj = request.registry.get('product.characteristic.product')
domain = []
for key_val in attributes:
domain.append(("attribute_id", "=", key_val[0]))
for key_val in characteristics:
domain.append(("characteristic_id", "=", key_val[0]))
if isinstance(key_val[1], list):
domain.append(("value", ">=", key_val[1][0]))
domain.append(("value", "<=", key_val[1][1]))
@ -199,10 +199,10 @@ class Ecommerce(http.Controller):
@website.route([
'/shop/',
'/shop/page/<int:page>/',
'/shop/category/<int:category>/',
'/shop/category/<int:category>/page/<int:page>/'
'/shop/category/<model("product.public.category"):category>/',
'/shop/category/<model("product.public.category"):category>/page/<int:page>/'
], type='http', auth="public", multilang=True)
def shop(self, category=0, page=0, filters='', search='', **post):
def shop(self, category=None, page=0, filters='', search='', **post):
cr, uid, context = request.cr, request.uid, request.context
product_obj = request.registry.get('product.template')
domain = request.registry.get('website').ecommerce_get_product_domain()
@ -211,11 +211,11 @@ class Ecommerce(http.Controller):
('name', 'ilike', "%%%s%%" % search),
('description', 'ilike', "%%%s%%" % search)]
if category:
domain.append(('product_variant_ids.public_categ_id', 'child_of', category))
domain.append(('product_variant_ids.public_categ_id', 'child_of', category.id))
if filters:
filters = simplejson.loads(filters)
if filters:
ids = self.attributes_to_ids(filters)
ids = self.characteristics_to_ids(filters)
domain.append(('id', 'in', ids or [0]))
product_count = product_obj.search_count(cr, uid, domain, context=context)
@ -286,7 +286,7 @@ class Ecommerce(http.Controller):
}
return request.website.render("website_sale.product", values)
@website.route(['/shop/product/<int:product_template_id>/comment'], type='http', auth="public")
@website.route(['/shop/product/comment'], type='http', auth="public", methods=['POST'])
def product_comment(self, product_template_id, **post):
cr, uid, context = request.cr, request.uid, request.context
if post.get('comment'):
@ -298,11 +298,11 @@ class Ecommerce(http.Controller):
context=dict(context, mail_create_nosubcribe=True))
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
@website.route(['/shop/add_product/', '/shop/category/<int:cat_id>/add_product/'], type='http', auth="user", multilang=True, methods=['POST'])
def add_product(self, name="New Product", cat_id=0, **post):
@website.route(['/shop/add_product/'], type='http', auth="user", multilang=True, methods=['POST'])
def add_product(self, name="New Product", category=0, **post):
Product = request.registry.get('product.product')
product_id = Product.create(request.cr, request.uid, {
'name': name, 'public_categ_id': cat_id
'name': name, 'public_categ_id': category
}, context=request.context)
product = Product.browse(request.cr, request.uid, product_id, context=request.context)
@ -491,10 +491,6 @@ class Ecommerce(http.Controller):
shipping_partner = orm_partner.browse(cr, SUPERUSER_ID, shipping_ids[0], context)
checkout.update(info.from_partner(shipping_partner, address_type='shipping'))
for field_name in info.mandatory_fields():
if not checkout[field_name]:
error[field_name] = 'missing'
return request.website.render("website_sale.checkout", values)
@website.route(['/shop/confirm_order/'], type='http', auth="public", multilang=True)
@ -549,7 +545,7 @@ class Ecommerce(http.Controller):
company_ids = orm_parter.search(cr, SUPERUSER_ID, [("name", "ilike", company_name), ('is_company', '=', True)], context=context)
company_id = (company_ids and company_ids[0]) or orm_parter.create(cr, SUPERUSER_ID, {'name': company_name, 'is_company': True}, context)
billing_info = dict(checkout)
billing_info = dict((k, v) for k,v in checkout.items() if "shipping_" not in k and k != "company")
billing_info['parent_id'] = company_id
if request.uid != request.registry['website'].get_public_user(cr, uid, context):

View File

@ -2,6 +2,11 @@
<openerp>
<data noupdate="1">
<record id="product.group_product_characteristics" model="res.groups">
<field name="name">Product Characteristic (not supported)</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
<record id="menu_shop" model="website.menu">
<field name="name">Shop</field>
<field name="url">/shop</field>

View File

@ -1,6 +1,7 @@
import website_styles
import payment_transaction
import product
import product_attributes
import product_characteristics
import res_config
import sale_order
import website

View File

@ -1,87 +0,0 @@
from openerp.osv import osv, fields
class attributes(osv.Model):
_name = "product.attribute"
def _get_float_max(self, cr, uid, ids, field_name, arg, context=None):
result = dict.fromkeys(ids, 0)
if ids:
cr.execute("""
SELECT attribute_id, MAX(value)
FROM product_attribute_product
WHERE attribute_id in (%s)
GROUP BY attribute_id
""" % ",".join(map(str, ids)))
result.update(dict(cr.fetchall()))
return result
def _get_float_min(self, cr, uid, ids, field_name, arg, context=None):
result = dict.fromkeys(ids, 0)
if ids:
cr.execute("""
SELECT attribute_id, MIN(value)
FROM product_attribute_product
WHERE attribute_id in (%s)
GROUP BY attribute_id
""" % ",".join(map(str, ids)))
result.update(dict(cr.fetchall()))
return result
def _get_min_max(self, cr, uid, ids, context=None):
result = {}
for value in self.pool.get('product.attribute.product').browse(cr, uid, ids, context=context):
if value.type == 'float':
result[value.attribute_id.id] = True
return result.keys()
_columns = {
'name': fields.char('Name', size=64, translate=True, required=True),
'type': fields.selection([('distinct', 'Textual Value'), ('float', 'Numeric Value')], "Type", required=True),
'value_ids': fields.one2many('product.attribute.value', 'attribute_id', 'Values'),
'attr_product_ids': fields.one2many('product.attribute.product', 'attribute_id', 'Products'),
'float_max': fields.function(_get_float_max, type='float', string="Max", store={
'product.attribute.product': (_get_min_max, ['value','attribute_id'], 20),
}),
'float_min': fields.function(_get_float_min, type='float', string="Min", store={
'product.attribute.product': (_get_min_max, ['value','attribute_id'], 20),
}),
'visible': fields.boolean('Display Filter on Website'),
}
_defaults = {
'type': 'distinct',
'visible': True,
}
class attributes_value(osv.Model):
_name = "product.attribute.value"
_columns = {
'name': fields.char('Value', size=64, translate=True, required=True),
'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
'atr_product_ids': fields.one2many('product.attribute.product', 'value_id', 'Products'),
}
class attributes_product(osv.Model):
_name = "product.attribute.product"
_order = 'attribute_id, value_id, value'
_columns = {
'value': fields.float('Numeric Value'),
'value_id': fields.many2one('product.attribute.value', 'Textual Value'),
'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
'product_tmpl_id': fields.many2one('product.template', 'Product', required=True),
'type': fields.related('attribute_id', 'type', type='selection',
selection=[('distinct', 'Distinct'), ('float', 'Float')], string='Type'),
}
def onchange_attribute_id(self, cr, uid, ids, attribute_id, context=None):
attribute = self.pool.get('product.attribute').browse(cr, uid, attribute_id, context=context)
return {'value': {'type': attribute.type, 'value_id': False, 'value': ''}}
class product_template(osv.Model):
_inherit = "product.template"
_columns = {
'website_attribute_ids': fields.one2many('product.attribute.product', 'product_tmpl_id', 'Product Attributes'),
}

View File

@ -0,0 +1,87 @@
from openerp.osv import osv, fields
class characteristics(osv.Model):
_name = "product.characteristic"
def _get_float_max(self, cr, uid, ids, field_name, arg, context=None):
result = dict.fromkeys(ids, 0)
if ids:
cr.execute("""
SELECT characteristic_id, MAX(value)
FROM product_characteristic_product
WHERE characteristic_id in (%s)
GROUP BY characteristic_id
""" % ",".join(map(str, ids)))
result.update(dict(cr.fetchall()))
return result
def _get_float_min(self, cr, uid, ids, field_name, arg, context=None):
result = dict.fromkeys(ids, 0)
if ids:
cr.execute("""
SELECT characteristic_id, MIN(value)
FROM product_characteristic_product
WHERE characteristic_id in (%s)
GROUP BY characteristic_id
""" % ",".join(map(str, ids)))
result.update(dict(cr.fetchall()))
return result
def _get_min_max(self, cr, uid, ids, context=None):
result = {}
for value in self.pool.get('product.characteristic.product').browse(cr, uid, ids, context=context):
if value.type == 'float':
result[value.characteristic_id.id] = True
return result.keys()
_columns = {
'name': fields.char('Name', size=64, translate=True, required=True),
'type': fields.selection([('distinct', 'Textual Value'), ('float', 'Numeric Value')], "Type", required=True),
'value_ids': fields.one2many('product.characteristic.value', 'characteristic_id', 'Values'),
'attr_product_ids': fields.one2many('product.characteristic.product', 'characteristic_id', 'Products'),
'float_max': fields.function(_get_float_max, type='float', string="Max", store={
'product.characteristic.product': (_get_min_max, ['value','characteristic_id'], 20),
}),
'float_min': fields.function(_get_float_min, type='float', string="Min", store={
'product.characteristic.product': (_get_min_max, ['value','characteristic_id'], 20),
}),
'visible': fields.boolean('Display Filter on Website'),
}
_defaults = {
'type': 'distinct',
'visible': True,
}
class characteristics_value(osv.Model):
_name = "product.characteristic.value"
_columns = {
'name': fields.char('Value', size=64, translate=True, required=True),
'characteristic_id': fields.many2one('product.characteristic', 'Characteristic', required=True),
'atr_product_ids': fields.one2many('product.characteristic.product', 'value_id', 'Products'),
}
class characteristics_product(osv.Model):
_name = "product.characteristic.product"
_order = 'characteristic_id, value_id, value'
_columns = {
'value': fields.float('Numeric Value'),
'value_id': fields.many2one('product.characteristic.value', 'Textual Value'),
'characteristic_id': fields.many2one('product.characteristic', 'Characteristic', required=True),
'product_tmpl_id': fields.many2one('product.template', 'Product', required=True),
'type': fields.related('characteristic_id', 'type', type='selection',
selection=[('distinct', 'Distinct'), ('float', 'Float')], string='Type'),
}
def onchange_characteristic_id(self, cr, uid, ids, characteristic_id, context=None):
characteristic = self.pool.get('product.characteristic').browse(cr, uid, characteristic_id, context=context)
return {'value': {'type': characteristic.type, 'value_id': False, 'value': ''}}
class product_template(osv.Model):
_inherit = "product.template"
_columns = {
'website_characteristic_ids': fields.one2many('product.characteristic.product', 'product_tmpl_id', 'Product Characteristics'),
}

View File

@ -0,0 +1,11 @@
from openerp.osv import osv, fields
class sale_configuration(osv.osv_memory):
_inherit = 'sale.config.settings'
_columns = {
'group_product_characteristics': fields.boolean("Support multiple characteristics per products ",
implied_group='product.group_product_characteristics',
help="""Allow to manage several characteristics per product. This characteristics are used for filter and compare your products. As an example, if you sell all in one computers, you may have characteristics like RAM, Processor Speed, Manufacturing, to compare products"""),
}

View File

@ -7,8 +7,8 @@ access_product_pricelist_version_public,product.pricelist.version.public,product
access_product_pricelist_public,product.pricelist.public,product.model_product_pricelist,base.group_public,1,0,0,0
access_product_pricelist_item_public,product.pricelist.item.public,product.model_product_pricelist_item,base.group_public,1,0,0,0
access_product_product_price_type_public,product.price.type.public,product.model_product_price_type,base.group_public,1,0,0,0
access_product_attribute,product.attribute.public,website_sale.model_product_attribute,,1,0,0,0
access_product_attribute_value,product.attribute.value.public,website_sale.model_product_attribute_value,,1,0,0,0
access_product_attribute_product,product.attribute.product.public,website_sale.model_product_attribute_product,,1,0,0,0
access_product_characteristic,product.characteristic.public,website_sale.model_product_characteristic,,1,0,0,0
access_product_characteristic_value,product.characteristic.value.public,website_sale.model_product_characteristic_value,,1,0,0,0
access_product_characteristic_product,product.characteristic.product.public,website_sale.model_product_characteristic_product,,1,0,0,0
access_website_product_style,website.product.style.public,website_sale.model_website_product_style,,1,0,0,0
access_product_supplierinfo,product.supplierinfo.public,product.model_product_supplierinfo,base.group_public,1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
7 access_product_pricelist_public product.pricelist.public product.model_product_pricelist base.group_public 1 0 0 0
8 access_product_pricelist_item_public product.pricelist.item.public product.model_product_pricelist_item base.group_public 1 0 0 0
9 access_product_product_price_type_public product.price.type.public product.model_product_price_type base.group_public 1 0 0 0
10 access_product_attribute access_product_characteristic product.attribute.public product.characteristic.public website_sale.model_product_attribute website_sale.model_product_characteristic 1 0 0 0
11 access_product_attribute_value access_product_characteristic_value product.attribute.value.public product.characteristic.value.public website_sale.model_product_attribute_value website_sale.model_product_characteristic_value 1 0 0 0
12 access_product_attribute_product access_product_characteristic_product product.attribute.product.public product.characteristic.product.public website_sale.model_product_attribute_product website_sale.model_product_characteristic_product 1 0 0 0
13 access_website_product_style website.product.style.public website_sale.model_website_product_style 1 0 0 0
14 access_product_supplierinfo product.supplierinfo.public product.model_product_supplierinfo base.group_public 1 0 0 0

View File

@ -51,7 +51,7 @@
<template id="products_cart" name="Shopping cart">
<div class="ribbon-wrapper">
<div class="ribbon btn btn-danger">Promo</div>
<div class="ribbon btn btn-danger">Sale</div>
</div>
<div class="oe_product_image">
<a t-href="/shop/product/#{ slug(product) }/" t-keep-query="category,search,filters">
@ -92,7 +92,7 @@
<div class="oe_structure"/>
<div class="container oe_website_sale">
<div class="products_pager">
<div>
<div class="row">
<form action="/shop/" method="get" class="pagination form-inline col-md-3">
<t t-call="website_sale.search" />
</form>
@ -188,7 +188,8 @@
</table>
<t t-if="not bins">
<div class="text-center text-muted">
<h3>No product found</h3>
<h3 class="css_editable_display">No product found</h3>
<h3 class="css_non_editable_mode_hidden">There isn't available products right know, click <a t-href="/page/website.contactus">here</a> to contact us</h3>
<t groups="base.group_website_publisher">
<p>Click on "Content" to define a new product or "Help" for more informations.</p>
<img src="/website/static/src/img/content_here.png"/>
@ -370,13 +371,13 @@
</xpath>
</template>
<!-- Product option: attributes -->
<template id="product_attributes" inherit_option_id="website_sale.product" name="Product Attributes">
<!-- Product option: characteristics -->
<template id="product_characteristics" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Product Characteristics" groups="product.group_product_characteristics">
<xpath expr="//p[@t-field='product.description_sale']" position="after">
<hr t-if="product.website_attribute_ids"/>
<hr t-if="product.website_characteristic_ids"/>
<p class="text-muted">
<t t-set="attr" t-value="None"/>
<t t-foreach="product.website_attribute_ids" t-as="attribute"><br t-if="attr and attribute.attribute_id.id != attr"/><t t-if="attribute.attribute_id.id != attr"><span t-field="attribute.attribute_id"/>: </t><t t-if="attribute.attribute_id.id == attr">, </t><t t-if="attribute.attribute_id.type == 'distinct'"><span t-field="attribute.value_id"/></t><t t-if="attribute.attribute_id.type == 'float'"><span t-field="attribute.value"/></t><t t-set="attr" t-value="attribute.attribute_id.id"/></t>
<t t-foreach="product.website_characteristic_ids" t-as="characteristic"><br t-if="attr and characteristic.characteristic_id.id != attr"/><t t-if="characteristic.characteristic_id.id != attr"><span t-field="characteristic.characteristic_id"/>: </t><t t-if="characteristic.characteristic_id.id == attr">, </t><t t-if="characteristic.characteristic_id.type == 'distinct'"><span t-field="characteristic.value_id"/></t><t t-if="characteristic.characteristic_id.type == 'float'"><span t-field="characteristic.value"/></t><t t-set="attr" t-value="characteristic.characteristic_id.id"/></t>
</p>
</xpath>
</template>
@ -594,36 +595,36 @@
</xpath>
</template>
<template id="products_attributes" inherit_option_id="website_sale.products" name="Product Filters and Attributes">
<template id="products_characteristics" inherit_id="website_sale.products" inherit_option_id="website_sale.products" name="Product Characteristic's Filters" groups="product.group_product_characteristics">
<xpath expr="//div[@id='products_grid_before']" position="inside">
<form t-action="/shop/filters/" method="post" t-keep-query="category,search">
<ul class="nav nav-pills nav-stacked mt16">
<t t-set="attribute_ids" t-value="Ecommerce.get_attribute_ids()"/>
<t t-foreach="attribute_ids" t-as="attribute_id">
<t t-if="attribute_id.visible">
<li t-if="attribute_id.value_ids and attribute_id.type == 'distinct'">
<div t-field="attribute_id.name"/>
<t t-set="characteristic_ids" t-value="Ecommerce.get_characteristic_ids()"/>
<t t-foreach="characteristic_ids" t-as="characteristic_id">
<t t-if="characteristic_id.visible">
<li t-if="characteristic_id.value_ids and characteristic_id.type == 'distinct'">
<div t-field="characteristic_id.name"/>
<ul class="nav nav-pills nav-stacked">
<t t-foreach="attribute_id.value_ids" t-as="value_id">
<li t-att-class="Ecommerce.has_search_filter(attribute_id.id, value_id.id) and 'active' or ''">
<t t-foreach="characteristic_id.value_ids" t-as="value_id">
<li t-att-class="Ecommerce.has_search_filter(characteristic_id.id, value_id.id) and 'active' or ''">
<label style="margin: 0 20px;">
<input type="checkbox" t-att-name="'att-%s-%s' % (attribute_id.id, value_id.id)"
t-att-checked="Ecommerce.has_search_filter(attribute_id.id, value_id.id) and 'checked' or ''"/>
<input type="checkbox" t-att-name="'att-%s-%s' % (characteristic_id.id, value_id.id)"
t-att-checked="Ecommerce.has_search_filter(characteristic_id.id, value_id.id) and 'checked' or ''"/>
<span style="font-weight: normal" t-field="value_id.name"/>
</label>
</li>
</t>
</ul>
</li>
<li t-if="attribute_id.type == 'float' and attribute_id.float_min != attribute_id.float_max">
<div t-field="attribute_id.name"/>
<t t-set="attribute" t-value="Ecommerce.has_search_filter(attribute_id.id)"/>
<li t-if="characteristic_id.type == 'float' and characteristic_id.float_min != characteristic_id.float_max">
<div t-field="characteristic_id.name"/>
<t t-set="characteristic" t-value="Ecommerce.has_search_filter(characteristic_id.id)"/>
<div style="margin: 0 20px;" class="js_slider"
t-att-data-id="attribute_id.id"
t-att-data-value-min="attribute and attribute[1][0] or attribute_id.float_min"
t-att-data-value-max="attribute and attribute[1][1] or attribute_id.float_max"
t-att-data-min="attribute_id.float_min"
t-att-data-max="attribute_id.float_max"></div>
t-att-data-id="characteristic_id.id"
t-att-data-value-min="characteristic and characteristic[1][0] or characteristic_id.float_min"
t-att-data-value-max="characteristic and characteristic[1][1] or characteristic_id.float_max"
t-att-data-min="characteristic_id.float_min"
t-att-data-max="characteristic_id.float_max"></div>
</li>
</t>
</t>
@ -732,112 +733,110 @@
<a t-if="not partner" t-attf-href="/web#action=redirect&amp;url=#{ request.httprequest.url }">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 class="control-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 class="control-label" for="company" style="font-weight: normal">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 class="control-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 class="control-label" for="phone">Phone</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 class="control-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 class="control-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 class="control-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 class="control-label" for="state_id" style="font-weight: normal">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 class="control-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 class="row">
<div t-attf-class="form-group #{error.get('name') and 'has-error' or ''} col-lg-6">
<label class="control-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 class="control-label" for="company" style="font-weight: normal">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 class="control-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 class="control-label" for="phone">Phone</label>
<input type="tel" name="phone" class="form-control" t-att-value="checkout.get('phone')"/>
</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 class="control-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 class="control-label" for="contact_name">Phone</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 class="control-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 class="control-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 class="control-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 class="control-label" for="contact_name" style="font-weight: normal">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 class="control-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 t-attf-class="form-group #{error.get('street') and 'has-error' or ''} col-lg-6">
<label class="control-label" for="street">Street</label>
<input type="text" name="street" class="form-control" t-att-value="checkout.get('street')"/>
</div>
<button type="submit" class="btn btn-default btn-primary pull-right mb32">Confirm <span class="fa fa-long-arrow-right"/></button>
<div class="clearfix"/>
<div t-attf-class="form-group #{error.get('city') and 'has-error' or ''} col-lg-6">
<label class="control-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 class="control-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 class="control-label" for="state_id" style="font-weight: normal">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 class="control-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" groups="sale.group_delivery_invoice_address">
<label>
<input type="checkbox" name="shipping_different" t-att-checked="shipping"/>
Ship to a different address
</label>
</div>
</div>
<div class="js_shipping row mb16" t-att-style="not shipping and 'display:none' or ''" groups="sale.group_delivery_invoice_address">
<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 class="control-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 class="control-label" for="contact_name">Phone</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 class="control-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 class="control-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 class="control-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 class="control-label" for="contact_name" style="font-weight: normal">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 class="control-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="fa fa-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="fa fa-arrow-right"/> change</a></small></h3>
@ -961,19 +960,19 @@
<div>
<a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
</div>
<h4 class="mt32">Ship To:</h4>
<t t-if="website_sale_order.partner_shipping_id and website_sale_order.partner_shipping_id.id != website_sale_order.partner_invoice_id.id">
<div t-field="order.partner_shipping_id" t-field-options='{
"widget": "contact",
"fields": ["address", "name", "phone"]
}'/>
<t groups="sale.group_delivery_invoice_address">
<h4 class="mt32">Ship To:</h4>
<t t-if="website_sale_order.partner_shipping_id and website_sale_order.partner_shipping_id.id != website_sale_order.partner_invoice_id.id">
<div t-field="order.partner_shipping_id" t-field-options='{
"widget": "contact",
"fields": ["address", "name", "phone"]
}'/>
</t>
<address t-if="website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id">Ship to the same address</address>
<div class="mb32">
<a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
</div>
</t>
<address t-if="website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id">Ship to the same address</address>
<div class="mb32">
<a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
</div>
</div>
</div>
@ -1035,14 +1034,16 @@
"widget": "contact",
"fields": ["address", "name", "phone", "email"]
}'/>
<h4 class="mt32">Ship To:</h4>
<t t-if="order.partner_shipping_id and order.partner_shipping_id.id != order.partner_invoice_id.id">
<div t-field="order.partner_shipping_id" t-field-options='{
"widget": "contact",
"fields": ["address", "name", "phone"]
}'/>
<t groups="sale.group_delivery_invoice_address">
<h4 class="mt32">Ship To:</h4>
<t t-if="order.partner_shipping_id and order.partner_shipping_id.id != order.partner_invoice_id.id">
<div t-field="order.partner_shipping_id" t-field-options='{
"widget": "contact",
"fields": ["address", "name", "phone"]
}'/>
</t>
<address t-if="order.partner_shipping_id.id == order.partner_invoice_id.id">Ship to the same address</address>
</t>
<address t-if="order.partner_shipping_id.id == order.partner_invoice_id.id">Ship to the same address</address>
</div>
</div>

View File

@ -2,6 +2,19 @@
<openerp>
<data>
<record id="view_sales_config_website_sale" model="ir.ui.view">
<field name="name">sale settings</field>
<field name="model">sale.config.settings</field>
<field name="inherit_id" ref="sale.view_sales_config"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='Product Features']/div" position="inside">
<div>
<field name="group_product_characteristics" class="oe_inline"/>
<label for="group_product_characteristics"/>
</div>
</xpath>
</field>
</record>
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">product.normal.form.inherit</field>
@ -48,15 +61,15 @@
<group colspan="4" string="Website Options">
<field name="suggested_product_ids" widget="many2many_tags"/>
<field name="website_style_ids" widget="many2many_tags"/>
<field colspan="4" name="website_attribute_ids" nolabel="1">
<tree string="Product Attributes" editable="bottom">
<field name="attribute_id" on_change="onchange_attribute_id(attribute_id)"/>
<field colspan="4" name="website_characteristic_ids" nolabel="1" groups="product.group_product_characteristics">
<tree string="Product Characteristics" editable="bottom">
<field name="characteristic_id" on_change="onchange_characteristic_id(characteristic_id)"/>
<field name="type" invisible="1"/>
<field name="value" attrs="{'required': [('type','=','float')]}"/>
<field name="value_id"
attrs="{'required': [('type','=','distinct')]}"
context="{'default_attribute_id': attribute_id}"
domain="[('attribute_id', '=', attribute_id)]"/>
context="{'default_characteristic_id': characteristic_id}"
domain="[('characteristic_id', '=', characteristic_id)]"/>
</tree>
</field>
</group>
@ -65,11 +78,11 @@
</field>
</record>
<record model="ir.ui.view" id="view_product_attribute_form">
<field name="name">product.attribute.form</field>
<field name="model">product.attribute</field>
<record model="ir.ui.view" id="view_product_characteristic_form">
<field name="name">product.characteristic.form</field>
<field name="model">product.characteristic</field>
<field name="arch" type="xml">
<form string="Product Attributes" version="7.0">
<form string="Product Characteristics" version="7.0">
<group>
<field name="name"/>
<field name="type"/>

View File

@ -2,6 +2,7 @@
from openerp.addons.website_sale.controllers.main import Ecommerce
from openerp.addons.web.http import request
from openerp.addons.website.models import website
from openerp import SUPERUSER_ID
class Ecommerce(Ecommerce):
@ -15,8 +16,8 @@ class Ecommerce(Ecommerce):
if order and carrier_id:
# recompute delivery costs
SaleOrder = request.registry['sale.order']
SaleOrder.write(cr, uid, [order.id], {'carrier_id': carrier_id}, context=context)
SaleOrder.delivery_set(cr, uid, [order.id], context=context)
SaleOrder.write(cr, SUPERUSER_ID, [order.id], {'carrier_id': carrier_id}, context=context)
SaleOrder.delivery_set(cr, SUPERUSER_ID, [order.id], context=context)
res = super(Ecommerce, self).payment(**post)
return res