[MERGE] forward port of branch 8.0 up to 83bd9ee
authorChristophe Simonis <chs@odoo.com>
Wed, 12 Nov 2014 18:47:04 +0000 (19:47 +0100)
committerChristophe Simonis <chs@odoo.com>
Wed, 12 Nov 2014 18:47:04 +0000 (19:47 +0100)
27 files changed:
1  2 
addons/account/account_invoice_view.xml
addons/account/security/ir.model.access.csv
addons/account_asset/account_asset.py
addons/account_voucher/account_voucher.py
addons/account_voucher/voucher_payment_receipt_view.xml
addons/account_voucher/voucher_sales_purchase_view.xml
addons/calendar/calendar_view.xml
addons/crm/crm_phonecall_view.xml
addons/mail/mail_mail.py
addons/mrp/mrp_view.xml
addons/point_of_sale/point_of_sale.py
addons/point_of_sale/static/src/css/pos.css
addons/point_of_sale/static/src/js/models.js
addons/point_of_sale/static/src/js/widget_base.js
addons/point_of_sale/static/src/js/widgets.js
addons/point_of_sale/static/src/xml/pos.xml
addons/product/product.py
addons/product/product_view.xml
addons/sale/__openerp__.py
addons/stock/static/src/js/widgets.js
addons/web/controllers/main.py
addons/web/static/src/js/formats.js
addons/web/static/src/js/view_form.js
addons/web_kanban/static/src/css/kanban.css
addons/web_kanban/static/src/css/kanban.sass
addons/website_forum/models/forum.py
openerp/models.py

Simple merge
Simple merge
                  <field name="date"/>
                  <field name="state"/>
                  <filter string="My Phonecalls" domain="[('user_id', '=', uid)]"/>
 -                <filter string="My Team" domain="[('section_id.user_id', '=', uid)]"/>
 +                <filter string="My Team" domain="[('team_id.user_id', '=', uid)]"/>
                  <filter string="Unassigned" domain="[('user_id','=',False)]"/>
                  <separator/>
-                 <filter string="To Do" name="current" domain="[('state','=','open')]"/>
+                 <filter string="To Do" name="current" domain="[('state','in',('open','pending'))]"/>
                  <separator/>
                  <filter string="New Mail" name="message_unread" domain="[('message_unread','=',True)]"/>
                  <separator/>
Simple merge
                                  <tree string="Components" editable="bottom">
                                      <field name="sequence" widget="handle"/>
                                      <field name="product_id" on_change="onchange_product_id(product_id, product_qty)"/>
 -                                    <field name="type"/>
 +                                    <field name="type" groups="mrp.group_route_line_type"/>
                                      <field name="product_qty"/>
                                      <field name="product_uom" on_change="onchange_uom(product_id, product_uom)" groups="product.group_uom"/>
 -                                    <field name="product_rounding"/>
 -                                    <field name="product_efficiency"/>
 +                                    <field name="product_rounding" groups="mrp.group_rounding_efficiency"/>
 +                                    <field name="product_efficiency" groups="mrp.group_rounding_efficiency"/>
                                      <field name="date_start"/>
                                      <field name="date_stop"/>
-                                     <field name="attribute_value_ids" widget="many2many_tags"/>
+                                     <field name="attribute_value_ids" widget="many2many_tags" domain="[('product_ids.product_tmpl_id', '=', parent.product_tmpl_id)]"/>
                                  </tree>
                              </field>
                          </page>
@@@ -680,9 -682,9 +680,9 @@@ class pos_order(osv.osv)
          'date_order': fields.datetime('Order Date', readonly=True, select=True),
          'user_id': fields.many2one('res.users', 'Salesman', help="Person who uses the the cash register. It can be a reliever, a student or an interim employee."),
          'amount_tax': fields.function(_amount_all, string='Taxes', digits_compute=dp.get_precision('Account'), multi='all'),
