1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/approvals_purchase/tests/test_approvals_purchase.py
2024-12-10 09:04:09 +07:00

459 lines
21 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import datetime
from odoo.addons.approvals_purchase.tests.common import TestApprovalsCommon
from odoo.exceptions import UserError
from odoo.tests.common import Form
class TestApprovalsPurchase(TestApprovalsCommon):
def get_purchase_order_for_seller(self, seller):
return self.env['purchase.order'].search([
('partner_id', '=', seller.id)
])
def test_01_create_purchase_request(self):
""" Creates new purchase request then verifies all is correctly set. """
request_form = self.create_request_form()
request_purchase = request_form.save()
self.assertEqual(request_purchase.has_product, 'required')
self.assertEqual(request_purchase.has_quantity, 'required',
"A purchase request must have `has_quantity` forced on 'required'.")
self.assertEqual(request_purchase.has_product, 'required',
"A purchase request must have `has_product` forced on 'required'.")
def test_02_check_constrains(self):
""" Checks all constrains are respected and all errors are raised. """
# Create a new purchase request and save it.
request_form = self.create_request_form(approver=self.user_approver)
request_purchase = request_form.save()
# Try to submit it without any product lines -> must raise an UserError.
with self.assertRaises(UserError):
request_purchase.action_confirm()
# Add new lines, they require a description but a onchange will fill the
# description automatically if we set the product id.
request_form = Form(request_purchase)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_mouse
line.quantity = 1
with request_form.product_line_ids.new() as line:
line.description = "The thing with a screen and a keyboard..."
line.quantity = 1
# Try to validate, should be OK now.
request_purchase = request_form.save()
request_purchase.action_confirm()
self.assertEqual(request_purchase.request_status, 'pending')
# Try to approve it...
with self.assertRaises(UserError):
# ... but raise an error because all product line need a product_id.
request_purchase.action_approve()
# Edit the line without product id then try to approve it again.
request_purchase.action_draft()
request_form = Form(request_purchase)
with request_form.product_line_ids.edit(1) as line:
line.product_id = self.product_computer
request_purchase = request_form.save()
request_purchase.with_user(self.user_approver).action_approve()
# ... should be approved now.
self.assertEqual(request_purchase.request_status, 'approved')
# Try to generate a purchase order from the request...
with self.assertRaises(UserError):
# ... but must fail because mouse product doesn't have any seller.
request_purchase.action_create_purchase_orders()
self.assertEqual(request_purchase.purchase_order_count, 0)
# Edit mouse product to add a vendor, then try again.
self.product_mouse.seller_ids = [(0, 0, {
'partner_id': self.partner_seller_1.id,
'min_qty': 1,
'price': 15,
})]
# Should be ok now, check the approval request has purchase order.
request_purchase.action_create_purchase_orders()
self.assertEqual(request_purchase.purchase_order_count, 1)
def test_purchase_01_check_create_purchase(self):
""" Checks an approval purchase request will create a new purchase order
and checks also this purchase will have the right seller when create
purchase (depending of the vendor price list). """
# Checks we have really no purchase orders for the sellers.
po_for_seller_1 = self.get_purchase_order_for_seller(self.partner_seller_1)
po_for_seller_2 = self.get_purchase_order_for_seller(self.partner_seller_2)
self.assertEqual(len(po_for_seller_1), 0)
self.assertEqual(len(po_for_seller_2), 0)
# Create a new purchase request for 9 computers. The selected seller for
# the purchase order must be partner_seller_1 because he is the one who
# has the best price under 10 units.
request_form = self.create_request_form(approver=self.user_approver)
# Create a purchase product line.
with request_form.product_line_ids.new() as line:
line.product_id = self.product_computer
line.quantity = 9
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
# Check we have a purchase order and if it is correclty set.
self.assertEqual(request_purchase.purchase_order_count, 1)
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(purchase_order.partner_id.id, self.partner_seller_1.id)
self.assertEqual(len(purchase_order.order_line), 1)
self.assertEqual(purchase_order.origin, request_purchase.name)
# Check the purchase order line fields.
po_line = purchase_order.order_line[0]
self.assertEqual(po_line.product_qty, 9)
self.assertEqual(po_line.price_unit, 250)
# Checks to be sure we created only one purchase order for the seller_1.
po_for_seller_1 = self.get_purchase_order_for_seller(self.partner_seller_1)
po_for_seller_2 = self.get_purchase_order_for_seller(self.partner_seller_2)
self.assertEqual(len(po_for_seller_1), 1)
self.assertEqual(len(po_for_seller_2), 0)
# check that the payment term is set
self.assertEqual(po_for_seller_1.payment_term_id, self.payment_terms)
# Now, do the same but for 12 computers. The selected seller for the
# purchase order must be partner_seller_2 because he has better price
# than partner_seller_1 for 10 units or more.
request_form = self.create_request_form(approver=self.user_approver)
# Create a purchase product line.
with request_form.product_line_ids.new() as line:
line.product_id = self.product_computer
line.quantity = 12
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
# Check we have a purchase order and if it is correclty set.
self.assertEqual(request_purchase.purchase_order_count, 1)
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(purchase_order.partner_id.id, self.partner_seller_2.id)
self.assertEqual(len(purchase_order.order_line), 1)
self.assertEqual(purchase_order.origin, request_purchase.name)
# Check the purchase order line fields.
po_line = purchase_order.order_line[0]
self.assertEqual(po_line.product_qty, 12)
self.assertEqual(po_line.price_unit, 230)
# Checks we created a another purchase order for seller_2 now.
po_for_seller_1 = self.get_purchase_order_for_seller(self.partner_seller_1)
po_for_seller_2 = self.get_purchase_order_for_seller(self.partner_seller_2)
self.assertEqual(len(po_for_seller_1), 1)
self.assertEqual(len(po_for_seller_2), 1)
def test_purchase_02_add_order_line(self):
""" Checks we don't create a new purchase order but modify the existing
one, creating a new purchase order line if needed. """
# Create a purchase order for partner_seller_1 without order lines.
po_origin = 'From an another galaxy'
purchase_order = self.create_purchase_order(origin=po_origin)
# Create a new purchase request who will update the purchase order and
# add into it a new purchase order line.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_computer
line.quantity = 4
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
# Check we have a purchase order and if it is correclty set.
self.assertEqual(request_purchase.purchase_order_count, 1)
request_po = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
request_po.id, purchase_order.id,
"The purchase order linked to the AR must be the existing one."
)
self.assertEqual(
purchase_order.origin, (po_origin + ', ' + request_purchase.name)
)
self.assertEqual(len(purchase_order.order_line), 1)
# Check the purchase order line fields.
po_line = purchase_order.order_line[0]
self.assertEqual(po_line.product_qty, 4)
self.assertEqual(po_line.price_unit, 250)
def test_purchase_03_edit_order_line(self):
""" Checks we don't create a new purchase order but modify the existing
one, increasing the product quantity of the existing order line. """
# Create a purchase order for partner_seller_1 with an order line.
po_origin = 'From an another galaxy'
purchase_order = self.create_purchase_order(
origin=po_origin,
lines=[{
'product': self.product_computer,
'price': 250,
'quantity': 10,
}]
)
# Create a new purchase request who will update the purchase order and
# modify the product quantity of its purchase order line.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_computer
line.quantity = 4
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
# Check we have a purchase order and if it is correclty set.
self.assertEqual(request_purchase.purchase_order_count, 1)
request_po = self.get_purchase_order(request_purchase)
self.assertEqual(
request_po.id, purchase_order.id,
"The purchase order linked to the AR must be the existing one."
)
self.assertEqual(
purchase_order.origin, (po_origin + ', ' + request_purchase.name)
)
self.assertEqual(len(purchase_order.order_line), 1)
# Check the purchase order line fields.
po_line = purchase_order.order_line[0]
self.assertEqual(po_line.product_qty, 14)
self.assertEqual(po_line.price_unit, 250)
def test_purchase_04_create_multiple_purchase(self):
""" Checks purchase approval requests with multiple product lines will,
in function of how they are set, create purchase order, add purchase
order line or edit the product quantity of the order line. """
# Add seller for product mouse.
self.product_mouse.seller_ids = [(0, 0, {
'partner_id': self.partner_seller_1.id,
'min_qty': 1,
'price': 15,
})]
# Create a purchase order with a order line for some computers.
purchase_order_1 = self.create_purchase_order(lines=[{
'product': self.product_computer,
'price': 250,
'quantity': 7
}])
# Create and edit an approval request.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_mouse
line.quantity = 20
with request_form.product_line_ids.new() as line:
line.product_id = self.product_computer
line.quantity = 10
# Confirm, approves and ask to create purchase orders.
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
self.assertEqual(
request_purchase.purchase_order_count, 2,
"Must have two purchase orders linked to the approval request."
)
request_po = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
request_po.id, purchase_order_1.id,
"The first purchase order must the already existing one."
)
self.assertEqual(len(purchase_order_1.order_line), 2)
self.assertEqual(
purchase_order_1.order_line[0].product_id.id, self.product_computer.id
)
self.assertEqual(purchase_order_1.order_line[0].product_qty, 7)
self.assertEqual(purchase_order_1.order_line[0].price_unit, 250)
self.assertEqual(
purchase_order_1.order_line[1].product_id.id, self.product_mouse.id
)
self.assertEqual(purchase_order_1.order_line[1].product_qty, 20)
self.assertEqual(purchase_order_1.order_line[1].price_unit, 15)
purchase_order_2 = self.get_purchase_order(request_purchase, 1)
self.assertEqual(
purchase_order_2.partner_id.id, self.partner_seller_2.id,
"The second purchase order must been created with the good seller."
)
self.assertEqual(len(purchase_order_2.order_line), 1)
self.assertEqual(
purchase_order_2.order_line.product_id.id, self.product_computer.id
)
self.assertEqual(purchase_order_2.order_line.product_qty, 10)
self.assertEqual(purchase_order_2.order_line.price_unit, 230)
def test_purchase_05_convert_price_currency(self):
""" Checks the price is correclty set when create a purchase order line
for a product (currency conversion). """
date_now = datetime.datetime.now()
currency_a = self.env['res.currency'].create({
'name': 'ZEN',
'symbol': 'Z',
'rounding': 0.01,
'currency_unit_label': 'Zenny',
'rate': 1,
})
# Create a partner to use as company owner.
partner_company_owner = self.env['res.partner'].create({
'name': 'Joe McKikou'
})
current_company = self.env.company
# Create a new company using the currency_a and set it as current company.
new_company = self.env['res.company'].create({
'currency_id': currency_a.id,
'name': 'Kikou Corp',
'partner_id': partner_company_owner.id,
})
# Change company for the user.
self.env.user.company_ids += new_company
self.env.user.company_id = new_company
currency_b = self.env['res.currency'].create({
'name': 'RUP',
'symbol': 'R',
'rounding': 1,
'currency_unit_label': 'Rupis',
'rate_ids': [(0, 0, {
'rate': 2.5,
'company_id': new_company.id,
'name': date_now,
})],
})
# Set price vendor with currency_b.
self.product_mouse.seller_ids = [(0, 0, {
'partner_id': self.partner_seller_1.id,
'min_qty': 1,
'price': 5,
'currency_id': currency_b.id,
})]
# Define a purchase approval category for the new company.
approval_category_form = Form(self.env['approval.category'])
approval_category_form.name = 'Product Request (Kikou Corp)'
approval_category_form.approval_type = 'purchase'
purchase_category_2 = approval_category_form.save()
# Create a new user to use as approver for this company.
user_approver_2 = self.env['res.users'].create({
'login': 'big_cheese',
'name': 'Clément Tall',
})
# Create new purchase approval request and create purchase order.
request_form = self.create_request_form(
approver=user_approver_2,
category=purchase_category_2,
)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_mouse
line.quantity = 1
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(user_approver_2).action_approve()
request_purchase.action_create_purchase_orders()
# Compare prices.
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
purchase_order.order_line[0].price_unit, 2, "Price must be adapted."
)
# Resets the company.
self.env.user.company_id = current_company
self.env.user.company_ids -= new_company
def test_uom_01_create_purchase(self):
""" Check the amount of product is correctly set, regarding the UoM of
the approval request and the UoM on the purchase order line. """
# Set the product UoM on 'fortnight'.
self.product_earphone.uom_id = self.uom_fortnight
# Create a request for 2 fortnights of the product.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_earphone
line.quantity = 2
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
request_product_line = request_purchase.product_line_ids[0]
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
request_product_line.product_uom_id.id, self.uom_fortnight.id
)
self.assertEqual(
purchase_order.order_line[0].product_uom.id, self.uom_unit.id
)
self.assertEqual(
purchase_order.order_line[0].product_qty, 30,
"Must have 30 units (= 2 fortnights)."
)
def test_uom_02_create_purchase(self):
""" Check the amount of product is correctly set, regarding the UoM of
the approval request and the UoM on the purchase order line. """
# Set the product purchase's UoM on 'fortnight'.
self.product_earphone.uom_po_id = self.uom_fortnight
# Create a request for 30 units of the product.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_earphone
line.quantity = 30
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
request_product_line = request_purchase.product_line_ids[0]
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
request_product_line.product_uom_id.id, self.uom_unit.id
)
self.assertEqual(
purchase_order.order_line[0].product_uom.id, self.uom_fortnight.id
)
self.assertEqual(
purchase_order.order_line[0].product_qty, 2,
"Must have 2 fortnights (= 30 units)."
)
def test_uom_03_update_purchase_order_line(self):
""" Check the approval request will use the right UoM for purchase, even
if a compatible purchase order already exists with an order line using
an another UoM. """
# Create a purchase order for partner_seller_1 with an order line.
purchase_order = self.create_purchase_order(lines=[{
'product': self.product_earphone,
'price': 250,
'quantity': 7,
'uom': self.uom_unit.id,
}])
# Set the product UoM on 'fortnight'.
self.product_earphone.uom_po_id = self.uom_fortnight
# Create a request for 2 fortnights of the product.
request_form = self.create_request_form(approver=self.user_approver)
with request_form.product_line_ids.new() as line:
line.product_id = self.product_earphone
line.quantity = 30
request_purchase = request_form.save()
request_purchase.action_confirm()
request_purchase.with_user(self.user_approver).action_approve()
request_purchase.action_create_purchase_orders()
request_product_line = request_purchase.product_line_ids[0]
purchase_order = self.get_purchase_order(request_purchase, 0)
self.assertEqual(
request_product_line.product_uom_id.id, self.uom_unit.id
)
self.assertEqual(len(purchase_order.order_line), 2)
self.assertEqual(
purchase_order.order_line[0].product_uom.id, self.uom_unit.id
)
self.assertEqual(
purchase_order.order_line[1].product_uom.id, self.uom_fortnight.id
)
self.assertEqual(purchase_order.order_line[0].product_qty, 7)
self.assertEqual(
purchase_order.order_line[1].product_qty, 2,
"Must have 2 fortnights (= 30 units)."
)