← Back to team overview

openerp-community-reviewer team mailing list archive

[Merge] lp:~akretion-team/account-closing/61-cutoff-modules-with-forecast into lp:account-closing/6.1

 

Alexis de Lattre has proposed merging lp:~akretion-team/account-closing/61-cutoff-modules-with-forecast into lp:account-closing/6.1.

Requested reviews:
  Account Core Editors (account-core-editors)

For more details, see:
https://code.launchpad.net/~akretion-team/account-closing/61-cutoff-modules-with-forecast/+merge/210067

This is the backport to OpenERP 6.1 of my cut-off modules : account_cutoff_base, account_cutoff_accrual_base, account_cutoff_accrual_picking, account_cutoff_prepaid. It also includes the code of the "prepaid forecast" feature, which is under review here : https://code.launchpad.net/~akretion-team/account-closing/70-forecast-prepaid/+merge/210066
-- 
https://code.launchpad.net/~akretion-team/account-closing/61-cutoff-modules-with-forecast/+merge/210067
Your team Account Core Editors is requested to review the proposed merge of lp:~akretion-team/account-closing/61-cutoff-modules-with-forecast into lp:account-closing/6.1.
=== added directory 'account_cutoff_accrual_base'
=== added file 'account_cutoff_accrual_base/__init__.py'
--- account_cutoff_accrual_base/__init__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/__init__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,25 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 . import company
+from . import account
+from . import account_cutoff

=== added file 'account_cutoff_accrual_base/__openerp__.py'
--- account_cutoff_accrual_base/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/__openerp__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,46 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cutoff Accrual Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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': 'Account Accrual Base',
+    'version': '0.1',
+    'category': 'Accounting & Finance',
+    'license': 'AGPL-3',
+    'summary': 'Base module for accrued expenses and revenues',
+    'description': """This module contains objets, fields and menu entries that are used by other accrual modules. So you need to install other accrual modules to get the additionnal functionalities :
+- the module 'account_cutoff_accrual_picking' will manage accrued expenses and revenues based on pickings.
+- a not-developped-yet module will manage accrued expenses and revenues based on timesheets.
+
+Please contact Alexis de Lattre from Akretion <alexis.delattre@xxxxxxxxxxxx> for any help or question about this module.
+    """,
+    'author': 'Akretion',
+    'website': 'http://www.akretion.com',
+    'depends': ['account_cutoff_base'],
+    'data': [
+        'company_view.xml',
+        'account_view.xml',
+        'account_cutoff_view.xml',
+    ],
+    'installable': True,
+    'active': False,
+}

=== added file 'account_cutoff_accrual_base/account.py'
--- account_cutoff_accrual_base/account.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/account.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,36 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 account_tax(orm.Model):
+    _inherit = 'account.tax'
+
+    _columns = {
+        'account_accrued_revenue_id': fields.many2one(
+            'account.account', 'Accrued Revenue Tax Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+        'account_accrued_expense_id': fields.many2one(
+            'account.account', 'Accrued Expense Tax Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+        }

=== added file 'account_cutoff_accrual_base/account_cutoff.py'
--- account_cutoff_accrual_base/account_cutoff.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/account_cutoff.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,57 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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
+import decimal_precision as dp
+
+
+class account_cutoff(orm.Model):
+    _inherit = 'account.cutoff'
+
+    def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
+        if context is None:
+            context = {}
+        account_id = super(account_cutoff, self).\
+            _inherit_default_cutoff_account_id(
+                cr, uid, context=context)
+        type = context.get('type')
+        company = self.pool['res.users'].browse(
+            cr, uid, uid, context=context).company_id
+        if type == 'accrued_expense':
+            account_id = company.default_accrued_expense_account_id.id or False
+        elif type == 'accrued_revenue':
+            account_id = company.default_accrued_revenue_account_id.id or False
+        return account_id
+
+
+class account_cutoff_line(orm.Model):
+    _inherit = 'account.cutoff.line'
+
+    _columns = {
+        'quantity': fields.float(
+            'Quantity', digits_compute=dp.get_precision('Product UoS'),
+            readonly=True),
+        'price_unit': fields.float(
+            'Unit Price', digits_compute=dp.get_precision('Product Price'),
+            readonly=True, help="Price per unit (discount included)"),
+        }

=== added file 'account_cutoff_accrual_base/account_cutoff_view.xml'
--- account_cutoff_accrual_base/account_cutoff_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/account_cutoff_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<!-- Form view for lines -->
+<record id="account_cutoff_line_form" model="ir.ui.view">
+    <field name="name">accrual.account_cutoff_line</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
+    <field name="arch" type="xml">
+        <field name="amount" position="before">
+            <field name="quantity" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="price_unit" invisible="'accrued' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+<!-- Tree view for lines -->
+<record id="account_cutoff_line_tree" model="ir.ui.view">
+    <field name="name">accrual.account_cutoff_line_tree</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
+    <field name="arch" type="xml">
+        <field name="analytic_account_code" position="after">
+            <field name="quantity" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="price_unit" invisible="'accrued' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+
+<record id="account_expense_accrual_action" model="ir.actions.act_window">
+    <field name="name">Accrued Expense</field>
+    <field name="res_model">account.cutoff</field>
+    <field name="view_type">form</field>
+    <field name="view_mode">tree,form</field>
+    <field name="domain">[('type', '=', 'accrued_expense')]</field>
+    <field name="context">{'type': 'accrued_expense'}</field>
+</record>
+
+
+<menuitem id="account_expense_accrual_menu"
+        parent="account_cutoff_base.cutoff_menu"
+        action="account_expense_accrual_action"
+        sequence="35"/>
+
+
+<record id="account_revenue_accrual_action" model="ir.actions.act_window">
+    <field name="name">Accrued Revenue</field>
+    <field name="res_model">account.cutoff</field>
+    <field name="view_type">form</field>
+    <field name="view_mode">tree,form</field>
+    <field name="domain">[('type', '=', 'accrued_revenue')]</field>
+    <field name="context">{'type': 'accrued_revenue'}</field>
+</record>
+
+
+<menuitem id="account_revenue_accrual_menu"
+        parent="account_cutoff_base.cutoff_menu"
+        action="account_revenue_accrual_action"
+        sequence="30"/>
+
+
+</data>
+</openerp>

=== added file 'account_cutoff_accrual_base/account_view.xml'
--- account_cutoff_accrual_base/account_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/account_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<record id="view_tax_form" model="ir.ui.view">
+    <field name="name">account.cutoff.accrual.view_tax_form</field>
+    <field name="model">account.tax</field>
+    <field name="inherit_id" ref="account.view_tax_form" />
+    <field name="arch" type="xml">
+        <separator string="Tax Declaration: Invoices" position="before">
+            <field name="account_accrued_revenue_id" attrs="{'invisible': [('type_tax_use', '=', 'purchase')]}"/>
+            <newline />
+            <field name="account_accrued_expense_id" attrs="{'invisible': [('type_tax_use', '=', 'sale')]}"/>
+        </separator>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added file 'account_cutoff_accrual_base/company.py'
--- account_cutoff_accrual_base/company.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/company.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,37 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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_company(orm.Model):
+    _inherit = 'res.company'
+
+    _columns = {
+        'default_accrued_revenue_account_id': fields.many2one(
+            'account.account', 'Default Account for Accrued Revenues',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+        'default_accrued_expense_account_id': fields.many2one(
+            'account.account', 'Default Account for Accrued Expenses',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+    }

=== added file 'account_cutoff_accrual_base/company_view.xml'
--- account_cutoff_accrual_base/company_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/company_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<record id="view_company_form" model="ir.ui.view">
+    <field name="name">accrual.base.company.form</field>
+    <field name="model">res.company</field>
+    <field name="inherit_id" ref="account_cutoff_base.view_company_form" />
+    <field name="arch" type="xml">
+        <field name="default_cutoff_journal_id" position="after">
+            <field name="default_accrued_revenue_account_id" />
+            <field name="default_accrued_expense_account_id" />
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added directory 'account_cutoff_accrual_base/i18n'
=== added file 'account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot'
--- account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot	2014-03-09 00:39:34 +0000
@@ -0,0 +1,119 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+#	* account_cutoff_accrual_base
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 6.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-09 00:25+0000\n"
+"PO-Revision-Date: 2014-03-09 00:25+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: account_cutoff_accrual_base
+#: sql_constraint:account.cutoff:0
+msgid "A cutoff of the same type already exists with this cut-off date !"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.model,name:account_cutoff_accrual_base.model_account_cutoff_line
+msgid "Account Cut-off Line"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:res.company,default_accrued_expense_account_id:0
+msgid "Default Account for Accrued Expenses"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: constraint:account.cutoff:0
+msgid "The start date is after the end date!"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.model,name:account_cutoff_accrual_base.model_account_cutoff
+msgid "Account Cut-off"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.model,name:account_cutoff_accrual_base.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.actions.act_window,name:account_cutoff_accrual_base.account_expense_accrual_action
+#: model:ir.ui.menu,name:account_cutoff_accrual_base.account_expense_accrual_menu
+msgid "Accrued Expense"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:account.cutoff.line,price_unit:0
+msgid "Unit Price"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.actions.act_window,name:account_cutoff_accrual_base.account_revenue_accrual_action
+#: model:ir.ui.menu,name:account_cutoff_accrual_base.account_revenue_accrual_menu
+msgid "Accrued Revenue"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: view:account.tax:0
+msgid "Tax Declaration: Invoices"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:account.tax,account_accrued_revenue_id:0
+msgid "Accrued Revenue Tax Account"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:res.company,default_accrued_revenue_account_id:0
+msgid "Default Account for Accrued Revenues"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: sql_constraint:account.cutoff:0
+msgid "A cut-off of the same type already exists with the same date(s) !"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: help:account.cutoff.line,price_unit:0
+msgid "Price per unit (discount included)"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: model:ir.model,name:account_cutoff_accrual_base.model_account_tax
+msgid "account.tax"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: sql_constraint:account.tax:0
+msgid "Tax Name must be unique per company!"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:account.tax,account_accrued_expense_id:0
+msgid "Accrued Expense Tax Account"
+msgstr ""
+
+#. module: account_cutoff_accrual_base
+#: field:account.cutoff.line,quantity:0
+msgid "Quantity"
+msgstr ""
+

=== added directory 'account_cutoff_accrual_picking'
=== added file 'account_cutoff_accrual_picking/__init__.py'
--- account_cutoff_accrual_picking/__init__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_picking/__init__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,23 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Picking module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 . import account_cutoff

=== added file 'account_cutoff_accrual_picking/__openerp__.py'
--- account_cutoff_accrual_picking/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_picking/__openerp__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,61 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Picking module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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': 'Account Accrual Picking',
+    'version': '0.1',
+    'category': 'Accounting & Finance',
+    'license': 'AGPL-3',
+    'summary': 'Accrued Expense & Accrued Revenue from Pickings',
+    'description': """
+Manage expense and revenue accruals from pickings
+=================================================
+
+This module generates expense and revenue accruals based on the status of pickings.
+
+For revenue accruals, OpenERP will take into account all the delivery orders in *Delivered* state that have been shipped before the cut-off date and that have *Invoice Control* = *To Be Invoiced*.
+
+For expense accruals, OpenERP will take into account all the incoming shipments in *Received* state that have been received before the cut-off date and that have *Invoice Control* = *To Be Invoiced*.
+
+The current code of the module only works when :
+
+* on sale orders, the *Create Invoice* field is set to *On Delivery Order* ;
+* for purchase orders, the *Invoicing Control* field is set to *Based on incoming shipments*.
+
+Please contact Alexis de Lattre from Akretion <alexis.delattre@xxxxxxxxxxxx> for any help or question about this module.
+    """,
+    'author': 'Akretion',
+    'website': 'http://www.akretion.com',
+    'depends': ['account_cutoff_accrual_base', 'purchase', 'sale'],
+    'data': [
+        'account_cutoff_view.xml',
+    ],
+    'images': [
+        'images/accrued_expense_draft.jpg',
+        'images/accrued_expense_journal_entry.jpg',
+        'images/accrued_expense_done.jpg',
+        ],
+    'installable': True,
+    'active': False,
+    'application': True,
+}

=== added file 'account_cutoff_accrual_picking/account_cutoff.py'
--- account_cutoff_accrual_picking/account_cutoff.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_picking/account_cutoff.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,220 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Accrual Picking module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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.tools.translate import _
+
+
+class account_cutoff(orm.Model):
+    _inherit = 'account.cutoff'
+
+    def _prepare_lines_from_picking(
+            self, cr, uid, ids, cur_cutoff, move_line, account_mapping,
+            context=None):
+        tax_obj = self.pool['account.tax']
+        curr_obj = self.pool['res.currency']
+        company_currency_id = cur_cutoff['company_currency_id'][0]
+        assert cur_cutoff['type'] in ('accrued_expense', 'accrued_revenue'),\
+            "The field 'type' has a wrong value"
+        if cur_cutoff['type'] == 'accrued_expense':
+            account_id = move_line.product_id.property_account_expense.id
+            if not account_id:
+                account_id = move_line.product_id.categ_id.\
+                    property_account_expense_categ.id
+            if not account_id:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing expense account on product '%s' or on its "
+                        "related product category.")
+                    % (move_line.product_id.name))
+            currency = move_line.purchase_line_id.order_id.\
+                pricelist_id.currency_id
+            analytic_account_id = move_line.purchase_line_id.\
+                account_analytic_id.id or False
+            price_unit = move_line.purchase_line_id.price_unit
+            taxes = move_line.purchase_line_id.taxes_id
+            partner_id = move_line.purchase_line_id.order_id.partner_id.id
+            tax_account_field_name = 'account_accrued_expense_id'
+            tax_account_field_label = 'Accrued Expense Tax Account'
+
+        elif cur_cutoff['type'] == 'accrued_revenue':
+            account_id = move_line.product_id.property_account_income.id
+            if not account_id:
+                account_id = move_line.product_id.categ_id.\
+                    property_account_income_categ.id
+            if not account_id:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing income account on product '%s' or on its "
+                        "related product category.")
+                    % (move_line.product_id.name))
+            currency = move_line.sale_line_id.order_id.pricelist_id.currency_id
+            analytic_account_id = move_line.sale_line_id.order_id.\
+                project_id.id or False
+            discount = move_line.sale_line_id.discount
+            price_unit = move_line.sale_line_id.price_unit *\
+                (1-(discount or 0.0)/100.0)
+            taxes = move_line.sale_line_id.tax_id
+            partner_id = move_line.sale_line_id.order_id.partner_id.id
+            tax_account_field_name = 'account_accrued_revenue_id'
+            tax_account_field_label = 'Accrued Revenue Tax Account'
+
+        currency_id = currency.id
+        quantity = move_line.product_qty
+        tax_line_ids = []
+        tax_res = self.pool['account.tax'].compute_all(
+            cr, uid, taxes, price_unit, quantity,
+            move_line.product_id.id, partner_id)
+        amount = tax_res['total']  # =total without taxes
+        if cur_cutoff['type'] == 'accrued_expense':
+            amount = amount * -1
+        context_currency_compute = context.copy()
+        context_currency_compute['date'] = cur_cutoff['cutoff_date']
+        for tax_line in tax_res['taxes']:
+            tax_read = tax_obj.read(
+                cr, uid, tax_line['id'],
+                [tax_account_field_name, 'name'], context=context)
+            tax_accrual_account_id = tax_read[tax_account_field_name]
+            if not tax_accrual_account_id:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing '%s' on tax '%s'.")
+                    % (tax_account_field_label, tax_read['name']))
+            else:
+                tax_accrual_account_id = tax_accrual_account_id[0]
+            if cur_cutoff['type'] == 'accrued_expense':
+                tax_line['amount'] = tax_line['amount'] * -1
+            if company_currency_id != currency_id:
+                tax_accrual_amount = curr_obj.compute(
+                    cr, uid, currency_id, company_currency_id,
+                    tax_line['amount'],
+                    context=context_currency_compute)
+            else:
+                tax_accrual_amount = tax_line['amount']
+            tax_line_ids.append((0, 0, {
+                'tax_id': tax_line['id'],
+                'base': curr_obj.round(
+                    cr, uid, currency,
+                    tax_line['price_unit'] * quantity),
+                'amount': tax_line['amount'],
+                'sequence': tax_line['sequence'],
+                'cutoff_account_id': tax_accrual_account_id,
+                'cutoff_amount': tax_accrual_amount,
+                'analytic_account_id':
+                tax_line['account_analytic_collected_id'],
+                # account_analytic_collected_id is for
+                # invoices IN and OUT
+                }))
+        if company_currency_id != currency_id:
+            amount_company_currency = curr_obj.compute(
+                cr, uid, currency_id, company_currency_id, amount,
+                context=context_currency_compute)
+        else:
+            amount_company_currency = amount
+
+        # we use account mapping here
+        if account_id in account_mapping:
+            accrual_account_id = account_mapping[account_id]
+        else:
+            accrual_account_id = account_id
+        res = {
+            'parent_id': ids[0],
+            'partner_id': partner_id,
+            'stock_move_id': move_line.id,
+            'name': move_line.name,
+            'account_id': account_id,
+            'cutoff_account_id': accrual_account_id,
+            'analytic_account_id': analytic_account_id,
+            'currency_id': currency_id,
+            'quantity': quantity,
+            'price_unit': price_unit,
+            'tax_ids': [(6, 0, [tax.id for tax in taxes])],
+            'amount': amount,
+            'cutoff_amount': amount_company_currency,
+            'tax_line_ids': tax_line_ids,
+            }
+        return res
+
+    def get_lines_from_picking(self, cr, uid, ids, context=None):
+        assert len(ids) == 1, \
+            'This function should only be used for a single id at a time'
+        pick_obj = self.pool['stock.picking']
+        line_obj = self.pool['account.cutoff.line']
+        mapping_obj = self.pool['account.cutoff.mapping']
+
+        cur_cutoff = self.read(cr, uid, ids[0], [
+            'line_ids', 'type', 'cutoff_date', 'company_id',
+            'company_currency_id',
+            ],
+            context=context)
+        # delete existing lines based on pickings
+        to_delete_line_ids = line_obj.search(
+            cr, uid, [
+                ('parent_id', '=', cur_cutoff['id']),
+                ('stock_move_id', '!=', False)
+                ],
+            context=context)
+        if to_delete_line_ids:
+            line_obj.unlink(cr, uid, to_delete_line_ids, context=context)
+        pick_type_map = {
+            'accrued_revenue': 'out',
+            'accrued_expense': 'in',
+        }
+        assert cur_cutoff['type'] in pick_type_map, \
+            "cur_cutoff['type'] should be in pick_type_map.keys()"
+        pick_ids = pick_obj.search(cr, uid, [
+            ('type', '=', pick_type_map[cur_cutoff['type']]),
+            ('state', '=', 'done'),
+            ('invoice_state', '=', '2binvoiced'),
+            ('date_done', '<=', cur_cutoff['cutoff_date'])
+            ], context=context)
+        #print "pick_ids=", pick_ids
+        # Create account mapping dict
+        account_mapping = mapping_obj._get_mapping_dict(
+            cr, uid, cur_cutoff['company_id'][0], cur_cutoff['type'],
+            context=context)
+        for picking in pick_obj.browse(cr, uid, pick_ids, context=context):
+            for move_line in picking.move_lines:
+                line_obj.create(
+                    cr, uid, self._prepare_lines_from_picking(
+                        cr, uid, ids, cur_cutoff, move_line,
+                        account_mapping, context=context),
+                    context=context)
+        return True
+
+
+class account_cutoff_line(orm.Model):
+    _inherit = 'account.cutoff.line'
+
+    _columns = {
+        'stock_move_id': fields.many2one(
+            'stock.move', 'Stock Move', readonly=True),
+        'product_id': fields.related(
+            'stock_move_id', 'product_id', type='many2one',
+            relation='product.product', string='Product', readonly=True),
+        'picking_id': fields.related(
+            'stock_move_id', 'picking_id', type='many2one',
+            relation='stock.picking', string='Picking', readonly=True),
+        'picking_date_done': fields.related(
+            'picking_id', 'date_done', type='date',
+            string='Date Done of the Picking', readonly=True),
+        }

