first commit

This commit is contained in:
root
2026-03-14 09:42:12 +00:00
commit 0adbd20c2c
10991 changed files with 1646955 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
__all__ = ['MoveLineMixin']
def __getattr__(name):
if name == 'MoveLineMixin':
from .move import MoveLineMixin
return MoveLineMixin
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3416
modules/account/account.py Normal file

File diff suppressed because it is too large Load Diff

957
modules/account/account.xml Normal file
View File

@@ -0,0 +1,957 @@
<?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. -->
<tryton>
<data>
<record model="res.group" id="group_account">
<field name="name">Accounting</field>
</record>
<record model="res.group" id="group_account_admin">
<field name="name">Accounting Administration</field>
<field name="parent" ref="group_account"/>
</record>
<record model="res.user-res.group" id="user_admin_group_account">
<field name="user" ref="res.user_admin"/>
<field name="group" ref="group_account"/>
</record>
<record model="res.user-res.group" id="user_admin_group_account_admin">
<field name="user" ref="res.user_admin"/>
<field name="group" ref="group_account_admin"/>
</record>
<record model="ir.ui.icon" id="account_icon">
<field name="name">tryton-account</field>
<field name="path">icons/tryton-account.svg</field>
</record>
<record model="ir.ui.icon" id="account_open_icon">
<field name="name">tryton-account-open</field>
<field name="path">icons/tryton-account-open.svg</field>
</record>
<record model="ir.ui.icon" id="account_close_icon">
<field name="name">tryton-account-close</field>
<field name="path">icons/tryton-account-close.svg</field>
</record>
<record model="ir.ui.icon" id="account_block_icon">
<field name="name">tryton-account-block</field>
<field name="path">icons/tryton-account-block.svg</field>
</record>
<menuitem
name="Financial"
id="menu_account"
sequence="60"
icon="tryton-account"/>
<record model="ir.ui.menu-res.group" id="menu_account_group_account">
<field name="menu" ref="menu_account"/>
<field name="group" ref="group_account"/>
</record>
<record model="ir.ui.menu-res.group" id="menu_account_group_account_admin">
<field name="menu" ref="menu_account"/>
<field name="group" ref="group_account_admin"/>
</record>
<menuitem
name="Configuration"
parent="menu_account"
sequence="0"
id="menu_account_configuration"
icon="tryton-settings"/>
<record model="ir.ui.menu-res.group"
id="menu_account_configuration_group_account_admin">
<field name="menu" ref="menu_account_configuration"/>
<field name="group" ref="group_account_admin"/>
</record>
<menuitem
name="Templates"
parent="menu_account_configuration"
sequence="10"
id="menu_templates"/>
<menuitem
name="General Account"
parent="menu_account_configuration"
sequence="20"
id="menu_general_account_configuration"/>
<menuitem
name="Entries"
parent="menu_account"
sequence="30"
id="menu_entries"/>
<menuitem
name="Processing"
parent="menu_account"
sequence="50"
id="menu_processing"/>
<menuitem
name="Reporting"
parent="menu_account"
sequence="100"
id="menu_reporting"/>
<record model="ir.ui.view" id="account_type_template_view_form">
<field name="model">account.account.type.template</field>
<field name="type">form</field>
<field name="name">account_type_template_form</field>
</record>
<record model="ir.ui.view" id="account_type_template_view_list">
<field name="model">account.account.type.template</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">account_type_template_list</field>
</record>
<record model="ir.ui.view" id="account_type_template_view_tree">
<field name="model">account.account.type.template</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="field_childs">childs</field>
<field name="name">account_type_template_tree</field>
</record>
<record model="ir.action.act_window" id="act_account_type_template_tree">
<field name="name">Account Types</field>
<field name="res_model">account.account.type.template</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_account_type_template_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_type_template_view_tree"/>
<field name="act_window" ref="act_account_type_template_tree"/>
</record>
<record model="ir.action.act_window.view"
id="act_account_type_template_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_type_template_view_form"/>
<field name="act_window" ref="act_account_type_template_tree"/>
</record>
<menuitem
parent="menu_templates"
action="act_account_type_template_tree"
sequence="10"
id="menu_account_type_template_tree"/>
<record model="ir.ui.view" id="account_type_view_form">
<field name="model">account.account.type</field>
<field name="type">form</field>
<field name="name">account_type_form</field>
</record>
<record model="ir.ui.view" id="account_type_view_tree">
<field name="model">account.account.type</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="field_childs">childs</field>
<field name="name">account_type_tree</field>
</record>
<record model="ir.ui.view" id="account_type_view_list">
<field name="model">account.account.type</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">account_type_list</field>
</record>
<record model="ir.action.act_window" id="act_account_type_tree">
<field name="name">Account Types</field>
<field name="res_model">account.account.type</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_type_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_type_view_tree"/>
<field name="act_window" ref="act_account_type_tree"/>
</record>
<record model="ir.action.act_window.view" id="act_account_type_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_type_view_form"/>
<field name="act_window" ref="act_account_type_tree"/>
</record>
<menuitem
parent="menu_general_account_configuration"
action="act_account_type_tree"
sequence="10"
id="menu_account_type_tree"/>
<record model="ir.action.act_window" id="act_account_type_list">
<field name="name">Account Types</field>
<field name="res_model">account.account.type</field>
</record>
<record model="ir.action.act_window.view" id="act_account_type_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_type_view_list"/>
<field name="act_window" ref="act_account_type_list"/>
</record>
<record model="ir.action.act_window.view" id="act_account_type_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_type_view_form"/>
<field name="act_window" ref="act_account_type_list"/>
</record>
<menuitem
parent="menu_account_type_tree"
action="act_account_type_list"
sequence="10"
id="menu_account_type_list"/>
<record model="ir.model.access" id="access_account_type">
<field name="model">account.account.type</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_account_type_account_admin">
<field name="model">account.account.type</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_type_amount">
<field name="model">account.account.type</field>
<field name="field">amount</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_type_amount_account">
<field name="model">account.account.type</field>
<field name="field">amount</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_type_amount_cmp">
<field name="model">account.account.type</field>
<field name="field">amount_cmp</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_type_amount_cmp_account">
<field name="model">account.account.type</field>
<field name="field">amount_cmp</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_account_type_companies">
<field name="name">User in companies</field>
<field name="model">account.account.type</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_account_type_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_account_type_companies"/>
</record>
<record model="ir.action.report" id="report_account_type_statement">
<field name="name">Statement</field>
<field name="records">listed</field>
<field name="model">account.account.type</field>
<field name="report_name">account.account.type.statement</field>
<field name="report">account/type_statement.fodt</field>
</record>
<record model="ir.action.keyword" id="report_account_type_statement_keyword">
<field name="keyword">form_print</field>
<field name="model">account.account.type,-1</field>
<field name="action" ref="report_account_type_statement"/>
</record>
<record model="ir.action-res.group" id="report_account_type_statement_group_account">
<field name="action" ref="report_account_type_statement"/>
<field name="group" ref="group_account"/>
</record>
<record model="ir.ui.view" id="account_template_view_form">
<field name="model">account.account.template</field>
<field name="type">form</field>
<field name="name">account_template_form</field>
</record>
<record model="ir.ui.view" id="account_template_view_list">
<field name="model">account.account.template</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">account_template_list</field>
</record>
<record model="ir.ui.view" id="account_template_view_tree">
<field name="model">account.account.template</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="field_childs">childs</field>
<field name="name">account_template_tree</field>
</record>
<record model="ir.action.act_window" id="act_account_template_tree">
<field name="name">Accounts</field>
<field name="res_model">account.account.template</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_template_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_template_view_tree"/>
<field name="act_window" ref="act_account_template_tree"/>
</record>
<record model="ir.action.act_window.view" id="act_account_template_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_template_view_form"/>
<field name="act_window" ref="act_account_template_tree"/>
</record>
<menuitem
parent="menu_templates"
action="act_account_template_tree"
sequence="20"
id="menu_account_template_tree"/>
<record model="ir.model.access" id="access_account_template">
<field name="model">account.account.template</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="account_deferral_view_form">
<field name="model">account.account.deferral</field>
<field name="type">form</field>
<field name="name">account_deferral_form</field>
</record>
<record model="ir.ui.view" id="account_deferral_view_tree">
<field name="model">account.account.deferral</field>
<field name="type">tree</field>
<field name="name">account_deferral_tree</field>
</record>
<record model="ir.ui.view" id="create_chart_start_view_form">
<field name="model">account.create_chart.start</field>
<field name="type">form</field>
<field name="name">create_chart_start_form</field>
</record>
<record model="ir.ui.view" id="create_chart_account_view_form">
<field name="model">account.create_chart.account</field>
<field name="type">form</field>
<field name="name">create_chart_account_form</field>
</record>
<record model="ir.ui.view" id="create_chart_properties_view_form">
<field name="model">account.create_chart.properties</field>
<field name="type">form</field>
<field name="name">create_chart_properties_form</field>
</record>
<record model="ir.action.wizard" id="wizard_create_chart">
<field name="name">Create Chart of Accounts from Template</field>
<field name="wiz_name">account.create_chart</field>
</record>
<menuitem
parent="menu_templates"
action="wizard_create_chart"
sequence="90"
id="menu_create_chart"/>
<record model="ir.module.config_wizard.item"
id="config_wizard_item_chart_account">
<field name="action" ref="wizard_create_chart"/>
</record>
<record model="ir.ui.view" id="update_chart_start_view_form">
<field name="model">account.update_chart.start</field>
<field name="type">form</field>
<field name="name">update_chart_start_form</field>
</record>
<record model="ir.ui.view" id="update_chart_succeed_view_form">
<field name="model">account.update_chart.succeed</field>
<field name="type">form</field>
<field name="name">update_chart_succeed_form</field>
</record>
<record model="ir.action.wizard" id="wizard_update_chart">
<field name="name">Update Chart of Accounts from Template</field>
<field name="wiz_name">account.update_chart</field>
</record>
<menuitem
parent="menu_templates"
action="wizard_update_chart"
sequence="90"
id="menu_update_chart"/>
<record model="ir.ui.view" id="account_view_form">
<field name="model">account.account</field>
<field name="type">form</field>
<field name="name">account_form</field>
</record>
<record model="ir.ui.view" id="account_view_tree">
<field name="model">account.account</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="field_childs">childs</field>
<field name="name">account_tree</field>
</record>
<record model="ir.ui.view" id="account_view_list">
<field name="model">account.account</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">account_list</field>
</record>
<record model="ir.action.act_window" id="act_account_tree">
<field name="name">Accounts</field>
<field name="res_model">account.account</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_view_tree"/>
<field name="act_window" ref="act_account_tree"/>
</record>
<record model="ir.action.act_window.view" id="act_account_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_view_form"/>
<field name="act_window" ref="act_account_tree"/>
</record>
<menuitem
parent="menu_general_account_configuration"
action="act_account_tree"
sequence="20"
id="menu_account_tree"/>
<record model="ir.action.act_window" id="act_account_list">
<field name="name">Accounts</field>
<field name="res_model">account.account</field>
</record>
<record model="ir.action.act_window.view" id="act_account_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_view_list"/>
<field name="act_window" ref="act_account_list"/>
</record>
<record model="ir.action.act_window.view" id="act_account_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="account_view_form"/>
<field name="act_window" ref="act_account_list"/>
</record>
<menuitem
parent="menu_account_tree"
action="act_account_list"
sequence="10"
id="menu_account_list"/>
<record model="ir.ui.view" id="account_view_list_balance_sheet">
<field name="model">account.account</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">account_list_balance_sheet</field>
</record>
<record model="ir.action.act_window" id="act_account_balance_sheet">
<field name="name">Accounts</field>
<field name="res_model">account.account</field>
<field name="context_model">account.balance_sheet.context</field>
<field name="context_domain"
eval="[('company', '=', Eval('company', -1))]"
pyson="1"/>
<field name="domain"
eval="[['OR', ('type', 'child_of', Eval('active_id'), 'parent'), ('debit_type', 'child_of', Eval('active_id'), 'parent')], ('type', '!=', None), ('closed', '!=', True)]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_list2_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_view_list_balance_sheet"/>
<field name="act_window" ref="act_account_balance_sheet"/>
</record>
<record model="ir.action.wizard" id="act_open_type">
<field name="name">Open Type</field>
<field name="wiz_name">account.account.open_type</field>
<field name="model">account.account.type</field>
</record>
<record model="ir.action.keyword" id="act_open_type_keyword">
<field name="keyword">tree_open</field>
<field name="model">account.account.type,-1</field>
<field name="action" ref="act_open_type"/>
</record>
<record model="ir.ui.view" id="account_view_tree_chart">
<field name="model">account.account</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="priority" eval="20"/>
<field name="name">account_tree_chart</field>
</record>
<record model="ir.action.act_window" id="act_account_tree_chart">
<field name="name">Chart of Accounts</field>
<field name="res_model">account.account</field>
<field name="context_model">account.account.context</field>
<field name="domain"
eval="[('parent', '=', None), ('context_company', '=', True)]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_tree_chart_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_view_tree_chart"/>
<field name="act_window" ref="act_account_tree_chart"/>
</record>
<menuitem
parent="menu_reporting"
action="act_account_tree_chart"
sequence="30"
id="menu_account_tree_chart"/>
<record model="ir.model.access" id="access_account">
<field name="model">account.account</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_account_account_admin">
<field name="model">account.account</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_balance">
<field name="model">account.account</field>
<field name="field">balance</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_balance_account">
<field name="model">account.account</field>
<field name="field">balance</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_credit">
<field name="model">account.account</field>
<field name="field">credit</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_credit_account">
<field name="model">account.account</field>
<field name="field">credit</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_debit">
<field name="model">account.account</field>
<field name="field">debit</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_debit_account">
<field name="model">account.account</field>
<field name="field">debit</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_account_amount_second_currency">
<field name="model">account.account</field>
<field name="field">amount_second_currency</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_account_amount_second_currency_account">
<field name="model">account.account</field>
<field name="field">amount_second_currency</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_account_companies">
<field name="name">User in companies</field>
<field name="model">account.account</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_account_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_account_companies"/>
</record>
<record model="ir.ui.view" id="account_context_view_form">
<field name="model">account.account.context</field>
<field name="type">form</field>
<field name="name">account_context_form</field>
</record>
<record model="ir.action.report" id="report_general_ledger">
<field name="name">General Ledger</field>
<field name="records">listed</field>
<field name="model">account.general_ledger.account</field>
<field name="report_name">account.general_ledger</field>
<field name="report">account/general_ledger.fodt</field>
</record>
<record model="ir.action.keyword" id="report_general_ledger_keyword">
<field name="keyword">form_print</field>
<field name="model">account.general_ledger.account,-1</field>
<field name="action" ref="report_general_ledger"/>
</record>
<record model="ir.action.report" id="report_trial_balance">
<field name="name">Trial Balance</field>
<field name="records">listed</field>
<field name="model">account.general_ledger.account</field>
<field name="report_name">account.trial_balance</field>
<field name="report">account/trial_balance.fodt</field>
</record>
<record model="ir.action.keyword" id="report_trial_balance_keyword">
<field name="keyword">form_print</field>
<field name="model">account.general_ledger.account,-1</field>
<field name="action" ref="report_trial_balance"/>
</record>
<record model="ir.ui.view" id="general_ledger_account_view_list">
<field name="model">account.general_ledger.account</field>
<field name="type">tree</field>
<field name="name">general_ledger_account_list</field>
</record>
<record model="ir.action.act_window" id="act_general_ledger_account_form">
<field name="name">General Ledger - Accounts</field>
<field name="res_model">account.general_ledger.account</field>
<field name="context_model">account.general_ledger.account.context</field>
<field name="search_value" eval="[('line_count', '!=', 0)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_general_ledger_account_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="general_ledger_account_view_list"/>
<field name="act_window" ref="act_general_ledger_account_form"/>
</record>
<menuitem
name="General Ledger"
parent="menu_reporting"
action="act_general_ledger_account_form"
sequence="10"
id="menu_general_ledger"/>
<record model="ir.action.act_window" id="act_account_general_ledger">
<field name="name">Accounts</field>
<field name="res_model">account.general_ledger.account</field>
<field name="context_model">account.general_ledger.account.context</field>
<field
name="context_domain"
eval="[('company', '=', Eval('company', -1))]"
pyson="1"/>
<field
name="domain"
eval="['OR', ('type', 'child_of', Eval('active_id'), 'parent'), ('debit_type', 'child_of', Eval('active_id'), 'parent')]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_account_general_ledger_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="general_ledger_account_view_list"/>
<field name="act_window" ref="act_account_general_ledger"/>
</record>
<record model="ir.model.access" id="access_general_ledger_account">
<field name="model">account.general_ledger.account</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_general_ledger_account_account">
<field name="model">account.general_ledger.account</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.rule.group" id="rule_group_general_ledger_account_companies">
<field name="name">User in companies</field>
<field name="model">account.general_ledger.account</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_general_ledger_account_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_general_ledger_account_companies"/>
</record>
<record model="ir.ui.view" id="general_ledger_account_party_view_list">
<field name="model">account.general_ledger.account.party</field>
<field name="inherit" ref="general_ledger_account_view_list"/>
<field name="name">general_ledger_account_party_list</field>
</record>
<record model="ir.action.act_window" id="act_general_ledger_account_party_form">
<field name="name">General Ledger - Account Parties</field>
<field name="res_model">account.general_ledger.account.party</field>
<field name="context_model">account.general_ledger.account.context</field>
<field
name="domain"
eval="[('account', 'in', Eval('active_ids', []))]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_general_ledger_account_party_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="general_ledger_account_party_view_list"/>
<field name="act_window" ref="act_general_ledger_account_party_form"/>
</record>
<record model="ir.action.keyword" id="act_general_ledger_account_party_form_keyword1">
<field name="keyword">tree_open</field>
<field name="model">account.general_ledger.account,-1</field>
<field name="action" ref="act_general_ledger_account_party_form"/>
</record>
<record model="ir.action.keyword" id="act_general_ledger_account_party_form_keyword_account">
<field name="keyword">form_relate</field>
<field name="model">account.account,-1</field>
<field name="action" ref="act_general_ledger_account_party_form"/>
</record>
<record model="ir.action.wizard" id="act_general_ledger_account_party_open">
<field name="name">Open General Ledger Account Parties</field>
<field name="wiz_name">account.general_ledger.account.party.open</field>
</record>
<record model="ir.action.keyword" id="act_general_ledger_account_party_open_keyword1">
<field name="keyword">tree_open</field>
<field name="model">account.general_ledger.account.party,-1</field>
<field name="action" ref="act_general_ledger_account_party_open"/>
</record>
<record model="ir.action.act_window" id="act_general_ledger_account_party_form_party">
<field name="name">Accounts</field>
<field name="res_model">account.general_ledger.account.party</field>
<field name="context_model">account.general_ledger.account.context</field>
<field name="domain" eval="[('party', 'in', Eval('active_ids'))]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_general_ledger_account_party_form_party_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="general_ledger_account_party_view_list"/>
<field name="act_window" ref="act_general_ledger_account_party_form_party"/>
</record>
<record model="ir.action.keyword" id="act_general_ledger_account_party_form_party_relate_keyword1">
<field name="keyword">form_relate</field>
<field name="model">party.party,-1</field>
<field name="action" ref="act_general_ledger_account_party_form_party"/>
</record>
<record model="ir.model.access" id="access_general_ledger_account_party">
<field name="model">account.general_ledger.account.party</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_general_ledger_account_account_party">
<field name="model">account.general_ledger.account.party</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.rule.group" id="rule_group_general_ledger_account_party_companies">
<field name="name">User in companies</field>
<field name="model">account.general_ledger.account.party</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_general_ledger_account_party_companies">
<field
name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_general_ledger_account_party_companies"/>
</record>
<record model="ir.ui.view" id="general_ledger_line_view_list">
<field name="model">account.general_ledger.line</field>
<field name="type">tree</field>
<field name="name">general_ledger_line_list</field>
</record>
<record model="ir.action.act_window" id="act_general_ledger_line_form">
<field name="name">General Ledger - Lines</field>
<field name="res_model">account.general_ledger.line</field>
<field name="context_model">account.general_ledger.line.context</field>
<field name="domain" eval="[('account', 'in', Eval('active_ids', []))]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_general_ledger_line_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="general_ledger_line_view_list"/>
<field name="act_window" ref="act_general_ledger_line_form"/>
</record>
<record model="ir.action.keyword" id="act_general_ledger_line_form_keyword">
<field name="keyword">tree_open</field>
<field name="model">account.general_ledger.account,-1</field>
<field name="action" ref="act_general_ledger_line_form"/>
</record>
<record model="ir.action.keyword" id="act_general_ledger_line_form_keyword_account">
<field name="keyword">form_relate</field>
<field name="model">account.account,-1</field>
<field name="action" ref="act_general_ledger_line_form"/>
</record>
<record model="ir.rule.group" id="rule_group_general_ledger_line_companies">
<field name="name">User in companies</field>
<field name="model">account.general_ledger.line</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_general_ledger_line_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_general_ledger_line_companies"/>
</record>
<record model="ir.ui.view" id="general_ledger_account_context_view_form">
<field name="model">account.general_ledger.account.context</field>
<field name="type">form</field>
<field name="name">general_ledger_account_context_form</field>
</record>
<record model="ir.ui.view" id="general_ledger_line_context_view_form">
<field name="model">account.general_ledger.line.context</field>
<field name="inherit" ref="general_ledger_account_context_view_form"/>
<field name="name">general_ledger_line_context_form</field>
</record>
<record model="ir.ui.view" id="account_balance_sheet_view_tree">
<field name="model">account.account.type</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="name">account_balance_sheet_tree</field>
</record>
<record model="ir.action.act_window" id="act_account_balance_sheet_tree">
<field name="name">Balance Sheet</field>
<field name="res_model">account.account.type</field>
<field name="context_model">account.balance_sheet.comparison.context</field>
<field name="context_domain"
eval="[('company', '=', Eval('company', -1))]"
pyson="1"/>
<field name="domain"
eval="[('statement', '=', 'balance'), ['OR', ('parent', '=', None), ('parent.statement', '!=', 'balance'), ('parent.statement', '=', None)]]"
pyson="1"/>
<field name="context" eval="{'cumulate': True}" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_balance_sheet_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_balance_sheet_view_tree"/>
<field name="act_window" ref="act_account_balance_sheet_tree"/>
</record>
<menuitem
parent="menu_reporting"
action="act_account_balance_sheet_tree"
sequence="20"
id="menu_open_balance_sheet"/>
<record model="ir.ui.view" id="balance_sheet_context_view_form">
<field name="model">account.balance_sheet.context</field>
<field name="type">form</field>
<field name="name">balance_sheet_context_form</field>
</record>
<record model="ir.ui.view" id="balance_sheet_comparison_context_view_form">
<field name="model">account.balance_sheet.comparison.context</field>
<field name="inherit" ref="balance_sheet_context_view_form"/>
<field name="name">balance_sheet_context_comparison_form</field>
</record>
<record model="ir.ui.view" id="account_income_statement_view_tree">
<field name="model">account.account.type</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="name">account_income_statement_tree</field>
</record>
<record model="ir.action.act_window" id="act_account_income_statement_tree">
<field name="name">Income Statement</field>
<field name="res_model">account.account.type</field>
<field name="context_model">account.income_statement.context</field>
<field name="context_domain"
eval="[('company', '=', Eval('company', -1))]"
pyson="1"/>
<field name="domain"
eval="[('statement', '=', 'income'), ['OR', ('parent', '=', None), ('parent.statement', '!=', 'income'), ('parent.statement', '=', None)]]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_income_statement_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="account_income_statement_view_tree"/>
<field name="act_window" ref="act_account_income_statement_tree"/>
</record>
<menuitem
parent="menu_reporting"
action="act_account_income_statement_tree"
sequence="20"
id="menu_open_income_statement"/>
<record model="ir.ui.view" id="income_statement_context_view_form">
<field name="model">account.income_statement.context</field>
<field name="type">form</field>
<field name="name">income_statement_context_form</field>
</record>
<record model="ir.ui.view" id="aged_balance_view_list">
<field name="model">account.aged_balance</field>
<field name="type">tree</field>
<field name="name">aged_balance_list</field>
</record>
<record model="ir.action.act_window" id="act_aged_balance_list">
<field name="name">Aged Balance</field>
<field name="res_model">account.aged_balance</field>
<field name="context_model">account.aged_balance.context</field>
</record>
<record model="ir.action.act_window.view" id="act_aged_balance_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="aged_balance_view_list"/>
<field name="act_window" ref="act_aged_balance_list"/>
</record>
<menuitem
parent="menu_reporting"
action="act_aged_balance_list"
sequence="50"
id="menu_aged_balance"/>
<record model="ir.model.access" id="access_aged_balance">
<field name="model">account.aged_balance</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_aged_balance_account">
<field name="model">account.aged_balance</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.rule.group" id="rule_group_aged_balance_companies">
<field name="name">User in companies</field>
<field name="model">account.aged_balance</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_aged_balance_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_aged_balance_companies"/>
</record>
<record model="ir.ui.view" id="aged_balance_context_view_form">
<field name="model">account.aged_balance.context</field>
<field name="type">form</field>
<field name="name">aged_balance_context_form</field>
</record>
<record model="ir.action.report" id="report_aged_balance">
<field name="name">Aged Balance</field>
<field name="model">account.aged_balance</field>
<field name="report_name">account.aged_balance</field>
<field name="report">account/aged_balance.fodt</field>
</record>
<record model="ir.action.keyword" id="report_aged_balance_keyword">
<field name="keyword">form_print</field>
<field name="model">account.aged_balance,-1</field>
<field name="action" ref="report_aged_balance"/>
</record>
</data>
</tryton>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,579 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta><meta:generator>LibreOffice/5.2.7.2$Linux_X86_64 LibreOffice_project/20m0$Build-2</meta:generator><meta:creation-date>2008-08-27T16:35:46</meta:creation-date><dc:date>2008-08-27T16:52:26</dc:date><meta:editing-cycles>1</meta:editing-cycles><meta:editing-duration>PT0S</meta:editing-duration><meta:document-statistic meta:character-count="1242" meta:image-count="0" meta:non-whitespace-character-count="1183" meta:object-count="0" meta:page-count="1" meta:paragraph-count="27" meta:table-count="3" meta:word-count="86"/><meta:user-defined meta:name="Info 1"/><meta:user-defined meta:name="Info 2"/><meta:user-defined meta:name="Info 3"/><meta:user-defined meta:name="Info 4"/></office:meta>
<office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaWidth" config:type="long">43760</config:config-item>
<config:config-item config:name="ViewAreaHeight" config:type="long">21691</config:config-item>
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
<config:config-item-map-indexed config:name="Views">
<config:config-item-map-entry>
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
<config:config-item config:name="ViewLeft" config:type="long">8162</config:config-item>
<config:config-item config:name="ViewTop" config:type="long">5443</config:config-item>
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleRight" config:type="long">43759</config:config-item>
<config:config-item config:name="VisibleBottom" config:type="long">21689</config:config-item>
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutColumns" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
<config:config-item config:name="ZoomFactor" config:type="short">100</config:config-item>
<config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
</config:config-item-map-entry>
</config:config-item-map-indexed>
</config:config-item-set>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintFaxName" config:type="string"/>
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item>
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterName" config:type="string"/>
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
<config:config-item config:name="Rsid" config:type="int">2183537</config:config-item>
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="ApplyUserData" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">false</config:config-item>
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
<config:config-item config:name="RsidRoot" config:type="int">765130</config:config-item>
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
</config:config-item-set>
</office:settings>
<office:scripts>
<office:script script:language="ooo:Basic">
<ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</office:script>
</office:scripts>
<office:font-face-decls>
<style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/>
<style:font-face style:name="Liberation Serif1" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Bold" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Regular" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Thorndale AMT" svg:font-family="&apos;Thorndale AMT&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Andale Sans UI" svg:font-family="&apos;Andale Sans UI&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="graphic">
<style:graphic-properties svg:stroke-color="#000000" draw:fill-color="#99ccff" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.1181in" draw:shadow-offset-y="0.1181in" draw:start-line-spacing-horizontal="0.1114in" draw:start-line-spacing-vertical="0.1114in" draw:end-line-spacing-horizontal="0.1114in" draw:end-line-spacing-vertical="0.1114in" style:flow-with-text="false"/>
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
<style:tab-stops/>
</style:paragraph-properties>
<style:text-properties style:use-window-font-color="true" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"/>
</style:default-style>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="0.4925in" style:writing-mode="lr-tb"/>
<style:text-properties style:use-window-font-color="true" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2"/>
</style:default-style>
<style:default-style style:family="table">
<style:table-properties table:border-model="collapsing"/>
</style:default-style>
<style:default-style style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.1665in" fo:margin-bottom="0.0835in" loext:contextual-spacing="false" fo:keep-with-next="always"/>
<style:text-properties style:font-name="Liberation Serif" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Regular" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="16pt" style:font-name-asian="DejaVu Sans" style:font-family-asian="&apos;DejaVu Sans&apos;" style:font-family-generic-asian="system" style:font-pitch-asian="variable" style:font-size-asian="14pt" style:font-name-complex="DejaVu Sans" style:font-family-complex="&apos;DejaVu Sans&apos;" style:font-family-generic-complex="system" style:font-pitch-complex="variable" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0in" fo:margin-bottom="0.0835in" loext:contextual-spacing="false"/>
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="List" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="list">
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties fo:margin-top="0.0835in" fo:margin-bottom="0.0835in" loext:contextual-spacing="false" text:number-lines="false" text:line-number="0"/>
<style:text-properties fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-size-complex="12pt" style:font-style-complex="italic"/>
</style:style>
<style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text">
<style:text-properties fo:font-size="16pt" fo:font-weight="bold" style:font-size-asian="115%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Table_20_Heading" style:display-name="Table Heading" style:family="paragraph" style:parent-style-name="Table_20_Contents" style:class="extra" style:master-page-name="">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" style:page-number="auto" text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-name="Liberation Serif1" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Bold" style:font-family-generic="roman" style:font-pitch="variable" fo:font-weight="bold" style:font-size-asian="10.5pt" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Header" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="3.4626in" style:type="center"/>
<style:tab-stop style:position="6.9252in" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_2" style:display-name="Heading 2" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="14pt" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-style-complex="italic" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="3.4626in" style:type="center"/>
<style:tab-stop style:position="6.9252in" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_3" style:display-name="Heading 3" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-weight="bold" style:font-size-asian="14pt" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Text_20_body_20_indent" style:display-name="Text body indent" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-left="0.1965in" fo:margin-right="0in" fo:margin-top="0in" fo:margin-bottom="0in" loext:contextual-spacing="false" fo:text-indent="0in" style:auto-text-indent="false"/>
</style:style>
<style:style style:name="Text" style:family="paragraph" style:parent-style-name="Caption" style:class="extra"/>
<style:style style:name="Quotations" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
<style:paragraph-properties fo:margin-left="0.3937in" fo:margin-right="0.3937in" fo:margin-top="0in" fo:margin-bottom="0.1965in" loext:contextual-spacing="false" fo:text-indent="0in" style:auto-text-indent="false"/>
</style:style>
<style:style style:name="Title" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties fo:font-size="28pt" fo:font-weight="bold" style:font-size-asian="28pt" style:font-weight-asian="bold" style:font-size-complex="28pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Subtitle" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:margin-top="0.0417in" fo:margin-bottom="0.0835in" loext:contextual-spacing="false" fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties fo:font-size="18pt" style:font-size-asian="18pt" style:font-size-complex="18pt"/>
</style:style>
<style:style style:name="Placeholder" style:family="text">
<style:text-properties fo:font-variant="small-caps" fo:color="#008080" style:text-underline-style="dotted" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="Bullet_20_Symbols" style:display-name="Bullet Symbols" style:family="text">
<style:text-properties style:font-name="StarSymbol" fo:font-family="StarSymbol" fo:font-size="9pt" style:font-name-asian="StarSymbol" style:font-family-asian="StarSymbol" style:font-size-asian="9pt" style:font-name-complex="StarSymbol" style:font-family-complex="StarSymbol" style:font-size-complex="9pt"/>
</style:style>
<text:outline-style style:name="Outline">
<text:outline-level-style text:level="1" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="2" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="3" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="4" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="5" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="6" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="7" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="8" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="9" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
<text:outline-level-style text:level="10" style:num-format="">
<style:list-level-properties text:min-label-distance="0.15in"/>
</text:outline-level-style>
</text:outline-style>
<text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
<text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
<text:linenumbering-configuration text:number-lines="false" text:offset="0.1965in" style:num-format="1" text:number-position="left" text:increment="5"/>
</office:styles>
<office:automatic-styles>
<style:style style:name="Table3" style:family="table">
<style:table-properties style:width="6.6924in" table:align="margins"/>
</style:style>
<style:style style:name="Table3.A" style:family="table-column">
<style:table-column-properties style:column-width="2.2306in" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table3.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border="none"/>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="6.6924in" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="3.3465in" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table2.B" style:family="table-column">
<style:table-column-properties style:column-width="3.3458in" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border="none"/>
</style:style>
<style:style style:name="Table3" style:family="table">
<style:table-properties style:width="6.6924in" table:align="margins"/>
</style:style>
<style:style style:name="Table3.A" style:family="table-column">
<style:table-column-properties style:column-width="2.2306in" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table3.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border="none"/>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="6.6924in" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="3.3465in" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table2.B" style:family="table-column">
<style:table-column-properties style:column-width="3.3458in" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border="none"/>
</style:style>
<style:style style:name="Table1" style:family="table">
<style:table-properties style:width="6.6896in" fo:margin-left="0in" fo:margin-right="0.0028in" table:align="margins"/>
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
<style:table-column-properties style:column-width="1.7694in" style:rel-column-width="17334*"/>
</style:style>
<style:style style:name="Table1.B" style:family="table-column">
<style:table-column-properties style:column-width="0.984in" style:rel-column-width="9640*"/>
</style:style>
<style:style style:name="Table1.F" style:family="table-column">
<style:table-column-properties style:column-width="0.984in" style:rel-column-width="9641*"/>
</style:style>
<style:style style:name="Table1.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1.F1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.0382in" fo:border="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1.2" style:family="table-row">
<style:table-row-properties style:min-row-height="0.2313in"/>
</style:style>
<style:style style:name="Table1.A2" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.F2" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.A3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.B3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.C3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.D3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.E3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.F3" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.A4" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.F4" style:family="table-cell">
<style:table-cell-properties fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Table1.5" style:family="table-row">
<style:table-row-properties style:min-row-height="0.0528in"/>
</style:style>
<style:style style:name="Table1.A5" style:family="table-cell">
<style:table-cell-properties fo:background-color="#e6e6e6" fo:padding="0.0382in" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1.F5" style:family="table-cell">
<style:table-cell-properties fo:background-color="#e6e6e6" fo:padding="0.0382in" fo:border="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P2" style:family="paragraph" style:parent-style-name="Footer">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P3" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P4" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" style:font-size-asian="14pt" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="P5" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:text-properties fo:font-size="14pt" fo:font-weight="normal" style:font-size-asian="14pt" style:font-weight-asian="normal" style:font-size-complex="14pt" style:font-weight-complex="normal"/>
</style:style>
<style:style style:name="P6" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:text-properties fo:font-size="14pt" fo:font-weight="bold" style:font-size-asian="14pt" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P7" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" officeooo:paragraph-rsid="0017ee93" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="normal"/>
</style:style>
<style:style style:name="P9" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" officeooo:paragraph-rsid="0020f549" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="normal"/>
</style:style>
<style:style style:name="P10" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" fo:font-weight="bold" officeooo:paragraph-rsid="0017ee93" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P11" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" fo:font-weight="bold" officeooo:paragraph-rsid="0020f549" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P12" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" style:text-underline-style="none" style:font-size-asian="14pt" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="P13" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:text-properties officeooo:rsid="0017c172" officeooo:paragraph-rsid="0017c172"/>
</style:style>
<style:style style:name="P14" style:family="paragraph" style:parent-style-name="Heading_20_1">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties fo:font-size="14pt" fo:language="en" fo:country="US" officeooo:rsid="000e7ba0" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="T2" style:family="text">
<style:text-properties officeooo:rsid="001a39a1"/>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="8.2673in" fo:page-height="11.6925in" style:num-format="1" style:print-orientation="portrait" fo:margin-top="0.7874in" fo:margin-bottom="0.7874in" fo:margin-left="0.7874in" fo:margin-right="0.7874in" style:writing-mode="lr-tb" style:footnote-max-height="0in">
<style:footnote-sep style:width="0.0071in" style:distance-before-sep="0.0398in" style:distance-after-sep="0.0398in" style:line-style="none" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
</style:page-layout-properties>
<style:header-style>
<style:header-footer-properties fo:min-height="0in" fo:margin-left="0in" fo:margin-right="0in" fo:margin-bottom="0.1965in"/>
</style:header-style>
<style:footer-style>
<style:header-footer-properties fo:min-height="0in" fo:margin-left="0in" fo:margin-right="0in" fo:margin-top="0.1965in"/>
</style:footer-style>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1">
<style:header>
<table:table table:name="Table3" table:style-name="Table3">
<table:table-column table:style-name="Table3.A" table:number-columns-repeated="3"/>
<table:table-row>
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="Header">Company: <text:placeholder text:placeholder-type="text">&lt;company.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="Header">Aged Balance for <text:placeholder text:placeholder-type="text">&lt;type&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="P1">Print Date: <text:placeholder text:placeholder-type="text">&lt;format_date(datetime.date.today(), user.language)&gt;</text:placeholder> at <text:placeholder text:placeholder-type="text">&lt;datetime.datetime.now().strftime(&apos;%H:%M:%S&apos;)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:header>
<style:footer>
<table:table table:name="Table2" table:style-name="Table2">
<table:table-column table:style-name="Table2.A"/>
<table:table-column table:style-name="Table2.B"/>
<table:table-row>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="Footer">User: <text:placeholder text:placeholder-type="text">&lt;user.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="P2"><text:page-number text:select-page="current">1</text:page-number>/<text:page-count>1</text:page-count></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:footer>
</style:master-page>
</office:master-styles>
<office:body>
<office:text>
<office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
<text:sequence-decls>
<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
</text:sequence-decls>
<text:h text:style-name="P14" text:outline-level="1">Aged Balance for <text:placeholder text:placeholder-type="text">&lt;type&gt;</text:placeholder></text:h>
<text:p text:style-name="P13">Date: <text:span text:style-name="T1"><text:placeholder text:placeholder-type="text">&lt;format_date(date, user.language)&gt;</text:placeholder></text:span></text:p>
<table:table table:name="Table1" table:style-name="Table1">
<table:table-column table:style-name="Table1.A"/>
<table:table-column table:style-name="Table1.B" table:number-columns-repeated="4"/>
<table:table-column table:style-name="Table1.F"/>
<table:table-header-rows>
<table:table-row>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P3">Party</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P5"><text:placeholder text:placeholder-type="text">&lt;str(term0)&gt;</text:placeholder> <text:placeholder text:placeholder-type="text">&lt;unit&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P5"><text:placeholder text:placeholder-type="text">&lt;str(term1)&gt;</text:placeholder> <text:placeholder text:placeholder-type="text">&lt;unit&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P5"><text:placeholder text:placeholder-type="text">&lt;str(term2)&gt;</text:placeholder> <text:placeholder text:placeholder-type="text">&lt;unit&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P5"><text:placeholder text:placeholder-type="text">&lt;str(term3)&gt;</text:placeholder><text:span text:style-name="T2">+</text:span> <text:placeholder text:placeholder-type="text">&lt;unit&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.F1" office:value-type="string">
<text:p text:style-name="P6">Balance</text:p>
</table:table-cell>
</table:table-row>
</table:table-header-rows>
<table:table-row table:style-name="Table1.2">
<table:table-cell table:style-name="Table1.A2" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="P7"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;record in records&quot;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:table-cell table:style-name="Table1.F2" office:value-type="string">
<text:p text:style-name="P7"/>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table1.2">
<table:table-cell table:style-name="Table1.A3" office:value-type="string">
<text:p text:style-name="P7"><text:placeholder text:placeholder-type="text">&lt;record.party.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.B3" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;format_currency(record.term0, user.language, currency=company.currency)or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.C3" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;format_currency(record.term1, user.language, currency=company.currency) or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.D3" office:value-type="string">
<text:p text:style-name="P9"><text:placeholder text:placeholder-type="text">&lt;format_currency(record.term2, user.language, currency=company.currency) or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.E3" office:value-type="string">
<text:p text:style-name="P9"><text:placeholder text:placeholder-type="text">&lt;format_currency(record.term3, user.language, currency=company.currency) or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.F3" office:value-type="string">
<text:p text:style-name="P9"><text:placeholder text:placeholder-type="text">&lt;format_currency(record.balance, user.language, currency=company.currency) or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table1.2">
<table:table-cell table:style-name="Table1.A4" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="P7"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:table-cell table:style-name="Table1.F4" office:value-type="string">
<text:p text:style-name="P7"/>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Table1.5">
<table:table-cell table:style-name="Table1.A5" office:value-type="string">
<text:p text:style-name="P4">Total</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A5" office:value-type="string">
<text:p text:style-name="P10"><text:placeholder text:placeholder-type="text">&lt;format_currency(sum(records, &apos;term0&apos;), user.language, currency=company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A5" office:value-type="string">
<text:p text:style-name="P11"><text:placeholder text:placeholder-type="text">&lt;format_currency(sum(records, &apos;term1&apos;), user.language, currency=company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A5" office:value-type="string">
<text:p text:style-name="P11"><text:placeholder text:placeholder-type="text">&lt;format_currency(sum(records, &apos;term2&apos;), user.language, currency=company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A5" office:value-type="string">
<text:p text:style-name="P11"><text:placeholder text:placeholder-type="text">&lt;format_currency(sum(records, &apos;term3&apos;), user.language, currency=company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.F5" office:value-type="string">
<text:p text:style-name="P11"><text:placeholder text:placeholder-type="text">&lt;format_currency(sum(records, &apos;balance&apos;), user.language, currency=company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="P12"/>
</office:text>
</office:body>
</office:document>

180
modules/account/common.py Normal file
View File

@@ -0,0 +1,180 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import datetime
from sql import Literal
from sql.conditionals import Coalesce
from trytond.model import Model, fields
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If
from trytond.transaction import Transaction
class PeriodMixin(Model):
start_date = fields.Date(
"Start Date",
domain=[
If(Eval('start_date') & Eval('end_date'),
('start_date', '<=', Eval('end_date')),
()),
])
end_date = fields.Date(
"End Date",
domain=[
If(Eval('start_date') & Eval('end_date'),
('end_date', '>=', Eval('start_date')),
()),
])
@classmethod
def __setup__(cls):
super().__setup__()
if (hasattr(cls, 'parent')
and hasattr(cls, 'childs')
and hasattr(cls, 'company')):
cls.parent.domain = [
('company', '=', Eval('company', 0)),
['OR',
If(Bool(Eval('start_date')),
('start_date', '>=', Eval('start_date', None)),
()),
('start_date', '=', None),
],
['OR',
If(Bool(Eval('end_date')),
('end_date', '<=', Eval('end_date', None)),
()),
('end_date', '=', None),
],
]
cls.parent.depends.update({'company', 'start_date', 'end_date'})
cls.childs.domain = [
('company', '=', Eval('company', 0)),
If(Bool(Eval('start_date')),
('start_date', '>=', Eval('start_date', None)),
()),
If(Bool(Eval('end_date')),
('end_date', '<=', Eval('end_date', None)),
()),
]
cls.childs.depends.update({'company', 'start_date', 'end_date'})
class ActivePeriodMixin(PeriodMixin):
active = fields.Function(fields.Boolean("Active"), 'on_change_with_active')
@classmethod
def _active_dates(cls):
pool = Pool()
Date = pool.get('ir.date')
FiscalYear = pool.get('account.fiscalyear')
Period = pool.get('account.period')
context = Transaction().context
today = Date.today()
date = context.get('date')
from_date, to_date = context.get('from_date'), context.get('to_date')
period_ids = context.get('periods')
fiscalyear_id = context.get('fiscalyear')
if date:
fiscalyears = FiscalYear.search([
('start_date', '<=', date),
('end_date', '>=', date),
])
elif from_date or to_date:
domain = []
if from_date:
domain.append(('end_date', '>=', from_date))
if to_date:
domain.append(('start_date', '<=', to_date))
fiscalyears = FiscalYear.search(domain)
elif period_ids:
periods = Period.browse(period_ids)
fiscalyears = list(set(p.fiscalyear for p in periods))
elif fiscalyear_id:
fiscalyears = FiscalYear.browse([fiscalyear_id])
else:
fiscalyears = FiscalYear.search([
('start_date', '<=', today),
('end_date', '>=', today),
], limit=1)
if not fiscalyears:
return (from_date or date or today, to_date or date or today)
return (
min(f.start_date for f in fiscalyears),
max(f.end_date for f in fiscalyears))
@classmethod
def default_active(cls):
return True
@fields.depends('start_date', 'end_date')
def on_change_with_active(self, name=None):
from_date, to_date = self._active_dates()
start_date = self.start_date or datetime.date.min
end_date = self.end_date or datetime.date.max
return (start_date <= to_date <= end_date
or start_date <= from_date <= end_date
or (from_date <= start_date and end_date <= to_date))
@classmethod
def domain_active(cls, domain, tables):
table, _ = tables[None]
_, operator, value = domain
from_date, to_date = cls._active_dates()
start_date = Coalesce(table.start_date, datetime.date.min)
end_date = Coalesce(table.end_date, datetime.date.max)
expression = (((start_date <= to_date) & (end_date >= to_date))
| ((start_date <= from_date) & (end_date >= from_date))
| ((start_date >= from_date) & (end_date <= to_date)))
if operator in {'=', '!='}:
if (operator == '=') != value:
expression = ~expression
elif operator in {'in', 'not in'}:
if True in value and False not in value:
pass
elif False in value and True not in value:
expression = ~expression
else:
expression = Literal(True)
else:
expression = Literal(True)
return expression
class ContextCompanyMixin(Model):
context_company = fields.Function(fields.Boolean("Context Company"),
'get_context_company')
def get_context_company(self, name):
context = Transaction().context
return self.company.id == context.get('company')
@classmethod
def domain_context_company(cls, domain, tables):
context = Transaction().context
table, _ = tables[None]
_, operator, value = domain
expression = table.company == context.get('company')
if operator in {'=', '!='}:
if (operator == '=') != value:
expression = ~expression
elif operator in {'in', 'not in'}:
if True in value and False not in value:
pass
elif False in value and True not in value:
expression = ~expression
else:
expression = Literal(True)
else:
expression = Literal(True)
return expression

149
modules/account/company.py Normal file
View File

@@ -0,0 +1,149 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from sql import Literal, Null
from sql.aggregate import Sum
from sql.conditionals import Coalesce
from trytond import backend
from trytond.i18n import gettext
from trytond.model import fields
from trytond.model.exceptions import AccessError
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.transaction import Transaction
class Company(metaclass=PoolMeta):
__name__ = 'company.company'
receivable = fields.Function(Monetary(
"Receivable", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
payable = fields.Function(Monetary(
"Payable", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
receivable_today = fields.Function(Monetary(
"Receivable Today", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
payable_today = fields.Function(Monetary(
"Payable Today", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
@classmethod
def get_receivable_payable(cls, companies, names):
amounts = {}
pool = Pool()
MoveLine = pool.get('account.move.line')
Account = pool.get('account.account')
AccountType = pool.get('account.account.type')
Date = pool.get('ir.date')
cursor = Transaction().connection.cursor()
line = MoveLine.__table__()
account = Account.__table__()
account_type = AccountType.__table__()
for name in names:
assert name in {
'receivable', 'payable', 'receivable_today', 'payable_today'}
amounts[name] = dict.fromkeys(map(int, companies), Decimal(0))
exp = {
c.id: Decimal(str(10.0 ** -c.currency.digits)) for c in companies}
today = Date.today()
amount = Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0))
for name in names:
if name.endswith('_today'):
code = name[:-len('_today')]
today_where = (
(line.maturity_date <= today)
| (line.maturity_date == Null))
else:
code = name
today_where = Literal(True)
for sub_companies in grouped_slice(companies):
sub_ids = [p.id for p in sub_companies]
company_where = reduce_ids(account.company, sub_ids)
query = (line
.join(account,
condition=account.id == line.account)
.join(account_type,
condition=account.type == account_type.id)
.select(account.company.as_('id'), amount.as_(name),
where=(getattr(account_type, code)
& (line.reconciliation == Null)
& company_where
& today_where),
group_by=account.company))
if backend.name == 'sqlite':
sqlite_apply_types(query, [None, 'NUMERIC'])
cursor.execute(*query)
for company_id, value in cursor:
amounts[name][company_id] = value.quantize(exp[company_id])
return amounts
@classmethod
def search_receivable_payable(cls, name, clause):
pool = Pool()
MoveLine = pool.get('account.move.line')
Account = pool.get('account.account')
AccountType = pool.get('account.account.type')
Date = pool.get('ir.date')
line = MoveLine.__table__()
account = Account.__table__()
account_type = AccountType.__table__()
assert name in {
'receivable', 'payable', 'receivable_today', 'payable_today'}
_, operator, value = clause
today = Date.today()
if name.endswith('_today'):
code = name[:-len('_today')]
today_query = ((line.maturity_date <= today)
| (line.maturity_date == Null))
else:
code = name
today_query = Literal(True)
Operator = fields.SQL_OPERATORS[operator]
# Need to cast numeric for sqlite
cast_ = MoveLine.debit.sql_cast
amount = cast_(Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0)))
if operator in {'in', 'not in'}:
value = [cast_(Literal(Decimal(v or 0))) for v in value]
else:
value = cast_(Literal(Decimal(value or 0)))
query = (line
.join(account, condition=account.id == line.account)
.join(account_type, condition=account.type == account_type.id)
.select(account.company,
where=(getattr(account_type, code)
& (line.reconciliation == Null)
& today_query),
group_by=account.company,
having=Operator(amount, value)))
return [('id', 'in', query)]
@classmethod
def check_modification(cls, mode, companies, values=None, external=False):
pool = Pool()
Move = pool.get('account.move')
super().check_modification(
mode, companies, values=values, external=external)
if mode == 'write':
if 'currency' in values:
moves = Move.search([
('company', 'in', [c.id for c in companies]),
],
limit=1, order=[])
if moves:
raise AccessError(gettext(
'account.msg_company_change_currency'))

View File

@@ -0,0 +1,66 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="company_view_list">
<field name="model">company.company</field>
<field name="inherit" ref="company.company_view_list"/>
<field name="name">company_list</field>
</record>
<record model="ir.ui.view" id="company_view_form">
<field name="model">company.company</field>
<field name="inherit" ref="company.company_view_form"/>
<field name="name">company_form</field>
</record>
<record model="ir.model.field.access" id="access_company_receivable">
<field name="model">company.company</field>
<field name="field">receivable</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_company_receivable_account">
<field name="model">company.company</field>
<field name="field">receivable</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_company_payable">
<field name="model">company.company</field>
<field name="field">payable</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_company_payable_account">
<field name="model">company.company</field>
<field name="field">payable</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_company_receivable_today">
<field name="model">company.company</field>
<field name="field">receivable_today</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_company_receivable_today_account">
<field name="model">company.company</field>
<field name="field">receivable_today</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_company_payable_today">
<field name="model">company.company</field>
<field name="field">payable_today</field>
<field name="perm_read" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_company_payable_today_account">
<field name="model">company.company</field>
<field name="field">payable_today</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,218 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import ModelSingleton, ModelSQL, ModelView, fields
from trytond.modules.company.model import (
CompanyMultiValueMixin, CompanyValueMixin)
from trytond.pool import Pool
from trytond.pyson import Eval, Id
tax_roundings = [
('document', 'Per Document'),
('line', 'Per Line'),
]
class Configuration(
ModelSingleton, ModelSQL, ModelView, CompanyMultiValueMixin):
__name__ = 'account.configuration'
default_account_receivable = fields.MultiValue(fields.Many2One(
'account.account', "Default Account Receivable",
domain=[
('closed', '!=', True),
('type.receivable', '=', True),
('party_required', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
]))
default_account_payable = fields.MultiValue(fields.Many2One(
'account.account', "Default Account Payable",
domain=[
('closed', '!=', True),
('type.payable', '=', True),
('party_required', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
]))
default_customer_tax_rule = fields.MultiValue(fields.Many2One(
'account.tax.rule', "Default Customer Tax Rule",
domain=[
('company', '=', Eval('context', {}).get('company', -1)),
('kind', 'in', ['sale', 'both']),
],
help="Default customer tax rule for new parties."))
default_supplier_tax_rule = fields.MultiValue(fields.Many2One(
'account.tax.rule', "Default Supplier Tax Rule",
domain=[
('company', '=', Eval('context', {}).get('company', -1)),
('kind', 'in', ['purchase', 'both']),
],
help="Default supplier tax rule for new parties."))
tax_rounding = fields.MultiValue(fields.Selection(
tax_roundings, "Tax Rounding"))
reconciliation_sequence = fields.MultiValue(fields.Many2One(
'ir.sequence', "Reconciliation Sequence", required=True,
domain=[
('company', 'in',
[Eval('context', {}).get('company', -1), None]),
('sequence_type', '=',
Id('account',
'sequence_type_account_move_reconciliation')),
]))
currency_exchange_journal = fields.MultiValue(fields.Many2One(
'account.journal', "Currency Exchange Journal",
domain=[
('type', '=', 'write-off'),
]))
currency_exchange_credit_account = fields.MultiValue(fields.Many2One(
'account.account', "Currency Exchange Credit Account",
domain=[
('closed', '!=', True),
('type.statement', '=', 'income'),
('company', '=', Eval('context', {}).get('company', -1)),
('second_currency', '=', None),
]))
currency_exchange_debit_account = fields.MultiValue(fields.Many2One(
'account.account', "Currency Exchange Debit Account",
domain=[
('closed', '!=', True),
('type.statement', '=', 'income'),
('company', '=', Eval('context', {}).get('company', -1)),
('second_currency', '=', None),
]))
@classmethod
def multivalue_model(cls, field):
pool = Pool()
if field in {
'default_account_receivable', 'default_account_payable',
'currency_exchange_credit_account',
'currency_exchange_debit_account'}:
return pool.get('account.configuration.default_account')
if field in {'default_customer_tax_rule', 'default_supplier_tax_rule'}:
return pool.get('account.configuration.default_tax_rule')
if field == 'reconciliation_sequence':
return pool.get('account.configuration.sequence')
elif field == 'currency_exchange_journal':
return pool.get('account.configuration.journal')
return super().multivalue_model(field)
@classmethod
def default_tax_rounding(cls, **pattern):
return cls.multivalue_model('tax_rounding').default_tax_rounding()
@classmethod
def default_reconciliation_sequence(cls, **pattern):
return cls.multivalue_model(
'reconciliation_sequence').default_reconciliation_sequence()
@classmethod
def default_currency_exchange_journal(cls, **pattern):
return cls.multivalue_model(
'currency_exchange_journal').default_currency_exchange_journal()
class ConfigurationDefaultAccount(ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.default_account'
default_account_receivable = fields.Many2One(
'account.account', "Default Account Receivable",
domain=[
('closed', '!=', True),
('type.receivable', '=', True),
('party_required', '=', True),
('company', '=', Eval('company', -1)),
])
default_account_payable = fields.Many2One(
'account.account', "Default Account Payable",
domain=[
('closed', '!=', True),
('type.payable', '=', True),
('party_required', '=', True),
('company', '=', Eval('company', -1)),
])
currency_exchange_credit_account = fields.Many2One(
'account.account', "Currency Exchange Credit Account",
domain=[
('closed', '!=', True),
('type.statement', '=', 'income'),
('company', '=', Eval('company', -1)),
('second_currency', '=', None),
])
currency_exchange_debit_account = fields.Many2One(
'account.account', "Currency Exchange Debit Account",
domain=[
('closed', '!=', True),
('type.statement', '=', 'income'),
('company', '=', Eval('company', -1)),
('second_currency', '=', None),
])
class DefaultTaxRule(ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.default_tax_rule'
default_customer_tax_rule = fields.Many2One(
'account.tax.rule', "Default Customer Tax Rule",
domain=[
('company', '=', Eval('company', -1)),
('kind', 'in', ['sale', 'both']),
])
default_supplier_tax_rule = fields.Many2One(
'account.tax.rule', "Default Supplier Tax Rule",
domain=[
('company', '=', Eval('company', -1)),
('kind', 'in', ['purchase', 'both']),
])
class ConfigurationTaxRounding(ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.tax_rounding'
configuration = fields.Many2One('account.configuration', 'Configuration',
required=True, ondelete='CASCADE',
context={
'company': Eval('company', -1),
},
depends={'company'})
tax_rounding = fields.Selection(tax_roundings, 'Method', required=True)
@classmethod
def default_tax_rounding(cls):
return 'document'
class Sequence(ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.sequence'
reconciliation_sequence = fields.Many2One(
'ir.sequence', "Reconciliation Sequence", required=True,
domain=[
('company', 'in', [Eval('company', -1), None]),
('sequence_type', '=',
Id('account', 'sequence_type_account_move_reconciliation')),
])
@classmethod
def default_reconciliation_sequence(cls):
pool = Pool()
ModelData = pool.get('ir.model.data')
try:
return ModelData.get_id(
'account', 'sequence_account_move_reconciliation')
except KeyError:
return None
class Journal(ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.journal'
currency_exchange_journal = fields.Many2One(
'account.journal', "Currency Exchange Journal",
domain=[
('type', '=', 'write-off'),
],
context={
'company': Eval('company', -1),
})
@classmethod
def default_currency_exchange_journal(cls):
pool = Pool()
ModelData = pool.get('ir.model.data')
try:
return ModelData.get_id('account', 'journal_currency_exchange')
except KeyError:
return None

View File

@@ -0,0 +1,46 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="configuration_view_form">
<field name="model">account.configuration</field>
<field name="type">form</field>
<field name="name">configuration_form</field>
</record>
<record model="ir.action.act_window"
id="act_configuration_form">
<field name="name">Configuration</field>
<field name="res_model">account.configuration</field>
</record>
<record model="ir.action.act_window.view"
id="act_configuration_view1">
<field name="sequence" eval="1"/>
<field name="view" ref="configuration_view_form"/>
<field name="act_window" ref="act_configuration_form"/>
</record>
<menuitem
parent="menu_account_configuration"
action="act_configuration_form"
sequence="0"
id="menuitem_account_configuration"
icon="tryton-list"/>
<record model="ir.model.access" id="access_account_configuration">
<field name="model">account.configuration</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access"
id="access_account_configuration_account_admin">
<field name="model">account.configuration</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,109 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.exceptions import UserError, UserWarning
from trytond.model.exceptions import ValidationError
class PeriodNotFoundError(UserError):
pass
class PeriodValidationError(ValidationError):
pass
class ClosePeriodError(PeriodValidationError):
pass
class PeriodDatesError(PeriodValidationError):
pass
class FiscalYearNotFoundError(UserError):
pass
class FiscalYearCloseError(UserError):
pass
class FiscalYearReOpenError(UserError):
pass
class JournalMissing(UserError):
pass
class AccountMissing(UserError):
pass
class AccountValidationError(ValidationError):
pass
class SecondCurrencyError(AccountValidationError):
pass
class ChartWarning(UserWarning):
pass
class PostError(UserError):
pass
class MoveTemplateExpressionError(UserError):
pass
class MoveTemplateKeywordValidationError(ValidationError):
pass
class CopyWarning(UserWarning):
pass
class CancelWarning(UserWarning):
pass
class ReconciliationError(ValidationError):
pass
class ReconciliationDeleteWarning(UserWarning):
pass
class CancelDelegatedWarning(UserWarning):
pass
class GroupLineError(UserError):
pass
class GroupLineWarning(UserWarning):
pass
class RescheduleLineError(UserError):
pass
class RescheduleLineWarning(UserWarning):
pass
class DelegateLineError(UserError):
pass
class DelegateLineWarning(UserWarning):
pass

View File

@@ -0,0 +1,716 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from dateutil.relativedelta import relativedelta
from sql import Null
from sql.conditionals import Case
from sql.operators import Equal, NotEqual
from trytond.cache import Cache
from trytond.i18n import gettext
from trytond.model import (
Exclude, ModelSQL, ModelView, Unique, Workflow, fields)
from trytond.model.exceptions import AccessError
from trytond.pool import Pool
from trytond.pyson import Eval, Id
from trytond.rpc import RPC
from trytond.sql.functions import DateRange
from trytond.sql.operators import RangeOverlap
from trytond.transaction import Transaction
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
from .exceptions import (
FiscalYearCloseError, FiscalYearNotFoundError, FiscalYearReOpenError)
STATES = {
'readonly': Eval('state') != 'open',
}
class FiscalYear(Workflow, ModelSQL, ModelView):
__name__ = 'account.fiscalyear'
name = fields.Char('Name', size=None, required=True)
start_date = fields.Date(
"Start Date", required=True, states=STATES,
domain=[('start_date', '<=', Eval('end_date', None))])
end_date = fields.Date(
"End Date", required=True, states=STATES,
domain=[('end_date', '>=', Eval('start_date', None))])
periods = fields.One2Many('account.period', 'fiscalyear', 'Periods',
states=STATES,
domain=[
('company', '=', Eval('company', -1)),
],
order=[('start_date', 'ASC'), ('id', 'ASC')])
state = fields.Selection([
('open', 'Open'),
('closed', 'Closed'),
('locked', 'Locked'),
], 'State', readonly=True, required=True, sort=False)
move_sequence = fields.Many2One(
'ir.sequence.strict', "Move Sequence", required=True,
domain=[
('sequence_type', '=',
Id('account', 'sequence_type_account_move')),
('company', '=', Eval('company', -1)),
],
help="Used to generate the move number when posting "
"if the period has no sequence.")
company = fields.Many2One(
'company.company', "Company", required=True)
icon = fields.Function(fields.Char("Icon"), 'get_icon')
_find_cache = Cache(__name__ + '.find', context=False)
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls._sql_constraints += [
('dates_overlap',
Exclude(t,
(t.company, Equal),
(DateRange(t.start_date, t.end_date, '[]'), RangeOverlap),
),
'account.msg_fiscalyear_overlap'),
('open_earlier',
Exclude(t,
(t.company, Equal),
(DateRange(
Case(
(t.state == 'open', t.start_date), else_=Null),
t.end_date), RangeOverlap),
(Case((t.state == 'open', t.id), else_=-1), NotEqual)),
'account.msg_open_fiscalyear_earlier'),
('move_sequence_unique', Unique(t, t.move_sequence),
'account.msg_fiscalyear_move_sequence_unique'),
]
cls._order.insert(0, ('start_date', 'DESC'))
cls._transitions |= set((
('open', 'closed'),
('closed', 'locked'),
('closed', 'open'),
))
cls._buttons.update({
'create_periods': {
'invisible': ((Eval('state') != 'open')
| Eval('periods', [0])),
'depends': ['state'],
},
'close': {
'invisible': Eval('state') != 'open',
'depends': ['state'],
},
'reopen': {
'invisible': Eval('state') != 'closed',
'depends': ['state'],
},
'lock_': {
'invisible': Eval('state') != 'closed',
'depends': ['state'],
},
})
cls.__rpc__.update({
'create_period': RPC(readonly=False, instantiate=0),
})
@classmethod
def __register__(cls, module):
pool = Pool()
Period = pool.get('account.period')
Sequence = pool.get('ir.sequence')
SequenceStrict = pool.get('ir.sequence.strict')
table_h = cls.__table_handler__(module)
cursor = Transaction().connection.cursor()
t = cls.__table__()
migrate_move_sequence = not table_h.column_exist('move_sequence')
super().__register__(module)
# Migration from 6.8: rename state close to closed
cursor.execute(
*t.update([t.state], ['closed'], where=t.state == 'close'))
# Migrationn from 7.4: use strict sequence
if (table_h.column_exist('post_move_sequence')
and migrate_move_sequence):
table_h.not_null_action('post_move_sequence', 'remove')
period_h = Period.__table_handler__(module)
period = Period.__table__()
old2new = {}
period_migrated = (
period_h.column_exist('post_move_sequence')
and period_h.column_exist('move_sequence'))
if period_migrated:
cursor.execute(*period.select(
period.post_move_sequence, period.move_sequence))
old2new.update(cursor)
cursor.execute(*t.select(t.post_move_sequence, distinct=True))
for sequence_id, in cursor:
if sequence_id not in old2new:
sequence = Sequence(sequence_id)
new_sequence = SequenceStrict(
name=sequence.name,
sequence_type=sequence.sequence_type,
prefix=sequence.prefix,
suffix=sequence.suffix,
type=sequence.type,
number_next=sequence.number_next,
number_increment=sequence.number_increment,
padding=sequence.padding,
timestamp_rounding=sequence.timestamp_rounding,
timestamp_offset=sequence.timestamp_offset,
last_timestamp=sequence.last_timestamp,
company=sequence.company)
new_sequence.save()
old2new[sequence_id] = new_sequence.id
for old_id, new_id in old2new.items():
cursor.execute(*t.update(
[t.move_sequence], [new_id],
where=t.post_move_sequence == old_id))
if period_migrated:
table_h.drop_column('post_move_sequence')
period_h.drop_column('post_move_sequence')
@staticmethod
def default_state():
return 'open'
@staticmethod
def default_company():
return Transaction().context.get('company')
def get_icon(self, name):
return {
'open': 'tryton-account-open',
'closed': 'tryton-account-close',
'locked': 'tryton-account-block',
}.get(self.state)
@classmethod
def validate_fields(cls, fiscalyears, field_names):
super().validate_fields(fiscalyears, field_names)
cls.check_period_dates(fiscalyears, field_names)
@classmethod
def check_period_dates(cls, fiscalyears, field_names=None):
pool = Pool()
Period = pool.get('account.period')
if field_names and not (field_names & {'start_date', 'end_date'}):
return
periods = [p for f in fiscalyears for p in f.periods]
Period.check_fiscalyear_dates(periods, field_names={'fiscalyear'})
@classmethod
def check_modification(
cls, mode, fiscalyears, values=None, external=False):
pool = Pool()
Move = pool.get('account.move')
super().check_modification(
mode, fiscalyears, values=values, external=external)
if mode == 'write' and 'move_sequence' in values:
for fiscalyear in fiscalyears:
if sequence := fiscalyear.move_sequence:
if sequence.id != values['move_sequence']:
if Move.search([
('period.fiscalyear', '=', fiscalyear.id),
('state', '=', 'posted'),
], limit=1):
raise AccessError(
gettext('account.'
'msg_change_fiscalyear_move_sequence',
fiscalyear=fiscalyear.rec_name))
@classmethod
def on_modification(cls, mode, records, field_names=None):
super().on_modification(mode, records, field_names=field_names)
cls._find_cache.clear()
@classmethod
def create_period(cls, fiscalyears, interval=1, end_day=31):
'''
Create periods for the fiscal years with month interval
'''
Period = Pool().get('account.period')
to_create = []
for fiscalyear in fiscalyears:
period_start_date = fiscalyear.start_date
while period_start_date < fiscalyear.end_date:
month_offset = 1 if period_start_date.day < end_day else 0
period_end_date = (period_start_date
+ relativedelta(months=interval - month_offset)
+ relativedelta(day=end_day))
if period_end_date > fiscalyear.end_date:
period_end_date = fiscalyear.end_date
name = period_start_date.strftime('%Y-%m')
if name != period_end_date.strftime('%Y-%m'):
name += ' - ' + period_end_date.strftime('%Y-%m')
to_create.append({
'name': name,
'start_date': period_start_date,
'end_date': period_end_date,
'fiscalyear': fiscalyear.id,
'type': 'standard',
})
period_start_date = period_end_date + relativedelta(days=1)
if to_create:
Period.create(to_create)
@classmethod
@ModelView.button_action('account.act_create_periods')
def create_periods(cls, fiscalyears):
pass
@classmethod
def find(cls, company, date=None, test_state=True):
'''
Return the fiscal year for the company at the date or the current date
or raise FiscalYearNotFoundError.
If test_state is true, it searches on non-closed fiscal years
'''
pool = Pool()
Lang = pool.get('ir.lang')
Date = pool.get('ir.date')
Company = pool.get('company.company')
company_id = int(company) if company is not None else None
if not date:
with Transaction().set_context(company=company_id):
date = Date.today()
key = (company_id, date)
fiscalyear = cls._find_cache.get(key, -1)
if fiscalyear is not None and fiscalyear < 0:
clause = [
('start_date', '<=', date),
('end_date', '>=', date),
('company', '=', company_id),
]
fiscalyears = cls.search(
clause, order=[('start_date', 'DESC')], limit=1)
if fiscalyears:
fiscalyear, = fiscalyears
else:
fiscalyear = None
cls._find_cache.set(key, int(fiscalyear) if fiscalyear else None)
elif fiscalyear is not None:
fiscalyear = cls(fiscalyear)
found = fiscalyear and (not test_state or fiscalyear.state == 'open')
if not found:
lang = Lang.get()
if company is not None and not isinstance(company, Company):
company = Company(company)
if not fiscalyear:
raise FiscalYearNotFoundError(
gettext('account.msg_no_fiscalyear_date',
date=lang.strftime(date),
company=company.rec_name if company else ''))
else:
raise FiscalYearNotFoundError(
gettext('account.msg_no_open_fiscalyear_date',
date=lang.strftime(date),
fiscalyear=fiscalyear.rec_name,
company=company.rec_name if company else ''))
else:
return fiscalyear
def get_deferral(self, account):
'Computes deferrals for accounts'
pool = Pool()
Currency = pool.get('currency.currency')
Deferral = pool.get('account.account.deferral')
if not account.type:
return
if not account.deferral:
if not Currency.is_zero(self.company.currency, account.balance):
raise FiscalYearCloseError(
gettext('account'
'.msg_close_fiscalyear_account_balance_not_zero',
account=account.rec_name))
else:
deferral = Deferral()
deferral.account = account
deferral.fiscalyear = self
deferral.debit = account.debit
deferral.credit = account.credit
deferral.line_count = account.line_count
deferral.amount_second_currency = account.amount_second_currency
return deferral
@classmethod
@ModelView.button
@Workflow.transition('closed')
def close(cls, fiscalyears):
'''
Close a fiscal year
'''
pool = Pool()
Period = pool.get('account.period')
Account = pool.get('account.account')
Deferral = pool.get('account.account.deferral')
# Prevent create new fiscal year or period
cls.lock()
Period.lock()
deferrals = []
for fiscalyear in fiscalyears:
if cls.search([
('end_date', '<=', fiscalyear.start_date),
('state', '=', 'open'),
('company', '=', fiscalyear.company.id),
]):
raise FiscalYearCloseError(
gettext('account.msg_close_fiscalyear_earlier',
fiscalyear=fiscalyear.rec_name))
periods = Period.search([
('fiscalyear', '=', fiscalyear.id),
])
Period.close(periods)
with Transaction().set_context(fiscalyear=fiscalyear.id,
date=None, cumulate=True, journal=None):
accounts = Account.search([
('company', '=', fiscalyear.company.id),
])
for account in accounts:
deferral = fiscalyear.get_deferral(account)
if deferral:
deferrals.append(deferral)
Deferral.save(deferrals)
@classmethod
@ModelView.button
@Workflow.transition('open')
def reopen(cls, fiscalyears):
'''
Reopen a fiscal year
'''
Deferral = Pool().get('account.account.deferral')
for fiscalyear in fiscalyears:
if cls.search([
('start_date', '>=', fiscalyear.end_date),
('state', '!=', 'open'),
('company', '=', fiscalyear.company.id),
]):
raise FiscalYearReOpenError(
gettext('account.msg_reopen_fiscalyear_later',
fiscalyear=fiscalyear.rec_name))
deferrals = Deferral.search([
('fiscalyear', '=', fiscalyear.id),
])
Deferral.delete(deferrals)
@classmethod
@ModelView.button
@Workflow.transition('locked')
def lock_(cls, fiscalyears):
pool = Pool()
Period = pool.get('account.period')
periods = Period.search([
('fiscalyear', 'in', [f.id for f in fiscalyears]),
])
Period.lock_(periods)
class BalanceNonDeferralStart(ModelView):
__name__ = 'account.fiscalyear.balance_non_deferral.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True, domain=[('state', '=', 'open')])
company = fields.Function(fields.Many2One('company.company', 'Company'),
'on_change_with_company')
journal = fields.Many2One('account.journal', 'Journal', required=True,
domain=[
('type', '=', 'situation'),
],
context={
'company': Eval('company', -1),
},
depends={'company'})
period = fields.Many2One('account.period', 'Period', required=True,
domain=[
('fiscalyear', '=', Eval('fiscalyear', -1)),
('type', '=', 'adjustment'),
])
credit_account = fields.Many2One('account.account', 'Credit Account',
required=True,
domain=[
('type', '!=', None),
('closed', '!=', True),
('company', '=', Eval('company', -1)),
('deferral', '=', True),
])
debit_account = fields.Many2One('account.account', 'Debit Account',
required=True,
domain=[
('type', '!=', None),
('closed', '!=', True),
('company', '=', Eval('company', -1)),
('deferral', '=', True),
])
@fields.depends('fiscalyear')
def on_change_with_company(self, name=None):
return self.fiscalyear.company if self.fiscalyear else None
class BalanceNonDeferral(Wizard):
__name__ = 'account.fiscalyear.balance_non_deferral'
start = StateView('account.fiscalyear.balance_non_deferral.start',
'account.fiscalyear_balance_non_deferral_start_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('OK', 'balance', 'tryton-ok', default=True),
])
balance = StateAction('account.act_move_form')
def get_move_line(self, account):
pool = Pool()
Line = pool.get('account.move.line')
# Don't use account.balance because we need the non-commulated balance
balance = account.debit - account.credit
if account.company.currency.is_zero(balance):
return
line = Line()
line.account = account
if balance >= 0:
line.credit = abs(balance)
line.debit = 0
else:
line.credit = 0
line.debit = abs(balance)
return line
def get_counterpart_line(self, amount):
pool = Pool()
Line = pool.get('account.move.line')
if self.start.fiscalyear.company.currency.is_zero(amount):
return
line = Line()
if amount >= 0:
line.credit = abs(amount)
line.debit = 0
line.account = self.start.credit_account
else:
line.credit = 0
line.debit = abs(amount)
line.account = self.start.debit_account
return line
def create_move(self):
pool = Pool()
Account = pool.get('account.account')
Move = pool.get('account.move')
with Transaction().set_context(fiscalyear=self.start.fiscalyear.id,
date=None, cumulate=False):
accounts = Account.search([
('company', '=', self.start.fiscalyear.company.id),
('deferral', '=', False),
('type', '!=', None),
('closed', '!=', True),
])
lines = []
for account in accounts:
line = self.get_move_line(account)
if line:
lines.append(line)
if not lines:
return
amount = sum(l.debit - l.credit for l in lines)
counter_part_line = self.get_counterpart_line(amount)
if counter_part_line:
lines.append(counter_part_line)
move = Move()
move.period = self.start.period
move.journal = self.start.journal
move.date = self.start.period.start_date
move.origin = self.start.fiscalyear
move.lines = lines
move.save()
return move
def do_balance(self, action):
move = self.create_move()
if move:
action['views'].reverse()
return action, {'res_id': move.id if move else None}
class CreatePeriodsStart(ModelView):
__name__ = 'account.fiscalyear.create_periods.start'
frequency = fields.Selection([
('monthly', "Monthly"),
('quarterly', "Quarterly"),
('other', "Other"),
], "Frequency", sort=False, required=True)
interval = fields.Integer("Interval", required=True,
states={
'invisible': Eval('frequency') != 'other',
},
help="The length of each period, in months.")
end_day = fields.Integer("End Day", required=True,
help="The day of the month on which periods end.\n"
"Months with fewer days will end on the last day.")
@classmethod
def default_frequency(cls):
return 'monthly'
@classmethod
def default_end_day(cls):
return 31
@classmethod
def frequency_intervals(cls):
return {
'monthly': 1,
'quarterly': 3,
'other': None,
}
@fields.depends('frequency', 'interval')
def on_change_frequency(self):
if self.frequency:
self.interval = self.frequency_intervals()[self.frequency]
class CreatePeriods(Wizard):
__name__ = 'account.fiscalyear.create_periods'
start = StateView('account.fiscalyear.create_periods.start',
'account.fiscalyear_create_periods_start_view_form', [
Button("Cancel", 'end', 'tryton-cancel'),
Button("Create", 'create_periods', 'tryton-ok', default=True),
])
create_periods = StateTransition()
def transition_create_periods(self):
self.model.create_period(
[self.record], self.start.interval, self.start.end_day)
return 'end'
def month_delta(d1, d2):
month_offset = 1 if d1.day < d2.day else 0
return (d1.year - d2.year) * 12 + d1.month - d2.month - month_offset
class RenewFiscalYearStart(ModelView):
__name__ = 'account.fiscalyear.renew.start'
name = fields.Char("Name", required=True)
company = fields.Many2One('company.company', "Company", required=True)
previous_fiscalyear = fields.Many2One(
'account.fiscalyear', "Previous Fiscalyear", required=True,
domain=[
('company', '=', Eval('company', -1)),
],
help="Used as reference for fiscalyear configuration.")
start_date = fields.Date("Start Date", required=True)
end_date = fields.Date("End Date", required=True)
reset_sequences = fields.Boolean("Reset Sequences",
help="If checked, new sequences will be created.")
@classmethod
def default_company(cls):
return Transaction().context.get('company')
@classmethod
def default_previous_fiscalyear(cls):
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
fiscalyears = FiscalYear.search([
('company', '=', cls.default_company() or -1),
],
order=[('end_date', 'DESC')], limit=1)
if fiscalyears:
fiscalyear, = fiscalyears
return fiscalyear.id
@classmethod
def default_reset_sequences(cls):
return True
@fields.depends('previous_fiscalyear')
def on_change_previous_fiscalyear(self):
if self.previous_fiscalyear:
fiscalyear = self.previous_fiscalyear
months = month_delta(
fiscalyear.end_date, fiscalyear.start_date) + 1
self.start_date = fiscalyear.start_date + relativedelta(
months=months, day=fiscalyear.start_date.day)
self.end_date = fiscalyear.end_date + relativedelta(
months=months, day=fiscalyear.end_date.day)
self.name = fiscalyear.name.replace(
str(fiscalyear.end_date.year),
str(self.end_date.year)).replace(
str(fiscalyear.start_date.year),
str(self.start_date.year))
class RenewFiscalYear(Wizard):
__name__ = 'account.fiscalyear.renew'
start = StateView('account.fiscalyear.renew.start',
'account.fiscalyear_renew_start_view_form', [
Button("Cancel", 'end', 'tryton-cancel'),
Button("Create", 'create_', 'tryton-ok', default=True),
])
create_ = StateAction('account.act_fiscalyear_form')
def fiscalyear_defaults(self):
pool = Pool()
Sequence = pool.get('ir.sequence.strict')
defaults = {
'name': self.start.name,
'start_date': self.start.start_date,
'end_date': self.start.end_date,
'periods': [],
}
previous_sequence = self.start.previous_fiscalyear.move_sequence
sequence, = Sequence.copy([previous_sequence],
default={
'name': lambda data: data['name'].replace(
self.start.previous_fiscalyear.name,
self.start.name)
})
if self.start.reset_sequences:
sequence.number_next = 1
else:
sequence.number_next = previous_sequence.number_next
sequence.save()
defaults['move_sequence'] = sequence.id
return defaults
def create_fiscalyear(self):
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
fiscalyear, = FiscalYear.copy(
[self.start.previous_fiscalyear],
default=self.fiscalyear_defaults())
periods = [
p for p in self.start.previous_fiscalyear.periods
if p.type == 'standard']
if periods:
months = month_delta(fiscalyear.end_date, fiscalyear.start_date)
months += 1
interval = months / len(periods)
end_day = max(
p.end_date.day
for p in self.start.previous_fiscalyear.periods
if p.type == 'standard')
if interval.is_integer():
FiscalYear.create_period([fiscalyear], interval, end_day)
return fiscalyear
def do_create_(self, action):
fiscalyear = self.create_fiscalyear()
fiscalyear.save()
action['views'].reverse()
return action, {'res_id': fiscalyear.id}

View File

@@ -0,0 +1,168 @@
<?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. -->
<tryton>
<data>
<menuitem
name="Fiscal Years"
parent="menu_account_configuration"
sequence="30"
id="menu_fiscalyear_configuration"/>
<record model="ir.ui.view" id="fiscalyear_view_form">
<field name="model">account.fiscalyear</field>
<field name="type">form</field>
<field name="name">fiscalyear_form</field>
</record>
<record model="ir.ui.view" id="fiscalyear_view_tree">
<field name="model">account.fiscalyear</field>
<field name="type">tree</field>
<field name="name">fiscalyear_tree</field>
</record>
<record model="ir.ui.view" id="fiscalyear_view_list_close">
<field name="model">account.fiscalyear</field>
<field name="type">tree</field>
<field name="name">fiscalyear_list_close</field>
</record>
<record model="ir.action.act_window" id="act_fiscalyear_form">
<field name="name">Fiscal Years</field>
<field name="res_model">account.fiscalyear</field>
</record>
<record model="ir.action.act_window.view" id="act_fiscalyear_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="fiscalyear_view_tree"/>
<field name="act_window" ref="act_fiscalyear_form"/>
</record>
<record model="ir.action.act_window.view" id="act_fiscalyear_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="fiscalyear_view_form"/>
<field name="act_window" ref="act_fiscalyear_form"/>
</record>
<menuitem
parent="menu_fiscalyear_configuration"
action="act_fiscalyear_form"
sequence="10"
id="menu_fiscalyear_form"/>
<record model="ir.model.access" id="access_fiscalyear">
<field name="model">account.fiscalyear</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_fiscalyear_account_admin">
<field name="model">account.fiscalyear</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.button" id="fiscalyear_create_periods_button">
<field name="model">account.fiscalyear</field>
<field name="name">create_periods</field>
<field name="string">Create Periods</field>
</record>
<record model="ir.model.button" id="fiscalyear_reopen_button">
<field name="model">account.fiscalyear</field>
<field name="name">reopen</field>
<field name="string">Reopen</field>
</record>
<record model="ir.model.button" id="fiscalyear_close_button">
<field name="model">account.fiscalyear</field>
<field name="name">close</field>
<field name="string">Close</field>
</record>
<record model="ir.model.button" id="fiscalyear_lock_button">
<field name="model">account.fiscalyear</field>
<field name="name">lock_</field>
<field name="string">Lock</field>
<field name="confirm">Are you sure you want to lock the fiscal year?</field>
</record>
<record model="ir.rule.group" id="rule_group_fiscalyear_companies">
<field name="name">User in companies</field>
<field name="model">account.fiscalyear</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_fiscalyear_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_fiscalyear_companies"/>
</record>
<record model="ir.action.act_window" id="act_fiscalyear_form_close">
<field name="name">Close Fiscal Years</field>
<field name="res_model">account.fiscalyear</field>
<field name="search_value"
eval="[('state', '=', 'open')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_fiscalyear_form_close_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="fiscalyear_view_list_close"/>
<field name="act_window" ref="act_fiscalyear_form_close"/>
</record>
<menuitem
parent="menu_processing"
action="act_fiscalyear_form_close"
sequence="50"
id="menu_close_fiscalyear"/>
<record model="ir.ui.view" id="fiscalyear_create_periods_start_view_form">
<field name="model">account.fiscalyear.create_periods.start</field>
<field name="type">form</field>
<field name="name">fiscalyear_create_periods_start_form</field>
</record>
<record model="ir.action.wizard" id="act_create_periods">
<field name="name">Create Periods</field>
<field name="wiz_name">account.fiscalyear.create_periods</field>
</record>
<record model="ir.ui.view"
id="fiscalyear_balance_non_deferral_start_view_form">
<field
name="model">account.fiscalyear.balance_non_deferral.start</field>
<field name="type">form</field>
<field
name="name">fiscalyear_balance_non_deferral_start_form</field>
</record>
<record model="ir.action.wizard" id="act_balance_non_deferral">
<field name="name">Balance Non-Deferral</field>
<field
name="wiz_name">account.fiscalyear.balance_non_deferral</field>
</record>
<menuitem
parent="menu_processing"
action="act_balance_non_deferral"
sequence="40"
id="menu_balance_non_deferral"/>
<record model="ir.ui.view" id="fiscalyear_renew_start_view_form">
<field name="model">account.fiscalyear.renew.start</field>
<field name="type">form</field>
<field name="name">renew_fiscalyear_start_form</field>
</record>
<record model="ir.action.wizard" id="act_renew_fiscalyear">
<field name="name">Renew Fiscal Year</field>
<field name="wiz_name">account.fiscalyear.renew</field>
</record>
<record model="ir.action-res.group"
id="act_renew_fiscalyear_group_admin">
<field name="action" ref="act_renew_fiscalyear"/>
<field name="group" ref="group_account_admin"/>
</record>
<menuitem
parent="menu_fiscalyear_configuration"
action="act_renew_fiscalyear"
sequence="90"
id="menu_renew_fiscalyear"/>
</data>
</tryton>

View File

@@ -0,0 +1,603 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ooo="http://openoffice.org/2004/office" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:rpt="http://openoffice.org/2005/report" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta><meta:generator>LibreOffice/6.4.7.2$Linux_X86_64 LibreOffice_project/40$Build-2</meta:generator><meta:creation-date>2012-11-14T22:45:37</meta:creation-date><meta:editing-cycles>1</meta:editing-cycles><meta:editing-duration>P0D</meta:editing-duration><meta:document-statistic meta:table-count="3" meta:image-count="0" meta:object-count="0" meta:page-count="1" meta:paragraph-count="34" meta:word-count="76" meta:character-count="875" meta:non-whitespace-character-count="832"/><meta:user-defined meta:name="Info 1"/><meta:user-defined meta:name="Info 2"/><meta:user-defined meta:name="Info 3"/><meta:user-defined meta:name="Info 4"/></office:meta>
<office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item config:name="ViewAreaTop" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaWidth" config:type="long">25640</config:config-item>
<config:config-item config:name="ViewAreaHeight" config:type="long">23021</config:config-item>
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
<config:config-item-map-indexed config:name="Views">
<config:config-item-map-entry>
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
<config:config-item config:name="ViewLeft" config:type="long">13259</config:config-item>
<config:config-item config:name="ViewTop" config:type="long">10862</config:config-item>
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleTop" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleRight" config:type="long">25638</config:config-item>
<config:config-item config:name="VisibleBottom" config:type="long">23019</config:config-item>
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutColumns" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
<config:config-item config:name="ZoomFactor" config:type="short">100</config:config-item>
<config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
<config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">false</config:config-item>
</config:config-item-map-entry>
</config:config-item-map-indexed>
</config:config-item-set>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">false</config:config-item>
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyUserData" config:type="boolean">false</config:config-item>
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="Rsid" config:type="int">2105963</config:config-item>
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterName" config:type="string"/>
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
<config:config-item config:name="RsidRoot" config:type="int">991389</config:config-item>
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintFaxName" config:type="string"/>
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
</config:config-item-set>
</office:settings>
<office:scripts>
<office:script script:language="ooo:Basic">
<ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</office:script>
</office:scripts>
<office:font-face-decls>
<style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/>
<style:font-face style:name="Liberation Serif1" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Bold" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Regular" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Thorndale AMT" svg:font-family="&apos;Thorndale AMT&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Andale Sans UI" svg:font-family="&apos;Andale Sans UI&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="graphic">
<style:graphic-properties svg:stroke-color="#000000" draw:fill-color="#99ccff" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
<style:tab-stops/>
</style:paragraph-properties>
<style:text-properties style:use-window-font-color="true" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"/>
</style:default-style>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="lr-tb"/>
<style:text-properties style:use-window-font-color="true" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/>
</style:default-style>
<style:default-style style:family="table">
<style:table-properties table:border-model="collapsing"/>
</style:default-style>
<style:default-style style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" loext:contextual-spacing="false" fo:keep-with-next="always"/>
<style:text-properties style:font-name="Liberation Serif" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Regular" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="16pt" style:font-name-asian="DejaVu Sans" style:font-family-asian="&apos;DejaVu Sans&apos;" style:font-family-generic-asian="system" style:font-pitch-asian="variable" style:font-size-asian="14pt" style:font-name-complex="DejaVu Sans" style:font-family-complex="&apos;DejaVu Sans&apos;" style:font-family-generic-complex="system" style:font-pitch-complex="variable" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.212cm" loext:contextual-spacing="false"/>
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="List" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="list">
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties fo:margin-top="0.212cm" fo:margin-bottom="0.212cm" loext:contextual-spacing="false" text:number-lines="false" text:line-number="0"/>
<style:text-properties fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-size-complex="12pt" style:font-style-complex="italic"/>
</style:style>
<style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="16pt" fo:font-weight="bold" style:font-size-asian="115%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Table_20_Heading" style:display-name="Table Heading" style:family="paragraph" style:parent-style-name="Table_20_Contents" style:class="extra">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-name="Liberation Serif1" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Bold" style:font-family-generic="roman" style:font-pitch="variable" fo:font-weight="bold" style:font-size-asian="10.5pt" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Header_20_and_20_Footer" style:display-name="Header and Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.5cm" style:type="center"/>
<style:tab-stop style:position="17cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="Header" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_2" style:display-name="Heading 2" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="14pt" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-style-complex="italic" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_3" style:display-name="Heading 3" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-weight="bold" style:font-size-asian="14pt" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Text_20_body_20_indent" style:display-name="Text body indent" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-left="0.499cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" loext:contextual-spacing="false" fo:text-indent="0cm" style:auto-text-indent="false"/>
</style:style>
<style:style style:name="Header_20_right" style:display-name="Header right" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="Header_20_left" style:display-name="Header left" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="Placeholder" style:family="text">
<style:text-properties fo:font-variant="small-caps" fo:color="#008080" style:text-underline-style="dotted" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="Bullet_20_Symbols" style:display-name="Bullet Symbols" style:family="text">
<style:text-properties style:font-name="StarSymbol" fo:font-family="StarSymbol" fo:font-size="9pt" style:font-name-asian="StarSymbol" style:font-family-asian="StarSymbol" style:font-size-asian="9pt" style:font-name-complex="StarSymbol" style:font-family-complex="StarSymbol" style:font-size-complex="9pt"/>
</style:style>
<text:outline-style style:name="Outline">
<text:outline-level-style text:level="1" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="2" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="3" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="4" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="5" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="6" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="7" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="8" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="9" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="10" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
</text:outline-style>
<text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
<text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
<text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
</office:styles>
<office:automatic-styles>
<style:style style:name="Table3" style:family="table">
<style:table-properties style:width="17.59cm" table:align="margins"/>
</style:style>
<style:style style:name="Table3.A" style:family="table-column">
<style:table-column-properties style:column-width="5.863cm" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table3.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="transparent" fo:padding="0.097cm" fo:border="none">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="17.59cm" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="8.795cm" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table2.B" style:family="table-column">
<style:table-column-properties style:column-width="8.795cm" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border="none"/>
</style:style>
<style:style style:name="Table3" style:family="table">
<style:table-properties style:width="17.59cm" table:align="margins"/>
</style:style>
<style:style style:name="Table3.A" style:family="table-column">
<style:table-column-properties style:column-width="5.863cm" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table3.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="transparent" fo:padding="0.097cm" fo:border="none">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="17.59cm" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="8.795cm" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table2.B" style:family="table-column">
<style:table-column-properties style:column-width="8.795cm" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border="none"/>
</style:style>
<style:style style:name="Table4" style:family="table">
<style:table-properties style:width="17.59cm" fo:margin-top="0.4cm" fo:margin-bottom="0cm" table:align="margins" fo:background-color="transparent" style:may-break-between-rows="false">
<style:background-image/>
</style:table-properties>
</style:style>
<style:style style:name="Table4.A" style:family="table-column">
<style:table-column-properties style:column-width="3.517cm" style:rel-column-width="13107*"/>
</style:style>
<style:style style:name="Table4.1" style:family="table-row">
<style:table-row-properties fo:background-color="transparent">
<style:background-image/>
</style:table-row-properties>
</style:style>
<style:style style:name="Table4.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="" fo:background-color="#cccccc" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="none" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.B1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.049cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="none" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.C1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.049cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="none" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.D1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.049cm" fo:border-left="none" fo:border-right="0.05pt solid #000000" fo:border-top="0.05pt solid #000000" fo:border-bottom="none" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.A2" style:family="table-cell">
<style:table-cell-properties style:vertical-align="middle" fo:background-color="#cccccc" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.A3" style:family="table-cell">
<style:table-cell-properties fo:background-color="#dddddd" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.D3" style:family="table-cell">
<style:table-cell-properties fo:background-color="#dddddd" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.E3" style:family="table-cell">
<style:table-cell-properties fo:background-color="#dddddd" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table4.A4" style:family="table-cell">
<style:table-cell-properties fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page"/>
</style:style>
<style:style style:name="Table4.A5" style:family="table-cell">
<style:table-cell-properties fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page"/>
</style:style>
<style:style style:name="Table4.D5" style:family="table-cell">
<style:table-cell-properties style:vertical-align="middle" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page"/>
</style:style>
<style:style style:name="Table4.E5" style:family="table-cell">
<style:table-cell-properties style:vertical-align="middle" fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page"/>
</style:style>
<style:style style:name="Table4.A6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.049cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="page"/>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P2" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P3" style:family="paragraph" style:parent-style-name="Footer">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P4" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:text-properties fo:font-size="12pt" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P5" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties officeooo:paragraph-rsid="001e5148"/>
</style:style>
<style:style style:name="P6" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P7" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" officeooo:paragraph-rsid="001960ab" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" officeooo:paragraph-rsid="001b5738" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P9" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P10" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" officeooo:paragraph-rsid="001b5738" style:font-size-asian="12pt" style:font-size-complex="12pt"/>
</style:style>
<style:style style:name="P11" style:family="paragraph" style:parent-style-name="Heading_20_1">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="P12" style:family="paragraph" style:parent-style-name="Heading_20_1">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="Sect1" style:family="section">
<style:section-properties style:editable="false">
<style:columns fo:column-count="1" fo:column-gap="0cm"/>
</style:section-properties>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="21.59cm" fo:page-height="27.94cm" style:num-format="1" style:print-orientation="portrait" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="44" style:layout-grid-base-height="0.55cm" style:layout-grid-ruby-height="0cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="true" style:layout-grid-display="true" style:footnote-max-height="0cm">
<style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="none" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
</style:page-layout-properties>
<style:header-style>
<style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-bottom="0.499cm"/>
</style:header-style>
<style:footer-style>
<style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.499cm"/>
</style:footer-style>
</style:page-layout>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1">
<style:header>
<table:table table:name="Table3" table:style-name="Table3">
<table:table-column table:style-name="Table3.A" table:number-columns-repeated="3"/>
<table:table-row table:style-name="TableLine94266545094448">
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="Header">Company: <text:placeholder text:placeholder-type="text">&lt;company.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="P1">General Journal</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A1" office:value-type="string">
<text:p text:style-name="P2">Print Date: <text:placeholder text:placeholder-type="text">&lt;format_date(datetime.date.today(), user.language)&gt;</text:placeholder><text:s/>at <text:placeholder text:placeholder-type="text">&lt;datetime.datetime.now().strftime(&apos;%H:%M:%S&apos;)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:header>
<style:footer>
<table:table table:name="Table2" table:style-name="Table2">
<table:table-column table:style-name="Table2.A"/>
<table:table-column table:style-name="Table2.B"/>
<table:table-row table:style-name="TableLine94266545229984">
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="Footer">User: <text:placeholder text:placeholder-type="text">&lt;user.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="P3"><text:page-number text:select-page="current">1</text:page-number>/<text:page-count>1</text:page-count></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:footer>
</style:master-page>
</office:master-styles>
<office:body>
<office:text>
<office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
<text:sequence-decls>
<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
<text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
</text:sequence-decls>
<text:p text:style-name="P11">General Journal</text:p>
<text:section text:style-name="Sect1" text:name="Section1">
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;move in records&quot;&gt;</text:placeholder></text:p>
<table:table table:name="Table4" table:style-name="Table4">
<table:table-column table:style-name="Table4.A" table:number-columns-repeated="5"/>
<table:table-header-rows>
<table:table-row table:style-name="Table4.1">
<table:table-cell table:style-name="Table4.A1" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Journal Entry:<text:line-break/><text:placeholder text:placeholder-type="text">&lt;move.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table4.C1" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Date:<text:line-break/> <text:placeholder text:placeholder-type="text">&lt;format_date(move.date, user.language)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table4.C1" office:value-type="string">
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;move.origin&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading">Origin:<text:line-break/><text:placeholder text:placeholder-type="text">&lt;getattr(move.origin, &apos;rec_name&apos;, &apos;&apos;)&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table4.D1" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;move.state == &apos;posted&apos;&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading">Posted<text:line-break/><text:placeholder text:placeholder-type="text">&lt;format_date(move.post_date, user.language)&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;move.state == &apos;draft&apos;&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="Table_20_Heading">Draft</text:p>
<text:p text:style-name="Table_20_Heading"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Table4.1">
<table:table-cell table:style-name="Table4.A2" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="P5"><text:placeholder text:placeholder-type="text">&lt;move.description&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Table4.1">
<table:table-cell table:style-name="Table4.A3" table:number-columns-spanned="3" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Account</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:table-cell table:style-name="Table4.D3" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Debit</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table4.E3" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Credit</text:p>
</table:table-cell>
</table:table-row>
</table:table-header-rows>
<table:table-row table:style-name="TableLine94266545333792">
<table:table-cell table:style-name="Table4.A4" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;line in move.lines&quot;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="TableLine94266545335008">
<table:table-cell table:style-name="Table4.A5" table:number-columns-spanned="3" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;line.account.rec_name&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;line.party&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;&apos;[%s] %s&apos; % (line.party.code, line.party.name)&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;line.description&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;line.description&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:table-cell table:style-name="Table4.D5" office:value-type="string">
<text:p text:style-name="P10"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.debit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table4.E5" office:value-type="string">
<text:p text:style-name="P10"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.credit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="TableLine94266545337328">
<table:table-cell table:style-name="Table4.A6" table:number-columns-spanned="5" office:value-type="string">
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
</table:table>
<text:p text:style-name="Text_20_body"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</text:section>
</office:text>
</office:body>
</office:document>

View File

@@ -0,0 +1,979 @@
<?xml version="1.0" encoding="UTF-8"?>
<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
<office:meta><meta:generator>LibreOffice/7.3.5.2$Linux_X86_64 LibreOffice_project/30$Build-2</meta:generator><meta:creation-date>2008-06-07T15:26:41</meta:creation-date><dc:date>2008-08-27T17:03:36</dc:date><meta:editing-cycles>1</meta:editing-cycles><meta:editing-duration>PT0S</meta:editing-duration><meta:document-statistic meta:table-count="4" meta:image-count="0" meta:object-count="0" meta:page-count="3" meta:paragraph-count="51" meta:word-count="145" meta:character-count="1808" meta:non-whitespace-character-count="1714"/><meta:user-defined meta:name="Info 1"/><meta:user-defined meta:name="Info 2"/><meta:user-defined meta:name="Info 3"/><meta:user-defined meta:name="Info 4"/></office:meta>
<office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item config:name="ViewAreaTop" config:type="long">24130</config:config-item>
<config:config-item config:name="ViewAreaLeft" config:type="long">0</config:config-item>
<config:config-item config:name="ViewAreaWidth" config:type="long">48129</config:config-item>
<config:config-item config:name="ViewAreaHeight" config:type="long">22994</config:config-item>
<config:config-item config:name="ShowRedlineChanges" config:type="boolean">true</config:config-item>
<config:config-item config:name="InBrowseMode" config:type="boolean">false</config:config-item>
<config:config-item-map-indexed config:name="Views">
<config:config-item-map-entry>
<config:config-item config:name="ViewId" config:type="string">view2</config:config-item>
<config:config-item config:name="ViewLeft" config:type="long">19627</config:config-item>
<config:config-item config:name="ViewTop" config:type="long">29242</config:config-item>
<config:config-item config:name="VisibleLeft" config:type="long">0</config:config-item>
<config:config-item config:name="VisibleTop" config:type="long">24130</config:config-item>
<config:config-item config:name="VisibleRight" config:type="long">48128</config:config-item>
<config:config-item config:name="VisibleBottom" config:type="long">47122</config:config-item>
<config:config-item config:name="ZoomType" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutColumns" config:type="short">0</config:config-item>
<config:config-item config:name="ViewLayoutBookMode" config:type="boolean">false</config:config-item>
<config:config-item config:name="ZoomFactor" config:type="short">100</config:config-item>
<config:config-item config:name="IsSelectedFrame" config:type="boolean">false</config:config-item>
<config:config-item config:name="KeepRatio" config:type="boolean">false</config:config-item>
<config:config-item config:name="AnchoredTextOverflowLegacy" config:type="boolean">false</config:config-item>
</config:config-item-map-entry>
</config:config-item-map-indexed>
</config:config-item-set>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item config:name="PrintProspect" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintReversed" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintSingleJobs" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintLeftPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintTables" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintControls" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintPageBackground" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintDrawings" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrintBlackFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintAnnotationMode" config:type="short">0</config:config-item>
<config:config-item config:name="PrintTextPlaceholder" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectFields" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectBookmarks" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmptyDbFieldHidesPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="DisableOffPagePositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="SubtractFlysAnchoredAtFlys" config:type="boolean">true</config:config-item>
<config:config-item config:name="PropLineSpacingShrinksFirstLine" config:type="boolean">false</config:config-item>
<config:config-item config:name="ApplyParagraphMarkFormatToNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="GutterAtTop" config:type="boolean">false</config:config-item>
<config:config-item config:name="TreatSingleColumnBreakAsPageBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedSystemFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedComplexScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedAsianScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedLatinScriptFonts" config:type="boolean">true</config:config-item>
<config:config-item config:name="EmbedOnlyUsedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="ContinuousEndnotes" config:type="boolean">false</config:config-item>
<config:config-item config:name="EmbedFonts" config:type="boolean">false</config:config-item>
<config:config-item config:name="ClippedPictures" config:type="boolean">false</config:config-item>
<config:config-item config:name="FloattableNomargins" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnbreakableNumberings" config:type="boolean">false</config:config-item>
<config:config-item config:name="HeaderSpacingBelowLastPara" config:type="boolean">false</config:config-item>
<config:config-item config:name="AllowPrintJobCancel" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseOldPrinterMetrics" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabOverMargin" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabsRelativeToIndent" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseOldNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="InvertBorderSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="UpdateFromTemplate" config:type="boolean">true</config:config-item>
<config:config-item config:name="CurrentDatabaseCommandType" config:type="int">0</config:config-item>
<config:config-item config:name="LinkUpdateMode" config:type="short">1</config:config-item>
<config:config-item config:name="AddParaSpacingToTableCells" config:type="boolean">true</config:config-item>
<config:config-item config:name="FrameAutowidthWithMorePara" config:type="boolean">false</config:config-item>
<config:config-item config:name="CurrentDatabaseCommand" config:type="string"/>
<config:config-item config:name="PrinterIndependentLayout" config:type="string">high-resolution</config:config-item>
<config:config-item config:name="ApplyUserData" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintFaxName" config:type="string"/>
<config:config-item config:name="CurrentDatabaseDataSource" config:type="string"/>
<config:config-item config:name="ClipAsCharacterAnchoredWriterFlyFrames" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsKernAsianPunctuation" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveThumbnail" config:type="boolean">true</config:config-item>
<config:config-item config:name="UseFormerTextWrapping" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddExternalLeading" config:type="boolean">true</config:config-item>
<config:config-item config:name="AddParaTableSpacing" config:type="boolean">true</config:config-item>
<config:config-item config:name="StylesNoDefault" config:type="boolean">false</config:config-item>
<config:config-item config:name="ChartAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="PrinterSetup" config:type="base64Binary"/>
<config:config-item config:name="AddParaTableSpacingAtStart" config:type="boolean">true</config:config-item>
<config:config-item config:name="Rsid" config:type="int">4069242</config:config-item>
<config:config-item config:name="EmbeddedDatabaseName" config:type="string"/>
<config:config-item config:name="FieldAutoUpdate" config:type="boolean">true</config:config-item>
<config:config-item config:name="OutlineLevelYieldsNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="FootnoteInColumnToPageEnd" config:type="boolean">true</config:config-item>
<config:config-item config:name="AlignTabStopPosition" config:type="boolean">true</config:config-item>
<config:config-item config:name="CharacterCompressionType" config:type="short">0</config:config-item>
<config:config-item config:name="PrinterName" config:type="string"/>
<config:config-item config:name="SaveGlobalDocumentLinks" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrinterPaperFromSetup" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerLineSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddParaLineSpacingToTableCells" config:type="boolean">false</config:config-item>
<config:config-item config:name="UseFormerObjectPositioning" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintGraphics" config:type="boolean">true</config:config-item>
<config:config-item config:name="SurroundTextWrapSmall" config:type="boolean">false</config:config-item>
<config:config-item config:name="ConsiderTextWrapOnObjPos" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompTrailingBlanks" config:type="boolean">false</config:config-item>
<config:config-item config:name="TabAtLeftIndentForParagraphsInList" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintRightPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabOverSpacing" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreFirstLineIndentInNumbering" config:type="boolean">false</config:config-item>
<config:config-item config:name="RedlineProtectionKey" config:type="base64Binary"/>
<config:config-item config:name="DoNotJustifyLinesWithManualBreak" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintProspectRTL" config:type="boolean">false</config:config-item>
<config:config-item config:name="PrintEmptyPages" config:type="boolean">true</config:config-item>
<config:config-item config:name="DoNotResetParaAttrsForNumFont" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="IgnoreTabsAndBlanksForLineCalculation" config:type="boolean">false</config:config-item>
<config:config-item config:name="LoadReadonly" config:type="boolean">false</config:config-item>
<config:config-item config:name="DoNotCaptureDrawObjsOnPage" config:type="boolean">false</config:config-item>
<config:config-item config:name="AddVerticalFrameOffsets" config:type="boolean">false</config:config-item>
<config:config-item config:name="UnxForceZeroExtLeading" config:type="boolean">false</config:config-item>
<config:config-item config:name="IsLabelDocument" config:type="boolean">false</config:config-item>
<config:config-item config:name="TableRowKeep" config:type="boolean">false</config:config-item>
<config:config-item config:name="RsidRoot" config:type="int">2070049</config:config-item>
<config:config-item config:name="PrintHiddenText" config:type="boolean">false</config:config-item>
<config:config-item config:name="ProtectForm" config:type="boolean">false</config:config-item>
<config:config-item config:name="MsWordCompMinLineHeightByFly" config:type="boolean">false</config:config-item>
<config:config-item config:name="BackgroundParaOverDrawings" config:type="boolean">false</config:config-item>
<config:config-item config:name="SaveVersionOnClose" config:type="boolean">false</config:config-item>
<config:config-item config:name="MathBaselineAlignment" config:type="boolean">false</config:config-item>
<config:config-item config:name="SmallCapsPercentage66" config:type="boolean">true</config:config-item>
<config:config-item config:name="CollapseEmptyCellPara" config:type="boolean">true</config:config-item>
<config:config-item config:name="TabOverflow" config:type="boolean">false</config:config-item>
</config:config-item-set>
</office:settings>
<office:scripts>
<office:script script:language="ooo:Basic">
<ooo:libraries xmlns:ooo="http://openoffice.org/2004/office" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</office:script>
</office:scripts>
<office:font-face-decls>
<style:font-face style:name="Andale Sans UI" svg:font-family="&apos;Andale Sans UI&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="DejaVu Sans" svg:font-family="&apos;DejaVu Sans&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-adornments="Regular" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif1" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Bold" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif2" svg:font-family="&apos;Liberation Serif&apos;" style:font-adornments="Regular" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="StarSymbol" svg:font-family="StarSymbol"/>
<style:font-face style:name="Thorndale AMT" svg:font-family="&apos;Thorndale AMT&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
</office:font-face-decls>
<office:styles>
<style:default-style style:family="graphic">
<style:graphic-properties svg:stroke-color="#000000" draw:fill-color="#99ccff" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
<style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
<style:tab-stops/>
</style:paragraph-properties>
<style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none"/>
</style:default-style>
<style:default-style style:family="paragraph">
<style:paragraph-properties fo:hyphenation-ladder-count="no-limit" style:text-autospace="ideograph-alpha" style:punctuation-wrap="hanging" style:line-break="strict" style:tab-stop-distance="1.251cm" style:writing-mode="lr-tb"/>
<style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Thorndale AMT" fo:font-size="12pt" fo:language="en" fo:country="US" style:letter-kerning="true" style:font-name-asian="Andale Sans UI" style:font-size-asian="10.5pt" style:language-asian="zxx" style:country-asian="none" style:font-name-complex="Andale Sans UI" style:font-size-complex="12pt" style:language-complex="zxx" style:country-complex="none" fo:hyphenate="false" fo:hyphenation-remain-char-count="2" fo:hyphenation-push-char-count="2" loext:hyphenation-no-caps="false"/>
</style:default-style>
<style:default-style style:family="table">
<style:table-properties table:border-model="collapsing"/>
</style:default-style>
<style:default-style style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:default-style>
<style:style style:name="Standard" style:family="paragraph" style:class="text">
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false" fo:keep-with-next="always"/>
<style:text-properties style:font-name="Liberation Serif2" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Regular" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="16pt" style:font-name-asian="DejaVu Sans" style:font-family-asian="&apos;DejaVu Sans&apos;" style:font-family-generic-asian="system" style:font-pitch-asian="variable" style:font-size-asian="14pt" style:font-name-complex="DejaVu Sans" style:font-family-complex="&apos;DejaVu Sans&apos;" style:font-family-generic-complex="system" style:font-pitch-complex="variable" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="Text_20_body" style:display-name="Text body" style:family="paragraph" style:parent-style-name="Standard" style:class="text">
<style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false"/>
<style:text-properties style:font-name="Liberation Sans" fo:font-family="&apos;Liberation Sans&apos;" style:font-style-name="Regular" style:font-family-generic="swiss" style:font-pitch="variable" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="List" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="list">
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Caption" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties fo:margin-top="0.212cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false" text:number-lines="false" text:line-number="0"/>
<style:text-properties fo:font-size="12pt" fo:font-style="italic" style:font-size-asian="12pt" style:font-style-asian="italic" style:font-size-complex="12pt" style:font-style-complex="italic"/>
</style:style>
<style:style style:name="Index" style:family="paragraph" style:parent-style-name="Standard" style:class="index">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-size-asian="12pt"/>
</style:style>
<style:style style:name="Table_20_Contents" style:display-name="Table Contents" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0"/>
<style:text-properties fo:font-size="11pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="16pt" fo:font-weight="bold" style:font-size-asian="115%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Table_20_Heading" style:display-name="Table Heading" style:family="paragraph" style:parent-style-name="Table_20_Contents" style:class="extra">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" text:number-lines="false" text:line-number="0"/>
<style:text-properties style:font-name="Liberation Serif1" fo:font-family="&apos;Liberation Serif&apos;" style:font-style-name="Bold" style:font-family-generic="roman" style:font-pitch="variable" fo:font-size="12pt" fo:font-weight="bold" style:font-size-asian="10.5pt" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Horizontal_20_Line" style:display-name="Horizontal Line" style:family="paragraph" style:parent-style-name="Standard" style:next-style-name="Text_20_body" style:class="html">
<style:paragraph-properties fo:margin-top="0cm" fo:margin-bottom="0.499cm" style:contextual-spacing="false" style:border-line-width-bottom="0.002cm 0.035cm 0.002cm" fo:padding="0cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="1.11pt double #808080" text:number-lines="false" text:line-number="0" style:join-border="false"/>
<style:text-properties fo:font-size="6pt" style:font-size-asian="6pt" style:font-size-complex="6pt"/>
</style:style>
<style:style style:name="Header_20_and_20_Footer" style:display-name="Header and Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.5cm" style:type="center"/>
<style:tab-stop style:position="17cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="Header" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_2" style:display-name="Heading 2" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-style="italic" fo:font-weight="bold" style:font-size-asian="14pt" style:font-style-asian="italic" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-style-complex="italic" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Footer" style:family="paragraph" style:parent-style-name="Standard" style:class="extra">
<style:paragraph-properties text:number-lines="false" text:line-number="0">
<style:tab-stops>
<style:tab-stop style:position="8.795cm" style:type="center"/>
<style:tab-stop style:position="17.59cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="Heading_20_3" style:display-name="Heading 3" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="text">
<style:text-properties fo:font-size="14pt" fo:font-weight="bold" style:font-size-asian="14pt" style:font-weight-asian="bold" style:font-size-complex="14pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Text_20_body_20_indent" style:display-name="Text body indent" style:family="paragraph" style:parent-style-name="Text_20_body" style:class="text">
<style:paragraph-properties fo:margin-left="0.499cm" fo:margin-right="0cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:contextual-spacing="false" fo:text-indent="0cm" style:auto-text-indent="false"/>
</style:style>
<style:style style:name="Quotations" style:family="paragraph" style:parent-style-name="Standard" style:class="html">
<style:paragraph-properties fo:margin-left="1cm" fo:margin-right="1cm" fo:margin-top="0cm" fo:margin-bottom="0.499cm" style:contextual-spacing="false" fo:text-indent="0cm" style:auto-text-indent="false"/>
</style:style>
<style:style style:name="Title" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties fo:font-size="28pt" fo:font-weight="bold" style:font-size-asian="28pt" style:font-weight-asian="bold" style:font-size-complex="28pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="Subtitle" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:class="chapter">
<style:paragraph-properties fo:margin-top="0.106cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false" fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties fo:font-size="18pt" style:font-size-asian="18pt" style:font-size-complex="18pt"/>
</style:style>
<style:style style:name="Placeholder" style:family="text">
<style:text-properties fo:font-variant="small-caps" fo:color="#008080" loext:opacity="100%" style:text-underline-style="dotted" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="Bullet_20_Symbols" style:display-name="Bullet Symbols" style:family="text">
<style:text-properties style:font-name="StarSymbol" fo:font-family="StarSymbol" fo:font-size="9pt" style:font-name-asian="StarSymbol" style:font-family-asian="StarSymbol" style:font-size-asian="9pt" style:font-name-complex="StarSymbol" style:font-family-complex="StarSymbol" style:font-size-complex="9pt"/>
</style:style>
<text:outline-style style:name="Outline">
<text:outline-level-style text:level="1" loext:num-list-format="%1%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="2" loext:num-list-format="%2%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="3" loext:num-list-format="%3%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="4" loext:num-list-format="%4%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="5" loext:num-list-format="%5%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="6" loext:num-list-format="%6%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="7" loext:num-list-format="%7%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="8" loext:num-list-format="%8%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="9" loext:num-list-format="%9%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
<text:outline-level-style text:level="10" loext:num-list-format="%10%" style:num-format="">
<style:list-level-properties text:min-label-distance="0.381cm"/>
</text:outline-level-style>
</text:outline-style>
<text:notes-configuration text:note-class="footnote" style:num-format="1" text:start-value="0" text:footnotes-position="page" text:start-numbering-at="document"/>
<text:notes-configuration text:note-class="endnote" style:num-format="i" text:start-value="0"/>
<text:linenumbering-configuration text:number-lines="false" text:offset="0.499cm" style:num-format="1" text:number-position="left" text:increment="5"/>
<style:style style:name="Default_20_Style.1" style:display-name="Default Style.1" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-top="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.2" style:display-name="Default Style.2" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.3" style:display-name="Default Style.3" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.4" style:display-name="Default Style.4" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-right="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.5" style:display-name="Default Style.5" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.6" style:display-name="Default Style.6" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.7" style:display-name="Default Style.7" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.8" style:display-name="Default Style.8" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.9" style:display-name="Default Style.9" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.10" style:display-name="Default Style.10" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-right="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.11" style:display-name="Default Style.11" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-top="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.12" style:display-name="Default Style.12" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-right="0.51pt solid #000000" fo:border-top="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.13" style:display-name="Default Style.13" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.14" style:display-name="Default Style.14" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-right="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.15" style:display-name="Default Style.15" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-top="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<style:style style:name="Default_20_Style.16" style:display-name="Default Style.16" style:family="table-cell">
<style:table-cell-properties fo:border-left="0.51pt solid #000000" fo:border-bottom="0.51pt solid #000000"/>
</style:style>
<table:table-template table:name="Default Style" table:first-row-end-column="row" table:first-row-start-column="row" table:last-row-end-column="row" table:last-row-start-column="row">
<table:first-row table:style-name="Default_20_Style.1"/>
<table:last-row table:style-name="Default_20_Style.2"/>
<table:first-column table:style-name="Default_20_Style.3"/>
<table:last-column table:style-name="Default_20_Style.4"/>
<table:body table:style-name="Default_20_Style.9"/>
<table:even-rows table:style-name="Default_20_Style.5"/>
<table:odd-rows table:style-name="Default_20_Style.6"/>
<table:even-columns table:style-name="Default_20_Style.7"/>
<table:odd-columns table:style-name="Default_20_Style.8"/>
<table:background table:style-name="Default_20_Style.10"/>
<loext:first-row-even-column table:style-name="Default_20_Style.15"/>
<loext:last-row-even-column table:style-name="Default_20_Style.16"/>
<loext:first-row-end-column table:style-name="Default_20_Style.12"/>
<loext:first-row-start-column table:style-name="Default_20_Style.11"/>
<loext:last-row-end-column table:style-name="Default_20_Style.14"/>
<loext:last-row-start-column table:style-name="Default_20_Style.13"/>
</table:table-template>
</office:styles>
<office:automatic-styles>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="23.94cm" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="7.98cm" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="transparent" fo:padding="0.097cm" fo:border="none">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1" style:family="table">
<style:table-properties style:width="23.94cm" table:align="margins"/>
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
<style:table-column-properties style:column-width="11.97cm" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table1.B" style:family="table-column">
<style:table-column-properties style:column-width="11.97cm" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table1.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border="none"/>
</style:style>
<style:style style:name="Table2" style:family="table">
<style:table-properties style:width="23.94cm" table:align="margins"/>
</style:style>
<style:style style:name="Table2.A" style:family="table-column">
<style:table-column-properties style:column-width="7.98cm" style:rel-column-width="21845*"/>
</style:style>
<style:style style:name="Table2.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="transparent" fo:padding="0.097cm" fo:border="none">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table1" style:family="table">
<style:table-properties style:width="23.94cm" table:align="margins"/>
</style:style>
<style:style style:name="Table1.A" style:family="table-column">
<style:table-column-properties style:column-width="11.97cm" style:rel-column-width="32768*"/>
</style:style>
<style:style style:name="Table1.B" style:family="table-column">
<style:table-column-properties style:column-width="11.97cm" style:rel-column-width="32767*"/>
</style:style>
<style:style style:name="Table1.A1" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border="none"/>
</style:style>
<style:style style:name="Lines" style:family="table">
<style:table-properties style:width="23.94cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:break-before="auto" fo:break-after="auto" table:align="margins" fo:background-color="transparent" fo:keep-with-next="always" style:may-break-between-rows="true" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-properties>
</style:style>
<style:style style:name="Lines.A" style:family="table-column">
<style:table-column-properties style:column-width="2.499cm" style:rel-column-width="1417*"/>
</style:style>
<style:style style:name="Lines.B" style:family="table-column">
<style:table-column-properties style:column-width="3.358cm" style:rel-column-width="1904*"/>
</style:style>
<style:style style:name="Lines.C" style:family="table-column">
<style:table-column-properties style:column-width="3.36cm" style:rel-column-width="1905*"/>
</style:style>
<style:style style:name="Lines.F" style:family="table-column">
<style:table-column-properties style:column-width="4.002cm" style:rel-column-width="2269*"/>
</style:style>
<style:style style:name="Lines.1" style:family="table-row">
<style:table-row-properties fo:keep-together="always"/>
</style:style>
<style:style style:name="Lines.A1" style:family="table-cell">
<style:table-cell-properties fo:background-color="#b3b3b3" fo:padding="0.097cm" fo:border="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.A2" style:family="table-cell">
<style:table-cell-properties fo:background-color="#b3b3b3" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.A3" style:family="table-cell">
<style:table-cell-properties fo:background-color="#e6e6e6" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.G3" style:family="table-cell">
<style:table-cell-properties fo:background-color="#e6e6e6" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.A4" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="0.05pt solid #000000" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.C4" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.G4" style:family="table-cell">
<style:table-cell-properties fo:background-color="#cccccc" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Lines.A5" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.A6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.B6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.C6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.D6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.E6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.F6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.G6" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.A7" style:family="table-cell">
<style:table-cell-properties fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000"/>
</style:style>
<style:style style:name="Lines.A8" style:family="table-cell">
<style:table-cell-properties fo:background-color="#e6e6e6" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table3" style:family="table" style:master-page-name="">
<style:table-properties style:width="23.94cm" style:page-number="auto" fo:break-before="auto" fo:break-after="auto" table:align="margins" fo:background-color="transparent" style:shadow="none" fo:keep-with-next="always" style:may-break-between-rows="true" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-properties>
</style:style>
<style:style style:name="Table3.A" style:family="table-column">
<style:table-column-properties style:column-width="5.851cm" style:rel-column-width="3317*"/>
</style:style>
<style:style style:name="Table3.B" style:family="table-column">
<style:table-column-properties style:column-width="3.362cm" style:rel-column-width="1906*"/>
</style:style>
<style:style style:name="Table3.E" style:family="table-column">
<style:table-column-properties style:column-width="4.001cm" style:rel-column-width="2268*"/>
</style:style>
<style:style style:name="Table3.1" style:family="table-row">
<style:table-row-properties fo:background-color="transparent" fo:keep-together="always">
<style:background-image/>
</style:table-row-properties>
</style:style>
<style:style style:name="Table3.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="" fo:background-color="#b3b3b3" fo:padding="0.097cm" fo:border="0.05pt solid #000000" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table3.A2" style:family="table-cell">
<style:table-cell-properties style:vertical-align="" fo:background-color="#b3b3b3" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table3.A3" style:family="table-cell">
<style:table-cell-properties style:vertical-align="" fo:background-color="#cccccc" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="Table3.F3" style:family="table-cell">
<style:table-cell-properties style:vertical-align="" fo:background-color="#cccccc" fo:padding="0.097cm" fo:border-left="0.05pt solid #000000" fo:border-right="0.05pt solid #000000" fo:border-top="none" fo:border-bottom="0.05pt solid #000000" style:writing-mode="lr-tb">
<style:background-image/>
</style:table-cell-properties>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P2" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P3" style:family="paragraph" style:parent-style-name="Footer">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P4" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
</style:style>
<style:style style:name="P5" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:keep-together="always" style:shadow="none" fo:keep-with-next="always"/>
</style:style>
<style:style style:name="P6" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:keep-together="always" fo:keep-with-next="always"/>
</style:style>
<style:style style:name="P7" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" style:shadow="none" fo:keep-with-next="always"/>
<style:text-properties fo:font-size="12pt" fo:font-weight="bold" style:font-size-asian="12pt" style:font-weight-asian="bold" style:font-size-complex="12pt" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-size="12pt" style:text-underline-style="none" fo:font-weight="normal" style:font-size-asian="10.5pt" style:font-weight-asian="normal" style:font-size-complex="12pt" style:font-weight-complex="normal"/>
</style:style>
<style:style style:name="P9" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="P10" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="P11" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties officeooo:paragraph-rsid="002aca3c" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="P12" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
</style:style>
<style:style style:name="P13" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties fo:font-size="11pt" style:font-size-asian="11pt" style:font-size-complex="11pt"/>
</style:style>
<style:style style:name="P14" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties fo:font-size="11pt" style:font-size-asian="11pt" style:font-size-complex="11pt"/>
</style:style>
<style:style style:name="P15" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties fo:font-size="11pt" style:text-underline-style="none" style:font-size-asian="11pt" style:font-size-complex="11pt"/>
</style:style>
<style:style style:name="P16" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:text-underline-style="none"/>
</style:style>
<style:style style:name="P17" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:text-underline-style="none" officeooo:paragraph-rsid="00251ac8"/>
</style:style>
<style:style style:name="P18" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties style:text-underline-style="none"/>
</style:style>
<style:style style:name="P19" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:text-underline-style="none" officeooo:paragraph-rsid="00251ac8" fo:background-color="transparent"/>
</style:style>
<style:style style:name="P20" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:text-properties style:text-underline-style="none"/>
</style:style>
<style:style style:name="P21" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:break-before="page"/>
<style:text-properties style:text-underline-style="none"/>
</style:style>
<style:style style:name="P22" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:text-properties officeooo:paragraph-rsid="0037c304"/>
</style:style>
<style:style style:name="P23" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:text-properties officeooo:paragraph-rsid="003a045d"/>
</style:style>
<style:style style:name="P24" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:text-properties officeooo:rsid="003955ec" officeooo:paragraph-rsid="003a045d"/>
</style:style>
<style:style style:name="P25" style:family="paragraph" style:parent-style-name="Heading_20_1">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="P26" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties style:font-name="Liberation Serif1" fo:font-weight="bold" style:font-size-asian="10.5pt" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P27" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
<style:text-properties style:text-underline-style="none" officeooo:paragraph-rsid="003e177a"/>
</style:style>
<style:style style:name="P28" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
</style:style>
<style:style style:name="P29" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:color="#000000" loext:opacity="100%" style:text-outline="false" style:text-line-through-style="none" style:text-line-through-type="none" style:font-name="Liberation Serif" fo:font-size="12pt" fo:font-style="normal" fo:text-shadow="none" style:text-underline-style="none" fo:font-weight="normal" style:font-size-asian="12pt" style:font-style-asian="normal" style:font-weight-asian="normal" style:font-size-complex="12pt" style:font-style-complex="normal" style:font-weight-complex="normal" style:text-overline-style="none" style:text-overline-color="font-color"/>
</style:style>
<style:style style:name="P30" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties officeooo:paragraph-rsid="002aca3c" style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="P31" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:font-size-asian="10.5pt"/>
</style:style>
<style:style style:name="P32" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="end" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P33" style:family="paragraph" style:parent-style-name="Table_20_Contents">
<style:paragraph-properties fo:text-align="center" style:justify-single-word="false"/>
</style:style>
<style:style style:name="P34" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P35" style:family="paragraph" style:parent-style-name="Table_20_Heading">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false"/>
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
</style:style>
<style:style style:name="P36" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:break-before="page" fo:keep-with-next="always"/>
<style:text-properties style:text-underline-style="none" officeooo:paragraph-rsid="003e177a"/>
</style:style>
<style:style style:name="P37" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties style:text-underline-style="none" officeooo:paragraph-rsid="003e177a"/>
</style:style>
<style:style style:name="P38" style:family="paragraph" style:parent-style-name="Text_20_body">
<style:paragraph-properties fo:text-align="start" style:justify-single-word="false" fo:keep-together="always" fo:keep-with-next="always"/>
<style:text-properties fo:font-size="12pt" style:text-underline-style="none" fo:font-weight="normal" officeooo:paragraph-rsid="003e177a" fo:background-color="transparent" style:font-size-asian="10.5pt" style:font-weight-asian="normal" style:font-size-complex="12pt" style:font-weight-complex="normal"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties officeooo:rsid="0037c304"/>
</style:style>
<style:style style:name="T2" style:family="text">
<style:text-properties officeooo:rsid="0039b016"/>
</style:style>
<style:style style:name="T3" style:family="text">
<style:text-properties officeooo:rsid="003e177a"/>
</style:style>
<style:style style:name="T4" style:family="text">
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color"/>
</style:style>
<style:style style:name="T5" style:family="text">
<style:text-properties style:text-underline-style="solid" style:text-underline-width="auto" style:text-underline-color="font-color" officeooo:rsid="003e177a"/>
</style:style>
<style:style style:name="T6" style:family="text">
<style:text-properties style:text-underline-style="none"/>
</style:style>
<style:style style:name="T7" style:family="text">
<style:text-properties style:text-underline-style="none" officeooo:rsid="003e177a"/>
</style:style>
<style:page-layout style:name="pm1">
<style:page-layout-properties fo:page-width="27.94cm" fo:page-height="21.59cm" style:num-format="1" style:print-orientation="landscape" fo:margin-top="2cm" fo:margin-bottom="2cm" fo:margin-left="2cm" fo:margin-right="2cm" style:writing-mode="lr-tb" style:layout-grid-color="#c0c0c0" style:layout-grid-lines="44" style:layout-grid-base-height="0.55cm" style:layout-grid-ruby-height="0cm" style:layout-grid-mode="none" style:layout-grid-ruby-below="false" style:layout-grid-print="true" style:layout-grid-display="true" style:footnote-max-height="0cm" loext:margin-gutter="0cm">
<style:footnote-sep style:width="0.018cm" style:distance-before-sep="0.101cm" style:distance-after-sep="0.101cm" style:line-style="none" style:adjustment="left" style:rel-width="25%" style:color="#000000"/>
</style:page-layout-properties>
<style:header-style>
<style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-bottom="0.499cm"/>
</style:header-style>
<style:footer-style>
<style:header-footer-properties fo:min-height="0cm" fo:margin-left="0cm" fo:margin-right="0cm" fo:margin-top="0.499cm"/>
</style:footer-style>
</style:page-layout>
<style:style style:name="dp1" style:family="drawing-page">
<style:drawing-page-properties draw:background-size="full"/>
</style:style>
</office:automatic-styles>
<office:master-styles>
<style:master-page style:name="Standard" style:page-layout-name="pm1" draw:style-name="dp1">
<style:header>
<table:table table:name="Table2" table:style-name="Table2">
<table:table-column table:style-name="Table2.A" table:number-columns-repeated="3"/>
<table:table-row table:style-name="TableLine94368948362784">
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="Header">Company: <text:placeholder text:placeholder-type="text">&lt;company.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="P27">General Ledger<text:placeholder text:placeholder-type="text">&lt;if test=&quot;not context.get(&apos;posted&apos;)&quot;&gt;</text:placeholder> <text:span text:style-name="T3">Draft</text:span><text:span text:style-name="T3"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:span></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table2.A1" office:value-type="string">
<text:p text:style-name="P2">Print Date: <text:placeholder text:placeholder-type="text">&lt;format_date(datetime.date.today(), user.language)&gt;</text:placeholder><text:s/>at <text:placeholder text:placeholder-type="text">&lt;datetime.datetime.now().strftime(&apos;%H:%M:%S&apos;)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:header>
<style:footer>
<table:table table:name="Table1" table:style-name="Table1">
<table:table-column table:style-name="Table1.A"/>
<table:table-column table:style-name="Table1.B"/>
<table:table-row table:style-name="TableLine94368949141280">
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="Footer">User: <text:placeholder text:placeholder-type="text">&lt;user.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table1.A1" office:value-type="string">
<text:p text:style-name="P3"><text:page-number text:select-page="current">1</text:page-number>/<text:page-count>3</text:page-count></text:p>
</table:table-cell>
</table:table-row>
</table:table>
</style:footer>
</style:master-page>
</office:master-styles>
<office:body>
<office:text text:use-soft-page-breaks="true">
<office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
<text:sequence-decls>
<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
<text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
</text:sequence-decls>
<text:p text:style-name="P25">General Ledger<text:placeholder text:placeholder-type="text">&lt;if test=&quot;not context.get(&apos;posted&apos;)&quot;&gt;</text:placeholder> <text:span text:style-name="T3">Draft</text:span><text:span text:style-name="T3"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:span></text:p>
<text:p text:style-name="P23"><text:span text:style-name="T1">Fiscal Year: </text:span><text:placeholder text:placeholder-type="text">&lt;fiscalyear.rec_name&gt;</text:placeholder></text:p>
<text:p text:style-name="P23"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;start_period or end_period&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P23"><text:span text:style-name="T1">From Period</text:span>: <text:placeholder text:placeholder-type="text">&lt;start_period.name if start_period else &apos;&apos;&gt;</text:placeholder><text:s/><text:span text:style-name="T2">To</text:span> <text:placeholder text:placeholder-type="text">&lt;end_period.name if end_period else &apos;&apos;&gt;</text:placeholder></text:p>
<text:p text:style-name="P23"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="P23"><text:placeholder text:placeholder-type="text">&lt;if test=&quot;from_date or to_date&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P24">From Date: <text:placeholder text:placeholder-type="text">&lt;format_date(from_date, user.language) if from_date else &apos;&apos;&gt;</text:placeholder><text:s/>To <text:placeholder text:placeholder-type="text">&lt;format_date(to_date, user.language) if to_date else &apos;&apos;&gt;</text:placeholder></text:p>
<text:p text:style-name="P23"><text:placeholder text:placeholder-type="text">&lt;/if&gt;</text:placeholder></text:p>
<text:p text:style-name="P20"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;account in accounts&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P36"><text:placeholder text:placeholder-type="text">&lt;choose test=&quot;&quot;&gt;</text:placeholder></text:p>
<text:p text:style-name="P37"><text:placeholder text:placeholder-type="text">&lt;when test=&quot;account.general_ledger_balance&quot;&gt;</text:placeholder></text:p>
<table:table table:name="Table3" table:style-name="Table3" table:template-name="Default Style">
<table:table-column table:style-name="Table3.A"/>
<table:table-column table:style-name="Table3.B" table:number-columns-repeated="3"/>
<table:table-column table:style-name="Table3.E" table:number-columns-repeated="2"/>
<table:table-header-rows>
<table:table-row table:style-name="Table3.1">
<table:table-cell table:style-name="Table3.A1" table:number-columns-spanned="6" office:value-type="string">
<text:p text:style-name="P34">Name</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Table3.1">
<table:table-cell table:style-name="Table3.A2" table:number-columns-spanned="6" office:value-type="string">
<text:p text:style-name="P35"><text:placeholder text:placeholder-type="text">&lt;account.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
</table:table-header-rows>
<table:table-row table:style-name="Table3.1">
<table:table-cell table:style-name="Table3.A3" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Balance</text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A3" office:value-type="string">
<text:p text:style-name="P11"/>
</table:table-cell>
<table:table-cell table:style-name="Table3.A3" office:value-type="string">
<text:p text:style-name="P11"/>
</table:table-cell>
<table:table-cell table:style-name="Table3.A3" office:value-type="string">
<text:p text:style-name="P11"><text:placeholder text:placeholder-type="text">&lt;format_currency(account.end_balance, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Table3.A3" office:value-type="string">
<text:p text:style-name="P10"/>
</table:table-cell>
<table:table-cell table:style-name="Table3.F3" office:value-type="string">
<text:p text:style-name="P10"/>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="P37"><text:placeholder text:placeholder-type="text">&lt;/when&gt;</text:placeholder></text:p>
<text:p text:style-name="P37"><text:placeholder text:placeholder-type="text">&lt;otherwise test=&quot;&quot;&gt;</text:placeholder></text:p>
<table:table table:name="Lines" table:style-name="Lines">
<table:table-column table:style-name="Lines.A"/>
<table:table-column table:style-name="Lines.B"/>
<table:table-column table:style-name="Lines.C"/>
<table:table-column table:style-name="Lines.B" table:number-columns-repeated="2"/>
<table:table-column table:style-name="Lines.F" table:number-columns-repeated="2"/>
<table:table-header-rows>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A1" table:number-columns-spanned="7" office:value-type="string">
<text:p text:style-name="P5">Name</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A2" table:number-columns-spanned="7" office:value-type="string">
<text:p text:style-name="P7"><text:placeholder text:placeholder-type="text">&lt;account.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="P6">Date</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="P6">Move</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="Table_20_Heading">Debit</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="P6">Credit</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="P6">Balance</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A3" office:value-type="string">
<text:p text:style-name="P6">Description</text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.G3" office:value-type="string">
<text:p text:style-name="P6">Origin</text:p>
</table:table-cell>
</table:table-row>
</table:table-header-rows>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A4" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="P6">Balance</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"><text:placeholder text:placeholder-type="text">&lt;format_currency(account.start_balance, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.G4" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A5" table:number-columns-spanned="7" office:value-type="string">
<text:p text:style-name="P16"><text:placeholder text:placeholder-type="text">&lt;for each=&quot;line in account.lines&quot;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A6" office:value-type="string">
<text:p text:style-name="P33"><text:placeholder text:placeholder-type="text">&lt;format_date(line.date, user.language)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.B6" office:value-type="string">
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text">&lt;line.move.rec_name&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.C6" office:value-type="string">
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.debit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.D6" office:value-type="string">
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.credit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.E6" office:value-type="string">
<text:p text:style-name="P32"><text:placeholder text:placeholder-type="text">&lt;format_currency(line.balance, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.F6" office:value-type="string">
<text:p text:style-name="Table_20_Contents"><text:placeholder text:placeholder-type="text">&lt;line.description or &apos;&apos;&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.G6" office:value-type="string">
<text:p text:style-name="Table_20_Contents"><text:placeholder text:placeholder-type="text">&lt;getattr(line.origin, &apos;rec_name&apos;, &apos;&apos;)&gt;</text:placeholder></text:p>
</table:table-cell>
</table:table-row>
<text:soft-page-break/>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A7" table:number-columns-spanned="7" office:value-type="string">
<text:p text:style-name="P18"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
<table:covered-table-cell/>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.A8" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="P6">Total</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:table-cell table:style-name="Lines.A8" office:value-type="string">
<text:p text:style-name="P4"><text:placeholder text:placeholder-type="text">&lt;format_currency(account.end_debit - account.start_debit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A8" office:value-type="string">
<text:p text:style-name="P4"><text:placeholder text:placeholder-type="text">&lt;format_currency(account.end_credit - account.start_credit, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A8" office:value-type="string">
<text:p text:style-name="P4"><text:placeholder text:placeholder-type="text">&lt;format_currency((account.end_debit - account.end_credit) - (account.start_debit - account.start_credit), user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.A8" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.G3" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Lines.1">
<table:table-cell table:style-name="Lines.C4" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="P6">Balance</text:p>
</table:table-cell>
<table:covered-table-cell/>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P4"><text:placeholder text:placeholder-type="text">&lt;format_currency(account.end_balance, user.language, company.currency)&gt;</text:placeholder></text:p>
</table:table-cell>
<table:table-cell table:style-name="Lines.C4" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
<table:table-cell table:style-name="Lines.G4" office:value-type="string">
<text:p text:style-name="P12"/>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="P38"><text:placeholder text:placeholder-type="text">&lt;/otherwise&gt;</text:placeholder></text:p>
<text:p text:style-name="P38"><text:placeholder text:placeholder-type="text">&lt;/choose&gt;</text:placeholder></text:p>
<text:p text:style-name="P8"><text:placeholder text:placeholder-type="text">&lt;/for&gt;</text:placeholder></text:p>
</office:text>
</office:body>
</office:document>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zM4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12zm8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8z"/></svg>

After

Width:  |  Height:  |  Size: 371 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/></svg>

After

Width:  |  Height:  |  Size: 363 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 17c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm6-9h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6h1.9c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm0 12H6V10h12v10z"/></svg>

After

Width:  |  Height:  |  Size: 369 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M4 10v7h3v-7H4zm6 0v7h3v-7h-3zM2 22h19v-3H2v3zm14-12v7h3v-7h-3zm-4.5-9L2 6v2h19V6l-9.5-5z"/>
</svg>

After

Width:  |  Height:  |  Size: 239 B

313
modules/account/journal.py Normal file
View File

@@ -0,0 +1,313 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql.aggregate import Sum
from sql.conditionals import Coalesce
from trytond import backend
from trytond.i18n import gettext
from trytond.model import (
DeactivableMixin, MatchMixin, ModelSQL, ModelView, Unique, Workflow,
fields, sequence_ordered)
from trytond.model.exceptions import AccessError
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import (
grouped_slice, is_full_text, lstrip_wildcard, reduce_ids,
sqlite_apply_types)
from trytond.transaction import Transaction
STATES = {
'readonly': Eval('state') == 'closed',
}
class Journal(
DeactivableMixin, MatchMixin,
sequence_ordered('matching_sequence', "Matching Sequence"),
ModelSQL, ModelView):
__name__ = 'account.journal'
name = fields.Char('Name', size=None, required=True, translate=True)
code = fields.Char('Code', size=None)
type = fields.Selection([
('general', "General"),
('revenue', "Revenue"),
('expense', "Expense"),
('cash', "Cash"),
('situation', "Situation"),
('write-off', "Write-Off"),
], 'Type', required=True)
debit = fields.Function(Monetary(
"Debit", currency='currency', digits='currency'),
'get_debit_credit_balance')
credit = fields.Function(Monetary(
"Credit", currency='currency', digits='currency'),
'get_debit_credit_balance')
balance = fields.Function(Monetary(
"Balance", currency='currency', digits='currency'),
'get_debit_credit_balance')
currency = fields.Function(fields.Many2One(
'currency.currency', "Currency"), 'get_currency')
@classmethod
def __setup__(cls):
super().__setup__()
cls._order.insert(0, ('name', 'ASC'))
@classmethod
def search_rec_name(cls, name, clause):
_, operator, operand, *extra = clause
if operator.startswith('!') or operator.startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
code_value = operand
if operator.endswith('like') and is_full_text(operand):
code_value = lstrip_wildcard(operand)
return [bool_op,
('code', operator, code_value, *extra),
(cls._rec_name, operator, operand, *extra),
]
@classmethod
def get_currency(cls, journals, name):
pool = Pool()
Company = pool.get('company.company')
company_id = Transaction().context.get('company')
if company_id is not None and company_id >= 0:
company = Company(company_id)
currency_id = company.currency.id
else:
currency_id = None
return dict.fromkeys([j.id for j in journals], currency_id)
@classmethod
def get_debit_credit_balance(cls, journals, names):
pool = Pool()
MoveLine = pool.get('account.move.line')
Move = pool.get('account.move')
Account = pool.get('account.account')
AccountType = pool.get('account.account.type')
Company = pool.get('company.company')
context = Transaction().context
cursor = Transaction().connection.cursor()
result = {}
ids = [j.id for j in journals]
for name in ['debit', 'credit', 'balance']:
result[name] = dict.fromkeys(ids, 0)
company_id = Transaction().context.get('company')
if not company_id:
return result
company = Company(company_id)
line = MoveLine.__table__()
move = Move.__table__()
account = Account.__table__()
account_type = AccountType.__table__()
where = ((move.date >= context.get('start_date'))
& (move.date <= context.get('end_date'))
& ~Coalesce(account_type.receivable, False)
& ~Coalesce(account_type.payable, False)
& (move.company == company.id))
for sub_journals in grouped_slice(journals):
sub_journals = list(sub_journals)
red_sql = reduce_ids(move.journal, [j.id for j in sub_journals])
query = line.join(move, 'LEFT', condition=line.move == move.id
).join(account, 'LEFT', condition=line.account == account.id
).join(account_type, 'LEFT',
condition=account.type == account_type.id
).select(
move.journal,
Sum(line.debit).as_('debit'),
Sum(line.credit).as_('credit'),
where=where & red_sql,
group_by=move.journal)
if backend.name == 'sqlite':
sqlite_apply_types(query, [None, 'NUMERIC', 'NUMERIC'])
cursor.execute(*query)
for journal_id, debit, credit in cursor:
result['debit'][journal_id] = company.currency.round(debit)
result['credit'][journal_id] = company.currency.round(credit)
result['balance'][journal_id] = company.currency.round(
debit - credit)
return result
@classmethod
def find(cls, pattern):
for journal in cls.search(
[],
order=[
('matching_sequence', 'ASC'),
('id', 'ASC'),
]):
if journal.match(pattern):
return journal
@classmethod
def check_modification(cls, mode, journals, values=None, external=False):
pool = Pool()
Move = pool.get('account.move')
super().check_modification(
mode, journals, values=values, external=external)
if mode == 'write' and 'type' in values:
for sub_journals in grouped_slice(journals):
moves = Move.search([
('journal', 'in', [j.id for j in sub_journals]),
('state', '=', 'posted')
], order=[], limit=1)
if moves:
move, = moves
raise AccessError(gettext(
'account.msg_journal_account_moves',
journal=move.journal.rec_name))
class JournalCashContext(ModelView):
__name__ = 'account.journal.open_cash.context'
start_date = fields.Date('Start Date', required=True)
end_date = fields.Date('End Date', required=True)
@classmethod
def default_start_date(cls):
return Pool().get('ir.date').today()
default_end_date = default_start_date
class JournalPeriod(Workflow, ModelSQL, ModelView):
__name__ = 'account.journal.period'
journal = fields.Many2One(
'account.journal', 'Journal', required=True, ondelete='CASCADE',
states=STATES,
context={
'company': Eval('company', None),
},
depends=['company'])
period = fields.Many2One('account.period', 'Period', required=True,
ondelete='CASCADE', states=STATES)
company = fields.Function(fields.Many2One(
'company.company', "Company"),
'on_change_with_company', searcher='search_company')
icon = fields.Function(fields.Char('Icon'), 'get_icon')
state = fields.Selection([
('open', 'Open'),
('closed', 'Closed'),
], 'State', readonly=True, required=True, sort=False)
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls._sql_constraints += [
('journal_period_uniq', Unique(t, t.journal, t.period),
'account.msg_journal_period_unique'),
]
cls._transitions |= set((
('open', 'closed'),
('closed', 'open'),
))
cls._buttons.update({
'close': {
'invisible': Eval('state') != 'open',
'depends': ['state'],
},
'reopen': {
'invisible': Eval('state') != 'closed',
'depends': ['state'],
},
})
@classmethod
def __register__(cls, module):
cursor = Transaction().connection.cursor()
t = cls.__table__()
super().__register__(module)
# Migration from 6.8: rename state close to closed
cursor.execute(
*t.update([t.state], ['closed'], where=t.state == 'close'))
@fields.depends('period')
def on_change_with_company(self, name=None):
return self.period.company if self.period else None
@classmethod
def search_company(cls, name, clause):
return [('period.' + clause[0], *clause[1:])]
@staticmethod
def default_state():
return 'open'
def get_rec_name(self, name):
return '%s - %s' % (self.journal.rec_name, self.period.rec_name)
@classmethod
def search_rec_name(cls, name, clause):
if clause[1].startswith('!') or clause[1].startswith('not '):
bool_op = 'AND'
else:
bool_op = 'OR'
return [bool_op,
[('journal.rec_name',) + tuple(clause[1:])],
[('period.rec_name',) + tuple(clause[1:])],
]
def get_icon(self, name):
return {
'open': 'tryton-account-open',
'closed': 'tryton-account-close',
}.get(self.state)
@classmethod
def _check(cls, periods):
Move = Pool().get('account.move')
for period in periods:
moves = Move.search([
('journal', '=', period.journal.id),
('period', '=', period.period.id),
], limit=1)
if moves:
raise AccessError(
gettext('account.msg_modify_delete_journal_period_moves',
journal_period=period.rec_name))
@classmethod
def check_modification(cls, mode, records, values=None, external=False):
super().check_modification(
mode, records, values=values, external=external)
if mode == 'create':
for record in records:
if record.period.state != 'open':
raise AccessError(gettext(
'account.msg_create_journal_period_closed_period',
period=record.period.rec_name))
elif mode in {'write', 'delete'}:
if values != {'state': 'closed'} and values != {'state': 'open'}:
cls._check(records)
if mode == 'write' and values.get('state') == 'open':
for record in records:
if record.period.state != 'open':
raise AccessError(gettext(
'account.'
'msg_open_journal_period_closed_period',
journal_period=record.rec_name,
period=record.period.rec_name))
@classmethod
@ModelView.button
@Workflow.transition('closed')
def close(cls, periods):
'''
Close journal - period
'''
pass
@classmethod
@ModelView.button
@Workflow.transition('open')
def reopen(cls, periods):
"Open journal - period"
pass

250
modules/account/journal.xml Normal file
View File

@@ -0,0 +1,250 @@
<?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. -->
<tryton>
<data>
<menuitem
name="Journals"
parent="menu_account_configuration"
sequence="50"
id="menu_journal_configuration"/>
<record model="ir.ui.view" id="journal_view_form">
<field name="model">account.journal</field>
<field name="type">form</field>
<field name="name">journal_form</field>
</record>
<record model="ir.ui.view" id="journal_view_tree">
<field name="model">account.journal</field>
<field name="priority" eval="10"/>
<field name="type">tree</field>
<field name="name">journal_tree</field>
</record>
<record model="ir.ui.view" id="journal_view_list_matching_sequence">
<field name="model">account.journal</field>
<field name="priority" eval="20"/>
<field name="type">tree</field>
<field name="name">journal_list_matching_sequence</field>
</record>
<record model="ir.ui.view" id="journal_view_list_cash">
<field name="model">account.journal</field>
<field name="priority" eval="20"/>
<field name="type">tree</field>
<field name="name">journal_list_cash</field>
</record>
<record model="ir.action.act_window" id="act_journal_form">
<field name="name">Journals</field>
<field name="res_model">account.journal</field>
<field name="order" eval="[('matching_sequence', 'ASC'), ('id', 'ASC')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_journal_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="journal_view_list_matching_sequence"/>
<field name="act_window" ref="act_journal_form"/>
</record>
<record model="ir.action.act_window.view" id="act_journal_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="journal_view_form"/>
<field name="act_window" ref="act_journal_form"/>
</record>
<menuitem
parent="menu_journal_configuration"
action="act_journal_form"
sequence="10"
id="menu_journal_form"/>
<record model="ir.ui.view" id="journal_cash_context_view_form">
<field name="model">account.journal.open_cash.context</field>
<field name="type">form</field>
<field name="name">journal_open_cash_context</field>
</record>
<record model="ir.action.act_window" id="act_journal_open_cash">
<field name="name">Journals Cash</field>
<field name="res_model">account.journal</field>
<field name="domain" eval="[('type', '=', 'cash')]" pyson="1"/>
<field name="context_model">account.journal.open_cash.context</field>
</record>
<record model="ir.action.act_window.view"
id="act_journal_open_cash_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="journal_view_list_cash"/>
<field name="act_window" ref="act_journal_open_cash"/>
</record>
<menuitem
parent="menu_reporting"
action="act_journal_open_cash"
sequence="50"
id="menu_journal_open_cash"/>
<record model="ir.model.access" id="access_journal">
<field name="model">account.journal</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_journal_account_admin">
<field name="model">account.journal</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="journal_period_view_form">
<field name="model">account.journal.period</field>
<field name="type">form</field>
<field name="name">journal_period_form</field>
</record>
<record model="ir.ui.view" id="journal_period_view_tree">
<field name="model">account.journal.period</field>
<field name="type">tree</field>
<field name="name">journal_period_tree</field>
</record>
<record model="ir.ui.view" id="journal_period_view_list_close">
<field name="model">account.journal.period</field>
<field name="type">tree</field>
<field name="name">journal_period_list_close</field>
</record>
<record model="ir.action.act_window" id="act_journal_period_tree">
<field name="name">Journals - Periods</field>
<field name="res_model">account.journal.period</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
</record>
<record model="ir.action.act_window.view" id="act_journal_period_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="journal_period_view_tree"/>
<field name="act_window" ref="act_journal_period_tree"/>
</record>
<menuitem
parent="menu_reporting"
action="act_journal_period_tree"
sequence="50"
id="menu_journal_period_tree"/>
<record model="ir.action.act_window" id="act_journal_period_tree2">
<field name="name">Journals - Periods</field>
<field name="res_model">account.journal.period</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
<field name="search_value"
eval="[('state', '=', 'open')]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_journal_period_tree2_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="journal_period_view_tree"/>
<field name="act_window" ref="act_journal_period_tree2"/>
</record>
<menuitem
parent="menu_entries"
action="act_journal_period_tree2"
sequence="20"
id="menu_journal_period_tree2"/>
<record model="ir.action.act_window" id="act_journal_period_form_close">
<field name="name">Close Journals - Periods</field>
<field name="res_model">account.journal.period</field>
<field name="search_value"
eval="[('state', '=', 'open')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_journal_period_form_close_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="journal_period_view_list_close"/>
<field name="act_window" ref="act_journal_period_form_close"/>
</record>
<menuitem
parent="menu_processing"
action="act_journal_period_form_close"
sequence="20"
id="menu_close_journal_period"/>
<record model="ir.model.access" id="access_journal_period">
<field name="model">account.journal.period</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_journal_period_account">
<field name="model">account.journal.period</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_journal_period_account_admin">
<field name="model">account.journal.period</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_journal_period_companies">
<field name="name">User in companies</field>
<field name="model">account.journal.period</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_journal_period_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_journal_period_companies"/>
</record>
<record model="ir.model.button" id="journal_period_close_button">
<field name="model">account.journal.period</field>
<field name="name">close</field>
<field name="string">Close</field>
</record>
<record model="ir.model.button" id="journal_period_reopen_button">
<field name="model">account.journal.period</field>
<field name="name">reopen</field>
<field name="string">Reopen</field>
</record>
</data>
<data noupdate="1">
<record model="account.journal" id="journal_revenue">
<field name="name">Revenue</field>
<field name="code">REV</field>
<field name="type">revenue</field>
</record>
<record model="account.journal" id="journal_expense">
<field name="name">Expense</field>
<field name="code">EXP</field>
<field name="type">expense</field>
</record>
<record model="account.journal" id="journal_cash">
<field name="name">Cash</field>
<field name="code">CASH</field>
<field name="type">cash</field>
</record>
<record model="account.journal" id="journal_stock">
<field name="name">Stock</field>
<field name="code">STO</field>
<field name="type">general</field>
</record>
<record model="account.journal" id="journal_miscellaneous">
<field name="name">Miscellaneous</field>
<field name="code">MISC</field>
<field name="type">general</field>
</record>
<record model="account.journal" id="journal_currency_exchange">
<field name="name">Currency Exchange</field>
<field name="code">EXC</field>
<field name="type">write-off</field>
</record>
</data>
</tryton>

5605
modules/account/locale/bg.po Normal file

File diff suppressed because it is too large Load Diff

5069
modules/account/locale/ca.po Normal file

File diff suppressed because it is too large Load Diff

5272
modules/account/locale/cs.po Normal file

File diff suppressed because it is too large Load Diff

5118
modules/account/locale/de.po Normal file

File diff suppressed because it is too large Load Diff

5074
modules/account/locale/es.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

5341
modules/account/locale/et.po Normal file

File diff suppressed because it is too large Load Diff

5388
modules/account/locale/fa.po Normal file

File diff suppressed because it is too large Load Diff

5487
modules/account/locale/fi.po Normal file

File diff suppressed because it is too large Load Diff

5091
modules/account/locale/fr.po Normal file

File diff suppressed because it is too large Load Diff

5230
modules/account/locale/hu.po Normal file

File diff suppressed because it is too large Load Diff

5139
modules/account/locale/id.po Normal file

File diff suppressed because it is too large Load Diff

5452
modules/account/locale/it.po Normal file

File diff suppressed because it is too large Load Diff

5481
modules/account/locale/lo.po Normal file

File diff suppressed because it is too large Load Diff

5370
modules/account/locale/lt.po Normal file

File diff suppressed because it is too large Load Diff

5078
modules/account/locale/nl.po Normal file

File diff suppressed because it is too large Load Diff

5167
modules/account/locale/pl.po Normal file

File diff suppressed because it is too large Load Diff

5077
modules/account/locale/pt.po Normal file

File diff suppressed because it is too large Load Diff

5194
modules/account/locale/ro.po Normal file

File diff suppressed because it is too large Load Diff

5589
modules/account/locale/ru.po Normal file

File diff suppressed because it is too large Load Diff

5388
modules/account/locale/sl.po Normal file

File diff suppressed because it is too large Load Diff

5255
modules/account/locale/tr.po Normal file

File diff suppressed because it is too large Load Diff

5206
modules/account/locale/uk.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

281
modules/account/message.xml Normal file
View File

@@ -0,0 +1,281 @@
<?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. -->
<tryton>
<data grouped="1">
<record model="ir.message" id="msg_no_period_date">
<field name="text">To continue, you must create a period for the date "%(date)s" and company "%(company)s".</field>
</record>
<record model="ir.message" id="msg_no_open_period_date">
<field name="text">To continue, you must reopen the period "%(period)s" of company "%(company)s" for the date "%(date)s".</field>
</record>
<record model="ir.message" id="msg_create_period_closed_fiscalyear">
<field name="text">You cannot create a period in fiscal year "%(fiscalyear)s" because it is closed.</field>
</record>
<record model="ir.message" id="msg_open_period_closed_fiscalyear">
<field name="text">You cannot reopen period "%(period)s" because its fiscal year "%(fiscalyear)s" is closed.</field>
</record>
<record model="ir.message" id="msg_change_period_move_sequence">
<field name="text">You cannot change the move sequence in period "%(period)s" because it has posted moves.</field>
</record>
<record model="ir.message" id="msg_close_period_non_posted_moves">
<field name="text">To close period "%(period)s" you must post the moves "%(moves)s".</field>
</record>
<record model="ir.message" id="msg_period_standard_overlap">
<field name="text">The dates of standard period of the same fiscal year can not overlap.</field>
</record>
<record model="ir.message" id="msg_period_move_sequence_unique">
<field name="text">A move sequence can be reused only by periods in the same fiscal year.</field>
</record>
<record model="ir.message" id="msg_period_fiscalyear_dates">
<field name="text">The dates for period "%(period)s" must be between the dates of its fiscal year "%(fiscalyear)s".</field>
</record>
<record model="ir.message" id="msg_period_move_dates">
<field name="text">The dates for period "%(period)s" must include the date "%(move_date)s" of move "%(move)s".</field>
</record>
<record model="ir.message" id="msg_journal_period_unique">
<field name="text">You can create only one journal per period.</field>
</record>
<record model="ir.message" id="msg_modify_delete_journal_period_moves">
<field name="text">You cannot modify or delete journal-period "%(journal_period)s" because it contains moves.</field>
</record>
<record model="ir.message" id="msg_create_journal_period_closed_period">
<field name="text">You cannot create a journal-period in closed period "%(period)s".</field>
</record>
<record model="ir.message" id="msg_open_journal_period_closed_period">
<field name="text">You cannot reopen journal-period "%(journal_period)s" in closed period "%(period)s".</field>
</record>
<record model="ir.message" id="msg_tax_update_unit_price_with_parent">
<field name="text">You cannot set "Update Unit Price" on child tax "%(tax)s".</field>
</record>
<record model="ir.message" id="msg_modify_tax_line_closed_period">
<field name="text">You cannot add/modify/delete tax lines in closed period "%(period)s".</field>
</record>
<record model="ir.message" id="msg_change_fiscalyear_move_sequence">
<field name="text">You cannot change the move sequence on fiscal year "%(fiscalyear)s" because it contains posted moves.</field>
</record>
<record model="ir.message" id="msg_no_fiscalyear_date">
<field name="text">To continue, you must create a fiscal year for the date "%(date)s" and company "%(company)s".</field>
</record>
<record model="ir.message" id="msg_no_open_fiscalyear_date">
<field name="text">To continue, you must reopen the fiscal year "%(fiscalyear)s" of company "%(company)s" for the date "%(date)s".</field>
</record>
<record model="ir.message" id="msg_fiscalyear_overlap">
<field name="text">The dates of fiscal years of the same company can not overlap.</field>
</record>
<record model="ir.message" id="msg_open_fiscalyear_earlier">
<field name="text">Open fiscal years can not be before closed fiscal years.</field>
</record>
<record model="ir.message" id="msg_fiscalyear_move_sequence_unique">
<field name="text">The move sequence of fiscal years must be unique.</field>
</record>
<record model="ir.message" id="msg_close_fiscalyear_account_balance_not_zero">
<field name="text">To close the fiscal year, the balance of account "%(account)s" must be zero.</field>
</record>
<record model="ir.message" id="msg_close_fiscalyear_earlier">
<field name="text">To close fiscal year "%(fiscalyear)s", you must close all earlier fiscal years.</field>
</record>
<record model="ir.message" id="msg_reopen_fiscalyear_later">
<field name="text">To reopen fiscal year "%(fiscalyear)s", you must reopen all later fiscal years.</field>
</record>
<record model="ir.message" id="msg_party_missing_receivable_account">
<field name="text">To continue, you must define a receivable account for party "%(party)s".</field>
</record>
<record model="ir.message" id="msg_party_missing_payable_account">
<field name="text">To continue, you must define a payable account for party "%(party)s".</field>
</record>
<record model="ir.message" id="msg_erase_party_receivable_payable">
<field name="text">You cannot erase party "%(party)s" while they have pending receivable/payable with company "%(company)s".</field>
</record>
<record model="ir.message" id="msg_only_one_debit_credit_types">
<field name="text">Account can have only one of the debit or credit type set.</field>
</record>
<record model="ir.message" id="msg_account_invalid_type_second_currency">
<field name="text">To set a second currency for account "%(account)s", it must not have a type "payable", "revenue", "receivable" nor "expense".</field>
</record>
<record model="ir.message" id="msg_account_invalid_deferral_second_currency">
<field name="text">To set a second currency for account "%(account)s", it must be deferral.</field>
</record>
<record model="ir.message" id="msg_account_invalid_lines_second_currency">
<field name="text">To set a second currency for account "%(account)s", its lines must have the same second currency "%(currency)s".</field>
</record>
<record model="ir.message" id="msg_account_closed_lines">
<field name="text">You cannot close account "%(account)s" because it has move lines.</field>
</record>
<record model="ir.message" id="msg_account_no_type_lines">
<field name="text">You cannot remove type of account "%(account)s" because it has move lines.</field>
</record>
<record model="ir.message" id="msg_deferral_unique">
<field name="text">Deferral must be unique by account and fiscal year.</field>
</record>
<record model="ir.message" id="msg_write_deferral">
<field name="text">You cannot modify any account deferrals.</field>
</record>
<record model="ir.message" id="msg_account_chart_exists">
<field name="text">A chart of accounts already exists for company "%(company)s".</field>
</record>
<record model="ir.message" id="msg_post_empty_move">
<field name="text">To post move "%(move)s", you must fill in its lines.</field>
</record>
<record model="ir.message" id="msg_post_unbalanced_move">
<field name="text">To post move "%(move)s", you must balance all its lines debits and credits.</field>
</record>
<record model="ir.message" id="msg_modify_posted_moved">
<field name="text">You cannot modify posted move "%(move)s".</field>
</record>
<record model="ir.message" id="msg_move_copy_closed_period">
<field name="text">The period of move "%(move)s" is closed.
If you copy the move, the current period will be used.</field>
</record>
<record model="ir.message" id="msg_move_cancel_closed_period">
<field name="text">The period of move "%(move)s" is closed.
If you cancel the move, the current period will be used.</field>
</record>
<record model="ir.message" id="msg_move_template_invalid_description">
<field name="text">Failed to evaluate the description "%(description)s" from template "%(template)s" with error: "%(error)s"</field>
</record>
<record model="ir.message" id="msg_move_template_invalid_expression">
<field name="text">Failed to evaluate expression "%(expression)s" from template "%(template)s" with error:
"%(error)s"</field>
</record>
<record model="ir.message" id="msg_move_template_expression_not_number">
<field name="text">The value "%(value)s" of "%(expression)s" from template "%(template)s" is not a number.</field>
</record>
<record model="ir.message" id="msg_move_template_keyword_name_not_identifier">
<field name="text">The keyword name "%(name)s" is not a valid identifier.</field>
</record>
<record model="ir.message" id="msg_write_reconciliation">
<field name="text">You cannot modify any reconciliation.</field>
</record>
<record model="ir.message" id="msg_reconciliation_delete_delegated">
<field name="text">The reconciliation "%(reconciliation)s" is delegated to the line "%(line)s".
You may need to cancel its move "%(move)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_delete_write_off">
<field name="text">The reconciliation "%(reconciliation)s" is linked to the write-off line "%(line)s".
You may need to cancel its move "%(move)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_line_not_valid">
<field name="text">You cannot reconcile non-valid line "%(line)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_different_accounts">
<field name="text">You cannot reconcile line "%(line)s" with others because its account "%(account1)s" is different from "%(account2)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_account_not_reconcile">
<field name="text">To reconcile line "%(line)s", you must set its account "%(account)s" as reconcilable.</field>
</record>
<record model="ir.message" id="msg_reconciliation_different_parties">
<field name="text">You cannot reconcile line "%(line)s" with others because its party "%(party1)s" is different from "%(party2)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_unbalanced">
<field name="text">To reconcile lines, they must have the same debit "%(debit)s" and credit "%(credit)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_write_off_missing">
<field name="text">To reconcile lines with "%(amount)s" write-off, you must select a write-off method.</field>
</record>
<record model="ir.message" id="msg_reconciliation_write_off_same_account">
<field name="text">You cannot reconcile lines using the write-off "%(write_off)s" with the same "%(account)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_currency_exchange_journal_missing">
<field name="text">To reconcile lines, you must define a currency exchange journal for "%(company)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_currency_exchange_credit_account_missing">
<field name="text">To reconcile lines, you must define a currency exchange credit account for "%(company)s".</field>
</record>
<record model="ir.message" id="msg_reconciliation_currency_exchange_debit_account_missing">
<field name="text">To reconcile lines, you must define a currency exchange debit account for "%(company)s".</field>
</record>
<record model="ir.message" id="msg_line_debit_credit">
<field name="text">You cannot set both debit and credit on the line.</field>
</record>
<record model="ir.message" id="msg_line_second_currency_sign">
<field name="text">You must set the sign for second currency to match the sign of debit - credit.</field>
</record>
<record model="ir.message" id="msg_modify_line_closed_journal_period">
<field name="text">You cannot add/modify/delete lines on closed journal-period "%(journal_period)s".</field>
</record>
<record model="ir.message" id="msg_modify_line_posted_move">
<field name="text">You cannot modify line "%(line)s" from posted move "%(move)s".</field>
</record>
<record model="ir.message" id="msg_delete_line_reconciled">
<field name="text">In order to delete the reconciled line "%(line)s", you must first unreconcile it.</field>
</record>
<record model="ir.message" id="msg_modify_line_reconciled">
<field name="text">In order to modify the reconciled line "%(line)s", you must first unreconcile it.</field>
</record>
<record model="ir.message" id="msg_line_closed_account">
<field name="text">To create a line on account "%(account)s", you must set a type or unclose it.</field>
</record>
<record model="ir.message" id="msg_line_already_reconciled">
<field name="text">You cannot reconcile already reconciled line "%(line)s".</field>
</record>
<record model="ir.message" id="msg_line_party_required">
<field name="text">To create a line on account "%(account)s", you must set a party on line "%(line)s".</field>
</record>
<record model="ir.message" id="msg_line_party_set">
<field name="text">To create a line on account "%(account)s", you must remove the party on line "%(line)s".</field>
</record>
<record model="ir.message" id="msg_group_line">
<field name="text">Line "%(line)s" can not be grouped.</field>
</record>
<record model="ir.message" id="msg_group_line_single">
<field name="text">You cannot group a single line.</field>
</record>
<record model="ir.message" id="msg_group_line_many_parties">
<field name="text">You cannot group lines with different parties.</field>
</record>
<record model="ir.message" id="msg_group_line_same_company">
<field name="text">You cannot group lines of different companies.</field>
</record>
<record model="ir.message" id="msg_group_line_same_second_currency">
<field name="text">You cannot group lines of different second currencies.</field>
</record>
<record model="ir.message" id="msg_group_line_maximum_account">
<field name="text">You cannot group lines from more than 2 different accounts.</field>
</record>
<record model="ir.message" id="msg_reschedule_line_same_origins">
<field name="text">You cannot reschedule lines with different origins.</field>
</record>
<record model="ir.message" id="msg_reschedule_line_same_currency">
<field name="text">You cannot reschedule lines with different currencies.</field>
</record>
<record model="ir.message" id="msg_reschedule_line_same_account">
<field name="text">You cannot reschedule lines with different accounts.</field>
</record>
<record model="ir.message" id="msg_reschedule_line_same_party">
<field name="text">You cannot reschedule lines with different parties.</field>
</record>
<record model="ir.message" id="msg_reschedule_line_wrong_amount">
<field name="text">To reschedule the lines you must change the terms to have a total amount of %(total_amount)s instead of %(amount)s.</field>
</record>
<record model="ir.message" id="msg_delegate_line_same_company">
<field name="text">You cannot delegate together lines of different companies.</field>
</record>
<record model="ir.message" id="msg_delegate_line_same_origins">
<field name="text">You cannot delegate together lines with different origins.</field>
</record>
<record model="ir.message" id="msg_cancel_line_delegated">
<field name="text">The moves "%(moves)s" contain grouped lines, cancelling them will ungroup the lines.</field>
</record>
<record model="ir.message" id="msg_company_change_currency">
<field name="text">You cannot change the currency of a company which is associated with account moves.</field>
</record>
<record model="ir.message" id="msg_close_period_inactive_accounts">
<field name="text">To close period "%(period)s", you must balance the inactive account "%(account)s".</field>
</record>
<record model="ir.message" id="msg_journal_account_moves">
<field name="text">You cannot change the type of journal "%(journal)s" because it has posted moves.</field>
</record>
</data>
</tryton>

3274
modules/account/move.py Normal file

File diff suppressed because it is too large Load Diff

545
modules/account/move.xml Normal file
View File

@@ -0,0 +1,545 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="move_view_form">
<field name="model">account.move</field>
<field name="type">form</field>
<field name="name">move_form</field>
</record>
<record model="ir.ui.view" id="move_view_tree">
<field name="model">account.move</field>
<field name="type">tree</field>
<field name="name">move_tree</field>
</record>
<record model="ir.action.act_window" id="act_move_form">
<field name="name">Account Moves</field>
<field name="res_model">account.move</field>
<field name="context_model">account.move.context</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
<field name="context_domain" eval="[('company', '=', Eval('company', -1))]" pyson="1"/>
<field name="search_value"
eval="[('create_date', '>=', DateTime(hour=0, minute=0, second=0, microsecond=0, delta_years=-1))]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_move_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_view_tree"/>
<field name="act_window" ref="act_move_form"/>
</record>
<record model="ir.action.act_window.view" id="act_move_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="move_view_form"/>
<field name="act_window" ref="act_move_form"/>
</record>
<menuitem
parent="menu_entries"
action="act_move_form"
sequence="50"
id="menu_move_form"/>
<record model="ir.rule.group" id="rule_group_move_companies">
<field name="name">User in companies</field>
<field name="model">account.move</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_move_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_move_companies"/>
</record>
<record model="ir.model.access" id="access_move">
<field name="model">account.move</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_move_account">
<field name="model">account.move</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.model.button" id="move_post_button">
<field name="model">account.move</field>
<field name="name">post</field>
<field name="string">Post</field>
</record>
<record model="ir.sequence.type" id="sequence_type_account_move">
<field name="name">Account Move</field>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_account_move_group_admin">
<field name="sequence_type" ref="sequence_type_account_move"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_account_move_group_account_admin">
<field name="sequence_type" ref="sequence_type_account_move"/>
<field name="group" ref="group_account_admin"/>
</record>
<record model="ir.ui.view" id="move_context_view_form">
<field name="model">account.move.context</field>
<field name="type">form</field>
<field name="name">move_context_form</field>
</record>
<record model="ir.ui.view" id="move_reconciliation_view_form">
<field name="model">account.move.reconciliation</field>
<field name="type">form</field>
<field name="name">move_reconciliation_form</field>
</record>
<record model="ir.ui.view" id="move_reconciliation_view_tree">
<field name="model">account.move.reconciliation</field>
<field name="type">tree</field>
<field name="name">move_reconciliation_tree</field>
</record>
<record model="ir.action.act_window" id="act_move_reconciliation_lines">
<field name="name">Reconciliation Lines</field>
<field name="res_model">account.move.line</field>
<field name="domain"
eval="[If(Eval('active_ids', []) == [Eval('active_id')], ('reconciliation', '=', Eval('active_id')), ('reconciliation', 'in', Eval('active_ids')))]"
pyson="1"/>
</record>
<record model="ir.action.keyword" id="act_move_reconciliation_lines_keyword1">
<field name="keyword">form_relate</field>
<field name="model">account.move.reconciliation,-1</field>
<field name="action" ref="act_move_reconciliation_lines"/>
</record>
<record model="ir.rule.group" id="rule_group_move_reconciliation_companies">
<field name="name">User in companies</field>
<field name="model">account.move.reconciliation</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_move_reconciliation_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_move_reconciliation_companies"/>
</record>
<record model="ir.model.access" id="access_move_reconciliation">
<field name="model">account.move.reconciliation</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_move_reconciliation_account">
<field name="model">account.move.reconciliation</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_move_reconciliation_account_admin">
<field name="model">account.move.reconciliation</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.sequence.type" id="sequence_type_account_move_reconciliation">
<field name="name">Account Move Reconciliation</field>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_account_move_reconciliation_group_admin">
<field name="sequence_type" ref="sequence_type_account_move_reconciliation"/>
<field name="group" ref="res.group_admin"/>
</record>
<record model="ir.sequence.type-res.group"
id="sequence_type_account_move_reconciliation_group_account_admin">
<field name="sequence_type" ref="sequence_type_account_move_reconciliation"/>
<field name="group" ref="group_account_admin"/>
</record>
<record model="ir.sequence" id="sequence_account_move_reconciliation">
<field name="name">Default Account Move Reconciliation</field>
<field name="sequence_type" ref="sequence_type_account_move_reconciliation"/>
</record>
<record model="ir.ui.view" id="move_line_view_form">
<field name="model">account.move.line</field>
<field name="type">form</field>
<field name="priority" eval="10"/>
<field name="name">move_line_form</field>
</record>
<record model="ir.ui.view" id="move_line_view_form_move">
<field name="model">account.move.line</field>
<field name="type">form</field>
<field name="priority" eval="20"/>
<field name="name">move_line_form_move</field>
</record>
<record model="ir.ui.view" id="move_line_view_tree">
<field name="model">account.move.line</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">move_line_tree</field>
</record>
<record model="ir.ui.view" id="move_line_view_tree_move">
<field name="model">account.move.line</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">move_line_tree_move</field>
</record>
<record model="ir.ui.view" id="move_line_view_list_payable_receivable">
<field name="model">account.move.line</field>
<field name="type">tree</field>
<field name="priority" eval="30"/>
<field name="name">move_line_list_payable_receivable</field>
</record>
<record model="ir.ui.view" id="move_line_view_list_reconcile">
<field name="model">account.move.line</field>
<field name="type">tree</field>
<field name="priority" eval="30"/>
<field name="name">move_line_list_reconcile</field>
</record>
<record model="ir.action.act_window" id="act_move_line_form">
<field name="name">Account Move Lines</field>
<field name="res_model">account.move.line</field>
<field
name="domain"
eval="[('account', 'in', Eval('active_ids', [])), ('state', '=', 'valid')]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_move_line_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_line_view_tree"/>
<field name="act_window" ref="act_move_line_form"/>
</record>
<record model="ir.action.act_window.view" id="act_move_line_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="move_line_view_form"/>
<field name="act_window" ref="act_move_line_form"/>
</record>
<record model="ir.action.wizard" id="act_open_account">
<field name="name">Open Move Account</field>
<field name="wiz_name">account.move.open_account</field>
<field name="model">account.account</field>
</record>
<record model="ir.action.keyword" id="act_open_account_keyword1">
<field name="keyword">tree_open</field>
<field name="model">account.account,-1</field>
<field name="action" ref="act_open_account"/>
</record>
<record model="ir.action.keyword" id="act_open_account_keyword2">
<field name="keyword">form_relate</field>
<field name="model">account.account,-1</field>
<field name="action" ref="act_open_account"/>
</record>
<record model="ir.action.act_window"
id="act_move_line_payable_receivable">
<field name="name">Payable/Receivable Lines</field>
<field name="res_model">account.move.line</field>
<field name="context_model">account.move.line.receivable_payable.context</field>
<field name="domain" eval="[('party', 'in', Eval('active_ids'))]" pyson="1"/>
<field name="context_domain"
eval="[('company', '=', Eval('company', -1)), ['OR', If(Eval('receivable', True), ('account.type.receivable', '=', True), ('id', '&lt;', 0)), If(Eval('payable', True), ('account.type.payable', '=', True), ('id', '&lt;', 0))], If(Eval('reconciled', False), (), ('reconciliation', '=', None))]"
pyson="1"/>
<field name="search_value"></field>
<field name="order" eval="[('payable_receivable_date', 'ASC NULLS FIRST'), ('id', 'DESC')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_move_line_payable_receivable_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_line_view_list_payable_receivable"/>
<field name="act_window" ref="act_move_line_payable_receivable"/>
</record>
<record model="ir.action.keyword"
id="act_move_line_payable_receivable_keyword1">
<field name="keyword">form_relate</field>
<field name="model">party.party,-1</field>
<field name="action" ref="act_move_line_payable_receivable"/>
</record>
<record model="ir.action-res.group"
id="act_move_line_payable-group_account">
<field name="action" ref="act_move_line_payable_receivable"/>
<field name="group" ref="group_account"/>
</record>
<record model="ir.ui.view" id="move_line_receivable_payable_context_view_form">
<field name="model">account.move.line.receivable_payable.context</field>
<field name="type">form</field>
<field name="name">move_line_receivable_payable_context_form</field>
</record>
<record model="ir.ui.view" id="open_journal_ask_view_form">
<field name="model">account.move.open_journal.ask</field>
<field name="type">form</field>
<field name="name">open_journal_ask_form</field>
</record>
<record model="ir.action.wizard" id="act_open_journal">
<field name="name">Open Journal</field>
<field name="wiz_name">account.move.open_journal</field>
</record>
<record model="ir.action.keyword" id="act_open_journal_keyword">
<field name="keyword">tree_open</field>
<field name="model">account.journal.period,-1</field>
<field name="action" ref="act_open_journal"/>
</record>
<menuitem
parent="menu_entries"
action="act_open_journal"
sequence="20"
id="menu_open_journal"
icon="tryton-list"/>
<record model="ir.ui.view" id="reconcile_lines_writeoff_view_form">
<field name="model">account.move.reconcile_lines.writeoff</field>
<field name="type">form</field>
<field name="name">reconcile_lines_writeoff_form</field>
</record>
<record model="ir.action.wizard" id="act_reconcile_lines">
<field name="name">Reconcile Lines</field>
<field name="wiz_name">account.move.reconcile_lines</field>
<field name="model" eval="None"/>
</record>
<record model="ir.action.keyword" id="act_reconcile_lines_keyword">
<field name="keyword">form_action</field>
<field name="model">account.move.line,-1</field>
<field name="action" ref="act_reconcile_lines"/>
</record>
<record model="ir.action.keyword" id="act_reconcile_lines_keyword_general_ledger_line">
<field name="keyword">form_action</field>
<field name="model">account.general_ledger.line,-1</field>
<field name="action" ref="act_reconcile_lines"/>
</record>
<record model="ir.action.wizard" id="act_unreconcile_lines">
<field name="name">Unreconcile Lines</field>
<field name="wiz_name">account.move.unreconcile_lines</field>
<field name="model" eval="None"/>
</record>
<record model="ir.action.keyword" id="act_unreconcile_lines_keyword">
<field name="keyword">form_action</field>
<field name="model">account.move.line,-1</field>
<field name="action" ref="act_unreconcile_lines"/>
</record>
<record model="ir.action.keyword" id="act_unreconcile_lines_keyword_general_ledger_line">
<field name="keyword">form_action</field>
<field name="model">account.general_ledger.line,-1</field>
<field name="action" ref="act_unreconcile_lines"/>
</record>
<record model="ir.action.wizard" id="act_reconcile">
<field name="name">Reconcile Accounts</field>
<field name="wiz_name">account.reconcile</field>
<field name="window" eval="True"/>
</record>
<menuitem
parent="menu_processing"
action="act_reconcile"
sequence="20"
id="menu_reconcile"/>
<record model="ir.ui.view" id="reconcile_start_view_form">
<field name="model">account.reconcile.start</field>
<field name="type">form</field>
<field name="name">reconcile_start_form</field>
</record>
<record model="ir.ui.view" id="reconcile_show_view_form">
<field name="model">account.reconcile.show</field>
<field name="type">form</field>
<field name="name">reconcile_show_form</field>
</record>
<record model="ir.action.wizard" id="act_cancel_moves">
<field name="name">Cancel Moves</field>
<field name="wiz_name">account.move.cancel</field>
</record>
<record model="ir.action.keyword" id="act_cancel_moves_keyword1">
<field name="keyword">form_action</field>
<field name="model">account.move,-1</field>
<field name="action" ref="act_cancel_moves"/>
</record>
<record model="ir.ui.view" id="move_cancel_default_view_form">
<field name="model">account.move.cancel.default</field>
<field name="type">form</field>
<field name="name">move_cancel_default_form</field>
</record>
<record model="ir.ui.view" id="reconcile_writeoff_view_form">
<field name="model">account.move.reconcile.write_off</field>
<field name="type">form</field>
<field name="name">writeoff_form</field>
</record>
<record model="ir.ui.view" id="reconcile_writeoff_view_list">
<field name="model">account.move.reconcile.write_off</field>
<field name="type">tree</field>
<field name="name">writeoff_tree</field>
</record>
<record model="ir.action.act_window" id="act_reconcile_writeoff_form">
<field name="name">Write-off Methods</field>
<field name="res_model">account.move.reconcile.write_off</field>
</record>
<record model="ir.action.act_window.view" id="act_reconcile_writeoff_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="reconcile_writeoff_view_list"/>
<field name="act_window" ref="act_reconcile_writeoff_form"/>
</record>
<record model="ir.action.act_window.view" id="act_reconcile_writeoff_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="reconcile_writeoff_view_form"/>
<field name="act_window" ref="act_reconcile_writeoff_form"/>
</record>
<menuitem
parent="menu_journal_configuration"
action="act_reconcile_writeoff_form"
sequence="20"
id="menu_reconcile_writeoff_form"/>
<record model="ir.rule.group" id="rule_group_reconcile_writeoff_companies">
<field name="name">User in companies</field>
<field name="model">account.move.reconcile.write_off</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_reconcile_writeoff_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_reconcile_writeoff_companies"/>
</record>
<record model="ir.model.access" id="access_reconcile_writeoff">
<field name="model">account.move.reconcile.write_off</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_reconcile_writeoff_account_admin">
<field name="model">account.move.reconcile.write_off</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.action.wizard" id="act_group_lines_wizard">
<field name="name">Group Lines</field>
<field name="wiz_name">account.move.line.group</field>
</record>
<record model="ir.action.keyword" id="act_group_lines_keyword1">
<field name="keyword">form_action</field>
<field name="model">account.move.line,-1</field>
<field name="action" ref="act_group_lines_wizard"/>
</record>
<record model="ir.ui.view" id="move_line_group_start_view_form">
<field name="model">account.move.line.group.start</field>
<field name="type">form</field>
<field name="name">move_line_group_start_form</field>
</record>
<record model="ir.action.act_window" id="act_move_form_grouping">
<field name="name">Grouped Account Move</field>
<field name="res_model">account.move</field>
</record>
<record model="ir.action.act_window.view" id="act_move_form_grouping_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_view_form"/>
<field name="act_window" ref="act_move_form_grouping"/>
</record>
<record model="ir.action.wizard" id="act_reschedule_lines_wizard">
<field name="name">Reschedule Lines</field>
<field name="wiz_name">account.move.line.reschedule</field>
<field name="model">account.move.line</field>
</record>
<record model="ir.action.keyword" id="act_reschedule_lines_keyword1">
<field name="keyword">form_action</field>
<field name="model">account.move.line,-1</field>
<field name="action" ref="act_reschedule_lines_wizard"/>
</record>
<record model="ir.ui.view" id="move_line_reschedule_start_view_form">
<field name="model">account.move.line.reschedule.start</field>
<field name="type">form</field>
<field name="name">move_line_reschedule_start_form</field>
</record>
<record model="ir.ui.view" id="move_line_reschedule_preview_view_form">
<field name="model">account.move.line.reschedule.preview</field>
<field name="type">form</field>
<field name="name">move_line_reschedule_preview_form</field>
</record>
<record model="ir.ui.view" id="move_line_reschedule_term_view_list">
<field name="model">account.move.line.reschedule.term</field>
<field name="type">tree</field>
<field name="name">move_line_reschedule_term_list</field>
</record>
<record model="ir.action.act_window" id="act_move_form_rescheduling">
<field name="name">Reschedule Account Move</field>
<field name="res_model">account.move</field>
</record>
<record model="ir.action.act_window.view" id="act_move_form_rescheduling_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_view_form"/>
<field name="act_window" ref="act_move_form_rescheduling"/>
</record>
<record model="ir.action.wizard" id="act_delegate_lines_wizard">
<field name="name">Delegate Lines</field>
<field name="wiz_name">account.move.line.delegate</field>
<field name="model">account.move.line</field>
</record>
<record model="ir.action.keyword" id="act_delegate_lines_keyword1">
<field name="keyword">form_action</field>
<field name="model">account.move.line,-1</field>
<field name="action" ref="act_delegate_lines_wizard"/>
</record>
<record model="ir.ui.view" id="move_line_delegate_start_view_form">
<field name="model">account.move.line.delegate.start</field>
<field name="type">form</field>
<field name="name">move_line_delegate_start_form</field>
</record>
<record model="ir.action.act_window" id="act_move_form_delegate">
<field name="name">Delegate Account Move</field>
<field name="res_model">account.move</field>
</record>
<record model="ir.action.act_window.view" id="act_move_form_delegate_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_view_form"/>
<field name="act_window" ref="act_move_form_delegate"/>
</record>
<record model="ir.action.report" id="report_general_journal">
<field name="name">General Journal</field>
<field name="model">account.move</field>
<field name="report_name">account.move.general_journal</field>
<field name="report">account/general_journal.fodt</field>
</record>
<record model="ir.action.keyword" id="report_general_journal_keyword">
<field name="keyword">form_print</field>
<field name="model">account.move,-1</field>
<field name="action" ref="report_general_journal"/>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,491 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from xml.sax.saxutils import quoteattr
from simpleeval import InvalidExpression, simple_eval
from trytond.i18n import gettext
from trytond.model import (
DeactivableMixin, ModelSQL, ModelView, fields, sequence_ordered)
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import decistmt
from trytond.transaction import Transaction
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
from .exceptions import (
MoveTemplateExpressionError, MoveTemplateKeywordValidationError,
PeriodNotFoundError)
class MoveTemplate(DeactivableMixin, ModelSQL, ModelView):
__name__ = 'account.move.template'
name = fields.Char('Name', required=True, translate=True)
keywords = fields.One2Many('account.move.template.keyword', 'move',
'Keywords')
company = fields.Many2One('company.company', 'Company', required=True)
journal = fields.Many2One(
'account.journal', 'Journal', required=True,
context={
'company': Eval('company', -1),
},
depends={'company'})
description = fields.Char('Description',
help="Keyword value substitutions are identified "
"by braces ('{' and '}').")
lines = fields.One2Many('account.move.line.template', 'move', 'Lines',
domain=[
('account.company', '=', Eval('company', -1)),
])
@staticmethod
def default_company():
return Transaction().context.get('company')
@classmethod
def validate_fields(cls, templates, field_names):
super().validate_fields(templates, field_names)
cls.check_description(templates, field_names)
@classmethod
def check_description(cls, templates, field_names=None):
pool = Pool()
Keyword = pool.get('account.move.template.keyword')
if field_names and not (field_names & {'description', 'keywords'}):
return
for template in templates:
if template.description:
values = {k.name: '' for k in template.keywords}
try:
template.description.format(
**dict(Keyword.format_values(template, values)))
except (KeyError, ValueError) as e:
raise MoveTemplateKeywordValidationError(
gettext(
'account.msg_move_template_invalid_description',
description=template.description,
template=template.rec_name,
error=e)) from e
def get_move(self, values):
'Return the move for the keyword values'
pool = Pool()
Move = pool.get('account.move')
Keyword = pool.get('account.move.template.keyword')
move = Move()
move.company = self.company
move.journal = self.journal
if self.description:
try:
move.description = self.description.format(
**dict(Keyword.format_values(self, values)))
except (KeyError, ValueError) as e:
raise MoveTemplateExpressionError(
gettext(
'account.msg_move_template_invalid_description',
description=self.description,
template=self.rec_name,
error=e)) from e
move.lines = [l.get_line(values) for l in self.lines]
return move
class MoveTemplateKeyword(sequence_ordered(), ModelSQL, ModelView):
__name__ = 'account.move.template.keyword'
name = fields.Char('Name', required=True)
string = fields.Char('String', required=True, translate=True)
move = fields.Many2One(
'account.move.template', "Move", required=True, ondelete='CASCADE')
type_ = fields.Selection([
('char', 'Char'),
('numeric', 'Numeric'),
('date', 'Date'),
('party', 'Party'),
], 'Type')
required = fields.Boolean('Required')
digits = fields.Integer('Digits', states={
'invisible': Eval('type_') != 'numeric',
'required': Eval('type_') == 'numeric',
})
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.add('move')
@classmethod
def validate(cls, keywords):
for keyword in keywords:
keyword.check_name()
def check_name(self):
if self.name and not self.name.isidentifier():
raise MoveTemplateKeywordValidationError(
gettext('account.msg_name_not_valid',
name=self.name))
@staticmethod
def default_required():
return False
def get_field(self):
field = getattr(self, '_get_field_%s' % self.type_)()
field.update({
'name': self.name,
'string': self.string,
'required': self.required,
'help': '',
})
return field
def _get_field_char(self):
return {'type': 'char'}
def _get_field_numeric(self):
return {'type': 'numeric', 'digits': (16, self.digits)}
def _format_numeric(self, lang, value):
if value:
return lang.format('%.*f', (self.digits, value), True)
else:
return ''
def _get_field_date(self):
return {'type': 'date'}
def _format_date(self, lang, value):
if value:
return lang.strftime(value)
else:
return ''
def _get_field_party(self):
return {
'type': 'many2one',
'relation': 'party.party',
}
def _format_party(self, lang, value):
pool = Pool()
Party = pool.get('party.party')
if value:
return Party(value).rec_name
else:
return ''
@staticmethod
def format_values(template, values):
"Yield key and formatted value"
pool = Pool()
Lang = pool.get('ir.lang')
lang, = Lang.search([
('code', '=', Transaction().language),
])
keywords = {k.name: k for k in template.keywords}
for k, v in values.items():
keyword = keywords[k]
func = getattr(keyword, '_format_%s' % keyword.type_, None)
if func:
yield k, func(lang, v)
else:
yield k, v
class MoveLineTemplate(ModelSQL, ModelView):
__name__ = 'account.move.line.template'
move = fields.Many2One(
'account.move.template', "Move", required=True, ondelete='CASCADE')
operation = fields.Selection([
('debit', 'Debit'),
('credit', 'Credit'),
], 'Operation', required=True)
amount = fields.Char('Amount', required=True,
help="A python expression that will be evaluated with the keywords.")
account = fields.Many2One('account.account', 'Account', required=True,
domain=[
('type', '!=', None),
('closed', '!=', True),
('company', '=', Eval('_parent_move', {}).get('company', -1)),
])
party = fields.Char('Party',
states={
'required': Eval('party_required', False),
'invisible': ~Eval('party_required', False),
},
help="The name of the 'Party' keyword.")
party_required = fields.Function(fields.Boolean('Party Required'),
'on_change_with_party_required')
description = fields.Char('Description',
help="Keyword value substitutions are identified "
"by braces ('{' and '}').")
taxes = fields.One2Many('account.tax.line.template', 'line', 'Taxes')
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.add('move')
@fields.depends('account')
def on_change_with_party_required(self, name=None):
if self.account:
return self.account.party_required
return False
def get_line(self, values):
'Return the move line for the keyword values'
pool = Pool()
Line = pool.get('account.move.line')
Keyword = pool.get('account.move.template.keyword')
line = Line()
try:
amount = simple_eval(decistmt(self.amount),
functions={'Decimal': Decimal}, names=values)
except (InvalidExpression, SyntaxError) as e:
raise MoveTemplateExpressionError(
gettext('account.msg_move_template_invalid_expression',
expression=values,
template=self.move.rec_name,
error=e)) from e
if not isinstance(amount, Decimal):
raise MoveTemplateExpressionError(
gettext('account.msg_move_template_expression_not_number',
value=amount,
expression=self.move.name,
template=self.move.rec_name))
amount = self.move.company.currency.round(amount)
if self.operation == 'debit':
line.debit = amount
else:
line.credit = amount
line.account = self.account
if self.party:
line.party = values.get(self.party)
if self.description:
try:
line.description = self.description.format(
**dict(Keyword.format_values(self.move, values)))
except KeyError as e:
raise MoveTemplateExpressionError(
gettext('account.msg_move_template_invalid_expression',
expression=values,
template=self.move.name,
error=e)) from e
line.tax_lines = [t.get_line(values) for t in self.taxes]
return line
class TaxLineTemplate(ModelSQL, ModelView):
__name__ = 'account.tax.line.template'
line = fields.Many2One(
'account.move.line.template', "Line",
required=True, ondelete='CASCADE')
amount = fields.Char('Amount', required=True,
help="A python expression that will be evaluated with the keywords.")
type = fields.Selection([
('tax', "Tax"),
('base', "Base"),
], "Type", required=True)
tax = fields.Many2One('account.tax', 'Tax',
domain=[
('company', '=', Eval('_parent_line', {}
).get('_parent_move', {}).get('company', -1)),
],
depends={'line'})
@classmethod
def __setup__(cls):
super().__setup__()
cls.__access__.add('line')
def get_line(self, values):
'Return the tax line for the keyword values'
pool = Pool()
TaxLine = pool.get('account.tax.line')
line = TaxLine()
try:
amount = simple_eval(decistmt(self.amount),
functions={'Decimal': Decimal}, names=values)
except (InvalidExpression, SyntaxError) as e:
raise MoveTemplateExpressionError(
gettext('account.msg_template_invalid_expression',
expression=values,
template=self.line.rec_name,
error=e)) from e
if not isinstance(amount, Decimal):
raise MoveTemplateExpressionError(
gettext('account.msg_not_number',
result=amount,
expression=self.move.rec_name))
amount = self.line.move.company.currency.round(amount)
line.amount = amount
line.type = self.type
line.tax = self.tax
return line
class KeywordStateView(StateView):
def get_view(self, wizard, state_name):
fields = {}
view = {
'model': 'account.move.template.create.keywords',
'view_id': 0,
'type': 'form',
'fields': fields,
}
if not wizard.template.template:
return view
template = wizard.template.template
field_template = ('<label name=%(name)s/>'
'<field name=%(name)s/>')
view['arch'] = ('<?xml version="1.0"?>'
'<form col="2" string=%s>%s</form>' % (
quoteattr(template.name),
''.join(field_template % {'name': quoteattr(keyword.name)}
for keyword in template.keywords)
))
for keyword in template.keywords:
fields[keyword.name] = keyword.get_field()
return view
def get_defaults(self, wizard, state_name, fields):
return {}
class CreateMove(Wizard):
__name__ = 'account.move.template.create'
start = StateTransition()
template = StateView('account.move.template.create.template',
'account.move_template_create_template_view_form', [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Next', 'keywords', 'tryton-forward', default=True),
])
keywords = KeywordStateView('account.move.template.create.keywords',
None, [
Button('Cancel', 'end', 'tryton-cancel'),
Button('Create', 'create_', 'tryton-ok', default=True),
])
create_ = StateTransition()
open_ = StateAction('account.act_move_from_template')
def create_move(self):
template = self.template.template
values = {}
for keyword in template.keywords:
values[keyword.name] = getattr(self.keywords, keyword.name, None)
move = template.get_move(values)
move.date = self.template.date
move.period = self.template.period
move.save()
return move
def transition_start(self):
context = Transaction().context
action_id = context.get('action_id')
period = context.get('period')
if self.model and self.model.__name__ == 'account.move.line':
# Template id is used as action
self.template.template = action_id
self.template.period = period
return 'keywords'
else:
return 'template'
def transition_create_(self):
if self.model and self.model.__name__ == 'account.move.line':
self.create_move()
return 'end'
else:
return 'open_'
def do_open_(self, action):
move = self.create_move()
return action, {'res_id': move.id}
def end(self):
if self.model and self.model.__name__ == 'account.move.line':
return 'reload'
class CreateMoveTemplate(ModelView):
__name__ = 'account.move.template.create.template'
template = fields.Many2One('account.move.template', 'Template',
required=True,
domain=[
('company', '=', Eval('context', {}).get('company', -1)),
])
date = fields.Date('Effective Date', required=True)
period = fields.Many2One('account.period', 'Period', required=True,
domain=[
('state', '!=', 'closed'),
('fiscalyear.company.id', '=',
Eval('context', {}).get('company', 0)),
])
@classmethod
def default_date(cls):
pool = Pool()
Date = pool.get('ir.date')
return Date.today()
@classmethod
def default_period(cls):
pool = Pool()
Period = pool.get('account.period')
company = Transaction().context.get('company')
try:
period = Period.find(company)
except PeriodNotFoundError:
return None
return period.id
@fields.depends('date', 'period')
def on_change_date(self):
pool = Pool()
Period = pool.get('account.period')
company = Transaction().context.get('company')
if self.date:
if (not self.period
or not (
self.period.start_date <= self.date
<= self.period.end_date)):
try:
self.period = Period.find(company, date=self.date)
except PeriodNotFoundError:
pass
@fields.depends('period', 'date')
def on_change_period(self):
pool = Pool()
Date = pool.get('ir.date')
today = Date.today()
if self.period:
start_date = self.period.start_date
end_date = self.period.end_date
if (not self.date
or not (start_date <= self.date <= end_date)):
if start_date <= today:
if today <= end_date:
self.date = today
else:
self.date = end_date
else:
self.date = start_date
class CreateMoveKeywords(ModelView):
__no_slots__ = True
__name__ = 'account.move.template.create.keywords'

View File

@@ -0,0 +1,143 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="move_template_view_form">
<field name="model">account.move.template</field>
<field name="type">form</field>
<field name="name">move_template_form</field>
</record>
<record model="ir.ui.view" id="move_template_view_list">
<field name="model">account.move.template</field>
<field name="type">tree</field>
<field name="name">move_template_list</field>
</record>
<record model="ir.action.act_window" id="act_move_template_form">
<field name="name">Moves</field>
<field name="res_model">account.move.template</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
</record>
<record model="ir.action.act_window.view"
id="act_move_template_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_template_view_list"/>
<field name="act_window" ref="act_move_template_form"/>
</record>
<record model="ir.action.act_window.view"
id="act_move_template_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="move_template_view_form"/>
<field name="act_window" ref="act_move_template_form"/>
</record>
<menuitem
parent="menu_templates"
action="act_move_template_form"
sequence="10"
id="menu_move_template_form"/>
<record model="ir.rule.group" id="rule_group_move_template_companies">
<field name="name">User in companies</field>
<field name="model">account.move.template</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_move_template_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_move_template_companies"/>
</record>
<record model="ir.model.access" id="access_move_template">
<field name="model">account.move.template</field>
<field name="perm_read" eval="False"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_move_template_account">
<field name="model">account.move.template</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_move_template_account_admin">
<field name="model">account.move.template</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="move_template_keyword_view_form">
<field name="model">account.move.template.keyword</field>
<field name="type">form</field>
<field name="name">move_template_keyword_form</field>
</record>
<record model="ir.ui.view" id="move_template_keyword_view_list">
<field name="model">account.move.template.keyword</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">move_template_keyword_list</field>
</record>
<record model="ir.ui.view" id="move_template_keyword_view_list_sequence">
<field name="model">account.move.template.keyword</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">move_template_keyword_list_sequence</field>
</record>
<record model="ir.ui.view" id="move_line_template_view_form">
<field name="model">account.move.line.template</field>
<field name="type">form</field>
<field name="name">move_line_template_form</field>
</record>
<record model="ir.ui.view" id="move_line_template_view_list">
<field name="model">account.move.line.template</field>
<field name="type">tree</field>
<field name="name">move_line_template_list</field>
</record>
<record model="ir.ui.view" id="tax_line_template_view_form">
<field name="model">account.tax.line.template</field>
<field name="type">form</field>
<field name="name">tax_line_template_form</field>
</record>
<record model="ir.ui.view" id="tax_line_template_view_list">
<field name="model">account.tax.line.template</field>
<field name="type">tree</field>
<field name="name">tax_line_template_list</field>
</record>
<record model="ir.ui.view" id="move_template_create_template_view_form">
<field name="model">account.move.template.create.template</field>
<field name="type">form</field>
<field name="name">move_template_create_template_form</field>
</record>
<record model="ir.action.wizard" id="act_move_template_create">
<field name="name">Create Move from Template</field>
<field name="wiz_name">account.move.template.create</field>
</record>
<menuitem
parent="menu_entries"
action="act_move_template_create"
sequence="20"
id="menu_move_template_create"/>
<record model="ir.action.act_window" id="act_move_from_template">
<field name="name">Account Move</field>
<field name="res_model">account.move</field>
</record>
<record model="ir.action.act_window.view"
id="act_move_from_template_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="move_view_form"/>
<field name="act_window" ref="act_move_from_template"/>
</record>
</data>
</tryton>

358
modules/account/party.py Normal file
View File

@@ -0,0 +1,358 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from collections import defaultdict
from decimal import Decimal
from sql import Literal, Null
from sql.aggregate import Sum
from sql.conditionals import Coalesce
from trytond import backend
from trytond.i18n import gettext
from trytond.model import ModelSQL, fields
from trytond.modules.company.model import (
CompanyMultiValueMixin, CompanyValueMixin)
from trytond.modules.currency.fields import Monetary
from trytond.modules.party.exceptions import EraseError
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import timezone as tz
from trytond.transaction import Transaction
from .exceptions import AccountMissing
account_names = [
'account_payable', 'account_receivable',
'customer_tax_rule', 'supplier_tax_rule']
class Party(CompanyMultiValueMixin, metaclass=PoolMeta):
__name__ = 'party.party'
accounts = fields.One2Many('party.party.account', 'party', "Accounts")
account_payable = fields.MultiValue(fields.Many2One(
'account.account', "Account Payable",
domain=[
('closed', '!=', True),
('type.payable', '=', True),
('party_required', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
],
states={
'invisible': ~Eval('context', {}).get('company'),
}))
account_receivable = fields.MultiValue(fields.Many2One(
'account.account', "Account Receivable",
domain=[
('closed', '!=', True),
('type.receivable', '=', True),
('party_required', '=', True),
('company', '=', Eval('context', {}).get('company', -1)),
],
states={
'invisible': ~Eval('context', {}).get('company'),
}))
customer_tax_rule = fields.MultiValue(fields.Many2One(
'account.tax.rule', "Customer Tax Rule",
domain=[
('company', '=', Eval('context', {}).get('company', -1)),
('kind', 'in', ['sale', 'both']),
],
states={
'invisible': ~Eval('context', {}).get('company'),
}, help='Apply this rule on taxes when party is customer.'))
supplier_tax_rule = fields.MultiValue(fields.Many2One(
'account.tax.rule', "Supplier Tax Rule",
domain=[
('company', '=', Eval('context', {}).get('company', -1)),
('kind', 'in', ['purchase', 'both']),
],
states={
'invisible': ~Eval('context', {}).get('company'),
}, help='Apply this rule on taxes when party is supplier.'))
currency = fields.Function(fields.Many2One(
'currency.currency', "Currency"), 'get_currency')
receivable = fields.Function(Monetary(
"Receivable", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
payable = fields.Function(Monetary(
"Payable", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
receivable_today = fields.Function(Monetary(
"Receivable Today", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
payable_today = fields.Function(Monetary(
"Payable Today", currency='currency', digits='currency'),
'get_receivable_payable', searcher='search_receivable_payable')
@classmethod
def multivalue_model(cls, field):
pool = Pool()
if field in account_names:
return pool.get('party.party.account')
return super().multivalue_model(field)
@classmethod
def _default_tax_rule(cls, type_, **pattern):
pool = Pool()
Configuration = pool.get('account.configuration')
config = Configuration(1)
assert type_ in {'customer', 'supplier'}
tax_rule = config.get_multivalue(
'default_%s_tax_rule' % type_, **pattern)
return tax_rule.id if tax_rule else None
@classmethod
def default_customer_tax_rule(cls, **pattern):
return cls._default_tax_rule('customer', **pattern)
@classmethod
def default_supplier_tax_rule(cls, **pattern):
return cls._default_tax_rule('supplier', **pattern)
def get_currency(self, name):
pool = Pool()
Company = pool.get('company.company')
company_id = Transaction().context.get('company')
if company_id is not None and company_id >= 0:
company = Company(company_id)
return company.currency
@classmethod
def _receivable_payable_query(cls, names, company, parties=None):
pool = Pool()
Account = pool.get('account.account')
AccountType = pool.get('account.account.type')
Date = pool.get('ir.date')
Move = pool.get('account.move')
MoveLine = pool.get('account.move.line')
transaction = Transaction()
context = transaction.context
account = Account.__table__()
account_type = AccountType.__table__()
move = Move.__table__()
move_line = MoveLine.__table__()
if date := context.get('date'):
today = date
elif datetime := context.get('_datetime'):
if company.timezone:
timezone = tz.ZoneInfo(company.timezone)
datetime = datetime.astimezone(timezone)
today = datetime.date()
else:
with transaction.set_context(company=company.id):
today = Date.today()
date = Coalesce(move_line.maturity_date, move.date)
expressions = {
'receivable': Sum(
move_line.debit - move_line.credit,
filter_=account_type.receivable),
'receivable_today': Sum(
move_line.debit - move_line.credit,
filter_=account_type.receivable & (date <= today)),
'payable': Sum(
move_line.debit - move_line.credit,
filter_=account_type.payable),
'payable_today': Sum(
move_line.debit - move_line.credit,
filter_=account_type.payable & (date <= today)),
}
columns = []
for name in names:
columns.append(Coalesce(expressions[name], Decimal()).as_(name))
if parties is not None:
party_where = reduce_ids(move_line.party, [p.id for p in parties])
else:
party_where = Literal(True)
query = (
move_line
.join(move, condition=move_line.move == move.id)
.join(account, condition=move_line.account == account.id)
.join(account_type, condition=account.type == account_type.id)
.select(
move_line.party.as_('party'),
*columns,
where=(
(move_line.reconciliation == Null)
& (account.company == company.id)
& party_where),
group_by=move_line.party))
return query
@classmethod
def get_receivable_payable(cls, parties, names):
pool = Pool()
User = pool.get('res.user')
transaction = Transaction()
cursor = transaction.connection.cursor()
amounts = {name: defaultdict(Decimal) for name in names}
user = User(transaction.user)
if not user.company:
return amounts
company = user.company
currency = company.currency
for sub_parties in grouped_slice(parties):
query = cls._receivable_payable_query(names, company, sub_parties)
if backend.name == 'sqlite':
sqlite_apply_types(query, [None] + ['NUMERIC'] * 4)
cursor.execute(*query)
for party_id, *values in cursor:
for name, value in zip(names, values):
amounts[name][party_id] = currency.round(value)
return amounts
@classmethod
def search_receivable_payable(cls, name, clause):
pool = Pool()
User = pool.get('res.user')
MoveLine = pool.get('account.move.line')
transaction = Transaction()
user = User(transaction.user)
if not user.company:
return [('id', '=', -1)]
company = user.company
query = cls._receivable_payable_query([name], company)
columns = list(query.columns)
amount = columns.pop(1).expression
_, operator, value = clause
Operator = fields.SQL_OPERATORS[operator]
if backend.name == 'sqlite':
cast_ = MoveLine.debit.sql_cast
if operator in {'in', 'not in'}:
value = [cast_(Literal(Decimal(v or 0))) for v in value]
else:
value = cast_(Literal(Decimal(value or 0)))
amount = cast_(amount)
query.having = Operator(amount, value)
query.columns = columns
return [('id', 'in', query)]
@property
def account_payable_used(self):
pool = Pool()
Configuration = pool.get('account.configuration')
account = self.account_payable
if not account:
with Transaction().set_context(self._context):
config = Configuration(1)
account = config.get_multivalue('default_account_payable')
# Allow empty values on on_change
if not account and not Transaction().readonly:
raise AccountMissing(
gettext('account.msg_party_missing_payable_account',
party=self.rec_name))
if account:
return account.current()
@property
def account_receivable_used(self):
pool = Pool()
Configuration = pool.get('account.configuration')
account = self.account_receivable
if not account:
with Transaction().set_context(self._context):
config = Configuration(1)
account = config.get_multivalue('default_account_receivable')
# Allow empty values on on_change
if not account and not Transaction().readonly:
raise AccountMissing(
gettext('account.msg_party_missing_receivable_account',
party=self.rec_name))
if account:
return account.current()
@classmethod
def view_attributes(cls):
return super().view_attributes() + [
('/tree/field[@name="receivable_today"]',
'visual', If(Eval('receivable_today', 0) > 0, 'danger', '')),
('/tree/field[@name="payable_today"]',
'visual', If(Eval('payable_today', 0) < 0, 'warning', '')),
]
@classmethod
def copy(cls, parties, default=None):
default = default.copy() if default else {}
if Transaction().check_access:
fields = [
'accounts',
'account_payable', 'account_receivable',
'customer_tax_rule', 'supplier_tax_rule']
default_values = cls.default_get(fields, with_rec_name=False)
for fname in fields:
default.setdefault(fname, default_values.get(fname))
return super().copy(parties, default=default)
class PartyAccount(ModelSQL, CompanyValueMixin):
__name__ = 'party.party.account'
party = fields.Many2One(
'party.party', "Party", ondelete='CASCADE',
context={
'company': Eval('company', -1),
},
depends={'company'})
account_payable = fields.Many2One(
'account.account', "Account Payable",
domain=[
('type.payable', '=', True),
('party_required', '=', True),
('company', '=', Eval('company', -1)),
],
ondelete='RESTRICT')
account_receivable = fields.Many2One(
'account.account', "Account Receivable",
domain=[
('type.receivable', '=', True),
('party_required', '=', True),
('company', '=', Eval('company', -1)),
],
ondelete='RESTRICT')
customer_tax_rule = fields.Many2One(
'account.tax.rule', "Customer Tax Rule",
domain=[
('company', '=', Eval('company', -1)),
('kind', 'in', ['sale', 'both']),
],
ondelete='RESTRICT')
supplier_tax_rule = fields.Many2One(
'account.tax.rule', "Supplier Tax Rule",
domain=[
('company', '=', Eval('company', -1)),
('kind', 'in', ['purchase', 'both']),
],
ondelete='RESTRICT')
class PartyReplace(metaclass=PoolMeta):
__name__ = 'party.replace'
@classmethod
def fields_to_replace(cls):
return super().fields_to_replace() + [
('account.move.line', 'party'),
]
class PartyErase(metaclass=PoolMeta):
__name__ = 'party.erase'
def check_erase_company(self, party, company):
super().check_erase_company(party, company)
if party.receivable or party.payable:
raise EraseError(
gettext('account.msg_erase_party_receivable_payable',
party=party.rec_name,
company=company.rec_name))

88
modules/account/party.xml Normal file
View File

@@ -0,0 +1,88 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="party_view_tree">
<field name="model">party.party</field>
<field name="inherit" ref="party.party_view_tree"/>
<field name="name">party_tree</field>
</record>
<record model="ir.ui.view" id="party_view_form">
<field name="model">party.party</field>
<field name="inherit" ref="party.party_view_form"/>
<field name="name">party_form</field>
</record>
<record model="ir.model.field.access" id="access_party_accounts">
<field name="model">party.party</field>
<field name="field">accounts</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_party_accounts_account_account">
<field name="model">party.party</field>
<field name="field">accounts</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_party_account_payable">
<field name="model">party.party</field>
<field name="field">account_payable</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_party_account_payable_account">
<field name="model">party.party</field>
<field name="field">account_payable</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_party_account_receivable">
<field name="model">party.party</field>
<field name="field">account_receivable</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_party_account_receivable_account">
<field name="model">party.party</field>
<field name="field">account_receivable</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_party_customer_tax_rule">
<field name="model">party.party</field>
<field name="field">customer_tax_rule</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_party_customer_tax_rule_account">
<field name="model">party.party</field>
<field name="field">customer_tax_rule</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
<record model="ir.model.field.access" id="access_party_supplier_tax_rule">
<field name="model">party.party</field>
<field name="field">supplier_tax_rule</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
</record>
<record model="ir.model.field.access" id="access_party_supplier_tax_rule_account">
<field name="model">party.party</field>
<field name="field">supplier_tax_rule</field>
<field name="group" ref="group_account"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
</record>
</data>
</tryton>

439
modules/account/period.py Normal file
View File

@@ -0,0 +1,439 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql import Null
from sql.operators import Equal, NotEqual
from trytond.cache import Cache
from trytond.const import OPERATORS
from trytond.i18n import gettext
from trytond.model import Exclude, Index, ModelSQL, ModelView, Workflow, fields
from trytond.model.exceptions import AccessError
from trytond.pool import Pool
from trytond.pyson import Eval, Id
from trytond.sql.functions import DateRange
from trytond.sql.operators import RangeOverlap
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from .exceptions import ClosePeriodError, PeriodDatesError, PeriodNotFoundError
_STATES = {
'readonly': Eval('state') != 'open',
}
class Period(Workflow, ModelSQL, ModelView):
__name__ = 'account.period'
name = fields.Char('Name', required=True)
start_date = fields.Date(
"Start Date", required=True, states=_STATES,
domain=[('start_date', '<=', Eval('end_date', None))])
end_date = fields.Date(
"End Date", required=True, states=_STATES,
domain=[('end_date', '>=', Eval('start_date', None))])
fiscalyear = fields.Many2One(
'account.fiscalyear', "Fiscal Year", required=True, ondelete='CASCADE',
states=_STATES)
state = fields.Selection([
('open', 'Open'),
('closed', 'Closed'),
('locked', 'Locked'),
], 'State', readonly=True, required=True, sort=False)
move_sequence = fields.Many2One(
'ir.sequence.strict', "Move Sequence",
domain=[
('sequence_type', '=',
Id('account', 'sequence_type_account_move')),
['OR',
('company', '=', None),
('company', '=', Eval('company', -1)),
],
],
help="Used to generate the move number when posting.\n"
"Leave empty to use the fiscal year sequence.")
type = fields.Selection([
('standard', 'Standard'),
('adjustment', 'Adjustment'),
], 'Type', required=True,
states=_STATES)
company = fields.Function(fields.Many2One('company.company', 'Company',),
'on_change_with_company', searcher='search_company')
icon = fields.Function(fields.Char("Icon"), 'get_icon')
_find_cache = Cache(__name__ + '.find', context=False)
@classmethod
def __setup__(cls):
super().__setup__()
t = cls.__table__()
cls.__access__.add('fiscalyear')
cls._sql_constraints += [
('standard_dates_overlap',
Exclude(t,
(t.fiscalyear, Equal),
(DateRange(t.start_date, t.end_date, '[]'), RangeOverlap),
where=t.type == 'standard'),
'account.msg_period_standard_overlap'),
('move_sequence_unique',
Exclude(t,
(t.move_sequence, Equal),
(t.fiscalyear, NotEqual)),
'account.msg_period_move_sequence_unique'),
]
cls._sql_indexes.add(
Index(
t,
(t.start_date, Index.Range()),
(t.end_date, Index.Range()),
order='DESC'))
cls._order.insert(0, ('start_date', 'DESC'))
cls._transitions |= set((
('open', 'closed'),
('closed', 'locked'),
('closed', 'open'),
))
cls._buttons.update({
'close': {
'invisible': Eval('state') != 'open',
'depends': ['state'],
},
'reopen': {
'invisible': Eval('state') != 'closed',
'depends': ['state'],
},
'lock_': {
'invisible': Eval('state') != 'closed',
'depends': ['state'],
},
})
@classmethod
def __register__(cls, module):
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
Sequence = pool.get('ir.sequence')
SequenceStrict = pool.get('ir.sequence.strict')
table_h = cls.__table_handler__(module)
cursor = Transaction().connection.cursor()
t = cls.__table__()
migrate_move_sequence = not table_h.column_exist('move_sequence')
super().__register__(module)
# Migration from 6.8: rename state close to closed
cursor.execute(
*t.update([t.state], ['closed'], where=t.state == 'close'))
# Migrationn from 7.4: use strict sequence
if (table_h.column_exist('post_move_sequence')
and migrate_move_sequence):
table_h.not_null_action('post_move_sequence', 'remove')
fiscalyear_h = FiscalYear.__table_handler__(module)
fiscalyear = FiscalYear.__table__()
old2new = {}
fiscalyear_migrated = (
fiscalyear_h.column_exist('post_move_sequence')
and fiscalyear_h.column_exist('move_sequence'))
if fiscalyear_migrated:
cursor.execute(*fiscalyear.select(
fiscalyear.post_move_sequence,
fiscalyear.move_sequence))
old2new.update(cursor)
cursor.execute(*t.select(
t.post_move_sequence, distinct=True,
where=t.post_move_sequence != Null))
for sequence_id, in cursor:
if sequence_id not in old2new:
sequence = Sequence(sequence_id)
new_sequence = SequenceStrict(
name=sequence.name,
sequence_type=sequence.sequence_type,
prefix=sequence.prefix,
suffix=sequence.suffix,
type=sequence.type,
number_next=sequence.number_next,
number_increment=sequence.number_increment,
padding=sequence.padding,
timestamp_rounding=sequence.timestamp_rounding,
timestamp_offset=sequence.timestamp_offset,
last_timestamp=sequence.last_timestamp,
company=sequence.company)
new_sequence.save()
old2new[sequence_id] = new_sequence.id
for old_id, new_id in old2new.items():
cursor.execute(*t.update(
[t.move_sequence], [new_id],
where=t.post_move_sequence == old_id))
if fiscalyear_migrated:
table_h.drop_column('post_move_sequence')
fiscalyear_h.drop_column('post_move_sequence')
@staticmethod
def default_state():
return 'open'
@staticmethod
def default_type():
return 'standard'
@fields.depends('fiscalyear', '_parent_fiscalyear.company')
def on_change_with_company(self, name=None):
return self.fiscalyear.company if self.fiscalyear else None
@classmethod
def search_company(cls, name, clause):
return [('fiscalyear.' + clause[0],) + tuple(clause[1:])]
def get_icon(self, name):
return {
'open': 'tryton-account-open',
'closed': 'tryton-account-close',
'locked': 'tryton-account-block',
}.get(self.state)
@classmethod
def validate_fields(cls, periods, field_names):
super().validate_fields(periods, field_names)
cls.check_fiscalyear_dates(periods, field_names)
cls.check_move_dates(periods, field_names)
@classmethod
def check_fiscalyear_dates(cls, periods, field_names=None):
if field_names and not (
field_names & {
'start_date', 'end_date', 'fiscalyear'}):
return
for period in periods:
fiscalyear = period.fiscalyear
if (period.start_date < fiscalyear.start_date
or period.end_date > fiscalyear.end_date):
raise PeriodDatesError(
gettext('account.msg_period_fiscalyear_dates',
period=period.rec_name,
fiscalyear=fiscalyear.rec_name))
@classmethod
def check_move_dates(cls, periods, field_names=None):
pool = Pool()
Move = pool.get('account.move')
Lang = pool.get('ir.lang')
if field_names and not (field_names & {'start_date', 'end_date'}):
return
lang = Lang.get()
for sub_periods in grouped_slice(periods):
domain = ['OR']
for period in sub_periods:
domain.append([
('period', '=', period.id),
['OR',
('date', '<', period.start_date),
('date', '>', period.end_date),
],
])
moves = Move.search(domain, limit=1)
if moves:
move, = moves
raise PeriodDatesError(
gettext('account.msg_period_move_dates',
period=move.period.rec_name,
move=move.rec_name,
move_date=lang.strftime(move.date)))
@classmethod
def find(cls, company, date=None, test_state=True):
'''
Return the period for the company at the date or the current date
or raise PeriodNotFoundError.
If test_state is true, it searches on non-closed periods
'''
pool = Pool()
Date = pool.get('ir.date')
Lang = pool.get('ir.lang')
Company = pool.get('company.company')
company_id = int(company) if company is not None else None
if not date:
with Transaction().set_context(company=company_id):
date = Date.today()
key = (company_id, date, test_state)
period = cls._find_cache.get(key, -1)
if period is not None and period < 0:
clause = [
('start_date', '<=', date),
('end_date', '>=', date),
('fiscalyear.company', '=', company_id),
('type', '=', 'standard'),
]
periods = cls.search(
clause, order=[('start_date', 'DESC')], limit=1)
if periods:
period, = periods
else:
period = None
cls._find_cache.set(key, int(period) if period else None)
elif period is not None:
period = cls(period)
found = period and (not test_state or period.state == 'open')
if not found:
lang = Lang.get()
if company is not None and not isinstance(company, Company):
company = Company(company)
if not period:
raise PeriodNotFoundError(
gettext('account.msg_no_period_date',
date=lang.strftime(date),
company=company.rec_name if company else ''))
else:
raise PeriodNotFoundError(
gettext('account.msg_no_open_period_date',
date=lang.strftime(date),
period=period.rec_name,
company=company.rec_name if company else ''))
else:
return period
@classmethod
def search(cls, args, offset=0, limit=None, order=None, count=False,
query=False):
args = args[:]
def process_args(args):
i = 0
while i < len(args):
# add test for xmlrpc and pyson that doesn't handle tuple
if ((
isinstance(args[i], tuple)
or (isinstance(args[i], list) and len(args[i]) > 2
and args[i][1] in OPERATORS))
and args[i][0] in ('start_date', 'end_date')
and isinstance(args[i][2], (list, tuple))):
if not args[i][2][0]:
args[i] = ('id', '!=', '0')
else:
period = cls(args[i][2][0])
args[i] = (args[i][0], args[i][1],
getattr(period, args[i][2][1]))
elif isinstance(args[i], list):
process_args(args[i])
i += 1
process_args(args)
return super().search(args, offset=offset, limit=limit,
order=order, count=count, query=query)
@classmethod
def preprocess_values(cls, mode, values):
pool = Pool()
FiscalYear = pool.get('account.fiscalyear')
values = super().preprocess_values(mode, values)
if mode == 'create' and values.get('fiscalyear') is not None:
fiscalyear = FiscalYear(values['fiscalyear'])
if values.get('move_sequence') is None:
values['move_sequence'] = fiscalyear.move_sequence.id
return values
@classmethod
def check_modification(cls, mode, periods, values=None, external=False):
pool = Pool()
Move = pool.get('account.move')
super().check_modification(
mode, periods, values=values, external=external)
if mode == 'create':
for period in periods:
if period.fiscalyear.state != 'open':
raise AccessError(
gettext('account.msg_create_period_closed_fiscalyear',
fiscalyear=period.fiscalyear.rec_name))
elif mode == 'write':
if values.get('state') == 'open':
for period in periods:
if period.fiscalyear.state != 'open':
raise AccessError(
gettext(
'account.msg_open_period_closed_fiscalyear',
period=period.rec_name,
fiscalyear=period.fiscalyear.rec_name))
if 'move_sequence' in values:
for period in periods:
if sequence := period.move_sequence:
if sequence.id != values['move_sequence']:
if Move.search([
('period', '=', period.id),
('state', '=', 'posted'),
], limit=1, order=[]):
raise AccessError(gettext(
'account.'
'msg_change_period_move_sequence',
period=period.rec_name))
@classmethod
def on_modification(cls, mode, periods, field_names=None):
super().on_modification(mode, periods, field_names=field_names)
cls._find_cache.clear()
@classmethod
@ModelView.button
@Workflow.transition('closed')
def close(cls, periods):
pool = Pool()
JournalPeriod = pool.get('account.journal.period')
Move = pool.get('account.move')
Account = pool.get('account.account')
transaction = Transaction()
# Lock period and move to be sure no new record will be created
JournalPeriod.lock()
Move.lock()
for period in periods:
with transaction.set_context(
fiscalyear=period.fiscalyear.id, date=period.end_date,
cumulate=True, journal=None):
for account in Account.search([
('company', '=', period.company.id),
('end_date', '>=', period.start_date),
('end_date', '<=', period.end_date),
]):
if account.balance:
raise ClosePeriodError(
gettext('account.'
'msg_close_period_inactive_accounts',
account=account.rec_name,
period=period.rec_name))
unposted_moves = Move.search([
('period', 'in', [p.id for p in periods]),
('state', '!=', 'posted'),
], limit=1)
if unposted_moves:
unposted_move, = unposted_moves
raise ClosePeriodError(
gettext('account.msg_close_period_non_posted_moves',
period=unposted_move.period.rec_name,
moves=unposted_move.rec_name))
journal_periods = JournalPeriod.search([
('period', 'in', [p.id for p in periods]),
])
JournalPeriod.close(journal_periods)
@classmethod
@ModelView.button
@Workflow.transition('open')
def reopen(cls, periods):
"Reopen period"
pass
@classmethod
@ModelView.button
@Workflow.transition('locked')
def lock_(cls, periods):
pass
@property
def move_sequence_used(self):
return self.move_sequence or self.fiscalyear.move_sequence

View File

@@ -0,0 +1,95 @@
<?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. -->
<tryton>
<data>
<record model="ir.ui.view" id="period_view_form">
<field name="model">account.period</field>
<field name="type">form</field>
<field name="name">period_form</field>
</record>
<record model="ir.ui.view" id="period_view_tree">
<field name="model">account.period</field>
<field name="type">tree</field>
<field name="name">period_tree</field>
</record>
<record model="ir.ui.view" id="period_view_list_close">
<field name="model">account.period</field>
<field name="type">tree</field>
<field name="name">period_list_close</field>
</record>
<record model="ir.action.act_window" id="act_period_form">
<field name="name">Periods</field>
<field name="res_model">account.period</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
</record>
<record model="ir.action.act_window.view" id="act_period_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="period_view_tree"/>
<field name="act_window" ref="act_period_form"/>
</record>
<record model="ir.action.act_window.view" id="act_period_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="period_view_form"/>
<field name="act_window" ref="act_period_form"/>
</record>
<menuitem
parent="menu_fiscalyear_configuration"
action="act_period_form"
sequence="20"
id="menu_period_form"/>
<record model="ir.model.button" id="period_close_button">
<field name="model">account.period</field>
<field name="name">close</field>
<field name="string">Close</field>
</record>
<record model="ir.model.button" id="period_reopen_button">
<field name="model">account.period</field>
<field name="name">reopen</field>
<field name="string">Reopen</field>
</record>
<record model="ir.model.button" id="period_lock_button">
<field name="model">account.period</field>
<field name="name">lock_</field>
<field name="string">Lock</field>
<field name="confirm">Are you sure you want to lock the period?</field>
</record>
<record model="ir.action.act_window" id="act_period_form_close">
<field name="name">Close Periods</field>
<field name="res_model">account.period</field>
<field name="search_value"
eval="[('state', '=', 'open')]" pyson="1"/>
<field name="order" eval="[('start_date', 'ASC'), ('id', 'ASC')]" pyson="1"/>
</record>
<record model="ir.action.act_window.view"
id="act_period_form_close_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="period_view_list_close"/>
<field name="act_window" ref="act_period_form_close"/>
</record>
<menuitem
parent="menu_processing"
action="act_period_form_close"
sequence="30"
id="menu_close_period"/>
<record model="ir.rule.group" id="rule_group_period_companies">
<field name="name">User in companies</field>
<field name="model">account.period</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_period_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_period_companies"/>
</record>
</data>
</tryton>

1942
modules/account/tax.py Normal file

File diff suppressed because it is too large Load Diff

536
modules/account/tax.xml Normal file
View File

@@ -0,0 +1,536 @@
<?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. -->
<tryton>
<data>
<menuitem
name="Taxes"
parent="menu_account_configuration"
sequence="50"
id="menu_taxes"/>
<record model="ir.ui.view" id="tax_group_view_form">
<field name="model">account.tax.group</field>
<field name="type">form</field>
<field name="name">tax_group_form</field>
</record>
<record model="ir.ui.view" id="tax_group_view_tree">
<field name="model">account.tax.group</field>
<field name="type">tree</field>
<field name="name">tax_group_tree</field>
</record>
<record model="ir.action.act_window" id="act_tax_group_form">
<field name="name">Groups</field>
<field name="res_model">account.tax.group</field>
</record>
<record model="ir.action.act_window.view" id="act_tax_group_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_group_view_tree"/>
<field name="act_window" ref="act_tax_group_form"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_group_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_group_view_form"/>
<field name="act_window" ref="act_tax_group_form"/>
</record>
<menuitem
parent="menu_taxes"
action="act_tax_group_form"
sequence="20"
id="menu_tax_group_form"/>
<record model="ir.model.access" id="access_tax_group">
<field name="model">account.tax.group</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_tax_group_account_admin">
<field name="model">account.tax.group</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.ui.view" id="tax_code_template_view_form">
<field name="model">account.tax.code.template</field>
<field name="type">form</field>
<field name="name">tax_code_template_form</field>
</record>
<record model="ir.ui.view" id="tax_code_template_view_tree">
<field name="model">account.tax.code.template</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="name">tax_code_template_tree</field>
</record>
<record model="ir.action.act_window" id="act_tax_code_template_tree">
<field name="name">Tax Codes</field>
<field name="res_model">account.tax.code.template</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_template_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_code_template_view_tree"/>
<field name="act_window" ref="act_tax_code_template_tree"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_template_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_code_template_view_form"/>
<field name="act_window" ref="act_tax_code_template_tree"/>
</record>
<menuitem
parent="menu_templates"
action="act_tax_code_template_tree"
sequence="20"
id="menu_tax_code_template_tree"/>
<record model="ir.model.access" id="access_tax_code_template">
<field name="model">account.tax.code.template</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="tax_code_view_form">
<field name="model">account.tax.code</field>
<field name="type">form</field>
<field name="name">tax_code_form</field>
</record>
<record model="ir.ui.view" id="tax_code_view_tree">
<field name="model">account.tax.code</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="name">tax_code_tree</field>
</record>
<record model="ir.ui.view" id="tax_code_view_list">
<field name="model">account.tax.code</field>
<field name="type">tree</field>
<field name="name">tax_code_list</field>
</record>
<record model="ir.action.act_window" id="act_tax_code_tree">
<field name="name">Codes</field>
<field name="res_model">account.tax.code</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_tree_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_code_view_tree"/>
<field name="act_window" ref="act_tax_code_tree"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_tree_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_code_view_form"/>
<field name="act_window" ref="act_tax_code_tree"/>
</record>
<menuitem
parent="menu_taxes"
action="act_tax_code_tree"
sequence="20"
id="menu_tax_code_tree"/>
<record model="ir.action.act_window" id="act_tax_code_list">
<field name="name">Codes</field>
<field name="res_model">account.tax.code</field>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_code_view_list"/>
<field name="act_window" ref="act_tax_code_list"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_code_view_form"/>
<field name="act_window" ref="act_tax_code_list"/>
</record>
<menuitem
parent="menu_tax_code_tree"
action="act_tax_code_list"
sequence="10"
id="menu_tax_code_list"/>
<record model="ir.ui.view" id="tax_code_view_tree_chart">
<field name="model">account.tax.code</field>
<field name="type">tree</field>
<field name="field_childs">childs</field>
<field name="name">tax_code_tree_chart</field>
</record>
<record model="ir.action.act_window" id="act_tax_code_tree_chart">
<field name="name">Chart of Tax Codes</field>
<field name="res_model">account.tax.code</field>
<field name="context_model">account.tax.code.context</field>
<field name="domain"
eval="[('parent', '=', None), ('context_company', '=', True)]"
pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_code_tree_chart_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_code_view_tree_chart"/>
<field name="act_window" ref="act_tax_code_tree_chart"/>
</record>
<menuitem
parent="menu_reporting"
action="act_tax_code_tree_chart"
sequence="30"
id="menu_tax_code_tree_chart"/>
<record model="ir.ui.view" id="tax_code_context_view_form">
<field name="model">account.tax.code.context</field>
<field name="type">form</field>
<field name="name">tax_code_context_form</field>
</record>
<record model="ir.model.access" id="access_tax_code">
<field name="model">account.tax.code</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_tax_code_account_admin">
<field name="model">account.tax.code</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_tax_code_companies">
<field name="name">User in companies</field>
<field name="model">account.tax.code</field>
<field name="global_p" eval="True" />
</record>
<record model="ir.rule" id="rule_tax_code_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_tax_code_companies" />
</record>
<record model="ir.ui.view" id="tax_code_line_template_view_form">
<field name="model">account.tax.code.line.template</field>
<field name="type">form</field>
<field name="name">tax_code_line_template_form</field>
</record>
<record model="ir.ui.view" id="tax_code_line_template_view_list">
<field name="model">account.tax.code.line.template</field>
<field name="type">tree</field>
<field name="name">tax_code_line_template_list</field>
</record>
<record model="ir.ui.view" id="tax_code_line_view_form">
<field name="model">account.tax.code.line</field>
<field name="type">form</field>
<field name="name">tax_code_line_form</field>
</record>
<record model="ir.ui.view" id="tax_code_line_view_list">
<field name="model">account.tax.code.line</field>
<field name="type">tree</field>
<field name="name">tax_code_line_list</field>
</record>
<record model="ir.ui.view" id="tax_template_view_form">
<field name="model">account.tax.template</field>
<field name="type">form</field>
<field name="name">tax_template_form</field>
</record>
<record model="ir.ui.view" id="tax_template_view_list">
<field name="model">account.tax.template</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">tax_template_list</field>
</record>
<record model="ir.action.act_window" id="act_tax_template_list">
<field name="name">Taxes</field>
<field name="res_model">account.tax.template</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_template_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_template_view_list"/>
<field name="act_window" ref="act_tax_template_list"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_template_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_template_view_form"/>
<field name="act_window" ref="act_tax_template_list"/>
</record>
<menuitem
parent="menu_templates"
action="act_tax_template_list"
sequence="40"
id="menu_tax_template_list"/>
<record model="ir.model.access" id="access_tax_template">
<field name="model">account.tax.template</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="tax_view_form">
<field name="model">account.tax</field>
<field name="type">form</field>
<field name="name">tax_form</field>
</record>
<record model="ir.ui.view" id="tax_view_list">
<field name="model">account.tax</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">tax_list</field>
</record>
<record model="ir.action.act_window" id="act_tax_list">
<field name="name">Taxes</field>
<field name="res_model">account.tax</field>
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_list_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_view_list"/>
<field name="act_window" ref="act_tax_list"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_list_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_view_form"/>
<field name="act_window" ref="act_tax_list"/>
</record>
<menuitem
parent="menu_taxes"
action="act_tax_list"
sequence="10"
id="menu_tax_list"/>
<record model="ir.model.access" id="access_tax">
<field name="model">account.tax</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_tax_account_admin">
<field name="model">account.tax</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_tax_companies">
<field name="name">User in companies</field>
<field name="model">account.tax</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_tax_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_tax_companies"/>
</record>
<record model="ir.action.wizard" id="wizard_tax_test">
<field name="name">Test Tax</field>
<field name="wiz_name">account.tax.test</field>
</record>
<record model="ir.action.keyword" id="wizard_tax_test_keyword1">
<field name="keyword">form_action</field>
<field name="model">account.tax,-1</field>
<field name="action" ref="wizard_tax_test"/>
</record>
<menuitem
parent="menu_taxes"
action="wizard_tax_test"
sequence="90"
id="menu_tax_test"/>
<record model="ir.ui.view" id="tax_test_view_form">
<field name="model">account.tax.test</field>
<field name="type">form</field>
<field name="name">tax_test_form</field>
</record>
<record model="ir.ui.view" id="tax_test_result_view_list">
<field name="model">account.tax.test.result</field>
<field name="type">tree</field>
<field name="name">tax_test_result_list</field>
</record>
<record model="ir.ui.view" id="tax_line_view_form">
<field name="model">account.tax.line</field>
<field name="type">form</field>
<field name="name">tax_line_form</field>
</record>
<record model="ir.ui.view" id="tax_line_view_tree">
<field name="model">account.tax.line</field>
<field name="type">tree</field>
<field name="name">tax_line_tree</field>
</record>
<record model="ir.action.act_window" id="act_tax_line_form">
<field name="name">Tax Lines</field>
<field name="res_model">account.tax.line</field>
</record>
<record model="ir.action.act_window.view" id="act_tax_line_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_line_view_tree"/>
<field name="act_window" ref="act_tax_line_form"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_line_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_line_view_form"/>
<field name="act_window" ref="act_tax_line_form"/>
</record>
<record model="ir.action.wizard" id="act_open_tax_code">
<field name="name">Open Tax Code</field>
<field name="wiz_name">account.tax.open_code</field>
<field name="model">account.tax.code</field>
</record>
<record model="ir.action.keyword" id="act_open_tax_code_keyword">
<field name="keyword">tree_open</field>
<field name="model">account.tax.code,-1</field>
<field name="action" ref="act_open_tax_code"/>
</record>
<record model="ir.ui.view" id="tax_rule_template_view_form">
<field name="model">account.tax.rule.template</field>
<field name="type">form</field>
<field name="name">tax_rule_template_form</field>
</record>
<record model="ir.ui.view" id="tax_rule_template_view_tree">
<field name="model">account.tax.rule.template</field>
<field name="type">tree</field>
<field name="name">tax_rule_template_tree</field>
</record>
<record model="ir.action.act_window" id="act_tax_rule_template_form">
<field name="name">Tax Rules</field>
<field name="res_model">account.tax.rule.template</field>
</record>
<record model="ir.action.act_window.view" id="act_tax_rule_template_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_rule_template_view_tree"/>
<field name="act_window" ref="act_tax_rule_template_form"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_rule_template_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_rule_template_view_form"/>
<field name="act_window" ref="act_tax_rule_template_form"/>
</record>
<menuitem
parent="menu_templates"
action="act_tax_rule_template_form"
sequence="50"
id="menu_tax_rule_template_form"/>
<record model="ir.model.access" id="access_tax_rule_template">
<field name="model">account.tax.rule.template</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="tax_rule_view_form">
<field name="model">account.tax.rule</field>
<field name="type">form</field>
<field name="name">tax_rule_form</field>
</record>
<record model="ir.ui.view" id="tax_rule_view_tree">
<field name="model">account.tax.rule</field>
<field name="type">tree</field>
<field name="name">tax_rule_tree</field>
</record>
<record model="ir.action.act_window" id="act_tax_rule_form">
<field name="name">Rules</field>
<field name="res_model">account.tax.rule</field>
<!-- Migration from 7.4: force empty domain for multi company -->
<field name="domain" eval="None"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_rule_form_view1">
<field name="sequence" eval="10"/>
<field name="view" ref="tax_rule_view_tree"/>
<field name="act_window" ref="act_tax_rule_form"/>
</record>
<record model="ir.action.act_window.view" id="act_tax_rule_form_view2">
<field name="sequence" eval="20"/>
<field name="view" ref="tax_rule_view_form"/>
<field name="act_window" ref="act_tax_rule_form"/>
</record>
<menuitem
parent="menu_taxes"
action="act_tax_rule_form"
sequence="50"
id="menu_tax_rule_form"/>
<record model="ir.model.access" id="access_tax_rule">
<field name="model">account.tax.rule</field>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.model.access" id="access_tax_rule_account_admin">
<field name="model">account.tax.rule</field>
<field name="group" ref="group_account_admin"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/>
<field name="perm_create" eval="True"/>
<field name="perm_delete" eval="True"/>
</record>
<record model="ir.rule.group" id="rule_group_tax_rule_companies">
<field name="name">User in companies</field>
<field name="model">account.tax.rule</field>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_tax_rule_companies">
<field name="domain"
eval="[('company', 'in', Eval('companies', []))]"
pyson="1"/>
<field name="rule_group" ref="rule_group_tax_rule_companies"/>
</record>
<record model="ir.ui.view" id="tax_rule_line_template_view_form">
<field name="model">account.tax.rule.line.template</field>
<field name="type">form</field>
<field name="name">tax_rule_line_template_form</field>
</record>
<record model="ir.ui.view" id="tax_rule_line_template_view_tree">
<field name="model">account.tax.rule.line.template</field>
<field name="type">tree</field>
<field name="name">tax_rule_line_template_tree</field>
</record>
<record model="ir.ui.view" id="tax_rule_line_view_form">
<field name="model">account.tax.rule.line</field>
<field name="type">form</field>
<field name="name">tax_rule_line_form</field>
</record>
<record model="ir.ui.view" id="tax_rule_line_view_tree">
<field name="model">account.tax.rule.line</field>
<field name="type">tree</field>
<field name="priority" eval="10"/>
<field name="name">tax_rule_line_tree</field>
</record>
<record model="ir.ui.view" id="tax_rule_line_view_tree_sequence">
<field name="model">account.tax.rule.line</field>
<field name="type">tree</field>
<field name="priority" eval="20"/>
<field name="name">tax_rule_line_tree_sequence</field>
</record>
</data>
</tryton>

View File

@@ -0,0 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from .test_module import create_chart, get_fiscalyear
__all__ = ['create_chart', 'get_fiscalyear']

View File

@@ -0,0 +1,150 @@
=======================
Account Active Scenario
=======================
Imports::
>>> from dateutil.relativedelta import relativedelta
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Account = Model.get('account.account')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[1]
Get accounts::
>>> accounts = get_accounts()
>>> cash = accounts['cash']
Check active without start or end date::
>>> cash.active
True
>>> len(Account.find([('id', '=', cash.id)]))
1
>>> len(Account.find([('id', '=', cash.id), ('active', '=', True)]))
1
>>> len(Account.find([('id', '=', cash.id), ('active', 'in', [True])]))
1
>>> len(Account.find([('id', '=', cash.id), ('active', 'in', [True, False])]))
1
Check negative search::
>>> len(Account.find([('id', '=', cash.id), ('active', '=', False)]))
0
>>> len(Account.find([('id', '=', cash.id), ('active', 'in', [False])]))
0
Check active with a start date::
>>> cash.start_date = period.start_date
>>> cash.save()
>>> with config.set_context(date=period.start_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=period.end_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.start_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.start_date - relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
False
0
>>> with config.set_context(date=fiscalyear.end_date - relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
Check active with an end date::
>>> cash.start_date = None
>>> cash.end_date = period.end_date
>>> cash.save()
>>> with config.set_context(date=period.start_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=period.end_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.end_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.start_date - relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.end_date + relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
False
0
Check active with start and end date::
>>> cash.start_date = period.start_date
>>> cash.end_date = period.end_date
>>> cash.save()
>>> with config.set_context(date=period.start_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=period.end_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.start_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.end_date):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
True
1
>>> with config.set_context(date=fiscalyear.start_date - relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
False
0
>>> with config.set_context(date=fiscalyear.end_date + relativedelta(days=1)):
... Account(cash.id).active
... len(Account.find([('id', '=', cash.id)]))
False
0

View File

@@ -0,0 +1,4 @@
[
{"party_required": true}
,{"party_required": false}
]

View File

@@ -0,0 +1,126 @@
==========================
Account Reconcile Scenario
==========================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
>>> party_required = globals().get('party_required', True)
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Line = Model.get('account.move.line')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
>>> receivable.party_required = party_required
>>> receivable.save()
Create parties::
>>> customer = Party(name='Customer')
>>> customer.save()
Create Moves to reconcile::
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(42)
>>> if line.account.party_required:
... line.party = customer
>>> move.save()
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = cash
>>> line.debit = Decimal(40)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.credit = Decimal(40)
>>> if line.account.party_required:
... line.party = customer
>>> move.save()
Create a write off method::
>>> journal_writeoff = Journal(name='Write-Off', type='write-off')
>>> journal_writeoff.save()
>>> WriteOff = Model.get('account.move.reconcile.write_off')
>>> writeoff_method = WriteOff()
>>> writeoff_method.name = 'Write Off'
>>> writeoff_method.journal = journal_writeoff
>>> writeoff_method.debit_account = expense
>>> writeoff_method.credit_account = expense
>>> writeoff_method.save()
Run Reconcile for only balanced::
>>> reconcile = Wizard('account.reconcile')
>>> reconcile.form.only_balanced = True
>>> reconcile.execute('setup')
>>> reconcile.state
'end'
Run Reconcile wizard::
>>> reconcile = Wizard('account.reconcile')
>>> reconcile.execute('setup')
>>> assertEqual(reconcile.form.party, (customer if party_required else None))
>>> reconcile.form.write_off_amount
Decimal('0.00')
>>> len(reconcile.form.lines)
0
>>> reconcile.form.lines.extend(reconcile.form.lines.find())
>>> len(reconcile.form.lines)
2
>>> reconcile.form.write_off_amount
Decimal('2.00')
>>> reconcile.form.write_off = writeoff_method
>>> reconcile.execute('reconcile')
>>> lines = Line.find([('account', '=', receivable.id)])
>>> len(lines)
3
>>> all(l.reconciliation for l in lines)
True

View File

@@ -0,0 +1,84 @@
====================================
Account Reconcile Automatic Scenario
====================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Line = Model.get('account.move.line')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Create parties::
>>> customer = Party(name="Customer")
>>> customer.save()
Create Moves to reconcile::
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['revenue']
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.debit = Decimal(42)
>>> line.party = customer
>>> move.save()
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['cash']
>>> line.debit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.credit = Decimal(42)
>>> line.party = customer
>>> move.save()
Run Reconcile wizard::
>>> reconcile = Wizard('account.reconcile')
>>> reconcile.form.automatic = True
>>> reconcile.execute('setup')
>>> lines = Line.find([('account', '=', accounts['receivable'].id)])
>>> len(lines)
2
>>> all(l.reconciliation for l in lines)
True

View File

@@ -0,0 +1,187 @@
===============================
Account Reconciliation Scenario
===============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual, assertTrue
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> GLLine = Model.get('account.general_ledger.line')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
Create parties::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
Create Moves for direct reconciliation::
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(42)
>>> line.party = customer
>>> move.save()
>>> reconcile1, = [l for l in move.lines if l.account == receivable]
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = cash
>>> line.debit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.credit = Decimal(42)
>>> line.party = customer
>>> move.save()
>>> reconcile2, = [l for l in move.lines if l.account == receivable]
Reconcile Lines without writeoff::
>>> reconcile_lines = Wizard('account.move.reconcile_lines',
... [reconcile1, reconcile2])
>>> reconcile_lines.state
'end'
>>> reconcile1.reload()
>>> reconcile2.reload()
>>> assertEqual(reconcile1.reconciliation, reconcile2.reconciliation)
>>> assertTrue(reconcile1.reconciliation)
>>> len(reconcile1.reconciliation.lines)
2
Unreconcile lines::
>>> unreconcile_lines = Wizard(
... 'account.move.unreconcile_lines', [reconcile1])
>>> unreconcile_lines.state
'end'
>>> reconcile1.reload()
>>> reconcile1.reconciliation
>>> reconcile2.reload()
>>> reconcile2.reconciliation
Reconcile general ledger lines::
>>> gl_reconcile1 = GLLine(reconcile1.id)
>>> gl_reconcile2 = GLLine(reconcile2.id)
>>> reconcile_lines = Wizard('account.move.reconcile_lines',
... [gl_reconcile1, gl_reconcile2])
>>> reconcile_lines.state
'end'
>>> gl_reconcile1.reload()
>>> gl_reconcile2.reload()
>>> assertEqual(gl_reconcile1.reconciliation, gl_reconcile2.reconciliation)
>>> assertTrue(gl_reconcile1.reconciliation)
Unreconcile general ledger, lines::
>>> unreconcile_lines = Wizard(
... 'account.move.unreconcile_lines', [gl_reconcile1])
>>> unreconcile_lines.state
'end'
>>> gl_reconcile1.reload()
>>> gl_reconcile1.reconciliation
>>> gl_reconcile2.reload()
>>> gl_reconcile2.reconciliation
Create Moves for writeoff reconciliation::
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal(68)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(68)
>>> line.party = customer
>>> move.save()
>>> reconcile1, = [l for l in move.lines if l.account == receivable]
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = cash
>>> line.debit = Decimal(65)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.credit = Decimal(65)
>>> line.party = customer
>>> move.save()
>>> reconcile2, = [l for l in move.lines if l.account == receivable]
Create a write-off payment method::
>>> journal_writeoff = Journal(name='Write-Off', type='write-off')
>>> journal_writeoff.save()
>>> WriteOff = Model.get('account.move.reconcile.write_off')
>>> writeoff_method = WriteOff()
>>> writeoff_method.name = 'Write Off'
>>> writeoff_method.journal = journal_writeoff
>>> writeoff_method.debit_account = expense
>>> writeoff_method.credit_account = expense
>>> writeoff_method.save()
Reconcile Lines with write-off::
>>> reconcile_lines = Wizard('account.move.reconcile_lines',
... [reconcile1, reconcile2])
>>> reconcile_lines.form_state
'writeoff'
>>> reconcile_lines.form.writeoff = writeoff_method
>>> reconcile_lines.execute('reconcile')
>>> reconcile1.reload()
>>> reconcile2.reload()
>>> assertEqual(reconcile1.reconciliation, reconcile2.reconciliation)
>>> assertTrue(reconcile1.reconciliation)
>>> len(reconcile1.reconciliation.lines)
3
>>> writeoff_line1, = [l for l in reconcile1.reconciliation.lines
... if l.credit == Decimal(3)]
>>> writeoff_line2, = [l for l in writeoff_line1.move.lines
... if l != writeoff_line1]
>>> assertEqual(writeoff_line2.account, expense)
>>> writeoff_line2.debit
Decimal('3')

View File

@@ -0,0 +1,4 @@
[
{"post_moves": false}
,{"post_moves": true}
]

View File

@@ -0,0 +1,116 @@
=========================================
Account Reconciliation Alternate Currency
=========================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertEqual, assertTrue
>>> post_moves = globals().get('post_moves', False)
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Configuration = Model.get('account.configuration')
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
>>> Reconciliation = Model.get('account.move.reconciliation')
Create currencies::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Configure currency exchange::
>>> currency_exchange_account, = (
... accounts['revenue'].duplicate(
... default={'name': "Currency Exchange"}))
>>> configuration = Configuration(1)
>>> configuration.currency_exchange_credit_account = (
... currency_exchange_account)
>>> configuration.save()
Create party::
>>> party = Party(name="Party")
>>> party.save()
Create moves to reconcile::
>>> journal_expense, = Journal.find([('code', '=', 'EXP')])
>>> journal_cash, = Journal.find([('code', '=', 'CASH')])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_expense
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['expense']
>>> line.debit = Decimal('50.00')
>>> line = move.lines.new()
>>> line.account = accounts['payable']
>>> line.party = party
>>> line.credit = Decimal('50.00')
>>> line.amount_second_currency = Decimal('-90.00')
>>> line.second_currency = eur
>>> move.save()
>>> if post_moves:
... move.click('post')
>>> reconcile1, = [l for l in move.lines if l.account == accounts['payable']]
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.end_date
>>> line = move.lines.new()
>>> line.account = accounts['cash']
>>> line.credit = Decimal('45.00')
>>> line = move.lines.new()
>>> line.account = accounts['payable']
>>> line.party = party
>>> line.debit = Decimal('45.00')
>>> line.amount_second_currency = Decimal('-90.00')
>>> line.second_currency = eur
>>> move.save()
>>> if post_moves:
... move.click('post')
>>> reconcile2, = [l for l in move.lines if l.account == accounts['payable']]
Reconcile lines::
>>> reconcile_lines = Wizard(
... 'account.move.reconcile_lines', [reconcile1, reconcile2])
>>> reconcile_lines.state
'end'
>>> assertEqual(reconcile1.reconciliation, reconcile2.reconciliation)
>>> assertTrue(reconcile1.reconciliation)
>>> reconciliation, = Reconciliation.find([])
>>> len(reconciliation.lines)
3
>>> currency_exchange_account.reload()
>>> currency_exchange_account.balance
Decimal('-5.00')
>>> len(Move.find([('state', '=', 'posted' if post_moves else 'draft')]))
3

View File

@@ -0,0 +1,4 @@
[
{"post_moves": false}
,{"post_moves": true}
]

View File

@@ -0,0 +1,135 @@
========================================================
Account Reconciliation Alternate Currency with Write-Off
========================================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertTrue
>>> post_moves = globals().get('post_moves', False)
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Configuration = Model.get('account.configuration')
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
>>> Reconciliation = Model.get('account.move.reconciliation')
>>> WriteOff = Model.get('account.move.reconcile.write_off')
Create currencies::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Configure currency exchange::
>>> currency_exchange_account, = (
... accounts['revenue'].duplicate(
... default={'name': "Currency Exchange"}))
>>> configuration = Configuration(1)
>>> configuration.currency_exchange_credit_account = (
... currency_exchange_account)
>>> configuration.save()
Create write-off::
>>> journal_writeoff = Journal(
... name="Write-Off", type='write-off')
>>> journal_writeoff.save()
>>> write_off = WriteOff()
>>> write_off.name = "Write-Off"
>>> write_off.journal = journal_writeoff
>>> write_off.debit_account, = accounts['expense'].duplicate()
>>> write_off.credit_account, = accounts['revenue'].duplicate()
>>> write_off.save()
Create party::
>>> party = Party(name="Party")
>>> party.save()
Create moves to reconcile::
>>> journal_expense, = Journal.find([('code', '=', 'EXP')])
>>> journal_cash, = Journal.find([('code', '=', 'CASH')])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_expense
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['expense']
>>> line.debit = Decimal('50.00')
>>> line = move.lines.new()
>>> line.account = accounts['payable']
>>> line.party = party
>>> line.credit = Decimal('50.00')
>>> line.amount_second_currency = Decimal('-90.00')
>>> line.second_currency = eur
>>> move.save()
>>> if post_moves:
... move.click('post')
>>> reconcile1, = [l for l in move.lines if l.account == accounts['payable']]
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_cash
>>> move.date = period.end_date
>>> line = move.lines.new()
>>> line.account = accounts['cash']
>>> line.credit = Decimal('45.00')
>>> line = move.lines.new()
>>> line.account = accounts['payable']
>>> line.party = party
>>> line.debit = Decimal('45.00')
>>> line.amount_second_currency = Decimal('-89.00')
>>> line.second_currency = eur
>>> move.save()
>>> if post_moves:
... move.click('post')
>>> reconcile2, = [l for l in move.lines if l.account == accounts['payable']]
Reconcile lines::
>>> reconcile_lines = Wizard(
... 'account.move.reconcile_lines', [reconcile1, reconcile2])
>>> reconcile_lines.form_state
'writeoff'
>>> reconcile_lines.form.writeoff = write_off
>>> reconcile_lines.execute('reconcile')
>>> reconcile1.reconciliation == reconcile2.reconciliation
True
>>> assertTrue(reconcile1.reconciliation)
>>> reconciliation, = Reconciliation.find([])
>>> len(reconciliation.lines)
4
>>> write_off.credit_account.reload()
>>> write_off.credit_account.balance
Decimal('-0.50')
>>> currency_exchange_account.reload()
>>> currency_exchange_account.balance
Decimal('-4.50')
>>> len(Move.find([('state', '=', 'posted' if post_moves else 'draft')]))
4

View File

@@ -0,0 +1,69 @@
=====================================
Account Reconciliation Empty Scenario
=====================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertTrue
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
Create currencies::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
Get accounts::
>>> accounts = get_accounts()
>>> account = accounts['cash']
>>> account.reconcile = True
>>> account.save()
>>> journal, = Journal.find([('code', '=', 'CASH')])
Lines with empty debit/credit are reconciled::
>>> move = Move()
>>> move.journal = journal
>>> line = move.lines.new()
>>> line.account = account
>>> line.debit = line.credit = Decimal('0')
>>> move.save()
>>> move.click('post')
>>> move.state
'posted'
>>> line, = move.lines
>>> assertTrue(line.reconciliation)
Lines with empty debit/credit but second currency are not reconciled::
>>> move = Move()
>>> move.journal = journal
>>> line = move.lines.new()
>>> line.account = account
>>> line.debit = line.credit = Decimal('0')
>>> line.amount_second_currency = Decimal('0.15')
>>> line.second_currency = eur
>>> move.save()
>>> move.click('post')
>>> move.state
'posted'
>>> line, = move.lines
>>> line.reconciliation

View File

@@ -0,0 +1,137 @@
=================================
Account Close Fiscalyear Scenario
=================================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from dateutil.relativedelta import relativedelta
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
>>> last_year = today - relativedelta(years=1)
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Account = Model.get('account.account')
>>> AccountType = Model.get('account.account.type')
>>> Journal = Model.get('account.journal')
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
>>> Period = Model.get('account.period')
>>> Sequence = Model.get('ir.sequence')
Create fiscal year::
>>> fiscalyear = create_fiscalyear(today=last_year)
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Prepare the closing settings for fiscalyear close::
>>> journal_closing = Journal()
>>> journal_closing.name = 'Closing'
>>> journal_closing.code = 'CLO'
>>> journal_closing.type = 'situation'
>>> journal_closing.save()
>>> period_closing = Period()
>>> period_closing.name = 'Closing'
>>> period_closing.start_date = fiscalyear.end_date
>>> period_closing.end_date = fiscalyear.end_date
>>> period_closing.fiscalyear = fiscalyear
>>> period_closing.type = 'adjustment'
>>> period_closing.save()
>>> account_pl, = Account.find([('code', '=', '3.2.1')])
Create children accounts::
>>> receivable_customer = Account()
>>> receivable_customer.name = "Customer Receivable"
>>> receivable_customer.parent = accounts['receivable']
>>> receivable_customer.save()
Create parties::
>>> customer = Party(name="Customer")
>>> customer.save()
Create and post a move using children accounts::
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['revenue']
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = receivable_customer
>>> line.debit = Decimal(21)
>>> line.party = customer
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.debit = Decimal(21)
>>> line.party = customer
>>> move.save()
>>> move.click('post')
Balance non deferral::
>>> balance_non_deferral = Wizard('account.fiscalyear.balance_non_deferral')
>>> balance_non_deferral.form.fiscalyear = fiscalyear
>>> balance_non_deferral.form.journal = journal_closing
>>> balance_non_deferral.form.period = period_closing
>>> balance_non_deferral.form.credit_account = account_pl
>>> balance_non_deferral.form.debit_account = account_pl
>>> balance_non_deferral.execute('balance')
>>> move, = Move.find([('state', '=', 'draft')])
>>> move.click('post')
Renew fiscalyear using the wizard::
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
>>> renew_fiscalyear.form.reset_sequences = False
>>> renew_fiscalyear.execute('create_')
Check receivable balance before closing fiscalyear::
>>> accounts['receivable'].reload()
>>> accounts['receivable'].balance
Decimal('42.00')
>>> receivable_customer.reload()
>>> receivable_customer.balance
Decimal('21.00')
Close fiscalyear::
>>> fiscalyear.click('close')
>>> fiscalyear.state
'closed'
Check receivable amounts after closing fiscalyear::
>>> accounts['receivable'].reload()
>>> accounts['receivable'].balance
Decimal('42.00')
>>> receivable_customer.reload()
>>> receivable_customer.balance
Decimal('21.00')

View File

@@ -0,0 +1,135 @@
====================
Move Cancel Scenario
====================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Reconciliation = Model.get('account.move.reconciliation')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
Create parties::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
>>> party = Party(name='Party')
>>> party.save()
Create Move to cancel::
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> move = Move()
>>> move.period = period
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(32)
>>> line.party = customer
>>> line.second_currency = get_currency('EUR')
>>> line.amount_second_currency = Decimal(30)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(10)
>>> line.party = party
>>> move.save()
>>> revenue.reload()
>>> revenue.credit
Decimal('42.00')
>>> receivable.reload()
>>> receivable.debit
Decimal('42.00')
Cancel reversal Move::
>>> cancel_move = Wizard('account.move.cancel', [move])
>>> cancel_move.form.description = "Reversal"
>>> cancel_move.form.reversal = True
>>> cancel_move.execute('cancel')
>>> cancel_move.state
'end'
>>> move.reload()
>>> [bool(l.reconciliation) for l in move.lines if l.account == receivable]
[True, True]
>>> line, _ = [l for l in move.lines if l.account == receivable]
>>> cancel_move, = [l.move for l in line.reconciliation.lines
... if l.move != move]
>>> assertEqual(cancel_move.origin, move)
>>> cancel_move.description
'Reversal'
>>> assertEqual({l.origin for l in cancel_move.lines}, set(move.lines))
>>> revenue.reload()
>>> revenue.credit
Decimal('42.00')
>>> revenue.debit
Decimal('42.00')
>>> receivable.reload()
>>> receivable.credit
Decimal('42.00')
>>> receivable.debit
Decimal('42.00')
>>> reconciliations = {
... l.reconciliation for l in cancel_move.lines if l.reconciliation}
>>> Reconciliation.delete(list(reconciliations))
>>> cancel_move.reload()
>>> cancel_move.delete()
Cancel Move::
>>> cancel_move = Wizard('account.move.cancel', [move])
>>> cancel_move.form.description = 'Cancel'
>>> cancel_move.form.reversal = False
>>> cancel_move.execute('cancel')
>>> cancel_move.state
'end'
>>> move.reload()
>>> [bool(l.reconciliation) for l in move.lines if l.account == receivable]
[True, True]
>>> line, _ = [l for l in move.lines if l.account == receivable]
>>> cancel_move, = [l.move for l in line.reconciliation.lines
... if l.move != move]
>>> assertEqual(cancel_move.origin, move)
>>> cancel_move.description
'Cancel'
>>> assertEqual({l.origin for l in cancel_move.lines}, set(move.lines))
>>> revenue.reload()
>>> revenue.credit
Decimal('0.00')
>>> receivable.reload()
>>> receivable.debit
Decimal('0.00')

View File

@@ -0,0 +1,87 @@
==================
Move Copy Scenario
==================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual, assertNotEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
Create a fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Create a party::
>>> party = Party(name="Party")
>>> party.save()
Create a posted move::
>>> move = Move()
>>> move.period = period
>>> move.journal, = Journal.find([('code', '=', 'REV')])
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['revenue']
>>> line.credit = Decimal(42)
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.debit = Decimal(42)
>>> line.party = party
>>> move.save()
>>> move.click('post')
>>> move.state
'posted'
Copy move on open period::
>>> copy_move, = move.duplicate()
>>> copy_move.number
>>> copy_move.state
'draft'
>>> copy_move.post_date
>>> assertEqual(copy_move.period, move.period)
>>> assertEqual(copy_move.date, move.date)
>>> copy_move.delete()
Copy move on closed period::
>>> period.click('close')
>>> period.state
'closed'
>>> copy_move, = move.duplicate()
Traceback (most recent call last):
...
CopyWarning: ...
>>> config.skip_warning = True
>>> copy_move, = move.duplicate()
>>> copy_move.number
>>> copy_move.state
'draft'
>>> copy_move.post_date
>>> assertNotEqual(copy_move.period, move.period)
>>> copy_move.period.state
'open'
>>> assertNotEqual(copy_move.date, move.date)

View File

@@ -0,0 +1,101 @@
=======================
Delegate Lines Scenario
=======================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
Get currencies::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Create parties::
>>> party1 = Party(name="Party 1")
>>> party1.save()
>>> party2 = Party(name="Party 2")
>>> party2.save()
Create lines to delegate::
>>> journal, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> move = Move(journal=journal)
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['revenue']
>>> line.credit = Decimal('100.00')
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.party = party1
>>> line.debit = Decimal('80.00')
>>> line.second_currency = eur
>>> line.amount_second_currency = Decimal('100.00')
>>> line.maturity_date = period.end_date
>>> line = move.lines.new()
>>> line.account = accounts['receivable']
>>> line.party = party1
>>> line.debit = Decimal('20.00')
>>> move.save()
>>> receivable_lines = [
... l for l in move.lines if l.account == accounts['receivable']]
>>> accounts['receivable'].reload()
>>> accounts['receivable'].balance
Decimal('100.00')
>>> party1.reload()
>>> party1.receivable
Decimal('100.00')
>>> party2.reload()
>>> party2.receivable
Decimal('0')
Delegate lines::
>>> delegate = Wizard('account.move.line.delegate', receivable_lines)
>>> assertEqual(delegate.form.journal, journal)
>>> delegate.form.party = party2
>>> delegate.form.description = "Delegate lines"
>>> delegate.execute('delegate')
>>> accounts['receivable'].reload()
>>> accounts['receivable'].balance
Decimal('100.00')
>>> party1.reload()
>>> party1.receivable
Decimal('0')
>>> party2.reload()
>>> party2.receivable
Decimal('100.00')
>>> all(l.reconciliation.delegate_to for l in receivable_lines)
True

View File

@@ -0,0 +1,160 @@
====================
Group Lines Scenario
====================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.exceptions import CancelDelegatedWarning
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Warning = Model.get('res.user.warning')
Get currency::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
>>> payable = accounts['payable']
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
Create parties::
>>> Party = Model.get('party.party')
>>> party = Party(name="Party")
>>> party.save()
Create Lines to group::
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_expense, = Journal.find([
... ('code', '=', 'EXP'),
... ])
>>> move = Move()
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal(100)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.party = party
>>> line.debit = Decimal(100)
>>> line.second_currency = eur
>>> line.amount_second_currency = Decimal(90)
>>> line.maturity_date = period.start_date + dt.timedelta(days=2)
>>> move.save()
>>> move = Move()
>>> move.journal = journal_expense
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = expense
>>> line.debit = Decimal(50)
>>> line = move.lines.new()
>>> line.account = payable
>>> line.party = party
>>> line.credit = Decimal(50)
>>> line.second_currency = eur
>>> line.amount_second_currency = Decimal(45)
>>> line.maturity_date = period.start_date + dt.timedelta(days=4)
>>> move.save()
>>> receivable.reload()
>>> receivable.balance, receivable.amount_second_currency
(Decimal('100.00'), Decimal('90.00'))
>>> payable.reload()
>>> payable.balance, payable.amount_second_currency
(Decimal('-50.00'), Decimal('-45.00'))
Group lines::
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> Line = Model.get('account.move.line')
>>> lines = Line.find([('account', 'in', [payable.id, receivable.id])])
>>> len(lines)
2
>>> group = Wizard('account.move.line.group', lines)
>>> group.form.journal = journal_cash
>>> group.form.description = "Group lines"
>>> group.execute('group')
>>> receivable.reload()
>>> receivable.balance, receivable.amount_second_currency
(Decimal('50.00'), Decimal('45.00'))
>>> payable.reload()
>>> payable.balance, payable.amount_second_currency
(Decimal('0.00'), Decimal('0.00'))
>>> delegated_line1, delegated_line2 = lines
>>> delegated_line1.reload()
>>> delegated_line2.reload()
>>> delegated_line1.delegated_amount
Decimal('45')
>>> delegated_line2.delegated_amount
Decimal('45')
>>> Reconciliation = Model.get('account.move.reconciliation')
>>> reconciliations = Reconciliation.find([])
>>> len(reconciliations)
2
>>> all(r.delegate_to for r in reconciliations)
True
>>> delegate_to = reconciliations[0].delegate_to
>>> assertEqual(delegate_to.account, receivable)
>>> delegate_to.debit
Decimal('50')
>>> assertEqual(
... delegate_to.maturity_date, period.start_date + dt.timedelta(days=2))
>>> delegate_to.move_description_used
'Group lines'
Cancelling the delegation move::
>>> delegation_move = delegate_to.move
>>> cancel = Wizard('account.move.cancel', [delegation_move])
>>> try:
... cancel.execute('cancel')
... except CancelDelegatedWarning as warning:
... Warning(user=config.user, name=warning.name).save()
... raise
Traceback (most recent call last):
...
CancelDelegatedWarning: ...
>>> cancel.execute('cancel')
>>> Reconciliation.find([('id', '=', reconciliations[0].id)])
[]
>>> delegated_line1.reload()
>>> delegated_line1.delegated_amount

View File

@@ -0,0 +1,142 @@
=========================
Reschedule Lines Scenario
=========================
Imports::
>>> from decimal import Decimal
>>> from dateutil.relativedelta import relativedelta
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.modules.currency.tests.tools import get_currency
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> Journal = Model.get('account.journal')
>>> Line = Model.get('account.move.line')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
Get currencies::
>>> usd = get_currency('USD')
>>> eur = get_currency('EUR')
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
Create parties::
>>> party = Party(name="Party")
>>> party.save()
Create Lines to reschedule::
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> move = Move()
>>> move.journal = journal_revenue
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = revenue
>>> line.credit = Decimal('90.00')
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.party = party
>>> line.debit = Decimal('90.00')
>>> line.second_currency = eur
>>> line.amount_second_currency = Decimal('100.00')
>>> line.maturity_date = period.start_date
>>> move.save()
>>> line, = [l for l in move.lines if l.account == receivable]
>>> receivable.reload()
>>> receivable.balance, receivable.amount_second_currency
(Decimal('90.00'), Decimal('100.00'))
Split line by amount::
>>> reschedule = Wizard('account.move.line.reschedule', [line])
>>> reschedule.form.total_amount
Decimal('100.00')
>>> reschedule.form.start_date = period.end_date
>>> reschedule.form.frequency = 'other'
>>> reschedule.form.interval = 2
>>> reschedule.form.amount = Decimal('30.00')
>>> reschedule.execute('preview')
>>> term1, term2, term3, term4 = reschedule.form.terms
>>> assertEqual(term1.date, period.end_date)
>>> assertEqual(term2.date, period.end_date + relativedelta(months=2))
>>> assertEqual(term3.date, period.end_date + relativedelta(months=4))
>>> assertEqual(term4.date, period.end_date + relativedelta(months=6))
>>> term1.amount, term2.amount, term3.amount, term4.amount
(Decimal('30.00'), Decimal('30.00'), Decimal('30.00'), Decimal('10.00'))
Split line by number::
>>> reschedule = Wizard('account.move.line.reschedule', [line])
>>> reschedule.form.total_amount
Decimal('100.00')
>>> reschedule.form.start_date = period.end_date
>>> reschedule.form.frequency = 'monthly'
>>> reschedule.form.number = 3
>>> reschedule.execute('preview')
>>> reschedule.form.description = "Split 3 months"
>>> term1, term2, term3 = reschedule.form.terms
>>> assertEqual(term1.date, period.end_date)
>>> assertEqual(term2.date, period.end_date + relativedelta(months=1))
>>> assertEqual(term3.date, period.end_date + relativedelta(months=2))
>>> term1.amount, term2.amount, term3.amount
(Decimal('33.33'), Decimal('33.33'), Decimal('33.34'))
>>> term1.amount = Decimal('40.00')
>>> term2.amount = term3.amount = Decimal('30.00')
>>> term3.date = period.end_date + relativedelta(months=3)
>>> reschedule.execute('reschedule')
>>> reschedule_move, = reschedule.actions[0]
>>> reschedule_move.description
'Split 3 months'
Check receivable::
>>> receivable.reload()
>>> receivable.balance, receivable.amount_second_currency
(Decimal('90.00'), Decimal('100.00'))
>>> lines = Line.find([
... ('account', '=', receivable.id),
... ('reconciliation', '=', None),
... ], order=[('maturity_date', 'ASC')])
>>> line1, line2, line3 = lines
>>> line1.debit, line1.amount
(Decimal('36.00'), Decimal('40.00'))
>>> assertEqual(line1.maturity_date, period.end_date)
>>> line2.debit, line2.amount
(Decimal('27.00'), Decimal('30.00'))
>>> assertEqual(line2.maturity_date, period.end_date + relativedelta(months=1))
>>> line3.debit, line3.amount
(Decimal('27.00'), Decimal('30.00'))
>>> assertEqual(line3.maturity_date, period.end_date + relativedelta(months=3))

View File

@@ -0,0 +1,143 @@
======================
Move Template Scenario
======================
Imports::
>>> import datetime
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import (
... activate_modules, assertEqual, assertGreaterEqual, assertLessEqual)
>>> today = datetime.date.today()
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period_ids = [p.id for p in fiscalyear.periods]
Get accounts::
>>> accounts = get_accounts()
>>> payable = accounts['payable']
>>> expense = accounts['expense']
>>> tax = accounts['tax']
Create tax code::
>>> TaxCode = Model.get('account.tax.code')
>>> tax = create_tax(Decimal('0.1'))
>>> tax.save()
>>> base_code = create_tax_code(tax, amount='base')
>>> base_code.save()
>>> tax_code = create_tax_code(tax)
>>> tax_code.save()
Create parties::
>>> Party = Model.get('party.party')
>>> supplier = Party(name='Supplier')
>>> supplier.save()
Create Template::
>>> MoveTemplate = Model.get('account.move.template')
>>> Journal = Model.get('account.journal')
>>> template = MoveTemplate()
>>> template.name = 'Test'
>>> template.journal, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> _ = template.keywords.new(name='party', string='Party',
... type_='party')
>>> _ = template.keywords.new(name='description', string='Description',
... type_='char')
>>> _ = template.keywords.new(name='amount', string='Amount',
... type_='numeric', digits=2)
>>> template.description = '{party} - {description}'
>>> line = template.lines.new()
>>> line.operation = 'credit'
>>> line.account = payable
>>> line.party = 'party'
>>> line.amount = 'amount'
>>> line.description = "{description} 1"
>>> line = template.lines.new()
>>> line.operation = 'debit'
>>> line.account = expense
>>> line.amount = 'amount / 1.1'
>>> ttax = line.taxes.new()
>>> ttax.amount = line.amount
>>> ttax.tax = tax
>>> ttax.type = 'base'
>>> line.description = "{description} 2"
>>> line = template.lines.new()
>>> line.operation = 'debit'
>>> line.account = tax.invoice_account
>>> line.amount = 'amount * (1 - 1/1.1)'
>>> line.description = "{description} 3"
>>> ttax = line.taxes.new()
>>> ttax.amount = line.amount
>>> ttax.tax = tax
>>> ttax.type = 'tax'
>>> template.save()
Create Move::
>>> create_move = Wizard('account.move.template.create')
>>> assertEqual(create_move.form.date, today)
>>> period = create_move.form.period
>>> assertLessEqual(period.start_date, today)
>>> assertGreaterEqual(period.end_date, today)
>>> index = fiscalyear.periods.index(create_move.form.period)
>>> next_period = fiscalyear.periods[index + 1]
>>> create_move.form.date = next_period.start_date
>>> assertEqual(create_move.form.period, next_period)
>>> prev_period = fiscalyear.periods[index - 1]
>>> create_move.form.period = prev_period
>>> assertEqual(create_move.form.date, prev_period.end_date)
>>> create_move.form.period = next_period
>>> assertEqual(create_move.form.date, next_period.start_date)
>>> create_move.form.template = template
>>> create_move.execute('keywords')
>>> data = {}
>>> keywords = data['keywords'] = {}
>>> keywords['party'] = supplier.id
>>> keywords['description'] = 'Test'
>>> keywords['amount'] = Decimal('12.24')
>>> context = create_move._context.copy()
>>> context.update(create_move._config.context)
>>> _ = create_move._proxy.execute(create_move.session_id, data, 'create_',
... context)
.. note:: using custom call because proteus doesn't support fake model
Check the Move::
>>> Move = Model.get('account.move')
>>> move, = Move.find([])
>>> len(move.lines)
3
>>> sorted((l.debit, l.credit) for l in move.lines)
[(Decimal('0'), Decimal('12.24')), (Decimal('1.11'), Decimal('0')), (Decimal('11.13'), Decimal('0'))]
>>> sorted([l.description for l in move.lines])
['Test 1', 'Test 2', 'Test 3']
>>> move.description
'Supplier - Test'
>>> with config.set_context(periods=period_ids):
... base_code = TaxCode(base_code.id)
... base_code.amount
Decimal('11.13')
>>> with config.set_context(periods=period_ids):
... tax_code = TaxCode(tax_code.id)
... tax_code.amount
Decimal('1.11')

View File

@@ -0,0 +1,66 @@
=================================
Account Renew Fiscalyear Scenario
=================================
Imports::
>>> from proteus import Wizard
>>> from trytond.modules.account.tests.tools import create_fiscalyear
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company)
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods.new()
>>> period.name = 'Adjustment'
>>> period.start_date = fiscalyear.end_date
>>> period.end_date = fiscalyear.end_date
>>> period.type = 'adjustment'
>>> fiscalyear.save()
Set the sequence number::
>>> sequence = fiscalyear.move_sequence
>>> sequence.number_next = 10
>>> sequence.save()
Renew fiscalyear using the wizard::
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
>>> renew_fiscalyear.form.reset_sequences = False
>>> renew_fiscalyear.execute('create_')
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
>>> len(new_fiscalyear.periods)
12
>>> int(new_fiscalyear.move_sequence.number_next)
10
Renew fiscalyear resetting sequences::
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
>>> renew_fiscalyear.form.reset_sequences = True
>>> renew_fiscalyear.execute('create_')
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
>>> int(new_fiscalyear.move_sequence.number_next)
1
Set the sequence name::
>>> sequence = new_fiscalyear.move_sequence
>>> sequence.name = 'Sequence %s' % new_fiscalyear.name
>>> sequence.save()
Renew fiscalyear and test sequence name is updated::
>>> renew_fiscalyear = Wizard('account.fiscalyear.renew')
>>> renew_fiscalyear.form.reset_sequences = True
>>> renew_fiscalyear.execute('create_')
>>> new_fiscalyear, = renew_fiscalyear.actions[0]
>>> assertEqual(new_fiscalyear.move_sequence.name,
... 'Sequence %s' % new_fiscalyear.name)

View File

@@ -0,0 +1,366 @@
========================
Account Reports Scenario
========================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Report
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company, get_company
>>> from trytond.tests.tools import activate_modules
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
>>> company = get_company()
Create fiscal year::
>>> fiscalyear = create_fiscalyear(today=today)
>>> fiscalyear.click('create_period')
>>> periods = fiscalyear.periods
>>> period_1, period_3, period_5 = periods[0], periods[2], periods[4]
Get accounts::
>>> accounts = get_accounts()
>>> receivable = accounts['receivable']
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
Create a child account::
>>> _ = revenue.childs.new()
>>> revenue.save()
>>> child_revenue, = revenue.childs
Create parties::
>>> Party = Model.get('party.party')
>>> party = Party(name='Party')
>>> party.save()
Create a moves::
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> journal_revenue, = Journal.find([
... ('code', '=', 'REV'),
... ])
>>> journal_cash, = Journal.find([
... ('code', '=', 'CASH'),
... ])
>>> move = Move()
>>> move.period = period_3
>>> move.journal = journal_revenue
>>> move.date = period_3.start_date
>>> line = move.lines.new()
>>> line.account = child_revenue
>>> line.credit = Decimal(10)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.debit = Decimal(10)
>>> line.party = party
>>> move.save()
>>> move = Move()
>>> move.period = period_5
>>> move.journal = journal_cash
>>> move.date = period_5.start_date
>>> line = move.lines.new()
>>> line.account = cash
>>> line.debit = Decimal(10)
>>> line = move.lines.new()
>>> line.account = receivable
>>> line.credit = Decimal(10)
>>> line.party = party
>>> move.save()
Print some reports::
>>> GeneralLedgerAccount = Model.get('account.general_ledger.account')
>>> GeneralLedgerAccountParty = Model.get(
... 'account.general_ledger.account.party')
>>> gl_accounts = GeneralLedgerAccount.find([])
>>> _ = [(l.balance, l.party_required) for gl in gl_accounts
... for l in gl.lines]
>>> general_ledger = Report('account.general_ledger', context={
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... })
>>> _ = general_ledger.execute(gl_accounts)
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
... glp_receivable, = GeneralLedgerAccountParty.find([
... ('account', '=', receivable.id),
... ('party', '=', party.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('0.00')
>>> gl_child_revenue.credit
Decimal('10.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
1
>>> gl_revenue.start_balance
Decimal('0.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> glp_receivable.start_balance
Decimal('0.00')
>>> glp_receivable.credit
Decimal('10.00')
>>> glp_receivable.debit
Decimal('10.00')
>>> glp_receivable.end_balance
Decimal('0.00')
>>> glp_receivable.line_count
2
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... 'from_date': period_1.start_date,
... 'to_date': period_3.end_date,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
... glp_receivable, = GeneralLedgerAccountParty.find([
... ('account', '=', receivable.id),
... ('party', '=', party.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('0.00')
>>> gl_child_revenue.credit
Decimal('10.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
1
>>> gl_revenue.start_balance
Decimal('0.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> glp_receivable.start_balance
Decimal('0.00')
>>> glp_receivable.credit
Decimal('0.00')
>>> glp_receivable.debit
Decimal('10.00')
>>> glp_receivable.end_balance
Decimal('10.00')
>>> glp_receivable.line_count
1
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... 'start_period': period_3.id,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('0.00')
>>> gl_child_revenue.credit
Decimal('10.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
1
>>> gl_revenue.start_balance
Decimal('0.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... 'start_period': period_5.id,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('-10.00')
>>> gl_child_revenue.credit
Decimal('0.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
0
>>> gl_revenue.start_balance
Decimal('-10.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... 'from_date': period_3.start_date,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('0.00')
>>> gl_child_revenue.credit
Decimal('10.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
1
>>> gl_revenue.start_balance
Decimal('0.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> context = {
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... 'from_date': period_5.start_date,
... }
>>> with config.set_context(context):
... gl_child_revenue, = GeneralLedgerAccount.find([
... ('account', '=', child_revenue.id),
... ])
... gl_revenue, = GeneralLedgerAccount.find([
... ('account', '=', revenue.id),
... ])
>>> gl_child_revenue.start_balance
Decimal('-10.00')
>>> gl_child_revenue.credit
Decimal('0.00')
>>> gl_child_revenue.debit
Decimal('0.00')
>>> gl_child_revenue.end_balance
Decimal('-10.00')
>>> gl_child_revenue.line_count
0
>>> gl_revenue.start_balance
Decimal('-10.00')
>>> gl_revenue.credit
Decimal('0.00')
>>> gl_revenue.debit
Decimal('0.00')
>>> gl_revenue.end_balance
Decimal('-10.00')
>>> gl_revenue.line_count
0
>>> trial_balance = Report('account.trial_balance', context={
... 'company': company.id,
... 'fiscalyear': fiscalyear.id,
... })
>>> _ = trial_balance.execute(gl_accounts)
>>> Type = Model.get('account.account.type')
>>> statement = Report('account.account.type.statement')
>>> _ = statement.execute(Type.find([]))
>>> AgedBalance = Model.get('account.aged_balance')
>>> context = {
... 'company': company.id,
... 'type': 'customer',
... 'date': today,
... 'term1': 30,
... 'term2': 60,
... 'term3': 90,
... 'unit': 'day',
... }
>>> with config.set_context(context):
... aged_balances = AgedBalance.find([])
>>> aged_balance = Report('account.aged_balance', context=context)
>>> _ = aged_balance.execute(aged_balances)
>>> general_journal = Report('account.move.general_journal')
>>> _ = general_journal.execute(Move.find([]))
>>> with config.set_context(
... start_date=period_5.start_date,
... end_date=period_5.end_date):
... journal_cash = Journal(journal_cash.id)
>>> journal_cash.credit
Decimal('0.00')
>>> journal_cash.debit
Decimal('10.00')
>>> journal_cash.balance
Decimal('10.00')

View File

@@ -0,0 +1,87 @@
=========================
Account Tax Code Scenario
=========================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, create_tax, create_tax_code, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
Create fiscal year::
>>> fiscalyear = create_fiscalyear()
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Create tax code::
>>> TaxCode = Model.get('account.tax.code')
>>> tax = create_tax(Decimal('0.1'))
>>> tax.save()
>>> base_code = create_tax_code(tax, amount='base')
>>> base_code.save()
>>> tax_code_invoice = create_tax_code(tax)
>>> tax_code_invoice.save()
>>> tax_code_credit = create_tax_code(tax, type='credit')
>>> tax_code_credit.save()
Create parties::
>>> Party = Model.get('party.party')
>>> party = Party(name='Party')
>>> party.save()
Create some moves::
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> journal, = Journal.find([
... ('code', '=', 'EXP'),
... ])
>>> move = Move(period=period, journal=journal)
>>> move.date = period.start_date
>>> line = move.lines.new()
>>> line.account = accounts['expense']
>>> line.credit = Decimal(10)
>>> line = move.lines.new()
>>> line.account = accounts['payable']
>>> line.debit = Decimal(11)
>>> line.party = party
>>> line = move.lines.new()
>>> line.account = accounts['tax']
>>> line.credit = Decimal(1)
>>> tax_line = line.tax_lines.new()
>>> tax_line.amount = line.credit
>>> tax_line.type = 'tax'
>>> tax_line.tax = tax
>>> move.save()
>>> _ = move.duplicate()
>>> cancel_move = Wizard('account.move.cancel', [move])
>>> cancel_move.form.reversal = False
>>> cancel_move.execute('cancel')
Check tax code::
>>> TaxCode = Model.get('account.tax.code')
>>> with config.set_context(periods=[period.id]):
... tax_code_invoice = TaxCode(tax_code_invoice.id)
... tax_code_credit = TaxCode(tax_code_credit.id)
>>> tax_code_invoice.amount, tax_code_credit.amount
(Decimal('1.00'), Decimal('0.00'))

View File

@@ -0,0 +1,37 @@
=========================
Account Tax Test Scenario
=========================
Imports::
>>> from decimal import Decimal
>>> from proteus import Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_tax, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('account', create_company, create_chart)
Get accounts::
>>> accounts = get_accounts()
Create tax::
>>> tax = create_tax(Decimal('0.1'))
>>> tax.save()
Test Tax::
>>> tax_test = Wizard('account.tax.test')
>>> tax_test.form.unit_price = Decimal('100.00')
>>> tax_test.form.taxes.append(tax)
>>> result, = tax_test.form.result
>>> assertEqual(result.tax, tax)
>>> assertEqual(result.account, accounts['tax'])
>>> assertEqual(result.base, Decimal('100.00'))
>>> assertEqual(result.amount, Decimal('10.00'))

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import load_doc_tests
def load_tests(*args, **kwargs):
return load_doc_tests(__name__, __file__, *args, **kwargs)

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