[IMP] account, base_import: improve accounting import
- Remove FEC from res.config.settings - everything is now linked in the import guide (in enterprise) - Compute debit and credit from opening_balance - Update import templates for account.account, account.move, res.partner - Small UI changes in base_import: add an action title and improve the template button design task-2888243 closes odoo/odoo#96291 Related: odoo/enterprise#29627 Related: odoo/upgrade#3794 Signed-off-by: Cedric Snauwaert <csn@odoo.com>
This commit is contained in:
@@ -82,7 +82,8 @@ class AccountAccount(models.Model):
|
||||
)
|
||||
#has_unreconciled_entries = fields.Boolean(compute='_compute_has_unreconciled_entries',
|
||||
# help="The account has at least one unreconciled debit and credit since last time the invoices & payments matching was performed.")
|
||||
reconcile = fields.Boolean(string='Allow Reconciliation', default=False, tracking=True,
|
||||
reconcile = fields.Boolean(string='Allow Reconciliation', tracking=True,
|
||||
compute='_compute_reconcile', store=True, readonly=False,
|
||||
help="Check this box if this account allows invoices & payments matching of journal items.")
|
||||
tax_ids = fields.Many2many('account.tax', 'account_account_tax_default_rel',
|
||||
'account_id', 'tax_id', string='Default Taxes',
|
||||
@@ -96,10 +97,9 @@ class AccountAccount(models.Model):
|
||||
help="Account prefixes can determine account groups.")
|
||||
root_id = fields.Many2one('account.root', compute='_compute_account_root', store=True)
|
||||
allowed_journal_ids = fields.Many2many('account.journal', string="Allowed Journals", help="Define in which journals this account can be used. If empty, can be used in all journals.")
|
||||
|
||||
opening_debit = fields.Monetary(string="Opening Debit", compute='_compute_opening_debit_credit', inverse='_set_opening_debit')
|
||||
opening_credit = fields.Monetary(string="Opening Credit", compute='_compute_opening_debit_credit', inverse='_set_opening_credit')
|
||||
opening_balance = fields.Monetary(string="Opening Balance", compute='_compute_opening_debit_credit')
|
||||
opening_balance = fields.Monetary(string="Opening Balance", compute='_compute_opening_debit_credit', inverse='_set_opening_balance')
|
||||
|
||||
is_off_balance = fields.Boolean(compute='_compute_is_off_balance', default=False, store=True, readonly=True)
|
||||
|
||||
@@ -409,6 +409,11 @@ class AccountAccount(models.Model):
|
||||
if account.account_type:
|
||||
account.internal_group = 'off_balance' if account.account_type == 'off_balance' else account.account_type.split('_')[0]
|
||||
|
||||
@api.depends('account_type')
|
||||
def _compute_reconcile(self):
|
||||
for account in self:
|
||||
account.reconcile = account.account_type in ('asset_receivable', 'liability_payable')
|
||||
|
||||
def _set_opening_debit(self):
|
||||
for record in self:
|
||||
record._set_opening_debit_credit(record.opening_debit, 'debit')
|
||||
@@ -417,6 +422,12 @@ class AccountAccount(models.Model):
|
||||
for record in self:
|
||||
record._set_opening_debit_credit(record.opening_credit, 'credit')
|
||||
|
||||
def _set_opening_balance(self):
|
||||
for account in self:
|
||||
if account.opening_balance:
|
||||
side = 'debit' if account.opening_balance > 0 else 'credit'
|
||||
account._set_opening_debit_credit(abs(account.opening_balance), side)
|
||||
|
||||
def _set_opening_debit_credit(self, amount, field):
|
||||
""" Generic function called by both opening_debit and opening_credit's
|
||||
inverse function. 'Amount' parameter is the value to be set, and field
|
||||
@@ -529,11 +540,7 @@ class AccountAccount(models.Model):
|
||||
|
||||
@api.onchange('account_type')
|
||||
def _onchange_account_type(self):
|
||||
self.reconcile = self.account_type in ('asset_receivable', 'liability_payable')
|
||||
if self.account_type in ('asset_cash', 'liability_credit_card'):
|
||||
self.reconcile = False
|
||||
elif self.internal_group == 'off_balance':
|
||||
self.reconcile = False
|
||||
if self.internal_group == 'off_balance':
|
||||
self.tax_ids = False
|
||||
elif self.internal_group == 'income' and not self.tax_ids:
|
||||
self.tax_ids = self.company_id.account_sale_tax_id
|
||||
@@ -588,6 +595,9 @@ class AccountAccount(models.Model):
|
||||
companies = self.search([('id', 'in', rslt['ids'])]).mapped('company_id')
|
||||
for company in companies:
|
||||
company._auto_balance_opening_move()
|
||||
# the current_balance of the account only includes posted moves and
|
||||
# would always amount to 0 after the import if we didn't post the opening move
|
||||
company.account_opening_move_id.action_post()
|
||||
return rslt
|
||||
|
||||
def _toggle_reconcile_to_true(self):
|
||||
@@ -719,6 +729,13 @@ class AccountAccount(models.Model):
|
||||
'domain': [('id', 'in', related_taxes_ids)],
|
||||
}
|
||||
|
||||
@api.model
|
||||
def get_import_templates(self):
|
||||
return [{
|
||||
'label': _('Import Template for Chart of Accounts'),
|
||||
'template': '/account/static/xls/coa_import_template.xlsx'
|
||||
}]
|
||||
|
||||
|
||||
class AccountGroup(models.Model):
|
||||
_name = "account.group"
|
||||
|
||||
@@ -587,6 +587,10 @@ class AccountJournal(models.Model):
|
||||
@api.model
|
||||
def _fill_missing_values(self, vals):
|
||||
journal_type = vals.get('type')
|
||||
if 'import_file' in self.env.context and not journal_type:
|
||||
vals['type'] = 'general'
|
||||
if not vals.get('code'):
|
||||
vals['code'] = vals.get('name')
|
||||
|
||||
# 'type' field is required.
|
||||
if not journal_type:
|
||||
|
||||
@@ -2442,6 +2442,13 @@ class AccountMoveLine(models.Model):
|
||||
'reconciliation': reconciliation_fnames,
|
||||
}
|
||||
|
||||
@api.model
|
||||
def get_import_templates(self):
|
||||
return [{
|
||||
'label': _('Import Template for Journal Items'),
|
||||
'template': '/account/static/xls/aml_import_template.xlsx'
|
||||
}]
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# PUBLIC ACTIONS
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -104,8 +104,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
'-This installs the account_batch_payment module.')
|
||||
module_account_sepa = fields.Boolean(string='SEPA Credit Transfer (SCT)')
|
||||
module_account_sepa_direct_debit = fields.Boolean(string='Use SEPA Direct Debit')
|
||||
module_l10n_fr_fec_import = fields.Boolean("Import FEC files",
|
||||
help='Allows you to import FEC files.\n' '-This installs the l10n_fr_fec_import module.')
|
||||
module_account_bank_statement_import_qif = fields.Boolean("Import .qif files")
|
||||
module_account_bank_statement_import_ofx = fields.Boolean("Import in .ofx format")
|
||||
module_account_bank_statement_import_csv = fields.Boolean("Import in .csv format")
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -95,9 +95,9 @@
|
||||
<t t-set="close_model" t-value="'res.company'"/>
|
||||
|
||||
<t t-call="account.onboarding_fiscal_year_step" name="fiscal_year_step" />
|
||||
<t t-call="account.onboarding_chart_of_account_step" name="chart_of_account_step" />
|
||||
<t t-call="account.onboarding_taxes_step" name="taxes_step" />
|
||||
<t t-call="account.onboarding_bank_account_step" name="bank_account_step" />
|
||||
<t t-call="account.onboarding_taxes_step" name="taxes_step" />
|
||||
<t t-call="account.onboarding_chart_of_account_step" name="chart_of_account_step" />
|
||||
</t>
|
||||
</template>
|
||||
<!-- SAMPLE INVOICE EMAIL -->
|
||||
|
||||
@@ -595,25 +595,6 @@
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t groups="account.group_account_user">
|
||||
<h2>Accounting Import</h2>
|
||||
<div class="row mt16 o_settings_container" id="accounting_import">
|
||||
<div class="col-12 col-lg-6 o_setting_box"
|
||||
id="l10n_fr_fec_import"
|
||||
title="This adds a menu item in the Accounting Configuration menu to import FEC files.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_l10n_fr_fec_import" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="module_l10n_fr_fec_import" string="FEC Import"/>
|
||||
<div class="text-muted">
|
||||
Import your accounting data from FEC
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t groups="account.group_account_user">
|
||||
<h2>Fiscal Periods</h2>
|
||||
<div class="row mt16 o_settings_container" id="accounting_reports">
|
||||
|
||||
@@ -135,7 +135,7 @@ var DataImport = AbstractAction.extend({
|
||||
// import object id
|
||||
this.id = null;
|
||||
this.session = session;
|
||||
this._title = _t('Import a File'); // Displayed in the breadcrumbs
|
||||
this._title = action.name || _t('Import a File'); // Displayed in the breadcrumbs
|
||||
this.do_not_change_match = false;
|
||||
this.sheets = [];
|
||||
this.selectionFields = {}; // Used to compute fallback values in backend.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</p>
|
||||
<div class="mt16 mb4">Need Help?</div>
|
||||
<div t-foreach="widget.importTemplates" t-as="template">
|
||||
<a t-att-href="template.template" aria-label="Download" title="Download">
|
||||
<a class="btn btn-outline-primary mb32 mt8" t-att-href="template.template" aria-label="Download" title="Download">
|
||||
<i class="fa fa-download"/> <span><t t-esc="template.label"/></span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -1006,7 +1006,7 @@ class Partner(models.Model):
|
||||
def get_import_templates(self):
|
||||
return [{
|
||||
'label': _('Import Template for Customers'),
|
||||
'template': '/base/static/xls/res_partner.xls'
|
||||
'template': '/base/static/xls/res_partner.xlsx'
|
||||
}]
|
||||
|
||||
@api.model
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user