Skip to content
Browse files

[ADD] account: cron to post draft entries

Task 193992
The cron is used to post draft entries such as those created by the module account_asset
Also add an inverse to account.move.amount
Also add a reverse compute on amount, and adapt its value according to the currency
  • Loading branch information...
william-andre committed Feb 26, 2019
1 parent cb5d836 commit a42995fc8b2bda39cabe8a78fa320a6798301f9a
@@ -56,7 +56,7 @@
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<record id="ir_cron_auto_post_draft_entry" model="ir.cron">
<field name="name">Account; Post draft entries with auto_post set to True up to today</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="nextcall" eval="(, minute=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')" />
<field name="doall" eval="False"/>
<field name="model_id" ref="model_account_move"/>
<field name="code">model._run_post_draft_to_post()</field>
<field name="state">code</field>

This file was deleted.

Oops, something went wrong.
@@ -42,13 +42,38 @@ def name_get(self):
return result

@api.depends('line_ids.debit', '')
@api.depends('line_ids.debit', '', 'line_ids.amount_currency', 'line_ids.currency_id')
def _amount_compute(self):
for move in self:
total = 0.0
for line in move.line_ids:
total_currency = 0.0
currency_id = move.line_ids and move.line_ids[0] or False
for line in move.line_ids.filtered(lambda l: l.debit):
total += line.debit
move.amount = total
if currency_id and == currency_id:
total_currency += line.amount_currency
elif currency_id:
currency_id = False

if currency_id and total_currency:
move.amount = total_currency
move.currency_id = currency_id
move.currency_id = move.company_id.currency_id or self.env.user.company_id.currency_id
move.amount = total

