diff --git a/addons/account/models/account.py b/addons/account/models/account.py index baa0aed666e..cde55f97bf4 100644 --- a/addons/account/models/account.py +++ b/addons/account/models/account.py @@ -412,7 +412,7 @@ class AccountJournal(models.Model): belongs_to_company = fields.Boolean('Belong to the user\'s current company', compute="_belong_to_company", search="_search_company_journals",) # Bank journals fields - bank_account_id = fields.Many2one('res.partner.bank', string="Bank Account", ondelete='restrict', copy=False, domain="[('partner_id','=', company_id)]") + bank_account_id = fields.Many2one('res.partner.bank', string="Bank Account", ondelete='restrict', copy=False) bank_statements_source = fields.Selection([('undefined', 'Undefined Yet'),('manual', 'Record Manually')], string='Bank Feeds', default='undefined') bank_acc_number = fields.Char(related='bank_account_id.acc_number') bank_id = fields.Many2one('res.bank', related='bank_account_id.bank_id') @@ -522,11 +522,16 @@ class AccountJournal(models.Model): @api.multi def write(self, vals): for journal in self: + company = journal.company_id if ('company_id' in vals and journal.company_id.id != vals['company_id']): if self.env['account.move'].search([('journal_id', 'in', self.ids)], limit=1): raise UserError(_('This journal already contains items, therefore you cannot modify its company.')) - if self.bank_account_id: - self.bank_account_id.company_id = vals['company_id'] + company = self.env['res.company'].browse(vals['company_id']) + if self.bank_account_id.company_id and self.bank_account_id.company_id != company: + self.bank_account_id.write({ + 'company_id': company.id, + 'partner_id': company.partner_id.id, + }) if ('code' in vals and journal.code != vals['code']): if self.env['account.move'].search([('journal_id', 'in', self.ids)], limit=1): raise UserError(_('This journal already contains items, therefore you cannot modify its short name.')) @@ -542,8 +547,14 @@ class AccountJournal(models.Model): self.default_credit_account_id.currency_id = vals['currency_id'] if self.bank_account_id: self.bank_account_id.currency_id = vals['currency_id'] - if 'bank_account_id' in vals and not vals.get('bank_account_id'): - raise UserError(_('You cannot remove the bank account from the journal once set.')) + if 'bank_account_id' in vals: + if not vals.get('bank_account_id'): + raise UserError(_('You cannot remove the bank account from the journal once set.')) + else: + bank_account = self.env['res.partner.bank'].browse(vals['bank_account_id']) + if bank_account.partner_id != company.partner_id: + raise UserError(_("The partners of the journal's company and the related bank account mismatch.")) + result = super(AccountJournal, self).write(vals) # Create the bank_account_id if necessary diff --git a/addons/account/models/account_invoice.py b/addons/account/models/account_invoice.py index e05b02ae058..bca650dcc65 100644 --- a/addons/account/models/account_invoice.py +++ b/addons/account/models/account_invoice.py @@ -224,7 +224,7 @@ class AccountInvoice(models.Model): @api.depends('move_id.line_ids.amount_residual') def _compute_payments(self): payment_lines = set() - for line in self.move_id.line_ids: + for line in self.move_id.line_ids.filtered(lambda l: l.account_id.id == self.account_id.id): payment_lines.update(line.mapped('matched_credit_ids.credit_move_id.id')) payment_lines.update(line.mapped('matched_debit_ids.debit_move_id.id')) self.payment_move_line_ids = self.env['account.move.line'].browse(list(payment_lines)) @@ -267,7 +267,6 @@ class AccountInvoice(models.Model): ], string='Status', index=True, readonly=True, default='draft', track_visibility='onchange', copy=False, help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Invoice.\n" - " * The 'Pro-forma' status is used when the invoice does not have an invoice number.\n" " * The 'Open' status is used when user creates invoice, an invoice number is generated. It stays in the open status till the user pays the invoice.\n" " * The 'Paid' status is set automatically when the invoice is paid. Its related journal entries may or may not be reconciled.\n" " * The 'Cancelled' status is used when user cancel invoice.") diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index df18aa8fca9..5f9a2cf26ba 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -472,7 +472,7 @@ class AccountMoveLine(models.Model): tax_line_id = fields.Many2one('account.tax', string='Originator tax', ondelete='restrict') analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account') analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags') - company_id = fields.Many2one('res.company', related='account_id.company_id', string='Company', store=True) + company_id = fields.Many2one('res.company', related='account_id.company_id', string='Company', store=True, readonly=True) counterpart = fields.Char("Counterpart", compute='_get_counterpart', help="Compute the counter part accounts of this journal item for this journal entry. This can be needed in reports.") # TODO: put the invoice link and partner_id on the account_move @@ -525,7 +525,7 @@ class AccountMoveLine(models.Model): raise ValidationError(_("You cannot create journal items with a secondary currency without filling both 'currency' and 'amount currency' field.")) @api.multi - @api.constrains('amount_currency') + @api.constrains('amount_currency', 'debit', 'credit') def _check_currency_amount(self): for line in self: if line.amount_currency: @@ -936,7 +936,9 @@ class AccountMoveLine(models.Model): def _get_pair_to_reconcile(self): #field is either 'amount_residual' or 'amount_residual_currency' (if the reconciled account has a secondary currency set) - field = self[0].account_id.currency_id and 'amount_residual_currency' or 'amount_residual' + company_currency_id = self[0].account_id.company_id.currency_id + account_curreny_id = self[0].account_id.currency_id + field = (account_curreny_id and company_currency_id != account_curreny_id) and 'amount_residual_currency' or 'amount_residual' #reconciliation on bank accounts are special cases as we don't want to set them as reconcilable #but we still want to reconcile entries that are reversed together in order to clear those lines #in the bank reconciliation report. @@ -974,8 +976,9 @@ class AccountMoveLine(models.Model): #there is no more pair to reconcile so return what move_line are left if not sm_credit_move or not sm_debit_move: return self - - field = self[0].account_id.currency_id and 'amount_residual_currency' or 'amount_residual' + company_currency_id = self[0].account_id.company_id.currency_id + account_curreny_id = self[0].account_id.currency_id + field = (account_curreny_id and company_currency_id != account_curreny_id) and 'amount_residual_currency' or 'amount_residual' if not sm_debit_move.debit and not sm_debit_move.credit: #both debit and credit field are 0, consider the amount_residual_currency field because it's an exchange difference entry field = 'amount_residual_currency' diff --git a/addons/account/models/chart_template.py b/addons/account/models/chart_template.py index 93f17153fa8..d035fe594dc 100644 --- a/addons/account/models/chart_template.py +++ b/addons/account/models/chart_template.py @@ -738,6 +738,9 @@ class WizardMultiChartsAccounts(models.TransientModel): res.setdefault('domain', {}) res['domain']['sale_tax_id'] = repr(sale_tax_domain) res['domain']['purchase_tax_id'] = repr(purchase_tax_domain) + else: + self.sale_tax_id = False + self.purchase_tax_id = False if self.chart_template_id.transfer_account_id: self.transfer_account_id = self.chart_template_id.transfer_account_id.id if self.chart_template_id.code_digits: diff --git a/addons/account/models/res_config_settings.py b/addons/account/models/res_config_settings.py index 68d8ef3e83b..d4593130d2c 100644 --- a/addons/account/models/res_config_settings.py +++ b/addons/account/models/res_config_settings.py @@ -36,12 +36,12 @@ class ResConfigSettings(models.TransientModel): module_account_budget = fields.Boolean(string='Budget Management') module_account_payment = fields.Boolean(string='Online Payment') module_account_reports = fields.Boolean("Dynamic Reports") - module_account_reports_followup = fields.Boolean("Enable payment followup management") + module_account_reports_followup = fields.Boolean("Follow-up Levels") module_account_check_printing = fields.Boolean("Allow check printing and deposits") module_account_batch_deposit = fields.Boolean(string='Use batch deposit', help='This allows you to group received checks before you deposit them to the bank.\n' '-This installs the module account_batch_deposit.') - module_account_sepa = fields.Boolean(string='Use SEPA payments') + module_account_sepa = fields.Boolean(string='SEPA Credit Transfer (SCT)') module_account_sepa_direct_debit = fields.Boolean(string='Use SEPA Direct Debit') module_account_plaid = fields.Boolean(string="Plaid Connector") module_account_yodlee = fields.Boolean("Bank Interface - Sync your bank feeds automatically") @@ -49,7 +49,7 @@ class ResConfigSettings(models.TransientModel): module_account_bank_statement_import_ofx = fields.Boolean("Import in .ofx format") module_account_bank_statement_import_csv = fields.Boolean("Import in .csv format") module_account_bank_statement_import_camt = fields.Boolean("Import in CAMT.053 format") - module_currency_rate_live = fields.Boolean(string="Allow Currency Rate Live") + module_currency_rate_live = fields.Boolean(string="Automatic Currency Rates") module_print_docsaway = fields.Boolean(string="Docsaway") module_product_margin = fields.Boolean(string="Allow Product Margin") module_l10n_eu_service = fields.Boolean(string="EU Digital Goods VAT") diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py index d280b6cb850..4de3fedbbd4 100644 --- a/addons/account/report/account_aged_partner_balance.py +++ b/addons/account/report/account_aged_partner_balance.py @@ -13,6 +13,10 @@ class ReportAgedPartnerBalance(models.AbstractModel): _name = 'report.account.report_agedpartnerbalance' def _get_partner_move_lines(self, account_type, date_from, target_move, period_length): + # This method can receive the context key 'include_nullified_amount' {Boolean} + # Do an invoice and a payment and unreconcile. The amount will be nullified + # By default, the partner wouldn't appear in this report. + # The context key allow it to appear periods = {} start = datetime.strptime(date_from, "%Y-%m-%d") for i in range(5)[::-1]: @@ -190,7 +194,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): values['name'] = _('Unknown Partner') values['trust'] = False - if at_least_one_amount: + if at_least_one_amount or self._context.get('include_nullified_amount'): res.append(values) return res, total, lines diff --git a/addons/account/report/account_overdue_report.py b/addons/account/report/account_overdue_report.py index dbfd933c99a..a41803f7062 100644 --- a/addons/account/report/account_overdue_report.py +++ b/addons/account/report/account_overdue_report.py @@ -25,7 +25,7 @@ class ReportOverdue(models.AbstractModel): "FROM account_move_line l " "JOIN account_account_type at ON (l.user_type_id = at.id) " "JOIN account_move m ON (l.move_id = m.id) " - "WHERE l.partner_id IN %s AND at.type IN ('receivable', 'payable') AND NOT l.reconciled GROUP BY l.date, l.name, l.ref, l.date_maturity, l.partner_id, at.type, l.blocked, l.amount_currency, l.currency_id, l.move_id, m.name", (((fields.date.today(), ) + (tuple(partner_ids),)))) + "WHERE l.partner_id IN %s AND at.type IN ('receivable', 'payable') AND l.full_reconcile_id IS NULL GROUP BY l.date, l.name, l.ref, l.date_maturity, l.partner_id, at.type, l.blocked, l.amount_currency, l.currency_id, l.move_id, m.name", (((fields.date.today(), ) + (tuple(partner_ids),)))) for row in self.env.cr.dictfetchall(): res[row.pop('partner_id')].append(row) return res diff --git a/addons/account/report/account_partner_ledger.py b/addons/account/report/account_partner_ledger.py index 2da6c42abe7..852b2a14e00 100644 --- a/addons/account/report/account_partner_ledger.py +++ b/addons/account/report/account_partner_ledger.py @@ -14,7 +14,7 @@ class ReportPartnerLedger(models.AbstractModel): full_account = [] currency = self.env['res.currency'] query_get_data = self.env['account.move.line'].with_context(data['form'].get('used_context', {}))._query_get() - reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".reconciled = false ' + reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL ' params = [partner.id, tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2] query = """ SELECT "account_move_line".id, "account_move_line".date, j.code, acc.code as a_code, acc.name as a_name, "account_move_line".ref, m.name as move_name, "account_move_line".name, "account_move_line".debit, "account_move_line".credit, "account_move_line".amount_currency,"account_move_line".currency_id, c.symbol AS currency_code @@ -51,7 +51,7 @@ class ReportPartnerLedger(models.AbstractModel): return result = 0.0 query_get_data = self.env['account.move.line'].with_context(data['form'].get('used_context', {}))._query_get() - reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".reconciled = false ' + reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL ' params = [partner.id, tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2] query = """SELECT sum(""" + field + """) @@ -95,7 +95,7 @@ class ReportPartnerLedger(models.AbstractModel): AND NOT a.deprecated""", (tuple(data['computed']['ACCOUNT_TYPE']),)) data['computed']['account_ids'] = [a for (a,) in self.env.cr.fetchall()] params = [tuple(data['computed']['move_state']), tuple(data['computed']['account_ids'])] + query_get_data[2] - reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".reconciled = false ' + reconcile_clause = "" if data['form']['reconciled'] else ' AND "account_move_line".full_reconcile_id IS NULL ' query = """ SELECT DISTINCT "account_move_line".partner_id FROM """ + query_get_data[0] + """, account_account AS account, account_move AS am diff --git a/addons/account/views/account_invoice_view.xml b/addons/account/views/account_invoice_view.xml index 50124617526..6fdc285a97b 100644 --- a/addons/account/views/account_invoice_view.xml +++ b/addons/account/views/account_invoice_view.xml @@ -252,7 +252,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -397,7 +397,7 @@ - +