Merge lp:~jgrandguillaume-c2c/account-financial-tools/account-constraints-adding into lp:~account-core-editors/account-financial-tools/6.1

Proposed by Joël Grand-Guillaume @ camptocamp
Status: Rejected
Rejected by: Guewen Baconnier @ Camptocamp
Proposed branch: lp:~jgrandguillaume-c2c/account-financial-tools/account-constraints-adding
Merge into: lp:~account-core-editors/account-financial-tools/6.1
Diff against target: 182 lines (+137/-1)
2 files modified
account_constraints/__openerp__.py (+8/-0)
account_constraints/account_constraints.py (+129/-1)
To merge this branch: bzr merge lp:~jgrandguillaume-c2c/account-financial-tools/account-constraints-adding
Reviewer Review Type Date Requested Status
Alexandre Fayolle - camptocamp resubmitting from elsewhere with fixes Disapprove
Review via email: mp+144141@code.launchpad.net

Description of the change

Remove the possibility to modify or delete a move line related to an
  invoice or a bank statement, no matter what the status of the move
  (draft, validated or posted). This is usefule in standard context but
  moreover if you're using : account_default_draft_move. This way you ensure
  user cannot make mistake even in draft, he must pass through the
  parent object to make his modification.

I had to use monkey patching here cause a method hasn't the context in args :(

To post a comment you must log in.
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :

I can't fix the various typos in this MP, so I'm resubmitting it using a branch owned by the camptocamp account.

review: Disapprove (resubmitting from elsewhere with fixes)
Revision history for this message
Alexandre Fayolle - camptocamp (alexandre-fayolle-c2c) wrote :
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote :

> The new MP is at https://code.launchpad.net/~camptocamp/account-financial-
> tools/account-constraints-adding/+merge/144241