def _set_amount(self):
for move in self:
if len(move.line_ids) == 2 and move.amount != 0:
amount_in_company_currency = move.amount
if move.currency_id and move.currency_id != move.company_id.currency_id:
amount_in_company_currency = move.currency_id._convert(move.amount, move.company_id.currency_id, move.company_id,
for line in move.line_ids:
line.amount_currency = line.debit and move.amount or -move.amount
for line in move.with_context(check_move_validity=False).line_ids:
line.debit = line.debit and amount_in_company_currency or 0.0 = and amount_in_company_currency or 0.0

@api.depends('line_ids.debit', '', 'line_ids.matched_debit_ids.amount', 'line_ids.matched_credit_ids.amount', 'line_ids.account_id.user_type_id.type')
def _compute_matched_percentage(self):
@@ -87,11 +112,6 @@ def _search_reconcile_model(self, operator, operand):
return [('id', 'in', rmi.ids)]
return [('id', '=', False)]
def _compute_currency(self):
self.currency_id = self.company_id.currency_id or self.env.user.company_id.currency_id

def _get_default_journal(self):
if self.env.context.get('default_journal_type'):
@@ -116,7 +136,6 @@ def _onchange_date(self):
ref = fields.Char(string='Reference', copy=False)
date = fields.Date(required=True, states={'posted': [('readonly', True)]}, index=True, default=fields.Date.context_today)
journal_id = fields.Many2one('account.journal', string='Journal', required=True, states={'posted': [('readonly', True)]}, default=_get_default_journal)
currency_id = fields.Many2one('res.currency', compute='_compute_currency', store=True, string="Currency")
state = fields.Selection([('draft', 'Unposted'), ('posted', 'Posted')], string='Status',
required=True, readonly=True, copy=False, default='draft',
help='All manually created new journal entries are usually in the status \'Unposted\', '
@@ -127,7 +146,8 @@ def _onchange_date(self):
line_ids = fields.One2many('account.move.line', 'move_id', string='Journal Items',
states={'posted': [('readonly', True)]}, copy=True)
partner_id = fields.Many2one('res.partner', compute='_compute_partner_id', string="Partner", store=True, readonly=True)
amount = fields.Monetary(compute='_amount_compute', store=True)
amount = fields.Monetary(compute='_amount_compute', inverse="_set_amount", store=True)
currency_id = fields.Many2one('res.currency', compute='_amount_compute', store=True, string="Currency")
narration = fields.Text(string='Internal Note')
company_id = fields.Many2one('', related='journal_id.company_id', string='Company', store=True, readonly=True)
matched_percentage = fields.Float('Percentage Matched', compute='_compute_matched_percentage', digits=0, store=True, readonly=True, help="Technical field used in cash basis method")
@@ -139,13 +159,12 @@ def _onchange_date(self):
string='Tax Cash Basis Entry of',
help="Technical field used to keep track of the tax cash basis reconciliation. "
"This is needed when cancelling the source: it will post the inverse journal entry to cancel that part too.")
auto_reverse = fields.Boolean(string='Reverse Automatically', default=False, help='If this checkbox is ticked, this entry will be automatically reversed at the reversal date you defined.')
reverse_date = fields.Date(string='Reversal Date', help='Date of the reverse accounting entry.')
auto_post = fields.Boolean(string='Post Automatically', default=False, help='If this checkbox is ticked, this entry will be automatically posted at its date.')
reverse_entry_id = fields.Many2one('account.move', String="Reverse entry", store=True, readonly=True)
to_check = fields.Boolean(string='To Check', default=False, help='If this checkbox is ticked, it means that the user was not sure of all the related informations at the time of the creation of the move and that the move needs to be checked again.')
tax_type_domain = fields.Char(store=False, help='Technical field used to have a dynamic taxes domain on the form view.')

@api.constrains('line_ids', 'journal_id', 'auto_reverse', 'reverse_date')
@api.constrains('line_ids', 'journal_id')
def _validate_move_modification(self):
if 'posted' in self.mapped('line_ids.payment_id.state'):
raise ValidationError(_("You cannot modify a journal entry linked to a posted payment."))
@@ -314,6 +333,9 @@ def post(self):
# Create the analytic lines in batch is faster as it leads to less cache invalidation.
for move in self:
if move.auto_post and >
raise UserError(_("This move is configured to be auto-posted. If you are sure you want to post it, please untick the checkbox."))

if == '/':
new_name = False
journal = move.journal_id
@@ -416,14 +438,14 @@ def assert_balanced(self):
return True

def _reverse_move(self, date=None, journal_id=None, auto=False):
def _reverse_move(self, date=None, journal_id=None):
with self.env.norecompute():
reversed_move = self.copy(default={
'date': date,
'journal_id': if journal_id else,
'ref': (_('Automatic reversal of: %s') if auto else _('Reversal of: %s')) % (,
'auto_reverse': False})
'ref': _('Reversal of: %s') % (,
for acm_line in reversed_move.line_ids.with_context(check_move_validity=False):
@@ -435,16 +457,14 @@ def _reverse_move(self, date=None, journal_id=None, auto=False):
return reversed_move

def reverse_moves(self, date=None, journal_id=None, auto=False):
def reverse_moves(self, date=None, journal_id=None):
date = date or
reversed_moves = self.env['account.move']
for ac_move in self:
#unreconcile all lines reversed
aml = ac_move.line_ids.filtered(lambda x: x.account_id.reconcile or x.account_id.internal_type == 'liquidity')
reversed_move = ac_move._reverse_move(date=date,
reversed_move = ac_move._reverse_move(date=date, journal_id=journal_id)
reversed_moves |= reversed_move
#reconcile together the reconcilable (or the liquidity aml) and their newly created counterpart
for account in set([x.account_id for x in aml]):
@@ -475,18 +495,17 @@ def action_duplicate(self):
return action

def _run_reverses_entries(self):
''' This method is called from a cron job. '''
def _run_post_draft_to_post(self):
''' This method is called from a cron job.
It is used to post entries such as those created by the module
records =[
('state', '=', 'posted'),
('auto_reverse', '=', True),
('reverse_date', '<=',,
('reverse_entry_id', '=', False)])
for move in records:
date = None
if move.reverse_date and (not self.env.user.company_id.period_lock_date or move.reverse_date > self.env.user.company_id.period_lock_date):
date = move.reverse_date
move.reverse_moves(date=date, auto=True)
('state', '=', 'draft'),
('date', '<=',,
('auto_post', '=', True),

def action_view_reverse_entry(self):
Oops, something went wrong.

0 comments on commit a42995f

Please sign in to comment.
You can’t perform that action at this time.