← Back to team overview

openerp-community team mailing list archive

[Merge] lp:~ajite/openobject-addons/elico-7.0-imp-intercompany-000001 into lp:~openerp-community/openobject-addons/elico-7.0

 

Augustin Cisterne-Kaas - www.elico-corp.com has proposed merging lp:~ajite/openobject-addons/elico-7.0-imp-intercompany-000001 into lp:~openerp-community/openobject-addons/elico-7.0.

Requested reviews:
  LIN Yu (lin-yu)

For more details, see:
https://code.launchpad.net/~ajite/openobject-addons/elico-7.0-imp-intercompany-000001/+merge/202396

Improved intercompany modules using the connector.
-- 
https://code.launchpad.net/~ajite/openobject-addons/elico-7.0-imp-intercompany-000001/+merge/202396
Your team OpenERP Community is subscribed to branch lp:~openerp-community/openobject-addons/elico-7.0.
=== added directory 'base_intercompany'
=== removed directory 'base_intercompany'
=== added file 'base_intercompany/__init__.py'
--- base_intercompany/__init__.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/__init__.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import connector
+import consumer
+import backend
+import company
+import icops_model

=== removed file 'base_intercompany/__init__.py'
--- base_intercompany/__init__.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Augustin Cisterne-Kaas <augustin.cisterne-kaaas@xxxxxxxxxxxxxx>
-#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-import company
-import sale
-import purchase
-# import stock_picking
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'base_intercompany/__openerp__.py'
--- base_intercompany/__openerp__.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/__openerp__.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{'name': 'Base Intercompany',
+ 'version': '0.3',
+ 'category': '',
+ 'depends': ['connector'],
+ 'author': 'Elico Corp',
+ 'license': 'AGPL-3',
+ 'website': 'https://www.elico-corp.com',
+ 'description': """
+
+""",
+ 'images': [],
+ 'demo': ['base_intercompany_demo.xml'],
+ 'data': ['security/base_intercompany_security.xml',
+          'security/ir.model.access.csv',
+          'icops_model_view.xml',
+          'base_intercompany_menu.xml'],
+ 'installable': True,
+ 'application': False,
+ }

=== removed file 'base_intercompany/__openerp__.py'
--- base_intercompany/__openerp__.py	2013-11-29 06:49:52 +0000
+++ base_intercompany/__openerp__.py	1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Augustin Cisterne-Kaas <augustin.cisterne-kaaas@xxxxxxxxxxxxxx>
-#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-{
-    'name': 'Base Inter-Company',
-    'version': '1.0',
-    'author': 'Elico Corp',
-    'website': 'http://www.elico-corp.com',
-    'summary': '',
-    'description': """
-Inter-Company Processing (ICOPS)
-This module is designed to manage Inter-company Process (ICOPS) and allow 2 companies to create objects in each other:
-- When a PO to company B is created in company A, it creates automatically a SO in company B
-- When a SO to company B is created in company A, it creates automatically a PO in company B
-- Update PO from/to SO
-- Confirm SO for PO and vice versa
-- It is generic enough to allow intercompany process companies in cascade
-- it can be uni-directional/bi-directional (eg SO in company A creates PO in company B and when the PO is validated in company B it validate the SO in company A).
-
-Works fine with SO/PO
-Under construction: Sales invoice/Purchase invoice and Stock Moves
-Blueprint: https://blueprints.launchpad.net/multi-company/+spec/icops
-
-
-    """,
-    'depends': ['base', 'sale', 'stock',
-                'sale_stock', 'purchase', 'account_cancel',
-                'multi_company', ],
-    'category': 'Sale',
-    'sequence': 10,
-    'demo': ['base_intercompany_demo.xml'],
-    'data': [
-        'company_view.xml',
-        'sale_wkf.xml',
-        'purchase_wkf.xml',
-        #'stock_picking_wkf.xml',
-        'security/intercompany_security.xml',
-        'security/ir.model.access.csv'],
-    'test': [],
-    'installable': True,
-    'application': False,
-    'auto_install': False,
-    'css': [],
-}
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'base_intercompany/backend.py'
--- base_intercompany/backend.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/backend.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import openerp.addons.connector.backend as backend
+
+
+icops = backend.Backend('icops')
+""" Generic ICOPS Backend """
+
+icops7 = backend.Backend(parent=icops, version='7.0')
+""" ICOPS Backend for OpenERP 7 """

=== added file 'base_intercompany/base_intercompany_demo.xml'
--- base_intercompany/base_intercompany_demo.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany/base_intercompany_demo.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+        <record id="customer_origin" model="res.partner">
+            <field name="name">Company Origin</field>
+        </record>
+
+        <record id="supplier_destination" model="res.partner">
+            <field name="name">Company Destination</field>
+            <field name="supplier" eval="True" />
+        </record>
+
+        <record id="company_origin" model="res.company">
+            <field name="name">Company Origin</field>
+            <field name="parent_id" ref="base.main_company"/>
+            <field name="partner_id" ref="customer_origin" />
+        </record>
+
+        <record id="company_destination" model="res.company">
+            <field name="name">Company Destination</field>
+            <field name="parent_id" ref="base.main_company"/>
+            <field name="partner_id" ref="supplier_destination" />
+        </record>
+
+        <record id="customer_origin" model="res.partner">
+            <field name="company_id"></field>
+        </record>
+
+        <record id="supplier_destination" model="res.partner">
+            <field name="company_id"></field>
+        </record>
+
+        <record id="partner_origin" model="res.partner">
+            <field name="name">User Origin</field>
+            <field name="company_id" ref="company_origin"/>
+            <field name="customer" eval="False"/>
+        </record>
+
+        <record id="user_origin" model="res.users">
+            <field name="partner_id" ref="partner_origin"/>
+            <field name="login">user.origin</field>
+            <field name="password">user.origin</field>
+            <field name="company_id" ref="company_origin"/>
+            <field name="company_ids" eval="[(6,0,[ref('company_origin')])]" />
+            <field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager')])]"/>
+        </record>
+
+        <record id="partner_destination" model="res.partner">
+            <field name="name">User Destination</field>
+            <field name="company_id" ref="company_destination"/>
+            <field name="customer" eval="False"/>
+        </record>
+
+        <record id="user_destination" model="res.users">
+            <field name="partner_id" ref="partner_destination"/>
+            <field name="login">user.destination</field>
+            <field name="password">user.destination</field>
+            <field name="company_id" ref="company_destination"/>
+            <field name="company_ids" eval="[(6,0,[ref('company_destination')])]" />
+            <field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager')])]"/>
+        </record>
+        
+        <!-- ICOPS Setup -->
+        <record id="backend_origin" model="icops.backend">
+            <field name="name">Backend Origin</field>
+            <field name="company_id" ref="company_origin" />
+            <field name="icops_uid" ref="user_origin" />
+        </record>
+
+        <record id="backend_destination" model="icops.backend">
+            <field name="name">Backend Destination</field>
+            <field name="company_id" ref="company_destination" />
+            <field name="icops_uid" ref="user_destination" />
+        </record>
+    </data>
+</openerp>
\ No newline at end of file

=== removed file 'base_intercompany/base_intercompany_demo.xml'
--- base_intercompany/base_intercompany_demo.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/base_intercompany_demo.xml	1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-    <data noupdate="0">
-        <record id="partner_icops1" model="res.partner">
-            <field name="name">ICOPS User 1</field>
-            <field name="company_id" ref="base.main_company"/>
-            <field name="customer" eval="False"/>
-            <field name="email">icops1@xxxxxxxxxxx</field>
-        </record>
-
-        <record id="user_icops1" model="res.users">
-            <field name="partner_id" ref="partner_icops1"/>
-            <field name="login">icops1</field>
-            <field name="password">icops1</field>
-            <field name="signature">--
-Mr Icops 1</field>
-            <field name="company_id" ref="base.main_company"/>
-            <field name="company_ids" eval="[(6,0,[ref('base.main_company')])]" />
-            <field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager'), ref('base.group_sale_manager'), ref('purchase.group_purchase_manager'), ref('group_intercompany_user')])]"/>
-        </record>
-        <record id="partner_icops2" model="res.partner">
-            <field name="name">ICOPS User 2</field>
-            <field name="company_id" ref="multi_company.res_company_oerp_be"/>
-            <field name="customer" eval="False"/>
-            <field name="email">icops2@xxxxxxxxxxx</field>
-        </record>
-
-        <record id="user_icops2" model="res.users">
-            <field name="partner_id" ref="partner_icops2"/>
-            <field name="login">icops2</field>
-            <field name="password">icops2</field>
-            <field name="signature">--
-Mr Icops 2</field>
-            <field name="company_id" ref="multi_company.res_company_oerp_be"/>
-            <field name="company_ids" eval="[(6,0,[ref('multi_company.res_company_oerp_be')])]" />
-            <field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('base.group_partner_manager'), ref('base.group_sale_manager'), ref('purchase.group_purchase_manager'), ref('group_intercompany_user')])]"/>
-        </record>
-        <record id="stock_location_shop_icops_1" model="stock.location">
-            <field model="res.partner" name="partner_id" ref="partner_icops1" />
-            <field name="company_id" ref="base.main_company"/>
-            <field name="location_id" ref="stock.stock_location_locations"/>
-            <field name="usage">internal</field>
-            <field eval="1" name="active"/>
-            <field name="name">Icops 1 shop</field>
-        </record>
-        <record id="stock_warehouse_shop_icops_1" model="stock.warehouse">
-                    <field name="lot_output_id" ref="stock_location_shop_icops_1"/>
-                    <field name="name">Icops 1 Warehouse</field>
-                    <field name="lot_stock_id" ref="stock_location_shop_icops_1"/>
-                    <field model="res.partner" name="partner_id" ref="partner_icops1" />
-                    <field name="company_id" ref="base.main_company"/>
-                    <field name="lot_input_id" ref="stock_location_shop_icops_1"/>
-        </record>
-        <record id="sale_shop_icops_1" model="sale.shop">
-            <field name="name">Icops 1 sale shop</field>
-            <field model="account.payment.term" name="payment_default_id" search="[]"/>
-            <field name="warehouse_id" ref="stock_warehouse_shop_icops_1"/>
-        </record>
-        <record id="stock_location_shop_icops_2" model="stock.location">
-            <field model="res.partner" name="partner_id" ref="partner_icops2" />
-            <field name="company_id" ref="multi_company.res_company_oerp_be"/>
-            <field name="location_id" ref="stock.stock_location_locations"/>
-            <field name="usage">internal</field>
-            <field eval="1" name="active"/>
-            <field name="name">Icops 2 shop</field>
-        </record>
-        <record id="stock_warehouse_shop_icops_2" model="stock.warehouse">
-                    <field name="lot_output_id" ref="stock_location_shop_icops_2"/>
-                    <field name="name">Icops 2 Warehouse</field>
-                    <field name="lot_stock_id" ref="stock_location_shop_icops_2"/>
-                    <field model="res.partner" name="partner_id" ref="partner_icops2" />
-                    <field name="company_id" ref="multi_company.res_company_oerp_be"/>
-                    <field name="lot_input_id" ref="stock_location_shop_icops_2"/>
-        </record>
-        <record id="sale_shop_icops_2" model="sale.shop">
-            <field name="name">Icops 2 sale shop</field>
-            <field model="account.payment.term" name="payment_default_id" search="[]"/>
-            <field name="warehouse_id" ref="stock_warehouse_shop_icops_2"/>
-        </record>
-    </data>
-</openerp>
\ No newline at end of file

=== added file 'base_intercompany/base_intercompany_menu.xml'
--- base_intercompany/base_intercompany_menu.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany/base_intercompany_menu.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+  <data>
+    <menuitem id="menu_icops_root"
+        parent="connector.menu_connector_root"
+        name="ICOPS"
+        sequence="10"
+        groups="connector.group_connector_manager"/>
+
+    <menuitem id="menu_icops_backend"
+        name="Backends"
+        parent="menu_icops_root"
+        action="action_icops_backend"/>
+
+    <menuitem id="menu_server_root"
+        parent="connector.menu_connector_root"
+        name="Server"
+        sequence="20"
+        groups="connector.group_connector_manager"/>
+
+  </data>
+</openerp>

=== added file 'base_intercompany/company.py'
--- base_intercompany/company.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/company.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,142 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+
+
+class res_intercompany(orm.Model):
+    _name = 'res.intercompany'
+    _description = 'Inter-Company'
+
+    def _select_concepts(self, cr, uid, context=None):
+        """ Available concepts
+
+        Can be inherited to add custom versions.
+        """
+        return []
+
+    def _select_object_names(self, cr, uid, context=None):
+        """ Available Object names
+
+        Can be inherited to add custom versions.
+        """
+        return {}
+
+    def _get_object_name(self, cr, uid, ids, name, arg, context=None):
+        """ Available versions
+
+        Can be inherited to add custom versions.
+        """
+        res = {}
+        for intercompany in self.browse(cr, uid, ids, context):
+            object_name = None
+            if intercompany.concept:
+                object_name = self._select_object_names(
+                    cr, uid)[intercompany.concept]
+            res[intercompany.id] = object_name
+        return res
+
+    def get_intercompany(self, cr, uid, obj_id,
+                         obj_class_name, obj_name, context=None):
+        """
+        get company from and to
+        """
+        if isinstance(obj_id, list):
+            obj_id = obj_id[0]
+        assert isinstance(obj_id, int) or isinstance(obj_id, long)
+        obj = self.pool.get(obj_class_name).browse(
+            cr,
+            uid,
+            obj_id,
+            context=None)
+        company = obj.company_id
+        ic_uid_ids = None
+        company_to_ids = []
+        for ic in company.intercompany_ids:
+            if ic.concept == obj_name:
+                company_to_ids.append(ic.company_to.id)
+                ic_uid_ids = ic.icops_uid.id
+        if company.intercompany_ids:
+            ic_uid_ids = company.intercompany_ids[0].icops_uid.id
+        return obj.company_id.id, company_to_ids, ic_uid_ids
+
+    def _check_intercompany_user(self, cr, uid, ids, context=None):
+        for ic in self.browse(cr, uid, ids, context=context):
+            if not ic.icops_uid:
+                return False
+        return True
+
+    _columns = {
+        'backend_id': fields.many2one('icops.backend', 'Original Backend',
+                                      required=True, ondelete='cascade'),
+        'backend_to': fields.many2one('icops.backend', 'Destination Backend',
+                                      required=True, ondelete='cascade'),
+        'concept': fields.selection(_select_concepts, string="Concept",
+                                    required=True),
+        'object_name': fields.function(_get_object_name, type='char',
+                                       string='Object', store=False),
+        'icops_uid': fields.related(
+            'backend_to', 'icops_uid', type='many2one',
+            relation='res.users', readonly=True, string='IC User'),
+        'on_create': fields.boolean('Create'),
+        'on_write': fields.boolean('Update'),
+        'on_unlink': fields.boolean('Delete'),
+        'on_confirm': fields.boolean('Confirm'),
+        'on_cancel': fields.boolean('Cancel')
+    }
+
+    _constraints = [
+        (_check_intercompany_user, 'Please set IC user for the Company first',
+            ['icops_uid'])
+    ]
+
+    _defaults = {
+        'backend_id': lambda self, cr, uid, c: c.get('active_id', False),
+    }
+    # _sql_constraints = [(
+    #     'company_from_company_to_unique', 'unique(company_from, company_to)',
+    #     'A setup for that company already exists')]
+
+    def check_need_create_intercompany_object(
+            self, cr, uid, company_from, company_to, concept,
+            event, return_list_type=False, regular=False):
+        """ @company_from
+            @company_to
+            @o2o_field_name  file name.Example, so2po po2so ,,,,
+            @node  value of  o2o_field_name ,  draft, confirm
+            @return_list_type,  the return type is list or boolean
+        """
+
+        if type(company_to) != list:
+            company_to = [company_to]
+        request = [('company_from', '=', company_from),
+                   ('concept', '=', concept),
+                   (event, '=', True)]
+        if not regular:
+            request.append(('company_to', 'in', company_to))
+        intercompany_ids = self.search(
+            cr, uid, request)
+        if return_list_type:
+            return intercompany_ids
+        else:
+            return intercompany_ids and True or False

=== removed file 'base_intercompany/company.py'
--- base_intercompany/company.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/company.py	1970-01-01 00:00:00 +0000
@@ -1,154 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Augustin Cisterne-Kaas <augustin.cisterne-kaaas@xxxxxxxxxxxxxx>
-#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from openerp.osv import orm, fields
-
-
-class res_intercompany(orm.Model):
-    _name = "res.intercompany"
-    _description = "Inter-Company"
-
-    def get_intercompany(self, cr, uid, obj_id,
-                         obj_class_name, obj_name, context=None):
-        """
-        get company from and to
-        """
-
-        assert isinstance(obj_id, int) or isinstance(obj_id, long)
-        obj = self.pool.get(obj_class_name).browse(
-            cr,
-            uid,
-            obj_id,
-            context=None)
-        company = obj.company_id
-        ic_uid_ids = None
-        company_to_ids = []
-        for ic in company.intercompany_ids:
-            if ic.obj2obj == obj_name:
-                company_to_ids.append(ic.company_to.id)
-                ic_uid_ids = ic.intercompany_uid.id
-        if company.intercompany_ids:
-            ic_uid_ids = company.intercompany_ids[0].intercompany_uid.id
-        return obj.company_id.id, company_to_ids, ic_uid_ids
-
-    def _check_intercompany_user(self, cr, uid, ids, context=None):
-        for ic in self.browse(cr, uid, ids, context=context):
-            if not ic.intercompany_uid:
-                return False
-        return True
-
-    _columns = {
-        'company_from': fields.many2one('res.company', 'Company From',
-                                        required=True, ondelete='cascade'),
-        'company_to': fields.many2one('res.company', 'Company', required=True,
-                                      ondelete='cascade'),
-        'obj2obj': fields.selection(
-            [('so2po', 'SO to PO'),
-             ('po2so', 'PO to SO'),
-             ('is2do', 'IS to DO'),
-             ('do2is', 'DO to IS'),
-             ('ci2si', 'CI to SI'),
-             ('si2ci', 'SI to CI')],
-            string="Relation", required=True),
-        'status': fields.selection(
-            [('draft', 'On Creation'),
-             ('confirm', 'On Confirmation'),
-             ('cancel', 'On Cancel'),
-             ('unlink', 'On Deletion')],
-            string='Status', required=True),
-        'direction': fields.selection(
-            [('bidirectional', 'Bidirectional'),
-             ('regular', 'Regular'),
-             ('inverse', 'Inverse')],
-            'Modification Direction', required=True),
-        'auto_confirm': fields.boolean('Automatic Confirm'),
-        'intercompany_uid': fields.related(
-            'company_to', 'intercompany_uid', type='many2one',
-            relation='res.users', readonly=True, string='IC User'),
-    }
-    _defaults = {
-        'auto_confirm': lambda *a: True,
-        'direction': lambda *a: 'bidirectional',
-    }
-
-    _constraints = [
-        (_check_intercompany_user, 'Please set IC user for the Company first',
-            ['intercompany_uid'])
-    ]
-
-    def check_need_create_intercompany_object(
-            self, cr, uid, company_from, company_to, o2o_field_name,
-            node=None, return_list_type=False):
-        """ @company_from
-            @company_to
-            @o2o_field_name  file name.Example, so2po po2so ,,,,
-            @node  value of  o2o_field_name ,  draft, confirm
-            @return_list_type,  the return type is list or boolean
-        """
-
-        if type(company_to) != list:
-            company_to = [company_to]
-
-        intercompany_ids = self.search(
-            cr, uid,
-            [('company_from', '=', company_from),
-             ('company_to', 'in', company_to),
-             ('obj2obj', '=', o2o_field_name),
-             ('status', '=', node)])
-        if return_list_type:
-            return intercompany_ids
-        else:
-            return intercompany_ids and True or False
-
-    def check_need_automatic_confirm(
-            self, cr, uid, company_from, company_to,
-            o2o_field_name, node=None, return_list_type=False):
-        """
-        check is need to automatic confirm internal company object
-        """
-        intercompany_ids = self.search(
-            cr, uid,
-            [('company_from', '=', company_from),
-             ('company_to', '=', company_to),
-             (o2o_field_name, '=', node),
-             ('auto_confirm', '=', True)])
-        return intercompany_ids and True or False
-
-
-class res_company(orm.Model):
-    _inherit = "res.company"
-
-    _columns = {
-        'intercompany_ids': fields.one2many(
-            'res.intercompany', 'company_from', 'Inter-Company Setup'),
-        'intercompany_uid': fields.many2one(
-            'res.users', 'IC User',
-            required=True,
-            domain="[('company_id', '=', id)]",
-            help="User to create update unlink IC records"),
-        'intercompany_shop_id': fields.many2one(
-            'sale.shop', 'IC Default location',
-            domain="[('company_id', '=', id)]")
-    }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== removed file 'base_intercompany/company_view.xml'
--- base_intercompany/company_view.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/company_view.xml	1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-    <data>
-        <record id="inherit_view_intercompany_form" model="ir.ui.view">
-            <field name="name">res.intercompany.form</field>
-            <field name="model">res.company</field>
-            <field name="inherit_id" ref="base.view_company_form"/>
-            <field name="arch" type="xml">
-                <xpath expr="//page[@string='Configuration']" position="before">
-                    <page string="InterCompany" groups="base.group_multi_company">
-                        <group string="Intercompany">
-                            <field name="intercompany_uid" />
-                            <field name="intercompany_shop_id" />
-	                        <field name="intercompany_ids">
-	                            <tree editable="bottom">
-	                                <field name="company_to"/>
-	                                <field name='intercompany_uid'/>
-	                                <field name="obj2obj"/> 
-                                    <field name="status" />
-	                                <field name="direction"/>
-	                                <field name="auto_confirm"/>
-	                            </tree>
-	                        </field>
-                        </group>
-                    </page>
-                </xpath>
-            </field>
-        </record>
-    </data>
-</openerp>

