GoodERP
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.

436 line
18KB

  1. # Copyright 2016 上海开阖软件有限公司 (http://www.osbzr.com)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo.tests.common import TransactionCase
  4. from odoo.exceptions import UserError
  5. class TestBuyOrder(TransactionCase):
  6. @classmethod
  7. def setUpClass(cls):
  8. super().setUpClass()
  9. # Declare the business roles required by the original order workflow.
  10. cls.env.user.groups_id |= cls.env.ref('buy.group_buy')
  11. def setUp(self):
  12. super(TestBuyOrder, self).setUp()
  13. # 给buy_order_1中的商品“键盘”的分类设置科目
  14. self.env.ref('core.goods_category_1').account_id = self.env.ref(
  15. 'finance.account_goods').id
  16. self.order = self.env.ref('buy.buy_order_1')
  17. self.order.bank_account_id = False
  18. # 因同一个业务伙伴不能存在两张未审核的收付款单,把系统里已有的相关业务伙伴未审核的收付款单审核
  19. self.env.ref('money.get_40000').money_order_done()
  20. self.env.ref('money.pay_2000').money_order_done()
  21. def test_get_paid_amount(self):
  22. ''' 测试:计算采购订单付款/退款 '''
  23. self.order.buy_order_done()
  24. receipt = self.env['buy.receipt'].search([('order_id', '=', self.order.id)])
  25. receipt.payment = 1
  26. receipt.bank_account_id = self.env.ref('core.comm').id
  27. receipt.buy_receipt_done()
  28. money = self.env['money.order'].search([('buy_id', '=', self.order.id)])
  29. money.money_order_done()
  30. self.assertTrue(self.order.paid_amount == 1)
  31. def test_get_paid_amount_pay_divided(self):
  32. ''' 测试:分批付款时,采购订单付款/退款 '''
  33. self.order.invoice_by_receipt = False
  34. plan = self.env['payment.plan'].create({
  35. 'buy_id': self.order.id,
  36. 'name': 'first',
  37. 'amount_money': 10,
  38. })
  39. plan.request_payment()
  40. # 生成的发票未核销,已付金额为0
  41. self.assertTrue(self.order.paid_amount == 0)
  42. def test_onchange_discount_rate(self):
  43. ''' 优惠率改变时,改变优惠金额,成交金额也改变'''
  44. amount_before = self.order.amount
  45. discount_amount_before = self.order.discount_amount
  46. self.order.discount_rate = 10
  47. self.order.onchange_discount_rate()
  48. if amount_before:
  49. self.assertTrue(self.order.amount != amount_before)
  50. self.assertTrue(self.order.discount_amount !=
  51. discount_amount_before)
  52. def test_get_buy_goods_state(self):
  53. '''返回收货状态'''
  54. # order商品总数量为10
  55. self.order.buy_order_done()
  56. # 采购订单行的已入库数量为0时,将商品状态写为未入库
  57. self.assertTrue(self.order.goods_state == '未入库')
  58. receipt = self.env['buy.receipt'].search(
  59. [('order_id', '=', self.order.id)])
  60. # 采购订单行的已入库数量等于商品数量时,将商品状态写为全部入库
  61. receipt.buy_receipt_done()
  62. self.assertTrue(self.order.goods_state == '全部入库')
  63. def test_get_buy_goods_state_part_in(self):
  64. '''返回收货状态:部分入库'''
  65. # 采购订单行的已入库数量小于商品数量时,将商品状态写为部分入库
  66. self.order.buy_order_done()
  67. receipt = self.env['buy.receipt'].search(
  68. [('order_id', '=', self.order.id)])
  69. for line in receipt.line_in_ids:
  70. line.goods_qty = 5
  71. receipt.buy_receipt_done()
  72. self.assertTrue(self.order.goods_state == '部分入库')
  73. back_rec = self.env['buy.receipt'].search(
  74. [('order_id', '=', self.order.id), ('state', '=', 'draft')])
  75. back_rec.action_cancel()
  76. self.assertTrue(self.order.goods_state == '部分入库剩余作废')
  77. def test_default_warehouse_dest(self):
  78. '''新建采购订单时默认调入仓库'''
  79. order = self.env['buy.order'].with_context({
  80. 'warehouse_dest_type': 'stock'
  81. }).create({})
  82. self.assertTrue(order.warehouse_dest_id.type == 'stock')
  83. def test_unlink(self):
  84. '''测试删除已审核的采购订单'''
  85. self.order.buy_order_done()
  86. with self.assertRaises(UserError):
  87. self.order.unlink()
  88. # 删除草稿状态的采购订单
  89. self.order.buy_order_draft()
  90. self.order.unlink()
  91. def test_buy_order_done(self):
  92. '''采购订单审核'''
  93. # 正常审核
  94. self.order.buy_order_done()
  95. self.assertTrue(self.order.state == 'done')
  96. # 重复审核报错
  97. with self.assertRaises(UserError):
  98. self.order.buy_order_done()
  99. # 数量单价小于0应报错
  100. self.order.buy_order_draft()
  101. for line in self.order.line_ids:
  102. line.quantity = 0
  103. with self.assertRaises(UserError):
  104. self.order.buy_order_done()
  105. # 输入预付款和结算账户
  106. bank_account = self.env.ref('core.alipay')
  107. bank_account.balance = 1000000
  108. self.order.prepayment = 50.0
  109. self.order.bank_account_id = bank_account
  110. for line in self.order.line_ids:
  111. line.quantity = 1
  112. line.tax_rate = 0
  113. self.order.buy_order_done()
  114. # 预付款不为空时,请选择结算账户
  115. self.order.buy_order_draft()
  116. self.order.bank_account_id = False
  117. self.order.prepayment = 50.0
  118. with self.assertRaises(UserError):
  119. self.order.buy_order_done()
  120. # 没有订单行时审核报错
  121. for line in self.order.line_ids:
  122. line.unlink()
  123. with self.assertRaises(UserError):
  124. self.order.buy_order_done()
  125. def test_buy_order_done_foreign_currency(self):
  126. """测试审核采购订单,外币免税"""
  127. self.order.currency_id = self.env.ref('base.USD')
  128. for line in self.order.line_ids:
  129. line.price_taxed = 1170
  130. line.tax_rate = 17
  131. with self.assertRaises(UserError):
  132. self.order.buy_order_done()
  133. def test_buy_order_draft(self):
  134. '''采购订单反审核'''
  135. # 正常反审核
  136. self.order.buy_order_done()
  137. self.order.buy_order_draft()
  138. receipt = self.env['buy.receipt'].search(
  139. [('order_id', '=', self.order.id)])
  140. self.assertTrue(not receipt)
  141. self.assertTrue(self.order.state == 'draft')
  142. self.assertTrue(not self.order.approve_uid.id)
  143. # 重复反审核报错
  144. self.order.buy_order_done()
  145. self.order.buy_order_draft()
  146. with self.assertRaises(UserError):
  147. self.order.buy_order_draft()
  148. # 订单已收货不能反审核
  149. self.order.buy_order_done()
  150. receipt = self.env['buy.receipt'].search(
  151. [('order_id', '=', self.order.id)])
  152. receipt.buy_receipt_done()
  153. with self.assertRaises(UserError):
  154. self.order.buy_order_draft()
  155. def test_buy_order_draft_with_prepayment(self):
  156. '''有预付款的采购订单反审核'''
  157. # 输入预付款和结算账户
  158. bank_account = self.env.ref('core.alipay')
  159. bank_account.balance = 1000000
  160. self.order.prepayment = 100
  161. self.order.bank_account_id = bank_account
  162. self.order.buy_order_done()
  163. money_order = self.env['money.order'].search([
  164. ('origin_name', '=', self.order.name)])
  165. money_order.money_order_done()
  166. with self.assertRaises(UserError):
  167. self.order.buy_order_draft()
  168. def test_buy_generate_receipt(self):
  169. '''测试采购订单生成入库单,批次管理拆分折扣金额'''
  170. # 采购订单
  171. # 全部入库
  172. self.order.buy_order_done()
  173. receipt = self.env['buy.receipt'].search(
  174. [('order_id', '=', self.order.id)])
  175. receipt.buy_receipt_done()
  176. self.assertTrue(self.order.goods_state == '全部入库')
  177. # 批次管理拆分订单行
  178. new_order = self.order.copy()
  179. for line in new_order.line_ids:
  180. line.goods_id = self.env.ref('goods.mouse').id
  181. new_order.buy_generate_receipt()
  182. receipt = self.env['buy.receipt'].search(
  183. [('order_id', '=', new_order.id)])
  184. self.assertTrue(len(receipt.line_in_ids) == 10)
  185. # 退货订单
  186. # 全部入库
  187. return_receipt = self.env.ref('buy.buy_return_order_1')
  188. return_receipt.buy_order_done()
  189. receipt = self.env['buy.receipt'].search(
  190. [('order_id', '=', return_receipt.id)])
  191. receipt.buy_receipt_done()
  192. return_receipt.buy_generate_receipt()
  193. def test_onchange_partner_id(self):
  194. # partner 无 税率,采购单行商品无税率
  195. self.env.ref('core.lenovo').tax_rate = 0
  196. self.env.ref('goods.keyboard').tax_rate = 0
  197. self.order.onchange_partner_id()
  198. # partner 有 税率,采购单行商品无税率
  199. self.env.ref('core.lenovo').tax_rate = 10
  200. self.env.ref('goods.keyboard').tax_rate = 0
  201. self.order.onchange_partner_id()
  202. # partner 无税率,采购单行商品无税率
  203. self.env.ref('core.lenovo').tax_rate = 0
  204. self.env.ref('goods.keyboard').tax_rate = 10
  205. self.order.onchange_partner_id()
  206. # partner 税率 > 采购单行商品税率
  207. self.env.ref('core.lenovo').tax_rate = 11
  208. self.env.ref('goods.keyboard').tax_rate = 10
  209. self.order.onchange_partner_id()
  210. # partner 税率 =< 采购单行商品税率
  211. self.env.ref('core.lenovo').tax_rate = 11
  212. self.env.ref('goods.keyboard').tax_rate = 12
  213. self.order.onchange_partner_id()
  214. def test_compute_receipt_and_invoice(self):
  215. '''计算生成入库单和结算单的个数'''
  216. self.order.buy_order_done()
  217. self.assertTrue(self.order.receipt_count == 1)
  218. self.order.receipt_ids[0].buy_receipt_done()
  219. self.assertTrue(self.order.invoice_count == 1)
  220. self.assertTrue(self.order.invoice_ids ==
  221. self.order.receipt_ids[0].invoice_id)
  222. def test_action_view_receipt(self):
  223. '''查看生成的入库单'''
  224. # 生成一张入库单
  225. self.order.buy_order_done()
  226. self.order.action_view_receipt()
  227. # 生成两张入库单
  228. self.order.buy_order_draft()
  229. self.order.buy_order_done()
  230. for line in self.order.receipt_ids[0].line_in_ids:
  231. line.goods_qty = 3
  232. self.order.receipt_ids[0].buy_receipt_done()
  233. self.order.action_view_receipt()
  234. def test_action_view_return(self):
  235. '''查看生成的采购退货单'''
  236. self.order.type = 'return'
  237. self.env.ref('buy.buy_order_line_1').goods_id = self.env.ref('goods.cable').id
  238. self.env.ref('buy.buy_order_line_1').attribute_id = False
  239. self.env.ref('warehouse.wh_in_whin0').warehouse_dest_id = self.env.ref('warehouse.sh_stock').id
  240. self.env.ref('warehouse.wh_in_whin0').approve_order()
  241. # 生成一张采购退货单
  242. self.order.buy_order_done()
  243. self.order.action_view_return()
  244. # 生成两张采购退货单
  245. self.order.buy_order_draft()
  246. self.order.buy_order_done()
  247. for line in self.order.receipt_ids[0].line_out_ids:
  248. line.goods_qty = 3
  249. self.order.receipt_ids[0].buy_receipt_done()
  250. self.order.action_view_return()
  251. def test_action_view_invoice(self):
  252. '''查看生成的结算单'''
  253. # 生成一张入库单,审核后查看结算单
  254. self.order.buy_order_done()
  255. self.order.action_view_invoice()
  256. self.order.receipt_ids[0].buy_receipt_done()
  257. self.order.action_view_invoice()
  258. # 生成两张入库单,都审核后在采购订单上查看结算单
  259. self.order.receipt_ids[0].buy_receipt_draft()
  260. self.order.buy_order_draft()
  261. self.order.buy_order_done()
  262. for line in self.order.receipt_ids[0].line_in_ids:
  263. line.goods_qty = 3
  264. self.order.receipt_ids[0].buy_receipt_done()
  265. self.order.action_view_invoice()
  266. def test_action_view_receipt(self):
  267. """ 测试 查看发货/退货单 """
  268. self.order.buy_order_done()
  269. self.order.action_view_receipt()
  270. receipt = self.env['buy.receipt'].search(
  271. [('order_id', '=', self.order.id)])
  272. for line in receipt.line_in_ids:
  273. line.goods_qty = 1
  274. receipt.buy_receipt_done()
  275. self.order.action_view_receipt()
  276. def test_buy_order_done_no_attribute(self):
  277. '''检查属性是否填充'''
  278. self.order.line_ids[0].attribute_id = False
  279. with self.assertRaises(UserError):
  280. self.order.buy_order_done()
  281. class TestBuyOrderLine(TransactionCase):
  282. def setUp(self):
  283. super(TestBuyOrderLine, self).setUp()
  284. self.order = self.env.ref('buy.buy_order_1')
  285. self.cable = self.env.ref('goods.cable')
  286. def test_compute_using_attribute(self):
  287. '''返回订单行中商品是否使用属性'''
  288. for line in self.order.line_ids:
  289. self.assertTrue(line.using_attribute)
  290. line.goods_id = self.env.ref('goods.mouse')
  291. self.assertTrue(not line.using_attribute)
  292. def test_compute_all_amount(self):
  293. '''当订单行的数量、含税单价、折扣额、税率改变时,改变采购金额、税额、价税合计'''
  294. for line in self.order.line_ids:
  295. line.price_taxed = 11.7
  296. self.assertTrue(line.amount == 100)
  297. self.assertTrue(line.tax_amount == 17)
  298. self.assertAlmostEqual(line.price_taxed, 11.7)
  299. self.assertTrue(line.subtotal == 117)
  300. def test_compute_all_amount_foreign_currency(self):
  301. '''外币测试:当订单行的数量、含税单价、折扣额、税率改变时,改变采购金额、税额、价税合计'''
  302. # 单据上外币是公司本位币
  303. self.order.currency_id = self.env.ref('base.CNY')
  304. for line in self.order.line_ids:
  305. line.price_taxed = 11.7
  306. # 外币
  307. self.order.currency_id = self.env.ref('base.EUR')
  308. for line in self.order.line_ids:
  309. line.price_taxed = 11.7
  310. def test_compute_all_amount_wrong_tax_rate(self):
  311. '''明细行上输入错误税率,应报错'''
  312. for line in self.order.line_ids:
  313. with self.assertRaises(UserError):
  314. line.tax_rate = -1
  315. with self.assertRaises(UserError):
  316. line.tax_rate = 102
  317. def test_onchange_price(self):
  318. '''当订单行的不含税单价改变时,改变含税单价'''
  319. for line in self.order.line_ids:
  320. line.price_taxed = 0
  321. line.price = 10
  322. line.onchange_price()
  323. self.assertAlmostEqual(line.price_taxed, 11.7)
  324. def test_onchange_goods_id(self):
  325. '''当订单行的商品变化时,带出商品上的单位、成本'''
  326. for line in self.order.line_ids:
  327. line.goods_id = self.cable
  328. line.onchange_goods_id()
  329. self.assertTrue(line.uom_id.name == '件')
  330. # 测试价格是否是商品的成本
  331. self.assertTrue(line.price == self.cable.cost)
  332. def test_onchange_goods_id_tax_rate(self):
  333. ''' 测试 修改商品时,采购单行税率变化 '''
  334. self.order_line = self.env.ref('buy.buy_order_line_1')
  335. # partner 无 税率,采购单行商品无税率
  336. self.env.ref('core.lenovo').tax_rate = 0
  337. self.env.ref('goods.keyboard').tax_rate = 0
  338. self.order_line.onchange_goods_id()
  339. # partner 有 税率,采购单行商品无税率
  340. self.env.ref('core.lenovo').tax_rate = 10
  341. self.env.ref('goods.keyboard').tax_rate = 0
  342. self.order_line.onchange_goods_id()
  343. # partner 无税率,采购单行商品有税率
  344. self.env.ref('core.lenovo').tax_rate = 0
  345. self.env.ref('goods.keyboard').tax_rate = 10
  346. self.order_line.onchange_goods_id()
  347. # partner 税率 > 采购单行商品税率
  348. self.env.ref('core.lenovo').tax_rate = 11
  349. self.env.ref('goods.keyboard').tax_rate = 10
  350. self.order_line.onchange_goods_id()
  351. # partner 税率 =< 采购单行商品税率
  352. self.env.ref('core.lenovo').tax_rate = 9
  353. self.env.ref('goods.keyboard').tax_rate = 10
  354. self.order_line.onchange_goods_id()
  355. def test_onchange_goods_id_vendor(self):
  356. '''当订单行的商品变化时,带出商品上供应商价'''
  357. # 添加网线的供应商价
  358. self.cable.vendor_ids.create({
  359. 'goods_id': self.cable.id,
  360. 'vendor_id': self.env.ref('core.lenovo').id,
  361. 'price': 2, })
  362. # 不选择供应商时,应弹出警告
  363. self.order.partner_id = False
  364. for line in self.order.line_ids:
  365. with self.assertRaises(UserError):
  366. line.onchange_goods_id()
  367. # 选择供应商联想,得到供应商价
  368. self.order.partner_id = self.env.ref('core.lenovo')
  369. for line in self.order.line_ids:
  370. line.goods_id = self.cable
  371. line.onchange_goods_id()
  372. self.assertTrue(line.price == 2)
  373. def test_onchange_discount_rate(self):
  374. ''' 订单行优惠率改变时,改变优惠金额'''
  375. for line in self.order.line_ids:
  376. line.price_taxed = 11.7
  377. line.discount_rate = 10
  378. line.onchange_discount_rate()
  379. self.assertTrue(line.discount_amount == 10)
  380. class TestOrderRoleBoundary(TransactionCase):
  381. def test_order_actions_require_business_group(self):
  382. from odoo.tests.common import new_test_user
  383. user = new_test_user(self.env, login='native_buy_no_role', groups='base.group_user')
  384. self.assertFalse(user.has_group('buy.group_buy'))
  385. order = self.env.ref('buy.buy_order_1')
  386. before = order.state
  387. for action in ('buy_order_done', 'buy_order_draft'):
  388. with self.subTest(action=action), self.assertRaisesRegex(UserError, '只有'):
  389. getattr(order.with_user(user), action)()
  390. self.assertEqual(order.state, before)
上海开阖软件有限公司 沪ICP备12045867号-1