-         'amount_total': fields.function(_amount_all, string='Total', multi='all'),
+         'amount_total': fields.function(_amount_all, string='Total', digits_compute=dp.get_precision('Account'),  multi='all'),
          'amount_paid': fields.function(_amount_all, string='Paid', states={'draft': [('readonly', False)]}, readonly=True, digits_compute=dp.get_precision('Account'), multi='all'),
 -        'amount_return': fields.function(_amount_all, 'Returned', digits_compute=dp.get_precision('Account'), multi='all'),
 +        'amount_return': fields.function(_amount_all, string='Returned', digits_compute=dp.get_precision('Account'), multi='all'),
          'lines': fields.one2many('pos.order.line', 'order_id', 'Order Lines', states={'draft': [('readonly', False)]}, readonly=True, copy=True),
          'statement_ids': fields.one2many('account.bank.statement.line', 'pos_statement_id', 'Payments', states={'draft': [('readonly', False)]}, readonly=True),
          'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, states={'draft': [('readonly', False)]}, readonly=True),
@@@ -1164,10 -1113,11 +1164,14 @@@ td 
      word-wrap: break-word;
  }
  
+ @page {
+     margin: 0;
+ }
  @media print {
 +    body {
 +        margin: 0;
 +    }
      .oe_leftbar,
      .pos .pos-topheader, 
      .pos .pos-leftpane, 
@@@ -17,36 -18,24 +18,30 @@@ function openerp_pos_basewidget(instanc
              options = options || {};
              this.pos = options.pos || (parent ? parent.pos : undefined);
              this.pos_widget = options.pos_widget || (parent ? parent.pos_widget : undefined);
-             this.build_currency_template();
          },
-         build_currency_template: function(){
+         format_currency: function(amount,precision){
+             var currency = (this.pos && this.pos.currency) ? this.pos.currency : {symbol:'$', position: 'after', rounding: 0.01, decimals: 2};
+             var decimals = currency.decimals;
  
-             if(this.pos && this.pos.currency){
-                 this.currency = this.pos.currency;
-             }else{
-                 this.currency = {symbol: '$', position: 'after', rounding: 0.01};
+             if (precision && (typeof this.pos.dp[precision]) !== undefined) {
+                 decimals = this.pos.dp[precision];
              }
  
-             var decimals = Math.max(0,Math.ceil(Math.log(1.0 / this.currency.rounding) / Math.log(10)));
 +            this.format_currency_no_symbol = function(amount){
 +                amount = round_pr(amount,this.currency.rounding);
 +                amount = amount.toFixed(decimals);
 +                return amount;
 +            };
 +
-             this.format_currency = function(amount){
-                 if(typeof amount === 'number'){
-                     amount = Math.round(amount*100)/100;
-                     amount = amount.toFixed(decimals);
-                 }
-                 if(this.currency.position === 'after'){
-                     return amount + ' ' + (this.currency.symbol || '');
-                 }else{
-                     return (this.currency.symbol || '') + ' ' + amount;
-                 }
-             };
+             if (typeof amount === 'number') {
+                 amount = round_di(amount,decimals).toFixed(decimals);
+             }
  
+             if (currency.position === 'after') {
+                 return amount + ' ' + (currency.symbol || '');
+             } else {
+                 return (currency.symbol || '') + ' ' + amount;
+             }
          },
          show: function(){
              this.$el.removeClass('oe_hidden');
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -1,11 -1,10 +1,14 @@@
 +.ui-tabs .oe-view-manager-view-kanban {
 +  position: static;
 +}
 +
  .openerp .oe_kanban_view {
    background: white;
 -  height: inherit;
 +  height: 100%;
  }
+ .openerp .oe_kanban_view.oe_background_grey > table.oe_kanban_groups {
+   background-color: #eee;
+ }
  .openerp .oe_kanban_view .oe_kanban_column_higlight {
    background: #eeddf6 !important;
  }
  .openerp .oe_kanban_view .oe_kanban_content div:first-child {
    margin-right: 16px;
  }
--.openerp .oe_kanban_view .oe_kanban_button_new {
--  color: white;
--  background: #DC5F59;
--}
  .openerp .oe_kanban_view .oe_kanban_groups {
    height: inherit;
  }
    -webkit-border-radius: 4px;
    margin-bottom: 5px;
  }
--.openerp .oe_kanban_view .oe_kanban_box_header {
--  border-bottom: 1px solid #CCC;
--}
--.openerp .oe_kanban_view .oe_kanban_title {
--  font-size: 95%;
--  font-weight: bold;
--  padding: 0 4px 0 4px;
--}
--.openerp .oe_kanban_view .oe_kanban_small {
--  font-size: 80%;
--  font-weight: normal;
--}
  .openerp .oe_kanban_view .oe_kanban_show_more {
    clear: both;
    text-align: center;
  .openerp .oe_kanban_view .oe_kanban_color_border {
    border-color: #CCCCCC;
  }
--.openerp .oe_kanban_view .oe_kanban_color_border {
--  border-color: #CCCCCC;
--}
  .openerp .oe_kanban_view .oe_kanban_tooltip ul, .openerp .oe_kanban_view ul.oe_kanban_tooltip {
    padding: 0 0 4px 0;
    margin: 5px 0 0 15px;
      // KanbanView {{{
      //background: url(data:image/pngbase64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAKElEQVQIHWP8DwTv379nAAFBQUEGhnfv3oHEwADEZgJLIRGMIClkLQCr3x2Htp/lLwAAAABJRU5ErkJggg==)
      background: white
 +    height: 100%
+     &.oe_background_grey
+         > table.oe_kanban_groups
+             background-color: #eee
 -    height: inherit
      .oe_kanban_column_higlight
          background: #eeddf6 !important
      .oe_view_nocontent
@@@ -294,79 -362,80 +294,79 @@@ class Post(models.Model)
                  raise KarmaError('Not enough karma to accept or refuse an answer')
              # update karma except for self-acceptance
              mult = 1 if vals['is_correct'] else -1
 -            for post in self.browse(cr, uid, ids, context=context):
 -                if vals['is_correct'] != post.is_correct and post.create_uid.id != uid:
 -                    self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [post.create_uid.id], post.forum_id.karma_gen_answer_accepted * mult, context=context)
 -                    self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [uid], post.forum_id.karma_gen_answer_accept * mult, context=context)
 -        if any(key not in ['state', 'active', 'is_correct', 'closed_uid', 'closed_date', 'closed_reason_id'] for key in vals.keys()) and any(not post.can_edit for post in posts):
 +            for post in self:
 +                if vals['is_correct'] != post.is_correct and post.create_uid.id != self._uid:
 +                    post.create_uid.sudo().add_karma(post.forum_id.karma_gen_answer_accepted * mult)
 +                    self.env.user.sudo().add_karma(post.forum_id.karma_gen_answer_accept * mult)
 +        if any(key not in ['state', 'active', 'is_correct', 'closed_uid', 'closed_date', 'closed_reason_id'] for key in vals.keys()) and any(not post.can_edit for post in self):
              raise KarmaError('Not enough karma to edit a post.')
  
 -        res = super(Post, self).write(cr, uid, ids, vals, context=context)
 +        res = super(Post, self).write(vals)
          # if post content modify, notify followers
          if 'content' in vals or 'name' in vals:
 -            for post in posts:
 +            for post in self:
                  if post.parent_id:
                      body, subtype = _('Answer Edited'), 'website_forum.mt_answer_edit'
 -                    obj_id = post.parent_id.id
 +                    obj_id = post.parent_id
                  else:
                      body, subtype = _('Question Edited'), 'website_forum.mt_question_edit'
 -                    obj_id = post.id
 -                self.message_post(cr, uid, obj_id, body=body, subtype=subtype, context=context)
 +                    obj_id = post
 +                obj_id.message_post(body=body, subtype=subtype)
          return res
  
 -
 -    def reopen(self, cr, uid, ids, context=None):
 -        if any(post.parent_id or post.state != 'close'
 -                    for post in self.browse(cr, uid, ids, context=context)):
 +    @api.multi
 +    def reopen(self):
 +        if any(post.parent_id or post.state != 'close' for post in self):
              return False
  
 -        reason_offensive = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'website_forum.reason_7')
 -        reason_spam = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'website_forum.reason_8')
 -        for post in self.browse(cr, uid, ids, context=context):
 -            if post.closed_reason_id.id in (reason_offensive, reason_spam):
 +        reason_offensive = self.env.ref('website_forum.reason_7')
 +        reason_spam = self.env.ref('website_forum.reason_8')
 +        for post in self:
 +            if post.closed_reason_id in (reason_offensive, reason_spam):
                  _logger.info('Upvoting user <%s>, reopening spam/offensive question',
-                              post.create_uid.login)
+                              post.create_uid)
                  # TODO: in master, consider making this a tunable karma parameter
 -                self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [post.create_uid.id],
 -                                                 post.forum_id.karma_gen_question_downvote * -5,
 -                                                 context=context)
 -        self.pool['forum.post'].write(cr, SUPERUSER_ID, ids, {'state': 'active'}, context=context)
 +                post.create_uid.sudo().add_karma(post.forum_id.karma_gen_question_downvote * -5)
  
 -    def close(self, cr, uid, ids, reason_id, context=None):
 -        if any(post.parent_id for post in self.browse(cr, uid, ids, context=context)):
 +        self.sudo().write({'state': 'active'})
 +
 +    @api.multi
 +    def close(self, reason_id):
 +        if any(post.parent_id for post in self):
              return False
  
 -        reason_offensive = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'website_forum.reason_7')
 -        reason_spam = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'website_forum.reason_8')
 +        reason_offensive = self.env.ref('website_forum.reason_7').id
 +        reason_spam = self.env.ref('website_forum.reason_8').id
          if reason_id in (reason_offensive, reason_spam):
 -            for post in self.browse(cr, uid, ids, context=context):
 +            for post in self:
                  _logger.info('Downvoting user <%s> for posting spam/offensive contents',
-                              post.create_uid.login)
+                              post.create_uid)
                  # TODO: in master, consider making this a tunable karma parameter
 -                self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [post.create_uid.id],
 -                                                 post.forum_id.karma_gen_question_downvote * 5,
 -                                                 context=context)
 +                post.create_uid.sudo().add_karma(post.forum_id.karma_gen_question_downvote * 5)
  
 -        self.pool['forum.post'].write(cr, uid, ids, {
 +        self.write({
              'state': 'close',
 -            'closed_uid': uid,
 +            'closed_uid': self._uid,
              'closed_date': datetime.today().strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT),
              'closed_reason_id': reason_id,
 -        }, context=context)
 +        })
 +        return True
  
 -    def unlink(self, cr, uid, ids, context=None):
 -        posts = self.browse(cr, uid, ids, context=context)
 -        if any(not post.can_unlink for post in posts):
 +    @api.multi
 +    def unlink(self):
 +        if any(not post.can_unlink for post in self):
              raise KarmaError('Not enough karma to unlink a post')
          # if unlinking an answer with accepted answer: remove provided karma
 -        for post in posts:
 +        for post in self:
              if post.is_correct:
 -                self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [post.create_uid.id], post.forum_id.karma_gen_answer_accepted * -1, context=context)
 -                self.pool['res.users'].add_karma(cr, SUPERUSER_ID, [uid], post.forum_id.karma_gen_answer_accept * -1, context=context)
 -        return super(Post, self).unlink(cr, uid, ids, context=context)
 -
 -    def vote(self, cr, uid, ids, upvote=True, context=None):
 -        Vote = self.pool['forum.post.vote']
 -        vote_ids = Vote.search(cr, uid, [('post_id', 'in', ids), ('user_id', '=', uid)], context=context)
 +                post.create_uid.sudo().add_karma(post.forum_id.karma_gen_answer_accepted * -1)
 +                self.env.user.sudo().add_karma(post.forum_id.karma_gen_answer_accepted * -1)
 +        return super(Post, self).unlink()
 +
 +    @api.multi
 +    def vote(self, upvote=True):
 +        Vote = self.env['forum.post.vote']
 +        vote_ids = Vote.search([('post_id', 'in', self._ids), ('user_id', '=', self._uid)])
          new_vote = '1' if upvote else '-1'
          voted_forum_ids = set()
          if vote_ids:
Simple merge