Начальное наполнение

This commit is contained in:
parent f31b6129a0
commit c008ed1ab6
332 changed files with 1262625 additions and 1 deletions

View File

@ -1,2 +1,68 @@
# account
Odoo Accounting
---------------
The Odoo <a href="https://www.odoo.com/app/accounting">Open Source Accounting</a> app allows a better way to
collaborate with your accountants, your customers and control your suppliers.
Activate features on demand, from integrated analytic accounting to budget,
assets and multiple companies consolidation.
A Smart User Interface
----------------------
Record transactions in a few clicks and easily manage all financial activities
in one place. Odoo's user interface is designed with productivity in mind.
A Better Way To Work Together
-------------------------------
Share access to your latest business numbers with your team and your accountant
so everyone is up to speed. From work, home or on the go.
Connect Your Bank Accounts
--------------------------
Import your bank statements and reconcile them in just a few clicks. Prepare
payment orders based on your supplier invoices and payment terms.
Electronic invoicing and automated follow-ups
---------------------------------------------
Create and send professional invoices & get paid online. Get rid of the stress
of having to constantly remind your debtors. Simply set-up and automate
follow-ups to get paid quickly.
Sales Integration
-----------------
Automatically create invoices from sales orders, delivery orders or base them
on time and material. Re-invoice expenses on projects to your customer in just
a few clicks.
Purchase Integration
--------------------
Control supplier invocies based on purchase orders. Get real-time inventory
valuation reports automatically posted in your accounts.
Multi-Level Analytic Accounting
-------------------------------
Integrate your analytic accounting operations with timesheets, projects,
invoices, expenses, etc. No need to record transactions, all analytic entries
are posted automatically following your business rules.
Everything you need to grow
---------------------------
Manage your assets, track expenses, control budgets, multi-level analytic
accounting; Odoo has all the features you need to sustain all your business
activities.
Scale With Your Organization
----------------------------
Odoo supports multiple currencies, multiple users with different access rights,
multiple companies with real time consolidation and unlimited analytic plans.

63
__init__.py Normal file
View File

@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
SYSCOHADA_LIST = ['BJ', 'BF', 'CM', 'CF', 'KM', 'CG', 'CI', 'GA', 'GN', 'GW', 'GQ', 'ML', 'NE',
'CD', 'SN', 'TD', 'TG']
VAT_LIST = ['AT', 'BE', 'CA', 'CO', 'DE', 'EC', 'ES', 'ET', 'FR', 'GR', 'IT', 'LU', 'MX', 'NL',
'NO', 'PL', 'PT', 'RO', 'SI', 'TR', 'GB', 'VE', 'VN']
def _set_fiscal_country(env):
""" Sets the fiscal country on existing companies when installing the module.
That field is an editable computed field. It doesn't automatically get computed
on existing records by the ORM when installing the module, so doing that by hand
ensures existing records will get a value for it if needed.
"""
env['res.company'].search([]).compute_account_tax_fiscal_country()
def _auto_install_l10n(env):
# Check the country of the main company (only) and eventually load some module needed in that country
country = env.company.country_id
country_code = country.code
if country_code:
module_list = []
if not env.company.chart_template:
template_code = env['account.chart.template']._guess_chart_template(country)
module_list.append(env['account.chart.template']._get_chart_template_mapping()[template_code]['module'])
if country_code in ['US', 'CA']:
module_list.append('account_check_printing')
if country_code in SYSCOHADA_LIST + VAT_LIST:
module_list.append('base_vat')
if country_code == 'uk':
module_list.append('account_bacs')
module_ids = env['ir.module.module'].search([('name', 'in', module_list), ('state', '=', 'uninstalled')])
if module_ids:
module_ids.sudo().button_install()
def _auto_install_avatax(env):
""" Install the avatax module automatically if the company is in a country that uses avatax """
avatax_country_codes = ['US', 'CA']
country = env.company.country_id
country_code = country.code
if country_code in avatax_country_codes:
module = env['ir.module.module'].search([('name', '=', 'account_avatax')])
if module.state == 'uninstalled':
module.sudo().button_install()
def _account_post_init(env):
_auto_install_l10n(env)
_set_fiscal_country(env)
_auto_install_avatax(env)
# imported here to avoid dependency cycle issues
# pylint: disable=wrong-import-position
from . import controllers
from . import models
from . import demo
from . import wizard
from . import report
from . import populate
from . import tools

117
__manifest__.py Normal file
View File

@ -0,0 +1,117 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name' : 'Invoicing',
'version' : '1.2',
'summary': 'Invoices & Payments',
'sequence': 10,
'description': """
Invoicing & Payments
====================
The specific and easy-to-use Invoicing system in Odoo allows you to keep track of your accounting, even when you are not an accountant. It provides an easy way to follow up on your vendors and customers.
You could use this simplified accounting in case you work with an (external) account to keep your books, and you still want to keep track of payments. This module also offers you an easy method of registering payments, without having to encode complete abstracts of account.
""",
'category': 'Accounting/Accounting',
'website': 'https://www.odoo.com/app/invoicing',
'depends': ['base_setup', 'onboarding', 'product', 'analytic', 'portal', 'digest'],
'data': [
'security/account_security.xml',
'security/ir.model.access.csv',
'data/account_data.xml',
'data/digest_data.xml',
'views/account_report.xml',
'data/mail_template_data.xml',
'data/onboarding_data.xml',
'views/account_payment_view.xml',
'wizard/account_automatic_entry_wizard_views.xml',
'wizard/account_unreconcile_view.xml',
'wizard/account_move_reversal_view.xml',
'wizard/account_resequence_views.xml',
'wizard/account_payment_register_views.xml',
'views/account_move_views.xml',
'wizard/setup_wizards_view.xml',
'views/account_account_views.xml',
'views/account_group_views.xml',
'views/account_journal_views.xml',
'views/account_account_tag_views.xml',
'views/account_bank_statement_views.xml',
'views/account_reconcile_model_views.xml',
'views/account_tax_views.xml',
'views/account_full_reconcile_views.xml',
'views/account_payment_term_views.xml',
'views/account_payment_method.xml',
'views/res_partner_bank_views.xml',
'views/report_statement.xml',
'views/terms_template.xml',
'wizard/account_validate_move_view.xml',
'views/res_company_views.xml',
'views/product_view.xml',
'views/account_analytic_plan_views.xml',
'views/account_analytic_account_views.xml',
'views/account_analytic_distribution_model_views.xml',
'views/account_analytic_line_views.xml',
'views/report_invoice.xml',
'report/account_invoice_report_view.xml',
'views/account_cash_rounding_view.xml',
'views/ir_module_views.xml',
'views/res_config_settings_views.xml',
'views/partner_view.xml',
'views/account_journal_dashboard_view.xml',
'views/account_portal_templates.xml',
'views/report_payment_receipt_templates.xml',
'data/service_cron.xml',
'views/account_incoterms_view.xml',
'data/account_incoterms_data.xml',
'views/digest_views.xml',
'wizard/account_move_send_views.xml',
'report/account_hash_integrity_templates.xml',
'views/res_currency.xml',
'views/account_menuitem.xml',
'wizard/account_tour_upload_bill.xml',
'wizard/accrued_orders.xml',
'views/bill_preview_template.xml',
'data/account_reports_data.xml',
'views/uom_uom_views.xml',
],
'demo': [
'demo/account_demo.xml',
],
'installable': True,
'application': True,
'post_init_hook': '_account_post_init',
'assets': {
'web._assets_primary_variables': [
'account/static/src/scss/variables.scss',
],
'web.assets_backend': [
'account/static/src/css/account_bank_and_cash.css',
'account/static/src/css/account.css',
'account/static/src/scss/account_journal_dashboard.scss',
'account/static/src/scss/account_searchpanel.scss',
'account/static/src/components/**/*',
'account/static/src/services/*.js',
'account/static/src/js/tours/account.js',
'account/static/src/views/**/*.js',
'account/static/src/js/search/search_bar/search_bar.js',
],
'web.assets_frontend': [
'account/static/src/js/account_portal_sidebar.js',
'account/static/src/js/account_portal.js',
],
'web.assets_tests': [
'account/static/tests/tours/**/*',
],
'web.qunit_suite_tests': [
'account/static/tests/helpers/*.js',
'account/static/tests/*.js',
],
'web.report_assets_common': [
'account/static/src/css/report_invoice.css',
],
'web.report_assets_pdf': [
'account/static/src/css/report_invoice.css',
],
},
'license': 'LGPL-3',
}

6
controllers/__init__.py Normal file
View File

@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import portal
from . import terms
from . import download_docs

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo.http import request, content_disposition
def _get_zip_headers(content, filename):
return [
('Content-Type', 'zip'),
('X-Content-Type-Options', 'nosniff'),
('Content-Length', len(content)),
('Content-Disposition', content_disposition(filename)),
]
class AccountDocumentDownloadController(http.Controller):
@http.route('/account/export_zip_documents', type='http', auth='user')
def export_zip_documents(self, **args):
""" Download zipped attachments. """
ids = list(map(int, request.httprequest.args.getlist('ids')))
filename = request.httprequest.args.get('filename')
attachments = request.env['ir.attachment'].browse(ids)
attachments.check_access_rights('read')
attachments.check_access_rule('read')
content = attachments._build_zip_from_attachments()
headers = _get_zip_headers(content, filename)
return request.make_response(content, headers)

180
controllers/portal.py Normal file
View File

