[PATCH] Upstream patch - 26022022

This commit is contained in:
Parthiv Patel
2022-02-26 08:34:22 +00:00
parent 03e0da2dde
commit 6a5f4442e7
7 changed files with 272 additions and 25 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ class AccountMove(models.Model):
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
vehicle_id = fields.Many2one('fleet.vehicle', string='Vehicle')
vehicle_id = fields.Many2one('fleet.vehicle', string='Vehicle', index=True)
need_vehicle = fields.Boolean(compute='_compute_need_vehicle',
help="Technical field to decide whether the vehicle_id field is editable")
+7 -1
View File
@@ -16,8 +16,14 @@ class FleetVehicle(models.Model):
self.bill_count = 0
return
moves = self.env['account.move.line'].read_group(
domain=[('vehicle_id', 'in', self.ids), ('move_id.state', '!=', 'cancel')],
fields=['vehicle_id', 'move_id:array_agg'],
groupby=['vehicle_id'],
)
vehicle_move_mapping = {move['vehicle_id'][0]: set(move['move_id']) for move in moves}
for vehicle in self:
vehicle.account_move_ids = self.env['account.move.line'].search([('vehicle_id', '=', vehicle.id), ('move_id.state', '!=', 'cancel')]).move_id
vehicle.account_move_ids = [(6, 0, vehicle_move_mapping.get(vehicle.id, []))]
vehicle.bill_count = len(vehicle.account_move_ids)
def action_view_bills(self):
@@ -59,7 +59,7 @@ class GoogleDrive(models.Model):
}
try:
req = requests.post(
'https://sheets.googleapis.com/v4/spreadsheets/%s/values:batchUpdate?%s' % (spreadsheet_key, werkzeug.url_encode({'access_token': access_token})),
'https://sheets.googleapis.com/v4/spreadsheets/%s/values:batchUpdate?%s' % (spreadsheet_key, werkzeug.urls.url_encode({'access_token': access_token})),
data=json.dumps(request),
headers={'content-type': 'application/json', 'If-Match': '*'},
timeout=TIMEOUT,
+1 -1
View File
@@ -153,7 +153,7 @@
<field name="date"/>
<field name="user_id" invisible="1"/>
<field name="employee_id" required="1" widget="many2one_avatar_employee"/>
<field name="name"/>
<field name="name" required="0"/>
<field name="unit_amount" string="Duration" widget="float_time" decoration-danger="unit_amount &gt; 24"/>
<field name="project_id" invisible="1"/>
<field name="task_id" invisible="1"/>
+14 -11
View File
@@ -494,7 +494,12 @@ class PosSession(models.Model):
invoice_receivables[key] = self._update_amounts(invoice_receivables[key], {'amount': order.amount_total}, order.date_order)
# side loop to gather receivable lines by account for reconciliation
for move_line in order.account_move.line_ids.filtered(lambda aml: aml.account_id.internal_type == 'receivable' and not aml.reconciled):
order_account_move_receivable_lines[move_line.account_id.id] |= move_line
# NOTE: Negative (Positive) amount in the order's invoice's receivable line, will be paired to
# the respective positive (negative) balance in session's invoice receivable lines. That's why the comparator to
# calculate `key`s for `invoice_receivable_lines` in `_create_invoice_receivable_lines` is inverted.
# The key ensures we don't reconcile invoice receivable lines with opposite sign together
key = (order.partner_id.commercial_partner_id.id, order.amount_total < 0, move_line.account_id.id)
order_account_move_receivable_lines[key] |= move_line
else:
order_taxes = defaultdict(tax_amounts)
for order_line in order.lines:
@@ -690,10 +695,11 @@ class PosSession(models.Model):
receivable_lines = MoveLine.create(vals)
for receivable_line in receivable_lines:
if (not receivable_line.reconciled):
if account_id not in invoice_receivable_lines:
invoice_receivable_lines[account_id] = receivable_line
key = (commercial_partner.id, receivable_line.balance > 0, account_id)
if key not in invoice_receivable_lines:
invoice_receivable_lines[key] = receivable_line
else:
invoice_receivable_lines[account_id] |= receivable_line
invoice_receivable_lines[key] |= receivable_line
data.update({'invoice_receivable_lines': invoice_receivable_lines})
return data
@@ -754,9 +760,9 @@ class PosSession(models.Model):
pass
# reconcile invoice receivable lines
for account_id in order_account_move_receivable_lines:
( order_account_move_receivable_lines[account_id]
| invoice_receivable_lines.get(account_id, self.env['account.move.line'])
for key in order_account_move_receivable_lines:
( order_account_move_receivable_lines[key]
| invoice_receivable_lines.get(key, self.env['account.move.line'])
).reconcile()
# reconcile stock output lines
@@ -791,10 +797,7 @@ class PosSession(models.Model):
# of the key used for summing taxes. Since the POS UI doesn't support the tags, inconsistencies
# may arise in 'Round Globally'.
check_refund = lambda x: x.qty * x.price_unit < 0
if self.company_id.tax_calculation_rounding_method == 'round_globally':
is_refund = all(check_refund(line) for line in order_line.order_id.lines)
else:
is_refund = check_refund(order_line)
is_refund = check_refund(order_line)
tax_data = tax_ids.compute_all(price_unit=price, quantity=abs(order_line.qty), currency=self.currency_id, is_refund=is_refund)
taxes = tax_data['taxes']
# For Cash based taxes, use the account from the repartition line immediately as it has been paid already
+68 -10
View File
@@ -145,6 +145,10 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
cls.company_data['company'].write({
'point_of_sale_update_stock_quantities': 'real',
'country_id': cls.env['res.country'].create({
'name': 'PoS Land',
'code': 'WOW',
}),
})
# Set basic defaults
@@ -224,6 +228,7 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
'location_id': cls.company_data['default_warehouse'].lot_stock_id.id,
})
#####################
## private methods ##
#####################
@@ -345,11 +350,57 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
tax7: 7%, excluded in product price
tax10: 10%, included in product price
tax21: 21%, included in product price
"""
tax7 = cls.env['account.tax'].create({'name': 'Tax 7%', 'amount': 7})
tax10 = cls.env['account.tax'].create({'name': 'Tax 10%', 'amount': 10, 'price_include': True, 'include_base_amount': False})
(tax7 | tax10).mapped('invoice_repartition_line_ids').write({'account_id': cls.tax_received_account.id})
(tax7 | tax10).mapped('refund_repartition_line_ids').write({'account_id': cls.tax_received_account.id})
def create_tag(name):
return cls.env['account.account.tag'].create({
'name': name,
'applicability': 'taxes',
'country_id': cls.env.company.country_id.id
})
cls.tax_tag_invoice_base = create_tag('Invoice Base tag')
cls.tax_tag_invoice_tax = create_tag('Invoice Tax tag')
cls.tax_tag_refund_base = create_tag('Refund Base tag')
cls.tax_tag_refund_tax = create_tag('Refund Tax tag')
def create_tax(percentage, price_include=False):
return cls.env['account.tax'].create({
'name': f'Tax {percentage}%',
'amount': percentage,
'price_include': price_include,
'include_base_amount': False,
'invoice_repartition_line_ids': [
(0, 0, {
'factor_percent': 100,
'repartition_type': 'base',
'tag_ids': [(6, 0, cls.tax_tag_invoice_base.ids)],
}),
(0, 0, {
'factor_percent': 100,
'repartition_type': 'tax',
'account_id': cls.tax_received_account.id,
'tag_ids': [(6, 0, cls.tax_tag_invoice_tax.ids)],
}),
],
'refund_repartition_line_ids': [
(0, 0, {
'factor_percent': 100,
'repartition_type': 'base',
'tag_ids': [(6, 0, cls.tax_tag_refund_base.ids)],
}),
(0, 0, {
'factor_percent': 100,
'repartition_type': 'tax',
'account_id': cls.tax_received_account.id,
'tag_ids': [(6, 0, cls.tax_tag_refund_tax.ids)],
}),
],
})
tax7 = create_tax(7, price_include=False)
tax10 = create_tax(10, price_include=True)
tax21 = create_tax(21, price_include=True)
tax_group_7_10 = tax7.copy()
with Form(tax_group_7_10) as tax:
@@ -361,6 +412,7 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
return {
'tax7': tax7,
'tax10': tax10,
'tax21': tax21,
'tax_group_7_10': tax_group_7_10
}
@@ -371,7 +423,7 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
def create_random_uid(self):
return ('%05d-%03d-%04d' % (randint(1, 99999), randint(1, 999), randint(1, 9999)))
def create_ui_order_data(self, product_quantity_pairs, customer=False, is_invoiced=False, payments=None, uid=None):
def create_ui_order_data(self, product_quantity_discount_triplet, customer=False, is_invoiced=False, payments=None, uid=None):
""" Mocks the order_data generated by the pos ui.
This is useful in making orders in an open pos session without making tours.
@@ -386,17 +438,19 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
The above values should be set when `self.open_new_session` is called.
:param list(tuple) product_quantity_pairs: pair of `ordered product` and `quantity`
:param list(tuple) product_quantity_discount_triplet: pairs of `ordered product` and `quantity`
or triplet of `ordered product`, `quantity` and discount
:param list(tuple) payments: pair of `payment_method` and `amount`
"""
default_fiscal_position = self.config.default_fiscal_position_id
fiscal_position = customer.property_account_position_id if customer else default_fiscal_position
def create_order_line(product, quantity):
def create_order_line(product, quantity, discount=0.0):
price_unit = self.pricelist.get_product_price(product, quantity, False)
tax_ids = fiscal_position.map_tax(product.taxes_id)
price_unit_after_discount = price_unit * (1 - discount / 100.0)
tax_values = (
tax_ids.compute_all(price_unit, self.currency, quantity)
tax_ids.compute_all(price_unit_after_discount, self.currency, quantity)
if tax_ids
else {
'total_excluded': price_unit * quantity,
@@ -404,7 +458,7 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
}
)
return (0, 0, {
'discount': 0,
'discount': discount,
'id': randint(1, 1000000),
'pack_lot_ids': [],
'price_unit': price_unit,
@@ -425,7 +479,11 @@ class TestPoSCommon(ValuationReconciliationTestCommon):
uid = uid or self.create_random_uid()
# 1. generate the order lines
order_lines = [create_order_line(product, quantity) for product, quantity in product_quantity_pairs]
order_lines = [
create_order_line(product, quantity, discount and discount[0] or 0.0)
for product, quantity, *discount
in product_quantity_discount_triplet
]
# 2. generate the payments
total_amount_incl = sum(line[2]['price_subtotal_incl'] for line in order_lines)
@@ -293,3 +293,183 @@ class TestPoSProductsWithTax(TestPoSCommon):
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined and should be debit.')
def test_pos_create_correct_account_move(self):
""" Test for orders with global rounding disabled
Orders
======
+---------+----------+-----------+----------+------+----------+------------------+--------+
| order | payments | invoiced? | product | qty | untaxed | tax | total |
+---------+----------+-----------+----------+------+----------+------------------+--------+
| order 1 | cash | no | product1 | 1 | 10.0 | 2.10 | 12.10 |
| | | | product2 | -1 | -5.0 | -1.05 | -6.05 |
+---------+----------+-----------+----------+------+----------+------------------+--------+
"""
tax_21_incl = self.taxes['tax21']
product1 = self.create_product(
name='Product 1',
category=self.categ_basic,
lst_price=12.10,
tax_ids=tax_21_incl.ids,
)
product2 = self.create_product(
name='Product 2',
category=self.categ_basic,
lst_price=6.05,
tax_ids=tax_21_incl.ids,
)
self.open_new_session()
self.env['pos.order'].create_from_ui([self.create_ui_order_data([
(product1, 1),
(product2, -1),
])])
self.pos_session.action_pos_session_validate()
lines = self.pos_session.move_id.line_ids.sorted('balance')
self.assertEqual(2, len(lines.filtered(lambda l: l.tax_ids)), "Taxes should have been set on 2 lines")
self.assertEqual(4, len(lines.filtered(lambda l: l.tax_tag_ids)), "Tags should have been set on 4 lines")
self.assertRecordValues(lines, [
{'account_id': self.sale_account.id, 'balance': -10.0, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_invoice_base.ids},
{'account_id': self.tax_received_account.id, 'balance': -2.10, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_invoice_tax.ids},
{'account_id': self.tax_received_account.id, 'balance': 1.05, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_refund_tax.ids},
{'account_id': self.sale_account.id, 'balance': 5.00, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_refund_base.ids},
{'account_id': self.pos_receivable_account.id, 'balance': 6.05, 'tax_ids': [], 'tax_tag_ids': []},
])
def test_pos_create_account_move_round_globally(self):
""" Test for orders with global rounding enabled
Orders
======
+---------+----------+-----------+----------+------+----------+------------------+--------+
| order | payments | invoiced? | product | qty | untaxed | tax | total |
+---------+----------+-----------+----------+------+----------+------------------+--------+
| order 1 | cash | no | product1 | 1 | 10.0 | 2.10 | 12.10 |
| | | | product2 | -1 | -5.0 | -1.05 | -6.05 |
+---------+----------+-----------+----------+------+----------+------------------+--------+
"""
tax_21_incl = self.taxes['tax21']
tax_21_incl.company_id.tax_calculation_rounding_method = 'round_globally'
product1 = self.create_product(
name='Product 1',
category=self.categ_basic,
lst_price=12.10,
tax_ids=tax_21_incl.ids,
)
product2 = self.create_product(
name='Product 2',
category=self.categ_basic,
lst_price=6.05,
tax_ids=tax_21_incl.ids,
)
self.open_new_session()
self.env['pos.order'].create_from_ui([self.create_ui_order_data([
(product1, 1),
(product2, -1),
])])
self.pos_session.action_pos_session_validate()
lines = self.pos_session.move_id.line_ids.sorted('balance')
self.assertEqual(2, len(lines.filtered(lambda l: l.tax_ids)), "Taxes should have been set on 2 lines")
self.assertEqual(4, len(lines.filtered(lambda l: l.tax_tag_ids)), "Tags should have been set on 4 lines")
self.assertRecordValues(lines, [
{'account_id': self.sale_account.id, 'balance': -10.0, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_invoice_base.ids},
{'account_id': self.tax_received_account.id, 'balance': -2.10, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_invoice_tax.ids},
{'account_id': self.tax_received_account.id, 'balance': 1.05, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_refund_tax.ids},
{'account_id': self.sale_account.id, 'balance': 5.00, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_refund_base.ids},
{'account_id': self.pos_receivable_account.id, 'balance': 6.05, 'tax_ids': [], 'tax_tag_ids': []},
])
def test_pos_create_correct_account_move_round_globally_discount(self):
""" Test for orders with global rounding enabled
Orders
======
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
| order | payments | inv? | product | qty | original price unit | Discount | price unit after discount | untaxed | tax | total |
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
| order 1 | cash | no | product1 | 1 | 12.10 | 5% | 10.89 | 9.00 | 1.89 | 10.89 |
| | | | product2 | -1 | 6.05 | 5% | 5.45 | -4.50 | -0.95 | -5.445 |
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
"""
tax_21_incl = self.taxes['tax21']
tax_21_incl.company_id.tax_calculation_rounding_method = 'round_globally'
product1 = self.create_product(
name='Product 1',
category=self.categ_basic,
lst_price=12.10,
tax_ids=tax_21_incl.ids,
)
product2 = self.create_product(
name='Product 2',
category=self.categ_basic,
lst_price=6.05,
tax_ids=tax_21_incl.ids,
)
self.open_new_session()
self.env['pos.order'].create_from_ui([self.create_ui_order_data([
(product1, 1, 10),
(product2, -1, 10),
])])
self.pos_session.action_pos_session_validate()
lines = self.pos_session.move_id.line_ids.sorted('balance')
self.assertEqual(2, len(lines.filtered(lambda l: l.tax_ids)), "Taxes should have been set on 2 lines")
self.assertEqual(4, len(lines.filtered(lambda l: l.tax_tag_ids)), "Tags should have been set on 4 lines")
self.assertRecordValues(lines, [
{'account_id': self.sale_account.id, 'balance': - 9.0, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_invoice_base.ids},
{'account_id': self.tax_received_account.id, 'balance': -1.89, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_invoice_tax.ids},
{'account_id': self.tax_received_account.id, 'balance': 0.95, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_refund_tax.ids},
{'account_id': self.sale_account.id, 'balance': 4.5, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_refund_base.ids},
{'account_id': self.pos_receivable_account.id, 'balance': 5.44, 'tax_ids': [], 'tax_tag_ids': []},
])
def test_pos_create_correct_account_move_round_globally_discount_real_use_case(self):
""" Test for orders with global rounding enabled
Orders
======
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
| order | payments | inv? | product | qty | original price unit | Discount | price unit after discount | untaxed | tax | total |
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
| order 1 | cash | no | product1 | 6 | 11.80 | 5% | 11.21 | 55.59 | 11.67 | 67.26 |
| | | | product2 | -6 | 15.30 | 5% | 14.535 | -72.07 | -15.14 | -87.21 |
+---------+----------+------+----------+------+---------------------+-----------+---------------------------+---------+--------+--------+
"""
tax_21_incl = self.taxes['tax21']
tax_21_incl.company_id.tax_calculation_rounding_method = 'round_globally'
product1 = self.create_product(
name='Product 1',
category=self.categ_basic,
lst_price=11.80,
tax_ids=tax_21_incl.ids,
)
product2 = self.create_product(
name='Product 2',
category=self.categ_basic,
lst_price=15.30,
tax_ids=tax_21_incl.ids,
)
self.open_new_session()
self.env['pos.order'].create_from_ui([self.create_ui_order_data([
(product1, 6, 5),
(product2, -6, 5),
])])
self.pos_session.action_pos_session_validate()
lines = self.pos_session.move_id.line_ids.sorted('balance')
self.assertEqual(2, len(lines.filtered(lambda l: l.tax_ids)), "Taxes should have been set on 2 lines")
self.assertEqual(4, len(lines.filtered(lambda l: l.tax_tag_ids)), "Tags should have been set on 4 lines")
self.assertRecordValues(lines, [
{'account_id': self.sale_account.id, 'balance': -55.59, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_invoice_base.ids},
{'account_id': self.pos_receivable_account.id, 'balance': -19.95, 'tax_ids': [], 'tax_tag_ids': []},
{'account_id': self.tax_received_account.id, 'balance': -11.67, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_invoice_tax.ids},
{'account_id': self.tax_received_account.id, 'balance': 15.14, 'tax_ids': [], 'tax_tag_ids': self.tax_tag_refund_tax.ids},
{'account_id': self.sale_account.id, 'balance': 72.07, 'tax_ids': tax_21_incl.ids, 'tax_tag_ids': self.tax_tag_refund_base.ids},
])