diff --git a/MetaAnalytic.py b/MetaAnalytic.py index d15ef62b9568eb1d0658e9d2e5927d781ab37c0f_TWV0YUFuYWx5dGljLnB5..9becded7f7472d77e31194e2e22d1a34ad26fad1_TWV0YUFuYWx5dGljLnB5 100644 --- a/MetaAnalytic.py +++ b/MetaAnalytic.py @@ -102,7 +102,8 @@ "Generated Analytic Field", domain=[ (domain_field, '=', model_name), - ('usable', '=', True) + ('usable', '=', True), + ('usable_per_company', '=', True), ], track_visibility='onchange', ) diff --git a/README b/README index d15ef62b9568eb1d0658e9d2e5927d781ab37c0f_UkVBRE1F..9becded7f7472d77e31194e2e22d1a34ad26fad1_UkVBRE1F 100644 --- a/README +++ b/README @@ -166,3 +166,19 @@ name_get and name_search, using those of analytic code. This allows the analytic code's description to be displayed (and searched) along with the entry's name in many2one fields targeting the model. + + + +=== Active / Usable / Usable in my company === + + +Differences between the various "active" fields: + +- Active: Controls whether the code is in the referential; when inactive, a +code is invisible. + +- Usable: Controls whether the code can be selected; unlike "active", it is +still in the referential. + +- Usable per company: Controls whether the code can be selected by users in the +company of the current user; unlike "active", it is still in the referential. diff --git a/analytic_code.py b/analytic_code.py index d15ef62b9568eb1d0658e9d2e5927d781ab37c0f_YW5hbHl0aWNfY29kZS5weQ==..9becded7f7472d77e31194e2e22d1a34ad26fad1_YW5hbHl0aWNfY29kZS5weQ== 100644 --- a/analytic_code.py +++ b/analytic_code.py @@ -31,6 +31,77 @@ _parent_order = 'name' _order = 'parent_left' + def _read_usable_per_company( + self, cr, uid, ids, field_name, arg, context + ): + """Mark the code as usable when it is not in the blacklist (depending + on the current user's company). + """ + + anc_obj = self.pool['analytic.code'] + user_obj = self.pool['res.users'] + + company_id = user_obj.read( + cr, uid, [uid], ['company_id'], context=context + )[0]['company_id'][0] + + ret = {} + + for anc in anc_obj.browse(cr, uid, ids, context=context): + blacklist = (company.id for company in anc.blacklist_ids) + ret[anc.id] = company_id not in blacklist + + return ret + + def _write_usable_per_company( + self, cr, uid, anc_id, field_name, field_value, arg, context + ): + """Update the blacklist depending on the current user's company. + """ + + anc_obj = self.pool['analytic.code'] + user_obj = self.pool['res.users'] + + company_id = user_obj.read( + cr, uid, [uid], ['company_id'], context=context + )[0]['company_id'][0] + + anc = anc_obj.browse(cr, uid, anc_id, context=context) + blacklist = (company.id for company in anc.blacklist_ids) + + to_write = None + if field_value and company_id in blacklist: + to_write = [(3, company_id)] # Unlink. + elif not field_value and company_id not in blacklist: + to_write = [(4, company_id)] # Link. + + if to_write: + anc_obj.write( + cr, uid, [anc_id], {'blacklist_ids': to_write}, context=context + ) + + return True + + def _search_usable_per_company( + self, cr, uid, model_again, field_name, criterion, context + ): + """Update the domain to take the blacklist into account (depending on + the current user's company). + """ + + user_obj = self.pool['res.users'] + + company_id = user_obj.read( + cr, uid, [uid], ['company_id'], context=context + )[0]['company_id'][0] + + # We assume the criterion was "usable_per_company = True". + return [ + '|', + ('blacklist_ids', '=', False), + ('blacklist_ids.id', '!=', company_id), + ] + _columns = { 'name': fields.char( u"Name", @@ -46,6 +117,23 @@ ), 'active': fields.boolean(u"Active"), 'usable': fields.boolean(u"Usable"), + 'blacklist_ids': fields.many2many( + 'res.company', + 'analytic_code_company_rel', + 'code_id', + 'company_id', + u"Blacklist", + help=u"Companies the code is hidden in.", + ), + 'usable_per_company': fields.function( + _read_usable_per_company, + fnct_inv=_write_usable_per_company, + fnct_search=_search_usable_per_company, + method=True, + type='boolean', + store=False, # Not persistent as it dpeends on the company. + string=u"Usable in my company", + ), 'nd_name': fields.related( 'nd_id', 'name', @@ -74,8 +162,9 @@ } _defaults = { - 'active': 1, - 'usable': 1, + 'active': lambda *a: True, + 'usable': lambda *a: True, + 'usable_per_company': lambda *a: True, } _constraints = [ diff --git a/analytic_structure.py b/analytic_structure.py index d15ef62b9568eb1d0658e9d2e5927d781ab37c0f_YW5hbHl0aWNfc3RydWN0dXJlLnB5..9becded7f7472d77e31194e2e22d1a34ad26fad1_YW5hbHl0aWNfc3RydWN0dXJlLnB5 100644 --- a/analytic_structure.py +++ b/analytic_structure.py @@ -82,7 +82,7 @@ } _defaults = { - 'company_id': False, + 'company_id': lambda *a: False, } _constraints = [ diff --git a/analytic_views.xml b/analytic_views.xml index d15ef62b9568eb1d0658e9d2e5927d781ab37c0f_YW5hbHl0aWNfdmlld3MueG1s..9becded7f7472d77e31194e2e22d1a34ad26fad1_YW5hbHl0aWNfdmlld3MueG1s 100644 --- a/analytic_views.xml +++ b/analytic_views.xml @@ -29,7 +29,7 @@ <field name="model">analytic.code</field> <field name="arch" type="xml"> - <tree string="Analytic Codes" version="7.0" editable="bottom"> + <tree string="Analytic Codes" version="7.0"> <field name="id" invisible="1" /> <field name="active" /> <field name="usable" /> @@ -33,6 +33,7 @@ <field name="id" invisible="1" /> <field name="active" /> <field name="usable" /> + <field name="usable_per_company" /> <field name="name" /> <field name="description" /> <field name="nd_id" @@ -52,16 +53,30 @@ <field name="model">analytic.code</field> <field name="arch" type="xml"> <form string="Analytic Code"> - <field name="id" invisible="1" /> - <field name="active" /> - <field name="usable" /> - <field name="name" /> - <field name="description" /> - <field name="nd_id" - invisible="context.get('default_nd_id', None) is not None" - required="context.get('default_nd_id', None) is not False" /> - <field name="code_parent_id" attrs="{'readonly': [('nd_id', '=', False)]}" - domain="[('id', '!=', id), ('nd_id', '=', nd_id)]" /> + <group> + <field name="id" invisible="1" /> + + <group> + <field name="name" /> + <field name="description" /> + <field name="nd_id" + invisible="context.get('default_nd_id', None) is not None" + required="context.get('default_nd_id', None) is not False" /> + <field name="code_parent_id" + attrs="{'readonly': [('nd_id', '=', False)]}" + domain="[('id', '!=', id), ('nd_id', '=', nd_id)]" /> + </group> + + <group> + <field name="active" /> + <field name="usable" /> + <field name="usable_per_company" /> + </group> + + <group colspan="2"> + <field name="blacklist_ids" groups="base.group_multi_company" /> + </group> + </group> </form> </field> </record>