@ -0,0 +1,180 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from collections import OrderedDict
from odoo import http, _
from odoo.osv import expression
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
from odoo.addons.account.controllers.download_docs import _get_zip_headers
from odoo.exceptions import AccessError, MissingError
from odoo.http import request
class PortalAccount(CustomerPortal):
def _prepare_home_portal_values(self, counters):
values = super()._prepare_home_portal_values(counters)
if 'invoice_count' in counters:
invoice_count = request.env['account.move'].search_count(self._get_invoices_domain('out'), limit=1) \
if request.env['account.move'].check_access_rights('read', raise_exception=False) else 0
values['invoice_count'] = invoice_count
if 'bill_count' in counters:
bill_count = request.env['account.move'].search_count(self._get_invoices_domain('in'), limit=1) \
if request.env['account.move'].check_access_rights('read', raise_exception=False) else 0
values['bill_count'] = bill_count
return values
# ------------------------------------------------------------
# My Invoices
# ------------------------------------------------------------
def _invoice_get_page_view_values(self, invoice, access_token, **kwargs):
values = {
'page_name': 'invoice',
'invoice': invoice,
}
return self._get_page_view_values(invoice, access_token, values, 'my_invoices_history', False, **kwargs)
def _get_invoices_domain(self, m_type=None):
if m_type in ['in', 'out']:
move_type = [m_type+move for move in ('_invoice', '_refund', '_receipt')]
else:
move_type = ('out_invoice', 'out_refund', 'in_invoice', 'in_refund', 'out_receipt', 'in_receipt')
return [('state', 'not in', ('cancel', 'draft')), ('move_type', 'in', move_type)]
def _get_account_searchbar_sortings(self):
return {
'date': {'label': _('Date'), 'order': 'invoice_date desc'},
'duedate': {'label': _('Due Date'), 'order': 'invoice_date_due desc'},
'name': {'label': _('Reference'), 'order': 'name desc'},
'state': {'label': _('Status'), 'order': 'state'},
}
def _get_account_searchbar_filters(self):
return {
'all': {'label': _('All'), 'domain': []},
'invoices': {'label': _('Invoices'), 'domain': [('move_type', 'in', ('out_invoice', 'out_refund', 'out_receipt'))]},
'bills': {'label': _('Bills'), 'domain': [('move_type', 'in', ('in_invoice', 'in_refund', 'in_receipt'))]},
}
@http.route(['/my/invoices', '/my/invoices/page/<int:page>'], type='http', auth="user", website=True)
def portal_my_invoices(self, page=1, date_begin=None, date_end=None, sortby=None, filterby=None, **kw):
values = self._prepare_my_invoices_values(page, date_begin, date_end, sortby, filterby)
# pager
pager = portal_pager(**values['pager'])
# content according to pager and archive selected
invoices = values['invoices'](pager['offset'])
request.session['my_invoices_history'] = invoices.ids[:100]
values.update({
'invoices': invoices,
'pager': pager,
})
return request.render("account.portal_my_invoices", values)
def _prepare_my_invoices_values(self, page, date_begin, date_end, sortby, filterby, domain=None, url="/my/invoices"):
values = self._prepare_portal_layout_values()
AccountInvoice = request.env['account.move']
domain = expression.AND([
domain or [],
self._get_invoices_domain(),
])
searchbar_sortings = self._get_account_searchbar_sortings()
# default sort by order
if not sortby:
sortby = 'date'
order = searchbar_sortings[sortby]['order']
searchbar_filters = self._get_account_searchbar_filters()
# default filter by value
if not filterby:
filterby = 'all'
domain += searchbar_filters[filterby]['domain']
if date_begin and date_end:
domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
values.update({
'date': date_begin,
# content according to pager and archive selected
# lambda function to get the invoices recordset when the pager will be defined in the main method of a route
'invoices': lambda pager_offset: (
AccountInvoice.search(domain, order=order, limit=self._items_per_page, offset=pager_offset)
if AccountInvoice.check_access_rights('read', raise_exception=False) else
AccountInvoice
),
'page_name': 'invoice',
'pager': { # vals to define the pager.
"url": url,
"url_args": {'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
"total": AccountInvoice.search_count(domain) if AccountInvoice.check_access_rights('read', raise_exception=False) else 0,
"page": page,
"step": self._items_per_page,
},
'default_url': url,
'searchbar_sortings': searchbar_sortings,
'sortby': sortby,
'searchbar_filters': OrderedDict(sorted(searchbar_filters.items())),
'filterby': filterby,
})
return values
@http.route(['/my/invoices/<int:invoice_id>'], type='http', auth="public", website=True)
def portal_my_invoice_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw):
try:
invoice_sudo = self._document_check_access('account.move', invoice_id, access_token)
except (AccessError, MissingError):
return request.redirect('/my')
if report_type == 'pdf' and download and invoice_sudo.state == 'posted':
# Send & Print wizard with only the 'download' checkbox to get the official attachment(s)
template = request.env.ref(invoice_sudo._get_mail_template())
attachment_ids = invoice_sudo._generate_pdf_and_send_invoice(template, bypass_download=True, checkbox_send_mail=False, checkbox_download=True)
attachments = request.env['ir.attachment'].browse(attachment_ids)
if len(attachments) > 1:
filename = invoice_sudo._get_invoice_report_filename(extension='zip')
zip_content = attachments.sudo()._build_zip_from_attachments()
headers = _get_zip_headers(zip_content, filename)
return request.make_response(zip_content, headers)
headers = self._get_http_headers(invoice_sudo, report_type, attachments.raw, download)
return request.make_response(attachments.raw, list(headers.items()))
elif report_type in ('html', 'pdf', 'text'):
return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account.account_invoices', download=download)
values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw)
return request.render("account.portal_invoice_page", values)
# ------------------------------------------------------------
# My Home
# ------------------------------------------------------------
def details_form_validate(self, data, partner_creation=False):
error, error_message = super(PortalAccount, self).details_form_validate(data)
# prevent VAT/name change if invoices exist
partner = request.env['res.users'].browse(request.uid).partner_id
# Skip this test if we're creating a new partner as we won't ever block him from filling values.
if not partner_creation and not partner.can_edit_vat():
if 'vat' in data and (data['vat'] or False) != (partner.vat or False):
error['vat'] = 'error'
error_message.append(_('Changing VAT number is not allowed once invoices have been issued for your account. Please contact us directly for this operation.'))
if 'name' in data and (data['name'] or False) != (partner.name or False):
error['name'] = 'error'
error_message.append(_('Changing your name is not allowed once invoices have been issued for your account. Please contact us directly for this operation.'))
if 'company_name' in data and (data['company_name'] or False) != (partner.company_name or False):
error['company_name'] = 'error'
error_message.append(_('Changing your company name is not allowed once invoices have been issued for your account. Please contact us directly for this operation.'))
return error, error_message
def extra_details_form_validate(self, data, additional_required_fields, error, error_message):
""" Ensure that all additional required fields have a value in the data """
for field in additional_required_fields:
if field.name not in data or not data[field.name]:
error[field.name] = 'error'
error_message.append(_('The field %s must be filled.', field.field_description.lower()))
return error, error_message

29
controllers/terms.py Normal file
View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo.http import request
def sitemap_terms(env, rule, qs):
if qs and qs.lower() not in '/terms':
return
use_invoice_terms = env['ir.config_parameter'].sudo().get_param('account.use_invoice_terms')
if use_invoice_terms and env.company.terms_type == 'html':
yield {'loc': '/terms'}
class TermsController(http.Controller):
@http.route('/terms', type='http', auth='public', website=True, sitemap=sitemap_terms)
def terms_conditions(self, **kwargs):
use_invoice_terms = request.env['ir.config_parameter'].sudo().get_param('account.use_invoice_terms')
if not (use_invoice_terms and request.env.company.terms_type == 'html'):
return request.render('http_routing.http_error', {
'status_code': _('Oops'),
'status_message': _("""The requested page is invalid, or doesn't exist anymore.""")})
values = {
'use_invoice_terms': use_invoice_terms,
'company': request.env.company
}
return request.render("account.account_terms_conditions_page", values)