=== added file 'account_cutoff_accrual_picking/account_cutoff_view.xml'
--- account_cutoff_accrual_picking/account_cutoff_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_picking/account_cutoff_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<!-- Form view -->
+<record id="account_cutoff_form" model="ir.ui.view">
+    <field name="name">account.cutoff.picking.form</field>
+    <field name="model">account.cutoff</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_form"/>
+    <field name="arch" type="xml">
+        <button name="create_move" position="before">
+            <button name="get_lines_from_picking" string="Re-Generate Lines from Picking" type="object" states="draft" invisible="'accrued' not in context.get('type', '-')"/>
+        </button>
+    </field>
+</record>
+
+<!-- Form view for lines -->
+<record id="account_cutoff_line_form" model="ir.ui.view">
+    <field name="name">account.cutoff.line.picking.form</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
+    <field name="arch" type="xml">
+        <field name="parent_id" position="after">
+            <field name="stock_move_id" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="product_id" invisible="'accrued' not in context.get('type', '-')" />
+            <field name="picking_id" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="picking_date_done" invisible="'accrued' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+<!-- Tree view for lines -->
+<record id="account_cutoff_line_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.line.picking.tree</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
+    <field name="arch" type="xml">
+        <field name="parent_id" position="after">
+            <field name="stock_move_id" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="picking_date_done" invisible="'accrued' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added directory 'account_cutoff_accrual_picking/i18n'
=== added file 'account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot'
--- account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot	1970-01-01 00:00:00 +0000
+++ account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot	2014-03-09 00:39:34 +0000
@@ -0,0 +1,93 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+#	* account_cutoff_accrual_picking
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 6.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-09 00:26+0000\n"
+"PO-Revision-Date: 2014-03-09 00:26+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: account_cutoff_accrual_picking
+#: sql_constraint:account.cutoff:0
+msgid "A cutoff of the same type already exists with this cut-off date !"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: model:ir.model,name:account_cutoff_accrual_picking.model_account_cutoff_line
+msgid "Account Cut-off Line"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: field:account.cutoff.line,product_id:0
+msgid "Product"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: field:account.cutoff.line,stock_move_id:0
+msgid "Stock Move"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: model:ir.model,name:account_cutoff_accrual_picking.model_account_cutoff
+msgid "Account Cut-off"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: view:account.cutoff:0
+msgid "Re-Generate Lines from Picking"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:67
+#, python-format
+msgid "Missing income account on product '%s' or on its related product category."
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:46
+#, python-format
+msgid "Missing expense account on product '%s' or on its related product category."
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:100
+#, python-format
+msgid "Missing '%s' on tax '%s'."
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: sql_constraint:account.cutoff:0
+msgid "A cut-off of the same type already exists with the same date(s) !"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: constraint:account.cutoff:0
+msgid "The start date is after the end date!"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: field:account.cutoff.line,picking_id:0
+msgid "Picking"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: field:account.cutoff.line,picking_date_done:0
+msgid "Date Done of the Picking"
+msgstr ""
+
+#. module: account_cutoff_accrual_picking
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:45
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:66
+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:99
+#, python-format
+msgid "Error:"
+msgstr ""
+