=== added file 'base_intercompany/connector.py'
--- base_intercompany/connector.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/connector.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+from openerp.addons.connector.connector import Environment
+from openerp.addons.connector.checkpoint import checkpoint
+
+
+class base_intercompany_installed(orm.AbstractModel):
+    """Empty model used to know if the module is installed on the
+    database.
+
+    If the model is in the registry, the module is installed.
+    """
+    _name = 'base_intercompany.installed'
+
+
+def get_environment(session, model_name, backend_id):
+    """ Create an environment to work with.  """
+    backend_record = session.browse('icops.backend', backend_id)
+    env = Environment(backend_record, session, model_name)
+    lang_code = 'en_US'
+    env.set_lang(code=lang_code)
+    return env
+
+
+class icops_binding(orm.AbstractModel):
+    _name = 'icops.binding'
+    _inherit = 'external.binding'
+    _description = 'Coswin Binding (abstract)'
+
+    _columns = {
+        'backend_id': fields.many2one(
+            'icops.backend',
+            'ICOPS Backend',
+            required=True,
+            ondelete='restrict'),
+        'icops_ids': fields.one2many(
+            'icops.record', 'binding_id',
+            string="ICOPS Record"),
+    }
+
+
+class icops_record(orm.Model):
+    _name = 'icops.record'
+
+    _columns = {
+        'binding_id': fields.integer('ICOPS Binding'),
+        'record_id': fields.integer('ICOPS ID'),
+        'concept': fields.char('Concept'),
+        'backend_id': fields.many2one(
+            'icops.backend', 'ICOPS Backends')
+    }
+
+
+def add_checkpoint(session, model_name, record_id, backend_id):
+    """ Add a row in the model ``connector.checkpoint`` for a record,
+    meaning it has to be reviewed by a user.
+
+    :param session: current session
+    :type session: :py:class:openerp.addons.connector.session.ConnectorSession
+    :param model_name: name of the model of the record to be reviewed
+    :type model_name: str
+    :param record_id: ID of the record to be reviewed
+    :type record_id: int
+    :param backend_id: ID of the Coswin Backend
+    :type backend_id: int
+    """
+    return checkpoint.add_checkpoint(session, model_name, record_id,
+                                     'icops.backend', backend_id)

=== added file 'base_intercompany/consumer.py'
--- base_intercompany/consumer.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/consumer.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.addons.connector.event import (on_record_write,
+                                            on_record_create,
+                                            on_record_unlink
+                                            )
+from .unit.export_synchronizer import (
+    export_record)
+
+_MODEL_NAMES = ()
+_BIND_MODEL_NAMES = ()
+_UNLINK_MODEL_NAMES = ()
+_UNLINK_BIND_MODEL_NAMES = ()
+
+
+@on_record_create(model_names=_BIND_MODEL_NAMES)
+@on_record_write(model_names=_BIND_MODEL_NAMES)
+def delay_export(session, model_name, record_id, fields=None):
+    """ Delay a job which export a binding record.
+
+    (A binding record being a ``icops.res.partner``,
+    ``icops.sale.order``, ...)
+    """
+    export_record(session, model_name, record_id, fields=fields)
+
+
+@on_record_write(model_names=_MODEL_NAMES)
+def delay_export_all_bindings(session, model_name, record_id, fields=None):
+    """ Delay a job which export all the bindings of a record.
+
+    In this case, it is called on records of normal models and will delay
+    the export for all the bindings.
+    """
+    model = session.pool.get(model_name)
+    record = model.browse(session.cr, session.uid,
+                          record_id, context=session.context)
+    for binding in record.icops_bind_ids:
+        export_record(session, binding._model._name, binding.id,
+                      fields=fields)
+
+
+@on_record_unlink(model_names=_UNLINK_MODEL_NAMES)
+def delay_unlink(session, model_name, record_id):
+    """ Delay a job which delete a record on Magento.
+
+    Called on binding records."""
+    fields = {'icops_delete': True}
+    delay_export_all_bindings(session, model_name, record_id, fields)
+
+
+@on_record_unlink(model_names=_UNLINK_BIND_MODEL_NAMES)
+def delay_unlink_binding(session, model_name, record_id):
+    """ Delay a job which delete a record on Magento.
+
+    Called on binding records."""
+    fields = {'icops_delete': True}
+    delay_export(session, model_name, record_id, fields)

=== removed directory 'base_intercompany/icops'
=== removed file 'base_intercompany/icops/__init__.py'
--- base_intercompany/icops/__init__.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/icops/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-import order