152
data/account_data.xml Normal file
View File

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record forcecreate="True" id="decimal_payment" model="decimal.precision">
<field name="name">Payment Terms</field>
<field name="digits">6</field>
</record>
<!-- Open Settings from Purchase Journal to configure mail servers -->
<record id="action_open_settings" model="ir.actions.act_window">
<field name="name">Settings</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context" eval="{'module': 'general_settings', 'bin_size': False}"/>
</record>
<!-- TAGS FOR CASH FLOW STATEMENT DIRECT METHOD -->
<record id="account_tag_operating" model="account.account.tag">
<field name="name">Operating Activities</field>
<field name="applicability">accounts</field>
</record>
<record id="account_tag_financing" model="account.account.tag">
<field name="name">Financing Activities</field>
<field name="applicability">accounts</field>
</record>
<record id="account_tag_investing" model="account.account.tag">
<field name="name">Investing &amp; Extraordinary Activities</field>
<field name="applicability">accounts</field>
</record>
<!--
Payment terms
-->
<record id="account_payment_term_immediate" model="account.payment.term">
<field name="name">Immediate Payment</field>
<field name="note">Payment terms: Immediate Payment</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 0})]"/>
</record>
<record id="account_payment_term_15days" model="account.payment.term">
<field name="name">15 Days</field>
<field name="note">Payment terms: 15 Days</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 15})]"/>
</record>
<record id="account_payment_term_21days" model="account.payment.term">
<field name="name">21 Days</field>
<field name="note">Payment terms: 21 Days</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 21})]"/>
</record>
<record id="account_payment_term_30days" model="account.payment.term">
<field name="name">30 Days</field>
<field name="note">Payment terms: 30 Days</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 30})]"/>
</record>
<record id="account_payment_term_45days" model="account.payment.term">
<field name="name">45 Days</field>
<field name="note">Payment terms: 45 Days</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 45})]"/>
</record>
<record id="account_payment_term_end_following_month" model="account.payment.term">
<field name="name">End of Following Month</field>
<field name="note">Payment terms: End of Following Month</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'delay_type':'days_after_end_of_next_month', 'nb_days': 0})]"/>
</record>
<record id="account_payment_term_30_days_end_month_the_10" model="account.payment.term">
<field name="name">10 Days after End of Next Month</field>
<field name="note">Payment terms: 10 Days after End of Next Month</field>
<field name="line_ids" eval="[Command.clear(), Command.create({'value': 'percent', 'value_amount': 100.0, 'delay_type':'days_after_end_of_next_month', 'nb_days': 10})]"/>
</record>
<record id="account_payment_term_advance_60days" model="account.payment.term">
<field name="name">30% Now, Balance 60 Days</field>
<field name="note">Payment terms: 30% Now, Balance 60 Days</field>
<field name="line_ids" eval="[
Command.clear(),
Command.create({'value': 'percent', 'value_amount': 30.0, 'nb_days': 0}),
Command.create({'value': 'percent', 'value_amount': 70.0, 'nb_days': 60})]"/>
</record>
<record id="account_payment_term_30days_early_discount" model="account.payment.term">
<field name="name">2/7 Net 30</field>
<field name="note">Payment terms: 30 Days, 2% Early Payment Discount under 7 days</field>
<field name="display_on_invoice">True</field>
<field name="early_discount">True</field>
<field name="discount_percentage">2</field>
<field name="discount_days">7</field>
<field name="line_ids" eval="[
Command.clear(),
Command.create({'value': 'percent', 'value_amount': 100.0, 'nb_days': 30})]"/>
</record>
<!-- Account-related subtypes for messaging / Chatter -->
<record id="mt_invoice_validated" model="mail.message.subtype">
<field name="name">Validated</field>
<field name="res_model">account.move</field>
<field name="default" eval="False"/>
<field name="description">Invoice validated</field>
</record>
<record id="mt_invoice_paid" model="mail.message.subtype">
<field name="name">Paid</field>
<field name="res_model">account.move</field>
<field name="default" eval="False"/>
<field name="description">Invoice paid</field>
</record>
<record id="mt_invoice_created" model="mail.message.subtype">
<field name="name">Invoice Created</field>
<field name="res_model">account.move</field>
<field name="default" eval="False"/>
<field name="hidden" eval="True"/>
<field name="description">Invoice Created</field>
</record>
<!-- Payment methods -->
<record id="account_payment_method_manual_in" model="account.payment.method">
<field name="name">Manual</field>
<field name="code">manual</field>
<field name="payment_type">inbound</field>
</record>
<record id="account_payment_method_manual_out" model="account.payment.method">
<field name="name">Manual</field>
<field name="code">manual</field>
<field name="payment_type">outbound</field>
</record>
<!-- Partner Trust Property -->
<record forcecreate="True" id="default_followup_trust" model="ir.property">
<field name="name">Followup Trust Property</field>
<field name="fields_id" search="[('model', '=', 'res.partner'), ('name', '=', 'trust')]"/>
<field name="value">normal</field>
<field name="type">selection</field>
</record>
<!-- Share Button in action menu -->
<record id="model_account_move_action_share" model="ir.actions.server">
<field name="name">Share</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="binding_model_id" ref="account.model_account_move"/>
<field name="binding_view_types">form</field>
<field name="state">code</field>
<field name="code">action = records.action_share()</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="incoterm_EXW" model="account.incoterms">
<field name="code">EXW</field>
<field name="name">EX WORKS</field>
</record>
<record id="incoterm_FCA" model="account.incoterms">
<field name="code">FCA</field>
<field name="name">FREE CARRIER</field>
</record>
<record id="incoterm_FAS" model="account.incoterms">
<field name="code">FAS</field>
<field name="name">FREE ALONGSIDE SHIP</field>
</record>
<record id="incoterm_FOB" model="account.incoterms">
<field name="code">FOB</field>
<field name="name">FREE ON BOARD</field>
</record>
<record id="incoterm_CFR" model="account.incoterms">
<field name="code">CFR</field>
<field name="name">COST AND FREIGHT</field>
</record>
<record id="incoterm_CIF" model="account.incoterms">
<field name="code">CIF</field>
<field name="name">COST, INSURANCE AND FREIGHT</field>
</record>
<record id="incoterm_CPT" model="account.incoterms">
<field name="code">CPT</field>
<field name="name">CARRIAGE PAID TO</field>
</record>
<record id="incoterm_CIP" model="account.incoterms">
<field name="code">CIP</field>
<field name="name">CARRIAGE AND INSURANCE PAID TO</field>
</record>
<record id="incoterm_DPU" model="account.incoterms">
<field name="code">DPU</field>
<field name="name">DELIVERED AT PLACE UNLOADED</field>
</record>
<record id="incoterm_DAP" model="account.incoterms">
<field name="code">DAP</field>
<field name="name">DELIVERED AT PLACE</field>
</record>
<record id="incoterm_DDP" model="account.incoterms">
<field name="code">DDP</field>
<field name="name">DELIVERED DUTY PAID</field>
</record>
</data>
</odoo>

View File

@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<!-- GENERIC TAX REPORT -->
<record id="generic_tax_report" model="account.report">
<field name="name">Generic Tax report</field>
<field name="filter_multi_company">tax_units</field>
<field name="filter_fiscal_position" eval="1"/>
<field name="default_opening_date_filter">last_tax_period</field>
<field name="only_tax_exigible" eval="True"/>
<field name="column_ids">
<record id="generic_tax_report_column_net" model="account.report.column">
<field name="name">Net</field>
<field name="expression_label">net</field>
<field name="figure_type">monetary</field>
</record>
<record id="generic_tax_report_column_tax" model="account.report.column">
<field name="name">Tax</field>
<field name="expression_label">tax</field>
<field name="figure_type">monetary</field>
</record>
</field>
</record>
<record id="generic_tax_report_account_tax" model="account.report">
<field name="name">Group by: Account &gt; Tax </field>
<field name="root_report_id" ref="generic_tax_report"/>
<field name="column_ids">
<record id="generic_tax_report_account_tax_column_net" model="account.report.column">
<field name="name">Net</field>
<field name="expression_label">net</field>
<field name="figure_type">monetary</field>
</record>
<record id="generic_tax_report_account_tax_column_tax" model="account.report.column">
<field name="name">Tax</field>
<field name="expression_label">tax</field>
<field name="figure_type">monetary</field>
</record>
</field>
</record>
<record id="generic_tax_report_tax_account" model="account.report">
<field name="name">Group by: Tax &gt; Account </field>
<field name="root_report_id" ref="generic_tax_report"/>
<field name="column_ids">
<record id="generic_tax_report_tax_account_column_net" model="account.report.column">
<field name="name">Net</field>
<field name="expression_label">net</field>
<field name="figure_type">monetary</field>
</record>
<record id="generic_tax_report_tax_account_column_tax" model="account.report.column">
<field name="name">Tax</field>
<field name="expression_label">tax</field>
<field name="figure_type">monetary</field>
</record>
</field>
</record>
</data>
</odoo>

23
data/digest_data.xml Normal file
View File

@ -0,0 +1,23 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data noupdate="1">
<record id="digest.digest_digest_default" model="digest.digest">
<field name="kpi_account_total_revenue">True</field>
</record>
</data>
<data>
<record id="digest_tip_account_0" model="digest.tip">
<field name="name">Tip: No need to print, put in an envelop and post your invoices</field>
<field name="sequence">700</field>
<field name="group_id" ref="account.group_account_invoice" />
<field name="tip_description" type="html">
<div>
<p class="tip_title">Tip: No need to print, put in an envelop and post your invoices</p>
<p class="tip_content">Use the “<i>Send by Post</i>” option to post invoices automatically. For the cost of a local stamp, we do all the manual work: your invoice will be printed in the right country, put in an envelop and sent by snail mail. Use this feature from the list view to post hundreds of invoices in bulk.</p>
<img src="https://download.odoocdn.com/digests/account/static/src/img/invoice-stamps.png" width="540" class="illustration_border" />
</div>
</field>
</record>
</data>
</odoo>

139
data/mail_template_data.xml Normal file
View File

