openerp-community team mailing list archive
-
openerp-community team
-
Mailing list archive
-
Message #04520
[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