=== added directory 'account_cutoff_accrual_picking/images'
=== added file 'account_cutoff_accrual_picking/images/accrued_expense_done.jpg'
Binary files account_cutoff_accrual_picking/images/accrued_expense_done.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_accrual_picking/images/accrued_expense_done.jpg	2014-03-09 00:39:34 +0000 differ
=== added file 'account_cutoff_accrual_picking/images/accrued_expense_draft.jpg'
Binary files account_cutoff_accrual_picking/images/accrued_expense_draft.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_accrual_picking/images/accrued_expense_draft.jpg	2014-03-09 00:39:34 +0000 differ
=== added file 'account_cutoff_accrual_picking/images/accrued_expense_journal_entry.jpg'
Binary files account_cutoff_accrual_picking/images/accrued_expense_journal_entry.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_accrual_picking/images/accrued_expense_journal_entry.jpg	2014-03-09 00:39:34 +0000 differ
=== added directory 'account_cutoff_accrual_picking/static'
=== added directory 'account_cutoff_accrual_picking/static/src'
=== added directory 'account_cutoff_accrual_picking/static/src/img'
=== added file 'account_cutoff_accrual_picking/static/src/img/icon.png'
Binary files account_cutoff_accrual_picking/static/src/img/icon.png	1970-01-01 00:00:00 +0000 and account_cutoff_accrual_picking/static/src/img/icon.png	2014-03-09 00:39:34 +0000 differ
=== added directory 'account_cutoff_base'
=== added file 'account_cutoff_base/__init__.py'
--- account_cutoff_base/__init__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/__init__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,24 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 . import account_cutoff
+from . import company

=== added file 'account_cutoff_base/__openerp__.py'
--- account_cutoff_base/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/__openerp__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,47 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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': 'Account Cut-off Base',
+    'version': '0.1',
+    'category': 'Accounting & Finance',
+    'license': 'AGPL-3',
+    'summary': 'Base module for Account Cut-offs',
+    'description': """This module contains objets, fields and menu entries that are used by other cut-off modules. So you need to install other cut-off modules to get the additionnal functionalities :
+
+* the module *account_cutoff_prepaid* will manage prepaid cut-offs based on start date and end date,
+* the module *account_cutoff_accrual_picking* will manage the accruals based on the status of the pickings.
+
+Please contact Alexis de Lattre from Akretion <alexis.delattre@xxxxxxxxxxxx> for any help or question about this module.
+    """,
+    'author': 'Akretion',
+    'website': 'http://www.akretion.com',
+    'depends': ['account_accountant'],
+    'data': [
+        'company_view.xml',
+        'account_cutoff_view.xml',
+        'security/ir.model.access.csv',
+    ],
+    'installable': True,
+    'active': False,
+}

