diff --git a/addons/account/account.py b/addons/account/account.py index e1a2dfabec6..8ef4da0d66b 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -2921,7 +2921,7 @@ class account_fiscal_position_template(osv.osv): 'chart_template_id': fields.many2one('account.chart.template', 'Chart Template', required=True), 'account_ids': fields.one2many('account.fiscal.position.account.template', 'position_id', 'Account Mapping'), 'tax_ids': fields.one2many('account.fiscal.position.tax.template', 'position_id', 'Tax Mapping'), - 'note': fields.text('Notes', translate=True), + 'note': fields.text('Notes'), } def generate_fiscal_position(self, cr, uid, chart_temp_id, tax_template_ref, acc_template_ref, company_id, context=None): diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index be41b06e346..d1186396b12 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -565,6 +565,9 @@ class account_move_line(osv.osv): cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = \'account_move_line_journal_id_period_id_index\'') if not cr.fetchone(): cr.execute('CREATE INDEX account_move_line_journal_id_period_id_index ON account_move_line (journal_id, period_id)') + cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s', ('account_move_line_date_id_index',)) + if not cr.fetchone(): + cr.execute('CREATE INDEX account_move_line_date_id_index ON account_move_line (date DESC, id desc)') return res def _check_no_view(self, cr, uid, ids, context=None): diff --git a/addons/account/partner.py b/addons/account/partner.py index f24ffcf55b4..249ad45d96e 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -33,7 +33,7 @@ class account_fiscal_position(osv.osv): 'company_id': fields.many2one('res.company', 'Company'), 'account_ids': fields.one2many('account.fiscal.position.account', 'position_id', 'Account Mapping'), 'tax_ids': fields.one2many('account.fiscal.position.tax', 'position_id', 'Tax Mapping'), - 'note': fields.text('Notes', translate=True), + 'note': fields.text('Notes'), } _defaults = { diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index e48533ebeb4..6c5e8d4d6cb 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -214,6 +214,7 @@ class base_action_rule(osv.osv): """ Wrap the methods `create` and `write` of the models specified by the rules given by `ids` (or all existing rules if `ids` is `None`.) """ + updated = False if ids is None: ids = self.search(cr, SUPERUSER_ID, []) for action_rule in self.browse(cr, SUPERUSER_ID, ids): @@ -223,20 +224,21 @@ class base_action_rule(osv.osv): model_obj.create = self._wrap_create(model_obj.create, model) model_obj.write = self._wrap_write(model_obj.write, model) model_obj.base_action_ruled = True - return True + updated = True + return updated def create(self, cr, uid, vals, context=None): res_id = super(base_action_rule, self).create(cr, uid, vals, context=context) - self._register_hook(cr, [res_id]) - openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) + if self._register_hook(cr, [res_id]): + openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) return res_id def write(self, cr, uid, ids, vals, context=None): if isinstance(ids, (int, long)): ids = [ids] super(base_action_rule, self).write(cr, uid, ids, vals, context=context) - self._register_hook(cr, ids) - openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) + if self._register_hook(cr, ids): + openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname) return True def onchange_model_id(self, cr, uid, ids, model_id, context=None): @@ -266,7 +268,10 @@ class base_action_rule(osv.osv): action_ids = self.search(cr, uid, action_dom, context=context) for action in self.browse(cr, uid, action_ids, context=context): now = datetime.now() - last_run = get_datetime(action.last_run) if action.last_run else False + if action.last_run: + last_run = get_datetime(action.last_run) + else: + last_run = datetime.utcfromtimestamp(0) # retrieve all the records that satisfy the action's condition model = self.pool[action.model_id.model] @@ -297,11 +302,16 @@ class base_action_rule(osv.osv): if not record_dt: continue action_dt = self._check_delay(cr, uid, action, record, record_dt, context=context) - if last_run and (last_run <= action_dt < now) or (action_dt < now): + if last_run <= action_dt < now: try: + context = dict(context or {}, action=True) self._process(cr, uid, action, [record.id], context=context) except Exception: import traceback _logger.error(traceback.format_exc()) action.write({'last_run': now.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) + + if automatic: + # auto-commit for batch processing + cr.commit() diff --git a/addons/base_action_rule/base_action_rule_data.xml b/addons/base_action_rule/base_action_rule_data.xml index 7a9aabedf5f..d4b12f5d4a3 100644 --- a/addons/base_action_rule/base_action_rule_data.xml +++ b/addons/base_action_rule/base_action_rule_data.xml @@ -10,7 +10,7 @@ - + diff --git a/addons/delivery/__openerp__.py b/addons/delivery/__openerp__.py index 1ee6bf413ec..844ceb69ab5 100644 --- a/addons/delivery/__openerp__.py +++ b/addons/delivery/__openerp__.py @@ -41,7 +41,9 @@ invoices from picking, OpenERP is able to add and compute the shipping line. 'delivery_data.xml' ], 'demo': ['delivery_demo.xml'], - 'test': ['test/delivery_cost.yml'], + 'test': ['test/delivery_cost.yml', + 'test/delivery_chained_pickings.yml', + ], 'installable': True, 'auto_install': False, 'images': ['images/1_delivery_method.jpeg','images/2_delivery_pricelist.jpeg'], diff --git a/addons/delivery/stock.py b/addons/delivery/stock.py index 42c24b4a27d..adae3e63c50 100644 --- a/addons/delivery/stock.py +++ b/addons/delivery/stock.py @@ -166,6 +166,17 @@ class stock_move(osv.osv): } return res + def _prepare_chained_picking(self, cr, uid, picking_name, picking, picking_type, moves_todo, context=None): + values = super(stock_move, self)._prepare_chained_picking(cr, uid, picking_name, picking, picking_type, moves_todo, context=context) + if picking.carrier_id: + values['carrier_id'] = picking.carrier_id.id + values['volume'] = picking.volume + values['weight'] = picking.weight + values['weight_net'] = picking.weight_net + values['carrier_tracking_ref'] = picking.carrier_tracking_ref + values['number_of_packages'] = picking.number_of_packages + return values + _columns = { 'weight': fields.function(_cal_move_weight, type='float', string='Weight', digits_compute= dp.get_precision('Stock Weight'), multi='_cal_move_weight', store={ diff --git a/addons/delivery/test/delivery_chained_pickings.yml b/addons/delivery/test/delivery_chained_pickings.yml new file mode 100644 index 00000000000..1d368e51d86 --- /dev/null +++ b/addons/delivery/test/delivery_chained_pickings.yml @@ -0,0 +1,50 @@ +- + I setup product and locations +- + !record {model: stock.location, id: dest_chained_location}: + name: DestChainedLocation + usage: internal +- + !record {model: stock.location, id: source_chained_location}: + name: Source Chained Location + chained_auto_packing: auto + chained_location_type: fixed + usage: internal + chained_location_id: dest_chained_location +- + I create a picking to location_convenience_shop, which is chained with location_refrigerator +- + !record {model: stock.picking, id: shipment_with_delivery}: + type: internal + carrier_id: delivery.delivery_carrier + volume: 42 + carrier_tracking_ref: FDX123 + number_of_packages: 7 +- + I add a move in the picking +- + !record {model: stock.move, id: icecream_move}: + picking_id: shipment_with_delivery + product_id: product_product_delivery + product_uom: product.product_uom_kgm + product_qty: 130.0 + location_id: stock.stock_location_suppliers + location_dest_id: source_chained_location +- + I confirm the picking +- + !workflow {model: stock.picking, action: button_confirm, ref: shipment_with_delivery} +- + I check that the delivery fields have been propagated to the chained picking +- + !python {model: stock.move}: | + original_move = self.browse(cr, uid, ref('icecream_move'), context=context) + original_picking = original_move.picking_id + chained_move = original_move.move_dest_id + chained_picking = chained_move.picking_id + assert chained_picking.carrier_tracking_ref == original_picking.carrier_tracking_ref, 'no propagation of carrier_tracking_ref' + assert chained_picking.carrier_id == original_picking.carrier_id, 'no propagation of carrier_id' + assert chained_picking.volume == original_picking.volume, 'no propagation of volume' + assert chained_picking.weight == original_picking.weight, 'no propagation of weight' + assert chained_picking.weight_net == original_picking.weight_net, 'no propagation of weight' + diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml index 644586ec502..1b4f733eb8a 100644 --- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml +++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml @@ -134,7 +134,7 @@ - + diff --git a/addons/l10n_multilang/account.py b/addons/l10n_multilang/account.py index 55770c5ec14..3f171cfc2de 100644 --- a/addons/l10n_multilang/account.py +++ b/addons/l10n_multilang/account.py @@ -72,6 +72,7 @@ class account_fiscal_position(osv.osv): _inherit = 'account.fiscal.position' _columns = { 'name': fields.char('Fiscal Position', size=64, required=True, translate=True), + 'note': fields.text('Notes', translate=True), } @@ -79,6 +80,7 @@ class account_fiscal_position_template(osv.osv): _inherit = 'account.fiscal.position.template' _columns = { 'name': fields.char('Fiscal Position Template', size=64, required=True, translate=True), + 'note': fields.text('Notes', translate=True), } diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index a7f7bbfc869..9280848e36d 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -123,7 +123,8 @@ class sale_order(osv.osv): ('shipping_except', 'Shipping Exception'), ('invoice_except', 'Invoice Exception'), ('done', 'Done'), - ], 'Status', readonly=True,help="Gives the status of the quotation or sales order.\ + ], 'Status', readonly=True, track_visibility='onchange', + help="Gives the status of the quotation or sales order.\ \nThe exception status is automatically set when a cancel operation occurs \ in the invoice validation (Invoice Exception) or in the picking list process (Shipping Exception).\nThe 'Waiting Schedule' status is set when the invoice is confirmed\ but waiting for the scheduler to run on the order date.", select=True),