diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index e06e41cf001..17c0a77c30f 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -154,12 +154,11 @@ for a particular financial year and for preparation of vouchers there is a modul 'test/account_period_close.yml', 'test/account_use_model.yml', 'test/account_validate_account_move.yml', - 'test/account_fiscalyear_close.yml', #'test/account_bank_statement.yml', #'test/account_cash_statement.yml', 'test/test_edi_invoice.yml', 'test/account_report.yml', - 'test/account_fiscalyear_close_state.yml', #last test, as it will definitively close the demo fiscalyear + 'test/account_fiscalyear_close.yml', #last test, as it will definitively close the demo fiscalyear ], 'installable': True, 'auto_install': False, diff --git a/addons/account/account.py b/addons/account/account.py index 21a5ce992d7..75936320e58 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -3047,6 +3047,20 @@ class wizard_multi_charts_accounts(osv.osv_memory): 'complete_tax_set': fields.boolean('Complete Set of Taxes', help='This boolean helps you to choose if you want to propose to the user to encode the sales and purchase rates or use the usual m2o fields. This last choice assumes that the set of tax defined for the chosen template is complete'), } + + def _get_chart_parent_ids(self, cr, uid, chart_template, context=None): + """ Returns the IDs of all ancestor charts, including the chart itself. + (inverse of child_of operator) + + :param browse_record chart_template: the account.chart.template record + :return: the IDS of all ancestor charts, including the chart itself. + """ + result = [chart_template.id] + while chart_template.parent_id: + chart_template = chart_template.parent_id + result.append(chart_template.id) + return result + def onchange_tax_rate(self, cr, uid, ids, rate=False, context=None): return {'value': {'purchase_tax_rate': rate or False}} @@ -3060,12 +3074,17 @@ class wizard_multi_charts_accounts(osv.osv_memory): res['value'].update({'complete_tax_set': data.complete_tax_set, 'currency_id': currency_id}) if data.complete_tax_set: # default tax is given by the lowest sequence. For same sequence we will take the latest created as it will be the case for tax created while isntalling the generic chart of account - sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id" - , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence, id desc") - purchase_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id" - , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence, id desc") - res['value'].update({'sale_tax': sale_tax_ids and sale_tax_ids[0] or False, 'purchase_tax': purchase_tax_ids and purchase_tax_ids[0] or False}) - + chart_ids = self._get_chart_parent_ids(cr, uid, data, context=context) + base_tax_domain = [("chart_template_id", "in", chart_ids), ('parent_id', '=', False)] + sale_tax_domain = base_tax_domain + [('type_tax_use', 'in', ('sale','all'))] + purchase_tax_domain = base_tax_domain + [('type_tax_use', 'in', ('purchase','all'))] + sale_tax_ids = tax_templ_obj.search(cr, uid, sale_tax_domain, order="sequence, id desc") + purchase_tax_ids = tax_templ_obj.search(cr, uid, purchase_tax_domain, order="sequence, id desc") + res['value'].update({'sale_tax': sale_tax_ids and sale_tax_ids[0] or False, + 'purchase_tax': purchase_tax_ids and purchase_tax_ids[0] or False}) + res.setdefault('domain', {}) + res['domain']['sale_tax'] = repr(sale_tax_domain) + res['domain']['purchase_tax'] = repr(purchase_tax_domain) if data.code_digits: res['value'].update({'code_digits': data.code_digits}) return res @@ -3073,6 +3092,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): def default_get(self, cr, uid, fields, context=None): res = super(wizard_multi_charts_accounts, self).default_get(cr, uid, fields, context=context) tax_templ_obj = self.pool.get('account.tax.template') + account_chart_template = self.pool['account.chart.template'] if 'bank_accounts_id' in fields: res.update({'bank_accounts_id': [{'acc_name': _('Cash'), 'account_type': 'cash'},{'acc_name': _('Bank'), 'account_type': 'bank'}]}) @@ -3086,23 +3106,28 @@ class wizard_multi_charts_accounts(osv.osv_memory): currency_id = company_obj.on_change_country(cr, uid, company_id, country_id, context=context)['value']['currency_id'] res.update({'currency_id': currency_id}) - ids = self.pool.get('account.chart.template').search(cr, uid, [('visible', '=', True)], context=context) + ids = account_chart_template.search(cr, uid, [('visible', '=', True)], context=context) if ids: + #in order to set default chart which was last created set max of ids. + chart_id = max(ids) + if context.get("default_charts"): + model_data = self.pool.get('ir.model.data').search_read(cr, uid, [('model','=','account.chart.template'),('module','=',context.get("default_charts"))], ['res_id'], context=context) + if model_data: + chart_id = model_data[0]['res_id'] + chart = account_chart_template.browse(cr, uid, chart_id, context=context) + chart_hierarchy_ids = self._get_chart_parent_ids(cr, uid, chart, context=context) if 'chart_template_id' in fields: - #in order to get set default chart which was last created set max of ids. - chart_id = max(ids) - if context.get("default_charts"): - model_data = self.pool.get('ir.model.data').search_read(cr, uid, [('model','=','account.chart.template'),('module','=',context.get("default_charts"))], ['res_id'], context=context) - if model_data: - chart_id = model_data[0]['res_id'] - res.update({'only_one_chart_template': len(ids) == 1, 'chart_template_id': chart_id}) + res.update({'only_one_chart_template': len(ids) == 1, + 'chart_template_id': chart_id}) if 'sale_tax' in fields: - sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id" - , "=", ids[0]), ('type_tax_use', 'in', ('sale','all'))], order="sequence") + sale_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id", "in", chart_hierarchy_ids), + ('type_tax_use', 'in', ('sale','all'))], + order="sequence") res.update({'sale_tax': sale_tax_ids and sale_tax_ids[0] or False}) if 'purchase_tax' in fields: - purchase_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id" - , "=", ids[0]), ('type_tax_use', 'in', ('purchase','all'))], order="sequence") + purchase_tax_ids = tax_templ_obj.search(cr, uid, [("chart_template_id", "in", chart_hierarchy_ids), + ('type_tax_use', 'in', ('purchase','all'))], + order="sequence") res.update({'purchase_tax': purchase_tax_ids and purchase_tax_ids[0] or False}) res.update({ 'purchase_tax_rate': 15.0, @@ -3370,12 +3395,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): obj_tax_temp = self.pool.get('account.tax.template') chart_template = obj_wizard.chart_template_id vals = {} - # get the ids of all the parents of the selected account chart template - current_chart_template = chart_template - all_parents = [current_chart_template.id] - while current_chart_template.parent_id: - current_chart_template = current_chart_template.parent_id - all_parents.append(current_chart_template.id) + all_parents = self._get_chart_parent_ids(cr, uid, chart_template, context=context) # create tax templates and tax code templates from purchase_tax_rate and sale_tax_rate fields if not chart_template.complete_tax_set: value = obj_wizard.sale_tax_rate diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index 1b7bd658faf..3cf10f477e2 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -463,7 +463,7 @@ - + diff --git a/addons/account/partner.py b/addons/account/partner.py index a7df31b2f32..d0db2ed4f6c 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -113,7 +113,8 @@ class res_partner(osv.osv): LEFT JOIN account_account a ON (l.account_id=a.id) WHERE a.type IN ('receivable','payable') AND l.partner_id IN %s - AND l.reconcile_id IS NULL + AND (l.reconcile_id IS NULL OR + reconcile_id in (SELECT id FROM account_move_reconcile WHERE opening_reconciliation is TRUE)) AND """ + query + """ GROUP BY l.partner_id, a.type """, diff --git a/addons/account/static/src/js/account_move_line_quickadd.js b/addons/account/static/src/js/account_move_line_quickadd.js index 0b904e19da6..997b2b03bb6 100644 --- a/addons/account/static/src/js/account_move_line_quickadd.js +++ b/addons/account/static/src/js/account_move_line_quickadd.js @@ -84,7 +84,7 @@ openerp.account.quickadd = function (instance) { }, search_by_journal_period: function() { var self = this; - var domain = ['|',['debit', '!=', 0], ['credit', '!=', 0]]; + var domain = []; if (self.current_journal !== null) domain.push(["journal_id", "=", self.current_journal]); if (self.current_period !== null) domain.push(["period_id", "=", self.current_period]); self.last_context["journal_id"] = self.current_journal === null ? false : self.current_journal; diff --git a/addons/account/test/account_fiscalyear_close.yml b/addons/account/test/account_fiscalyear_close.yml index 1c3547ccefd..b80cfd0e6e9 100644 --- a/addons/account/test/account_fiscalyear_close.yml +++ b/addons/account/test/account_fiscalyear_close.yml @@ -17,7 +17,20 @@ fiscalyear_id: account_fiscalyear_fiscalyear0 name: !eval "'OP %s' %(datetime.now().year+1)" special: 1 - +- + I create a new account invoice a the partner in current fiscalyear +- + !record {model: account.invoice, id: account_invoice_current1}: + partner_id: base.res_partner_2 + invoice_line: + - partner_id: base.res_partner_2 + quantity: 1.0 + price_unit: 15.00 + name: Bying stuff +- + I validate it the invoice +- + !workflow {model: account.invoice, action: invoice_open, ref: account.account_invoice_current1} - I made modification in journal so it can move entries - @@ -41,9 +54,30 @@ report_name: End of Fiscal Year Entry - I clicked on create Button - - !python {model: account.fiscalyear.close}: | self.data_save(cr, uid, [ref("account_fiscalyear_close_0")], {"lang": 'en_US', "active_model": "ir.ui.menu", "active_ids": [ref("account.menu_wizard_fy_close")], - "tz": False, "active_id": ref("account.menu_wizard_fy_close"), }) \ No newline at end of file + "tz": False, "active_id": ref("account.menu_wizard_fy_close"), }) +- + I close the previous fiscalyear +- + !record {model: account.fiscalyear.close.state, id: account_fiscalyear_close_state_0}: + fy_id: data_fiscalyear +- + I clicked on Close States Button to close fiscalyear +- + !python {model: account.fiscalyear.close.state}: | + self.data_save(cr, uid, [ref("account_fiscalyear_close_state_0")], {"lang": 'en_US', + "active_model": "ir.ui.menu", "active_ids": [ref("account.menu_wizard_fy_close_state")], + "tz": False, "active_id": ref("account.menu_wizard_fy_close_state"), }) +- + I check that the fiscalyear state is now "Done" +- + !assert {model: account.fiscalyear, id: data_fiscalyear, string: Fiscal Year is in Done state}: + - state == 'done' +- + I check that the past accounts are taken into account in partner credit +- + !assert {model: res.partner, id: base.res_partner_2}: + - credit == 15.0, "Total Receivable does not takes unreconciled previous moves" diff --git a/addons/account/test/account_fiscalyear_close_state.yml b/addons/account/test/account_fiscalyear_close_state.yml deleted file mode 100644 index 18c7dd570ed..00000000000 --- a/addons/account/test/account_fiscalyear_close_state.yml +++ /dev/null @@ -1,19 +0,0 @@ -- - I run the Close a Fiscalyear wizard to close the demo fiscalyear -- - !record {model: account.fiscalyear.close.state, id: account_fiscalyear_close_state_0}: - fy_id: data_fiscalyear -- - I clicked on Close States Button to close fiscalyear - -- - !python {model: account.fiscalyear.close.state}: | - self.data_save(cr, uid, [ref("account_fiscalyear_close_state_0")], {"lang": 'en_US', - "active_model": "ir.ui.menu", "active_ids": [ref("account.menu_wizard_fy_close_state")], - "tz": False, "active_id": ref("account.menu_wizard_fy_close_state"), }) -- - I check that the fiscalyear state is now "Done" -- - !assert {model: account.fiscalyear, id: data_fiscalyear, string: Fiscal Year is in Done state}: - - state == 'done' - diff --git a/addons/account_analytic_analysis/i18n/zh_CN.po b/addons/account_analytic_analysis/i18n/zh_CN.po index c3bd697646c..3bcf3f4406b 100644 --- a/addons/account_analytic_analysis/i18n/zh_CN.po +++ b/addons/account_analytic_analysis/i18n/zh_CN.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2013-10-18 05:51+0000\n" -"X-Generator: Launchpad (build 16799)\n" +"X-Launchpad-Export-Date: 2013-10-19 04:59+0000\n" +"X-Generator: Launchpad (build 16807)\n" #. module: account_analytic_analysis #: view:account.analytic.account:0 diff --git a/addons/account_followup/account_followup.py b/addons/account_followup/account_followup.py index 715860cab83..9237282ad80 100644 --- a/addons/account_followup/account_followup.py +++ b/addons/account_followup/account_followup.py @@ -185,7 +185,7 @@ class res_partner(osv.osv): return {} data['partner_ids'] = wizard_partner_ids datas = { - 'ids': [], + 'ids': wizard_partner_ids, 'model': 'account_followup.followup', 'form': data } diff --git a/addons/account_followup/wizard/account_followup_print.py b/addons/account_followup/wizard/account_followup_print.py index c14b5c071f6..00ecab7b860 100644 --- a/addons/account_followup/wizard/account_followup_print.py +++ b/addons/account_followup/wizard/account_followup_print.py @@ -50,9 +50,9 @@ class account_followup_stat_by_partner(osv.osv): # to send him follow-ups separately . An assumption that the number of companies will not # reach 10 000 records is made, what should be enough for a time. cr.execute(""" - create or replace view account_followup_stat_by_partner as ( + create view account_followup_stat_by_partner as ( SELECT - l.partner_id * 10000 + l.company_id as id, + l.partner_id * 10000::bigint + l.company_id as id, l.partner_id AS partner_id, min(l.date) AS date_move, max(l.date) AS date_move_last, @@ -67,11 +67,10 @@ class account_followup_stat_by_partner(osv.osv): a.active AND a.type = 'receivable' AND l.reconcile_id is NULL AND - l.partner_id IS NOT NULL AND - (l.blocked = False) + l.partner_id IS NOT NULL GROUP BY l.partner_id, l.company_id - )""") #Blocked is to take into account litigation + )""") class account_followup_sending_results(osv.osv_memory): diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml index 4674d62b6a0..41d3c6fc1f6 100644 --- a/addons/account_voucher/account_voucher_view.xml +++ b/addons/account_voucher/account_voucher_view.xml @@ -130,7 +130,7 @@ - + diff --git a/addons/account_voucher/voucher_payment_receipt_view.xml b/addons/account_voucher/voucher_payment_receipt_view.xml index 5d259772363..1169d5ef7c3 100644 --- a/addons/account_voucher/voucher_payment_receipt_view.xml +++ b/addons/account_voucher/voucher_payment_receipt_view.xml @@ -12,7 +12,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/addons/account_voucher/voucher_sales_purchase_view.xml b/addons/account_voucher/voucher_sales_purchase_view.xml index dc732129803..e35061e1836 100644 --- a/addons/account_voucher/voucher_sales_purchase_view.xml +++ b/addons/account_voucher/voucher_sales_purchase_view.xml @@ -11,7 +11,7 @@ - + @@ -33,7 +33,7 @@ - + diff --git a/addons/auth_signup/auth_signup_data.xml b/addons/auth_signup/auth_signup_data.xml index 31e3b61a9f6..1b4e3e05502 100644 --- a/addons/auth_signup/auth_signup_data.xml +++ b/addons/auth_signup/auth_signup_data.xml @@ -22,7 +22,7 @@ Reset Password - ]]> + ]]> ${object.email} Password reset OpenERP Enterprise Connection - ]]> + ]]> ${object.email} diff --git a/addons/base_action_rule/base_action_rule.py b/addons/base_action_rule/base_action_rule.py index 3497255fa76..59d61ba5b67 100644 --- a/addons/base_action_rule/base_action_rule.py +++ b/addons/base_action_rule/base_action_rule.py @@ -63,7 +63,10 @@ class base_action_rule(osv.osv): 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of rules."), 'kind': fields.selection( - [('on_create', 'On Creation'), ('on_write', 'On Update'), ('on_time', 'Based on Timed Condition')], + [('on_create', 'On Creation'), + ('on_write', 'On Update'), + ('on_create_or_write', 'On Creation & Update'), + ('on_time', 'Based on Timed Condition')], string='When to Run'), 'trg_date_id': fields.many2one('ir.model.fields', string='Trigger Date', help="When should the condition be triggered. If present, will be checked by the scheduler. If empty, will be checked at creation and update.", @@ -97,9 +100,9 @@ class base_action_rule(osv.osv): def onchange_kind(self, cr, uid, ids, kind, context=None): clear_fields = [] - if kind == 'on_create': + if kind in ['on_create', 'on_create_or_write']: clear_fields = ['filter_pre_id', 'trg_date_id', 'trg_date_range', 'trg_date_range_type'] - elif kind == 'on_write': + elif kind in ['on_write', 'on_create_or_write']: clear_fields = ['trg_date_id', 'trg_date_range', 'trg_date_range_type'] elif kind == 'on_time': clear_fields = ['filter_pre_id'] @@ -156,7 +159,7 @@ class base_action_rule(osv.osv): new_id = old_create(cr, uid, vals, context=context) # retrieve the action rules to run on creation - action_dom = [('model', '=', model), ('kind', '=', 'on_create')] + action_dom = [('model', '=', model), ('kind', 'in', ['on_create', 'on_create_or_write'])] action_ids = self.search(cr, uid, action_dom, context=context) # check postconditions, and execute actions on the records that satisfy them @@ -180,7 +183,7 @@ class base_action_rule(osv.osv): ids = [ids] if isinstance(ids, (int, long, str)) else ids # retrieve the action rules to run on update - action_dom = [('model', '=', model), ('kind', '=', 'on_write')] + action_dom = [('model', '=', model), ('kind', 'in', ['on_write', 'on_create_or_write'])] action_ids = self.search(cr, uid, action_dom, context=context) actions = self.browse(cr, uid, action_ids, context=context) diff --git a/addons/crm/base_partner_merge.py b/addons/crm/base_partner_merge.py index 42e1ab7c7ec..c73b5fdf599 100644 --- a/addons/crm/base_partner_merge.py +++ b/addons/crm/base_partner_merge.py @@ -235,9 +235,12 @@ class MergePartnerAutomatic(osv.TransientModel): record_ids = proxy.search(cr, openerp.SUPERUSER_ID, domain, context=context) for record in proxy.browse(cr, openerp.SUPERUSER_ID, record_ids, context=context): - proxy_model = self.pool[record.model] - - field_type = proxy_model._columns.get(record.name).__class__._type + try: + proxy_model = self.pool[record.model] + field_type = proxy_model._columns[record.name].__class__._type + except KeyError: + # unknown model or field => skip + continue if field_type == 'function': continue diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py index bb080a95399..c580fd728e2 100644 --- a/addons/crm/crm_lead.py +++ b/addons/crm/crm_lead.py @@ -352,10 +352,14 @@ class crm_lead(format_address, osv.osv): """ if isinstance(cases, (int, long)): cases = self.browse(cr, uid, cases, context=context) + if context is None: + context = {} + # check whether we should try to add a condition on type + avoid_add_type_term = any([term for term in domain if len(term) == 3 if term[0] == 'type']) # collect all section_ids section_ids = set() types = ['both'] - if not cases: + if not cases and context.get('default_type'): ctx_type = context.get('default_type') types += [ctx_type] if section_id: @@ -373,7 +377,8 @@ class crm_lead(format_address, osv.osv): search_domain.append(('section_ids', '=', section_id)) search_domain.append(('case_default', '=', True)) # AND with cases types - search_domain.append(('type', 'in', types)) + if not avoid_add_type_term: + search_domain.append(('type', 'in', types)) # AND with the domain in parameter search_domain += list(domain) # perform search, return the first found @@ -607,10 +612,12 @@ class crm_lead(format_address, osv.osv): opportunities = self.browse(cr, uid, ids, context=context) sequenced_opps = [] + # Sorting the leads/opps according to the confidence level of its stage, which relates to the probability of winning it + # The confidence level increases with the stage sequence, except when the stage probability is 0.0 (Lost cases) + # An Opportunity always has higher confidence level than a lead, unless its stage probability is 0.0 for opportunity in opportunities: sequence = -1 - # TDE: was "if opportunity.stage_id and opportunity.stage_id.state != 'cancel':" - if opportunity.probability == 0 and opportunity.stage_id and opportunity.stage_id.sequence != 1 and opportunity.stage_id.fold: + if opportunity.stage_id and (opportunity.stage_id.probability != 0 or opportunity.stage_id.sequence == 1): sequence = opportunity.stage_id.sequence sequenced_opps.append(((int(sequence != -1 and opportunity.type == 'opportunity'), sequence, -opportunity.id), opportunity)) diff --git a/addons/crm_partner_assign/crm_lead_view.xml b/addons/crm_partner_assign/crm_lead_view.xml index 3b253b1c3d4..7550396e886 100644 --- a/addons/crm_partner_assign/crm_lead_view.xml +++ b/addons/crm_partner_assign/crm_lead_view.xml @@ -8,7 +8,7 @@ - + @@ -145,6 +149,10 @@ +
+ + +
diff --git a/addons/crm_partner_assign/res_partner_view.xml b/addons/crm_partner_assign/res_partner_view.xml index 6823c262f02..734d5a31e95 100644 --- a/addons/crm_partner_assign/res_partner_view.xml +++ b/addons/crm_partner_assign/res_partner_view.xml @@ -138,6 +138,7 @@ + + icon="gtk-convert" + attrs="{'invisible':[('type','=','opportunity')]}" />