1# -*- coding: utf-8 -*- 2from odoo.addons.account.tests.common import AccountTestInvoicingCommon 3from odoo.tests import tagged 4 5 6@tagged('post_install', '-at_install') 7class TestTaxCommon(AccountTestInvoicingCommon): 8 9 @classmethod 10 def setUpClass(cls, chart_template_ref=None): 11 super().setUpClass(chart_template_ref=chart_template_ref) 12 13 # Setup another company having a rounding of 1.0. 14 cls.currency_data['currency'].rounding = 1.0 15 cls.currency_no_decimal = cls.currency_data['currency'] 16 cls.company_data_2 = cls.setup_company_data('company_2', currency_id=cls.currency_no_decimal.id) 17 cls.env.user.company_id = cls.company_data['company'] 18 19 cls.fixed_tax = cls.env['account.tax'].create({ 20 'name': "Fixed tax", 21 'amount_type': 'fixed', 22 'amount': 10, 23 'sequence': 1, 24 }) 25 cls.fixed_tax_bis = cls.env['account.tax'].create({ 26 'name': "Fixed tax bis", 27 'amount_type': 'fixed', 28 'amount': 15, 29 'sequence': 2, 30 }) 31 cls.percent_tax = cls.env['account.tax'].create({ 32 'name': "Percent tax", 33 'amount_type': 'percent', 34 'amount': 10, 35 'sequence': 3, 36 }) 37 cls.percent_tax_bis = cls.env['account.tax'].create({ 38 'name': "Percent tax bis", 39 'amount_type': 'percent', 40 'amount': 10, 41 'sequence': 4, 42 }) 43 cls.division_tax = cls.env['account.tax'].create({ 44 'name': "Division tax", 45 'amount_type': 'division', 46 'amount': 10, 47 'sequence': 4, 48 }) 49 cls.group_tax = cls.env['account.tax'].create({ 50 'name': "Group tax", 51 'amount_type': 'group', 52 'amount': 0, 53 'sequence': 5, 54 'children_tax_ids': [ 55 (4, cls.fixed_tax.id, 0), 56 (4, cls.percent_tax.id, 0) 57 ] 58 }) 59 cls.group_tax_bis = cls.env['account.tax'].create({ 60 'name': "Group tax bis", 61 'amount_type': 'group', 62 'amount': 0, 63 'sequence': 6, 64 'children_tax_ids': [ 65 (4, cls.fixed_tax.id, 0), 66 (4, cls.percent_tax.id, 0) 67 ] 68 }) 69 cls.group_tax_percent = cls.env['account.tax'].create({ 70 'name': "Group tax percent", 71 'amount_type': 'group', 72 'amount': 0, 73 'sequence': 6, 74 'children_tax_ids': [ 75 (4, cls.percent_tax.id, 0), 76 (4, cls.percent_tax_bis.id, 0) 77 ] 78 }) 79 cls.group_of_group_tax = cls.env['account.tax'].create({ 80 'name': "Group of group tax", 81 'amount_type': 'group', 82 'amount': 0, 83 'sequence': 7, 84 'children_tax_ids': [ 85 (4, cls.group_tax.id, 0), 86 (4, cls.group_tax_bis.id, 0) 87 ] 88 }) 89 cls.tax_with_no_account = cls.env['account.tax'].create({ 90 'name': "Tax with no account", 91 'amount_type': 'fixed', 92 'amount': 0, 93 'sequence': 8, 94 }) 95 some_account = cls.env['account.account'].search([], limit=1) 96 cls.tax_with_account = cls.env['account.tax'].create({ 97 'name': "Tax with account", 98 'amount_type': 'fixed', 99 'amount': 0, 100 'sequence': 8, 101 'invoice_repartition_line_ids': [ 102 (0,0, { 103 'factor_percent': 100, 104 'repartition_type': 'base', 105 }), 106 107 (0,0, { 108 'factor_percent': 100, 109 'repartition_type': 'tax', 110 'account_id': some_account.id, 111 }), 112 ], 113 'refund_repartition_line_ids': [ 114 (0,0, { 115 'factor_percent': 100, 116 'repartition_type': 'base', 117 }), 118 119 (0,0, { 120 'factor_percent': 100, 121 'repartition_type': 'tax', 122 'account_id': some_account.id, 123 }), 124 ], 125 }) 126 127 cls.tax_0_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 128 'name': "test_0_percent", 129 'amount_type': 'percent', 130 'amount': 0, 131 }) 132 133 cls.tax_5_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 134 'name': "test_5_percent", 135 'amount_type': 'percent', 136 'amount': 5, 137 }) 138 139 cls.tax_8_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 140 'name': "test_8_percent", 141 'amount_type': 'percent', 142 'amount': 8, 143 }) 144 cls.tax_12_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 145 'name': "test_12_percent", 146 'amount_type': 'percent', 147 'amount': 12, 148 }) 149 150 cls.tax_19_percent = cls.env['account.tax'].with_company(cls.company_data_2['company']).create({ 151 'name': "test_19_percent", 152 'amount_type': 'percent', 153 'amount': 19, 154 }) 155 156 cls.tax_21_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 157 'name': "test_21_percent", 158 'amount_type': 'percent', 159 'amount': 19, 160 }) 161 162 cls.tax_21_percent = cls.env['account.tax'].with_company(cls.company_data['company']).create({ 163 'name': "test_rounding_methods_2", 164 'amount_type': 'percent', 165 'amount': 21, 166 }) 167 168 cls.bank_journal = cls.company_data['default_journal_bank'] 169 cls.bank_account = cls.bank_journal.default_account_id 170 cls.expense_account = cls.company_data['default_account_expense'] 171 172 def _check_compute_all_results(self, total_included, total_excluded, taxes, res): 173 self.assertAlmostEqual(res['total_included'], total_included) 174 self.assertAlmostEqual(res['total_excluded'], total_excluded) 175 for i in range(0, len(taxes)): 176 self.assertAlmostEqual(res['taxes'][i]['base'], taxes[i][0]) 177 self.assertAlmostEqual(res['taxes'][i]['amount'], taxes[i][1]) 178 179 180@tagged('post_install', '-at_install') 181class TestTax(TestTaxCommon): 182 183 @classmethod 184 def setUpClass(cls): 185 super(TestTax, cls).setUpClass() 186 187 def test_tax_group_of_group_tax(self): 188 self.fixed_tax.include_base_amount = True 189 res = self.group_of_group_tax.compute_all(200.0) 190 self._check_compute_all_results( 191 263, # 'total_included' 192 200, # 'total_excluded' 193 [ 194 # base , amount | seq | amount | incl | incl_base 195 # --------------------------------------------------- 196 (200.0, 10.0), # | 1 | 10 | | t 197 (210.0, 21.0), # | 3 | 10% | | 198 (210.0, 10.0), # | 1 | 10 | | t 199 (220.0, 22.0), # | 3 | 10% | | 200 # --------------------------------------------------- 201 ], 202 res 203 ) 204 205 def test_tax_group(self): 206 res = self.group_tax.compute_all(200.0) 207 self._check_compute_all_results( 208 230, # 'total_included' 209 200, # 'total_excluded' 210 [ 211 # base , amount | seq | amount | incl | incl_base 212 # --------------------------------------------------- 213 (200.0, 10.0), # | 1 | 10 | | 214 (200.0, 20.0), # | 3 | 10% | | 215 # --------------------------------------------------- 216 ], 217 res 218 ) 219 220 def test_tax_group_percent(self): 221 res = self.group_tax_percent.with_context({'force_price_include':True}).compute_all(100.0) 222 self._check_compute_all_results( 223 100, # 'total_included' 224 83.33, # 'total_excluded' 225 [ 226 # base , amount | seq | amount | incl | incl_base 227 # --------------------------------------------------- 228 (83.33, 8.33), # | 1 | 10% | | 229 (83.33, 8.34), # | 2 | 10% | | 230 # --------------------------------------------------- 231 ], 232 res 233 ) 234 235 def test_tax_percent_division(self): 236 self.division_tax.price_include = True 237 self.division_tax.include_base_amount = True 238 res_division = self.division_tax.compute_all(200.0) 239 self._check_compute_all_results( 240 200, # 'total_included' 241 180, # 'total_excluded' 242 [ 243 # base , amount | seq | amount | incl | incl_base 244 # --------------------------------------------------- 245 (180.0, 20.0), # | 4 | 10/ | t | t 246 # --------------------------------------------------- 247 ], 248 res_division 249 ) 250 self.percent_tax.price_include = False 251 self.percent_tax.include_base_amount = False 252 res_percent = self.percent_tax.compute_all(100.0) 253 self._check_compute_all_results( 254 110, # 'total_included' 255 100, # 'total_excluded' 256 [ 257 # base , amount | seq | amount | incl | incl_base 258 # --------------------------------------------------- 259 (100.0, 10.0), # | 3 | 10% | | 260 # --------------------------------------------------- 261 ], 262 res_percent 263 ) 264 self.division_tax.price_include = False 265 self.division_tax.include_base_amount = False 266 res_division = self.division_tax.compute_all(180.0) 267 self._check_compute_all_results( 268 200, # 'total_included' 269 180, # 'total_excluded' 270 [ 271 # base, amount | seq | amount | incl | incl_base 272 # --------------------------------------------------- 273 (180.0, 20.0), # | 4 | 10/ | | 274 # --------------------------------------------------- 275 ], 276 res_division 277 ) 278 self.percent_tax.price_include = True 279 self.percent_tax.include_base_amount = True 280 res_percent = self.percent_tax.compute_all(110.0) 281 self._check_compute_all_results( 282 110, # 'total_included' 283 100, # 'total_excluded' 284 [ 285 # base, amount | seq | amount | incl | incl_base 286 # --------------------------------------------------- 287 (100.0, 10.0), # | 3 | 10% | t | t 288 # --------------------------------------------------- 289 ], 290 res_percent 291 ) 292 self.percent_tax_bis.price_include = True 293 self.percent_tax_bis.include_base_amount = True 294 self.percent_tax_bis.amount = 21 295 res_percent = self.percent_tax_bis.compute_all(7.0) 296 self._check_compute_all_results( 297 7.0, # 'total_included' 298 5.79, # 'total_excluded' 299 [ 300 # base , amount | seq | amount | incl | incl_base 301 # --------------------------------------------------- 302 (5.79, 1.21), # | 3 | 21% | t | t 303 # --------------------------------------------------- 304 ], 305 res_percent 306 ) 307 308 def test_tax_sequence_normalized_set(self): 309 self.division_tax.sequence = 1 310 self.fixed_tax.sequence = 2 311 self.percent_tax.sequence = 3 312 taxes_set = (self.group_tax | self.division_tax) 313 res = taxes_set.compute_all(200.0) 314 self._check_compute_all_results( 315 252.22, # 'total_included' 316 200, # 'total_excluded' 317 [ 318 # base , amount | seq | amount | incl | incl_base 319 # --------------------------------------------------- 320 (200.0, 22.22), # | 1 | 10/ | | 321 (200.0, 10.0), # | 2 | 10 | | 322 (200.0, 20.0), # | 3 | 10% | | 323 # --------------------------------------------------- 324 ], 325 res 326 ) 327 328 def test_fixed_tax_include_base_amount(self): 329 self.fixed_tax.include_base_amount = True 330 res = self.group_tax.compute_all(200.0) 331 self._check_compute_all_results( 332 231, # 'total_included' 333 200, # 'total_excluded' 334 [ 335 # base , amount | seq | amount | incl | incl_base 336 # --------------------------------------------------- 337 (200.0, 10.0), # | 1 | 10 | | t 338 (210.0, 21.0), # | 3 | 10% | | 339 # --------------------------------------------------- 340 ], 341 res 342 ) 343 344 self.fixed_tax.price_include = True 345 self.fixed_tax.include_base_amount = False 346 res = self.fixed_tax.compute_all(100.0, quantity=2.0) 347 self._check_compute_all_results( 348 200, # 'total_included' 349 180, # 'total_excluded' 350 [ 351 # base , amount | seq | amount | incl | incl_base 352 # --------------------------------------------------- 353 (180.0, 20.0), # | 1 | 20 | | t 354 # --------------------------------------------------- 355 ], 356 res 357 ) 358 359 def test_percent_tax_include_base_amount(self): 360 self.percent_tax.price_include = True 361 self.percent_tax.amount = 21.0 362 res = self.percent_tax.compute_all(7.0) 363 self._check_compute_all_results( 364 7.0, # 'total_included' 365 5.79, # 'total_excluded' 366 [ 367 # base , amount | seq | amount | incl | incl_base 368 # --------------------------------------------------- 369 (5.79, 1.21), # | 3 | 21% | t | 370 # --------------------------------------------------- 371 ], 372 res 373 ) 374 375 self.percent_tax.price_include = True 376 self.percent_tax.amount = 20.0 377 res = self.percent_tax.compute_all(399.99) 378 self._check_compute_all_results( 379 399.99, # 'total_included' 380 333.33, # 'total_excluded' 381 [ 382 # base , amount | seq | amount | incl | incl_base 383 # --------------------------------------------------- 384 (333.33, 66.66), # | 3 | 20% | t | 385 # --------------------------------------------------- 386 ], 387 res 388 ) 389 390 def test_tax_decimals(self): 391 """Test the rounding of taxes up to 6 decimals (maximum decimals places allowed for currencies)""" 392 self.env.user.company_id.currency_id.rounding = 0.000001 393 394 self.percent_tax.price_include = True 395 self.percent_tax.amount = 21.0 396 res = self.percent_tax.compute_all(7.0) 397 self._check_compute_all_results( 398 7.0, # 'total_included' 399 5.785124, # 'total_excluded' 400 [ 401 # base , amount | seq | amount | incl | incl_base 402 # -------------------------------------------------------- 403 (5.785124, 1.214876), # | 3 | 21% | t | 404 # -------------------------------------------------------- 405 ], 406 res 407 ) 408 409 self.percent_tax.price_include = True 410 self.percent_tax.amount = 20.0 411 res = self.percent_tax.compute_all(399.999999) 412 self._check_compute_all_results( 413 399.999999, # 'total_included' 414 333.333333, # 'total_excluded' 415 [ 416 # base , amount | seq | amount | incl | incl_base 417 # ----------------------------------------------------------- 418 (333.333333, 66.666666), # | 3 | 20% | t | 419 # ----------------------------------------------------------- 420 ], 421 res 422 ) 423 424 def test_advanced_taxes_computation_0(self): 425 '''Test more advanced taxes computation (see issue 34471).''' 426 tax_1 = self.env['account.tax'].create({ 427 'name': 'test_advanced_taxes_computation_0_1', 428 'amount_type': 'percent', 429 'amount': 10, 430 'price_include': True, 431 'include_base_amount': True, 432 'sequence': 1, 433 'invoice_repartition_line_ids': [ 434 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 435 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 436 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 437 ], 438 'refund_repartition_line_ids': [ 439 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 440 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 441 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 442 ], 443 }) 444 tax_2 = self.env['account.tax'].create({ 445 'name': 'test_advanced_taxes_computation_0_2', 446 'amount_type': 'percent', 447 'amount': 10, 448 'sequence': 2, 449 'invoice_repartition_line_ids': [ 450 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 451 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 452 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 453 ], 454 'refund_repartition_line_ids': [ 455 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 456 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 457 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 458 ], 459 }) 460 tax_3 = self.env['account.tax'].create({ 461 'name': 'test_advanced_taxes_computation_0_3', 462 'amount_type': 'percent', 463 'amount': 10, 464 'price_include': True, 465 'sequence': 3, 466 'invoice_repartition_line_ids': [ 467 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 468 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 469 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 470 ], 471 'refund_repartition_line_ids': [ 472 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 473 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 474 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 475 ], 476 }) 477 tax_4 = self.env['account.tax'].create({ 478 'name': 'test_advanced_taxes_computation_0_4', 479 'amount_type': 'percent', 480 'amount': 10, 481 'sequence': 4, 482 'invoice_repartition_line_ids': [ 483 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 484 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 485 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 486 ], 487 'refund_repartition_line_ids': [ 488 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 489 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 490 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 491 ], 492 }) 493 tax_5 = self.env['account.tax'].create({ 494 'name': 'test_advanced_taxes_computation_0_5', 495 'amount_type': 'percent', 496 'amount': 10, 497 'price_include': True, 498 'sequence': 5, 499 'invoice_repartition_line_ids': [ 500 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 501 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 502 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 503 ], 504 'refund_repartition_line_ids': [ 505 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 506 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 507 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 508 ], 509 }) 510 taxes = tax_1 + tax_2 + tax_3 + tax_4 + tax_5 511 512 # Test with positive amount. 513 self._check_compute_all_results( 514 154, # 'total_included' 515 100, # 'total_excluded' 516 [ 517 # base , amount | seq | amount | incl | incl_base 518 # --------------------------------------------------- 519 (100.0, 5.0), # | 1 | 10% | t | t 520 (100.0, 5.0), # | 1 | 10% | t | t 521 (110.0, 5.5), # | 2 | 10% | | 522 (110.0, 5.5), # | 2 | 10% | | 523 (110.0, 5.5), # | 3 | 10% | t | 524 (110.0, 5.5), # | 3 | 10% | t | 525 (110.0, 5.5), # | 4 | 10% | | 526 (110.0, 5.5), # | 4 | 10% | | 527 (110.0, 5.5), # | 5 | 10% | t | 528 (110.0, 5.5), # | 5 | 10% | t | 529 # --------------------------------------------------- 530 ], 531 taxes.compute_all(132.0) 532 ) 533 534 # Test with negative amount. 535 self._check_compute_all_results( 536 -154, # 'total_included' 537 -100, # 'total_excluded' 538 [ 539 # base , amount | seq | amount | incl | incl_base 540 # --------------------------------------------------- 541 (-100.0, -5.0), # | 1 | 10% | t | t 542 (-100.0, -5.0), # | 1 | 10% | t | t 543 (-110.0, -5.5), # | 2 | 10% | | 544 (-110.0, -5.5), # | 2 | 10% | | 545 (-110.0, -5.5), # | 3 | 10% | t | 546 (-110.0, -5.5), # | 3 | 10% | t | 547 (-110.0, -5.5), # | 4 | 10% | | 548 (-110.0, -5.5), # | 4 | 10% | | 549 (-110.0, -5.5), # | 5 | 10% | t | 550 (-110.0, -5.5), # | 5 | 10% | t | 551 # --------------------------------------------------- 552 ], 553 taxes.compute_all(-132.0) 554 ) 555 556 def test_intracomm_taxes_computation_0(self): 557 ''' Test usage of intracomm taxes having e.g.+100%, -100% as repartition lines. ''' 558 intracomm_tax = self.env['account.tax'].create({ 559 'name': 'test_intracomm_taxes_computation_0_1', 560 'amount_type': 'percent', 561 'amount': 21, 562 'invoice_repartition_line_ids': [ 563 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 564 (0, 0, {'repartition_type': 'tax', 'factor_percent': 100.0}), 565 (0, 0, {'repartition_type': 'tax', 'factor_percent': -100.0}), 566 ], 567 'refund_repartition_line_ids': [ 568 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 569 (0, 0, {'repartition_type': 'tax', 'factor_percent': 100.0}), 570 (0, 0, {'repartition_type': 'tax', 'factor_percent': -100.0}), 571 ], 572 }) 573 574 # Test with positive amount. 575 self._check_compute_all_results( 576 100, # 'total_included' 577 100, # 'total_excluded' 578 [ 579 # base , amount 580 # --------------- 581 (100.0, 21.0), 582 (100.0, -21.0), 583 # --------------- 584 ], 585 intracomm_tax.compute_all(100.0) 586 ) 587 588 # Test with negative amount. 589 self._check_compute_all_results( 590 -100, # 'total_included' 591 -100, # 'total_excluded' 592 [ 593 # base , amount 594 # --------------- 595 (-100.0, -21.0), 596 (-100.0, 21.0), 597 # --------------- 598 ], 599 intracomm_tax.compute_all(-100.0) 600 ) 601 602 def test_rounding_issues_0(self): 603 ''' Test taxes having a complex setup of repartition lines. ''' 604 tax = self.env['account.tax'].create({ 605 'name': 'test_rounding_issues_0', 606 'amount_type': 'percent', 607 'amount': 3, 608 'invoice_repartition_line_ids': [ 609 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 610 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 611 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 612 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 613 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 614 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 615 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 616 ], 617 'refund_repartition_line_ids': [ 618 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 619 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 620 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 621 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 622 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 623 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 624 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 625 ], 626 }) 627 628 # Test with positive amount. 629 self._check_compute_all_results( 630 1.09, # 'total_included' 631 1, # 'total_excluded' 632 [ 633 # base , amount 634 # --------------- 635 (1.0, 0.01), 636 (1.0, 0.01), 637 (1.0, 0.01), 638 (1.0, 0.02), 639 (1.0, 0.02), 640 (1.0, 0.02), 641 # --------------- 642 ], 643 tax.compute_all(1.0) 644 ) 645 646 # Test with negative amount. 647 self._check_compute_all_results( 648 -1.09, # 'total_included' 649 -1, # 'total_excluded' 650 [ 651 # base , amount 652 # --------------- 653 (-1.0, -0.01), 654 (-1.0, -0.01), 655 (-1.0, -0.01), 656 (-1.0, -0.02), 657 (-1.0, -0.02), 658 (-1.0, -0.02), 659 # --------------- 660 ], 661 tax.compute_all(-1.0) 662 ) 663 664 def test_rounding_issues_1(self): 665 ''' Test taxes having a complex setup of repartition lines. ''' 666 tax = self.env['account.tax'].create({ 667 'name': 'test_advanced_taxes_repartition_lines_computation_1', 668 'amount_type': 'percent', 669 'amount': 3, 670 'invoice_repartition_line_ids': [ 671 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 672 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 673 (0, 0, {'repartition_type': 'tax', 'factor_percent': -50.0}), 674 (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}), 675 (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}), 676 (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}), 677 (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}), 678 ], 679 'refund_repartition_line_ids': [ 680 (0, 0, {'repartition_type': 'base', 'factor_percent': 100.0}), 681 (0, 0, {'repartition_type': 'tax', 'factor_percent': 50.0}), 682 (0, 0, {'repartition_type': 'tax', 'factor_percent': -50.0}), 683 (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}), 684 (0, 0, {'repartition_type': 'tax', 'factor_percent': 25.0}), 685 (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}), 686 (0, 0, {'repartition_type': 'tax', 'factor_percent': -25.0}), 687 ], 688 }) 689 690 # Test with positive amount. 691 self._check_compute_all_results( 692 1, # 'total_included' 693 1, # 'total_excluded' 694 [ 695 # base , amount 696 # --------------- 697 (1.0, 0.02), 698 (1.0, -0.02), 699 (1.0, 0.01), 700 (1.0, 0.01), 701 (1.0, -0.01), 702 (1.0, -0.01), 703 # --------------- 704 ], 705 tax.compute_all(1.0) 706 ) 707 708 # Test with negative amount. 709 self._check_compute_all_results( 710 -1, # 'total_included' 711 -1, # 'total_excluded' 712 [ 713 # base , amount 714 # --------------- 715 (-1.0, -0.02), 716 (-1.0, 0.02), 717 (-1.0, -0.01), 718 (-1.0, -0.01), 719 (-1.0, 0.01), 720 (-1.0, 0.01), 721 # --------------- 722 ], 723 tax.compute_all(-1.0) 724 ) 725 726 def test_rounding_tax_excluded_round_per_line_01(self): 727 ''' Test the rounding of a 19% price excluded tax in an invoice having 22689 and 9176 as lines. 728 The decimal precision is set to zero. 729 The computation must be similar to round(22689 * 0.19) + round(9176 * 0.19). 730 ''' 731 self.tax_19_percent.company_id.currency_id.rounding = 1.0 732 self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_per_line' 733 734 res1 = self.tax_19_percent.compute_all(22689) 735 self._check_compute_all_results( 736 27000, # 'total_included' 737 22689, # 'total_excluded' 738 [ 739 # base, amount 740 # --------------- 741 (22689, 4311), 742 # --------------- 743 ], 744 res1 745 ) 746 747 res2 = self.tax_19_percent.compute_all(9176) 748 self._check_compute_all_results( 749 10919, # 'total_included' 750 9176, # 'total_excluded' 751 [ 752 # base , amount 753 # --------------- 754 (9176, 1743), 755 # --------------- 756 ], 757 res2 758 ) 759 760 def test_rounding_tax_excluded_round_globally(self): 761 ''' Test the rounding of a 19% price excluded tax in an invoice having 22689 and 9176 as lines. 762 The decimal precision is set to zero. 763 The computation must be similar to round((22689 + 9176) * 0.19). 764 ''' 765 self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_globally' 766 767 res1 = self.tax_19_percent.compute_all(22689) 768 self._check_compute_all_results( 769 27000, # 'total_included' 770 22689, # 'total_excluded' 771 [ 772 # base, amount 773 # --------------- 774 (22689, 4310.91), 775 # --------------- 776 ], 777 res1 778 ) 779 780 res2 = self.tax_19_percent.compute_all(9176) 781 self._check_compute_all_results( 782 10919, # 'total_included' 783 9176, # 'total_excluded' 784 [ 785 # base , amount 786 # --------------- 787 (9176, 1743.44), 788 # --------------- 789 ], 790 res2 791 ) 792 793 def test_rounding_tax_included_round_per_line_01(self): 794 ''' Test the rounding of a 19% price included tax in an invoice having 27000 and 10920 as lines. 795 The decimal precision is set to zero. 796 The computation must be similar to round(27000 / 1.19) + round(10920 / 1.19). 797 ''' 798 self.tax_19_percent.price_include = True 799 self.tax_19_percent.company_id.currency_id.rounding = 1.0 800 self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_per_line' 801 802 res1 = self.tax_19_percent.compute_all(27000) 803 self._check_compute_all_results( 804 27000, # 'total_included' 805 22689, # 'total_excluded' 806 [ 807 # base , amount 808 # --------------- 809 (22689, 4311), 810 # --------------- 811 ], 812 res1 813 ) 814 815 res2 = self.tax_19_percent.compute_all(10920) 816 self._check_compute_all_results( 817 10920, # 'total_included' 818 9176, # 'total_excluded' 819 [ 820 # base , amount 821 # --------------- 822 (9176, 1744), 823 # --------------- 824 ], 825 res2 826 ) 827 828 def test_rounding_tax_included_round_per_line_02(self): 829 ''' Test the rounding of a 12% price included tax in an invoice having 52.50 as line. 830 The decimal precision is set to 2. 831 ''' 832 self.tax_12_percent.price_include = True 833 self.tax_12_percent.company_id.currency_id.rounding = 0.01 834 835 res1 = self.tax_12_percent.compute_all(52.50) 836 self._check_compute_all_results( 837 52.50, # 'total_included' 838 46.88, # 'total_excluded' 839 [ 840 # base , amount 841 # ------------- 842 (46.88, 5.62), 843 # ------------- 844 ], 845 res1 846 ) 847 848 def test_rounding_tax_included_round_per_line_03(self): 849 ''' Test the rounding of a 8% and 0% price included tax in an invoice having 8 * 15.55 as line. 850 The decimal precision is set to 2. 851 ''' 852 self.tax_0_percent.company_id.currency_id.rounding = 0.01 853 self.tax_0_percent.price_include = True 854 self.tax_8_percent.price_include = True 855 856 self.group_tax.children_tax_ids = [(6, 0, self.tax_0_percent.ids)] 857 self.group_tax_bis.children_tax_ids = [(6, 0, self.tax_8_percent.ids)] 858 859 res1 = (self.tax_8_percent | self.tax_0_percent).compute_all(15.55, quantity=8.0) 860 self._check_compute_all_results( 861 124.40, # 'total_included' 862 115.19, # 'total_excluded' 863 [ 864 # base , amount 865 # ------------- 866 (115.19, 9.21), 867 (115.19, 0.00), 868 # ------------- 869 ], 870 res1 871 ) 872 873 res2 = (self.tax_0_percent | self.tax_8_percent).compute_all(15.55, quantity=8.0) 874 self._check_compute_all_results( 875 124.40, # 'total_included' 876 115.19, # 'total_excluded' 877 [ 878 # base , amount 879 # ------------- 880 (115.19, 0.00), 881 (115.19, 9.21), 882 # ------------- 883 ], 884 res2 885 ) 886 887 def test_rounding_tax_included_round_per_line_04(self): 888 ''' Test the rounding of a 5% price included tax. 889 The decimal precision is set to 0.05. 890 ''' 891 self.tax_5_percent.price_include = True 892 self.tax_5_percent.company_id.currency_id.rounding = 0.05 893 self.tax_5_percent.company_id.tax_calculation_rounding_method = 'round_per_line' 894 895 res1 = self.tax_5_percent.compute_all(5) 896 self._check_compute_all_results( 897 5, # 'total_included' 898 4.75, # 'total_excluded' 899 [ 900 # base , amount 901 # --------------- 902 (4.75, 0.25), 903 # --------------- 904 ], 905 res1 906 ) 907 908 res2 = self.tax_5_percent.compute_all(10) 909 self._check_compute_all_results( 910 10, # 'total_included' 911 9.5, # 'total_excluded' 912 [ 913 # base , amount 914 # --------------- 915 (9.5, 0.5), 916 # --------------- 917 ], 918 res2 919 ) 920 921 res3 = self.tax_5_percent.compute_all(50) 922 self._check_compute_all_results( 923 50, # 'total_included' 924 47.6, # 'total_excluded' 925 [ 926 # base , amount 927 # --------------- 928 (47.6, 2.4), 929 # --------------- 930 ], 931 res3 932 ) 933 934 def test_rounding_tax_included_round_globally_01(self): 935 ''' Test the rounding of a 19% price included tax in an invoice having 27000 and 10920 as lines. 936 The decimal precision is set to zero. 937 The computation must be similar to round((27000 + 10920) / 1.19). 938 ''' 939 self.tax_19_percent.price_include = True 940 self.tax_19_percent.company_id.tax_calculation_rounding_method = 'round_globally' 941 942 res1 = self.tax_19_percent.compute_all(27000) 943 self._check_compute_all_results( 944 27000, # 'total_included' 945 22689, # 'total_excluded' 946 [ 947 # base , amount 948 # --------------- 949 (22689, 4311), 950 # --------------- 951 ], 952 res1 953 ) 954 955 res2 = self.tax_19_percent.compute_all(10920) 956 self._check_compute_all_results( 957 10920, # 'total_included' 958 9176, # 'total_excluded' 959 [ 960 # base , amount 961 # --------------- 962 (9176, 1744), 963 # --------------- 964 ], 965 res2 966 ) 967 968 def test_rounding_tax_included_round_globally_02(self): 969 ''' Test the rounding of a 21% price included tax in an invoice having 11.90 and 2.80 as lines. 970 The decimal precision is set to 2. 971 ''' 972 self.tax_21_percent.price_include = True 973 self.tax_21_percent.company_id.currency_id.rounding = 0.01 974 self.tax_21_percent.company_id.tax_calculation_rounding_method = 'round_globally' 975 976 res1 = self.tax_21_percent.compute_all(11.90) 977 self._check_compute_all_results( 978 11.90, # 'total_included' 979 9.83, # 'total_excluded' 980 [ 981 # base , amount 982 # --------------- 983 (9.83, 2.07), 984 # --------------- 985 ], 986 res1 987 ) 988 989 res2 = self.tax_21_percent.compute_all(2.80) 990 self._check_compute_all_results( 991 2.80, # 'total_included' 992 2.31, # 'total_excluded' 993 [ 994 # base , amount 995 # --------------- 996 (2.31, 0.49), 997 # --------------- 998 ], 999 res2 1000 ) 1001 1002 def test_rounding_tax_included_round_globally_03(self): 1003 ''' Test the rounding of a 5% price included tax. 1004 The decimal precision is set to 0.05. 1005 ''' 1006 self.tax_5_percent.price_include = True 1007 self.tax_5_percent.company_id.currency_id.rounding = 0.05 1008 self.tax_5_percent.company_id.tax_calculation_rounding_method = 'round_globally' 1009 1010 res1 = self.tax_5_percent.compute_all(5) 1011 self._check_compute_all_results( 1012 5, # 'total_included' 1013 4.75, # 'total_excluded' 1014 [ 1015 # base , amount 1016 # --------------- 1017 (4.75, 0.25), 1018 # --------------- 1019 ], 1020 res1 1021 ) 1022 1023 res2 = self.tax_5_percent.compute_all(10) 1024 self._check_compute_all_results( 1025 10, # 'total_included' 1026 9.5, # 'total_excluded' 1027 [ 1028 # base , amount 1029 # --------------- 1030 (9.50, 0.50), 1031 # --------------- 1032 ], 1033 res2 1034 ) 1035 1036 res3 = self.tax_5_percent.compute_all(50) 1037 self._check_compute_all_results( 1038 50, # 'total_included' 1039 47.6, # 'total_excluded' 1040 [ 1041 # base , amount 1042 # --------------- 1043 (47.60, 2.40), 1044 # --------------- 1045 ], 1046 res3 1047 ) 1048 1049 def test_mixing_price_included_excluded_with_affect_base(self): 1050 tax_10_fix = self.env['account.tax'].create({ 1051 'name': "tax_10_fix", 1052 'amount_type': 'fixed', 1053 'amount': 10.0, 1054 'include_base_amount': True, 1055 }) 1056 tax_21 = self.env['account.tax'].create({ 1057 'name': "tax_21", 1058 'amount_type': 'percent', 1059 'amount': 21.0, 1060 'price_include': True, 1061 'include_base_amount': True, 1062 }) 1063 1064 self._check_compute_all_results( 1065 1222.1, # 'total_included' 1066 1000.0, # 'total_excluded' 1067 [ 1068 # base , amount 1069 # --------------- 1070 (1000.0, 10.0), 1071 (1010.0, 212.1), 1072 # --------------- 1073 ], 1074 (tax_10_fix + tax_21).compute_all(1210), 1075 ) 1076