I changed the status of the proposal to 'Rejected' to reflect that.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'account_constraints/__openerp__.py'
2--- account_constraints/__openerp__.py 2013-01-16 09:16:56 +0000
3+++ account_constraints/__openerp__.py 2013-01-21 15:52:21 +0000
4@@ -67,6 +67,14 @@
5 * Forbid to remove the reconcile on opening entries. We introduce a new
6 boolean field to distinguish the reconciliations made by the closing process
7 from others.
8+
9+* Remove the possibility to modify or delete a move line related to an
10+ invoice or a bank statement, no matter what the status of the move
11+ (draft, validated or posted). This is usefule in standard context but
12+ moreover if you're using : account_default_draft_move. This way you ensure
13+ user cannot make mistake even in draft, he must pass through the
14+ parent object to make his modification.
15+
16 """,
17 'website': 'http://www.camptocamp.com',
18 'init_xml': [],
19
20=== modified file 'account_constraints/account_constraints.py'
21--- account_constraints/account_constraints.py 2013-01-16 09:28:38 +0000
22+++ account_constraints/account_constraints.py 2013-01-21 15:52:21 +0000
23@@ -20,6 +20,46 @@
24
25 from openerp.osv import fields, osv, orm
26 from openerp.tools.translate import _
27+from openerp.addons.account_invoice import account_invoice as original_invoice_model
28+
29+def action_cancel(self, cr, uid, ids, *args):
30+ """
31+ Override the whole function in order to pass the context in it as we need it
32+ in the move to know if this is allowed or not. The trouble was in the original
33+ method, there was context = {} that just scratch the whole context content...
34+ I marked chages with # --- start changes / end changes
35+ """
36+ # ---- Start of changes
37+ # context = {} # TODO: Use context from arguments
38+ context = args[-1] if args and isinstance(args[-1], dict) else {}
39+ # ---- End of changes
40+ account_move_obj = self.pool.get('account.move')
41+ invoices = self.read(cr, uid, ids, ['move_id', 'payment_ids'])
42+ move_ids = [] # ones that we will need to remove
43+ for i in invoices:
44+ if i['move_id']:
45+ move_ids.append(i['move_id'][0])
46+ if i['payment_ids']:
47+ account_move_line_obj = self.pool.get('account.move.line')
48+ pay_ids = account_move_line_obj.browse(cr, uid, i['payment_ids'])
49+ for move_line in pay_ids:
50+ if move_line.reconcile_partial_id and move_line.reconcile_partial_id.line_partial_ids:
51+ raise osv.except_osv(_('Error !'), _('You can not cancel an invoice which is partially paid! You need to unreconcile related payment entries first!'))
52+
53+ # First, set the invoices as cancelled and detach the move ids
54+ self.write(cr, uid, ids, {'state':'cancel', 'move_id':False})
55+ if move_ids:
56+ # second, invalidate the move(s)
57+ account_move_obj.button_cancel(cr, uid, move_ids, context=context)
58+ # delete the move this invoice was pointing to
59+ # Note that the corresponding move_lines and move_reconciles
60+ # will be automatically deleted too
61+ account_move_obj.unlink(cr, uid, move_ids, context=context)
62+ self._log_event(cr, uid, ids, -1.0, 'Cancel Invoice')
63+ return True
64+
65+# Monkey patch the original method in order to parse the context !
66+original_invoice_model.action_cancel = action_cancel
67
68
69 class AccountAccount(orm.Model):
70@@ -91,6 +131,53 @@
71 class AccountMoveLine(orm.Model):
72 _inherit = "account.move.line"
73
74+ def _check_invoice_related_move(self, cr, uid, ids, context=None):
75+ for line in self.browse(cr, uid, ids, context=context):
76+ if line.invoice:
77+ err_msg = _('Invoice name (id): %s (%s)') % (line.invoice.name, str(line.invoice.id))
78+ raise osv.except_osv(
79+ _('Error!'),
80+ _('You cannot do this on an entry generated by an invoice. You must '
81+ 'change the related invoice directly.\n%s.') % err_msg)
82+ return True
83+
84+ def _check_statement_related_move(self, cr, uid, ids, context=None):
85+ for line in self.browse(cr, uid, ids, context=context):
86+ if line.statement_id:
87+ err_msg = _('Bank statement name (id): %s (%s)') % (line.statement_id.name, str(line.statement_id.id))
88+ raise osv.except_osv(
89+ _('Error!'),
90+ _('You cannot do this on an entry generated by a bank statement. '
91+ 'You must change the related bank statement directly.\n%s.') % err_msg)
92+ return True
93+
94+ def unlink(self, cr, uid, ids, context=None, check=True):
95+ """ Add the verification of:
96+ - Is the move related to an invoice
97+ - Is the move related to a bank statement
98+ In that case, we forbid the move to be deleted even if draft. We should
99+ never delete directly a move line related or generated by another object.
100+ This is mandatory if you use the all move in draft (module: account_default_draft_move)
101+ """
102+ if not context.get('from_parent_object', False):
103+ self._check_invoice_related_move(cr, uid, ids, context=context)
104+ self._check_statement_related_move(cr, uid, ids, context=context)
105+ return super(AccountMoveLine, self).unlink(cr, uid, ids, context=context, check=check)
106+
107+ def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True):
108+ """ Add the verification of:
109+ - Is the move related to an invoice
110+ - Is the move related to a bank statement
111+ In that case, we forbid the move to be modified even if draft. We should
112+ never update directly a move line related or generated by another object.
113+ This is mandatory if you use the all move in draft (module: account_default_draft_move)
114+ """
115+ if not context.get('from_parent_object', False):
116+ self._check_invoice_related_move(cr, uid, ids, context=context)
117+ self._check_statement_related_move(cr, uid, ids, context=context)
118+ return super(AccountMoveLine, self).write(cr, uid, ids, vals,
119+ context=context, check=check, update_check=update_check)
120+
121 def _remove_move_reconcile(self, cr, uid, move_ids=None,
122 opening_reconciliation=False, context=None):
123 """Redefine the whole method to add the kwarg opening_reconciliation."""
124@@ -238,11 +325,27 @@
125 class Invoice(orm.Model):
126 _inherit = 'account.invoice'
127
128+ def action_move_create(self, cr, uid, ids, context=None):
129+ """Override the method to add the key 'from_parent_object' in
130+ the context."""
131+ if context is None:
132+ context = {}
133+ context['from_parent_object'] = True
134+ return super(Invoice,self).action_move_create(cr, uid, ids, context=context)
135+
136 # Forbid to cancel an invoice if the related move lines have already been
137 # used in a payment order. The risk is that importing the payment line
138 # in the bank statement will result in a crash cause no more move will
139- # be found in the payment line
140+ # be found in the payment line + Override the method to add the key 'from_parent_object' in
141+ # the context.
142 def action_cancel(self, cr, uid, ids, *args):
143+ """
144+ As the signature of the original function isn't good, we
145+ append context at the end of *args.
146+ """
147+ # Hack to take the last args...
148+ context = args[-1] if args and isinstance(args[-1], dict) else {}
149+ context['from_parent_object'] = True
150 payment_line_obj = self.pool.get('payment.line')
151 for inv in self.browse(cr, uid, ids, *args):
152 pl_line_ids = False
153@@ -259,4 +362,29 @@
154 "imported in a payment order. Remove it from the "
155 "following payment order : %s." % payment_order_name)
156 )
157+ args = list(args)
158+ args.append(context)
159 return super(Invoice, self).action_cancel(cr, uid, ids, *args)
160+
161+
162+class AccountBankStatement(orm.Model):
163+ _inherit = "account.bank.statement"
164+
165+ def button_cancel(self, cr, uid, ids, context=None):
166+ """Override the method to add the key 'from_parent_object' in
167+ the context. This is to allow to delete move line related to bank statement
168+ through the buton cancel."""
169+ if context is None:
170+ context = {}
171+ context['from_parent_object'] = True
172+ return super(AccountBankStatement, self).button_cancel(cr, uid, ids, context=context)
173+
174+ def create_move_from_st_line(self, cr, uid, st_line_id, company_currency_id, st_line_number, context=None):
175+ """Add the from_parent_object key in context in order to be able to post the move."""
176+ if context is None:
177+ context = {}
178+ context['from_parent_object'] = True
179+ return super(AccountBankStatement, self).create_move_from_st_line(cr, uid,
180+ st_line_id, company_currency_id, st_line_number, context=context)
181+
182+

Subscribers

People subscribed via source and target branches