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

Proposed by Alexis de Lattre
Status: Needs review
Proposed branch: lp:~akretion-team/account-closing/61-cutoff-modules-with-forecast
Merge into: lp:~account-core-editors/account-closing/6.1
Diff against target: 3530 lines (+3315/-0)
36 files modified
account_cutoff_accrual_base/__init__.py (+25/-0)
account_cutoff_accrual_base/__openerp__.py (+46/-0)
account_cutoff_accrual_base/account.py (+36/-0)
account_cutoff_accrual_base/account_cutoff.py (+57/-0)
account_cutoff_accrual_base/account_cutoff_view.xml (+72/-0)
account_cutoff_accrual_base/account_view.xml (+27/-0)
account_cutoff_accrual_base/company.py (+37/-0)
account_cutoff_accrual_base/company_view.xml (+26/-0)
account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot (+119/-0)
account_cutoff_accrual_picking/__init__.py (+23/-0)
account_cutoff_accrual_picking/__openerp__.py (+61/-0)
account_cutoff_accrual_picking/account_cutoff.py (+220/-0)
account_cutoff_accrual_picking/account_cutoff_view.xml (+54/-0)
account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot (+93/-0)
account_cutoff_base/__init__.py (+24/-0)
account_cutoff_base/__openerp__.py (+47/-0)
account_cutoff_base/account_cutoff.py (+438/-0)
account_cutoff_base/account_cutoff_view.xml (+218/-0)
account_cutoff_base/company.py (+35/-0)
account_cutoff_base/company_view.xml (+27/-0)
account_cutoff_base/i18n/account_cutoff_base.pot (+403/-0)
account_cutoff_base/security/ir.model.access.csv (+9/-0)
account_cutoff_prepaid/__init__.py (+26/-0)
account_cutoff_prepaid/__openerp__.py (+57/-0)
account_cutoff_prepaid/account.py (+150/-0)
account_cutoff_prepaid/account_cutoff.py (+253/-0)
account_cutoff_prepaid/account_cutoff_view.xml (+146/-0)
account_cutoff_prepaid/account_invoice_view.xml (+53/-0)
account_cutoff_prepaid/account_view.xml (+53/-0)
account_cutoff_prepaid/company.py (+37/-0)
account_cutoff_prepaid/company_view.xml (+27/-0)
account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot (+289/-0)
account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py (+29/-0)
account_cutoff_prepaid/product.py (+36/-0)
account_cutoff_prepaid/product_demo.xml (+25/-0)
account_cutoff_prepaid/product_view.xml (+37/-0)
To merge this branch: bzr merge lp:~akretion-team/account-closing/61-cutoff-modules-with-forecast
Reviewer Review Type Date Requested Status
Account Core Editors Pending
Review via email: mp+210067@code.launchpad.net

Description of the change

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

To post a comment you must log in.

Unmerged revisions

43. By Alexis de Lattre

Add POT files.

42. By Alexis de Lattre

Delete lines when changing the "forecast" param.
Small code enhancements.

41. By Alexis de Lattre

Remove a print.

40. By Alexis de Lattre

Add support for prepaid forecasts
Add context in on_change (for web_context_tunnel)

39. By Alexis de Lattre

Backport latest enhancements from v7.0 branch.

38. By Alexis de Lattre

Backport to OpenERP 6.1
prepaid cutoffs : don't take into account the move lines dated after cut-off date.

37. By Alexis de Lattre

Remove the unnecessary "and True or False" after 'xxx' not in context.get('type', '-')

36. By Alexis de Lattre

Forgot to move some code to the new _prepare function.

35. By Alexis de Lattre

Add _prepare functions to allow to inherit before create
Use assert
Remove .keys()
No space before colon
PEP8/Flake8 : getting closer to compliancy

34. By Alexis de Lattre