=== removed file 'base_intercompany/icops/order.py'
--- base_intercompany/icops/order.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/icops/order.py	1970-01-01 00:00:00 +0000
@@ -1,157 +0,0 @@
-from openerp import SUPERUSER_ID
-from openerp.osv import osv
-from openerp.tools.translate import _
-from openerp import netsvc
-
-
-class icops_order(object):
-
-    def __init__(self, obj):
-        self.obj = obj
-        self.obj2obj_1 = 'so2po'
-        self.obj2obj_2 = 'po2so'
-        self.attr_id_1 = 'purchase_id'
-        self.attr_id_2 = 'sale_id'
-        self.name_2 = 'purchase.order'
-        self.confirm = 'purchase_confirm'
-        if self.obj._name == 'purchase.order':
-            self.confirm = 'order_confirm'
-            self.obj2obj_1 = 'po2so'
-            self.obj2obj_2 = 'so2po'
-            self.name_2 = 'sale.order'
-            self.attr_id_1 = 'sale_id'
-            self.attr_id_2 = 'purchase_id'
-        self.order_pool = self.obj.pool.get(self.name_2)
-
-    def create_intercompany(self, cr, uid, ids, node='draft', context=None):
-        ic_pool = self.obj.pool.get('res.intercompany')
-        company_from, company_to, ic_uid = ic_pool.get_intercompany(
-            cr, uid, ids[0], self.obj._name, self.obj2obj_1, context=context)
-        if ic_pool.check_need_create_intercompany_object(
-                cr, uid, company_from, company_to, self.obj2obj_1, node):
-            self._create_intercompany(
-                cr, uid, ids[0], company_to, ic_uid, context=context)
-        return True
-
-    def _create_intercompany(
-            self, cr, uid, id, company_to, ic_uid, context=None):
-        if isinstance(company_to, list):
-            company_to = company_to[0]
-        context = context or {}
-        order = self.obj.read(cr, uid, id, ['partner_id'], context=context)
-        company = self.obj.pool.get('res.company').read(
-            cr, ic_uid, company_to, ['partner_id'], context=context)
-        if order['partner_id'] != company['partner_id']:
-            return None
-        order_data = self.obj._prepare_IC(
-            cr, uid, id, company_to,
-            ic_uid, context=context)
-        if not 'is_locked' in context:
-            order_pool = self.obj.pool.get(self.name_2)
-            res = order_pool.create(cr, ic_uid, order_data, context=context)
-            data = {self.attr_id_1: res}
-            self.obj.write(
-                cr, uid, id, data, context=context)
-
-            return res
-
-    def action(self, cr, uid, ids, values=None, state='draft', context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        for order in self.obj.read(
-                cr, uid, ids,
-                ['company_id', self.attr_id_1], context=context):
-            if not self.attr_id_1 in order:
-                continue
-            if values and 'state' in values:
-                if values['state'] == 'cancel':
-                    state = 'cancel'
-                elif values['state'] == 'confirmed':
-                    return
-            company_pool = self.obj.pool.get('res.company')
-            company = company_pool.read(
-                cr, uid, order['company_id'][0],
-                ['intercompany_ids'], context=context)
-            self.loop(
-                cr, uid, order['id'], company['intercompany_ids'], 'regular',
-                self.obj2obj_1, state, context)
-            company = None
-            if not order[self.attr_id_1]:
-                continue
-            obj = self.obj.pool.get(self.name_2).read(
-                cr, SUPERUSER_ID, order[self.attr_id_1][0],
-                ['company_id'], context=context)
-            if not obj:
-                continue
-            company = company_pool.read(
-                cr, SUPERUSER_ID, obj['company_id'][0],
-                ['intercompany_uid', 'intercompany_ids'], context=context)
-            ic_uid = company['intercompany_uid'][0]
-            self.loop(
-                cr, ic_uid, obj['id'],
-                company['intercompany_ids'], 'inverse', self.obj2obj_2,
-                state, context=context)
-        return True
-
-    def loop(
-            self, cr, uid, id, icops_ids,
-            direction, obj2obj, state, context=None):
-
-        order_pool = self.obj.pool.get(self.name_2)
-        opposite_direction = 'inverse' if direction == 'regular' else 'regular'
-        icops_pool = self.obj.pool.get('res.intercompany')
-        ic_att = ['obj2obj', 'status', 'intercompany_uid', 'direction',
-                  'company_to']
-        for ic in icops_pool.read(cr, uid, icops_ids, ic_att, context=context):
-            if ic['obj2obj'] != obj2obj or ic['status'] != state:
-                continue
-
-            ic_uid = ic['intercompany_uid'][0]
-            ic_order_ids = order_pool.search(
-                cr, ic_uid,
-                [(self.attr_id_2, '=', id)], context=context)
-            ic_order_id = ic_order_ids and ic_order_ids[0]
-            if((ic['direction'] == direction
-                    or ic['direction'] == 'bidirectional')
-                or
-                    ('force_update' in context)):
-                context['is_external'] = True
-                if state == 'draft':
-                    data = self.obj._prepare_IC(
-                        cr, uid, id, ic['company_to'][0], ic_uid,
-                        context=context)
-                    obj = order_pool.read(cr, ic_uid, ic_order_id, ['state'],
-                                          context=context)
-                    try:
-                        if not isinstance(obj, dict):
-                            continue
-                        if obj['state'] == "progress" and 'order_line' in data:
-                            data.pop('order_line')
-                    except:
-                        pass
-                    order_pool.write(
-                        cr, ic_uid, ic_order_id, data, context=context)
-                elif state == 'cancel':
-
-                    try:
-                        order_pool.action_cancel(
-                            cr, ic_uid, [ic_order_id], context=context)
-                    except:
-                        continue
-                elif state == 'confirm':
-                    if self.obj._name == 'purchase.order':
-                        order_pool.action_wait(
-                            cr, ic_uid, [ic_order_id], context=context)
-                        continue
-                    order_pool.wkf_confirm_order(
-                        cr, ic_uid, [ic_order_id], context=context)
-                elif state == 'unlink':
-                    order_pool.unlink(
-                        cr, SUPERUSER_ID, ic_order_id, context=context)
-
-            elif(not 'is_external' in context and
-                 ic['direction'] == opposite_direction):
-                raise osv.except_osv(
-                    _('Error!'),
-                    _('You can\'t edit this %s mode quotation'
-                        % opposite_direction))

=== added file 'base_intercompany/icops_model.py'
--- base_intercompany/icops_model.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/icops_model.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import logging
+from openerp.osv import fields, orm
+
+_logger = logging.getLogger(__name__)
+
+
+class icops_backend(orm.Model):
+    _name = 'icops.backend'
+    _description = 'ICOPS Backend'
+    _inherit = 'connector.backend'
+
+    _backend_type = 'icops'
+
+    def _select_versions(self, cr, uid, context=None):
+        """ Available versions
+
+        Can be inherited to add custom versions.
+        """
+        return [('7.0', '7.0')]
+
+    _columns = {
+        'version': fields.selection(
+            _select_versions,
+            string='Version',
+            required=True),
+        'company_id': fields.many2one(
+            'res.company', string="Company", required=True),
+        'icops_ids': fields.one2many(
+            'res.intercompany', 'backend_id', 'Inter-Company Setup'),
+        'icops_uid': fields.many2one(
+            'res.users', 'IC User',
+            required=True,
+            domain="[('company_id', '=', company_id)]",
+            help="User to create update unlink IC records")
+    }
+
+    _defaults = {
+        'version': '7.0',
+    }
+
+    def _icops_backend(self, cr, uid, callback, domain=None,
+                       context=None):
+        if domain is None:
+            domain = []
+            ids = self.search(cr, uid, domain, context=context)
+            if ids:
+                callback(cr, uid, ids, context=context)
+
+    def prepare_binding(self, cr, uid, data, context=None):
+        context = context or {}
+        icops_bind_ids = []
+        if not 'icops_bind_ids' in data:
+            data['icops_bind_ids'] = None
+        if not 'icops' in context and not data['icops_bind_ids']:
+            user = self.pool.get('res.users').browse(
+                cr, uid, uid, context)
+            backend_pool = self.pool.get('icops.backend')
+            backend_ids = backend_pool.search(
+                cr, uid, [('company_id', '=', user.company_id.id)])
+            if backend_ids:
+                backends = backend_pool.browse(
+                    cr, uid, backend_ids, context)
+                for backend in backends:
+                    icops_bind_ids.append(
+                        (0, 0, {'backend_id': backend.id}))
+        return icops_bind_ids

=== added file 'base_intercompany/icops_model_view.xml'
--- base_intercompany/icops_model_view.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany/icops_model_view.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        <record id="view_icops_backend_form" model="ir.ui.view">
+            <field name="name">icops.backend.form</field>
+            <field name="model">icops.backend</field>
+            <field name="arch" type="xml">
+                <form string="ICOPS Backend" version="7.0">
+                    <sheet>
+                        <label for="name" class="oe_edit_only"/>
+                        <h1>
+                            <field name="name" class="oe_inline" />
+                        </h1>
+                        <group name="icops" string="ICOPS Configuration">
+                            <group colspan="4" col="4">
+                                <field name="version" cols="4" />
+                                <field name="company_id" cols="2" />
+                                <field name="icops_uid" cols="2" />
+                            </group>
+                        </group>
+                        <field name="icops_ids" context="{'active_id': active_id}">
+                            <tree editable="bottom">
+                                <field name="concept"/> 
+                                <field name="object_name" invisible="1" /> 
+                                <field name="backend_id" invisible="1" />
+                                <field name="backend_to" />
+                                <field name='icops_uid' invisible="1" />
+                                <field name="on_create" />
+                                <field name="on_write" />
+                                <field name="on_unlink" />
+                                <field name="on_confirm" />
+                                <field name="on_cancel" />
+                            </tree>
+                        </field>
+                    </sheet>
+                </form>
+            </field>
+        </record>
+
+        <record id="view_icops_backend_tree" model="ir.ui.view">
+            <field name="name">icops.backend.tree</field>
+            <field name="model">icops.backend</field>
+            <field name="arch" type="xml">
+                <tree string="ICOPS Backend" version="7.0">
+                    <field name="name"/>
+                    <field name="company_id" />
+                </tree>
+            </field>
+        </record>
+
+        <record id="action_icops_backend" model="ir.actions.act_window">
+            <field name="name">ICOPS Backends</field>
+            <field name="res_model">icops.backend</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree,form</field>
+            <field name="view_id" ref="view_icops_backend_tree"/>
+        </record>
+    </data>
+</openerp>

=== removed file 'base_intercompany/invoice.py'
--- base_intercompany/invoice.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/invoice.py	1970-01-01 00:00:00 +0000
@@ -1,198 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#     Jon Chow <jon.chow@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from openerp.osv import osv, fields
-from openerp import SUPERUSER_ID
-
-
-class account_invoice(osv.osv):
-    _inherit = "account.invoice"
-    _name = "account.invoice"
-
-    _columns = {
-        'is_locked': fields.boolean('Locked for Intercompany'),
-        'ic_create': fields.boolean('Intercompany Invoice generated'),
-        'invoice_ic_id': fields.many2one('account.invoice', 'Invoice'),
-    }
-
-    def get_from_to_company(self, cr, uid, ids, context=None):
-        """ get company from and to """
-        assert len(ids) == 1
-        cr.execute(""" 
-            SELECT
-                inv.company_id AS from_c, cmp.id AS to_c
-            FROM account_invoice AS inv
-                LEFT JOIN res_partner as part ON (inv.partner_id = part.id)
-                LEFT JOIN res_company as cmp  ON (part.id = cmp.partner_id )
-            WHERE inv.id=%s """, (ids[0],),
-        )
-        return cr.fetchone()
-
-    def need_to_create_intercompany_invoice(self, cr, uid, ids, o2o_field_name=None, node=None, context=None):
-        """
-        @o2o_field_name  
-        @node,  draft' or 'confirm', res.intercompany.so2po value ,
-        return boolean
-        """
-        company_from, company_to = self.get_from_to_company(cr, uid, ids, context=context)
-        need = self.pool.get('res.intercompany').check_need_create_intercompany_object(cr, uid, company_from, company_to, o2o_field_name, node)
-        return need
-
-    def action_draft(self, cr, uid, ids, context=None):
-        """
-        Picking wkf Draft action,
-        Use Administrator operate intercompany action
-        """
-        assert len(ids) == 1
-        self.action_intercompany(cr, SUPERUSER_ID, ids, node='draft', context=context)
-        return True
-
-    def action_intercompany(self, cr, uid, ids, node=None, context=None):
-        """
-        if CI, create SI
-        if SI, create CI
-        @node, draft or confirm,  
-        """
-        assert len(ids) == 1
-        cr.execute(""" SELECT type FROM account_invoice WHERE id=%s """,(ids[0],))
-        invoice_type = cr.fetchone()[0]
-
-        if invoice_type in ['in_invoice', 'out_invoice']:
-            #if type=in, check is2do,  type=out,
-            o2o_field_name = invoice_type=='in_invoice' and 'ci2si' or 'si2ci'
-            if self.need_to_create_intercompany_invoice(cr, uid, ids, o2o_field_name, node=node, context=context):
-                self.create_intercompany_invoice(cr, uid, ids, self_type=invoice_type, context=None)
-
-    def create_intercompany_invoice(self, cr, uid, ids, self_type=None, context=None):
-        invoice    = self.browse(cr, uid, ids[0])
-        company_from, company_to = self.get_from_to_company(cr, uid, ids, context=context)
-        data       = self.prepare_intercompany_invoice(cr, uid, invoice, company_to, context=context)
-        invoice_id = self.create(cr, uid, data, context=context)
-        return invoice_id
-
-    def prepare_intercompany_invoice(self, cr, uid, invoice, company_to,context=None):
-        """ prepare  intercompany invoice data
-            @invoice, browse of account.invoice 
-            @company_to,  intercompany_invoice company_id
-            return {}, data of create invoice
-        """
-        line_pool    = self.pool.get('account.invoice.line')
-        journal_pool = self.pool.get('account.journal')
-        period_pool  = self.pool.get('account.period')
-        part         = invoice.company_id.partner_id
-
-        #Invoice Type and acc_id
-        hash = {
-            'in_invoice': {'create_type':'out_invoice', 'value_reference_name':'property_account_payable'  },
-            'out_invoice':{'create_type':'in_invoice' , 'value_reference_name':'property_account_receivable' }
-        }
-        acc_id = part.property_account_receivable.id
-        cr.execute("SELECT value_reference FROM ir_property WHERE name=%s AND res_id='res.partner,%s' AND company_id=%s",(hash[invoice.type]['value_reference_name'],part.id,company_to, ))
-        prop = cr.fetchone()
-        if prop and prop[0]:
-            acc_id = prop[0].split('account.account,')[1]
-
-        #Invoice Journal
-        type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale_refund', 'in_refund': 'purchase_refund'}        
-        res          = journal_pool.search(cr, uid, [('type', '=', type2journal.get(hash[invoice.type]['create_type'], 'sale')), ('company_id', '=', company_to)], limit=1)
-        journal_id   = res and res[0] or False
-        # We assume periods in Inter-companies have the same code. 
-        period_ids = period_pool.search(cr, uid, [('code', '=', invoice.period_id.code), ('company_id', '=', company_to)], limit=1)
-        period_id  = period_ids and period_ids[0] or False
-
-        lines_data=[(5,)]
-        for invoice_line in invoice.invoice_line:
-            data_line = {
-                # invoice_id:  ,
-                'name':       invoice_line.name,
-                'origin':     invoice_line.origin,
-                'sequence':   invoice_line.sequence,
-                'uos_id':     invoice_line.uos_id     and invoice_line.uos_id.id     or False,
-                'product_id': invoice_line.product_id and invoice_line.product_id.id or False,
-                'account_id': acc_id,
-                'price_unit': invoice_line.price_unit,
-                'quantity':   invoice_line.quantity,
-                'discount':   invoice_line.discount,
-                'company_id': company_to,
-            }
-            lines_data.append( (0, 0, data_line) )
-
-        invoice_data = {
-            'name':           invoice.name,
-            'origin':         invoice.number and 'IC:' + str(invoice.number) or '',
-            'supplier_invoice_number': invoice.supplier_invoice_number,
-            'type':           hash[invoice.type]['create_type'],
-            'reference':      invoice.reference,
-            'reference_type': invoice.reference_type,
-            'comment':        invoice.comment,
-            'date_invoice':   invoice.date_invoice,
-            'date_due':       invoice.date_due,
-            'partner_id':     part.id,
-            'payment_term':   invoice.payment_term and invoice.payment_term.id or False,
-            'period_id':      period_id,
-            'account_id':     acc_id,
-            'journal_id':     journal_id,
-            'company_id':     company_to , 
-            'invoice_ic_id':  invoice.id,
-            'is_locked':      True,
-            'ic_create':      True,       
-            'invoice_line':   lines_data,      
-             #'currency_id':   invoice.currency_id and invoice.currency_id.id or False,
-        }
-        return invoice_data
-
-    def write(self, cr, uid, ids, values, context=None):
-        res = super(account_invoice, self).write(cr, uid, ids, values, context=context)
-        if type(ids) != list:
-            ids = [ids]
-        self.update_intercompany_invoice(cr, uid, ids, context=None)
-        return res
-
-    def unlink(self, cr, uid, ids, context=None):
-        res = super(account_invoice, self).unlink(cr, uid, ids, context=context)
-        if type(ids) != type([]):
-            ids = [ids]
-
-        for inv_id in ids:
-            inv_ic_ids = self.search(cr, uid, [('invoice_ic_id','=',inv_id)], context=context)
-            if inv_ic_ids:
-                self.unlink(cr, uid, inv_ic_ids, context=context)
-        return res
-
-    def update_intercompany_invoice(self, cr, uid, ids, context=None):
-        for invoice in self.browse(cr, uid, ids, context):
-            invoice_ic_id = self.search(cr, uid, [('invoice_ic_id','=',invoice.id )])
-            if invoice_ic_id:
-                company_from, company_to = self.get_from_to_company(cr, uid, [invoice.id,] ,context=context)
-                data = self.prepare_intercompany_invoice(cr, uid, invoice, company_to, context=context)
-                self.write(cr, uid, invoice_ic_id, data)
-        return True
-
-    def invoice_validate(self, cr, uid, ids, context=None):
-        res = super(account_invoice, self).invoice_validate(cr, uid, ids, context=context)
-        if res:
-            self.action_intercompany(cr, uid, ids, node='confirm', context=context)
-        return res
-
-account_invoice()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file

=== removed file 'base_intercompany/invoice_wkf.xml'
--- base_intercompany/invoice_wkf.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/invoice_wkf.xml	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
-<data>
-
-<!-- add the action_draft to invoice WKF. jon.chow#elico-corp.com Aug 23, 2013-->
-<record id="account.act_draft" model="workflow.activity">
-	    <field name="kind">function</field>
-	    <field name="action">action_draft()</field>
-</record>
-
-
-    
-</data>
-</openerp>
\ No newline at end of file

=== removed file 'base_intercompany/purchase.py'
--- base_intercompany/purchase.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/purchase.py	1970-01-01 00:00:00 +0000
@@ -1,263 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Augustin Cisterne-Kaas <augustin.cisterne-kaaas@xxxxxxxxxxxxxx>
-#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from openerp import SUPERUSER_ID
-from openerp.osv import fields, orm, osv
-from openerp.tools.translate import _
-from openerp import netsvc
-from icops.order import icops_order
-from openerp import netsvc
-
-
-class purchase_order(orm.Model):
-    _inherit = 'purchase.order'
-    _columns = {
-        'is_locked': fields.boolean('Locked for Intercompany'),
-        'ic_create': fields.boolean('Intercompany PO generated'),
-        'sale_id': fields.many2one('sale.order', 'Sales Order'),
-    }
-
-    _sql_constraints = [(
-        'sale_id_unique', 'unique(sale_id)',
-        'Sale Id already exists')]
-
-    def action_draft(self, cr, uid, ids, context=None):
-        """
-        function of wkf active draft,
-        intercompany action operate by Administrator
-        SUPERUSER_ID used to search, browse kinds of object.
-        but not used of create, write anything
-        """
-
-        assert len(ids) == 1
-        context = context or {}
-        order = self.read(cr, uid, ids[0], ['sale_id'])
-        if order['sale_id']:
-            context['is_locked'] = True
-            context['is_external'] = True
-        icops = icops_order(self)
-        icops.create_intercompany(cr, uid, ids,
-                                  node='draft', context=context)
-        return True
-
-    def write(self, cr, uid, ids, values, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        context = context or {}
-
-        res = super(purchase_order, self).write(
-            cr, uid, ids, values, context=context)
-        if 'is_locked' not in context:
-            if 'is_external' in context:
-                context['is_locked'] = True
-            icops = icops_order(self)
-            try:
-                icops.action(
-                    cr, uid, ids, values, context=context)
-            except:
-                raise
-        return res
-
-    def unlink(self, cr, uid, ids, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        context = context or {}
-        if 'is_locked' not in context:
-            if 'is_external' in context:
-                context['is_locked'] = True
-            icops = icops_order(self)
-            try:
-                icops.action(cr, uid, ids, state="unlink",
-                             context=context)
-            except:
-                raise
-
-        return super(purchase_order, self).unlink(
-            cr, uid, ids, context=context)
-
-    def action_cancel(self, cr, uid, ids, context=None):
-        wf_service = netsvc.LocalService("workflow")
-        for purchase in self.browse(cr, uid, ids, context=context):
-            for pick in purchase.picking_ids:
-                if pick.state not in ('draft', 'cancel'):
-                    raise osv.except_osv(
-                        _('Unable to cancel this purchase order.'),
-                        _('First cancel all receptions related\
-                           to this purchase order.'))
-            for pick in purchase.picking_ids:
-                wf_service.trg_validate(
-                    uid, 'stock.picking', pick.id, 'button_cancel', cr)
-            for inv in purchase.invoice_ids:
-                if inv and inv.state not in ('cancel', 'draft'):
-                    raise osv.except_osv(
-                        _('Unable to cancel this purchase order.'),
-                        _('You must first cancel all receptions related to \
-                            this purchase order.'))
-                if inv:
-                    wf_service.trg_validate(
-                        uid, 'account.invoice', inv.id, 'invoice_cancel', cr)
-        self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
-
-        for (id, name) in self.name_get(cr, uid, ids):
-            wf_service.trg_validate(
-                uid, 'purchase.order', id, 'purchase_cancel', cr)
-        return True
-
-    def _prepare_IC(self, cr, uid, id,
-                    company_to, ic_uid, context=None):
-        """
-        according the PO and company_to, prepare the SO data,
-        It can be used to create or update SO record.
-        @po  SO browse record
-        @company_to      company_id
-        @ic_uid
-        return { }, value of SO data
-        """
-        if isinstance(company_to, list):
-            company_to = company_to[0]
-        order = self.read(cr, uid, id, ['name', 'company_id', 'order_line',
-                                        'state'])
-        company_pool = self.pool.get('res.company')
-        company = company_pool.read(
-            cr, uid, order['company_id'][0], ['partner_id'])
-        partner_pool = self.pool.get('res.partner')
-        customer = partner_pool.read(
-            cr, ic_uid, company['partner_id'][0],
-            ['property_product_pricelist',
-             'property_account_position',
-             'property_payment_term',
-             'user_id'])
-
-        addr = partner_pool.address_get(cr, uid, [customer['id']],
-                                        ['delivery', 'invoice', 'contact'])
-
-        pricelist = (customer['property_product_pricelist'][0]
-                     if customer['property_product_pricelist']
-                     else False)
-
-        fiscal_position = (customer['property_account_position'][0]
-                           if customer['property_account_position']
-                           else False)
-        payment_term = (customer['property_payment_term'][0]
-                        if customer['property_payment_term']
-                        else False)
-
-        salesman = customer['user_id'][0] if customer['user_id'] else ic_uid
-        company = company_pool.read(
-            cr, ic_uid, company_to, ['intercompany_shop_id'])
-
-        if not 'intercompany_shop_id' in company:
-            raise osv.except_osv(
-                _('Error!'),
-                _('There is no default shop for the destination company!'))
-
-        shop_id = company['intercompany_shop_id'][0]
-        sol_datas = [(5,)]
-        pol_pool = self.pool.get('purchase.order.line')
-        i = 0
-        for line in pol_pool.read(
-                cr, uid, order['order_line'],
-                ['name', 'ic_pol_id', 'product_qty',
-                 'product_id', 'product_uom', 'price_unit',
-                 'state']):
-            line_data = (0, 0, {
-                #'order_id':       so_id,
-                'name': line['name'],
-                'ic_pol_id': line['id'],
-                'product_uom_qty': line['product_qty'],
-                'product_id': line['product_id'][0],
-                'product_uom': line['product_uom'][0],
-                'price_unit': line['price_unit']
-            })
-            sol_datas.append(line_data)
-        state = "draft" if order['state'] != "approved" else "progress"
-        so_data = {
-            'partner_id': customer['id'],
-            'pricelist_id': pricelist,
-            'partner_invoice_id': addr['invoice'],
-            # 'partner_order_id': addr['contact'],
-            'partner_shipping_id': addr['delivery'],
-            'payment_term': payment_term,
-            'fiscal_position': fiscal_position,
-            'user_id': salesman,
-            'purchase_id': order['id'],
-            'ic_create': True,
-            'shop_id': shop_id,
-            'origin': 'IC:' + str(order['name']),
-            'order_line': sol_datas,
-            'state': state
-        }
-        if 'is_external' in context:
-            so_data = {
-                'order_line': sol_datas,
-                'state': state
-            }
-
-        return so_data
-
-    def copy(self, cr, uid, id, default=None, context=None):
-        if not default:
-            default = {}
-        default.update({
-            'sale_id': None
-        })
-        return super(purchase_order, self).copy(cr, uid, id, default, context)
-
-    def wkf_confirm_order(self, cr, uid, ids, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        context = context or {}
-        if 'is_external' not in context:
-            icops = icops_order(self)
-            try:
-                icops.action(
-                    cr, uid, ids, state='confirm', context=context)
-            except:
-                raise
-            todo = []
-            sol_pool = self.pool.get('sale.order.line')
-            for po in self.read(cr, uid, ids, ['order_line']):
-                if not po['order_line']:
-                    raise osv.except_osv(_('Error!'), _(
-                        'You cannot confirm a purchase order without any\
-                         purchase order line.'))
-                for line in sol_pool.read(cr, uid, po['order_line'], ['state']):
-                    if line['state'] == 'draft':
-                        todo.append(line.id)
-
-            self.pool.get('purchase.order.line').action_confirm(
-                cr, uid, todo, context)
-            for id in ids:
-                self.write(
-                    cr, uid, [id], {'state': 'confirmed', 'validator': uid},
-                    context=context)
-        return True
-
-
-class purchase_order_line(orm.Model):
-    _inherit = 'purchase.order.line'
-    _columns = {
-        'ic_sol_id': fields.many2one('sale.order.line', 'IC SOL'),
-    }
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== removed file 'base_intercompany/purchase_wkf.xml'
--- base_intercompany/purchase_wkf.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/purchase_wkf.xml	1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
-	<data>
-		<!-- purchase order wkf draft action  jon.chow#elico-corp.com Aug 8, 2013-->
-		<record id="purchase.act_draft" model="workflow.activity">
-		    <field name="wkf_id" ref="purchase.purchase_order"/>
-		   <field name="kind">function</field>
-		   <field name="action">action_draft()</field>
-		</record>
-        <record id="purchase.act_cancel" model="workflow.activity">
-            <field name="action">action_cancel()</field>
-        </record>
-		
-	</data>
-</openerp>

=== removed file 'base_intercompany/sale.py'
--- base_intercompany/sale.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/sale.py	1970-01-01 00:00:00 +0000
@@ -1,246 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Augustin Cisterne-Kaas <augustin.cisterne-kaaas@xxxxxxxxxxxxxx>
-#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-from openerp.osv import fields, orm, osv
-from openerp.tools.translate import _
-from icops.order import icops_order
-from openerp import SUPERUSER_ID
-from openerp import netsvc
-from collections import namedtuple
-
-
-class sale_order(orm.Model):
-    _inherit = 'sale.order'
-    _columns = {
-        'is_locked': fields.boolean('Locked for Intercompany'),
-        'ic_create': fields.boolean('Intercompany SO generated'),
-        'purchase_id': fields.many2one('purchase.order', 'Purchase Order'),
-    }
-
-    _sql_constraints = [(
-        'purchase_id_unique', 'unique(purchase_id)',
-        'Purchase Id already exists')]
-
-    def action_draft(self, cr, uid, ids, context=None):
-        """
-        SO wkf Draft action,
-        Use Administrator operate intercompany action
-        """
-        assert len(ids) == 1
-        if context is None:
-            context = {}
-        order = self.browse(cr, SUPERUSER_ID, ids[0], context=context)
-        if order.purchase_id:
-            if order.purchase_id:
-                context['is_locked'] = True
-                context['is_external'] = True
-        icops = icops_order(self)
-        icops.create_intercompany(cr, uid, ids, context=context)
-        return True
-
-    def write(self, cr, uid, ids, values, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        context = context or {}
-        res = super(sale_order, self).write(
-            cr, uid, ids, values, context=context)
-        if 'is_locked' not in context:
-            if 'is_external' in context:
-                context['is_locked'] = True
-            icops = icops_order(self)
-            try:
-                icops.action(cr, uid, ids, values,
-                             context=context)
-            except:
-                raise
-        return res
-
-    def unlink(self, cr, uid, ids, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        if not isinstance(context, dict):
-            context = {}
-        if 'is_locked' not in context:
-            if 'is_external' in context:
-                context['is_locked'] = True
-            icops = icops_order(self)
-            try:
-                icops.action(cr, uid, ids, state="unlink",
-                             context=context)
-            except:
-                raise
-        return super(sale_order, self).unlink(
-            cr, uid, ids, context=context)
-
-    def action_cancel(self, cr, uid, ids, context=None):
-        wf_service = netsvc.LocalService("workflow")
-        context = context or {}
-        sale_order_line_obj = self.pool.get('sale.order.line')
-        for sale in self.browse(cr, uid, ids, context=context):
-            for inv in sale.invoice_ids:
-                if inv.state not in ('draft', 'cancel'):
-                    raise osv.except_osv(
-                        _('Cannot cancel this sales order!'),
-                        _('First cancel all invoices attached\
-                            to this sales order.'))
-            for r in self.read(cr, uid, ids, ['invoice_ids']):
-                for inv in r['invoice_ids']:
-                    wf_service.trg_validate(
-                        uid, 'account.invoice', inv, 'invoice_cancel', cr)
-                    sale_order_line_obj.write(
-                        cr, uid, [l.id for l in sale.order_line],
-                        {'state': 'cancel'})
-            self.write(cr, uid, ids, {'state': 'cancel'}, context=context)
-        return True
-
-    def action_wait(self, cr, uid, ids, context=None):
-        if not isinstance(ids, list):
-            ids = [ids]
-        context = context or {}
-        if 'is_external' not in context:
-            icops = icops_order(self)
-            try:
-                icops.action(
-                    cr, uid, ids, state='confirm', context=context)
-            except:
-                raise
-            return super(sale_order, self).action_wait(
-                cr, uid, ids, context=context)
-
-    def _prepare_IC(self, cr, uid, id,
-                    company_to, ic_uid, context=None):
-
-        """
-        prepare the intercompany PO data,
-        it can be used to create or update PO record
-        @ so  SO browse record
-        @ company_to  company_id
-        @ic_uid  Internal company user id
-        """
-        if isinstance(company_to, list):
-            company_to = company_to[0]
-        # to avoid many SQL requests
-        OrderStruct = namedtuple('OrderStruct', 'company_id')
-        CompanyStruct = namedtuple('CompanyStruct', 'security_lead')
-        LineStruct = namedtuple('LineStruct', 'delay')
-
-        order = self.read(cr, uid, id,
-                          ['order_line', 'date_order', 'company_id',
-                           'state', 'name'])
-        company_pool = self.pool.get('res.company')
-        company = company_pool.read(
-            cr, uid, order['company_id'][0], ['partner_id', 'security_lead'])
-
-        fake_company_obj = CompanyStruct(
-            security_lead=company['security_lead'] or 0)
-        fake_so_obj = OrderStruct(company_id=fake_company_obj)
-        supplier = self.pool.get('res.partner').read(
-            cr, ic_uid, company['partner_id'][0],
-            ['property_product_pricelist_purchase',
-             'property_account_position',
-             'property_supplier_payment_term'])
-        pricelist = (supplier['property_product_pricelist_purchase'][0]
-                     if supplier['property_product_pricelist_purchase']
-                     else False)
-
-        fiscal_position = (supplier['property_account_position'][0]
-                           if supplier['property_account_position']
-                           else False)
-        payment_term = (supplier['property_supplier_payment_term'][0]
-                        if supplier['property_supplier_payment_term']
-                        else False)
-
-        company = company_pool.read(
-            cr, ic_uid, company_to, ['intercompany_shop_id'])
-        intercompany_shop = self.pool.get('sale.shop').read(
-            cr, ic_uid, company['intercompany_shop_id'][0], ['warehouse_id'])
-        warehouse = self.pool.get('stock.warehouse').read(
-            cr, ic_uid, intercompany_shop['warehouse_id'][0], ['lot_stock_id'])
-
-        if not 'lot_stock_id' in warehouse:
-            raise osv.except_osv(
-                _('Error!'),
-                _('prepare_intercompany_po_data,not found location_id'))
-
-        location_id = warehouse['lot_stock_id'][0]
-        polines_data = [(5,)]
-        sol_pool = self.pool.get('sale.order.line')
-        for line in sol_pool.read(
-                cr, uid, order['order_line'],
-                ['name', 'product_uom_qty', 'product_id', 'product_uom',
-                 'price_unit', 'delay']):
-
-            fake_line_obj = LineStruct(delay=line['delay'])
-            date_planned = self._get_date_planned(
-                cr, uid, fake_so_obj,
-                fake_line_obj,
-                order['date_order'], context=context)
-            pol_data = (0, 0, {
-                'ic_sol_id': line['id'],
-                'name': line['name'],
-                'product_qty': line['product_uom_qty'],
-                'product_id': line['product_id'][0],
-                'product_uom': line['product_uom'][0],
-                'price_unit': line['price_unit'],
-                'date_planned': date_planned,
-            })
-            polines_data.append(pol_data)
-        company_id = company_to
-        state = "draft" if order['state'] != "progress" else "approved"
-        po_data = {
-            'partner_id': supplier['id'],
-            'pricelist_id': pricelist,
-            'payment_term_id': payment_term,
-            'fiscal_position': fiscal_position,
-            'sale_id': order['id'],
-            'ic_create': True,
-            'company_id': company['id'],
-            'location_id': location_id,
-            'origin': 'IC:' + str(order['name']),
-            'order_line': polines_data,
-            'state': state
-        }
-        if 'is_external' in context:
-            po_data = {
-                'order_line': polines_data,
-                'state': state
-            }
-
-        return po_data
-
-    def copy(self, cr, uid, id, default=None, context=None):
-        if not default:
-            default = {}
-        default.update({
-            'purchase_id': None
-        })
-        return super(sale_order, self).copy(cr, uid, id, default, context)
-
-
-class sale_order_line(orm.Model):
-    _inherit = 'sale.order.line'
-    _columns = {
-        'ic_pol_id': fields.many2one('purchase.order.line',
-                                     'Intercompany PO Line'),
-    }
-#vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== removed file 'base_intercompany/sale_wkf.xml'
--- base_intercompany/sale_wkf.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/sale_wkf.xml	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
-	<data>
-		<!-- action draft   Activity -->
-		<record id="sale.act_draft" model="workflow.activity">
-		    <field name="wkf_id" ref="sale.wkf_sale"/>
-		    <field name="kind">function</field>
-		    <field name="action">action_draft()</field>
-		</record>
-        <record id="sale.act_cancel" model="workflow.activity">
-            <field name="action">action_cancel()</field>
-        </record>
-	</data>
-</openerp>
\ No newline at end of file

=== added directory 'base_intercompany/security'
=== removed directory 'base_intercompany/security'
=== added file 'base_intercompany/security/base_intercompany_security.xml'
--- base_intercompany/security/base_intercompany_security.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany/security/base_intercompany_security.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+    <record id="group_connector_user" model="res.groups">
+        <field name="name">Connector User</field>
+        <field name="category_id" ref="connector.module_category_connector"/>
+        <field name="users" eval="[(4, ref('base.user_root'))]"/>
+    </record>
+
+    </data>
+</openerp>

=== removed file 'base_intercompany/security/intercompany_security.xml'
--- base_intercompany/security/intercompany_security.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/security/intercompany_security.xml	1970-01-01 00:00:00 +0000
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<openerp>
-    <!-- Groups -->
-	<data noupdate="1">
-	    <record id="group_intercompany_user" model="res.groups">
-	        <field name="name">InterCompany User</field>
-	        <field name="users" eval="[(4, ref('base.user_root'))]"/>
-	    </record>
-	    <record id="group_intercompany_manager" model="res.groups">
-	        <field name="name">InterCompany Manager</field>
-	        <field name="implied_ids" eval="[(4, ref('group_intercompany_user'))]"/>
-	        <field name="users" eval="[(4, ref('base.user_root'))]"/>
-	    </record>
-	</data>
-	
-	<!-- Rules -->
-	<data noupdate="1">
-	    <record id="sale_order_intercompany" model="ir.rule">
-	        <field name="name">IC Sales Orders</field>
-	        <field ref="sale.model_sale_order" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="sale_order_line_intercompany" model="ir.rule">
-	        <field name="name">IC Sales Order Lines</field>
-	        <field ref="sale.model_sale_order_line" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="purchase_order_intercompany" model="ir.rule">
-	        <field name="name">IC Purchase Orders</field>
-	        <field ref="purchase.model_purchase_order" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="purchase_order_line_intercompany" model="ir.rule">
-	        <field name="name">IC Purchase Order Lines</field>
-	        <field ref="purchase.model_purchase_order_line" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="stock_picking_in_intercompany" model="ir.rule">
-	        <field name="name">IC Picking IN</field>
-	        <field ref="stock.model_stock_picking_in" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="stock_picking_out_intercompany" model="ir.rule">
-	        <field name="name">IC Picking OUT</field>
-	        <field ref="stock.model_stock_picking_out" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="stock_move_intercompany" model="ir.rule">
-	        <field name="name">IC Stock Moves</field>
-	        <field ref="stock.model_stock_move" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="account_invoice_intercompany" model="ir.rule">
-	        <field name="name">IC Invoices</field>
-	        <field ref="account.model_account_invoice" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	    <record id="account_invoice_line_intercompany" model="ir.rule">
-	        <field name="name">IC Invoice Lines</field>
-	        <field ref="account.model_account_invoice_line" name="model_id"/>
-	        <field name="domain_force">[(1,'=',1)]</field>
-	        <field name="groups" eval="[(4, ref('group_intercompany_user'))]"/>
-	    </record>
-	</data>
-</openerp>
\ No newline at end of file

=== added file 'base_intercompany/security/ir.model.access.csv'
--- base_intercompany/security/ir.model.access.csv	1970-01-01 00:00:00 +0000
+++ base_intercompany/security/ir.model.access.csv	2014-01-21 03:17:46 +0000
@@ -0,0 +1,5 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_res_intercompany_manager,res intercompany manager,base_intercompany.model_res_intercompany,connector.group_connector_manager,1,1,1,1
+access_res_intercompany_user,res intercompany user,base_intercompany.model_res_intercompany,base_intercompany.group_connector_user,1,1,1,1
+access_icops_backend_manager,icops backend manager,base_intercompany.model_icops_backend,connector.group_connector_manager,1,1,1,1
+access_icops_backend_user,icops backend user,base_intercompany.model_icops_backend,base_intercompany.group_connector_user,1,0,0,0

=== removed file 'base_intercompany/security/ir.model.access.csv'
--- base_intercompany/security/ir.model.access.csv	2013-11-29 04:03:22 +0000
+++ base_intercompany/security/ir.model.access.csv	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
-access_intercompany_user,intercompany.user,model_res_intercompany,base.group_user,1,0,0,0
-access_intercompany_manager,intercompany.manager,model_res_intercompany,group_intercompany_manager,1,1,1,1

=== removed directory 'base_intercompany/static'
=== removed directory 'base_intercompany/static/description'
=== removed file 'base_intercompany/static/description/Intercompany_setup.png'
Binary files base_intercompany/static/description/Intercompany_setup.png	2013-11-29 06:49:52 +0000 and base_intercompany/static/description/Intercompany_setup.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'base_intercompany/static/description/index.html'
--- base_intercompany/static/description/index.html	2013-11-29 06:51:20 +0000
+++ base_intercompany/static/description/index.html	1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-<section class="oe_container">
-    <div class="oe_row">
-    <h2 class="oe_slogan">base_intercompany</h2> 
-    <h3 class="oe_slogan">Inter-Company Processing (ICOPS) <br></h3>
-    <h4 class="oe_slogan"><a href="http://www.elico-corp.com";>By Elico Corp</a></h4>
-       <p>
-
-This module is designed to manage Inter-company Process (ICOPS) and allow 2 companies to create objects in each other:<br>
-- When a PO to company B is created in company A, it creates automatically a SO in company B<br>
-- When a SO to company B is created in company A, it creates automatically a PO in company B<br>
-- Update PO from/to SO<br>
-- Confirm SO for PO and vice versa<br>
-- It is generic enough to allow intercompany process companies in cascade<br>
-- it can be uni-directional/bi-directional (eg SO in company A creates PO in company B and when the PO is validated in company B it validate the SO in company A).</br>
-</br>
-Works fine with SO/PO<br>
-Under construction: Sales invoice/Purchase invoice and Stock Moves<br>
-TODO: demo data to be improved and tests <br>
-Blueprint: https://blueprints.launchpad.net/multi-company/+spec/icops<br>
-</p>
-        <div class="oe_row_img oe_centered oe_mt32">
-            <img class="oe_picture oe_screenshot" src="Intercompany_setup.png">
-        </div>
-    </div>
-     <div class="oe_row oe_centeralign oe_more_space">
-            <a href="http://www.elico-corp.com/saas/"; class="oe_button oe_big">Start your <span class="oe_emph">free</span> trial</a>
-        </div>
-        <h4 class="oe_slogan">or</h4>
-</section>

=== removed directory 'base_intercompany/static/src'
=== removed directory 'base_intercompany/static/src/img'
=== removed file 'base_intercompany/static/src/img/icon.png'
Binary files base_intercompany/static/src/img/icon.png	2013-11-30 03:28:44 +0000 and base_intercompany/static/src/img/icon.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'base_intercompany/stock_picking.py'
--- base_intercompany/stock_picking.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/stock_picking.py	1970-01-01 00:00:00 +0000
@@ -1,806 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-#    OpenERP, Open Source Management Solution
-#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
-#    Jon Chow <jon.chow@xxxxxxxxxxxxxx>
-#
-#    This program is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU Affero General Public License as
-#    published by the Free Software Foundation, either version 3 of the
-#    License, or (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU Affero General Public License for more details.
-#
-#    You should have received a copy of the GNU Affero General Public License
-#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-# from openerp import SUPERUSER_ID, netsvc
-# from openerp.osv import fields, osv
-# from openerp.tools.translate import _
-
-
-# class stock_move(osv.osv):
-#     _inherit = 'stock.move'
-#     _name = 'stock.move'
-
-#     def _default_location_source(self, cr, uid, context=None):
-#         """
-#         Gets default address of partner for source location
-#         @return: Address id or False
-#         """
-#         context = context or {}
-#         mod_pool = self.pool.get('ir.model.data')
-#         picking_type = context.get('picking_type')
-#         location_id = False
-
-#         if context.get('move_line', []):
-#             try:
-#                 location_id = context['move_line'][0][2]['location_id']
-#             except:
-#                 pass
-#         elif context.get('address_in_id', False):
-#             part_obj_add = self.pool.get('res.partner').browse(
-#                 cr, uid, context['address_in_id'], context=context)
-#             if part_obj_add:
-#                 location_id = part_obj_add.property_stock_supplier.id
-#         else:
-#             location_xml_id = False
-#             if picking_type == 'in':
-#                 location_xml_id = 'stock_location_suppliers'
-#                 location_model, location_id = mod_pool.get_object_reference(
-#                     cr, uid, 'stock', location_xml_id)
-#             elif picking_type == 'internal':
-#                 location_xml_id = 'stock_location_stock'
-#                 location_model, location_id = mod_pool.get_object_reference(
-#                     cr, uid, 'stock', location_xml_id)
-#             else:
-#                 company_id = self.pool.get('res.users').browse(
-#                     cr, uid, uid, context=context).company_id.id
-#                 cr.execute("""
-#                 SELECT
-#                     id
-#                 FROM
-#                     stock_location
-#                 WHERE
-#                     company_id=%s AND name = 'Stock'
-#                 """, (company_id,))
-#                 location_id = cr.fetchone()[0]
-#         return location_id
-
-#     def _default_location_destination(self, cr, uid, context=None):
-#         """
-#         Gets default address of partner for destination location
-#         @return: Address id or False
-#         """
-
-#         context = context or {}
-#         mod_pool = self.pool.get('ir.model.data')
-#         picking_type = context.get('picking_type')
-#         location_id = False
-
-#         if context.get('move_line', []):
-#             if context['move_line'][0]:
-#                 if isinstance(context['move_line'][0], (tuple, list)):
-#                     location_id = (context['move_line'][0][2]
-#                                    and context['move_line'][0][2].get(
-#                                        'location_dest_id', False)
-#                                    )
-#                 else:
-#                     move_list = self.pool.get('stock.move').read(
-#                         cr, uid, context['move_line'][0], ['location_dest_id'])
-#                     location_id = (move_list
-#                                    and move_list['location_dest_id'][0]
-#                                    or False)
-#         elif context.get('address_out_id', False):
-#             property_out = self.pool.get('res.partner').browse(
-#                 cr, uid, context['address_out_id'],
-#                 context).property_stock_customer
-#             location_id = property_out and property_out.id or False
-#         else:
-#             location_xml_id = False
-#             if picking_type == 'internal':
-#                 location_xml_id = 'stock_location_stock'
-#                 location_model, location_id = mod_pool.get_object_reference(
-#                     cr, uid, 'stock', location_xml_id)
-#             elif picking_type == 'out':
-#                 location_xml_id = 'stock_location_customers'
-#                 location_model, location_id = mod_pool.get_object_reference(
-#                     cr, uid, 'stock', location_xml_id)
-#             else:
-#                 company_id = self.pool.get('res.users').browse(
-#                     cr, uid, uid, context=context).company_id.id
-#                 cr.execute("""
-#                 SELECT
-#                     id
-#                 FROM
-#                     stock_location
-#                 WHERE
-#                     company_id=%s AND name = 'Stock'
-#                 """, (company_id,))
-#                 location_id = cr.fetchone()[0]
-#         return location_id
-
-#     _defaults = {
-#         'location_id': _default_location_source,
-#         'location_dest_id': _default_location_destination,
-#     }
-
-# stock_move()
-
-
-# class stock_picking(osv.osv):
-#     _inherit = 'stock.picking'
-#     _name = 'stock.picking'
-
-#     _columns = {
-#         'is_locked': fields.boolean('Locked for Intercompany'),
-#         'ic_create': fields.boolean('Intercompany Picking generated'),
-#         'picking_ic_id': fields.many2one('stock.picking', 'Stock Picking'),
-#     }
-
-#     def get_intercompany(self, cr, uid, id, context=None):
-#         """
-#         Return company_from company_to
-#         """
-
-#         assert isinstance(id, int) or isinstance(id, long)
-#         cr.execute("""
-#         SELECT
-#             pick.company_id AS from_c, cmp.id AS to_c, cmp.intercompany_uid
-#         FROM
-#             stock_picking AS pick
-#             LEFT JOIN res_partner AS part ON (pick.partner_id=part.id)
-#             LEFT JOIN res_company AS cmp  ON (part.id=cmp.partner_id)
-#         WHERE
-#             pick.id=%s
-#         """, (id,))
-#         return cr.fetchone()
-
-#     def need_to_create_intercompany_picking(
-#             self, cr, uid, ids, o2o_field_name=None, node=None, context=None):
-#         """
-#         @o2o_field_name
-#         @node,  draft' or 'confirm', res.intercompany.so2po value,
-#         """
-
-#         intercompany_obj = self.pool.get('res.intercompany')
-#         cf, ct, ic_uid = self.get_intercompany(cr, uid, ids[0],
-#                                                context=context)
-#         return intercompany_obj.check_need_create_intercompany_object(
-#             cr, uid, cf, ct, o2o_field_name, node)
-
-#     def action_draft(self, cr, uid, ids, context=None):
-#         """
-#         Picking wkf Draft action,
-#         Use Administrator operate intercompany action
-#         """
-
-#         assert len(ids) == 1
-#         self.action_intercompany(cr, SUPERUSER_ID, ids,
-#                                  node='draft', context=context)
-#         return True
-
-#     def action_confirm(self, cr, uid, ids, context=None):
-#         """
-#         Action confirm include intercompany action
-#         """
-
-#         res = super(stock_picking, self).action_confirm(cr, uid, ids,
-#                                                         context=context)
-#         if res:
-#             self.action_intercompany(cr, uid, ids, node='confirm',
-#                                      context=context)
-#         return res
-
-#     def action_cancel(self, cr, uid, ids, context=None):
-#         """
-#         """
-
-#         res = super(stock_picking, self).action_cancel(cr, uid, ids,
-#                                                        context=context)
-#         wkf_service = netsvc.LocalService("workflow")
-
-#         if res:
-#             for pick_id in ids:
-#                 ic_uid = self.get_intercompany(cr, uid, pick_id)[2]
-#                 pick_ic_ids = self.search(cr, uid,
-#                                           [('picking_ic_id', '=', pick_id)]
-#                                           )
-#                 for pick_ic_id in pick_ic_ids:
-#                     wkf_service.trg_validate(ic_uid, 'stock.picking',
-#                                              pick_ic_id, 'button_cancel', cr)
-
-#         return res
-
-#     def action_intercompany(self, cr, uid, ids, node=None, context=None):
-#         """
-#         @node, draft or confirm
-#         """
-
-#         assert len(ids) == 1
-#         cr.execute("SELECT type FROM stock_picking WHERE id=%s", (ids[0],))
-#         pick_type = cr.fetchone()[0]
-
-#         if pick_type in ['in', 'out']:
-#             o2o_field_name = pick_type == 'in' and 'is2do' or 'do2is'
-#             if self.need_to_create_intercompany_picking(
-#                     cr, uid, ids, o2o_field_name, node=node, context=context):
-#                 self.create_intercompany_picking(
-#                     cr, uid, ids, self_type=pick_type, context=None)
-
-#     def create_intercompany_picking(self, cr, uid,
-#                                     ids, self_type, context=None):
-#         """
-#         prepare out and prepare in is similar, but don to merger it,
-#         @self_type,  self.type
-#         """
-
-#         pick = self.browse(cr, uid, ids[0])
-#         cf, ct, ic_uid = self.get_intercompany(cr, uid, ids[0],
-#                                                context=context)
-#         picking_pool = (self_type == 'in'
-#                         and self.pool.get('stock.picking.out')
-#                         or self.pool.get('stock.picking.in'))
-
-#         if self_type == 'in':
-#             picking_data = self.prepare_intercompany_picking_out_data(
-#                 cr, uid, pick, ct, ic_uid, context=context)
-#         elif self_type == 'out':
-#             picking_data = self.prepare_intercompany_picking_in_data(
-#                 cr, uid, pick, ct, ic_uid, context=context)
-
-#         return picking_pool.create(cr, ic_uid, picking_data, context=context)
-
-#     def prepare_intercompany_picking_out_data(
-#             self, cr, uid, pick_in, company_to, ic_uid, context=None):
-#         """
-#         prepare the picking.out data
-#         @pick_in  browse record of stock.picking, type == in
-#         @company_to  the company_id of this picking.out record
-#         """
-
-#         context = context or {}
-#         # context for to create stock.move, count the location
-#         context.update({'picking_type': 'out'})
-#         part_pool = self.pool.get('res.partner')
-#         customer = part_pool.browse(cr, ic_uid,
-#                                     pick_in.company_id.partner_id.id)
-
-#         location_id = False
-#         cr.execute("""
-#         SELECT
-#             id
-#         FROM
-#             stock_location
-#         WHERE
-#             company_id=%s
-#             AND name='Stock'
-#         """, (company_to,))
-#         location = cr.fetchone()
-#         if location and location[0]:
-#             location_id = location[0]
-#         location_dest_id = (customer.property_stock_customer
-#                             and customer.property_stock_customer.id
-#                             or False)
-
-#         if (not location_dest_id or not location_id):
-#             raise osv.except_osv(
-#                 _('Error!'),
-#                 _("""prepare_intercompany_picking_out_data location%s
-#                     location_dest%s"""
-#                   % (location_id, location_dest_id)))
-
-#         move_lines_data = [(5,)]
-#         for move_line in pick_in.move_lines:
-#             line_data = {
-#                 #'picking_id':        ic_id,
-#                 'name': move_line.name,
-#                 'product_qty': move_line.product_qty,
-#                 'product_id': move_line.product_id.id,
-#                 'product_uom': move_line.product_uom.id,
-#                 'price_unit': move_line.price_unit,
-#                 'price_currency_id': (move_line.price_currency_id
-#                                       and move_line.price_currency_id.id
-#                                       or False),
-#                 'location_id': location_id,
-#                 'location_dest_id': location_dest_id,
-#                 'company_id': company_to,
-#             }
-#             move_lines_data.append((0, 0, line_data))
-
-#         picking_data = {
-#             'partner_id': customer.id,
-#             'picking_ic_id': pick_in.id,
-#             'is_locked': True,
-#             'ic_create': True,
-#             'company_id': company_to,
-#             'type': 'out',
-#             'origin': 'IC:' + pick_in.name,
-#             'move_lines': move_lines_data,
-#             'magento_bind_ids': False,
-#             'related_backorder_ids': False,
-#         }
-#         return picking_data
-
-#     def prepare_intercompany_picking_in_data(
-#             self, cr, uid, pick_out, company_to, ic_uid, context=None):
-#         """
-#         prepare the picking.out data
-#         @pick_out  browse record of stock.picking, type == in
-#         @company_to  the company_id of this picking.out record
-#         """
-#         context = context or {}
-#         #context for to create stock.move, count the location
-#         context.update({'picking_type': 'in'})
-#         part_pool = self.pool.get('res.partner')
-#         supplier = part_pool.browse(cr, ic_uid,
-#                                     pick_out.company_id.partner_id.id)
-
-#         location_id = (supplier.property_stock_supplier
-#                        and supplier.property_stock_supplier.id
-#                        or False)
-#         location_dest_id = False
-#         cr.execute("""
-#         SELECT
-#             id
-#         FROM
-#             stock_location
-#         WHERE
-#             company_id=%s
-#             AND name='Stock'
-#         """, (company_to,))
-#         location = cr.fetchone()
-#         if location and location[0]:
-#             location_dest_id = location[0]
-
-#         if (not location_dest_id or not location_id):
-#             raise osv.except_osv(
-#                 _('Error!'),
-#                 _('''prepare_intercompany_picking_in_data
-#                     location%s location_dest%s'''
-#                   % (location_id, location_dest_id)))
-
-#         move_lines_data = [(5,)]
-#         for move_line in pick_out.move_lines:
-#             line_data = {
-#                 #'picking_id': ic_id,
-#                 'name': move_line.name,
-#                 'product_qty': move_line.product_qty,
-#                 'product_id': move_line.product_id.id,
-#                 'product_uom': move_line.product_uom.id,
-#                 'price_unit': move_line.price_unit,
-#                 'price_currency_id': (move_line.price_currency_id
-#                                       and move_line.price_currency_id.id
-#                                       or False),
-#                 'location_id': location_id,
-#                 'location_dest_id': location_dest_id,
-#                 'company_id': company_to,
-#             }
-#             move_lines_data.append((0, 0, line_data))
-
-#         picking_data = {
-#             'partner_id': supplier.id,
-#             'picking_ic_id': pick_out.id,
-#             'is_locked': True,
-#             'ic_create': True,
-#             'company_id': company_to,
-#             'type': 'in',
-#             'origin': 'IC:' + pick_out.name,
-#             'move_lines': move_lines_data,
-#             'magento_bind_ids': False,
-#             'related_backorder_ids': False,
-#         }
-#         return picking_data
-
-# stock_picking()
-
-
-# class stock_picking_in(osv.osv):
-#     _inherit = 'stock.picking.in'
-#     _name = 'stock.picking.in'
-
-#     _columns = {
-#         'is_locked': fields.boolean('Locked for Intercompany'),
-#         'ic_create': fields.boolean('Intercompany Picking generated'),
-#         'picking_ic_id': fields.many2one('stock.picking', 'Stock Picking'),
-#     }
-
-#     def get_intercompany(self, cr, uid, id, context=None):
-#         """
-#         get company from and to
-#         """
-
-#         assert isinstance(id, int) or isinstance(id, long)
-#         cr.execute("""
-#         SELECT
-#             pick.company_id AS from_c, cmp.id AS to_c,cmp.intercompany_uid
-#         FROM
-#             stock_picking AS pick
-#             LEFT JOIN res_partner AS part ON (pick.partner_id=part.id)
-#             LEFT JOIN res_company AS cmp ON (part.id=cmp.partner_id)
-#         WHERE pick.id=%s
-#         """, (id,))
-#         return cr.fetchone()
-
-#     #this function is same as the stock.picking function,
-#     #when modify this function of  stock.picking ,
-#     #copy and replace this.
-#     def prepare_IC_pick_out(self, cr, uid, pick_in, company_to,
-#                             ic_uid, context=None):
-#         """
-#         prepare the picking.out data
-#         @pick_in  browse record of stock.picking, type == in
-#         @company_to  the company_id of this picking.out record
-#         """
-
-#         context = context or {}
-#         # context for to create stock.move, count the location
-#         context.update({'picking_type': 'out'})
-#         part_pool = self.pool.get('res.partner')
-#         customer = part_pool.browse(cr, ic_uid,
-#                                     pick_in.company_id.partner_id.id)
-#         location_id = False
-#         cr.execute("""
-#         SELECT
-#             id
-#         FROM
-#             stock_location
-#         WHERE company_id=%s
-#             AND name='Stock'
-#         """, (company_to,))
-
-#         location = cr.fetchone()
-#         if location and location[0]:
-#             location_id = location[0]
-#         location_dest_id = (customer.property_stock_customer
-#                             and customer.property_stock_customer.id
-#                             or False)
-
-#         if (not location_dest_id or not location_id):
-#             raise osv.except_osv(
-#                 _('Error!'),
-#                 _('''prepare_intercompany_picking_out_data
-#                 location%s location_dest%s'''
-#                     % (location_id, location_dest_id)))
-
-#         move_lines_data = [(5,)]
-#         for move_line in pick_in.move_lines:
-#             line_data = {
-#                 #'picking_id':        ic_id,
-#                 'name': move_line.name,
-#                 'product_qty': move_line.product_qty,
-#                 'product_id': move_line.product_id.id,
-#                 'product_uom': move_line.product_uom.id,
-#                 'price_unit': move_line.price_unit,
-#                 'price_currency_id': (move_line.price_currency_id
-#                                       and move_line.price_currency_id.id
-#                                       or False),
-#                 'location_id': location_id,
-#                 'location_dest_id': location_dest_id,
-#                 'company_id': company_to,
-#             }
-#             move_lines_data.append((0, 0, line_data))
-
-#         picking_data = {
-#             'partner_id': customer.id,
-#             'picking_ic_id': pick_in.id,
-#             'is_locked': True,
-#             'ic_create': True,
-#             'company_id': company_to,
-#             'type': 'out',
-#             'origin': 'IC:' + pick_in.name,
-#             'move_lines': move_lines_data,
-#             'magento_bind_ids': False,
-#             'related_backorder_ids': False,
-#         }
-#         return picking_data
-
-#     def write(self, cr, uid, ids, values, context=None,
-#               ban_update_out=False, ban_inverse_out=False):
-#         """
-#         @need_update_out
-#             auto: according the IC set,return True or False
-#             True   update_intercompany_picking_out
-#             False  no update_intercompany_picking_out
-#         @need_inverse_out
-#             like need_update_out
-#         """
-#         print """>>>>picking in write ids:%s ban_update_out%s,
-#             ban_inverse_out%s
-#             """ % (ids, ban_update_out, ban_inverse_out)
-#         if isinstance(ids, int) or isinstance(ids, long):
-#             ids = [ids]
-#         res = super(stock_picking_in, self).write(cr, uid, ids,
-#                                                   values, context=context)
-
-#         if res and not ban_update_out:
-#             self.update_IC_pick_out(cr, SUPERUSER_ID, ids, context=context)
-#         if res and not ban_inverse_out:
-#             self.inverse_IC_pick_out(cr, SUPERUSER_ID, ids, context=context)
-#         return res
-
-#     def update_IC_pick_out(self, cr, uid, ids, context=None):
-#         """
-#         """
-#         out_pool = self.pool.get('stock.picking.out')
-#         ic_pool = self.pool.get('res.intercompany')
-
-#         for pick_in in self.browse(cr, uid, ids, context):
-#             out_id = out_pool.search(
-#                 cr, uid, [('picking_ic_id', '=', pick_in.id)])
-#             if out_id:
-#                 cf, ct, ic_uid = self.get_intercompany(cr, uid, pick_in.id,
-#                                                        context=context)
-#                 modify_mode = ic_pool.get_modify_model(cr, uid, cf,
-#                                                        ct, 'is2do',)
-#                 if modify_mode in ['regular', 'bidirectional']:
-#                     p_out_data = self.prepare_IC_pick_out(
-#                         cr, uid, pick_in, ct, ic_uid, context=context)
-#                     out_pool.write(cr, ic_uid, out_id,
-#                                    p_out_data, ban_inverse_in=True)
-#         return True
-
-#     def inverse_IC_pick_out(self, cr, uid, ids, context=None):
-#         """
-#         """
-#         pick_out_pool = self.pool.get('stock.picking.out')
-#         intercompany_pool = self.pool.get('res.intercompany')
-
-#         for pick_in in self.browse(cr, uid, ids, context=context):
-#             pick_out = pick_in.picking_ic_id
-#             if pick_out:
-#                 company_from, company_to = pick_out_pool.get_intercompany(
-#                     cr, uid, pick_out.id)[0:2]
-#                 modify_mode = intercompany_pool.get_modify_model(
-#                     cr, uid, company_from, company_to, 'do2is',)
-#                 if modify_mode in ['inverse', 'bidirectional']:
-
-#                     lines_data = [(5,)]
-#                     #TODO, all location is the same ?
-#                     #or how to make sure the location?
-#                     location_id = pick_out.move_lines[0].location_id.id
-#                     dest_id = pick_out.move_lines[0].location_dest_id.id
-
-#                     for in_line in pick_in.move_lines:
-#                         data = (0, 0, {
-#                             'name': in_line.name,
-#                             'product_qty': in_line.product_qty,
-#                             'product_id': in_line.product_id.id,
-#                             'product_uom': in_line.product_uom.id,
-#                             'price_unit': in_line.price_unit,
-#                             'price_currency_id': (
-#                                 in_line.price_currency_id
-#                                 and in_line.price_currency_id.id
-#                                 or False),
-#                             'location_id': location_id,
-#                             'location_dest_id': dest_id,
-#                             'company_id': pick_out.company_id.id,
-#                         })
-#                         lines_data.append(data)
-
-#                     pick_out_pool.write(cr, uid, pick_out.id,
-#                                         {'move_lines': lines_data},
-#                                         ban_update_in=True)
-#         return True
-
-#     def unlink(self, cr, uid, ids, context=None):
-#         res = super(stock_picking_in, self).unlink(cr, uid, ids,
-#                                                    context=context)
-#         if isinstance(ids, int) or isinstance(ids, long):
-#             ids = [ids]
-
-#         pick_out_pool = self.pool.get('stock.picking.out')
-#         for pick_in_id in ids:
-#             pick_out_ids = pick_out_pool.search(
-#                 cr, uid,
-#                 [('picking_ic_id', '=', pick_in_id)],
-#                 context=context)
-#             if pick_out_ids:
-#                 pick_out_pool.unlink(cr, uid, pick_out_ids, context=context)
-#         return res
-
-# stock_picking_in()
-
-
-# class stock_picking_out(osv.osv):
-#     _inherit = 'stock.picking.out'
-#     _name = 'stock.picking.out'
-
-#     _columns = {
-#         'is_locked': fields.boolean('Locked for Intercompany'),
-#         'ic_create': fields.boolean('Intercompany Picking generated'),
-#         'picking_ic_id': fields.many2one('stock.picking', 'Stock Picking'),
-#     }
-
-#     def get_intercompany(self, cr, uid, id, context=None):
-#         """
-#         get company from and to
-#         """
-
-#         assert isinstance(id, int) or isinstance(id, long)
-#         cr.execute("""
-#         SELECT
-#             pick.company_id AS from_c, cmp.id AS to_c, cmp.intercompany_uid
-#         FROM stock_picking AS pick
-#             LEFT JOIN res_partner AS part ON (pick.partner_id=part.id)
-#             LEFT JOIN res_company AS cmp  ON (part.id=cmp.partner_id)
-#         WHERE pick.id=%s
-#         """, (id,))
-#         return cr.fetchone()
-
-#     def write(self, cr, uid, ids, values, context=None,
-#               ban_update_in=False, ban_inverse_in=False):
-#         """
-#         """
-
-#         res = super(stock_picking_out, self).write(cr, uid, ids,
-#                                                    values, context=context)
-#         if isinstance(ids, int) or isinstance(ids, long):
-#             ids = [ids]
-#         if res and not ban_update_in:
-#             self.update_IC_pick_in(cr, SUPERUSER_ID, ids, context=context)
-#         if res and not ban_inverse_in:
-#             self.inverse_IC_pick_in(cr, SUPERUSER_ID, ids, context=context)
-
-#         return res
-
-#     def update_IC_pick_in(self, cr, uid, ids, context=None):
-#         pick_in_obj = self.pool.get('stock.picking.in')
-#         ic_pool = self.pool.get('res.intercompany')
-
-#         for pick_out in self.browse(cr, uid, ids, context):
-#             pick_in_id = pick_in_obj.search(
-#                 cr, uid, [('picking_ic_id', '=', pick_out.id)])
-#             if pick_in_id:
-#                 cf, ct, ic_uid = self.get_intercompany(cr, uid, pick_out.id,
-#                                                        context=context)
-#                 modify_mode = ic_pool.get_modify_model(cr, uid, cf, ct,
-#                                                        'do2is',)
-#                 if modify_mode in ['regular', 'bidirectional']:
-#                     p_in_data = self.prepare_intercompany_picking_in_data(
-#                         cr, uid, pick_out, ct, ic_uid, context=context)
-#                     pick_in_obj.write(cr, ic_uid, pick_in_id, p_in_data,
-#                                       ban_inverse_out=True)
-#         return True
-
-#     def inverse_IC_pick_in(self, cr, uid, ids, context=None):
-#         """
-#         """
-
-#         pick_in_pool = self.pool.get('stock.picking.in')
-#         intercompany_pool = self.pool.get('res.intercompany')
-
-#         for pick_out in self.browse(cr, uid, ids, context=context):
-#             pick_in = pick_out.picking_ic_id
-#             if pick_in:
-#                 cf, ct = pick_in_pool.get_intercompany(cr, uid,
-#                                                        pick_in.id)[0:2]
-#                 modify_mode = intercompany_pool.get_modify_model(cr, uid, cf,
-#                                                                  ct, 'is2do',)
-#                 if modify_mode in ['inverse', 'bidirectional']:
-#                     lines_data = [(5,)]
-#                     #TODO, all location is the same ?
-#                     #or how to make sure the location?
-#                     location_id = pick_in.move_lines[0].location_id.id
-#                     dest_id = pick_in.move_lines[0].location_dest_id.id
-
-#                     for out_line in pick_out.move_lines:
-#                         data = (0, 0, {
-#                             'picking_id': pick_in.id,
-#                             'name': out_line.name,
-#                             'product_qty': out_line.product_qty,
-#                             'product_id': out_line.product_id.id,
-#                             'product_uom': out_line.product_uom.id,
-#                             'price_unit': out_line.price_unit,
-#                             'price_currency_id': (
-#                                 out_line.price_currency_id
-#                                 and out_line.price_currency_id.id
-#                                 or False),
-#                             'location_id': location_id,
-#                             'location_dest_id': dest_id,
-#                             'company_id': pick_in.company_id.id,
-#                         })
-#                         lines_data.append(data)
-#                     #pick_in_uid = pick_in.create_uid or
-#                     #pick_in.company_id.itercompany_uid
-#                     pick_in_pool.write(cr, uid, pick_in.id,
-#                                        {'move_lines': lines_data},
-#                                        ban_update_out=True)
-#         return True
-
-#     def unlink(self, cr, uid, ids, context=None):
-#         res = super(stock_picking_out, self).unlink(cr, uid, ids,
-#                                                     context=context)
-#         if isinstance(ids, int) or isinstance(ids, long):
-#             ids = [ids]
-
-#         pick_in_pool = self.pool.get('stock.picking.in')
-#         for pick_out_id in ids:
-#             pick_in_ids = pick_in_pool.search(
-#                 cr, uid, [('picking_ic_id', '=', pick_out_id)],
-#                 context=context)
-#             if pick_in_ids:
-#                 pick_in_pool.unlink(cr, uid, pick_in_ids, context=context)
-#         return res
-
-#     #this function is same as stock.picking,
-#     #when modify that, copy and replace this
-#     def prepare_intercompany_picking_in_data(
-#             self, cr, uid, pick_out, company_to, ic_uid, context=None):
-#         """
-#         prepare the picking.out data
-#         @pick_out  browse record of stock.picking, type == in
-#         @company_to  the company_id of this picking.out record
-#         """
-
-#         context = context or {}
-#         # context for to create stock.move, count the location
-#         context.update({'picking_type': 'in'})
-#         part_pool = self.pool.get('res.partner')
-#         supplier_id = pick_out.company_id.partner_id.id
-#         supplier = part_pool.browse(cr, ic_uid, supplier_id)
-
-#         location_id = (supplier.property_stock_supplier
-#                        and supplier.property_stock_supplier.id
-#                        or False)
-#         location_dest_id = False
-#         cr.execute("""
-#         SELECT
-#             id
-#         FROM
-#             stock_location
-#         WHERE company_id=%s
-#             AND name='Stock'
-#         """, (company_to,))
-#         location = cr.fetchone()
-#         if location and location[0]:
-#             location_dest_id = location[0]
-
-#         if (not location_dest_id or not location_id):
-#             raise osv.except_osv(
-#                 _('Error!'),
-#                 _('''prepare_intercompany_picking_in_data
-#                     location%s location_dest%s'''
-#                     % (location_id, location_dest_id)))
-
-#         move_lines_data = [(5,)]
-#         for move_line in pick_out.move_lines:
-#             line_data = {
-#                 #'picking_id': ic_id,
-#                 'name': move_line.name,
-#                 'product_qty': move_line.product_qty,
-#                 'product_id': move_line.product_id.id,
-#                 'product_uom': move_line.product_uom.id,
-#                 'price_unit': move_line.price_unit,
-#                 'price_currency_id': (move_line.price_currency_id
-#                                       and move_line.price_currency_id.id
-#                                       or False),
-#                 'location_id': location_id,
-#                 'location_dest_id': location_dest_id,
-#                 'company_id': company_to,
-#             }
-#             move_lines_data.append((0, 0, line_data))
-
-#         picking_data = {
-#             'partner_id': supplier.id,
-#             'picking_ic_id': pick_out.id,
-#             'is_locked': True,    
-#             'ic_create': True,
-#             'company_id': company_to,
-#             'type': 'in',
-#             'origin': 'IC:' + pick_out.name,
-#             'move_lines': move_lines_data,
-#             'magento_bind_ids': False,
-#             'related_backorder_ids': False,
-#         }
-#         return picking_data
-
-# stock_picking_out()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== removed file 'base_intercompany/stock_picking_wkf.xml'
--- base_intercompany/stock_picking_wkf.xml	2013-11-29 04:03:22 +0000
+++ base_intercompany/stock_picking_wkf.xml	1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<openerp>
-	<data>
-		<record id="stock.act_draft" model="workflow.activity">
-		    <field name="kind">function</field>
-		    <field name="action">action_draft()</field>
-		</record>
-	</data>
-</openerp>
\ No newline at end of file

=== removed directory 'base_intercompany/tests'
=== removed file 'base_intercompany/tests/__init__.py'
--- base_intercompany/tests/__init__.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/tests/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
-import test_sale
-
-fast_suite = [
-]
-
-checks = [
-    # test_sale
-]

=== removed file 'base_intercompany/tests/test_sale.py'
--- base_intercompany/tests/test_sale.py	2013-11-29 04:03:22 +0000
+++ base_intercompany/tests/test_sale.py	1970-01-01 00:00:00 +0000
@@ -1,559 +0,0 @@
-import mock
-import unittest2
-from datetime import datetime, timedelta
-
-import openerp
-import openerp.tests.common as common
-from openerp.osv import osv
-
-DB = common.DB
-ADMIN_USER_ID = common.ADMIN_USER_ID
-
-
-class test_icops_sale(common.TransactionCase):
-
-    def setUp(self):
-        super(test_icops_sale, self).setUp()
-        # get super user
-        self.m = self.registry('ir.model.data')
-        self.user_pool = self.registry('res.users')
-        self.super_user = self.user_pool.browse(self.cr, self.uid, self.uid)
-        # creates companies
-        self.company_1 = self.m.get_object(
-            self.cr, self.uid, 'base', 'main_company')
-
-        self.company_2 = self.m.get_object(
-            self.cr, self.uid, 'multi_company', 'res_company_oerp_be')
-
-        self.user_1 = self.m.get_object(
-            self.cr, self.uid, 'base_intercompany', 'user_icops1')
-
-        self.user_2 = self.m.get_object(
-            self.cr, self.uid, 'base_intercompany', 'user_icops2')
-
-        self.shop_1 = self.m.get_object(
-            self.cr, self.uid, 'base_intercompany',
-            'sale_shop_icops_1')
-
-        self.shop_2 = self.m.get_object(
-            self.cr, self.uid, 'base_intercompany',
-            'sale_shop_icops_2')
-
-        company_pool = self.registry('res.company')
-        company_pool.write(
-            self.cr, self.uid, self.company_1.id,
-            {'intercompany_uid': self.user_1.id,
-             'intercompany_shop_id': self.shop_1.id})
-
-        company_pool.write(
-            self.cr, self.uid, self.company_2.id,
-            {'intercompany_uid': self.user_2.id,
-             'intercompany_shop_id': self.shop_2.id})
-
-        self.icops_pool = self.registry('res.intercompany')
-        self.so_pool = self.registry('sale.order')
-        self.po_pool = self.registry('purchase.order')
-
-    def test_01_so_creates_po(self):
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'regular'})
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_2.partner_id.id,
-            'partner_invoice_id': self.company_2.partner_id.id,
-            'partner_shipping_id': self.company_2.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-        self.assertTrue(so.purchase_id.id)
-        po = self.po_pool.browse(self.cr, self.uid, so.purchase_id.id)
-        self.assertIsNotNone(po.id)
-        self.assertEqual(so.purchase_id.id, po.id)
-        self.assertEqual(po.sale_id.id, so.id)
-
-    def test_02_creates_normal_so(self):
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'regular'})
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_1.partner_id.id,
-            'partner_invoice_id': self.company_1.partner_id.id,
-            'partner_shipping_id': self.company_1.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-        self.assertFalse(so.purchase_id.id)
-
-    def test_03_so_creates_po_updates_so_line_regular(self):
-        product = self.m.get_object(
-            self.cr, self.uid, 'product', 'product_product_1')
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'regular'})
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_2.partner_id.id,
-            'partner_invoice_id': self.company_2.partner_id.id,
-            'partner_shipping_id': self.company_2.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-        po = so.purchase_id
-        self.assertEqual(so.order_line, po.order_line)
-        sol = [(0, False, {
-            'product_uos_qty': 1, 'product_id': product.id,
-            'product_uom': 1, 'price_unit': 885,
-            'product_uom_qty': 1, 'th_weight': 0, 'product_uos': False,
-            'tax_id': [[6, False, []]],
-            'name': product.name})]
-        self.so_pool.write(
-            self.cr, self.user_1.id, so.id, {'order_line': sol})
-        so = self.so_pool.browse(
-            self.cr, self.user_1.id, so.id)
-
-        self.assertEqual(len(so.order_line), 1)
-
-        po = self.po_pool.browse(
-            self.cr, self.user_2.id, po.id)
-        self.assertEqual(
-            so.order_line[0].product_id, po.order_line[0].product_id)
-        self.assertEqual(
-            so.order_line[0].product_uom_qty, po.order_line[0].product_qty)
-
-    def test_04_so_creates_po_updates_so_line_inverse(self):
-        product = self.m.get_object(
-            self.cr, self.uid, 'product', 'product_product_1')
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'inverse'})
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_2.partner_id.id,
-            'partner_invoice_id': self.company_2.partner_id.id,
-            'partner_shipping_id': self.company_2.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-        po = so.purchase_id
-        self.assertEqual(so.order_line, po.order_line)
-        sol = [(0, False, {
-            'product_uos_qty': 1, 'product_id': product.id,
-            'product_uom': 1, 'price_unit': 885,
-            'product_uom_qty': 1, 'th_weight': 0, 'product_uos': False,
-            'tax_id': [[6, False, []]],
-            'name': product.name})]
-
-        self.assertEqual(len(so.order_line), 0)
-        a = None
-        with self.assertRaises(osv.except_osv):
-            a = self.so_pool.write(
-                self.cr, self.user_1.id, so.id, {'order_line': sol})
-
-        so = self.so_pool.browse(
-            self.cr, self.user_1.id, so.id)
-
-        self.assertEqual(len(so.order_line), 0)
-
-        pol = [(0, False, {
-            'product_id': product.id,
-            'name': product.name,
-            'date_planned': '10/20/2013',
-            'product_qty': 1,
-            'price_unit': 885,
-            'product_uom': 1,
-            'tax_id': [[6, False, []]]
-        })]
-        self.po_pool.write(
-            self.cr, self.user_2.id, po.id, {'order_line': pol})
-
-        so = self.so_pool.browse(
-            self.cr, self.user_1.id, so.id)
-
-        self.assertEqual(len(so.order_line), 1)
-
-        po = self.po_pool.browse(
-            self.cr, self.user_2.id, po.id)
-        self.assertEqual(
-            so.order_line[0].product_id, po.order_line[0].product_id)
-        self.assertEqual(
-            so.order_line[0].product_uom_qty, po.order_line[0].product_qty)
-
-    # def test_05_so_creates_po_updates_so_line_bidirectional(self):
-    #     product = self.m.get_object(
-    #         self.cr, self.uid, 'product', 'product_product_1')
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'draft',
-    #          'direction': 'bidirectional'})
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-    #     po = so.purchase_id
-    #     self.assertEqual(so.order_line, po.order_line)
-    #     sol = [(0, False, {
-    #         'product_uos_qty': 1, 'product_id': product.id,
-    #         'product_uom': 1, 'price_unit': 885,
-    #         'product_uom_qty': 1, 'th_weight': 0, 'product_uos': False,
-    #         'tax_id': [[6, False, []]],
-    #         'name': product.name})]
-    #     self.so_pool.write(
-    #         self.cr, self.user_1.id, so.id, {'order_line': sol})
-    #     so = self.so_pool.browse(
-    #         self.cr, self.user_1.id, so.id)
-
-    #     self.assertEqual(len(so.order_line), 1)
-
-    #     po = self.po_pool.browse(
-    #         self.cr, self.user_2.id, po.id)
-
-    #     self.assertEqual(
-    #         so.order_line[0].product_id, po.order_line[0].product_id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_uom_qty, po.order_line[0].product_qty)
-
-    #     self.assertEqual(po.order_line[0].product_qty, 1)
-    #     pol = [(1, po.order_line[0].id, {
-    #         'product_qty': 2,
-    #     })]
-    #     self.po_pool.write(
-    #         self.cr, self.user_2.id, po.id, {'order_line': pol})
-
-    #     so = self.so_pool.browse(
-    #         self.cr, self.user_1.id, so.id)
-
-    #     self.assertEqual(len(so.order_line), 1)
-
-    #     po = self.po_pool.browse(
-    #         self.cr, self.user_2.id, po.id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_id, po.order_line[0].product_id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_uom_qty, po.order_line[0].product_qty)
-    #     self.assertEqual(so.order_line[0].product_uom_qty, 2)
-
-    # def test_06_delete_so(self):
-
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     result = self.so_pool.unlink(self.cr, self.user_1.id, sale_id)
-    #     self.assertTrue(result)
-
-    def test_07_so_deletes_po(self):
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'regular'})
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'unlink',
-             'direction': 'regular'})
-
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_2.partner_id.id,
-            'partner_invoice_id': self.company_2.partner_id.id,
-            'partner_shipping_id': self.company_2.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-        po_ids = self.po_pool.search(
-            self.cr, self.uid, [('sale_id', '=', so.id)])
-
-        self.assertEqual(len(po_ids), 1)
-
-        self.so_pool.unlink(
-            self.cr, self.user_1.id, so.id)
-
-        po_ids = self.po_pool.search(
-            self.cr, self.user_2.id, [('sale_id', '=', so.id)])
-        self.assertEqual(len(po_ids), 0)
-
-    def test_07_so_deletes_po_inverse(self):
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'draft',
-             'direction': 'regular'})
-
-        self.icops_pool.create(
-            self.cr, self.uid,
-            {'company_from': self.company_1.id,
-             'company_to': self.company_2.id,
-             'obj2obj': 'so2po',
-             'status': 'unlink',
-             'direction': 'inverse'})
-
-        sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-            'partner_id': self.company_2.partner_id.id,
-            'partner_invoice_id': self.company_2.partner_id.id,
-            'partner_shipping_id': self.company_2.partner_id.id,
-            'shop_id': self.shop_1.id,
-            'date_order': datetime.now().strftime('%Y-%m-%d'),
-            'pricelist_id': self.user_1.property_product_pricelist.id
-        })
-        so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-        po_ids = self.po_pool.search(
-            self.cr, self.user_2.id, [('sale_id', '=', so.id)])
-
-        self.assertEqual(len(po_ids), 1)
-
-        so_ids = self.so_pool.search(
-            self.cr, self.user_1.id, [('purchase_id', '=', so.purchase_id.id)])
-
-        self.assertEqual(len(po_ids), 1)
-
-        # with self.assertRaises(osv.except_osv):
-        #     self.so_pool.unlink(
-        #         self.cr, self.user_1.id, so.id)
-
-        # so_ids = self.so_pool.search(
-        #     self.cr, self.user_1.id, [('purchase_id', '=', so.purchase_id.id)])
-
-        # self.assertEqual(len(po_ids), 1)
-
-        self.po_pool.unlink(
-            self.cr, self.user_2.id, so.purchase_id.id)
-
-        so_ids = self.so_pool.search(
-            self.cr, self.user_1.id, [('purchase_id', '=', so.purchase_id.id)])
-
-        self.assertEqual(len(so_ids), 0)
-
-    # def test_08_so_deletes_po_bidirectional_1(self):
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'draft',
-    #          'direction': 'regular'})
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'unlink',
-    #          'direction': 'bidirectional'})
-
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-    #     po_ids = self.po_pool.search(
-    #         self.cr, self.uid, [('sale_id', '=', so.id)])
-
-    #     self.assertEqual(len(po_ids), 1)
-
-    #     self.so_pool.unlink(
-    #         self.cr, self.user_1.id, so.id)
-
-    #     po_ids = self.po_pool.search(
-    #         self.cr, self.user_2.id, [('sale_id', '=', so.id)])
-    #     self.assertEqual(len(po_ids), 0)
-
-    # def test_09_so_deletes_po_bidirectional_2(self):
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'draft',
-    #          'direction': 'regular'})
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'unlink',
-    #          'direction': 'bidirectional'})
-
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-    #     po_ids = self.po_pool.search(
-    #         self.cr, self.uid, [('sale_id', '=', so.id)])
-
-    #     self.assertEqual(len(po_ids), 1)
-
-    #     self.po_pool.unlink(
-    #         self.cr, self.user_2.id, so.purchase_id.id)
-
-    #     so_ids = self.so_pool.search(
-    #         self.cr, self.user_1.id, [('purchase_id', '=', so.purchase_id.id)])
-    #     self.assertEqual(len(so_ids), 0)
-
-    # def test_100_so_creates_po_double_setup(self):
-    #     product = self.m.get_object(
-    #         self.cr, self.uid, 'product', 'product_product_1')
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'draft',
-    #          'direction': 'bidirectional'})
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_2.id,
-    #          'company_to': self.company_1.id,
-    #          'obj2obj': 'po2so',
-    #          'status': 'draft',
-    #          'direction': 'bidirectional'})
-
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-    #     po = so.purchase_id
-    #     self.assertEqual(so.order_line, po.order_line)
-    #     sol = [(0, False, {
-    #         'product_uos_qty': 1, 'product_id': product.id,
-    #         'product_uom': 1, 'price_unit': 885,
-    #         'product_uom_qty': 1, 'th_weight': 0, 'product_uos': False,
-    #         'tax_id': [[6, False, []]],
-    #         'name': product.name})]
-    #     self.so_pool.write(
-    #         self.cr, self.user_1.id, so.id, {'order_line': sol})
-    #     so = self.so_pool.browse(
-    #         self.cr, self.user_1.id, so.id)
-
-    #     self.assertEqual(len(so.order_line), 1)
-
-    #     po = self.po_pool.browse(
-    #         self.cr, self.user_2.id, po.id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_id, po.order_line[0].product_id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_uom_qty, po.order_line[0].product_qty)
-
-    # def test_101_so_creates_po_double_setup_inverse(self):
-    #     product = self.m.get_object(
-    #         self.cr, self.uid, 'product', 'product_product_1')
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_1.id,
-    #          'company_to': self.company_2.id,
-    #          'obj2obj': 'so2po',
-    #          'status': 'draft',
-    #          'direction': 'inverse'})
-
-    #     self.icops_pool.create(
-    #         self.cr, self.uid,
-    #         {'company_from': self.company_2.id,
-    #          'company_to': self.company_1.id,
-    #          'obj2obj': 'po2so',
-    #          'status': 'draft',
-    #          'direction': 'inverse'})
-
-    #     sale_id = self.so_pool.create(self.cr, self.user_1.id, {
-    #         'partner_id': self.company_2.partner_id.id,
-    #         'partner_invoice_id': self.company_2.partner_id.id,
-    #         'partner_shipping_id': self.company_2.partner_id.id,
-    #         'shop_id': self.shop_1.id,
-    #         'date_order': datetime.now().strftime('%Y-%m-%d'),
-    #         'pricelist_id': self.user_1.property_product_pricelist.id
-    #     })
-    #     so = self.so_pool.browse(self.cr, self.user_1.id, sale_id)
-
-    #     po = so.purchase_id
-    #     self.assertEqual(so.order_line, po.order_line)
-    #     sol = [(0, False, {
-    #         'product_uos_qty': 1, 'product_id': product.id,
-    #         'product_uom': 1, 'price_unit': 885,
-    #         'product_uom_qty': 1, 'th_weight': 0, 'product_uos': False,
-    #         'tax_id': [[6, False, []]],
-    #         'name': product.name})]
-    #     self.so_pool.write(
-    #         self.cr, self.user_1.id, so.id, {'order_line': sol})
-    #     so = self.so_pool.browse(
-    #         self.cr, self.user_1.id, so.id)
-
-    #     self.assertEqual(len(so.order_line), 1)
-
-    #     po = self.po_pool.browse(
-    #         self.cr, self.user_2.id, po.id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_id, po.order_line[0].product_id)
-    #     self.assertEqual(
-    #         so.order_line[0].product_uom_qty, po.order_line[0].product_qty)