@ -0,0 +1,139 @@
<?xml version="1.0" ?>
<odoo>
<!-- Mail template are declared in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="1">
<!--Email template -->
<record id="email_template_edi_invoice" model="mail.template">
<field name="name">Invoice: Sending</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="email_from">{{ (object.invoice_user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
<field name="partner_to">{{ object.partner_id.id }}</field>
<field name="subject">{{ object.company_id.name }} Invoice (Ref {{ object.name or 'n/a' }})</field>
<field name="description">Sent to customers with their invoices in attachment</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
Dear
<t t-if="object.partner_id.parent_id">
<t t-out="object.partner_id.name or ''">Brandon Freeman</t> (<t t-out="object.partner_id.parent_id.name or ''">Azure Interior</t>),
</t>
<t t-else="">
<t t-out="object.partner_id.name or ''">Brandon Freeman</t>,
</t>
<br /><br />
Here is your
<t t-if="object.name">
invoice <span style="font-weight:bold;" t-out="object.name or ''">INV/2021/05/0005</span>
</t>
<t t-else="">
invoice
</t>
<t t-if="object.invoice_origin">
(with reference: <t t-out="object.invoice_origin or ''">SUB003</t>)
</t>
amounting in <span style="font-weight:bold;" t-out="format_amount(object.amount_total, object.currency_id) or ''">$ 143,750.00</span>
from <t t-out="object.company_id.name or ''">YourCompany</t>.
<t t-if="object.payment_state in ('paid', 'in_payment')">
This invoice is already paid.
</t>
<t t-else="">
Please remit payment at your earliest convenience.
<t t-if="object.payment_reference">
<br /><br />
Please use the following communication for your payment: <span style="font-weight:bold;" t-out="object.payment_reference or ''">INV/2021/05/0005</span>.
</t>
</t>
<t t-if="hasattr(object, 'timesheet_count') and object.timesheet_count">
<br /><br />
PS: you can review your timesheets <a t-att-href="'my/timesheets?search_in=invoice&amp;search=%s' % object.name">from the portal.</a>
</t>
<br /><br />
Do not hesitate to contact us if you have any questions.
<t t-if="not is_html_empty(object.invoice_user_id.signature)">
<br /><br />
<t t-out="object.invoice_user_id.signature or ''">--<br/>Mitchell Admin</t>
</t>
</p>
</div>
</field>
<field name="report_template_ids" eval="[(4, ref('account.account_invoices'))]"/>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="auto_delete" eval="True"/>
</record>
<record id="mail_template_data_payment_receipt" model="mail.template">
<field name="name">Payment: Payment Receipt</field>
<field name="model_id" ref="account.model_account_payment"/>
<field name="subject">{{ object.company_id.name }} Payment Receipt (Ref {{ object.name or 'n/a' }})</field>
<field name="partner_to">{{ object.partner_id.id }}</field>
<field name="description">Sent manually to customer when clicking on 'Send receipt by email' in payment action</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
Dear <t t-out="object.partner_id.name or ''">Azure Interior</t><br/><br/>
Thank you for your payment.
Here is your payment receipt <span style="font-weight:bold;" t-out="(object.name or '').replace('/','-') or ''">BNK1-2021-05-0002</span> amounting
to <span style="font-weight:bold;" t-out="format_amount(object.amount, object.currency_id) or ''">$ 10.00</span> from <t t-out="object.company_id.name or ''">YourCompany</t>.
<br/><br/>
Do not hesitate to contact us if you have any questions.
<br/><br/>
Best regards,
<t t-if="not is_html_empty(user.signature)">
<br/><br/>
<t t-out="user.signature or ''">--<br/>Mitchell Admin</t>
</t>
</p>
</div>
</field>
<field name="report_template_ids" eval="[(4, ref('account.action_report_payment_receipt'))]"/>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="auto_delete" eval="True"/>
</record>
<!-- Credit note template -->
<record id="email_template_edi_credit_note" model="mail.template">
<field name="name">Credit Note: Sending</field>
<field name="model_id" ref="account.model_account_move"/>
<field name="email_from">{{ (object.invoice_user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
<field name="partner_to">{{ object.partner_id.id }}</field>
<field name="subject">{{ object.company_id.name }} Credit Note (Ref {{ object.name or 'n/a' }})</field>
<field name="description">Sent to customers with the credit note in attachment</field>
<field name="body_html" type="html">
<div style="margin: 0px; padding: 0px;">
<p style="margin: 0px; padding: 0px; font-size: 13px;">
Dear
<t t-if="object.partner_id.parent_id">
<t t-out="object.partner_id.name or ''">Brandon Freeman</t> (<t t-out="object.partner_id.parent_id.name or ''">Azure Interior</t>),
</t>
<t t-else="">
<t t-out="object.partner_id.name or ''">Brandon Freeman</t>,
</t>
<br /><br />
Here is your
<t t-if="object.name">
credit note <span style="font-weight:bold;" t-out="object.name or ''">RINV/2021/05/0001</span>
</t>
<t t-else="">
credit note
</t>
<t t-if="object.invoice_origin">
(with reference: <t t-out="object.invoice_origin or ''">SUB003</t>)
</t>
amounting in <span style="font-weight:bold;" t-out="format_amount(object.amount_total, object.currency_id) or ''">$ 143,750.00</span>
from <t t-out="object.company_id.name or ''">YourCompany</t>.
<br /><br />
Do not hesitate to contact us if you have any questions.
<t t-if="not is_html_empty(object.invoice_user_id.signature)">
<br /><br />
<t t-out="object.invoice_user_id.signature or ''">--<br/>Mitchell Admin</t>
</t>
</p>
</div>
</field>
<field name="report_template_ids" eval="[(4, ref('account.account_invoices'))]"/>
<field name="lang">{{ object.partner_id.lang }}</field>
<field name="auto_delete" eval="True"/>
</record>
</data>
</odoo>

134
data/onboarding_data.xml Normal file
View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!-- ONBOARDING STEPS -->
<!-- INVOICING -->
<record id="onboarding_onboarding_step_company_data" model="onboarding.onboarding.step">
<field name="title">Company Data</field>
<field name="description">Set your company's data for documents header/footer.</field>
<field name="button_text">Let's start!</field>
<field name="done_text">Looks great!</field>
<field name="panel_step_open_action_name">action_open_step_company_data</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_company-data.png"></field>
<field name="step_image_filename">onboarding_company-data.png</field>
<field name="step_image_alt">Onboarding Company Data</field>
<field name="sequence">1</field>
</record>
<record id="onboarding_onboarding_step_base_document_layout" model="onboarding.onboarding.step">
<field name="title">Documents Layout</field>
<field name="description">Customize the look of your documents.</field>
<field name="button_text">Customize</field>
<field name="done_text">Looks great!</field>
<field name="panel_step_open_action_name">action_open_step_base_document_layout</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_quotation-layout.png"></field>
<field name="step_image_filename">onboarding_quotation-layout.png</field>
<field name="step_image_alt">Onboarding Documents Layout</field>
<field name="sequence">3</field>
</record>
<record id="onboarding_onboarding_step_create_invoice" model="onboarding.onboarding.step">
<field name="title">Create Invoice</field>
<field name="description">Create your first invoice.</field>
<field name="button_text">Create</field>
<field name="done_text">First invoice sent!</field>
<field name="panel_step_open_action_name">action_open_step_create_invoice</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_default.png"></field>
<field name="step_image_filename">onboarding_default.png</field>
<field name="step_image_alt">Onboarding Create Invoice</field>
<field name="sequence">4</field>
</record>
<!-- DASHBOARD -->
<record id="onboarding_onboarding_step_fiscal_year" model="onboarding.onboarding.step">
<field name="title">Accounting Periods</field>
<field name="description">Define your fiscal years &amp; tax returns periodicity.</field>
<field name="button_text">Configure</field>
<field name="done_text">Step completed!</field>
<field name="panel_step_open_action_name">action_open_step_fiscal_year</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_accounting-periods.png"></field>
<field name="step_image_filename">onboarding_accounting-periods.png</field>
<field name="step_image_alt">Onboarding Accounting Periods</field>
<field name="sequence">1</field>
</record>
<record id="onboarding_onboarding_step_bank_account" model="onboarding.onboarding.step">
<field name="title">Bank Account</field>
<field name="description">Connect your financial accounts in seconds.</field>
<field name="button_text">Add a bank account</field>
<field name="done_text">Step Completed!</field>
<field name="panel_step_open_action_name">action_open_step_bank_account</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_puzzle.png"></field>
<field name="step_image_filename">onboarding_puzzle.png</field>
<field name="step_image_alt">Onboarding Bank Account</field>
<field name="sequence">2</field>
</record>
<record id="onboarding_onboarding_step_default_taxes" model="onboarding.onboarding.step">
<field name="title">Taxes</field>
<field name="description">Set default Taxes for sales and purchase transactions.</field>
<field name="button_text">Review</field>
<field name="done_text">Taxes set!</field>
<field name="panel_step_open_action_name">action_open_step_default_taxes</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_taxes.png"></field>
<field name="step_image_filename">onboarding_taxes.png</field>
<field name="step_image_alt">Onboarding Taxes</field>
<field name="sequence">3</field>
</record>
<record id="onboarding_onboarding_step_chart_of_accounts" model="onboarding.onboarding.step">
<field name="title">Chart of Accounts</field>
<field name="description">Set up your chart of accounts and record initial balances.</field>
<field name="button_text">Review</field>
<field name="done_text">Chart of accounts set!</field>
<field name="panel_step_open_action_name">action_open_step_chart_of_accounts</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_chart-of-accounts.png"></field>
<field name="step_image_filename">onboarding_chart-of-accounts.png</field>
<field name="step_image_alt">Onboarding Bank Account</field>
<field name="sequence">4</field>
</record>
<!-- WITHOUT PANEL -->
<record id="onboarding_onboarding_step_setup_bill" model="onboarding.onboarding.step">
<field name="title">Import Vendor Bills</field>
<field name="sequence">1000</field>
</record>
<record id="onboarding_onboarding_step_sales_tax" model="onboarding.onboarding.step">
<field name="title">Taxes</field>
<!-- Fields values used if/when added in a panel within other modules -->
<field name="description">Choose a default sales tax for your products.</field>
<field name="button_text">Set taxes</field>
<field name="done_text">Step Completed!</field>
<field name="panel_step_open_action_name">action_open_step_sales_tax</field>
<field name="step_image" type="base64" file="base/static/img/onboarding_puzzle.png"></field>
<field name="step_image_filename">onboarding_puzzle.png</field>
<field name="step_image_alt">Onboarding Bank Account</field>
<field name="sequence">100</field> <!-- after "Online Payment" -->
</record>
<!-- ONBOARDING PANELS -->
<record id="onboarding_onboarding_account_invoice" model="onboarding.onboarding">
<field name="name">Invoicing Onboarding</field>
<field name="step_ids" eval="[
Command.link(ref('account.onboarding_onboarding_step_company_data')),
Command.link(ref('account.onboarding_onboarding_step_base_document_layout')),
Command.link(ref('account.onboarding_onboarding_step_create_invoice'))
]"/>
<field name="route_name">account_invoice</field>
<field name="panel_close_action_name">action_close_panel_account_invoice</field>
</record>
<record id="onboarding_onboarding_account_dashboard" model="onboarding.onboarding">
<field name="name">Account Dashboard Onboarding</field>
<field name="step_ids" eval="[
Command.link(ref('account.onboarding_onboarding_step_fiscal_year')),
Command.link(ref('account.onboarding_onboarding_step_bank_account')),
Command.link(ref('account.onboarding_onboarding_step_default_taxes')),
Command.link(ref('account.onboarding_onboarding_step_chart_of_accounts'))
]"/>
<field name="route_name">account_dashboard</field>
<field name="panel_close_action_name">action_close_panel_account_dashboard</field>
</record>
</data>
</odoo>

25
data/service_cron.xml Normal file
View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="ir_cron_auto_post_draft_entry" model="ir.cron">
<field name="name">Account: Post draft entries with auto_post enabled and accounting date up to today</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="nextcall" eval="(DateTime.now().replace(hour=2, minute=0) + timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S')" />
<field name="doall" eval="False"/>
<field name="model_id" ref="model_account_move"/>
<field name="code">model._autopost_draft_entries()</field>
<field name="state">code</field>
</record>
<record id="ir_cron_account_move_send" model="ir.cron">
<field name="name">Send invoices automatically</field>
<field name="model_id" ref="model_account_move"/>
<field name="state">code</field>
<field name="code">model._cron_account_move_send(job_count=20)</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
</record>
</odoo>

View File

@ -0,0 +1,41 @@
"id","name","code","account_type","tag_ids","reconcile"
"current_assets","Current Assets","1010","asset_current","","False"
"stock_valuation","Stock Valuation","1101","asset_current","","False"
"stock_in","Stock Interim (Received)","1102","asset_current","","True"
"stock_out","Stock Interim (Delivered)","1103","asset_current","","True"
"cost_of_production","Cost of Production","1104","asset_current","","True"
"receivable","Account Receivable","1210","asset_receivable","","True"
"to_receive_rec","Products to receive","1211","asset_current","","True"
"tax_paid","Tax Paid","1310","asset_current","","False"
"tax_receivable","Tax Receivable","1320","asset_current","","False"
"prepayments","Prepayments","1410","asset_prepayments","","False"
"fixed_assets","Fixed Asset","1510","asset_fixed","","False"
"non_current_assets","Non-current assets","1910","asset_non_current","","False"
"current_liabilities","Current Liabilities","2010","liability_current","","False"
"payable","Account Payable","2110","liability_payable","","True"
"to_receive_pay","Bills to receive","2111","liability_current","","True"
"salary_payable","Salary Payable","2300","liability_current","","True"
"employee_payroll_taxes","Employee Payroll Taxes","2301","liability_current","","True"
"employer_payroll_taxes","Employer Payroll Taxes","2302","liability_current","","True"
"tax_received","Tax Received","2510","liability_current","","False"
"tax_payable","Tax Payable","2520","liability_current","","False"
"non_current_liabilities","Non-current Liabilities","2910","liability_non_current","","False"
"capital","Capital","3010","equity","","False"
"dividends","Dividends","3020","equity","","False"
"income","Product Sales","4000","income","account.account_tag_operating","False"
"income_currency_exchange","Foreign Exchange Gain","4410","income","account.account_tag_financing","False"
"cash_diff_income","Cash Difference Gain","4420","income","account.account_tag_investing","False"
"cash_discount_loss","Cash Discount Loss","4430","expense","","False"
"other_income","Other Income","4500","income_other","","False"
"cost_of_goods_sold","Cost of Goods Sold","5000","expense_direct_cost","account.account_tag_operating","False"
"expense","Expenses","6000","expense","account.account_tag_operating","False"
"expense_invest","Purchase of Equipments","6110","expense","account.account_tag_investing","False"
"expense_rent","Rent","6120","expense","account.account_tag_investing","False"
"expense_finance","Bank Fees","6200","expense","account.account_tag_financing","False"
"expense_salary","Salary Expenses","6300","expense","account.account_tag_operating","False"
"expense_currency_exchange","Foreign Exchange Loss","6410","expense","account.account_tag_financing","False"
"cash_diff_expense","Cash Difference Loss","6420","expense","account.account_tag_investing","False"
"cash_discount_gain","Cash Discount Gain","6430","income","","False"
"expense_rd","RD Expenses","9610","expense","account.account_tag_investing","False"
"expense_sales","Sales Expenses","9620","expense","account.account_tag_investing","False"
"pos_receivable","Account Receivable (PoS)","1013","asset_receivable","","True"
1 id name code account_type tag_ids reconcile
2 current_assets Current Assets 1010 asset_current False
3 stock_valuation Stock Valuation 1101 asset_current False
4 stock_in Stock Interim (Received) 1102 asset_current True
5 stock_out Stock Interim (Delivered) 1103 asset_current True
6 cost_of_production Cost of Production 1104 asset_current True
7 receivable Account Receivable 1210 asset_receivable True
8 to_receive_rec Products to receive 1211 asset_current True
9 tax_paid Tax Paid 1310 asset_current False
10 tax_receivable Tax Receivable 1320 asset_current False
11 prepayments Prepayments 1410 asset_prepayments False
12 fixed_assets Fixed Asset 1510 asset_fixed False
13 non_current_assets Non-current assets 1910 asset_non_current False
14 current_liabilities Current Liabilities 2010 liability_current False
15 payable Account Payable 2110 liability_payable True
16 to_receive_pay Bills to receive 2111 liability_current True
17 salary_payable Salary Payable 2300 liability_current True
18 employee_payroll_taxes Employee Payroll Taxes 2301 liability_current True
19 employer_payroll_taxes Employer Payroll Taxes 2302 liability_current True
20 tax_received Tax Received 2510 liability_current False
21 tax_payable Tax Payable 2520 liability_current False
22 non_current_liabilities Non-current Liabilities 2910 liability_non_current False
23 capital Capital 3010 equity False
24 dividends Dividends 3020 equity False
25 income Product Sales 4000 income account.account_tag_operating False
26 income_currency_exchange Foreign Exchange Gain 4410 income account.account_tag_financing False
27 cash_diff_income Cash Difference Gain 4420 income account.account_tag_investing False
28 cash_discount_loss Cash Discount Loss 4430 expense False
29 other_income Other Income 4500 income_other False
30 cost_of_goods_sold Cost of Goods Sold 5000 expense_direct_cost account.account_tag_operating False
31 expense Expenses 6000 expense account.account_tag_operating False
32 expense_invest Purchase of Equipments 6110 expense account.account_tag_investing False
33 expense_rent Rent 6120 expense account.account_tag_investing False
34 expense_finance Bank Fees 6200 expense account.account_tag_financing False
35 expense_salary Salary Expenses 6300 expense account.account_tag_operating False
36 expense_currency_exchange Foreign Exchange Loss 6410 expense account.account_tag_financing False
37 cash_diff_expense Cash Difference Loss 6420 expense account.account_tag_investing False
38 cash_discount_gain Cash Discount Gain 6430 income False
39 expense_rd RD Expenses 9610 expense account.account_tag_investing False
40 expense_sales Sales Expenses 9620 expense account.account_tag_investing False
41 pos_receivable Account Receivable (PoS) 1013 asset_receivable True

View File

@ -0,0 +1,9 @@
"id","name","description","invoice_label","amount","type_tax_use","tax_group_id","repartition_line_ids/document_type","repartition_line_ids/factor_percent","repartition_line_ids/repartition_type","repartition_line_ids/account_id"
"sale_tax_template","15%","","","15","sale","tax_group_15","invoice","100","base",""
"","","","","","","","invoice","100","tax","tax_received"
"","","","","","","","refund","100","base",""
"","","","","","","","refund","100","tax","tax_received"
"purchase_tax_template","15%","","","15","purchase","tax_group_15","invoice","100","base",""
"","","","","","","","invoice","100","tax","tax_paid"
"","","","","","","","refund","100","base",""
"","","","","","","","refund","100","tax","tax_paid"
1 id name description invoice_label amount type_tax_use tax_group_id repartition_line_ids/document_type repartition_line_ids/factor_percent repartition_line_ids/repartition_type repartition_line_ids/account_id
2 sale_tax_template 15% 15 sale tax_group_15 invoice 100 base
3 invoice 100 tax tax_received
4 refund 100 base
5 refund 100 tax tax_received
6 purchase_tax_template 15% 15 purchase tax_group_15 invoice 100 base
7 invoice 100 tax tax_paid
8 refund 100 base
9 refund 100 tax tax_paid

View File

@ -0,0 +1,2 @@
id,name,country_id,tax_payable_account_id,tax_receivable_account_id
tax_group_15,Tax 15%,base.us,tax_payable,tax_receivable
1 id name country_id tax_payable_account_id tax_receivable_account_id
2 tax_group_15 Tax 15% base.us tax_payable tax_receivable

3
demo/__init__.py Normal file
View File

@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import account_demo

491
demo/account_demo.py Normal file
View File

@ -0,0 +1,491 @@
# -*- coding: utf-8 -*-
import logging
import time
from datetime import timedelta
from dateutil.relativedelta import relativedelta
from odoo import api, fields, models, Command
from odoo.tools.misc import file_open, formatLang
from odoo.exceptions import UserError, ValidationError
_logger = logging.getLogger(__name__)
class AccountChartTemplate(models.AbstractModel):
_inherit = "account.chart.template"
@api.model
def _get_demo_data(self, company=False):
"""Generate the demo data related to accounting."""
# This is a generator because data created here might be referenced by xml_id to data
# created later but defined in this same function.
self._get_demo_data_products(company)
return {
'account.move': self._get_demo_data_move(company),
'account.bank.statement': self._get_demo_data_statement(company),
'account.bank.statement.line': self._get_demo_data_transactions(company),
'account.reconcile.model': self._get_demo_data_reconcile_model(company),
'ir.attachment': self._get_demo_data_attachment(company),
'mail.message': self._get_demo_data_mail_message(company),
'mail.activity': self._get_demo_data_mail_activity(company),
}
def _post_load_demo_data(self, company=False):
invoices = (
self.ref('demo_invoice_1')
+ self.ref('demo_invoice_2')
+ self.ref('demo_invoice_3')
+ self.ref('demo_invoice_followup')
+ self.ref('demo_invoice_5')
+ self.ref('demo_invoice_equipment_purchase')
+ self.ref('demo_move_auto_reconcile_1')
+ self.ref('demo_move_auto_reconcile_2')
+ self.ref('demo_move_auto_reconcile_3')
+ self.ref('demo_move_auto_reconcile_4')
+ self.ref('demo_move_auto_reconcile_5')
+ self.ref('demo_move_auto_reconcile_6')
+ self.ref('demo_move_auto_reconcile_7')
+ self.ref('demo_move_auto_reconcile_8')
+ self.ref('demo_move_auto_reconcile_9')
)
# the invoice_extract acts like a placeholder for the OCR to be ran and doesn't contain
# any lines yet
for move in invoices:
try:
move.action_post()
except (UserError, ValidationError):
_logger.exception('Error while posting demo data')
@api.model
def _get_demo_data_products(self, company=False):
prod_templates = self.env['product.product'].search(self.env['product.product']._check_company_domain(company))
if self.env.company.account_sale_tax_id:
prod_templates_sale = prod_templates.filtered(
lambda p: not p.taxes_id.filtered_domain(p.taxes_id._check_company_domain(company)))
prod_templates_sale.write({'taxes_id': [Command.link(self.env.company.account_sale_tax_id.id)]})
if self.env.company.account_purchase_tax_id:
prod_templates_purchase = prod_templates.filtered(
lambda p: not p.supplier_taxes_id.filtered_domain(p.taxes_id._check_company_domain(company)))
prod_templates_purchase.write({'supplier_taxes_id': [Command.link(self.env.company.account_purchase_tax_id.id)]})
@api.model
def _get_demo_data_move(self, company=False):
one_month_ago = fields.Date.today() + relativedelta(months=-1)
fifteen_months_ago = fields.Date.today() + relativedelta(months=-15)
cid = company.id or self.env.company.id
misc_journal = self.env['account.journal'].search(
domain=[
*self.env['account.journal']._check_company_domain(cid),
('type', '=', 'general'),
],
limit=1,
)
bank_journal = self.env['account.journal'].search(
domain=[
*self.env['account.journal']._check_company_domain(cid),
('type', '=', 'bank'),
],
limit=1,
)
default_receivable = self.env.ref('base.res_partner_3').with_company(company).property_account_receivable_id
income_account = self.env['account.account'].search([
('company_id', '=', cid),
('account_type', '=', 'income'),
('id', '!=', (company or self.env.company).account_journal_early_pay_discount_gain_account_id.id)
], limit=1)
return {
'demo_invoice_1': {
'move_type': 'out_invoice',
'partner_id': 'base.res_partner_12',
'invoice_user_id': 'base.user_demo',
'invoice_payment_term_id': 'account.account_payment_term_end_following_month',
'invoice_date': time.strftime('%Y-%m-01'),
'delivery_date': time.strftime('%Y-%m-01'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_02', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_invoice_2': {
'move_type': 'out_invoice',
'partner_id': 'base.res_partner_2',
'invoice_user_id': False,
'invoice_date': (fields.Date.today() + timedelta(days=-2)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-2)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_01', 'quantity': 20}),
],
},
'demo_invoice_3': {
'move_type': 'out_invoice',
'partner_id': 'base.res_partner_2',
'invoice_user_id': False,
'invoice_date': (fields.Date.today() + timedelta(days=-3)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-3)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_01', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_invoice_followup': {
'move_type': 'out_invoice',
'partner_id': 'base.res_partner_2',
'invoice_user_id': 'base.user_demo',
'invoice_payment_term_id': 'account.account_payment_term_immediate',
'invoice_date': (fields.Date.today() + timedelta(days=-15)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-15)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_02', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_invoice_5': {
'move_type': 'in_invoice',
'partner_id': 'base.res_partner_12',
'invoice_payment_term_id': 'account.account_payment_term_end_following_month',
'invoice_date': time.strftime('%Y-%m-01'),
'delivery_date': time.strftime('%Y-%m-01'),
'invoice_line_ids': [
Command.create({'product_id': 'product.product_delivery_01', 'price_unit': 10.0, 'quantity': 1}),
Command.create({'product_id': 'product.product_order_01', 'price_unit': 4.0, 'quantity': 5}),
],
},
'demo_invoice_extract': {
'move_type': 'in_invoice',
'message_main_attachment_id': 'ir_attachment_in_invoice_1',
},
'demo_invoice_equipment_purchase': {
'move_type': 'in_invoice',
'ref': f'INV/{fifteen_months_ago.year}/0057',
'partner_id': 'base.res_partner_12',
'invoice_user_id': False,
'invoice_date': fifteen_months_ago.strftime("%Y-%m-17"),
'delivery_date': fifteen_months_ago.strftime("%Y-%m-17"),
'invoice_line_ids': [
Command.create({'name': 'Redeem Reference Number: PO02529', 'quantity': 1, 'price_unit': 541.10,
'tax_ids': self.env.company.account_purchase_tax_id.ids}),
],
'message_main_attachment_id': 'ir_attachment_in_invoice_2',
},
'demo_move_auto_reconcile_1': {
'move_type': 'out_refund',
'partner_id': 'base.res_partner_12',
'invoice_date': one_month_ago.strftime("%Y-%m-02"),
'delivery_date': one_month_ago.strftime("%Y-%m-02"),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_move_auto_reconcile_2': {
'move_type': 'out_refund',
'partner_id': 'base.res_partner_12',
'invoice_date': one_month_ago.strftime("%Y-%m-03"),
'delivery_date': one_month_ago.strftime("%Y-%m-03"),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_02', 'quantity': 5}),
],
},
'demo_move_auto_reconcile_3': {
'move_type': 'in_refund',
'partner_id': 'base.res_partner_12',
'invoice_date': time.strftime('%Y-%m-01'),
'delivery_date': time.strftime('%Y-%m-01'),
'invoice_line_ids': [
Command.create({'product_id': 'product.product_delivery_01', 'price_unit': 10.0, 'quantity': 1}),
Command.create({'product_id': 'product.product_order_01', 'price_unit': 4.0, 'quantity': 5}),
],
},
'demo_move_auto_reconcile_4': {
'move_type': 'in_refund',
'partner_id': 'base.res_partner_12',
'invoice_date': fifteen_months_ago.strftime("%Y-%m-19"),
'delivery_date': fifteen_months_ago.strftime("%Y-%m-19"),
'invoice_line_ids': [
Command.create({'name': 'Redeem Reference Number: PO02529', 'quantity': 1, 'price_unit': 541.10,
'tax_ids': self.env.company.account_purchase_tax_id.ids}),
],
},
'demo_move_auto_reconcile_5': {
'move_type': 'out_refund',
'partner_id': 'base.res_partner_2',
'invoice_date': (fields.Date.today() + timedelta(days=-10)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-10)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_02', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_move_auto_reconcile_6': {
'move_type': 'out_refund',
'partner_id': 'base.res_partner_2',
'invoice_user_id': False,
'invoice_date': (fields.Date.today() + timedelta(days=-1)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-1)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_01', 'quantity': 20}),
],
},
'demo_move_auto_reconcile_7': {
'move_type': 'out_refund',
'partner_id': 'base.res_partner_2',
'invoice_date': (fields.Date.today() + timedelta(days=-2)).strftime('%Y-%m-%d'),
'delivery_date': (fields.Date.today() + timedelta(days=-2)).strftime('%Y-%m-%d'),
'invoice_line_ids': [
Command.create({'product_id': 'product.consu_delivery_01', 'quantity': 5}),
Command.create({'product_id': 'product.consu_delivery_03', 'quantity': 5}),
],
},
'demo_move_auto_reconcile_8': {
'move_type': 'entry',
'partner_id': 'base.res_partner_2',
'date': (fields.Date.today() + timedelta(days=-20)).strftime('%Y-%m-%d'),
'journal_id': misc_journal.id,
'line_ids': [
Command.create({'debit': 0.0, 'credit': 2500.0, 'account_id': default_receivable.id}),
Command.create({'debit': 2500.0, 'credit': 0.0, 'account_id': bank_journal.default_account_id.id}),
],
},
'demo_move_auto_reconcile_9': {
'move_type': 'entry',
'partner_id': 'base.res_partner_2',
'date': (fields.Date.today() + timedelta(days=-20)).strftime('%Y-%m-%d'),
'journal_id': misc_journal.id,
'line_ids': [
Command.create({'debit': 2500.0, 'credit': 0.0, 'account_id': default_receivable.id}),
Command.create({'debit': 0.0, 'credit': 2500.0, 'account_id': income_account.id}),
],
},
}
@api.model
def _get_demo_data_statement(self, company=False):
cid = company.id or self.env.company.id
bnk_journal = self.env['account.journal'].search(
domain=[
*self.env['account.journal']._check_company_domain(cid),
('type', '=', 'bank'),
],
limit=1,
)
return {
'demo_bank_statement_1': {
'name': f'{bnk_journal.name} - {time.strftime("%Y")}-01-01/1',
'balance_end_real': 6378.0,
'balance_start': 0.0,
'line_ids': [
Command.create({
'journal_id': bnk_journal.id,
'payment_ref': 'Initial balance',
'amount': 5103.0,
'date': time.strftime('%Y-01-01'),
}),
Command.create({
'journal_id': bnk_journal.id,
'payment_ref': time.strftime('INV/%Y/00002 and INV/%Y/00003'),
'amount': 1275.0,
'date': time.strftime('%Y-01-01'),
'partner_id': 'base.res_partner_12',
}),
]
},
}
@api.model
def _get_demo_data_transactions(self, company=False):
cid = company.id or self.env.company.id
bnk_journal = self.env['account.journal'].search(
domain=[
*self.env['account.journal']._check_company_domain(cid),
('type', '=', 'bank'),
],
limit=1,
)
return {
'demo_bank_statement_line_0': {
'journal_id': bnk_journal.id,
'payment_ref': 'Bank Fees',
'amount': -32.58,
'date': time.strftime('%Y-01-01'),
},
'demo_bank_statement_line_1': {
'journal_id': bnk_journal.id,
'payment_ref': 'Prepayment',
'amount': 650,
'date': time.strftime('%Y-01-01'),
'partner_id': 'base.res_partner_12',
},
'demo_bank_statement_line_2': {
'journal_id': bnk_journal.id,
'payment_ref': time.strftime(f'First {formatLang(self.env, 2000, currency_obj=self.env.company.currency_id)} of invoice %Y/00001'),
'amount': 2000,
'date': time.strftime('%Y-01-01'),
'partner_id': 'base.res_partner_12',
},
'demo_bank_statement_line_3': {
'journal_id': bnk_journal.id,
'payment_ref': 'Last Year Interests',
'amount': 102.78,
'date': time.strftime('%Y-01-01'),
},
'demo_bank_statement_line_4': {
'journal_id': bnk_journal.id,
'payment_ref': time.strftime('INV/%Y/00002'),
'amount': 750,
'date': time.strftime('%Y-01-01'),
'partner_id': 'base.res_partner_2',
},
'demo_bank_statement_line_5': {
'journal_id': bnk_journal.id,
'payment_ref': f'R:9772938 10/07 AX 9415116318 T:5 BRT: {formatLang(self.env, 100.0, digits=2)} C/ croip',
'amount': 96.67,
'date': time.strftime('%Y-01-01'),
},
}
@api.model
def _get_demo_data_reconcile_model(self, company=False):
return {
'reconcile_from_label': {
'name': 'Line with Bank Fees',
'rule_type': 'writeoff_suggestion',
'match_label': 'contains',
'match_label_param': 'BRT',
'line_ids': [
Command.create({
'label': 'Due amount',
'account_id': self._get_demo_account(
'income',
'income',
self.env.company,
).id,
'amount_type': 'regex',
'amount_string': r'BRT: ([\d,.]+)',
}),
Command.create({
'label': 'Bank Fees',
'account_id': self._get_demo_account(
'cost_of_goods_sold',
'expense_direct_cost',
self.env.company,
).id,
'amount_type': 'percentage',
'amount_string': '100',
}),
]
},
}
@api.model
def _get_demo_data_attachment(self, company=False):
return {
'ir_attachment_in_invoice_1': {
'type': 'binary',
'name': 'in_invoice_yourcompany_demo.pdf',
'res_model': 'account.move',
'res_id': 'demo_invoice_extract',
'raw': file_open(
'account/static/demo/in_invoice_yourcompany_demo_1.pdf', 'rb'
).read()
},
'ir_attachment_in_invoice_2': {
'type': 'binary',
'name': 'in_invoice_yourcompany_demo.pdf',
'res_model': 'account.move',
'res_id': 'demo_invoice_equipment_purchase',
'raw': file_open(
'account/static/demo/in_invoice_yourcompany_demo_2.pdf', 'rb'
).read()
},
}
@api.model
def _get_demo_data_mail_message(self, company=False):
return {
'mail_message_in_invoice_1': {
'model': 'account.move',
'res_id': 'demo_invoice_extract',
'body': 'Vendor Bill attachment',
'message_type': 'comment',
'author_id': 'base.partner_demo',
'attachment_ids': [Command.set([
'ir_attachment_in_invoice_1',
])]
},
'mail_message_in_invoice_2': {
'model': 'account.move',
'res_id': 'demo_invoice_equipment_purchase',
'body': 'Vendor Bill attachment',
'message_type': 'comment',
'author_id': 'base.partner_demo',
'attachment_ids': [Command.set([
'ir_attachment_in_invoice_2',
])]
},
}
@api.model
def _get_demo_data_mail_activity(self, company=False):
return {
'invoice_activity_1': {
'res_id': 'demo_invoice_3',
'res_model_id': 'account.model_account_move',
'activity_type_id': 'mail.mail_activity_data_todo',
'date_deadline': (fields.Datetime.today() + relativedelta(days=5)).strftime('%Y-%m-%d %H:%M'),
'summary': 'Follow-up on payment',
'create_uid': 'base.user_admin',
'user_id': 'base.user_admin',
},
'invoice_activity_2': {
'res_id': 'demo_invoice_2',
'res_model_id': 'account.model_account_move',
'activity_type_id': 'mail.mail_activity_data_call',
'date_deadline': fields.Datetime.today().strftime('%Y-%m-%d %H:%M'),
'create_uid': 'base.user_admin',
'user_id': 'base.user_admin',
},
'invoice_activity_3': {
'res_id': 'demo_invoice_1',
'res_model_id': 'account.model_account_move',
'activity_type_id': 'mail.mail_activity_data_todo',
'date_deadline': (fields.Datetime.today() + relativedelta(days=5)).strftime('%Y-%m-%d %H:%M'),
'summary': 'Include upsell',
'create_uid': 'base.user_admin',
'user_id': 'base.user_admin',
},
'invoice_activity_4': {
'res_id': 'demo_invoice_extract',
'res_model_id': 'account.model_account_move',
'activity_type_id': 'mail.mail_activity_data_todo',
'date_deadline': (fields.Datetime.today() + relativedelta(days=5)).strftime('%Y-%m-%d %H:%M'),
'summary': 'Update address',
'create_uid': 'base.user_admin',
'user_id': 'base.user_admin',
},
}
@api.model
def _get_demo_account(self, xml_id, account_type, company):
"""Find the most appropriate account possible for demo data creation.
:param xml_id (str): the xml_id of the account template in the generic coa
:param account_type (str): the full xml_id of the account type wanted
:param company (Model<res.company>): the company for which we search the account
:return (Model<account.account>): the most appropriate record found
"""
return (
self.env['account.account'].browse(self.env['ir.model.data'].sudo().search([
('name', '=', '%d_%s' % (company.id, xml_id)),
('model', '=', 'account.account'),
('module', '=like', 'l10n%')
], limit=1).res_id)
or self.env['account.account'].search([
*self.env['account.account']._check_company_domain(company),
('account_type', '=', account_type),
], limit=1)
or self.env['account.account'].search([
*self.env['account.account']._check_company_domain(company),
], limit=1)
)

66
demo/account_demo.xml Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="base.user_demo" model="res.users">
<field name="groups_id" eval="[(3, ref('account.group_account_manager'))]"/>
</record>
</data>
<data>
<function model="account.chart.template" name="try_loading">
<value eval="[]"/>
<value>generic_coa</value>
<value model="res.company" search="[('partner_id.country_id.code', 'in', ['US', False])]"/>
</function>
<!-- TAGS FOR RETRIEVING THE DEMO ACCOUNTS -->
<record id="demo_capital_account" model="account.account.tag">
<field name="name">Demo Capital Account</field>
</record>
<record id="demo_stock_account" model="account.account.tag">
<field name="name">Demo Stock Account</field>
</record>
<record id="demo_sale_of_land_account" model="account.account.tag">
<field name="name">Demo Sale of Land Account</field>
</record>
<record id="demo_ceo_wages_account" model="account.account.tag">
<field name="name">Demo CEO Wages Account</field>
</record>
<record id="demo_office_furniture_account" model="account.account.tag">
<field name="name">Office Furniture</field>
</record>
<!-- Payment Terms -->
<record id="account_payment_term_advance" model="account.payment.term">
<field name="name">30% Advance End of Following Month</field>
<field name="note">Payment terms: 30% Advance End of Following Month</field>
<field name="line_ids" eval="[
Command.clear(),
Command.create({'value': 'percent', 'value_amount': 30.0, 'nb_days': 0}),
Command.create({'value': 'percent', 'value_amount': 70.0, 'delay_type': 'days_after_end_of_next_month','nb_days': 0})]"/>
</record>
<!-- Add Payment terms on some demo partners -->
<record id="base.res_partner_2" model="res.partner">
<field name="property_payment_term_id" ref="account.account_payment_term_30days"/>
</record>
<record id="base.res_partner_12" model="res.partner">
<field name="property_payment_term_id" ref="account.account_payment_term_end_following_month"/>
<field name="property_supplier_payment_term_id" ref="account.account_payment_term_end_following_month"/>
</record>
<record id="base.res_partner_4" model="res.partner">
<field name="property_supplier_payment_term_id" ref="account.account_payment_term_30days"/>
</record>
<record id="base.res_partner_1" model="res.partner">
<field name="property_supplier_payment_term_id" ref="account.account_payment_term_end_following_month"/>
</record>
<!-- Analytic -->
<record id="analytic.analytic_plan_internal" model="account.analytic.plan">
<field name="applicability_ids" eval="[
Command.create({
'business_domain': 'invoice',
'account_prefix': '450000',
'applicability': 'mandatory'})]"/>
</record>
</data>
</odoo>

BIN
doc/account_anglo_saxon.ods Normal file

Binary file not shown.

BIN
doc/account_anglo_saxon.pdf Normal file

Binary file not shown.

16786
i18n/account.pot Normal file

File diff suppressed because it is too large Load Diff

15039
i18n/af.po Normal file

File diff suppressed because it is too large Load Diff

15035
i18n/am.po Normal file

File diff suppressed because it is too large Load Diff

17606
i18n/ar.po Normal file

File diff suppressed because it is too large Load Diff

15106
i18n/az.po Normal file

File diff suppressed because it is too large Load Diff

17058
i18n/bg.po Normal file

File diff suppressed because it is too large Load Diff

15043
i18n/bs.po Normal file

File diff suppressed because it is too large Load Diff

17887
i18n/ca.po Normal file

File diff suppressed because it is too large Load Diff

17791
i18n/cs.po Normal file

File diff suppressed because it is too large Load Diff

17500
i18n/da.po Normal file

File diff suppressed because it is too large Load Diff

18014
i18n/de.po Normal file

File diff suppressed because it is too large Load Diff

15073
i18n/el.po Normal file

File diff suppressed because it is too large Load Diff

16077
i18n/en_AU.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/en_GB.po Normal file

File diff suppressed because it is too large Load Diff

17958
i18n/es.po Normal file

File diff suppressed because it is too large Load Diff

17955
i18n/es_419.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_BO.po Normal file

File diff suppressed because it is too large Load Diff

15039
i18n/es_CL.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_CO.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_CR.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_DO.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_EC.po Normal file

File diff suppressed because it is too large Load Diff

15217
i18n/es_MX.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_PE.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_PY.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/es_VE.po Normal file

File diff suppressed because it is too large Load Diff

17294
i18n/et.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/eu.po Normal file

File diff suppressed because it is too large Load Diff

17378
i18n/fa.po Normal file

File diff suppressed because it is too large Load Diff

17827
i18n/fi.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/fo.po Normal file

File diff suppressed because it is too large Load Diff

17996
i18n/fr.po Normal file

File diff suppressed because it is too large Load Diff

15040
i18n/fr_BE.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/fr_CA.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/gl.po Normal file

File diff suppressed because it is too large Load Diff

15211
i18n/gu.po Normal file

File diff suppressed because it is too large Load Diff

17142
i18n/he.po Normal file

File diff suppressed because it is too large Load Diff

15098
i18n/hr.po Normal file

File diff suppressed because it is too large Load Diff

16981
i18n/hu.po Normal file

File diff suppressed because it is too large Load Diff

17861
i18n/id.po Normal file

File diff suppressed because it is too large Load Diff

15059
i18n/is.po Normal file

File diff suppressed because it is too large Load Diff

17960
i18n/it.po Normal file

File diff suppressed because it is too large Load Diff

17145
i18n/ja.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/ka.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/kab.po Normal file

File diff suppressed because it is too large Load Diff

15764
i18n/km.po Normal file

File diff suppressed because it is too large Load Diff

17236
i18n/ko.po Normal file

File diff suppressed because it is too large Load Diff

15039
i18n/lb.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/lo.po Normal file

File diff suppressed because it is too large Load Diff

17084
i18n/lt.po Normal file

File diff suppressed because it is too large Load Diff

17814
i18n/lv.po Normal file

File diff suppressed because it is too large Load Diff

15038
i18n/mk.po Normal file

File diff suppressed because it is too large Load Diff

15127
i18n/mn.po Normal file

File diff suppressed because it is too large Load Diff

15074
i18n/nb.po Normal file

File diff suppressed because it is too large Load Diff

15035
i18n/ne.po Normal file

File diff suppressed because it is too large Load Diff

17926
i18n/nl.po Normal file

File diff suppressed because it is too large Load Diff

17716
i18n/pl.po Normal file

File diff suppressed because it is too large Load Diff

17190
i18n/pt.po Normal file

File diff suppressed because it is too large Load Diff

17926
i18n/pt_BR.po Normal file

File diff suppressed because it is too large Load Diff

15184
i18n/ro.po Normal file

File diff suppressed because it is too large Load Diff

17935
i18n/ru.po Normal file

File diff suppressed because it is too large Load Diff

17264
i18n/sk.po Normal file

File diff suppressed because it is too large Load Diff

16889
i18n/sl.po Normal file

File diff suppressed because it is too large Load Diff

15039
i18n/sq.po Normal file

File diff suppressed because it is too large Load Diff

17801
i18n/sr.po Normal file

File diff suppressed because it is too large Load Diff

15048
i18n/sr@latin.po Normal file

File diff suppressed because it is too large Load Diff

17741
i18n/sv.po Normal file

File diff suppressed because it is too large Load Diff

17644
i18n/th.po Normal file

File diff suppressed because it is too large Load Diff

17725
i18n/tr.po Normal file

File diff suppressed because it is too large Load Diff

17862
i18n/uk.po Normal file

File diff suppressed because it is too large Load Diff

17827
i18n/vi.po Normal file

File diff suppressed because it is too large Load Diff

17127
i18n/zh_CN.po Normal file

File diff suppressed because it is too large Load Diff

17107
i18n/zh_TW.po Normal file

File diff suppressed because it is too large Load Diff

44
models/__init__.py Normal file
View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
from . import sequence_mixin
from . import partner
from . import ir_http
from . import res_partner_bank
from . import account_account_tag
from . import account_account
from . import account_journal
from . import account_tax
from . import account_reconcile_model
from . import account_payment_term
from . import account_move
from . import account_move_line
from . import account_move_line_tax_details
from . import account_partial_reconcile
from . import account_full_reconcile
from . import account_payment
from . import account_payment_method
from . import account_bank_statement
from . import account_bank_statement_line
from . import chart_template
from . import account_analytic_account
from . import account_analytic_distribution_model
from . import account_analytic_plan
from . import account_analytic_line
from . import account_journal_dashboard
from . import product
from . import company
from . import res_config_settings
from . import account_cash_rounding
from . import account_incoterms
from . import decimal_precision
from . import digest
from . import res_users
from . import ir_attachment
from . import ir_actions_report
from . import ir_module
from . import res_currency
from . import account_report
from . import onboarding_onboarding
from . import onboarding_onboarding_step
from . import template_generic_coa
from . import uom_uom

1036
models/account_account.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
from odoo import osv
class AccountAccountTag(models.Model):
_name = 'account.account.tag'
_description = 'Account Tag'
name = fields.Char('Tag Name', required=True, translate=True)
applicability = fields.Selection([('accounts', 'Accounts'), ('taxes', 'Taxes'), ('products', 'Products')], required=True, default='accounts')
color = fields.Integer('Color Index')
active = fields.Boolean(default=True, help="Set active to false to hide the Account Tag without removing it.")
tax_negate = fields.Boolean(string="Negate Tax Balance", help="Check this box to negate the absolute value of the balance of the lines associated with this tag in tax report computation.")
country_id = fields.Many2one(string="Country", comodel_name='res.country', help="Country for which this tag is available, when applied on taxes.")
_sql_constraints = [('name_uniq', "unique(name, applicability, country_id)", "A tag with the same name and applicability already exists in this country.")]
@api.depends('applicability', 'country_id')
@api.depends_context('company')
def _compute_display_name(self):
if not self.env.company.multi_vat_foreign_country_ids:
return super()._compute_display_name()
for tag in self:
name = tag.name
if tag.applicability == "taxes" and tag.country_id and tag.country_id != self.env.company.account_fiscal_country_id:
name = _("%s (%s)", tag.name, tag.country_id.code)
tag.display_name = name
@api.model
def _get_tax_tags(self, tag_name, country_id):
""" Returns all the tax tags corresponding to the tag name given in parameter
in the specified country.
"""
domain = self._get_tax_tags_domain(tag_name, country_id)
return self.env['account.account.tag'].with_context(active_test=False).search(domain)
@api.model
def _get_tax_tags_domain(self, tag_name, country_id, sign=None):
""" Returns a domain to search for all the tax tags corresponding to the tag name given in parameter
in the specified country.
"""
escaped_tag_name = tag_name.replace('\\', '\\\\').replace('%', '\%').replace('_', '\_')
return [
('name', '=like', (sign or '_') + escaped_tag_name),
('country_id', '=', country_id),
('applicability', '=', 'taxes')
]
def _get_related_tax_report_expressions(self):
if not self:
return self.env['account.report.expression']
or_domains = []
for record in self:
expr_domain = [
'&',
('report_line_id.report_id.country_id', '=', record.country_id.id),
('formula', '=', record.name[1:]),
]
or_domains.append(expr_domain)
domain = osv.expression.AND([[('engine', '=', 'tax_tags')], osv.expression.OR(or_domains)])
return self.env['account.report.expression'].search(domain)

View File

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
from odoo import api, fields, models, _
class AccountAnalyticAccount(models.Model):
_inherit = 'account.analytic.account'
invoice_count = fields.Integer(
"Invoice Count",
compute='_compute_invoice_count',
)
vendor_bill_count = fields.Integer(
"Vendor Bill Count",
compute='_compute_vendor_bill_count',
)
@api.depends('line_ids')
def _compute_invoice_count(self):
sale_types = self.env['account.move'].get_sale_types(include_receipts=True)
query = self.env['account.move.line']._search([
('parent_state', '=', 'posted'),
('move_id.move_type', 'in', sale_types),
])
query.add_where(
'account_move_line.analytic_distribution ?| %s',
[[str(account_id) for account_id in self.ids]],
)
query_string, query_param = query.select(
'jsonb_object_keys(account_move_line.analytic_distribution) as account_id',
'COUNT(DISTINCT(account_move_line.move_id)) as move_count',
)
query_string = f"{query_string} GROUP BY jsonb_object_keys(account_move_line.analytic_distribution)"
self._cr.execute(query_string, query_param)
data = {int(record.get('account_id')): record.get('move_count') for record in self._cr.dictfetchall()}
for account in self:
account.invoice_count = data.get(account.id, 0)
@api.depends('line_ids')
def _compute_vendor_bill_count(self):
purchase_types = self.env['account.move'].get_purchase_types(include_receipts=True)
query = self.env['account.move.line']._search([
('parent_state', '=', 'posted'),
('move_id.move_type', 'in', purchase_types),
])
query.add_where(
'account_move_line.analytic_distribution ?| %s',
[[str(account_id) for account_id in self.ids]],
)
query_string, query_param = query.select(
'jsonb_object_keys(account_move_line.analytic_distribution) as account_id',
'COUNT(DISTINCT(account_move_line.move_id)) as move_count',
)
query_string = f"{query_string} GROUP BY jsonb_object_keys(account_move_line.analytic_distribution)"
self._cr.execute(query_string, query_param)
data = {int(record.get('account_id')): record.get('move_count') for record in self._cr.dictfetchall()}
for account in self:
account.vendor_bill_count = data.get(account.id, 0)
def action_view_invoice(self):
self.ensure_one()
query = self.env['account.move.line']._search([('move_id.move_type', 'in', self.env['account.move'].get_sale_types())])
query.add_where('analytic_distribution ? %s', [str(self.id)])
query_string, query_param = query.select('DISTINCT account_move_line.move_id')
self._cr.execute(query_string, query_param)
move_ids = [line.get('move_id') for line in self._cr.dictfetchall()]
result = {
"type": "ir.actions.act_window",
"res_model": "account.move",
"domain": [('id', 'in', move_ids)],
"context": {"create": False, 'default_move_type': 'out_invoice'},
"name": _("Customer Invoices"),
'view_mode': 'tree,form',
}
return result
def action_view_vendor_bill(self):
self.ensure_one()
query = self.env['account.move.line']._search([('move_id.move_type', 'in', self.env['account.move'].get_purchase_types())])
query.add_where('analytic_distribution ? %s', [str(self.id)])
query_string, query_param = query.select('DISTINCT account_move_line.move_id')
self._cr.execute(query_string, query_param)
move_ids = [line.get('move_id') for line in self._cr.dictfetchall()]
result = {
"type": "ir.actions.act_window",
"res_model": "account.move",
"domain": [('id', 'in', move_ids)],
"context": {"create": False, 'default_move_type': 'in_invoice'},
"name": _("Vendor Bills"),
'view_mode': 'tree,form',
}
return result

View File

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from odoo import fields, models
class AccountAnalyticDistributionModel(models.Model):
_inherit = 'account.analytic.distribution.model'
account_prefix = fields.Char(
string='Accounts Prefix',
help="This analytic distribution will apply to all financial accounts sharing the prefix specified.",
)
product_id = fields.Many2one(
'product.product',
string='Product',
ondelete='cascade',
check_company=True,
help="Select a product for which the analytic distribution will be used (e.g. create new customer invoice or Sales order if we select this product, it will automatically take this as an analytic account)",
)
product_categ_id = fields.Many2one(
'product.category',
string='Product Category',
ondelete='cascade',
help="Select a product category which will use analytic account specified in analytic default (e.g. create new customer invoice or Sales order if we select this product, it will automatically take this as an analytic account)",
)
def _create_domain(self, fname, value):
if not fname == 'account_prefix':
return super()._create_domain(fname, value)

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