diff --git a/addons/account/__init__.py b/addons/account/__init__.py index c5a3a154740..5ff55f6f3dc 100644 --- a/addons/account/__init__.py +++ b/addons/account/__init__.py @@ -19,10 +19,10 @@ # ############################################################################## +import partner import account import installer import project -import partner import account_invoice import account_bank_statement import account_bank diff --git a/addons/account/account_bank_view.xml b/addons/account/account_bank_view.xml index 4b3436c8a51..8ceb8a91885 100644 --- a/addons/account/account_bank_view.xml +++ b/addons/account/account_bank_view.xml @@ -9,7 +9,6 @@ Partner Bank Accounts - Journal res.partner.bank - form @@ -26,7 +25,6 @@ Partner Bank Accounts - Add currency on tree res.partner.bank - tree diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index d2661674bae..c92d4eda602 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -3,7 +3,6 @@ account.installer.form account.installer - form
diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 064ba419ebd..012bde42eff 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -1351,11 +1351,11 @@ class account_invoice_line(osv.osv): 'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'), 'product_id': fields.many2one('product.product', 'Product', ondelete='set null'), 'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."), - 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Account')), + 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), 'price_subtotal': fields.function(_amount_line, string='Subtotal', type="float", digits_compute= dp.get_precision('Account'), store=True), - 'quantity': fields.float('Quantity', required=True), - 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Account')), + 'quantity': fields.float('Quantity', digits_compute= dp.get_precision('Product Unit of Measure'), required=True), + 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), 'invoice_line_tax_id': fields.many2many('account.tax', 'account_invoice_line_tax', 'invoice_line_id', 'tax_id', 'Taxes', domain=[('parent_id','=',False)]), 'account_analytic_id': fields.many2one('account.analytic.account', 'Analytic Account'), 'company_id': fields.related('invoice_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True), diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index d04030c909e..143c5514141 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -6,7 +6,6 @@ account.invoice.calendar account.invoice - calendar @@ -18,7 +17,6 @@ account.invoice.graph account.invoice - graph @@ -30,7 +28,6 @@ account.invoice.line.tree account.invoice.line - tree @@ -47,7 +44,6 @@ account.invoice.line.form account.invoice.line - form @@ -78,7 +74,6 @@ account.invoice.tax.tree account.invoice.tax - tree @@ -94,7 +89,6 @@ account.invoice.tax.form account.invoice.tax - form @@ -120,7 +114,6 @@ account.invoice.tree account.invoice - tree @@ -146,10 +139,9 @@ account.invoice.supplier.form account.invoice - form 2 - +
+ +or + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.ttf b/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.ttf new file mode 100755 index 00000000000..94809d3a57f Binary files /dev/null and b/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.ttf differ diff --git a/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.woff b/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.woff new file mode 100755 index 00000000000..1d6c4abc9d9 Binary files /dev/null and b/addons/auth_oauth/static/lib/zocial/css/zocial-regular-webfont.woff differ diff --git a/addons/auth_oauth/static/lib/zocial/css/zocial.css b/addons/auth_oauth/static/lib/zocial/css/zocial.css new file mode 100644 index 00000000000..89fc7450631 --- /dev/null +++ b/addons/auth_oauth/static/lib/zocial/css/zocial.css @@ -0,0 +1,420 @@ +@charset "UTF-8"; + +/*! +Code written by Sam Collins (@smcllns) of www.eventasaur.us +You are free to use this work commercially +You are free to extend this work without permissions from the author (just do so tastefully eh?) +Enjoy +*/ + +/* Reference icons from font-files */ + +@font-face { + font-family: 'zocial'; + font-style: normal; + font-weight: normal; + src: url('zocial-regular-webfont.eot'); + src: url('zocial-regular-webfont.eot?#iefix') format('embedded-opentype'), + url('zocial-regular-webfont.woff') format('woff'), + url('zocial-regular-webfont.ttf') format('truetype'), + url('zocial-regular-webfont.svg#ZocialRegular') format('svg'); + unicode-range: U+0-U+10FFFF; +} + +/* Button structure */ + +.zocial, +a.zocial { + border: 1px solid #777; + border-color: rgba(0,0,0,0.2); + border-bottom-color: #333; + border-bottom-color: rgba(0,0,0,0.4); + color: #fff; + -moz-box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.4), inset 0 0 0.1em rgba(255,255,255,0.9); + -webkit-box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.4), inset 0 0 0.1em rgba(255,255,255,0.9); + box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.4), inset 0 0 0.1em rgba(255,255,255,0.9); + cursor: pointer; + display: inline-block; + font: bold 100%/2.1 "Lucida Grande", Tahoma, sans-serif; + padding: 0 .95em 0 0; + text-align: center; + text-decoration: none; + text-shadow: 0 1px 0 rgba(0,0,0,0.5); + white-space: nowrap; + + -moz-user-select: none; + -webkit-user-select: none; + user-select: none; + + position: relative; + + -moz-border-radius: .3em; + -webkit-border-radius: .3em; + border-radius: .3em; +} + +.zocial:before { + content: ""; + border-right: 0.075em solid rgba(0,0,0,0.1); + float: left; + font: 120%/1.65 zocial; + font-style: normal; + font-weight: normal; + margin: 0 0.5em 0 0; + padding: 0 0.5em; + text-align: center; + text-decoration: none; + text-transform: none; + + -moz-box-shadow: 0.075em 0 0 rgba(255,255,255,0.25); + -webkit-box-shadow: 0.075em 0 0 rgba(255,255,255,0.25); + box-shadow: 0.075em 0 0 rgba(255,255,255,0.25); + + -webkit-font-smoothing: antialiased; +} + +.zocial:active { + outline: none; /* outline is visible on :focus */ +} + +/* Buttons can be displayed as standalone icons by adding a class of "icon" */ + +.zocial.icon { + overflow: hidden; + max-width: 2.4em; + padding-left: 0; + padding-right: 0; + max-height: 2.15em; + white-space: nowrap; +} +.zocial.icon:before { + padding: 0; + width: 2em; + height: 2em; + + box-shadow: none; + border: none; +} + +/* Gradients */ + +.zocial { + background-image: -moz-linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); + background-image: -ms-linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); + background-image: -o-linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.1)), color-stop(49%, rgba(255,255,255,.05)), color-stop(51%, rgba(0,0,0,.05)), to(rgba(0,0,0,.1))); + background-image: -webkit-linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); + background-image: linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.05) 49%, rgba(0,0,0,.05) 51%, rgba(0,0,0,.1)); +} + +.zocial:hover, .zocial:focus { + background-image: -moz-linear-gradient(rgba(255,255,255,.15) 49%, rgba(0,0,0,.1) 51%, rgba(0,0,0,.15)); + background-image: -ms-linear-gradient(rgba(255,255,255,.15) 49%, rgba(0,0,0,.1) 51%, rgba(0,0,0,.15)); + background-image: -o-linear-gradient(rgba(255,255,255,.15) 49%, rgba(0,0,0,.1) 51%, rgba(0,0,0,.15)); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.15)), color-stop(49%, rgba(255,255,255,.15)), color-stop(51%, rgba(0,0,0,.1)), to(rgba(0,0,0,.15))); + background-image: -webkit-linear-gradient(rgba(255,255,255,.15) 49%, rgba(0,0,0,.1) 51%, rgba(0,0,0,.15)); + background-image: linear-gradient(rgba(255,255,255,.15) 49%, rgba(0,0,0,.1) 51%, rgba(0,0,0,.15)); +} + +.zocial:active { + background-image: -moz-linear-gradient(bottom, rgba(255,255,255,.1), rgba(255,255,255,0) 30%, transparent 50%, rgba(0,0,0,.1)); + background-image: -ms-linear-gradient(bottom, rgba(255,255,255,.1), rgba(255,255,255,0) 30%, transparent 50%, rgba(0,0,0,.1)); + background-image: -o-linear-gradient(bottom, rgba(255,255,255,.1), rgba(255,255,255,0) 30%, transparent 50%, rgba(0,0,0,.1)); + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,.1)), color-stop(30%, rgba(255,255,255,0)), color-stop(50%, transparent), to(rgba(0,0,0,.1))); + background-image: -webkit-linear-gradient(bottom, rgba(255,255,255,.1), rgba(255,255,255,0) 30%, transparent 50%, rgba(0,0,0,.1)); + background-image: linear-gradient(bottom, rgba(255,255,255,.1), rgba(255,255,255,0) 30%, transparent 50%, rgba(0,0,0,.1)); +} + +/* Adjustments for light background buttons */ + +.zocial.bitcoin, +.zocial.cloudapp, +.zocial.dropbox, +.zocial.email, +.zocial.eventful, +.zocial.github, +.zocial.gmail, +.zocial.instapaper, +.zocial.itunes, +.zocial.ninetyninedesigns, +.zocial.openid, +.zocial.plancast, +.zocial.posterous, +.zocial.reddit, +.zocial.secondary, +.zocial.viadeo, +.zocial.weibo, +.zocial.wikipedia { + border: 1px solid #aaa; + border-color: rgba(0,0,0,0.3); + border-bottom-color: #777; + border-bottom-color: rgba(0,0,0,0.5); + -moz-box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.7), inset 0 0 0.08em rgba(255,255,255,0.5); + -webkit-box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.7), inset 0 0 0.08em rgba(255,255,255,0.5); + box-shadow: inset 0 0.08em 0 rgba(255,255,255,0.7), inset 0 0 0.08em rgba(255,255,255,0.5); + text-shadow: 0 1px 0 rgba(255,255,255,0.8); +} + +/* :hover adjustments for light background buttons */ + +.zocial.bitcoin:focus, +.zocial.bitcoin:hover, +.zocial.dropbox:focus, +.zocial.dropbox:hover, +.zocial.email:focus, +.zocial.email:hover, +.zocial.eventful:focus, +.zocial.eventful:hover, +.zocial.github:focus, +.zocial.github:hover, +.zocial.gmail:focus, +.zocial.gmail:hover, +.zocial.instapaper:focus, +.zocial.instapaper:hover, +.zocial.itunes:focus, +.zocial.itunes:hover, +.zocial.ninetyninedesigns:focus, +.zocial.ninetyninedesigns:hover, +.zocial.openid:focus, +.zocial.openid:hover, +.zocial.plancast:focus, +.zocial.plancast:hover, +.zocial.posterous:focus, +.zocial.posterous:hover, +.zocial.reddit:focus, +.zocial.reddit:hover, +.zocial.secondary:focus, +.zocial.secondary:hover, +.zocial.twitter:focus, +.zocial.viadeo:focus, +.zocial.viadeo:hover, +.zocial.weibo:focus, +.zocial.weibo:hover, +.zocial.wikipedia:focus, +.zocial.wikipedia:hover { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0.5)), color-stop(49%, rgba(255,255,255,0.2)), color-stop(51%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.15))); + background-image: -moz-linear-gradient(top, rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); + background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); + background-image: -o-linear-gradient(top, rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); + background-image: -ms-linear-gradient(top, rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); + background-image: linear-gradient(top, rgba(255,255,255,0.5), rgba(255,255,255,0.2) 49%, rgba(0,0,0,0.05) 51%, rgba(0,0,0,0.15)); +} + +/* :active adjustments for light background buttons */ + +.zocial.bitcoin:active, +.zocial.dropbox:active, +.zocial.email:active, +.zocial.eventful:active, +.zocial.github:active, +.zocial.gmail:active, +.zocial.instapaper:active, +.zocial.itunes:active, +.zocial.ninetyninedesigns:active, +.zocial.openid:active, +.zocial.plancast:active, +.zocial.posterous:active, +.zocial.reddit:active, +.zocial.secondary:active, +.zocial.viadeo:active, +.zocial.weibo:active, +.zocial.wikipedia:active { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(255,255,255,0)), color-stop(30%, rgba(255,255,255,0)), color-stop(50%, rgba(0,0,0,0)), to(rgba(0,0,0,0.1))); + background-image: -moz-linear-gradient(bottom, rgba(255,255,255,0), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.1)); + background-image: -webkit-linear-gradient(bottom, rgba(255,255,255,0), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.1)); + background-image: -o-linear-gradient(bottom, rgba(255,255,255,0), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.1)); + background-image: -ms-linear-gradient(bottom, rgba(255,255,255,0), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.1)); + background-image: linear-gradient(bottom, rgba(255,255,255,0), rgba(255,255,255,0) 30%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.1)); +} + +/* Button icon and color */ +/* Icon characters are stored in unicode private area */ +.zocial.amazon:before {content: "\E040";} +.zocial.android:before {content: "\E005";} +.zocial.angellist:before {content: "\E06C";} +.zocial.aol:before {content: "\E001";} +.zocial.appstore:before {content: "\E020";} +.zocial.bitcoin:before {content: "\E011"; color: #f7931a;} +.zocial.blogger:before {content: "\E021";} +.zocial.call:before {content: "\E016";} +.zocial.cal:before {content: "\E00D";} +.zocial.cart:before {content: "\E06A";} +.zocial.chrome:before {content: "\E03A";} +.zocial.cloudapp:before {content: "\E042";} +.zocial.creativecommons:before {content: "\E022";} +.zocial.delicious:before {content: "\E002";} +.zocial.digg:before {content: "\E01A";} +.zocial.disqus:before {content: "\E030";} +.zocial.dribbble:before {content: "\E023";} +.zocial.dropbox:before {content: "\E043"; color: #1f75cc;} +.zocial.email:before {content: "\E03C"; color: #312c2a;} +.zocial.eventasaurus:before {content: "\E055"; color: #9de428;} +.zocial.eventbrite:before {content: "\E05B";} +.zocial.eventful:before {content: "\E006"; color: #0066CC;} +.zocial.evernote:before {content: "\E024";} +.zocial.facebook:before {content: "\E045";} +.zocial.fivehundredpx:before {content: "\E00F"; color: #29b6ff;} +.zocial.flattr:before {content: "\E004";} +.zocial.flickr:before {content: "\E025";} +.zocial.forrst:before {content: "\E019"; color: #50894f;} +.zocial.foursquare:before {content: "\E013";} +.zocial.github:before {content: "\E046";} +.zocial.gmail:before {content: "\E04C"; color: #f00;} +.zocial.google:before {content: "\E026";} +.zocial.googleplay:before {content: "\E05E";} +.zocial.googleplus:before {content: "\E00A";} +.zocial.gowalla:before {content: "\E01F";} +.zocial.grooveshark:before {content: "\E017";} +.zocial.guest:before {content: "\E01E";} +.zocial.html5:before {content: "\E014";} +.zocial.ie:before {content: "\E015";} +.zocial.instagram:before {content: "\E06D";} +.zocial.instapaper:before {content: "\E028";} +.zocial.intensedebate:before {content: "\E05A";} +.zocial.itunes:before {content: "\E048"; color: #1a6dd2;} +.zocial.klout:before {content: "\E02A"; } +.zocial.lanyrd:before {content: "\E00C";} +.zocial.lastfm:before {content: "\E04B";} +.zocial.linkedin:before {content: "\E02B";} +.zocial.macstore:before {content: "\E03D";} +.zocial.meetup:before {content: "\E02C";} +.zocial.myspace:before {content: "\E03E";} +.zocial.ninetyninedesigns:before {content: "\E018"; color: #f50;} +.zocial.openid:before {content: "\E04E"; color: #ff921d;} +.zocial.opentable:before {content: "\E05F";} +.zocial.paypal:before {content: "\E003";} +.zocial.pinboard:before {content: "\E04D";} +.zocial.pinterest:before {content: "\E010";} +.zocial.plancast:before {content: "\E02F";} +.zocial.plurk:before {content: "\E049";} +.zocial.podcast:before {content: "\E03F";} +.zocial.posterous:before {content: "\E05D";} +.zocial.print:before {content: "\E06B";} +.zocial.quora:before {content: "\E050";} +.zocial.reddit:before {content: "\E01D"; color: red;} +.zocial.rss:before {content: "\E031";} +.zocial.scribd:before {content: "\E05C"; color: #00d5ea;} +.zocial.skype:before {content: "\E032";} +.zocial.smashing:before {content: "\E009";} +.zocial.songkick:before {content: "\E04A";} +.zocial.soundcloud:before {content: "\E052";} +.zocial.spotify:before {content: "\E01C";} +.zocial.stumbleupon:before {content: "\E00E";} +.zocial.tumblr:before {content: "\E053";} +.zocial.twitter:before {content: "\E033";} +.zocial.viadeo:before {content: "\E027"; color: #f59b20;} +.zocial.vimeo:before {content: "\E035";} +.zocial.weibo:before {content: "\E029"; color: #e6162d;} +.zocial.wikipedia:before {content: "\E00B";} +.zocial.windows:before {content: "\E036";} +.zocial.xing:before {content: "\E037"} +.zocial.wordpress:before {content: "\E056";} +.zocial.yahoo:before {content: "\E038";} +.zocial.yelp:before {content: "\E058";} +.zocial.youtube:before {content: "\E034";} + +/* Button background and text color */ + +.zocial.amazon {background-color: #ffad1d; color: #030037; text-shadow: 0 1px 0 rgba(255,255,255,0.5);} +.zocial.android {background-color: #a4c639;} +.zocial.angellist {background-color: #000;} +.zocial.aol {background-color: #f00;} +.zocial.appstore {background-color: #000;} +.zocial.bitcoin {background-color: #efefef; color: #4d4d4d;} +.zocial.blogger {background-color: #ee5a22;} +.zocial.call {background-color: #008000;} +.zocial.cal {background-color: #d63538;} +.zocial.cart {background-color: #333;} +.zocial.chrome {background-color: #006cd4;} +.zocial.cloudapp {background-color: #fff; color: #312c2a;} +.zocial.creativecommons {background-color: #000;} +.zocial.delicious {background-color: #3271cb;} +.zocial.digg {background-color: #164673;} +.zocial.disqus {background-color: #5d8aad;} +.zocial.dribbble {background-color: #ea4c89;} +.zocial.dropbox {background-color: #fff; color: #312c2a;} +.zocial.email {background-color: #f0f0eb; color: #312c2a;} +.zocial.eventasaurus {background-color: #192931; color: #fff;} +.zocial.eventbrite {background-color: #ff5616;} +.zocial.eventful {background-color: #fff; color: #47ab15;} +.zocial.evernote {background-color: #6bb130; color: #fff;} +.zocial.facebook {background-color: #4863ae;} +.zocial.fivehundredpx {background-color: #333;} +.zocial.flattr {background-color: #8aba42;} +.zocial.flickr {background-color: #ff0084;} +.zocial.forrst {background-color: #1e360d;} +.zocial.foursquare {background-color: #44a8e0;} +.zocial.github {background-color: #fbfbfb; color: #050505;} +.zocial.gmail {background-color: #efefef; color: #222;} +.zocial.google {background-color: #4e6cf7;} +.zocial.googleplay {background-color: #000;} +.zocial.googleplus {background-color: #dd4b39;} +.zocial.gowalla {background-color: #ff720a;} +.zocial.grooveshark {background-color: #111; color:#eee;} +.zocial.guest {background-color: #1b4d6d;} +.zocial.html5 {background-color: #ff3617;} +.zocial.ie {background-color: #00a1d9;} +.zocial.instapaper {background-color: #eee; color: #222;} +.zocial.instagram {background-color: #3f729b;} +.zocial.intensedebate {background-color: #0099e1;} +.zocial.klout {background-color: #e34a25;} +.zocial.itunes {background-color: #efefeb; color: #312c2a;} +.zocial.lanyrd {background-color: #2e6ac2;} +.zocial.lastfm {background-color: #dc1a23;} +.zocial.linkedin {background-color: #0083a8;} +.zocial.macstore {background-color: #007dcb} +.zocial.meetup {background-color: #ff0026;} +.zocial.myspace {background-color: #000;} +.zocial.ninetyninedesigns {background-color: #fff; color: #072243;} +.zocial.openid {background-color: #f5f5f5; color: #333;} +.zocial.opentable {background-color: #990000;} +.zocial.paypal {background-color: #fff; color: #32689a; text-shadow: 0 1px 0 rgba(255,255,255,0.5);} +.zocial.pinboard {background-color: blue;} +.zocial.pinterest {background-color: #c91618;} +.zocial.plancast {background-color: #e7ebed; color: #333;} +.zocial.plurk {background-color: #cf682f;} +.zocial.podcast {background-color: #9365ce;} +.zocial.posterous {background-color: #ffd959; color: #bc7134;} +.zocial.print {background-color: #f0f0eb; color: #222; text-shadow: 0 1px 0 rgba(255,255,255,0.8);} +.zocial.quora {background-color: #a82400;} +.zocial.reddit {background-color: #fff; color: #222;} +.zocial.rss {background-color: #ff7f25;} +.zocial.scribd {background-color: #231c1a;} +.zocial.skype {background-color: #00a2ed;} +.zocial.smashing {background-color: #ff4f27;} +.zocial.songkick {background-color: #ff0050;} +.zocial.soundcloud {background-color: #ff4500;} +.zocial.spotify {background-color: #60af00;} +.zocial.stumbleupon {background-color: #eb4924;} +.zocial.tumblr {background-color: #374a61;} +.zocial.twitter {background-color: #46c0fb;} +.zocial.viadeo {background-color: #fff; color: #000;} +.zocial.vimeo {background-color: #00a2cd;} +.zocial.weibo {background-color: #faf6f1; color: #000;} +.zocial.wikipedia {background-color: #fff; color: #000;} +.zocial.windows {background-color: #0052a4; color: #fff;} +.zocial.wordpress {background-color: #464646;} +.zocial.xing {background-color: #0A5D5E;} +.zocial.yahoo {background-color: #a200c2;} +.zocial.yelp {background-color: #e60010;} +.zocial.youtube {background-color: #f00;} + +/* +The Miscellaneous Buttons +These button have no icons and can be general purpose buttons while ensuring consistent button style +Credit to @guillermovs for suggesting +*/ + +.zocial.primary, .zocial.secondary {margin: 0.1em 0; padding: 0 1em;} +.zocial.primary:before, .zocial.secondary:before {display: none;} +.zocial.primary {background-color: #333;} +.zocial.secondary {background-color: #f0f0eb; color: #222; text-shadow: 0 1px 0 rgba(255,255,255,0.8);} + +/* Any browser-specific adjustments */ + +button:-moz-focus-inner { + border: 0; + padding: 0; +} + + diff --git a/addons/auth_oauth/static/lib/zocial/sample.html b/addons/auth_oauth/static/lib/zocial/sample.html new file mode 100644 index 00000000000..98dec554ff1 --- /dev/null +++ b/addons/auth_oauth/static/lib/zocial/sample.html @@ -0,0 +1,265 @@ + + + + + Zocial CSS3 Buttons + + + + + + + + + + + + + Sign in with Google+ + + Sign in with LinkedIn + +

The Cool Kids

+ Sync with Dropbox + Clip to Evernote + Follow me on Forrst + Sign in with Dribbble + Sign in to CloudApp + Fork me on Github + Play on Spotify + Read It Later + Follow me on Soundcloud + Follow me on Tumblr + Read on Smashing Magazine + Available on iTunes + Available on the App Store + Available on the Mac App Store + Available on Android Market + Follow me on Pinterest + Follow me on Quora + Attend on Lanyrd + +

The Not-So-Cool But Have-To-Be-Invited Kids

+ Pay with Paypal + Sign in with Amazon + Call me on Skype + Sign in with Last.fm + Write a review on Yelp + Check in with foursquare + Influence with Klout + +

The Older (but Solid) Kids

+ View on Wikipedia + Sign in with Disqus + Sign in with IntenseDebate + Sign in with Google + Sign in with Gmail + Upload to Vimeo + Read more on Scribd + Subscribe on YouTube + Sign in with WordPress + Sign in with Songkick + Sign in with Posterous + Sign in with Eventbrite + Tip with Flattr + Follow me on Plancast + + +

The Kids That Kinda Smell but Some People Don't Mind

+ Submit resume for CEO + Download Internet Explorer 5 + Report bugs with Meetup.com + Learn how-to-use OpenID + Register now for HTML6 + Chat with your parents + +

The Kids That Nobody Normally Notices

+ Sign in as guest + View Creative Commons Licence + Subscribe to RSS + Add to Chrome + +

The He's-My-Son-So-Of-Course-He's-Here Kid

+ Sign up for Eventasaurus + +

Kids By Request

+ Join me on Weibo + Sign in with Plurk + Play on Grooveshark + Post on Blogger + Sign in with Viadeo + Subscribe to this Podcast + View Portfolio on 500px + Bitcoin accepted here + View Portfolio on 99Designs + Bookmark with Pinboard + Stumble! + Find me on Myspace + Sign in with Windows Live + Find Events with Eventful + Sign in with Xing + Upload to Flickr + Sign in with Del.icio.us + Download from Google Play + Reserve with OpenTable + Digg this + Share on Reddit + Fund us on AngelList + Sign-in with Instagram + +

The Multi-Purpose Kids (Credit: Pictos Icons)

+ + Call a phone + + Add to calendar + Add to cart + Print this page + Primary action + Secondary action + + +

Icon versions of the above

+ + Sign in with Google+ + + Sign in with Google + Sign in with LinkedIn + Pay with Paypal + Sign in with Amazon + Sync with Dropbox + Clip to Evernote + Call me on Skype + Sign in as guest + Play on Spotify + Sign in with Last.fm + Sign in with Songkick + Follow me on Forrst + Sign in with Dribbble + Sign in to CloudApp + Fork me on Github + Follow me on Pinterest + Follow me on Quora + Bookmark with Pinboard + Attend on Lanyrd + Download on iTunes + Download on Android + Sign in with Disqus + Sign in with Yahoo + Upload to Vimeo + Add to Chrome + Get a new browser + Made from HTML5 + Read It Later + Read more on Scribd + View on Wikipedia + Tip with Flattr + Follow me on Tumblr + Subscribe to my Posterous + Check in with Gowalla + Check in with foursquare + Write a review on Yelp + Follow me on Soundcloud + Read on Smashing Magazine + Sign in with WordPress + Sign in with IntenseDebate + Sign in with OpenID + Sign in with Gmail + Sign in with Eventbrite + Sign in with Eventasaurus + Sign in with Meetup.com + Sign in with AIM + Follow me on Plancast + Subscribe on YouTube + Available on the Mac App Store + View Creative Commons Licence + Subscribe to RSS + Follow me on Weibo + Follow me on Plurk + Follow me on Grooveshark + Post on Blogger + Sign in with Viadeo + Subscribe to this Podcast + View Portfolio on 500px + Bitcoin accepted here + View Portfolio on 99Designs + Stumble! + Download on iTunes + Find me on Myspace + Sign in with Windows Live + Find Events with Eventful + Influence with Klout + Sign in with Xing + Upload to Flickr + Sign in with Del.icio.us + Download from Google Play + Reserve with OpenTable + Digg this + Share on Reddit + Fund us on AngelList + Sign-in with Instagram + Call a phone + + Add to calendar + Print this page + Add to cart + + + +

Thanks to @guillermovs, @kamens, @vizualover, and @leaverou for code refinements and suggestions.

+ +

Massive thanks to @drewwilson for making the multi-purpose buttons possible with his incredible Pictos icons.

+ +

See code samples at zocial.smcllns.com — ask questions to @smcllns

+ + + + + + + + diff --git a/addons/auth_oauth/static/src/js/auth_oauth.js b/addons/auth_oauth/static/src/js/auth_oauth.js new file mode 100644 index 00000000000..d63631c262d --- /dev/null +++ b/addons/auth_oauth/static/src/js/auth_oauth.js @@ -0,0 +1,62 @@ +openerp.auth_oauth = function(instance) { + var QWeb = instance.web.qweb; + + instance.web.Login = instance.web.Login.extend({ + start: function(parent, params) { + var d = this._super.apply(this, arguments); + this.$element.on('click', 'a.zocial', this.on_oauth_sign_in); + this.oauth_providers = []; + if(this.params.oauth_error === 1) { + this.do_warn("Sign up error.","Sign up is not allowed on this database."); + } else if(this.params.oauth_error === 2) { + this.do_warn("Authentication error",""); + } + return d.then(this.do_oauth_load); + }, + do_oauth_load: function() { + var db = this.$("form [name=db]").val(); + if (db) { + this.rpc("/auth_oauth/list_providers", { dbname: db }).then(this.on_oauth_loaded); + } + }, + on_oauth_loaded: function(result) { + this.oauth_providers = result; + var buttons = QWeb.render("auth_oauth.Login.button",{"widget":this}); + this.$(".oe_login_pane form ul").after(buttons); + }, + on_oauth_sign_in: function(ev) { + ev.preventDefault(); + var index = $(ev.target).data('index'); + var p = this.oauth_providers[index]; + var ret = location.protocol+"//"+location.host+"/"; + var dbname = self.$("form [name=db]").val(); + var state_object = { + d: dbname, + p: p.id + } + var state = JSON.stringify(state_object); + var params = { + response_type: 'token', + client_id: p.client_id, + redirect_uri: ret, + scope: p.scope, + state: state, + }; + var url = p.auth_endpoint + '?' + $.param(params); + window.location = url; + }, + }); + + instance.web.WebClient = instance.web.WebClient.extend({ + start: function() { + this._super.apply(this, arguments); + var params = $.deparam(window.location.hash.substring(1)); + // alert(JSON.stringify(params)); + if (params.hasOwnProperty('access_token')) { + var url = "/auth_oauth/signin" + '?' + $.param(params); + window.location = url; + } + }, + }); + +}; diff --git a/addons/auth_oauth/static/src/xml/auth_oauth.xml b/addons/auth_oauth/static/src/xml/auth_oauth.xml new file mode 100644 index 00000000000..c2693804e59 --- /dev/null +++ b/addons/auth_oauth/static/src/xml/auth_oauth.xml @@ -0,0 +1,9 @@ + + + + + +
+
+
+
diff --git a/addons/auth_openid/controllers/main.py b/addons/auth_openid/controllers/main.py index dc81730daf2..eba711dae7a 100644 --- a/addons/auth_openid/controllers/main.py +++ b/addons/auth_openid/controllers/main.py @@ -28,6 +28,7 @@ import werkzeug.urls import werkzeug.exceptions from openerp.modules.registry import RegistryManager +from openerp.addons.web.controllers.main import login_and_redirect, set_cookie_and_redirect try: import openerp.addons.web.common.http as openerpweb except ImportError: @@ -159,7 +160,7 @@ class OpenIDController(openerpweb.Controller): def process(self, req, **kw): session = getattr(req.session, 'openid_session', None) if not session: - return werkzeug.utils.redirect('/') + return set_cookie_and_redirect(req, '/') oidconsumer = consumer.Consumer(session, self._store, consumer_class=GoogleAppsAwareConsumer) @@ -168,12 +169,11 @@ class OpenIDController(openerpweb.Controller): display_identifier = info.getDisplayIdentifier() session['status'] = info.status - user_id = None if info.status == consumer.SUCCESS: dbname = session['dbname'] - with utils.cursor(dbname) as cr: - registry = RegistryManager.get(dbname) + registry = RegistryManager.get(dbname) + with registry.cursor() as cr: Modules = registry.get('ir.module.module') installed = Modules.search_count(cr, 1, ['&', ('name', '=', 'auth_openid'), ('state', '=', 'installed')]) == 1 @@ -206,10 +206,9 @@ class OpenIDController(openerpweb.Controller): # TODO fill empty fields with the ones from sreg/ax cr.commit() - req.session.authenticate(dbname, login, key, {}) + return login_and_redirect(req, dbname, login, key) - if not user_id: - session['message'] = 'This OpenID identifier is not associated to any active users' + session['message'] = 'This OpenID identifier is not associated to any active users' elif info.status == consumer.SETUP_NEEDED: session['message'] = info.setup_url @@ -223,8 +222,7 @@ class OpenIDController(openerpweb.Controller): # information in a log. session['message'] = 'Verification failed.' - fragment = '#loginerror' if not user_id else '' - return werkzeug.utils.redirect('/' + fragment) + return set_cookie_and_redirect(req, '/#action=login&loginerror=1') @openerpweb.jsonrequest def status(self, req): diff --git a/addons/auth_openid/res_users.py b/addons/auth_openid/res_users.py index 3fb8cefcbd4..9b02ce42991 100644 --- a/addons/auth_openid/res_users.py +++ b/addons/auth_openid/res_users.py @@ -2,7 +2,7 @@ ############################################################################## # # OpenERP, Open Source Management Solution -# Copyright (C) 2010-2011 OpenERP s.a. (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## +from openerp.modules.registry import RegistryManager from openerp.osv import osv, fields import openerp.exceptions import tools @@ -64,23 +65,22 @@ class res_users(osv.osv): if result: return result else: - with utils.cursor(db) as cr: + with RegistryManager.get(db).cursor() as cr: cr.execute("""UPDATE res_users - SET date=now() AT TIME ZONE 'UTC' + SET login_date=now() AT TIME ZONE 'UTC' WHERE login=%s AND openid_key=%s AND active=%s RETURNING id""", (tools.ustr(login), tools.ustr(password), True)) res = cr.fetchone() cr.commit() return res[0] if res else False - def check(self, db, uid, passwd): try: return super(res_users, self).check(db, uid, passwd) except openerp.exceptions.AccessDenied: if not passwd: raise - with utils.cursor(db) as cr: + with RegistryManager.get(db).cursor() as cr: cr.execute('''SELECT COUNT(1) FROM res_users WHERE id=%s diff --git a/addons/auth_openid/res_users.xml b/addons/auth_openid/res_users.xml index df0c31856e2..be4fbdf294b 100644 --- a/addons/auth_openid/res_users.xml +++ b/addons/auth_openid/res_users.xml @@ -4,7 +4,6 @@ res.users.form res.users - form diff --git a/addons/auth_openid/static/src/js/auth_openid.js b/addons/auth_openid/static/src/js/auth_openid.js index fd6ec01cc0f..1417bc471ce 100644 --- a/addons/auth_openid/static/src/js/auth_openid.js +++ b/addons/auth_openid/static/src/js/auth_openid.js @@ -8,7 +8,7 @@ instance.web.Login = instance.web.Login.extend({ this._super.apply(this, arguments); var self = this; - this._default_error_message = this.$element.find('.login_error_message').text(); + this._default_error_message = this.$element.find('.oe_login_error_message').text(); this.$openid_selected_button = $(); this.$openid_selected_input = $(); @@ -40,8 +40,7 @@ instance.web.Login = instance.web.Login.extend({ } }); - this._check_fragment(); - + this._check_error(); }, @@ -67,11 +66,9 @@ instance.web.Login = instance.web.Login.extend({ }, - _check_fragment: function() { + _check_error: function() { var self = this; - var fragment = jQuery.deparam.fragment(); - console.log(fragment); - if (fragment.loginerror !== undefined) { + if (this.params.loginerror !== undefined) { this.rpc('/auth_openid/login/status', {}, function(result) { if (_.contains(['success', 'failure'], result.status) && result.message) { self.do_warn('Invalid OpenID Login', result.message); @@ -132,11 +129,12 @@ instance.web.Login = instance.web.Login.extend({ do_warn: function(title, msg) { //console.warn(title, msg); - this.$element.find('.login_error_message').text(msg).show(); + this.$element.find('.oe_login_error_message').text(msg).show(); + this._super(title, msg); }, reset_error_message: function() { - this.$element.find('.login_error_message').text(this._default_error_message); + this.$element.find('.oe_login_error_message').text(this._default_error_message); } }); diff --git a/addons/auth_openid/static/src/xml/auth_openid.xml b/addons/auth_openid/static/src/xml/auth_openid.xml index 34894555668..aa61d161657 100644 --- a/addons/auth_openid/static/src/xml/auth_openid.xml +++ b/addons/auth_openid/static/src/xml/auth_openid.xml @@ -3,7 +3,7 @@ - + - - - - - - - - - - - - - - - - - - +
  • Google Apps Domain
  • @@ -54,7 +37,7 @@
    - + this.each(function() { var $i = $(this), dp = $i.find('input').attr('name'); diff --git a/addons/auth_openid/utils.py b/addons/auth_openid/utils.py index 444b5eeaa05..806198f99c2 100644 --- a/addons/auth_openid/utils.py +++ b/addons/auth_openid/utils.py @@ -1,8 +1,8 @@ #!/usr/bin/env python ############################################################################## -# +# # OpenERP, Open Source Management Solution -# Copyright (C) 2010-2011 OpenERP s.a. (). +# Copyright (C) 2010-2012 OpenERP s.a. (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -15,11 +15,9 @@ # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# along with this program. If not, see . # ############################################################################## -from contextlib import contextmanager -from openerp.modules.registry import RegistryManager KEY_LENGTH = 16 @@ -35,14 +33,4 @@ SREG2AX = { # from http://www.axschema.org/types/#sreg 'timezone': 'http://axschema.org/pref/timezone', } - -@contextmanager -def cursor(db): - cr = RegistryManager.get(db).db.cursor() - try: - yield cr - finally: - cr.close() - - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_reset_password/static/src/js/reset_password.js b/addons/auth_reset_password/static/src/js/reset_password.js index 41b48c7e59b..13cf070a548 100644 --- a/addons/auth_reset_password/static/src/js/reset_password.js +++ b/addons/auth_reset_password/static/src/js/reset_password.js @@ -31,7 +31,7 @@ openerp.auth_reset_password = function(instance) { }, do_reset_password: function(db, email) { var self = this; - instance.connection.session_authenticate(db, 'anonymous', 'anonymous', true).pipe(function () { + instance.session.session_authenticate(db, 'anonymous', 'anonymous', true).pipe(function () { var func = new instance.web.Model("res.users").get_func("send_reset_password_request"); return func(email).then(function(res) { // show message diff --git a/addons/auth_signup/__init__.py b/addons/auth_signup/__init__.py index 2e404949550..2331ae629a8 100644 --- a/addons/auth_signup/__init__.py +++ b/addons/auth_signup/__init__.py @@ -1,2 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## + +import controllers import res_config -import auth_signup +import res_users diff --git a/addons/auth_signup/__openerp__.py b/addons/auth_signup/__openerp__.py index a869c623db0..765a36ef252 100644 --- a/addons/auth_signup/__openerp__.py +++ b/addons/auth_signup/__openerp__.py @@ -1,22 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2009-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## + { - 'name': 'Signup', - 'description': 'Allow users to sign up', - 'author': 'OpenERP SA', - 'version': '1.0', - 'category': 'Authentication', - 'website': 'http://www.openerp.com', - 'installable': True, - 'depends': ['auth_anonymous', 'base_setup'], - 'data': [ - 'res_config.xml', - ], - 'js': [ - 'static/src/js/auth_signup.js', - ], - 'css': [ - 'static/src/css/auth_signup.css', - ], - 'qweb': [ - 'static/src/xml/auth_signup.xml', - ], + 'name': 'Signup', + 'description': 'Allow users to sign up', + 'author': 'OpenERP SA', + 'version': '1.0', + 'category': 'Authentication', + 'website': 'http://www.openerp.com', + 'installable': True, + 'depends': ['base_setup'], + 'data': [ + 'res_config.xml', + ], + 'js': [ + 'static/src/js/auth_signup.js', + ], + 'qweb': [ + 'static/src/xml/auth_signup.xml', + ], } diff --git a/addons/auth_signup/auth_signup.py b/addons/auth_signup/auth_signup.py deleted file mode 100644 index ebc72b3aeac..00000000000 --- a/addons/auth_signup/auth_signup.py +++ /dev/null @@ -1,39 +0,0 @@ -from openerp.osv import osv, fields - -class res_users(osv.Model): - _inherit = 'res.users' - - _sql_constraints = [ - ('email_uniq', 'UNIQUE (user_email)', 'You can not have two users with the same email!') - ] - -class signup_signup(osv.TransientModel): - _name = 'auth.signup' - - # TODO add captcha - _columns = { - 'name': fields.char('Name', size=64), - 'email': fields.char('Email', size=64), - 'password': fields.char('Password', size=64), - } - - def create(self, cr, uid, values, context=None): - # NOTE here, invalid values raises exceptions to avoid storing - # sensitive data into the database (which then are available to anyone) - - new_user = { - 'name': values['name'], - 'login': values['email'], - 'user_email': values['email'], - 'password': values['password'], - 'active': True, - } - - user_template_id = self.pool.get('ir.config_parameter').get_param(cr, uid, 'auth.signup_template_user_id', 0) - if user_template_id: - self.pool.get('res.users').copy(cr, 1, user_template_id, new_user, context=context) - else: - self.pool.get('res.users').create(cr, 1, new_user, context=context) - - # Dont store anything - return 0 diff --git a/addons/auth_signup/controllers/__init__.py b/addons/auth_signup/controllers/__init__.py new file mode 100644 index 00000000000..e11f9ba81bb --- /dev/null +++ b/addons/auth_signup/controllers/__init__.py @@ -0,0 +1,3 @@ +import main + +# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py new file mode 100644 index 00000000000..0ed2151d12b --- /dev/null +++ b/addons/auth_signup/controllers/main.py @@ -0,0 +1,34 @@ +import logging + +import werkzeug.urls + +from openerp.modules.registry import RegistryManager +from openerp.addons.web.controllers.main import login_and_redirect +import openerp.addons.web.common.http as openerpweb + +_logger = logging.getLogger(__name__) + +class OpenIDController(openerpweb.Controller): + _cp_path = '/auth_signup' + + @openerpweb.httprequest + def signup(self, req, dbname, name, login, password): + url = '/' + registry = RegistryManager.get(dbname) + with registry.cursor() as cr: + try: + Users = registry.get('res.users') + credentials = Users.auth_signup(cr, 1, name, login, password) + cr.commit() + return login_and_redirect(req, *credentials) + except AttributeError: + # auth_signup is not installed + _logger.exception('attribute error when signup') + url = "/#action=auth_signup&error=NA" # Not Available + except Exception: + # signup error + _logger.exception('error when signup') + url = "/#action=auth_signup&error=UE" # Unexcpected Error + return werkzeug.utils.redirect(url) + +# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/auth_signup/res_config.py b/addons/auth_signup/res_config.py index 2828a2b55fd..6afd1c5b581 100644 --- a/addons/auth_signup/res_config.py +++ b/addons/auth_signup/res_config.py @@ -1,10 +1,32 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2012-today OpenERP SA () +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see +# +############################################################################## + from openerp.osv import osv, fields class base_config_settings(osv.TransientModel): _inherit = 'base.config.settings' _columns = { - 'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup') + 'auth_signup_uninvited': fields.boolean('allow public users to sign up', help="If unchecked only invited users may sign up"), + 'auth_signup_template_user_id': fields.many2one('res.users', 'Template user for new users created through signup'), } def get_default_signup(self, cr, uid, fields, context=None): diff --git a/addons/auth_signup/res_config.xml b/addons/auth_signup/res_config.xml index d30d383ecdb..49669d36618 100644 --- a/addons/auth_signup/res_config.xml +++ b/addons/auth_signup/res_config.xml @@ -6,18 +6,16 @@ base.config.settings.signup base.config.settings - form - - - + +
    + +
    +
    +
    diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py new file mode 100644 index 00000000000..1d77a3f9473 --- /dev/null +++ b/addons/auth_signup/res_users.py @@ -0,0 +1,46 @@ +import openerp +from openerp.osv import osv + +class res_users(osv.Model): + _inherit = 'res.users' + + def auth_signup_create(self, cr, uid, new_user, context=None): + # new_user: + # login + # email + # name (optional) + # partner_id (optional) + # groups (optional) + # sign (for partner_id and groups) + # + user_template_id = self.pool.get('ir.config_parameter').get_param(cr, uid, 'auth.signup_template_user_id', 0) + if user_template_id: + self.pool.get('res.users').copy(cr, 1, user_template_id, new_user, context=context) + else: + self.pool.get('res.users').create(cr, 1, new_user, context=context) + + def auth_signup(self, cr, uid, name, login, password, context=None): + r = (cr.dbname, login, password) + res = self.search(cr, uid, [("login", "=", login)]) + if res: + # Existing user + user_id = res[0] + try: + self.check(cr.dbname, user_id, password) + # Same password + except openerp.exceptions.AccessDenied: + # Different password + raise + else: + # New user + new_user = { + 'name': name, + 'login': login, + 'user_email': login, + 'password': password, + 'active': True, + } + self.auth_signup_create(cr, uid, new_user) + return r + +# diff --git a/addons/auth_signup/static/src/css/auth_signup.css b/addons/auth_signup/static/src/css/auth_signup.css deleted file mode 100644 index 1e8d7d9d8d8..00000000000 --- a/addons/auth_signup/static/src/css/auth_signup.css +++ /dev/null @@ -1,9 +0,0 @@ -.openerp .oe_login .oe_login_pane ul.oe_signup a { - color: #eeeeee; - margin: 0 8px; -} -.openerp .oe_login .oe_login_pane ul.oe_signup a:hover { - text-decoration: underline; -} - - diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js index 7384fe1e5f5..2ab13aa7598 100644 --- a/addons/auth_signup/static/src/js/auth_signup.js +++ b/addons/auth_signup/static/src/js/auth_signup.js @@ -1,65 +1,38 @@ openerp.auth_signup = function(instance) { + instance.auth_signup = instance.auth_signup || {}; var _t = instance.web._t; instance.web.Login.include({ start: function() { var self = this; - this.$('a.oe_signup').click(function() { - var db = self.$("form [name=db]").val(); - if (!db) { - self.do_warn(_t("Login"), _t("No database selected!")); - return false; - } - - var cnx = instance.connection; - if (cnx.session_is_valid()) { - self._signup(); - } else { - cnx.session_authenticate(db, 'anonymous', 'anonymous', true).then(function() { - self._signup(); - }).fail(function(error, event) { - console.log(error); - // cannot log as anonymous or auth_signup not installed - self.do_warn(_t('Sign Up'), _.str.sprintf(_t('Signup functionnality is not available for database %s'), db), true); - }); - } + var dbname = self.$("form [name=db]").val(); + self.do_action({ + type: 'ir.actions.client', + tag: 'auth_signup.signup', + params: {'dbname': dbname}, + target: 'new', + name: 'Sign up' + }); return true; }); return this._super(); - }, - - _signup: function() { - this.do_action({ - type: 'ir.actions.client', - tag: 'auth_signup.signup', - target: 'new', - name: 'Sign up' - }); - } }); - instance.auth_signup = instance.auth_signup || {}; instance.auth_signup.Signup = instance.web.Widget.extend({ template: 'auth_signup.signup', - init: function() { - this._super.apply(this, arguments); - this.dataset = new instance.web.DataSet(this, 'auth.signup'); + init: function(parent, params) { + this.params = params; + return this._super(); }, start: function() { var self = this; - this.$('input[type=password]').change(function() { + this.$('input[name=password_confirmation]').keyup(function() { var v = $(this).val(); - var e = !_.isEmpty(v); - if (e) { - e =_.all(self.$('input[type=password]'), function(i) { - return $(i).val() === v; - }); - } var $b = self.$('button'); - if (e) { + if (_.isEmpty(v) || self.$('input[name=password]').val() === v) { $b.removeAttr('disabled'); } else { $b.attr('disabled', 'disabled'); @@ -70,36 +43,18 @@ openerp.auth_signup = function(instance) { if(ev) { ev.preventDefault(); } - var name = self.$('input[name=name]').val(); - var email = self.$('input[name=email]').val(); - var password = self.$('input[name=password]').val(); - - self.dataset.create({ - name: name, - email: email, - password: password - }, function() { - self.do_action({ - type: 'ir.actions.client', - tag: 'login', - params: { - db: instance.connection.db, - login: email, - password: password, - login_successful: function() { - self.do_action('home'); - } - } - }); - }); - return false; - + var params = { + dbname : self.params.dbname, + name: self.$('input[name=name]').val(), + login: self.$('input[name=email]').val(), + password: self.$('input[name=password]').val(), + }; + var url = "/auth_signup/signup?" + $.param(params); + window.location = url; }); - return $.when(this._super()); + return this._super(); } - }); instance.web.client_actions.add("auth_signup.signup", "instance.auth_signup.Signup"); - }; diff --git a/addons/auth_signup/static/src/xml/auth_signup.xml b/addons/auth_signup/static/src/xml/auth_signup.xml index 92343d96281..c2eec846d15 100644 --- a/addons/auth_signup/static/src/xml/auth_signup.xml +++ b/addons/auth_signup/static/src/xml/auth_signup.xml @@ -14,10 +14,10 @@
    - Name = - Email = - Password = - Confirmation = + Name =
    + Email =
    + Password =
    + Confirmation =
    diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 7699256985c..b6eacda63c0 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -292,7 +292,7 @@ the rule to mark CC(mail to any other person defined in actions)."), 'object_description': hasattr(obj, 'description') and obj.description or False, 'object_user': hasattr(obj, 'user_id') and (obj.user_id and obj.user_id.name) or '/', 'object_user_email': hasattr(obj, 'user_id') and (obj.user_id and \ - obj.user_id.user_email) or '/', + obj.user_id.email) or '/', 'object_user_phone': hasattr(obj, 'partner_address_id') and (obj.partner_address_id and \ obj.partner_address_id.phone) or '/', 'partner': hasattr(obj, 'partner_id') and (obj.partner_id and obj.partner_id.name) or '/', @@ -319,8 +319,8 @@ the rule to mark CC(mail to any other person defined in actions)."), mail_message = self.pool.get('mail.message') body = self.format_mail(obj, body) if not emailfrom: - if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.user_email: - emailfrom = obj.user_id.user_email + if hasattr(obj, 'user_id') and obj.user_id and obj.user_id.email: + emailfrom = obj.user_id.email name = '[%d] %s' % (obj.id, tools.ustr(obj.name)) emailfrom = tools.ustr(emailfrom) @@ -419,7 +419,7 @@ the rule to mark CC(mail to any other person defined in actions)."), emails = [] if hasattr(obj, 'user_id') and action.act_mail_to_user: if obj.user_id: - emails.append(obj.user_id.user_email) + emails.append(obj.user_id.email) if action.act_mail_to_watchers: emails += (action.act_email_cc or '').split(',') diff --git a/addons/base_action_rule/base_action_rule_view.xml b/addons/base_action_rule/base_action_rule_view.xml index ba51b729305..0d268438a41 100644 --- a/addons/base_action_rule/base_action_rule_view.xml +++ b/addons/base_action_rule/base_action_rule_view.xml @@ -10,7 +10,6 @@ base.action.rule.form base.action.rule - form
    @@ -98,7 +97,6 @@ base.action.rule.tree base.action.rule - tree diff --git a/addons/base_calendar/base_calendar.py b/addons/base_calendar/base_calendar.py index b570c2ef011..be3244f8a5b 100644 --- a/addons/base_calendar/base_calendar.py +++ b/addons/base_calendar/base_calendar.py @@ -245,7 +245,7 @@ class calendar_attendee(osv.osv): continue else: result[id][name] = self._get_address(attdata.sent_by_uid.name, \ - attdata.sent_by_uid.user_email) + attdata.sent_by_uid.email) if name == 'cn': if attdata.user_id: @@ -289,7 +289,7 @@ class calendar_attendee(osv.osv): if name == 'language': user_obj = self.pool.get('res.users') - lang = user_obj.read(cr, uid, uid, ['context_lang'], context=context)['context_lang'] + lang = user_obj.read(cr, uid, uid, ['lang'], context=context)['lang'] result[id][name] = lang.replace('_', '-') return result @@ -434,7 +434,7 @@ property or property parameter."), if not organizer: organizer = event_obj.user_id event_org.params['CN'] = [organizer.name] - event_org.value = 'MAILTO:' + (organizer.user_email or organizer.name) + event_org.value = 'MAILTO:' + (organizer.email or organizer.name) if event_obj.alarm_id: # computes alarm data @@ -535,7 +535,7 @@ property or property parameter."), return {'value': {'email': ''}} usr_obj = self.pool.get('res.users') user = usr_obj.browse(cr, uid, user_id, *args) - return {'value': {'email': user.user_email, 'availability':user.availability}} + return {'value': {'email': user.email, 'availability':user.availability}} def do_tentative(self, cr, uid, ids, context=None, *args): """ Makes event invitation as Tentative @@ -891,9 +891,9 @@ From: """ % (alarm.name, alarm.trigger_date, alarm.description, \ alarm.user_id.name, alarm.user_id.signature) - mail_to = [alarm.user_id.user_email] + mail_to = [alarm.user_id.email] for att in alarm.attendee_ids: - mail_to.append(att.user_id.user_email) + mail_to.append(att.user_id.email) if mail_to: mail_message.schedule_with_attach(cr, uid, tools.config.get('email_from', False), @@ -947,7 +947,7 @@ class calendar_event(osv.osv): value['duration'] = duration # change start_date's time to 00:00:00 in the user's timezone user = self.pool.get('res.users').browse(cr, uid, uid) - tz = pytz.timezone(user.context_tz) if user.context_tz else pytz.utc + tz = pytz.timezone(user.tz) if user.tz else pytz.utc start = pytz.utc.localize(start).astimezone(tz) # convert start in user's timezone start = start.replace(hour=0, minute=0, second=0) # change start's time to 00:00:00 start = start.astimezone(pytz.utc) # convert start back to utc @@ -1097,8 +1097,8 @@ rule or repeating pattern of time to exclude from the recurring rule."), user_pool = self.pool.get('res.users') user = user_pool.browse(cr, uid, uid, context=context) res = user.name - if user.user_email: - res += " <%s>" %(user.user_email) + if user.email: + res += " <%s>" %(user.email) return res _defaults = { diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml index 0e12d835710..89066ce74bb 100644 --- a/addons/base_calendar/base_calendar_view.xml +++ b/addons/base_calendar/base_calendar_view.xml @@ -6,7 +6,6 @@ calendar.attendee.form calendar.attendee - form
    @@ -62,7 +61,6 @@ calendar.attendee.tree calendar.attendee - tree @@ -81,7 +79,6 @@ calendar.attendee.search calendar.attendee - search @@ -129,7 +126,6 @@ res.alarm.form res.alarm - form @@ -150,7 +146,6 @@ res.alarm.tree res.alarm - tree @@ -189,7 +184,6 @@ Event Form calendar.event - form
    @@ -363,7 +357,6 @@ Event Tree calendar.event - tree @@ -382,7 +375,6 @@ Events Calendar calendar.event - calendar @@ -398,7 +390,6 @@ Calendar Events Search calendar.event - search diff --git a/addons/base_calendar/crm_meeting_data.xml b/addons/base_calendar/crm_meeting_data.xml index 82752d1dc7d..44838514935 100644 --- a/addons/base_calendar/crm_meeting_data.xml +++ b/addons/base_calendar/crm_meeting_data.xml @@ -13,7 +13,7 @@ - Phone Call + Off-site Meeting diff --git a/addons/base_calendar/crm_meeting_demo.xml b/addons/base_calendar/crm_meeting_demo.xml index ad88c11bb1b..221653e5fc3 100644 --- a/addons/base_calendar/crm_meeting_demo.xml +++ b/addons/base_calendar/crm_meeting_demo.xml @@ -1,79 +1,78 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + Follow-up for Project proposal + Meeting to discuss project plan and hash out the details of implementation. + - - + + + open - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + Initial discussion + Discussion with partner for product. + + + + + draft + + + + + + Pricing Discussion + Internal meeting for discussion for new pricing for product and services. + + + + + done + + + + + + Requirements review + + + + + open + + + + + + Changes in Designing + + + + + draft + + + + + + Presentation for new Services + + + + + done diff --git a/addons/base_calendar/crm_meeting_view.xml b/addons/base_calendar/crm_meeting_view.xml index a97d2967ffa..51d17ed43f8 100644 --- a/addons/base_calendar/crm_meeting_view.xml +++ b/addons/base_calendar/crm_meeting_view.xml @@ -45,7 +45,6 @@ Meeting Types Tree crm.meeting.type - tree @@ -68,7 +67,6 @@ CRM - Meetings Form crm.meeting - form
    @@ -235,6 +233,7 @@
    +
    @@ -245,7 +244,6 @@ CRM - Meetings Tree crm.meeting - tree @@ -264,7 +262,6 @@ CRM - Meetings Calendar crm.meeting - calendar @@ -279,7 +276,6 @@ CRM - Meetings Gantt crm.meeting - gantt @@ -290,7 +286,6 @@ CRM - Meetings Search crm.meeting - search diff --git a/addons/base_calendar/test/base_calendar_test.yml b/addons/base_calendar/test/base_calendar_test.yml index e9a0f21e26e..2f5ff7945ee 100644 --- a/addons/base_calendar/test/base_calendar_test.yml +++ b/addons/base_calendar/test/base_calendar_test.yml @@ -1,5 +1,5 @@ -- | - In Order to test base_calendar, I will first create One Simple Event with real data +- + In Order to test base_calendar, I will first create One Simple Event with real data - !record {model: calendar.event, id: calendar_event_technicalpresentation0}: class: private @@ -11,27 +11,25 @@ location: OpenERP S.A. name: Technical Presentation rrule_type: none -- | - Now I will set recurrence for this event to occur monday and friday of week +- + Now I will set recurrence for this event to occur monday and friday of week - !python {model: calendar.event}: | data = {'fr': 1, 'mo': 1, 'interval': 1, 'rrule_type': 'weekly', 'end_type': 'end_date', 'end_date': '2011-05-31 00:00:00', 'recurrency' : True} self.write(cr, uid, [ref("calendar_event_technicalpresentation0")], data) -- | - In order to check that recurrent events are views successfully in calendar view, - I will open calendar view of events +- + In order to check that recurrent events are views successfully in calendar view, I will open calendar view of events - !python {model: calendar.event}: | self.fields_view_get(cr, uid, False, 'calendar', context) -- | - In order to check that recurrent events are views successfully in calendar view, - I will search for one of the recurrent event and count the number of events +- + In order to check that recurrent events are views successfully in calendar view, I will search for one of the recurrent event and count the number of events - !python {model: calendar.event}: | ids = self.search(cr, uid, [('date', '>=', '2011-04-30 16:00:00'), ('date', '<=', '2011-05-31 00:00:00')], context={'virtual_id': True} ) assert len(ids) == 9 -- | - Now I will make All day event and test it +- + Now I will make All day event and test it - !record {model: calendar.event, id: calendar_event_alldaytestevent0}: allday: 1 @@ -42,8 +40,8 @@ location: School name: All day test event rrule_type: none -- | - In order to check reminder I will first create reminder +- + In order to check reminder I will first create reminder - !record {model: res.alarm, id: res_alarm_daybeforeeventstarts0}: name: 1 Day before event starts @@ -51,13 +49,13 @@ trigger_interval: days trigger_occurs: before trigger_related: start -- | - Now I will assign this reminder to all day event +- + Now I will assign this reminder to all day event - !python {model: calendar.event}: | self.write(cr, uid, [ref("calendar_event_alldaytestevent0")], {'alarm_id': ref("res_alarm_daybeforeeventstarts0")}) -- | - In order to assign attendee I will invite Demo user +- + In order to assign attendee I will invite Demo user - !record {model: base_calendar.invite.attendee, id: base_calendar_invite_attendee_0}: type: internal @@ -65,13 +63,13 @@ partner_id: base.res_partner_9 # Put bcz of problem in read user_ids: - base.user_demo -- | - Then I click on Invite Button +- + Then I click on Invite Button - !python {model: base_calendar.invite.attendee}: | self.do_invite(cr, uid, [ref("base_calendar_invite_attendee_0")], {'active_id': ref("calendar_event_alldaytestevent0"), 'model' : 'calendar.event', 'attendee_field':'attendee_ids'}) -- | - Now I will Accept this invitation +- + Now I will Accept this invitation - !python {model: calendar.attendee}: | ids = self.search(cr, uid, [('ref', '=', 'calendar.event' + ',' + str(ref("calendar_event_alldaytestevent0")))]) diff --git a/addons/base_calendar/wizard/base_calendar_invite_attendee.py b/addons/base_calendar/wizard/base_calendar_invite_attendee.py index b49c4219ce8..344056eb585 100644 --- a/addons/base_calendar/wizard/base_calendar_invite_attendee.py +++ b/addons/base_calendar/wizard/base_calendar_invite_attendee.py @@ -99,12 +99,12 @@ send an Email to Invited Person') user = user_obj.browse(cr, uid, user_id) res = { 'user_id': user_id, - 'email': user.user_email + 'email': user.email } res.update(ref) vals.append(res) - if user.user_email: - mail_to.append(user.user_email) + if user.email: + mail_to.append(user.email) elif type == 'external' and datas.get('email'): res = {'email': datas['email']} @@ -143,7 +143,7 @@ send an Email to Invited Person') self._columns['type'].selection)) raise osv.except_osv(_('Error!'), _("%s must have an email address to send mail.") %(name[0])) att_obj._send_mail(cr, uid, attendees, mail_to, \ - email_from = current_user.user_email or tools.config.get('email_from', False)) + email_from = current_user.email or tools.config.get('email_from', False)) return {'type': 'ir.actions.act_window_close'} diff --git a/addons/base_calendar/wizard/base_calendar_invite_attendee_view.xml b/addons/base_calendar/wizard/base_calendar_invite_attendee_view.xml index 3bdb9144907..5510259a7a7 100644 --- a/addons/base_calendar/wizard/base_calendar_invite_attendee_view.xml +++ b/addons/base_calendar/wizard/base_calendar_invite_attendee_view.xml @@ -7,7 +7,6 @@ model="ir.ui.view"> Invite Attendees base_calendar.invite.attendee - form
    diff --git a/addons/base_crypt/crypt.py b/addons/base_crypt/crypt.py index f7e200560a3..b27dad22363 100644 --- a/addons/base_crypt/crypt.py +++ b/addons/base_crypt/crypt.py @@ -213,7 +213,7 @@ class users(osv.osv): # Check if the encrypted password matches against the one in the db. cr.execute("""UPDATE res_users - SET date=now() AT TIME ZONE 'UTC' + SET login_date=now() AT TIME ZONE 'UTC' WHERE id=%s AND password=%s AND active RETURNING id""", (int(id), encrypted_pw.encode('utf-8'))) diff --git a/addons/base_module_doc_rst/base_module_doc_rst_view.xml b/addons/base_module_doc_rst/base_module_doc_rst_view.xml index 2fa4e220d0d..b90583ae635 100644 --- a/addons/base_module_doc_rst/base_module_doc_rst_view.xml +++ b/addons/base_module_doc_rst/base_module_doc_rst_view.xml @@ -10,7 +10,6 @@ ir.module.module.form.graph ir.module.module - form diff --git a/addons/base_module_doc_rst/wizard/generate_relation_graph_view.xml b/addons/base_module_doc_rst/wizard/generate_relation_graph_view.xml index 4072db42318..ed30fc64822 100644 --- a/addons/base_module_doc_rst/wizard/generate_relation_graph_view.xml +++ b/addons/base_module_doc_rst/wizard/generate_relation_graph_view.xml @@ -5,7 +5,6 @@ create.relation.graph.form create.relation.graph - form diff --git a/addons/base_module_doc_rst/wizard/tech_guide_rst_view.xml b/addons/base_module_doc_rst/wizard/tech_guide_rst_view.xml index 50166dffc96..86c7002568c 100644 --- a/addons/base_module_doc_rst/wizard/tech_guide_rst_view.xml +++ b/addons/base_module_doc_rst/wizard/tech_guide_rst_view.xml @@ -5,7 +5,6 @@ tech.guide.rst.form tech.guide.rst - form diff --git a/addons/base_module_record/wizard/base_module_record_data_view.xml b/addons/base_module_record/wizard/base_module_record_data_view.xml index 281576b0b6a..afe9833c209 100644 --- a/addons/base_module_record/wizard/base_module_record_data_view.xml +++ b/addons/base_module_record/wizard/base_module_record_data_view.xml @@ -5,7 +5,6 @@ base_module_record_data base.module.data - form @@ -53,7 +52,6 @@ module.create.xml.form base.module.record.data - form diff --git a/addons/base_module_record/wizard/base_module_record_object_view.xml b/addons/base_module_record/wizard/base_module_record_object_view.xml index a621ae69547..fdfb6e9fc66 100644 --- a/addons/base_module_record/wizard/base_module_record_object_view.xml +++ b/addons/base_module_record/wizard/base_module_record_object_view.xml @@ -5,7 +5,6 @@ base_module_record_objects base.module.record - form @@ -57,7 +56,6 @@ module.create.form base.module.record.objects - form @@ -83,7 +81,6 @@ info.start.form.view base.module.record.objects - form @@ -109,7 +106,6 @@ module_recording_message base.module.record.objects - form