=== added directory 'base_intercompany/unit'
=== added file 'base_intercompany/unit/__init__.py'
--- base_intercompany/unit/__init__.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/unit/__init__.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import binder
+import export_synchronizer
+import backend_adapter

=== added file 'base_intercompany/unit/backend_adapter.py'
--- base_intercompany/unit/backend_adapter.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/unit/backend_adapter.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import logging
+from openerp.addons.connector.unit.backend_adapter import CRUDAdapter
+
+_logger = logging.getLogger(__name__)
+recorder = {}
+
+
+def call_to_key(method, arguments):
+    """ Used to 'freeze' the method and arguments of a call to Coswin
+    so they can be hashable; they will be stored in a dict.
+
+    Used in both the recorder and the tests.
+    """
+    def freeze(arg):
+        if isinstance(arg, dict):
+            items = dict((key, freeze(value)) for key, value
+                         in arg.iteritems())
+            return frozenset(items.iteritems())
+        elif isinstance(arg, list):
+            return tuple([freeze(item) for item in arg])
+        else:
+            return arg
+
+    new_args = []
+    for arg in arguments:
+        new_args.append(freeze(arg))
+    return (method, tuple(new_args))
+
+
+def record(method, arguments, result):
+    """ Utility function which can be used to record test data
+    during synchronisations. Call it from CoswinOracleAdapter._call
+
+    Then ``output_recorder`` can be used to write the data recorded
+    to a file.
+    """
+    recorder[call_to_key(method, arguments)] = result
+
+
+def output_recorder(filename):
+    import pprint
+    with open(filename, 'w') as f:
+        pprint.pprint(recorder, f)
+    _logger.debug('recorder written to file %s', filename)
+
+
+# class ICOPSLocation(object):
+
+#     def __init__(self, location, db_name, username, password):
+#         self.location = location
+#         self.db_name = db_name
+#         self.username = username
+#         self.password = password
+
+
+class GenericAdapter(CRUDAdapter):
+
+    """ External Records Adapter for Coswin """
+
+    def __init__(self, environment):
+        """
+
+        :param environment: current environment (backend, session, ...)
+        :type environment: :py:class:`connector.connector.Environment`
+        """
+        super(GenericAdapter, self).__init__(environment)
+        # self.icops = ICOPSLocation(self.backend_record.icops_server,
+        #                              self.backend_record.backup_server)
+
+    def search(self, filters=None):
+        """ Search records according to some criterias
+        and returns a list of ids """
+        raise NotImplementedError
+
+    def read(self, id, attributes=None):
+        """ Returns the information of a record """
+        raise NotImplementedError
+
+    def search_read(self, filters=None):
+        """ Search records according to some criterias
+        and returns their information"""
+        raise NotImplementedError
+
+    def create(self, data):
+        """ Create a record on the external system """
+        raise NotImplementedError
+
+    def write(self, id, data):
+        """ Update records on the external system """
+        raise NotImplementedError
+
+    def delete(self, id):
+        """ Delete a record on the external system """
+        raise NotImplementedError
+
+    def _write(self, text):
+        return True
+
+
+class ICOPSAdapter(GenericAdapter):
+
+    _model_name = None
+
+    def __init__(self, environment):
+        super(GenericAdapter, self).__init__(environment)
+        self._icops = None
+        self._backend_to = None
+
+    def _get_pool(self):
+        raise NotImplementedError
+
+    def create(self, data):
+        sess = self.session
+        pool = self._get_pool()
+        return pool.create(
+            sess.cr, self._backend_to.icops_uid.id, data, {'icops': True})
+
+    def write(self, id, data):
+        sess = self.session
+        pool = self._get_pool()
+        pool.write(sess.cr, self._backend_to.icops_uid.id, id, data)
+
+    def delete(self, id):
+        sess = self.session
+        pool = self._get_pool()
+        pool.unlink(sess.cr, self._backend_to.icops_uid.id, [id])

