会计本地化

警告

本教程要求了解如何在 Odoo 中构建模块(参见 服务器框架入门 )。

安装流程

安装 account 模块时,会自动安装与公司国家代码对应的本地化模块。如果未设置国家代码或未找到本地化模块,则默认安装 l10n_generic_coa (美国)本地化模块。有关详细信息,请查看 post init hook

例如,如果公司的国家为 瑞士 ,则将安装 l10n_ch

构建本地化模块

一个基本的 l10n_XX 模块结构可以通过以下 __manifest__.py 文件描述:

{
    "name": "COUNTRY - Accounting",
    "version": "1.0.0",
    "category": "Accounting/Localizations/Account Charts",
    "license": "LGPL-3",
    "depends": [
        "account",
    ],
    "data": [
        "data/other_data.xml",
        "views/xxxmodel_views.xml",
    ],
    "demo": [
        "demo/demo_company.xml",
    ]
}

您的工作目录应如下所示

l10n_xx
├── data
│   ├── template
│   │   ├── account.account-xx.csv
│   │   ├── account.group-xx.csv
│   │   └── account.tax.group-xx.csv
│   └── other_data.xml
├── views
│   └── xxxmodel_views.xml
├── demo
│   └── demo_company.xml
├── models
│   ├── template_xx.py
│   └── __init__.py
├── __init__.py
└── __manifest__.py

在第一个文件 models/template_xx.py 中,我们设置了账目表的名称以及一些基本字段。

Example

addons/l10n_be/models/template_be.py

    def _get_be_template_data(self):
        return {
            'name': _('Base'),
            'visible': False,
            'code_digits': '6',
            'property_account_receivable_id': 'a400',
            'property_account_payable_id': 'a440',
            'downpayment_account_id': 'a46',
        }

    @template('be', 'res.company')
    def _get_be_res_company(self):
        return {
            self.env.company.id: {
                'account_fiscal_country_id': 'base.be',
                'bank_account_code_prefix': '550',
                'cash_account_code_prefix': '570',
                'transfer_account_code_prefix': '580',
                'account_default_pos_receivable_account_id': 'a4001',
                'income_currency_exchange_account_id': 'a754',
                'expense_currency_exchange_account_id': 'a654',
                'account_journal_suspense_account_id': 'a499',
                'account_journal_early_pay_discount_loss_account_id': 'a657000',
                'account_journal_early_pay_discount_gain_account_id': 'a757000',
                'account_sale_tax_id': 'attn_VAT-OUT-21-L',
                'account_purchase_tax_id': 'attn_VAT-IN-V81-21',
                'account_purchase_receipt_fiscal_position_id': 'fiscal_position_template_6',
                'default_cash_difference_income_account_id': 'a757100',
                'default_cash_difference_expense_account_id': 'a657100',
                'transfer_account_id': 'a58',
                'expense_account_id': 'a600',
                'income_account_id': 'a7000',
            },
        }

    @template('be', 'account.journal')
    def _get_be_account_journal(self):
        return {
            'sale': {'refund_sequence': True},
            'purchase': {'refund_sequence': True},
        }

    @template('be', 'account.reconcile.model')

账目表

账户标签

标签是一种对账户进行分类的方法。例如,假设您想创建一份包含多行的财务报告,但无法根据账户的 code 找到分配规则。解决方案是使用标签,每行报告对应一个标签,以按需过滤账户。

将标签放入 data/account_account_tag_data.xml 文件中。

Example

addons/l10n_lt/data/template/account.account-lt.csv

"id","name","code","account_type","tag_ids","reconcile","non_trade","name@lt"
"account_account_template_1130","Software Acquisition Cost","1130","asset_non_current","l10n_lt.account_account_tag_a_1_3","False","","Programinės įrangos įsigijimo savikaina"
"account_account_template_1138","Amortization of Software Value (-)","1138","asset_non_current","l10n_lt.account_account_tag_a_1_3","False","","Programinės įrangos vertės amortizacija (−)"
"account_account_template_1200","Land Acquisition Cost","1200","asset_fixed","l10n_lt.account_account_tag_a_2_1","False","","Žemės įsigijimo savikaina"
"account_account_template_1201","Change of Land Value after Revaluation","1201","asset_fixed","l10n_lt.account_account_tag_a_2_1","False","","Žemės vertės pokytis dėl perkainojimo"

