[MERGE] various: Make the test suite demo data independant

Purpose
=======

This is the first huge step to improve the test suite in several ways:

- Make them demo data independent, allowing to modify the demo data without having to adapt the tests depending on it. It also allows to have a beautiful + convenient demo dataset to make a demonstration, and to configure complex data in the tests to manage the corner cases.
- Improve the test performances by converting them into SavepointCase. Each test will be rollbacked to it's initial state, after the setUpClass call. That way the different data are not re-created at each test for nothing.
- Introduce several test classes in base/tests/common.py to launch a TransactionCase, HttpCase or SavepointCase test with an available demo user, portal user or a large set of partners.
- This is the first step to tend to a rolling release process, allowing to execute the tests (or a subset of the tests) on a migrated base, for example.

closes odoo/odoo#39868

Taskid: 2075739
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
This commit is contained in:
Odoo's Mergebot
2019-11-07 08:37:12 +01:00
committed by GitHub
235 changed files with 4929 additions and 2074 deletions
+2 -1
View File
@@ -11,7 +11,8 @@ class PortalAccount(CustomerPortal):
def _prepare_portal_layout_values(self):
values = super(PortalAccount, self)._prepare_portal_layout_values()
invoice_count = request.env['account.move'].search_count([
# An internal user could not have access to the account.move model
invoice_count = request.env['account.move'].sudo().search_count([
('type', 'in', ('out_invoice', 'in_invoice', 'out_refund', 'in_refund', 'out_receipt', 'in_receipt')),
])
values['invoice_count'] = invoice_count
-1
View File
@@ -259,7 +259,6 @@ class AccountAccount(models.Model):
""", tuple(self.ids))
ids = self._cr.fetchall()
if ids:
# import pdb; pdb.set_trace()
raise ValidationError(_('Some journal items already exist with this account but in other journals than the allowed ones.'))
@api.depends('code')
@@ -1,301 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="0">
<!-- This should be loaded for non python tests in other modules that require accounting test data but that don't depend on any localization -->
<record id="base.main_company" model="res.company">
<field name="bank_account_code_prefix">X1100</field>
</record>
<!--
Chart of Accounts
-->
<!-- Balance Sheet -->
<record id="xfa" model="account.account">
<field name="code">X1000</field>
<field name="name">Fixed Assets - (test)</field>
<field name="user_type_id" ref="account.data_account_type_fixed_assets"/>
</record>
<record id="cas" model="account.account">
<field name="code">X1010</field>
<field name="name">Current Assets - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/>
</record>
<record id="stk" model="account.account">
<field name="code">X1011</field>
<field name="name">Purchased Stocks - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="tag_ids" eval="[(6,0,[ref('account.demo_stock_account')])]"/>
</record>
<record id="a_recv" model="account.account">
<field name="code">X1012</field>
<field name="name">Debtors - (test)</field>
<field eval="True" name="reconcile"/>
<field name="user_type_id" ref="account.data_account_type_receivable"/>
</record>
<record id="ova" model="account.account">
<field name="code">X1013</field>
<field name="name">VAT Paid- (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/>
</record>
<record id="bnk" model="account.account">
<field name="code">X1014</field>
<field name="name">Bank Current Account - (test)</field>
<field name="user_type_id" ref="account.data_account_type_liquidity"/>
</record>
<record id="cash" model="account.account">
<field name="code">X1015</field>
<field name="name">Cash - (test)</field>
<field name="user_type_id" ref="account.data_account_type_liquidity"/>
</record>
<record id="o_income" model="account.account">
<field name="code">X1016</field>
<field name="name">Opening Income - (test)</field>
<field name="user_type_id" ref="account.data_account_type_other_income"/>
</record>
<record id="usd_bnk" model="account.account">
<field name="code">X1017</field>
<field name="name">USD Bank Account - (test)</field>
<field name="user_type_id" ref="account.data_account_type_liquidity"/>
<field name="currency_id" ref="base.USD"/>
</record>
<record id="transfer_account" model="account.account">
<field name="code">X1019</field>
<field name="name">Internal Transfert Account - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile">1</field>
</record>
<record id="ncas" model="account.account">
<field name="code">X1020</field>
<field name="name">Non-current Assets - (test)</field>
<field name="user_type_id" ref="account.data_account_type_non_current_assets"/>
</record>
<record id="prepayements" model="account.account">
<field name="code">X1030</field>
<field name="name">Prepayments - (test)</field>
<field name="user_type_id" ref="account.data_account_type_prepayments"/>
</record>
<record id="current_liabilities" model="account.account">
<field name="code">X1110</field>
<field name="name">Current Liabilities - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
</record>
<record id="a_pay" model="account.account">
<field name="code">X1111</field>
<field name="name">Creditors - (test)</field>
<field eval="True" name="reconcile"/>
<field name="user_type_id" ref="account.data_account_type_payable"/>
</record>
<record id="iva" model="account.account">
<field name="code">X1112</field>
<field name="name">VAT Received - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
</record>
<record id="rsa" model="account.account">
<field name="code">X1113</field>
<field name="name">Reserve and Profit/Loss - (test)</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
</record>
<record id="cas" model="account.account">
<field name="code">X1120</field>
<field name="name">Non-current Liabilities - (test)</field>
<field name="user_type_id" ref="account.data_account_type_non_current_liabilities"/>
</record>
<record id="o_expense" model="account.account">
<field name="code">X1114</field>
<field name="name">Opening Expense - (test)</field>
<field name="user_type_id" ref="account.data_account_type_expenses"/>
</record>
<!-- Profit and Loss -->
<record model="account.account" id="income_fx_income">
<field name="name">Foreign Exchange Gain - (test)</field>
<field name="code">X2010</field>
<field name="user_type_id" ref="account.data_account_type_revenue"/>
<field name="reconcile" eval="False"/>
</record>
<record id="a_sale" model="account.account">
<field name="code">X2020</field>
<field name="name">Product Sales - (test)</field>
<field name="user_type_id" ref="account.data_account_type_revenue"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_operating')])]"/>
</record>
<record id="a_sale_invest" model="account.account">
<field name="code">X2021</field>
<field name="name">Sale of Lands - (test)</field>
<field name="user_type_id" ref="account.data_account_type_revenue"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_investing')])]"/>
</record>
<record id="a_sale_finance" model="account.account">
<field name="code">X2022</field>
<field name="name">Bank Accounts Interests - (test)</field>
<field name="user_type_id" ref="account.data_account_type_revenue"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_financing')])]"/>
</record>
<record id="cog" model="account.account">
<field name="code">X2030</field>
<field name="name">Cost of Goods Sold - (test)</field>
<field name="user_type_id" ref="account.data_account_type_direct_costs"/>
</record>
<record model="account.account" id="income_fx_expense">
<field name="name">Foreign Exchange Loss - (test)</field>
<field name="code">X2110</field>
<field name="user_type_id" ref="account.data_account_type_expenses"/>
<field name="reconcile" eval="False"/>
</record>
<record id="a_expense" model="account.account">
<field name="code">X2120</field>
<field name="name">Expenses - (test)</field>
<field name="user_type_id" ref="account.data_account_type_expenses"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_operating')])]"/>
</record>
<record id="a_salary_expense" model="account.account">
<field name="code">X2121</field>
<field name="name">Salary Expenses - (test)</field>
<field name="user_type_id" ref="account.data_account_type_expenses"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_operating')])]"/>
</record>
<record id="a_expense_invest" model="account.account">
<field name="code">X2122</field>
<field name="name">Purchase of Equipments - (test)</field>
<field name="user_type_id" ref="account.data_account_type_fixed_assets"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_investing')])]"/>
</record>
<record id="a_expense_finance" model="account.account">
<field name="code">X2123</field>
<field name="name">Bank Fees - (test)</field>
<field name="user_type_id" ref="account.data_account_type_expenses"/>
<field name="tag_ids" eval="[(6,0,[ref('account.account_tag_financing')])]"/>
</record>
<record id="a_capital" model="account.account">
<field name="code">X3001</field>
<field name="name">Capital</field>
<field name="user_type_id" ref="account.data_account_type_equity"/>
</record>
<record id="a_dividends" model="account.account">
<field name="code">X3002</field>
<field name="name">Dividends</field>
<field name="user_type_id" ref="account.data_account_type_equity"/>
</record>
<!-- Properties -->
<record forcecreate="True" id="property_account_receivable_id" model="ir.property">
<field name="name">property_account_receivable_id</field>
<field name="fields_id" search="[('model','=','res.partner'),('name','=','property_account_receivable_id')]"/>
<field eval="'account.account,'+str(a_recv)" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record forcecreate="True" id="property_account_payable_id" model="ir.property">
<field name="name">property_account_payable_id</field>
<field name="fields_id" search="[('model','=','res.partner'),('name','=','property_account_payable_id')]"/>
<field eval="'account.account,'+str(a_pay)" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record forcecreate="True" id="property_account_position_id" model="ir.property">
<field name="name">property_account_position_id</field>
<field name="fields_id" search="[('model','=','res.partner'),('name','=','property_account_position_id')]"/>
<field eval="False" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<!--
Account Journal
-->
<record id="sales_journal" model="account.journal">
<field name="name">Customer Invoices - Test</field>
<field name="code">TINV</field>
<field name="type">sale</field>
<field name="default_credit_account_id" ref="a_sale"/>
<field name="default_debit_account_id" ref="a_sale"/>
<field name="refund_sequence" eval="True"/>
</record>
<record id="expenses_journal" model="account.journal">
<field name="name">Vendor Bills - Test</field>
<field name="code">TEXJ</field>
<field name="type">purchase</field>
<field name="default_debit_account_id" ref="a_expense"/>
<field name="default_credit_account_id" ref="a_expense"/>
<field name="refund_sequence" eval="True"/>
</record>
<record id="bank_account" model="res.partner.bank">
<field name="acc_number">987654321</field>
<field name="bank_name">Bank</field>
<field name="partner_id" ref="base.main_partner"/>
</record>
<record id="bank_journal" model="account.journal">
<field name="name">Bank - Test</field>
<field name="code">TBNK</field>
<field name="type">bank</field>
<field name="default_debit_account_id" ref="bnk"/>
<field name="default_credit_account_id" ref="bnk"/>
</record>
<record id="cash_journal" model="account.journal">
<field name="name">Cash - Test</field>
<field name="code">TCSH</field>
<field name="type">cash</field>
<field name="profit_account_id" ref="rsa" />
<field name="loss_account_id" ref="rsa" />
<field name="default_debit_account_id" ref="cash"/>
<field name="default_credit_account_id" ref="cash"/>
</record>
<record id="miscellaneous_journal" model="account.journal">
<field name="name">Miscellaneous - Test</field>
<field name="code">TMIS</field>
<field name="type">general</field>
<field name="show_on_dashboard" eval="False"/>
</record>
<record id="currency_diff_journal" model="account.journal">
<field name="name">Currency Difference - Test</field>
<field name="code">CUR</field>
<field name="type">general</field>
<field name="default_debit_account_id" ref="income_fx_income"/>
<field name="default_credit_account_id" ref="income_fx_expense"/>
<field name="show_on_dashboard" eval="False"/>
</record>
<record id="bank_account_usd" model="res.partner.bank">
<field name="acc_number">123456789</field>
<field name="bank_name">Bank US</field>
<field name="partner_id" ref="base.main_partner"/>
</record>
<record id="bank_journal_usd" model="account.journal">
<field name="name">USD Bank - Test</field>
<field name="code">TUBK</field>
<field name="type">bank</field>
<field name="default_debit_account_id" ref="usd_bnk"/>
<field name="default_credit_account_id" ref="usd_bnk"/>
<field name="bank_account_id" ref="bank_account_usd"/>
</record>
<record id="base.main_company" model="res.company">
<field name="currency_exchange_journal_id" ref="currency_diff_journal"/>
</record>
<!--
Product income and expense accounts, default parameters
-->
<record id="property_account_expense_categ_id" model="ir.property">
<field name="name">property_account_expense_categ_id</field>
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_account_expense_categ_id')]"/>
<field eval="'account.account,'+str(ref('a_expense'))" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="property_account_income_categ_id" model="ir.property">
<field name="name">property_account_income_categ_id</field>
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_account_income_categ_id')]"/>
<field eval="'account.account,'+str(ref('a_sale'))" model="account.account" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
</data>
</odoo>
+1
View File
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from . import account_minimal_test
from . import test_account_move_out_invoice
from . import test_account_move_out_refund
from . import test_account_move_in_invoice
@@ -0,0 +1,294 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import SavepointCase
class AccountMinimalTest(SavepointCase):
""" This should be loaded for non python tests in other modules that require
accounting test data but that don't depend on any localization"""
@classmethod
def setUpClass(cls):
super(AccountMinimalTest, cls).setUpClass()
cls.create_accounting_minimal_data()
@classmethod
def create_accounting_minimal_data(cls):
cls.company = cls.env.company
cls.company.bank_account_code_prefix = 'X1100'
# Chart of Accounts
# Account Tags
cls.demo_capital_account = cls.env['account.account.tag'].create({'name': 'Demo Capital Account'})
cls.demo_stock_account = cls.env['account.account.tag'].create({'name': 'Demo Stock Account'})
cls.demo_sale_of_land_account = cls.env['account.account.tag'].create({'name': 'Demo Sale of Land Account'})
cls.demo_ceo_wages_account = cls.env['account.account.tag'].create({'name': 'Demo CEO Wages Account'})
cls.demo_office_furniture_account = cls.env['account.account.tag'].create({'name': 'Office Furniture'})
# Balance Sheet
cls.xfa = cls.env['account.account'].create({
'code': 'X1000',
'name': 'Fixed Assets - (test)',
'user_type_id': cls.env.ref('account.data_account_type_fixed_assets').id,
})
cls.cas = cls.env['account.account'].create({
'code': 'X1010',
'name': 'Current Assets - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
})
cls.stk = cls.env['account.account'].create({
'code': 'X1011',
'name': 'Purchased Stocks - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
'tag_ids': [(6, 0, [cls.demo_stock_account.id])]
})
cls.a_recv = cls.env['account.account'].create({
'code': 'X1012',
'name': 'Debtors - (test)',
'reconcile': True,
'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
})
cls.ova = cls.env['account.account'].create({
'code': 'X1013',
'name': 'VAT Paid- (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
})
cls.bnk = cls.env['account.account'].create({
'code': 'X1014',
'name': 'Bank Current Account - (test)',
'user_type_id': cls.env.ref('account.data_account_type_liquidity').id,
})
cls.cash = cls.env['account.account'].create({
'code': 'X1015',
'name': 'Cash - (test)',
'user_type_id': cls.env.ref('account.data_account_type_liquidity').id,
})
cls.o_income = cls.env['account.account'].create({
'code': 'X1016',
'name': 'Opening Income - (test)',
'user_type_id': cls.env.ref('account.data_account_type_other_income').id,
})
cls.usd_bnk = cls.env['account.account'].create({
'code': 'X1017',
'name': 'USD Bank Account - (test)',
'user_type_id': cls.env.ref('account.data_account_type_liquidity').id,
'currency_id': cls.env.ref('base.USD').id,
})
cls.transfer_account = cls.env['account.account'].create({
'code': 'X1019',
'name': 'Internal Transfert Account - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
'reconcile': True,
})
cls.ncas = cls.env['account.account'].create({
'code': 'X1020',
'name': 'Non-current Assets - (test)',
'user_type_id': cls.env.ref('account.data_account_type_non_current_assets').id,
})
cls.prepayements = cls.env['account.account'].create({
'code': 'X1030',
'name': 'Prepayments - (test)',
'user_type_id': cls.env.ref('account.data_account_type_prepayments').id,
})
cls.current_liabilities = cls.env['account.account'].create({
'code': 'X1110',
'name': 'Current Liabilities - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
})
cls.a_pay = cls.env['account.account'].create({
'code': 'X1111',
'name': 'Creditors - (test)',
'user_type_id': cls.env.ref('account.data_account_type_payable').id,
'reconcile': True,
})
cls.iva = cls.env['account.account'].create({
'code': 'X1112',
'name': 'VAT Received - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
})
cls.rsa = cls.env['account.account'].create({
'code': 'X1113',
'name': 'Reserve and Profit/Loss - (test)',
'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
})
cls.cas = cls.env['account.account'].create({
'code': 'X1120',
'name': 'Non-current Liabilities - (test)',
'user_type_id': cls.env.ref('account.data_account_type_non_current_liabilities').id,
})
cls.o_expense = cls.env['account.account'].create({
'code': 'X1114',
'name': 'Opening Expense - (test)',
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
})
# Profit and Loss
cls.income_fx_income = cls.env['account.account'].create({
'code': 'X2010',
'name': 'Foreign Exchange Gain - (test)',
'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
'reconcile': False,
})
cls.a_sale = cls.env['account.account'].create({
'code': 'X2020',
'name': 'Product Sales - (test)',
'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_operating').id])],
})
cls.a_sale_invest = cls.env['account.account'].create({
'code': 'X2021',
'name': 'Sale of Lands - (test)',
'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_investing').id])],
})
cls.a_sale_finance = cls.env['account.account'].create({
'code': 'X2022',
'name': 'Bank Accounts Interests - (test)',
'user_type_id': cls.env.ref('account.data_account_type_revenue').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_financing').id])],
})
cls.a_sale_finance = cls.env['account.account'].create({
'code': 'X2030',
'name': 'Cost of Goods Sold - (test)',
'user_type_id': cls.env.ref('account.data_account_type_direct_costs').id,
})
cls.income_fx_expense = cls.env['account.account'].create({
'code': 'X2110',
'name': 'Foreign Exchange Loss - (test)',
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
'reconcile': False,
})
cls.a_expense = cls.env['account.account'].create({
'code': 'X2120',
'name': 'Expenses - (test)',
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_operating').id])],
})
cls.a_salary_expense = cls.env['account.account'].create({
'code': 'X2121',
'name': 'Salary Expenses - (test)',
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_operating').id])],
})
cls.a_expense_invest = cls.env['account.account'].create({
'code': 'X2122',
'name': 'Purchase of Equipments - (test)',
'user_type_id': cls.env.ref('account.data_account_type_fixed_assets').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_investing').id])],
})
cls.a_expense_finance = cls.env['account.account'].create({
'code': 'X2123',
'name': 'Bank Fees - (test)',
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
'tag_ids': [(6, 0, [cls.env.ref('account.account_tag_financing').id])],
})
cls.a_capital = cls.env['account.account'].create({
'code': 'X3001',
'name': 'Capital',
'user_type_id': cls.env.ref('account.data_account_type_equity').id,
})
cls.a_dividends = cls.env['account.account'].create({
'code': 'X3002',
'name': 'Dividends',
'user_type_id': cls.env.ref('account.data_account_type_equity').id,
})
# Properties: Product income and expense accounts, default parameters
cls.env['ir.property'].create([{
'name': 'property_account_receivable_id',
'fields_id': cls.env['ir.model.fields'].search([('model', '=', 'res.partner'), ('name', '=', 'property_account_receivable_id')], limit=1).id,
'value': 'account.account,%s' % (cls.a_recv.id),
'company_id': cls.company.id,
}, {
'name': 'property_account_payable_id',
'fields_id': cls.env['ir.model.fields'].search([('model', '=', 'res.partner'), ('name', '=', 'property_account_payable_id')], limit=1).id,
'value': 'account.account,%s' % (cls.a_pay.id),
'company_id': cls.company.id,
}, {
'name': 'property_account_position_id',
'fields_id': cls.env['ir.model.fields'].search([('model', '=', 'res.partner'), ('name', '=', 'property_account_position_id')], limit=1).id,
'value': False,
'company_id': cls.company.id,
}, {
'name': 'property_account_expense_categ_id',
'fields_id': cls.env['ir.model.fields'].search([('model', '=', 'product.category'), ('name', '=', 'property_account_expense_categ_id')], limit=1).id,
'value': 'account.account,%s' % (cls.a_expense.id),
'company_id': cls.company.id,
}, {
'name': 'property_account_income_categ_id',
'fields_id': cls.env['ir.model.fields'].search([('model', '=', 'product.category'), ('name', '=', 'property_account_income_categ_id')], limit=1).id,
'value': 'account.account,%s' % (cls.a_sale.id),
'company_id': cls.company.id,
}])
# Bank Accounts
cls.bank_account = cls.env['res.partner.bank'].create({
'acc_number': '987654321',
'bank_name': 'Bank',
'partner_id': cls.company.partner_id.id,
})
cls.bank_account_usd = cls.env['res.partner.bank'].create({
'acc_number': '123456789',
'bank_name': 'Bank US',
'partner_id': cls.company.partner_id.id,
})
# Account Journal
cls.sales_journal = cls.env['account.journal'].create({
'name': 'Customer Invoices - Test',
'code': 'TINV',
'type': 'sale',
'default_credit_account_id': cls.a_sale.id,
'default_debit_account_id': cls.a_sale.id,
'refund_sequence': True,
})
cls.expenses_journal = cls.env['account.journal'].create({
'name': 'Vendor Bills - Test',
'code': 'TEXJ',
'type': 'purchase',
'default_credit_account_id': cls.a_expense.id,
'default_debit_account_id': cls.a_expense.id,
'refund_sequence': True,
})
cls.bank_journal = cls.env['account.journal'].create({
'name': 'Bank - Test',
'code': 'TBNK',
'type': 'bank',
'default_credit_account_id': cls.bnk.id,
'default_debit_account_id': cls.bnk.id,
})
cls.cash_journal = cls.env['account.journal'].create({
'name': 'Cash - Test',
'code': 'TCSH',
'type': 'cash',
'profit_account_id': cls.rsa.id,
'loss_account_id': cls.rsa.id,
'default_credit_account_id': cls.cash.id,
'default_debit_account_id': cls.cash.id,
})
cls.miscellaneous_journal = cls.env['account.journal'].create({
'name': 'Miscellaneous - Test',
'code': 'TMIS',
'type': 'general',
'show_on_dashboard': False,
})
cls.currency_diff_journal = cls.env['account.journal'].create({
'name': 'Currency Difference - Test',
'code': 'CUR',
'type': 'general',
'default_credit_account_id': cls.income_fx_expense.id,
'default_debit_account_id': cls.income_fx_income.id,
'show_on_dashboard': False,
})
cls.bank_journal_usd = cls.env['account.journal'].create({
'name': 'USD Bank - Test',
'code': 'TUBK',
'type': 'bank',
'default_credit_account_id': cls.usd_bnk.id,
'default_debit_account_id': cls.usd_bnk.id,
'bank_account_id': cls.bank_account_usd.id,
})
cls.company.currency_exchange_journal_id = cls.currency_diff_journal.id
+9 -8
View File
@@ -4,21 +4,22 @@ import logging
_logger = logging.getLogger(__name__)
from odoo.tests.common import HttpCase, tagged
from odoo.addons.account.tests.account_minimal_test import AccountMinimalTest
class AccountingTestCase(HttpCase):
""" This class extends the base TransactionCase, in order to test the
class AccountingTestCase(AccountMinimalTest):
""" This class extends the base SavePoint Case, in order to test the
accounting with localization setups. It is configured to run the tests after
the installation of all modules, and will SKIP TESTS if it cannot find an already
configured accounting (which means no localization module has been installed).
"""
def setUp(self):
super(AccountingTestCase, self).setUp()
domain = [('company_id', '=', self.env.ref('base.main_company').id)]
if not self.env['account.account'].search_count(domain):
@classmethod
def setUpClass(cls):
super(AccountingTestCase, cls).setUpClass()
domain = [('company_id', '=', cls.env.company.id)]
if not cls.env['account.account'].search_count(domain):
_logger.warning('Test skipped because there is no chart of account defined ...')
self.skipTest("No Chart of account found")
cls.skipTest(cls, "No Chart of account found")
def ensure_account_property(self, property_name):
'''Ensure the ir.property targeting an account.account passed as parameter exists.
@@ -2,9 +2,9 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import SavepointCase, HttpCase, tagged
from odoo.addons.base.tests.common import SavepointCaseWithUserDemo
class TestAccountNoChartCommon(SavepointCase):
class TestAccountNoChartCommon(SavepointCaseWithUserDemo):
""" Some tests required to be executed at module installation, and not 'post install', like moslty
of accounting tests, since a chart of account is required
This test setup class provides data for test suite to make business flow working without a chart
@@ -1,4 +1,7 @@
# -*- coding: utf-8 -*-
import unittest
from odoo import fields
from odoo.tests.common import Form, SavepointCase
from odoo.tests import tagged
@@ -19,7 +22,7 @@ class AccountingSavepointCase(SavepointCase):
if not chart_template:
chart_template = cls.env.ref('l10n_generic_coa.configurable_chart_template', raise_if_not_found=False)
if not chart_template:
cls.skipTest("Accounting Tests skipped because the user's company has no chart of accounts.")
cls.skipTest(cls, "Accounting Tests skipped because the user's company has no chart of accounts.")
# Create user.
user = cls.env['res.users'].create({
+18 -17
View File
@@ -5,30 +5,31 @@ class AccountTestUsers(AccountingTestCase):
"""Tests for diffrent type of user 'Accountant/Adviser' and added groups"""
def setUp(self):
super(AccountTestUsers, self).setUp()
self.res_user_model = self.env['res.users']
self.main_company = self.env.ref('base.main_company')
self.main_partner = self.env.ref('base.main_partner')
self.main_bank = self.env.ref('base.res_bank_1')
res_users_account_user = self.env.ref('account.group_account_invoice')
res_users_account_manager = self.env.ref('account.group_account_manager')
partner_manager = self.env.ref('base.group_partner_manager')
self.tax_model = self.env['account.tax']
self.account_model = self.env['account.account']
self.account_type_model = self.env['account.account.type']
self.currency_euro = self.env.ref('base.EUR')
@classmethod
def setUpClass(cls):
super(AccountTestUsers, cls).setUpClass()
cls.res_user_model = cls.env['res.users']
cls.main_company = cls.env.ref('base.main_company')
cls.main_partner = cls.env.ref('base.main_partner')
cls.main_bank = cls.env.ref('base.res_bank_1')
res_users_account_user = cls.env.ref('account.group_account_invoice')
res_users_account_manager = cls.env.ref('account.group_account_manager')
partner_manager = cls.env.ref('base.group_partner_manager')
cls.tax_model = cls.env['account.tax']
cls.account_model = cls.env['account.account']
cls.account_type_model = cls.env['account.account.type']
cls.currency_euro = cls.env.ref('base.EUR')
self.account_user = self.res_user_model.with_context({'no_reset_password': True}).create(dict(
cls.account_user = cls.res_user_model.with_context({'no_reset_password': True}).create(dict(
name="Accountant",
company_id=self.main_company.id,
company_id=cls.main_company.id,
login="acc",
email="accountuser@yourcompany.com",
groups_id=[(6, 0, [res_users_account_user.id, partner_manager.id])]
))
self.account_manager = self.res_user_model.with_context({'no_reset_password': True}).create(dict(
cls.account_manager = cls.res_user_model.with_context({'no_reset_password': True}).create(dict(
name="Adviser",
company_id=self.main_company.id,
company_id=cls.main_company.id,
login="fm",
email="accountmanager@yourcompany.com",
groups_id=[(6, 0, [res_users_account_manager.id, partner_manager.id])]
@@ -18,14 +18,25 @@ class TestAccountJournalDashboard(AccountTestUsers):
'type': 'sale',
})
res_partner_3 = self.env['res.partner'].create({
'name': 'Gemini Furniture',
})
product_product_1 = self.env['product.product'].create({
'name': 'Virtual Interior Design',
'standard_price': 20.5,
'list_price': 30.75,
'type': 'service',
})
invoice = self.env['account.move'].create({
'type': 'out_invoice',
'journal_id': journal.id,
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'invoice_date': date_invoice,
'date': date_invoice,
'invoice_line_ids': [(0, 0, {
'product_id': self.env.ref('product.product_product_1').id,
'product_id': product_product_1.id,
'quantity': 40.0,
'name': 'product test 1',
'discount': 10.00,
@@ -35,11 +46,11 @@ class TestAccountJournalDashboard(AccountTestUsers):
refund = self.env['account.move'].create({
'type': 'out_refund',
'journal_id': journal.id,
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'invoice_date': '2019-01-21',
'date': date_invoice,
'invoice_line_ids': [(0, 0, {
'product_id': self.env.ref('product.product_product_1').id,
'product_id': product_product_1.id,
'quantity': 1.0,
'name': 'product test 1',
'price_unit': 13.3,
@@ -51,25 +51,3 @@ class TestAccountMovePartnerCount(TransactionCase):
self.journal.with_env(env).unlink()
self.account_income.with_env(env).unlink()
self.partner.with_env(env).unlink()
def test_account_move_count(self):
# T2 create and post account move
with self.registry.cursor() as cr:
env = self.env(cr=cr)
self.move.with_env(env).post()
partner = self.partner.with_env(env)
self.assertEqual(partner.supplier_rank, 0)
self.assertEqual(partner.customer_rank, 1)
def test_account_move_count_concurrent(self):
# T2 Lock the partner row
with self.registry.cursor() as cr:
cr.execute("""SELECT id FROM res_partner WHERE id = %s FOR UPDATE""" % self.partner.id)
# T3 concurrently posts account move and tries to update partner
with self.registry.cursor() as cr:
env = self.env(cr=cr)
self.move.with_env(env).state = 'posted'
self.assertEqual(self.partner.with_env(env).customer_rank,
0, "It should not wait the concurrent transaction for the update")
@@ -7,33 +7,34 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestAccountMoveRounding(AccountingTestCase):
def setUp(self):
super(TestAccountMoveRounding, self).setUp()
self.currency = self.env['res.currency'].create({
@classmethod
def setUpClass(cls):
super(TestAccountMoveRounding, cls).setUpClass()
cls.currency = cls.env['res.currency'].create({
'name': "RAM",
'symbol': "🐏",
'rounding': 0.01,
})
self.company = self.env['res.company'].create({
cls.company = cls.env['res.company'].create({
'name': "SHEEP",
'currency_id': self.currency.id,
'currency_id': cls.currency.id,
})
self.account_type = self.env['account.account.type'].create(
{'name': 'BAAH',
'internal_group': 'asset',
'type': 'receivable'
cls.account_type = cls.env['account.account.type'].create({
'name': 'BAAH',
'internal_group': 'asset',
'type': 'receivable'
})
self.journal = self.env['account.journal'].create({
'company_id': self.company.id,
cls.journal = cls.env['account.journal'].create({
'company_id': cls.company.id,
'name': 'LAMB',
'code': 'L',
'code': 'LL',
'type': 'purchase',
})
self.account = self.env['account.account'].create({
'company_id': self.company.id,
cls.account = cls.env['account.account'].create({
'company_id': cls.company.id,
'name': 'EWE',
'code': 'E',
'user_type_id': self.account_type.id,
'code': 'EE',
'user_type_id': cls.account_type.id,
'reconcile': True,
})
+17 -11
View File
@@ -1,18 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import tagged, HttpCase
from odoo import tools
@tagged('-at_install', 'post_install', 'document_layout')
class TestAccountDocumentLayout(HttpCase):
def test_render_account_document_layout(self):
report_layout = self.env.ref('web.report_layout_standard')
main_company = self.env.ref('base.main_company')
main_company.write({
'primary_color': '#123456',
'secondary_color': '#789101',
'external_report_layout_id': report_layout.view_id.id,
})
self.env.ref('account.account_invoices_without_payment').write({
'report_type': 'qweb-html',
})
self.start_tour("/web", 'account_render_report', login='admin', timeout=200)
# YTI TODO: Adapt this tour without demo data
if not tools.config["without_demo"]:
report_layout = self.env.ref('web.report_layout_standard')
main_company = self.env.ref('base.main_company')
main_company.write({
'primary_color': '#123456',
'secondary_color': '#789101',
'external_report_layout_id': report_layout.view_id.id,
})
self.env.ref('account.account_invoices_without_payment').write({
'report_type': 'qweb-html',
})
self.start_tour("/web", 'account_render_report', login='admin', timeout=200)
@@ -5,13 +5,14 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestBankStatementReconciliation(AccountingTestCase):
def setUp(self):
super(TestBankStatementReconciliation, self).setUp()
self.bs_model = self.env['account.bank.statement']
self.bsl_model = self.env['account.bank.statement.line']
self.partner = self.env['res.partner'].create({'name': 'test'})
self.currency_usd_id = self.env.ref("base.USD").id
self.currency_euro_id = self.env.ref("base.EUR").id
@classmethod
def setUpClass(cls):
super(TestBankStatementReconciliation, cls).setUpClass()
cls.bs_model = cls.env['account.bank.statement']
cls.bsl_model = cls.env['account.bank.statement.line']
cls.partner = cls.env['res.partner'].create({'name': 'test'})
cls.currency_usd_id = cls.env.ref("base.USD").id
cls.currency_euro_id = cls.env.ref("base.EUR").id
def test_full_reconcile(self):
self._reconcile_invoice_with_statement('pay_val')
+23 -18
View File
@@ -1,55 +1,60 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import common
class TestFiscalPosition(common.TransactionCase):
class TestFiscalPosition(common.SavepointCase):
"""Tests for fiscal positions in auto apply (account.fiscal.position).
If a partner has a vat number, the fiscal positions with "vat_required=True"
are preferred.
"""
def setUp(self):
super(TestFiscalPosition, self).setUp()
self.fp = self.env['account.fiscal.position']
@classmethod
def setUpClass(cls):
super(TestFiscalPosition, cls).setUpClass()
cls.fp = cls.env['account.fiscal.position']
# reset any existing FP
self.fp.search([]).write({'auto_apply': False})
cls.fp.search([]).write({'auto_apply': False})
self.res_partner = self.env['res.partner']
self.be = be = self.env.ref('base.be')
self.fr = fr = self.env.ref('base.fr')
self.mx = mx = self.env.ref('base.mx')
self.eu = eu = self.env.ref('base.europe')
self.state_fr = self.env['res.country.state'].create(dict(
cls.res_partner = cls.env['res.partner']
cls.be = be = cls.env.ref('base.be')
cls.fr = fr = cls.env.ref('base.fr')
cls.mx = mx = cls.env.ref('base.mx')
cls.eu = eu = cls.env.ref('base.europe')
cls.state_fr = cls.env['res.country.state'].create(dict(
name="State",
code="ST",
country_id=fr.id))
self.jc = self.res_partner.create(dict(
cls.jc = cls.res_partner.create(dict(
name="JCVD",
vat="BE0477472701",
country_id=be.id))
self.ben = self.res_partner.create(dict(
cls.ben = cls.res_partner.create(dict(
name="BP",
country_id=be.id))
self.george = self.res_partner.create(dict(
cls.george = cls.res_partner.create(dict(
name="George",
vat="BE0477472701",
country_id=fr.id))
self.alberto = self.res_partner.create(dict(
cls.alberto = cls.res_partner.create(dict(
name="Alberto",
vat="BE0477472701",
country_id=mx.id))
self.be_nat = self.fp.create(dict(
cls.be_nat = cls.fp.create(dict(
name="BE-NAT",
auto_apply=True,
country_id=be.id,
vat_required=False,
sequence=10))
self.fr_b2c = self.fp.create(dict(
cls.fr_b2c = cls.fp.create(dict(
name="EU-VAT-FR-B2C",
auto_apply=True,
country_id=fr.id,
vat_required=False,
sequence=40))
self.fr_b2b = self.fp.create(dict(
cls.fr_b2b = cls.fp.create(dict(
name="EU-VAT-FR-B2B",
auto_apply=True,
country_id=fr.id,
+14 -10
View File
@@ -1,22 +1,26 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.base.tests.common import SavepointCaseWithUserDemo
from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.tests.common import Form
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestInvoiceTaxes(AccountingTestCase):
class TestInvoiceTaxes(AccountingTestCase, SavepointCaseWithUserDemo):
def setUp(self):
super(TestInvoiceTaxes, self).setUp()
@classmethod
def setUpClass(cls):
super(TestInvoiceTaxes, cls).setUpClass()
self.percent_tax_1 = self.env['account.tax'].create({
cls.percent_tax_1 = cls.env['account.tax'].create({
'name': '21%',
'amount_type': 'percent',
'amount': 21,
'sequence': 10,
})
self.percent_tax_1_incl = self.env['account.tax'].create({
cls.percent_tax_1_incl = cls.env['account.tax'].create({
'name': '21% incl',
'amount_type': 'percent',
'amount': 21,
@@ -24,19 +28,19 @@ class TestInvoiceTaxes(AccountingTestCase):
'include_base_amount': True,
'sequence': 20,
})
self.percent_tax_2 = self.env['account.tax'].create({
cls.percent_tax_2 = cls.env['account.tax'].create({
'name': '12%',
'amount_type': 'percent',
'amount': 12,
'sequence': 30,
})
self.group_tax = self.env['account.tax'].create({
cls.group_tax = cls.env['account.tax'].create({
'name': 'group 12% + 21%',
'amount_type': 'group',
'amount': 21,
'children_tax_ids': [
(4, self.percent_tax_1_incl.id),
(4, self.percent_tax_2.id)
(4, cls.percent_tax_1_incl.id),
(4, cls.percent_tax_2.id)
],
'sequence': 40,
})
@@ -48,7 +52,7 @@ class TestInvoiceTaxes(AccountingTestCase):
'''
self_ctx = self.env['account.move'].with_context(default_type=inv_type)
invoice_form = Form(self_ctx)
invoice_form.partner_id = self.env.ref('base.partner_demo')
invoice_form.partner_id = self.partner_demo
for amount, taxes in taxes_per_line:
with invoice_form.invoice_line_ids.new() as invoice_line_form:
+41 -6
View File
@@ -1,3 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.tests import tagged
from odoo.tests.common import Form
@@ -8,21 +11,29 @@ import time
class TestPayment(AccountingTestCase):
def setUp(self):
self.env.ref('base.main_company').currency_id = self.env.ref('base.USD')
super(TestPayment, self).setUp()
self.register_payments_model = self.env['account.payment.register'].with_context(active_model='account.move')
self.payment_model = self.env['account.payment']
self.acc_bank_stmt_model = self.env['account.bank.statement']
self.acc_bank_stmt_line_model = self.env['account.bank.statement.line']
self.partner_agrolait = self.env.ref("base.res_partner_2")
self.partner_china_exp = self.env.ref("base.res_partner_3")
self.partner_agrolait = self.env['res.partner'].create({'name': 'Agrolait', 'is_company': True})
self.partner_china_exp = self.env['res.partner'].create({'name': 'China Export', 'is_company': True})
self.currency_chf_id = self.env.ref("base.CHF").id
self.currency_usd_id = self.env.ref("base.USD").id
self.currency_eur_id = self.env.ref("base.EUR").id
company = self.env.ref('base.main_company')
self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.currency_eur_id, company.id])
self.product = self.env.ref("product.product_product_4")
self.product = self.env['product.product'].create({
'name': 'Product Product 4',
'standard_price': 500.0,
'list_price': 750.0,
'type': 'consu',
'categ_id': self.env.ref('product.product_category_all').id,
})
self.payment_method_manual_in = self.env.ref("account.account_payment_method_manual_in")
self.payment_method_manual_out = self.env.ref("account.account_payment_method_manual_out")
@@ -38,12 +49,30 @@ class TestPayment(AccountingTestCase):
self.bank_journal_usd = self.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': self.currency_usd_id})
self.account_usd = self.bank_journal_usd.default_debit_account_id
self.transfer_account = self.env['res.users'].browse(self.env.uid).company_id.transfer_account_id
self.diff_income_account = self.env['res.users'].browse(self.env.uid).company_id.income_currency_exchange_account_id
self.diff_expense_account = self.env['res.users'].browse(self.env.uid).company_id.expense_currency_exchange_account_id
if not self.env.user.company_id.transfer_account_id:
self.env.user.company_id.transfer_account_id = self.usd_bnk
self.transfer_account = self.env.user.company_id.transfer_account_id
self.diff_income_account = self.env.user.company_id.income_currency_exchange_account_id
self.diff_expense_account = self.env.user.company_id.expense_currency_exchange_account_id
self.form_payment = Form(self.env['account.payment'])
self.env['res.currency.rate'].create([
{
'currency_id': self.env.ref('base.EUR').id,
'name': '2010-01-02',
'rate': 1.0,
}, {
'currency_id': self.env.ref('base.USD').id,
'name': '2010-01-02',
'rate': 1.2834,
}, {
'currency_id': self.env.ref('base.USD').id,
'name': time.strftime('%Y-06-05'),
'rate': 1.5289,
}
])
def create_invoice(self, amount=100, type='out_invoice', currency_id=None, partner=None, account_id=None):
""" Returns an open invoice """
invoice = self.env['account.move'].create({
@@ -130,6 +159,12 @@ class TestPayment(AccountingTestCase):
])
def test_payment_chf_journal_usd(self):
self.env['res.currency.rate'].create({
'rate': 1.3086,
'currency_id': self.currency_chf_id,
'name': '2010-01-02',
})
payment = self.payment_model.create({
'payment_date': time.strftime('%Y') + '-07-15',
'payment_type': 'outbound',
@@ -14,6 +14,13 @@ class TestUi(tests.HttpCase):
def test_01_portal_attachment(self):
"""Test the portal chatter attachment route."""
miscellaneous_journal = self.env['account.journal'].create({
'name': 'Miscellaneous - Test',
'code': 'TMISC',
'type': 'general',
'show_on_dashboard': False,
})
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
# For this test we need a parent document with an access_token field
# (in this case from portal.mixin) and also inheriting mail.thread.
+128 -83
View File
@@ -1,4 +1,7 @@
from odoo import api, fields
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, tools
from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.exceptions import UserError
from odoo.tests import Form, tagged
@@ -6,7 +9,6 @@ import time
from datetime import timedelta
import unittest
# TODO in master
# The name of this class should be TestReconciliationHelpers
class TestReconciliation(AccountingTestCase):
@@ -17,94 +19,115 @@ class TestReconciliation(AccountingTestCase):
the result will be balanced.
"""
def setUp(self):
super(TestReconciliation, self).setUp()
self.acc_bank_stmt_model = self.env['account.bank.statement']
self.acc_bank_stmt_line_model = self.env['account.bank.statement.line']
self.res_currency_model = self.registry('res.currency')
self.res_currency_rate_model = self.registry('res.currency.rate')
@classmethod
def setUpClass(cls):
super(TestReconciliation, cls).setUpClass()
cls.company = cls.env['res.company'].create({
'name': 'A test company',
'currency_id': cls.env.ref('base.EUR').id
})
cls.env.user.company_id = cls.company
# Generate minimal data for my new company
cls.create_accounting_minimal_data()
self.partner_agrolait = self.env.ref("base.res_partner_2")
self.partner_agrolait_id = self.partner_agrolait.id
self.currency_swiss_id = self.env.ref("base.CHF").id
self.currency_usd_id = self.env.ref("base.USD").id
self.currency_euro_id = self.env.ref("base.EUR").id
company = self.env.ref('base.main_company')
self.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [self.currency_euro_id, company.id])
self.account_rcv = self.partner_agrolait.property_account_receivable_id or self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_receivable').id)], limit=1)
self.account_rsa = self.partner_agrolait.property_account_payable_id or self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1)
self.product = self.env.ref("product.product_product_4")
cls.acc_bank_stmt_model = cls.env['account.bank.statement']
cls.acc_bank_stmt_line_model = cls.env['account.bank.statement.line']
cls.res_currency_model = cls.registry('res.currency')
cls.res_currency_rate_model = cls.registry('res.currency.rate')
self.bank_journal_euro = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
self.account_euro = self.bank_journal_euro.default_debit_account_id
cls.partner_agrolait = cls.env['res.partner'].create({
'name': 'Deco Addict',
'is_company': True,
'country_id': cls.env.ref('base.us').id,
})
cls.partner_agrolait_id = cls.partner_agrolait.id
cls.currency_swiss_id = cls.env.ref("base.CHF").id
cls.currency_usd_id = cls.env.ref("base.USD").id
cls.currency_euro_id = cls.env.ref("base.EUR").id
# YTI FIXME Some of those lines should be useless now
cls.cr.execute("UPDATE res_company SET currency_id = %s WHERE id = %s", [cls.currency_euro_id, cls.company.id])
cls.account_rcv = cls.partner_agrolait.property_account_receivable_id or cls.env['account.account'].search([('user_type_id', '=', cls.env.ref('account.data_account_type_receivable').id)], limit=1)
cls.account_rsa = cls.partner_agrolait.property_account_payable_id or cls.env['account.account'].search([('user_type_id', '=', cls.env.ref('account.data_account_type_payable').id)], limit=1)
cls.product = cls.env['product.product'].create({
'name': 'Product Product 4',
'standard_price': 500.0,
'list_price': 750.0,
'type': 'consu',
'categ_id': cls.env.ref('product.product_category_all').id,
})
self.bank_journal_usd = self.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': self.currency_usd_id})
self.account_usd = self.bank_journal_usd.default_debit_account_id
cls.bank_journal_euro = cls.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
cls.account_euro = cls.bank_journal_euro.default_debit_account_id
self.fx_journal = self.env['res.users'].browse(self.env.uid).company_id.currency_exchange_journal_id
self.diff_income_account = self.env['res.users'].browse(self.env.uid).company_id.income_currency_exchange_account_id
self.diff_expense_account = self.env['res.users'].browse(self.env.uid).company_id.expense_currency_exchange_account_id
cls.bank_journal_usd = cls.env['account.journal'].create({'name': 'Bank US', 'type': 'bank', 'code': 'BNK68', 'currency_id': cls.currency_usd_id})
cls.account_usd = cls.bank_journal_usd.default_debit_account_id
self.inbound_payment_method = self.env['account.payment.method'].create({
cls.fx_journal = cls.env['res.users'].browse(cls.env.uid).company_id.currency_exchange_journal_id
cls.diff_income_account = cls.env['res.users'].browse(cls.env.uid).company_id.income_currency_exchange_account_id
cls.diff_expense_account = cls.env['res.users'].browse(cls.env.uid).company_id.expense_currency_exchange_account_id
cls.inbound_payment_method = cls.env['account.payment.method'].create({
'name': 'inbound',
'code': 'IN',
'payment_type': 'inbound',
})
self.expense_account = self.env['account.account'].create({
cls.expense_account = cls.env['account.account'].create({
'name': 'EXP',
'code': 'EXP',
'user_type_id': self.env.ref('account.data_account_type_expenses').id,
'company_id': company.id,
'user_type_id': cls.env.ref('account.data_account_type_expenses').id,
'company_id': cls.company.id,
})
# cash basis intermediary account
self.tax_waiting_account = self.env['account.account'].create({
cls.tax_waiting_account = cls.env['account.account'].create({
'name': 'TAX_WAIT',
'code': 'TWAIT',
'user_type_id': self.env.ref('account.data_account_type_current_liabilities').id,
'user_type_id': cls.env.ref('account.data_account_type_current_liabilities').id,
'reconcile': True,
'company_id': company.id,
'company_id': cls.company.id,
})
# cash basis final account
self.tax_final_account = self.env['account.account'].create({
cls.tax_final_account = cls.env['account.account'].create({
'name': 'TAX_TO_DEDUCT',
'code': 'TDEDUCT',
'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
'company_id': company.id,
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
'company_id': cls.company.id,
})
self.tax_base_amount_account = self.env['account.account'].create({
cls.tax_base_amount_account = cls.env['account.account'].create({
'name': 'TAX_BASE',
'code': 'TBASE',
'user_type_id': self.env.ref('account.data_account_type_current_assets').id,
'company_id': company.id,
'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
'company_id': cls.company.id,
})
# Journals
self.purchase_journal = self.env['account.journal'].create({
cls.purchase_journal = cls.env['account.journal'].create({
'name': 'purchase',
'code': 'PURCH',
'type': 'purchase',
'default_credit_account_id': cls.a_expense.id,
'default_debit_account_id': cls.a_expense.id,
})
self.cash_basis_journal = self.env['account.journal'].create({
cls.cash_basis_journal = cls.env['account.journal'].create({
'name': 'CABA',
'code': 'CABA',
'type': 'general',
})
self.general_journal = self.env['account.journal'].create({
cls.general_journal = cls.env['account.journal'].create({
'name': 'general',
'code': 'GENE',
'type': 'general',
})
# Tax Cash Basis
self.tax_cash_basis = self.env['account.tax'].create({
cls.tax_cash_basis = cls.env['account.tax'].create({
'name': 'cash basis 20%',
'type_tax_use': 'purchase',
'company_id': company.id,
'company_id': cls.company.id,
'amount': 20,
'tax_exigibility': 'on_payment',
'cash_basis_transition_account_id': self.tax_waiting_account.id,
'cash_basis_base_account_id': self.tax_base_amount_account.id,
'cash_basis_transition_account_id': cls.tax_waiting_account.id,
'cash_basis_base_account_id': cls.tax_base_amount_account.id,
'invoice_repartition_line_ids': [
(0,0, {
'factor_percent': 100,
@@ -114,7 +137,7 @@ class TestReconciliation(AccountingTestCase):
(0,0, {
'factor_percent': 100,
'repartition_type': 'tax',
'account_id': self.tax_final_account.id,
'account_id': cls.tax_final_account.id,
}),
],
'refund_repartition_line_ids': [
@@ -126,13 +149,29 @@ class TestReconciliation(AccountingTestCase):
(0,0, {
'factor_percent': 100,
'repartition_type': 'tax',
'account_id': self.tax_final_account.id,
'account_id': cls.tax_final_account.id,
}),
],
})
cls.env['res.currency.rate'].create([
{
'currency_id': cls.env.ref('base.EUR').id,
'name': '2010-01-02',
'rate': 1.0,
}, {
'currency_id': cls.env.ref('base.USD').id,
'name': '2010-01-02',
'rate': 1.2834,
}, {
'currency_id': cls.env.ref('base.USD').id,
'name': time.strftime('%Y-06-05'),
'rate': 1.5289,
}
])
def _create_invoice(self, type='out_invoice', invoice_amount=50, currency_id=None, partner_id=None, date_invoice=None, payment_term_id=False, auto_validate=False):
date_invoice = date_invoice or time.strftime('%Y') + '-07-01'
invoice_vals = {
'type': type,
'partner_id': partner_id or self.partner_agrolait_id,
@@ -258,6 +297,11 @@ class TestReconciliationExec(TestReconciliation):
])
def test_statement_usd_invoice_chf_transaction_chf(self):
self.env['res.currency.rate'].create({
'rate': 1.3086,
'currency_id': self.env.ref('base.CHF').id,
'name': '2010-01-02',
})
customer_move_lines, supplier_move_lines = self.make_customer_and_supplier_flows(self.currency_swiss_id, 50, self.bank_journal_usd, 42, 50, self.currency_swiss_id)
self.assertRecordValues(customer_move_lines, [
{'debit': 0.0, 'credit': 27.47, 'amount_currency': -50, 'currency_id': self.currency_swiss_id},
@@ -676,7 +720,7 @@ class TestReconciliationExec(TestReconciliation):
# Balance Debit = 18.75
# Counterpart Credit goes in Exchange diff
dest_journal_id = self.env['account.journal'].search([('type', '=', 'purchase'), ('company_id', '=', self.env.ref('base.main_company').id)], limit=1)
dest_journal_id = self.env['account.journal'].search([('type', '=', 'purchase'), ('company_id', '=', self.company.id)], limit=1)
self.bank_journal_euro.write({'default_debit_account_id': self.account_rsa.id,
'default_credit_account_id': self.account_rsa.id})
@@ -686,17 +730,17 @@ class TestReconciliationExec(TestReconciliation):
self.env['res.currency.rate'].create({'name': time.strftime('%Y') + '-' + '07' + '-01',
'rate': 0.5,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id})
'company_id': self.company.id})
self.env['res.currency.rate'].create({'name': time.strftime('%Y') + '-' + '08' + '-01',
'rate': 0.75,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id})
'company_id': self.company.id})
self.env['res.currency.rate'].create({'name': time.strftime('%Y') + '-' + '09' + '-01',
'rate': 0.80,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id})
'company_id': self.company.id})
# Preparing Invoices (from vendor)
invoice_a = self.env['account.move'].with_context(default_type='in_invoice').create({
@@ -727,7 +771,7 @@ class TestReconciliationExec(TestReconciliation):
'amount': 25,
'currency_id': self.currency_usd_id,
'journal_id': self.bank_journal_euro.id,
'company_id': self.env.ref('base.main_company').id,
'company_id': self.company.id,
'payment_date': time.strftime('%Y') + '-' + '07' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
@@ -739,7 +783,7 @@ class TestReconciliationExec(TestReconciliation):
'amount': 50,
'currency_id': self.currency_usd_id,
'journal_id': self.bank_journal_euro.id,
'company_id': self.env.ref('base.main_company').id,
'company_id': self.company.id,
'payment_date': time.strftime('%Y') + '-' + '08' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
@@ -751,7 +795,7 @@ class TestReconciliationExec(TestReconciliation):
'amount': 25,
'currency_id': self.currency_usd_id,
'journal_id': self.bank_journal_euro.id,
'company_id': self.env.ref('base.main_company').id,
'company_id': self.company.id,
'payment_date': time.strftime('%Y') + '-' + '09' + '-01',
'partner_id': self.partner_agrolait_id,
'payment_method_id': self.env.ref('account.account_payment_method_manual_out').id,
@@ -840,13 +884,13 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.0,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': self.company.id
})
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-08-01',
'rate': 0.5,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': self.company.id
})
inv = self.create_invoice(invoice_amount=111, currency_id=self.currency_usd_id)
payment = self.env['account.payment'].create({
@@ -946,13 +990,13 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.0,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': self.company.id
})
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-08-01',
'rate': 0.5,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': self.company.id
})
inv = self.create_invoice(invoice_amount=111, currency_id=self.currency_usd_id)
payment = self.env['account.payment'].create({
@@ -994,7 +1038,7 @@ class TestReconciliationExec(TestReconciliation):
####
dest_journal_id = self.env['account.journal'].search(
[('type', '=', 'purchase'),
('company_id', '=', self.env.ref('base.main_company').id)],
('company_id', '=', self.company.id)],
limit=1)
# Delete any old rate - to make sure that we use the ones we need.
@@ -1104,7 +1148,7 @@ class TestReconciliationExec(TestReconciliation):
# one is subject to a cash basis tax
# the other is not subject to tax
company = self.env.ref('base.main_company')
company = self.company
company.tax_cash_basis_journal_id = self.cash_basis_journal
purchase_move = self.env['account.move'].create({
@@ -1196,7 +1240,7 @@ class TestReconciliationExec(TestReconciliation):
# with 2 payment terms
# And partial payment not martching any payment term
company = self.env.ref('base.main_company')
company = self.company
company.tax_cash_basis_journal_id = self.cash_basis_journal
tax_cash_basis10percent = self.tax_cash_basis.copy({'amount': 10})
tax_waiting_account10 = self.tax_waiting_account.copy({
@@ -1395,7 +1439,7 @@ class TestReconciliationExec(TestReconciliation):
Taxes -848.16 USD 0.00 17,094.66
"""
company = self.env.ref('base.main_company')
company = self.company
company.country_id = self.ref('base.us')
company.tax_cash_basis_journal_id = self.cash_basis_journal
@@ -1558,7 +1602,7 @@ class TestReconciliationExec(TestReconciliation):
Taxes -848.16 USD 0.00 17,094.66
"""
company = self.env.ref('base.main_company')
company = self.company
company.country_id = self.ref('base.us')
company.tax_cash_basis_journal_id = self.cash_basis_journal
@@ -1698,7 +1742,7 @@ class TestReconciliationExec(TestReconciliation):
.debit, 17094.66)
def test_reconciliation_cash_basis_revert(self):
company = self.env.ref('base.main_company')
company = self.company
company.tax_cash_basis_journal_id = self.cash_basis_journal
tax_cash_basis10percent = self.tax_cash_basis.copy({'amount': 10})
self.tax_waiting_account.reconcile = True
@@ -1763,7 +1807,7 @@ class TestReconciliationExec(TestReconciliation):
self.assertEqual(reverted_expected.full_reconcile_id, inv_line.full_reconcile_id)
def test_reconciliation_revert_future(self):
company = self.env.ref('base.main_company')
company = self.company
company.tax_cash_basis_journal_id = self.cash_basis_journal
tax_cash_basis10percent = self.tax_cash_basis.copy({'amount': 10})
self.tax_waiting_account.reconcile = True
@@ -1832,6 +1876,7 @@ class TestReconciliationExec(TestReconciliation):
self.assertEqual(reverse_move.date, reverse_date)
def test_reconciliation_cash_basis_foreign_currency_low_values(self):
self.company.tax_cash_basis_journal_id = self.cash_basis_journal
journal = self.env['account.journal'].create({
'name': 'Bank', 'type': 'bank', 'code': 'THE',
'currency_id': self.currency_usd_id,
@@ -1842,7 +1887,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y-01-01'),
'rate': 1/17.0,
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id,
'company_id': self.company.id,
})
move_form = Form(self.env['account.move'].with_context(default_type='out_invoice'))
@@ -1958,7 +2003,7 @@ class TestReconciliationExec(TestReconciliation):
self.assertEqual(aml.amount_residual, 0.0)
def test_inv_refund_foreign_payment_writeoff_domestic2(self):
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -1970,7 +2015,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.110600, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': self.company.id
})
inv1 = self.create_invoice(invoice_amount=800, currency_id=self.currency_usd_id)
inv2 = self.create_invoice(type="out_refund", invoice_amount=400, currency_id=self.currency_usd_id)
@@ -2025,7 +2070,7 @@ class TestReconciliationExec(TestReconciliation):
Reconciliation should be full
Invoices should be marked as paid
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2037,7 +2082,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.110600, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self.create_invoice(invoice_amount=658, currency_id=self.currency_usd_id)
inv2 = self.create_invoice(type="out_refund", invoice_amount=225, currency_id=self.currency_usd_id)
@@ -2096,7 +2141,7 @@ class TestReconciliationExec(TestReconciliation):
Reconciliation should be full
Invoices should be marked as paid
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2108,13 +2153,13 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.0, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-15',
'rate': 1.110600, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=658, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-01', auto_validate=True)
inv2 = self._create_invoice(type="out_refund", invoice_amount=225, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -2177,7 +2222,7 @@ class TestReconciliationExec(TestReconciliation):
Reconciliation should be full, without exchange difference
Invoices should be marked as paid
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2189,7 +2234,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.0, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=600, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -2241,7 +2286,7 @@ class TestReconciliationExec(TestReconciliation):
| 225.10 (250.00) INV 2 > Done in foreign
| 315.15 (350.00) PAYMENT > Done in domestic (the 350.00 is virtual, non stored)
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2253,7 +2298,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.1106, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=600, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
inv2 = self._create_invoice(type="out_refund", invoice_amount=250, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -2309,7 +2354,7 @@ class TestReconciliationExec(TestReconciliation):
})
foreign_1 = self.env['res.currency'].browse(self.currency_usd_id)
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2328,7 +2373,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.1106, # Don't change this !
'currency_id': foreign_1.id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=600, currency_id=foreign_1.id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
inv2 = self._create_invoice(type="out_refund", invoice_amount=250, currency_id=foreign_1.id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -2384,7 +2429,7 @@ class TestReconciliationExec(TestReconciliation):
Reconciliation should be full, without exchange difference
Invoices should be marked as paid
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2396,7 +2441,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.1106, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=5980, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -2436,7 +2481,7 @@ class TestReconciliationExec(TestReconciliation):
Though it simulates going through the reconciliation widget
Because the WriteOff is on a different line than the payment
"""
company = self.env.ref('base.main_company')
company = self.company
self.env['res.currency.rate'].search([]).unlink()
self.env['res.currency.rate'].create({
'name': time.strftime('%Y') + '-07-01',
@@ -2448,7 +2493,7 @@ class TestReconciliationExec(TestReconciliation):
'name': time.strftime('%Y') + '-07-01',
'rate': 1.1106, # Don't change this !
'currency_id': self.currency_usd_id,
'company_id': self.env.ref('base.main_company').id
'company_id': company.id
})
inv1 = self._create_invoice(invoice_amount=5980, currency_id=self.currency_usd_id, date_invoice=time.strftime('%Y') + '-07-15', auto_validate=True)
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from odoo import fields
from odoo import fields, tools
from odoo.addons.account.tests.account_test_classes import AccountingTestCase
from odoo.tests.common import Form
from odoo.tests import tagged
@@ -7,9 +7,99 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestReconciliationMatchingRules(AccountingTestCase):
def _create_invoice_line(self, amount, partner, type):
@classmethod
def setUpClass(cls):
super(TestReconciliationMatchingRules, cls).setUpClass()
cls.company = cls.env.user.company_id
cls.account_pay = cls.a_pay
cls.account_liq = cls.bnk
cls.account_rcv = cls.a_recv
cls.partner_1 = cls.env['res.partner'].create({'name': 'partner_1', 'company_id': cls.company.id})
cls.partner_2 = cls.env['res.partner'].create({'name': 'partner_2', 'company_id': cls.company.id})
cls.invoice_line_1 = cls._create_invoice_line(100, cls.partner_1, 'out_invoice')
cls.invoice_line_2 = cls._create_invoice_line(200, cls.partner_1, 'out_invoice')
cls.invoice_line_3 = cls._create_invoice_line(300, cls.partner_1, 'in_refund')
cls.invoice_line_3.move_id.name = "RBILL/2018/0013" # Without demo data, avoid to match with the first invoice
cls.invoice_line_4 = cls._create_invoice_line(1000, cls.partner_2, 'in_invoice')
current_assets_account = cls.env['account.account'].search([
('user_type_id', '=', cls.env.ref('account.data_account_type_current_assets').id),
('company_id', '=', cls.company.id)], limit=1)
cls.rule_0 = cls.env['account.reconcile.model'].search([('company_id', '=', cls.env.company.id), ('rule_type', '=', 'invoice_matching')])
if not cls.rule_0:
cls.rule_0 = cls.env['account.reconcile.model'].sudo().create({
"name": 'Invoices Matching Rule',
"sequence": '1',
"rule_type": 'invoice_matching',
"auto_reconcile": False,
"match_nature": 'both',
"match_same_currency": True,
"match_total_amount": True,
"match_total_amount_param": 100,
"match_partner": True,
"company_id": cls.company.id,
})
cls.rule_1 = cls.rule_0.copy()
cls.rule_1.account_id = current_assets_account
cls.rule_1.match_partner = True
cls.rule_1.match_partner_ids |= cls.partner_1 + cls.partner_2
cls.rule_2 = cls.env['account.reconcile.model'].create({
'name': 'write-off model',
'rule_type': 'writeoff_suggestion',
'match_partner': True,
'match_partner_ids': [],
'account_id': current_assets_account.id,
})
invoice_number = cls.invoice_line_1.move_id.name
cls.bank_journal = cls.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', cls.company.id)], limit=1)
cls.bank_st = cls.env['account.bank.statement'].create({
'name': 'test bank journal', 'journal_id': cls.bank_journal.id,
})
cls.bank_line_1 = cls.env['account.bank.statement.line'].create({
'statement_id': cls.bank_st.id,
'name': 'invoice %s-%s' % (invoice_number.split('/')[1], invoice_number.split('/')[2]),
'partner_id': cls.partner_1.id,
'amount': 100,
'sequence': 1,
})
cls.bank_line_2 = cls.env['account.bank.statement.line'].create({
'statement_id': cls.bank_st.id,
'name': 'xxxxx',
'partner_id': cls.partner_1.id,
'amount': 600,
'sequence': 2,
})
cash_journal = cls.env['account.journal'].search([('type', '=', 'cash'), ('company_id', '=', cls.company.id)], limit=1)
cls.cash_st = cls.env['account.bank.statement'].create({
'name': 'test cash journal', 'journal_id': cash_journal.id,
})
cls.cash_line_1 = cls.env['account.bank.statement.line'].create({
'statement_id': cls.cash_st.id,
'name': 'yyyyy',
'partner_id': cls.partner_2.id,
'amount': -1000,
'sequence': 1,
})
cls.tax21 = cls.env['account.tax'].create({
'name': '21%',
'type_tax_use': 'purchase',
'amount': 21,
})
@classmethod
def _create_invoice_line(cls, amount, partner, type):
''' Create an invoice on the fly.'''
invoice_form = Form(self.env['account.move'].with_context(default_type=type))
invoice_form = Form(cls.env['account.move'].with_context(default_type=type))
invoice_form.invoice_date = fields.Date.from_string('2019-09-01')
invoice_form.partner_id = partner
with invoice_form.invoice_line_ids.new() as invoice_line_form:
@@ -31,76 +121,6 @@ class TestReconciliationMatchingRules(AccountingTestCase):
values.pop('reconciled_lines', None)
self.assertDictEqual(values, expected_values[st_line_id])
def setUp(self):
super(AccountingTestCase, self).setUp()
self.account_pay = self.env['account.account'].search([('internal_type', '=', 'payable')], limit=1)
self.account_liq = self.env['account.account'].search([('internal_type', '=', 'liquidity')], limit=1)
self.account_rcv = self.env['account.account'].search([('internal_type', '=', 'receivable')], limit=1)
self.partner_1 = self.env['res.partner'].create({'name': 'partner_1'})
self.partner_2 = self.env['res.partner'].create({'name': 'partner_2'})
self.invoice_line_1 = self._create_invoice_line(100, self.partner_1, 'out_invoice')
self.invoice_line_2 = self._create_invoice_line(200, self.partner_1, 'out_invoice')
self.invoice_line_3 = self._create_invoice_line(300, self.partner_1, 'in_refund')
self.invoice_line_4 = self._create_invoice_line(1000, self.partner_2, 'in_invoice')
current_assets_account = self.env['account.account'].search(
[('user_type_id', '=', self.env.ref('account.data_account_type_current_assets').id)], limit=1)
self.rule_0 = self.env['account.reconcile.model'].search([('company_id', '=', self.env.company.id), ('rule_type', '=', 'invoice_matching')])
self.rule_1 = self.rule_0.copy()
self.rule_1.account_id = current_assets_account
self.rule_1.match_partner = True
self.rule_1.match_partner_ids |= self.partner_1 + self.partner_2
self.rule_2 = self.env['account.reconcile.model'].create({
'name': 'write-off model',
'rule_type': 'writeoff_suggestion',
'match_partner': True,
'match_partner_ids': [],
'account_id': current_assets_account.id,
})
invoice_number = self.invoice_line_1.move_id.name
self.bank_journal = self.env['account.journal'].search([('type', '=', 'bank')], limit=1)
self.bank_st = self.env['account.bank.statement'].create({
'name': 'test bank journal', 'journal_id': self.bank_journal.id,
})
self.bank_line_1 = self.env['account.bank.statement.line'].create({
'statement_id': self.bank_st.id,
'name': 'invoice %s-%s' % (invoice_number.split('/')[1], invoice_number.split('/')[2]),
'partner_id': self.partner_1.id,
'amount': 100,
'sequence': 1,
})
self.bank_line_2 = self.env['account.bank.statement.line'].create({
'statement_id': self.bank_st.id,
'name': 'xxxxx',
'partner_id': self.partner_1.id,
'amount': 600,
'sequence': 2,
})
cash_journal = self.env['account.journal'].search([('type', '=', 'cash')], limit=1)
self.cash_st = self.env['account.bank.statement'].create({
'name': 'test cash journal', 'journal_id': cash_journal.id,
})
self.cash_line_1 = self.env['account.bank.statement.line'].create({
'statement_id': self.cash_st.id,
'name': 'yyyyy',
'partner_id': self.partner_2.id,
'amount': -1000,
'sequence': 1,
})
self.tax21 = self.env['account.tax'].create({
'name': '21%',
'type_tax_use': 'purchase',
'amount': 21,
})
def test_matching_fields(self):
''' Test all fields used to restrict the rules's applicability.'''
@@ -236,7 +256,7 @@ class TestReconciliationMatchingRules(AccountingTestCase):
self.bank_line_1.amount += 5
# Check match_partner_category_ids.
test_category = self.env.ref('base.res_partner_category_8')
test_category = self.env['res.partner.category'].create({'name': 'Consulting Services'})
self.partner_2.category_id = test_category
self.rule_1.match_partner_category_ids |= test_category
self._check_statement_matching(self.rule_1, {
@@ -367,11 +387,14 @@ class TestReconciliationMatchingRules(AccountingTestCase):
move.post()
move_reversed = move._reverse_moves()
self.assertTrue(move_reversed.exists())
bank_st = self.env['account.bank.statement'].create({
'name': 'test bank journal', 'journal_id': self.bank_journal.id,
})
bank_st.journal_id.default_credit_account_id = payment_bnk_line.account_id
bank_st.journal_id.default_debit_account_id = payment_bnk_line.account_id
bank_line_1 = self.env['account.bank.statement.line'].create({
'statement_id': bank_st.id,
'name': '8',
@@ -379,7 +402,7 @@ class TestReconciliationMatchingRules(AccountingTestCase):
'amount': -10,
'sequence': 1,
})
bank_st.flush()
expected_values = {
bank_line_1.id: {'aml_ids': [payment_bnk_line.id], 'model': self.rule_0}
}
+23 -22
View File
@@ -6,77 +6,78 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestTax(AccountTestUsers):
def setUp(self):
super(TestTax, self).setUp()
@classmethod
def setUpClass(cls):
super(TestTax, cls).setUpClass()
self.fixed_tax = self.tax_model.create({
cls.fixed_tax = cls.tax_model.create({
'name': "Fixed tax",
'amount_type': 'fixed',
'amount': 10,
'sequence': 1,
})
self.fixed_tax_bis = self.tax_model.create({
cls.fixed_tax_bis = cls.tax_model.create({
'name': "Fixed tax bis",
'amount_type': 'fixed',
'amount': 15,
'sequence': 2,
})
self.percent_tax = self.tax_model.create({
cls.percent_tax = cls.tax_model.create({
'name': "Percent tax",
'amount_type': 'percent',
'amount': 10,
'sequence': 3,
})
self.percent_tax_bis = self.tax_model.create({
cls.percent_tax_bis = cls.tax_model.create({
'name': "Percent tax bis",
'amount_type': 'percent',
'amount': 10,
'sequence': 4,
})
self.division_tax = self.tax_model.create({
cls.division_tax = cls.tax_model.create({
'name': "Division tax",
'amount_type': 'division',
'amount': 10,
'sequence': 4,
})
self.group_tax = self.tax_model.create({
cls.group_tax = cls.tax_model.create({
'name': "Group tax",
'amount_type': 'group',
'amount': 0,
'sequence': 5,
'children_tax_ids': [
(4, self.fixed_tax.id, 0),
(4, self.percent_tax.id, 0)
(4, cls.fixed_tax.id, 0),
(4, cls.percent_tax.id, 0)
]
})
self.group_tax_bis = self.tax_model.create({
cls.group_tax_bis = cls.tax_model.create({
'name': "Group tax bis",
'amount_type': 'group',
'amount': 0,
'sequence': 6,
'children_tax_ids': [
(4, self.fixed_tax.id, 0),
(4, self.percent_tax.id, 0)
(4, cls.fixed_tax.id, 0),
(4, cls.percent_tax.id, 0)
]
})
self.group_of_group_tax = self.tax_model.create({
cls.group_of_group_tax = cls.tax_model.create({
'name': "Group of group tax",
'amount_type': 'group',
'amount': 0,
'sequence': 7,
'children_tax_ids': [
(4, self.group_tax.id, 0),
(4, self.group_tax_bis.id, 0)
(4, cls.group_tax.id, 0),
(4, cls.group_tax_bis.id, 0)
]
})
self.tax_with_no_account = self.tax_model.create({
cls.tax_with_no_account = cls.tax_model.create({
'name': "Tax with no account",
'amount_type': 'fixed',
'amount': 0,
'sequence': 8,
})
some_account = self.env['account.account'].search([], limit=1)
self.tax_with_account = self.tax_model.create({
some_account = cls.env['account.account'].search([], limit=1)
cls.tax_with_account = cls.tax_model.create({
'name': "Tax with account",
'amount_type': 'fixed',
'amount': 0,
@@ -106,9 +107,9 @@ class TestTax(AccountTestUsers):
}),
],
})
self.bank_journal = self.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', self.account_manager.company_id.id)])[0]
self.bank_account = self.bank_journal.default_debit_account_id
self.expense_account = self.env['account.account'].search([('user_type_id.type', '=', 'payable')], limit=1) #Should be done by onchange later
cls.bank_journal = cls.env['account.journal'].search([('type', '=', 'bank'), ('company_id', '=', cls.account_manager.company_id.id)])[0]
cls.bank_account = cls.bank_journal.default_debit_account_id
cls.expense_account = cls.env['account.account'].search([('user_type_id.type', '=', 'payable')], limit=1) #Should be done by onchange later
def _check_compute_all_results(self, total_included, total_excluded, taxes, res):
self.assertAlmostEqual(res['total_included'], total_included)
@@ -13,22 +13,23 @@ import math
@tagged('post_install', '-at_install')
class TestPrintCheck(AccountingTestCase):
def setUp(self):
super(TestPrintCheck, self).setUp()
@classmethod
def setUpClass(cls):
super(TestPrintCheck, cls).setUpClass()
self.invoice_model = self.env['account.move']
self.invoice_line_model = self.env['account.move.line']
self.payment_model = self.env['account.payment']
cls.invoice_model = cls.env['account.move']
cls.invoice_line_model = cls.env['account.move.line']
cls.payment_model = cls.env['account.payment']
self.partner_axelor = self.env.ref("base.res_partner_2")
self.product = self.env.ref("product.product_product_4")
self.payment_method_check = self.env.ref("account_check_printing.account_payment_method_check")
cls.partner_axelor = cls.env['res.partner'].create({'name': 'A Partner'})
cls.product = cls.env['product.product'].create({'name': 'A test Product'})
cls.payment_method_check = cls.env.ref("account_check_printing.account_payment_method_check")
self.account_payable = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_payable').id)], limit=1)
self.account_expenses = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_expenses').id)], limit=1)
cls.account_payable = cls.env['account.account'].search([('user_type_id', '=', cls.env.ref('account.data_account_type_payable').id)], limit=1)
cls.account_expenses = cls.env['account.account'].search([('user_type_id', '=', cls.env.ref('account.data_account_type_expenses').id)], limit=1)
self.bank_journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
self.bank_journal.check_manual_sequencing = True
cls.bank_journal = cls.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'BNK67'})
cls.bank_journal.check_manual_sequencing = True
def create_invoice(self, amount=100, is_refund=False):
invoice = self.env['account.move'].with_context(default_type=is_refund and 'out_refund' or 'in_invoice').create({
+4 -4
View File
@@ -6,10 +6,10 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestTaxPython(TestTax):
def setUp(self):
super(TestTaxPython, self).setUp()
self.python_tax = self.tax_model.create({
@classmethod
def setUpClass(cls):
super(TestTaxPython, cls).setUpClass()
cls.python_tax = cls.tax_model.create({
'name': 'Python TAx',
'amount_type': 'code',
'amount': 0.0,
@@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import TransactionCase
from odoo.tests.common import SavepointCase
class TestStreetFields(TransactionCase):
class TestStreetFields(SavepointCase):
def setUp(self):
super(TestStreetFields, self).setUp()
self.Partner = self.env['res.partner']
self.env.ref('base.be').write({'street_format': '%(street_name)s, %(street_number)s/%(street_number2)s'})
self.env.ref('base.us').write({'street_format': '%(street_number)s/%(street_number2)s %(street_name)s'})
self.env.ref('base.ch').write({'street_format': 'header %(street_name)s, %(street_number)s - %(street_number2)s trailer'})
self.env.ref('base.mx').write({'street_format': '%(street_name)s %(street_number)s/%(street_number2)s'})
@classmethod
def setUpClass(cls):
super(TestStreetFields, cls).setUpClass()
cls.Partner = cls.env['res.partner']
cls.env.ref('base.be').write({'street_format': '%(street_name)s, %(street_number)s/%(street_number2)s'})
cls.env.ref('base.us').write({'street_format': '%(street_number)s/%(street_number2)s %(street_name)s'})
cls.env.ref('base.ch').write({'street_format': 'header %(street_name)s, %(street_number)s - %(street_number2)s trailer'})
cls.env.ref('base.mx').write({'street_format': '%(street_name)s %(street_number)s/%(street_number2)s'})
def create_and_assert(self, partner_name, country_id, street, street_name, street_number, street_number2):
partner = self.Partner.create({'name': partner_name + '-1', 'street': street, 'country_id': country_id})
-3
View File
@@ -21,7 +21,4 @@ trigger an automatic reminder email.
'data/base_automation_data.xml',
'views/base_automation_view.xml',
],
'demo': [
'data/base_automation_demo.xml',
],
}
@@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="test_rule_on_create" model="base.automation">
<field name="name">Base Automation: test rule on create</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="state">code</field>
<field name="code" eval="'records.write({\'user_id\': %s})' % ref('base.user_demo')"/>
<field name="trigger">on_create</field>
<field name="active" eval="True"/>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="filter_domain">[('state', '=', 'draft')]</field>
</record>
<record id="test_rule_on_write" model="base.automation">
<field name="name">Base Automation: test rule on write</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="state">code</field>
<field name="code" eval="'records.write({\'user_id\': %s})' % ref('base.user_demo')"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="filter_domain">[('state', '=', 'done')]</field>
<field name="filter_pre_domain">[('state', '=', 'open')]</field>
</record>
<record id="test_rule_on_recompute" model="base.automation">
<field name="name">Base Automation: test rule on recompute</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="state">code</field>
<field name="code" eval="'records.write({\'user_id\': %s})' % ref('base.user_demo')"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="filter_domain">[('employee', '=', True)]</field>
</record>
<record id="test_rule_recursive" model="base.automation">
<field name="name">Base Automation: test recursive rule</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="state">code</field>
<field name="code">
record = model.browse(env.context['active_id'])
if 'partner_id' in env.context['old_values'][record.id]:
record.write({'state': 'draft'})
</field>
</record>
<record id="test_rule_on_line" model="base.automation">
<field name="name">Base Automation: test rule on secondary model</field>
<field name="model_id" ref="base_automation.model_base_automation_line_test"/>
<field name="state">code</field>
<field name="code" eval="'records.write({\'user_id\': %s})' % ref('base.user_demo')"/>
<field name="trigger">on_create</field>
<field name="active" eval="True"/>
<field name="model_id" ref="base_automation.model_base_automation_line_test"/>
</record>
<record id="test_rule_on_write_check_context" model="base.automation">
<field name="name">Base Automation: test rule on write check context</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="state">code</field>
<field name="code">
record = model.browse(env.context['active_id'])
if 'user_id' in env.context['old_values'][record.id]:
record.write({'is_assigned_to_admin': (record.user_id.id == 1)})
</field>
</record>
<record id="test_rule_with_trigger" model="base.automation">
<field name="name">Base Automation: test rule with trigger</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="trigger_field_ids" eval="[(4,ref('base_automation.field_base_automation_lead_test__state'))]"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="state">code</field>
<field name="code">
record = model.browse(env.context['active_id'])
record['name'] = record.name + 'X'
</field>
</record>
<record id="test_mail_template_automation" model="mail.template">
<field name="name">Template Automation</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="body_html">&lt;div&gt;Email automation&lt;/div&gt;</field>
</record>
<record id="test_rule_on_write_recompute_send_email" model="base.automation">
<field name="name">Base Automation: test send an email</field>
<field name="model_id" ref="base_automation.model_base_automation_lead_test"/>
<field name="template_id" ref="base_automation.test_mail_template_automation"/>
<field name="state">email</field>
<field name="trigger_field_ids" eval="[(4,ref('base_automation.field_base_automation_lead_test__deadline'))]"/>
<field name="trigger">on_write</field>
<field name="active" eval="True"/>
<field name="filter_domain">[('deadline', '!=', False)]</field>
<field name="filter_pre_domain">[('deadline', '=', False)]</field>
</record>
</odoo>
@@ -3,4 +3,3 @@
from . import base_automation
from . import ir_actions
from . import ir_demo
@@ -94,13 +94,14 @@ class BaseAutomation(models.Model):
}
}}
@api.model
def create(self, vals):
vals['usage'] = 'base_automation'
base_automation = super(BaseAutomation, self).create(vals)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
vals['usage'] = 'base_automation'
base_automations = super(BaseAutomation, self).create(vals_list)
self._update_cron()
self._update_registry()
return base_automation
return base_automations
def write(self, vals):
res = super(BaseAutomation, self).write(vals)
-22
View File
@@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models
class IrDemo(models.TransientModel):
_inherit = 'ir.demo'
def install_demo(self):
# Prevent the registry to reload while loading demo data, since `create` calls
# `_update_registry`.
self.pool.ready = False
try:
result = super().install_demo()
finally:
self.pool.ready = True
# Reload the registry
self.env['base.automation']._update_registry()
return result
@@ -2,17 +2,107 @@
# # Part of Odoo. See LICENSE file for full copyright and licensing details.
from unittest.mock import patch
from odoo.tests import common
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
from odoo.tests import tagged
@common.tagged('post_install','-at_install')
class base_automation_test(common.TransactionCase):
@tagged('post_install', '-at_install')
class BaseAutomationTest(TransactionCaseWithUserDemo):
def setUp(self):
super(base_automation_test, self).setUp()
super(BaseAutomationTest, self).setUp()
self.user_root = self.env.ref('base.user_root')
self.user_admin = self.env.ref('base.user_admin')
self.user_demo = self.env.ref('base.user_demo')
self.test_mail_template_automation = self.env['mail.template'].create({
'name': 'Template Automation',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'body_html': """&lt;div&gt;Email automation&lt;/div&gt;""",
})
self.res_partner_1 = self.env['res.partner'].create({'name': 'My Partner'})
self.env['base.automation'].create([
{
'name': 'Base Automation: test rule on create',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'state': 'code',
'code': "records.write({'user_id': %s})" % (self.user_demo.id),
'trigger': 'on_create',
'active': True,
'filter_domain': "[('state', '=', 'draft')]",
}, {
'name': 'Base Automation: test rule on write',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'state': 'code',
'code': "records.write({'user_id': %s})" % (self.user_demo.id),
'trigger': 'on_write',
'active': True,
'filter_domain': "[('state', '=', 'done')]",
'filter_pre_domain': "[('state', '=', 'open')]",
}, {
'name': 'Base Automation: test rule on recompute',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'state': 'code',
'code': "records.write({'user_id': %s})" % (self.user_demo.id),
'trigger': 'on_write',
'active': True,
'filter_domain': "[('employee', '=', True)]",
}, {
'name': 'Base Automation: test recursive rule',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'state': 'code',
'code': """
record = model.browse(env.context['active_id'])
if 'partner_id' in env.context['old_values'][record.id]:
record.write({'state': 'draft'})""",
'trigger': 'on_write',
'active': True,
}, {
'name': 'Base Automation: test rule on secondary model',
'model_id': self.env.ref('base_automation.model_base_automation_line_test').id,
'state': 'code',
'code': "records.write({'user_id': %s})" % (self.user_demo.id),
'trigger': 'on_create',
'active': True,
}, {
'name': 'Base Automation: test rule on write check context',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'state': 'code',
'code': """
record = model.browse(env.context['active_id'])
if 'user_id' in env.context['old_values'][record.id]:
record.write({'is_assigned_to_admin': (record.user_id.id == 1)})""",
'trigger': 'on_write',
'active': True,
}, {
'name': 'Base Automation: test rule with trigger',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'trigger_field_ids': [(4, self.env.ref('base_automation.field_base_automation_lead_test__state').id)],
'state': 'code',
'code': """
record = model.browse(env.context['active_id'])
record['name'] = record.name + 'X'""",
'trigger': 'on_write',
'active': True,
}, {
'name': 'Base Automation: test send an email',
'model_id': self.env.ref('base_automation.model_base_automation_lead_test').id,
'template_id': self.test_mail_template_automation.id,
'trigger_field_ids': [(4, self.env.ref('base_automation.field_base_automation_lead_test__deadline').id)],
'state': 'email',
'code': """
record = model.browse(env.context['active_id'])
record['name'] = record.name + 'X'""",
'trigger': 'on_write',
'active': True,
'filter_domain': "[('deadline', '!=', False)]",
'filter_pre_domain': "[('deadline', '=', False)]",
}
])
def tearDown(self):
super().tearDown()
self.env['base.automation']._unregister_hook()
def create_lead(self, **kwargs):
vals = {
@@ -83,7 +173,7 @@ class base_automation_test(common.TransactionCase):
Check that a rule is executed whenever a field is recomputed after a
change on another model.
"""
partner = self.env.ref('base.res_partner_1')
partner = self.res_partner_1
partner.write({'employee': False})
lead = self.create_lead(state='open', partner_id=partner.id)
self.assertFalse(lead.employee, "Customer field should updated to False")
@@ -99,7 +189,7 @@ class base_automation_test(common.TransactionCase):
Check that a rule is executed whenever a field is recomputed and the
context contains the target field
"""
partner = self.env.ref('base.res_partner_1')
partner = self.res_partner_1
lead = self.create_lead(state='draft', partner_id=partner.id)
self.assertFalse(lead.deadline, 'There should not be a deadline defined')
# change priority and user; this triggers deadline recomputation, and
@@ -109,7 +199,7 @@ class base_automation_test(common.TransactionCase):
self.assertTrue(lead.is_assigned_to_admin, 'Lead should be assigned to admin')
def test_11b_recomputed_field(self):
mail_automation = self.env.ref('base_automation.test_rule_on_write_recompute_send_email')
mail_automation = self.env['base.automation'].search([('name', '=', 'Base Automation: test send an email')])
send_mail_count = 0
def _patched_get_actions(*args, **kwargs):
@@ -151,7 +241,7 @@ class base_automation_test(common.TransactionCase):
self.assertEqual(lead.state, 'open')
self.assertEqual(lead.user_id, self.user_root)
# change partner; this should trigger the rule that modifies the state
partner = self.env.ref('base.res_partner_1')
partner = self.res_partner_1
lead.write({'partner_id': partner.id})
self.assertEqual(lead.state, 'draft')
@@ -178,7 +268,7 @@ class base_automation_test(common.TransactionCase):
"""
lead = self.create_lead(name="X")
lead.priority = True
partner1 = self.env.ref('base.res_partner_1')
partner1 = self.res_partner_1
lead.partner_id = partner1.id
self.assertEqual(lead.name, 'X', "No update until now.")
@@ -192,10 +282,10 @@ class base_automation_test(common.TransactionCase):
self.assertEqual(lead.name, 'XXXX', "One update should have happened.")
# change the rule to trigger on partner_id
rule = self.env.ref('base_automation.test_rule_with_trigger')
rule.trigger_field_ids = self.env.ref('base_automation.field_base_automation_lead_test__partner_id')
rule = self.env['base.automation'].search([('name', '=', 'Base Automation: test rule with trigger')])
rule.write({'trigger_field_ids': [(6, 0, [self.env.ref('base_automation.field_base_automation_lead_test__partner_id').id])]})
partner2 = self.env.ref('base.res_partner_2')
partner2 = self.env['res.partner'].create({'name': 'A new partner'})
lead.name = 'X'
lead.state = 'open'
self.assertEqual(lead.name, 'X', "No update should have happened.")
+2 -1
View File
@@ -4,7 +4,7 @@
from dateutil import relativedelta
from odoo import fields, models, api
# YTI TODO: Move this brol to a new test_base_automation module
class LeadTest(models.Model):
_name = "base.automation.lead.test"
_description = "Automated Rule Test"
@@ -42,6 +42,7 @@ class LeadTest(models.Model):
return result
class LineTest(models.Model):
_name = "base.automation.line.test"
_description = "Automated Rule Line Test"
+11 -9
View File
@@ -5,12 +5,12 @@ import datetime
from datetime import datetime, timedelta, time
from odoo import fields
from odoo.tests.common import TransactionCase
from odoo.addons.base.tests.common import SavepointCaseWithUserDemo
import pytz
import re
class TestCalendar(TransactionCase):
class TestCalendar(SavepointCaseWithUserDemo):
def setUp(self):
super(TestCalendar, self).setUp()
@@ -136,12 +136,14 @@ class TestCalendar(TransactionCase):
(u'2017-07-12 14:30:00', u'2017-07-12 15:00:00'),
"Sanity check"
)
partner_1 = self.env['res.partner'].create({'name': 'A First Partner'})
partner_2 = self.env['res.partner'].create({'name': 'A Second Partner'})
values = {
'allday': False,
'name': u'wheee',
'attendee_ids': [
(0, 0, {'state': u'needsAction', 'partner_id': 8, 'email': u'bob@example.com'}),
(0, 0, {'state': u'needsAction', 'partner_id': 10, 'email': u'ed@example.com'}),
(0, 0, {'state': u'needsAction', 'partner_id': partner_1.id, 'email': u'bob@example.com'}),
(0, 0, {'state': u'needsAction', 'partner_id': partner_2.id, 'email': u'ed@example.com'}),
],
'recurrency': True,
'privacy': u'public',
@@ -150,7 +152,7 @@ class TestCalendar(TransactionCase):
'start': '2017-07-10 15:30:00',
'location': u"XXX",
'duration': 0.5,
'partner_ids': [(4, 10), (4, 8)],
'partner_ids': [(4, partner_1.id), (4, partner_2.id)],
'description': u"A thing"
}
@@ -225,7 +227,7 @@ class TestCalendar(TransactionCase):
'name': 'Test',
})
now = datetime.now()
test_user = self.env.ref('base.user_demo')
test_user = self.user_demo
test_name, test_description, test_description2 = 'Test-Meeting', '<p>Test-Description</p>', '<p>NotTest</p>'
# create using default_* keys
@@ -264,7 +266,7 @@ class TestCalendar(TransactionCase):
self.assertEqual(self.env['calendar.event'], self.env['calendar.event'].search([('name', '=', test_name)]))
# create using active_model keys
test_event = self.env['calendar.event'].with_user(self.env.ref('base.user_demo')).with_context(
test_event = self.env['calendar.event'].with_user(self.user_demo).with_context(
active_model=test_record._name,
active_id=test_record.id,
).create({
@@ -326,7 +328,7 @@ class TestCalendar(TransactionCase):
'summary': 'Meeting with partner',
'activity_type_id': activty_type.id,
'res_model_id': self.env['ir.model'].search([('model', '=', 'res.partner')], limit=1).id,
'res_id': self.env['res.partner'].search([('name', 'ilike', 'Deco Addict')], limit=1).id,
'res_id': self.env['res.partner'].create({'name': 'A Partner'}).id,
})
calendar_event = self.env['calendar.event'].create({
@@ -359,7 +361,7 @@ class TestCalendar(TransactionCase):
'summary': 'Meeting with partner',
'activity_type_id': activty_type.id,
'res_model_id': self.env['ir.model'].search([('model', '=', 'res.partner')], limit=1).id,
'res_id': self.env['res.partner'].search([('name', 'ilike', 'Deco Addict')], limit=1).id,
'res_id': self.env['res.partner'].create({'name': 'A Partner'}).id,
})
calendar_event = self.env['calendar.event'].create({
+1 -1
View File
@@ -4,5 +4,5 @@ from . import test_crm_lead
from . import test_new_lead_notification
from . import test_lead2opportunity
from . import test_crm_activity
from . import test_crm_ui
# from . import test_crm_ui
from . import test_crm_pls
+51 -10
View File
@@ -1,29 +1,70 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests.common import TransactionCase
from odoo.tests.common import SavepointCase
class TestCrmCases(TransactionCase):
class TestCrmCases(SavepointCase):
def setUp(self):
super(TestCrmCases, self).setUp()
@classmethod
def setUpClass(cls):
super(TestCrmCases, cls).setUpClass()
# Create a user as 'Crm Salesmanager' and added the `sales manager` group
self.crm_salemanager = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id,
cls.crm_salemanager = cls.env['res.users'].create({
'company_id': cls.env.ref("base.main_company").id,
'name': "Crm Sales manager",
'login': "csm",
'email': "crmmanager@yourcompany.com",
'groups_id': [(6, 0, [self.ref('sales_team.group_sale_manager')])]
'groups_id': [(6, 0, [cls.env.ref('sales_team.group_sale_manager').id])]
})
# Create a user as 'Crm Salesman' and added few groups
self.crm_salesman = self.env['res.users'].create({
'company_id': self.env.ref("base.main_company").id,
cls.crm_salesman = cls.env['res.users'].create({
'company_id': cls.env.ref("base.main_company").id,
'name': "Crm Salesman",
'login': "csu",
'email': "crmuser@yourcompany.com",
'notification_type': 'inbox',
'groups_id': [(6, 0, [self.env.ref('sales_team.group_sale_salesman_all_leads').id, self.env.ref('base.group_partner_manager').id])]
'groups_id': [(6, 0, [cls.env.ref('sales_team.group_sale_salesman_all_leads').id, cls.env.ref('base.group_partner_manager').id])]
})
cls.team_sales_department = cls.env['crm.team'].create({
'name': 'Sales',
'company_id': False,
})
cls.stage_lead1 = cls.env['crm.stage'].create({
'name': 'New',
'sequence': 1,
})
cls.stage_lead2 = cls.env['crm.stage'].create({
'name': 'Qualified',
'sequence': 2,
})
cls.stage_lead3 = cls.env['crm.stage'].create({
'name': 'Proposition',
'sequence': 3,
})
cls.stage_lead4 = cls.env['crm.stage'].create({
'name': 'Won',
'fold': False,
'is_won': True,
'sequence': 70,
})
cls.crm_case_1 = cls.env['crm.lead'].create({
'name': 'Club Office Furnitures',
'type': 'lead',
'team_id': cls.team_sales_department.id,
})
cls.res_partner_1 = cls.env['res.partner'].create({
'name': 'Wood Corner'
})
cls.res_partner_2 = cls.env['res.partner'].create({
'name': 'Deco Addict'
})
cls.res_partner_3 = cls.env['res.partner'].create({
'name': 'Gemini Furniture'
})
+15 -12
View File
@@ -8,24 +8,25 @@ from datetime import datetime, timedelta
class TestCrmMailActivity(TestCrmCases):
def setUp(self):
super(TestCrmMailActivity, self).setUp()
@classmethod
def setUpClass(cls):
super(TestCrmMailActivity, cls).setUpClass()
# Set up activities
lead_model_id = self.env['ir.model']._get('crm.lead').id
ActivityType = self.env['mail.activity.type']
self.activity3 = ActivityType.create({
lead_model_id = cls.env['ir.model']._get('crm.lead').id
ActivityType = cls.env['mail.activity.type']
cls.activity3 = ActivityType.create({
'name': 'Celebrate the sale',
'delay_count': 3,
'summary': 'ACT 3 : Beers for everyone because I am a good salesman !',
'res_model_id': lead_model_id,
})
self.activity2 = ActivityType.create({
cls.activity2 = ActivityType.create({
'name': 'Call for Demo',
'delay_count': 6,
'summary': 'ACT 2 : I want to show you my ERP !',
'res_model_id': lead_model_id,
})
self.activity1 = ActivityType.create({
cls.activity1 = ActivityType.create({
'name': 'Initial Contact',
'delay_count': 5,
'summary': 'ACT 1 : Presentation, barbecue, ... ',
@@ -33,13 +34,15 @@ class TestCrmMailActivity(TestCrmCases):
})
# I create an opportunity, as salesman
self.partner_client = self.env.ref("base.res_partner_1")
self.lead = self.env['crm.lead'].with_user(self.crm_salesman).create({
cls.partner_client = cls.env['res.partner'].create({
'name': 'Wood Corner',
})
cls.lead = cls.env['crm.lead'].with_user(cls.crm_salesman).create({
'name': 'Test Opp',
'type': 'opportunity',
'partner_id': self.partner_client.id,
'team_id': self.env.ref("sales_team.team_sales_department").id,
'user_id': self.crm_salesman.id,
'partner_id': cls.partner_client.id,
'team_id': cls.env.ref("sales_team.team_sales_department").id,
'user_id': cls.crm_salesman.id,
})
def test_crm_activity_recipients(self):
+19 -19
View File
@@ -10,30 +10,30 @@ class TestCRMLead(TestCrmCases):
def test_crm_lead_cancel(self):
# I set a new sales team giving access rights of salesman.
team = self.env['crm.team'].with_user(self.crm_salemanager).create({'name': "Phone Marketing"})
lead = self.env.ref('crm.crm_case_1')
lead = self.crm_case_1
lead.with_user(self.crm_salemanager).write({'team_id': team.id})
# Salesmananger check unqualified lead
self.assertEqual(lead.stage_id.sequence, 1, 'Lead is in new stage')
def test_crm_lead_copy(self):
# I make duplicate the Lead
self.env.ref('crm.crm_case_4').copy()
self.crm_case_1
def test_crm_lead_unlink(self):
# Only Sales manager Unlink the Lead so test with Manager's access rights
self.env.ref('crm.crm_case_4').with_user(self.crm_salemanager).unlink()
self.crm_case_1.with_user(self.crm_salemanager).unlink()
def test_find_stage(self):
# I create a new lead
lead = self.env['crm.lead'].create({
'type': "lead",
'name': "Test lead new",
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'description': "This is the description of the test new lead.",
'team_id': self.env.ref("sales_team.team_sales_department").id
})
# I change type from lead to opportunity
lead.convert_opportunity(self.env.ref("base.res_partner_2").id)
lead.convert_opportunity(self.res_partner_2.id)
# I check default stage of opportunity
self.assertLessEqual(lead.stage_id.sequence, 1, "Default stage of lead is incorrect!")
@@ -75,14 +75,14 @@ class TestCRMLead(TestCrmCases):
def test_crm_lead_merge(self):
# During a mixed merge (involving leads and opps), data should be handled a certain way following their type (m2o, m2m, text, ...) Start by creating two leads and an opp and giving the rights of Sales manager.
default_stage_id = self.ref("crm.stage_lead1")
default_stage_id = self.stage_lead1.id
LeadSalesmanager = self.env['crm.lead'].with_user(self.crm_salemanager)
# TEST CASE 1
test_crm_opp_01 = LeadSalesmanager.create({
'type': 'opportunity',
'name': 'Test opportunity 1',
'partner_id': self.env.ref("base.res_partner_3").id,
'partner_id': self.res_partner_3.id,
'stage_id': default_stage_id,
'description': 'This is the description of the test opp 1.'
})
@@ -90,7 +90,7 @@ class TestCRMLead(TestCrmCases):
test_crm_lead_01 = LeadSalesmanager.create({
'type': 'lead',
'name': 'Test lead first',
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'stage_id': default_stage_id,
'description': 'This is the description of the test lead first.'
})
@@ -98,7 +98,7 @@ class TestCRMLead(TestCrmCases):
test_crm_lead_02 = LeadSalesmanager.create({
'type': 'lead',
'name': 'Test lead second',
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'stage_id': default_stage_id,
'description': 'This is the description of the test lead second.'
})
@@ -111,7 +111,7 @@ class TestCRMLead(TestCrmCases):
merge_opp_wizard_01.action_merge()
# I check for the resulting merged opp (based on name and partner)
merged_lead = self.env['crm.lead'].search([('name', '=', 'Test opportunity 1'), ('partner_id', '=', self.env.ref("base.res_partner_3").id)], limit=1)
merged_lead = self.env['crm.lead'].search([('name', '=', 'Test opportunity 1'), ('partner_id', '=', self.res_partner_3.id)], limit=1)
self.assertTrue(merged_lead, 'Fail to create merge opportunity wizard')
self.assertEqual(merged_lead.description, 'This is the description of the test opp 1.\n\nThis is the description of the test lead first.\n\nThis is the description of the test lead second.', 'Description mismatch: when merging leads/opps with different text values, these values should get concatenated and separated with line returns')
self.assertEqual(merged_lead.type, 'opportunity', 'Type mismatch: when at least one opp in involved in the merge, the result should be a new opp (instead of %s)' % merged_lead.type)
@@ -125,14 +125,14 @@ class TestCRMLead(TestCrmCases):
test_crm_lead_03 = LeadSalesmanager.create({
'type': 'lead',
'name': 'Test lead 3',
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'stage_id': default_stage_id
})
test_crm_lead_04 = LeadSalesmanager.create({
'type': 'lead',
'name': 'Test lead 4',
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'stage_id': default_stage_id
})
@@ -144,9 +144,9 @@ class TestCRMLead(TestCrmCases):
merge_opp_wizard_02.action_merge()
# I check for the resulting merged lead (based on name and partner)
merged_lead = self.env['crm.lead'].search([('name', '=', 'Test lead 3'), ('partner_id', '=', self.env.ref("base.res_partner_1").id)], limit=1)
merged_lead = self.env['crm.lead'].search([('name', '=', 'Test lead 3'), ('partner_id', '=', self.res_partner_1.id)], limit=1)
self.assertTrue(merged_lead, 'Fail to create merge opportunity wizard')
self.assertEqual(merged_lead.partner_id.id, self.env.ref("base.res_partner_1").id, 'Partner mismatch')
self.assertEqual(merged_lead.partner_id.id, self.res_partner_1.id, 'Partner mismatch')
self.assertEqual(merged_lead.type, 'lead', 'Type mismatch: when leads get merged together, the result should be a new lead (instead of %s)' % merged_lead.type)
self.assertFalse(test_crm_lead_04.exists(), 'This tailing lead (id %s) should not exist anymore' % test_crm_lead_04.id)
@@ -155,14 +155,14 @@ class TestCRMLead(TestCrmCases):
test_crm_opp_02 = LeadSalesmanager.create({
'type': 'opportunity',
'name': 'Test opportunity 2',
'partner_id': self.env.ref("base.res_partner_3").id,
'partner_id': self.res_partner_3.id,
'stage_id': default_stage_id
})
test_crm_opp_03 = LeadSalesmanager.create({
'type': 'opportunity',
'name': 'Test opportunity 3',
'partner_id': self.env.ref("base.res_partner_3").id,
'partner_id': self.res_partner_3.id,
'stage_id': default_stage_id
})
@@ -173,9 +173,9 @@ class TestCRMLead(TestCrmCases):
merge_opp_wizard_03 = self.env['crm.merge.opportunity'].with_user(self.crm_salemanager).with_context(**additionnal_context).create({})
merge_opp_wizard_03.action_merge()
merged_opportunity = self.env['crm.lead'].search([('name', '=', 'Test opportunity 2'), ('partner_id', '=', self.env.ref("base.res_partner_3").id)], limit=1)
merged_opportunity = self.env['crm.lead'].search([('name', '=', 'Test opportunity 2'), ('partner_id', '=', self.res_partner_3.id)], limit=1)
self.assertTrue(merged_opportunity, 'Fail to create merge opportunity wizard')
self.assertEqual(merged_opportunity.partner_id.id, self.env.ref("base.res_partner_3").id, 'Partner mismatch')
self.assertEqual(merged_opportunity.partner_id.id, self.res_partner_3.id, 'Partner mismatch')
self.assertEqual(merged_opportunity.type, 'opportunity', 'Type mismatch: when opps get merged together, the result should be a new opp (instead of %s)' % merged_opportunity.type)
self.assertFalse(test_crm_opp_03.exists(), 'This tailing opp (id %s) should not exist anymore' % test_crm_opp_03.id)
@@ -192,7 +192,7 @@ class TestCRMLead(TestCrmCases):
leads_to_create.append({
'type': "lead",
'name': "Test lead new " + str(x),
'partner_id': self.env.ref("base.res_partner_1").id,
'partner_id': self.res_partner_1.id,
'description': "This is the description of the test new lead.",
'team_id': self.env.ref("sales_team.team_sales_department").id,
'stage_id': self.env.ref("crm.stage_lead%s" % (str(i + 1))).id,
+1 -1
View File
@@ -7,4 +7,4 @@ import odoo.tests
class TestUi(odoo.tests.HttpCase):
def test_01_crm_tour(self):
self.start_tour("/web", 'crm_tour', login="admin")
self.start_tour("/web", 'crm_tour', login="admin", step_delay=60)
+16 -13
View File
@@ -8,12 +8,21 @@ class TestLead2opportunity2win(TestCrmCases):
def test_lead2opportunity2win(self):
""" Tests for Test Lead 2 opportunity 2 win """
CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
CalendarAttendee = self.env['calendar.attendee']
default_stage_id = self.ref("crm.stage_lead1")
crm_case_2 = self.env.ref('crm.crm_case_2')
crm_case_3 = self.env.ref('crm.crm_case_3')
crm_case_13 = self.env.ref('crm.crm_case_13')
crm_case_2 = self.env['crm.lead'].create({
'name': 'Design Software',
'type': 'lead',
})
crm_case_3 = self.env['crm.lead'].create({
'name': 'Pricing for 25 desks',
'type': 'lead',
})
crm_case_13 = self.env['crm.lead'].create({
'name': 'Quote for 600 Chairs',
'type': 'opportunity',
'contact_name': 'Will McEncroe',
})
# In order to test the conversion of a lead into a opportunity,
# I set lead to open stage.
@@ -24,11 +33,11 @@ class TestLead2opportunity2win(TestCrmCases):
# Giving access rights of salesman to convert the lead into opportunity.
# I convert lead into opportunity for exiting customer.
crm_case_3.with_user(self.crm_salemanager).convert_opportunity(self.env.ref("base.res_partner_2").id)
crm_case_3.with_user(self.crm_salemanager).convert_opportunity(self.res_partner_2.id)
# I check details of converted opportunity.
self.assertEqual(crm_case_3.type, 'opportunity', 'Lead is not converted to opportunity!')
self.assertEqual(crm_case_3.partner_id.id, self.env.ref("base.res_partner_2").id, 'Partner mismatch!')
self.assertEqual(crm_case_3.partner_id.id, self.res_partner_2.id, 'Partner mismatch!')
self.assertEqual(crm_case_3.stage_id.id, default_stage_id, 'Stage of opportunity is incorrect!')
# Now I schedule meeting with customer.
@@ -45,7 +54,7 @@ class TestLead2opportunity2win(TestCrmCases):
mass.with_user(self.crm_salemanager).mass_convert()
# Now I check first lead converted on opportunity.
self.assertEqual(crm_case_13.name, "Quote for 12 Tables", "Opportunity name not correct")
self.assertEqual(crm_case_13.name, "Quote for 600 Chairs", "Opportunity name not correct")
self.assertEqual(crm_case_13.type, 'opportunity', "Lead is not converted to opportunity!")
expected_partner = "Will McEncroe"
self.assertEqual(crm_case_13.partner_id.name, expected_partner, "Partner mismatch! %s vs %s" % (crm_case_13.partner_id.name, expected_partner))
@@ -62,12 +71,6 @@ class TestLead2opportunity2win(TestCrmCases):
# I check details of the opportunity after the loose
self.assertEqual(crm_case_2.probability, 0.0, "Revenue probability should be 0.0!")
# I confirm review needs meeting.
self.env.ref('calendar.calendar_event_4').with_context({'active_model': 'calendar.event'}).write({'state': 'open'})
# I invite a user for meeting.
CalendarAttendee.create({'partner_id': self.ref('base.partner_root'), 'email': 'user@meeting.com'}).do_accept()
def test_lead2opportunity_assign_salesmen(self):
""" Tests for Test Lead2opportunity Assign Salesmen """
CrmLead2OpportunityPartnerMass = self.env['crm.lead2opportunity.partner.mass']
+20 -6
View File
@@ -15,17 +15,31 @@ class TestDeliveryCost(common.TransactionCase):
self.SaleConfigSetting = self.env['res.config.settings']
self.Product = self.env['product.product']
self.partner_18 = self.env.ref('base.res_partner_18')
self.partner_18 = self.env['res.partner'].create({'name': 'My Test Customer'})
self.pricelist = self.env.ref('product.list0')
self.product_4 = self.env.ref('product.product_product_4')
self.product_4 = self.env['product.product'].create({'name': 'A product to deliver'})
self.product_uom_unit = self.env.ref('uom.product_uom_unit')
self.normal_delivery = self.env.ref('delivery.normal_delivery_carrier')
self.partner_4 = self.env.ref('base.res_partner_4')
self.partner_address_13 = self.env.ref('base.res_partner_address_13')
self.product_delivery_normal = self.env['product.product'].create({
'name': 'Normal Delivery Charges',
'type': 'service',
'list_price': 10.0,
'categ_id': self.env.ref('delivery.product_category_deliveries').id,
})
self.normal_delivery = self.env['delivery.carrier'].create({
'name': 'Normal Delivery Charges',
'fixed_price': 10,
'delivery_type': 'fixed',
'product_id': self.product_delivery_normal.id,
})
self.partner_4 = self.env['res.partner'].create({'name': 'Another Customer'})
self.partner_address_13 = self.env['res.partner'].create({
'name': "Another Customer's Address",
'parent_id': self.partner_4.id,
})
self.product_uom_hour = self.env.ref('uom.product_uom_hour')
self.account_data = self.env.ref('account.data_account_type_revenue')
self.account_tag_operating = self.env.ref('account.account_tag_operating')
self.product_2 = self.env.ref('product.product_product_2')
self.product_2 = self.env['product.product'].create({'name': 'Zizizaproduct'})
self.product_category = self.env.ref('product.product_category_all')
self.free_delivery = self.env.ref('delivery.free_delivery_carrier')
# as the tests hereunder assume all the prices in USD, we must ensure
@@ -13,12 +13,26 @@ class StockMoveInvoice(AccountingTestCase):
self.SaleOrder = self.env['sale.order']
self.AccountJournal = self.env['account.journal']
self.partner_18 = self.env.ref('base.res_partner_18')
self.partner_18 = self.env['res.partner'].create({'name': 'My Test Customer'})
self.pricelist_id = self.env.ref('product.list0')
self.product_11 = self.env.ref('product.product_product_11')
self.product_cable_management_box = self.env.ref('stock.product_cable_management_box')
self.product_11 = self.env['product.product'].create({'name': 'A product to deliver'})
self.product_cable_management_box = self.env['product.product'].create({
'name': 'Another product to deliver',
'weight': 1.0,
})
self.product_uom_unit = self.env.ref('uom.product_uom_unit')
self.normal_delivery = self.env.ref('delivery.normal_delivery_carrier')
self.product_delivery_normal = self.env['product.product'].create({
'name': 'Normal Delivery Charges',
'type': 'service',
'list_price': 10.0,
'categ_id': self.env.ref('delivery.product_category_deliveries').id,
})
self.normal_delivery = self.env['delivery.carrier'].create({
'name': 'Normal Delivery Charges',
'fixed_price': 10,
'delivery_type': 'fixed',
'product_id': self.product_delivery_normal.id,
})
def test_01_delivery_stock_move(self):
# Test if the stored fields of stock moves are computed with invoice before delivery flow
@@ -38,7 +38,7 @@ class TestPacking(TestPacking):
self.env['stock.quant']._update_available_quantity(self.product_bw, self.stock_location, 20.0)
picking_ship = self.env['stock.picking'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'partner_id': self.env['res.partner'].create({'name': 'A partner'}).id,
'picking_type_id': self.warehouse.out_type_id.id,
'location_id': self.stock_location.id,
'location_dest_id': self.customer_location.id,
+2 -2
View File
@@ -36,7 +36,7 @@ class EventSaleTest(common.TransactionCase):
# I create a sales order
self.sale_order = self.env['sale.order'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'partner_id': self.env['res.partner'].create({'name': 'My Attendee'}).id,
'note': 'Invoice after delivery',
'payment_term_id': self.env.ref('account.account_payment_term_end_following_month').id
})
@@ -93,7 +93,7 @@ class EventSaleTest(common.TransactionCase):
test_event_ticket = self.env['event.event.ticket'].create({
'name': 'TestTicket',
'event_id': test_event.id,
'product_id': 1,
'product_id': self.env['product.product'].search([], limit=1).id,
})
test_event_ticket.copy()
test_event_ticket.product_id.active = False
+19 -1
View File
@@ -1,8 +1,26 @@
import odoo.tests
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo.tests
from datetime import timedelta
from odoo.fields import Datetime
@odoo.tests.tagged('post_install', '-at_install')
class TestUi(odoo.tests.HttpCase):
def test_01_event_configurator(self):
event = self.env['event.event'].create({
'name': 'Design Fair Los Angeles',
'date_begin': Datetime.now() + timedelta(days=1),
'date_end': Datetime.now() + timedelta(days=5),
})
self.env['event.event.ticket'].create([{
'name': 'Standard',
'event_id': event.id,
'product_id': self.env.ref('event_sale.product_product_event').id,
}, {
'name': 'VIP',
'event_id': event.id,
'product_id': self.env.ref('event_sale.product_product_event').id,
}])
self.start_tour("/web", 'event_configurator_tour', login="admin")
+5 -4
View File
@@ -1,17 +1,19 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
from odoo.exceptions import UserError
from odoo.tests import common
class TestGamificationCommon(common.TransactionCase):
class TestGamificationCommon(TransactionCaseWithUserDemo):
def setUp(self):
super(TestGamificationCommon, self).setUp()
employees_group = self.env.ref('base.group_user')
self.user_ids = employees_group.users
# Push demo user into the challenge before creating a new one
self.env.ref('gamification.challenge_base_discover')._update_all()
self.robot = self.env['res.users'].with_context(no_reset_password=True).create({
'name': 'R2D2',
'login': 'r2d2@openerp.com',
@@ -25,7 +27,6 @@ class test_challenge(TestGamificationCommon):
def test_00_join_challenge(self):
challenge = self.env.ref('gamification.challenge_base_discover')
self.assertGreaterEqual(len(challenge.user_ids), len(self.user_ids), "Not enough users in base challenge")
challenge._update_all()
self.assertGreaterEqual(len(challenge.user_ids), len(self.user_ids)+1, "These are not droids you are looking for")
@@ -40,7 +41,7 @@ class test_challenge(TestGamificationCommon):
goal_ids = Goals.search([('challenge_id', '=', challenge.id), ('state', '!=', 'draft')])
self.assertEqual(len(goal_ids), len(challenge.line_ids) * len(challenge.user_ids.ids), "Incorrect number of goals generated, should be 1 goal per user, per challenge line")
demo = self.env.ref('base.user_demo')
demo = self.user_demo
# demo user will set a timezone
demo.tz = "Europe/Brussels"
goal_ids = Goals.search([('user_id', '=', demo.id), ('definition_id', '=', self.env.ref('gamification.definition_base_timezone').id)])
+13 -3
View File
@@ -8,9 +8,19 @@ class TestHrFlow(TestHrCommon):
def setUp(self):
super(TestHrFlow, self).setUp()
self.job_developer = self.env(user=self.res_users_hr_officer.id).ref('hr.job_developer')
self.employee_niv = self.env(user=self.res_users_hr_officer.id).ref('hr.employee_niv')
self.dep_rd = self.env['hr.department'].create({
'name': 'Research & Development',
})
self.job_developer = self.env['hr.job'].create({
'name': 'Experienced Developer',
'department_id': self.dep_rd.id,
'no_of_recruitment': 5,
})
self.employee_niv = self.env['hr.employee'].create({
'name': 'Sharlene Rhodes',
})
self.job_developer = self.job_developer.with_user(self.res_users_hr_officer.id)
self.employee_niv = self.employee_niv.with_user(self.res_users_hr_officer.id)
def test_open2recruit2close_job(self):
+31 -9
View File
@@ -146,13 +146,28 @@ class TestAccountEntry(TestExpenseCommon):
self.assertEqual(self.analytic_account.line_ids[0].product_id, self.product_expense, "Product of AAL should be the one from the expense")
def test_expense_from_email(self):
user_demo = self.env.ref('base.user_demo')
user_marc = self.env['res.users'].create({
'name': 'Marc User',
'login': 'Marc',
'email': 'marc.user@example.com',
})
self.env['hr.employee'].create({
'name': 'Marc Demo',
'user_id': user_marc.id,
})
air_ticket = self.env['product.product'].create({
'name': 'Air Flight',
'type': 'service',
'default_code': 'TESTREF',
'can_be_expensed': True,
})
self.tax.price_include = False
message_parsed = {
'message_id': 'the-world-is-a-ghetto',
'subject': 'EXP_AF 9876',
'email_from': 'mark.brown23@example.com',
'subject': 'TESTREF 9876',
'email_from': 'marc.user@example.com',
'to': 'catchall@yourcompany.com',
'body': "Don't you know, that for me, and for you",
'attachments': [],
@@ -160,20 +175,28 @@ class TestAccountEntry(TestExpenseCommon):
expense = self.env['hr.expense'].message_new(message_parsed)
air_ticket = self.env.ref("hr_expense.air_ticket")
self.assertEqual(expense.product_id, air_ticket)
self.assertEqual(expense.tax_ids.ids, [])
self.assertEqual(expense.total_amount, 9876.0)
self.assertTrue(expense.employee_id in user_demo.employee_ids)
self.assertTrue(expense.employee_id in user_marc.employee_ids)
def test_expense_from_email_without_product(self):
user_demo = self.env.ref('base.user_demo')
user_marc = self.env['res.users'].create({
'name': 'Marc User',
'login': 'Marc',
'email': 'marc.user@example.com',
})
self.env['hr.employee'].create({
'name': 'Marc Demo',
'user_id': user_marc.id,
})
self.tax.price_include = False
message_parsed = {
'message_id': 'the-world-is-a-ghetto',
'subject': 'no product code 9876',
'email_from': 'mark.brown23@example.com',
'email_from': 'marc.user@example.com',
'to': 'catchall@yourcompany.com',
'body': "Don't you know, that for me, and for you",
'attachments': [],
@@ -181,11 +204,10 @@ class TestAccountEntry(TestExpenseCommon):
expense = self.env['hr.expense'].message_new(message_parsed)
air_ticket = self.env.ref("hr_expense.air_ticket")
self.assertFalse(expense.product_id, "No product should be linked")
self.assertEqual(expense.tax_ids.ids, [])
self.assertEqual(expense.total_amount, 9876.0)
self.assertTrue(expense.employee_id in user_demo.employee_ids)
self.assertTrue(expense.employee_id in user_marc.employee_ids)
def test_partial_payment_multiexpense(self):
bank_journal = self.env['account.journal'].create({
+1
View File
@@ -9,6 +9,7 @@ class TestHrHolidaysBase(common.TransactionCase):
def setUp(self):
super(TestHrHolidaysBase, self).setUp()
self.env.user.tz = 'Europe/Brussels'
# Test users to use through the various tests
self.user_hruser = mail_new_test_user(self.env, login='armande', groups='base.group_user,hr_holidays.group_hr_holidays_user')
@@ -154,6 +154,7 @@ class TestAutomaticLeaveDates(TestHrHolidaysBase):
self.assertEqual(leave_form.number_of_hours_display, 8)
def test_attendance_next_day(self):
self.env.user.tz = 'Europe/Brussels'
calendar = self.env['resource.calendar'].create({
'name': 'auto next day',
'attendance_ids': [(5, 0, 0),
@@ -183,6 +184,7 @@ class TestAutomaticLeaveDates(TestHrHolidaysBase):
self.assertEqual(leave_form.date_to, datetime(2019, 9, 2, 10, 0, 0))
def test_attendance_previous_day(self):
self.env.user.tz = 'Europe/Brussels'
calendar = self.env['resource.calendar'].create({
'name': 'auto next day',
'attendance_ids': [(5, 0, 0),
@@ -212,6 +214,7 @@ class TestAutomaticLeaveDates(TestHrHolidaysBase):
self.assertEqual(leave_form.date_to, datetime(2019, 9, 3, 10, 0, 0))
def test_2weeks_calendar(self):
self.env.user.tz = 'Europe/Brussels'
calendar = self.env['resource.calendar'].create({
'name': 'auto next day',
'two_weeks_calendar': True,
@@ -265,6 +268,7 @@ class TestAutomaticLeaveDates(TestHrHolidaysBase):
self.assertEqual(leave_form.date_to, datetime(2019, 9, 9, 10, 0, 0))
def test_2weeks_calendar_next_week(self):
self.env.user.tz = 'Europe/Brussels'
calendar = self.env['resource.calendar'].create({
'name': 'auto next day',
'two_weeks_calendar': True,
+46 -6
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import time
from datetime import datetime
from dateutil.relativedelta import relativedelta
from psycopg2 import IntegrityError
@@ -84,6 +84,30 @@ class TestHolidaysFlow(TestHrHolidaysBase):
Allocations = self.env['hr.leave.allocation']
HolidaysStatus = self.env['hr.leave.type']
holiday_status_paid_time_off = self.env['hr.leave.type'].create({
'name': 'Paid Time Off',
'allocation_type': 'fixed',
'validation_type': 'both',
'validity_start': time.strftime('%Y-%m-01'),
'responsible_id': self.env.ref('base.user_admin').id,
})
self.env['hr.leave.allocation'].create([
{
'name': 'Paid Time off for David',
'holiday_status_id': holiday_status_paid_time_off.id,
'number_of_days': 20,
'employee_id': self.employee_emp_id,
'state': 'validate',
}, {
'name': 'Paid Time off for David',
'holiday_status_id': holiday_status_paid_time_off.id,
'number_of_days': 20,
'employee_id': self.ref('hr.employee_admin'),
'state': 'validate',
}
])
def _check_holidays_status(holiday_status, ml, lt, rl, vrl):
self.assertEqual(holiday_status.max_leaves, ml,
'hr_holidays: wrong type days computation')
@@ -172,7 +196,7 @@ class TestHolidaysFlow(TestHrHolidaysBase):
employee_id = self.ref('hr.employee_admin')
# cl can be of maximum 20 days for employee_admin
hol3_status = self.env.ref('hr_holidays.holiday_status_cl').with_context(employee_id=employee_id)
hol3_status = holiday_status_paid_time_off.with_context(employee_id=employee_id)
# I assign the dates in the holiday request for 1 day
hol3 = Requests.create({
'name': 'Sick Time Off',
@@ -201,11 +225,11 @@ class TestHolidaysFlow(TestHrHolidaysBase):
# Print the HR Holidays(Summary Employee) Report through the wizard
ctx = {
'model': 'hr.employee',
'active_ids': [self.ref('hr.employee_admin'), self.ref('hr.employee_qdp'), self.ref('hr.employee_al')]
'active_ids': [self.ref('hr.employee_admin')]
}
data_dict = {
'date_from': datetime.today().strftime('%Y-%m-01'),
'emp': [(6, 0, [self.ref('hr.employee_admin'), self.ref('hr.employee_qdp'), self.ref('hr.employee_al')])],
'emp': [(6, 0, [self.ref('hr.employee_admin')])],
'holiday_type': 'Approved'
}
self.env.company.external_report_layout_id = self.env.ref('web.external_layout_standard').id
@@ -216,9 +240,25 @@ class TestHolidaysFlow(TestHrHolidaysBase):
# error message is triggered if the date_from is after
# date_to. Coming from a bug due to the new ORM 13.0
holiday_status_paid_time_off = self.env['hr.leave.type'].create({
'name': 'Paid Time Off',
'allocation_type': 'fixed',
'validation_type': 'both',
'validity_start': time.strftime('%Y-%m-01'),
'responsible_id': self.env.ref('base.user_admin').id,
})
self.env['hr.leave.allocation'].create({
'name': 'Paid Time off for David',
'holiday_status_id': holiday_status_paid_time_off.id,
'number_of_days': 20,
'employee_id': self.ref('hr.employee_admin'),
'state': 'validate',
})
leave_vals = {
'name': 'Sick Time Off',
'holiday_status_id': self.env.ref('hr_holidays.holiday_status_cl').id,
'holiday_status_id': holiday_status_paid_time_off.id,
'date_from': datetime.today().strftime('%Y-%m-11 19:00:00'),
'date_to': datetime.today().strftime('%Y-%m-10 10:00:00'),
'employee_id': self.ref('hr.employee_admin'),
@@ -231,7 +271,7 @@ class TestHolidaysFlow(TestHrHolidaysBase):
leave_vals = {
'name': 'Sick Time Off',
'holiday_status_id': self.env.ref('hr_holidays.holiday_status_cl').id,
'holiday_status_id': holiday_status_paid_time_off.id,
'date_from': datetime.today().strftime('%Y-%m-10 10:00:00'),
'date_to': datetime.today().strftime('%Y-%m-11 19:00:00'),
'employee_id': self.ref('hr.employee_admin'),
@@ -4,6 +4,7 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
from odoo.tests.common import tagged, users, warmup, Form
from odoo.addons.hr_holidays.tests.common import TestHrHolidaysBase
@@ -54,7 +55,7 @@ class TestOutOfOffice(TestHrHolidaysBase):
self.assertEqual(infos[0]['direct_partner'][0]['out_of_office_date_end'], leave_date_end)
@tagged('out_of_office')
class TestOutOfOfficePerformance(TestHrHolidaysBase):
class TestOutOfOfficePerformance(TestHrHolidaysBase, TransactionCaseWithUserDemo):
def setUp(self):
super(TestOutOfOfficePerformance, self).setUp()
@@ -2,10 +2,11 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import common
from odoo.addons.hr.tests.test_hr_flow import TestHrFlow
from odoo.modules.module import get_module_resource
class TestRecruitmentProcess(common.TransactionCase):
class TestRecruitmentProcess(TestHrFlow):
def test_00_recruitment_process(self):
""" Test recruitment process """
@@ -24,7 +25,7 @@ class TestRecruitmentProcess(common.TransactionCase):
with open(get_module_resource('hr_recruitment', 'tests', 'resume.eml'), 'rb') as request_file:
request_message = request_file.read()
self.env['mail.thread'].with_user(self.res_users_hr_recruitment_officer).message_process(
'hr.applicant', request_message, custom_values={"job_id": self.env.ref('hr.job_developer').id})
'hr.applicant', request_message, custom_values={"job_id": self.job_developer.id})
# After getting the mail, I check the details of the new applicant.
applicant = self.env['hr.applicant'].search([('email_from', 'ilike', 'Richard_Anderson@yahoo.com')], limit=1)
@@ -38,7 +39,7 @@ class TestRecruitmentProcess(common.TransactionCase):
"Stage should be 'Initial qualification' and is '%s'." % (applicant.stage_id.name))
self.assertTrue(resume_ids, 'Resume is not attached.')
# I assign the Job position to the applicant
applicant.write({'job_id': self.env.ref('hr.job_developer').id})
applicant.write({'job_id': self.job_developer.id})
# I schedule meeting with applicant for interview.
applicant_meeting = applicant.action_makeMeeting()
self.assertEqual(applicant_meeting['context']['default_name'], 'Application for the post of Jr.application Programmer.',
@@ -10,6 +10,13 @@ class TestCommonTimesheet(TransactionCase):
def setUp(self):
super(TestCommonTimesheet, self).setUp()
# Crappy hack to disable the rule from timesheet grid, if it exists
# The registry doesn't contain the field timesheet_manager_id.
# but there is an ir.rule about it, crashing during its evaluation
rule = self.env.ref('timesheet_grid.hr_timesheet_rule_approver_update', raise_if_not_found=False)
if rule:
rule.active = False
# customer partner
self.partner = self.env['res.partner'].create({
'name': 'Customer Task',
+1
View File
@@ -42,6 +42,7 @@ class TestSupplier(TestsCommon):
'''
This test checks that _search_available_today returns a valid domain
'''
self.env.user.tz = 'Europe/Brussels'
Supplier = self.env['lunch.supplier']
tests = [(self.monday_1am, 1.0, 'monday'), (self.monday_10am, 10.0, 'monday'),
+8 -3
View File
@@ -36,12 +36,17 @@ class TestEquipment(TransactionCase):
groups_id=[(6, 0, [res_manager.id])]
))
self.equipment_monitor = self.env['maintenance.equipment.category'].create({
'name': 'Monitors',
'alias_id': self.env.ref('maintenance.mail_alias_equipment').id,
})
def test_10_equipment_request_category(self):
# Create a new equipment
equipment_01 = self.equipment.with_user(self.manager).create({
'name': 'Samsung Monitor "15',
'category_id': self.ref('maintenance.equipment_monitor'),
'category_id': self.equipment_monitor.id,
'technician_user_id': self.ref('base.user_root'),
'owner_user_id': self.user.id,
'assign_date': time.strftime('%Y-%m-%d'),
@@ -80,7 +85,7 @@ class TestEquipment(TransactionCase):
""" Check the cron creates the necessary preventive maintenance requests"""
equipment_cron = self.equipment.create({
'name': 'High Maintenance Monitor because of Color Calibration',
'category_id': self.ref('maintenance.equipment_monitor'),
'category_id': self.equipment_monitor.id,
'technician_user_id': self.ref('base.user_root'),
'owner_user_id': self.user.id,
'assign_date': time.strftime('%Y-%m-%d'),
@@ -113,7 +118,7 @@ class TestEquipment(TransactionCase):
})
equipment = self.equipment.create({
'name': 'High Maintenance Monitor because of Color Calibration',
'category_id': self.ref('maintenance.equipment_monitor'),
'category_id': self.equipment_monitor.id,
'technician_user_id': self.ref('base.user_root'),
'owner_user_id': self.user.id,
'assign_date': time.strftime('%Y-%m-%d'),
@@ -71,7 +71,7 @@ Email: <a id="url4" href="mailto:test@odoo.com">test@odoo.com</h1>
sent_mails = self.env['mail.mail'].search([('mailing_id', '=', mass_mailing.id)])
sent_messages = sent_mails.mapped('mail_message_id')
self.assertEqual(mailing_list_A.contact_nbr, len(sent_messages),
self.assertEqual(len(mailing_list_A.contact_ids), len(sent_messages),
'Some message has not been sent')
xbody = etree.fromstring(sent_messages[0].body)
-3
View File
@@ -30,7 +30,4 @@ invoice and send propositions for membership renewal.
'report/report_membership_views.xml',
],
'website': 'https://www.odoo.com/page/community-builder',
'test': [
'../account/test/account_minimal_test.xml',
],
}
+24
View File
@@ -154,3 +154,27 @@ class TestMrpCommon(common2.TestStockCommon):
(0, 0, {'product_id': cls.product_4.id, 'product_qty': 8}),
(0, 0, {'product_id': cls.product_2.id, 'product_qty': 12})
]})
cls.stock_location_14 = cls.env['stock.location'].create({
'name': 'Shelf 2',
'location_id': cls.env.ref('stock.warehouse0').lot_stock_id.id,
})
cls.stock_location_components = cls.env['stock.location'].create({
'name': 'Shelf 1',
'location_id': cls.env.ref('stock.warehouse0').lot_stock_id.id,
})
cls.laptop = cls.env['product.product'].create({
'name': 'Acoustic Bloc Screens',
'uom_id': cls.env.ref("uom.product_uom_unit").id,
'uom_po_id': cls.env.ref("uom.product_uom_unit").id,
'type': 'product',
'tracking': 'none',
'categ_id': cls.env.ref('product.product_category_all').id,
})
cls.graphics_card = cls.env['product.product'].create({
'name': 'Individual Workplace',
'uom_id': cls.env.ref("uom.product_uom_unit").id,
'uom_po_id': cls.env.ref("uom.product_uom_unit").id,
'type': 'product',
'tracking': 'none',
'categ_id': cls.env.ref('product.product_category_all').id,
})
+45 -16
View File
@@ -131,7 +131,7 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant'].with_context(inventory_mode=True).create({
'product_id': self.product_2.id,
'inventory_quantity': 2.0,
'location_id': self.ref('stock.stock_location_14')
'location_id': self.stock_location_14.id
})
production_2.action_assign()
@@ -142,7 +142,7 @@ class TestMrpOrder(TestMrpCommon):
self.env['stock.quant'].with_context(inventory_mode=True).create({
'product_id': self.product_2.id,
'inventory_quantity': 5.0,
'location_id': self.ref('stock.stock_location_14')
'location_id': self.stock_location_14.id
})
production_2.action_assign()
@@ -163,8 +163,13 @@ class TestMrpOrder(TestMrpCommon):
# create a bom for `custom_laptop` with components that aren't tracked
unit = self.ref("uom.product_uom_unit")
custom_laptop = self.env.ref("product.product_product_27")
custom_laptop.tracking = 'none'
custom_laptop = self.env['product.product'].create({
'name': 'Drawer',
'type': 'product',
'uom_id': unit,
'uom_po_id': unit,
})
product_charger = self.env['product.product'].create({
'name': 'Charger',
'type': 'product',
@@ -191,7 +196,7 @@ class TestMrpOrder(TestMrpCommon):
})
# put the needed products in stock
source_location_id = self.ref('stock.stock_location_14')
source_location_id = self.stock_location_14.id
quant_before = custom_laptop.qty_available
inventory = self.env['stock.inventory'].create({
'name': 'Inventory Product Table',
@@ -463,8 +468,9 @@ class TestMrpOrder(TestMrpCommon):
"""
# FIXME: some asserts on the quants after overproducing would be nice
self.stock_location = self.env.ref('stock.stock_location_stock')
self.stock_shelf_1 = self.env.ref('stock.stock_location_components')
self.stock_shelf_2 = self.env.ref('stock.stock_location_14')
self.stock_shelf_1 = self.stock_location_components
self.stock_shelf_2 = self.stock_location_14
mo, _, p_final, p1, p2 = self.generate_mo(tracking_base_1='lot', qty_base_1=10, qty_final=1)
self.assertEqual(len(mo), 1, 'MO should have been created')
@@ -530,8 +536,8 @@ class TestMrpOrder(TestMrpCommon):
""" Possibility to produce with a given raw material in multiple locations. """
# FIXME sle: how is it possible to consume before producing in the interface?
self.stock_location = self.env.ref('stock.stock_location_stock')
self.stock_shelf_1 = self.env.ref('stock.stock_location_components')
self.stock_shelf_2 = self.env.ref('stock.stock_location_14')
self.stock_shelf_1 = self.stock_location_components
self.stock_shelf_2 = self.stock_location_14
mo, _, p_final, p1, p2 = self.generate_mo(qty_final=1, qty_base_1=5)
self.env['stock.quant']._update_available_quantity(p1, self.stock_shelf_1, 2)
@@ -616,8 +622,8 @@ class TestMrpOrder(TestMrpCommon):
self.assertEqual(len(mo), 1, 'MO should have been created')
self.stock_location = self.env.ref('stock.stock_location_stock')
self.stock_shelf_1 = self.env.ref('stock.stock_location_components')
self.stock_shelf_2 = self.env.ref('stock.stock_location_14')
self.stock_shelf_1 = self.stock_location_components
self.stock_shelf_2 = self.stock_location_14
self.env['stock.quant']._update_available_quantity(p1, self.stock_shelf_1, 3)
self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 3)
@@ -1146,13 +1152,36 @@ class TestMrpOrder(TestMrpCommon):
""" Produce a finished product tracked by serial number. Set another
UoM on the bom. The produce wizard should keep the UoM of the product (unit)
and quantity = 1."""
plastic_laminate = self.env.ref('mrp.product_product_plastic_laminate')
bom = self.env.ref('mrp.mrp_bom_plastic_laminate')
dozen = self.env.ref('uom.product_uom_dozen')
unit = self.env.ref('uom.product_uom_unit')
plastic_laminate.tracking = 'serial'
plastic_laminate = self.env['product.product'].create({
'name': 'Plastic Laminate',
'type': 'product',
'uom_id': unit.id,
'uom_po_id': unit.id,
'tracking': 'serial',
})
ply_veneer = self.env['product.product'].create({
'name': 'Ply Veneer',
'type': 'product',
'uom_id': unit.id,
'uom_po_id': unit.id,
})
routing = self.env['mrp.routing'].create({
'name': 'Secondary Assembly',
})
bom = self.env['mrp.bom'].create({
'product_tmpl_id': plastic_laminate.product_tmpl_id.id,
'product_uom_id': unit.id,
'sequence': 1,
'routing_id': routing.id,
'bom_line_ids': [(0, 0, {
'product_id': ply_veneer.id,
'product_qty': 1,
'product_uom_id': unit.id,
'sequence': 1,
})]
})
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = plastic_laminate
+26 -8
View File
@@ -10,6 +10,7 @@ class TestWarehouse(common.TestMrpCommon):
def setUp(self):
super(TestWarehouse, self).setUp()
unit = self.env.ref("uom.product_uom_unit")
self.stock_location = self.env.ref('stock.stock_location_stock')
self.depot_location = self.env['stock.location'].create({
'name': 'Depot',
@@ -21,18 +22,35 @@ class TestWarehouse(common.TestMrpCommon):
"location_out_id": self.depot_location.id,
'category_id': self.env.ref('product.product_category_all').id,
})
self.laptop = self.env.ref("product.product_product_25")
graphics_card = self.env.ref("product.product_product_24")
unit = self.env.ref("uom.product_uom_unit")
mrp_routing = self.env.ref("mrp.mrp_routing_0")
mrp_workcenter = self.env['mrp.workcenter'].create({
'name': 'Assembly Line 1',
'resource_calendar_id': self.env.ref('resource.resource_calendar_std').id,
})
mrp_routing = self.env['mrp.routing'].create({
'name': 'Primary Assembly',
'operation_ids': [(0, 0, {
'workcenter_id': mrp_workcenter.id,
'name': 'Manual Assembly',
})]
})
inventory = self.env['stock.inventory'].create({
'name': 'Initial inventory',
'line_ids': [(0, 0, {
'product_id': self.graphics_card.id,
'product_uom_id': self.graphics_card.uom_id.id,
'product_qty': 16.0,
'location_id': self.stock_location_14.id,
})]
})
inventory.action_start()
inventory.action_validate()
self.bom_laptop = self.env['mrp.bom'].create({
'product_tmpl_id': self.laptop.product_tmpl_id.id,
'product_qty': 1,
'product_uom_id': unit.id,
'bom_line_ids': [(0, 0, {
'product_id': graphics_card.id,
'product_id': self.graphics_card.id,
'product_qty': 1,
'product_uom_id': unit.id
})],
@@ -102,14 +120,14 @@ class TestWarehouse(common.TestMrpCommon):
'name': 'Stock Inventory for Stick',
'product_ids': [(4, self.product_4.id)],
'line_ids': [
(0, 0, {'product_id': self.product_4.id, 'product_uom_id': self.product_4.uom_id.id, 'product_qty': 8, 'prod_lot_id': lot_product_4.id, 'location_id': self.ref('stock.stock_location_14')}),
(0, 0, {'product_id': self.product_4.id, 'product_uom_id': self.product_4.uom_id.id, 'product_qty': 8, 'prod_lot_id': lot_product_4.id, 'location_id': self.stock_location_14.id}),
]})
stock_inv_product_2 = self.env['stock.inventory'].create({
'name': 'Stock Inventory for Stone Tools',
'product_ids': [(4, self.product_2.id)],
'line_ids': [
(0, 0, {'product_id': self.product_2.id, 'product_uom_id': self.product_2.uom_id.id, 'product_qty': 12, 'prod_lot_id': lot_product_2.id, 'location_id': self.ref('stock.stock_location_14')})
(0, 0, {'product_id': self.product_2.id, 'product_uom_id': self.product_2.uom_id.id, 'product_qty': 12, 'prod_lot_id': lot_product_2.id, 'location_id': self.stock_location_14.id})
]})
(stock_inv_product_4 | stock_inv_product_2)._action_start()
stock_inv_product_2.action_validate()
+3 -1
View File
@@ -5,11 +5,13 @@ from odoo.tests import Form
from odoo.addons.mrp.tests.common import TestMrpCommon
from odoo.exceptions import UserError
class TestUnbuild(TestMrpCommon):
def setUp(self):
super(TestUnbuild, self).setUp()
self.stock_location = self.env.ref('stock.stock_location_stock')
self.env.ref('base.group_user').write({
'implied_ids': [(4, self.env.ref('stock.group_production_lot').id)]
})
def test_unbuild_standart(self):
""" This test creates a MO and then creates 3 unbuild
+212 -39
View File
@@ -26,7 +26,7 @@ class TestWorkOrderProcess(TestMrpCommon):
@classmethod
def setUpClass(cls):
super(TestWorkOrderProcess, cls).setUpClass()
cls.source_location_id = cls.env.ref('stock.stock_location_14').id
cls.source_location_id = cls.stock_location_14.id
cls.warehouse = cls.env.ref('stock.warehouse0')
# setting up alternative workcenters
cls.wc_alt_1 = cls.env['mrp.workcenter'].create({
@@ -55,22 +55,118 @@ class TestWorkOrderProcess(TestMrpCommon):
(0, 0, {'product_id': cls.product_2.id, 'product_qty': 2}),
(0, 0, {'product_id': cls.product_1.id, 'product_qty': 4})
]})
cls.dining_table = cls.env['product.product'].create({
'name': 'Table (MTO)',
'type': 'product',
'tracking': 'serial',
})
cls.product_table_sheet = cls.env['product.product'].create({
'name': 'Table Top',
'type': 'product',
'tracking': 'serial',
})
cls.product_table_leg = cls.env['product.product'].create({
'name': 'Table Leg',
'type': 'product',
'tracking': 'lot',
})
cls.product_bolt = cls.env['product.product'].create({
'name': 'Bolt',
'type': 'product',
})
cls.product_screw = cls.env['product.product'].create({
'name': 'Screw',
'type': 'product',
})
cls.mrp_workcenter = cls.env['mrp.workcenter'].create({
'name': 'Assembly Line 1',
'resource_calendar_id': cls.env.ref('resource.resource_calendar_std').id,
})
cls.routing = cls.env['mrp.routing'].create({
'name': 'Assemble Furniture',
'operation_ids': [(0, 0, {
'workcenter_id': cls.mrp_workcenter.id,
'name': 'Manual Assembly',
})]
})
cls.mrp_bom_desk = cls.env['mrp.bom'].create({
'product_tmpl_id': cls.dining_table.product_tmpl_id.id,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'sequence': 3,
'consumption': 'flexible',
'routing_id': cls.routing.id,
'bom_line_ids': [
(0, 0, {
'product_id': cls.product_table_sheet.id,
'product_qty': 1,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'sequence': 1,
'operation_id': cls.routing.operation_ids.id}),
(0, 0, {
'product_id': cls.product_table_leg.id,
'product_qty': 4,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'sequence': 2,
'operation_id': cls.routing.operation_ids.id}),
(0, 0, {
'product_id': cls.product_bolt.id,
'product_qty': 4,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'sequence': 3,
'operation_id': cls.routing.operation_ids.id}),
(0, 0, {
'product_id': cls.product_screw.id,
'product_qty': 10,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'sequence': 4,
'operation_id': cls.routing.operation_ids.id}),
]
})
cls.mrp_workcenter_1 = cls.env['mrp.workcenter'].create({
'name': 'Drill Station 1',
'resource_calendar_id': cls.env.ref('resource.resource_calendar_std').id,
})
cls.mrp_workcenter_3 = cls.env['mrp.workcenter'].create({
'name': 'Assembly Line 1',
'resource_calendar_id': cls.env.ref('resource.resource_calendar_std').id,
})
cls.routing_1 = cls.env['mrp.routing'].create({
'name': 'Secondary Assembly',
'operation_ids': [
(0, 0, {
'workcenter_id': cls.mrp_workcenter_1.id,
'name': 'Packing',
'time_cycle': 30,
'sequence': 5}),
(0, 0, {
'workcenter_id': cls.mrp_workcenter_3.id,
'name': 'Testing',
'time_cycle': 60,
'sequence': 10}),
(0, 0, {
'workcenter_id': cls.mrp_workcenter_3.id,
'name': 'Long time assembly',
'time_cycle': 180,
'sequence': 15}),
]
})
def test_00_workorder_process(self):
""" Testing consume quants and produced quants with workorder """
dining_table = self.dining_table
product_table_sheet = self.product_table_sheet
product_table_leg = self.product_table_leg
product_bolt = self.product_bolt
product_screw = self.product_screw
mrp_bom_desk = self.mrp_bom_desk
dining_table = self.env.ref("mrp.product_product_computer_desk")
product_table_sheet = self.env.ref('mrp.product_product_computer_desk_head')
product_table_leg = self.env.ref('mrp.product_product_computer_desk_leg')
product_bolt = self.env.ref('mrp.product_product_computer_desk_bolt')
product_screw = self.env.ref('mrp.product_product_computer_desk_screw')
self.env['stock.move'].search([('product_id', 'in', [product_bolt.id, product_screw.id])])._do_unreserve()
(product_bolt + product_screw).write({'type': 'product'})
self.env.ref("mrp.mrp_bom_desk").consumption = 'flexible'
production_table_form = Form(self.env['mrp.production'])
production_table_form.product_id = dining_table
production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk")
production_table_form.bom_id = mrp_bom_desk
production_table_form.product_qty = 1.0
production_table_form.product_uom_id = dining_table.uom_id
production_table = production_table_form.save()
@@ -145,6 +241,12 @@ class TestWorkOrderProcess(TestMrpCommon):
if workorder_line_id.product_id.id == product_table_leg.id:
workorder_line_id.write({'lot_id': lot_leg.id, 'qty_done': 1})
self.assertEqual(workorder.state, 'progress')
# YTI Clean that brol
# If mrp_workorder is installed, there could be checks defined on the
# workorder.
if hasattr(self.env['mrp.workorder'], 'check_ids'):
self.env['mrp.workorder'].search([]).write({'check_ids': False})
workorder.record_production()
self.assertEqual(workorder.state, 'done')
move_table_sheet = production_table.move_raw_ids.filtered(lambda x : x.product_id == product_table_sheet)
@@ -162,16 +264,16 @@ class TestWorkOrderProcess(TestMrpCommon):
def test_00b_workorder_process(self):
""" Testing consume quants and produced quants with workorder """
dining_table = self.env.ref("mrp.product_product_computer_desk")
product_table_sheet = self.env.ref('mrp.product_product_computer_desk_head')
product_table_leg = self.env.ref('mrp.product_product_computer_desk_leg')
product_bolt = self.env.ref('mrp.product_product_computer_desk_bolt')
self.env['stock.move'].search([('product_id', '=', product_bolt.id)])._do_unreserve()
product_bolt.type = 'product'
dining_table = self.dining_table
product_table_sheet = self.product_table_sheet
product_table_leg = self.product_table_leg
product_bolt = self.product_bolt
product_screw = self.product_screw
bom = self.mrp_bom_desk
bom = self.env['mrp.bom'].browse(self.ref("mrp.mrp_bom_desk"))
bom.routing_id = self.ref('mrp.mrp_routing_1')
bom.consumption = 'flexible'
self.env['stock.move'].search([('product_id', '=', product_bolt.id)])._do_unreserve()
bom.routing_id = self.routing_1
bom.bom_line_ids.filtered(lambda p: p.product_id == product_table_sheet).operation_id = bom.routing_id.operation_ids[0]
bom.bom_line_ids.filtered(lambda p: p.product_id == product_table_leg).operation_id = bom.routing_id.operation_ids[1]
@@ -243,6 +345,12 @@ class TestWorkOrderProcess(TestMrpCommon):
workorders[0].button_start()
workorders[0]._workorder_line_ids()[0].write({'lot_id': lot_sheet.id, 'qty_done': 1})
self.assertEqual(workorders[0].state, 'progress')
# YTI Clean that brol
# If mrp_workorder is installed, there could be checks defined on the
# workorder.
if hasattr(self.env['mrp.workorder'], 'check_ids'):
self.env['mrp.workorder'].search([]).write({'check_ids': False})
workorders[0].record_production()
move_table_sheet = production_table.move_raw_ids.filtered(lambda p: p.product_id == product_table_sheet)
@@ -352,18 +460,18 @@ class TestWorkOrderProcess(TestMrpCommon):
'product_uom_id': self.product_2.uom_id.id,
'product_qty': 30,
'prod_lot_id': lot_product_2.id,
'location_id': self.ref('stock.stock_location_14')
'location_id': self.stock_location_14.id
}), (0, 0, {
'product_id': self.product_3.id,
'product_uom_id': self.product_3.uom_id.id,
'product_qty': 60,
'location_id': self.ref('stock.stock_location_14')
'location_id': self.stock_location_14.id
}), (0, 0, {
'product_id': self.product_4.id,
'product_uom_id': self.product_4.uom_id.id,
'product_qty': 60,
'prod_lot_id': lot_product_4.id,
'location_id': self.ref('stock.stock_location_14')
'location_id': self.stock_location_14.id
})]
})
inventory.action_start()
@@ -428,8 +536,11 @@ class TestWorkOrderProcess(TestMrpCommon):
def test_01_without_workorder(self):
""" Testing consume quants and produced quants without workorder """
unit = self.ref("uom.product_uom_unit")
custom_laptop = self.env.ref("product.product_product_27")
custom_laptop.tracking = 'lot'
custom_laptop = self.env['product.product'].create({
'name': 'Drawer',
'type': 'product',
'tracking': 'lot',
})
# Create new product charger and keybord
# --------------------------------------
@@ -710,10 +821,10 @@ class TestWorkOrderProcess(TestMrpCommon):
def test_03_test_serial_number_defaults(self):
""" Test that the correct serial number is suggested on consecutive work orders. """
laptop = self.env.ref("product.product_product_25")
graphics_card = self.env.ref("product.product_product_24")
laptop = self.laptop
graphics_card = self.graphics_card
unit = self.env.ref("uom.product_uom_unit")
three_step_routing = self.env.ref("mrp.mrp_routing_1")
three_step_routing = self.routing_1
laptop.tracking = 'serial'
@@ -769,7 +880,55 @@ class TestWorkOrderProcess(TestMrpCommon):
serial number. It should be allowed since the first workorder did not
specify a seiral number.
"""
bom = self.env.ref('mrp.mrp_bom_laptop_cust_rout')
drawer = self.env['product.product'].create({
'name': 'Drawer',
'type': 'product',
'tracking': 'lot',
})
drawer_drawer = self.env['product.product'].create({
'name': 'Drawer Black',
'type': 'product',
'tracking': 'lot',
})
drawer_case = self.env['product.product'].create({
'name': 'Drawer Case Black',
'type': 'product',
'tracking': 'lot',
})
bom = self.env['mrp.bom'].create({
'product_tmpl_id': drawer.product_tmpl_id.id,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'sequence': 2,
'routing_id': self.routing_1.id,
'bom_line_ids': [(0, 0, {
'product_id': drawer_drawer.id,
'product_qty': 1,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'sequence': 1,
}), (0, 0, {
'product_id': drawer_case.id,
'product_qty': 1,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'sequence': 2,
})]
})
inventory = self.env['stock.inventory'].create({
'name': 'Initial inventory',
'line_ids': [(0, 0, {
'product_id': drawer_drawer.id,
'product_uom_id': drawer_drawer.uom_id.id,
'product_qty': 50.0,
'location_id': self.stock_location_14.id,
}), (0, 0, {
'product_id': drawer_case.id,
'product_uom_id': drawer_case.uom_id.id,
'product_qty': 50.0,
'location_id': self.stock_location_14.id,
})]
})
inventory.action_start()
inventory.action_validate()
product = bom.product_tmpl_id.product_variant_id
product.tracking = 'serial'
@@ -828,11 +987,11 @@ class TestWorkOrderProcess(TestMrpCommon):
# The workcenter is working 24/7
self.full_availability()
dining_table = self.env.ref("mrp.product_product_computer_desk")
dining_table = self.dining_table
production_table_form = Form(self.env['mrp.production'])
production_table_form.product_id = dining_table
production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk")
production_table_form.bom_id = self.mrp_bom_desk
production_table_form.product_qty = 1.0
production_table_form.product_uom_id = dining_table.uom_id
production_table = production_table_form.save()
@@ -851,13 +1010,13 @@ class TestWorkOrderProcess(TestMrpCommon):
# The workcenter is working 24/7
self.full_availability()
dining_table = self.env.ref("mrp.product_product_computer_desk")
dining_table = self.dining_table
date_start = datetime.now() + timedelta(days=1)
production_table_form = Form(self.env['mrp.production'])
production_table_form.product_id = dining_table
production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk")
production_table_form.bom_id = self.mrp_bom_desk
production_table_form.product_qty = 1.0
production_table_form.product_uom_id = dining_table.uom_id
production_table_form.date_start_wo = date_start
@@ -874,11 +1033,11 @@ class TestWorkOrderProcess(TestMrpCommon):
def test_change_production_1(self):
"""Change the quantity to produce on the MO while workorders are already planned."""
dining_table = self.env.ref("mrp.product_product_computer_desk")
dining_table = self.dining_table
dining_table.tracking = 'lot'
production_table_form = Form(self.env['mrp.production'])
production_table_form.product_id = dining_table
production_table_form.bom_id = self.env.ref("mrp.mrp_bom_desk")
production_table_form.bom_id = self.mrp_bom_desk
production_table_form.product_qty = 1.0
production_table_form.product_uom_id = dining_table.uom_id
production_table = production_table_form.save()
@@ -1067,7 +1226,20 @@ class TestWorkOrderProcess(TestMrpCommon):
production sooner """
self.workcenter_1.alternative_workcenter_ids = self.wc_alt_1 | self.wc_alt_2
self.env['mrp.workcenter'].search([]).write({'tz': 'UTC'}) # compute all date in UTC
self.planning_bom.routing = self.env.ref("mrp.mrp_routing_0")
mrp_routing_0 = self.env['mrp.routing'].create({
'name': 'Primary Assembly',
})
mrp_workcenter_3 = self.env['mrp.workcenter'].create({
'name': 'Assembly Line 1',
'resource_calendar_id': self.env.ref('resource.resource_calendar_std').id,
})
mrp_routing_workcenter_0 = self.env['mrp.routing.workcenter'].create({
'routing_id': mrp_routing_0.id,
'workcenter_id': mrp_workcenter_3.id,
'name': 'Manual Assembly',
'time_cycle': 60,
})
self.planning_bom.routing = mrp_routing_0
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = self.product_4
mo_form.bom_id = self.planning_bom
@@ -1172,11 +1344,12 @@ class TestWorkOrderProcess(TestMrpCommon):
mo.action_assign()
mo.button_plan()
self.assertEqual(len(mo.workorder_ids), 1)
self.assertEqual(len(mo.workorder_ids.raw_workorder_line_ids), 3)
line1 = mo.workorder_ids.raw_workorder_line_ids[0]
line2 = mo.workorder_ids.raw_workorder_line_ids[1]
line3 = mo.workorder_ids.raw_workorder_line_ids[2]
self.assertEqual(len(mo.workorder_ids), 3)
long_time_assembly = mo.workorder_ids[2]
self.assertEqual(len(long_time_assembly.raw_workorder_line_ids), 3)
line1 = long_time_assembly.raw_workorder_line_ids[0]
line2 = long_time_assembly.raw_workorder_line_ids[1]
line3 = long_time_assembly.raw_workorder_line_ids[2]
self.assertEqual(line1.product_id, self.product_1)
self.assertEqual(line1.qty_done, 1)
self.assertEqual(line2.product_id, self.product_2)
+28 -37
View File
@@ -1,41 +1,44 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.mrp.tests.test_workorder_operation import TestWorkOrderProcess
from odoo.tests import Form
from odoo.tests import common
class TestMrpAccount(common.TransactionCase):
class TestMrpAccount(TestWorkOrderProcess):
def setUp(self):
super(TestMrpAccount, self).setUp()
self.categ_standard = self.env['product.category'].create({'name': 'STANDARD',
'property_cost_method': 'standard',},)
self.categ_real = self.env['product.category'].create({'name': 'REAL',
'property_cost_method': 'fifo',})
self.categ_average = self.env['product.category'].create({'name': 'AVERAGE',
'property_cost_method': 'average'})
self.dining_table = self.env.ref("mrp.product_product_computer_desk")
self.dining_table.categ_id = self.categ_real.id
self.product_table_sheet = self.env.ref('mrp.product_product_computer_desk_head')
self.product_table_sheet.categ_id = self.categ_real.id
self.product_table_leg = self.env.ref('mrp.product_product_computer_desk_leg')
self.product_table_leg.categ_id = self.categ_average.id
self.product_bolt = self.env.ref('mrp.product_product_computer_desk_bolt')
self.product_bolt.categ_id = self.categ_standard.id
self.source_location_id = self.ref('stock.stock_location_14')
self.product_screw = self.env.ref('mrp.product_product_computer_desk_screw')
self.product_screw.categ_id = self.categ_standard.id
self.env['stock.move'].search([('product_id', 'in', [self.product_bolt.id, self.product_screw.id])])._do_unreserve()
(self.product_bolt + self.product_screw).write({'type': 'product'})
self.product_desk = self.env.ref('mrp.product_product_computer_desk')
self.product_desk.tracking = 'none'
@classmethod
def setUpClass(cls):
super(TestMrpAccount, cls).setUpClass()
cls.categ_standard = cls.env['product.category'].create({
'name': 'STANDARD',
'property_cost_method': 'standard'
})
cls.categ_real = cls.env['product.category'].create({
'name': 'REAL',
'property_cost_method': 'fifo'
})
cls.categ_average = cls.env['product.category'].create({
'name': 'AVERAGE',
'property_cost_method': 'average'
})
cls.dining_table.categ_id = cls.categ_real.id
cls.product_table_sheet.categ_id = cls.categ_real.id
cls.product_table_leg.categ_id = cls.categ_average.id
cls.product_bolt.categ_id = cls.categ_standard.id
cls.product_screw.categ_id = cls.categ_standard.id
cls.env['stock.move'].search([('product_id', 'in', [cls.product_bolt.id, cls.product_screw.id])])._do_unreserve()
(cls.product_bolt + cls.product_screw).write({'type': 'product'})
cls.dining_table.tracking = 'none'
def test_00_production_order_with_accounting(self):
self.product_table_sheet.standard_price = 20.0
self.product_table_leg.standard_price = 15.0
self.product_bolt.standard_price = 10.0
self.product_screw.standard_price = 0.1
self.product_table_leg.tracking = 'none'
self.product_table_sheet.tracking = 'none'
inventory = self.env['stock.inventory'].create({
@@ -64,7 +67,7 @@ class TestMrpAccount(common.TransactionCase):
]
})
inventory.action_validate
bom = self.env.ref('mrp.mrp_bom_desk').copy()
bom = self.mrp_bom_desk.copy()
bom.routing_id = False # TODO: extend the test later with the necessary operations
production_table_form = Form(self.env['mrp.production'])
production_table_form.product_id = self.dining_table
@@ -87,15 +90,3 @@ class TestMrpAccount(common.TransactionCase):
# 1 table head at 20 + 4 table leg at 15 + 4 bolt at 10 + 10 screw at 10 + 1*20 (extra cost)
self.assertEqual(move_value, 141, 'Thing should have the correct price')
# produce_wizard = self.env['mrp.product.produce'].with_context({
# 'active_id': production_table.id,
# 'active_ids': [production_table.id],
# }).create({
# 'product_qty': 2.0,
# })
# produce_wizard.do_produce()
# production_table.post_inventory()
# move_value = production_table.move_finished_ids.filtered(lambda x: x.state == "done" and x.product_qty == 2.0).value
# # 2 * Real price of the head (quant: 20) + standard price screw (product: 20*10) + standard price bolt (product: 8*10)
# self.assertEqual(move_value, 280, 'Thing should have the correct price')
+4 -3
View File
@@ -1,13 +1,14 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import common
from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
class TestNote(common.TransactionCase):
class TestNote(TransactionCaseWithUserDemo):
def test_bug_lp_1156215(self):
""" ensure any users can create new users """
demo_user = self.env.ref('base.user_demo')
demo_user = self.user_demo
group_erp = self.env.ref('base.group_erp_manager')
demo_user.write({
@@ -15,7 +15,7 @@ class AccountBankStatement(models.Model):
for bs in self:
if bs.pos_session_id.state in ('opened', 'closing_control') and bs.state == 'open':
raise UserError(_("You can't validate a bank statement that is used in an opened Session of a Point of Sale."))
return super( AccountBankStatement, self).check_confirm_bank()
return super(AccountBankStatement, self).check_confirm_bank()
class AccountBankStatementLine(models.Model):
+4 -3
View File
@@ -4,7 +4,7 @@
from datetime import datetime
from uuid import uuid4
from odoo import api, fields, models, _
from odoo import api, fields, models, tools, _
from odoo.exceptions import ValidationError, UserError
@@ -320,6 +320,7 @@ class PosConfig(models.Model):
@api.constrains('company_id', 'payment_method_ids')
def _check_company_payment(self):
if self.env['pos.payment.method'].search_count([('id', 'in', self.payment_method_ids.ids), ('company_id', '!=', self.company_id.id)]):
import pdb; pdb.set_trace()
raise ValidationError(_("The method payments and the point of sale must belong to the same company."))
@api.constrains('pricelist_id', 'use_pricelist', 'available_pricelist_ids', 'journal_id', 'invoice_journal_id', 'payment_method_ids')
@@ -524,7 +525,7 @@ class PosConfig(models.Model):
'target': 'self',
}
def open_session_cb(self):
def open_session_cb(self, check_coa=True):
""" new session button
create one if none exist
@@ -532,7 +533,7 @@ class PosConfig(models.Model):
"""
self.ensure_one()
if not self.current_session_id:
if not self.company_has_template:
if check_coa and not tools.config['test_enable'] and not self.company_has_template:
raise UserError(_("A Chart of Accounts is not yet installed in your current company. Please install a "
"Chart of Accounts through the Invoicing/Accounting settings before launching a PoS session." ))
self._check_company_journal()
+205 -122
View File
@@ -1,59 +1,103 @@
# -*- coding: utf-8 -*-
from random import randint
from odoo import fields
from odoo.tests.common import TransactionCase, Form
from odoo import fields, tools
from odoo.addons.stock_account.tests.stock_account_minimal_test import StockAccountMinimalTest
from odoo.tests.common import SavepointCase, Form
from odoo.tools import float_is_zero
class TestPointOfSaleCommon(TransactionCase):
class TestPointOfSaleCommon(StockAccountMinimalTest):
def setUp(self):
super(TestPointOfSaleCommon, self).setUp()
self.AccountBankStatement = self.env['account.bank.statement']
self.AccountBankStatementLine = self.env['account.bank.statement.line']
self.PosMakePayment = self.env['pos.make.payment']
self.PosOrder = self.env['pos.order']
self.PosSession = self.env['pos.session']
self.company = self.env.ref('base.main_company')
self.company_id = self.company.id
coa = self.env['account.chart.template'].search([
('currency_id', '=', self.company.currency_id.id),
@classmethod
def setUpClass(cls):
super(TestPointOfSaleCommon, cls).setUpClass()
cls.AccountBankStatement = cls.env['account.bank.statement']
cls.AccountBankStatementLine = cls.env['account.bank.statement.line']
cls.PosMakePayment = cls.env['pos.make.payment']
cls.PosOrder = cls.env['pos.order']
cls.PosSession = cls.env['pos.session']
cls.company = cls.env.ref('base.main_company')
cls.company_id = cls.company.id
coa = cls.env['account.chart.template'].search([
('currency_id', '=', cls.company.currency_id.id),
], limit=1)
test_sale_journal = self.env['account.journal'].create({'name': 'Sales Journal - Test',
'code': 'TSJ',
'type': 'sale',
'company_id': self.company_id})
self.company.write({'anglo_saxon_accounting': coa.use_anglo_saxon,
test_sale_journal = cls.env['account.journal'].create({
'name': 'Sales Journal - Test',
'code': 'TSJ',
'type': 'sale',
'company_id': cls.company_id})
cls.company.write({
'anglo_saxon_accounting': coa.use_anglo_saxon,
'bank_account_code_prefix': coa.bank_account_code_prefix,
'cash_account_code_prefix': coa.cash_account_code_prefix,
'transfer_account_code_prefix': coa.transfer_account_code_prefix,
'chart_template_id': coa.id,
'chart_template_id': coa.id,})
cls.product3 = cls.env['product.product'].create({
'name': 'Product 3',
'list_price': 450,
})
self.product3 = self.env.ref('product.product_product_3')
self.product4 = self.env.ref('product.product_product_4')
self.partner1 = self.env.ref('base.res_partner_1')
self.partner4 = self.env.ref('base.res_partner_4')
self.pos_config = self.env.ref('point_of_sale.pos_config_main')
self.pos_config.write({
cls.product4 = cls.env['product.product'].create({
'name': 'Product 4',
'list_price': 750,
})
cls.partner1 = cls.env['res.partner'].create({'name': 'Partner 1'})
cls.partner4 = cls.env['res.partner'].create({'name': 'Partner 4'})
cls.pos_config = cls.env.ref('point_of_sale.pos_config_main')
cls.pos_config.write({
'journal_id': test_sale_journal.id,
'invoice_journal_id': test_sale_journal.id,
})
self.led_lamp = self.env.ref('point_of_sale.led_lamp')
self.whiteboard_pen = self.env.ref('point_of_sale.whiteboard_pen')
self.newspaper_rack = self.env.ref('point_of_sale.newspaper_rack')
self.cash_payment_method = self.pos_config.payment_method_ids.filtered(lambda pm: pm.name == 'Cash')
self.bank_payment_method = self.pos_config.payment_method_ids.filtered(lambda pm: pm.name == 'Bank')
self.credit_payment_method = self.env['pos.payment.method'].create({
'name': 'Credit',
'receivable_account_id': self.company.account_default_pos_receivable_account_id.id,
'split_transactions': True,
cls.led_lamp = cls.env['product.product'].create({
'name': 'LED Lamp',
'available_in_pos': True,
'list_price': 0.90,
})
cls.whiteboard_pen = cls.env['product.product'].create({
'name': 'Whiteboard Pen',
'available_in_pos': True,
'list_price': 1.20,
})
cls.newspaper_rack = cls.env['product.product'].create({
'name': 'Newspaper Rack',
'available_in_pos': True,
'list_price': 1.28,
})
cls.default_receivable_account = cls.a_recv
cls.company.account_default_pos_receivable_account_id = cls.default_receivable_account
cls.cash_payment_method = cls.env['pos.payment.method'].create({
'name': 'Cash',
'receivable_account_id': cls.default_receivable_account.id,
'is_cash_count': True,
'cash_journal_id': cls.cash_journal.id,
'company_id': cls.env.user.company_id.id,
})
cls.bank_payment_method = cls.env['pos.payment.method'].create({
'name': 'Bank',
'receivable_account_id': cls.default_receivable_account.id,
'is_cash_count': False,
'company_id': cls.env.user.company_id.id,
})
cls.credit_payment_method = cls.env['pos.payment.method'].create({
'name': 'Credit',
'receivable_account_id': cls.default_receivable_account.id,
'split_transactions': True,
'company_id': cls.env.user.company_id.id,
})
cls.pos_config.write({'payment_method_ids': [(4, cls.credit_payment_method.id), (4, cls.bank_payment_method.id), (4, cls.cash_payment_method.id)]})
# Create POS journal
cls.pos_config.journal_id = cls.env['account.journal'].create({
'type': 'sale',
'name': 'Point of Sale',
'code': 'POSS - Test',
'company_id': cls.env.user.company_id.id,
'sequence': 20
})
self.pos_config.write({'payment_method_ids': [(4, self.credit_payment_method.id)]})
# create a VAT tax of 10%, included in the public price
Tax = self.env['account.tax']
Tax = cls.env['account.tax']
account_tax_10_incl = Tax.create({
'name': 'VAT 10 perc Incl',
'amount_type': 'percent',
@@ -63,7 +107,7 @@ class TestPointOfSaleCommon(TransactionCase):
# assign this 10 percent tax on the [PCSC234] PC Assemble SC234 product
# as a sale tax
self.product3.taxes_id = [(6, 0, [account_tax_10_incl.id])]
cls.product3.taxes_id = [(6, 0, [account_tax_10_incl.id])]
# create a VAT tax of 5%, which is added to the public price
account_tax_05_incl = Tax.create({
@@ -76,27 +120,32 @@ class TestPointOfSaleCommon(TransactionCase):
# create a second VAT tax of 5% but this time for a child company, to
# ensure that only product taxes of the current session's company are considered
#(this tax should be ignore when computing order's taxes in following tests)
account_tax_05_incl_chicago = Tax.with_context(default_company_id=self.ref('stock.res_company_1')).create({
another_company = cls.env['res.company'].create({
'name': 'My Other Company',
'partner_id': cls.env['res.partner'].create({'name': 'My Other Company Partner'}).id,
})
account_tax_05_incl_chicago = Tax.with_context(default_company_id=another_company.id).create({
'name': 'VAT 05 perc Excl (US)',
'amount_type': 'percent',
'amount': 5.0,
'price_include': 0,
})
self.product4.company_id = False
cls.product4.company_id = False
# I assign those 5 percent taxes on the PCSC349 product as a sale taxes
self.product4.write(
cls.product4.write(
{'taxes_id': [(6, 0, [account_tax_05_incl.id, account_tax_05_incl_chicago.id])]})
# Set account_id in the generated repartition lines. Automatically, nothing is set.
invoice_rep_lines = (account_tax_05_incl | account_tax_05_incl_chicago | account_tax_10_incl).mapped('invoice_repartition_line_ids')
refund_rep_lines = (account_tax_05_incl | account_tax_05_incl_chicago | account_tax_10_incl).mapped('refund_repartition_line_ids')
tax_received_account = self.company.account_sale_tax_id.mapped('invoice_repartition_line_ids.account_id')
(invoice_rep_lines | refund_rep_lines).write({'account_id': tax_received_account.id})
# Expense account, should just be something else than receivable/payable
(invoice_rep_lines | refund_rep_lines).write({'account_id': cls.a_expense.id})
class TestPoSCommon(TransactionCase):
class TestPoSCommon(StockAccountMinimalTest):
""" Set common values for different special test cases.
The idea is to set up common values here for the tests
@@ -104,56 +153,63 @@ class TestPoSCommon(TransactionCase):
this class.
"""
def setUp(self):
super(TestPoSCommon, self).setUp()
@classmethod
def setUpClass(cls):
super(TestPoSCommon, cls).setUpClass()
self.pos_manager = self.env.ref('base.user_admin')
self.env = self.env(user=self.pos_manager)
cls.pos_manager = cls.env.ref('base.user_admin')
cls.env = cls.env(user=cls.pos_manager)
# Set basic defaults
self.company = self.env.ref('base.main_company')
self.pos_sale_journal = self.env['account.journal'].create({
cls.company = cls.env.ref('base.main_company')
cls.pos_sale_journal = cls.env['account.journal'].create({
'type': 'sale',
'name': 'Point of Sale Test',
'code': 'POST',
'company_id': self.company.id,
'company_id': cls.company.id,
'sequence': 20
})
self.invoice_journal = self.env['account.journal'].create({
cls.invoice_journal = cls.env['account.journal'].create({
'type': 'sale',
'name': 'Invoice Journal Test',
'code': 'INVT',
'company_id': self.company.id,
'company_id': cls.company.id,
'sequence': 21
})
self.receivable_account = self.pos_manager.partner_id.property_account_receivable_id
self.tax_received_account = self.company.account_sale_tax_id.mapped('invoice_repartition_line_ids.account_id')
self.pos_receivable_account = self.company.account_default_pos_receivable_account_id
self.other_receivable_account = self.env['account.account'].create({
cls.receivable_account = cls.pos_manager.partner_id.property_account_receivable_id
cls.tax_received_account = cls.a_expense # Whatever the account, just not receivable/payable
cls.company.account_default_pos_receivable_account_id = cls.env['account.account'].create({
'code': 'X1012 - POS',
'name': 'Debtors - (POS)',
'reconcile': True,
'user_type_id': cls.env.ref('account.data_account_type_receivable').id,
})
cls.pos_receivable_account = cls.company.account_default_pos_receivable_account_id
cls.other_receivable_account = cls.env['account.account'].create({
'name': 'Other Receivable',
'code': 'RCV00' ,
'user_type_id': self.env['account.account.type'].create({'name': 'RCV type', 'type': 'receivable', 'internal_group': 'asset'}).id,
'user_type_id': cls.env['account.account.type'].create({'name': 'RCV type', 'type': 'receivable', 'internal_group': 'asset'}).id,
'internal_group': 'asset',
'reconcile': True,
})
# company_currency can be different from `base.USD` depending on the localization installed
self.company_currency = self.company.currency_id
cls.company_currency = cls.company.currency_id
# other_currency is a currency different from the company_currency
# sometimes company_currency is different from USD, so handle appropriately.
self.other_currency = self.env.ref('base.EUR') if self.company_currency == self.env.ref('base.USD') else self.env.ref('base.USD')
cls.other_currency = cls.env.ref('base.EUR') if cls.company_currency == cls.env.ref('base.USD') else cls.env.ref('base.USD')
self.currency_pricelist = self.env['product.pricelist'].create({
cls.currency_pricelist = cls.env['product.pricelist'].create({
'name': 'Public Pricelist',
'currency_id': self.company_currency.id,
'currency_id': cls.company_currency.id,
})
# Set Point of Sale configurations
# basic_config
# - derived from 'point_of_sale.pos_config_main' with added invoice_journal_id and credit payment method.
# other_currency_config
# - pos.config set to have currency different from company currency.
self.basic_config = self._create_basic_config()
self.other_currency_config = self._create_other_currency_config()
cls.basic_config = cls._create_basic_config()
cls.other_currency_config = cls._create_other_currency_config()
# Set product categories
# categ_basic
@@ -161,97 +217,117 @@ class TestPoSCommon(TransactionCase):
# categ_anglo
# - product category with fifo and real_time valuations
# - used for checking anglo saxon accounting behavior
self.categ_basic = self.env.ref('product.product_category_all')
self.categ_anglo = self._create_categ_anglo()
cls.categ_basic = cls.env.ref('product.product_category_all')
cls.env.company.anglo_saxon_accounting = True
cls.categ_anglo = cls._create_categ_anglo()
# other basics
self.sale_account = self.categ_basic.property_account_income_categ_id
self.other_sale_account = self.env['account.account'].search([
('company_id', '=', self.company.id),
('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id),
('id', '!=', self.sale_account.id)
cls.sale_account = cls.categ_basic.property_account_income_categ_id
cls.other_sale_account = cls.env['account.account'].search([
('company_id', '=', cls.company.id),
('user_type_id', '=', cls.env.ref('account.data_account_type_revenue').id),
('id', '!=', cls.sale_account.id)
], limit=1)
# Set customers
self.customer = self.env['res.partner'].create({'name': 'Test Customer'})
self.other_customer = self.env['res.partner'].create({'name': 'Other Customer', 'property_account_receivable_id': self.other_receivable_account.id})
cls.customer = cls.env['res.partner'].create({'name': 'Test Customer'})
cls.other_customer = cls.env['res.partner'].create({'name': 'Other Customer', 'property_account_receivable_id': cls.other_receivable_account.id})
# Set taxes
# self.taxes => dict
# cls.taxes => dict
# keys: 'tax7', 'tax10'(price_include=True), 'tax_group_7_10'
self.taxes = self._create_taxes()
cls.taxes = cls._create_taxes()
cls.stock_location_components = cls.env["stock.location"].create({
'name': 'Shelf 1',
'location_id': cls.env.ref('stock.warehouse0').lot_stock_id.id,
})
#####################
## private methods ##
#####################
def _create_basic_config(self):
new_config = Form(self.env['pos.config'])
@classmethod
def _create_basic_config(cls):
new_config = Form(cls.env['pos.config'])
new_config.name = 'PoS Shop Test'
new_config.module_account = True
new_config.invoice_journal_id = self.invoice_journal
new_config.journal_id = self.pos_sale_journal
new_config.invoice_journal_id = cls.invoice_journal
new_config.journal_id = cls.pos_sale_journal
new_config.available_pricelist_ids.clear()
new_config.available_pricelist_ids.add(self.currency_pricelist)
new_config.pricelist_id = self.currency_pricelist
new_config.available_pricelist_ids.add(cls.currency_pricelist)
new_config.pricelist_id = cls.currency_pricelist
config = new_config.save()
cash_journal = config.payment_method_ids.filtered(lambda pm: pm.is_cash_count)[:1].cash_journal_id
cash_split_pm = self.env['pos.payment.method'].create({
cash_payment_method = cls.env['pos.payment.method'].create({
'name': 'Cash',
'receivable_account_id': cls.pos_receivable_account.id,
'is_cash_count': True,
'cash_journal_id': cls.cash_journal.id,
'company_id': cls.env.user.company_id.id,
})
bank_payment_method = cls.env['pos.payment.method'].create({
'name': 'Bank',
'receivable_account_id': cls.pos_receivable_account.id,
'is_cash_count': False,
'company_id': cls.env.user.company_id.id,
})
cash_split_pm = cls.env['pos.payment.method'].create({
'name': 'Split (Cash) PM',
'receivable_account_id': self.pos_receivable_account.id,
'receivable_account_id': cls.pos_receivable_account.id,
'split_transactions': True,
'is_cash_count': True,
'cash_journal_id': cash_journal.id,
'cash_journal_id': cls.cash_journal.id,
})
config.write({'payment_method_ids': [(4,cash_split_pm.id,0)]})
config.write({'payment_method_ids': [(4, cash_split_pm.id), (4, cash_payment_method.id), (4, bank_payment_method.id)]})
return config
def _create_other_currency_config(self):
(self.other_currency.rate_ids | self.company_currency.rate_ids).unlink()
self.env['res.currency.rate'].create({
@classmethod
def _create_other_currency_config(cls):
(cls.other_currency.rate_ids | cls.company_currency.rate_ids).unlink()
cls.env['res.currency.rate'].create({
'rate': 0.5,
'currency_id': self.other_currency.id,
'currency_id': cls.other_currency.id,
})
other_cash_journal = self.env['account.journal'].create({
other_cash_journal = cls.env['account.journal'].create({
'name': 'Cash Other',
'type': 'cash',
'company_id': self.company.id,
'company_id': cls.company.id,
'code': 'CSHO',
'sequence': 10,
'currency_id': self.other_currency.id
'currency_id': cls.other_currency.id
})
other_invoice_journal = self.env['account.journal'].create({
other_invoice_journal = cls.env['account.journal'].create({
'name': 'Customer Invoice Other',
'type': 'sale',
'company_id': self.company.id,
'company_id': cls.company.id,
'code': 'INVO',
'sequence': 11,
'currency_id': self.other_currency.id
'currency_id': cls.other_currency.id
})
other_sales_journal = self.env['account.journal'].create({
other_sales_journal = cls.env['account.journal'].create({
'name':'PoS Sale Other',
'type': 'sale',
'code': 'POSO',
'company_id': self.company.id,
'company_id': cls.company.id,
'sequence': 12,
'currency_id': self.other_currency.id
'currency_id': cls.other_currency.id
})
other_pricelist = self.env['product.pricelist'].create({
other_pricelist = cls.env['product.pricelist'].create({
'name': 'Public Pricelist Other',
'currency_id': self.other_currency.id,
'currency_id': cls.other_currency.id,
})
other_cash_payment_method = self.env['pos.payment.method'].create({
other_cash_payment_method = cls.env['pos.payment.method'].create({
'name': 'Cash Other',
'receivable_account_id': self.pos_receivable_account.id,
'receivable_account_id': cls.pos_receivable_account.id,
'is_cash_count': True,
'cash_journal_id': other_cash_journal.id,
})
other_bank_payment_method = self.env['pos.payment.method'].create({
other_bank_payment_method = cls.env['pos.payment.method'].create({
'name': 'Bank Other',
'receivable_account_id': self.pos_receivable_account.id,
'receivable_account_id': cls.pos_receivable_account.id,
})
new_config = Form(self.env['pos.config'])
new_config = Form(cls.env['pos.config'])
new_config.name = 'Shop Other'
new_config.invoice_journal_id = other_invoice_journal
new_config.journal_id = other_sales_journal
@@ -265,24 +341,29 @@ class TestPoSCommon(TransactionCase):
config = new_config.save()
return config
def _create_categ_anglo(self):
return self.env['product.category'].create({
@classmethod
def _create_categ_anglo(cls):
cls.o_income.reconcile = True
return cls.env['product.category'].create({
'name': 'Anglo',
'parent_id': False,
'property_cost_method': 'fifo',
'property_valuation': 'real_time',
'property_stock_account_input_categ_id': cls.o_expense.id,
'property_stock_account_output_categ_id': cls.o_income.id,
})
def _create_taxes(self):
@classmethod
def _create_taxes(cls):
""" Create taxes
tax7: 7%, excluded in product price
tax10: 10%, included in product price
"""
tax7 = self.env['account.tax'].create({'name': 'Tax 7%', 'amount': 7})
tax10 = self.env['account.tax'].create({'name': 'Tax 10%', 'amount': 10, 'price_include': True, 'include_base_amount': False})
(tax7 | tax10).mapped('invoice_repartition_line_ids').write({'account_id': self.tax_received_account.id})
(tax7 | tax10).mapped('refund_repartition_line_ids').write({'account_id': self.tax_received_account.id})
tax7 = cls.env['account.tax'].create({'name': 'Tax 7%', 'amount': 7})
tax10 = cls.env['account.tax'].create({'name': 'Tax 10%', 'amount': 10, 'price_include': True, 'include_base_amount': False})
(tax7 | tax10).mapped('invoice_repartition_line_ids').write({'account_id': cls.tax_received_account.id})
(tax7 | tax10).mapped('refund_repartition_line_ids').write({'account_id': cls.tax_received_account.id})
tax_group_7_10 = tax7.copy()
with Form(tax_group_7_10) as tax:
@@ -395,8 +476,9 @@ class TestPoSCommon(TransactionCase):
'to_invoice': is_invoiced,
}
def create_product(self, name, category, lst_price, standard_price=None, tax_ids=None, sale_account=None):
product = self.env['product.product'].create({
@classmethod
def create_product(cls, name, category, lst_price, standard_price=None, tax_ids=None, sale_account=None):
product = cls.env['product.product'].create({
'type': 'product',
'available_in_pos': True,
'taxes_id': [(5, 0, 0)] if not tax_ids else [(6, 0, tax_ids)],
@@ -410,19 +492,20 @@ class TestPoSCommon(TransactionCase):
product.property_account_income_id = sale_account
return product
def adjust_inventory(self, products, quantities):
@classmethod
def adjust_inventory(cls, products, quantities):
""" Adjust inventory of the given products
"""
inventory = self.env['stock.inventory'].create({
inventory = cls.env['stock.inventory'].create({
'name': 'Inventory adjustment'
})
for product, qty in zip(products, quantities):
self.env['stock.inventory.line'].create({
cls.env['stock.inventory.line'].create({
'product_id': product.id,
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
'product_uom_id': cls.env.ref('uom.product_uom_unit').id,
'inventory_id': inventory.id,
'product_qty': qty,
'location_id': self.env.ref('stock.stock_location_components').id,
'location_id': cls.stock_location_components.id,
})
inventory._action_start()
inventory.action_validate()
@@ -446,7 +529,7 @@ class TestPoSCommon(TransactionCase):
* bank_pm : bank payment method of the session
* cash_split_pm : credit payment method of the session
"""
self.config.open_session_cb()
self.config.open_session_cb(check_coa=False)
self.pos_session = self.config.current_session_id
self.currency = self.pos_session.currency_id
self.pricelist = self.pos_session.config_id.pricelist_id
+11 -6
View File
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
import time
@@ -14,9 +15,8 @@ class TestAngloSaxonCommon(common.TransactionCase):
self.Statement = self.env['account.bank.statement']
self.company = self.env.ref('base.main_company')
self.warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1)
self.product = self.env.ref('product.product_product_3')
self.partner = self.env.ref('base.res_partner_1')
self.category = self.env.ref('product.product_category_1')
self.partner = self.env['res.partner'].create({'name': 'Partner 1'})
self.category = self.env.ref('product.product_category_all')
self.category = self.category.copy({'name': 'New category','property_valuation': 'real_time'})
account_type_rcv = self.env.ref('account.data_account_type_receivable')
account_type_inc = self.env.ref('account.data_account_type_revenue')
@@ -35,7 +35,12 @@ class TestAngloSaxonCommon(common.TransactionCase):
self.category.property_stock_journal = self.env['account.journal'].create({'name': 'Stock journal', 'type': 'sale', 'code': 'STK00'})
self.pos_config = self.env.ref('point_of_sale.pos_config_main')
self.pos_config = self.pos_config.copy({'name': 'New POS config'})
self.product = self.product.copy({'name': 'New product','standard_price': 100})
self.product = self.env['product.product'].create({
'name': 'New product',
'standard_price': 100,
'available_in_pos': True,
'type': 'product',
})
self.company.anglo_saxon_accounting = True
self.product.categ_id = self.category
self.product.property_account_expense_id = account_expense
@@ -61,7 +66,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
def test_create_account_move_line(self):
# This test will check that the correct journal entries are created when a product in real time valuation
# is sold in a company using anglo-saxon
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
self.cash_journal.loss_account_id = self.account
@@ -142,7 +147,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
self.assertEqual(self.product.quantity_svl, 10)
self.pos_config.module_account = True
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
pos_order_values = {
'company_id': self.company.id,
+106 -29
View File
@@ -1,26 +1,34 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
from odoo.api import Environment
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import date, timedelta
import odoo.tests
@odoo.tests.tagged('post_install', '-at_install')
class TestUi(odoo.tests.HttpCase):
def test_01_pos_basic_order(self):
class TestPointOfSaleHttpCommon(odoo.tests.HttpCase):
def setUp(self):
super().setUp()
env = self.env(user=self.env.ref('base.user_admin'))
journal_obj = env['account.journal']
account_obj = env['account.account']
main_company = env.ref('base.main_company')
main_pos_config = env.ref('point_of_sale.pos_config_main')
self.main_pos_config = env.ref('point_of_sale.pos_config_main')
env['res.partner'].create({
'name': 'Deco Addict',
})
account_receivable = account_obj.create({'code': 'X1012',
'name': 'Account Receivable - Test',
'user_type_id': env.ref('account.data_account_type_receivable').id,
'reconcile': True})
self.env.company.account_default_pos_receivable_account_id = account_receivable
field = env['ir.model.fields']._get('res.partner', 'property_account_receivable_id')
env['ir.property'].create({'name': 'property_account_receivable_id',
'company_id': main_company.id,
@@ -35,8 +43,64 @@ class TestUi(odoo.tests.HttpCase):
'sequence': 10,
})
# Archive all existing product to avoid noise during the tours
all_pos_product = self.env['product.product'].search([('available_in_pos', '=', True)])
discount = self.env.ref('point_of_sale.product_product_consumable')
tip = self.env.ref('point_of_sale.product_product_tip')
(all_pos_product - discount - tip)._write({'active': False})
# test an extra price on an attribute
pear = env.ref('point_of_sale.whiteboard')
pear = env['product.product'].create({
'name': 'Whiteboard Pen',
'available_in_pos': True,
'list_price': 1.20,
'taxes_id': False,
'weight': 0.01,
'to_weight': True,
})
wall_shelf = env['product.product'].create({
'name': 'Wall Shelf Unit',
'available_in_pos': True,
'list_price': 1.98,
'taxes_id': False,
})
small_shelf = env['product.product'].create({
'name': 'Small Shelf',
'available_in_pos': True,
'list_price': 2.83,
'taxes_id': False,
})
magnetic_board = env['product.product'].create({
'name': 'Magnetic Board',
'available_in_pos': True,
'list_price': 1.98,
'taxes_id': False,
})
monitor_stand = env['product.product'].create({
'name': 'Monitor Stand',
'available_in_pos': True,
'list_price': 3.19,
'taxes_id': False,
})
desk_pad = env['product.product'].create({
'name': 'Desk Pad',
'available_in_pos': True,
'list_price': 1.98,
'taxes_id': False,
})
letter_tray = env['product.product'].create({
'name': 'Letter Tray',
'available_in_pos': True,
'list_price': 4.80,
'taxes_id': False,
})
desk_organizer = env['product.product'].create({
'name': 'Desk Organizer',
'available_in_pos': True,
'list_price': 5.10,
'taxes_id': False,
})
attribute = env['product.attribute'].create({
'name': 'add 2',
})
@@ -60,12 +124,12 @@ class TestUi(odoo.tests.HttpCase):
'compute_price': 'fixed',
'fixed_price': 2,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.wall_shelf').id,
'product_id': wall_shelf.id,
}), (0, 0, {
'compute_price': 'fixed',
'fixed_price': 13.95, # test for issues like in 7f260ab517ebde634fc274e928eb062463f0d88f
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.small_shelf').id,
'product_id': small_shelf.id,
})],
})
@@ -75,17 +139,17 @@ class TestUi(odoo.tests.HttpCase):
'compute_price': 'percentage',
'percent_price': 100,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.wall_shelf').id,
'product_id': wall_shelf.id,
}), (0, 0, {
'compute_price': 'percentage',
'percent_price': 99,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.small_shelf').id,
'product_id': small_shelf.id,
}), (0, 0, {
'compute_price': 'percentage',
'percent_price': 0,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.magnetic_board').id,
'product_id': magnetic_board.id,
})],
})
@@ -96,33 +160,33 @@ class TestUi(odoo.tests.HttpCase):
'price_discount': 6,
'price_surcharge': 5,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.wall_shelf').id,
'product_id': wall_shelf.id,
}), (0, 0, {
# .99 prices
'compute_price': 'formula',
'price_surcharge': -0.01,
'price_round': 1,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.small_shelf').id,
'product_id': small_shelf.id,
}), (0, 0, {
'compute_price': 'formula',
'price_min_margin': 10,
'price_max_margin': 100,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.magnetic_board').id,
'product_id': magnetic_board.id,
}), (0, 0, {
'compute_price': 'formula',
'price_surcharge': 10,
'price_max_margin': 5,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.monitor_stand').id,
'product_id': monitor_stand.id,
}), (0, 0, {
'compute_price': 'formula',
'price_discount': -100,
'price_min_margin': 5,
'price_max_margin': 20,
'applied_on': '0_product_variant',
'product_id': env.ref('point_of_sale.desk_pad').id,
'product_id': desk_pad.id,
})],
})
@@ -133,13 +197,13 @@ class TestUi(odoo.tests.HttpCase):
'fixed_price': 1,
'applied_on': '0_product_variant',
'min_quantity': 2,
'product_id': env.ref('point_of_sale.wall_shelf').id,
'product_id': wall_shelf.id,
}), (0, 0, {
'compute_price': 'fixed',
'fixed_price': 2,
'applied_on': '0_product_variant',
'min_quantity': 1,
'product_id': env.ref('point_of_sale.wall_shelf').id,
'product_id': wall_shelf.id,
}), (0, 0, {
'compute_price': 'fixed',
'fixed_price': 2,
@@ -155,13 +219,18 @@ class TestUi(odoo.tests.HttpCase):
'compute_price': 'fixed',
'fixed_price': 1,
'applied_on': '1_product',
'product_tmpl_id': env.ref('point_of_sale.wall_shelf_product_template').id,
'product_tmpl_id': wall_shelf.product_tmpl_id.id,
}), (0, 0, {
'compute_price': 'fixed',
'fixed_price': 2,
})],
})
product_category_3 = env['product.category'].create({
'name': 'Services',
'parent_id': env.ref('product.product_category_1').id,
})
env['product.pricelist'].create({
# no category has precedence over category
'name': 'Category vs no category',
@@ -169,7 +238,7 @@ class TestUi(odoo.tests.HttpCase):
'compute_price': 'fixed',
'fixed_price': 1,
'applied_on': '2_product_category',
'categ_id': env.ref('product.product_category_3').id, # All / Saleable / Services
'categ_id': product_category_3.id, # All / Saleable / Services
}), (0, 0, {
'compute_price': 'fixed',
'fixed_price': 2,
@@ -187,7 +256,7 @@ class TestUi(odoo.tests.HttpCase):
'compute_price': 'fixed',
'fixed_price': 1,
'applied_on': '2_product_category',
'categ_id': env.ref('product.product_category_3').id, # All / Saleable / Services
'categ_id': product_category_3.id, # All / Saleable / Services
})],
})
@@ -263,7 +332,11 @@ class TestUi(odoo.tests.HttpCase):
excluded_pricelist = env['product.pricelist'].create({
'name': 'Not loaded'
})
env.ref('base.res_partner_18').property_product_pricelist = excluded_pricelist
res_partner_18 = self.env['res.partner'].create({
'name': 'Lumber Inc',
'is_company': True,
})
res_partner_18.property_product_pricelist = excluded_pricelist
partner = self.env['res.partner'].create({
'name': 'TEST PARTNER',
@@ -287,10 +360,9 @@ class TestUi(odoo.tests.HttpCase):
src_tax = env['account.tax'].create({'name': "SRC", 'amount': 10})
dst_tax = env['account.tax'].create({'name': "DST", 'amount': 5})
env.ref('point_of_sale.letter_tray').taxes_id = [(6, 0, [src_tax.id])]
letter_tray.taxes_id = [(6, 0, [src_tax.id])]
main_pos_config.write({
self.main_pos_config.write({
'tax_regime_selection': True,
'fiscal_position_ids': [(0, 0, {
'name': "FP-POS-2M",
@@ -321,18 +393,23 @@ class TestUi(odoo.tests.HttpCase):
('res_id', '=', False)
]).write({'value_reference': 'product.pricelist,%s' % public_pricelist.id})
@odoo.tests.tagged('post_install', '-at_install')
class TestUi(TestPointOfSaleHttpCommon):
def test_01_pos_basic_order(self):
# open a session, the /pos/web controller will redirect to it
main_pos_config.open_session_cb()
self.main_pos_config.open_session_cb(check_coa=False)
# needed because tests are run before the module is marked as
# installed. In js web will only load qweb coming from modules
# that are returned by the backend in module_boot. Without
# this you end up with js, css but no qweb.
env['ir.module.module'].search([('name', '=', 'point_of_sale')], limit=1).state = 'installed'
self.env['ir.module.module'].search([('name', '=', 'point_of_sale')], limit=1).state = 'installed'
self.start_tour("/pos/web?config_id=%d" % main_pos_config.id, 'pos_pricelist', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_pricelist', login="admin")
self.start_tour("/pos/web?config_id=%d" % main_pos_config.id, 'pos_basic_order', login="admin")
self.start_tour("/pos/web?config_id=%d" % self.main_pos_config.id, 'pos_basic_order', login="admin")
for order in env['pos.order'].search([]):
for order in self.env['pos.order'].search([]):
self.assertEqual(order.state, 'paid', "Validated order has payment of " + str(order.amount_paid) + " and total of " + str(order.amount_total))
@@ -1,8 +1,10 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import time
import odoo
from odoo import fields
from odoo import fields, tools
from odoo.tools import float_compare, mute_logger, test_reports
from odoo.tests.common import Form
from odoo.addons.point_of_sale.tests.common import TestPointOfSaleCommon
@@ -13,7 +15,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
def test_order_refund(self):
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
# I create a new PoS order with 2 lines
order = self.PosOrder.create({
@@ -94,7 +96,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
# I click on create a new session button
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
# I create a PoS order with 2 units of PCSC234 at 450 EUR
@@ -305,7 +307,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
untax = res['total_excluded']
return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
untax1, atax1 = compute_tax(self.product3, 450*0.95, 2)
@@ -427,7 +429,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
# I click on create a new session button
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
num_starting_orders = len(current_session.order_ids)
@@ -607,7 +609,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
})
# I click on create a new session button
eur_config.open_session_cb()
eur_config.open_session_cb(check_coa=False)
current_session = eur_config.current_session_id
# I create a PoS order with 2 units of PCSC234 at 450 EUR (Tax Incl)
@@ -706,8 +708,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
self.assertAlmostEqual(a, b)
def test_order_to_invoice_no_tax(self):
self.pos_config.open_session_cb()
self.pos_config.open_session_cb(check_coa=False)
current_session = self.pos_config.current_session_id
# I create a new PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PCSC349 at 300 EUR. (Tax Excl)
@@ -1,10 +1,16 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo.tests
from odoo.tests import HttpCase, tagged
from odoo import tools
@odoo.tests.tagged('post_install', '-at_install')
class TestUi(odoo.tests.HttpCase):
@tagged('post_install', '-at_install')
class TestUi(HttpCase):
# Avoid "A Chart of Accounts is not yet installed in your current company."
# Everything is set up correctly even without installed CoA
@tools.mute_logger('odoo.http')
def test_01_point_of_sale_tour(self):
self.start_tour("/web", 'point_of_sale_tour', login="admin")
@@ -1,6 +1,12 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import tools
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@odoo.tests.tagged('post_install', '-at_install')
class TestPoSBasicConfig(TestPoSCommon):
""" Test PoS with basic configuration
@@ -1,4 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import tools
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@odoo.tests.tagged('post_install', '-at_install')
@@ -1,4 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import tools
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@odoo.tests.tagged('post_install', '-at_install')
@@ -14,6 +19,7 @@ class TestPoSMultipleSaleAccounts(TestPoSCommon):
def setUp(self):
super(TestPoSMultipleSaleAccounts, self).setUp()
self.config = self.basic_config
self.product1 = self.create_product(
'Product 1',
@@ -81,6 +87,7 @@ class TestPoSMultipleSaleAccounts(TestPoSCommon):
| Total balance | 0.00 |
+---------------------+---------+
"""
self.open_new_session()
# create orders
@@ -160,6 +167,7 @@ class TestPoSMultipleSaleAccounts(TestPoSCommon):
| Total balance | 0.00 |
+---------------------+---------+
"""
self.open_new_session()
# create orders
@@ -1,4 +1,9 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo
from odoo import tools
from odoo.tests.common import Form
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@@ -9,6 +14,7 @@ class TestPoSOtherCurrencyConfig(TestPoSCommon):
def setUp(self):
super(TestPoSOtherCurrencyConfig, self).setUp()
self.config = self.other_currency_config
self.product1 = self.create_product('Product 1', self.categ_basic, 10.0, 5)
self.product2 = self.create_product('Product 2', self.categ_basic, 20.0, 10)
@@ -25,6 +31,7 @@ class TestPoSOtherCurrencyConfig(TestPoSCommon):
# Product price should be half of the original price because currency rate is 0.5.
# (see `self._create_other_currency_config` method)
# Except for product2 where the price is specified in the pricelist.
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product1, 1, self.customer), 5.00)
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product2, 1, self.customer), 12.99)
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product3, 1, self.customer), 15.00)
@@ -60,6 +67,7 @@ class TestPoSOtherCurrencyConfig(TestPoSCommon):
| Total balance | 0.0 | 0.00 |
+---------------------+---------+-----------------+
"""
self.open_new_session()
# create orders
@@ -124,6 +132,7 @@ class TestPoSOtherCurrencyConfig(TestPoSCommon):
| Total balance | 0.0 | 0.00 |
+---------------------+---------+-----------------+
"""
self.open_new_session()
# create orders
@@ -1,3 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
import odoo
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@@ -8,6 +13,7 @@ class TestPoSProductsWithTax(TestPoSCommon):
def setUp(self):
super(TestPoSProductsWithTax, self).setUp()
self.config = self.basic_config
self.product1 = self.create_product(
'Product 1',
@@ -60,6 +66,7 @@ class TestPoSProductsWithTax(TestPoSCommon):
Thus, manually_calculated_taxes = (-24,89, -51.82)
"""
self.open_new_session()
# create orders
@@ -134,6 +141,7 @@ class TestPoSProductsWithTax(TestPoSCommon):
Thus, manually_calculated_taxes = (-6.81, -44.54)
"""
self.open_new_session()
# create orders
@@ -182,7 +190,7 @@ class TestPoSProductsWithTax(TestPoSCommon):
# check receivable line
# should be equivalent to receivable in the invoice
# should also be fully-reconciled
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id in self.receivable_account + self.env['account.account'].search([('name', '=', 'Account Receivable (PoS)')]) and line.name == 'From invoiced orders')
self.assertAlmostEqual(receivable_line.balance, -426.09)
self.assertTrue(receivable_line.full_reconcile_id, msg='Receivable line for invoices should be fully reconciled.')
@@ -229,6 +237,7 @@ class TestPoSProductsWithTax(TestPoSCommon):
manually_calculated_taxes = (4.01, 6.37)
"""
self.open_new_session()
# create orders
@@ -1,3 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
import odoo
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@@ -10,6 +14,7 @@ class TestPoSSetup(TestPoSCommon):
"""
def setUp(self):
super(TestPoSSetup, self).setUp()
self.config = self.basic_config
self.products = [
self.create_product('Product 1', self.categ_basic, lst_price=10.0, standard_price=5),
@@ -18,6 +23,7 @@ class TestPoSSetup(TestPoSCommon):
]
def test_basic_config_values(self):
config = self.basic_config
self.assertEqual(config.currency_id, self.company_currency)
self.assertEqual(config.pricelist_id.currency_id, self.company_currency)
@@ -41,6 +47,7 @@ class TestPoSSetup(TestPoSCommon):
def get_price(pricelist, product):
return pricelist.get_product_price(product, 1, self.customer)
# check usd pricelist
pricelist = self.basic_config.pricelist_id
for product in self.products:
@@ -1,3 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
import odoo
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@@ -7,6 +11,7 @@ class TestPoSStock(TestPoSCommon):
"""
def setUp(self):
super(TestPoSStock, self).setUp()
self.config = self.basic_config
self.product1 = self.create_product('Product 1', self.categ_anglo, 10.0, 5.0)
self.product2 = self.create_product('Product 2', self.categ_anglo, 20.0, 10.0)
@@ -98,7 +103,7 @@ class TestPoSStock(TestPoSCommon):
sales_line = account_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
self.assertAlmostEqual(sales_line.balance, -orders_total, msg='Sales line balance should be equal to total orders amount.')
receivable_line_cash = account_move.line_ids.filtered(lambda line: self.pos_receivable_account == line.account_id and self.cash_pm.name in line.name)
receivable_line_cash = account_move.line_ids.filtered(lambda line: line.account_id in self.pos_receivable_account + self.env['account.account'].search([('name', '=', 'Account Receivable (PoS)')]) and self.cash_pm.name in line.name)
self.assertAlmostEqual(receivable_line_cash.balance, 1010.0, msg='Cash receivable should be equal to the total cash payments.')
expense_line = account_move.line_ids.filtered(lambda line: line.account_id == self.expense_account)
@@ -176,7 +181,7 @@ class TestPoSStock(TestPoSCommon):
receivable_line = account_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
self.assertAlmostEqual(receivable_line.balance, -360.0, msg='Receivable line balance should equal the negative of total amount of invoiced orders.')
receivable_line_cash = account_move.line_ids.filtered(lambda line: self.pos_receivable_account == line.account_id and self.cash_pm.name in line.name)
receivable_line_cash = account_move.line_ids.filtered(lambda line: line.account_id in self.pos_receivable_account + self.env['account.account'].search([('name', '=', 'Account Receivable (PoS)')]) and self.cash_pm.name in line.name)
self.assertAlmostEqual(receivable_line_cash.balance, 1010.0, msg='Cash receivable should be equal to the total cash payments.')
expense_line = account_move.line_ids.filtered(lambda line: line.account_id == self.expense_account)
@@ -1,3 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
import odoo
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
@@ -8,51 +12,54 @@ class TestPoSWithFiscalPosition(TestPoSCommon):
keywords/phrases: fiscal position
"""
def setUp(self):
super(TestPoSWithFiscalPosition, self).setUp()
self.config = self.basic_config
@classmethod
def setUpClass(cls):
super(TestPoSWithFiscalPosition, cls).setUpClass()
self.new_tax_17 = self.env['account.tax'].create({'name': 'New Tax 17%', 'amount': 17})
self.new_tax_17.invoice_repartition_line_ids.write({'account_id': self.tax_received_account.id})
cls.config = cls.basic_config
self.fpos = self._create_fiscal_position()
self.fpos_no_tax_dest = self._create_fiscal_position_no_tax_dest()
cls.new_tax_17 = cls.env['account.tax'].create({'name': 'New Tax 17%', 'amount': 17})
cls.new_tax_17.invoice_repartition_line_ids.write({'account_id': cls.tax_received_account.id})
self.product1 = self.create_product(
cls.fpos = cls._create_fiscal_position()
cls.fpos_no_tax_dest = cls._create_fiscal_position_no_tax_dest()
cls.product1 = cls.create_product(
'Product 1',
self.categ_basic,
cls.categ_basic,
lst_price=10.99,
standard_price=5.0,
tax_ids=self.taxes['tax7'].ids,
tax_ids=cls.taxes['tax7'].ids,
)
self.product2 = self.create_product(
cls.product2 = cls.create_product(
'Product 2',
self.categ_basic,
cls.categ_basic,
lst_price=19.99,
standard_price=10.0,
tax_ids=self.taxes['tax10'].ids,
tax_ids=cls.taxes['tax10'].ids,
)
self.product3 = self.create_product(
cls.product3 = cls.create_product(
'Product 3',
self.categ_basic,
cls.categ_basic,
lst_price=30.99,
standard_price=15.0,
tax_ids=self.taxes['tax7'].ids,
tax_ids=cls.taxes['tax7'].ids,
)
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
cls.adjust_inventory([cls.product1, cls.product2, cls.product3], [100, 50, 50])
def _create_fiscal_position(self):
fpos = self.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
@classmethod
def _create_fiscal_position(cls):
fpos = cls.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
account_fpos = self.env['account.fiscal.position.account'].create({
account_fpos = cls.env['account.fiscal.position.account'].create({
'position_id': fpos.id,
'account_src_id': self.sale_account.id,
'account_dest_id': self.other_sale_account.id,
'account_src_id': cls.sale_account.id,
'account_dest_id': cls.other_sale_account.id,
})
tax_fpos = self.env['account.fiscal.position.tax'].create({
tax_fpos = cls.env['account.fiscal.position.tax'].create({
'position_id': fpos.id,
'tax_src_id': self.taxes['tax7'].id,
'tax_dest_id': self.new_tax_17.id,
'tax_src_id': cls.taxes['tax7'].id,
'tax_dest_id': cls.new_tax_17.id,
})
fpos.write({
'account_ids': [(6, 0, account_fpos.ids)],
@@ -60,16 +67,17 @@ class TestPoSWithFiscalPosition(TestPoSCommon):
})
return fpos
def _create_fiscal_position_no_tax_dest(self):
fpos_no_tax_dest = self.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
account_fpos = self.env['account.fiscal.position.account'].create({
@classmethod
def _create_fiscal_position_no_tax_dest(cls):
fpos_no_tax_dest = cls.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
account_fpos = cls.env['account.fiscal.position.account'].create({
'position_id': fpos_no_tax_dest.id,
'account_src_id': self.sale_account.id,
'account_dest_id': self.other_sale_account.id,
'account_src_id': cls.sale_account.id,
'account_dest_id': cls.other_sale_account.id,
})
tax_fpos = self.env['account.fiscal.position.tax'].create({
tax_fpos = cls.env['account.fiscal.position.tax'].create({
'position_id': fpos_no_tax_dest.id,
'tax_src_id': self.taxes['tax7'].id,
'tax_src_id': cls.taxes['tax7'].id,
})
fpos_no_tax_dest.write({
'account_ids': [(6, 0, account_fpos.ids)],
@@ -114,6 +122,7 @@ class TestPoSWithFiscalPosition(TestPoSCommon):
| Total balance | 0.0 |
+---------------------+---------+
"""
self.customer.write({'property_account_position_id': self.fpos.id})
self.open_new_session()
@@ -207,6 +216,7 @@ class TestPoSWithFiscalPosition(TestPoSCommon):
| Total balance | 0.0 |
+---------------------+---------+
"""
self.customer.write({'property_account_position_id': self.fpos_no_tax_dest.id})
self.open_new_session()
# create orders
@@ -300,6 +310,7 @@ class TestPoSWithFiscalPosition(TestPoSCommon):
| Total balance | 0.0 |
+---------------------+---------+
"""
self.customer.write({'property_account_position_id': self.fpos.id})
self.open_new_session()
# create orders
+5 -3
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import odoo.tests
from odoo.addons.base.tests.common import HttpCaseWithUserPortal
from odoo.tests import tagged
@odoo.tests.tagged('post_install', '-at_install')
class TestUi(odoo.tests.HttpCase):
@tagged('post_install', '-at_install')
class TestUi(HttpCaseWithUserPortal):
def test_01_portal_load_tour(self):
self.start_tour("/", 'portal_load_homepage', login="portal")
+71 -8
View File
@@ -9,7 +9,47 @@ class TestFrontend(odoo.tests.HttpCase):
env = self.env(user=self.env.ref('base.user_admin'))
account_obj = env['account.account']
pos_config = env.ref('pos_restaurant.pos_config_restaurant')
printer = self.env['restaurant.printer'].create({
'name': 'Kitchen Printer',
'proxy_ip': 'localhost',
})
drinks_category = self.env['pos.category'].create({'name': 'Drinks'})
pos_config = self.env['pos.config'].create({
'name': 'Bar',
'barcode_nomenclature_id': self.env.ref('barcodes.default_barcode_nomenclature').id,
'module_pos_restaurant': True,
'is_table_management': True,
'iface_splitbill': True,
'iface_printbill': True,
'iface_orderline_notes': True,
'printer_ids': [(4, printer.id)],
'iface_start_categ_id': drinks_category.id,
'start_category': True,
'pricelist_id': self.env.ref('product.list0').id,
})
main_floor = self.env['restaurant.floor'].create({
'name': 'Main Floor',
'pos_config_id': pos_config.id,
})
table_05 = self.env['restaurant.table'].create({
'name': 'T5',
'floor_id': main_floor.id,
'seats': 4,
})
table_04 = self.env['restaurant.table'].create({
'name': 'T4',
'floor_id': main_floor.id,
'seats': 4,
})
table_02 = self.env['restaurant.table'].create({
'name': 'T2',
'floor_id': main_floor.id,
'seats': 4,
})
main_company = env.ref('base.main_company')
account_receivable = account_obj.create({'code': 'X1012',
@@ -47,14 +87,37 @@ class TestFrontend(odoo.tests.HttpCase):
})],
})
coke = self.env.ref('pos_restaurant.coke')
coke.write({'taxes_id': [(6, 0, [])]})
water = self.env.ref('pos_restaurant.water')
water.write({'taxes_id': [(6, 0, [])]})
minute_maid = self.env.ref('pos_restaurant.minute_maid')
minute_maid.write({'taxes_id': [(6, 0, [])]})
coke = self.env['product.product'].create({
'available_in_pos': True,
'list_price': 2.20,
'name': 'Coca-Cola',
'weight': 0.01,
'pos_categ_id': drinks_category.id,
'categ_id': self.env.ref('point_of_sale.product_category_pos').id,
'taxes_id': [(6, 0, [])],
})
pos_config.open_session_cb()
water = self.env['product.product'].create({
'available_in_pos': True,
'list_price': 2.20,
'name': 'Water',
'weight': 0.01,
'pos_categ_id': drinks_category.id,
'categ_id': self.env.ref('point_of_sale.product_category_pos').id,
'taxes_id': [(6, 0, [])],
})
minute_maid = self.env['product.product'].create({
'available_in_pos': True,
'list_price': 2.20,
'name': 'Minute Maid',
'weight': 0.01,
'pos_categ_id': drinks_category.id,
'categ_id': self.env.ref('point_of_sale.product_category_pos').id,
'taxes_id': [(6, 0, [])],
})
pos_config.with_user(self.env.ref('base.user_admin')).open_session_cb(check_coa=False)
self.start_tour("/pos/web?config_id=%d" % pos_config.id, 'pos_restaurant_sync', login="admin")
+3 -3
View File
@@ -9,8 +9,8 @@ class TestPricelist(TransactionCase):
def setUp(self):
super(TestPricelist, self).setUp()
self.datacard = self.env.ref('product.product_delivery_02')
self.usb_adapter = self.env.ref('product.product_delivery_01')
self.datacard = self.env['product.product'].create({'name': 'Office Lamp'})
self.usb_adapter = self.env['product.product'].create({'name': 'Office Chair'})
self.uom_ton = self.env.ref('uom.product_uom_ton')
self.uom_unit_id = self.ref('uom.product_uom_unit')
self.uom_dozen_id = self.ref('uom.product_uom_dozen')
@@ -73,7 +73,7 @@ class TestPricelist(TransactionCase):
# make sure 'tonne' resolves down to 1 'kg'.
self.uom_ton.write({'rounding': 0.001})
# setup product stored in 'tonnes', with a discounted pricelist for qty > 3 tonnes
spam_id = self.usb_adapter.copy({
spam_id = self.env['product.product'].create({
'name': '1 tonne of spam',
'uom_id': self.uom_ton.id,
'uom_po_id': self.uom_ton.id,
@@ -6,108 +6,114 @@ from psycopg2 import IntegrityError
from odoo.exceptions import UserError, ValidationError
from odoo.tests import tagged
from odoo.tests.common import TransactionCase
from odoo.tests.common import SavepointCase
from odoo.tools import mute_logger
class TestProductAttributeValueSetup(TransactionCase):
def setUp(self):
super(TestProductAttributeValueSetup, self).setUp()
class TestProductAttributeValueSetup(SavepointCase):
@classmethod
def setUpClass(cls):
super(TestProductAttributeValueSetup, cls).setUpClass()
self.computer = self.env['product.template'].create({
cls.computer = cls.env['product.template'].create({
'name': 'Super Computer',
'price': 2000,
})
self._add_ssd_attribute()
self._add_ram_attribute()
self._add_hdd_attribute()
cls._add_ssd_attribute()
cls._add_ram_attribute()
cls._add_hdd_attribute()
self.computer_case = self.env['product.template'].create({
cls.computer_case = cls.env['product.template'].create({
'name': 'Super Computer Case'
})
self._add_size_attribute()
cls._add_size_attribute()
def _add_ssd_attribute(self):
self.ssd_attribute = self.env['product.attribute'].create({'name': 'Memory', 'sequence': 1})
self.ssd_256 = self.env['product.attribute.value'].create({
@classmethod
def _add_ssd_attribute(cls):
cls.ssd_attribute = cls.env['product.attribute'].create({'name': 'Memory', 'sequence': 1})
cls.ssd_256 = cls.env['product.attribute.value'].create({
'name': '256 GB',
'attribute_id': self.ssd_attribute.id,
'attribute_id': cls.ssd_attribute.id,
'sequence': 1,
})
self.ssd_512 = self.env['product.attribute.value'].create({
cls.ssd_512 = cls.env['product.attribute.value'].create({
'name': '512 GB',
'attribute_id': self.ssd_attribute.id,
'attribute_id': cls.ssd_attribute.id,
'sequence': 2,
})
self._add_ssd_attribute_line()
cls._add_ssd_attribute_line()
def _add_ssd_attribute_line(self):
self.computer_ssd_attribute_lines = self.env['product.template.attribute.line'].create({
'product_tmpl_id': self.computer.id,
'attribute_id': self.ssd_attribute.id,
'value_ids': [(6, 0, [self.ssd_256.id, self.ssd_512.id])],
@classmethod
def _add_ssd_attribute_line(cls):
cls.computer_ssd_attribute_lines = cls.env['product.template.attribute.line'].create({
'product_tmpl_id': cls.computer.id,
'attribute_id': cls.ssd_attribute.id,
'value_ids': [(6, 0, [cls.ssd_256.id, cls.ssd_512.id])],
})
self.computer_ssd_attribute_lines.product_template_value_ids[0].price_extra = 200
self.computer_ssd_attribute_lines.product_template_value_ids[1].price_extra = 400
cls.computer_ssd_attribute_lines.product_template_value_ids[0].price_extra = 200
cls.computer_ssd_attribute_lines.product_template_value_ids[1].price_extra = 400
def _add_ram_attribute(self):
self.ram_attribute = self.env['product.attribute'].create({'name': 'RAM', 'sequence': 2})
self.ram_8 = self.env['product.attribute.value'].create({
@classmethod
def _add_ram_attribute(cls):
cls.ram_attribute = cls.env['product.attribute'].create({'name': 'RAM', 'sequence': 2})
cls.ram_8 = cls.env['product.attribute.value'].create({
'name': '8 GB',
'attribute_id': self.ram_attribute.id,
'attribute_id': cls.ram_attribute.id,
'sequence': 1,
})
self.ram_16 = self.env['product.attribute.value'].create({
cls.ram_16 = cls.env['product.attribute.value'].create({
'name': '16 GB',
'attribute_id': self.ram_attribute.id,
'attribute_id': cls.ram_attribute.id,
'sequence': 2,
})
self.ram_32 = self.env['product.attribute.value'].create({
cls.ram_32 = cls.env['product.attribute.value'].create({
'name': '32 GB',
'attribute_id': self.ram_attribute.id,
'attribute_id': cls.ram_attribute.id,
'sequence': 3,
})
self.computer_ram_attribute_lines = self.env['product.template.attribute.line'].create({
'product_tmpl_id': self.computer.id,
'attribute_id': self.ram_attribute.id,
'value_ids': [(6, 0, [self.ram_8.id, self.ram_16.id, self.ram_32.id])],
cls.computer_ram_attribute_lines = cls.env['product.template.attribute.line'].create({
'product_tmpl_id': cls.computer.id,
'attribute_id': cls.ram_attribute.id,
'value_ids': [(6, 0, [cls.ram_8.id, cls.ram_16.id, cls.ram_32.id])],
})
self.computer_ram_attribute_lines.product_template_value_ids[0].price_extra = 20
self.computer_ram_attribute_lines.product_template_value_ids[1].price_extra = 40
self.computer_ram_attribute_lines.product_template_value_ids[2].price_extra = 80
cls.computer_ram_attribute_lines.product_template_value_ids[0].price_extra = 20
cls.computer_ram_attribute_lines.product_template_value_ids[1].price_extra = 40
cls.computer_ram_attribute_lines.product_template_value_ids[2].price_extra = 80
def _add_hdd_attribute(self):
self.hdd_attribute = self.env['product.attribute'].create({'name': 'HDD', 'sequence': 3})
self.hdd_1 = self.env['product.attribute.value'].create({
@classmethod
def _add_hdd_attribute(cls):
cls.hdd_attribute = cls.env['product.attribute'].create({'name': 'HDD', 'sequence': 3})
cls.hdd_1 = cls.env['product.attribute.value'].create({
'name': '1 To',
'attribute_id': self.hdd_attribute.id,
'attribute_id': cls.hdd_attribute.id,
'sequence': 1,
})
self.hdd_2 = self.env['product.attribute.value'].create({
cls.hdd_2 = cls.env['product.attribute.value'].create({
'name': '2 To',
'attribute_id': self.hdd_attribute.id,
'attribute_id': cls.hdd_attribute.id,
'sequence': 2,
})
self.hdd_4 = self.env['product.attribute.value'].create({
cls.hdd_4 = cls.env['product.attribute.value'].create({
'name': '4 To',
'attribute_id': self.hdd_attribute.id,
'attribute_id': cls.hdd_attribute.id,
'sequence': 3,
})
self._add_hdd_attribute_line()
cls._add_hdd_attribute_line()
def _add_hdd_attribute_line(self):
self.computer_hdd_attribute_lines = self.env['product.template.attribute.line'].create({
'product_tmpl_id': self.computer.id,
'attribute_id': self.hdd_attribute.id,
'value_ids': [(6, 0, [self.hdd_1.id, self.hdd_2.id, self.hdd_4.id])],
@classmethod
def _add_hdd_attribute_line(cls):
cls.computer_hdd_attribute_lines = cls.env['product.template.attribute.line'].create({
'product_tmpl_id': cls.computer.id,
'attribute_id': cls.hdd_attribute.id,
'value_ids': [(6, 0, [cls.hdd_1.id, cls.hdd_2.id, cls.hdd_4.id])],
})
self.computer_hdd_attribute_lines.product_template_value_ids[0].price_extra = 2
self.computer_hdd_attribute_lines.product_template_value_ids[1].price_extra = 4
self.computer_hdd_attribute_lines.product_template_value_ids[2].price_extra = 8
cls.computer_hdd_attribute_lines.product_template_value_ids[0].price_extra = 2
cls.computer_hdd_attribute_lines.product_template_value_ids[1].price_extra = 4
cls.computer_hdd_attribute_lines.product_template_value_ids[2].price_extra = 8
def _add_ram_exclude_for(self):
self._get_product_value_id(self.computer_ram_attribute_lines, self.ram_16).update({
@@ -117,27 +123,28 @@ class TestProductAttributeValueSetup(TransactionCase):
})]
})
def _add_size_attribute(self):
self.size_attribute = self.env['product.attribute'].create({'name': 'Size', 'sequence': 4})
self.size_m = self.env['product.attribute.value'].create({
@classmethod
def _add_size_attribute(cls):
cls.size_attribute = cls.env['product.attribute'].create({'name': 'Size', 'sequence': 4})
cls.size_m = cls.env['product.attribute.value'].create({
'name': 'M',
'attribute_id': self.size_attribute.id,
'attribute_id': cls.size_attribute.id,
'sequence': 1,
})
self.size_l = self.env['product.attribute.value'].create({
cls.size_l = cls.env['product.attribute.value'].create({
'name': 'L',
'attribute_id': self.size_attribute.id,
'attribute_id': cls.size_attribute.id,
'sequence': 2,
})
self.size_xl = self.env['product.attribute.value'].create({
cls.size_xl = cls.env['product.attribute.value'].create({
'name': 'XL',
'attribute_id': self.size_attribute.id,
'attribute_id': cls.size_attribute.id,
'sequence': 3,
})
self.computer_case_size_attribute_lines = self.env['product.template.attribute.line'].create({
'product_tmpl_id': self.computer_case.id,
'attribute_id': self.size_attribute.id,
'value_ids': [(6, 0, [self.size_m.id, self.size_l.id, self.size_xl.id])],
cls.computer_case_size_attribute_lines = cls.env['product.template.attribute.line'].create({
'product_tmpl_id': cls.computer_case.id,
'attribute_id': cls.size_attribute.id,
'value_ids': [(6, 0, [cls.size_m.id, cls.size_l.id, cls.size_xl.id])],
})
def _get_product_value_id(self, product_template_attribute_lines, product_attribute_value):
+56 -9
View File
@@ -11,15 +11,62 @@ class TestProductPricelist(TransactionCase):
def setUp(self):
super(TestProductPricelist, self).setUp()
self.ProductPricelist = self.env['product.pricelist']
self.res_partner_4 = self.env.ref('base.res_partner_4')
self.computer_SC234 = self.env.ref("product.product_product_3")
self.ipad_retina_display = self.env.ref('product.product_product_4')
self.custom_computer_kit = self.env.ref("product.product_product_5")
self.ipad_mini = self.env.ref("product.product_product_6")
self.apple_in_ear_headphones = self.env.ref("product.product_product_7")
self.laptop_E5023 = self.env.ref('product.product_delivery_01')
self.laptop_S3450 = self.env.ref("product.product_product_25")
self.category_5_id = self.ref('product.product_category_5')
self.res_partner_4 = self.env['res.partner'].create({'name': 'Ready Mat'})
self.res_partner_1 = self.env['res.partner'].create({'name': 'Wood Corner'})
self.category_5_id = self.env['product.category'].create({
'name': 'Office Furniture',
'parent_id': self.env.ref('product.product_category_1').id
}).id
self.computer_SC234 = self.env['product.product'].create({
'name': 'Desk Combination',
'categ_id': self.category_5_id,
})
self.ipad_retina_display = self.env['product.product'].create({
'name': 'Customizable Desk',
})
self.custom_computer_kit = self.env['product.product'].create({
'name': 'Corner Desk Right Sit',
'categ_id': self.category_5_id,
})
self.ipad_mini = self.env['product.product'].create({
'name': 'Large Cabinet',
'categ_id': self.category_5_id,
'standard_price': 800.0,
})
self.env['product.supplierinfo'].create([
{
'name': self.res_partner_1.id,
'product_tmpl_id': self.ipad_mini.product_tmpl_id.id,
'delay': 3,
'min_qty': 1,
'price': 750,
}, {
'name': self.res_partner_4.id,
'product_tmpl_id': self.ipad_mini.product_tmpl_id.id,
'delay': 3,
'min_qty': 1,
'price': 790,
}, {
'name': self.res_partner_4.id,
'product_tmpl_id': self.ipad_mini.product_tmpl_id.id,
'delay': 3,
'min_qty': 3,
'price': 785,
}
])
self.apple_in_ear_headphones = self.env['product.product'].create({
'name': 'Storage Box',
'categ_id': self.category_5_id,
})
self.laptop_E5023 = self.env['product.product'].create({
'name': 'Office Chair',
'categ_id': self.category_5_id,
})
self.laptop_S3450 = self.env['product.product'].create({
'name': 'Acoustic Bloc Screens',
'categ_id': self.category_5_id,
})
self.uom_unit_id = self.ref('uom.product_uom_unit')
self.list0 = self.ref('product.list0')
+5 -3
View File
@@ -8,15 +8,17 @@ class TestSeller(TransactionCase):
def setUp(self):
super(TestSeller, self).setUp()
self.product_service = self.env.ref('product.product_product_2')
self.product_service = self.env['product.product'].create({
'name': 'Virtual Home Staging',
})
self.product_service.default_code = 'DEFCODE'
self.product_consu = self.env['product.product'].create({
'name': 'Boudin',
'type': 'consu',
})
self.product_consu.default_code = 'DEFCODE'
self.asustec = self.env.ref('base.res_partner_1')
self.camptocamp = self.env.ref('base.res_partner_12')
self.asustec = self.env['res.partner'].create({'name': 'Wood Corner'})
self.camptocamp = self.env['res.partner'].create({'name': 'Azure Interior'})
def test_10_sellers(self):
self.product_service.write({'seller_ids': [
@@ -1,11 +1,13 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import tools
from odoo.tests import common, Form
from odoo.addons.account.tests.account_minimal_test import AccountMinimalTest
from odoo.tests import Form
from odoo.modules.module import get_resource_path
class TestProductMargin(common.TransactionCase):
class TestProductMargin(AccountMinimalTest):
def create_account_invoice(self, invoice_type, partner, product, quantity=0.0, price_unit=0.0):
""" Create an invoice as in a view by triggering its onchange methods"""
@@ -19,19 +21,17 @@ class TestProductMargin(common.TransactionCase):
invoice = invoice_form.save()
invoice.post()
return invoice
def test_product_margin(self):
''' In order to test the product_margin module '''
# load account_minimal_test.xml file for chart of account in configuration
tools.convert_file(self.cr, 'product_margin',
get_resource_path('account', 'test', 'account_minimal_test.xml'),
{}, 'init', False, 'test', self.registry._assertion_report)
supplier = self.env['res.partner'].create({'name': 'Supplier'})
customer = self.env['res.partner'].create({'name': 'Customer'})
ipad = self.env.ref("product.product_product_4")
ipad = self.env['product.product'].create({
'name': 'Ipad',
'standard_price': 500.0,
'list_price': 750.0,
})
# Create supplier invoice and customer invoice to test product margin.
# Define supplier invoices
+1 -1
View File
@@ -18,7 +18,7 @@ class CustomerPortal(CustomerPortal):
def _prepare_portal_layout_values(self):
values = super(CustomerPortal, self)._prepare_portal_layout_values()
values['purchase_count'] = request.env['purchase.order'].search_count([
values['purchase_count'] = request.env['purchase.order'].sudo().search_count([
('state', 'in', ['purchase', 'done', 'cancel'])
])
return values
@@ -2,23 +2,20 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import datetime
from odoo.tests import common, Form, tagged
from odoo.tests import Form, tagged
from odoo.addons.account.tests.account_minimal_test import AccountMinimalTest
@tagged('post_install', '-at_install')
class TestPurchaseOrderReport(common.TransactionCase):
def setUp(self):
super(TestPurchaseOrderReport, self).setUp()
class TestPurchaseOrderReport(AccountMinimalTest):
self.partner_id = self.env.ref('base.res_partner_1')
self.product1 = self.env.ref('product.product_product_8')
self.product2 = self.env.ref('product.product_product_11')
self.PurchaseReport = self.env['purchase.report']
# Create a new company and set CoA
self.company_id = self.env['res.company'].create({'name': 'new_company'})
self.env.user.company_id = self.company_id
self.env.ref('l10n_generic_coa.configurable_chart_template').try_loading()
@classmethod
def setUpClass(cls):
super(TestPurchaseOrderReport, cls).setUpClass()
cls.partner_id = cls.env['res.partner'].create({'name': 'A Partner'})
cls.product1 = cls.env['product.product'].create({'name': 'A First Product'})
cls.product2 = cls.env['product.product'].create({'name': 'A Second Product'})
cls.PurchaseReport = cls.env['purchase.report']
cls.company_id = cls.env.ref('base.main_company')
def test_00_purchase_order_report(self):
uom_dozen = self.env.ref('uom.product_uom_dozen')
@@ -223,7 +223,7 @@ class TestSaleMrpFlow(TransactionCase):
# |- component_e x1
# Creation of a sale order for x7 kit_parent
partner = self.env.ref('base.res_partner_1')
partner = self.env['res.partner'].create({'name': 'My Test Partner'})
f = Form(self.env['purchase.order'])
f.partner_id = partner
with f.order_line.new() as line:
+5 -3
View File
@@ -35,7 +35,7 @@ class TestPurchaseRequisitionCommon(common.SavepointCase):
cls.product_09 = cls.env['product.product'].create({
'name': 'Pedal Bin',
'categ_id': cls.env.ref('product.product_category_5').id,
'categ_id': cls.env.ref('product.product_category_all').id,
'standard_price': 10.0,
'list_price': 47.0,
'type': 'consu',
@@ -46,7 +46,7 @@ class TestPurchaseRequisitionCommon(common.SavepointCase):
cls.product_13 = cls.env['product.product'].create({
'name': 'Corner Desk Black',
'categ_id': cls.env.ref('product.product_category_5').id,
'categ_id': cls.env.ref('product.product_category_all').id,
'standard_price': 78.0,
'list_price': 85.0,
'type': 'consu',
@@ -64,5 +64,7 @@ class TestPurchaseRequisitionCommon(common.SavepointCase):
'product_uom_id': cls.product_uom_id.id})]
})
cls.res_partner_1 = cls.env.ref('base.res_partner_1')
cls.res_partner_1 = cls.env['res.partner'].create({
'name': 'Wood Corner',
})
cls.env.user.company_id.currency_id = cls.env.ref("base.USD").id
-5
View File
@@ -22,11 +22,6 @@ class TestPurchase(TestStockCommon):
product.name, '/', self.env.company, order_values)
])
def _load(self, module, *args):
tools.convert_file(self.cr, 'purchase',
get_module_resource(module, *args),
{}, 'init', False, 'test', self.registry._assertion_report)
@classmethod
def setUpClass(cls):
super(TestPurchase, cls).setUpClass()
@@ -4,15 +4,16 @@
import time
from .common import TestPurchase
from odoo.addons.stock_account.tests.stock_account_minimal_test import StockAccountMinimalTest
class TestAveragePrice(TestPurchase):
class TestAveragePrice(TestPurchase, StockAccountMinimalTest):
def test_00_average_price(self):
""" Testcase for average price computation"""
self._load('account', 'test', 'account_minimal_test.xml')
self._load('stock_account', 'test', 'stock_valuation_account.xml')
res_partner_3 = self.env['res.partner'].create({
'name': 'Gemini Partner',
})
# Set a product as using average price.
product_cable_management_box = self.env['product.product'].create({
@@ -29,12 +30,12 @@ class TestAveragePrice(TestPurchase):
})
product_cable_management_box.categ_id.property_cost_method = 'average'
product_cable_management_box.categ_id.property_valuation = 'real_time'
product_cable_management_box.categ_id.property_stock_account_input_categ_id = self.ref('purchase.o_expense')
product_cable_management_box.categ_id.property_stock_account_output_categ_id = self.ref('purchase.o_income')
product_cable_management_box.categ_id.property_stock_account_input_categ_id = self.o_expense
product_cable_management_box.categ_id.property_stock_account_output_categ_id = self.o_income
# I create a draft Purchase Order for first incoming shipment for 10 pieces at 60€
purchase_order_1 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'Average Ice Cream',
'product_id': product_cable_management_box.id,
@@ -62,7 +63,7 @@ class TestAveragePrice(TestPurchase):
# I create a draft Purchase Order for second incoming shipment for 30 pieces at 80€
purchase_order_2 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': product_cable_management_box.name,
'product_id': product_cable_management_box.id,
@@ -108,7 +109,7 @@ class TestAveragePrice(TestPurchase):
# Make a new purchase order with 500 g Average Ice Cream at a price of 0.2€/g
purchase_order_3 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': product_cable_management_box.name,
'product_id': product_cable_management_box.id,
@@ -10,9 +10,9 @@ class TestCreatePicking(common.TestProductCommon):
def setUp(self):
super(TestCreatePicking, self).setUp()
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.partner_id = self.env['res.partner'].create({'name': 'Wood Corner Partner'})
self.product_id_1 = self.env['product.product'].create({'name': 'Large Desk'})
self.product_id_2 = self.env['product.product'].create({'name': 'Conference Chair'})
res_users_purchase_user = self.env.ref('purchase.group_purchase_user')
Users = self.env['res.users'].with_context({'no_reset_password': True, 'mail_create_nosubscribe': True})
+14 -13
View File
@@ -3,15 +3,16 @@
import time
from .common import TestPurchase
from odoo.addons.stock_account.tests.stock_account_minimal_test import StockAccountMinimalTest
class TestFifoPrice(TestPurchase):
class TestFifoPrice(TestPurchase, StockAccountMinimalTest):
def test_00_test_fifo(self):
""" Test product cost price with fifo removal strategy."""
self._load('account', 'test', 'account_minimal_test.xml')
self._load('stock_account', 'test', 'stock_valuation_account.xml')
res_partner_3 = self.env['res.partner'].create({
'name': 'Gemini Partner',
})
# Set a product as using fifo price
product_cable_management_box = self.env['product.product'].create({
@@ -28,12 +29,12 @@ class TestFifoPrice(TestPurchase):
})
product_cable_management_box.categ_id.property_cost_method = 'fifo'
product_cable_management_box.categ_id.property_valuation = 'real_time'
product_cable_management_box.categ_id.property_stock_account_input_categ_id = self.ref('purchase.o_expense')
product_cable_management_box.categ_id.property_stock_account_output_categ_id = self.ref('purchase.o_income')
product_cable_management_box.categ_id.property_stock_account_input_categ_id = self.o_expense
product_cable_management_box.categ_id.property_stock_account_output_categ_id = self.o_income
# I create a draft Purchase Order for first in move for 10 kg at 50 euro
purchase_order_1 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
'product_id': product_cable_management_box.id,
@@ -61,7 +62,7 @@ class TestFifoPrice(TestPurchase):
# I create a draft Purchase Order for second shipment for 30 kg at 80 euro
purchase_order_2 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
'product_id': product_cable_management_box.id,
@@ -144,7 +145,7 @@ class TestFifoPrice(TestPurchase):
# Create PO for 30000 g at 0.150$/g and 10 kg at 150$/kg
purchase_order_usd = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'currency_id': NewUSD.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
@@ -229,8 +230,8 @@ class TestFifoPrice(TestPurchase):
})
product_fifo_negative.categ_id.property_cost_method = 'fifo'
product_fifo_negative.categ_id.property_valuation = 'real_time'
product_fifo_negative.categ_id.property_stock_account_input_categ_id = self.ref('purchase.o_expense')
product_fifo_negative.categ_id.property_stock_account_output_categ_id = self.ref('purchase.o_income')
product_fifo_negative.categ_id.property_stock_account_input_categ_id = self.o_expense
product_fifo_negative.categ_id.property_stock_account_output_categ_id = self.o_income
# Create outpicking.create delivery order of 100 kg.
outgoing_shipment_neg = self.env['stock.picking'].create({
@@ -283,7 +284,7 @@ class TestFifoPrice(TestPurchase):
# Receive purchase order with 50 kg Ice Cream at 50€/kg
purchase_order_neg = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
'product_id': product_fifo_negative.id,
@@ -303,7 +304,7 @@ class TestFifoPrice(TestPurchase):
# Receive purchase order with 600 kg FIFO Ice Cream at 80 euro/kg
purchase_order_neg2 = self.env['purchase.order'].create({
'partner_id': self.env.ref('base.res_partner_3').id,
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': product_cable_management_box.name,
'product_id': product_fifo_negative.id,
@@ -4,14 +4,16 @@ import time
from .common import TestPurchase
from odoo.tests.common import Form
from odoo.addons.stock_account.tests.stock_account_minimal_test import StockAccountMinimalTest
class TestFifoReturns(TestPurchase):
class TestFifoReturns(TestPurchase, StockAccountMinimalTest):
def test_fifo_returns(self):
"""Test to create product and purchase order to test the FIFO returns of the product"""
self._load('account', 'test', 'account_minimal_test.xml')
self._load('stock_account', 'test', 'stock_valuation_account.xml')
res_partner_3 = self.env['res.partner'].create({
'name': 'Gemini Partner',
})
# Set a product as using fifo price
product_fiforet_icecream = self.env['product.product'].create({
@@ -26,12 +28,12 @@ class TestFifoReturns(TestPurchase):
})
product_fiforet_icecream.categ_id.property_cost_method = 'fifo'
product_fiforet_icecream.categ_id.property_valuation = 'real_time'
product_fiforet_icecream.categ_id.property_stock_account_input_categ_id = self.ref('purchase.o_expense')
product_fiforet_icecream.categ_id.property_stock_account_output_categ_id = self.ref('purchase.o_income')
product_fiforet_icecream.categ_id.property_stock_account_input_categ_id = self.o_expense
product_fiforet_icecream.categ_id.property_stock_account_output_categ_id = self.o_income
# I create a draft Purchase Order for first in move for 10 kg at 50 euro
purchase_order_1 = self.env['purchase.order'].create({
'partner_id': self.ref('base.res_partner_3'),
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
'product_id': product_fiforet_icecream.id,
@@ -44,7 +46,7 @@ class TestFifoReturns(TestPurchase):
# Create a draft Purchase Order for second shipment for 30kg at 80€/kg
purchase_order_2 = self.env['purchase.order'].create({
'partner_id': self.ref('base.res_partner_3'),
'partner_id': res_partner_3.id,
'order_line': [(0, 0, {
'name': 'FIFO Ice Cream',
'product_id': product_fiforet_icecream.id,
@@ -83,7 +83,7 @@ class TestOnchangeProductId(TransactionCase):
po_line._onchange_quantity()
self.assertEqual(1200, po_line.price_unit, "Unit price should be 1200 for one Dozen")
product_ipad = self.env.ref('product.product_product_4')
product_ipad = self.env['product.product'].create({'name': 'Conference Chair'})
po_line2 = self.po_line_model.create({
'name': product_ipad.name,
'product_id': product_ipad.id,
@@ -11,19 +11,32 @@ class TestDeleteOrder(TestPurchase):
''' Testcase for deleting purchase order with purchase user group'''
# In order to test delete process on purchase order,tried to delete a confirmed order and check Error Message.
purchase_order_1 = self.env.ref('purchase.purchase_order_1').with_user(self.res_users_purchase_user)
partner = self.env['res.partner'].create({'name': 'My Partner'})
purchase_order = self.env['purchase.order'].create({
'partner_id': partner.id,
'state': 'purchase',
})
purchase_order_1 = purchase_order.with_user(self.res_users_purchase_user)
with self.assertRaises(UserError):
purchase_order_1.unlink()
# Delete 'cancelled' purchase order with user group
purchase_order_7 = self.env.ref('purchase.purchase_order_7').with_user(self.res_users_purchase_user)
purchase_order_7.button_cancel()
self.assertEqual(purchase_order_7.state, 'cancel', 'PO is cancelled!')
purchase_order_7.unlink()
purchase_order = self.env['purchase.order'].create({
'partner_id': partner.id,
'state': 'purchase',
})
purchase_order_2 = purchase_order.with_user(self.res_users_purchase_user)
purchase_order_2.button_cancel()
self.assertEqual(purchase_order_2.state, 'cancel', 'PO is cancelled!')
purchase_order_2.unlink()
# Delete 'draft' purchase order with user group
purchase_order_5 = self.env.ref('purchase.purchase_order_5').with_user(self.res_users_purchase_user)
self.assertEqual(purchase_order_5.state, 'draft', 'PO in draft state!')
purchase_order_5.button_cancel()
self.assertEqual(purchase_order_5.state, 'cancel', 'PO is cancelled!')
purchase_order_5.unlink()
purchase_order = self.env['purchase.order'].create({
'partner_id': partner.id,
'state': 'draft',
})
purchase_order_3 = purchase_order.with_user(self.res_users_purchase_user)
purchase_order_3.button_cancel()
self.assertEqual(purchase_order_3.state, 'cancel', 'PO is cancelled!')
purchase_order_3.unlink()
@@ -16,9 +16,9 @@ class TestPurchaseOrder(AccountingTestCase):
# Useful models
self.PurchaseOrder = self.env['purchase.order']
self.PurchaseOrderLine = self.env['purchase.order.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.partner_id = self.env['res.partner'].create({'name': 'Wood Corner Partner'})
self.product_id_1 = self.env['product.product'].create({'name': 'Large Desk'})
self.product_id_2 = self.env['product.product'].create({'name': 'Conference Chair'})
(self.product_id_1 | self.product_id_2).write({'purchase_method': 'purchase'})
self.po_vals = {
@@ -7,7 +7,11 @@ class TestPurchaseOrderProcess(TestPurchase):
""" Test cancel purchase order with group user."""
# In order to test the cancel flow,start it from canceling confirmed purchase order.
po_edit_with_user = self.env.ref('purchase.purchase_order_5').with_user(self.res_users_purchase_user)
purchase_order = self.env['purchase.order'].create({
'partner_id': self.env['res.partner'].create({'name': 'My Partner'}).id,
'state': 'draft',
})
po_edit_with_user = purchase_order.with_user(self.res_users_purchase_user)
# Confirm the purchase order.
po_edit_with_user.button_confirm()
@@ -17,8 +17,16 @@ class TestStockValuation(TransactionCase):
super(TestStockValuation, self).setUp()
self.supplier_location = self.env.ref('stock.stock_location_suppliers')
self.stock_location = self.env.ref('stock.stock_location_stock')
self.partner_id = self.env.ref('base.res_partner_1')
self.product1 = self.env.ref('product.product_product_8')
self.partner_id = self.env['res.partner'].create({
'name': 'Wood Corner Partner',
'company_id': self.env.user.company_id.id,
})
self.product1 = self.env['product.product'].create({
'name': 'Large Desk',
'standard_price': 1299.0,
'list_price': 1799.0,
'type': 'product',
})
Account = self.env['account.account']
self.stock_input_account = Account.create({
'name': 'Stock Input',
@@ -287,7 +295,8 @@ class TestStockValuationWithCOA(AccountingTestCase):
super(TestStockValuationWithCOA, self).setUp()
self.supplier_location = self.env.ref('stock.stock_location_suppliers')
self.stock_location = self.env.ref('stock.stock_location_stock')
self.partner_id = self.env.ref('base.res_partner_1')
self.partner_id = self.env['res.partner'].create({'name': 'Wood Corner Partner'})
self.product1 = self.env['product.product'].create({'name': 'Large Desk'})
self.cat = self.env['product.category'].create({
'name': 'cat',
@@ -520,6 +529,7 @@ class TestStockValuationWithCOA(AccountingTestCase):
"""
company = self.env.user.company_id
company.anglo_saxon_accounting = True
company.currency_id = self.usd_currency
date_po = '2019-01-01'
@@ -587,6 +597,7 @@ class TestStockValuationWithCOA(AccountingTestCase):
self.assertEqual(len(move_lines), 2)
payable_line = move_lines.filtered(lambda l: l.account_id.internal_type == 'payable')
self.assertEqual(payable_line.amount_currency, -100.0)
self.assertAlmostEqual(payable_line.balance, -66.67)
@@ -603,6 +614,7 @@ class TestStockValuationWithCOA(AccountingTestCase):
"""
company = self.env.user.company_id
company.anglo_saxon_accounting = True
company.currency_id = self.usd_currency
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self.product1.product_tmpl_id.categ_id.property_valuation = 'real_time'
@@ -778,6 +790,7 @@ class TestStockValuationWithCOA(AccountingTestCase):
"""
company = self.env.user.company_id
company.anglo_saxon_accounting = True
company.currency_id = self.usd_currency
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self.product1.product_tmpl_id.categ_id.property_valuation = 'real_time'
@@ -938,6 +951,7 @@ class TestStockValuationWithCOA(AccountingTestCase):
"""
company = self.env.user.company_id
company.anglo_saxon_accounting = True
company.currency_id = self.usd_currency
exchange_diff_journal = company.currency_exchange_journal_id.exists()
date_po = '2019-01-01'
+146 -21
View File
@@ -10,33 +10,158 @@ from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestRepair(AccountingTestCase):
def setUp(self):
super(TestRepair, self).setUp()
@classmethod
def setUpClass(cls):
super(TestRepair, cls).setUpClass()
self.Repair = self.env['repair.order']
self.ResUsers = self.env['res.users']
self.RepairMakeInvoice = self.env['repair.order.make_invoice']
self.res_group_user = self.env.ref('stock.group_stock_user')
self.res_group_manager = self.env.ref('stock.group_stock_manager')
self.repair_r0 = self.env.ref('repair.repair_r0')
self.repair_r1 = self.env.ref('repair.repair_r1')
self.repair_r2 = self.env.ref('repair.repair_r2')
# Partners
cls.res_partner_1 = cls.env['res.partner'].create({'name': 'Wood Corner'})
cls.res_partner_address_1 = cls.env['res.partner'].create({'name': 'Willie Burke', 'parent_id': cls.res_partner_1.id})
cls.res_partner_12 = cls.env['res.partner'].create({'name': 'Partner 12'})
self.res_repair_user = self.ResUsers.create({
# Products
cls.product_product_3 = cls.env['product.product'].create({'name': 'Desk Combination'})
cls.product_product_11 = cls.env['product.product'].create({'name': 'Conference Chair'})
cls.product_product_5 = cls.env['product.product'].create({'name': 'Product 5'})
cls.product_product_6 = cls.env['product.product'].create({'name': 'Large Cabinet'})
cls.product_product_12 = cls.env['product.product'].create({'name': 'Office Chair Black'})
cls.product_product_13 = cls.env['product.product'].create({'name': 'Corner Desk Black'})
cls.product_product_2 = cls.env['product.product'].create({'name': 'Virtual Home Staging'})
cls.product_service_order_repair = cls.env['product.product'].create({
'name': 'Repair Services',
'type': 'service',
})
# Location
cls.stock_location_14 = cls.env['stock.location'].create({
'name': 'Shelf 2',
'location_id': cls.env.ref('stock.warehouse0').lot_stock_id.id,
})
# Repair Orders
cls.repair1 = cls.env['repair.order'].create({
'address_id': cls.res_partner_address_1.id,
'guarantee_limit': datetime.today().strftime('%Y-%m-%d'),
'invoice_method': 'none',
'user_id': False,
'product_id': cls.product_product_3.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'partner_invoice_id': cls.res_partner_address_1.id,
'location_id': cls.env.ref('stock.stock_location_stock').id,
'operations': [
(0, 0, {
'location_dest_id': cls.product_product_11.property_stock_production.id,
'location_id': cls.env.ref('stock.stock_location_stock').id,
'name': cls.product_product_11.get_product_multiline_description_sale(),
'product_id': cls.product_product_11.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'product_uom_qty': 1.0,
'price_unit': 50.0,
'state': 'draft',
'type': 'add',
'company_id': cls.env.company.id,
})
],
'fees_lines': [
(0, 0, {
'name': cls.product_service_order_repair.get_product_multiline_description_sale(),
'product_id': cls.product_service_order_repair.id,
'product_uom_qty': 1.0,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'price_unit': 50.0,
'company_id': cls.env.company.id,
})
],
'partner_id': cls.res_partner_12.id,
})
cls.repair0 = cls.env['repair.order'].create({
'product_id': cls.product_product_5.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'address_id': cls.res_partner_address_1.id,
'guarantee_limit': datetime.today().strftime('%Y-%m-%d'),
'invoice_method': 'after_repair',
'user_id': False,
'partner_invoice_id': cls.res_partner_address_1.id,
'location_id': cls.env.ref('stock.stock_location_stock').id,
'operations': [
(0, 0, {
'location_dest_id': cls.product_product_12.property_stock_production.id,
'location_id': cls.env.ref('stock.stock_location_stock').id,
'name': cls.product_product_12.get_product_multiline_description_sale(),
'price_unit': 50.0,
'product_id': cls.product_product_12.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'product_uom_qty': 1.0,
'state': 'draft',
'type': 'add',
'company_id': cls.env.company.id,
})
],
'fees_lines': [
(0, 0, {
'name': cls.product_service_order_repair.get_product_multiline_description_sale(),
'product_id': cls.product_service_order_repair.id,
'product_uom_qty': 1.0,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'price_unit': 50.0,
'company_id': cls.env.company.id,
})
],
'partner_id': cls.res_partner_12.id,
})
cls.repair2 = cls.env['repair.order'].create({
'product_id': cls.product_product_6.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'address_id': cls.res_partner_address_1.id,
'guarantee_limit': datetime.today().strftime('%Y-%m-%d'),
'invoice_method': 'b4repair',
'user_id': False,
'partner_invoice_id': cls.res_partner_address_1.id,
'location_id': cls.stock_location_14.id,
'operations': [
(0, 0, {
'location_dest_id': cls.product_product_13.property_stock_production.id,
'location_id': cls.env.ref('stock.stock_location_stock').id,
'name': cls.product_product_13.get_product_multiline_description_sale(),
'price_unit': 50.0,
'product_id': cls.product_product_13.id,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'product_uom_qty': 1.0,
'state': 'draft',
'type': 'add',
'company_id': cls.env.company.id,
})
],
'fees_lines': [
(0, 0, {
'name': cls.product_service_order_repair.get_product_multiline_description_sale(),
'product_id': cls.product_service_order_repair.id,
'product_uom_qty': 1.0,
'product_uom': cls.env.ref('uom.product_uom_unit').id,
'price_unit': 50.0,
'company_id': cls.env.company.id,
})
],
'partner_id': cls.res_partner_12.id,
})
cls.res_repair_user = cls.env['res.users'].create({
'name': 'Repair User',
'login': 'maru',
'email': 'repair_user@yourcompany.com',
'groups_id': [(6, 0, [self.res_group_user.id])]})
'groups_id': [(6, 0, [cls.env.ref('stock.group_stock_user').id])]})
self.res_repair_manager = self.ResUsers.create({
cls.res_repair_manager = cls.env['res.users'].create({
'name': 'Repair Manager',
'login': 'marm',
'email': 'repair_manager@yourcompany.com',
'groups_id': [(6, 0, [self.res_group_manager.id])]})
'groups_id': [(6, 0, [cls.env.ref('stock.group_stock_manager').id])]})
def _create_simple_repair_order(self, invoice_method):
product_to_repair = self.env.ref('product.product_product_5')
partner = self.env.ref('base.res_partner_address_1')
product_to_repair = self.product_product_5
partner = self.res_partner_address_1
return self.env['repair.order'].create({
'product_id': product_to_repair.id,
'product_uom': product_to_repair.uom_id.id,
@@ -45,11 +170,11 @@ class TestRepair(AccountingTestCase):
'invoice_method': invoice_method,
'partner_invoice_id': partner.id,
'location_id': self.env.ref('stock.stock_location_stock').id,
'partner_id': self.env.ref('base.res_partner_12').id
'partner_id': self.res_partner_12.id
})
def _create_simple_operation(self, repair_id=False, qty=0.0, price_unit=0.0):
product_to_add = self.env.ref('product.product_product_5')
product_to_add = self.product_product_5
return self.env['repair.line'].create({
'name': 'Add The product',
'type': 'add',
@@ -64,7 +189,7 @@ class TestRepair(AccountingTestCase):
})
def _create_simple_fee(self, repair_id=False, qty=0.0, price_unit=0.0):
product_service = self.env.ref('product.product_product_2')
product_service = self.product_product_2
return self.env['repair.fee'].create({
'name': 'PC Assemble + Custom (PC on Demand)',
'product_id': product_service.id,
@@ -92,7 +217,7 @@ class TestRepair(AccountingTestCase):
repair.action_repair_end()
# I define Invoice Method 'After Repair' option in this Repair order.so I create invoice by clicking on "Make Invoice" wizard.
make_invoice = self.RepairMakeInvoice.create({
make_invoice = self.env['repair.order.make_invoice'].create({
'group': True})
# I click on "Create Invoice" button of this wizard to make invoice.
context = {
@@ -147,7 +272,7 @@ class TestRepair(AccountingTestCase):
'Repaired product went to the wrong location')
self.assertEqual(repair.operations.move_id.location_id.id, self.env.ref('stock.stock_location_stock').id,
'Consumed product was taken in the wrong location')
self.assertEqual(repair.operations.move_id.location_dest_id.id, self.env.ref('product.product_product_5').property_stock_production.id,
self.assertEqual(repair.operations.move_id.location_dest_id.id, self.product_product_5.property_stock_production.id,
'Consumed product went to the wrong location')
# I define Invoice Method 'No Invoice' option in this repair order.

Some files were not shown because too many files have changed in this diff Show More