=== added file 'base_intercompany/unit/binder.py'
--- base_intercompany/unit/binder.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/unit/binder.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from datetime import datetime
+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
+from openerp.addons.connector.connector import Binder
+from ..backend import icops
+
+
+class ICOPSBinder(Binder):
+    """ Generic Binder for ICOPS """
+
+
+@icops
+class ICOPSModelBinder(ICOPSBinder):
+    """
+    Bindings are done directly on the binding model.
+
+    Binding models are models called ``icops.{normal_model}``,
+    like ``icops.res.partner`` or ``icops.sale.order``.
+    They are ``_inherits`` of the normal models and contains
+    the ICOPS ID, the ID of the ICOPS Backend and the additional
+    fields belonging to the ICOPS instance.
+    """
+    _model_name = [
+        'icops.sale.order',
+        'icops.sale.order.line',
+        'icops.purchase.order',
+        'icops.purchase.order.line'
+    ]
+
+    def to_openerp(self, external_id, unwrap=False):
+        """ Give the OpenERP ID for an external ID
+
+        :param external_id: external ID for which we want the OpenERP ID
+        :param unwrap: if True, returns the openerp_id of the icops_xxxx
+        record, else return the id (binding id) of that record
+        :return: a record ID, depending on the value of unwrap,
+                 or None if the external_id is not mapped
+        :rtype: int
+        """
+        binding_ids = self.session.search(
+            self.model._name,
+            [('icops_id', '=', external_id),
+             ('backend_id', '=', self.backend_record.id)])
+        if not binding_ids:
+            return None
+        assert len(binding_ids) == 1, "Several records found: %s" % binding_ids
+        binding_id = binding_ids[0]
+        if unwrap:
+            return self.session.read(self.model._name,
+                                     binding_id,
+                                     ['openerp_id'])['openerp_id'][0]
+        else:
+            return binding_id
+
+    def to_backend(self, binding_id):
+        """ Give the external ID for an OpenERP ID
+
+        :param binding_id: OpenERP ID for which we want the external id
+        :return: backend identifier of the record
+        """
+        record = self.session.browse(self.model._name,
+                                     binding_id)
+        assert record
+        res = {}
+        for icops in record.icops_ids:
+            key = '%s_%s' % (icops.backend_id.id, icops.concept)
+            res[key] = icops.record_id
+        return res
+
+    def bind(self, records, binding_id):
+        """ Create the link between an external ID and an OpenERP ID and
+        update the last synchronization date.
+
+        :param external_ids: External ID to bind
+        :param binding_id: OpenERP ID to bind
+        :type binding_id: int
+        """
+        # avoid to trigger the export when we modify the `icops_id`
+        if not records:
+            return
+        context = self.session.context.copy()
+        context['connector_no_export'] = True
+        now_fmt = datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
+        icops_ids = []
+        for record, record_id in records.items():
+            backend_id, concept = record.split('_')
+
+            icops_id = (0, 0, {'record_id': record_id,
+                        'backend_id': backend_id,
+                        'concept': concept,
+                        'binding_id': binding_id})
+            icops_ids.append(icops_id)
+
+        self.environment.model.write(
+            self.session.cr,
+            self.session.uid,
+            binding_id,
+            {'icops_ids': icops_ids, 'sync_date': now_fmt},
+            context=context)