=== added file 'account_cutoff_base/account_cutoff.py'
--- account_cutoff_base/account_cutoff.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/account_cutoff.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,438 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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
+import decimal_precision as dp
+from openerp.tools.translate import _
+from datetime import datetime
+
+
+class account_cutoff(orm.Model):
+    _name = 'account.cutoff'
+    _rec_name = 'cutoff_date'
+    _order = 'cutoff_date desc'
+    _description = 'Account Cut-off'
+
+    def copy(self, cr, uid, id, default=None, context=None):
+        if default is None:
+            default = {}
+        default.update({
+            'cutoff_date': '%d-12-31' % datetime.today().year,
+            'move_id': False,
+            'state': 'draft',
+            'line_ids': False,
+            })
+        return super(account_cutoff, self).copy(
+            cr, uid, id, default=default, context=context)
+
+    def _compute_total_cutoff(self, cr, uid, ids, name, arg, context=None):
+        res = {}
+        for cutoff in self.browse(cr, uid, ids, context=context):
+            res[cutoff.id] = 0
+            for line in cutoff.line_ids:
+                res[cutoff.id] += line.cutoff_amount
+        return res
+
+    _columns = {
+        'cutoff_date': fields.date(
+            'Cut-off Date', readonly=True,
+            states={'draft': [('readonly', False)]}),
+        'type': fields.selection([
+            ('accrued_revenue', 'Accrued Revenue'),
+            ('accrued_expense', 'Accrued Expense'),
+            ('prepaid_revenue', 'Prepaid Revenue'),
+            ('prepaid_expense', 'Prepaid Expense'),
+            ], 'Type', required=True, readonly=True,
+            states={'draft': [('readonly', False)]}),
+        'move_id': fields.many2one(
+            'account.move', 'Cut-off Journal Entry', readonly=True),
+        'move_label': fields.char(
+            'Label of the Cut-off Journal Entry',
+            size=64, readonly=True,
+            states={'draft': [('readonly', False)]},
+            help="This label will be written in the 'Name' field of the "
+            "Cut-off Account Move Lines and in the 'Reference' field of "
+            "the Cut-off Account Move."),
+        'cutoff_account_id': fields.many2one(
+            'account.account', 'Cut-off Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            readonly=True, states={'draft': [('readonly', False)]}),
+        'cutoff_journal_id': fields.many2one(
+            'account.journal', 'Cut-off Account Journal',
+            readonly=True, states={'draft': [('readonly', False)]}),
+        'total_cutoff_amount': fields.function(
+            _compute_total_cutoff, type='float', string="Total Cut-off Amount",
+            readonly=True),
+        'company_id': fields.many2one(
+            'res.company', 'Company', required=True, readonly=True,
+            states={'draft': [('readonly', False)]}),
+        'company_currency_id': fields.related(
+            'company_id', 'currency_id', readonly=True, type='many2one',
+            relation='res.currency', string='Company Currency'),
+        'line_ids': fields.one2many(
+            'account.cutoff.line', 'parent_id', 'Cut-off Lines', readonly=True,
+            states={'draft': [('readonly', False)]}),
+        'state': fields.selection([
+            ('draft', 'Draft'),
+            ('done', 'Done'),
+            ],
+            'State', select=True, readonly=True,
+            help="State of the cutoff. When the Journal Entry is created, "
+            "the state is set to 'Done' and the fields become read-only."),
+    }
+
+    def _get_default_journal(self, cr, uid, context=None):
+        cur_user = self.pool['res.users'].browse(cr, uid, uid, context=context)
+        return cur_user.company_id.default_cutoff_journal_id.id or None
+
+    def _default_move_label(self, cr, uid, context=None):
+        if context is None:
+            context = {}
+        type = context.get('type')
+        cutoff_date = context.get('cutoff_date')
+        if cutoff_date:
+            cutoff_date_label = ' dated %s' % cutoff_date
+        else:
+            cutoff_date_label = ''
+        label = ''
+        if type == 'accrued_expense':
+            label = _('Accrued Expense%s') % cutoff_date_label
+        elif type == 'accrued_revenue':
+            label = _('Accrued Revenue%s') % cutoff_date_label
+        elif type == 'prepaid_revenue':
+            label = _('Prepaid Revenue%s') % cutoff_date_label
+        elif type == 'prepaid_expense':
+            label = _('Prepaid Expense%s') % cutoff_date_label
+        return label
+
+    def _default_type(self, cr, uid, context=None):
+        if context is None:
+            context = {}
+        return context.get('type')
+
+    def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
+        '''Function designed to be inherited by other cutoff modules'''
+        return None
+
+    def _default_cutoff_account_id(self, cr, uid, context=None):
+        '''This function can't be inherited, so we use a second function'''
+        return self._inherit_default_cutoff_account_id(
+            cr, uid, context=context)
+
+    _defaults = {
+        'state': 'draft',
+        'company_id': lambda self, cr, uid, context:
+        self.pool['res.users'].browse(
+            cr, uid, uid, context=context).company_id.id,
+        'cutoff_journal_id': _get_default_journal,
+        'move_label': _default_move_label,
+        'type': _default_type,
+        'cutoff_account_id': _default_cutoff_account_id,
+        }
+
+    _sql_constraints = [(
+        'date_type_company_uniq',
+        'unique(cutoff_date, company_id, type)',
+        'A cutoff of the same type already exists with this cut-off date !'
+        )]
+
+    def cutoff_date_onchange(
+            self, cr, uid, ids, type, cutoff_date, move_label, context=None):
+        if context is None:
+            context = {}
+        res = {'value': {}}
+        if type and cutoff_date:
+            ctx = context.copy()
+            ctx.update({'type': type, 'cutoff_date': cutoff_date})
+            res['value']['move_label'] = self._default_move_label(
+                cr, uid, context=ctx)
+        return res
+
+    def back2draft(self, cr, uid, ids, context=None):
+        assert len(ids) == 1,\
+            'This function should only be used for a single id at a time'
+        cur_cutoff = self.browse(cr, uid, ids[0], context=context)
+        if cur_cutoff.move_id:
+            self.pool['account.move'].unlink(
+                cr, uid, [cur_cutoff.move_id.id], context=context)
+        self.write(cr, uid, ids[0], {'state': 'draft'}, context=context)
+        return True
+
+    def _prepare_move(self, cr, uid, cur_cutoff, to_provision, context=None):
+        if context is None:
+            context = {}
+        movelines_to_create = []
+        amount_total = 0
+        move_label = cur_cutoff.move_label
+        for (cutoff_account_id, analytic_account_id), amount in \
+                to_provision.items():
+            movelines_to_create.append((0, 0, {
+                'account_id': cutoff_account_id,
+                'name': move_label,
+                'debit': amount < 0 and amount * -1 or 0,
+                'credit': amount >= 0 and amount or 0,
+                'analytic_account_id': analytic_account_id,
+            }))
+            amount_total += amount
+
+        # add contre-partie
+        counterpart_amount = amount_total * -1
+        movelines_to_create.append((0, 0, {
+            'account_id': cur_cutoff.cutoff_account_id.id,
+            'debit': counterpart_amount < 0 and counterpart_amount * -1 or 0,
+            'credit': counterpart_amount >= 0 and counterpart_amount or 0,
+            'name': move_label,
+            'analytic_account_id': False,
+        }))
+
+        # Select period
+        local_ctx = context.copy()
+        local_ctx['account_period_prefer_normal'] = True
+        period_search = self.pool['account.period'].find(
+            cr, uid, cur_cutoff.cutoff_date, context=local_ctx)
+        if len(period_search) != 1:
+            raise orm.except_orm(
+                'Error:', "No matching period for date '%s'"
+                % cur_cutoff.cutoff_date)
+        period_id = period_search[0]
+
+        res = {
+            'journal_id': cur_cutoff.cutoff_journal_id.id,
+            'date': cur_cutoff.cutoff_date,
+            'period_id': period_id,
+            'ref': move_label,
+            'line_id': movelines_to_create,
+            }
+        return res
+
+    def create_move(self, cr, uid, ids, context=None):
+        assert len(ids) == 1, \
+            'This function should only be used for a single id at a time'
+        move_obj = self.pool['account.move']
+        cur_cutoff = self.browse(cr, uid, ids[0], context=context)
+        if cur_cutoff.move_id:
+            raise orm.except_orm(
+                _('Error:'),
+                _("The Cut-off Journal Entry already exists. You should "
+                    "delete it before running this function."))
+        if not cur_cutoff.line_ids:
+            raise orm.except_orm(
+                _('Error:'),
+                _("There are no lines on this Cut-off, so we can't create "
+                    "a Journal Entry."))
+        to_provision = {}
+        # key = (cutoff_account_id, analytic_account_id)
+        # value = amount
+        for line in cur_cutoff.line_ids:
+            # if it is already present
+            if (
+                    line.cutoff_account_id.id,
+                    line.analytic_account_id.id or False
+                    ) in to_provision:
+                to_provision[(
+                    line.cutoff_account_id.id,
+                    line.analytic_account_id.id or False
+                    )] += line.cutoff_amount
+            else:
+            # if not already present
+                to_provision[(
+                    line.cutoff_account_id.id,
+                    line.analytic_account_id.id or False
+                    )] = line.cutoff_amount
+            # Same for tax lines
+            for tax_line in line.tax_line_ids:
+                if (
+                        tax_line.cutoff_account_id.id,
+                        tax_line.analytic_account_id.id or False
+                        ) in to_provision:
+                    to_provision[(
+                        tax_line.cutoff_account_id.id,
+                        tax_line.analytic_account_id.id or False
+                        )] += tax_line.cutoff_amount
+                else:
+                    to_provision[(
+                        tax_line.cutoff_account_id.id,
+                        tax_line.analytic_account_id.id or False
+                        )] = tax_line.cutoff_amount
+
+        vals = self._prepare_move(
+            cr, uid, cur_cutoff, to_provision, context=context)
+        move_id = move_obj.create(cr, uid, vals, context=context)
+        move_obj.validate(cr, uid, [move_id], context=context)
+        self.write(cr, uid, ids[0], {
+            'move_id': move_id,
+            'state': 'done',
+            }, context=context)
+
+        action = {
+            'name': 'Cut-off Account Move',
+            'view_type': 'form',
+            'view_mode': 'form,tree',
+            'res_id': move_id,
+            'res_model': 'account.move',
+            'type': 'ir.actions.act_window',
+            'nodestroy': True,
+            'target': 'current',
+            }
+        return action
+
+
+class account_cutoff_line(orm.Model):
+    _name = 'account.cutoff.line'
+    _description = 'Account Cut-off Line'
+
+    _columns = {
+        'parent_id': fields.many2one(
+            'account.cutoff', 'Cut-off', ondelete='cascade'),
+        'name': fields.char('Description', size=64),
+        'company_currency_id': fields.related(
+            'parent_id', 'company_currency_id', type='many2one',
+            relation='res.currency', string="Company Currency", readonly=True),
+        'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
+        'account_id': fields.many2one(
+            'account.account', 'Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            required=True, readonly=True),
+        'cutoff_account_id': fields.many2one(
+            'account.account', 'Cut-off Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            required=True, readonly=True),
+        'cutoff_account_code': fields.related(
+            'cutoff_account_id', 'code', type='char',
+            string='Cut-off Account Code', readonly=True),
+        'analytic_account_id': fields.many2one(
+            'account.analytic.account', 'Analytic Account',
+            domain=[('type', 'not in', ('view', 'template'))],
+            readonly=True),
+        'analytic_account_code': fields.related(
+            'analytic_account_id', 'code', type='char',
+            string='Analytic Account Code', readonly=True),
+        'currency_id': fields.many2one(
+            'res.currency', 'Amount Currency', readonly=True,
+            help="Currency of the 'Amount' field."),
+        'amount': fields.float(
+            'Amount', digits_compute=dp.get_precision('Account'),
+            readonly=True,
+            help="Amount that is used as base to compute the Cut-off Amount. "
+            "This Amount is in the 'Amount Currency', which may be different "
+            "from the 'Company Currency'."),
+        'cutoff_amount': fields.float(
+            'Cut-off Amount', digits_compute=dp.get_precision('Account'),
+            readonly=True,
+            help="Cut-off Amount without taxes in the Company Currency."),
+        'tax_ids': fields.many2many(
+            'account.tax', id1='cutoff_line_id', id2='tax_id', string='Taxes',
+            readonly=True),
+        'tax_line_ids': fields.one2many(
+            'account.cutoff.tax.line', 'parent_id', 'Cut-off Tax Lines',
+            readonly=True),
+    }
+
+
+class account_cutoff_tax_line(orm.Model):
+    _name = 'account.cutoff.tax.line'
+    _description = 'Account Cut-off Tax Line'
+
+    _columns = {
+        'parent_id': fields.many2one(
+            'account.cutoff.line', 'Account Cut-off Line',
+            ondelete='cascade', required=True),
+        'tax_id': fields.many2one('account.tax', 'Tax', required=True),
+        'cutoff_account_id': fields.many2one(
+            'account.account', 'Cut-off Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            required=True, readonly=True),
+        'analytic_account_id': fields.many2one(
+            'account.analytic.account', 'Analytic Account',
+            domain=[('type', 'not in', ('view', 'template'))],
+            readonly=True),
+        'base': fields.float(
+            'Base', digits_compute=dp.get_precision('Account'),
+            readonly=True, help="Base Amount in the currency of the PO."),
+        'amount': fields.float(
+            'Tax Amount', digits_compute=dp.get_precision('Account'),
+            readonly=True, help='Tax Amount in the currency of the PO.'),
+        'sequence': fields.integer('Sequence', readonly=True),
+        'cutoff_amount': fields.float(
+            'Cut-off Tax Amount', digits_compute=dp.get_precision('Account'),
+            readonly=True,
+            help="Tax Cut-off Amount in the company currency."),
+        'currency_id': fields.related(
+            'parent_id', 'currency_id', type='many2one',
+            relation='res.currency', string='Currency', readonly=True),
+        'company_currency_id': fields.related(
+            'parent_id', 'company_currency_id',
+            type='many2one', relation='res.currency',
+            string="Company Currency", readonly=True),
+        }
+
+
+class account_cutoff_mapping(orm.Model):
+    _name = 'account.cutoff.mapping'
+    _description = 'Account Cut-off Mapping'
+    _rec_name = 'account_id'
+
+    _columns = {
+        'company_id': fields.many2one('res.company', 'Company', required=True),
+        'account_id': fields.many2one(
+            'account.account', 'Regular Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            required=True),
+        'cutoff_account_id': fields.many2one(
+            'account.account', 'Cut-off Account',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
+            required=True),
+        'cutoff_type': fields.selection([
+            ('all', 'All Cut-off Types'),
+            ('accrued_revenue', 'Accrued Revenue'),
+            ('accrued_expense', 'Accrued Expense'),
+            ('prepaid_revenue', 'Prepaid Revenue'),
+            ('prepaid_expense', 'Prepaid Expense'),
+            ], 'Cut-off Type', required=True),
+    }
+
+    _defaults = {
+        'company_id': lambda self, cr, uid, context:
+        self.pool['res.users'].browse(
+            cr, uid, uid, context=context).company_id.id,
+        }
+
+    def _get_mapping_dict(
+            self, cr, uid, company_id, cutoff_type='all', context=None):
+        '''return a dict with:
+        key = ID of account,
+        value = ID of cutoff_account'''
+        if cutoff_type == 'all':
+            cutoff_type_filter = ('all')
+        else:
+            cutoff_type_filter = ('all', cutoff_type)
+        mapping_ids = self.search(
+            cr, uid, [
+                ('company_id', '=', company_id),
+                ('cutoff_type', 'in', cutoff_type_filter),
+                ],
+            context=context)
+        mapping_read = self.read(cr, uid, mapping_ids, context=context)
+        mapping = {}
+        for item in mapping_read:
+            mapping[item['account_id'][0]] = item['cutoff_account_id'][0]
+        return mapping

=== added file 'account_cutoff_base/account_cutoff_view.xml'
--- account_cutoff_base/account_cutoff_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/account_cutoff_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<menuitem id="cutoff_menu"
+    parent="account.menu_finance_periodical_processing"
+    name="Cut-offs"
+    sequence="24"
+    groups="account.group_account_user,account.group_account_manager,account.group_account_invoice"/>
+
+<!-- Form view -->
+<record id="account_cutoff_form" model="ir.ui.view">
+    <field name="name">account.cutoff.form</field>
+    <field name="model">account.cutoff</field>
+    <field name="type">form</field>
+    <field name="arch" type="xml">
+        <form string="Cut-offs">
+            <group name="general-params" colspan="2" col="2">
+                <field name="type" readonly="1" />
+                <field name="cutoff_date" on_change="cutoff_date_onchange(type, cutoff_date, move_label, context)" required="1"/>
+                <field name="total_cutoff_amount" />
+                <field name="company_currency_id" />
+                <field name="company_id" groups="base.group_multi_company" widget="selection" />
+            </group>
+            <group name="accounting-params" colspan="2" col="2">
+                <field name="cutoff_journal_id" required="1"/>
+                <field name="cutoff_account_id" required="1"/>
+                <field name="move_label" required="1"/>
+                <field name="move_id"/>
+            </group>
+            <button name="create_move" string="Create Journal Entry" type="object" states="draft" attrs="{'invisible': ['|', ('line_ids', '=', False), ('state', '=', 'done')]}"/>
+            <newline />
+            <field name="line_ids" nolabel="1" context="{'type': type}" colspan="4"/>
+            <group colspan="4">
+                <field name="state" widget="statusbar" />
+                <button name="back2draft" string="Back to Draft" type="object" states="done" />
+            </group>
+        </form>
+    </field>
+</record>
+
+<!-- Tree view -->
+<record id="account_cutoff_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.tree</field>
+    <field name="model">account.cutoff</field>
+    <field name="type">tree</field>
+    <field name="arch" type="xml">
+        <tree string="Cut-offs" colors="blue:state=='draft'">
+            <field name="type" invisible="context.get('type')" />
+            <field name="cutoff_date" />
+            <field name="total_cutoff_amount"/>
+            <field name="company_currency_id"/>
+            <field name="state"/>
+        </tree>
+    </field>
+</record>
+
+<!-- Search view -->
+<record id="account_cutoff_filter" model="ir.ui.view">
+    <field name="name">account.cutoff.filter</field>
+    <field name="model">account.cutoff</field>
+    <field name="type">search</field>
+    <field name="arch" type="xml">
+        <search string="Search Cut-offs">
+            <filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" icon="terp-document-new" />
+            <filter name="done" string="Done" domain="[('state', '=', 'done')]" icon="terp-camera_test" />
+        </search>
+    </field>
+</record>
+
+<!-- Form view for lines -->
+<record id="account_cutoff_line_form" model="ir.ui.view">
+    <field name="name">account.cutoff.line.form</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="type">form</field>
+    <field name="arch" type="xml">
+        <form string="Cut-off Lines">
+            <group name="source" string="Source" colspan="4" col="4">
+                <field name="parent_id" invisible="not context.get('account_cutoff_line_main_view', False)"/>
+                <field name="partner_id"/>
+                <field name="name"/>
+                <field name="account_id"/>
+                <field name="cutoff_account_id"/>
+                <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
+                <field name="tax_ids" invisible="'accrued' not in context.get('type', '-')"/>
+                <field name="amount" />
+                <field name="currency_id" />
+            </group>
+            <group name="cutoff" string="Cut-off Computation" colspan="4" col="4">
+                <field name="cutoff_amount" />
+                <field name="company_currency_id" />
+                <field name="tax_line_ids" nolabel="1" invisible="'accrued' not in context.get('type', '-')" colspan="4"/>
+            </group>
+        </form>
+    </field>
+</record>
+
+<!-- Tree view for lines -->
+<record id="account_cutoff_line_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.line.tree</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="type">tree</field>
+    <field name="arch" type="xml">
+        <tree string="Cut-off Lines">
+            <field name="parent_id" invisible="not context.get('account_cutoff_line_main_view', False)"/>
+            <field name="partner_id"/>
+            <field name="name"/>
+            <field name="cutoff_account_code"/>
+            <field name="analytic_account_code" groups="analytic.group_analytic_accounting"/>
+            <field name="tax_ids" invisible="'accrued' not in context.get('type', '-')"/>
+            <field name="amount"/>
+            <field name="currency_id"/>
+            <field name="cutoff_amount"/>
+            <field name="company_currency_id"/>
+        </tree>
+    </field>
+</record>
+
+<!-- Form view for tax lines -->
+<record id="account_cutoff_tax_line_form" model="ir.ui.view">
+    <field name="name">account.cutoff.tax.line.form</field>
+    <field name="model">account.cutoff.tax.line</field>
+    <field name="type">form</field>
+    <field name="arch" type="xml">
+        <form string="Cut-off Tax Lines">
+            <group name="tax" string="Tax">
+                <field name="parent_id" invisible="not context.get('account_cutoff_tax_line_main_view', False)"/>
+                <field name="tax_id"/>
+                <field name="sequence"/>
+                <field name="cutoff_account_id"/>
+                <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
+                <field name="base"/>
+                <field name="amount"/>
+                <field name="currency_id"/>
+            </group>
+            <group name="cutoff" string="Cut-off Computation">
+                <field name="cutoff_amount"/>
+                <field name="company_currency_id"/>
+            </group>
+        </form>
+    </field>
+</record>
+
+<!-- Tree view for tax lines -->
+<record id="account_cutoff_tax_line_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.tax.line.tree</field>
+    <field name="model">account.cutoff.tax.line</field>
+    <field name="type">tree</field>
+    <field name="arch" type="xml">
+        <tree string="Cut-off Tax Lines">
+            <field name="parent_id" invisible="not context.get('account_cutoff_tax_line_main_view', False)"/>
+            <field name="tax_id"/>
+            <field name="cutoff_account_id"/>
+            <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
+            <field name="base"/>
+            <field name="amount"/>
+            <field name="currency_id"/>
+            <field name="cutoff_amount"/>
+            <field name="company_currency_id"/>
+            <field name="sequence" invisible="True"/>
+        </tree>
+    </field>
+</record>
+
+<!-- Form view for account mappings -->
+<record id="account_cutoff_mapping_form" model="ir.ui.view">
+    <field name="name">account.cutoff.mapping.form</field>
+    <field name="model">account.cutoff.mapping</field>
+    <field name="type">form</field>
+    <field name="arch" type="xml">
+        <form string="Account Cut-off Mapping">
+            <field name="company_id" groups="base.group_multi_company" widget="selection" invisible="not context.get('account_cutoff_mapping_main_view', False)" />
+            <field name="account_id"/>
+            <field name="cutoff_account_id"/>
+            <field name="cutoff_type"/>
+        </form>
+    </field>
+</record>
+
+<!-- Tree view for account mappings -->
+<record id="account_cutoff_mapping_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.mapping.tree</field>
+    <field name="model">account.cutoff.mapping</field>
+    <field name="type">tree</field>
+    <field name="arch" type="xml">
+        <tree string="Account Cut-off Mapping" editable="bottom">
+            <field name="company_id" groups="base.group_multi_company" widget="selection" invisible="not context.get('account_cutoff_mapping_main_view', False)" />
+            <field name="account_id"/>
+            <field name="cutoff_account_id"/>
+            <field name="cutoff_type"/>
+        </tree>
+    </field>
+</record>
+
+<!-- Action for account mappings -->
+<record id="account_cutoff_mapping_action" model="ir.actions.act_window">
+    <field name="name">Cut-off Account Mapping</field>
+    <field name="res_model">account.cutoff.mapping</field>
+    <field name="view_type">form</field>
+    <field name="view_mode">tree,form</field>
+    <field name="context">{'account_cutoff_mapping_main_view': True}</field>
+</record>
+
+<!-- Menu entry for account mapping -->
+<menuitem id="account_cutoff_mapping_menu"
+    parent="account.account_account_menu"
+    action="account_cutoff_mapping_action"
+    sequence="100"/>
+
+</data>
+</openerp>

=== added file 'account_cutoff_base/company.py'
--- account_cutoff_base/company.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/company.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,35 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Base module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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_company(orm.Model):
+    _inherit = 'res.company'
+
+    _columns = {
+        'default_cutoff_journal_id': fields.many2one(
+            'account.journal', 'Default Cut-off Journal'),
+        'cutoff_account_mapping_ids': fields.one2many(
+            'account.cutoff.mapping', 'company_id', 'Cut-off Account Mapping'),
+    }

=== added file 'account_cutoff_base/company_view.xml'
--- account_cutoff_base/company_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/company_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<record id="view_company_form" model="ir.ui.view">
+    <field name="name">cutoff.company.form</field>
+    <field name="model">res.company</field>
+    <field name="inherit_id" ref="base.view_company_form" />
+    <field name="arch" type="xml">
+        <field name="currency_id" position="after">
+            <group name="cutoff" string="Cut-offs" colspan="2" col="2">
+                <field name="default_cutoff_journal_id" />
+            </group>
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added directory 'account_cutoff_base/i18n'
=== added file 'account_cutoff_base/i18n/account_cutoff_base.pot'
--- account_cutoff_base/i18n/account_cutoff_base.pot	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/i18n/account_cutoff_base.pot	2014-03-09 00:39:34 +0000
@@ -0,0 +1,403 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+#	* account_cutoff_base
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 6.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-09 00:22+0000\n"
+"PO-Revision-Date: 2014-03-09 00:22+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: account_cutoff_base
+#: field:account.cutoff,line_ids:0
+#: view:account.cutoff.line:0
+msgid "Cut-off Lines"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,move_id:0
+msgid "Cut-off Journal Entry"
+msgstr ""
+
+#. module: account_cutoff_base
+#: constraint:account.cutoff:0
+msgid "The start date is after the end date!"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff,move_label:0
+msgid "This label will be written in the 'Name' field of the Cut-off Account Move Lines and in the 'Reference' field of the Cut-off Account Move."
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+msgid "Search Cut-offs"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff,state:0
+msgid "State of the cutoff. When the Journal Entry is created, the state is set to 'Done' and the fields become read-only."
+msgstr ""
+
+#. module: account_cutoff_base
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.mapping,cutoff_type:0
+msgid "Cut-off Type"
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:235
+#, python-format
+msgid "The Cut-off Journal Entry already exists. You should delete it before running this function."
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff.line:0
+msgid "Source"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,state:0
+msgid "State"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,cutoff_account_code:0
+msgid "Cut-off Account Code"
+msgstr ""
+
+#. module: account_cutoff_base
+#: selection:account.cutoff,type:0
+#: selection:account.cutoff.mapping,cutoff_type:0
+msgid "Prepaid Expense"
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:240
+#, python-format
+msgid "There are no lines on this Cut-off, so we can't create a Journal Entry."
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff.mapping:0
+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_mapping
+msgid "Account Cut-off Mapping"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.tax.line,amount:0
+msgid "Tax Amount in the currency of the PO."
+msgstr ""
+
+#. module: account_cutoff_base
+#: selection:account.cutoff,type:0
+#: selection:account.cutoff.mapping,cutoff_type:0
+msgid "Accrued Revenue"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,partner_id:0
+msgid "Partner"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,cutoff_date:0
+msgid "Cut-off Date"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,name:0
+msgid "Description"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,type:0
+msgid "Type"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,company_id:0
+#: field:account.cutoff.mapping,company_id:0
+msgid "Company"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,cutoff_journal_id:0
+msgid "Cut-off Account Journal"
+msgstr ""
+
+#. module: account_cutoff_base
+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_tax_line
+msgid "Account Cut-off Tax Line"
+msgstr ""
+
+#. module: account_cutoff_base
+#: selection:account.cutoff,type:0
+#: selection:account.cutoff.mapping,cutoff_type:0
+msgid "Prepaid Revenue"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.line,currency_id:0
+msgid "Currency of the 'Amount' field."
+msgstr ""
+
+#. module: account_cutoff_base
+#: selection:account.cutoff,type:0
+#: selection:account.cutoff.mapping,cutoff_type:0
+msgid "Accrued Expense"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,total_cutoff_amount:0
+msgid "Total Cut-off Amount"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,company_currency_id:0
+#: field:account.cutoff.line,company_currency_id:0
+#: field:account.cutoff.tax.line,company_currency_id:0
+msgid "Company Currency"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,base:0
+msgid "Base"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:res.company,default_cutoff_journal_id:0
+msgid "Default Cut-off Journal"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+#: selection:account.cutoff,state:0
+msgid "Done"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,parent_id:0
+msgid "Cut-off"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+msgid "Back to Draft"
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:234
+#: code:addons/account_cutoff_base/account_cutoff.py:239
+#, python-format
+msgid "Error:"
+msgstr ""
+
+#. module: account_cutoff_base
+#: sql_constraint:account.cutoff:0
+msgid "A cutoff of the same type already exists with this cut-off date !"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,parent_id:0
+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_line
+msgid "Account Cut-off Line"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,account_id:0
+msgid "Account"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,tax_line_ids:0
+#: view:account.cutoff.tax.line:0
+msgid "Cut-off Tax Lines"
+msgstr ""
+
+#. module: account_cutoff_base
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,cutoff_amount:0
+msgid "Cut-off Tax Amount"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.tax.line,cutoff_amount:0
+msgid "Tax Cut-off Amount in the company currency."
+msgstr ""
+
+#. module: account_cutoff_base
+#: model:ir.model,name:account_cutoff_base.model_account_cutoff
+msgid "Account Cut-off"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,amount:0
+msgid "Tax Amount"
+msgstr ""
+
+#. module: account_cutoff_base
+#: model:ir.model,name:account_cutoff_base.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,tax_ids:0
+msgid "Taxes"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+#: model:ir.ui.menu,name:account_cutoff_base.cutoff_menu
+#: view:res.company:0
+msgid "Cut-offs"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+msgid "Create Journal Entry"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,currency_id:0
+msgid "Amount Currency"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.mapping,account_id:0
+msgid "Regular Account"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,move_label:0
+msgid "Label of the Cut-off Journal Entry"
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:124
+#, python-format
+msgid "Prepaid Expense%s"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff.line:0
+#: view:account.cutoff.tax.line:0
+msgid "Cut-off Computation"
+msgstr ""
+
+#. module: account_cutoff_base
+#: selection:account.cutoff.mapping,cutoff_type:0
+msgid "All Cut-off Types"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.tax.line,base:0
+msgid "Base Amount in the currency of the PO."
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:120
+#, python-format
+msgid "Accrued Revenue%s"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,sequence:0
+msgid "Sequence"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff.tax.line:0
+#: field:account.cutoff.tax.line,tax_id:0
+msgid "Tax"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,amount:0
+msgid "Amount"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff,cutoff_account_id:0
+#: field:account.cutoff.line,cutoff_account_id:0
+#: field:account.cutoff.mapping,cutoff_account_id:0
+#: field:account.cutoff.tax.line,cutoff_account_id:0
+msgid "Cut-off Account"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,analytic_account_id:0
+#: field:account.cutoff.tax.line,analytic_account_id:0
+msgid "Analytic Account"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.tax.line,currency_id:0
+msgid "Currency"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,analytic_account_code:0
+msgid "Analytic Account Code"
+msgstr ""
+
+#. module: account_cutoff_base
+#: model:ir.actions.act_window,name:account_cutoff_base.account_cutoff_mapping_action
+#: model:ir.ui.menu,name:account_cutoff_base.account_cutoff_mapping_menu
+#: field:res.company,cutoff_account_mapping_ids:0
+msgid "Cut-off Account Mapping"
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:122
+#, python-format
+msgid "Prepaid Revenue%s"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.line,amount:0
+msgid "Amount that is used as base to compute the Cut-off Amount. This Amount is in the 'Amount Currency', which may be different from the 'Company Currency'."
+msgstr ""
+
+#. module: account_cutoff_base
+#: sql_constraint:account.cutoff:0
+msgid "A cut-off of the same type already exists with the same date(s) !"
+msgstr ""
+
+#. module: account_cutoff_base
+#: view:account.cutoff:0
+#: selection:account.cutoff,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: account_cutoff_base
+#: help:account.cutoff.line,cutoff_amount:0
+msgid "Cut-off Amount without taxes in the Company Currency."
+msgstr ""
+
+#. module: account_cutoff_base
+#: code:addons/account_cutoff_base/account_cutoff.py:118
+#, python-format
+msgid "Accrued Expense%s"
+msgstr ""
+
+#. module: account_cutoff_base
+#: field:account.cutoff.line,cutoff_amount:0
+msgid "Cut-off Amount"
+msgstr ""
+

=== added directory 'account_cutoff_base/security'
=== added file 'account_cutoff_base/security/ir.model.access.csv'
--- account_cutoff_base/security/ir.model.access.csv	1970-01-01 00:00:00 +0000
+++ account_cutoff_base/security/ir.model.access.csv	2014-03-09 00:39:34 +0000
@@ -0,0 +1,9 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_account_cutoff_mapping,Full access on account.cutoff.mapping,model_account_cutoff_mapping,account.group_account_manager,1,1,1,1
+access_account_cutoff_mapping_user,Read access on account.cutoff.mapping,model_account_cutoff_mapping,base.group_user,1,0,0,0
+access_account_cutoff,Full access on account.cutoff,model_account_cutoff,account.group_account_manager,1,1,1,1
+access_account_cutoff_read,Read access on account.cutoff,model_account_cutoff,account.group_account_user,1,0,0,0
+access_account_cutoff_line,Full access on account.cutoff.line,model_account_cutoff_line,account.group_account_manager,1,1,1,1
+access_account_cutoff_line_read,Read access on account.cutoff.line,model_account_cutoff_line,account.group_account_user,1,0,0,0
+access_account_cutoff_tax_line,Full access on account.cutoff.tax.line,model_account_cutoff_tax_line,account.group_account_manager,1,1,1,1
+access_account_cutoff_tax_line_read,Read access on account.cutoff.tax.line,model_account_cutoff_tax_line,account.group_account_user,1,0,0,0

=== added directory 'account_cutoff_prepaid'
=== added file 'account_cutoff_prepaid/__init__.py'
--- account_cutoff_prepaid/__init__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/__init__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 . import company
+from . import product
+from . import account
+from . import account_cutoff

=== added file 'account_cutoff_prepaid/__openerp__.py'
--- account_cutoff_prepaid/__openerp__.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/__openerp__.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,57 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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': 'Account Cut-off Prepaid',
+    'version': '0.2',
+    'category': 'Accounting & Finance',
+    'license': 'AGPL-3',
+    'summary': 'Prepaid Expense, Prepaid Revenue',
+    'description': """
+Manage prepaid expense and revenue based on start and end dates
+===============================================================
+
+This module adds a **Start Date** and **End Date** field on invoice lines. For example, if you have an insurance contrat for your company that run from April 1st 2013 to March 31st 2014, you will enter these dates as start and end dates on the supplier invoice line. If your fiscal year ends on December 31st 2013, 3 months of expenses are part of the 2014 fiscal year and should not be part of the 2013 fiscal year. So, thanks to this module, you will create a *Prepaid Expense* on December 31st 2013 and OpenERP will identify this expense with the 3 months that are after the cut-off date and propose to generate the appropriate cut-off journal entry.
+
+Please contact Alexis de Lattre from Akretion <alexis.delattre@xxxxxxxxxxxx> for any help or question about this module.
+    """,
+    'author': 'Akretion',
+    'website': 'http://www.akretion.com',
+    'depends': ['account_cutoff_base'],
+    'data': [
+        'company_view.xml',
+        'product_view.xml',
+        'account_invoice_view.xml',
+        'account_view.xml',
+        'account_cutoff_view.xml',
+    ],
+    'demo': ['product_demo.xml'],
+    'images': [
+        'images/prepaid_revenue_draft.jpg',
+        'images/prepaid_revenue_journal_entry.jpg',
+        'images/prepaid_revenue_done.jpg',
+        ],
+    'installable': True,
+    'active': False,
+    'application': True,
+}

=== added file 'account_cutoff_prepaid/account.py'
--- account_cutoff_prepaid/account.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/account.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,150 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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.tools.translate import _
+
+
+class account_invoice_line(orm.Model):
+    _inherit = 'account.invoice.line'
+
+    _columns = {
+        'start_date': fields.date('Start Date'),
+        'end_date': fields.date('End Date'),
+    }
+
+    def _check_start_end_dates(self, cr, uid, ids):
+        for invline in self.browse(cr, uid, ids):
+            if invline.start_date and not invline.end_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing End Date for invoice line with "
+                        "Description '%s'.")
+                    % (invline.name))
+            if invline.end_date and not invline.start_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing Start Date for invoice line with "
+                        "Description '%s'.")
+                    % (invline.name))
+            if invline.end_date and invline.start_date and \
+                    invline.start_date > invline.end_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Start Date should be before or be the same as "
+                        "End Date for invoice line with Description '%s'.")
+                    % (invline.name))
+            # Note : we can't check invline.product_id.must_have_dates
+            # have start_date and end_date here, because it would
+            # block automatic invoice generation. So we do the check
+            # upon validation of the invoice (see below the function
+            # action_move_create)
+        return True
+
+    _constraints = [
+        (_check_start_end_dates, "Error msg in raise",
+            ['start_date', 'end_date', 'product_id']),
+    ]
+
+    def move_line_get_item(self, cr, uid, line, context=None):
+        res = super(account_invoice_line, self).move_line_get_item(
+            cr, uid, line, context=context)
+        res['start_date'] = line.start_date
+        res['end_date'] = line.end_date
+        return res
+
+
+class account_move_line(orm.Model):
+    _inherit = "account.move.line"
+
+    _columns = {
+        'start_date': fields.date('Start Date'),
+        'end_date': fields.date('End Date'),
+    }
+
+    def _check_start_end_dates(self, cr, uid, ids):
+        for moveline in self.browse(cr, uid, ids):
+            if moveline.start_date and not moveline.end_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing End Date for move line with Name '%s'.")
+                    % (moveline.name))
+            if moveline.end_date and not moveline.start_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Missing Start Date for move line with Name '%s'.")
+                    % (moveline.name))
+            if moveline.end_date and moveline.start_date and \
+                    moveline.start_date > moveline.end_date:
+                raise orm.except_orm(
+                    _('Error:'),
+                    _("Start Date should be before End Date for move line "
+                        "with Name '%s'.")
+                    % (moveline.name))
+        # should we check that it's related to an expense / revenue ?
+        # -> I don't think so
+        return True
+
+    _constraints = [(
+        _check_start_end_dates,
+        "Error msg in raise",
+        ['start_date', 'end_date']
+        )]
+
+
+class account_invoice(orm.Model):
+    _inherit = 'account.invoice'
+
+    def inv_line_characteristic_hashcode(self, invoice, invoice_line):
+        '''Add start and end dates to hashcode used when the option "Group
+        Invoice Lines" is active on the Account Journal'''
+        code = super(account_invoice, self).inv_line_characteristic_hashcode(
+            invoice, invoice_line)
+        hashcode = '%s-%s-%s' % (
+            code, invoice_line.get('start_date', 'False'),
+            invoice_line.get('end_date', 'False'),
+            )
+        return hashcode
+
+    def line_get_convert(self, cr, uid, x, part, date, context=None):
+        res = super(account_invoice, self).line_get_convert(
+            cr, uid, x, part, date, context=context)
+        res['start_date'] = x.get('start_date', False)
+        res['end_date'] = x.get('end_date', False)
+        return res
+
+    def action_move_create(self, cr, uid, ids, context=None):
+        '''Check that products with must_have_dates=True have
+        Start and End Dates'''
+        for invoice in self.browse(cr, uid, ids, context=context):
+            for invline in invoice.invoice_line:
+                if invline.product_id and invline.product_id.must_have_dates:
+                    if not invline.start_date or not invline.end_date:
+                        raise orm.except_orm(
+                            _('Error:'),
+                            _("Missing Start Date and End Date for invoice "
+                                "line with Product '%s' which has the "
+                                "property 'Must Have Start and End Dates'.")
+                            % (invline.product_id.name))
+        return super(account_invoice, self).action_move_create(
+            cr, uid, ids, context=context)

