GoodERP
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

139 lines
7.0KB

  1. """2026-10-05:13 → 18 指定修复的回归用例,使用独立事务。"""
  2. from odoo.tests import tagged
  3. from odoo.tests.common import TransactionCase
  4. @tagged('post_install', '-at_install', 'port_13_18')
  5. class TestPortWarehouse(TransactionCase):
  6. def _line(self, **values):
  7. vals = {'type': 'out', 'goods_id': self.env.ref('goods.mouse').id, 'goods_qty': 10,
  8. 'price': 100, 'price_taxed': 113, 'tax_rate': 13,
  9. 'discount_amount': 100, 'discount_rate': 0}
  10. vals.update(values)
  11. return self.env['wh.move.line'].new(vals)
  12. def test_unsaved_manual_discount_survives(self):
  13. line = self._line(goods_qty=4, discount_amount=40)
  14. line.onchange_discount_rate()
  15. self.assertEqual(line.discount_amount, 40)
  16. self.assertAlmostEqual(line.subtotal, 412)
  17. def test_saved_manual_discount_quantity_zero_and_return(self):
  18. self.env.ref('goods.mouse').force_batch_one = False
  19. original = self._line()
  20. origin = self.env['wh.move.line'].create(original._convert_to_write(original._cache))
  21. for qty in (4, 0, -2):
  22. line = self.env['wh.move.line'].new({
  23. 'goods_qty': qty, 'price': 100, 'price_taxed': 113,
  24. 'goods_id': origin.goods_id.id, 'tax_rate': 13,
  25. 'discount_rate': 0, 'discount_amount': 100,
  26. }, origin=origin)
  27. line.onchange_discount_rate()
  28. self.assertAlmostEqual(line.discount_amount, 10 * qty)
  29. def test_rate_discount(self):
  30. line = self._line(goods_qty=4, discount_rate=10)
  31. line.onchange_discount_rate()
  32. self.assertEqual(line.discount_amount, 40)
  33. def test_clear_rate_cancels_discount(self):
  34. line = self._line(discount_rate=0)
  35. # 执行实际注册的 rate onchange,而不是调用待新增方法。
  36. for method in line._onchange_methods['discount_rate']:
  37. method(line)
  38. self.assertEqual(line.discount_amount, 0)
  39. def _stock(self):
  40. stock = self.env.ref('warehouse.hd_stock')
  41. supplier = self.env.ref('warehouse.warehouse_supplier')
  42. move = self.env['wh.move'].create({'origin': 'wh.in.others',
  43. 'warehouse_id': supplier.id, 'warehouse_dest_id': stock.id})
  44. goods_ids = []
  45. for mark in (True, False, None):
  46. goods = self.env.ref('goods.mouse').copy({'name': 'PORT库存%s' % mark, 'code': 'PORT%s' % mark,
  47. 'no_stock': bool(mark), 'force_batch_one': False})
  48. self.env['wh.move.line'].create({'move_id': move.id, 'type': 'in',
  49. 'goods_id': goods.id, 'goods_qty': 5, 'price': 10, 'cost_unit': 10,
  50. 'state': 'done', 'date': '2026-10-01'})
  51. goods_ids.append(goods.id)
  52. self.env.flush_all()
  53. self.env.cr.execute('UPDATE goods SET no_stock = NULL WHERE id = %s', [goods_ids[2]])
  54. self.env['goods'].invalidate_model(['no_stock'])
  55. return stock, goods_ids
  56. def test_inventory_true_false_null(self):
  57. stock, ids = self._stock()
  58. inv = self.env['wh.inventory'].create({'warehouse_id': stock.id, 'goods': [(6, 0, ids)]})
  59. rows = inv.get_line_detail()
  60. self.assertEqual({row['goods_id'] for row in rows}, set(ids[1:]))
  61. self.assertEqual(sum(row['qty'] for row in rows), 10)
  62. def test_ageing_true_false_null(self):
  63. stock, ids = self._stock()
  64. wizard = self.env['non.active.report.wizard'].create({'warehouse_id': stock.id,
  65. 'first_stage_day': 30, 'second_stage_day': 60, 'third_stage_day': 90})
  66. action = wizard.open_non_active_report()
  67. records = self.env['non.active.report'].search(action['domain']).filtered(lambda r: r.goods_id.id in ids)
  68. self.assertEqual(set(records.goods_id.ids), set(ids[1:]))
  69. self.assertEqual(sum(records.mapped('subtotal')), 10)
  70. def test_new_manual_discount_on_previously_undiscounted_line(self):
  71. self.env.ref('goods.mouse').force_batch_one = False
  72. line = self._line(discount_amount=0)
  73. origin = self.env['wh.move.line'].create(line._convert_to_write(line._cache))
  74. edited = self.env['wh.move.line'].new({'goods_id': origin.goods_id.id,
  75. 'goods_qty': 4, 'price_taxed': 113, 'tax_rate': 13, 'discount_amount': 40}, origin=origin)
  76. edited.onchange_discount_rate()
  77. self.assertEqual(edited.discount_amount, 40)
  78. def test_cleared_rate_does_not_return_on_quantity_change(self):
  79. self.env.ref('goods.mouse').force_batch_one = False
  80. line = self._line(discount_rate=10)
  81. origin = self.env['wh.move.line'].create(line._convert_to_write(line._cache))
  82. edited = self.env['wh.move.line'].new({'goods_id': origin.goods_id.id,
  83. 'goods_qty': 4, 'price_taxed': 113, 'tax_rate': 13,
  84. 'discount_rate': 0, 'discount_amount': 0}, origin=origin)
  85. edited.onchange_discount_rate()
  86. self.assertEqual(edited.discount_amount, 0)
  87. def test_form_onchange_sequence(self):
  88. from odoo.tests import Form
  89. self.env.ref('goods.mouse').force_batch_one = False
  90. view = self.env['ir.ui.view'].create({'name': 'port.discount.form', 'model': 'wh.move.line',
  91. 'arch': '''<form><field name="type"/><field name="goods_id"/>
  92. <field name="goods_qty"/><field name="price"/><field name="price_taxed"/>
  93. <field name="tax_rate"/><field name="discount_rate"/><field name="discount_amount"/>
  94. <field name="subtotal"/><field name="amount"/><field name="tax_amount"/></form>'''})
  95. line = self._line()
  96. original = self.env['wh.move.line'].create(line._convert_to_write(line._cache))
  97. form = Form(original, view=view)
  98. form.goods_qty = 4
  99. self.assertEqual(form.discount_amount, 40)
  100. self.assertAlmostEqual(form.subtotal, 412)
  101. form.discount_rate = 5
  102. self.assertEqual(form.discount_amount, 20)
  103. form.discount_rate = 0
  104. self.assertEqual(form.discount_amount, 0)
  105. form.goods_qty = 3
  106. self.assertEqual(form.discount_amount, 0)
  107. form.save()
  108. def test_form_unsaved_amount_and_zero_quantity(self):
  109. from odoo.tests import Form
  110. view = self.env['ir.ui.view'].create({'name': 'port.new.discount.form', 'model': 'wh.move.line',
  111. 'arch': '''<form><field name="type"/><field name="goods_id"/>
  112. <field name="goods_qty"/><field name="price"/><field name="price_taxed"/>
  113. <field name="tax_rate"/><field name="discount_rate"/><field name="discount_amount"/>
  114. <field name="subtotal"/></form>'''})
  115. form = Form(self.env['wh.move.line'].with_context(default_type='out'), view=view)
  116. form.goods_id = self.env.ref('goods.mouse')
  117. form.goods_qty = 4
  118. form.price_taxed = 100
  119. form.discount_amount = 40
  120. form.goods_qty = 3
  121. self.assertEqual(form.discount_amount, 40)
  122. form.discount_rate = 10
  123. form.discount_rate = 0
  124. form.goods_qty = 0
  125. self.assertEqual(form.discount_amount, 0)
上海开阖软件有限公司 沪ICP备12045867号-1