=== added file 'base_intercompany/unit/export_synchronizer.py'
--- base_intercompany/unit/export_synchronizer.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/unit/export_synchronizer.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,238 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import logging
+from openerp.tools.translate import _
+from openerp.addons.connector.queue.job import job
+from openerp.addons.connector.unit.synchronizer import ExportSynchronizer
+from ..connector import get_environment
+from openerp.addons.connector.exception import MappingError
+from osv import osv
+
+_logger = logging.getLogger(__name__)
+
+
+"""
+
+Exporters for ICOPS.
+
+In addition to its export job, an exporter has to:
+
+* check in ICOPS if the record has been updated more recently than the
+  last sync date and if yes, delay an import
+* call the ``bind`` method of the binder to update the last sync date
+
+"""
+
+
+class ICOPSBaseExporter(ExportSynchronizer):
+
+    """ Base exporter for ICOPS """
+
+    def __init__(self, environment):
+        """
+        :param environment: current environment (backend, session, ...)
+        :type environment: :py:class:`connector.connector.Environment`
+        """
+        super(ICOPSBaseExporter, self).__init__(environment)
+        self.binding_id = None
+        self.icops_ids = {}
+
+    def _get_openerp_data(self):
+        """ Return the raw OpenERP data for ``self.binding_id`` """
+        return self.session.browse(self.model._name, self.binding_id)
+
+    def run(self, binding_id, *args, **kwargs):
+        """ Run the synchronization
+
+        :param binding_id: identifier of the binding record to export
+        """
+        self.binding_id = binding_id
+        self.binding_record = self._get_openerp_data()
+
+        self.icops_ids = self.binder.to_backend(self.binding_id)
+        result = self._run(*args, **kwargs)
+        self.binder.bind(self.icops_ids, self.binding_id)
+        return result
+
+    def _run(self):
+        """ Flow of the synchronization, implemented in inherited classes"""
+        raise NotImplementedError
+
+
+class ICOPSExporter(ICOPSBaseExporter):
+
+    _concepts = None
+    """ A common flow for the exports to ICOPS """
+    def __init__(self, environment):
+        """
+        :param environment: current environment (backend, session, ...)
+        :type environment: :py:class:`connector.connector.Environment`
+        """
+        super(ICOPSExporter, self).__init__(environment)
+        self.binding_record = None
+
+    def _has_to_skip(self):
+        """ Return True if the export can be skipped """
+        return False
+
+    def _routing(self, record, fields=None):
+            fields = fields or []
+            icops = self.mapper._icops
+            icops_id = self._get_icops_id(
+                icops.backend_to.id, icops.concept)
+            if 'icops_delete' in fields:
+                self._delete(icops_id)
+            else:
+                self._custom_routing(icops_id, record, fields)
+
+    def _custom_routing(self, id, record, fields=None):
+        self._write(id, record)
+
+    def _run(self, fields=None):
+        """ Flow of the synchronization, implemented in inherited classes"""
+        assert self.binding_id
+        assert self.binding_record
+
+        if not self.icops_ids:
+            fields = None  # should be created with all the fields
+
+        if self._has_to_skip():
+            return
+
+        nb_records = 0
+        icops_ids = {}
+        for icops in self._get_icops():
+            backend = self._get_backend_with_permission(icops)
+            self._set_icops(icops, backend)
+            try:
+                self._map_data(fields=fields)
+            except MappingError:
+                continue
+            if self.icops_ids:
+                record = self.mapper.data
+                if not record:
+                    continue
+                nb_records += 1
+                self._validate_data(record)
+                self._routing(record, fields)
+            else:
+                record = self.mapper.data_for_create
+                if not record:
+                    continue
+                nb_records += 1
+                self._validate_data(record)
+                key = '%s_%s' % (icops.backend_to.id, icops.concept)
+                icops_ids[key] = self._create(record)
+
+        self.icops_ids = icops_ids
+
+        if nb_records == 0:
+            return _('Nothing to export.')
+        return _('Record exported.')
+
+    def _get_backend_with_permission(self, icops):
+        sess = self.session
+        backend_pool = sess.pool.get('icops.backend')
+        return backend_pool.browse(
+            sess.cr, icops.icops_uid.id, icops.backend_to.id)
+
+    def _get_icops(self):
+        res = []
+        sess = self.session
+        user_pool = sess.pool.get('res.users')
+        user = user_pool.browse(sess.cr, sess.uid, sess.uid)
+        backend_pool = sess.pool.get('icops.backend')
+        backend_ids = backend_pool.search(
+            sess.cr, sess.uid, [('company_id', '=', user.company_id.id)])
+        if not backend_ids:
+            return res
+        intercompany_pool = sess.pool.get('res.intercompany')
+        intercompany_ids = intercompany_pool.search(
+            sess.cr, sess.uid,
+            [('backend_id', '=', backend_ids[0]),
+             ('concept', 'in', self._concepts),
+             ('object_name', '=', self.binding_record.openerp_id._name)])
+        res = intercompany_pool.browse(sess.cr, sess.uid, intercompany_ids)
+        return res
+
+    def _set_icops(self, icops, backend):
+        self.mapper._icops = icops
+        self.backend_adapter._icops = icops
+        self.mapper._backend_to = backend
+        self.backend_adapter._backend_to = backend
+
+    def _create(self, data):
+        if not self.backend_adapter._icops.on_create:
+            raise osv.except_osv('ICOPS Error', 'Can\'t create')
+        return self.backend_adapter.create(data)
+
+    def _write(self, id, data):
+        if not self.backend_adapter._icops.on_write:
+            raise osv.except_osv('ICOPS Error', 'Can\'t write')
+        self.backend_adapter.write(id, data)
+
+    def _confirm(self, id):
+        if not self.backend_adapter._icops.on_confirm:
+            raise osv.except_osv('ICOPS Error', 'Can\'t confirm')
+        self.backend_adapter.confirm(id)
+
+    def _cancel(self, id):
+        if not self.backend_adapter._icops.on_cancel:
+            raise osv.except_osv('ICOPS Error', 'Can\'t cancel')
+        self.backend_adapter.cancel(id)
+
+    def _delete(self, id):
+        if not self.backend_adapter._icops.on_unlink:
+            raise osv.except_osv('ICOPS Error', 'Can\'t delete')
+        self.backend_adapter.delete(id)
+
+    def _map_data(self, fields=None):
+        """ Convert the external record to OpenERP """
+        self.mapper.convert(self.binding_record, fields=fields)
+
+    def _validate_data(self, data):
+        """ Check if the values to export are correct
+
+        Pro-actively check before the ``Model.create`` or
+        ``Model.update`` if some fields are missing
+
+        Raise `InvalidDataError`
+        """
+        return
+
+    def _get_icops_id(self, backend_id, concept):
+        key = '%s_%s' % (backend_id, concept)
+        print "\n\n"
+        print key
+        print "\n\n"
+        return self.icops_ids[key]
+
+
+@job
+def export_record(session, model_name, binding_id, fields=None):
+    """ Export a record on ICOPS """
+    record = session.browse(model_name, binding_id)
+    env = get_environment(session, model_name, record.backend_id.id)
+    exporter = env.get_connector_unit(ICOPSExporter)
+    return exporter.run(binding_id, fields=fields)