=== added file 'account_cutoff_prepaid/account_cutoff.py'
--- account_cutoff_prepaid/account_cutoff.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/account_cutoff.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,253 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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.tools.translate import _
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
+from datetime import datetime
+
+
+class account_cutoff(orm.Model):
+    _inherit = 'account.cutoff'
+
+    _columns = {
+        'source_journal_ids': fields.many2many(
+            'account.journal', id1='cutoff_id', id2='journal_id',
+            string='Source Journals', readonly=True,
+            states={'draft': [('readonly', False)]}),
+        'forecast': fields.boolean(
+            'Forecast',
+            readonly=True, states={'draft': [('readonly', False)]},
+            help="The Forecast mode allows the user to compute "
+            "the prepaid revenue/expense between 2 dates in the future."),
+        'start_date': fields.date('Start Date'),
+        'end_date': fields.date('End Date'),
+    }
+
+    def _get_default_source_journals(self, cr, uid, context=None):
+        if context is None:
+            context = {}
+        journal_obj = self.pool['account.journal']
+        res = []
+        type = context.get('type')
+        mapping = {
+            'prepaid_expense': ('purchase', 'purchase_refund'),
+            'prepaid_revenue': ('sale', 'sale_refund'),
+            }
+        if type in mapping:
+            src_journal_ids = journal_obj.search(
+                cr, uid, [('type', 'in', mapping[type])])
+            if src_journal_ids:
+                res = src_journal_ids
+        return res
+
+    _defaults = {
+        'source_journal_ids': _get_default_source_journals,
+        }
+
+    _sql_constraints = [(
+        'date_type_forecast_company_uniq',
+        'unique(cutoff_date, company_id, type, forecast, start_date, end_date)',
+        'A cut-off of the same type already exists with the same date(s) !'
+        )]
+
+    def _check_start_end_dates(self, cr, uid, ids):
+        for prepaid in self.browse(cr, uid, ids):
+            if prepaid.forecast and prepaid.start_date and prepaid.end_date \
+                    and prepaid.start_date > prepaid.end_date:
+                return False
+        return True
+
+    _constraints = [
+        (_check_start_end_dates, "The start date is after the end date!",
+            ['start_date', 'end_date', 'forecast']),
+    ]
+
+    def forecast_onchange(self, cr, uid, ids, forecast, context=None):
+        res = {'value': {}}
+        line_ids = self.pool['account.cutoff.line'].search(
+            cr, uid, [('parent_id', 'in', ids)], context=context)
+        self.pool['account.cutoff.line'].unlink(
+            cr, uid, line_ids, context=context)
+        if forecast:
+            res['value']['cutoff_date'] = False
+        else:
+            res['value']['start_date'] = False
+            res['value']['end_date'] = False
+        return res
+
+    def _prepare_prepaid_lines(
+            self, cr, uid, ids, aml, cur_cutoff, mapping, context=None):
+        start_date = datetime.strptime(
+            aml['start_date'], DEFAULT_SERVER_DATE_FORMAT)
+        end_date = datetime.strptime(
+            aml['end_date'], DEFAULT_SERVER_DATE_FORMAT)
+        # Here, we compute the amount of the cutoff
+        # That's the important part !
+        total_days = (end_date - start_date).days + 1
+        if cur_cutoff['forecast']:
+            out_days = 0
+            forecast_start_date = datetime.strptime(
+                cur_cutoff['start_date'], DEFAULT_SERVER_DATE_FORMAT)
+            forecast_end_date = datetime.strptime(
+                cur_cutoff['end_date'], DEFAULT_SERVER_DATE_FORMAT)
+            if aml['end_date'] > cur_cutoff['end_date']:
+                out_days += (end_date - forecast_end_date).days
+            if aml['start_date'] < cur_cutoff['start_date']:
+                out_days += (forecast_start_date - start_date).days
+            prepaid_days = total_days - out_days
+        else:
+            cutoff_date_str = cur_cutoff['cutoff_date']
+            cutoff_date = datetime.strptime(
+                cutoff_date_str, DEFAULT_SERVER_DATE_FORMAT)
+            if aml['start_date'] > cutoff_date_str:
+                prepaid_days = total_days
+            else:
+                prepaid_days = (end_date - cutoff_date).days
+        if total_days:
+            cutoff_amount = (aml['debit'] - aml['credit'])\
+                * prepaid_days / float(total_days)
+        else:
+            raise orm.except_orm(
+                _('Error:'),
+                "Should never happen. Total days should always be > 0")
+
+        # we use account mapping here
+        if aml['account_id'][0] in mapping:
+            cutoff_account_id = mapping[aml['account_id'][0]]
+        else:
+            cutoff_account_id = aml['account_id'][0]
+
+        res = {
+            'parent_id': ids[0],
+            'move_line_id': aml['id'],
+            'partner_id': aml['partner_id'] and aml['partner_id'][0] or False,
+            'name': aml['name'],
+            'start_date': aml['start_date'],
+            'end_date': aml['end_date'],
+            'account_id': aml['account_id'][0],
+            'cutoff_account_id': cutoff_account_id,
+            'analytic_account_id':
+            aml['analytic_account_id'] and aml['analytic_account_id'][0]
+            or False,
+            'total_days': total_days,
+            'prepaid_days': prepaid_days,
+            'amount': aml['credit'] - aml['debit'],
+            'currency_id': cur_cutoff['company_currency_id'][0],
+            'cutoff_amount': cutoff_amount,
+            }
+        return res
+
+    def get_prepaid_lines(self, cr, uid, ids, context=None):
+        assert len(ids) == 1,\
+            'This function should only be used for a single id at a time'
+        aml_obj = self.pool['account.move.line']
+        line_obj = self.pool['account.cutoff.line']
+        mapping_obj = self.pool['account.cutoff.mapping']
+        cur_cutoff = self.read(
+            cr, uid, ids[0], [
+                'line_ids', 'source_journal_ids', 'cutoff_date', 'company_id',
+                'type', 'company_currency_id', 'forecast', 'start_date',
+                'end_date',
+                ],
+            context=context)
+        src_journal_ids = cur_cutoff['source_journal_ids']
+        if not src_journal_ids:
+            raise orm.except_orm(
+                _('Error:'), _("You should set at least one Source Journal."))
+        cutoff_date_str = cur_cutoff['cutoff_date']
+        # Delete existing lines
+        if cur_cutoff['line_ids']:
+            line_obj.unlink(cr, uid, cur_cutoff['line_ids'], context=context)
+
+        if cur_cutoff['forecast']:
+            domain = [
+                ('start_date', '<=', cur_cutoff['end_date']),
+                ('end_date', '>=', cur_cutoff['start_date']),
+                ('journal_id', 'in', src_journal_ids)
+                ]
+        else:
+            domain = [
+                ('start_date', '!=', False),
+                ('journal_id', 'in', src_journal_ids),
+                ('end_date', '>', cutoff_date_str),
+                ('date', '<=', cutoff_date_str)
+                ]
+
+        # Search for account move lines in the source journals
+        aml_ids = aml_obj.search(cr, uid, domain, context=context)
+        # Create mapping dict
+        mapping = mapping_obj._get_mapping_dict(
+            cr, uid, cur_cutoff['company_id'][0], cur_cutoff['type'],
+            context=context)
+
+        # Loop on selected account move lines to create the cutoff lines
+        for aml in aml_obj.read(
+                cr, uid, aml_ids, [
+                    'credit', 'debit', 'start_date', 'end_date', 'account_id',
+                    'analytic_account_id', 'partner_id', 'name'
+                    ],
+                context=context):
+
+            line_obj.create(
+                cr, uid, self._prepare_prepaid_lines(
+                    cr, uid, ids, aml, cur_cutoff, mapping, context=context),
+                context=context)
+        return True
+
+    def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
+        if context is None:
+            context = {}
+        account_id = super(account_cutoff, self).\
+            _inherit_default_cutoff_account_id(cr, uid, context=context)
+        type = context.get('type')
+        company = self.pool['res.users'].browse(
+            cr, uid, uid, context=context).company_id
+        if type == 'prepaid_revenue':
+            account_id = company.default_prepaid_revenue_account_id.id or False
+        elif type == 'prepaid_expense':
+            account_id = company.default_prepaid_expense_account_id.id or False
+        return account_id
+
+
+class account_cutoff_line(orm.Model):
+    _inherit = 'account.cutoff.line'
+
+    _columns = {
+        'move_line_id': fields.many2one(
+            'account.move.line', 'Accout Move Line', readonly=True),
+        'move_date': fields.related(
+            'move_line_id', 'date', type='date',
+            string='Account Move Date', readonly=True),
+        'invoice_id': fields.related(
+            'move_line_id', 'invoice', type='many2one',
+            relation='account.invoice', string='Invoice', readonly=True),
+        'start_date': fields.date('Start Date', readonly=True),
+        'end_date': fields.date('End Date', readonly=True),
+        'total_days': fields.integer('Total Number of Days', readonly=True),
+        'prepaid_days': fields.integer(
+            'Prepaid Days', readonly=True,
+            help="In regular mode, this is the number of days after the "
+            "cut-off date. In forecast mode, this is the number of days "
+            "between the start date and the end date."),
+        }

