You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
8.8 KiB

  1. # Copyright 2017 LasLabs Inc.
  2. # Copyright 2018 ACSONE SA/NV
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from dateutil.relativedelta import relativedelta
  5. from odoo.tests.common import TransactionCase
  6. from odoo.exceptions import ValidationError
  7. from odoo.fields import Date
  8. class TestSaleOrder(TransactionCase):
  9. def setUp(self):
  10. super(TestSaleOrder, self).setUp()
  11. self.product1 = self.env.ref('product.product_product_1')
  12. self.product2 = self.env.ref('product.product_product_2')
  13. self.sale = self.env.ref('sale.sale_order_2')
  14. self.contract_template1 = self.env['account.analytic.contract'].create(
  15. {'name': 'Template 1'}
  16. )
  17. self.contract_template2 = self.env['account.analytic.contract'].create(
  18. {
  19. 'name': 'Template 2',
  20. 'recurring_invoice_line_ids': [
  21. (
  22. 0,
  23. 0,
  24. {
  25. 'product_id': self.product2.id,
  26. 'name': 'Services from #START# to #END#',
  27. 'quantity': 1,
  28. 'uom_id': self.product2.uom_id.id,
  29. 'price_unit': 100,
  30. 'discount': 50,
  31. 'recurring_rule_type': 'yearly',
  32. 'recurring_interval': 1,
  33. },
  34. )
  35. ],
  36. }
  37. )
  38. self.product1.write(
  39. {
  40. 'is_contract': True,
  41. 'is_auto_renew': True,
  42. 'contract_template_id': self.contract_template1.id,
  43. }
  44. )
  45. self.product2.write(
  46. {
  47. 'is_contract': True,
  48. 'contract_template_id': self.contract_template2.id,
  49. }
  50. )
  51. self.order_line1 = self.sale.order_line.filtered(
  52. lambda l: l.product_id == self.product1
  53. )
  54. self.order_line1.date_start = '2018-01-01'
  55. pricelist = self.sale.partner_id.property_product_pricelist.id
  56. self.contract = self.env["account.analytic.account"].create(
  57. {
  58. "name": "Test Contract 2",
  59. "partner_id": self.sale.partner_id.id,
  60. "pricelist_id": pricelist,
  61. "recurring_invoices": True,
  62. "contract_type": "sale",
  63. "contract_template_id": self.contract_template1.id,
  64. "recurring_invoice_line_ids": [
  65. (
  66. 0,
  67. 0,
  68. {
  69. "product_id": self.product1.id,
  70. "name": "Services from #START# to #END#",
  71. "quantity": 1,
  72. "uom_id": self.product1.uom_id.id,
  73. "price_unit": 100,
  74. "discount": 50,
  75. "recurring_rule_type": "monthly",
  76. "recurring_interval": 1,
  77. "date_start": "2016-02-15",
  78. "recurring_next_date": "2016-02-29",
  79. },
  80. )
  81. ],
  82. }
  83. )
  84. self.contract_line = self.contract.recurring_invoice_line_ids[0]
  85. def test_compute_is_contract(self):
  86. """Sale Order should have is_contract true if one of its lines is
  87. contract"""
  88. self.assertTrue(self.sale.is_contract)
  89. def test_action_confirm_auto_renew_without_date_end(self):
  90. with self.assertRaises(ValidationError):
  91. self.sale.action_confirm()
  92. def test_action_confirm(self):
  93. """ It should create a contract for each contract template used in
  94. order_line """
  95. self.order_line1.onchange_product()
  96. self.sale.action_confirm()
  97. contracts = self.sale.order_line.mapped('contract_id')
  98. self.assertEqual(len(contracts), 2)
  99. self.assertEqual(
  100. self.order_line1.contract_id.contract_template_id,
  101. self.contract_template1,
  102. )
  103. def test_sale_contract_count(self):
  104. """It should count contracts as many different contract template used
  105. in order_line"""
  106. self.order_line1.onchange_product()
  107. self.sale.action_confirm()
  108. self.assertEqual(self.sale.contract_count, 2)
  109. def test_onchange_product(self):
  110. """ It should get recurrence invoicing info to the sale line from
  111. its product """
  112. self.order_line1.onchange_product()
  113. self.assertEqual(
  114. self.order_line1.recurring_rule_type,
  115. self.product1.recurring_rule_type,
  116. )
  117. self.assertEqual(
  118. self.order_line1.recurring_interval,
  119. self.product1.recurring_interval,
  120. )
  121. self.assertEqual(
  122. self.order_line1.recurring_invoicing_type,
  123. self.product1.recurring_invoicing_type,
  124. )
  125. self.assertEqual(self.order_line1.date_end, Date.to_date('2018-12-31'))
  126. def test_check_contract_sale_partner(self):
  127. """Can't link order line to a partner contract different then the
  128. order one"""
  129. contract2 = self.env['account.analytic.account'].create(
  130. {
  131. 'name': 'Contract',
  132. 'contract_template_id': self.contract_template2.id,
  133. 'partner_id': self.sale.partner_id.id,
  134. }
  135. )
  136. with self.assertRaises(ValidationError):
  137. self.order_line1.contract_id = contract2
  138. def test_check_contract_sale_contract_template(self):
  139. """Can't link order line to a contract with different contract
  140. template then the product one"""
  141. contract1 = self.env['account.analytic.account'].create(
  142. {
  143. 'name': 'Contract',
  144. 'contract_template_id': self.contract_template1.id,
  145. }
  146. )
  147. with self.assertRaises(ValidationError):
  148. self.order_line1.contract_id = contract1
  149. def test_no_contract_proudct(self):
  150. """it should create contract for only product contract"""
  151. self.product1.is_contract = False
  152. self.sale.action_confirm()
  153. self.assertFalse(self.order_line1.contract_id)
  154. def test_sale_order_line_invoice_status(self):
  155. """Sale order line for contract product should have nothing to
  156. invoice as status"""
  157. self.order_line1.onchange_product()
  158. self.sale.action_confirm()
  159. self.assertEqual(self.order_line1.invoice_status, 'no')
  160. def test_sale_order_invoice_status(self):
  161. """Sale order with only contract product should have nothing to
  162. invoice status directtly"""
  163. self.sale.order_line.filtered(
  164. lambda line: not line.product_id.is_contract
  165. ).unlink()
  166. self.order_line1.onchange_product()
  167. self.sale.action_confirm()
  168. self.assertEqual(self.sale.invoice_status, 'no')
  169. def test_sale_order_create_invoice(self):
  170. """Should not invoice contract product on sale order create invoice"""
  171. self.product2.is_contract = False
  172. self.product2.invoice_policy = 'order'
  173. self.order_line1.onchange_product()
  174. self.sale.action_confirm()
  175. self.sale.action_invoice_create()
  176. self.assertEqual(len(self.sale.invoice_ids), 1)
  177. invoice_line = self.sale.invoice_ids.invoice_line_ids.filtered(
  178. lambda line: line.product_id.is_contract
  179. )
  180. self.assertEqual(len(invoice_line), 0)
  181. def test_link_contract_invoice_to_sale_order(self):
  182. """It should link contract invoice to sale order"""
  183. self.order_line1.onchange_product()
  184. self.sale.action_confirm()
  185. invoice = self.order_line1.contract_id.recurring_create_invoice()
  186. self.assertTrue(invoice in self.sale.invoice_ids)
  187. def test_contract_upsell(self):
  188. """Should stop contract line at sale order line start date"""
  189. self.order_line1.contract_id = self.contract
  190. self.order_line1.contract_line_id = self.contract_line
  191. self.contract_line.date_end = Date.today() + relativedelta(months=4)
  192. self.contract_line.is_auto_renew = True
  193. self.order_line1.date_start = "2018-06-01"
  194. self.order_line1.onchange_product()
  195. self.sale.action_confirm()
  196. self.assertEqual(
  197. self.contract_line.date_end, Date.to_date("2018-05-31")
  198. )
  199. self.assertFalse(self.contract_line.is_auto_renew)
  200. new_contract_line = self.env['account.analytic.invoice.line'].search(
  201. [('sale_order_line_id', '=', self.order_line1.id)]
  202. )
  203. self.assertEqual(
  204. self.contract_line.successor_contract_line_id, new_contract_line
  205. )
  206. self.assertEqual(
  207. new_contract_line.predecessor_contract_line_id, self.contract_line
  208. )