Remove accounts from products
The edition of accounting categories are limited to accounting administrators. If a product does not have an accounting category, the default value defined on the configuration are used. issue3805 review45111002
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
* Remove accounts from products
|
||||
|
||||
Version 4.8.0 - 2018-04-23
|
||||
* Bug fixes (see mercurial logs for details)
|
||||
|
||||
|
||||
+12
-16
@@ -2,28 +2,24 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.pool import Pool
|
||||
from .product import *
|
||||
from .configuration import *
|
||||
from . import product
|
||||
from . import configuration
|
||||
from . import account
|
||||
|
||||
|
||||
def register():
|
||||
Pool.register(
|
||||
ProductConfiguration,
|
||||
Category,
|
||||
CategoryAccount,
|
||||
CategoryCustomerTax,
|
||||
CategorySupplierTax,
|
||||
product.Category,
|
||||
product.CategoryAccount,
|
||||
product.CategoryCustomerTax,
|
||||
product.CategorySupplierTax,
|
||||
account.CreateChartProperties,
|
||||
Template,
|
||||
TemplateAccount,
|
||||
TemplateCustomerTax,
|
||||
TemplateSupplierTax,
|
||||
Product,
|
||||
TemplateAccountCategory,
|
||||
TemplateCategoryAll,
|
||||
Configuration,
|
||||
ConfigurationDefaultAccount,
|
||||
product.Template,
|
||||
product.Product,
|
||||
product.TemplateAccountCategory,
|
||||
product.TemplateCategoryAll,
|
||||
configuration.Configuration,
|
||||
configuration.ConfigurationDefaultAccount,
|
||||
module='account_product', type_='model')
|
||||
Pool.register(
|
||||
account.CreateChart,
|
||||
|
||||
+3
-16
@@ -12,20 +12,6 @@ class CreateChartProperties:
|
||||
__metaclass__ = PoolMeta
|
||||
__name__ = 'account.create_chart.properties'
|
||||
|
||||
product_account_expense = fields.Many2One(
|
||||
'account.account', 'Default Expense Account',
|
||||
domain=[
|
||||
('kind', '=', 'expense'),
|
||||
('company', '=', Eval('company')),
|
||||
],
|
||||
depends=['company'])
|
||||
product_account_revenue = fields.Many2One(
|
||||
'account.account', 'Default Revenue Account',
|
||||
domain=[
|
||||
('kind', '=', 'revenue'),
|
||||
('company', '=', Eval('company')),
|
||||
],
|
||||
depends=['company'])
|
||||
category_account_expense = fields.Many2One(
|
||||
'account.account', 'Default Expense Account',
|
||||
domain=[
|
||||
@@ -53,8 +39,9 @@ class CreateChart:
|
||||
|
||||
with Transaction().set_context(company=self.properties.company.id):
|
||||
config = Configuration(1)
|
||||
for name in ['product_account_expense', 'product_account_revenue',
|
||||
'category_account_expense', 'category_account_revenue']:
|
||||
for name in [
|
||||
'category_account_expense',
|
||||
'category_account_revenue']:
|
||||
setattr(config, 'default_%s' % name,
|
||||
getattr(self.properties, name, None))
|
||||
config.save()
|
||||
|
||||
+2
-63
@@ -3,29 +3,15 @@
|
||||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.model import fields
|
||||
from trytond.pyson import Eval
|
||||
from trytond import backend
|
||||
|
||||
|
||||
__all__ = ['Configuration', 'ConfigurationDefaultAccount',
|
||||
'ProductConfiguration']
|
||||
__all__ = ['Configuration', 'ConfigurationDefaultAccount']
|
||||
|
||||
|
||||
class Configuration:
|
||||
__metaclass__ = PoolMeta
|
||||
__name__ = 'account.configuration'
|
||||
|
||||
default_product_account_expense = fields.MultiValue(fields.Many2One(
|
||||
'account.account', 'Default Account Expense',
|
||||
domain=[
|
||||
('kind', '=', 'expense'),
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
]))
|
||||
default_product_account_revenue = fields.MultiValue(fields.Many2One(
|
||||
'account.account', 'Default Account Revenue',
|
||||
domain=[
|
||||
('kind', '=', 'revenue'),
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
]))
|
||||
default_category_account_expense = fields.MultiValue(fields.Many2One(
|
||||
'account.account', 'Default Account Expense',
|
||||
domain=[
|
||||
@@ -42,9 +28,7 @@ class Configuration:
|
||||
@classmethod
|
||||
def multivalue_model(cls, field):
|
||||
pool = Pool()
|
||||
if field in {'default_product_account_expense',
|
||||
'default_product_account_revenue',
|
||||
'default_category_account_expense',
|
||||
if field in {'default_category_account_expense',
|
||||
'default_category_account_revenue'}:
|
||||
return pool.get('account.configuration.default_account')
|
||||
return super(Configuration, cls).multivalue_model(field)
|
||||
@@ -53,20 +37,6 @@ class Configuration:
|
||||
class ConfigurationDefaultAccount:
|
||||
__metaclass__ = PoolMeta
|
||||
__name__ = 'account.configuration.default_account'
|
||||
default_product_account_expense = fields.Many2One(
|
||||
'account.account', "Default Account Expense",
|
||||
domain=[
|
||||
('kind', '=', 'expense'),
|
||||
('company', '=', Eval('company', -1)),
|
||||
],
|
||||
depends=['company'])
|
||||
default_product_account_revenue = fields.Many2One(
|
||||
'account.account', "Default Account Revenue",
|
||||
domain=[
|
||||
('kind', '=', 'revenue'),
|
||||
('company', '=', Eval('company', -1)),
|
||||
],
|
||||
depends=['company'])
|
||||
default_category_account_expense = fields.Many2One(
|
||||
'account.account', "Default Account Expense",
|
||||
domain=[
|
||||
@@ -81,34 +51,3 @@ class ConfigurationDefaultAccount:
|
||||
('company', '=', Eval('company', -1)),
|
||||
],
|
||||
depends=['company'])
|
||||
|
||||
|
||||
class ProductConfiguration:
|
||||
__metaclass__ = PoolMeta
|
||||
__name__ = 'product.configuration'
|
||||
|
||||
default_accounts_category = fields.Boolean(
|
||||
'Use Category\'s accounts by default')
|
||||
default_taxes_category = fields.Boolean(
|
||||
'Use Category\' taxes by default')
|
||||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
TableHandler = backend.get('TableHandler')
|
||||
|
||||
# Migration from 3.8: rename default_account_category into
|
||||
# default_accounts_category
|
||||
table = TableHandler(cls, module_name)
|
||||
if table.column_exist('default_account_category'):
|
||||
table.column_rename(
|
||||
'default_account_category', 'default_accounts_category')
|
||||
|
||||
super(ProductConfiguration, cls).__register__(module_name)
|
||||
|
||||
@classmethod
|
||||
def default_default_accounts_category(cls):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def default_default_taxes_category(cls):
|
||||
return False
|
||||
|
||||
@@ -8,11 +8,5 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="inherit" ref="account.configuration_view_form"/>
|
||||
<field name="name">configuration_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_configuration_view_form">
|
||||
<field name="model">product.configuration</field>
|
||||
<field name="inherit" ref="product.product_configuration_view_form"/>
|
||||
<field name="name">product_configuration_form</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
|
||||
+42
-220
@@ -15,13 +15,14 @@ from trytond.modules.company.model import (
|
||||
|
||||
__all__ = ['Category', 'CategoryAccount',
|
||||
'CategoryCustomerTax', 'CategorySupplierTax',
|
||||
'Template', 'TemplateAccount',
|
||||
'TemplateCustomerTax', 'TemplateSupplierTax',
|
||||
'Product', 'account_used', 'template_property',
|
||||
'Template', 'Product', 'account_used', 'template_property',
|
||||
'TemplateAccountCategory', 'TemplateCategoryAll']
|
||||
|
||||
|
||||
def account_used(field_name):
|
||||
def account_used(field_name, field_string=None):
|
||||
if field_string is None:
|
||||
field_string = field_name
|
||||
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
def wrapper(self):
|
||||
@@ -30,10 +31,10 @@ def account_used(field_name):
|
||||
account = self.get_account(field_name + '_used')
|
||||
# Allow empty values on on_change
|
||||
if not account and not Transaction().readonly:
|
||||
field_string = (
|
||||
self.fields_get([field_name])[field_name]['string'])
|
||||
field = (
|
||||
self.fields_get([field_string])[field_string]['string'])
|
||||
self.raise_user_error('missing_account', {
|
||||
'field': field_string,
|
||||
'field': field,
|
||||
'name': self.rec_name,
|
||||
})
|
||||
return account
|
||||
@@ -310,68 +311,7 @@ class Template(CompanyMultiValueMixin):
|
||||
account_category = fields.Many2One('product.category', 'Account Category',
|
||||
domain=[
|
||||
('accounting', '=', True),
|
||||
],
|
||||
states={
|
||||
'required': (Eval('accounts_category', False)
|
||||
| Eval('taxes_category', False)),
|
||||
},
|
||||
depends=['accounts_category', 'taxes_category'])
|
||||
accounts_category = fields.Boolean('Use Category\'s accounts',
|
||||
help="Check to use the accounts defined on the account category.")
|
||||
accounts = fields.One2Many(
|
||||
'product.template.account', 'template', "Accounts")
|
||||
account_expense = fields.MultiValue(fields.Many2One('account.account',
|
||||
'Account Expense', domain=[
|
||||
('kind', '=', 'expense'),
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
],
|
||||
states={
|
||||
'invisible': (~Eval('context', {}).get('company')
|
||||
| Eval('accounts_category')),
|
||||
},
|
||||
help=("The account to use instead of the one defined on the "
|
||||
"account category."), depends=['accounts_category']))
|
||||
account_revenue = fields.MultiValue(fields.Many2One('account.account',
|
||||
'Account Revenue', domain=[
|
||||
('kind', '=', 'revenue'),
|
||||
('company', '=', Eval('context', {}).get('company', -1)),
|
||||
],
|
||||
states={
|
||||
'invisible': (~Eval('context', {}).get('company')
|
||||
| Eval('accounts_category')),
|
||||
},
|
||||
help=("The account to use instead of the one defined on the "
|
||||
"account category."), depends=['accounts_category']))
|
||||
taxes_category = fields.Boolean('Use Category\'s Taxes',
|
||||
help="Check to use the taxes defined on the account category.")
|
||||
customer_taxes = fields.Many2Many('product.template-customer-account.tax',
|
||||
'product', 'tax', 'Customer Taxes',
|
||||
order=[('tax.sequence', 'ASC'), ('tax.id', 'ASC')],
|
||||
domain=[('parent', '=', None), ['OR',
|
||||
('group', '=', None),
|
||||
('group.kind', 'in', ['sale', 'both'])],
|
||||
],
|
||||
states={
|
||||
'invisible': (~Eval('context', {}).get('company')
|
||||
| Eval('taxes_category')),
|
||||
}, depends=['taxes_category'],
|
||||
help="The taxes to apply when selling the product.")
|
||||
supplier_taxes = fields.Many2Many('product.template-supplier-account.tax',
|
||||
'product', 'tax', 'Supplier Taxes',
|
||||
order=[('tax.sequence', 'ASC'), ('tax.id', 'ASC')],
|
||||
domain=[('parent', '=', None), ['OR',
|
||||
('group', '=', None),
|
||||
('group.kind', 'in', ['purchase', 'both'])],
|
||||
],
|
||||
states={
|
||||
'invisible': (~Eval('context', {}).get('company')
|
||||
| Eval('taxes_category')),
|
||||
}, depends=['taxes_category'],
|
||||
help="The taxes to apply when purchasing the product.")
|
||||
customer_taxes_used = fields.Function(fields.One2Many('account.tax', None,
|
||||
'Customer Taxes Used'), 'get_taxes')
|
||||
supplier_taxes_used = fields.Function(fields.One2Many('account.tax', None,
|
||||
'Supplier Taxes Used'), 'get_taxes')
|
||||
])
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
@@ -379,169 +319,53 @@ class Template(CompanyMultiValueMixin):
|
||||
cls._error_messages.update({
|
||||
'missing_account': ('There is no '
|
||||
'"%(field)s" defined on the product "%(name)s"'),
|
||||
'missing_taxes': ('There is no account category defined '
|
||||
'on the product "%(name)s"'),
|
||||
})
|
||||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
TableHandler = backend.get('TableHandler')
|
||||
cursor = Transaction().connection.cursor()
|
||||
pool = Pool()
|
||||
Category = pool.get('product.category')
|
||||
sql_table = cls.__table__()
|
||||
category = Category.__table__()
|
||||
|
||||
table = TableHandler(cls, module_name)
|
||||
category_exists = table.column_exist('category')
|
||||
|
||||
# Migration from 3.8: rename account_category into accounts_category
|
||||
if (table.column_exist('account_category')
|
||||
and not table.column_exist('accounts_category')):
|
||||
table.column_rename('account_category', 'accounts_category')
|
||||
|
||||
super(Template, cls).__register__(module_name)
|
||||
|
||||
# Migration from 3.8: duplicate category into account_category
|
||||
if category_exists:
|
||||
# Only accounting category until now
|
||||
cursor.execute(*category.update([category.accounting], [True]))
|
||||
cursor.execute(*sql_table.update(
|
||||
[sql_table.account_category],
|
||||
[sql_table.category]))
|
||||
|
||||
@classmethod
|
||||
def multivalue_model(cls, field):
|
||||
pool = Pool()
|
||||
if field in {'account_expense', 'account_revenue'}:
|
||||
return pool.get('product.template.account')
|
||||
return super(Template, cls).multivalue_model(field)
|
||||
|
||||
@classmethod
|
||||
def default_account_expense(cls, **pattern):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('account.configuration')
|
||||
config = Configuration(1)
|
||||
account = config.get_multivalue(
|
||||
'default_product_account_expense', **pattern)
|
||||
return account.id if account else None
|
||||
|
||||
@classmethod
|
||||
def default_account_revenue(cls, **pattern):
|
||||
pool = Pool()
|
||||
Configuration = pool.get('account.configuration')
|
||||
config = Configuration(1)
|
||||
account = config.get_multivalue(
|
||||
'default_product_account_revenue', **pattern)
|
||||
return account.id if account else None
|
||||
|
||||
@classmethod
|
||||
def default_accounts_category(cls):
|
||||
pool = Pool()
|
||||
Config = pool.get('product.configuration')
|
||||
return Config(1).default_accounts_category
|
||||
|
||||
@classmethod
|
||||
def default_taxes_category(cls):
|
||||
pool = Pool()
|
||||
Config = pool.get('product.configuration')
|
||||
return Config(1).default_taxes_category
|
||||
|
||||
def get_account(self, name, **pattern):
|
||||
if self.accounts_category:
|
||||
if self.account_category:
|
||||
return self.account_category.get_account(name, **pattern)
|
||||
else:
|
||||
return self.get_multivalue(name[:-5], **pattern)
|
||||
|
||||
def get_taxes(self, name):
|
||||
if self.taxes_category:
|
||||
return [x.id for x in getattr(self.account_category, name)]
|
||||
else:
|
||||
return [x.id for x in getattr(self, name[:-5])]
|
||||
|
||||
@fields.depends('account_category', 'account_expense')
|
||||
def on_change_account_expense(self):
|
||||
if not self.account_category:
|
||||
if self.account_expense:
|
||||
self.supplier_taxes = self.account_expense.taxes
|
||||
else:
|
||||
self.supplier_taxes = []
|
||||
|
||||
@fields.depends('account_category', 'account_revenue')
|
||||
def on_change_account_revenue(self):
|
||||
if not self.account_category:
|
||||
if self.account_revenue:
|
||||
self.customer_taxes = self.account_revenue.taxes
|
||||
else:
|
||||
self.customer_taxes = []
|
||||
if self.account_category:
|
||||
return getattr(self.account_category, name)
|
||||
|
||||
@property
|
||||
@account_used('account_expense')
|
||||
@account_used('account_expense', 'account_category')
|
||||
def account_expense_used(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
@account_used('account_revenue')
|
||||
@account_used('account_revenue', 'account_category')
|
||||
def account_revenue_used(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def customer_taxes_used(self):
|
||||
taxes = self.get_taxes('customer_taxes_used')
|
||||
if taxes is None:
|
||||
account = self.account_revenue_used
|
||||
if account:
|
||||
taxes = account.taxes
|
||||
if taxes is None:
|
||||
self.raise_user_error('missing_taxes', {
|
||||
'name': self.rec_name,
|
||||
})
|
||||
return taxes
|
||||
|
||||
class TemplateAccount(ModelSQL, CompanyValueMixin):
|
||||
"Product Template Account"
|
||||
__name__ = 'product.template.account'
|
||||
template = fields.Many2One(
|
||||
'product.template', "Template", ondelete='CASCADE', select=True)
|
||||
account_expense = fields.Many2One(
|
||||
'account.account', "Account Expense",
|
||||
domain=[
|
||||
('kind', '=', 'expense'),
|
||||
('company', '=', Eval('company', -1)),
|
||||
],
|
||||
depends=['company'])
|
||||
account_revenue = fields.Many2One(
|
||||
'account.account', "Account Revenue",
|
||||
domain=[
|
||||
('kind', '=', 'revenue'),
|
||||
('company', '=', Eval('company', -1)),
|
||||
],
|
||||
depends=['company'])
|
||||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
TableHandler = backend.get('TableHandler')
|
||||
exist = TableHandler.table_exist(cls._table)
|
||||
|
||||
super(TemplateAccount, cls).__register__(module_name)
|
||||
|
||||
if not exist:
|
||||
cls._migrate_property([], [], [])
|
||||
|
||||
@classmethod
|
||||
def _migrate_property(cls, field_names, value_names, fields):
|
||||
field_names.extend(['account_expense', 'account_revenue'])
|
||||
value_names.extend(['account_expense', 'account_revenue'])
|
||||
fields.append('company')
|
||||
migrate_property(
|
||||
'product.template', field_names, cls, value_names,
|
||||
parent='template', fields=fields)
|
||||
|
||||
|
||||
class TemplateCustomerTax(ModelSQL):
|
||||
'Product Template - Customer Tax'
|
||||
__name__ = 'product.template-customer-account.tax'
|
||||
_table = 'product_customer_taxes_rel'
|
||||
product = fields.Many2One('product.template', 'Product Template',
|
||||
ondelete='CASCADE', select=True, required=True)
|
||||
tax = fields.Many2One('account.tax', 'Tax', ondelete='RESTRICT',
|
||||
required=True)
|
||||
|
||||
|
||||
class TemplateSupplierTax(ModelSQL):
|
||||
'Product Template - Supplier Tax'
|
||||
__name__ = 'product.template-supplier-account.tax'
|
||||
_table = 'product_supplier_taxes_rel'
|
||||
product = fields.Many2One('product.template', 'Product Template',
|
||||
ondelete='CASCADE', select=True, required=True)
|
||||
tax = fields.Many2One('account.tax', 'Tax', ondelete='RESTRICT',
|
||||
required=True)
|
||||
@property
|
||||
def supplier_taxes_used(self):
|
||||
taxes = self.get_taxes('supplier_taxes_used')
|
||||
if taxes is None:
|
||||
account = self.account_expense_used
|
||||
if account:
|
||||
taxes = account.taxes
|
||||
if taxes is None:
|
||||
self.raise_user_error('missing_taxes', {
|
||||
'name': self.rec_name,
|
||||
})
|
||||
return taxes
|
||||
|
||||
|
||||
class Product:
|
||||
@@ -549,10 +373,8 @@ class Product:
|
||||
__name__ = 'product.product'
|
||||
account_expense_used = template_property('account_expense_used')
|
||||
account_revenue_used = template_property('account_revenue_used')
|
||||
customer_taxes_used = fields.Function(fields.One2Many('account.tax', None,
|
||||
'Customer Taxes Used'), 'get_template')
|
||||
supplier_taxes_used = fields.Function(fields.One2Many('account.tax', None,
|
||||
'Supplier Taxes Used'), 'get_template')
|
||||
customer_taxes_used = template_property('customer_taxes_used')
|
||||
supplier_taxes_used = template_property('supplier_taxes_used')
|
||||
|
||||
|
||||
class TemplateAccountCategory(ModelSQL):
|
||||
|
||||
+25
-24
@@ -10,6 +10,31 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="name">category_form</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rule_group_category_default">
|
||||
<field name="model" search="[('model', '=', 'product.category')]"/>
|
||||
<field name="default_p" eval="True"/>
|
||||
<field name="global_p" eval="False"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="rule_category_default_non_accounting">
|
||||
<field name="domain" eval="[('accounting', '=', False)]" pyson="1"/>
|
||||
<field name="rule_group" ref="rule_group_category_default"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rule_group_category_accounting">
|
||||
<field name="model" search="[('model', '=', 'product.category')]"/>
|
||||
<field name="global_p" eval="False"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.rule.group-res.group" id="rule_group_category_accounting-account_admin">
|
||||
<field name="rule_group" ref="rule_group_category_accounting"/>
|
||||
<field name="group" ref="account.group_account_admin"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="rule_category_accounting_accounting">
|
||||
<field name="domain" eval="[('accounting', '=', True)]" pyson="1"/>
|
||||
<field name="rule_group" ref="rule_group_category_accounting"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="template_view_form">
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit" ref="product.template_view_form"/>
|
||||
@@ -46,29 +71,5 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="rule_group" ref="rule_group_category_supplier_taxes"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rule_group_template_customer_taxes">
|
||||
<field name="model"
|
||||
search="[('model', '=', 'product.template-customer-account.tax')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="rule_template_customer_taxes">
|
||||
<field name="domain"
|
||||
eval="[('tax.company', '=', Eval('user', {}).get('company', None))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rule_group_template_customer_taxes"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule.group" id="rule_group_template_supplier_taxes">
|
||||
<field name="model"
|
||||
search="[('model', '=', 'product.template-supplier-account.tax')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="rule_template_supplier_taxes">
|
||||
<field name="domain"
|
||||
eval="[('tax.company', '=', Eval('user', {}).get('company', None))]"
|
||||
pyson="1"/>
|
||||
<field name="rule_group" ref="rule_group_template_supplier_taxes"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
|
||||
@@ -45,34 +45,16 @@ class AccountProductTestCase(ModuleTestCase):
|
||||
)
|
||||
template.save()
|
||||
|
||||
self.assertIsNone(template.account_expense)
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
template.account_expense_used
|
||||
|
||||
# with account
|
||||
template = ProductTemplate(
|
||||
name='test account used',
|
||||
list_price=Decimal(10),
|
||||
default_uom=unit.id,
|
||||
account_expense=account_expense.id,
|
||||
products=[],
|
||||
)
|
||||
template.save()
|
||||
|
||||
self.assertEqual(template.account_expense, account_expense)
|
||||
self.assertEqual(template.account_expense_used, account_expense)
|
||||
|
||||
# with account on category
|
||||
category = ProductCategory(name='test account used',
|
||||
account_expense=account_expense, accounting=True)
|
||||
category.save()
|
||||
template.account_expense = None
|
||||
template.accounts_category = True
|
||||
template.account_category = category
|
||||
template.save()
|
||||
|
||||
self.assertIsNone(template.account_expense)
|
||||
self.assertEqual(template.account_expense_used, account_expense)
|
||||
|
||||
# with account on grant category
|
||||
@@ -84,30 +66,25 @@ class AccountProductTestCase(ModuleTestCase):
|
||||
category.parent = parent_category
|
||||
category.save()
|
||||
|
||||
self.assertIsNone(category.account_expense)
|
||||
self.assertEqual(template.account_expense_used, account_expense)
|
||||
self.assertEqual(category.account_expense_used, account_expense)
|
||||
|
||||
# raise only at direct usage
|
||||
templates = ProductTemplate.create([{
|
||||
categories = ProductCategory.create([{
|
||||
'name': 'test with account',
|
||||
'list_price': Decimal(10),
|
||||
'default_uom': unit.id,
|
||||
'accounting': True,
|
||||
'account_expense': account_expense.id,
|
||||
'products': [],
|
||||
}, {
|
||||
'name': 'test without account',
|
||||
'list_price': Decimal(10),
|
||||
'default_uom': unit.id,
|
||||
'accounting': True,
|
||||
'account_expense': None,
|
||||
'products': [],
|
||||
}])
|
||||
|
||||
self.assertEqual(templates[0].account_expense_used.id,
|
||||
self.assertEqual(categories[0].account_expense_used.id,
|
||||
account_expense.id)
|
||||
|
||||
with self.assertRaises(UserError):
|
||||
templates[1].account_expense_used
|
||||
categories[1].account_expense_used
|
||||
|
||||
|
||||
def suite():
|
||||
|
||||
@@ -4,11 +4,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/field[@name='default_account_payable']"
|
||||
position="after">
|
||||
<separator id="product" string="Product" colspan="4"/>
|
||||
<label name="default_product_account_revenue"/>
|
||||
<field name="default_product_account_revenue"/>
|
||||
<label name="default_product_account_expense"/>
|
||||
<field name="default_product_account_expense"/>
|
||||
<separator id="category" string="Category" colspan="4"/>
|
||||
<label name="default_category_account_revenue"/>
|
||||
<field name="default_category_account_revenue"/>
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/field[@name='account_payable']" position="after">
|
||||
<separator id="product" string="Product" colspan="4"/>
|
||||
<label name="product_account_revenue"/>
|
||||
<field name="product_account_revenue"/>
|
||||
<label name="product_account_expense"/>
|
||||
<field name="product_account_expense"/>
|
||||
<separator id="category" string="Category" colspan="4"/>
|
||||
<label name="category_account_revenue"/>
|
||||
<field name="category_account_revenue"/>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form" position="inside">
|
||||
<newline/>
|
||||
<label name="default_accounts_category"/>
|
||||
<field name="default_accounts_category"/>
|
||||
<label name="default_taxes_category"/>
|
||||
<field name="default_taxes_category"/>
|
||||
</xpath>
|
||||
</data>
|
||||
@@ -8,20 +8,6 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<page string="Accounting" col="4" id="accounting">
|
||||
<label name="account_category"/>
|
||||
<field name="account_category"/>
|
||||
<separator string="Accounts" id="accounts" colspan="4"/>
|
||||
<label name="accounts_category"/>
|
||||
<field name="accounts_category"/>
|
||||
<newline/>
|
||||
<label name="account_revenue"/>
|
||||
<field name="account_revenue"/>
|
||||
<label name="account_expense"/>
|
||||
<field name="account_expense"/>
|
||||
<separator string="Taxes" id="taxes" colspan="4"/>
|
||||
<label name="taxes_category"/>
|
||||
<field name="taxes_category"/>
|
||||
<newline/>
|
||||
<field name="customer_taxes" colspan="2"/>
|
||||
<field name="supplier_taxes" colspan="2"/>
|
||||
</page>
|
||||
</xpath>
|
||||
</data>
|
||||
|
||||
Reference in New Issue
Block a user