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