[REF] point_of_sale: refactoring of journal entries creation

* Allows to overwrite and change the account.move.line values that will be created upon a pos session closing for example to add additional data introduced by a localization module.
 * Small refactoring of _create_account_move() method: All the parameter values of _create_account_move could easily be found from pos.order recordset itself, hence removed them and adapted call to it everywhere.

Part of PR #26262 related to the indian GST
This commit is contained in:
Jigar Vaghela
2019-01-18 08:34:32 +00:00
committed by qdp-odoo
parent 212ca45660
commit 86e90fcbea
2 changed files with 92 additions and 87 deletions
+88 -79
View File
@@ -158,10 +158,15 @@ class PosOrder(models.Model):
'''This method is designed to be inherited in a custom module'''
return False
def _create_account_move(self, dt, ref, journal_id, company_id):
date_tz_user = fields.Datetime.context_timestamp(self, fields.Datetime.from_string(dt))
def _create_account_move(self):
self.ensure_one()
date_tz_user = fields.Datetime.context_timestamp(self, fields.Datetime.from_string(self.session_id.start_at))
date_tz_user = fields.Date.to_string(date_tz_user)
return self.env['account.move'].sudo().create({'ref': ref, 'journal_id': journal_id, 'date': date_tz_user})
return self.env['account.move'].sudo().create({
'ref': self.name,
'journal_id': self.sale_journal.id,
'date': date_tz_user
})
def _prepare_invoice(self):
"""
@@ -243,7 +248,7 @@ class PosOrder(models.Model):
inv_line.update(price_unit=line.price_unit, discount=line.discount, name=inv_name)
return InvoiceLine.sudo().create(inv_line)
def _create_account_move_line(self, session=None, move=None):
def _prepare_account_move_line(self, line, partner_id, current_company, currency_id, rounding_method):
def _flatten_tax_and_children(taxes, group_done=None):
children = self.env['account.tax']
if group_done is None:
@@ -253,6 +258,79 @@ class PosOrder(models.Model):
group_done.add(tax.id)
children |= _flatten_tax_and_children(tax.children_tax_ids, group_done)
return taxes + children
res = []
order = line.order_id
cur_company = order.company_id.currency_id
date_order = order.date_order.date() if order.date_order else fields.Date.today()
if currency_id != cur_company:
amount_subtotal = currency_id._convert(line.price_subtotal, cur_company, order.company_id, date_order)
else:
amount_subtotal = line.price_subtotal
# Search for the income account
if line.product_id.property_account_income_id.id:
income_account = line.product_id.property_account_income_id.id
elif line.product_id.categ_id.property_account_income_categ_id.id:
income_account = line.product_id.categ_id.property_account_income_categ_id.id
else:
raise UserError(_('Please define income '
'account for this product: "%s" (id:%d).')
% (line.product_id.name, line.product_id.id))
name = line.product_id.name
if line.notice:
# add discount reason in move
name = name + ' (' + line.notice + ')'
# Create a move for the line for the order line
# Just like for invoices, a group of taxes must be present on this base line
# As well as its children
base_line_tax_ids = _flatten_tax_and_children(line.tax_ids_after_fiscal_position).filtered(lambda tax: tax.type_tax_use in ['sale', 'none'])
data = {
'name': name,
'quantity': line.qty,
'product_id': line.product_id.id,
'account_id': income_account,
'analytic_account_id': self._prepare_analytic_account(line),
'credit': ((amount_subtotal > 0) and amount_subtotal) or 0.0,
'debit': ((amount_subtotal < 0) and -amount_subtotal) or 0.0,
'tax_ids': [(6, 0, base_line_tax_ids.ids)],
'partner_id': partner_id
}
if currency_id != cur_company:
data['currency_id'] = currency_id.id
data['amount_currency'] = -abs(line.price_subtotal) if data.get('credit') else abs(line.price_subtotal)
res.append({'data_type': 'product', 'values': data})
# Create the tax lines
taxes = line.tax_ids_after_fiscal_position.filtered(lambda t: t.company_id.id == current_company.id)
if taxes:
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
for tax in taxes.compute_all(price, currency_id, line.qty)['taxes']:
if currency_id != cur_company:
round_tax = False if rounding_method == 'round_globally' else True
amount_tax = currency_id._convert(tax['amount'], cur_company, order.company_id, date_order, round=round_tax)
# amount_tax = currency_id.with_context(date=date_order).compute(tax['amount'], cur_company, round=round_tax)
else:
amount_tax = tax['amount']
data = {
'name': _('Tax') + ' ' + tax['name'],
'product_id': line.product_id.id,
'quantity': line.qty,
'account_id': tax['account_id'] or income_account,
'credit': ((amount_tax > 0) and amount_tax) or 0.0,
'debit': ((amount_tax < 0) and -amount_tax) or 0.0,
'tax_line_id': tax['id'],
'partner_id': partner_id,
'order_id': order.id
}
if currency_id != cur_company:
data['currency_id'] = currency_id.id
data['amount_currency'] = -abs(tax['amount']) if data.get('credit') else abs(tax['amount'])
res.append({'data_type': 'tax', 'values': data})
return res
def _create_account_move_line(self, session=None):
# Tricky, via the workflow, we only have one id in the ids variable
"""Create a account move line of order grouped by products or not."""
@@ -300,19 +378,16 @@ class PosOrder(models.Model):
'debit': line2['debit'] or 0.0,
'partner_id': line2['partner_id']
})
move = False
for order in self.filtered(lambda o: not o.account_move or o.state == 'paid'):
current_company = order.sale_journal.company_id
account_def = IrProperty.get(
'property_account_receivable_id', 'res.partner')
order_account = order.partner_id.property_account_receivable_id.id or account_def and account_def.id
partner_id = ResPartner._find_accounting_partner(order.partner_id).id or False
if move is None:
if not move:
# Create an entry for the sale
journal_id = self.env['ir.config_parameter'].sudo().get_param(
'pos.closing.journal_id_%s' % current_company.id, default=order.sale_journal.id)
move = self._create_account_move(
order.session_id.start_at, order.name, int(journal_id), order.company_id.id)
move = order._create_account_move()
def insert_data(data_type, values):
# if have_to_group_by:
@@ -358,77 +433,11 @@ class PosOrder(models.Model):
cur = order.pricelist_id.currency_id
cur_company = order.company_id.currency_id
amount_cur_company = 0.0
date_order = order.date_order.date() if order.date_order else fields.Date.today()
for line in order.lines:
if cur != cur_company:
amount_subtotal = cur._convert(line.price_subtotal, cur_company, order.company_id, date_order)
else:
amount_subtotal = line.price_subtotal
# Search for the income account
if line.product_id.property_account_income_id.id:
income_account = line.product_id.property_account_income_id.id
elif line.product_id.categ_id.property_account_income_categ_id.id:
income_account = line.product_id.categ_id.property_account_income_categ_id.id
else:
raise UserError(_('Please define income '
'account for this product: "%s" (id:%d).')
% (line.product_id.name, line.product_id.id))
name = line.product_id.name
if line.notice:
# add discount reason in move
name = name + ' (' + line.notice + ')'
# Create a move for the line for the order line
# Just like for invoices, a group of taxes must be present on this base line
# As well as its children
base_line_tax_ids = _flatten_tax_and_children(line.tax_ids_after_fiscal_position).filtered(lambda tax: tax.type_tax_use in ['sale', 'none'])
data = {
'name': name,
'quantity': line.qty,
'product_id': line.product_id.id,
'account_id': income_account,
'analytic_account_id': self._prepare_analytic_account(line),
'credit': ((amount_subtotal > 0) and amount_subtotal) or 0.0,
'debit': ((amount_subtotal < 0) and -amount_subtotal) or 0.0,
'tax_ids': [(6, 0, base_line_tax_ids.ids)],
'partner_id': partner_id
}
if cur != cur_company:
data['currency_id'] = cur.id
data['amount_currency'] = -abs(line.price_subtotal) if data.get('credit') else abs(line.price_subtotal)
amount_cur_company += data['credit'] - data['debit']
insert_data('product', data)
# Create the tax lines
taxes = line.tax_ids_after_fiscal_position.filtered(lambda t: t.company_id.id == current_company.id)
if not taxes:
continue
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
for tax in taxes.compute_all(price, cur, line.qty)['taxes']:
for move_line in self._prepare_account_move_line(line, partner_id, current_company, cur, rounding_method):
if cur != cur_company:
round_tax = False if rounding_method == 'round_globally' else True
amount_tax = cur._convert(tax['amount'], cur_company, order.company_id, date_order, round=round_tax)
# amount_tax = cur.with_context(date=date_order).compute(tax['amount'], cur_company, round=round_tax)
else:
amount_tax = tax['amount']
data = {
'name': _('Tax') + ' ' + tax['name'],
'product_id': line.product_id.id,
'quantity': line.qty,
'account_id': tax['account_id'] or income_account,
'credit': ((amount_tax > 0) and amount_tax) or 0.0,
'debit': ((amount_tax < 0) and -amount_tax) or 0.0,
'tax_line_id': tax['id'],
'partner_id': partner_id,
'order_id': order.id
}
if cur != cur_company:
data['currency_id'] = cur.id
data['amount_currency'] = -abs(tax['amount']) if data.get('credit') else abs(tax['amount'])
amount_cur_company += data['credit'] - data['debit']
insert_data('tax', data)
amount_cur_company += move_line['values']['credit'] - move_line['values']['debit']
insert_data(move_line['data_type'], move_line['values'])
# round tax lines per order
if rounding_method == 'round_globally':
+4 -8
View File
@@ -19,15 +19,11 @@ class PosSession(models.Model):
def _confirm_orders(self):
for session in self:
company_id = session.config_id.journal_id.company_id.id
orders = session.order_ids.filtered(lambda order: order.state == 'paid')
journal_id = self.env['ir.config_parameter'].sudo().get_param(
'pos.closing.journal_id_%s' % company_id, default=session.config_id.journal_id.id)
if not journal_id:
journal = session.config_id.journal_id
if not journal:
raise UserError(_("You have to set a Sale Journal for the POS:%s") % (session.config_id.name,))
move = self.env['pos.order'].with_context(force_company=company_id)._create_account_move(session.start_at, session.name, int(journal_id), company_id)
orders.with_context(force_company=company_id)._create_account_move_line(session, move)
orders = session.order_ids.filtered(lambda order: order.state == 'paid')
orders.with_context(force_company=journal.company_id.id)._create_account_move_line(session)
for order in session.order_ids.filtered(lambda o: o.state not in ['done', 'invoiced']):
if order.state not in ('paid'):
raise UserError(