账户

显然,没有 账户 就无法存在 账目表 。您需要在 data/account.account.template.csv 中指定它们。

Example

addons/l10n_ch/data/template/account.account-ch.csv

"id","name","code","account_type","reconcile","non_trade","name@de","name@it","name@fr"
"ch_coa_1060","Securities (with stock exchange price)","1060","asset_current","False","","Wertpapiere (mit Börsenkurs)","Titoli","Titres"
"ch_coa_1069","Accumulated depreciation on securities","1069","asset_current","False","","Kumulierte Abschreibungen auf Wertpapiere","Rettifica valore titoli","Ajustement de la valeur des titres"
"ch_coa_1090","Salary-Pass-Through Account","1090","asset_current","True","","Gehaltsdurchlaufkonto","Conto di trasferimento dello stipendio","Compte de transfert de salaire"
"ch_coa_1091","Transfer account: Salaries","1091","asset_current","True","","Transferkonto: Gehälter","Conto d'attesa - Salari","Compte d'attente pour salaires"
"ch_coa_1099","Transfer account: miscellaneous","1099","asset_current","True","","Transferkonto: Verschiedenes","Conto d'attesa - altro","Compte d'attente autre"
"ch_coa_1100","Accounts receivable from goods and services (Debtors)","1100","asset_receivable","True","","Forderungen aus Lieferungen und Leistungen (Debitoren)","Crediti da forniture e prestazioni (debitori)","Débiteurs"
"ch_coa_1101","Receivable (PoS)","1101","asset_receivable","True","","Forderungen (PoS)","Crediti (Punti Vendita)","Débiteurs (PoS)"
"ch_coa_1109","Del credere (Acc. depr. on debtors)","1109","asset_current","False","","Delkredere (Akontoabzug für Schuldner)","Delcredere","Ducroire"
"ch_coa_1140","Advances and loans","1140","asset_current","False","","Vorschüsse und Darlehen","Anticipi e prestiti","Avances et prêts"
"ch_coa_1149","Advances and loans adjustments","1149","asset_current","False","","Anpassungen von Vorschüssen und Darlehen","Rettifica valore anticipi e prestiti","Ajustement de la valeur des avances et des prêts"
"ch_coa_1170","Input Tax (VAT) receivable on material, goods, services, energy","1170","asset_current","False","","Vorsteuer (MwSt.) auf Material, Waren, Dienstleistungen, Energie","IVA, Imposta precedente su materiale, merce, servizi e energia","Impôt préalable: TVA s/matériel, marchandises, prestations et énergie"
"ch_coa_1171","Input Tax (VAT) receivable on investments, other operating expenses","1171","asset_current","False","","Vorsteuer (MwSt.) auf Investitionen, sonstige betriebliche Aufwendungen","IVA, imposta precedente su investimenti e altri costi d’esercizio","Impôt préalable: TVA s/investissements et autres charges d’exploitation"

警告

  • 避免使用 asset_cash 类型的 account_type !实际上,银行和现金账户会在安装本地化模块时直接创建,然后与 account.journal 关联。

  • 对于通用情况,仅需一个应付/应收类型的账户即可。然而,我们也需要定义一个 PoS 应收账户(在账目表中关联)。

  • 不要创建过多的账户:200-300个已经足够。但更重要的是,我们需要找到一个平衡点,使账目表(CoA)在大多数公司使用时只需进行最少的调整。

账户组

账户组用于描述账目表的层级结构。需要在报告中激活过滤器,然后当您展开到日记账分录时,它将显示该账户的父级。

它通过前缀 start/end 工作,因此所有代码介于 startend 之间的账户都会将此 account.group 作为其父组。此外,账户组还可以拥有父账户组以形成层级结构。

Example

addons/l10n_il/data/template/account.group-il.csv

ID

起始代码前缀

结束代码前缀

名称

名称@希伯来语

以色列分组_100100

100100

100499

固定资产

固定资产(希伯来语)

