# HG changeset patch
# User Jérémie Gavrel <jeremie.gavrel@xcg-consulting.fr>
# Date 1403600936 -7200
#      Tue Jun 24 11:08:56 2014 +0200
# Node ID 13a4690448202115041f689769ec0821ee1981f0
# Parent  6078d7eb15f01fddd90149339de1c3216ff78e20
Structures can now be restricted to one company. Bound dimensions: added the code_ref_ids (and code_ref_module) options to generate external IDs for all analytic codes of the dimension.

diff --git a/MetaAnalytic.py b/MetaAnalytic.py
--- a/MetaAnalytic.py
+++ b/MetaAnalytic.py
@@ -209,6 +209,12 @@
 
         use_code_name_methods = dimension.get('use_code_name_methods', False)
 
+        code_ref_ids = dimension.get('code_ref_ids', False)
+        if code_ref_ids is True:
+            code_ref_ids = ref_id
+
+        code_ref_module = dimension.get('code_ref_module', '')
+
         if use_inherits:
             inherits = nmspc.get('_inherits', {})
             inherits['analytic.code'] = column
@@ -276,7 +282,7 @@
 
             super(superclass, self).__init__(pool, cr)
 
-            data_osv = self.pool.get('ir.model.data')
+            data_osv = self.pool['ir.model.data']
             try:
                 self._bound_dimension_id = data_osv.get_object_reference(
                     cr, SUPERUSER_ID, ref_module, ref_id
@@ -288,14 +294,43 @@
                     xml_id=ref_id, noupdate=True
                 )
 
+        if code_ref_ids:
+            prefix = config.get_misc('analytic', 'code_ref_prefix', False)
+
+            # This function is called as a method and can be overridden.
+            @AddMethod(superclass)
+            def _generate_code_ref_id(self, cr, uid, ids, context=None):
+                data_osv = self.pool['ir.model.data']
+                records = self.browse(cr, uid, ids, context=None)
+                if not isinstance(records, list):
+                    records = [records]
+
+                for record in records:
+                    code = record[column]
+                    code_ref_id_builder = [prefix] if prefix else []
+                    if 'company_id' in record and record.company_id:
+                        code_ref_id_builder.append(record.company_id.code)
+                    code_ref_id_builder.append('ANC')
+                    code_ref_id_builder.append(code_ref_ids)
+                    code_ref_id_builder.append(code.name)
+
+                    vals = {
+                        'name': "_".join(code_ref_id_builder),
+                        'module': code_ref_module,
+                        'model': 'analytic.code',
+                        'res_id': code.id,
+                    }
+                    data_osv.create(cr, uid, vals, context=context)
+
         @AddMethod(superclass)
         def create(self, cr, uid, vals, context=None):
             """Create the analytic code."""
 
-            code_vals = {
-                'nd_id': self._bound_dimension_id,
-                'name': vals.get(rel_name[1] if rel_name else 'name'),
-            }
+            code_vals = {'nd_id': self._bound_dimension_id}
+            if use_inherits:
+                code_vals.update(vals)
+            else:
+                code_vals['name'] = vals.get('name')
             if sync_parent:
                 cp = self._get_code_parent(cr, uid, vals, context=context)
                 if cp is not None:
@@ -309,17 +344,20 @@
                 elif model_col in self._defaults:
                     code_vals[code_col] = self._defaults[model_col]
 
-            if use_inherits:
-                vals.update(code_vals)
-            else:
-                code_osv = self.pool.get('analytic.code')
-                code_id = code_osv.create(cr, uid, code_vals, context=context)
-                vals[column] = code_id
+            # We also have to create the code separately, even with inherits.
+            code_osv = self.pool.get('analytic.code')
+            code_id = code_osv.create(cr, uid, code_vals, context=context)
+            vals[column] = code_id
 
-            return super(superclass, self).create(
+            res = super(superclass, self).create(
                 cr, uid, vals, context=context
             )
 
+            if code_ref_ids:
+                self._generate_code_ref_id(cr, uid, res, context=context)
+
+            return res
+
         if sync_parent:
             # This function is called as a method and can be overridden.
             @AddMethod(superclass)
@@ -407,6 +445,7 @@
             ):
                 """Return the records whose analytic code matches the name."""
 
+                print self._name
                 code_osv = self.pool.get('analytic.code')
                 args.append(('nd_id', '=', self._bound_dimension_id))
                 names = code_osv.name_search(
diff --git a/README b/README
--- a/README
+++ b/README
@@ -87,7 +87,7 @@
 
 <field name="order_line" colspan="4" nolabel="1" context="{
     'form_view_ref' : 'module.view_id',
-    'tree_view_ref' : 'model.view_id'
+    'tree_view_ref' : 'module.view_id'
 }"/>
 
 
diff --git a/analytic_dimension.xml b/analytic_dimension.xml
--- a/analytic_dimension.xml
+++ b/analytic_dimension.xml
@@ -114,6 +114,8 @@
                         <field name="nd_id"/>
                         <newline />
                         <field name="ordering"/>
+                        <newline />
+                        <field name="company_id" placeholder="All" />
                     </group>
                 </form>
             </field>
diff --git a/analytic_structure.py b/analytic_structure.py
--- a/analytic_structure.py
+++ b/analytic_structure.py
@@ -41,6 +41,21 @@
             setattr(self, '_order_selection', order_selection)
         return order_selection
 
+    def _check_unique_ordering_no_company(self, cr, uid, ids, context=None):
+        columns = ['company_id', 'model_name', 'ordering']
+        structures = self.read(cr, uid, ids, columns, context=context)
+        for structure in structures:
+            if structure['company_id']:
+                continue    # Already checked by the SQL constraint.
+            domain = [
+                ('model_name', '=', structure['model_name']),
+                ('ordering', '=', structure['ordering']),
+            ]
+            count = self.search(cr, uid, domain, count=True, context=context)
+            if count > 1:
+                return False
+        return True
+
     _columns = dict(
         model_name=fields.char("Object", size=128, required=True, select="1"),
         nd_id=fields.many2one(
@@ -55,13 +70,30 @@
             'Analysis slot',
             required=True
         ),
+        company_id=fields.many2one(
+            'res.company',
+            'Company'
+        ),
     )
 
+    _defaults = {
+        'company_id': False,
+    }
+
+    _constraints = [
+        (
+            _check_unique_ordering_no_company,
+            u"One dimension per Analysis slot per object when the structure "
+            u"is common to all companies.",
+            ['company_id', 'model_name', 'ordering']
+        )
+    ]
+
     _sql_constraints = [
         (
             'unique_ordering',
-            'unique(model_name,ordering)',
-            'One dimension per Analysis slot per object'
+            'unique(company_id,model_name,ordering)',
+            u"One dimension per Analysis slot per object per company."
         ),
     ]
 
diff --git a/security/record_rules.xml b/security/record_rules.xml
--- a/security/record_rules.xml
+++ b/security/record_rules.xml
@@ -5,5 +5,12 @@
             <field name="name"> Manage analytic structure</field>
             <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
         </record>
+        <record id="analytic_structure_comp_rule" model="ir.rule">
+            <field name="name">Analytic Structure</field>
+            <field name="model_id" ref="model_analytic_structure"/>
+            <field name="global" eval="True"/>
+            <field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
+        </record>
     </data>
+
 </openerp>