190 lines
9.5 KiB
Python
190 lines
9.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
|
|
|
|
from datetime import datetime
|
|
import time
|
|
from flectra.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
|
from flectra.addons.account.tests.account_test_classes import AccountingTestCase
|
|
|
|
|
|
class TestPurchaseOrder(AccountingTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestPurchaseOrder, self).setUp()
|
|
# Useful models
|
|
self.PurchaseOrder = self.env['purchase.order']
|
|
self.PurchaseOrderLine = self.env['purchase.order.line']
|
|
self.AccountInvoice = self.env['account.invoice']
|
|
self.AccountInvoiceLine = self.env['account.invoice.line']
|
|
self.partner_id = self.env.ref('base.res_partner_1')
|
|
self.product_id_1 = self.env.ref('product.product_product_8')
|
|
self.product_id_2 = self.env.ref('product.product_product_11')
|
|
self.product_id_3 = self.env.ref('product.product_product_9')
|
|
self.current_time = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
|
|
self.main_company = self.env.ref('base.main_company')
|
|
self.child_company = self.env.ref('stock.res_company_1')
|
|
self.purchase_user_group = self.env.ref('purchase.group_purchase_user')
|
|
self.stock_user_group = self.env.ref('stock.group_stock_user')
|
|
self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
|
|
self.branch_2 = self.env.ref('base_branch_company.data_branch_2')
|
|
self.account = self.env.ref('l10n_generic_coa.conf_a_pay')
|
|
|
|
(self.product_id_1 | self.product_id_2).write({'purchase_method': 'purchase'})
|
|
self.po_vals = {
|
|
'partner_id': self.partner_id.id,
|
|
'order_line': [
|
|
(0, 0, {
|
|
'name': self.product_id_1.name,
|
|
'product_id': self.product_id_1.id,
|
|
'product_qty': 5.0,
|
|
'product_uom': self.product_id_1.uom_po_id.id,
|
|
'price_unit': 500.0,
|
|
'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
|
}),
|
|
(0, 0, {
|
|
'name': self.product_id_2.name,
|
|
'product_id': self.product_id_2.id,
|
|
'product_qty': 5.0,
|
|
'product_uom': self.product_id_2.uom_po_id.id,
|
|
'price_unit': 250.0,
|
|
'date_planned': datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
|
})],
|
|
}
|
|
|
|
|
|
def test_00_purchase_order_flow(self):
|
|
|
|
# Ensure product_id_2 doesn't have res_partner_1 as supplier
|
|
if self.partner_id in self.product_id_2.seller_ids.mapped('name'):
|
|
id_to_remove = self.product_id_2.seller_ids.filtered(lambda r: r.name == self.partner_id).ids[0] if self.product_id_2.seller_ids.filtered(lambda r: r.name == self.partner_id) else False
|
|
if id_to_remove:
|
|
self.product_id_2.write({
|
|
'seller_ids': [(2, id_to_remove, False)],
|
|
})
|
|
self.assertFalse(self.product_id_2.seller_ids.filtered(lambda r: r.name == self.partner_id), 'Purchase: the partner should not be in the list of the product suppliers')
|
|
|
|
self.po = self.PurchaseOrder.create(self.po_vals)
|
|
self.assertTrue(self.po, 'Purchase: no purchase order created')
|
|
self.assertEqual(self.po.invoice_status, 'no', 'Purchase: PO invoice_status should be "Not purchased"')
|
|
self.assertEqual(self.po.order_line.mapped('qty_received'), [0.0, 0.0], 'Purchase: no product should be received"')
|
|
self.assertEqual(self.po.order_line.mapped('qty_invoiced'), [0.0, 0.0], 'Purchase: no product should be invoiced"')
|
|
|
|
self.po.button_confirm()
|
|
self.assertEqual(self.po.state, 'purchase', 'Purchase: PO state should be "Purchase"')
|
|
self.assertEqual(self.po.invoice_status, 'to invoice', 'Purchase: PO invoice_status should be "Waiting Invoices"')
|
|
|
|
self.assertTrue(self.product_id_2.seller_ids.filtered(lambda r: r.name == self.partner_id), 'Purchase: the partner should be in the list of the product suppliers')
|
|
|
|
seller = self.product_id_2._select_seller(partner_id=self.partner_id, quantity=2.0, date=self.po.date_planned, uom_id=self.product_id_2.uom_po_id)
|
|
price_unit = seller.price if seller else 0.0
|
|
if price_unit and seller and self.po.currency_id and seller.currency_id != self.po.currency_id:
|
|
price_unit = seller.currency_id.compute(price_unit, self.po.currency_id)
|
|
self.assertEqual(price_unit, 250.0, 'Purchase: the price of the product for the supplier should be 250.0.')
|
|
|
|
self.assertEqual(self.po.picking_count, 1, 'Purchase: one picking should be created"')
|
|
self.picking = self.po.picking_ids[0]
|
|
self.picking.force_assign()
|
|
self.picking.move_line_ids.write({'qty_done': 5.0})
|
|
self.picking.button_validate()
|
|
self.assertEqual(self.po.order_line.mapped('qty_received'), [5.0, 5.0], 'Purchase: all products should be received"')
|
|
|
|
self.invoice = self.AccountInvoice.create({
|
|
'partner_id': self.partner_id.id,
|
|
'purchase_id': self.po.id,
|
|
'account_id': self.partner_id.property_account_payable_id.id,
|
|
'type': 'in_invoice',
|
|
})
|
|
self.invoice.purchase_order_change()
|
|
self.assertEqual(self.po.order_line.mapped('qty_invoiced'), [5.0, 5.0], 'Purchase: all products should be invoiced"')
|
|
|
|
def test_02_po_return(self):
|
|
"""
|
|
Test a PO with a product on Incoming shipment. Validate the PO, then do a return
|
|
of the picking with Refund.
|
|
"""
|
|
# Draft purchase order created
|
|
self.po2 = self.env['purchase.order'].create({
|
|
'partner_id': self.partner_id.id,
|
|
'order_line': [
|
|
(0, 0, {
|
|
'name': self.product_id_1.name,
|
|
'product_id': self.product_id_1.id,
|
|
'product_qty': 5.0,
|
|
'product_uom': self.product_id_1.uom_po_id.id,
|
|
'price_unit': 100.0,
|
|
'date_planned': datetime.today().strftime(
|
|
DEFAULT_SERVER_DATETIME_FORMAT),
|
|
}),
|
|
],
|
|
})
|
|
|
|
self.assertTrue(self.po2, 'Purchase: no purchase order created')
|
|
self.po2.button_confirm()
|
|
|
|
self.assertEqual(self.po2.state, 'purchase', 'Purchase: PO state '
|
|
'should be "Purchase"')
|
|
self.assertEqual(self.po2.invoice_status, 'to invoice', 'Purchase: '
|
|
'PO invoice_status should be "Waiting Invoices"')
|
|
self.assertEqual(self.po2.picking_count, 1, 'Purchase: one picking '
|
|
'should be created"')
|
|
|
|
self.picking = self.po2.picking_ids[0]
|
|
self.picking.move_lines.quantity_done = 5
|
|
self.picking.button_validate()
|
|
|
|
self.assertEqual(self.po2.order_line.mapped('qty_received'), [5.0],
|
|
'Purchase: all products should be received"')
|
|
|
|
#After Receiving all products create vendor bill.
|
|
self.invoice2 = self.AccountInvoice.create({
|
|
'partner_id': self.partner_id.id,
|
|
'purchase_id': self.po2.id,
|
|
'account_id': self.partner_id.property_account_payable_id.id,
|
|
'type': 'in_invoice',
|
|
})
|
|
self.invoice2.purchase_order_change()
|
|
self.invoice2.action_invoice_open()
|
|
self.invoice2.invoice_validate()
|
|
self.assertEqual(self.po2.order_line.mapped('qty_invoiced'), [5.0],
|
|
'Purchase: all products should be invoiced"')
|
|
|
|
# Check quantity received
|
|
received_qty = sum(pol.qty_received for pol in self.po2.order_line)
|
|
|
|
self.assertEqual(received_qty, 5.0,
|
|
'Purchase: Received quantity should be 5.0 '
|
|
'instead of %s after validating incoming '
|
|
'shipment' % received_qty)
|
|
|
|
# Create return picking
|
|
StockReturnPicking = self.env['stock.return.picking']
|
|
pick = self.po2.picking_ids
|
|
default_data = StockReturnPicking.with_context(active_ids=pick.ids, active_id=pick.ids[0]).default_get(['move_dest_exists', 'original_location_id', 'product_return_moves', 'parent_location_id', 'location_id'])
|
|
return_wiz = StockReturnPicking.with_context(active_ids=pick.ids, active_id=pick.ids[0]).create(default_data)
|
|
return_wiz.product_return_moves.write({'quantity': 5.0,
|
|
'to_refund':True})
|
|
# Return only 5 qty
|
|
res = return_wiz.create_returns()
|
|
return_pick = self.env['stock.picking'].browse(res['res_id'])
|
|
|
|
# Validate picking
|
|
return_pick.force_assign()
|
|
return_pick.move_line_ids.write({'qty_done': 5.0})
|
|
return_pick.do_transfer()
|
|
|
|
# I created a credit note Using Add Credit Note Button
|
|
|
|
context = {"active_model": 'account.invoice',
|
|
"active_ids": [self.invoice2.id],
|
|
"active_id": self.invoice2.id}
|
|
|
|
invoice_refund_obj = self.env['account.invoice.refund']
|
|
self.AccountInvoiceRefund = invoice_refund_obj.with_context(context).create(dict(
|
|
description='Create Credit Note for Purchase Order',
|
|
filter_refund='refund',
|
|
|
|
))
|
|
# I clicked on Add Credit Note button.
|
|
self.AccountInvoiceRefund.with_context(context).invoice_refund()
|
|
self.invoice2.refund_invoice_ids and self.invoice2.refund_invoice_ids[
|
|
0].invoice_validate() |