diff --git a/__init__.py b/__init__.py
index 4e351ec..55d77fd 100644
--- a/__init__.py
+++ b/__init__.py
@@ -4,11 +4,16 @@ from trytond.pool import Pool
from . import account
from . import sale
from . import purchase
+from . import office
+from . import party
def register():
Pool.register(
account.Rule,
+ account.AnalyticAccount,
+ office.Office,
+ office.OfficeAnalytic,
module='analytic_office', type_='model')
Pool.register(
sale.Sale,
@@ -21,3 +26,16 @@ def register():
module='analytic_office', type_='model',
depends=['purchase_office', 'analytic_purchase', 'analytic_apply_rule']
)
+ Pool.register(
+ party.Party,
+ module='analytic_office', type_='model',
+ depends=['analytic_party'])
+ Pool.register(
+ office.SaleLine,
+ module='analytic_office', type_='model',
+ depends=['sale_office', 'analytic_sale', 'analytic_party'])
+ Pool.register(
+ office.PurchaseLine,
+ module='analytic_office', type_='model',
+ depends=['purchase_office', 'analytic_purchase', 'analytic_party']
+ )
diff --git a/account.py b/account.py
index c486bc5..d8d6534 100644
--- a/account.py
+++ b/account.py
@@ -16,3 +16,14 @@ class Rule(metaclass=PoolMeta):
('company', '=', Eval('company'))
],
depends=['company'])
+
+
+class AnalyticAccount(metaclass=PoolMeta):
+
+ __name__ = 'analytic_account.account'
+
+ offices = fields.Many2Many(
+ 'company.office-analytic_account.account', 'account', 'office',
+ 'Offices',
+ domain=[
+ ('company', '=', Eval('context', {}).get('company', -1))])
diff --git a/office.py b/office.py
new file mode 100644
index 0000000..2ba8618
--- /dev/null
+++ b/office.py
@@ -0,0 +1,59 @@
+# The COPYRIGHT file at the top level of this repository contains the full
+# copyright notices and license terms.
+from trytond.pool import PoolMeta
+from trytond.model import fields, ModelSQL
+from trytond.pyson import If, Eval
+from trytond.transaction import Transaction
+
+
+class Office(metaclass=PoolMeta):
+ __name__ = 'company.office'
+
+ analytic_accounts = fields.Many2Many(
+ 'company.office-analytic_account.account', 'office', 'account',
+ 'Analytic Accounts',
+ domain=[
+ ('type', '=', 'view'),
+ If(Eval('company', None),
+ ('company', '=', Eval('company')),
+ ('company', '=', Eval('context', {}).get('company', -1))),
+ ],
+ depends=['company'])
+
+
+class OfficeAnalytic(ModelSQL):
+ """Office - Analytic Account"""
+ __name__ = 'company.office-analytic_account.account'
+
+ office = fields.Many2One('company.office', 'Office', select=True,
+ ondelete='CASCADE')
+ account = fields.Many2One('analytic_account.account', 'Account',
+ select=True, ondelete='CASCADE')
+
+
+class SaleLine(metaclass=PoolMeta):
+ __name__ = 'sale.line'
+
+ @fields.depends('sale', '_parent_sale.office')
+ def get_party_analytic_account_domain(self, root):
+ domain = super().get_party_analytic_account_domain(root)
+ if self.sale and self.sale.office:
+ domain.append(('parent.offices', '=', self.sale.office.id))
+ else:
+ domain.append(('parent.offices', '=',
+ Transaction().context.get('office', -1)))
+ return domain
+
+
+class PurchaseLine(metaclass=PoolMeta):
+ __name__ = 'purchase.line'
+
+ @fields.depends('purchase', '_parent_purchase.office')
+ def get_party_analytic_account_domain(self, root):
+ domain = super().get_party_analytic_account_domain(root)
+ if self.purchase and self.purchase.office:
+ domain.append(('parent.offices', '=', self.purchase.office.id))
+ else:
+ domain.append(('parent.offices', '=',
+ Transaction().context.get('office', -1)))
+ return domain
diff --git a/office.xml b/office.xml
new file mode 100644
index 0000000..07538e6
--- /dev/null
+++ b/office.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ company.office
+
+ office_form
+
+
\ No newline at end of file
diff --git a/party.py b/party.py
new file mode 100644
index 0000000..0372650
--- /dev/null
+++ b/party.py
@@ -0,0 +1,19 @@
+# The COPYRIGHT file at the top level of this repository contains the full
+# copyright notices and license terms.
+from trytond.pool import PoolMeta
+from trytond.pyson import If, Eval
+
+
+class Party(metaclass=PoolMeta):
+ __name__ = 'party.party'
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.analytic_accounts.domain.extend([
+ If(Eval('offices'),
+ ('parent.offices', 'in', Eval('offices')), ()),
+ (('parent.offices', 'in',
+ Eval('context', {}).get('offices', [])))])
+ if 'offices' not in cls.analytic_accounts.depends:
+ cls.analytic_accounts.depends.append('offices')
diff --git a/party.xml b/party.xml
new file mode 100644
index 0000000..0d16d8d
--- /dev/null
+++ b/party.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 6ee9038..2a1855a 100644
--- a/setup.py
+++ b/setup.py
@@ -67,6 +67,20 @@ dependency_links = {
'branch': branch,
'series': series
},
+ 'purchase_office':
+ 'git+https://gitlab.com/datalifeit/'
+ 'trytond-purchase_office@%(branch)s'
+ '#egg=datalife_purchase_office-%(series)s' % {
+ 'branch': branch,
+ 'series': series
+ },
+ 'analytic_party':
+ 'git+https://gitlab.com/datalifeit/'
+ 'trytond-analytic_party@%(branch)s'
+ '#egg=datalife_analytic_party-%(series)s' % {
+ 'branch': branch,
+ 'series': series
+ },
}
requires = []
@@ -82,8 +96,11 @@ requires.append(get_require_version('trytond'))
tests_require = [
get_require_version('proteus'),
get_require_version('trytond_analytic_sale'),
+ get_require_version('trytond_analytic_purchase'),
get_require_version('datalife_analytic_apply_rule'),
- get_require_version('datalife_sale_office')
+ get_require_version('datalife_sale_office'),
+ get_require_version('datalife_purchase_office'),
+ get_require_version('datalife_analytic_party')
]
dependency_links = list(dependency_links.values())
diff --git a/tests/scenario_analytic_office.rst b/tests/scenario_analytic_office.rst
index 5cd2f81..a4f1e88 100644
--- a/tests/scenario_analytic_office.rst
+++ b/tests/scenario_analytic_office.rst
@@ -1,161 +1,159 @@
-================================
-Analytic Company Office Scenario
-================================
+========================
+Analytic Office Scenario
+========================
Imports::
- >>> import datetime
- >>> from dateutil.relativedelta import relativedelta
- >>> from decimal import Decimal
- >>> from operator import attrgetter
- >>> from proteus import Model, Wizard, Report
- >>> from trytond.tests.tools import activate_modules, set_user
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
- >>> from trytond.modules.account.tests.tools import create_fiscalyear, \
- ... create_chart, get_accounts
- >>> from trytond.modules.account_invoice.tests.tools import \
- ... set_fiscalyear_invoice_sequences, create_payment_term
- >>> today = datetime.date.today()
+
Install analytic_office::
- >>> config = activate_modules(['analytic_sale', 'sale_office', 'analytic_office', 'analytic_apply_rule'])
+ >>> config = activate_modules(['analytic_office', 'analytic_party'])
+
Create company::
>>> _ = create_company()
>>> company = get_company()
-Create sale user::
+
+Get user::
>>> User = Model.get('res.user')
- >>> Group = Model.get('res.group')
- >>> sale_user = User()
- >>> sale_user.name = 'Sale'
- >>> sale_user.login = 'sale'
- >>> sale_user.main_company = company
- >>> sale_group, = Group.find([('name', '=', 'Sales')])
- >>> sale_user.groups.append(sale_group)
- >>> sale_user.save()
+ >>> admin = User(config.user)
-Create fiscal year::
- >>> fiscalyear = set_fiscalyear_invoice_sequences(
- ... create_fiscalyear(company))
- >>> fiscalyear.click('create_period')
+Create party::
-Create chart of accounts::
+ >>> Party = Model.get('party.party')
+ >>> party = Party(name='Party')
+ >>> party.save()
- >>> _ = create_chart(company)
- >>> accounts = get_accounts(company)
- >>> revenue = accounts['revenue']
- >>> expense = accounts['expense']
-
-Create branch office::
-
- >>> Office = Model.get('company.office')
- >>> office1 = Office(name='Office 1')
- >>> office1.save()
- >>> office2 = Office(name='Office 2')
- >>> office2.save()
- >>> User = Model.get('res.user')
- >>> Group = Model.get('res.group')
- >>> user = User(config.user)
- >>> user.offices.extend([office1, office2])
- >>> office1 = Office(office1.id)
- >>> user.office = office1
- >>> user.save()
- >>> set_user(user)
- >>> config._context = User.get_preferences(True, {})
Create analytic accounts::
>>> AnalyticAccount = Model.get('analytic_account.account')
- >>> root = AnalyticAccount(type='root', name='Root')
+ >>> root = AnalyticAccount()
+ >>> root.name = 'Root'
+ >>> root.code = '1'
+ >>> root.type = 'root'
>>> root.save()
- >>> analytic_account = AnalyticAccount(root=root, parent=root,
- ... name='Analytic')
+ >>> view_account = AnalyticAccount()
+ >>> view_account.name = 'View 1'
+ >>> view_account.code = '11'
+ >>> view_account.type = 'view'
+ >>> view_account.root = root
+ >>> view_account.parent = root
+ >>> view_account.save()
+ >>> analytic_account = AnalyticAccount()
+ >>> analytic_account.name = 'Analytic 1'
+ >>> analytic_account.code = '111'
+ >>> analytic_account.root = root
+ >>> analytic_account.parent = view_account
>>> analytic_account.save()
- >>> mandatory_root = AnalyticAccount(type='root', name='Root',
- ... mandatory=True)
- >>> mandatory_root.save()
- >>> mandatory_analytic_account1 = AnalyticAccount(root=mandatory_root,
- ... parent=mandatory_root, name='Mandatory Analytic 1')
- >>> mandatory_analytic_account1.save()
- >>> mandatory_analytic_account2 = AnalyticAccount(root=mandatory_root,
- ... parent=mandatory_root, name='Mandatory Analytic 2')
- >>> mandatory_analytic_account2.save()
- >>> mandatory_analytic_account3 = AnalyticAccount(root=mandatory_root,
- ... parent=mandatory_root, name='Mandatory Analytic 3')
- >>> mandatory_analytic_account3.save()
+ >>> view_account2 = AnalyticAccount()
+ >>> view_account2.name = 'View 2'
+ >>> view_account2.code = '12'
+ >>> view_account2.type = 'view'
+ >>> view_account2.root = root
+ >>> view_account2.parent = root
+ >>> view_account2.save()
+ >>> analytic_account2 = AnalyticAccount()
+ >>> analytic_account2.name = 'Analytic 2'
+ >>> analytic_account2.code = '121'
+ >>> analytic_account2.root = root
+ >>> analytic_account2.parent = view_account2
+ >>> analytic_account2.save()
-Create parties::
- >>> Party = Model.get('party.party')
- >>> customer = Party(name='Customer')
- >>> customer.save()
- >>> customer2 = Party(name='Customer 2')
- >>> customer2.save()
+Create offices::
-Create analytic rules::
+ >>> Office = Model.get('company.office')
+ >>> office = Office()
+ >>> office.name = 'Office 1'
+ >>> office.company = company
+ >>> office.save()
+ >>> office2 = Office()
+ >>> office2.name = 'Office 2'
+ >>> office2.company = company
+ >>> office2.save()
- >>> Rule = Model.get('analytic_account.rule')
- >>> rule = Rule()
- >>> _, mandatory_entry = rule.analytic_accounts
- >>> mandatory_entry.root = mandatory_root
- >>> mandatory_entry.account = mandatory_analytic_account3
- >>> rule.save()
- >>> rule = Rule(sale=True, party=customer, office=office2)
- >>> _, mandatory_entry = rule.analytic_accounts
- >>> mandatory_entry.root = mandatory_root
- >>> mandatory_entry.account = mandatory_analytic_account1
- >>> rule.save()
- >>> rule = Rule(sale=True, office=office1)
- >>> _, mandatory_entry = rule.analytic_accounts
- >>> mandatory_entry.root = mandatory_root
- >>> mandatory_entry.account = mandatory_analytic_account2
- >>> rule.save()
-Create account category::
+Add office to admin user and reload context::
- >>> ProductCategory = Model.get('product.category')
- >>> account_category = ProductCategory(name="Account Category")
- >>> account_category.accounting = True
- >>> account_category.account_expense = expense
- >>> account_category.account_revenue = revenue
- >>> account_category.save()
+ >>> admin.offices.append(office)
+ >>> office = Office(office.id)
+ >>> admin.offices.append(office2)
+ >>> office2 = Office(office2.id)
+ >>> admin.office = office
+ >>> admin.save()
+ >>> config._context = User.get_preferences(True, config.context)
-Create product::
- >>> ProductUom = Model.get('product.uom')
- >>> unit, = ProductUom.find([('name', '=', 'Unit')])
- >>> ProductTemplate = Model.get('product.template')
- >>> template = ProductTemplate()
- >>> template.name = 'product'
- >>> template.default_uom = unit
- >>> template.type = 'goods'
- >>> template.salable = True
- >>> template.list_price = Decimal('10')
- >>> template.account_category = account_category
- >>> template.save()
- >>> product, = template.products
+Add analytic account to party when account office isn't set::
-Create payment term::
+ >>> party.analytic_accounts.append(analytic_account)
+ >>> analytic_account = AnalyticAccount(analytic_account.id)
+ >>> party.save()
+ Traceback (most recent call last):
+ ...
+ trytond.exceptions.UserError: The value of the field "Analytic Accounts" on "Party" is not valid according to its domain. -
+ >>> party.reload()
- >>> payment_term = create_payment_term()
- >>> payment_term.save()
-Sale with analytic accounts::
+Add analytic_account to offices::
- >>> Sale = Model.get('sale.sale')
- >>> SaleLine = Model.get('sale.line')
- >>> sale = Sale()
- >>> sale.party = customer
- >>> sale.payment_term = payment_term
- >>> sale.office == office1
- True
- >>> sale_line = sale.lines.new()
- >>> mandatory_entry, = [a for a in sale_line.analytic_accounts if a.required]
- >>> mandatory_entry.account == mandatory_analytic_account2
- True
\ No newline at end of file
+ >>> office.analytic_accounts.append(analytic_account)
+ >>> analytic_account = AnalyticAccount(analytic_account.id)
+ >>> office.save()
+ Traceback (most recent call last):
+ ...
+ trytond.exceptions.UserError: The value of the field "Analytic Accounts" on "Company branch office" is not valid according to its domain. -
+ >>> office.reload()
+ >>> office.analytic_accounts.append(view_account)
+ >>> view_account = AnalyticAccount(view_account.id)
+ >>> office.save()
+ >>> office2.analytic_accounts.append(view_account2)
+ >>> view_account2 = AnalyticAccount(view_account2.id)
+ >>> office2.save()
+
+
+Add analytic account Again to party::
+
+ >>> party.analytic_accounts.append(analytic_account)
+ >>> analytic_account = AnalyticAccount(analytic_account.id)
+ >>> party.save()
+
+
+Add wrong office to party::
+
+ >>> party.offices.append(office2)
+ >>> office2 = Office(office2.id)
+ >>> party.save()
+ Traceback (most recent call last):
+ ...
+ trytond.exceptions.UserError: The value of the field "Analytic Accounts" on "Party" is not valid according to its domain. -
+
+ >>> party.reload()
+
+
+Add office to party::
+
+ >>> party.offices.append(office)
+ >>> office = Office(office.id)
+ >>> party.save()
+
+
+Add wrong office2 analytic account to party::
+
+ >>> party.analytic_accounts.append(analytic_account2)
+ >>> analytic_account2 = AnalyticAccount(analytic_account2.id)
+ >>> party.save()
+ Traceback (most recent call last):
+ ...
+ trytond.exceptions.UserError: The value of the field "Analytic Accounts" on "Party" is not valid according to its domain. -
+ >>> party.reload()
diff --git a/tests/scenario_analytic_office_rule.rst b/tests/scenario_analytic_office_rule.rst
new file mode 100644
index 0000000..bb07d84
--- /dev/null
+++ b/tests/scenario_analytic_office_rule.rst
@@ -0,0 +1,161 @@
+================================
+Analytic Office Rule Scenario
+================================
+
+Imports::
+
+ >>> import datetime
+ >>> from dateutil.relativedelta import relativedelta
+ >>> from decimal import Decimal
+ >>> from operator import attrgetter
+ >>> from proteus import Model, Wizard, Report
+ >>> from trytond.tests.tools import activate_modules, set_user
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+ >>> from trytond.modules.account.tests.tools import create_fiscalyear, \
+ ... create_chart, get_accounts
+ >>> from trytond.modules.account_invoice.tests.tools import \
+ ... set_fiscalyear_invoice_sequences, create_payment_term
+ >>> today = datetime.date.today()
+
+Install analytic_office::
+
+ >>> config = activate_modules(['analytic_sale', 'sale_office', 'analytic_office', 'analytic_apply_rule'])
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+Create sale user::
+
+ >>> User = Model.get('res.user')
+ >>> Group = Model.get('res.group')
+ >>> sale_user = User()
+ >>> sale_user.name = 'Sale'
+ >>> sale_user.login = 'sale'
+ >>> sale_user.main_company = company
+ >>> sale_group, = Group.find([('name', '=', 'Sales')])
+ >>> sale_user.groups.append(sale_group)
+ >>> sale_user.save()
+
+Create fiscal year::
+
+ >>> fiscalyear = set_fiscalyear_invoice_sequences(
+ ... create_fiscalyear(company))
+ >>> fiscalyear.click('create_period')
+
+Create chart of accounts::
+
+ >>> _ = create_chart(company)
+ >>> accounts = get_accounts(company)
+ >>> revenue = accounts['revenue']
+ >>> expense = accounts['expense']
+
+Create branch office::
+
+ >>> Office = Model.get('company.office')
+ >>> office1 = Office(name='Office 1')
+ >>> office1.save()
+ >>> office2 = Office(name='Office 2')
+ >>> office2.save()
+ >>> User = Model.get('res.user')
+ >>> Group = Model.get('res.group')
+ >>> user = User(config.user)
+ >>> user.offices.extend([office1, office2])
+ >>> office1 = Office(office1.id)
+ >>> user.office = office1
+ >>> user.save()
+ >>> set_user(user)
+ >>> config._context = User.get_preferences(True, {})
+
+Create analytic accounts::
+
+ >>> AnalyticAccount = Model.get('analytic_account.account')
+ >>> root = AnalyticAccount(type='root', name='Root')
+ >>> root.save()
+ >>> analytic_account = AnalyticAccount(root=root, parent=root,
+ ... name='Analytic')
+ >>> analytic_account.save()
+ >>> mandatory_root = AnalyticAccount(type='root', name='Root',
+ ... mandatory=True)
+ >>> mandatory_root.save()
+ >>> mandatory_analytic_account1 = AnalyticAccount(root=mandatory_root,
+ ... parent=mandatory_root, name='Mandatory Analytic 1')
+ >>> mandatory_analytic_account1.save()
+ >>> mandatory_analytic_account2 = AnalyticAccount(root=mandatory_root,
+ ... parent=mandatory_root, name='Mandatory Analytic 2')
+ >>> mandatory_analytic_account2.save()
+ >>> mandatory_analytic_account3 = AnalyticAccount(root=mandatory_root,
+ ... parent=mandatory_root, name='Mandatory Analytic 3')
+ >>> mandatory_analytic_account3.save()
+
+Create parties::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+ >>> customer2 = Party(name='Customer 2')
+ >>> customer2.save()
+
+Create analytic rules::
+
+ >>> Rule = Model.get('analytic_account.rule')
+ >>> rule = Rule()
+ >>> _, mandatory_entry = rule.analytic_accounts
+ >>> mandatory_entry.root = mandatory_root
+ >>> mandatory_entry.account = mandatory_analytic_account3
+ >>> rule.save()
+ >>> rule = Rule(sale=True, party=customer, office=office2)
+ >>> _, mandatory_entry = rule.analytic_accounts
+ >>> mandatory_entry.root = mandatory_root
+ >>> mandatory_entry.account = mandatory_analytic_account1
+ >>> rule.save()
+ >>> rule = Rule(sale=True, office=office1)
+ >>> _, mandatory_entry = rule.analytic_accounts
+ >>> mandatory_entry.root = mandatory_root
+ >>> mandatory_entry.account = mandatory_analytic_account2
+ >>> rule.save()
+
+Create account category::
+
+ >>> ProductCategory = Model.get('product.category')
+ >>> account_category = ProductCategory(name="Account Category")
+ >>> account_category.accounting = True
+ >>> account_category.account_expense = expense
+ >>> account_category.account_revenue = revenue
+ >>> account_category.save()
+
+Create product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'goods'
+ >>> template.salable = True
+ >>> template.list_price = Decimal('10')
+ >>> template.account_category = account_category
+ >>> template.save()
+ >>> product, = template.products
+
+Create payment term::
+
+ >>> payment_term = create_payment_term()
+ >>> payment_term.save()
+
+Sale with analytic accounts::
+
+ >>> Sale = Model.get('sale.sale')
+ >>> SaleLine = Model.get('sale.line')
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.payment_term = payment_term
+ >>> sale.office == office1
+ True
+ >>> sale_line = sale.lines.new()
+ >>> mandatory_entry, = [a for a in sale_line.analytic_accounts if a.required]
+ >>> mandatory_entry.account == mandatory_analytic_account2
+ True
\ No newline at end of file
diff --git a/tests/scenario_analytic_purchase.rst b/tests/scenario_analytic_purchase.rst
new file mode 100644
index 0000000..187daad
--- /dev/null
+++ b/tests/scenario_analytic_purchase.rst
@@ -0,0 +1,159 @@
+==========================
+Analytic Purchase Scenario
+==========================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+
+Install analytic_party::
+
+ >>> config = activate_modules(['analytic_office', 'analytic_party',
+ ... 'analytic_purchase', 'purchase_office'])
+
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+
+Get user::
+
+ >>> User = Model.get('res.user')
+ >>> admin = User(config.user)
+
+
+Create Supplier::
+
+ >>> Party = Model.get('party.party')
+ >>> supplier = Party(name='Supplier')
+ >>> supplier.save()
+
+
+Create analytic accounts::
+
+ >>> AnalyticAccount = Model.get('analytic_account.account')
+ >>> root = AnalyticAccount()
+ >>> root.name = 'Root'
+ >>> root.code = '1'
+ >>> root.type = 'root'
+ >>> root.save()
+ >>> view_account = AnalyticAccount()
+ >>> view_account.name = 'View'
+ >>> view_account.code = '11'
+ >>> view_account.type = 'view'
+ >>> view_account.root = root
+ >>> view_account.parent = root
+ >>> view_account.save()
+ >>> view_account2 = AnalyticAccount()
+ >>> view_account2.name = 'View 2'
+ >>> view_account2.code = '12'
+ >>> view_account2.type = 'view'
+ >>> view_account2.root = root
+ >>> view_account2.parent = root
+ >>> view_account2.save()
+ >>> analytic_account = AnalyticAccount()
+ >>> analytic_account.name = 'Analytic 111'
+ >>> analytic_account.code = '111'
+ >>> analytic_account.root = root
+ >>> analytic_account.parent = view_account
+ >>> analytic_account.save()
+ >>> analytic_account2 = AnalyticAccount()
+ >>> analytic_account2.name = 'Analytic 121'
+ >>> analytic_account2.code = '121'
+ >>> analytic_account2.root = root
+ >>> analytic_account2.parent = view_account2
+ >>> analytic_account2.save()
+
+
+Create office::
+
+ >>> Office = Model.get('company.office')
+ >>> office = Office()
+ >>> office.name = 'Office 1'
+ >>> office.company = company
+ >>> office.save()
+ >>> office2 = Office()
+ >>> office2.name = 'Office 2'
+ >>> office2.company = company
+ >>> office2.save()
+
+
+Setup offices to users and reload context::
+
+ >>> admin.offices.append(office)
+ >>> office = Office(office.id)
+ >>> admin.offices.append(office2)
+ >>> office2 = Office(office2.id)
+ >>> admin.office = office
+ >>> admin.save()
+ >>> config._context = User.get_preferences(True, config.context)
+
+
+Add analytic_accounts to offices::
+
+ >>> office.analytic_accounts.append(view_account)
+ >>> view_account = AnalyticAccount(view_account.id)
+ >>> office.save()
+ >>> office2.analytic_accounts.append(view_account2)
+ >>> view_account2 = AnalyticAccount(view_account2.id)
+ >>> office2.save()
+
+
+Add anaytic accounts to supplier::
+
+ >>> supplier.analytic_accounts.append(analytic_account)
+ >>> analytic_account = AnalyticAccount(analytic_account.id)
+ >>> supplier.analytic_accounts.append(analytic_account2)
+ >>> analytic_account2 = AnalyticAccount(analytic_account2.id)
+ >>> supplier.save()
+
+
+Create Product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'service'
+ >>> template.list_price = Decimal('40')
+ >>> template.purchasable = True
+ >>> template.save()
+ >>> product, = template.products
+
+
+Create Purchase::
+
+ >>> Purchase = Model.get('purchase.purchase')
+ >>> purchase = Purchase()
+ >>> purchase.party = supplier
+ >>> purchase.office = office
+ >>> pline = purchase.lines.new()
+ >>> pline.product = product
+ >>> pline.quantity = 2.0
+ >>> entry_acc, = pline.analytic_accounts
+ >>> entry_acc.account == analytic_account
+ True
+ >>> purchase.save()
+
+
+Create purchase with office2::
+
+ >>> purchase2 = Purchase()
+ >>> purchase2.party = supplier
+ >>> purchase2.office = office2
+ >>> pline = purchase2.lines.new()
+ >>> pline.product = product
+ >>> pline.quantity = 2.0
+ >>> entry_acc, = pline.analytic_accounts
+ >>> entry_acc.account == analytic_account2
+ True
+ >>> purchase2.save()
\ No newline at end of file
diff --git a/tests/scenario_analytic_sale.rst b/tests/scenario_analytic_sale.rst
new file mode 100644
index 0000000..137aab8
--- /dev/null
+++ b/tests/scenario_analytic_sale.rst
@@ -0,0 +1,159 @@
+======================
+Analytic Sale Scenario
+======================
+
+Imports::
+
+ >>> from decimal import Decimal
+ >>> from proteus import Model, Wizard
+ >>> from trytond.tests.tools import activate_modules
+ >>> from trytond.modules.company.tests.tools import create_company, \
+ ... get_company
+
+
+Install analytic_office::
+
+ >>> config = activate_modules(['analytic_office', 'analytic_party',
+ ... 'analytic_sale', 'sale_office'])
+
+
+Create company::
+
+ >>> _ = create_company()
+ >>> company = get_company()
+
+
+Get user::
+
+ >>> User = Model.get('res.user')
+ >>> admin = User(config.user)
+
+
+Create Customer::
+
+ >>> Party = Model.get('party.party')
+ >>> customer = Party(name='Customer')
+ >>> customer.save()
+
+
+Create analytic accounts::
+
+ >>> AnalyticAccount = Model.get('analytic_account.account')
+ >>> root = AnalyticAccount()
+ >>> root.name = 'Root'
+ >>> root.code = '1'
+ >>> root.type = 'root'
+ >>> root.save()
+ >>> view_account = AnalyticAccount()
+ >>> view_account.name = 'View'
+ >>> view_account.code = '11'
+ >>> view_account.type = 'view'
+ >>> view_account.root = root
+ >>> view_account.parent = root
+ >>> view_account.save()
+ >>> view_account2 = AnalyticAccount()
+ >>> view_account2.name = 'View 2'
+ >>> view_account2.code = '12'
+ >>> view_account2.type = 'view'
+ >>> view_account2.root = root
+ >>> view_account2.parent = root
+ >>> view_account2.save()
+ >>> analytic_account = AnalyticAccount()
+ >>> analytic_account.name = 'Analytic 111'
+ >>> analytic_account.code = '111'
+ >>> analytic_account.root = root
+ >>> analytic_account.parent = view_account
+ >>> analytic_account.save()
+ >>> analytic_account2 = AnalyticAccount()
+ >>> analytic_account2.name = 'Analytic 121'
+ >>> analytic_account2.code = '121'
+ >>> analytic_account2.root = root
+ >>> analytic_account2.parent = view_account2
+ >>> analytic_account2.save()
+
+
+Create office::
+
+ >>> Office = Model.get('company.office')
+ >>> office = Office()
+ >>> office.name = 'Office 1'
+ >>> office.company = company
+ >>> office.save()
+ >>> office2 = Office()
+ >>> office2.name = 'Office 2'
+ >>> office2.company = company
+ >>> office2.save()
+
+
+Setup offices to users and reload context::
+
+ >>> admin.offices.append(office)
+ >>> office = Office(office.id)
+ >>> admin.offices.append(office2)
+ >>> office2 = Office(office2.id)
+ >>> admin.office = office
+ >>> admin.save()
+ >>> config._context = User.get_preferences(True, config.context)
+
+
+Add analytic_accounts to offices::
+
+ >>> office.analytic_accounts.append(view_account)
+ >>> view_account = AnalyticAccount(view_account.id)
+ >>> office.save()
+ >>> office2.analytic_accounts.append(view_account2)
+ >>> view_account2 = AnalyticAccount(view_account2.id)
+ >>> office2.save()
+
+
+Add anaytic accounts to customer::
+
+ >>> customer.analytic_accounts.append(analytic_account)
+ >>> analytic_account = AnalyticAccount(analytic_account.id)
+ >>> customer.analytic_accounts.append(analytic_account2)
+ >>> analytic_account2 = AnalyticAccount(analytic_account2.id)
+ >>> customer.save()
+
+
+Create Product::
+
+ >>> ProductUom = Model.get('product.uom')
+ >>> unit, = ProductUom.find([('name', '=', 'Unit')])
+ >>> ProductTemplate = Model.get('product.template')
+ >>> template = ProductTemplate()
+ >>> template.name = 'product'
+ >>> template.default_uom = unit
+ >>> template.type = 'service'
+ >>> template.list_price = Decimal('40')
+ >>> template.salable = True
+ >>> template.save()
+ >>> product, = template.products
+
+
+Create Sale::
+
+ >>> Sale = Model.get('sale.sale')
+ >>> sale = Sale()
+ >>> sale.party = customer
+ >>> sale.office = office
+ >>> sline = sale.lines.new()
+ >>> sline.product = product
+ >>> sline.quantity = 2.0
+ >>> entry_acc, = sline.analytic_accounts
+ >>> entry_acc.account == analytic_account
+ True
+ >>> sale.save()
+
+
+Create sale with office2::
+
+ >>> sale2 = Sale()
+ >>> sale2.party = customer
+ >>> sale2.office = office2
+ >>> sline = sale2.lines.new()
+ >>> sline.product = product
+ >>> sline.quantity = 2.0
+ >>> entry_acc, = sline.analytic_accounts
+ >>> entry_acc.account == analytic_account2
+ True
+ >>> sale2.save()
\ No newline at end of file
diff --git a/tests/test_analytic_office.py b/tests/test_analytic_office.py
index 30b934d..12e04c9 100644
--- a/tests/test_analytic_office.py
+++ b/tests/test_analytic_office.py
@@ -24,4 +24,19 @@ def suite():
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+ suite.addTests(doctest.DocFileSuite(
+ 'scenario_analytic_office_rule.rst',
+ tearDown=doctest_teardown, encoding='utf-8',
+ checker=doctest_checker,
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+ suite.addTests(doctest.DocFileSuite(
+ 'scenario_analytic_sale.rst',
+ tearDown=doctest_teardown, encoding='utf-8',
+ checker=doctest_checker,
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+ suite.addTests(doctest.DocFileSuite(
+ 'scenario_analytic_purchase.rst',
+ tearDown=doctest_teardown, encoding='utf-8',
+ checker=doctest_checker,
+ optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite
diff --git a/tryton.cfg b/tryton.cfg
index 76a3f8e..d8ddfb7 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -12,7 +12,9 @@ extras_depend:
sale_office
analytic_purchase
purchase_office
+ analytic_party
xml:
account.xml
-
+ office.xml
+ party.xml
diff --git a/view/office_form.xml b/view/office_form.xml
new file mode 100644
index 0000000..18f4f3d
--- /dev/null
+++ b/view/office_form.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file