以色列分组_101110

101110

101400

流动资产

流动资产(希伯来语)

以色列分组_101401

101401

101799

银行与现金

银行与现金(希伯来语)

以色列分组_111000

111000

111999

流动负债

流动负债(希伯来语)

以色列分组_112000

112000

112210

非流动负债

非流动负债(希伯来语)

以色列分组_200000

200000

200199

销售收入

销售收入

il_group_200200

200200

200300

其他收入

其他收入

il_group_201000

201000

201299

销售成本

销售成本

il_group_202000

202000

220900

费用

费用

il_group_300000

300000

399999

资本和股份

资本和股份

税金

要添加税款,首先需要指定财政位置和税组。通常每个税率只需要一个税组,除了 0% 税率,因为您经常需要区分免税、0%、不适用等税款。此模型只有两个必填字段: namecountry 。创建文件 data/template/account.tax.group-xx.csv 并列出税组。

税款应属于至少一个财政位置,但可以由多个共享。如果您希望税款由所有财政位置共享,请将此字段留空。

Example

addons/l10n_uk/data/template/account.tax.group-uk.csv

"id","name","country_id","tax_payable_account_id","tax_receivable_account_id"
"tax_group_0","TAX 0%","base.uk","220200","220200"
"tax_group_5","TAX 5%","base.uk","220200","220200"
"tax_group_175","TAX 17.5%","base.uk","220200","220200"
"tax_group_20","TAX 20%","base.uk","220200","220200"

现在,您可以通过 data/template/account.tax-xx.csv 文件添加税金。您定义的第一个采购/销售税金也将成为产品的默认采购/销售税金。

Example

addons/l10n_ae/data/template/account.tax-ae.csv

"id","name","type_tax_use","amount","amount_type","description","invoice_label","tax_group_id","repartition_line_ids/repartition_type","repartition_line_ids/document_type","repartition_line_ids/tag_ids","repartition_line_ids/account_id","repartition_line_ids/factor_percent","fiscal_position_ids","original_tax_ids","repartition_line_ids/use_in_tax_closing","include_base_amount","price_include_override"
"uae_sale_tax_5_dubai","5% DU","sale","5.0","percent","Dubai","5%","ae_tax_group_5","base","invoice","1(b)B","","","account_fiscal_position_dubai","","","",""
"","","","","","","","","tax","invoice","1(b)T","uae_account_201017","","","","","",""
"","","","","","","","","base","refund","1(b)B","","","","","","",""
"","","","","","","","","tax","refund","1(b)T","uae_account_201017","","","","","",""
"uae_sale_tax_5_abu_dhabi","5% AZ","sale","5.0","percent","Abu Dhabi","5%","ae_tax_group_5","base","invoice","1(a)B","","","account_fiscal_position_abu_dhabi","uae_sale_tax_5_dubai","","",""
"","","","","","","","","tax","invoice","1(a)T","uae_account_201017","","","","","",""
"","","","","","","","","base","refund","1(a)B","","","","","","",""
"","","","","","","","","tax","refund","1(a)T","uae_account_201017","","","","","",""
"uae_sale_tax_5_sharjah","5% SH","sale","5.0","percent","Sharjah","5%","ae_tax_group_5","base","invoice","1(c)B","","","account_fiscal_position_sharjah","uae_sale_tax_5_dubai","","",""
"","","","","","","","","tax","invoice","1(c)T","uae_account_201017","","","","","",""
"","","","","","","","","base","refund","1(c)B","","","","","","",""
"","","","","","","","","tax","refund","1(c)T","uae_account_201017","","","","","",""
"uae_sale_tax_5_ajman","5% AJ","sale","5.0","percent","Ajman","5%","ae_tax_group_5","base","invoice","1(d)B","","","account_fiscal_position_ajman","uae_sale_tax_5_dubai","","",""
"","","","","","","","","tax","invoice","1(d)T","uae_account_201017","","","","","",""
"","","","","","","","","base","refund","1(d)B","","","","","","",""
"","","","","","","","","tax","refund","1(d)T","uae_account_201017","","","","","",""
"uae_sale_tax_5_umm_al_quwain","5% UQ","sale","5.0","percent","Umm Al Quwain","5%","ae_tax_group_5","base","invoice","1(e)B","","","account_fiscal_position_umm_al_quwain","uae_sale_tax_5_dubai","","",""
"","","","","","","","","tax","invoice","1(e)T","uae_account_201017","","","","","",""
"","","","","","","","","base","refund","1(e)B","","","","","","",""
"","","","","","","","","tax","refund","1(e)T","uae_account_201017","","","","","",""
"uae_sale_tax_5_ras_al_khaima","5% RK","sale","5.0","percent","Ras Al-Khaima","5%","ae_tax_group_5","base","invoice","1(f)B","","","account_fiscal_position_ras_al_khaima","uae_sale_tax_5_dubai","","",""