=== added file 'account_cutoff_prepaid/account_cutoff_view.xml'
--- account_cutoff_prepaid/account_cutoff_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/account_cutoff_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013-2014 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<!-- Tree view -->
+<record id="account_cutoff_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.prepaid.tree</field>
+    <field name="model">account.cutoff</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_tree"/>
+    <field name="arch" type="xml">
+        <field name="cutoff_date" position="after">
+            <field name="forecast" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+<!-- Form view -->
+<record id="account_cutoff_form" model="ir.ui.view">
+    <field name="name">account.cutoff.prepaid.form</field>
+    <field name="model">account.cutoff</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_form"/>
+    <field name="arch" type="xml">
+        <field name="type" position="after">
+            <field name="forecast"
+                invisible="'prepaid' not in context.get('type', '-')"
+                on_change="forecast_onchange(forecast, context)"/>
+            <field name="start_date"
+                attrs="{'invisible': [('forecast', '=', False)], 'required': [('forecast', '=', True)]}"/>
+            <field name="end_date"
+                attrs="{'invisible': [('forecast', '=', False)], 'required': [('forecast', '=', True)]}"/>
+        </field>
+        <field name="cutoff_date" position="attributes">
+            <attribute name="attrs">{'invisible': [('forecast', '=', True)], 'required': [('forecast', '=', False)]}</attribute>
+            <attribute name="required">0</attribute>
+        </field>
+        <group name="accounting-params" position="attributes">
+            <attribute name="attrs">{'invisible': [('forecast', '=', True)]}</attribute>
+        </group>
+        <field name="cutoff_journal_id" position="attributes">
+            <attribute name="required">0</attribute>
+            <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
+        </field>
+        <field name="cutoff_account_id" position="attributes">
+            <attribute name="required">0</attribute>
+            <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
+        </field>
+        <field name="move_label" position="attributes">
+            <attribute name="required">0</attribute>
+            <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
+        </field>
+        <button name="create_move" position="attributes">
+            <attribute name="attrs">{'invisible': [('forecast', '=', True)]}</attribute>
+        </button>
+        <button name="create_move" position="before">
+            <button name="get_prepaid_lines" string="Re-Generate Lines" type="object" states="draft" invisible="'prepaid' not in context.get('type', '-')"/>
+        </button>
+        <field name="cutoff_date" position="after">
+            <field name="source_journal_ids" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+<!-- Form view for lines -->
+<record id="account_cutoff_line_form" model="ir.ui.view">
+    <field name="name">account.cutoff.line.prepaid.form</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
+    <field name="arch" type="xml">
+        <field name="parent_id" position="after">
+            <field name="move_line_id" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="move_date" invisible="'prepaid' not in context.get('type', '-')" />
+            <field name="invoice_id" invisible="'prepaid' not in context.get('type', '-')" />
+        </field>
+        <field name="name" position="after">
+            <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+        <field name="cutoff_amount" position="before">
+            <field name="total_days" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="prepaid_days" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+<!-- Tree view for lines -->
+<record id="account_cutoff_line_tree" model="ir.ui.view">
+    <field name="name">account.cutoff.line.prepaid.tree</field>
+    <field name="model">account.cutoff.line</field>
+    <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
+    <field name="arch" type="xml">
+        <field name="parent_id" position="after">
+            <field name="move_line_id" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+        <field name="analytic_account_code" position="after">
+            <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="total_days" string="Days Total" invisible="'prepaid' not in context.get('type', '-')"/>
+            <field name="prepaid_days" invisible="'prepaid' not in context.get('type', '-')"/>
+        </field>
+    </field>
+</record>
+
+
+<record id="account_cutoff_prepaid_expense_action" model="ir.actions.act_window">
+    <field name="name">Prepaid Expense</field>
+    <field name="res_model">account.cutoff</field>
+    <field name="view_type">form</field>
+    <field name="view_mode">tree,form</field>
+    <field name="domain">[('type', '=', 'prepaid_expense')]</field>
+    <field name="context">{'type': 'prepaid_expense'}</field>
+</record>
+
+
+<menuitem id="account_cutoff_prepaid_expense_menu"
+        parent="account_cutoff_base.cutoff_menu"
+        action="account_cutoff_prepaid_expense_action"
+        sequence="25"/>
+
+
+<record id="account_cutoff_prepaid_revenue_action" model="ir.actions.act_window">
+    <field name="name">Prepaid Revenue</field>
+    <field name="res_model">account.cutoff</field>
+    <field name="view_type">form</field>
+    <field name="view_mode">tree,form</field>
+    <field name="domain">[('type', '=', 'prepaid_revenue')]</field>
+    <field name="context">{'type': 'prepaid_revenue'}</field>
+</record>
+
+
+<menuitem id="account_cutoff_prepaid_revenue_menu"
+        parent="account_cutoff_base.cutoff_menu"
+        action="account_cutoff_prepaid_revenue_action"
+        sequence="20"/>
+
+
+</data>
+</openerp>