=== added file 'base_intercompany/unit/mapper.py'
--- base_intercompany/unit/mapper.py	1970-01-01 00:00:00 +0000
+++ base_intercompany/unit/mapper.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.addons.connector.unit.mapper import ExportMapper
+
+
+class ICOPSExportMapper(ExportMapper):
+    def __init__(self, environment):
+        """
+
+        :param environment: current environment (backend, session, ...)
+        :type environment: :py:class:`connector.connector.Environment`
+        """
+        super(ICOPSExportMapper, self).__init__(environment)
+        self._icops = None
+        self._backend_to = None
+
+    def _format_child_rows(self, child_records):
+        return [(5, 0)] + [(0, 0, data) for data in child_records]
+
+    def _init_child_mapper(self, model_name):
+        mapper = super(ICOPSExportMapper, self)._init_child_mapper(model_name)
+        mapper._icops = self._icops
+        mapper._backend_to = self._backend_to
+        return mapper
+
+    def _get_mapping(self, name, record):
+        res = {}
+        for method in dir(self):
+            if method.startswith('%s_' % name):
+                new_dict = getattr(self, method)(record)
+                res = dict(res.items() + new_dict.items())
+        return res

=== added directory 'base_intercompany_sale'
=== added file 'base_intercompany_sale/__init__.py'
--- base_intercompany_sale/__init__.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/__init__.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+import connector
+import consumer
+import company
+import icops_model
+import sale
+import purchase

=== added file 'base_intercompany_sale/__openerp__.py'
--- base_intercompany_sale/__openerp__.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/__openerp__.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{'name': 'Base Intercompany Sale',
+ 'version': '0.3',
+ 'category': '',
+ 'depends': ['connector', 'base_intercompany',
+             'sale', 'purchase', 'stock', 'product'],
+ 'author': 'Elico Corp',
+ 'license': 'AGPL-3',
+ 'website': 'https://www.elico-corp.com',
+ 'description': """
+
+""",
+ 'images': [],
+ 'demo': ['base_intercompany_sale_demo.xml'],
+ 'data': ['security/ir.model.access.csv',
+          'icops_model_view.xml',
+          'sale_view.xml',
+          'purchase_view.xml'],
+ 'installable': True,
+ 'application': False,
+ }

=== added file 'base_intercompany_sale/base_intercompany_sale_demo.xml'
--- base_intercompany_sale/base_intercompany_sale_demo.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/base_intercompany_sale_demo.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+
+        <record id="base_intercompany.user_origin" model="res.users">
+            <field name="groups_id" eval="[(4, ref('base.group_sale_manager')), (4, ref('purchase.group_purchase_manager')), (4, ref('stock.group_stock_manager')), (4, ref('base_intercompany.group_connector_user'))]"/>
+        </record>
+
+        <record id="base_intercompany.user_destination" model="res.users">
+            <field name="groups_id" eval="[(4, ref('base.group_sale_manager')), (4, ref('purchase.group_purchase_manager')), (4, ref('stock.group_stock_manager')), (4, ref('base_intercompany.group_connector_user'))]"/>
+        </record>
+
+        <record id="warehouse_origin" model="stock.warehouse">
+            <field name="name">Warehouse Origin</field>
+            <field name="company_id" ref="base_intercompany.company_origin" />
+        </record>
+
+        <record id="warehouse_destination" model="stock.warehouse">
+            <field name="name">Warehouse Destination</field>
+            <field name="company_id" ref="base_intercompany.company_destination" />
+        </record>
+
+        <record id="shop_origin" model="sale.shop">
+            <field name="name">Shop Origin</field>
+            <field name="warehouse_id" ref="warehouse_origin" />
+            <field name="payment_default_id" ref="account.account_payment_term_immediate" />
+            <field name="company_id" ref="base_intercompany.company_origin" />
+        </record>
+
+        <record id="shop_destination" model="sale.shop">
+            <field name="name">Shop Destination</field>
+            <field name="warehouse_id" ref="warehouse_destination" />
+            <field name="payment_default_id" ref="account.account_payment_term_immediate" />
+            <field name="company_id" ref="base_intercompany.company_destination" />
+        </record>
+
+        <!-- ICOPS Setup -->
+        <record id="base_intercompany.backend_origin" model="icops.backend">
+            <field name="icops_shop_id" ref="shop_origin" />
+            <field name="icops_ids" eval="[(0, 0, {'concept': 'so2po', 'backend_to': ref('base_intercompany.backend_destination'), 'on_create': True, 'on_write': True, 'on_unlink': True, 'on_confirm': True, 'on_cancel': True})]" />
+        </record>
+
+        <record id="base_intercompany.backend_destination" model="icops.backend">
+            <field name="icops_shop_id" ref="shop_destination" />
+        </record>
+
+        <!-- Remove company_id from stock -->
+        <record id="stock.stock_location_3" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_4" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_5" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_7" model="stock.location">
+                <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_14" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_components" model="stock.location">
+        </record>
+        <record id="stock.stock_location_stock" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+        <record id="stock.stock_location_output" model="stock.location">
+            <field name="company_id"></field>
+        </record>
+
+        <!-- Sale Order -->
+        <record id="sale_order_1" model="sale.order">
+            <field name="partner_id" ref="base_intercompany.supplier_destination"/>
+            <field name="partner_invoice_id" ref="base_intercompany.supplier_destination"/>
+            <field name="partner_shipping_id" ref="base_intercompany.supplier_destination"/>
+            <field name="shop_id" ref="shop_origin"/>
+            <field name="user_id" ref="base_intercompany.user_origin"/>
+            <field name="pricelist_id" ref="product.list0"/>
+            <field name="icops_bind_ids" eval="[(0, 0, {'backend_id': ref('base_intercompany.backend_origin')})]" />
+        </record>
+
+        <record id="sale_order_line_1" model="sale.order.line">
+            <field name="order_id" ref="sale_order_1"/>
+            <field name="name">Laptop E5023</field>
+            <field name="product_id" ref="product.product_product_25"/>
+            <field name="product_uom_qty">3</field>
+            <field name="product_uos_qty">3</field>
+            <field name="product_uom" ref="product.product_uom_unit"/>
+            <field name="price_unit">2950.00</field>
+        </record>
+
+        <record id="sale_order_line_2" model="sale.order.line">
+            <field name="order_id" ref="sale_order_1"/>
+            <field name="name">Pen drive, 16GB</field>
+            <field name="product_id" ref="product.product_product_30"/>
+            <field name="product_uom_qty">5</field>
+            <field name="product_uos_qty">5</field>
+            <field name="product_uom" ref="product.product_uom_unit"/>
+            <field name="price_unit">145.00</field>
+        </record>
+    </data>
+</openerp>
\ No newline at end of file

=== added file 'base_intercompany_sale/company.py'
--- base_intercompany_sale/company.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/company.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import fields, orm
+
+
+class res_intercompany(orm.Model):
+    _inherit = 'res.intercompany'
+
+    def _select_concepts(self, cr, uid, context=None):
+        """ Available concepts
+
+        Can be inherited to add custom versions.
+        """
+        res = super(res_intercompany, self)._select_concepts(cr, uid, context)
+        res += [('so2po', 'SO to PO'),
+                ('so2so', 'SO to SO'),
+                ('po2so', 'PO to SO')]
+        return res
+
+    def _select_object_names(self, cr, uid, context=None):
+        """ Available Object names
+
+        Can be inherited to add custom versions.
+        """
+        res = super(res_intercompany, self)._select_object_names(
+            cr, uid, context)
+        new_dict = {'so2po': 'sale.order',
+                    'so2so': 'sale.order',
+                    'po2so': 'purchase.order'}
+        res = dict(res.items() + new_dict.items())
+        return res
+
+    _columns = {
+        'concept': fields.selection(_select_concepts, string="Concept",
+                                    required=True),
+    }

=== added file 'base_intercompany_sale/connector.py'
--- base_intercompany_sale/connector.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/connector.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import orm
+
+
+class base_intercompany_sale_installed(orm.AbstractModel):
+    """Empty model used to know if the module is installed on the
+    database.
+
+    If the model is in the registry, the module is installed.
+    """
+    _name = 'base_intercompany_sale.installed'

=== added file 'base_intercompany_sale/consumer.py'
--- base_intercompany_sale/consumer.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/consumer.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,79 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.addons.connector.event import (on_record_write,
+                                            on_record_create,
+                                            on_record_unlink
+                                            )
+from openerp.addons.base_intercompany.unit.export_synchronizer import (
+    export_record)
+
+_MODEL_NAMES = ('sale.order', 'sale.order.line',
+                'purchase.order', 'purchase.order.line')
+_BIND_MODEL_NAMES = ('icops.sale.order', 'icops.sale.order.line',
+                     'icops.purchase.order', 'icops.purchase.order.line')
+_UNLINK_MODEL_NAMES = ('sale.order', 'purchase.order')
+_UNLINK_BIND_MODEL_NAMES = ('icops.sale.order', 'icops.purchase.order')
+
+
+@on_record_create(model_names=_BIND_MODEL_NAMES)
+@on_record_write(model_names=_BIND_MODEL_NAMES)
+def delay_export(session, model_name, record_id, fields=None):
+    """ Delay a job which export a binding record.
+
+    (A binding record being a ``icops.res.partner``,
+    ``icops.sale.order``, ...)
+    """
+    export_record(session, model_name, record_id, fields=fields)
+
+
+@on_record_write(model_names=_MODEL_NAMES)
+def delay_export_all_bindings(session, model_name, record_id, fields=None):
+    """ Delay a job which export all the bindings of a record.
+
+    In this case, it is called on records of normal models and will delay
+    the export for all the bindings.
+    """
+    model = session.pool.get(model_name)
+    record = model.browse(session.cr, session.uid,
+                          record_id, context=session.context)
+    for binding in record.icops_bind_ids:
+        export_record(session, binding._model._name, binding.id,
+                      fields=fields)
+
+
+@on_record_unlink(model_names=_UNLINK_MODEL_NAMES)
+def delay_unlink(session, model_name, record_id):
+    """ Delay a job which delete a record on Magento.
+
+    Called on binding records."""
+    fields = {'icops_delete': True}
+    delay_export_all_bindings(session, model_name, record_id, fields)
+
+
+@on_record_unlink(model_names=_UNLINK_BIND_MODEL_NAMES)
+def delay_unlink_binding(session, model_name, record_id):
+    """ Delay a job which delete a record on Magento.
+
+    Called on binding records."""
+    fields = {'icops_delete': True}
+    delay_export(session, model_name, record_id, fields)

=== added file 'base_intercompany_sale/icops_model.py'
--- base_intercompany_sale/icops_model.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/icops_model.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import fields, orm
+
+
+class icops_backend(orm.Model):
+    _inherit = 'icops.backend'
+
+    _columns = {
+        'icops_shop_id': fields.many2one(
+            'sale.shop', 'IC Default location',
+            domain="[('company_id', '=', id)]")
+    }

=== added file 'base_intercompany_sale/icops_model_view.xml'
--- base_intercompany_sale/icops_model_view.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/icops_model_view.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+        <record id="view_icops_backend_form" model="ir.ui.view">
+            <field name="name">icops.backend.form</field>
+            <field name="model">icops.backend</field>
+            <field name="inherit_id" ref="base_intercompany.view_icops_backend_form" />
+            <field name="arch" type="xml">
+                <field name="icops_uid" position="after">
+                    <field name="icops_shop_id" cols="2" />
+                </field>
+            </field>
+        </record>
+    </data>
+</openerp>
\ No newline at end of file