一个税款也可以是另一个的替代品。当使用目标财政位置时,此替代生效。

税务报告

Enterprise feature

税务报告在 开票account )应用中声明,但只有在安装了 会计account_accountant )后才能访问该报告。

在上一节中,您可能注意到了字段 invoice_repartition_line_idsrefund_repartition_line_ids ,但可能对它们一无所知。好消息是:不止您一个人对此感到困惑。坏消息是:您需要稍微弄清楚一些内容。这个主题确实很复杂。

accounting_localization/tax_report.dot
> Graph not rendered because `dot` is not installed

简单来说,在税金模板中,您需要在发票/退款分配行中指明是否需要将税基或税金的百分比报告到哪一行(通过 minus/plus_report_line_ids 字段)。当您在 Odoo 界面中检查税金配置时,这一点也会变得清晰(或者查看文档 税金参考税金分配参考 )。

因此,一旦您正确配置了税金,只需添加 data/account_tax_report_data.xml 文件并在其中为您的 account.report 创建记录。为了使其被视为税务报告,您需要为其提供正确的 root_report_id

<odoo>
    <record id="tax_report" model="account.report">
        <field name="name">Tax Report</field>
        <field name="root_report_id" ref="account.generic_tax_report"/>
        <field name="country_id" ref="base.XX"/>
    </record>

    ...
</odoo>

… 随后声明其行,作为 account.report.line 记录。

Example

addons/l10n_au/data/account_tax_report_data.xml

    <record id="tax_report" model="account.report">
        <field name="name">BAS Report</field>
        <field name="root_report_id" ref="account.generic_tax_report"/>
        <field name="country_id" ref="base.au"/>
        <field name="allow_foreign_vat" eval="True"/>
        <field name="availability_condition">country</field>
        <field name="integer_rounding">DOWN</field>
        <field name="column_ids">
            <record id="tax_report_balance" model="account.report.column">
                <field name="name">Balance</field>
                <field name="expression_label">balance</field>
            </record>
        </field>
        <field name="line_ids">
            <record id="account_tax_report_gstrpt_sale_total" model="account.report.line">
                <field name="name">GST amounts you owe the Tax Office from sales</field>
                <field name="hierarchy_level">0</field>
                <field name="children_ids">
                    <record id="account_tax_report_gstrpt_g1" model="account.report.line">
                        <field name="name">G1: Total Sales (including any GST)</field>
                        <field name="code">G1</field>
                        <field name="expression_ids">
                            <record id="account_tax_report_gstrpt_g1_tag" model="account.report.expression">
                                <field name="label">balance</field>
                                <field name="engine">tax_tags</field>
                                <field name="formula">-G1</field>
                            </record>
                        </field>
                        <field name="children_ids">
                            <record id="account_tax_report_gstrpt_g2" model="account.report.line">
                                <field name="name">G2: Export sales</field>
                                <field name="code">G2</field>
                                <field name="expression_ids">
                                    <record id="account_tax_report_gstrpt_g2_tag" model="account.report.expression">
                                        <field name="label">balance</field>
                                        <field name="engine">tax_tags</field>
                                        <field name="formula">-G2</field>
                                    </record>
                                </field>
                            </record>

财税位置

data/template/account.fiscal.position-xx.csv 文件中指定财政位置。与公司国家匹配的第一个财政位置被视为国内财政位置。

Example

addons/l10n_es/data/template/account.fiscal.position-es_common_mainland.csv