=== added file 'account_cutoff_prepaid/account_invoice_view.xml'
--- account_cutoff_prepaid/account_invoice_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/account_invoice_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+
+<record id="view_invoice_line_tree" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.invoice_line_tree</field>
+    <field name="model">account.invoice.line</field>
+    <field name="inherit_id" ref="account.view_invoice_line_tree" />
+    <field name="arch" type="xml">
+        <field name="quantity" position="before">
+            <field name="start_date" />
+            <field name="end_date" />
+        </field>
+    </field>
+</record>
+
+
+<record id="invoice_supplier_form" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.invoice_supplier_form</field>
+    <field name="model">account.invoice</field>
+    <field name="inherit_id" ref="account.invoice_supplier_form" />
+    <field name="arch" type="xml">
+        <xpath expr="//field[@name='invoice_line']/tree/field[@name='account_analytic_id']" position="after">
+            <field name="start_date" />
+            <field name="end_date" />
+        </xpath>
+    </field>
+</record>
+
+
+<record id="view_invoice_line_form" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.invoice_line_form</field>
+    <field name="model">account.invoice.line</field>
+    <field name="inherit_id" ref="account.view_invoice_line_form"/>
+    <field name="arch" type="xml">
+        <field name="name" position="after">
+            <field name="start_date" />
+            <field name="end_date" />
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added file 'account_cutoff_prepaid/account_view.xml'
--- account_cutoff_prepaid/account_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/account_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+
+<record id="view_move_line_form" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.start.end.date.view_move_line_form</field>
+    <field name="model">account.move.line</field>
+    <field name="inherit_id" ref="account.view_move_line_form" />
+    <field name="arch" type="xml">
+        <field name="date_maturity" position="after">
+            <field name="start_date" />
+            <field name="end_date" />
+        </field>
+    </field>
+</record>
+
+
+<record id="view_move_line_form2" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.start.end.date.view_move_line_form2</field>
+    <field name="model">account.move.line</field>
+    <field name="inherit_id" ref="account.view_move_line_form2" />
+    <field name="arch" type="xml">
+        <field name="date_maturity" position="after">
+            <field name="start_date" />
+            <field name="end_date" />
+        </field>
+    </field>
+</record>
+
+
+<record id="view_move_form" model="ir.ui.view">
+    <field name="name">prepaid.cutoff.start.end.date.view_move_form</field>
+    <field name="model">account.move</field>
+    <field name="inherit_id" ref="account.view_move_form" />
+    <field name="arch" type="xml">
+        <field name="date_maturity" position="after">
+            <field name="start_date" />
+            <field name="end_date" />
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added file 'account_cutoff_prepaid/company.py'
--- account_cutoff_prepaid/company.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/company.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,37 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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_company(orm.Model):
+    _inherit = 'res.company'
+
+    _columns = {
+        'default_prepaid_revenue_account_id': fields.many2one(
+            'account.account', 'Default Account for Prepaid Revenue',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+        'default_prepaid_expense_account_id': fields.many2one(
+            'account.account', 'Default Account for Prepaid Expense',
+            domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
+    }

=== added file 'account_cutoff_prepaid/company_view.xml'
--- account_cutoff_prepaid/company_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/company_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+
+<record id="view_company_form" model="ir.ui.view">
+    <field name="name">account.prepaid.cutoff.company.form</field>
+    <field name="model">res.company</field>
+    <field name="inherit_id" ref="account_cutoff_base.view_company_form" />
+    <field name="arch" type="xml">
+        <field name="default_cutoff_journal_id" position="after">
+            <field name="default_prepaid_revenue_account_id" />
+            <field name="default_prepaid_expense_account_id" />
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added directory 'account_cutoff_prepaid/i18n'
=== added file 'account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot'
--- account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot	2014-03-09 00:39:34 +0000
@@ -0,0 +1,289 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+#	* account_cutoff_prepaid
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 6.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-03-09 00:24+0000\n"
+"PO-Revision-Date: 2014-03-09 00:24+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff.line,move_line_id:0
+msgid "Accout Move Line"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff,end_date:0
+#: field:account.cutoff.line,end_date:0
+#: field:account.invoice.line,end_date:0
+#: field:account.move.line,end_date:0
+msgid "End Date"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: help:product.template,must_have_dates:0
+msgid "If this option is active, the user will have to enter a Start Date and an End Date on the invoice lines that have this product."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:res.company:0
+msgid "Error! You can not create recursive companies."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:product.template,must_have_dates:0
+msgid "Must Have Start and End Dates"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff,forecast:0
+msgid "Forecast"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff,source_journal_ids:0
+msgid "Source Journals"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff.line,move_date:0
+msgid "Account Move Date"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:95
+#, python-format
+msgid "Missing Start Date for move line with Name '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:47
+#, python-format
+msgid "Missing Start Date for invoice line with Description '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.invoice.line:0
+#: constraint:account.move.line:0
+msgid "Error msg in raise"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.move.line:0
+msgid "Company must be the same for its related account and period."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.actions.act_window,name:account_cutoff_prepaid.account_cutoff_prepaid_expense_action
+#: model:ir.ui.menu,name:account_cutoff_prepaid.account_cutoff_prepaid_expense_menu
+msgid "Prepaid Expense"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.actions.act_window,name:account_cutoff_prepaid.account_cutoff_prepaid_revenue_action
+#: model:ir.ui.menu,name:account_cutoff_prepaid.account_cutoff_prepaid_revenue_menu
+msgid "Prepaid Revenue"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:101
+#, python-format
+msgid "Start Date should be before End Date for move line with Name '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_account_move_line
+msgid "Journal Items"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: view:account.cutoff:0
+msgid "Re-Generate Lines"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.move.line:0
+msgid "You can not create journal items on an account of type view."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: help:account.cutoff,forecast:0
+msgid "The Forecast mode allows the user to compute the prepaid revenue/expense between 2 dates in the future."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:40
+#: code:addons/account_cutoff_prepaid/account.py:46
+#: code:addons/account_cutoff_prepaid/account.py:53
+#: code:addons/account_cutoff_prepaid/account.py:89
+#: code:addons/account_cutoff_prepaid/account.py:94
+#: code:addons/account_cutoff_prepaid/account.py:100
+#: code:addons/account_cutoff_prepaid/account.py:144
+#: code:addons/account_cutoff_prepaid/account_cutoff.py:132
+#: code:addons/account_cutoff_prepaid/account_cutoff.py:177
+#, python-format
+msgid "Error:"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:res.company,default_prepaid_revenue_account_id:0
+msgid "Default Account for Prepaid Revenue"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: sql_constraint:account.cutoff:0
+msgid "A cutoff of the same type already exists with this cut-off date !"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_account_cutoff_line
+msgid "Account Cut-off Line"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: sql_constraint:res.company:0
+msgid "The company name must be unique !"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:product.template,name:account_cutoff_prepaid.product_insurance_contrat_product_template
+msgid "Car Insurance"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:product.template:0
+msgid "Error: The default UOM and the purchase UOM must be in the same category."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_account_cutoff
+msgid "Account Cut-off"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_res_company
+msgid "Companies"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.move.line:0
+msgid "You can not create journal items on closed account."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: view:account.cutoff.line:0
+msgid "Days Total"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:54
+#, python-format
+msgid "Start Date should be before or be the same as End Date for invoice line with Description '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:145
+#, python-format
+msgid "Missing Start Date and End Date for invoice line with Product '%s' which has the property 'Must Have Start and End Dates'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account_cutoff.py:177
+#, python-format
+msgid "You should set at least one Source Journal."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:41
+#, python-format
+msgid "Missing End Date for invoice line with Description '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.cutoff:0
+msgid "The start date is after the end date!"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: sql_constraint:account.invoice:0
+msgid "Invoice Number must be unique per Company!"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: code:addons/account_cutoff_prepaid/account.py:90
+#, python-format
+msgid "Missing End Date for move line with Name '%s'."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: help:account.cutoff.line,prepaid_days:0
+msgid "In regular mode, this is the number of days after the cut-off date. In forecast mode, this is the number of days between the start date and the end date."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_product_template
+msgid "Product Template"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: model:ir.model,name:account_cutoff_prepaid.model_account_invoice_line
+msgid "Invoice Line"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.move.line:0
+msgid "The selected account of your Journal Entry forces to provide a secondary currency. You should remove the secondary currency on the account or select a multi-currency view on the journal."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: constraint:account.move.line:0
+msgid "The date of your Journal Entry is not in the defined period! You should change the date or remove this constraint from the journal."
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff.line,total_days:0
+msgid "Total Number of Days"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:res.company,default_prepaid_expense_account_id:0
+msgid "Default Account for Prepaid Expense"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff.line,invoice_id:0
+#: model:ir.model,name:account_cutoff_prepaid.model_account_invoice
+msgid "Invoice"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: sql_constraint:account.cutoff:0
+msgid "A cut-off of the same type already exists with the same date(s) !"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: sql_constraint:account.move.line:0
+msgid "Wrong credit or debit value in accounting entry !"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff,start_date:0
+#: field:account.cutoff.line,start_date:0
+#: field:account.invoice.line,start_date:0
+#: field:account.move.line,start_date:0
+msgid "Start Date"
+msgstr ""
+
+#. module: account_cutoff_prepaid
+#: field:account.cutoff.line,prepaid_days:0
+msgid "Prepaid Days"
+msgstr ""
+

=== added directory 'account_cutoff_prepaid/images'
=== added file 'account_cutoff_prepaid/images/prepaid_revenue_done.jpg'
Binary files account_cutoff_prepaid/images/prepaid_revenue_done.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_prepaid/images/prepaid_revenue_done.jpg	2014-03-09 00:39:34 +0000 differ
=== added file 'account_cutoff_prepaid/images/prepaid_revenue_draft.jpg'
Binary files account_cutoff_prepaid/images/prepaid_revenue_draft.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_prepaid/images/prepaid_revenue_draft.jpg	2014-03-09 00:39:34 +0000 differ
=== added file 'account_cutoff_prepaid/images/prepaid_revenue_journal_entry.jpg'
Binary files account_cutoff_prepaid/images/prepaid_revenue_journal_entry.jpg	1970-01-01 00:00:00 +0000 and account_cutoff_prepaid/images/prepaid_revenue_journal_entry.jpg	2014-03-09 00:39:34 +0000 differ
=== added directory 'account_cutoff_prepaid/migrations'
=== added directory 'account_cutoff_prepaid/migrations/6.1.0.2'
=== added file 'account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py'
--- account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    Copyright (C) 2014 Akretion (http://www.akretion.com/)
+#    @author: Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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/>.
+#
+##############################################################################
+
+
+def migrate(cr, version):
+    if not version:
+        return
+
+    cr.execute(
+        'ALTER TABLE "account_cutoff_line" RENAME "after_cutoff_days" '
+        'TO "prepaid_days"')

=== added file 'account_cutoff_prepaid/product.py'
--- account_cutoff_prepaid/product.py	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/product.py	2014-03-09 00:39:34 +0000
@@ -0,0 +1,36 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+#    Account Cut-off Prepaid module for OpenERP
+#    Copyright (C) 2013 Akretion (http://www.akretion.com)
+#    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+#
+#    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 product_template(orm.Model):
+    _inherit = 'product.template'
+
+    _columns = {
+        'must_have_dates': fields.boolean(
+            'Must Have Start and End Dates',
+            help="If this option is active, the user will have to enter "
+            "a Start Date and an End Date on the invoice lines that have "
+            "this product."),
+    }

=== added file 'account_cutoff_prepaid/product_demo.xml'
--- account_cutoff_prepaid/product_demo.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/product_demo.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<record id="product_insurance_contrat" model="product.product">
+    <field name="name">Car Insurance</field>
+    <field name="default_code">CARINSUR</field>
+    <field name="type">service</field>
+    <field name="categ_id" ref="product.product_category_services0"/>
+    <field name="must_have_dates" eval="True" />
+    <field name="sale_ok" eval="True" />
+    <field name="purchase_ok" eval="True" />
+    <field name="list_price" eval="1200.0"/>
+    <field name="standard_price" eval="600.0"/>
+</record>
+
+</data>
+</openerp>

=== added file 'account_cutoff_prepaid/product_view.xml'
--- account_cutoff_prepaid/product_view.xml	1970-01-01 00:00:00 +0000
+++ account_cutoff_prepaid/product_view.xml	2014-03-09 00:39:34 +0000
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+    Copyright (C) 2013 Akretion (http://www.akretion.com/)
+    @author Alexis de Lattre <alexis.delattre@xxxxxxxxxxxx>
+    The licence is in the file __openerp__.py
+-->
+
+<openerp>
+<data>
+
+<record id="product_normal_form_view" model="ir.ui.view">
+    <field name="name">add.must.have.dates.on.product.product.form</field>
+    <field name="model">product.product</field>
+    <field name="inherit_id" ref="account.product_normal_form_view" />
+    <field name="arch" type="xml">
+        <field name="purchase_ok" position="after">
+            <field name="must_have_dates" />
+        </field>
+    </field>
+</record>
+
+
+<record id="product_template_form_view" model="ir.ui.view">
+    <field name="name">add.must.have.dates.on.product.template.form</field>
+    <field name="model">product.template</field>
+    <field name="inherit_id" ref="account.product_template_form_view" />
+    <field name="arch" type="xml">
+        <field name="purchase_ok" position="after">
+            <field name="must_have_dates" />
+        </field>
+    </field>
+</record>
+
+
+</data>
+</openerp>

=== added directory 'account_cutoff_prepaid/static'
=== added directory 'account_cutoff_prepaid/static/src'
=== added directory 'account_cutoff_prepaid/static/src/img'
=== added file 'account_cutoff_prepaid/static/src/img/icon.png'
Binary files account_cutoff_prepaid/static/src/img/icon.png	1970-01-01 00:00:00 +0000 and account_cutoff_prepaid/static/src/img/icon.png	2014-03-09 00:39:34 +0000 differ