forked from Mapan/odoo17e
459 lines
21 KiB
Python
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)."
|
|
)
|