"id","sequence","name","name@es","name@ca","auto_apply","vat_required","country_id","country_group_id","account_ids/account_src_id","account_ids/account_dest_id"
"l10n_es_domestic_fiscal_position","10","ES Domestic","España Peninsula","Espanya Península","1","","base.es","l10n_es.mainland_es","",""
"fp_intra_private","30","EU private","EU privado","EU privat","1","","","account.europe_vat","",""
"fp_intra","20","Intra-community","Régimen Intracomunitario","Règim intracomunitari","1","1","","account.europe_vat","",""
"","","","","","","","","","account_common_7000","account_common_7001"
"","","","","","","","","","account_common_7010","account_common_7011"
"","","","","","","","","","account_common_7020","account_common_7021"
"","","","","","","","","","account_common_7030","account_common_7031"
"","","","","","","","","","account_common_7040","account_common_7041"
"","","","","","","","","","account_common_7050","account_common_7051"

最后步骤

最后,您可以添加一个演示公司,以便在演示模式下轻松测试本地化功能。

Example

addons/l10n_ch/demo/demo_company.xml

    <record id="base.partner_demo_company_ch" model="res.partner" forcecreate="1">
        <field name="name">CH Company</field>
        <field name="vat">CHE-530781296TVA</field>
        <field name="street">14 Meierskappelerstrasse</field>
        <field name="city">Risch-Rotkreuz</field>
        <field name="country_id" ref="base.ch"/>

        <field name="zip">6343</field>
        <field name="phone">+41 78 123 45 67</field>
        <field name="email">info@company.chexample.com</field>
        <field name="website">www.chexample.com</field>
        <field name="is_company" eval="True"/>
    </record>

    <record id="base.demo_bank_ch" model="res.partner.bank" forcecreate="1">
        <field name="acc_type">iban</field>
        <field name="acc_number">CH4431999123000889012</field>
        <field name="partner_id" ref="base.partner_demo_company_ch"/>
    </record>

    <record id="base.demo_company_ch" model="res.company" forcecreate="1">
        <field name="name">CH Company</field>
        <field name="partner_id" ref="base.partner_demo_company_ch"/>
    </record>

    <function model="res.company" name="_onchange_country_id">
        <value eval="[ref('base.demo_company_ch')]"/>
    </function>

    <function model="res.users" name="write">
        <value eval="[ref('base.user_root'), ref('base.user_admin'), ref('base.user_demo')]"/>
        <value eval="{'company_ids': [(4, ref('base.demo_company_ch'))]}"/>
    </function>

    <function model="account.chart.template" name="try_loading">
        <value eval="[]"/>
        <value>ch</value>
        <value model="res.company" eval="obj().env.ref('base.demo_company_ch')"/>
        <value name="install_demo" eval="True"/>
    </function>

会计报告

Enterprise feature

参见

报表

会计报告应通过单独的模块 l10n_XX_reports 添加,该模块应放入 企业仓库

此类模块的基本 __manifest__.py 文件如下所示:

{
    "name": "COUNTRY - Accounting Reports",
    "category": "Accounting/Localizations/Reporting",
    "version": "1.0.0",
    "author": "Odoo S.A.",
    "license": "OEEL-1",
    "depends": [
        "l10n_XX", "account_reports"
    ],
    "data": [
        "data/balance_sheet.xml",
        "data/profit_and_loss.xml",
    ],
    "auto_install": True,
}

财务报告的功能概述请参见: 报表

一些好的示例:

您可以在此处查看字段的含义:

如果您为报告指定了 root_report_id ,它现在会出现在其变体选择器中。如果没有,您仍然需要为其添加一个菜单项。可以通过点击报告表单视图中的 操作 ‣ 创建菜单项 来创建默认菜单项。然后需要刷新页面才能看到它。或者,要为全新的报告在 报表 菜单中创建一个专用部分,您需要创建一个新的 ir.ui.menu 记录(通常在主 l10n_XX 模块中)和一个新的 ir.actions.client (通常在新的报告 XML 文件中),调用带有新 报告 IDaccount.report 。然后将新菜单设置为动作模型中的 parent_id 字段。