[MERGE]Merge main al branch.
bzr revid: bth@tinyerp.com-20130807133950-gm911a2plrqy42ym
This commit is contained in:
@@ -203,7 +203,7 @@ class event_event(osv.osv):
|
||||
'email_confirmation_id' : fields.many2one('email.template','Event Confirmation Email', help="If you set an email template, each participant will receive this email announcing the confirmation of the event."),
|
||||
'reply_to': fields.char('Reply-To Email', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."),
|
||||
'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who will be giving speech at the event."),
|
||||
'address_id': fields.many2one('res.partner','Location Address', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'address_id': fields.many2one('res.partner','Location', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'street': fields.related('address_id','street',type='char',string='Street'),
|
||||
'street2': fields.related('address_id','street2',type='char',string='Street2'),
|
||||
'state_id': fields.related('address_id','state_id',type='many2one', relation="res.country.state", string='State'),
|
||||
|
||||
@@ -80,18 +80,7 @@
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<label for="address_id" string="Location"/>
|
||||
<div>
|
||||
<field name="address_id" on_change="on_change_address_id(address_id)" />
|
||||
<field name="street" placeholder="Street..."/>
|
||||
<field name="street2"/>
|
||||
<div class="address_format">
|
||||
<field name="city" placeholder="City" style="width: 40%%"/>
|
||||
<field name="state_id" class="oe_no_button" placeholder="State" style="width: 37%%" options='{"no_open": true}'/>
|
||||
<field name="zip" placeholder="ZIP" style="width: 20%%"/>
|
||||
</div>
|
||||
<field name="country_id" placeholder="Country" class="oe_no_button" options='{"no_open": true}'/>
|
||||
</div>
|
||||
<field name="address_id" on_change="on_change_address_id(address_id)" context="{'show_address': 1}" options='{"always_reload": True}'/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="user_id"/>
|
||||
|
||||
@@ -8,7 +8,7 @@ OpenERP Website CMS
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['base'],
|
||||
'depends': ['web'],
|
||||
'installable': True,
|
||||
'data': [
|
||||
'views/views.xml',
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Enterprise Website Builder</h2>
|
||||
<h3 class="oe_slogan">Get an awesome website. Customize easily.</h3>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_demo oe_picture oe_screenshot">
|
||||
<a href="https://www.openerp.com/saas_master/demo?lang=en_US&module=website">
|
||||
<img src="">
|
||||
</a>
|
||||
<div class="oe_demo_footer oe_centeralign">Online Demo</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Create enterprise-grade website with our super easy builder; no backend, everything
|
||||
is editable inline. Benefit from out-of-the-box business features; shop, events, blogs,
|
||||
jobs announces, "our team" pages, etc.
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start?app=website" class="oe_button oe_big oe_tacky">Create your <span class="oe_emph">free</span> website</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Edit Anything Inline</h2>
|
||||
<h3 class="oe_slogan">What You See Is What You Get. Really!</h3>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Create websites with no technical knowledge. OpenERP's unique
|
||||
<em>'edit inline'</em> approach makes website creation
|
||||
surprisingly easy. No more complex backend with menu managers,
|
||||
page editors, banner manager, ... Just click anywhere to any
|
||||
content.
|
||||
</p><p>
|
||||
"Want to change the price of a product? or put it in bold? Want to
|
||||
change a blog title?" just click and change. What you see is what
|
||||
you get. Really.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img oe_centered">
|
||||
<img class="oe_picture" src="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Awsome. Astonishingly Beautiful.</h2>
|
||||
<h3 class="oe_slogan">Professional themes and building blocks</h3>
|
||||
<div class="oe_span6">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
OpenERP's building block feature and inline edition approach
|
||||
allows to design modern website that are not possible with
|
||||
traditional WYSIWYG page editors.
|
||||
</p><p>
|
||||
Whether it's for products descriptions, blogs or static pages,
|
||||
you don't need to be a professioanl designer to create modern
|
||||
and clean web pages.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Enterprise-Ready, out-of-the-box</h2>
|
||||
<h3 class="oe_slogan">Install professional features without effort.</h3>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Activate ready-to-use enterprise features in just a click;
|
||||
ecommerce, call-to-actions, jobs announces, events, customer
|
||||
references, "our team" page, blogs, newsletters, etc.
|
||||
</p><p>
|
||||
Traditional eCommerce and CMS have poor backends as it's not their
|
||||
core focus. The OpenERP integration allows you to benefit from the
|
||||
best management software to follow-up on your orders, your jobs
|
||||
applicants, your leads, etc.
|
||||
</p><p>
|
||||
You don't need anymore to synchronize your management software and
|
||||
your ecommerce.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Multi-languages Without Pain</h2>
|
||||
<h3 class="oe_slogan">Automate updates and transaltions easily</h3>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture" src="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Get your website translated in multiple languages with no effort.
|
||||
OpenERP proposes and propagates translations automatically
|
||||
across pages.
|
||||
</p>
|
||||
Our translation "on demand" features allows you to benefit from
|
||||
professional translators to translate all your changes
|
||||
automatically. Just change any part of your website (a new blog
|
||||
post, a new pages, updated products, ...) and the translated
|
||||
versions are updated automatically in around 32 hours.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Designer-Friendly Themes</h2>
|
||||
<h3 class="oe_slogan">Designers love working on OpenERP</h3>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
Themes are awesome and easy to design. You don't need to develop
|
||||
to create new pages, themes or building blocks. We use a clean
|
||||
HTML structure, a <a href="http://getbootstrap.com/">bootstrap</a>
|
||||
CSS and our modularity allows to distribute your themes easily.
|
||||
</p><p>
|
||||
The building block approach allows the website to remain clean
|
||||
after the end-users start creating new contents.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture" src="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Optimize your online presence efficiently</h2>
|
||||
<h3 class="oe_slogan">SEO tools at your finger tips</h3>
|
||||
<div class="oe_span6">
|
||||
<p class='oe_mt32'>
|
||||
SEO tools are ready to use, with no configuration required.
|
||||
OpenERP suggests keywords according to Google most searched
|
||||
terms, Google Analytics tracks your shopping cart events,
|
||||
sitemap and structuered content are created automatically for
|
||||
Google indexation, etc.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_bg_img">
|
||||
<img class="oe_picture oe_screenshot" src="">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.md or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
var containerTpl = CKEDITOR.addTemplate( 'sharedcontainer', '<div' +
|
||||
' id="cke_{name}"' +
|
||||
' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_shared cke_detached cke_{langDir} ' + CKEDITOR.env.cssClass + '"' +
|
||||
' dir="{langDir}"' +
|
||||
' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' +
|
||||
' lang="{langCode}"' +
|
||||
' role="presentation"' +
|
||||
'>' +
|
||||
'<div class="cke_inner">' +
|
||||
'<div id="{spaceId}" class="cke_{space}" role="presentation">{content}</div>' +
|
||||
'</div>' +
|
||||
'</div>' );
|
||||
|
||||
CKEDITOR.plugins.add( 'sharedspace', {
|
||||
afterInit: function( editor ) {
|
||||
var spaces = editor.config.sharedSpaces;
|
||||
|
||||
if ( spaces ) {
|
||||
for ( var spaceName in spaces ) {
|
||||
create( editor, spaceName, spaces[ spaceName ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function create( editor, spaceName, targetId ) {
|
||||
var target = CKEDITOR.document.getById( targetId ),
|
||||
innerHtml, space;
|
||||
|
||||
if ( target ) {
|
||||
// Have other plugins filling the space.
|
||||
innerHtml = editor.fire( 'uiSpace', { space: spaceName, html: '' } ).html;
|
||||
|
||||
if ( innerHtml ) {
|
||||
// Block the uiSpace handling by others (e.g. themed-ui).
|
||||
editor.on( 'uiSpace', function( ev ) {
|
||||
if ( ev.data.space == spaceName )
|
||||
ev.cancel();
|
||||
}, null, null, 1 ); // Hi-priority
|
||||
|
||||
// Inject the space into the target.
|
||||
space = target.append( CKEDITOR.dom.element.createFromHtml( containerTpl.output({
|
||||
id: editor.id,
|
||||
name: editor.name,
|
||||
langDir: editor.lang.dir,
|
||||
langCode: editor.langCode,
|
||||
space: spaceName,
|
||||
spaceId: editor.ui.spaceId( spaceName ),
|
||||
content: innerHtml
|
||||
})));
|
||||
|
||||
// Only the first container starts visible. Others get hidden.
|
||||
if ( target.getCustomData( 'cke_hasshared' ) )
|
||||
space.hide();
|
||||
else
|
||||
target.setCustomData( 'cke_hasshared', 1 );
|
||||
|
||||
// There's no need for the space to be selectable.
|
||||
space.unselectable();
|
||||
|
||||
// Prevent clicking on non-buttons area of the space from blurring editor.
|
||||
space.on( 'mousedown', function( evt ) {
|
||||
evt = evt.data;
|
||||
if ( !evt.getTarget().hasAscendant( 'a', 1 ) )
|
||||
evt.preventDefault();
|
||||
});
|
||||
|
||||
// Register this UI space to the focus manager.
|
||||
editor.focusManager.add( space, 1 );
|
||||
|
||||
// When the editor gets focus, show the space container, hiding others.
|
||||
editor.on( 'focus', function() {
|
||||
for ( var i = 0, sibling, children = target.getChildren(); ( sibling = children.getItem( i ) ); i++ ) {
|
||||
if ( sibling.type == CKEDITOR.NODE_ELEMENT &&
|
||||
!sibling.equals( space ) &&
|
||||
sibling.hasClass( 'cke_shared' ) ) {
|
||||
sibling.hide();
|
||||
}
|
||||
}
|
||||
|
||||
space.show();
|
||||
});
|
||||
|
||||
editor.on( 'destroy', function() {
|
||||
space.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Makes it possible to place some of the editor UI blocks, like the toolbar
|
||||
* and the elements path, into any element in the page.
|
||||
*
|
||||
* The elements used to hold the UI blocks can be shared among several editor
|
||||
* instances. In that case, only the blocks of the active editor instance will
|
||||
* display.
|
||||
*
|
||||
* // Place the toolbar inside the element with ID "someElementId" and the
|
||||
* // elements path into the element with ID "anotherId".
|
||||
* config.sharedSpaces = {
|
||||
* top: 'someElementId',
|
||||
* bottom: 'anotherId'
|
||||
* };
|
||||
*
|
||||
* // Place the toolbar inside the element with ID "someElementId". The
|
||||
* // elements path will remain attached to the editor UI.
|
||||
* config.sharedSpaces = {
|
||||
* top: 'someElementId'
|
||||
* };
|
||||
*
|
||||
* @cfg {Object} [sharedSpaces]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
@@ -1,3 +1,4 @@
|
||||
@charset "utf-8";
|
||||
.oe_website_editorbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -43,5 +44,13 @@
|
||||
}
|
||||
|
||||
.oe_editable:focus {
|
||||
outline: #80b5f2 solid 5px !important;
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.oe_carousel_options {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -39,4 +39,11 @@
|
||||
padding-left: 6px
|
||||
|
||||
.oe_editable:focus
|
||||
outline: #80B5F2 solid 5px !important
|
||||
outline: none !important
|
||||
|
||||
.oe_carousel_options
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
white-space: nowrap
|
||||
z-index: 1
|
||||
display: none
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
/* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
|
||||
*
|
||||
* css for editor buttons, openerp widget included in the website and other
|
||||
* stuff must go to the editor.css
|
||||
*
|
||||
*/
|
||||
/* ----- GENERIC LAYOUTING HELPERS ---- */
|
||||
/* Vertical Spacing */
|
||||
.mt128 {
|
||||
margin-top: 128px !important;
|
||||
}
|
||||
@@ -34,6 +42,88 @@
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
.mb128 {
|
||||
margin-bottom: 128px !important;
|
||||
}
|
||||
|
||||
.mb92 {
|
||||
margin-bottom: 92px !important;
|
||||
}
|
||||
|
||||
.mb64 {
|
||||
margin-bottom: 64px !important;
|
||||
}
|
||||
|
||||
.mb48 {
|
||||
margin-bottom: 48px !important;
|
||||
}
|
||||
|
||||
.mb32 {
|
||||
margin-bottom: 32px !important;
|
||||
}
|
||||
|
||||
.mb16 {
|
||||
margin-bottom: 16px !important;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.mb4 {
|
||||
margin-bottom: 4px !important;
|
||||
}
|
||||
|
||||
.mb0 {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
/* Grid of unequally tall elements */
|
||||
.grid > [class*="span"] {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
vertical-align: top;
|
||||
margin-right: -4px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.grid > [class*="span"].grid-align-top > [class*="span"] {
|
||||
vertical-align: top;
|
||||
}
|
||||
.grid > [class*="span"].grid-align-middle > [class*="span"] {
|
||||
vertical-align: middle;
|
||||
}
|
||||
.grid > [class*="span"].grid-align-bottom > [class*="span"] {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/* Table with two collumns aligned on the center */
|
||||
.table-equalized {
|
||||
width: 100%;
|
||||
}
|
||||
.table-equalized td:first-child {
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
padding-right: 1em;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.table-equalized td:last-child {
|
||||
width: 50%;
|
||||
text-align: left;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
/* Theming pagination inside navbar */
|
||||
.navbar-inner > .pagination {
|
||||
margin: 6px 0;
|
||||
}
|
||||
.navbar-inner > .pagination ul {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
border: solid 2px rgba(0, 0, 0, 0.05);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
|
||||
html, body {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
@@ -57,6 +147,7 @@ footer {
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
/* ---- HOMEPAGE THEME CUSTOMIZATION ---- */
|
||||
.subheader {
|
||||
letter-spacing: 3px;
|
||||
font-weight: 300;
|
||||
@@ -75,10 +166,20 @@ h5 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#myCarousel .item {
|
||||
min-height: 300px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav > .pull-right {
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
|
||||
.navbar .nav > li > p {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
@@ -98,16 +199,3 @@ h5 {
|
||||
.nav > li a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#myCarousel .item {
|
||||
min-height: 300px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.carousel > .css_carousel_options {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
}
|
||||
@@ -1,5 +1,16 @@
|
||||
@charset "utf-8"
|
||||
|
||||
/*
|
||||
* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
|
||||
*
|
||||
* css for editor buttons, openerp widget included in the website and other
|
||||
* stuff must go to the editor.css
|
||||
*
|
||||
*/
|
||||
|
||||
/* ----- GENERIC LAYOUTING HELPERS ---- */
|
||||
|
||||
/* Vertical Spacing */
|
||||
.mt128
|
||||
margin-top: 128px !important
|
||||
.mt92
|
||||
@@ -19,6 +30,62 @@
|
||||
.mt0
|
||||
margin-top: 0px !important
|
||||
|
||||
.mb128
|
||||
margin-bottom: 128px !important
|
||||
.mb92
|
||||
margin-bottom: 92px !important
|
||||
.mb64
|
||||
margin-bottom: 64px !important
|
||||
.mb48
|
||||
margin-bottom: 48px !important
|
||||
.mb32
|
||||
margin-bottom: 32px !important
|
||||
.mb16
|
||||
margin-bottom: 16px !important
|
||||
.mb8
|
||||
margin-bottom: 8px !important
|
||||
.mb4
|
||||
margin-bottom: 4px !important
|
||||
.mb0
|
||||
margin-bottom: 0px !important
|
||||
|
||||
/* Grid of unequally tall elements */
|
||||
.grid > [class*="span"]
|
||||
display: inline-block
|
||||
float: none
|
||||
vertical-align: top
|
||||
margin-right: -4px
|
||||
box-sizing: border-box
|
||||
&.grid-align-top > [class*="span"]
|
||||
vertical-align: top
|
||||
&.grid-align-middle > [class*="span"]
|
||||
vertical-align: middle
|
||||
&.grid-align-bottom > [class*="span"]
|
||||
vertical-align: bottom
|
||||
|
||||
/* Table with two collumns aligned on the center */
|
||||
.table-equalized
|
||||
width: 100%
|
||||
td:first-child
|
||||
width: 50%
|
||||
text-align: right
|
||||
padding-right: 1em
|
||||
vertical-align: bottom
|
||||
td:last-child
|
||||
width: 50%
|
||||
text-align: left
|
||||
vertical-align: bottom
|
||||
|
||||
/* Theming pagination inside navbar */
|
||||
.navbar-inner > .pagination
|
||||
margin: 6px 0
|
||||
ul
|
||||
position: relative
|
||||
top: 2px
|
||||
border: solid 2px rgba(0,0,0,0.05)
|
||||
border-radius: 8px
|
||||
|
||||
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
|
||||
|
||||
html,body
|
||||
height: 100%
|
||||
@@ -39,8 +106,8 @@ footer
|
||||
background: rgb(239, 248, 248) // rgb(221, 235, 227)
|
||||
padding-top: 64px
|
||||
padding-bottom: 64px
|
||||
//*
|
||||
color: #1abc9c !important
|
||||
|
||||
/* ---- HOMEPAGE THEME CUSTOMIZATION ---- */
|
||||
|
||||
.subheader
|
||||
letter-spacing: 3px
|
||||
@@ -56,9 +123,19 @@ header.navbar-fixed-top
|
||||
h5
|
||||
font-weight: bold
|
||||
|
||||
#myCarousel .item
|
||||
min-height: 300px
|
||||
color: white
|
||||
|
||||
|
||||
.nav > .pull-right
|
||||
float: right !important //bugfix for flatly theme
|
||||
|
||||
.thumbnail
|
||||
background: white
|
||||
|
||||
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
|
||||
|
||||
.navbar .nav > li > p
|
||||
margin-bottom: 0px
|
||||
|
||||
@@ -75,13 +152,3 @@ h5
|
||||
.nav > li a
|
||||
display: block
|
||||
|
||||
#myCarousel .item
|
||||
min-height: 300px
|
||||
color: white
|
||||
|
||||
.carousel > .css_carousel_options
|
||||
cursor: pointer
|
||||
position: absolute
|
||||
white-space: nowrap
|
||||
z-index: 1
|
||||
display: none
|
||||
@@ -159,157 +159,16 @@ instance.website.EditorBar = instance.web.Widget.extend({
|
||||
},
|
||||
});
|
||||
|
||||
instance.website.Action = instance.web.Widget.extend({
|
||||
tagName: 'button',
|
||||
attributes: {
|
||||
type: 'button',
|
||||
},
|
||||
events: { click: 'perform' },
|
||||
init: function (parent, name) {
|
||||
this._super(parent);
|
||||
this.name = name;
|
||||
},
|
||||
start: function () {
|
||||
this.$el.text(this.name);
|
||||
return this._super();
|
||||
},
|
||||
/**
|
||||
* Executes action
|
||||
*/
|
||||
perform: null,
|
||||
toggle: function (to) {
|
||||
this.$el.prop('disabled', !to);
|
||||
},
|
||||
});
|
||||
var Style = instance.website.Style = instance.website.Action.extend({
|
||||
init: function (parent, name, style) {
|
||||
this._super(parent, name);
|
||||
this.style = style;
|
||||
},
|
||||
perform: function () {
|
||||
this.getParent().with_editor(function (editor) {
|
||||
editor.applyStyle(new CKEDITOR.style(this.style))
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
var Command = instance.website.Command = instance.website.Action.extend({
|
||||
init: function (parent, name, command) {
|
||||
this._super(parent, name);
|
||||
this.command = command;
|
||||
},
|
||||
perform: function () {
|
||||
this.getParent().with_editor(function (editor) {
|
||||
switch (typeof this.command) {
|
||||
case 'string': editor.execCommand(this.command); break;
|
||||
case 'function': this.command(editor); break;
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
var Group = instance.website.ActionGroup = instance.website.Action.extend({
|
||||
template: 'Website.ActionGroup',
|
||||
events: { 'click > button': 'perform' },
|
||||
instances: [],
|
||||
init: function (parent, name, actions) {
|
||||
this._super(parent, name);
|
||||
this.actions = _(actions).map(this.getParent().proxy('init_command'));
|
||||
},
|
||||
start: function () {
|
||||
this.instances.push(this);
|
||||
var $ul = this.$('ul');
|
||||
return $.when.apply(null, _(this.actions).map(function (action) {
|
||||
var $li = $('<li>').appendTo($ul);
|
||||
return action.appendTo($li);
|
||||
}));
|
||||
},
|
||||
destroy: function () {
|
||||
this.instances = _(this.instances).without(this);
|
||||
return this._super();
|
||||
},
|
||||
perform: function () {
|
||||
this.getParent().with_editor(function () {
|
||||
_(this.instances).chain()
|
||||
.without(this)
|
||||
.pluck('$el')
|
||||
.invoke('removeClass', 'open');
|
||||
// JS part of bootstrap dropdown does really weird stuff which
|
||||
// interacts quite badly with the RTE thing, so bypass it
|
||||
this.$el.toggleClass('open');
|
||||
}.bind(this), false);
|
||||
return false;
|
||||
},
|
||||
toggle: function (to) {
|
||||
this.$('> button').prop('disabled', !to);
|
||||
},
|
||||
});
|
||||
|
||||
instance.website.RTE = instance.web.Widget.extend({
|
||||
tagName: 'li',
|
||||
id: 'oe_rte_toolbar',
|
||||
className: 'oe_right oe_rte_toolbar',
|
||||
commands: [
|
||||
[Command, "\uf032", 'bold'],
|
||||
[Command, "\uf033", 'italic'],
|
||||
[Command, "\uf0cd", 'underline'],
|
||||
[Command, "\uf0cc", 'strike'],
|
||||
[Command, "\uf12b", 'superscript'],
|
||||
[Command, "\uf12c", 'subscript'],
|
||||
[Command, "\uf0c1", 'link'],
|
||||
[Command, "\uf127", 'unlink'],
|
||||
[Command, "\uf10d", 'blockquote'],
|
||||
// 'image' uses either filebrowserImageUploadUrl or
|
||||
// filebrowserUploadUrl, and provides a `link` tab. imagebutton only
|
||||
// uses filebrowserImageUploadUrl and does not provide a `link` tab to
|
||||
// hotlink an image from the internets.
|
||||
[Command, "\uf03e", 'image'],
|
||||
// [Command, "\uf030", 'imagebutton'],
|
||||
[Group, "\uf0ca", [
|
||||
[Command, "\uf0ca", 'bulletedlist'],
|
||||
[Command, "\uf0cb", 'numberedlist'],
|
||||
[Command, "\uf03b", 'outdent'],
|
||||
[Command, "\uf03c", 'indent']
|
||||
]],
|
||||
[Group, _lt("Heading"), [
|
||||
[Style, _lt('H1'), { element: 'h1' }],
|
||||
[Style, _lt('H2'), { element: 'h2', }],
|
||||
[Style, _lt('H3'), { element: 'h3', }],
|
||||
[Style, _lt('H4'), { element: 'h4', }],
|
||||
[Style, _lt('H5'), { element: 'h5', }],
|
||||
[Style, _lt('H6'), { element: 'h6', }]
|
||||
]],
|
||||
[Group, "\uf039", [
|
||||
[Command, "\uf039", 'justifyblock'],
|
||||
[Command, "\uf036", 'justifyleft'],
|
||||
[Command, "\uf038", 'justifyright'],
|
||||
[Command, "\uf037", 'justifycenter']
|
||||
]]
|
||||
],
|
||||
// editor.ui.items -> possible commands &al
|
||||
// editor.applyStyle(new CKEDITOR.style({element: "span",styles: {color: "#(color)"},overrides: [{element: "font",attributes: {color: null}}]}, {color: '#ff0000'}));
|
||||
start: function () {
|
||||
this.$el.hide();
|
||||
|
||||
return $.when.apply(
|
||||
null, _(this.commands).map(this.proxy('start_command')));
|
||||
},
|
||||
init_command: function (command) {
|
||||
var type = command[0], args = command.slice(1);
|
||||
args.unshift(this);
|
||||
var F = function (args) {
|
||||
return type.apply(this, args);
|
||||
};
|
||||
F.prototype = type.prototype;
|
||||
|
||||
return new F(args);
|
||||
},
|
||||
start_command: function (command) {
|
||||
return this.init_command(command).appendTo(this.$el);
|
||||
},
|
||||
start_edition: function ($elements) {
|
||||
var self = this;
|
||||
this.$el.show();
|
||||
this.disable();
|
||||
this.snippet_carousel();
|
||||
CKEDITOR.on('currentInstance', this.proxy('_change_focused_editor'));
|
||||
$elements
|
||||
.not('span, [data-oe-type]')
|
||||
.each(function () {
|
||||
@@ -321,48 +180,17 @@ instance.website.RTE = instance.web.Widget.extend({
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Function} fn
|
||||
* @param {Boolean} [snapshot=true]
|
||||
* @returns {$.Deferred}
|
||||
*/
|
||||
with_editor: function (fn, snapshot) {
|
||||
var editor = this._current_editor();
|
||||
if (snapshot !== false) { editor.fire('saveSnapshot'); }
|
||||
return $.when(fn(editor)).then(function () {
|
||||
if (snapshot !== false) { editor.fire('saveSnapshot'); }
|
||||
editor.focus();
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
toggle: function (to) {
|
||||
_(this.getChildren()).chain()
|
||||
.filter(function (child) { return child instanceof instance.website.Action })
|
||||
.invoke('toggle', to);
|
||||
},
|
||||
disable: function () {
|
||||
this.toggle(false);
|
||||
},
|
||||
|
||||
_current_editor: function () {
|
||||
return CKEDITOR.currentInstance;
|
||||
},
|
||||
_change_focused_editor: function () {
|
||||
this.toggle(!!CKEDITOR.currentInstance);
|
||||
},
|
||||
_config: function () {
|
||||
var removed_plugins = [
|
||||
// remove toolbar entirely
|
||||
'toolbar,elementspath,resize',
|
||||
// remove custom context menu
|
||||
'contextmenu,tabletools,liststyle',
|
||||
// magicline captures mousein/mouseout => draggable does not work
|
||||
'magicline'
|
||||
];
|
||||
return {
|
||||
// Don't load ckeditor's style rules
|
||||
stylesSet: [],
|
||||
removePlugins: removed_plugins.join(','),
|
||||
uiColor: '',
|
||||
// Ensure no config file is loaded
|
||||
@@ -372,6 +200,31 @@ instance.website.RTE = instance.web.Widget.extend({
|
||||
// Don't insert paragraphs around content in e.g. <li>
|
||||
autoParagraph: false,
|
||||
filebrowserImageUploadUrl: "/website/attach",
|
||||
// Support for sharedSpaces in 4.x
|
||||
extraPlugins: 'sharedspace',
|
||||
// Place toolbar in controlled location
|
||||
sharedSpaces: { top: 'oe_rte_toolbar' },
|
||||
toolbar: [
|
||||
{name: 'items', items: [
|
||||
"Bold", "Italic", "Underline", "Strike", "Subscript",
|
||||
"Superscript", "TextColor", "BGColor", "RemoveFormat",
|
||||
"Link", "Unlink", "Blockquote", "BulletedList",
|
||||
"NumberedList", "Image", "Indent", "Outdent",
|
||||
"JustifyLeft", "JustifyCenter", "JustifyRight",
|
||||
"JustifyBlock", "Table", "Font", "FontSize", "Format",
|
||||
"Styles"
|
||||
]}
|
||||
],
|
||||
// styles dropdown in toolbar
|
||||
stylesSet: [
|
||||
// emphasis
|
||||
{name: "Muted", element: 'span', attributes: {'class': 'text-muted'}},
|
||||
{name: "Primary", element: 'span', attributes: {'class': 'text-primary'}},
|
||||
{name: "Warning", element: 'span', attributes: {'class': 'text-warning'}},
|
||||
{name: "Danger", element: 'span', attributes: {'class': 'text-danger'}},
|
||||
{name: "Success", element: 'span', attributes: {'class': 'text-success'}},
|
||||
{name: "Info", element: 'span', attributes: {'class': 'text-info'}}
|
||||
],
|
||||
};
|
||||
},
|
||||
// TODO clean
|
||||
|
||||
@@ -53,8 +53,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<title t-raw="title"><t t-esc="res_company.name"/></title>
|
||||
<script type="text/javascript" src="/web/static/lib/jquery/jquery-1.8.3.js"></script>
|
||||
<script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.2/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/website/static/lib/ckeditor.sharedspace/plugin.js"></script>
|
||||
<script type="text/javascript">
|
||||
CKEDITOR.disableAutoInline = true;
|
||||
CKEDITOR.dtd.$editable.li = 1;
|
||||
@@ -198,7 +199,7 @@
|
||||
|
||||
<section>
|
||||
<div id="myCarousel" class="carousel slide" data-interval='1000000'>
|
||||
<div class="css_carousel_options js_carousel_options" t-ignore="1">
|
||||
<div class="oe_carousel_options js_carousel_options" t-ignore="1">
|
||||
<span class="label js_add"><i class="icon-plus-sign"></i></span>
|
||||
<span class="label js_remove"><i class="icon-minus-sign"></i></span>
|
||||
</div>
|
||||
@@ -206,7 +207,7 @@
|
||||
<div class="carousel-inner">
|
||||
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;" >
|
||||
<div class='container'>
|
||||
<h1 class='mt64'>A Nice Banner</h1>
|
||||
<h1 class='mt64'>A Nice Bidule</h1>
|
||||
<h2>A convincing subtitle</h2>
|
||||
<a href='#' class='btn btn-success btn-large mt16'>And a <em>Call To Action</em></a>
|
||||
</div>
|
||||
@@ -318,13 +319,13 @@
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<h1>404: Page not found!</h1>
|
||||
<p class="oe_grey">
|
||||
<p>
|
||||
The page you were looking for could not be
|
||||
found; it is possible you have typed the
|
||||
address incorrectly, but it has most
|
||||
probably been removed due to the recent
|
||||
website reorganisation.
|
||||
</p><p class="oe_grey">
|
||||
</p><p>
|
||||
Maybe you were looking for one of these
|
||||
popular pages ?
|
||||
</p>
|
||||
@@ -335,8 +336,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<a class="oe_button oe_big oe_tacky" t-att-href="'/pagenew/'+path" t-if="editable">Create Page</a>
|
||||
<div class="span12 mt32">
|
||||
<a class="btn btn-primary" t-att-href="'/pagenew/'+path" t-if="editable">Create Page</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+20
-16
@@ -9,13 +9,10 @@ from openerp.addons.web.http import request
|
||||
|
||||
def auth_method_public():
|
||||
registry = openerp.modules.registry.RegistryManager.get(request.db)
|
||||
request.public_uid = None
|
||||
with registry.cursor() as cr:
|
||||
request.public_uid = request.registry['ir.model.data'].get_object_reference(cr, openerp.SUPERUSER_ID, 'website', 'public_user')[1]
|
||||
if not request.session.uid:
|
||||
request.uid = request.public_uid
|
||||
else:
|
||||
request.uid = request.session.uid
|
||||
if not request.session.uid:
|
||||
request.uid = registry['website'].get_public_user().id
|
||||
else:
|
||||
request.uid = request.session.uid
|
||||
http.auth_methods['public'] = auth_method_public
|
||||
|
||||
|
||||
@@ -23,14 +20,21 @@ class website(osv.osv):
|
||||
_name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
|
||||
_description = "Website"
|
||||
|
||||
public_user = None
|
||||
|
||||
def get_public_user(self):
|
||||
if not self.public_user:
|
||||
ref = request.registry['ir.model.data'].get_object_reference(request.cr, openerp.SUPERUSER_ID, 'website', 'public_user')
|
||||
self.public_user = request.registry[ref[0]].browse(request.cr, openerp.SUPERUSER_ID, ref[1])
|
||||
return self.public_user
|
||||
|
||||
def get_rendering_context(self, additional_values=None):
|
||||
debug = 'debug' in request.params
|
||||
editable = False
|
||||
if request.uid or (request.public_uid and request.uid != request.public_uid):
|
||||
editable = True
|
||||
is_public_user = request.uid == self.get_public_user().id
|
||||
values = {
|
||||
'debug': debug,
|
||||
'editable': editable,
|
||||
'is_public_user': is_public_user,
|
||||
'editable': not is_public_user,
|
||||
'request': request,
|
||||
'registry': request.registry,
|
||||
'cr': request.cr,
|
||||
@@ -38,7 +42,7 @@ class website(osv.osv):
|
||||
'host_url': request.httprequest.host_url,
|
||||
'res_company': request.registry['res.company'].browse(request.cr, openerp.SUPERUSER_ID, 1),
|
||||
}
|
||||
if editable:
|
||||
if values['editable']:
|
||||
values.update({
|
||||
'script': "\n".join(['<script type="text/javascript" src="%s"></script>' % i for i in main.manifest_list('js', db=request.db, debug=debug)]),
|
||||
'css': "\n".join('<link rel="stylesheet" href="%s">' % i for i in main.manifest_list('css', db=request.db, debug=debug))
|
||||
@@ -48,7 +52,7 @@ class website(osv.osv):
|
||||
return values
|
||||
|
||||
def render(self, template, values={}):
|
||||
# context = {
|
||||
# 'inherit_branding': values['editable'],
|
||||
# }
|
||||
return request.registry.get("ir.ui.view").render(request.cr, request.uid, template, values)
|
||||
context = {
|
||||
'inherit_branding': values.get('editable', False),
|
||||
}
|
||||
return request.registry.get("ir.ui.view").render(request.cr, request.uid, template, values, context=context)
|
||||
|
||||
@@ -8,7 +8,7 @@ OpenERP Blog
|
||||
|
||||
""",
|
||||
'author': 'OpenERP SA',
|
||||
'depends': ['website', 'event', 'website_sale'],
|
||||
'depends': ['website', 'event_sale', 'website_sale'],
|
||||
'data': [
|
||||
'views/website_event.xml',
|
||||
'security/ir.model.access.csv',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.tools.translate import _
|
||||
@@ -61,11 +62,10 @@ class website_event(http.Controller):
|
||||
domain_search["country"] = [("country_id", "=", int(searches.get("country")))]
|
||||
|
||||
def dom_without(without):
|
||||
domain = [(1, "=", 1)]
|
||||
domain = SUPERUSER_ID != request.uid and [('website_published', '=', True)] or [(1, "=", 1)]
|
||||
for key, search in domain_search.items():
|
||||
if key != without:
|
||||
domain += search
|
||||
print domain
|
||||
return domain
|
||||
|
||||
# count by domains without self search
|
||||
@@ -96,7 +96,7 @@ class website_event(http.Controller):
|
||||
@http.route(['/event/<int:event_id>'], type='http', auth="public")
|
||||
def event(self, event_id=None, **post):
|
||||
website = request.registry['website']
|
||||
event = request.registry['event.event'].browse(request.cr, request.uid, event_id)
|
||||
event = request.registry['event.event'].browse(request.cr, request.uid, event_id, {'show_address': 1})
|
||||
values = website.get_rendering_context({
|
||||
'event_id': event,
|
||||
'google_map_url': "http://maps.googleapis.com/maps/api/staticmap?center=%s&sensor=false&zoom=12&size=298x298" % urllib.quote_plus('%s, %s %s, %s' % (event.street, event.city, event.zip, event.country_id and event.country_id.name_get()[0][1] or ''))
|
||||
|
||||
@@ -8,16 +8,29 @@ class event(osv.osv):
|
||||
_columns = {
|
||||
'website_published': fields.boolean('Available in the website'),
|
||||
'description_website': fields.html('Description for the website'),
|
||||
'product_ids': fields.one2many('event.event.product', "event_id", "Event"),
|
||||
'event_product_ids': fields.one2many('event.event.product', "event_id", "Event"),
|
||||
'organizer_id': fields.many2one('res.partner', "Orgonizer"),
|
||||
'phone': fields.related('orgonizer_id', 'phone', type='char', string='Phone'),
|
||||
'email': fields.related('orgonizer_id', 'email', type='char', string='Email'),
|
||||
}
|
||||
|
||||
|
||||
class event_product(osv.osv):
|
||||
_name = 'event.event.product'
|
||||
_columns = {
|
||||
'deadline': fields.date("Sales End"),
|
||||
'event_id': fields.many2one('event.event', "Event"),
|
||||
'product_id': fields.many2one('product.product', 'Product'),
|
||||
'product_id': fields.many2one('product.product', 'Product', domain=[("event_type_id", "!=", False)]),
|
||||
'price': fields.float('Price'),
|
||||
'qty': fields.integer('Current Registrations', readonly=True),
|
||||
'max_qty': fields.integer('Maximum Registrations'),
|
||||
}
|
||||
def onchange_product_id(self, cr, uid, ids, product_id=False, context=None):
|
||||
return {'value': {'price': self.pool.get("product.product").browse(cr, uid, product_id).list_price or 0}}
|
||||
|
||||
|
||||
class product(osv.osv):
|
||||
_inherit = 'product.product'
|
||||
_columns = {
|
||||
'event_product_ids': fields.one2many('event.event.product', 'product_id', 'Linked event product'),
|
||||
}
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
|
||||
access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
|
||||
access_event_event_product_public,event.event.product.public,website_event.model_event_event_product,base.group_public,1,0,0,0
|
||||
access_event_product_product_public,event.product.product.public,product.model_product_product,base.group_public,1,0,0,0
|
||||
|
@@ -11,5 +11,25 @@
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record id="event_event_product_public" model="ir.rule">
|
||||
<field name="name">event product: Public</field>
|
||||
<field name="model_id" ref="website_event.model_event_event_product"/>
|
||||
<field name="domain_force">[('event_id.website_published', '=', True)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record id="event_product_product_public" model="ir.rule">
|
||||
<field name="name">Product linked to event: Public</field>
|
||||
<field name="model_id" ref="product.model_product_product"/>
|
||||
<field name="domain_force">[("event_type_id", "!=", False), ('event_product_ids.event_id.website_published', '=', True)]</field>
|
||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -10,17 +10,19 @@
|
||||
<data>
|
||||
<xpath expr="//notebook" position="inside">
|
||||
<page string="Tarifs">
|
||||
<group colspan="4">
|
||||
<field name="product_ids">
|
||||
<tree string="Payments" editable="top">
|
||||
<field name="product_id"/>
|
||||
<field name="price"/>
|
||||
<field name="max_qty"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
<field name="product_ids">
|
||||
<tree string="Payments" editable="bottom">
|
||||
<field name="product_id" on_change='onchange_product_id(product_id)'/>
|
||||
<field name="deadline"/>
|
||||
<field name="price"/>
|
||||
<field name="max_qty"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</xpath>
|
||||
<field name="address_id" position="after">
|
||||
<field name="organizer_id"/>
|
||||
</field>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
@@ -51,19 +53,7 @@
|
||||
</record>
|
||||
|
||||
<!-- Page -->
|
||||
<template id="button">
|
||||
<t t-if="event_id.register_avail">
|
||||
<span t-if="event_id.register_avail == 9999" class="label pull-right">No ticket available.</span>
|
||||
<span t-if="event_id.register_avail != 9999" t-att-class="'label pull-right label-%%s' %% (event_id.register_avail <= 10 and 'warning' or 'info')">
|
||||
<t t-if="event_id.register_avail <= 10">Only</t>
|
||||
<t t-esc="event_id.register_avail"/>
|
||||
<t t-if="event_id.register_avail > 1">tickets </t>
|
||||
<t t-if="event_id.register_avail == 1">ticket </t>
|
||||
available.
|
||||
</span>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
|
||||
<template id="index">
|
||||
<t t-call="website.layout">
|
||||
<t t-set="head">
|
||||
@@ -85,7 +75,7 @@
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">Category</li>
|
||||
<t t-foreach="types">
|
||||
<li t-if="type" t-att-class="searches.get('type') == str(type[0]) and 'active' or ''">
|
||||
<li t-if="type" t-att-class="searches.get('type') == str(type and type[0]) and 'active' or ''">
|
||||
<a t-att-href="'/event/%%s&type=%%s' %% (search_path, type[0])"><t t-esc="type[1]"/> <small>(<t t-esc="type_count"/>)</small></a>
|
||||
</li>
|
||||
</t>
|
||||
@@ -93,7 +83,7 @@
|
||||
<ul class="nav nav-list">
|
||||
<li class="nav-header">Location</li>
|
||||
<t t-foreach="countries">
|
||||
<li t-if="country_id" t-att-class="searches.get('country') == str(country_id[0]) and 'active' or ''">
|
||||
<li t-if="country_id" t-att-class="searches.get('country') == str(country_id and country_id[0]) and 'active' or ''">
|
||||
<a t-att-href="'/event/%%s&country=%%s' %% (search_path, country_id[0])"><t t-esc="country_id[1]"/><small>(<t t-esc="country_id_count"/>)</small></a>
|
||||
</li>
|
||||
</t>
|
||||
@@ -101,30 +91,37 @@
|
||||
</div>
|
||||
<div class="span8">
|
||||
<ul class="media-list mt32">
|
||||
<t t-foreach="event_ids" t-as="event_id">
|
||||
<li class="media thumbnail">
|
||||
<div class="media-body">
|
||||
<t t-call="website_event.button"/>
|
||||
<h4 class="media-heading"><a t-att-href="'/event/%%s' %% event_id.id"><span t-field="event_id.name"> </span></a></h4>
|
||||
<a t-if="editable" href="#" t-att-data-id="event_id.id" class="pull-right">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not event_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (event_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<div>
|
||||
<span t-field="event_id.type">: </span>
|
||||
<t t-if="event_id.user_id">
|
||||
Organized by: <span t-field="event_id.user_id"> </span>
|
||||
</t>
|
||||
</div>
|
||||
<div>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_begin"> </span> <i>to</i> <span t-field="event_id.date_end"> </span>
|
||||
</div>
|
||||
<div t-if="event_id.country_id">
|
||||
<i class="icon-map-marker"></i> <span t-field="event_id.city"> </span> <span t-field="event_id.zip"> </span>, <span t-field="event_id.country_id"> </span>
|
||||
</div>
|
||||
<li t-foreach="event_ids" t-as="event_id" class="media thumbnail">
|
||||
<div class="media-body">
|
||||
<t t-if="event_id.register_avail">
|
||||
<span t-if="event_id.register_avail == 9999" class="label pull-right">No ticket available.</span>
|
||||
<span t-if="event_id.register_avail != 9999" t-att-class="'label pull-right label-%%s' %% (event_id.register_avail <= 10 and 'warning' or 'info')">
|
||||
<t t-if="event_id.register_avail <= 10">Only</t>
|
||||
<t t-esc="event_id.register_avail"/>
|
||||
<t t-if="event_id.register_avail > 1">tickets </t>
|
||||
<t t-if="event_id.register_avail == 1">ticket </t>
|
||||
available.
|
||||
</span>
|
||||
</t>
|
||||
<h4 class="media-heading"><a t-att-href="'/event/%%s/' %% event_id.id"><span t-field="event_id.name"> </span></a></h4>
|
||||
<a t-if="editable" href="#" t-att-data-id="event_id.id" class="pull-right">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not event_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (event_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<div>
|
||||
<span t-field="event_id.type">: </span>
|
||||
<t t-if="event_id.user_id">
|
||||
Organized by: <span t-field="event_id.user_id"> </span>
|
||||
</t>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
<div>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_begin"> </span> <i>to</i> <span t-field="event_id.date_end"> </span>
|
||||
</div>
|
||||
<div t-if="event_id.country_id">
|
||||
<i class="icon-map-marker"></i> <span t-field="event_id.city"> </span> <span t-field="event_id.zip"> </span>, <span t-field="event_id.country_id"> </span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -145,41 +142,59 @@
|
||||
<h4>When & Where</h4>
|
||||
<img t-att-src="google_map_url"/>
|
||||
<address>
|
||||
<h4 t-field="event_id.address_id">Name</h4><br/>
|
||||
<span t-field="event_id.street"/><br/>
|
||||
<span t-field="event_id.city"/>, <span t-field="event_id.zip"/><br/>
|
||||
<span t-field="event_id.country_id"> </span><br/>
|
||||
<pre t-field="event_id.address_id"/>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_begin"> </span><br/>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_end"> </span><br/>
|
||||
<br/>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_end"> </span>
|
||||
<t t-if="event_id.user_id">
|
||||
Organized by: <span t-field="event_id.user_id"/><br/>
|
||||
<span>&#x2706; <span t-field="event_id.user_id.phone"></span></span><br/>
|
||||
<i class="icon-envelope"></i> <span t-field="event_id.user_id.email"></span>
|
||||
<h6>Organized by:</h6>
|
||||
<pre><t t-field="event_id.organizer_id"/><br/><span>&#x2706;</span> <span t-field="event_id.phone"></span><br/><i class="icon-envelope"></i> <span t-field="event_id.email"></span></pre>
|
||||
</t>
|
||||
</address>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<div class="media-body">
|
||||
<t t-call="website_event.button"/>
|
||||
<h4 class="media-heading"><a t-att-href="'/event/%%s' %% event_id.id"><span t-field="event_id.name"> </span></a></h4>
|
||||
<t t-if="event_id.register_avail">
|
||||
<span t-if="event_id.register_avail == 9999" class="label pull-right">No ticket available.</span>
|
||||
<span t-if="event_id.register_avail != 9999" t-att-class="'label pull-right label-%%s' %% (event_id.register_avail <= 10 and 'warning' or 'info')">
|
||||
<t t-if="event_id.register_avail <= 10">Only</t>
|
||||
<t t-esc="event_id.register_avail"/>
|
||||
<t t-if="event_id.register_avail > 1">tickets </t>
|
||||
<t t-if="event_id.register_avail == 1">ticket </t>
|
||||
available.
|
||||
</span>
|
||||
</t>
|
||||
<h4 class="media-heading"><a t-att-href="'/event/%%s/' %% event_id.id"><span t-field="event_id.name"> </span></a></h4>
|
||||
<h5 class="media-heading">
|
||||
<span t-field="event_id.address_id"/><br/>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_begin"/><br/>
|
||||
<i class="icon-time"></i> <span t-field="event_id.date_end"/>
|
||||
</h5>
|
||||
<a t-if="editable" href="#" t-att-data-id="event_id.id" class="pull-right">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not event_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (event_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<h4>Ticket Information</h4>
|
||||
<form t-att-action="'/event/%%s/add_cart' %% event_id.id" method="post">
|
||||
<div t-foreach="event_id.product_ids" t-as="prod">
|
||||
<span t-field="prod.product_id"/>
|
||||
<span t-field="prod.price"/>
|
||||
<span t-field="prod.qty"/>
|
||||
<span t-field="prod.max_qty"/>
|
||||
<select t-att-name="'product[%%s]' %% prod.id">
|
||||
<t t-foreach="range(0,10)" t-as="nb">
|
||||
<option t-esc="nb"/>
|
||||
</t>
|
||||
</select>
|
||||
</div>
|
||||
<h4 t-if="event_id.event_product_ids">Ticket Information</h4>
|
||||
<form t-att-action="'/event/%%s/add_cart' %% event_id.id" method="post" t-if="event_id.event_product_ids">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Ticket type</th>
|
||||
<th>Sales End</th>
|
||||
<th>Price</th>
|
||||
<th>Seats</th>
|
||||
<th>Quantity</th>
|
||||
</tr>
|
||||
<tr t-foreach="event_id.event_product_ids" t-as="prod">
|
||||
<td t-field="prod.product_id"/>
|
||||
<td t-field="prod.deadline"/>
|
||||
<td t-field="prod.price"/>
|
||||
<td><span t-if="prod.max_qty"><t t-esc="prod.qty"/>/<t t-field="prod.max_qty"/></span></td>
|
||||
<td>
|
||||
<select t-att-name="'product[%%s]' %% prod.id">
|
||||
<t t-foreach="range(0,10)" t-as="nb"><option t-esc="nb"/></t>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="submit" class="btn btn-primary">Order Now</button>
|
||||
</form>
|
||||
<h4>Event Details</h4>
|
||||
|
||||
@@ -7,6 +7,5 @@ class hr(osv.osv):
|
||||
_inherit = 'hr.employee'
|
||||
_columns = {
|
||||
'website_published': fields.boolean('Available in the website'),
|
||||
'website_published_on_contact_form': fields.boolean('Publish', help="Publish also on contact form"),
|
||||
}
|
||||
|
||||
|
||||
@@ -15,20 +15,4 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
$(document).on('click', '.js_publish_contact, .js_unpublish_contact', function (e) {
|
||||
e.preventDefault();
|
||||
var $link = $(this).parent();
|
||||
$link.find('.js_publish_contact, .js_unpublish_contact').addClass("hidden");
|
||||
var $unp = $link.find(".js_unpublish_contact");
|
||||
var $p = $link.find(".js_publish_contact");
|
||||
$.post('/hr/publish_contact', {'id': $link.data('id')}, function (result) {
|
||||
if (+result) {
|
||||
$p.addClass("hidden");
|
||||
$unp.removeClass("hidden");
|
||||
} else {
|
||||
$p.removeClass("hidden");
|
||||
$unp.addClass("hidden");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -27,35 +27,28 @@
|
||||
<t t-set="title">Team</t>
|
||||
<div class="container">
|
||||
<div class="thumbnails">
|
||||
<t t-foreach="employee_ids" t-as="employee_id">
|
||||
<div class="span4 mt16">
|
||||
<div class="media thumbnail">
|
||||
<a class="pull-left" href="#">
|
||||
<img class="media-object" t-att-src="'data:image/png;base64,%%s' %% employee_id.image_small"/>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<t t-if="editable">
|
||||
<div class="pull-right">
|
||||
<a href="#" t-att-data-id="employee_id.id">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not employee_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (employee_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a><br/>
|
||||
<a href="#" t-att-data-id="employee_id.id">
|
||||
<span t-att-class="'label label-success js_unpublish_contact %%s' %% (not employee_id.website_published and 'hidden' or '')">hidden on Contacts</span>
|
||||
<span t-att-class="'label label-important js_publish_contact %%s' %% (employee_id.website_published and 'hidden' or '')">display in Contacts</span>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
<h5 class="media-heading"><t t-esc="employee_id.name"/></h5>
|
||||
<div t-record="employee_id" t-field="department_id"> </div>
|
||||
<div t-record="employee_id" t-field="job_id"> </div>
|
||||
<div t-record="employee_id" t-field="work_location"> </div>
|
||||
<div t-record="employee_id" t-field="work_phone"> </div>
|
||||
<div t-record="employee_id" t-field="work_email"> </div>
|
||||
<div t-foreach="employee_ids" t-as="employee_id" class="span4 mt16">
|
||||
<div class="media thumbnail">
|
||||
<a class="pull-left" href="#">
|
||||
<img class="media-object" t-att-src="'data:image/png;base64,%%s' %% employee_id.image_small"/>
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<div t-if="editable" class="pull-right">
|
||||
<a href="#" t-att-data-id="employee_id.id">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not employee_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (employee_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
</div>
|
||||
<h5 class="media-heading" t-field="employee_id.name"/>
|
||||
<div t-field="employee_id.department_id"/>
|
||||
<div t-field="employee_id.job_id"/>
|
||||
<div t-field="employee_id.work_location"/>
|
||||
<div t-field="employee_id.work_phone"/>
|
||||
<div t-field="employee_id.work_email"/>
|
||||
<div t-field="employee_id.public_info"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.web.http import request
|
||||
import werkzeug
|
||||
@@ -12,11 +13,12 @@ _months = {1:_("January"), 2:_("February"), 3:_("March"), 4:_("April"), 5:_("May
|
||||
|
||||
class website_mail(http.Controller):
|
||||
|
||||
@http.route(['/blog', '/blog/<int:mail_group_id>', '/blog/<int:mail_group_id>/<int:blog_id>'], type='http', auth="public")
|
||||
@http.route(['/blog', '/blog/<int:mail_group_id>/', '/blog/<int:mail_group_id>/<int:blog_id>/'], type='http', auth="public")
|
||||
def blog(self, mail_group_id=None, blog_id=None, **post):
|
||||
website = request.registry['website']
|
||||
group_obj = request.registry['mail.group']
|
||||
message_obj = request.registry['mail.message']
|
||||
user_obj = request.registry['res.users']
|
||||
|
||||
values = website.get_rendering_context({
|
||||
'blog_ids': None,
|
||||
@@ -25,7 +27,15 @@ class website_mail(http.Controller):
|
||||
'prev_date': None,
|
||||
'next_date': None,
|
||||
'mail_group_id': mail_group_id,
|
||||
'subscribe': post.get('subscribe'),
|
||||
'website': website,
|
||||
})
|
||||
|
||||
if request.uid != website.get_public_user().id and mail_group_id:
|
||||
message_follower_ids = group_obj.read(request.cr, request.uid, [mail_group_id], ['message_follower_ids'])[0]['message_follower_ids']
|
||||
parent_id = user_obj.browse(request.cr, SUPERUSER_ID, request.uid).partner_id.id
|
||||
values['subscribe'] = parent_id in message_follower_ids
|
||||
|
||||
domain = mail_group_id and [("res_id", "=", mail_group_id)] or []
|
||||
|
||||
for group in message_obj.read_group(request.cr, request.uid, domain + group_obj.get_public_blog(request.cr, request.uid), ['subject', 'date'], groupby="date", orderby="create_date asc"):
|
||||
@@ -70,10 +80,11 @@ class website_mail(http.Controller):
|
||||
|
||||
@http.route(['/blog/<int:mail_group_id>/<int:blog_id>/post'], type='http', auth="public")
|
||||
def blog_post(self, mail_group_id=None, blog_id=None, **post):
|
||||
website = request.registry['website']
|
||||
url = request.httprequest.host_url
|
||||
if post.get('body'):
|
||||
request.session.body = post.get('body')
|
||||
if not request.uid != request.public_uid:
|
||||
if request.uid == website.get_public_user().id:
|
||||
return '%s/admin#action=redirect&url=%s/blog/%s/%s/post' % (url, url, mail_group_id, blog_id)
|
||||
|
||||
if 'body' in request.session and request.session.body:
|
||||
@@ -88,9 +99,9 @@ class website_mail(http.Controller):
|
||||
request.session.body = False
|
||||
|
||||
if post.get('body'):
|
||||
return '%s/blog/%s/%s' % (url, mail_group_id, blog_id)
|
||||
return '%s/blog/%s/%s/' % (url, mail_group_id, blog_id)
|
||||
else:
|
||||
return werkzeug.utils.redirect("/blog/%s/%s" % (mail_group_id, blog_id))
|
||||
return werkzeug.utils.redirect("/blog/%s/%s/" % (mail_group_id, blog_id))
|
||||
|
||||
@http.route(['/blog/<int:mail_group_id>/new'], type='http', auth="public")
|
||||
def new_blog_post(self, mail_group_id=None, **post):
|
||||
@@ -102,4 +113,41 @@ class website_mail(http.Controller):
|
||||
subtype='mt_comment',
|
||||
context={'mail_create_nosubsrequest.cribe': True},
|
||||
)
|
||||
return werkzeug.utils.redirect("/blog/%s/%s" % (mail_group_id, blog_id))
|
||||
return werkzeug.utils.redirect("/blog/%s/%s/" % (mail_group_id, blog_id))
|
||||
|
||||
@http.route(['/blog/<int:mail_group_id>/subscribe', '/blog/<int:mail_group_id>/<int:blog_id>/subscribe'], type='http', auth="public")
|
||||
def subscribe(self, mail_group_id=None, blog_id=None, **post):
|
||||
website = request.registry['website']
|
||||
partner_obj = request.registry['res.partner']
|
||||
group_obj = request.registry['mail.group']
|
||||
user_obj = request.registry['res.users']
|
||||
|
||||
if mail_group_id and 'subscribe' in post and (post.get('email') or request.uid != website.get_public_user().id):
|
||||
if request.uid == website.get_public_user().id:
|
||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", post.get('email'))])
|
||||
if not partner_ids:
|
||||
partner_ids = [partner_obj.create(request.cr, SUPERUSER_ID, {"email": post.get('email'), "name": "Subscribe: %s" % post.get('email')})]
|
||||
else:
|
||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid).partner_id.id]
|
||||
group_obj.check_access_rule(request.cr, request.uid, [mail_group_id], 'read')
|
||||
group_obj.message_subscribe(request.cr, SUPERUSER_ID, [mail_group_id], partner_ids)
|
||||
|
||||
return self.blog(mail_group_id=mail_group_id, blog_id=blog_id, subscribe=post.get('email'))
|
||||
|
||||
@http.route(['/blog/<int:mail_group_id>/unsubscribe', '/blog/<int:mail_group_id>/<int:blog_id>/unsubscribe'], type='http', auth="public")
|
||||
def unsubscribe(self, mail_group_id=None, blog_id=None, **post):
|
||||
website = request.registry['website']
|
||||
partner_obj = request.registry['res.partner']
|
||||
group_obj = request.registry['mail.group']
|
||||
user_obj = request.registry['res.users']
|
||||
|
||||
if mail_group_id and 'unsubscribe' in post and (post.get('email') or request.uid != website.get_public_user().id):
|
||||
if request.uid == website.get_public_user().id:
|
||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", post.get('email'))])
|
||||
else:
|
||||
partner_ids = [user_obj.browse(request.cr, request.uid, request.uid).partner_id.id]
|
||||
group_obj.check_access_rule(request.cr, request.uid, [mail_group_id], 'read')
|
||||
group_obj.message_unsubscribe(request.cr, SUPERUSER_ID, [mail_group_id], partner_ids)
|
||||
|
||||
return self.blog(mail_group_id=mail_group_id, blog_id=blog_id, subscribe=None)
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//li[last()]" position="after">
|
||||
<li class="pull-right"><a href="/blog/%(website_mail.website_mail_blog)d">News</a></li>
|
||||
<li class="pull-right"><a href="/blog/%(website_mail.website_mail_blog)d/">News</a></li>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
@@ -29,7 +29,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//a[@href='/page/website.news']" position="replace">
|
||||
<a href="/blog/%(website_mail.website_mail_blog)d">News</a>
|
||||
<a href="/blog/%(website_mail.website_mail_blog)d/">News</a>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
@@ -50,20 +50,27 @@
|
||||
<div class="span4">
|
||||
<ul class="nav nav-list">
|
||||
<a t-if="mail_group_id and editable" t-att-href="'/blog/%%s/new' %% mail_group_id" class="btn">Add a new Blog</a>
|
||||
<li class="nav-header">BLOG ARCHIVE</li>
|
||||
<li class="nav-header"><a t-att-href="'/blog/%%s/' %% mail_group_id">BLOG ARCHIVE</a></li>
|
||||
<!-- TODO: check qweb iteration -->
|
||||
<t t-foreach="nav_list" t-as="year">
|
||||
<li t-foreach="nav_list" t-as="year" class="js_nav_year">
|
||||
<t t-set="year" t-value="nav_list[year]"/>
|
||||
<li class="js_nav_year"><a href="#"><t t-esc="year['name']"/> <small>(<t t-esc="year['date_count']"/>)</small></a>
|
||||
<ul class="nav nav-list css_nav_month">
|
||||
<t t-foreach="year['months']">
|
||||
<li class="js_nav_month"><a href="#" t-att-data-domain="__domain"><t t-esc="date"/> <small>(<t t-esc="date_count"/>)</small></a>
|
||||
<ul class="nav nav-list"/>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
</t>
|
||||
<a href="#"><t t-esc="year['name']"/> <small>(<t t-esc="year['date_count']"/>)</small></a>
|
||||
<ul class="nav nav-list css_nav_month">
|
||||
<t t-foreach="year['months']">
|
||||
<li class="js_nav_month"><a href="#" t-att-data-domain="__domain"><t t-esc="date"/> <small>(<t t-esc="date_count"/>)</small></a>
|
||||
<ul class="nav nav-list"/>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
<form action="./subscribe" method="POST" class="form-inline" t-if="not subscribe">
|
||||
<input placeholder="Email Address" type="email" name="email" class="input-medium" t-if="is_public_user"/>
|
||||
<button type="submit" class="btn btn-primary" name="subscribe">Subscribe</button>
|
||||
</form>
|
||||
<form action="./unsubscribe" method="POST" class="form-inline" t-if="subscribe">
|
||||
<input type="hidden" name="email" t-att-value="subscribe"/>
|
||||
<button type="submit" class="btn" name="unsubscribe">Unsubscribe</button>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="span8" t-if="blog_id">
|
||||
@@ -73,61 +80,56 @@
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not blog_id.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (blog_id.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<h3 t-field="blog_id.subject"></h3>
|
||||
<div t-field="blog_id.body"></div>
|
||||
<h3 t-field="blog_id.subject"/>
|
||||
<div t-field="blog_id.body"/>
|
||||
<small class="pull-right muted text-right">
|
||||
<div><t t-field="blog_id.author_id"/></div>
|
||||
<div><t t-field="blog_id.date"/></div>
|
||||
<div t-field="blog_id.author_id"/>
|
||||
<div t-field="blog_id.date"/>
|
||||
</small>
|
||||
</div>
|
||||
<ul class="media-list">
|
||||
<t t-foreach="blog_id.child_ids" t-as="comment">
|
||||
<!-- TODO: check qweb iteration -->
|
||||
<li class="media">
|
||||
<div class="media-body">
|
||||
<a href="#" t-att-data-id="blog_id.id" class="pull-right" t-if="editable">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not comment.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (comment.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<t t-raw="comment.body"/>
|
||||
<small class="pull-right muted text-right">
|
||||
<div><t t-esc="comment.author_id"/></div>
|
||||
<div><t t-esc="comment.date"/></div>
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
<ul class="media-list" id="comment">
|
||||
<li t-foreach="blog_id.child_ids" t-as="comment" class="media">
|
||||
<div class="media-body">
|
||||
<a href="#" t-att-data-id="blog_id.id" class="pull-right" t-if="editable">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not comment.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (comment.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<t t-raw="comment.body"/>
|
||||
<small class="pull-right muted text-right">
|
||||
<div t-field="comment.author_id"/>
|
||||
<div t-field="comment.date"/>
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
<form id="post" t-att-action="'/blog/%%s/%%s/post#post' %% (blog_id.res_id, blog_id.id)" method="POST" class="form-horizontal text-center" groups="group_website_mail_reply">
|
||||
<textarea rows="4" placeholder="Your message" class="span7"> </textarea>
|
||||
<button type="submit" class="btn">Post your message</button>
|
||||
<textarea rows="4" placeholder="Your comment" class="span7"> </textarea>
|
||||
<button type="submit" class="btn">Post your comment</button>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span8" t-if="not blog_id and blog_ids">
|
||||
<ul class="media-list">
|
||||
<t t-foreach="blog_ids" t-as="blog">
|
||||
<li class="media well">
|
||||
<div t-att-class="'media-body %%s' %% (blog.website_published and 'css_published' or '')">
|
||||
<a href="#" t-att-data-id="blog.id" class="pull-right" t-if="editable">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not blog.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (blog.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<h4 class="media-heading" ><a t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)" t-field="blog.subject"></a></h4>
|
||||
<div class="media">
|
||||
<div t-field="blog.body"></div>
|
||||
<small class="pull-left muted text-right" t-if="len(blog.child_ids)">
|
||||
<a t-if="len(blog.child_ids) <= 1" t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Message</a>
|
||||
<a t-if="len(blog.child_ids) > 1" t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Messages</a>
|
||||
</small>
|
||||
<small class="pull-right muted text-right">
|
||||
<div><t t-field="blog.author_id"/></div>
|
||||
<div><t t-field="blog.date"/></div>
|
||||
</small>
|
||||
</div>
|
||||
<li t-foreach="blog_ids" t-as="blog" class="media well">
|
||||
<div t-att-class="'media-body %%s' %% (blog.website_published and 'css_published' or '')">
|
||||
<a href="#" t-att-data-id="blog.id" class="pull-right" t-if="editable">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not blog.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (blog.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<h4 class="media-heading" ><a t-att-href="'/blog/%%s/%%s#comment' %% (blog.res_id, blog.id)" t-field="blog.subject"></a></h4>
|
||||
<div class="media">
|
||||
<div t-field="blog.body"/>
|
||||
<small class="pull-left muted text-right" t-if="len(blog.child_ids)">
|
||||
<a t-if="len(blog.child_ids) <= 1" t-att-href="'/blog/%%s/%%s#comment' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Comment</a>
|
||||
<a t-if="len(blog.child_ids) > 1" t-att-href="'/blog/%%s/%%s#comment' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Comments</a>
|
||||
</small>
|
||||
<small class="pull-right muted text-right">
|
||||
<div t-field="blog.author_id"/>
|
||||
<div t-field="blog.date"/>
|
||||
</small>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="pager">
|
||||
<li t-if="next_date" class="previous">
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import math
|
||||
import openerp
|
||||
import simplejson
|
||||
from openerp.osv import osv
|
||||
@@ -17,9 +18,7 @@ def get_order(order_id=None):
|
||||
if not order_id:
|
||||
fields = [k for k, v in order_obj._columns.items()]
|
||||
order_value = order_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields)
|
||||
order_value['partner_id'] = openerp.SUPERUSER_ID != request.public_uid and \
|
||||
request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id or \
|
||||
None
|
||||
order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id
|
||||
order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
|
||||
order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value)
|
||||
return order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id)
|
||||
@@ -49,9 +48,47 @@ class website(osv.osv):
|
||||
|
||||
class Ecommerce(http.Controller):
|
||||
|
||||
def get_categories(self):
|
||||
category_obj = request.registry.get('pos.category')
|
||||
category_ids = category_obj.search(request.cr, openerp.SUPERUSER_ID, [('parent_id', '=', False)])
|
||||
categories = category_obj.browse(request.cr, openerp.SUPERUSER_ID, category_ids)
|
||||
print categories
|
||||
return categories
|
||||
|
||||
def get_current_order(self):
|
||||
order = self.get_order(request.httprequest.session.get('ecommerce_order_id'))
|
||||
request.httprequest.session['ecommerce_order_id'] = order.id
|
||||
return order
|
||||
|
||||
def get_order(self, order_id=None):
|
||||
|
||||
order_obj = request.registry.get('sale.order')
|
||||
# check if order allready exists
|
||||
if order_id:
|
||||
try:
|
||||
order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id).pricelist_id
|
||||
except:
|
||||
order_id = None
|
||||
if not order_id:
|
||||
fields = [k for k, v in order_obj._columns.items()]
|
||||
order_value = order_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields)
|
||||
order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id
|
||||
order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
|
||||
order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value)
|
||||
return order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id)
|
||||
|
||||
def render(self, template, values={}):
|
||||
_values = {
|
||||
'order': self.get_current_order(),
|
||||
'categories': self.get_categories(),
|
||||
}
|
||||
_values.update(values)
|
||||
return website.render(template, _values)
|
||||
|
||||
def recommended_product(self, my_pids):
|
||||
if not my_pids:
|
||||
return []
|
||||
product_obj = request.registry.get('product.product')
|
||||
|
||||
my_pids = str(my_pids)[1:-1]
|
||||
product_ids = []
|
||||
@@ -69,26 +106,55 @@ class Ecommerce(http.Controller):
|
||||
request.cr.execute(query)
|
||||
for p in request.cr.fetchall():
|
||||
product_ids.append(p[0])
|
||||
return request.registry.get('product.product').browse(request.cr, request.uid, product_ids)
|
||||
|
||||
@http.route(['/shop', '/shop/category/<cat_id>'], type='http', auth="public")
|
||||
def category(self, cat_id=0, offset=0, **post):
|
||||
# search to apply access rules
|
||||
product_ids = product_obj.search(request.cr, request.uid, [("id", "in", product_ids)])
|
||||
return product_obj.browse(request.cr, request.uid, product_ids)
|
||||
|
||||
@http.route(['/shop', '/shop/category/<cat_id>', '/shop/category/<cat_id>/page/<page>', '/shop/page/<page>'], type='http', auth="public")
|
||||
def category(self, cat_id=0, page=0, **post):
|
||||
|
||||
website = request.registry['website']
|
||||
product_obj = request.registry.get('product.product')
|
||||
|
||||
domain = [("sale_ok", "=", True)]
|
||||
if post.get("search"):
|
||||
domain += ['|', '|', ('name', 'ilike', "%%%s%%" % post.get("search")), ('desrequest.cription', 'ilike', "%%%s%%" % post.get("search")), ('pos_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
|
||||
if openerp.SUPERUSER_ID != request.uid:
|
||||
domain += [('website_published', '=', True)]
|
||||
|
||||
if cat_id:
|
||||
cat_id = cat_id and int(cat_id) or 0
|
||||
cat_id = int(cat_id)
|
||||
domain = [('pos_categ_id.id', 'child_of', cat_id)] + domain
|
||||
|
||||
product_obj = request.registry.get('product.product')
|
||||
product_count = len(product_obj.search(request.cr, request.uid, domain))
|
||||
page_count = int(math.ceil(product_count / 20.0))
|
||||
|
||||
#if post.get("search"):
|
||||
# domain += ['|', '|', ('name', 'ilike', "%%%s%%" % post.get("search")), ('description', 'ilike', "%%%s%%" % post.get("search")), ('pos_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
|
||||
|
||||
page = max(1,min(int(page),page_count))
|
||||
offset = (page-1) * 20
|
||||
|
||||
if page_count <= 5 or page <= 3:
|
||||
pmin = 1
|
||||
pmax = min(page_count,5)
|
||||
elif page >= page_count - 2:
|
||||
pmin = page_count - 4
|
||||
pmax = page_count
|
||||
else:
|
||||
pmin = page - 2
|
||||
pmax = page + 2
|
||||
|
||||
pages = range(pmin, pmax+1)
|
||||
|
||||
product_ids = product_obj.search(request.cr, request.uid, domain, limit=20, offset=offset)
|
||||
|
||||
values = website.get_rendering_context({
|
||||
'current_category': cat_id,
|
||||
'products': product_obj.browse(request.cr, request.uid, product_ids),
|
||||
'search': post.get("search"),
|
||||
'page_count': page_count,
|
||||
'pages': pages,
|
||||
'page': page,
|
||||
})
|
||||
return website.render("website_sale.products", values)
|
||||
|
||||
@@ -134,7 +200,6 @@ class Ecommerce(http.Controller):
|
||||
values = website.get_rendering_context()
|
||||
context = {}
|
||||
|
||||
order_obj = request.registry.get('sale.order')
|
||||
order_line_obj = request.registry.get('sale.order.line')
|
||||
user_obj = request.registry.get('res.users')
|
||||
|
||||
@@ -196,8 +261,7 @@ class Ecommerce(http.Controller):
|
||||
country_state_obj = request.registry.get('res.country.state')
|
||||
payment_obj = request.registry.get('portal.payment.acquirer')
|
||||
|
||||
|
||||
if request.uid != request.public_uid:
|
||||
if request.uid != website.get_public_user().id:
|
||||
values['partner'] = user_obj.browse(request.cr, request.uid, request.uid).partner_id
|
||||
shipping_ids = partner_obj.search(request.cr, request.uid, [("parent_id", "=", values['partner'].id), ('type', "=", 'delivery')])
|
||||
values['shipping'] = None
|
||||
@@ -217,6 +281,7 @@ class Ecommerce(http.Controller):
|
||||
|
||||
@http.route(['/shop/confirm_order'], type='http', auth="public")
|
||||
def confirm_order(self, **post):
|
||||
website = request.registry['website']
|
||||
order = get_current_order()
|
||||
|
||||
json = {'error': [], 'validation': False}
|
||||
@@ -260,7 +325,7 @@ class Ecommerce(http.Controller):
|
||||
'country_id': post['country_id'],
|
||||
'state_id': post['state_id'],
|
||||
}
|
||||
if request.uid != request.public_uid:
|
||||
if request.uid != website.get_public_user().id:
|
||||
partner_id = user_obj.browse(request.cr, request.uid, request.uid).partner_id.id
|
||||
partner_obj.write(request.cr, request.uid, [partner_id], partner_value)
|
||||
else:
|
||||
|
||||
@@ -7,4 +7,5 @@ class product_pricelist(osv.osv):
|
||||
_inherit = "product.product"
|
||||
_columns = {
|
||||
'website_published': fields.boolean('Available in the website'),
|
||||
'description_website': fields.html('Description for the website'),
|
||||
}
|
||||
@@ -1,2 +1,2 @@
|
||||
sass:
|
||||
sass --compass --trace -t expanded ecommerce.sass ecommerce.css
|
||||
sass --compass --trace -t expanded --watch ecommerce.sass:ecommerce.css
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
.oe_ecommerce .oe_total {
|
||||
font-size: 13px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.oe_ecommerce .oe_total td {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
.oe_ecommerce .oe_total table {
|
||||
width: auto;
|
||||
}
|
||||
.oe_ecommerce .oe_total td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
.oe_ecommerce .oe_total th:last-child {
|
||||
text-align: center;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
width: 180px;
|
||||
height: 220px;
|
||||
margin-right: 15px;
|
||||
margin-left: 3px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .pull-left {
|
||||
margin: 0;
|
||||
float: none;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_description {
|
||||
display: none;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product h4 {
|
||||
text-align: center;
|
||||
text-shadow: 0px 1px 1px rgba(200, 200, 200, 0.2);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product img {
|
||||
max-height: 110px;
|
||||
max-width: 130px;
|
||||
margin: 0 auto;
|
||||
padding-bottom: 14px;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_price {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 44px;
|
||||
text-shadow: 0px 1px 3px rgba(255, 255, 255, 0.7);
|
||||
text-align: center;
|
||||
font-size: 25px;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_price span {
|
||||
font-weight: bold;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_button_cart {
|
||||
bottom: 5px;
|
||||
left: 0;
|
||||
}
|
||||
.oe_ecommerce .oe_products .oe_product .oe_button_cart .btn-inverse {
|
||||
display: none;
|
||||
}
|
||||
.oe_ecommerce .oe_mycart .oe_product {
|
||||
display: inline-block;
|
||||
width: 250px;
|
||||
margin-left: 0px;
|
||||
float: none;
|
||||
margin-right: 16px;
|
||||
padding: 8px 5px 6px 10px;
|
||||
}
|
||||
.oe_ecommerce .oe_mycart .oe_product > .pull-left {
|
||||
width: 84px;
|
||||
height: 64px;
|
||||
}
|
||||
.oe_ecommerce .oe_mycart .oe_product > .pull-left img {
|
||||
max-width: 64px;
|
||||
max-height: 64px;
|
||||
margin: auto;
|
||||
}
|
||||
.oe_ecommerce .oe_mycart .oe_product .oe_button_cart {
|
||||
position: static;
|
||||
right: 6px;
|
||||
top: 6px;
|
||||
}
|
||||
.oe_ecommerce .oe_mycart form input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.oe_ecommerce .oe_product {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
margin-top: 0;
|
||||
margin-bottom: 15px;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.oe_ecommerce .oe_button_cart {
|
||||
width: 100%;
|
||||
font-size: 11px;
|
||||
position: absolute;
|
||||
}
|
||||
.oe_ecommerce .oe_button_cart button {
|
||||
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.44);
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 5px;
|
||||
padding: 2px;
|
||||
height: 22px;
|
||||
position: relative;
|
||||
}
|
||||
.oe_ecommerce .oe_button_cart button.btn-inverse {
|
||||
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #aaaaaa), color-stop(100%, #999999));
|
||||
background: -webkit-linear-gradient(#aaaaaa, #999999);
|
||||
background: -moz-linear-gradient(#aaaaaa, #999999);
|
||||
background: -o-linear-gradient(#aaaaaa, #999999);
|
||||
background: linear-gradient(#aaaaaa, #999999);
|
||||
}
|
||||
.oe_ecommerce .oe_button_cart button.btn-primary {
|
||||
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #0088cc), color-stop(100%, #0076b1));
|
||||
background: -webkit-linear-gradient(#0088cc, #0076b1);
|
||||
background: -moz-linear-gradient(#0088cc, #0076b1);
|
||||
background: -o-linear-gradient(#0088cc, #0076b1);
|
||||
background: linear-gradient(#0088cc, #0076b1);
|
||||
}
|
||||
.oe_ecommerce .oe_button_cart button.btn-success {
|
||||
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #51a351), color-stop(100%, #418541));
|
||||
background: -webkit-linear-gradient(#51a351, #418541);
|
||||
background: -moz-linear-gradient(#51a351, #418541);
|
||||
background: -o-linear-gradient(#51a351, #418541);
|
||||
background: linear-gradient(#51a351, #418541);
|
||||
}
|
||||
.oe_ecommerce .oe_search form {
|
||||
width: 100%;
|
||||
margin: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
.oe_ecommerce .oe_product_detail .oe_button_cart {
|
||||
position: relative;
|
||||
text-align: right;
|
||||
}
|
||||
.oe_ecommerce .oe_recommended a {
|
||||
margin: 0 3px;
|
||||
}
|
||||
.oe_ecommerce .oe_recommended img {
|
||||
max-width: 64px;
|
||||
max-height: 64px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout h4 {
|
||||
border-bottom: 1px solid #dddddd;
|
||||
margin-right: 30px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout input:not([type="radio"]):not([type="checkbox"]):not([type="image"]) {
|
||||
height: 20px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout input[type="image"] {
|
||||
height: 30px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout label > input:not([type="radio"]):not([type="checkbox"]), .oe_ecommerce .oe_checkout label > div, .oe_ecommerce .oe_checkout label > select {
|
||||
display: block;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout label select {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout label > div > input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout .css_payments {
|
||||
clear: both;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout .css_payments .css_payment {
|
||||
position: relative;
|
||||
width: 80px;
|
||||
overflow: hidden;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
padding: 10px 10px 0 0;
|
||||
}
|
||||
.oe_ecommerce .oe_checkout .css_payments .css_error_payment {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: +O;
|
||||
left: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
@import "compass/css3"
|
||||
|
||||
.oe_ecommerce
|
||||
.oe_total
|
||||
font-size: 13px
|
||||
margin-top: 10px
|
||||
td
|
||||
padding: 5px 10px
|
||||
table
|
||||
width: auto
|
||||
td:last-child
|
||||
text-align: right
|
||||
th:last-child
|
||||
text-align: center
|
||||
.oe_products
|
||||
.oe_product
|
||||
.oe_hidden
|
||||
visibility: hidden
|
||||
.pull-left
|
||||
margin: 0
|
||||
float: none
|
||||
.oe_ecommerce_description
|
||||
display: none
|
||||
h4
|
||||
text-align: center
|
||||
+text-shadow(0px 1px 1px rgba(200, 200, 200,.2))
|
||||
margin-bottom: 16px
|
||||
img
|
||||
max-height: 110px
|
||||
max-width: 130px
|
||||
margin: 0 auto
|
||||
padding-bottom: 14px
|
||||
text-align: center
|
||||
display: inline-block
|
||||
padding: 4px
|
||||
width: 180px
|
||||
height: 220px
|
||||
margin-right: 15px
|
||||
margin-left: 3px
|
||||
padding-top: 8px
|
||||
&:nth-child(3n)
|
||||
margin-right: 0
|
||||
.oe_ecommerce_price
|
||||
width: 100%
|
||||
position: absolute
|
||||
bottom: 44px
|
||||
+text-shadow(0px 1px 3px rgba(255, 255, 255, 0.7))
|
||||
text-align: center
|
||||
font-size: 25px
|
||||
span
|
||||
font-weight: bold
|
||||
.oe_button_cart
|
||||
bottom: 5px
|
||||
left: 0
|
||||
.btn-inverse
|
||||
display: none
|
||||
.oe_mycart
|
||||
.oe_product
|
||||
display: inline-block
|
||||
width: 250px
|
||||
margin-left: 0px
|
||||
float: none
|
||||
margin-right: 16px
|
||||
padding: 8px 5px 6px 10px
|
||||
> .pull-left
|
||||
width: 84px
|
||||
height: 64px
|
||||
img
|
||||
max-width: 64px
|
||||
max-height: 64px
|
||||
margin: auto
|
||||
.oe_button_cart
|
||||
position: static
|
||||
right: 6px
|
||||
top: 6px
|
||||
form
|
||||
input
|
||||
margin-bottom: 0
|
||||
.oe_product
|
||||
vertical-align: top
|
||||
position: relative
|
||||
margin-top: 0
|
||||
margin-bottom: 15px
|
||||
+border-radius(5px)
|
||||
border: 1px solid rgba(0,0,0,.1)
|
||||
+box-shadow(0px 1px 3px rgba(0,0,0,.1))
|
||||
.oe_button_cart
|
||||
width: 100%
|
||||
font-size: 11px
|
||||
position: absolute
|
||||
button
|
||||
+text-shadow(0px 1px 1px rgba(0, 0, 0, 0.44))
|
||||
overflow: hidden
|
||||
text-align: center
|
||||
font-size: 12px
|
||||
margin: 0 auto
|
||||
margin-bottom: 5px
|
||||
padding: 2px
|
||||
height: 22px
|
||||
position: relative
|
||||
&.btn-inverse
|
||||
@include background(linear-gradient(#aaaaaa,#999999))
|
||||
&.btn-primary
|
||||
@include background(linear-gradient(#0088cc,#0076b1))
|
||||
&.btn-success
|
||||
@include background(linear-gradient(#51a351, #418541))
|
||||
.oe_search
|
||||
form
|
||||
width: 100%
|
||||
margin: 24px
|
||||
text-align: center
|
||||
.oe_product_detail
|
||||
.oe_button_cart
|
||||
position: relative
|
||||
text-align: right
|
||||
.oe_recommended
|
||||
a
|
||||
margin: 0 3px
|
||||
img
|
||||
max-width: 64px
|
||||
max-height: 64px
|
||||
.oe_checkout
|
||||
.css_required
|
||||
input, select
|
||||
//background-color: #d2d2ff !important
|
||||
h4
|
||||
border-bottom: 1px solid #ddd
|
||||
margin-right: 30px
|
||||
input:not([type="radio"]):not([type="checkbox"]):not([type="image"])
|
||||
height: 20px
|
||||
input[type="image"]
|
||||
height: 30px
|
||||
label
|
||||
> input:not([type="radio"]):not([type="checkbox"]), > div, > select
|
||||
display: block
|
||||
margin-top: 3px
|
||||
select
|
||||
margin-top: 3px
|
||||
> div > input
|
||||
margin-bottom: 0
|
||||
.css_payments
|
||||
clear: both
|
||||
.css_payment
|
||||
position: relative
|
||||
width: 80px
|
||||
overflow: hidden
|
||||
height: 30px
|
||||
text-align: center
|
||||
padding: 10px 10px 0 0
|
||||
.css_error_payment
|
||||
width: 100%
|
||||
height: 100%
|
||||
position: absolute
|
||||
top: +O
|
||||
left: +0
|
||||
cursor: pointer
|
||||
@@ -30,7 +30,7 @@ $(document).ready(function () {
|
||||
.html(quantity);
|
||||
$add.toggleClass('btn-primary', !quantity)
|
||||
.toggleClass('btn-success', !!quantity);
|
||||
$remove.toggleClass('oe_hidden', !quantity);
|
||||
$remove.toggleClass('hidden', !quantity);
|
||||
if ($('.oe_mycart').size() && !quantity) {
|
||||
$product.remove()
|
||||
}
|
||||
@@ -65,4 +65,4 @@ $(document).ready(function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -54,17 +54,8 @@
|
||||
<t t-set="title">Shop - <t t-raw="title">Categories</t></t>
|
||||
<div class="container mt48 oe_ecommerce">
|
||||
<div class="row">
|
||||
<div class="span4 css_noprint">
|
||||
<ul class="nav nav-list">
|
||||
<t t-foreach="website_sale_get_categories()" t-as="category">
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<t t-raw="shop_content">
|
||||
</t>
|
||||
</div>
|
||||
<t t-call='website_sale.categories' />
|
||||
<t t-raw="shop_content" />
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -72,9 +63,20 @@
|
||||
|
||||
<!-- List of categories -->
|
||||
|
||||
<template id="categories">
|
||||
<div class="span4">
|
||||
<ul class="nav nav-list">
|
||||
<li t-att-class=" '' if current_category else 'active' " class='active'><a href='/shop/'>All Products</a></li>
|
||||
<t t-foreach="website_sale_get_categories()" t-as="category">
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="categories_recursive">
|
||||
<li t-att-class="category.id == current_category and 'active' or ''">
|
||||
<a t-att-href="'/shop/category/%%s' %% category.id"><span t-field="category.name"><t t-esc="category.name"/></span></a>
|
||||
<a t-att-href="'/shop/category/%%s' %% category.id" t-field="category.name"></a>
|
||||
<ul t-if="category.child_id" class="nav nav-list">
|
||||
<t t-foreach="category.child_id" t-as="category">
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
@@ -85,52 +87,84 @@
|
||||
|
||||
<!-- Product list -->
|
||||
|
||||
<template id="product_pager">
|
||||
<t t-set="classname" t-value="classname or ''" />
|
||||
<div t-if="page_count != 1" t-att-class="classname + ' pagination'">
|
||||
<ul>
|
||||
<li t-att-class=" 'disabled' if page == 1 else '' " ><a t-att-href=" '#' if page == 1 else ('/shop/category/%%s/page/%%s' %% (current_category, max(0,page-1))) ">Prev</a></li>
|
||||
<t t-foreach="pages" t-as="p">
|
||||
<li t-att-class=" 'active' if p == page else '' " ><a t-att-href=" '/shop/category/%%s/page/%%s' %% (current_category, p)" t-raw='p'></a></li>
|
||||
</t>
|
||||
<li t-att-class=" 'disabled' if page == page_count else '' "><a t-att-href=" '#' if page == page_count else ('/shop/category/%%s/page/%%s' %% (current_category, min(page_count,page+1))) ">Next</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="products">
|
||||
<t t-call="website_sale.page">
|
||||
<t t-set="title">Product</t>
|
||||
<t t-set="shop_content">
|
||||
<div class="oe_search clearfix">
|
||||
<form action="/shop" method="get" class="navbar-search pull-right">
|
||||
<input type="text" name="search" class="search-query span4" placeholder="Search" t-att-value="search or '' or ''"/>
|
||||
<button type="submit" class="btn">Submit</button>
|
||||
</form>
|
||||
<div class='span8 navbar navbar-inverse'>
|
||||
<div class='navbar-inner'>
|
||||
<t t-call="website_sale.product_pager" >
|
||||
<t t-set="classname">pull-left</t>
|
||||
</t>
|
||||
<form action="/shop" method="get" class="navbar-search pull-right">
|
||||
<input type="text" name="search" class="search-query span2" placeholder="Search" t-att-value="search or '' or ''"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span8">
|
||||
<div class='row grid grid-align-top'>
|
||||
<t t-foreach="products" t-as="product">
|
||||
<t t-set="quantity" t-value="([int(line.product_uom_qty) for line in (order.order_line or []) if line.product_id.id == product.id] + [0])[0]"/>
|
||||
<t t-call="website_sale.product_card"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span8 offset4 text-center">
|
||||
<t t-call="website_sale.product_pager" />
|
||||
</div>
|
||||
<span class="oe_products">
|
||||
<t t-foreach="products" t-as="product">
|
||||
<t t-set="quantity" t-value="([int(line.product_uom_qty) for line in (order.order_line or []) if line.product_id.id == product.id] + [0])[0]"/>
|
||||
<t t-call="website_sale.product_card"/>
|
||||
</t>
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="product_card">
|
||||
<div class="media oe_product span3">
|
||||
<a t-att-href="'/shop/product/%%s' %% product.id"><h4 class="media-heading"><span t-field="product.name"><t t-esc="product.name"/></span></h4></a>
|
||||
<a class="pull-left" t-att-href="'/shop/product/%%s' %% product.id"><img class="media-object" t-att-src="'data:image/png;base64,' + product.image"/></a>
|
||||
<div class="media-body">
|
||||
<div class="oe_ecommerce_description" t-field="product.description_sale"><t t-esc="product.description_sale"/></div>
|
||||
<div class="oe_ecommerce_price"><span><span t-field="product.list_price"><t t-esc="product.list_price"/></span>€</span></div>
|
||||
<div class="oe_button_cart">
|
||||
<div class="alert mb0" t-if="editable and not product.website_published">Product not published</div>
|
||||
<t t-if="product.website_published">
|
||||
<button t-att-class="'btn btn-small btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
|
||||
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">Add to cart
|
||||
<span class="oe_txt">(<span class="oe_quantity"><t t-esc="quantity"/></span>)</span>
|
||||
</button>
|
||||
</t>
|
||||
<div class="oe_product span2 mb16 thumbnail text-center">
|
||||
<a t-att-href="'/shop/product/%%s' %% product.id">
|
||||
<h5 t-field="product.name"> </h5>
|
||||
</a>
|
||||
<a t-att-href="'/shop/product/%%s' %% product.id">
|
||||
<img class="img-rounded" t-att-src="'data:image/png;base64,' + product.image"/>
|
||||
</a>
|
||||
<div>
|
||||
<div t-field="product.description_sale"></div>
|
||||
<div><span t-field="product.list_price"></span>€</div>
|
||||
<div class="mb8 mt8">
|
||||
<button t-att-class="'btn mb8 btn-small btn-inverse %%s' %% (not quantity and 'hidden' or '')" t-att-data-id="product.id">Remove one</button>
|
||||
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">
|
||||
Add to cart <t t-if="quantity">(<t t-esc="quantity"/>)</t>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="product_recommended">
|
||||
<div class="oe_recommended media well well-small" t-if="recommended_products">
|
||||
<h6>Other customers have also take this products:</h6>
|
||||
<div class="well mt32" t-if="recommended_products">
|
||||
<h4>Customers who have bought this item also bought</h4>
|
||||
<div class='row mt16'>
|
||||
<t t-foreach="recommended_products or []" t-as="product">
|
||||
<a t-att-href="'/shop/product/%%s' %% product.id"><img t-att-src="'data:image/png;base64,' + product.image"/></a>
|
||||
<div class='span2 thumbnail'>
|
||||
<a t-att-href="'/shop/product/%%s' %% product.id">
|
||||
<div class='mt16 text-center'>
|
||||
<img t-att-src="'data:image/png;base64,' + product.image"/>
|
||||
<h5 t-field='product.name'></h5>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -140,21 +174,22 @@
|
||||
<t t-call="website_sale.page">
|
||||
<t t-set="title">Product</t>
|
||||
<t t-set="shop_content">
|
||||
<div class="oe_product_detail">
|
||||
<div class="oe_product_detail span8">
|
||||
<a href="#" t-att-data-id="product.id" class="pull-right" t-if="editable">
|
||||
<span t-att-class="'label label-success js_unpublish %%s' %% (not product.website_published and 'hidden' or '')">Click to Unpublish</span>
|
||||
<span t-att-class="'label label-important js_publish %%s' %% (product.website_published and 'hidden' or '')">Click to Publish</span>
|
||||
</a>
|
||||
<h1 t-field="product.name"></h1>
|
||||
<h2 t-field="product.name"></h2>
|
||||
|
||||
<div class="oe_button_cart">
|
||||
<button t-att-class="'btn btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
|
||||
<button t-att-class="'btn %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">Add to cart
|
||||
<span class="oe_txt">(<span class="oe_quantity"><t t-esc="quantity"/></span>)</span>
|
||||
<button t-att-class="'btn btn-small btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
|
||||
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">
|
||||
Add to cart <t t-if="quantity" >(<t t-esc="quantity"/>)</t>
|
||||
</button>
|
||||
</div>
|
||||
<img class="media-object" t-att-src="'data:image/png;base64,' + product.image"/>
|
||||
<div t-field="product.description_sale"></div>
|
||||
<div class="oe_ecommerce_price" t-field="product.list_price"><t t-esc="product.list_price"/> €</div>
|
||||
<div t-field="product.description_website"></div>
|
||||
<div class="oe_ecommerce_price"><t t-field="product.list_price" />€</div>
|
||||
<t t-call="website_sale.product_recommended"/>
|
||||
</div>
|
||||
</t>
|
||||
@@ -167,22 +202,24 @@
|
||||
<t t-call="website_sale.page">
|
||||
<t t-set="title">My cart</t>
|
||||
<t t-set="shop_content">
|
||||
<span class="oe_mycart">
|
||||
<t t-foreach="order.order_line or []" t-as="line">
|
||||
<t t-set="product" t-value="line.product_id"/>
|
||||
<t t-set="quantity" t-value="int(line.product_uom_qty)"/>
|
||||
<t t-call="website_sale.product_card"/>
|
||||
</t>
|
||||
<t t-call="website_sale.product_recommended"/>
|
||||
<t t-call="website_sale.total"/>
|
||||
<div class="media well well-small" t-if="order.order_line">
|
||||
<form action="/shop/mycart" class="navbar-form">
|
||||
<input name="code" type="text" placeholder="Reduction Code..."/>
|
||||
<button class="btn">Submit your Reduction Code</button>
|
||||
</form>
|
||||
<div class="span8 oe_mycart">
|
||||
<h2>My Shopping Cart</h2>
|
||||
<h3 t-if="not order.order_line">Your cart is empty</h3>
|
||||
<div class='row mt32 grid grid-align-top'>
|
||||
<t t-foreach="order.order_line or []" t-as="line">
|
||||
<t t-set="product" t-value="line.product_id"/>
|
||||
<t t-set="quantity" t-value="int(line.product_uom_qty)"/>
|
||||
<t t-call="website_sale.product_card"/>
|
||||
</t>
|
||||
</div>
|
||||
<a t-if="order.order_line" href="/shop/checkout"><button class="btn btn-success">Next stage</button></a>
|
||||
</span>
|
||||
<t t-call="website_sale.total"/>
|
||||
<form t-if="order.order_line" class="well form-search" action="/shop/mycart" >
|
||||
<input name="code" class='input' type="text" placeholder="Reduction Code..."/>
|
||||
<button class="btn">Apply Code</button>
|
||||
</form>
|
||||
<a t-if="order.order_line" href="/shop/checkout"><button class="btn btn-success">Proceed To Payment</button></a>
|
||||
<t t-call="website_sale.product_recommended"/>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
@@ -190,14 +227,15 @@
|
||||
<!-- Total Shop my cart -->
|
||||
|
||||
<template id="total">
|
||||
<div class="oe_total">
|
||||
<div class="media well well-small">
|
||||
<table t-if="order.order_line">
|
||||
<tr><td>Untaxed Amount</td><td><t t-esc="order.amount_untaxed"/> €</td></tr>
|
||||
<tr><td>Taxes</td><td><t t-esc="order.amount_tax"/> €</td></tr>
|
||||
<tr><td>Total</td><td><h3><t t-esc="order.amount_total"/> €</h3></td></tr>
|
||||
</table>
|
||||
<span t-if="not order.order_line">Your cart is empty</span>
|
||||
<div class="row oe_total">
|
||||
<div class="span4">
|
||||
<div class="well">
|
||||
<table class='table-equalized' t-if="order.order_line">
|
||||
<tr> <td>Subtotal </td> <td><t t-esc="order.amount_untaxed"/> €</td></tr>
|
||||
<tr> <td>Taxes </td> <td><t t-esc="order.amount_tax"/> €</td></tr>
|
||||
<tr> <td><h4>Total</h4></td> <td><h4><t t-esc="order.amounttotal"/> €</h4></td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user