Coding style enhancements (osv.Model -> orm.Model, from . import xxx)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'account_cutoff_accrual_base'
2=== added file 'account_cutoff_accrual_base/__init__.py'
3--- account_cutoff_accrual_base/__init__.py 1970-01-01 00:00:00 +0000
4+++ account_cutoff_accrual_base/__init__.py 2014-03-09 00:39:34 +0000
5@@ -0,0 +1,25 @@
6+# -*- encoding: utf-8 -*-
7+##############################################################################
8+#
9+# Account Cut-off Accrual Base module for OpenERP
10+# Copyright (C) 2013 Akretion (http://www.akretion.com)
11+# @author Alexis de Lattre <alexis.delattre@akretion.com>
12+#
13+# This program is free software: you can redistribute it and/or modify
14+# it under the terms of the GNU Affero General Public License as
15+# published by the Free Software Foundation, either version 3 of the
16+# License, or (at your option) any later version.
17+#
18+# This program is distributed in the hope that it will be useful,
19+# but WITHOUT ANY WARRANTY; without even the implied warranty of
20+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+# GNU Affero General Public License for more details.
22+#
23+# You should have received a copy of the GNU Affero General Public License
24+# along with this program. If not, see <http://www.gnu.org/licenses/>.
25+#
26+##############################################################################
27+
28+from . import company
29+from . import account
30+from . import account_cutoff
31
32=== added file 'account_cutoff_accrual_base/__openerp__.py'
33--- account_cutoff_accrual_base/__openerp__.py 1970-01-01 00:00:00 +0000
34+++ account_cutoff_accrual_base/__openerp__.py 2014-03-09 00:39:34 +0000
35@@ -0,0 +1,46 @@
36+# -*- encoding: utf-8 -*-
37+##############################################################################
38+#
39+# Account Cutoff Accrual Base module for OpenERP
40+# Copyright (C) 2013 Akretion (http://www.akretion.com)
41+# @author Alexis de Lattre <alexis.delattre@akretion.com>
42+#
43+# This program is free software: you can redistribute it and/or modify
44+# it under the terms of the GNU Affero General Public License as
45+# published by the Free Software Foundation, either version 3 of the
46+# License, or (at your option) any later version.
47+#
48+# This program is distributed in the hope that it will be useful,
49+# but WITHOUT ANY WARRANTY; without even the implied warranty of
50+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51+# GNU Affero General Public License for more details.
52+#
53+# You should have received a copy of the GNU Affero General Public License
54+# along with this program. If not, see <http://www.gnu.org/licenses/>.
55+#
56+##############################################################################
57+
58+
59+{
60+ 'name': 'Account Accrual Base',
61+ 'version': '0.1',
62+ 'category': 'Accounting & Finance',
63+ 'license': 'AGPL-3',
64+ 'summary': 'Base module for accrued expenses and revenues',
65+ '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 :
66+- the module 'account_cutoff_accrual_picking' will manage accrued expenses and revenues based on pickings.
67+- a not-developped-yet module will manage accrued expenses and revenues based on timesheets.
68+
69+Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
70+ """,
71+ 'author': 'Akretion',
72+ 'website': 'http://www.akretion.com',
73+ 'depends': ['account_cutoff_base'],
74+ 'data': [
75+ 'company_view.xml',
76+ 'account_view.xml',
77+ 'account_cutoff_view.xml',
78+ ],
79+ 'installable': True,
80+ 'active': False,
81+}
82
83=== added file 'account_cutoff_accrual_base/account.py'
84--- account_cutoff_accrual_base/account.py 1970-01-01 00:00:00 +0000
85+++ account_cutoff_accrual_base/account.py 2014-03-09 00:39:34 +0000
86@@ -0,0 +1,36 @@
87+# -*- encoding: utf-8 -*-
88+##############################################################################
89+#
90+# Account Cut-off Accrual Base module for OpenERP
91+# Copyright (C) 2013 Akretion (http://www.akretion.com)
92+# @author Alexis de Lattre <alexis.delattre@akretion.com>
93+#
94+# This program is free software: you can redistribute it and/or modify
95+# it under the terms of the GNU Affero General Public License as
96+# published by the Free Software Foundation, either version 3 of the
97+# License, or (at your option) any later version.
98+#
99+# This program is distributed in the hope that it will be useful,
100+# but WITHOUT ANY WARRANTY; without even the implied warranty of
101+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
102+# GNU Affero General Public License for more details.
103+#
104+# You should have received a copy of the GNU Affero General Public License
105+# along with this program. If not, see <http://www.gnu.org/licenses/>.
106+#
107+##############################################################################
108+
109+from openerp.osv import orm, fields
110+
111+
112+class account_tax(orm.Model):
113+ _inherit = 'account.tax'
114+
115+ _columns = {
116+ 'account_accrued_revenue_id': fields.many2one(
117+ 'account.account', 'Accrued Revenue Tax Account',
118+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
119+ 'account_accrued_expense_id': fields.many2one(
120+ 'account.account', 'Accrued Expense Tax Account',
121+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
122+ }
123
124=== added file 'account_cutoff_accrual_base/account_cutoff.py'
125--- account_cutoff_accrual_base/account_cutoff.py 1970-01-01 00:00:00 +0000
126+++ account_cutoff_accrual_base/account_cutoff.py 2014-03-09 00:39:34 +0000
127@@ -0,0 +1,57 @@
128+# -*- encoding: utf-8 -*-
129+##############################################################################
130+#
131+# Account Cut-off Accrual Base module for OpenERP
132+# Copyright (C) 2013 Akretion (http://www.akretion.com)
133+# @author Alexis de Lattre <alexis.delattre@akretion.com>
134+#
135+# This program is free software: you can redistribute it and/or modify
136+# it under the terms of the GNU Affero General Public License as
137+# published by the Free Software Foundation, either version 3 of the
138+# License, or (at your option) any later version.
139+#
140+# This program is distributed in the hope that it will be useful,
141+# but WITHOUT ANY WARRANTY; without even the implied warranty of
142+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
143+# GNU Affero General Public License for more details.
144+#
145+# You should have received a copy of the GNU Affero General Public License
146+# along with this program. If not, see <http://www.gnu.org/licenses/>.
147+#
148+##############################################################################
149+
150+
151+from openerp.osv import orm, fields
152+import decimal_precision as dp
153+
154+
155+class account_cutoff(orm.Model):
156+ _inherit = 'account.cutoff'
157+
158+ def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
159+ if context is None:
160+ context = {}
161+ account_id = super(account_cutoff, self).\
162+ _inherit_default_cutoff_account_id(
163+ cr, uid, context=context)
164+ type = context.get('type')
165+ company = self.pool['res.users'].browse(
166+ cr, uid, uid, context=context).company_id
167+ if type == 'accrued_expense':
168+ account_id = company.default_accrued_expense_account_id.id or False
169+ elif type == 'accrued_revenue':
170+ account_id = company.default_accrued_revenue_account_id.id or False
171+ return account_id
172+
173+
174+class account_cutoff_line(orm.Model):
175+ _inherit = 'account.cutoff.line'
176+
177+ _columns = {
178+ 'quantity': fields.float(
179+ 'Quantity', digits_compute=dp.get_precision('Product UoS'),
180+ readonly=True),
181+ 'price_unit': fields.float(
182+ 'Unit Price', digits_compute=dp.get_precision('Product Price'),
183+ readonly=True, help="Price per unit (discount included)"),
184+ }
185
186=== added file 'account_cutoff_accrual_base/account_cutoff_view.xml'
187--- account_cutoff_accrual_base/account_cutoff_view.xml 1970-01-01 00:00:00 +0000
188+++ account_cutoff_accrual_base/account_cutoff_view.xml 2014-03-09 00:39:34 +0000
189@@ -0,0 +1,72 @@
190+<?xml version="1.0" encoding="utf-8"?>
191+
192+<!--
193+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
194+ @author Alexis de Lattre <alexis.delattre@akretion.com>
195+ The licence is in the file __openerp__.py
196+-->
197+
198+<openerp>
199+<data>
200+
201+<!-- Form view for lines -->
202+<record id="account_cutoff_line_form" model="ir.ui.view">
203+ <field name="name">accrual.account_cutoff_line</field>
204+ <field name="model">account.cutoff.line</field>
205+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
206+ <field name="arch" type="xml">
207+ <field name="amount" position="before">
208+ <field name="quantity" invisible="'accrued' not in context.get('type', '-')"/>
209+ <field name="price_unit" invisible="'accrued' not in context.get('type', '-')"/>
210+ </field>
211+ </field>
212+</record>
213+
214+<!-- Tree view for lines -->
215+<record id="account_cutoff_line_tree" model="ir.ui.view">
216+ <field name="name">accrual.account_cutoff_line_tree</field>
217+ <field name="model">account.cutoff.line</field>
218+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
219+ <field name="arch" type="xml">
220+ <field name="analytic_account_code" position="after">
221+ <field name="quantity" invisible="'accrued' not in context.get('type', '-')"/>
222+ <field name="price_unit" invisible="'accrued' not in context.get('type', '-')"/>
223+ </field>
224+ </field>
225+</record>
226+
227+
228+<record id="account_expense_accrual_action" model="ir.actions.act_window">
229+ <field name="name">Accrued Expense</field>
230+ <field name="res_model">account.cutoff</field>
231+ <field name="view_type">form</field>
232+ <field name="view_mode">tree,form</field>
233+ <field name="domain">[('type', '=', 'accrued_expense')]</field>
234+ <field name="context">{'type': 'accrued_expense'}</field>
235+</record>
236+
237+
238+<menuitem id="account_expense_accrual_menu"
239+ parent="account_cutoff_base.cutoff_menu"
240+ action="account_expense_accrual_action"
241+ sequence="35"/>
242+
243+
244+<record id="account_revenue_accrual_action" model="ir.actions.act_window">
245+ <field name="name">Accrued Revenue</field>
246+ <field name="res_model">account.cutoff</field>
247+ <field name="view_type">form</field>
248+ <field name="view_mode">tree,form</field>
249+ <field name="domain">[('type', '=', 'accrued_revenue')]</field>
250+ <field name="context">{'type': 'accrued_revenue'}</field>
251+</record>
252+
253+
254+<menuitem id="account_revenue_accrual_menu"
255+ parent="account_cutoff_base.cutoff_menu"
256+ action="account_revenue_accrual_action"
257+ sequence="30"/>
258+
259+
260+</data>
261+</openerp>
262
263=== added file 'account_cutoff_accrual_base/account_view.xml'
264--- account_cutoff_accrual_base/account_view.xml 1970-01-01 00:00:00 +0000
265+++ account_cutoff_accrual_base/account_view.xml 2014-03-09 00:39:34 +0000
266@@ -0,0 +1,27 @@
267+<?xml version="1.0" encoding="utf-8"?>
268+
269+<!--
270+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
271+ @author Alexis de Lattre <alexis.delattre@akretion.com>
272+ The licence is in the file __openerp__.py
273+-->
274+
275+<openerp>
276+<data>
277+
278+<record id="view_tax_form" model="ir.ui.view">
279+ <field name="name">account.cutoff.accrual.view_tax_form</field>
280+ <field name="model">account.tax</field>
281+ <field name="inherit_id" ref="account.view_tax_form" />
282+ <field name="arch" type="xml">
283+ <separator string="Tax Declaration: Invoices" position="before">
284+ <field name="account_accrued_revenue_id" attrs="{'invisible': [('type_tax_use', '=', 'purchase')]}"/>
285+ <newline />
286+ <field name="account_accrued_expense_id" attrs="{'invisible': [('type_tax_use', '=', 'sale')]}"/>
287+ </separator>
288+ </field>
289+</record>
290+
291+
292+</data>
293+</openerp>
294
295=== added file 'account_cutoff_accrual_base/company.py'
296--- account_cutoff_accrual_base/company.py 1970-01-01 00:00:00 +0000
297+++ account_cutoff_accrual_base/company.py 2014-03-09 00:39:34 +0000
298@@ -0,0 +1,37 @@
299+# -*- encoding: utf-8 -*-
300+##############################################################################
301+#
302+# Account Cut-off Accrual Base module for OpenERP
303+# Copyright (C) 2013 Akretion (http://www.akretion.com)
304+# @author Alexis de Lattre <alexis.delattre@akretion.com>
305+#
306+# This program is free software: you can redistribute it and/or modify
307+# it under the terms of the GNU Affero General Public License as
308+# published by the Free Software Foundation, either version 3 of the
309+# License, or (at your option) any later version.
310+#
311+# This program is distributed in the hope that it will be useful,
312+# but WITHOUT ANY WARRANTY; without even the implied warranty of
313+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
314+# GNU Affero General Public License for more details.
315+#
316+# You should have received a copy of the GNU Affero General Public License
317+# along with this program. If not, see <http://www.gnu.org/licenses/>.
318+#
319+##############################################################################
320+
321+
322+from openerp.osv import orm, fields
323+
324+
325+class res_company(orm.Model):
326+ _inherit = 'res.company'
327+
328+ _columns = {
329+ 'default_accrued_revenue_account_id': fields.many2one(
330+ 'account.account', 'Default Account for Accrued Revenues',
331+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
332+ 'default_accrued_expense_account_id': fields.many2one(
333+ 'account.account', 'Default Account for Accrued Expenses',
334+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
335+ }
336
337=== added file 'account_cutoff_accrual_base/company_view.xml'
338--- account_cutoff_accrual_base/company_view.xml 1970-01-01 00:00:00 +0000
339+++ account_cutoff_accrual_base/company_view.xml 2014-03-09 00:39:34 +0000
340@@ -0,0 +1,26 @@
341+<?xml version="1.0" encoding="utf-8"?>
342+
343+<!--
344+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
345+ @author Alexis de Lattre <alexis.delattre@akretion.com>
346+ The licence is in the file __openerp__.py
347+-->
348+
349+<openerp>
350+<data>
351+
352+<record id="view_company_form" model="ir.ui.view">
353+ <field name="name">accrual.base.company.form</field>
354+ <field name="model">res.company</field>
355+ <field name="inherit_id" ref="account_cutoff_base.view_company_form" />
356+ <field name="arch" type="xml">
357+ <field name="default_cutoff_journal_id" position="after">
358+ <field name="default_accrued_revenue_account_id" />
359+ <field name="default_accrued_expense_account_id" />
360+ </field>
361+ </field>
362+</record>
363+
364+
365+</data>
366+</openerp>
367
368=== added directory 'account_cutoff_accrual_base/i18n'
369=== added file 'account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot'
370--- account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot 1970-01-01 00:00:00 +0000
371+++ account_cutoff_accrual_base/i18n/account_cutoff_accrual_base.pot 2014-03-09 00:39:34 +0000
372@@ -0,0 +1,119 @@
373+# Translation of OpenERP Server.
374+# This file contains the translation of the following modules:
375+# * account_cutoff_accrual_base
376+#
377+msgid ""
378+msgstr ""
379+"Project-Id-Version: OpenERP Server 6.1\n"
380+"Report-Msgid-Bugs-To: \n"
381+"POT-Creation-Date: 2014-03-09 00:25+0000\n"
382+"PO-Revision-Date: 2014-03-09 00:25+0000\n"
383+"Last-Translator: <>\n"
384+"Language-Team: \n"
385+"MIME-Version: 1.0\n"
386+"Content-Type: text/plain; charset=UTF-8\n"
387+"Content-Transfer-Encoding: \n"
388+"Plural-Forms: \n"
389+
390+#. module: account_cutoff_accrual_base
391+#: sql_constraint:account.cutoff:0
392+msgid "A cutoff of the same type already exists with this cut-off date !"
393+msgstr ""
394+
395+#. module: account_cutoff_accrual_base
396+#: model:ir.model,name:account_cutoff_accrual_base.model_account_cutoff_line
397+msgid "Account Cut-off Line"
398+msgstr ""
399+
400+#. module: account_cutoff_accrual_base
401+#: field:res.company,default_accrued_expense_account_id:0
402+msgid "Default Account for Accrued Expenses"
403+msgstr ""
404+
405+#. module: account_cutoff_accrual_base
406+#: sql_constraint:res.company:0
407+msgid "The company name must be unique !"
408+msgstr ""
409+
410+#. module: account_cutoff_accrual_base
411+#: constraint:account.cutoff:0
412+msgid "The start date is after the end date!"
413+msgstr ""
414+
415+#. module: account_cutoff_accrual_base
416+#: constraint:res.company:0
417+msgid "Error! You can not create recursive companies."
418+msgstr ""
419+
420+#. module: account_cutoff_accrual_base
421+#: model:ir.model,name:account_cutoff_accrual_base.model_account_cutoff
422+msgid "Account Cut-off"
423+msgstr ""
424+
425+#. module: account_cutoff_accrual_base
426+#: model:ir.model,name:account_cutoff_accrual_base.model_res_company
427+msgid "Companies"
428+msgstr ""
429+
430+#. module: account_cutoff_accrual_base
431+#: model:ir.actions.act_window,name:account_cutoff_accrual_base.account_expense_accrual_action
432+#: model:ir.ui.menu,name:account_cutoff_accrual_base.account_expense_accrual_menu
433+msgid "Accrued Expense"
434+msgstr ""
435+
436+#. module: account_cutoff_accrual_base
437+#: field:account.cutoff.line,price_unit:0
438+msgid "Unit Price"
439+msgstr ""
440+
441+#. module: account_cutoff_accrual_base
442+#: model:ir.actions.act_window,name:account_cutoff_accrual_base.account_revenue_accrual_action
443+#: model:ir.ui.menu,name:account_cutoff_accrual_base.account_revenue_accrual_menu
444+msgid "Accrued Revenue"
445+msgstr ""
446+
447+#. module: account_cutoff_accrual_base
448+#: view:account.tax:0
449+msgid "Tax Declaration: Invoices"
450+msgstr ""
451+
452+#. module: account_cutoff_accrual_base
453+#: field:account.tax,account_accrued_revenue_id:0
454+msgid "Accrued Revenue Tax Account"
455+msgstr ""
456+
457+#. module: account_cutoff_accrual_base
458+#: field:res.company,default_accrued_revenue_account_id:0
459+msgid "Default Account for Accrued Revenues"
460+msgstr ""
461+
462+#. module: account_cutoff_accrual_base
463+#: sql_constraint:account.cutoff:0
464+msgid "A cut-off of the same type already exists with the same date(s) !"
465+msgstr ""
466+
467+#. module: account_cutoff_accrual_base
468+#: help:account.cutoff.line,price_unit:0
469+msgid "Price per unit (discount included)"
470+msgstr ""
471+
472+#. module: account_cutoff_accrual_base
473+#: model:ir.model,name:account_cutoff_accrual_base.model_account_tax
474+msgid "account.tax"
475+msgstr ""
476+
477+#. module: account_cutoff_accrual_base
478+#: sql_constraint:account.tax:0
479+msgid "Tax Name must be unique per company!"
480+msgstr ""
481+
482+#. module: account_cutoff_accrual_base
483+#: field:account.tax,account_accrued_expense_id:0
484+msgid "Accrued Expense Tax Account"
485+msgstr ""
486+
487+#. module: account_cutoff_accrual_base
488+#: field:account.cutoff.line,quantity:0
489+msgid "Quantity"
490+msgstr ""
491+
492
493=== added directory 'account_cutoff_accrual_picking'
494=== added file 'account_cutoff_accrual_picking/__init__.py'
495--- account_cutoff_accrual_picking/__init__.py 1970-01-01 00:00:00 +0000
496+++ account_cutoff_accrual_picking/__init__.py 2014-03-09 00:39:34 +0000
497@@ -0,0 +1,23 @@
498+# -*- encoding: utf-8 -*-
499+##############################################################################
500+#
501+# Account Cut-off Accrual Picking module for OpenERP
502+# Copyright (C) 2013 Akretion (http://www.akretion.com)
503+# @author Alexis de Lattre <alexis.delattre@akretion.com>
504+#
505+# This program is free software: you can redistribute it and/or modify
506+# it under the terms of the GNU Affero General Public License as
507+# published by the Free Software Foundation, either version 3 of the
508+# License, or (at your option) any later version.
509+#
510+# This program is distributed in the hope that it will be useful,
511+# but WITHOUT ANY WARRANTY; without even the implied warranty of
512+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
513+# GNU Affero General Public License for more details.
514+#
515+# You should have received a copy of the GNU Affero General Public License
516+# along with this program. If not, see <http://www.gnu.org/licenses/>.
517+#
518+##############################################################################
519+
520+from . import account_cutoff
521
522=== added file 'account_cutoff_accrual_picking/__openerp__.py'
523--- account_cutoff_accrual_picking/__openerp__.py 1970-01-01 00:00:00 +0000
524+++ account_cutoff_accrual_picking/__openerp__.py 2014-03-09 00:39:34 +0000
525@@ -0,0 +1,61 @@
526+# -*- encoding: utf-8 -*-
527+##############################################################################
528+#
529+# Account Cut-off Accrual Picking module for OpenERP
530+# Copyright (C) 2013 Akretion (http://www.akretion.com)
531+# @author Alexis de Lattre <alexis.delattre@akretion.com>
532+#
533+# This program is free software: you can redistribute it and/or modify
534+# it under the terms of the GNU Affero General Public License as
535+# published by the Free Software Foundation, either version 3 of the
536+# License, or (at your option) any later version.
537+#
538+# This program is distributed in the hope that it will be useful,
539+# but WITHOUT ANY WARRANTY; without even the implied warranty of
540+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
541+# GNU Affero General Public License for more details.
542+#
543+# You should have received a copy of the GNU Affero General Public License
544+# along with this program. If not, see <http://www.gnu.org/licenses/>.
545+#
546+##############################################################################
547+
548+
549+{
550+ 'name': 'Account Accrual Picking',
551+ 'version': '0.1',
552+ 'category': 'Accounting & Finance',
553+ 'license': 'AGPL-3',
554+ 'summary': 'Accrued Expense & Accrued Revenue from Pickings',
555+ 'description': """
556+Manage expense and revenue accruals from pickings
557+=================================================
558+
559+This module generates expense and revenue accruals based on the status of pickings.
560+
561+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*.
562+
563+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*.
564+
565+The current code of the module only works when :
566+
567+* on sale orders, the *Create Invoice* field is set to *On Delivery Order* ;
568+* for purchase orders, the *Invoicing Control* field is set to *Based on incoming shipments*.
569+
570+Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
571+ """,
572+ 'author': 'Akretion',
573+ 'website': 'http://www.akretion.com',
574+ 'depends': ['account_cutoff_accrual_base', 'purchase', 'sale'],
575+ 'data': [
576+ 'account_cutoff_view.xml',
577+ ],
578+ 'images': [
579+ 'images/accrued_expense_draft.jpg',
580+ 'images/accrued_expense_journal_entry.jpg',
581+ 'images/accrued_expense_done.jpg',
582+ ],
583+ 'installable': True,
584+ 'active': False,
585+ 'application': True,
586+}
587
588=== added file 'account_cutoff_accrual_picking/account_cutoff.py'
589--- account_cutoff_accrual_picking/account_cutoff.py 1970-01-01 00:00:00 +0000
590+++ account_cutoff_accrual_picking/account_cutoff.py 2014-03-09 00:39:34 +0000
591@@ -0,0 +1,220 @@
592+# -*- encoding: utf-8 -*-
593+##############################################################################
594+#
595+# Account Cut-off Accrual Picking module for OpenERP
596+# Copyright (C) 2013 Akretion (http://www.akretion.com)
597+# @author Alexis de Lattre <alexis.delattre@akretion.com>
598+#
599+# This program is free software: you can redistribute it and/or modify
600+# it under the terms of the GNU Affero General Public License as
601+# published by the Free Software Foundation, either version 3 of the
602+# License, or (at your option) any later version.
603+#
604+# This program is distributed in the hope that it will be useful,
605+# but WITHOUT ANY WARRANTY; without even the implied warranty of
606+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
607+# GNU Affero General Public License for more details.
608+#
609+# You should have received a copy of the GNU Affero General Public License
610+# along with this program. If not, see <http://www.gnu.org/licenses/>.
611+#
612+##############################################################################
613+
614+from openerp.osv import orm, fields
615+from openerp.tools.translate import _
616+
617+
618+class account_cutoff(orm.Model):
619+ _inherit = 'account.cutoff'
620+
621+ def _prepare_lines_from_picking(
622+ self, cr, uid, ids, cur_cutoff, move_line, account_mapping,
623+ context=None):
624+ tax_obj = self.pool['account.tax']
625+ curr_obj = self.pool['res.currency']
626+ company_currency_id = cur_cutoff['company_currency_id'][0]
627+ assert cur_cutoff['type'] in ('accrued_expense', 'accrued_revenue'),\
628+ "The field 'type' has a wrong value"
629+ if cur_cutoff['type'] == 'accrued_expense':
630+ account_id = move_line.product_id.property_account_expense.id
631+ if not account_id:
632+ account_id = move_line.product_id.categ_id.\
633+ property_account_expense_categ.id
634+ if not account_id:
635+ raise orm.except_orm(
636+ _('Error:'),
637+ _("Missing expense account on product '%s' or on its "
638+ "related product category.")
639+ % (move_line.product_id.name))
640+ currency = move_line.purchase_line_id.order_id.\
641+ pricelist_id.currency_id
642+ analytic_account_id = move_line.purchase_line_id.\
643+ account_analytic_id.id or False
644+ price_unit = move_line.purchase_line_id.price_unit
645+ taxes = move_line.purchase_line_id.taxes_id
646+ partner_id = move_line.purchase_line_id.order_id.partner_id.id
647+ tax_account_field_name = 'account_accrued_expense_id'
648+ tax_account_field_label = 'Accrued Expense Tax Account'
649+
650+ elif cur_cutoff['type'] == 'accrued_revenue':
651+ account_id = move_line.product_id.property_account_income.id
652+ if not account_id:
653+ account_id = move_line.product_id.categ_id.\
654+ property_account_income_categ.id
655+ if not account_id:
656+ raise orm.except_orm(
657+ _('Error:'),
658+ _("Missing income account on product '%s' or on its "
659+ "related product category.")
660+ % (move_line.product_id.name))
661+ currency = move_line.sale_line_id.order_id.pricelist_id.currency_id
662+ analytic_account_id = move_line.sale_line_id.order_id.\
663+ project_id.id or False
664+ discount = move_line.sale_line_id.discount
665+ price_unit = move_line.sale_line_id.price_unit *\
666+ (1-(discount or 0.0)/100.0)
667+ taxes = move_line.sale_line_id.tax_id
668+ partner_id = move_line.sale_line_id.order_id.partner_id.id
669+ tax_account_field_name = 'account_accrued_revenue_id'
670+ tax_account_field_label = 'Accrued Revenue Tax Account'
671+
672+ currency_id = currency.id
673+ quantity = move_line.product_qty
674+ tax_line_ids = []
675+ tax_res = self.pool['account.tax'].compute_all(
676+ cr, uid, taxes, price_unit, quantity,
677+ move_line.product_id.id, partner_id)
678+ amount = tax_res['total'] # =total without taxes
679+ if cur_cutoff['type'] == 'accrued_expense':
680+ amount = amount * -1
681+ context_currency_compute = context.copy()
682+ context_currency_compute['date'] = cur_cutoff['cutoff_date']
683+ for tax_line in tax_res['taxes']:
684+ tax_read = tax_obj.read(
685+ cr, uid, tax_line['id'],
686+ [tax_account_field_name, 'name'], context=context)
687+ tax_accrual_account_id = tax_read[tax_account_field_name]
688+ if not tax_accrual_account_id:
689+ raise orm.except_orm(
690+ _('Error:'),
691+ _("Missing '%s' on tax '%s'.")
692+ % (tax_account_field_label, tax_read['name']))
693+ else:
694+ tax_accrual_account_id = tax_accrual_account_id[0]
695+ if cur_cutoff['type'] == 'accrued_expense':
696+ tax_line['amount'] = tax_line['amount'] * -1
697+ if company_currency_id != currency_id:
698+ tax_accrual_amount = curr_obj.compute(
699+ cr, uid, currency_id, company_currency_id,
700+ tax_line['amount'],
701+ context=context_currency_compute)
702+ else:
703+ tax_accrual_amount = tax_line['amount']
704+ tax_line_ids.append((0, 0, {
705+ 'tax_id': tax_line['id'],
706+ 'base': curr_obj.round(
707+ cr, uid, currency,
708+ tax_line['price_unit'] * quantity),
709+ 'amount': tax_line['amount'],
710+ 'sequence': tax_line['sequence'],
711+ 'cutoff_account_id': tax_accrual_account_id,
712+ 'cutoff_amount': tax_accrual_amount,
713+ 'analytic_account_id':
714+ tax_line['account_analytic_collected_id'],
715+ # account_analytic_collected_id is for
716+ # invoices IN and OUT
717+ }))
718+ if company_currency_id != currency_id:
719+ amount_company_currency = curr_obj.compute(
720+ cr, uid, currency_id, company_currency_id, amount,
721+ context=context_currency_compute)
722+ else:
723+ amount_company_currency = amount
724+
725+ # we use account mapping here
726+ if account_id in account_mapping:
727+ accrual_account_id = account_mapping[account_id]
728+ else:
729+ accrual_account_id = account_id
730+ res = {
731+ 'parent_id': ids[0],
732+ 'partner_id': partner_id,
733+ 'stock_move_id': move_line.id,
734+ 'name': move_line.name,
735+ 'account_id': account_id,
736+ 'cutoff_account_id': accrual_account_id,
737+ 'analytic_account_id': analytic_account_id,
738+ 'currency_id': currency_id,
739+ 'quantity': quantity,
740+ 'price_unit': price_unit,
741+ 'tax_ids': [(6, 0, [tax.id for tax in taxes])],
742+ 'amount': amount,
743+ 'cutoff_amount': amount_company_currency,
744+ 'tax_line_ids': tax_line_ids,
745+ }
746+ return res
747+
748+ def get_lines_from_picking(self, cr, uid, ids, context=None):
749+ assert len(ids) == 1, \
750+ 'This function should only be used for a single id at a time'
751+ pick_obj = self.pool['stock.picking']
752+ line_obj = self.pool['account.cutoff.line']
753+ mapping_obj = self.pool['account.cutoff.mapping']
754+
755+ cur_cutoff = self.read(cr, uid, ids[0], [
756+ 'line_ids', 'type', 'cutoff_date', 'company_id',
757+ 'company_currency_id',
758+ ],
759+ context=context)
760+ # delete existing lines based on pickings
761+ to_delete_line_ids = line_obj.search(
762+ cr, uid, [
763+ ('parent_id', '=', cur_cutoff['id']),
764+ ('stock_move_id', '!=', False)
765+ ],
766+ context=context)
767+ if to_delete_line_ids:
768+ line_obj.unlink(cr, uid, to_delete_line_ids, context=context)
769+ pick_type_map = {
770+ 'accrued_revenue': 'out',
771+ 'accrued_expense': 'in',
772+ }
773+ assert cur_cutoff['type'] in pick_type_map, \
774+ "cur_cutoff['type'] should be in pick_type_map.keys()"
775+ pick_ids = pick_obj.search(cr, uid, [
776+ ('type', '=', pick_type_map[cur_cutoff['type']]),
777+ ('state', '=', 'done'),
778+ ('invoice_state', '=', '2binvoiced'),
779+ ('date_done', '<=', cur_cutoff['cutoff_date'])
780+ ], context=context)
781+ #print "pick_ids=", pick_ids
782+ # Create account mapping dict
783+ account_mapping = mapping_obj._get_mapping_dict(
784+ cr, uid, cur_cutoff['company_id'][0], cur_cutoff['type'],
785+ context=context)
786+ for picking in pick_obj.browse(cr, uid, pick_ids, context=context):
787+ for move_line in picking.move_lines:
788+ line_obj.create(
789+ cr, uid, self._prepare_lines_from_picking(
790+ cr, uid, ids, cur_cutoff, move_line,
791+ account_mapping, context=context),
792+ context=context)
793+ return True
794+
795+
796+class account_cutoff_line(orm.Model):
797+ _inherit = 'account.cutoff.line'
798+
799+ _columns = {
800+ 'stock_move_id': fields.many2one(
801+ 'stock.move', 'Stock Move', readonly=True),
802+ 'product_id': fields.related(
803+ 'stock_move_id', 'product_id', type='many2one',
804+ relation='product.product', string='Product', readonly=True),
805+ 'picking_id': fields.related(
806+ 'stock_move_id', 'picking_id', type='many2one',
807+ relation='stock.picking', string='Picking', readonly=True),
808+ 'picking_date_done': fields.related(
809+ 'picking_id', 'date_done', type='date',
810+ string='Date Done of the Picking', readonly=True),
811+ }
812
813=== added file 'account_cutoff_accrual_picking/account_cutoff_view.xml'
814--- account_cutoff_accrual_picking/account_cutoff_view.xml 1970-01-01 00:00:00 +0000
815+++ account_cutoff_accrual_picking/account_cutoff_view.xml 2014-03-09 00:39:34 +0000
816@@ -0,0 +1,54 @@
817+<?xml version="1.0" encoding="utf-8"?>
818+
819+<!--
820+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
821+ @author Alexis de Lattre <alexis.delattre@akretion.com>
822+ The licence is in the file __openerp__.py
823+-->
824+
825+<openerp>
826+<data>
827+
828+<!-- Form view -->
829+<record id="account_cutoff_form" model="ir.ui.view">
830+ <field name="name">account.cutoff.picking.form</field>
831+ <field name="model">account.cutoff</field>
832+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_form"/>
833+ <field name="arch" type="xml">
834+ <button name="create_move" position="before">
835+ <button name="get_lines_from_picking" string="Re-Generate Lines from Picking" type="object" states="draft" invisible="'accrued' not in context.get('type', '-')"/>
836+ </button>
837+ </field>
838+</record>
839+
840+<!-- Form view for lines -->
841+<record id="account_cutoff_line_form" model="ir.ui.view">
842+ <field name="name">account.cutoff.line.picking.form</field>
843+ <field name="model">account.cutoff.line</field>
844+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
845+ <field name="arch" type="xml">
846+ <field name="parent_id" position="after">
847+ <field name="stock_move_id" invisible="'accrued' not in context.get('type', '-')"/>
848+ <field name="product_id" invisible="'accrued' not in context.get('type', '-')" />
849+ <field name="picking_id" invisible="'accrued' not in context.get('type', '-')"/>
850+ <field name="picking_date_done" invisible="'accrued' not in context.get('type', '-')"/>
851+ </field>
852+ </field>
853+</record>
854+
855+<!-- Tree view for lines -->
856+<record id="account_cutoff_line_tree" model="ir.ui.view">
857+ <field name="name">account.cutoff.line.picking.tree</field>
858+ <field name="model">account.cutoff.line</field>
859+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
860+ <field name="arch" type="xml">
861+ <field name="parent_id" position="after">
862+ <field name="stock_move_id" invisible="'accrued' not in context.get('type', '-')"/>
863+ <field name="picking_date_done" invisible="'accrued' not in context.get('type', '-')"/>
864+ </field>
865+ </field>
866+</record>
867+
868+
869+</data>
870+</openerp>
871
872=== added directory 'account_cutoff_accrual_picking/i18n'
873=== added file 'account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot'
874--- account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot 1970-01-01 00:00:00 +0000
875+++ account_cutoff_accrual_picking/i18n/account_cutoff_accrual_picking.pot 2014-03-09 00:39:34 +0000
876@@ -0,0 +1,93 @@
877+# Translation of OpenERP Server.
878+# This file contains the translation of the following modules:
879+# * account_cutoff_accrual_picking
880+#
881+msgid ""
882+msgstr ""
883+"Project-Id-Version: OpenERP Server 6.1\n"
884+"Report-Msgid-Bugs-To: \n"
885+"POT-Creation-Date: 2014-03-09 00:26+0000\n"
886+"PO-Revision-Date: 2014-03-09 00:26+0000\n"
887+"Last-Translator: <>\n"
888+"Language-Team: \n"
889+"MIME-Version: 1.0\n"
890+"Content-Type: text/plain; charset=UTF-8\n"
891+"Content-Transfer-Encoding: \n"
892+"Plural-Forms: \n"
893+
894+#. module: account_cutoff_accrual_picking
895+#: sql_constraint:account.cutoff:0
896+msgid "A cutoff of the same type already exists with this cut-off date !"
897+msgstr ""
898+
899+#. module: account_cutoff_accrual_picking
900+#: model:ir.model,name:account_cutoff_accrual_picking.model_account_cutoff_line
901+msgid "Account Cut-off Line"
902+msgstr ""
903+
904+#. module: account_cutoff_accrual_picking
905+#: field:account.cutoff.line,product_id:0
906+msgid "Product"
907+msgstr ""
908+
909+#. module: account_cutoff_accrual_picking
910+#: field:account.cutoff.line,stock_move_id:0
911+msgid "Stock Move"
912+msgstr ""
913+
914+#. module: account_cutoff_accrual_picking
915+#: model:ir.model,name:account_cutoff_accrual_picking.model_account_cutoff
916+msgid "Account Cut-off"
917+msgstr ""
918+
919+#. module: account_cutoff_accrual_picking
920+#: view:account.cutoff:0
921+msgid "Re-Generate Lines from Picking"
922+msgstr ""
923+
924+#. module: account_cutoff_accrual_picking
925+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:67
926+#, python-format
927+msgid "Missing income account on product '%s' or on its related product category."
928+msgstr ""
929+
930+#. module: account_cutoff_accrual_picking
931+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:46
932+#, python-format
933+msgid "Missing expense account on product '%s' or on its related product category."
934+msgstr ""
935+
936+#. module: account_cutoff_accrual_picking
937+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:100
938+#, python-format
939+msgid "Missing '%s' on tax '%s'."
940+msgstr ""
941+
942+#. module: account_cutoff_accrual_picking
943+#: sql_constraint:account.cutoff:0
944+msgid "A cut-off of the same type already exists with the same date(s) !"
945+msgstr ""
946+
947+#. module: account_cutoff_accrual_picking
948+#: constraint:account.cutoff:0
949+msgid "The start date is after the end date!"
950+msgstr ""
951+
952+#. module: account_cutoff_accrual_picking
953+#: field:account.cutoff.line,picking_id:0
954+msgid "Picking"
955+msgstr ""
956+
957+#. module: account_cutoff_accrual_picking
958+#: field:account.cutoff.line,picking_date_done:0
959+msgid "Date Done of the Picking"
960+msgstr ""
961+
962+#. module: account_cutoff_accrual_picking
963+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:45
964+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:66
965+#: code:addons/account_cutoff_accrual_picking/account_cutoff.py:99
966+#, python-format
967+msgid "Error:"
968+msgstr ""
969+
970
971=== added directory 'account_cutoff_accrual_picking/images'
972=== added file 'account_cutoff_accrual_picking/images/accrued_expense_done.jpg'
973Binary 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
974=== added file 'account_cutoff_accrual_picking/images/accrued_expense_draft.jpg'
975Binary 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
976=== added file 'account_cutoff_accrual_picking/images/accrued_expense_journal_entry.jpg'
977Binary 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
978=== added directory 'account_cutoff_accrual_picking/static'
979=== added directory 'account_cutoff_accrual_picking/static/src'
980=== added directory 'account_cutoff_accrual_picking/static/src/img'
981=== added file 'account_cutoff_accrual_picking/static/src/img/icon.png'
982Binary 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
983=== added directory 'account_cutoff_base'
984=== added file 'account_cutoff_base/__init__.py'
985--- account_cutoff_base/__init__.py 1970-01-01 00:00:00 +0000
986+++ account_cutoff_base/__init__.py 2014-03-09 00:39:34 +0000
987@@ -0,0 +1,24 @@
988+# -*- encoding: utf-8 -*-
989+##############################################################################
990+#
991+# Account Cut-off Base module for OpenERP
992+# Copyright (C) 2013 Akretion (http://www.akretion.com)
993+# @author Alexis de Lattre <alexis.delattre@akretion.com>
994+#
995+# This program is free software: you can redistribute it and/or modify
996+# it under the terms of the GNU Affero General Public License as
997+# published by the Free Software Foundation, either version 3 of the
998+# License, or (at your option) any later version.
999+#
1000+# This program is distributed in the hope that it will be useful,
1001+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1002+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1003+# GNU Affero General Public License for more details.
1004+#
1005+# You should have received a copy of the GNU Affero General Public License
1006+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1007+#
1008+##############################################################################
1009+
1010+from . import account_cutoff
1011+from . import company
1012
1013=== added file 'account_cutoff_base/__openerp__.py'
1014--- account_cutoff_base/__openerp__.py 1970-01-01 00:00:00 +0000
1015+++ account_cutoff_base/__openerp__.py 2014-03-09 00:39:34 +0000
1016@@ -0,0 +1,47 @@
1017+# -*- encoding: utf-8 -*-
1018+##############################################################################
1019+#
1020+# Account Cut-off Base module for OpenERP
1021+# Copyright (C) 2013 Akretion (http://www.akretion.com)
1022+# @author Alexis de Lattre <alexis.delattre@akretion.com>
1023+#
1024+# This program is free software: you can redistribute it and/or modify
1025+# it under the terms of the GNU Affero General Public License as
1026+# published by the Free Software Foundation, either version 3 of the
1027+# License, or (at your option) any later version.
1028+#
1029+# This program is distributed in the hope that it will be useful,
1030+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1031+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1032+# GNU Affero General Public License for more details.
1033+#
1034+# You should have received a copy of the GNU Affero General Public License
1035+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1036+#
1037+##############################################################################
1038+
1039+
1040+{
1041+ 'name': 'Account Cut-off Base',
1042+ 'version': '0.1',
1043+ 'category': 'Accounting & Finance',
1044+ 'license': 'AGPL-3',
1045+ 'summary': 'Base module for Account Cut-offs',
1046+ '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 :
1047+
1048+* the module *account_cutoff_prepaid* will manage prepaid cut-offs based on start date and end date,
1049+* the module *account_cutoff_accrual_picking* will manage the accruals based on the status of the pickings.
1050+
1051+Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
1052+ """,
1053+ 'author': 'Akretion',
1054+ 'website': 'http://www.akretion.com',
1055+ 'depends': ['account_accountant'],
1056+ 'data': [
1057+ 'company_view.xml',
1058+ 'account_cutoff_view.xml',
1059+ 'security/ir.model.access.csv',
1060+ ],
1061+ 'installable': True,
1062+ 'active': False,
1063+}
1064
1065=== added file 'account_cutoff_base/account_cutoff.py'
1066--- account_cutoff_base/account_cutoff.py 1970-01-01 00:00:00 +0000
1067+++ account_cutoff_base/account_cutoff.py 2014-03-09 00:39:34 +0000
1068@@ -0,0 +1,438 @@
1069+# -*- encoding: utf-8 -*-
1070+##############################################################################
1071+#
1072+# Account Cut-off Base module for OpenERP
1073+# Copyright (C) 2013 Akretion (http://www.akretion.com)
1074+# @author Alexis de Lattre <alexis.delattre@akretion.com>
1075+#
1076+# This program is free software: you can redistribute it and/or modify
1077+# it under the terms of the GNU Affero General Public License as
1078+# published by the Free Software Foundation, either version 3 of the
1079+# License, or (at your option) any later version.
1080+#
1081+# This program is distributed in the hope that it will be useful,
1082+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1083+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1084+# GNU Affero General Public License for more details.
1085+#
1086+# You should have received a copy of the GNU Affero General Public License
1087+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1088+#
1089+##############################################################################
1090+
1091+from openerp.osv import orm, fields
1092+import decimal_precision as dp
1093+from openerp.tools.translate import _
1094+from datetime import datetime
1095+
1096+
1097+class account_cutoff(orm.Model):
1098+ _name = 'account.cutoff'
1099+ _rec_name = 'cutoff_date'
1100+ _order = 'cutoff_date desc'
1101+ _description = 'Account Cut-off'
1102+
1103+ def copy(self, cr, uid, id, default=None, context=None):
1104+ if default is None:
1105+ default = {}
1106+ default.update({
1107+ 'cutoff_date': '%d-12-31' % datetime.today().year,
1108+ 'move_id': False,
1109+ 'state': 'draft',
1110+ 'line_ids': False,
1111+ })
1112+ return super(account_cutoff, self).copy(
1113+ cr, uid, id, default=default, context=context)
1114+
1115+ def _compute_total_cutoff(self, cr, uid, ids, name, arg, context=None):
1116+ res = {}
1117+ for cutoff in self.browse(cr, uid, ids, context=context):
1118+ res[cutoff.id] = 0
1119+ for line in cutoff.line_ids:
1120+ res[cutoff.id] += line.cutoff_amount
1121+ return res
1122+
1123+ _columns = {
1124+ 'cutoff_date': fields.date(
1125+ 'Cut-off Date', readonly=True,
1126+ states={'draft': [('readonly', False)]}),
1127+ 'type': fields.selection([
1128+ ('accrued_revenue', 'Accrued Revenue'),
1129+ ('accrued_expense', 'Accrued Expense'),
1130+ ('prepaid_revenue', 'Prepaid Revenue'),
1131+ ('prepaid_expense', 'Prepaid Expense'),
1132+ ], 'Type', required=True, readonly=True,
1133+ states={'draft': [('readonly', False)]}),
1134+ 'move_id': fields.many2one(
1135+ 'account.move', 'Cut-off Journal Entry', readonly=True),
1136+ 'move_label': fields.char(
1137+ 'Label of the Cut-off Journal Entry',
1138+ size=64, readonly=True,
1139+ states={'draft': [('readonly', False)]},
1140+ help="This label will be written in the 'Name' field of the "
1141+ "Cut-off Account Move Lines and in the 'Reference' field of "
1142+ "the Cut-off Account Move."),
1143+ 'cutoff_account_id': fields.many2one(
1144+ 'account.account', 'Cut-off Account',
1145+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1146+ readonly=True, states={'draft': [('readonly', False)]}),
1147+ 'cutoff_journal_id': fields.many2one(
1148+ 'account.journal', 'Cut-off Account Journal',
1149+ readonly=True, states={'draft': [('readonly', False)]}),
1150+ 'total_cutoff_amount': fields.function(
1151+ _compute_total_cutoff, type='float', string="Total Cut-off Amount",
1152+ readonly=True),
1153+ 'company_id': fields.many2one(
1154+ 'res.company', 'Company', required=True, readonly=True,
1155+ states={'draft': [('readonly', False)]}),
1156+ 'company_currency_id': fields.related(
1157+ 'company_id', 'currency_id', readonly=True, type='many2one',
1158+ relation='res.currency', string='Company Currency'),
1159+ 'line_ids': fields.one2many(
1160+ 'account.cutoff.line', 'parent_id', 'Cut-off Lines', readonly=True,
1161+ states={'draft': [('readonly', False)]}),
1162+ 'state': fields.selection([
1163+ ('draft', 'Draft'),
1164+ ('done', 'Done'),
1165+ ],
1166+ 'State', select=True, readonly=True,
1167+ help="State of the cutoff. When the Journal Entry is created, "
1168+ "the state is set to 'Done' and the fields become read-only."),
1169+ }
1170+
1171+ def _get_default_journal(self, cr, uid, context=None):
1172+ cur_user = self.pool['res.users'].browse(cr, uid, uid, context=context)
1173+ return cur_user.company_id.default_cutoff_journal_id.id or None
1174+
1175+ def _default_move_label(self, cr, uid, context=None):
1176+ if context is None:
1177+ context = {}
1178+ type = context.get('type')
1179+ cutoff_date = context.get('cutoff_date')
1180+ if cutoff_date:
1181+ cutoff_date_label = ' dated %s' % cutoff_date
1182+ else:
1183+ cutoff_date_label = ''
1184+ label = ''
1185+ if type == 'accrued_expense':
1186+ label = _('Accrued Expense%s') % cutoff_date_label
1187+ elif type == 'accrued_revenue':
1188+ label = _('Accrued Revenue%s') % cutoff_date_label
1189+ elif type == 'prepaid_revenue':
1190+ label = _('Prepaid Revenue%s') % cutoff_date_label
1191+ elif type == 'prepaid_expense':
1192+ label = _('Prepaid Expense%s') % cutoff_date_label
1193+ return label
1194+
1195+ def _default_type(self, cr, uid, context=None):
1196+ if context is None:
1197+ context = {}
1198+ return context.get('type')
1199+
1200+ def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
1201+ '''Function designed to be inherited by other cutoff modules'''
1202+ return None
1203+
1204+ def _default_cutoff_account_id(self, cr, uid, context=None):
1205+ '''This function can't be inherited, so we use a second function'''
1206+ return self._inherit_default_cutoff_account_id(
1207+ cr, uid, context=context)
1208+
1209+ _defaults = {
1210+ 'state': 'draft',
1211+ 'company_id': lambda self, cr, uid, context:
1212+ self.pool['res.users'].browse(
1213+ cr, uid, uid, context=context).company_id.id,
1214+ 'cutoff_journal_id': _get_default_journal,
1215+ 'move_label': _default_move_label,
1216+ 'type': _default_type,
1217+ 'cutoff_account_id': _default_cutoff_account_id,
1218+ }
1219+
1220+ _sql_constraints = [(
1221+ 'date_type_company_uniq',
1222+ 'unique(cutoff_date, company_id, type)',
1223+ 'A cutoff of the same type already exists with this cut-off date !'
1224+ )]
1225+
1226+ def cutoff_date_onchange(
1227+ self, cr, uid, ids, type, cutoff_date, move_label, context=None):
1228+ if context is None:
1229+ context = {}
1230+ res = {'value': {}}
1231+ if type and cutoff_date:
1232+ ctx = context.copy()
1233+ ctx.update({'type': type, 'cutoff_date': cutoff_date})
1234+ res['value']['move_label'] = self._default_move_label(
1235+ cr, uid, context=ctx)
1236+ return res
1237+
1238+ def back2draft(self, cr, uid, ids, context=None):
1239+ assert len(ids) == 1,\
1240+ 'This function should only be used for a single id at a time'
1241+ cur_cutoff = self.browse(cr, uid, ids[0], context=context)
1242+ if cur_cutoff.move_id:
1243+ self.pool['account.move'].unlink(
1244+ cr, uid, [cur_cutoff.move_id.id], context=context)
1245+ self.write(cr, uid, ids[0], {'state': 'draft'}, context=context)
1246+ return True
1247+
1248+ def _prepare_move(self, cr, uid, cur_cutoff, to_provision, context=None):
1249+ if context is None:
1250+ context = {}
1251+ movelines_to_create = []
1252+ amount_total = 0
1253+ move_label = cur_cutoff.move_label
1254+ for (cutoff_account_id, analytic_account_id), amount in \
1255+ to_provision.items():
1256+ movelines_to_create.append((0, 0, {
1257+ 'account_id': cutoff_account_id,
1258+ 'name': move_label,
1259+ 'debit': amount < 0 and amount * -1 or 0,
1260+ 'credit': amount >= 0 and amount or 0,
1261+ 'analytic_account_id': analytic_account_id,
1262+ }))
1263+ amount_total += amount
1264+
1265+ # add contre-partie
1266+ counterpart_amount = amount_total * -1
1267+ movelines_to_create.append((0, 0, {
1268+ 'account_id': cur_cutoff.cutoff_account_id.id,
1269+ 'debit': counterpart_amount < 0 and counterpart_amount * -1 or 0,
1270+ 'credit': counterpart_amount >= 0 and counterpart_amount or 0,
1271+ 'name': move_label,
1272+ 'analytic_account_id': False,
1273+ }))
1274+
1275+ # Select period
1276+ local_ctx = context.copy()
1277+ local_ctx['account_period_prefer_normal'] = True
1278+ period_search = self.pool['account.period'].find(
1279+ cr, uid, cur_cutoff.cutoff_date, context=local_ctx)
1280+ if len(period_search) != 1:
1281+ raise orm.except_orm(
1282+ 'Error:', "No matching period for date '%s'"
1283+ % cur_cutoff.cutoff_date)
1284+ period_id = period_search[0]
1285+
1286+ res = {
1287+ 'journal_id': cur_cutoff.cutoff_journal_id.id,
1288+ 'date': cur_cutoff.cutoff_date,
1289+ 'period_id': period_id,
1290+ 'ref': move_label,
1291+ 'line_id': movelines_to_create,
1292+ }
1293+ return res
1294+
1295+ def create_move(self, cr, uid, ids, context=None):
1296+ assert len(ids) == 1, \
1297+ 'This function should only be used for a single id at a time'
1298+ move_obj = self.pool['account.move']
1299+ cur_cutoff = self.browse(cr, uid, ids[0], context=context)
1300+ if cur_cutoff.move_id:
1301+ raise orm.except_orm(
1302+ _('Error:'),
1303+ _("The Cut-off Journal Entry already exists. You should "
1304+ "delete it before running this function."))
1305+ if not cur_cutoff.line_ids:
1306+ raise orm.except_orm(
1307+ _('Error:'),
1308+ _("There are no lines on this Cut-off, so we can't create "
1309+ "a Journal Entry."))
1310+ to_provision = {}
1311+ # key = (cutoff_account_id, analytic_account_id)
1312+ # value = amount
1313+ for line in cur_cutoff.line_ids:
1314+ # if it is already present
1315+ if (
1316+ line.cutoff_account_id.id,
1317+ line.analytic_account_id.id or False
1318+ ) in to_provision:
1319+ to_provision[(
1320+ line.cutoff_account_id.id,
1321+ line.analytic_account_id.id or False
1322+ )] += line.cutoff_amount
1323+ else:
1324+ # if not already present
1325+ to_provision[(
1326+ line.cutoff_account_id.id,
1327+ line.analytic_account_id.id or False
1328+ )] = line.cutoff_amount
1329+ # Same for tax lines
1330+ for tax_line in line.tax_line_ids:
1331+ if (
1332+ tax_line.cutoff_account_id.id,
1333+ tax_line.analytic_account_id.id or False
1334+ ) in to_provision:
1335+ to_provision[(
1336+ tax_line.cutoff_account_id.id,
1337+ tax_line.analytic_account_id.id or False
1338+ )] += tax_line.cutoff_amount
1339+ else:
1340+ to_provision[(
1341+ tax_line.cutoff_account_id.id,
1342+ tax_line.analytic_account_id.id or False
1343+ )] = tax_line.cutoff_amount
1344+
1345+ vals = self._prepare_move(
1346+ cr, uid, cur_cutoff, to_provision, context=context)
1347+ move_id = move_obj.create(cr, uid, vals, context=context)
1348+ move_obj.validate(cr, uid, [move_id], context=context)
1349+ self.write(cr, uid, ids[0], {
1350+ 'move_id': move_id,
1351+ 'state': 'done',
1352+ }, context=context)
1353+
1354+ action = {
1355+ 'name': 'Cut-off Account Move',
1356+ 'view_type': 'form',
1357+ 'view_mode': 'form,tree',
1358+ 'res_id': move_id,
1359+ 'res_model': 'account.move',
1360+ 'type': 'ir.actions.act_window',
1361+ 'nodestroy': True,
1362+ 'target': 'current',
1363+ }
1364+ return action
1365+
1366+
1367+class account_cutoff_line(orm.Model):
1368+ _name = 'account.cutoff.line'
1369+ _description = 'Account Cut-off Line'
1370+
1371+ _columns = {
1372+ 'parent_id': fields.many2one(
1373+ 'account.cutoff', 'Cut-off', ondelete='cascade'),
1374+ 'name': fields.char('Description', size=64),
1375+ 'company_currency_id': fields.related(
1376+ 'parent_id', 'company_currency_id', type='many2one',
1377+ relation='res.currency', string="Company Currency", readonly=True),
1378+ 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True),
1379+ 'account_id': fields.many2one(
1380+ 'account.account', 'Account',
1381+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1382+ required=True, readonly=True),
1383+ 'cutoff_account_id': fields.many2one(
1384+ 'account.account', 'Cut-off Account',
1385+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1386+ required=True, readonly=True),
1387+ 'cutoff_account_code': fields.related(
1388+ 'cutoff_account_id', 'code', type='char',
1389+ string='Cut-off Account Code', readonly=True),
1390+ 'analytic_account_id': fields.many2one(
1391+ 'account.analytic.account', 'Analytic Account',
1392+ domain=[('type', 'not in', ('view', 'template'))],
1393+ readonly=True),
1394+ 'analytic_account_code': fields.related(
1395+ 'analytic_account_id', 'code', type='char',
1396+ string='Analytic Account Code', readonly=True),
1397+ 'currency_id': fields.many2one(
1398+ 'res.currency', 'Amount Currency', readonly=True,
1399+ help="Currency of the 'Amount' field."),
1400+ 'amount': fields.float(
1401+ 'Amount', digits_compute=dp.get_precision('Account'),
1402+ readonly=True,
1403+ help="Amount that is used as base to compute the Cut-off Amount. "
1404+ "This Amount is in the 'Amount Currency', which may be different "
1405+ "from the 'Company Currency'."),
1406+ 'cutoff_amount': fields.float(
1407+ 'Cut-off Amount', digits_compute=dp.get_precision('Account'),
1408+ readonly=True,
1409+ help="Cut-off Amount without taxes in the Company Currency."),
1410+ 'tax_ids': fields.many2many(
1411+ 'account.tax', id1='cutoff_line_id', id2='tax_id', string='Taxes',
1412+ readonly=True),
1413+ 'tax_line_ids': fields.one2many(
1414+ 'account.cutoff.tax.line', 'parent_id', 'Cut-off Tax Lines',
1415+ readonly=True),
1416+ }
1417+
1418+
1419+class account_cutoff_tax_line(orm.Model):
1420+ _name = 'account.cutoff.tax.line'
1421+ _description = 'Account Cut-off Tax Line'
1422+
1423+ _columns = {
1424+ 'parent_id': fields.many2one(
1425+ 'account.cutoff.line', 'Account Cut-off Line',
1426+ ondelete='cascade', required=True),
1427+ 'tax_id': fields.many2one('account.tax', 'Tax', required=True),
1428+ 'cutoff_account_id': fields.many2one(
1429+ 'account.account', 'Cut-off Account',
1430+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1431+ required=True, readonly=True),
1432+ 'analytic_account_id': fields.many2one(
1433+ 'account.analytic.account', 'Analytic Account',
1434+ domain=[('type', 'not in', ('view', 'template'))],
1435+ readonly=True),
1436+ 'base': fields.float(
1437+ 'Base', digits_compute=dp.get_precision('Account'),
1438+ readonly=True, help="Base Amount in the currency of the PO."),
1439+ 'amount': fields.float(
1440+ 'Tax Amount', digits_compute=dp.get_precision('Account'),
1441+ readonly=True, help='Tax Amount in the currency of the PO.'),
1442+ 'sequence': fields.integer('Sequence', readonly=True),
1443+ 'cutoff_amount': fields.float(
1444+ 'Cut-off Tax Amount', digits_compute=dp.get_precision('Account'),
1445+ readonly=True,
1446+ help="Tax Cut-off Amount in the company currency."),
1447+ 'currency_id': fields.related(
1448+ 'parent_id', 'currency_id', type='many2one',
1449+ relation='res.currency', string='Currency', readonly=True),
1450+ 'company_currency_id': fields.related(
1451+ 'parent_id', 'company_currency_id',
1452+ type='many2one', relation='res.currency',
1453+ string="Company Currency", readonly=True),
1454+ }
1455+
1456+
1457+class account_cutoff_mapping(orm.Model):
1458+ _name = 'account.cutoff.mapping'
1459+ _description = 'Account Cut-off Mapping'
1460+ _rec_name = 'account_id'
1461+
1462+ _columns = {
1463+ 'company_id': fields.many2one('res.company', 'Company', required=True),
1464+ 'account_id': fields.many2one(
1465+ 'account.account', 'Regular Account',
1466+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1467+ required=True),
1468+ 'cutoff_account_id': fields.many2one(
1469+ 'account.account', 'Cut-off Account',
1470+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')],
1471+ required=True),
1472+ 'cutoff_type': fields.selection([
1473+ ('all', 'All Cut-off Types'),
1474+ ('accrued_revenue', 'Accrued Revenue'),
1475+ ('accrued_expense', 'Accrued Expense'),
1476+ ('prepaid_revenue', 'Prepaid Revenue'),
1477+ ('prepaid_expense', 'Prepaid Expense'),
1478+ ], 'Cut-off Type', required=True),
1479+ }
1480+
1481+ _defaults = {
1482+ 'company_id': lambda self, cr, uid, context:
1483+ self.pool['res.users'].browse(
1484+ cr, uid, uid, context=context).company_id.id,
1485+ }
1486+
1487+ def _get_mapping_dict(
1488+ self, cr, uid, company_id, cutoff_type='all', context=None):
1489+ '''return a dict with:
1490+ key = ID of account,
1491+ value = ID of cutoff_account'''
1492+ if cutoff_type == 'all':
1493+ cutoff_type_filter = ('all')
1494+ else:
1495+ cutoff_type_filter = ('all', cutoff_type)
1496+ mapping_ids = self.search(
1497+ cr, uid, [
1498+ ('company_id', '=', company_id),
1499+ ('cutoff_type', 'in', cutoff_type_filter),
1500+ ],
1501+ context=context)
1502+ mapping_read = self.read(cr, uid, mapping_ids, context=context)
1503+ mapping = {}
1504+ for item in mapping_read:
1505+ mapping[item['account_id'][0]] = item['cutoff_account_id'][0]
1506+ return mapping
1507
1508=== added file 'account_cutoff_base/account_cutoff_view.xml'
1509--- account_cutoff_base/account_cutoff_view.xml 1970-01-01 00:00:00 +0000
1510+++ account_cutoff_base/account_cutoff_view.xml 2014-03-09 00:39:34 +0000
1511@@ -0,0 +1,218 @@
1512+<?xml version="1.0" encoding="utf-8"?>
1513+
1514+<!--
1515+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
1516+ @author Alexis de Lattre <alexis.delattre@akretion.com>
1517+ The licence is in the file __openerp__.py
1518+-->
1519+
1520+<openerp>
1521+<data>
1522+
1523+<menuitem id="cutoff_menu"
1524+ parent="account.menu_finance_periodical_processing"
1525+ name="Cut-offs"
1526+ sequence="24"
1527+ groups="account.group_account_user,account.group_account_manager,account.group_account_invoice"/>
1528+
1529+<!-- Form view -->
1530+<record id="account_cutoff_form" model="ir.ui.view">
1531+ <field name="name">account.cutoff.form</field>
1532+ <field name="model">account.cutoff</field>
1533+ <field name="type">form</field>
1534+ <field name="arch" type="xml">
1535+ <form string="Cut-offs">
1536+ <group name="general-params" colspan="2" col="2">
1537+ <field name="type" readonly="1" />
1538+ <field name="cutoff_date" on_change="cutoff_date_onchange(type, cutoff_date, move_label, context)" required="1"/>
1539+ <field name="total_cutoff_amount" />
1540+ <field name="company_currency_id" />
1541+ <field name="company_id" groups="base.group_multi_company" widget="selection" />
1542+ </group>
1543+ <group name="accounting-params" colspan="2" col="2">
1544+ <field name="cutoff_journal_id" required="1"/>
1545+ <field name="cutoff_account_id" required="1"/>
1546+ <field name="move_label" required="1"/>
1547+ <field name="move_id"/>
1548+ </group>
1549+ <button name="create_move" string="Create Journal Entry" type="object" states="draft" attrs="{'invisible': ['|', ('line_ids', '=', False), ('state', '=', 'done')]}"/>
1550+ <newline />
1551+ <field name="line_ids" nolabel="1" context="{'type': type}" colspan="4"/>
1552+ <group colspan="4">
1553+ <field name="state" widget="statusbar" />
1554+ <button name="back2draft" string="Back to Draft" type="object" states="done" />
1555+ </group>
1556+ </form>
1557+ </field>
1558+</record>
1559+
1560+<!-- Tree view -->
1561+<record id="account_cutoff_tree" model="ir.ui.view">
1562+ <field name="name">account.cutoff.tree</field>
1563+ <field name="model">account.cutoff</field>
1564+ <field name="type">tree</field>
1565+ <field name="arch" type="xml">
1566+ <tree string="Cut-offs" colors="blue:state=='draft'">
1567+ <field name="type" invisible="context.get('type')" />
1568+ <field name="cutoff_date" />
1569+ <field name="total_cutoff_amount"/>
1570+ <field name="company_currency_id"/>
1571+ <field name="state"/>
1572+ </tree>
1573+ </field>
1574+</record>
1575+
1576+<!-- Search view -->
1577+<record id="account_cutoff_filter" model="ir.ui.view">
1578+ <field name="name">account.cutoff.filter</field>
1579+ <field name="model">account.cutoff</field>
1580+ <field name="type">search</field>
1581+ <field name="arch" type="xml">
1582+ <search string="Search Cut-offs">
1583+ <filter name="draft" string="Draft" domain="[('state', '=', 'draft')]" icon="terp-document-new" />
1584+ <filter name="done" string="Done" domain="[('state', '=', 'done')]" icon="terp-camera_test" />
1585+ </search>
1586+ </field>
1587+</record>
1588+
1589+<!-- Form view for lines -->
1590+<record id="account_cutoff_line_form" model="ir.ui.view">
1591+ <field name="name">account.cutoff.line.form</field>
1592+ <field name="model">account.cutoff.line</field>
1593+ <field name="type">form</field>
1594+ <field name="arch" type="xml">
1595+ <form string="Cut-off Lines">
1596+ <group name="source" string="Source" colspan="4" col="4">
1597+ <field name="parent_id" invisible="not context.get('account_cutoff_line_main_view', False)"/>
1598+ <field name="partner_id"/>
1599+ <field name="name"/>
1600+ <field name="account_id"/>
1601+ <field name="cutoff_account_id"/>
1602+ <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
1603+ <field name="tax_ids" invisible="'accrued' not in context.get('type', '-')"/>
1604+ <field name="amount" />
1605+ <field name="currency_id" />
1606+ </group>
1607+ <group name="cutoff" string="Cut-off Computation" colspan="4" col="4">
1608+ <field name="cutoff_amount" />
1609+ <field name="company_currency_id" />
1610+ <field name="tax_line_ids" nolabel="1" invisible="'accrued' not in context.get('type', '-')" colspan="4"/>
1611+ </group>
1612+ </form>
1613+ </field>
1614+</record>
1615+
1616+<!-- Tree view for lines -->
1617+<record id="account_cutoff_line_tree" model="ir.ui.view">
1618+ <field name="name">account.cutoff.line.tree</field>
1619+ <field name="model">account.cutoff.line</field>
1620+ <field name="type">tree</field>
1621+ <field name="arch" type="xml">
1622+ <tree string="Cut-off Lines">
1623+ <field name="parent_id" invisible="not context.get('account_cutoff_line_main_view', False)"/>
1624+ <field name="partner_id"/>
1625+ <field name="name"/>
1626+ <field name="cutoff_account_code"/>
1627+ <field name="analytic_account_code" groups="analytic.group_analytic_accounting"/>
1628+ <field name="tax_ids" invisible="'accrued' not in context.get('type', '-')"/>
1629+ <field name="amount"/>
1630+ <field name="currency_id"/>
1631+ <field name="cutoff_amount"/>
1632+ <field name="company_currency_id"/>
1633+ </tree>
1634+ </field>
1635+</record>
1636+
1637+<!-- Form view for tax lines -->
1638+<record id="account_cutoff_tax_line_form" model="ir.ui.view">
1639+ <field name="name">account.cutoff.tax.line.form</field>
1640+ <field name="model">account.cutoff.tax.line</field>
1641+ <field name="type">form</field>
1642+ <field name="arch" type="xml">
1643+ <form string="Cut-off Tax Lines">
1644+ <group name="tax" string="Tax">
1645+ <field name="parent_id" invisible="not context.get('account_cutoff_tax_line_main_view', False)"/>
1646+ <field name="tax_id"/>
1647+ <field name="sequence"/>
1648+ <field name="cutoff_account_id"/>
1649+ <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
1650+ <field name="base"/>
1651+ <field name="amount"/>
1652+ <field name="currency_id"/>
1653+ </group>
1654+ <group name="cutoff" string="Cut-off Computation">
1655+ <field name="cutoff_amount"/>
1656+ <field name="company_currency_id"/>
1657+ </group>
1658+ </form>
1659+ </field>
1660+</record>
1661+
1662+<!-- Tree view for tax lines -->
1663+<record id="account_cutoff_tax_line_tree" model="ir.ui.view">
1664+ <field name="name">account.cutoff.tax.line.tree</field>
1665+ <field name="model">account.cutoff.tax.line</field>
1666+ <field name="type">tree</field>
1667+ <field name="arch" type="xml">
1668+ <tree string="Cut-off Tax Lines">
1669+ <field name="parent_id" invisible="not context.get('account_cutoff_tax_line_main_view', False)"/>
1670+ <field name="tax_id"/>
1671+ <field name="cutoff_account_id"/>
1672+ <field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
1673+ <field name="base"/>
1674+ <field name="amount"/>
1675+ <field name="currency_id"/>
1676+ <field name="cutoff_amount"/>
1677+ <field name="company_currency_id"/>
1678+ <field name="sequence" invisible="True"/>
1679+ </tree>
1680+ </field>
1681+</record>
1682+
1683+<!-- Form view for account mappings -->
1684+<record id="account_cutoff_mapping_form" model="ir.ui.view">
1685+ <field name="name">account.cutoff.mapping.form</field>
1686+ <field name="model">account.cutoff.mapping</field>
1687+ <field name="type">form</field>
1688+ <field name="arch" type="xml">
1689+ <form string="Account Cut-off Mapping">
1690+ <field name="company_id" groups="base.group_multi_company" widget="selection" invisible="not context.get('account_cutoff_mapping_main_view', False)" />
1691+ <field name="account_id"/>
1692+ <field name="cutoff_account_id"/>
1693+ <field name="cutoff_type"/>
1694+ </form>
1695+ </field>
1696+</record>
1697+
1698+<!-- Tree view for account mappings -->
1699+<record id="account_cutoff_mapping_tree" model="ir.ui.view">
1700+ <field name="name">account.cutoff.mapping.tree</field>
1701+ <field name="model">account.cutoff.mapping</field>
1702+ <field name="type">tree</field>
1703+ <field name="arch" type="xml">
1704+ <tree string="Account Cut-off Mapping" editable="bottom">
1705+ <field name="company_id" groups="base.group_multi_company" widget="selection" invisible="not context.get('account_cutoff_mapping_main_view', False)" />
1706+ <field name="account_id"/>
1707+ <field name="cutoff_account_id"/>
1708+ <field name="cutoff_type"/>
1709+ </tree>
1710+ </field>
1711+</record>
1712+
1713+<!-- Action for account mappings -->
1714+<record id="account_cutoff_mapping_action" model="ir.actions.act_window">
1715+ <field name="name">Cut-off Account Mapping</field>
1716+ <field name="res_model">account.cutoff.mapping</field>
1717+ <field name="view_type">form</field>
1718+ <field name="view_mode">tree,form</field>
1719+ <field name="context">{'account_cutoff_mapping_main_view': True}</field>
1720+</record>
1721+
1722+<!-- Menu entry for account mapping -->
1723+<menuitem id="account_cutoff_mapping_menu"
1724+ parent="account.account_account_menu"
1725+ action="account_cutoff_mapping_action"
1726+ sequence="100"/>
1727+
1728+</data>
1729+</openerp>
1730
1731=== added file 'account_cutoff_base/company.py'
1732--- account_cutoff_base/company.py 1970-01-01 00:00:00 +0000
1733+++ account_cutoff_base/company.py 2014-03-09 00:39:34 +0000
1734@@ -0,0 +1,35 @@
1735+# -*- encoding: utf-8 -*-
1736+##############################################################################
1737+#
1738+# Account Cut-off Base module for OpenERP
1739+# Copyright (C) 2013 Akretion (http://www.akretion.com)
1740+# @author Alexis de Lattre <alexis.delattre@akretion.com>
1741+#
1742+# This program is free software: you can redistribute it and/or modify
1743+# it under the terms of the GNU Affero General Public License as
1744+# published by the Free Software Foundation, either version 3 of the
1745+# License, or (at your option) any later version.
1746+#
1747+# This program is distributed in the hope that it will be useful,
1748+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1749+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1750+# GNU Affero General Public License for more details.
1751+#
1752+# You should have received a copy of the GNU Affero General Public License
1753+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1754+#
1755+##############################################################################
1756+
1757+
1758+from openerp.osv import orm, fields
1759+
1760+
1761+class res_company(orm.Model):
1762+ _inherit = 'res.company'
1763+
1764+ _columns = {
1765+ 'default_cutoff_journal_id': fields.many2one(
1766+ 'account.journal', 'Default Cut-off Journal'),
1767+ 'cutoff_account_mapping_ids': fields.one2many(
1768+ 'account.cutoff.mapping', 'company_id', 'Cut-off Account Mapping'),
1769+ }
1770
1771=== added file 'account_cutoff_base/company_view.xml'
1772--- account_cutoff_base/company_view.xml 1970-01-01 00:00:00 +0000
1773+++ account_cutoff_base/company_view.xml 2014-03-09 00:39:34 +0000
1774@@ -0,0 +1,27 @@
1775+<?xml version="1.0" encoding="utf-8"?>
1776+
1777+<!--
1778+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
1779+ @author Alexis de Lattre <alexis.delattre@akretion.com>
1780+ The licence is in the file __openerp__.py
1781+-->
1782+
1783+<openerp>
1784+<data>
1785+
1786+<record id="view_company_form" model="ir.ui.view">
1787+ <field name="name">cutoff.company.form</field>
1788+ <field name="model">res.company</field>
1789+ <field name="inherit_id" ref="base.view_company_form" />
1790+ <field name="arch" type="xml">
1791+ <field name="currency_id" position="after">
1792+ <group name="cutoff" string="Cut-offs" colspan="2" col="2">
1793+ <field name="default_cutoff_journal_id" />
1794+ </group>
1795+ </field>
1796+ </field>
1797+</record>
1798+
1799+
1800+</data>
1801+</openerp>
1802
1803=== added directory 'account_cutoff_base/i18n'
1804=== added file 'account_cutoff_base/i18n/account_cutoff_base.pot'
1805--- account_cutoff_base/i18n/account_cutoff_base.pot 1970-01-01 00:00:00 +0000
1806+++ account_cutoff_base/i18n/account_cutoff_base.pot 2014-03-09 00:39:34 +0000
1807@@ -0,0 +1,403 @@
1808+# Translation of OpenERP Server.
1809+# This file contains the translation of the following modules:
1810+# * account_cutoff_base
1811+#
1812+msgid ""
1813+msgstr ""
1814+"Project-Id-Version: OpenERP Server 6.1\n"
1815+"Report-Msgid-Bugs-To: \n"
1816+"POT-Creation-Date: 2014-03-09 00:22+0000\n"
1817+"PO-Revision-Date: 2014-03-09 00:22+0000\n"
1818+"Last-Translator: <>\n"
1819+"Language-Team: \n"
1820+"MIME-Version: 1.0\n"
1821+"Content-Type: text/plain; charset=UTF-8\n"
1822+"Content-Transfer-Encoding: \n"
1823+"Plural-Forms: \n"
1824+
1825+#. module: account_cutoff_base
1826+#: field:account.cutoff,line_ids:0
1827+#: view:account.cutoff.line:0
1828+msgid "Cut-off Lines"
1829+msgstr ""
1830+
1831+#. module: account_cutoff_base
1832+#: field:account.cutoff,move_id:0
1833+msgid "Cut-off Journal Entry"
1834+msgstr ""
1835+
1836+#. module: account_cutoff_base
1837+#: constraint:account.cutoff:0
1838+msgid "The start date is after the end date!"
1839+msgstr ""
1840+
1841+#. module: account_cutoff_base
1842+#: help:account.cutoff,move_label:0
1843+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."
1844+msgstr ""
1845+
1846+#. module: account_cutoff_base
1847+#: view:account.cutoff:0
1848+msgid "Search Cut-offs"
1849+msgstr ""
1850+
1851+#. module: account_cutoff_base
1852+#: help:account.cutoff,state:0
1853+msgid "State of the cutoff. When the Journal Entry is created, the state is set to 'Done' and the fields become read-only."
1854+msgstr ""
1855+
1856+#. module: account_cutoff_base
1857+#: constraint:res.company:0
1858+msgid "Error! You can not create recursive companies."
1859+msgstr ""
1860+
1861+#. module: account_cutoff_base
1862+#: field:account.cutoff.mapping,cutoff_type:0
1863+msgid "Cut-off Type"
1864+msgstr ""
1865+
1866+#. module: account_cutoff_base
1867+#: code:addons/account_cutoff_base/account_cutoff.py:235
1868+#, python-format
1869+msgid "The Cut-off Journal Entry already exists. You should delete it before running this function."
1870+msgstr ""
1871+
1872+#. module: account_cutoff_base
1873+#: view:account.cutoff.line:0
1874+msgid "Source"
1875+msgstr ""
1876+
1877+#. module: account_cutoff_base
1878+#: field:account.cutoff,state:0
1879+msgid "State"
1880+msgstr ""
1881+
1882+#. module: account_cutoff_base
1883+#: field:account.cutoff.line,cutoff_account_code:0
1884+msgid "Cut-off Account Code"
1885+msgstr ""
1886+
1887+#. module: account_cutoff_base
1888+#: selection:account.cutoff,type:0
1889+#: selection:account.cutoff.mapping,cutoff_type:0
1890+msgid "Prepaid Expense"
1891+msgstr ""
1892+
1893+#. module: account_cutoff_base
1894+#: code:addons/account_cutoff_base/account_cutoff.py:240
1895+#, python-format
1896+msgid "There are no lines on this Cut-off, so we can't create a Journal Entry."
1897+msgstr ""
1898+
1899+#. module: account_cutoff_base
1900+#: view:account.cutoff.mapping:0
1901+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_mapping
1902+msgid "Account Cut-off Mapping"
1903+msgstr ""
1904+
1905+#. module: account_cutoff_base
1906+#: help:account.cutoff.tax.line,amount:0
1907+msgid "Tax Amount in the currency of the PO."
1908+msgstr ""
1909+
1910+#. module: account_cutoff_base
1911+#: selection:account.cutoff,type:0
1912+#: selection:account.cutoff.mapping,cutoff_type:0
1913+msgid "Accrued Revenue"
1914+msgstr ""
1915+
1916+#. module: account_cutoff_base
1917+#: field:account.cutoff.line,partner_id:0
1918+msgid "Partner"
1919+msgstr ""
1920+
1921+#. module: account_cutoff_base
1922+#: field:account.cutoff,cutoff_date:0
1923+msgid "Cut-off Date"
1924+msgstr ""
1925+
1926+#. module: account_cutoff_base
1927+#: field:account.cutoff.line,name:0
1928+msgid "Description"
1929+msgstr ""
1930+
1931+#. module: account_cutoff_base
1932+#: field:account.cutoff,type:0
1933+msgid "Type"
1934+msgstr ""
1935+
1936+#. module: account_cutoff_base
1937+#: field:account.cutoff,company_id:0
1938+#: field:account.cutoff.mapping,company_id:0
1939+msgid "Company"
1940+msgstr ""
1941+
1942+#. module: account_cutoff_base
1943+#: field:account.cutoff,cutoff_journal_id:0
1944+msgid "Cut-off Account Journal"
1945+msgstr ""
1946+
1947+#. module: account_cutoff_base
1948+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_tax_line
1949+msgid "Account Cut-off Tax Line"
1950+msgstr ""
1951+
1952+#. module: account_cutoff_base
1953+#: selection:account.cutoff,type:0
1954+#: selection:account.cutoff.mapping,cutoff_type:0
1955+msgid "Prepaid Revenue"
1956+msgstr ""
1957+
1958+#. module: account_cutoff_base
1959+#: help:account.cutoff.line,currency_id:0
1960+msgid "Currency of the 'Amount' field."
1961+msgstr ""
1962+
1963+#. module: account_cutoff_base
1964+#: selection:account.cutoff,type:0
1965+#: selection:account.cutoff.mapping,cutoff_type:0
1966+msgid "Accrued Expense"
1967+msgstr ""
1968+
1969+#. module: account_cutoff_base
1970+#: field:account.cutoff,total_cutoff_amount:0
1971+msgid "Total Cut-off Amount"
1972+msgstr ""
1973+
1974+#. module: account_cutoff_base
1975+#: field:account.cutoff,company_currency_id:0
1976+#: field:account.cutoff.line,company_currency_id:0
1977+#: field:account.cutoff.tax.line,company_currency_id:0
1978+msgid "Company Currency"
1979+msgstr ""
1980+
1981+#. module: account_cutoff_base
1982+#: field:account.cutoff.tax.line,base:0
1983+msgid "Base"
1984+msgstr ""
1985+
1986+#. module: account_cutoff_base
1987+#: field:res.company,default_cutoff_journal_id:0
1988+msgid "Default Cut-off Journal"
1989+msgstr ""
1990+
1991+#. module: account_cutoff_base
1992+#: view:account.cutoff:0
1993+#: selection:account.cutoff,state:0
1994+msgid "Done"
1995+msgstr ""
1996+
1997+#. module: account_cutoff_base
1998+#: field:account.cutoff.line,parent_id:0
1999+msgid "Cut-off"
2000+msgstr ""
2001+
2002+#. module: account_cutoff_base
2003+#: view:account.cutoff:0
2004+msgid "Back to Draft"
2005+msgstr ""
2006+
2007+#. module: account_cutoff_base
2008+#: code:addons/account_cutoff_base/account_cutoff.py:234
2009+#: code:addons/account_cutoff_base/account_cutoff.py:239
2010+#, python-format
2011+msgid "Error:"
2012+msgstr ""
2013+
2014+#. module: account_cutoff_base
2015+#: sql_constraint:account.cutoff:0
2016+msgid "A cutoff of the same type already exists with this cut-off date !"
2017+msgstr ""
2018+
2019+#. module: account_cutoff_base
2020+#: field:account.cutoff.tax.line,parent_id:0
2021+#: model:ir.model,name:account_cutoff_base.model_account_cutoff_line
2022+msgid "Account Cut-off Line"
2023+msgstr ""
2024+
2025+#. module: account_cutoff_base
2026+#: field:account.cutoff.line,account_id:0
2027+msgid "Account"
2028+msgstr ""
2029+
2030+#. module: account_cutoff_base
2031+#: field:account.cutoff.line,tax_line_ids:0
2032+#: view:account.cutoff.tax.line:0
2033+msgid "Cut-off Tax Lines"
2034+msgstr ""
2035+
2036+#. module: account_cutoff_base
2037+#: sql_constraint:res.company:0
2038+msgid "The company name must be unique !"
2039+msgstr ""
2040+
2041+#. module: account_cutoff_base
2042+#: field:account.cutoff.tax.line,cutoff_amount:0
2043+msgid "Cut-off Tax Amount"
2044+msgstr ""
2045+
2046+#. module: account_cutoff_base
2047+#: help:account.cutoff.tax.line,cutoff_amount:0
2048+msgid "Tax Cut-off Amount in the company currency."
2049+msgstr ""
2050+
2051+#. module: account_cutoff_base
2052+#: model:ir.model,name:account_cutoff_base.model_account_cutoff
2053+msgid "Account Cut-off"
2054+msgstr ""
2055+
2056+#. module: account_cutoff_base
2057+#: field:account.cutoff.tax.line,amount:0
2058+msgid "Tax Amount"
2059+msgstr ""
2060+
2061+#. module: account_cutoff_base
2062+#: model:ir.model,name:account_cutoff_base.model_res_company
2063+msgid "Companies"
2064+msgstr ""
2065+
2066+#. module: account_cutoff_base
2067+#: field:account.cutoff.line,tax_ids:0
2068+msgid "Taxes"
2069+msgstr ""
2070+
2071+#. module: account_cutoff_base
2072+#: view:account.cutoff:0
2073+#: model:ir.ui.menu,name:account_cutoff_base.cutoff_menu
2074+#: view:res.company:0
2075+msgid "Cut-offs"
2076+msgstr ""
2077+
2078+#. module: account_cutoff_base
2079+#: view:account.cutoff:0
2080+msgid "Create Journal Entry"
2081+msgstr ""
2082+
2083+#. module: account_cutoff_base
2084+#: field:account.cutoff.line,currency_id:0
2085+msgid "Amount Currency"
2086+msgstr ""
2087+
2088+#. module: account_cutoff_base
2089+#: field:account.cutoff.mapping,account_id:0
2090+msgid "Regular Account"
2091+msgstr ""
2092+
2093+#. module: account_cutoff_base
2094+#: field:account.cutoff,move_label:0
2095+msgid "Label of the Cut-off Journal Entry"
2096+msgstr ""
2097+
2098+#. module: account_cutoff_base
2099+#: code:addons/account_cutoff_base/account_cutoff.py:124
2100+#, python-format
2101+msgid "Prepaid Expense%s"
2102+msgstr ""
2103+
2104+#. module: account_cutoff_base
2105+#: view:account.cutoff.line:0
2106+#: view:account.cutoff.tax.line:0
2107+msgid "Cut-off Computation"
2108+msgstr ""
2109+
2110+#. module: account_cutoff_base
2111+#: selection:account.cutoff.mapping,cutoff_type:0
2112+msgid "All Cut-off Types"
2113+msgstr ""
2114+
2115+#. module: account_cutoff_base
2116+#: help:account.cutoff.tax.line,base:0
2117+msgid "Base Amount in the currency of the PO."
2118+msgstr ""
2119+
2120+#. module: account_cutoff_base
2121+#: code:addons/account_cutoff_base/account_cutoff.py:120
2122+#, python-format
2123+msgid "Accrued Revenue%s"
2124+msgstr ""
2125+
2126+#. module: account_cutoff_base
2127+#: field:account.cutoff.tax.line,sequence:0
2128+msgid "Sequence"
2129+msgstr ""
2130+
2131+#. module: account_cutoff_base
2132+#: view:account.cutoff.tax.line:0
2133+#: field:account.cutoff.tax.line,tax_id:0
2134+msgid "Tax"
2135+msgstr ""
2136+
2137+#. module: account_cutoff_base
2138+#: field:account.cutoff.line,amount:0
2139+msgid "Amount"
2140+msgstr ""
2141+
2142+#. module: account_cutoff_base
2143+#: field:account.cutoff,cutoff_account_id:0
2144+#: field:account.cutoff.line,cutoff_account_id:0
2145+#: field:account.cutoff.mapping,cutoff_account_id:0
2146+#: field:account.cutoff.tax.line,cutoff_account_id:0
2147+msgid "Cut-off Account"
2148+msgstr ""
2149+
2150+#. module: account_cutoff_base
2151+#: field:account.cutoff.line,analytic_account_id:0
2152+#: field:account.cutoff.tax.line,analytic_account_id:0
2153+msgid "Analytic Account"
2154+msgstr ""
2155+
2156+#. module: account_cutoff_base
2157+#: field:account.cutoff.tax.line,currency_id:0
2158+msgid "Currency"
2159+msgstr ""
2160+
2161+#. module: account_cutoff_base
2162+#: field:account.cutoff.line,analytic_account_code:0
2163+msgid "Analytic Account Code"
2164+msgstr ""
2165+
2166+#. module: account_cutoff_base
2167+#: model:ir.actions.act_window,name:account_cutoff_base.account_cutoff_mapping_action
2168+#: model:ir.ui.menu,name:account_cutoff_base.account_cutoff_mapping_menu
2169+#: field:res.company,cutoff_account_mapping_ids:0
2170+msgid "Cut-off Account Mapping"
2171+msgstr ""
2172+
2173+#. module: account_cutoff_base
2174+#: code:addons/account_cutoff_base/account_cutoff.py:122
2175+#, python-format
2176+msgid "Prepaid Revenue%s"
2177+msgstr ""
2178+
2179+#. module: account_cutoff_base
2180+#: help:account.cutoff.line,amount:0
2181+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'."
2182+msgstr ""
2183+
2184+#. module: account_cutoff_base
2185+#: sql_constraint:account.cutoff:0
2186+msgid "A cut-off of the same type already exists with the same date(s) !"
2187+msgstr ""
2188+
2189+#. module: account_cutoff_base
2190+#: view:account.cutoff:0
2191+#: selection:account.cutoff,state:0
2192+msgid "Draft"
2193+msgstr ""
2194+
2195+#. module: account_cutoff_base
2196+#: help:account.cutoff.line,cutoff_amount:0
2197+msgid "Cut-off Amount without taxes in the Company Currency."
2198+msgstr ""
2199+
2200+#. module: account_cutoff_base
2201+#: code:addons/account_cutoff_base/account_cutoff.py:118
2202+#, python-format
2203+msgid "Accrued Expense%s"
2204+msgstr ""
2205+
2206+#. module: account_cutoff_base
2207+#: field:account.cutoff.line,cutoff_amount:0
2208+msgid "Cut-off Amount"
2209+msgstr ""
2210+
2211
2212=== added directory 'account_cutoff_base/security'
2213=== added file 'account_cutoff_base/security/ir.model.access.csv'
2214--- account_cutoff_base/security/ir.model.access.csv 1970-01-01 00:00:00 +0000
2215+++ account_cutoff_base/security/ir.model.access.csv 2014-03-09 00:39:34 +0000
2216@@ -0,0 +1,9 @@
2217+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2218+access_account_cutoff_mapping,Full access on account.cutoff.mapping,model_account_cutoff_mapping,account.group_account_manager,1,1,1,1
2219+access_account_cutoff_mapping_user,Read access on account.cutoff.mapping,model_account_cutoff_mapping,base.group_user,1,0,0,0
2220+access_account_cutoff,Full access on account.cutoff,model_account_cutoff,account.group_account_manager,1,1,1,1
2221+access_account_cutoff_read,Read access on account.cutoff,model_account_cutoff,account.group_account_user,1,0,0,0
2222+access_account_cutoff_line,Full access on account.cutoff.line,model_account_cutoff_line,account.group_account_manager,1,1,1,1
2223+access_account_cutoff_line_read,Read access on account.cutoff.line,model_account_cutoff_line,account.group_account_user,1,0,0,0
2224+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
2225+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
2226
2227=== added directory 'account_cutoff_prepaid'
2228=== added file 'account_cutoff_prepaid/__init__.py'
2229--- account_cutoff_prepaid/__init__.py 1970-01-01 00:00:00 +0000
2230+++ account_cutoff_prepaid/__init__.py 2014-03-09 00:39:34 +0000
2231@@ -0,0 +1,26 @@
2232+# -*- encoding: utf-8 -*-
2233+##############################################################################
2234+#
2235+# Account Cut-off Prepaid module for OpenERP
2236+# Copyright (C) 2013 Akretion (http://www.akretion.com)
2237+# @author Alexis de Lattre <alexis.delattre@akretion.com>
2238+#
2239+# This program is free software: you can redistribute it and/or modify
2240+# it under the terms of the GNU Affero General Public License as
2241+# published by the Free Software Foundation, either version 3 of the
2242+# License, or (at your option) any later version.
2243+#
2244+# This program is distributed in the hope that it will be useful,
2245+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2246+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2247+# GNU Affero General Public License for more details.
2248+#
2249+# You should have received a copy of the GNU Affero General Public License
2250+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2251+#
2252+##############################################################################
2253+
2254+from . import company
2255+from . import product
2256+from . import account
2257+from . import account_cutoff
2258
2259=== added file 'account_cutoff_prepaid/__openerp__.py'
2260--- account_cutoff_prepaid/__openerp__.py 1970-01-01 00:00:00 +0000
2261+++ account_cutoff_prepaid/__openerp__.py 2014-03-09 00:39:34 +0000
2262@@ -0,0 +1,57 @@
2263+# -*- encoding: utf-8 -*-
2264+##############################################################################
2265+#
2266+# Account Cut-off Prepaid module for OpenERP
2267+# Copyright (C) 2013 Akretion (http://www.akretion.com)
2268+# @author Alexis de Lattre <alexis.delattre@akretion.com>
2269+#
2270+# This program is free software: you can redistribute it and/or modify
2271+# it under the terms of the GNU Affero General Public License as
2272+# published by the Free Software Foundation, either version 3 of the
2273+# License, or (at your option) any later version.
2274+#
2275+# This program is distributed in the hope that it will be useful,
2276+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2277+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2278+# GNU Affero General Public License for more details.
2279+#
2280+# You should have received a copy of the GNU Affero General Public License
2281+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2282+#
2283+##############################################################################
2284+
2285+
2286+{
2287+ 'name': 'Account Cut-off Prepaid',
2288+ 'version': '0.2',
2289+ 'category': 'Accounting & Finance',
2290+ 'license': 'AGPL-3',
2291+ 'summary': 'Prepaid Expense, Prepaid Revenue',
2292+ 'description': """
2293+Manage prepaid expense and revenue based on start and end dates
2294+===============================================================
2295+
2296+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.
2297+
2298+Please contact Alexis de Lattre from Akretion <alexis.delattre@akretion.com> for any help or question about this module.
2299+ """,
2300+ 'author': 'Akretion',
2301+ 'website': 'http://www.akretion.com',
2302+ 'depends': ['account_cutoff_base'],
2303+ 'data': [
2304+ 'company_view.xml',
2305+ 'product_view.xml',
2306+ 'account_invoice_view.xml',
2307+ 'account_view.xml',
2308+ 'account_cutoff_view.xml',
2309+ ],
2310+ 'demo': ['product_demo.xml'],
2311+ 'images': [
2312+ 'images/prepaid_revenue_draft.jpg',
2313+ 'images/prepaid_revenue_journal_entry.jpg',
2314+ 'images/prepaid_revenue_done.jpg',
2315+ ],
2316+ 'installable': True,
2317+ 'active': False,
2318+ 'application': True,
2319+}
2320
2321=== added file 'account_cutoff_prepaid/account.py'
2322--- account_cutoff_prepaid/account.py 1970-01-01 00:00:00 +0000
2323+++ account_cutoff_prepaid/account.py 2014-03-09 00:39:34 +0000
2324@@ -0,0 +1,150 @@
2325+# -*- encoding: utf-8 -*-
2326+##############################################################################
2327+#
2328+# Account Cut-off Prepaid module for OpenERP
2329+# Copyright (C) 2013 Akretion (http://www.akretion.com)
2330+# @author Alexis de Lattre <alexis.delattre@akretion.com>
2331+#
2332+# This program is free software: you can redistribute it and/or modify
2333+# it under the terms of the GNU Affero General Public License as
2334+# published by the Free Software Foundation, either version 3 of the
2335+# License, or (at your option) any later version.
2336+#
2337+# This program is distributed in the hope that it will be useful,
2338+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2339+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2340+# GNU Affero General Public License for more details.
2341+#
2342+# You should have received a copy of the GNU Affero General Public License
2343+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2344+#
2345+##############################################################################
2346+
2347+
2348+from openerp.osv import orm, fields
2349+from openerp.tools.translate import _
2350+
2351+
2352+class account_invoice_line(orm.Model):
2353+ _inherit = 'account.invoice.line'
2354+
2355+ _columns = {
2356+ 'start_date': fields.date('Start Date'),
2357+ 'end_date': fields.date('End Date'),
2358+ }
2359+
2360+ def _check_start_end_dates(self, cr, uid, ids):
2361+ for invline in self.browse(cr, uid, ids):
2362+ if invline.start_date and not invline.end_date:
2363+ raise orm.except_orm(
2364+ _('Error:'),
2365+ _("Missing End Date for invoice line with "
2366+ "Description '%s'.")
2367+ % (invline.name))
2368+ if invline.end_date and not invline.start_date:
2369+ raise orm.except_orm(
2370+ _('Error:'),
2371+ _("Missing Start Date for invoice line with "
2372+ "Description '%s'.")
2373+ % (invline.name))
2374+ if invline.end_date and invline.start_date and \
2375+ invline.start_date > invline.end_date:
2376+ raise orm.except_orm(
2377+ _('Error:'),
2378+ _("Start Date should be before or be the same as "
2379+ "End Date for invoice line with Description '%s'.")
2380+ % (invline.name))
2381+ # Note : we can't check invline.product_id.must_have_dates
2382+ # have start_date and end_date here, because it would
2383+ # block automatic invoice generation. So we do the check
2384+ # upon validation of the invoice (see below the function
2385+ # action_move_create)
2386+ return True
2387+
2388+ _constraints = [
2389+ (_check_start_end_dates, "Error msg in raise",
2390+ ['start_date', 'end_date', 'product_id']),
2391+ ]
2392+
2393+ def move_line_get_item(self, cr, uid, line, context=None):
2394+ res = super(account_invoice_line, self).move_line_get_item(
2395+ cr, uid, line, context=context)
2396+ res['start_date'] = line.start_date
2397+ res['end_date'] = line.end_date
2398+ return res
2399+
2400+
2401+class account_move_line(orm.Model):
2402+ _inherit = "account.move.line"
2403+
2404+ _columns = {
2405+ 'start_date': fields.date('Start Date'),
2406+ 'end_date': fields.date('End Date'),
2407+ }
2408+
2409+ def _check_start_end_dates(self, cr, uid, ids):
2410+ for moveline in self.browse(cr, uid, ids):
2411+ if moveline.start_date and not moveline.end_date:
2412+ raise orm.except_orm(
2413+ _('Error:'),
2414+ _("Missing End Date for move line with Name '%s'.")
2415+ % (moveline.name))
2416+ if moveline.end_date and not moveline.start_date:
2417+ raise orm.except_orm(
2418+ _('Error:'),
2419+ _("Missing Start Date for move line with Name '%s'.")
2420+ % (moveline.name))
2421+ if moveline.end_date and moveline.start_date and \
2422+ moveline.start_date > moveline.end_date:
2423+ raise orm.except_orm(
2424+ _('Error:'),
2425+ _("Start Date should be before End Date for move line "
2426+ "with Name '%s'.")
2427+ % (moveline.name))
2428+ # should we check that it's related to an expense / revenue ?
2429+ # -> I don't think so
2430+ return True
2431+
2432+ _constraints = [(
2433+ _check_start_end_dates,
2434+ "Error msg in raise",
2435+ ['start_date', 'end_date']
2436+ )]
2437+
2438+
2439+class account_invoice(orm.Model):
2440+ _inherit = 'account.invoice'
2441+
2442+ def inv_line_characteristic_hashcode(self, invoice, invoice_line):
2443+ '''Add start and end dates to hashcode used when the option "Group
2444+ Invoice Lines" is active on the Account Journal'''
2445+ code = super(account_invoice, self).inv_line_characteristic_hashcode(
2446+ invoice, invoice_line)
2447+ hashcode = '%s-%s-%s' % (
2448+ code, invoice_line.get('start_date', 'False'),
2449+ invoice_line.get('end_date', 'False'),
2450+ )
2451+ return hashcode
2452+
2453+ def line_get_convert(self, cr, uid, x, part, date, context=None):
2454+ res = super(account_invoice, self).line_get_convert(
2455+ cr, uid, x, part, date, context=context)
2456+ res['start_date'] = x.get('start_date', False)
2457+ res['end_date'] = x.get('end_date', False)
2458+ return res
2459+
2460+ def action_move_create(self, cr, uid, ids, context=None):
2461+ '''Check that products with must_have_dates=True have
2462+ Start and End Dates'''
2463+ for invoice in self.browse(cr, uid, ids, context=context):
2464+ for invline in invoice.invoice_line:
2465+ if invline.product_id and invline.product_id.must_have_dates:
2466+ if not invline.start_date or not invline.end_date:
2467+ raise orm.except_orm(
2468+ _('Error:'),
2469+ _("Missing Start Date and End Date for invoice "
2470+ "line with Product '%s' which has the "
2471+ "property 'Must Have Start and End Dates'.")
2472+ % (invline.product_id.name))
2473+ return super(account_invoice, self).action_move_create(
2474+ cr, uid, ids, context=context)
2475
2476=== added file 'account_cutoff_prepaid/account_cutoff.py'
2477--- account_cutoff_prepaid/account_cutoff.py 1970-01-01 00:00:00 +0000
2478+++ account_cutoff_prepaid/account_cutoff.py 2014-03-09 00:39:34 +0000
2479@@ -0,0 +1,253 @@
2480+# -*- encoding: utf-8 -*-
2481+##############################################################################
2482+#
2483+# Account Cut-off Prepaid module for OpenERP
2484+# Copyright (C) 2013 Akretion (http://www.akretion.com)
2485+# @author Alexis de Lattre <alexis.delattre@akretion.com>
2486+#
2487+# This program is free software: you can redistribute it and/or modify
2488+# it under the terms of the GNU Affero General Public License as
2489+# published by the Free Software Foundation, either version 3 of the
2490+# License, or (at your option) any later version.
2491+#
2492+# This program is distributed in the hope that it will be useful,
2493+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2494+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2495+# GNU Affero General Public License for more details.
2496+#
2497+# You should have received a copy of the GNU Affero General Public License
2498+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2499+#
2500+##############################################################################
2501+
2502+
2503+from openerp.osv import orm, fields
2504+from openerp.tools.translate import _
2505+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
2506+from datetime import datetime
2507+
2508+
2509+class account_cutoff(orm.Model):
2510+ _inherit = 'account.cutoff'
2511+
2512+ _columns = {
2513+ 'source_journal_ids': fields.many2many(
2514+ 'account.journal', id1='cutoff_id', id2='journal_id',
2515+ string='Source Journals', readonly=True,
2516+ states={'draft': [('readonly', False)]}),
2517+ 'forecast': fields.boolean(
2518+ 'Forecast',
2519+ readonly=True, states={'draft': [('readonly', False)]},
2520+ help="The Forecast mode allows the user to compute "
2521+ "the prepaid revenue/expense between 2 dates in the future."),
2522+ 'start_date': fields.date('Start Date'),
2523+ 'end_date': fields.date('End Date'),
2524+ }
2525+
2526+ def _get_default_source_journals(self, cr, uid, context=None):
2527+ if context is None:
2528+ context = {}
2529+ journal_obj = self.pool['account.journal']
2530+ res = []
2531+ type = context.get('type')
2532+ mapping = {
2533+ 'prepaid_expense': ('purchase', 'purchase_refund'),
2534+ 'prepaid_revenue': ('sale', 'sale_refund'),
2535+ }
2536+ if type in mapping:
2537+ src_journal_ids = journal_obj.search(
2538+ cr, uid, [('type', 'in', mapping[type])])
2539+ if src_journal_ids:
2540+ res = src_journal_ids
2541+ return res
2542+
2543+ _defaults = {
2544+ 'source_journal_ids': _get_default_source_journals,
2545+ }
2546+
2547+ _sql_constraints = [(
2548+ 'date_type_forecast_company_uniq',
2549+ 'unique(cutoff_date, company_id, type, forecast, start_date, end_date)',
2550+ 'A cut-off of the same type already exists with the same date(s) !'
2551+ )]
2552+
2553+ def _check_start_end_dates(self, cr, uid, ids):
2554+ for prepaid in self.browse(cr, uid, ids):
2555+ if prepaid.forecast and prepaid.start_date and prepaid.end_date \
2556+ and prepaid.start_date > prepaid.end_date:
2557+ return False
2558+ return True
2559+
2560+ _constraints = [
2561+ (_check_start_end_dates, "The start date is after the end date!",
2562+ ['start_date', 'end_date', 'forecast']),
2563+ ]
2564+
2565+ def forecast_onchange(self, cr, uid, ids, forecast, context=None):
2566+ res = {'value': {}}
2567+ line_ids = self.pool['account.cutoff.line'].search(
2568+ cr, uid, [('parent_id', 'in', ids)], context=context)
2569+ self.pool['account.cutoff.line'].unlink(
2570+ cr, uid, line_ids, context=context)
2571+ if forecast:
2572+ res['value']['cutoff_date'] = False
2573+ else:
2574+ res['value']['start_date'] = False
2575+ res['value']['end_date'] = False
2576+ return res
2577+
2578+ def _prepare_prepaid_lines(
2579+ self, cr, uid, ids, aml, cur_cutoff, mapping, context=None):
2580+ start_date = datetime.strptime(
2581+ aml['start_date'], DEFAULT_SERVER_DATE_FORMAT)
2582+ end_date = datetime.strptime(
2583+ aml['end_date'], DEFAULT_SERVER_DATE_FORMAT)
2584+ # Here, we compute the amount of the cutoff
2585+ # That's the important part !
2586+ total_days = (end_date - start_date).days + 1
2587+ if cur_cutoff['forecast']:
2588+ out_days = 0
2589+ forecast_start_date = datetime.strptime(
2590+ cur_cutoff['start_date'], DEFAULT_SERVER_DATE_FORMAT)
2591+ forecast_end_date = datetime.strptime(
2592+ cur_cutoff['end_date'], DEFAULT_SERVER_DATE_FORMAT)
2593+ if aml['end_date'] > cur_cutoff['end_date']:
2594+ out_days += (end_date - forecast_end_date).days
2595+ if aml['start_date'] < cur_cutoff['start_date']:
2596+ out_days += (forecast_start_date - start_date).days
2597+ prepaid_days = total_days - out_days
2598+ else:
2599+ cutoff_date_str = cur_cutoff['cutoff_date']
2600+ cutoff_date = datetime.strptime(
2601+ cutoff_date_str, DEFAULT_SERVER_DATE_FORMAT)
2602+ if aml['start_date'] > cutoff_date_str:
2603+ prepaid_days = total_days
2604+ else:
2605+ prepaid_days = (end_date - cutoff_date).days
2606+ if total_days:
2607+ cutoff_amount = (aml['debit'] - aml['credit'])\
2608+ * prepaid_days / float(total_days)
2609+ else:
2610+ raise orm.except_orm(
2611+ _('Error:'),
2612+ "Should never happen. Total days should always be > 0")
2613+
2614+ # we use account mapping here
2615+ if aml['account_id'][0] in mapping:
2616+ cutoff_account_id = mapping[aml['account_id'][0]]
2617+ else:
2618+ cutoff_account_id = aml['account_id'][0]
2619+
2620+ res = {
2621+ 'parent_id': ids[0],
2622+ 'move_line_id': aml['id'],
2623+ 'partner_id': aml['partner_id'] and aml['partner_id'][0] or False,
2624+ 'name': aml['name'],
2625+ 'start_date': aml['start_date'],
2626+ 'end_date': aml['end_date'],
2627+ 'account_id': aml['account_id'][0],
2628+ 'cutoff_account_id': cutoff_account_id,
2629+ 'analytic_account_id':
2630+ aml['analytic_account_id'] and aml['analytic_account_id'][0]
2631+ or False,
2632+ 'total_days': total_days,
2633+ 'prepaid_days': prepaid_days,
2634+ 'amount': aml['credit'] - aml['debit'],
2635+ 'currency_id': cur_cutoff['company_currency_id'][0],
2636+ 'cutoff_amount': cutoff_amount,
2637+ }
2638+ return res
2639+
2640+ def get_prepaid_lines(self, cr, uid, ids, context=None):
2641+ assert len(ids) == 1,\
2642+ 'This function should only be used for a single id at a time'
2643+ aml_obj = self.pool['account.move.line']
2644+ line_obj = self.pool['account.cutoff.line']
2645+ mapping_obj = self.pool['account.cutoff.mapping']
2646+ cur_cutoff = self.read(
2647+ cr, uid, ids[0], [
2648+ 'line_ids', 'source_journal_ids', 'cutoff_date', 'company_id',
2649+ 'type', 'company_currency_id', 'forecast', 'start_date',
2650+ 'end_date',
2651+ ],
2652+ context=context)
2653+ src_journal_ids = cur_cutoff['source_journal_ids']
2654+ if not src_journal_ids:
2655+ raise orm.except_orm(
2656+ _('Error:'), _("You should set at least one Source Journal."))
2657+ cutoff_date_str = cur_cutoff['cutoff_date']
2658+ # Delete existing lines
2659+ if cur_cutoff['line_ids']:
2660+ line_obj.unlink(cr, uid, cur_cutoff['line_ids'], context=context)
2661+
2662+ if cur_cutoff['forecast']:
2663+ domain = [
2664+ ('start_date', '<=', cur_cutoff['end_date']),
2665+ ('end_date', '>=', cur_cutoff['start_date']),
2666+ ('journal_id', 'in', src_journal_ids)
2667+ ]
2668+ else:
2669+ domain = [
2670+ ('start_date', '!=', False),
2671+ ('journal_id', 'in', src_journal_ids),
2672+ ('end_date', '>', cutoff_date_str),
2673+ ('date', '<=', cutoff_date_str)
2674+ ]
2675+
2676+ # Search for account move lines in the source journals
2677+ aml_ids = aml_obj.search(cr, uid, domain, context=context)
2678+ # Create mapping dict
2679+ mapping = mapping_obj._get_mapping_dict(
2680+ cr, uid, cur_cutoff['company_id'][0], cur_cutoff['type'],
2681+ context=context)
2682+
2683+ # Loop on selected account move lines to create the cutoff lines
2684+ for aml in aml_obj.read(
2685+ cr, uid, aml_ids, [
2686+ 'credit', 'debit', 'start_date', 'end_date', 'account_id',
2687+ 'analytic_account_id', 'partner_id', 'name'
2688+ ],
2689+ context=context):
2690+
2691+ line_obj.create(
2692+ cr, uid, self._prepare_prepaid_lines(
2693+ cr, uid, ids, aml, cur_cutoff, mapping, context=context),
2694+ context=context)
2695+ return True
2696+
2697+ def _inherit_default_cutoff_account_id(self, cr, uid, context=None):
2698+ if context is None:
2699+ context = {}
2700+ account_id = super(account_cutoff, self).\
2701+ _inherit_default_cutoff_account_id(cr, uid, context=context)
2702+ type = context.get('type')
2703+ company = self.pool['res.users'].browse(
2704+ cr, uid, uid, context=context).company_id
2705+ if type == 'prepaid_revenue':
2706+ account_id = company.default_prepaid_revenue_account_id.id or False
2707+ elif type == 'prepaid_expense':
2708+ account_id = company.default_prepaid_expense_account_id.id or False
2709+ return account_id
2710+
2711+
2712+class account_cutoff_line(orm.Model):
2713+ _inherit = 'account.cutoff.line'
2714+
2715+ _columns = {
2716+ 'move_line_id': fields.many2one(
2717+ 'account.move.line', 'Accout Move Line', readonly=True),
2718+ 'move_date': fields.related(
2719+ 'move_line_id', 'date', type='date',
2720+ string='Account Move Date', readonly=True),
2721+ 'invoice_id': fields.related(
2722+ 'move_line_id', 'invoice', type='many2one',
2723+ relation='account.invoice', string='Invoice', readonly=True),
2724+ 'start_date': fields.date('Start Date', readonly=True),
2725+ 'end_date': fields.date('End Date', readonly=True),
2726+ 'total_days': fields.integer('Total Number of Days', readonly=True),
2727+ 'prepaid_days': fields.integer(
2728+ 'Prepaid Days', readonly=True,
2729+ help="In regular mode, this is the number of days after the "
2730+ "cut-off date. In forecast mode, this is the number of days "
2731+ "between the start date and the end date."),
2732+ }
2733
2734=== added file 'account_cutoff_prepaid/account_cutoff_view.xml'
2735--- account_cutoff_prepaid/account_cutoff_view.xml 1970-01-01 00:00:00 +0000
2736+++ account_cutoff_prepaid/account_cutoff_view.xml 2014-03-09 00:39:34 +0000
2737@@ -0,0 +1,146 @@
2738+<?xml version="1.0" encoding="utf-8"?>
2739+
2740+<!--
2741+ Copyright (C) 2013-2014 Akretion (http://www.akretion.com/)
2742+ @author Alexis de Lattre <alexis.delattre@akretion.com>
2743+ The licence is in the file __openerp__.py
2744+-->
2745+
2746+<openerp>
2747+<data>
2748+
2749+<!-- Tree view -->
2750+<record id="account_cutoff_tree" model="ir.ui.view">
2751+ <field name="name">account.cutoff.prepaid.tree</field>
2752+ <field name="model">account.cutoff</field>
2753+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_tree"/>
2754+ <field name="arch" type="xml">
2755+ <field name="cutoff_date" position="after">
2756+ <field name="forecast" invisible="'prepaid' not in context.get('type', '-')"/>
2757+ <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
2758+ <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
2759+ </field>
2760+ </field>
2761+</record>
2762+
2763+<!-- Form view -->
2764+<record id="account_cutoff_form" model="ir.ui.view">
2765+ <field name="name">account.cutoff.prepaid.form</field>
2766+ <field name="model">account.cutoff</field>
2767+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_form"/>
2768+ <field name="arch" type="xml">
2769+ <field name="type" position="after">
2770+ <field name="forecast"
2771+ invisible="'prepaid' not in context.get('type', '-')"
2772+ on_change="forecast_onchange(forecast, context)"/>
2773+ <field name="start_date"
2774+ attrs="{'invisible': [('forecast', '=', False)], 'required': [('forecast', '=', True)]}"/>
2775+ <field name="end_date"
2776+ attrs="{'invisible': [('forecast', '=', False)], 'required': [('forecast', '=', True)]}"/>
2777+ </field>
2778+ <field name="cutoff_date" position="attributes">
2779+ <attribute name="attrs">{'invisible': [('forecast', '=', True)], 'required': [('forecast', '=', False)]}</attribute>
2780+ <attribute name="required">0</attribute>
2781+ </field>
2782+ <group name="accounting-params" position="attributes">
2783+ <attribute name="attrs">{'invisible': [('forecast', '=', True)]}</attribute>
2784+ </group>
2785+ <field name="cutoff_journal_id" position="attributes">
2786+ <attribute name="required">0</attribute>
2787+ <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
2788+ </field>
2789+ <field name="cutoff_account_id" position="attributes">
2790+ <attribute name="required">0</attribute>
2791+ <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
2792+ </field>
2793+ <field name="move_label" position="attributes">
2794+ <attribute name="required">0</attribute>
2795+ <attribute name="attrs">{'required': [('forecast', '=', False)]}</attribute>
2796+ </field>
2797+ <button name="create_move" position="attributes">
2798+ <attribute name="attrs">{'invisible': [('forecast', '=', True)]}</attribute>
2799+ </button>
2800+ <button name="create_move" position="before">
2801+ <button name="get_prepaid_lines" string="Re-Generate Lines" type="object" states="draft" invisible="'prepaid' not in context.get('type', '-')"/>
2802+ </button>
2803+ <field name="cutoff_date" position="after">
2804+ <field name="source_journal_ids" invisible="'prepaid' not in context.get('type', '-')"/>
2805+ </field>
2806+ </field>
2807+</record>
2808+
2809+<!-- Form view for lines -->
2810+<record id="account_cutoff_line_form" model="ir.ui.view">
2811+ <field name="name">account.cutoff.line.prepaid.form</field>
2812+ <field name="model">account.cutoff.line</field>
2813+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_form"/>
2814+ <field name="arch" type="xml">
2815+ <field name="parent_id" position="after">
2816+ <field name="move_line_id" invisible="'prepaid' not in context.get('type', '-')"/>
2817+ <field name="move_date" invisible="'prepaid' not in context.get('type', '-')" />
2818+ <field name="invoice_id" invisible="'prepaid' not in context.get('type', '-')" />
2819+ </field>
2820+ <field name="name" position="after">
2821+ <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
2822+ <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
2823+ </field>
2824+ <field name="cutoff_amount" position="before">
2825+ <field name="total_days" invisible="'prepaid' not in context.get('type', '-')"/>
2826+ <field name="prepaid_days" invisible="'prepaid' not in context.get('type', '-')"/>
2827+ </field>
2828+ </field>
2829+</record>
2830+
2831+<!-- Tree view for lines -->
2832+<record id="account_cutoff_line_tree" model="ir.ui.view">
2833+ <field name="name">account.cutoff.line.prepaid.tree</field>
2834+ <field name="model">account.cutoff.line</field>
2835+ <field name="inherit_id" ref="account_cutoff_base.account_cutoff_line_tree"/>
2836+ <field name="arch" type="xml">
2837+ <field name="parent_id" position="after">
2838+ <field name="move_line_id" invisible="'prepaid' not in context.get('type', '-')"/>
2839+ </field>
2840+ <field name="analytic_account_code" position="after">
2841+ <field name="start_date" invisible="'prepaid' not in context.get('type', '-')"/>
2842+ <field name="end_date" invisible="'prepaid' not in context.get('type', '-')"/>
2843+ <field name="total_days" string="Days Total" invisible="'prepaid' not in context.get('type', '-')"/>
2844+ <field name="prepaid_days" invisible="'prepaid' not in context.get('type', '-')"/>
2845+ </field>
2846+ </field>
2847+</record>
2848+
2849+
2850+<record id="account_cutoff_prepaid_expense_action" model="ir.actions.act_window">
2851+ <field name="name">Prepaid Expense</field>
2852+ <field name="res_model">account.cutoff</field>
2853+ <field name="view_type">form</field>
2854+ <field name="view_mode">tree,form</field>
2855+ <field name="domain">[('type', '=', 'prepaid_expense')]</field>
2856+ <field name="context">{'type': 'prepaid_expense'}</field>
2857+</record>
2858+
2859+
2860+<menuitem id="account_cutoff_prepaid_expense_menu"
2861+ parent="account_cutoff_base.cutoff_menu"
2862+ action="account_cutoff_prepaid_expense_action"
2863+ sequence="25"/>
2864+
2865+
2866+<record id="account_cutoff_prepaid_revenue_action" model="ir.actions.act_window">
2867+ <field name="name">Prepaid Revenue</field>
2868+ <field name="res_model">account.cutoff</field>
2869+ <field name="view_type">form</field>
2870+ <field name="view_mode">tree,form</field>
2871+ <field name="domain">[('type', '=', 'prepaid_revenue')]</field>
2872+ <field name="context">{'type': 'prepaid_revenue'}</field>
2873+</record>
2874+
2875+
2876+<menuitem id="account_cutoff_prepaid_revenue_menu"
2877+ parent="account_cutoff_base.cutoff_menu"
2878+ action="account_cutoff_prepaid_revenue_action"
2879+ sequence="20"/>
2880+
2881+
2882+</data>
2883+</openerp>
2884
2885=== added file 'account_cutoff_prepaid/account_invoice_view.xml'
2886--- account_cutoff_prepaid/account_invoice_view.xml 1970-01-01 00:00:00 +0000
2887+++ account_cutoff_prepaid/account_invoice_view.xml 2014-03-09 00:39:34 +0000
2888@@ -0,0 +1,53 @@
2889+<?xml version="1.0" encoding="utf-8"?>
2890+
2891+<!--
2892+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
2893+ @author Alexis de Lattre <alexis.delattre@akretion.com>
2894+ The licence is in the file __openerp__.py
2895+-->
2896+
2897+<openerp>
2898+<data>
2899+
2900+
2901+<record id="view_invoice_line_tree" model="ir.ui.view">
2902+ <field name="name">prepaid.cutoff.invoice_line_tree</field>
2903+ <field name="model">account.invoice.line</field>
2904+ <field name="inherit_id" ref="account.view_invoice_line_tree" />
2905+ <field name="arch" type="xml">
2906+ <field name="quantity" position="before">
2907+ <field name="start_date" />
2908+ <field name="end_date" />
2909+ </field>
2910+ </field>
2911+</record>
2912+
2913+
2914+<record id="invoice_supplier_form" model="ir.ui.view">
2915+ <field name="name">prepaid.cutoff.invoice_supplier_form</field>
2916+ <field name="model">account.invoice</field>
2917+ <field name="inherit_id" ref="account.invoice_supplier_form" />
2918+ <field name="arch" type="xml">
2919+ <xpath expr="//field[@name='invoice_line']/tree/field[@name='account_analytic_id']" position="after">
2920+ <field name="start_date" />
2921+ <field name="end_date" />
2922+ </xpath>
2923+ </field>
2924+</record>
2925+
2926+
2927+<record id="view_invoice_line_form" model="ir.ui.view">
2928+ <field name="name">prepaid.cutoff.invoice_line_form</field>
2929+ <field name="model">account.invoice.line</field>
2930+ <field name="inherit_id" ref="account.view_invoice_line_form"/>
2931+ <field name="arch" type="xml">
2932+ <field name="name" position="after">
2933+ <field name="start_date" />
2934+ <field name="end_date" />
2935+ </field>
2936+ </field>
2937+</record>
2938+
2939+
2940+</data>
2941+</openerp>
2942
2943=== added file 'account_cutoff_prepaid/account_view.xml'
2944--- account_cutoff_prepaid/account_view.xml 1970-01-01 00:00:00 +0000
2945+++ account_cutoff_prepaid/account_view.xml 2014-03-09 00:39:34 +0000
2946@@ -0,0 +1,53 @@
2947+<?xml version="1.0" encoding="utf-8"?>
2948+
2949+<!--
2950+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
2951+ @author Alexis de Lattre <alexis.delattre@akretion.com>
2952+ The licence is in the file __openerp__.py
2953+-->
2954+
2955+<openerp>
2956+<data>
2957+
2958+
2959+<record id="view_move_line_form" model="ir.ui.view">
2960+ <field name="name">prepaid.cutoff.start.end.date.view_move_line_form</field>
2961+ <field name="model">account.move.line</field>
2962+ <field name="inherit_id" ref="account.view_move_line_form" />
2963+ <field name="arch" type="xml">
2964+ <field name="date_maturity" position="after">
2965+ <field name="start_date" />
2966+ <field name="end_date" />
2967+ </field>
2968+ </field>
2969+</record>
2970+
2971+
2972+<record id="view_move_line_form2" model="ir.ui.view">
2973+ <field name="name">prepaid.cutoff.start.end.date.view_move_line_form2</field>
2974+ <field name="model">account.move.line</field>
2975+ <field name="inherit_id" ref="account.view_move_line_form2" />
2976+ <field name="arch" type="xml">
2977+ <field name="date_maturity" position="after">
2978+ <field name="start_date" />
2979+ <field name="end_date" />
2980+ </field>
2981+ </field>
2982+</record>
2983+
2984+
2985+<record id="view_move_form" model="ir.ui.view">
2986+ <field name="name">prepaid.cutoff.start.end.date.view_move_form</field>
2987+ <field name="model">account.move</field>
2988+ <field name="inherit_id" ref="account.view_move_form" />
2989+ <field name="arch" type="xml">
2990+ <field name="date_maturity" position="after">
2991+ <field name="start_date" />
2992+ <field name="end_date" />
2993+ </field>
2994+ </field>
2995+</record>
2996+
2997+
2998+</data>
2999+</openerp>
3000
3001=== added file 'account_cutoff_prepaid/company.py'
3002--- account_cutoff_prepaid/company.py 1970-01-01 00:00:00 +0000
3003+++ account_cutoff_prepaid/company.py 2014-03-09 00:39:34 +0000
3004@@ -0,0 +1,37 @@
3005+# -*- encoding: utf-8 -*-
3006+##############################################################################
3007+#
3008+# Account Cut-off Prepaid module for OpenERP
3009+# Copyright (C) 2013 Akretion (http://www.akretion.com)
3010+# @author Alexis de Lattre <alexis.delattre@akretion.com>
3011+#
3012+# This program is free software: you can redistribute it and/or modify
3013+# it under the terms of the GNU Affero General Public License as
3014+# published by the Free Software Foundation, either version 3 of the
3015+# License, or (at your option) any later version.
3016+#
3017+# This program is distributed in the hope that it will be useful,
3018+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3019+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3020+# GNU Affero General Public License for more details.
3021+#
3022+# You should have received a copy of the GNU Affero General Public License
3023+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3024+#
3025+##############################################################################
3026+
3027+
3028+from openerp.osv import orm, fields
3029+
3030+
3031+class res_company(orm.Model):
3032+ _inherit = 'res.company'
3033+
3034+ _columns = {
3035+ 'default_prepaid_revenue_account_id': fields.many2one(
3036+ 'account.account', 'Default Account for Prepaid Revenue',
3037+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
3038+ 'default_prepaid_expense_account_id': fields.many2one(
3039+ 'account.account', 'Default Account for Prepaid Expense',
3040+ domain=[('type', '<>', 'view'), ('type', '<>', 'closed')]),
3041+ }
3042
3043=== added file 'account_cutoff_prepaid/company_view.xml'
3044--- account_cutoff_prepaid/company_view.xml 1970-01-01 00:00:00 +0000
3045+++ account_cutoff_prepaid/company_view.xml 2014-03-09 00:39:34 +0000
3046@@ -0,0 +1,27 @@
3047+<?xml version="1.0" encoding="utf-8"?>
3048+
3049+<!--
3050+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
3051+ @author Alexis de Lattre <alexis.delattre@akretion.com>
3052+ The licence is in the file __openerp__.py
3053+-->
3054+
3055+<openerp>
3056+<data>
3057+
3058+
3059+<record id="view_company_form" model="ir.ui.view">
3060+ <field name="name">account.prepaid.cutoff.company.form</field>
3061+ <field name="model">res.company</field>
3062+ <field name="inherit_id" ref="account_cutoff_base.view_company_form" />
3063+ <field name="arch" type="xml">
3064+ <field name="default_cutoff_journal_id" position="after">
3065+ <field name="default_prepaid_revenue_account_id" />
3066+ <field name="default_prepaid_expense_account_id" />
3067+ </field>
3068+ </field>
3069+</record>
3070+
3071+
3072+</data>
3073+</openerp>
3074
3075=== added directory 'account_cutoff_prepaid/i18n'
3076=== added file 'account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot'
3077--- account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot 1970-01-01 00:00:00 +0000
3078+++ account_cutoff_prepaid/i18n/account_cutoff_prepaid.pot 2014-03-09 00:39:34 +0000
3079@@ -0,0 +1,289 @@
3080+# Translation of OpenERP Server.
3081+# This file contains the translation of the following modules:
3082+# * account_cutoff_prepaid
3083+#
3084+msgid ""
3085+msgstr ""
3086+"Project-Id-Version: OpenERP Server 6.1\n"
3087+"Report-Msgid-Bugs-To: \n"
3088+"POT-Creation-Date: 2014-03-09 00:24+0000\n"
3089+"PO-Revision-Date: 2014-03-09 00:24+0000\n"
3090+"Last-Translator: <>\n"
3091+"Language-Team: \n"
3092+"MIME-Version: 1.0\n"
3093+"Content-Type: text/plain; charset=UTF-8\n"
3094+"Content-Transfer-Encoding: \n"
3095+"Plural-Forms: \n"
3096+
3097+#. module: account_cutoff_prepaid
3098+#: field:account.cutoff.line,move_line_id:0
3099+msgid "Accout Move Line"
3100+msgstr ""
3101+
3102+#. module: account_cutoff_prepaid
3103+#: field:account.cutoff,end_date:0
3104+#: field:account.cutoff.line,end_date:0
3105+#: field:account.invoice.line,end_date:0
3106+#: field:account.move.line,end_date:0
3107+msgid "End Date"
3108+msgstr ""
3109+
3110+#. module: account_cutoff_prepaid
3111+#: help:product.template,must_have_dates:0
3112+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."
3113+msgstr ""
3114+
3115+#. module: account_cutoff_prepaid
3116+#: constraint:res.company:0
3117+msgid "Error! You can not create recursive companies."
3118+msgstr ""
3119+
3120+#. module: account_cutoff_prepaid
3121+#: field:product.template,must_have_dates:0
3122+msgid "Must Have Start and End Dates"
3123+msgstr ""
3124+
3125+#. module: account_cutoff_prepaid
3126+#: field:account.cutoff,forecast:0
3127+msgid "Forecast"
3128+msgstr ""
3129+
3130+#. module: account_cutoff_prepaid
3131+#: field:account.cutoff,source_journal_ids:0
3132+msgid "Source Journals"
3133+msgstr ""
3134+
3135+#. module: account_cutoff_prepaid
3136+#: field:account.cutoff.line,move_date:0
3137+msgid "Account Move Date"
3138+msgstr ""
3139+
3140+#. module: account_cutoff_prepaid
3141+#: code:addons/account_cutoff_prepaid/account.py:95
3142+#, python-format
3143+msgid "Missing Start Date for move line with Name '%s'."
3144+msgstr ""
3145+
3146+#. module: account_cutoff_prepaid
3147+#: code:addons/account_cutoff_prepaid/account.py:47
3148+#, python-format
3149+msgid "Missing Start Date for invoice line with Description '%s'."
3150+msgstr ""
3151+
3152+#. module: account_cutoff_prepaid
3153+#: constraint:account.invoice.line:0
3154+#: constraint:account.move.line:0
3155+msgid "Error msg in raise"
3156+msgstr ""
3157+
3158+#. module: account_cutoff_prepaid
3159+#: constraint:account.move.line:0
3160+msgid "Company must be the same for its related account and period."
3161+msgstr ""
3162+
3163+#. module: account_cutoff_prepaid
3164+#: model:ir.actions.act_window,name:account_cutoff_prepaid.account_cutoff_prepaid_expense_action
3165+#: model:ir.ui.menu,name:account_cutoff_prepaid.account_cutoff_prepaid_expense_menu
3166+msgid "Prepaid Expense"
3167+msgstr ""
3168+
3169+#. module: account_cutoff_prepaid
3170+#: model:ir.actions.act_window,name:account_cutoff_prepaid.account_cutoff_prepaid_revenue_action
3171+#: model:ir.ui.menu,name:account_cutoff_prepaid.account_cutoff_prepaid_revenue_menu
3172+msgid "Prepaid Revenue"
3173+msgstr ""
3174+
3175+#. module: account_cutoff_prepaid
3176+#: code:addons/account_cutoff_prepaid/account.py:101
3177+#, python-format
3178+msgid "Start Date should be before End Date for move line with Name '%s'."
3179+msgstr ""
3180+
3181+#. module: account_cutoff_prepaid
3182+#: model:ir.model,name:account_cutoff_prepaid.model_account_move_line
3183+msgid "Journal Items"
3184+msgstr ""
3185+
3186+#. module: account_cutoff_prepaid
3187+#: view:account.cutoff:0
3188+msgid "Re-Generate Lines"
3189+msgstr ""
3190+
3191+#. module: account_cutoff_prepaid
3192+#: constraint:account.move.line:0
3193+msgid "You can not create journal items on an account of type view."
3194+msgstr ""
3195+
3196+#. module: account_cutoff_prepaid
3197+#: help:account.cutoff,forecast:0
3198+msgid "The Forecast mode allows the user to compute the prepaid revenue/expense between 2 dates in the future."
3199+msgstr ""
3200+
3201+#. module: account_cutoff_prepaid
3202+#: code:addons/account_cutoff_prepaid/account.py:40
3203+#: code:addons/account_cutoff_prepaid/account.py:46
3204+#: code:addons/account_cutoff_prepaid/account.py:53
3205+#: code:addons/account_cutoff_prepaid/account.py:89
3206+#: code:addons/account_cutoff_prepaid/account.py:94
3207+#: code:addons/account_cutoff_prepaid/account.py:100
3208+#: code:addons/account_cutoff_prepaid/account.py:144
3209+#: code:addons/account_cutoff_prepaid/account_cutoff.py:132
3210+#: code:addons/account_cutoff_prepaid/account_cutoff.py:177
3211+#, python-format
3212+msgid "Error:"
3213+msgstr ""
3214+
3215+#. module: account_cutoff_prepaid
3216+#: field:res.company,default_prepaid_revenue_account_id:0
3217+msgid "Default Account for Prepaid Revenue"
3218+msgstr ""
3219+
3220+#. module: account_cutoff_prepaid
3221+#: sql_constraint:account.cutoff:0
3222+msgid "A cutoff of the same type already exists with this cut-off date !"
3223+msgstr ""
3224+
3225+#. module: account_cutoff_prepaid
3226+#: model:ir.model,name:account_cutoff_prepaid.model_account_cutoff_line
3227+msgid "Account Cut-off Line"
3228+msgstr ""
3229+
3230+#. module: account_cutoff_prepaid
3231+#: sql_constraint:res.company:0
3232+msgid "The company name must be unique !"
3233+msgstr ""
3234+
3235+#. module: account_cutoff_prepaid
3236+#: model:product.template,name:account_cutoff_prepaid.product_insurance_contrat_product_template
3237+msgid "Car Insurance"
3238+msgstr ""
3239+
3240+#. module: account_cutoff_prepaid
3241+#: constraint:product.template:0
3242+msgid "Error: The default UOM and the purchase UOM must be in the same category."
3243+msgstr ""
3244+
3245+#. module: account_cutoff_prepaid
3246+#: model:ir.model,name:account_cutoff_prepaid.model_account_cutoff
3247+msgid "Account Cut-off"
3248+msgstr ""
3249+
3250+#. module: account_cutoff_prepaid
3251+#: model:ir.model,name:account_cutoff_prepaid.model_res_company
3252+msgid "Companies"
3253+msgstr ""
3254+
3255+#. module: account_cutoff_prepaid
3256+#: constraint:account.move.line:0
3257+msgid "You can not create journal items on closed account."
3258+msgstr ""
3259+
3260+#. module: account_cutoff_prepaid
3261+#: view:account.cutoff.line:0
3262+msgid "Days Total"
3263+msgstr ""
3264+
3265+#. module: account_cutoff_prepaid
3266+#: code:addons/account_cutoff_prepaid/account.py:54
3267+#, python-format
3268+msgid "Start Date should be before or be the same as End Date for invoice line with Description '%s'."
3269+msgstr ""
3270+
3271+#. module: account_cutoff_prepaid
3272+#: code:addons/account_cutoff_prepaid/account.py:145
3273+#, python-format
3274+msgid "Missing Start Date and End Date for invoice line with Product '%s' which has the property 'Must Have Start and End Dates'."
3275+msgstr ""
3276+
3277+#. module: account_cutoff_prepaid
3278+#: code:addons/account_cutoff_prepaid/account_cutoff.py:177
3279+#, python-format
3280+msgid "You should set at least one Source Journal."
3281+msgstr ""
3282+
3283+#. module: account_cutoff_prepaid
3284+#: code:addons/account_cutoff_prepaid/account.py:41
3285+#, python-format
3286+msgid "Missing End Date for invoice line with Description '%s'."
3287+msgstr ""
3288+
3289+#. module: account_cutoff_prepaid
3290+#: constraint:account.cutoff:0
3291+msgid "The start date is after the end date!"
3292+msgstr ""
3293+
3294+#. module: account_cutoff_prepaid
3295+#: sql_constraint:account.invoice:0
3296+msgid "Invoice Number must be unique per Company!"
3297+msgstr ""
3298+
3299+#. module: account_cutoff_prepaid
3300+#: code:addons/account_cutoff_prepaid/account.py:90
3301+#, python-format
3302+msgid "Missing End Date for move line with Name '%s'."
3303+msgstr ""
3304+
3305+#. module: account_cutoff_prepaid
3306+#: help:account.cutoff.line,prepaid_days:0
3307+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."
3308+msgstr ""
3309+
3310+#. module: account_cutoff_prepaid
3311+#: model:ir.model,name:account_cutoff_prepaid.model_product_template
3312+msgid "Product Template"
3313+msgstr ""
3314+
3315+#. module: account_cutoff_prepaid
3316+#: model:ir.model,name:account_cutoff_prepaid.model_account_invoice_line
3317+msgid "Invoice Line"
3318+msgstr ""
3319+
3320+#. module: account_cutoff_prepaid
3321+#: constraint:account.move.line:0
3322+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."
3323+msgstr ""
3324+
3325+#. module: account_cutoff_prepaid
3326+#: constraint:account.move.line:0
3327+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."
3328+msgstr ""
3329+
3330+#. module: account_cutoff_prepaid
3331+#: field:account.cutoff.line,total_days:0
3332+msgid "Total Number of Days"
3333+msgstr ""
3334+
3335+#. module: account_cutoff_prepaid
3336+#: field:res.company,default_prepaid_expense_account_id:0
3337+msgid "Default Account for Prepaid Expense"
3338+msgstr ""
3339+
3340+#. module: account_cutoff_prepaid
3341+#: field:account.cutoff.line,invoice_id:0
3342+#: model:ir.model,name:account_cutoff_prepaid.model_account_invoice
3343+msgid "Invoice"
3344+msgstr ""
3345+
3346+#. module: account_cutoff_prepaid
3347+#: sql_constraint:account.cutoff:0
3348+msgid "A cut-off of the same type already exists with the same date(s) !"
3349+msgstr ""
3350+
3351+#. module: account_cutoff_prepaid
3352+#: sql_constraint:account.move.line:0
3353+msgid "Wrong credit or debit value in accounting entry !"
3354+msgstr ""
3355+
3356+#. module: account_cutoff_prepaid
3357+#: field:account.cutoff,start_date:0
3358+#: field:account.cutoff.line,start_date:0
3359+#: field:account.invoice.line,start_date:0
3360+#: field:account.move.line,start_date:0
3361+msgid "Start Date"
3362+msgstr ""
3363+
3364+#. module: account_cutoff_prepaid
3365+#: field:account.cutoff.line,prepaid_days:0
3366+msgid "Prepaid Days"
3367+msgstr ""
3368+
3369
3370=== added directory 'account_cutoff_prepaid/images'
3371=== added file 'account_cutoff_prepaid/images/prepaid_revenue_done.jpg'
3372Binary 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
3373=== added file 'account_cutoff_prepaid/images/prepaid_revenue_draft.jpg'
3374Binary 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
3375=== added file 'account_cutoff_prepaid/images/prepaid_revenue_journal_entry.jpg'
3376Binary 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
3377=== added directory 'account_cutoff_prepaid/migrations'
3378=== added directory 'account_cutoff_prepaid/migrations/6.1.0.2'
3379=== added file 'account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py'
3380--- account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py 1970-01-01 00:00:00 +0000
3381+++ account_cutoff_prepaid/migrations/6.1.0.2/pre-migration.py 2014-03-09 00:39:34 +0000
3382@@ -0,0 +1,29 @@
3383+# -*- coding: utf-8 -*-
3384+##############################################################################
3385+#
3386+# Copyright (C) 2014 Akretion (http://www.akretion.com/)
3387+# @author: Alexis de Lattre <alexis.delattre@akretion.com>
3388+#
3389+# This program is free software: you can redistribute it and/or modify
3390+# it under the terms of the GNU Affero General Public License as
3391+# published by the Free Software Foundation, either version 3 of the
3392+# License, or (at your option) any later version.
3393+#
3394+# This program is distributed in the hope that it will be useful,
3395+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3396+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3397+# GNU Affero General Public License for more details.
3398+#
3399+# You should have received a copy of the GNU Affero General Public License
3400+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3401+#
3402+##############################################################################
3403+
3404+
3405+def migrate(cr, version):
3406+ if not version:
3407+ return
3408+
3409+ cr.execute(
3410+ 'ALTER TABLE "account_cutoff_line" RENAME "after_cutoff_days" '
3411+ 'TO "prepaid_days"')
3412
3413=== added file 'account_cutoff_prepaid/product.py'
3414--- account_cutoff_prepaid/product.py 1970-01-01 00:00:00 +0000
3415+++ account_cutoff_prepaid/product.py 2014-03-09 00:39:34 +0000
3416@@ -0,0 +1,36 @@
3417+# -*- encoding: utf-8 -*-
3418+##############################################################################
3419+#
3420+# Account Cut-off Prepaid module for OpenERP
3421+# Copyright (C) 2013 Akretion (http://www.akretion.com)
3422+# @author Alexis de Lattre <alexis.delattre@akretion.com>
3423+#
3424+# This program is free software: you can redistribute it and/or modify
3425+# it under the terms of the GNU Affero General Public License as
3426+# published by the Free Software Foundation, either version 3 of the
3427+# License, or (at your option) any later version.
3428+#
3429+# This program is distributed in the hope that it will be useful,
3430+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3431+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3432+# GNU Affero General Public License for more details.
3433+#
3434+# You should have received a copy of the GNU Affero General Public License
3435+# along with this program. If not, see <http://www.gnu.org/licenses/>.
3436+#
3437+##############################################################################
3438+
3439+
3440+from openerp.osv import orm, fields
3441+
3442+
3443+class product_template(orm.Model):
3444+ _inherit = 'product.template'
3445+
3446+ _columns = {
3447+ 'must_have_dates': fields.boolean(
3448+ 'Must Have Start and End Dates',
3449+ help="If this option is active, the user will have to enter "
3450+ "a Start Date and an End Date on the invoice lines that have "
3451+ "this product."),
3452+ }
3453
3454=== added file 'account_cutoff_prepaid/product_demo.xml'
3455--- account_cutoff_prepaid/product_demo.xml 1970-01-01 00:00:00 +0000
3456+++ account_cutoff_prepaid/product_demo.xml 2014-03-09 00:39:34 +0000
3457@@ -0,0 +1,25 @@
3458+<?xml version="1.0" encoding="utf-8"?>
3459+
3460+<!--
3461+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
3462+ @author Alexis de Lattre <alexis.delattre@akretion.com>
3463+ The licence is in the file __openerp__.py
3464+-->
3465+
3466+<openerp>
3467+<data>
3468+
3469+<record id="product_insurance_contrat" model="product.product">
3470+ <field name="name">Car Insurance</field>
3471+ <field name="default_code">CARINSUR</field>
3472+ <field name="type">service</field>
3473+ <field name="categ_id" ref="product.product_category_services0"/>
3474+ <field name="must_have_dates" eval="True" />
3475+ <field name="sale_ok" eval="True" />
3476+ <field name="purchase_ok" eval="True" />
3477+ <field name="list_price" eval="1200.0"/>
3478+ <field name="standard_price" eval="600.0"/>
3479+</record>
3480+
3481+</data>
3482+</openerp>
3483
3484=== added file 'account_cutoff_prepaid/product_view.xml'
3485--- account_cutoff_prepaid/product_view.xml 1970-01-01 00:00:00 +0000
3486+++ account_cutoff_prepaid/product_view.xml 2014-03-09 00:39:34 +0000
3487@@ -0,0 +1,37 @@
3488+<?xml version="1.0" encoding="utf-8"?>
3489+
3490+<!--
3491+ Copyright (C) 2013 Akretion (http://www.akretion.com/)
3492+ @author Alexis de Lattre <alexis.delattre@akretion.com>
3493+ The licence is in the file __openerp__.py
3494+-->
3495+
3496+<openerp>
3497+<data>
3498+
3499+<record id="product_normal_form_view" model="ir.ui.view">
3500+ <field name="name">add.must.have.dates.on.product.product.form</field>
3501+ <field name="model">product.product</field>
3502+ <field name="inherit_id" ref="account.product_normal_form_view" />
3503+ <field name="arch" type="xml">
3504+ <field name="purchase_ok" position="after">
3505+ <field name="must_have_dates" />
3506+ </field>
3507+ </field>
3508+</record>
3509+
3510+
3511+<record id="product_template_form_view" model="ir.ui.view">
3512+ <field name="name">add.must.have.dates.on.product.template.form</field>
3513+ <field name="model">product.template</field>
3514+ <field name="inherit_id" ref="account.product_template_form_view" />
3515+ <field name="arch" type="xml">
3516+ <field name="purchase_ok" position="after">
3517+ <field name="must_have_dates" />
3518+ </field>
3519+ </field>
3520+</record>
3521+
3522+
3523+</data>
3524+</openerp>
3525
3526=== added directory 'account_cutoff_prepaid/static'
3527=== added directory 'account_cutoff_prepaid/static/src'
3528=== added directory 'account_cutoff_prepaid/static/src/img'
3529=== added file 'account_cutoff_prepaid/static/src/img/icon.png'
3530Binary 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

Subscribers

People subscribed via source and target branches