From 905617b53002a0052bade2359b713f369faefdba Mon Sep 17 00:00:00 2001 From: Laetitia Gangloff Date: Fri, 6 Jun 2014 12:55:22 +0200 Subject: [PATCH 1/9] hr_timesheet_sheet: for attendance, set default value for employee_id in the context --- addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 @@ - + From ac117ac2200a250de9be44cebe172bd512a8afbd Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Fri, 6 Jun 2014 14:18:37 +0200 Subject: [PATCH 2/9] [FIX] delivery: propagate additional fields in chained pickings closes #367 --- addons/delivery/__openerp__.py | 4 +- addons/delivery/stock.py | 11 ++++ .../test/delivery_chained_pickings.yml | 50 +++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 addons/delivery/test/delivery_chained_pickings.yml diff --git a/addons/delivery/__openerp__.py b/addons/delivery/__openerp__.py index 0ea891bb6ae..dffc156e104 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 e96daea63d2..263a47696a5 100644 --- a/addons/delivery/stock.py +++ b/addons/delivery/stock.py @@ -167,6 +167,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' + From 0ceee2a1209b789c9cfcd9f6c8b9da50be425dca Mon Sep 17 00:00:00 2001 From: Alexandre Fayolle Date: Fri, 6 Jun 2014 14:47:33 +0200 Subject: [PATCH 3/9] [IMP] add an index on account_move_line(date, id) fixes https://launchpad.net/bugs/1311004 --- addons/account/account_move_line.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 4da965167ba..a7fd2adf33e 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -566,6 +566,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): From b38a129d71067933d99794f0c802e53a09b0d538 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Wed, 11 Jun 2014 14:53:59 +0200 Subject: [PATCH 4/9] [FIX] account: move translatable tag The field note on account.fiscal.position and account.fiscal.position.template should not be translatable in classic modules. The l10n_multilang module is intendend to make chart of accounts multilang and is the place to set translate=True --- addons/account/account.py | 2 +- addons/account/partner.py | 2 +- addons/l10n_multilang/account.py | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/account/account.py b/addons/account/account.py index 6cc7125db1c..a42bab8e7f5 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -2935,7 +2935,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/partner.py b/addons/account/partner.py index 22d6fcea394..051c7e8d54f 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/l10n_multilang/account.py b/addons/l10n_multilang/account.py index 4cb0e28b672..cf9e56652f8 100644 --- a/addons/l10n_multilang/account.py +++ b/addons/l10n_multilang/account.py @@ -78,6 +78,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), } account_fiscal_position() @@ -86,6 +87,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), } account_fiscal_position_template() From ff8b843b18e02cd9889eb08528f4e01e6a8b0820 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 11 Jun 2014 11:41:48 +0200 Subject: [PATCH 5/9] [FIX] base_action_rule: do not force registry reload when writing on a rule unless really needed Executing a rule always updates the `last_run` value, which would always force a useless registry reload to occur. Only signal the change if the rule applies to a model that was not previoulsy monitored for base action rules. --- addons/base_action_rule/base_action_rule.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 37c4980528e..988cff1b972 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -193,6 +193,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): @@ -202,20 +203,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): From d4356263f272cf25e6e7d29b2c4221522304af54 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 11 Jun 2014 11:46:00 +0200 Subject: [PATCH 6/9] [FIX] base_action_rule: do not repeatedly trigger already-executed rules based on time condition A programming error introduced at rco@openerp.com-20121220142445-emzzvhlw400q37c9 fails to properly check when a rule has already been executed in the past. Time-based rules should only be executed if the trigger date is in the past and: - either they never executed before - or the last execution date is older than the trigger date --- addons/base_action_rule/base_action_rule.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 988cff1b972..2488ebcb946 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -235,7 +235,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.get(action.model_id.model) @@ -268,7 +271,7 @@ class base_action_rule(osv.osv): if not record_dt: continue action_dt = get_datetime(record_dt) + delay - if last_run and (last_run <= action_dt < now) or (action_dt < now): + if last_run <= action_dt < now: try: self._process(cr, uid, action, [record.id], context=context) except Exception: From cf0be50f04ee5bdec25d45c630ecc601065ccc2d Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 11 Jun 2014 11:50:38 +0200 Subject: [PATCH 7/9] [FIX] base_action_rule: prevent recursive rule trigger also when processing time-based rules A safety guard already in place prevents the recursive trigger of rules while another rule is being executed, as a simple measure to prevent endless loops. This guard was missing when processing time-based rules. --- addons/base_action_rule/base_action_rule.py | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 2488ebcb946..a6793e9bac5 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -273,6 +273,7 @@ class base_action_rule(osv.osv): action_dt = get_datetime(record_dt) + delay 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 From 5ccfeaaeda425a3efe7311bab447e8bdfd36d56e Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Wed, 11 Jun 2014 11:52:29 +0200 Subject: [PATCH 8/9] [FIX] base_action_rule: automatic commit during background processing of rules This will make sure already processed rules are persisted in case a timeout occurs while processing the next ones, ensuring that *some* progress can be made in most cases. --- addons/base_action_rule/base_action_rule.py | 4 ++++ addons/base_action_rule/base_action_rule_data.xml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index a6793e9bac5..1b80f9f36c3 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -280,3 +280,7 @@ class base_action_rule(osv.osv): _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 @@ - + From 4d3a5df0012c2a59412360dc3ee6bd32a710b689 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 12 Jun 2014 12:37:11 +0200 Subject: [PATCH 9/9] [FIX] sale_order: set state field track_visibility sale_order module override state field of sale.oder (sale.sale.py) and forgot to reset the track_visibility, therefore sale orders state changes are no longer tracked once this module installed. --- addons/sale_stock/sale_stock.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/sale_stock/sale_stock.py b/addons/sale_stock/sale_stock.py index 1b21f889a78..d389715e6c1 100644 --- a/addons/sale_stock/sale_stock.py +++ b/addons/sale_stock/sale_stock.py @@ -125,7 +125,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),