=== added file 'base_intercompany_sale/purchase.py'
--- base_intercompany_sale/purchase.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/purchase.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,248 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import fields, orm
+from openerp.addons.base_intercompany.backend import icops
+from openerp.addons.base_intercompany.unit.export_synchronizer import (
+    ICOPSExporter)
+from openerp.addons.base_intercompany.unit.mapper import ICOPSExportMapper
+from openerp.addons.connector.unit.mapper import mapping
+from openerp.addons.base_intercompany.unit.backend_adapter import (
+    ICOPSAdapter)
+from openerp.addons.connector.exception import MappingError
+
+
+class purchase_order(orm.Model):
+    _inherit = 'purchase.order'
+
+    _columns = {
+        'openerp_id': fields.many2one('purchase.order',
+                                      string='Sale Order',
+                                      required=True,
+                                      ondelete='cascade'),
+        'icops_bind_ids': fields.one2many(
+            'icops.purchase.order', 'openerp_id',
+            string="ICOPS Bindings"),
+    }
+
+    def copy_data(self, cr, uid, id, default=None, context=None):
+        if default is None:
+            default = {}
+        default['icops_bind_ids'] = False
+        return super(purchase_order, self).copy_data(cr, uid, id,
+                                                     default=default,
+                                                     context=context)
+
+    def create(self, cr, uid, data, context=None):
+        data['icops_bind_ids'] = self.pool.get(
+            'icops.backend').prepare_binding(cr, uid, data, context)
+        return super(purchase_order, self).create(cr, uid, data, context)
+
+
+class icops_purchase_order(orm.Model):
+    _name = 'icops.purchase.order'
+    _inherit = 'icops.binding'
+    _inherits = {'purchase.order': 'openerp_id'}
+    _description = 'ICOPS Purchase Order'
+
+    _columns = {
+        'openerp_id': fields.many2one('purchase.order',
+                                      string='Product',
+                                      required=True,
+                                      ondelete='cascade'),
+        'backend_id': fields.many2one('icops.backend',
+                                      string='ICOPS Backend'),
+        'icops_order_line_ids': fields.one2many('icops.purchase.order.line',
+                                                'icops_order_id',
+                                                'ICOPS Order Lines'),
+    }
+
+
+class purchase_order_line(orm.Model):
+    _inherit = 'purchase.order.line'
+    _columns = {
+        'icops_bind_ids': fields.one2many(
+            'icops.purchase.order.line', 'openerp_id',
+            string="ICOPS Bindings"),
+    }
+
+    def copy_data(self, cr, uid, id, default=None, context=None):
+        if default is None:
+            default = {}
+        default['icops_bind_ids'] = False
+        return super(purchase_order_line, self).copy_data(cr, uid, id,
+                                                          default=default,
+                                                          context=context)
+
+
+class icops_purchase_order_line(orm.Model):
+    _name = 'icops.purchase.order.line'
+    _inherit = 'icops.binding'
+    _description = 'ICOPS Sale Order Line'
+    _inherits = {'purchase.order.line': 'openerp_id'}
+
+    def _get_lines_from_order(self, cr, uid, ids, context=None):
+        line_obj = self.pool.get('icops.purchase.order.line')
+        return line_obj.search(cr, uid,
+                               [('icops_order_id', 'in', ids)],
+                               context=context)
+    _columns = {
+        'icops_order_id': fields.many2one('icops.purchase.order',
+                                          'ICOPS Sale Order',
+                                          required=True,
+                                          ondelete='cascade',
+                                          select=True),
+        'openerp_id': fields.many2one('purchase.order.line',
+                                      string='Sale Order Line',
+                                      required=True,
+                                      ondelete='cascade'),
+        'backend_id': fields.related(
+            'icops_order_id', 'backend_id',
+            type='many2one',
+            relation='icops.backend',
+            string='ICOPS Backend',
+            store={'icops.purchase.order.line':
+                   (lambda self, cr, uid, ids, c=None: ids,
+                    ['icops_order_id'],
+                    10),
+                 'icops.purchase.order':
+                   (_get_lines_from_order, ['backend_id'], 20),
+                   },
+            readonly=True)
+    }
+
+    def create(self, cr, uid, vals, context=None):
+        icops_order_id = vals['icops_order_id']
+        info = self.pool['icops.purchase.order'].read(cr, uid,
+                        [icops_order_id],
+            ['openerp_id'],
+            context=context)
+        order_id = info[0]['openerp_id']
+        vals['order_id'] = order_id[0]
+        return super(icops_purchase_order_line, self).create(cr, uid, vals,
+                                                             context=context)
+
+
+@icops
+class PurchaseOrderAdapter(ICOPSAdapter):
+    _model_name = 'icops.purchase.order'
+
+    def _get_pool(self):
+        sess = self.session
+        return sess.pool.get('sale.order')
+
+    def confirm(self, id):
+        sess = self.session
+        pool = self._get_pool()
+        pool.action_wait(
+            sess.cr, self._backend_to.icops_uid.id, [id])
+
+    def cancel(self, id):
+        sess = self.session
+        pool = self._get_pool()
+        pool.action_cancel(sess.cr, self._backend_to.icops_uid.id, [id])
+
+
+@icops
+class PurchaseOrderExport(ICOPSExporter):
+    _model_name = ['icops.purchase.order']
+    _concepts = ['po2so']
+
+    def _custom_routing(self, id, record, fields=None):
+        if 'state' in fields:
+            state = record.pop('state')
+            if state == 'cancel':
+                self._cancel(id)
+            elif state == 'progress':
+                self._confirm(id)
+        elif fields:
+            self._write(id, record)
+
+
+@icops
+class PurchaseOrderExportMapper(ICOPSExportMapper):
+    _model_name = 'icops.purchase.order'
+
+    children = [
+        ('order_line', 'order_line', 'icops.purchase.order.line')
+    ]
+
+    @mapping
+    def state(self, record):
+        state = record.state
+        if record.state == 'approved':
+            state = 'progress'
+        return {'state': state}
+
+    @mapping
+    def address(self, record):
+        sess = self.session
+        backend = self._backend_to
+        partner = backend.company_id.partner_id
+        icops_uid = backend.icops_uid.id
+        partner_pool = sess.pool.get('res.partner')
+        addr = partner_pool.address_get(sess.cr, icops_uid, [partner.id],
+                                        ['delivery', 'invoice', 'contact'])
+        return {
+            'partner_invoice_id': addr['invoice'],
+            'partner_shipping_id': addr['delivery']
+        }
+
+    @mapping
+    def icops(self, record):
+        if not self._backend_to:
+            raise MappingError("Could not find an ICOPS backend")
+        backend = self._backend_to
+        icops_uid = backend.icops_uid.id
+        company = backend.company_id
+        partner = company.partner_id
+        pricelist = partner.property_product_pricelist
+        fiscal_position = partner.property_account_position
+        payment_term = partner.property_payment_term
+        shop = self._backend_to.icops_shop_id
+        if company.partner_id.id != record.partner_id.id:
+            raise MappingError("Wrong partner")
+        return {
+            'company_id': company.id,
+            'partner_id': partner.id,
+            'pricelist_id': pricelist.id,
+            'fiscal_position': fiscal_position.id,
+            'payment_term': payment_term.id,
+            'user_id': icops_uid,
+            'shop_id': shop.id
+        }
+
+
+@icops
+class PurchaseOrderLineExportMapper(ICOPSExportMapper):
+    _model_name = 'icops.purchase.order.line'
+
+    direct = [('name', 'name'),
+              ('price_unit', 'price_unit')]
+
+    @mapping
+    def product(self, record):
+        return {
+            'product_id': record.product_id.id,
+            'product_uom': record.product_uom.id,
+            'product_uom_qty': record.product_qty
+        }

=== added file 'base_intercompany_sale/purchase_view.xml'
--- base_intercompany_sale/purchase_view.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/purchase_view.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+        <record id="purchase_order_form" model="ir.ui.view">
+            <field name="name">purchase.order.form</field>
+            <field name="model">purchase.order</field>
+            <field name="inherit_id" ref="purchase.purchase_order_form" />
+            <field name="arch" type="xml">
+                <page string="Purchase Order" position="after">
+                    <page string="ICOPS">
+                        <field name="icops_bind_ids">
+                            <tree string="ICOPS Backend" editable="bottom">
+                                <field name="backend_id" />
+                                <field name="icops_ids" />
+                            </tree>
+                        </field>
+                    </page>
+                </page>
+            </field>
+        </record>
+    </data>
+</openerp>
\ No newline at end of file

=== added file 'base_intercompany_sale/sale.py'
--- base_intercompany_sale/sale.py	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/sale.py	2014-01-21 03:17:46 +0000
@@ -0,0 +1,328 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (c) 2010-2013 Elico Corp. All Rights Reserved.
+#    Augustin Cisterne-Kaas <augustin.cisterne-kaas@xxxxxxxxxxxxxx>
+#    Eric Caudal <eric.caudal@xxxxxxxxxxxxxx>
+
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+from openerp.osv import fields, orm
+from openerp.addons.base_intercompany.backend import icops
+from openerp.addons.base_intercompany.unit.export_synchronizer import (
+    ICOPSExporter)
+from openerp.addons.base_intercompany.unit.mapper import ICOPSExportMapper
+from openerp.addons.connector.unit.mapper import mapping
+from openerp.addons.connector.exception import MappingError
+from openerp.addons.base_intercompany.unit.backend_adapter import ICOPSAdapter
+
+
+class sale_order(orm.Model):
+    _inherit = 'sale.order'
+
+    _columns = {
+        'openerp_id': fields.many2one('sale.order',
+                                      string='Sale Order',
+                                      required=True,
+                                      ondelete='cascade'),
+        'icops_bind_ids': fields.one2many(
+            'icops.sale.order', 'openerp_id',
+            string="ICOPS Bindings"),
+    }
+
+    def copy_data(self, cr, uid, id, default=None, context=None):
+        if default is None:
+            default = {}
+        default['icops_bind_ids'] = False
+        return super(sale_order, self).copy_data(cr, uid, id,
+                                                 default=default,
+                                                 context=context)
+
+    def create(self, cr, uid, data, context=None):
+        data['icops_bind_ids'] = self.pool.get(
+            'icops.backend').prepare_binding(cr, uid, data, context)
+        return super(sale_order, self).create(cr, uid, data, context)
+
+
+class icops_sale_order(orm.Model):
+    _name = 'icops.sale.order'
+    _inherit = 'icops.binding'
+    _inherits = {'sale.order': 'openerp_id'}
+    _description = 'ICOPS Sale Order'
+
+    _columns = {
+        'openerp_id': fields.many2one('sale.order',
+                                      string='SaleOrder',
+                                      required=True,
+                                      ondelete='cascade'),
+        'backend_id': fields.many2one('icops.backend',
+                                      string='ICOPS Backend'),
+        'icops_order_line_ids': fields.one2many('icops.sale.order.line',
+                                                'icops_order_id',
+                                                'ICOPS Order Lines'),
+
+    }
+
+
+class sale_order_line(orm.Model):
+    _inherit = 'sale.order.line'
+    _columns = {
+        'icops_bind_ids': fields.one2many(
+            'icops.sale.order.line', 'openerp_id',
+            string="ICOPS Bindings"),
+    }
+
+    def copy_data(self, cr, uid, id, default=None, context=None):
+        if default is None:
+            default = {}
+        default['icops_bind_ids'] = False
+        return super(sale_order_line, self).copy_data(cr, uid, id,
+                                                      default=default,
+                                                      context=context)
+
+
+class icops_sale_order_line(orm.Model):
+    _name = 'icops.sale.order.line'
+    _inherit = 'icops.binding'
+    _description = 'ICOPS Sale Order Line'
+    _inherits = {'sale.order.line': 'openerp_id'}
+
+    def _get_lines_from_order(self, cr, uid, ids, context=None):
+        line_obj = self.pool.get('icops.sale.order.line')
+        return line_obj.search(cr, uid,
+                               [('icops_order_id', 'in', ids)],
+                               context=context)
+    _columns = {
+        'icops_order_id': fields.many2one('icops.sale.order',
+                                          'ICOPS Sale Order',
+                                          required=True,
+                                          ondelete='cascade',
+                                          select=True),
+        'openerp_id': fields.many2one('sale.order.line',
+                                      string='Sale Order Line',
+                                      required=True,
+                                      ondelete='cascade'),
+        'backend_id': fields.related(
+            'icops_order_id', 'backend_id',
+            type='many2one',
+            relation='icops.backend',
+            string='ICOPS Backend',
+            store={'icops.sale.order.line':
+                   (lambda self, cr, uid, ids, c=None: ids,
+                    ['icops_order_id'],
+                    10),
+                 'icops.sale.order':
+                   (_get_lines_from_order, ['backend_id'], 20),
+                   },
+            readonly=True)
+    }
+
+    def create(self, cr, uid, vals, context=None):
+        icops_order_id = vals['icops_order_id']
+        info = self.pool['icops.sale.order'].read(cr, uid,
+                        [icops_order_id],
+            ['openerp_id'],
+            context=context)
+        order_id = info[0]['openerp_id']
+        vals['order_id'] = order_id[0]
+        return super(icops_sale_order_line, self).create(cr, uid, vals,
+                                                         context=context)
+
+
+@icops
+class SaleOrderAdapter(ICOPSAdapter):
+    _model_name = 'icops.sale.order'
+
+    def _get_pool(self):
+        sess = self.session
+        name = ('purchase.order'
+                if self._icops.concept == 'so2po' else 'sale.order')
+        return sess.pool.get(name)
+
+    def confirm(self, id):
+        sess = self.session
+        pool = self._get_pool()
+        if hasattr(pool, 'wkf_confirm_order'):
+            pool.wkf_confirm_order(
+                sess.cr, self._backend_to.icops_uid.id, [id])
+        else:
+            pool.action_wait(
+                sess.cr, self._backend_to.icops_uid.id, [id])
+
+    def cancel(self, id):
+        sess = self.session
+        pool = self._get_pool()
+        pool.action_cancel(sess.cr, self._backend_to.icops_uid.id, [id])
+
+
+@icops
+class SaleOrderExport(ICOPSExporter):
+    _model_name = ['icops.sale.order']
+    _concepts = ['so2po', 'so2so']
+
+    def _custom_routing(self, id, record, fields=None):
+        if 'state' in fields:
+            state = record.pop('state')
+            if state == 'cancel':
+                self._cancel(id)
+            elif state in ('approved', 'progress', 'manual'):
+                self._confirm(id)
+        elif fields:
+            self._write(id, record)
+
+
+@icops
+class SaleOrderExportMapper(ICOPSExportMapper):
+    _model_name = 'icops.sale.order'
+
+    children = [
+        ('order_line', 'order_line', 'icops.sale.order.line')
+    ]
+
+    @mapping
+    def map_all(self, record):
+        assert self._icops
+        return self._get_mapping(self._icops.concept, record)
+
+    def so2so_partner(self, record):
+        supplier = record.company_id.partner_id
+        pricelist_id = (supplier.property_product_pricelist_purchase.id
+                        if supplier.property_product_pricelist_purchase
+                        else False)
+        fiscal_position_id = (supplier.property_account_position.id
+                              if supplier.property_account_position
+                              else False)
+        payment_term_id = (supplier.property_supplier_payment_term.id
+                           if supplier.property_supplier_payment_term
+                           else False)
+        return {'partner_id': supplier.id,
+                'pricelist_id': pricelist_id,
+                'payment_term_id': payment_term_id,
+                'fiscal_position': fiscal_position_id}
+
+    def so2so_icops(self, record):
+        if not self._backend_to:
+            raise MappingError("Could not find an ICOPS backend")
+        backend = self._backend_to
+        icops_uid = backend.icops_uid.id
+        company = backend.company_id
+        partner = company.partner_id
+        pricelist = partner.property_product_pricelist
+        fiscal_position = partner.property_account_position
+        payment_term = partner.property_payment_term
+        shop = self._backend_to.icops_shop_id
+
+        return {
+            'company_id': company.id,
+            'partner_id': partner.id,
+            'pricelist_id': pricelist.id,
+            'fiscal_position': fiscal_position.id,
+            'payment_term': payment_term.id,
+            'user_id': icops_uid,
+            'shop_id': shop.id
+        }
+
+    def so2so_address(self, record):
+        sess = self.session
+        backend = self._backend_to
+        partner = backend.company_id.partner_id
+        icops_uid = backend.icops_uid.id
+        partner_pool = sess.pool.get('res.partner')
+        addr = partner_pool.address_get(sess.cr, icops_uid, [partner.id],
+                                        ['delivery', 'invoice', 'contact'])
+        return {
+            'partner_invoice_id': addr['invoice'],
+            'partner_shipping_id': addr['delivery']
+        }
+
+    def so2so_policy(self, record):
+        return {'order_policy': record.order_policy}
+
+    def so2so_state(self, record):
+        return {'state': record.state}
+
+    def so2po_partner(self, record):
+        supplier = record.company_id.partner_id
+        pricelist_id = (supplier.property_product_pricelist_purchase.id
+                        if supplier.property_product_pricelist_purchase
+                        else False)
+        fiscal_position_id = (supplier.property_account_position.id
+                              if supplier.property_account_position
+                              else False)
+        payment_term_id = (supplier.property_supplier_payment_term.id
+                           if supplier.property_supplier_payment_term
+                           else False)
+        return {'partner_id': supplier.id,
+                'pricelist_id': pricelist_id,
+                'payment_term_id': payment_term_id,
+                'fiscal_position': fiscal_position_id}
+
+    def so2po_icops(self, record):
+        if not self._backend_to:
+            raise MappingError("Could not find an ICOPS backend")
+        backend = self._backend_to
+        company = backend.company_id
+        shop = backend.icops_shop_id
+        warehouse = shop.warehouse_id
+        location = warehouse.lot_stock_id
+
+        if company.partner_id.id != record.partner_id.id:
+            raise MappingError("Wrong partner")
+        return {
+            'company_id': company.id,
+            'location_id': location.id
+        }
+
+    def so2po_state(self, record):
+        state = record.state
+        if record.state in ('progress', 'manual'):
+            state = 'approved'
+        return {'state': state}
+
+
+@icops
+class SaleOrderLineExportMapper(ICOPSExportMapper):
+    _model_name = 'icops.sale.order.line'
+
+    direct = [('name', 'name'),
+              ('price_unit', 'price_unit')]
+
+    @mapping
+    def map_all(self, record):
+        assert self._icops
+        return self._get_mapping(self._icops.concept, record)
+
+    def so2so_product(self, record):
+        return {
+            'product_id': record.product_id.id,
+            'product_uom': record.product_uom.id,
+            'product_uom_qty': record.product_uom_qty
+        }
+
+    def so2po_product(self, record):
+        return {
+            'product_id': record.product_id.id,
+            'product_uom': record.product_uom.id,
+            'product_qty': record.product_uom_qty
+        }
+
+    def so2po_date_planned(self, record):
+        sess = self.session
+        order = record.order_id
+        order_pool = sess.pool.get(order._name)
+        date_planned = order_pool._get_date_planned(
+            sess.cr, sess.uid, order, record, order.date_order)
+        return {'date_planned': date_planned}

=== added file 'base_intercompany_sale/sale_view.xml'
--- base_intercompany_sale/sale_view.xml	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/sale_view.xml	2014-01-21 03:17:46 +0000
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+        <record id="view_order_form" model="ir.ui.view">
+            <field name="name">sale.order</field>
+            <field name="model">sale.order</field>
+            <field name="inherit_id" ref="sale.view_order_form" />
+            <field name="arch" type="xml">
+                <page string="Order Lines" position="after">
+                    <page string="ICOPS">
+                        <field name="icops_bind_ids">
+                            <tree string="ICOPS Backend" editable="bottom">
+                                <field name="backend_id" />
+                                <field name="icops_ids" />
+                            </tree>
+                        </field>
+                    </page>
+                </page>
+            </field>
+        </record>
+    </data>
+</openerp>
\ No newline at end of file

=== added directory 'base_intercompany_sale/security'
=== added file 'base_intercompany_sale/security/ir.model.access.csv'
--- base_intercompany_sale/security/ir.model.access.csv	1970-01-01 00:00:00 +0000
+++ base_intercompany_sale/security/ir.model.access.csv	2014-01-21 03:17:46 +0000
@@ -0,0 +1,13 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_icops_sale_order_manager,icops sale order manager,base_intercompany_sale.model_icops_sale_order,base.group_sale_manager,1,1,1,1
+access_icops_sale_order_user,icops sale order user,base_intercompany_sale.model_icops_sale_order,base.group_sale_salesman,1,1,1,1
+access_icops_sale_order_line_manager,icops sale order line manager,base_intercompany_sale.model_icops_sale_order_line,base.group_sale_manager,1,1,1,1
+access_icops_sale_order_line_user,icops sale order line user,base_intercompany_sale.model_icops_sale_order_line,base.group_sale_salesman,1,1,1,1
+access_icops_record_manager,icops record manager,base_intercompany.model_icops_record,base.group_sale_manager,1,1,1,1
+access_icops_record_user,icops record user,base_intercompany.model_icops_record,base.group_sale_salesman,1,1,1,1
+access_icops_purchase_order_manager,icops purchase order manager,base_intercompany_sale.model_icops_purchase_order,purchase.group_purchase_manager,1,1,1,1
+access_icops_purchase_order_user,icops purchase order user,base_intercompany_sale.model_icops_purchase_order,purchase.group_purchase_user,1,1,1,1
+access_icops_purchase_order_line_manager,icops purchase order line manager,base_intercompany_sale.model_icops_purchase_order_line,purchase.group_purchase_manager,1,1,1,1
+access_icops_purchase_order_line_user,icops purchase order line user,base_intercompany_sale.model_icops_purchase_order_line,purchase.group_purchase_user,1,1,1,1
+access_icops_record_manager,icops record manager,base_intercompany.model_icops_record,purchase.group_purchase_manager,1,1,1,1
+access_icops_record_user,icops record user,base_intercompany.model_icops_record,purchase.group_purchase_user,1,1,1,1
\ No newline at end of file


Follow ups