mirror of
https://gitlab.com/flectra-hq/flectra.git
synced 2025-02-25 18:55:21 -06:00
[PATCH] Upstream patch - 21092021
This commit is contained in:
@@ -407,6 +407,8 @@ class AccountMove(models.Model):
|
||||
if accounting_date != self.date:
|
||||
self.date = accounting_date
|
||||
self._onchange_currency()
|
||||
else:
|
||||
self._onchange_recompute_dynamic_lines()
|
||||
|
||||
@api.onchange('journal_id')
|
||||
def _onchange_journal(self):
|
||||
@@ -1935,13 +1937,14 @@ class AccountMove(models.Model):
|
||||
default['date'] = self.company_id._get_user_fiscal_lock_date() + timedelta(days=1)
|
||||
if self.move_type == 'entry':
|
||||
default['partner_id'] = False
|
||||
invoice = super().copy(default)
|
||||
move = super().copy(default)
|
||||
|
||||
# Make sure to recompute payment terms. This could be necessary if the date is different for example.
|
||||
# Also, this is necessary when creating a credit note because the current invoice is copied.
|
||||
invoice._recompute_payment_terms_lines()
|
||||
if move.is_invoice(include_receipts=True):
|
||||
# Make sure to recompute payment terms. This could be necessary if the date is different for example.
|
||||
# Also, this is necessary when creating a credit note because the current invoice is copied.
|
||||
move._recompute_payment_terms_lines()
|
||||
|
||||
return invoice
|
||||
return move
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
|
||||
@@ -718,7 +718,7 @@ class AccountPayment(models.Model):
|
||||
|
||||
if not any(field_name in changed_fields for field_name in (
|
||||
'date', 'amount', 'payment_type', 'partner_type', 'payment_reference', 'is_internal_transfer',
|
||||
'currency_id', 'partner_id', 'destination_account_id', 'partner_bank_id',
|
||||
'currency_id', 'partner_id', 'destination_account_id', 'partner_bank_id', 'journal_id',
|
||||
)):
|
||||
return
|
||||
|
||||
@@ -728,7 +728,8 @@ class AccountPayment(models.Model):
|
||||
# Make sure to preserve the write-off amount.
|
||||
# This allows to create a new payment with custom 'line_ids'.
|
||||
|
||||
if writeoff_lines:
|
||||
if liquidity_lines and counterpart_lines and writeoff_lines:
|
||||
|
||||
counterpart_amount = sum(counterpart_lines.mapped('amount_currency'))
|
||||
writeoff_amount = sum(writeoff_lines.mapped('amount_currency'))
|
||||
|
||||
@@ -751,10 +752,15 @@ class AccountPayment(models.Model):
|
||||
|
||||
line_vals_list = pay._prepare_move_line_default_vals(write_off_line_vals=write_off_line_vals)
|
||||
|
||||
line_ids_commands = [
|
||||
(1, liquidity_lines.id, line_vals_list[0]),
|
||||
(1, counterpart_lines.id, line_vals_list[1]),
|
||||
]
|
||||
line_ids_commands = []
|
||||
if liquidity_lines:
|
||||
line_ids_commands.append((1, liquidity_lines.id, line_vals_list[0]))
|
||||
else:
|
||||
line_ids_commands.append((0, 0, line_vals_list[0]))
|
||||
if counterpart_lines:
|
||||
line_ids_commands.append((1, counterpart_lines.id, line_vals_list[1]))
|
||||
else:
|
||||
line_ids_commands.append((0, 0, line_vals_list[1]))
|
||||
|
||||
for line in writeoff_lines:
|
||||
line_ids_commands.append((2, line.id))
|
||||
|
||||
@@ -44,4 +44,4 @@ class IrActionsReport(models.Model):
|
||||
if any(not move.is_invoice(include_receipts=True) for move in moves):
|
||||
raise UserError(_("Only invoices could be printed."))
|
||||
|
||||
return super().render_qweb_pdf(res_ids=res_ids, data=None)
|
||||
return super().render_qweb_pdf(res_ids=res_ids, data=data)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from freezegun import freeze_time
|
||||
|
||||
from flectra.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from flectra.tests.common import Form
|
||||
from flectra.tests import tagged
|
||||
@@ -149,6 +151,22 @@ class TestAccountMoveInInvoiceOnchanges(AccountTestInvoicingCommon):
|
||||
move_form.invoice_date = invoice_date
|
||||
self.assertEqual(self.invoice.date, fields.Date.to_date(accounting_date))
|
||||
|
||||
@freeze_time('2021-09-16')
|
||||
def test_in_invoice_onchange_invoice_date_2(self):
|
||||
invoice_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice', account_predictive_bills_disable_prediction=True))
|
||||
invoice_form.partner_id = self.partner_a
|
||||
invoice_form.invoice_payment_term_id = self.env.ref('account.account_payment_term_30days')
|
||||
with invoice_form.invoice_line_ids.new() as line_form:
|
||||
line_form.product_id = self.product_a
|
||||
invoice_form.invoice_date = fields.Date.from_string('2021-09-01')
|
||||
invoice = invoice_form.save()
|
||||
|
||||
self.assertRecordValues(invoice, [{
|
||||
'date': fields.Date.from_string('2021-09-16'),
|
||||
'invoice_date': fields.Date.from_string('2021-09-01'),
|
||||
'invoice_date_due': fields.Date.from_string('2021-10-01'),
|
||||
}])
|
||||
|
||||
def test_in_invoice_line_onchange_product_1(self):
|
||||
move_form = Form(self.invoice)
|
||||
with move_form.invoice_line_ids.edit(0) as line_form:
|
||||
|
||||
@@ -726,3 +726,41 @@ class TestAccountPayment(AccountTestInvoicingCommon):
|
||||
self.assertEqual(payment.name, '/')
|
||||
payment.action_post()
|
||||
self.assertRegex(payment.name, 'BNK1/\d{4}/\d{2}/0002')
|
||||
|
||||
def test_payment_form_onchange_journal(self):
|
||||
pay_form = Form(self.env['account.payment'])
|
||||
pay_form.journal_id = self.company_data['default_journal_bank']
|
||||
pay_form.partner_id = self.partner_a
|
||||
pay_form.name = '/'
|
||||
pay_form.amount = 123
|
||||
pay = pay_form.save()
|
||||
|
||||
self.assertRecordValues(pay.line_ids.sorted('balance'), [
|
||||
{
|
||||
'debit': 0.0,
|
||||
'credit': 123.0,
|
||||
'account_id': self.company_data['default_account_receivable'].id,
|
||||
},
|
||||
{
|
||||
'debit': 123.0,
|
||||
'credit': 0.0,
|
||||
'account_id': self.company_data['default_journal_bank'].payment_debit_account_id.id,
|
||||
},
|
||||
])
|
||||
|
||||
with Form(pay) as pay_form:
|
||||
pay_form.journal_id = self.company_data['default_journal_cash']
|
||||
pay_form.name = '/'
|
||||
|
||||
self.assertRecordValues(pay.line_ids.sorted('balance'), [
|
||||
{
|
||||
'debit': 0.0,
|
||||
'credit': 123.0,
|
||||
'account_id': self.company_data['default_account_receivable'].id,
|
||||
},
|
||||
{
|
||||
'debit': 123.0,
|
||||
'credit': 0.0,
|
||||
'account_id': self.company_data['default_journal_cash'].payment_debit_account_id.id,
|
||||
},
|
||||
])
|
||||
|
||||
@@ -426,41 +426,29 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
'destination_account_id': batch_result['lines'][0].account_id.id
|
||||
}
|
||||
|
||||
def _create_payments(self):
|
||||
self.ensure_one()
|
||||
batches = self._get_batches()
|
||||
edit_mode = self.can_edit_wizard and (len(batches[0]['lines']) == 1 or self.group_payment)
|
||||
def _init_payments(self, to_process, edit_mode=False):
|
||||
""" Create the payments.
|
||||
|
||||
to_reconcile = []
|
||||
if edit_mode:
|
||||
payment_vals = self._create_payment_vals_from_wizard()
|
||||
payment_vals_list = [payment_vals]
|
||||
to_reconcile.append(batches[0]['lines'])
|
||||
else:
|
||||
# Don't group payments: Create one batch per move.
|
||||
if not self.group_payment:
|
||||
new_batches = []
|
||||
for batch_result in batches:
|
||||
for line in batch_result['lines']:
|
||||
new_batches.append({
|
||||
**batch_result,
|
||||
'lines': line,
|
||||
})
|
||||
batches = new_batches
|
||||
:param to_process: A list of python dictionary, one for each payment to create, containing:
|
||||
* create_vals: The values used for the 'create' method.
|
||||
* to_reconcile: The journal items to perform the reconciliation.
|
||||
* batch: A python dict containing everything you want about the source journal items
|
||||
to which a payment will be created (see '_get_batches').
|
||||
:param edit_mode: Is the wizard in edition mode.
|
||||
"""
|
||||
|
||||
payment_vals_list = []
|
||||
for batch_result in batches:
|
||||
payment_vals_list.append(self._create_payment_vals_from_batch(batch_result))
|
||||
to_reconcile.append(batch_result['lines'])
|
||||
payments = self.env['account.payment'].create([x['create_vals'] for x in to_process])
|
||||
|
||||
payments = self.env['account.payment'].create(payment_vals_list)
|
||||
for payment, vals in zip(payments, to_process):
|
||||
vals['payment'] = payment
|
||||
|
||||
# If payments are made using a currency different than the source one, ensure the balance match exactly in
|
||||
# order to fully paid the source journal items.
|
||||
# For example, suppose a new currency B having a rate 100:1 regarding the company currency A.
|
||||
# If you try to pay 12.15A using 0.12B, the computed balance will be 12.00A for the payment instead of 12.15A.
|
||||
if edit_mode:
|
||||
lines = vals['to_reconcile']
|
||||
|
||||
# If payments are made using a currency different than the source one, ensure the balance match exactly in
|
||||
# order to fully paid the source journal items.
|
||||
# For example, suppose a new currency B having a rate 100:1 regarding the company currency A.
|
||||
# If you try to pay 12.15A using 0.12B, the computed balance will be 12.00A for the payment instead of 12.15A.
|
||||
if edit_mode:
|
||||
for payment, lines in zip(payments, to_reconcile):
|
||||
# Batches are made using the same currency so making 'lines.currency_id' is ok.
|
||||
if payment.currency_id != lines.currency_id:
|
||||
liquidity_lines, counterpart_lines, writeoff_lines = payment._seek_for_lines()
|
||||
@@ -491,23 +479,78 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
(1, debit_lines[0].id, {'debit': debit_lines[0].debit + delta_balance}),
|
||||
(1, credit_lines[0].id, {'credit': credit_lines[0].credit + delta_balance}),
|
||||
]})
|
||||
return payments
|
||||
|
||||
def _post_payments(self, to_process, edit_mode=False):
|
||||
""" Post the newly created payments.
|
||||
|
||||
:param to_process: A list of python dictionary, one for each payment to create, containing:
|
||||
* create_vals: The values used for the 'create' method.
|
||||
* to_reconcile: The journal items to perform the reconciliation.
|
||||
* batch: A python dict containing everything you want about the source journal items
|
||||
to which a payment will be created (see '_get_batches').
|
||||
:param edit_mode: Is the wizard in edition mode.
|
||||
"""
|
||||
payments = self.env['account.payment']
|
||||
for vals in to_process:
|
||||
payments |= vals['payment']
|
||||
payments.action_post()
|
||||
|
||||
def _reconcile_payments(self, to_process, edit_mode=False):
|
||||
""" Reconcile the payments.
|
||||
|
||||
:param to_process: A list of python dictionary, one for each payment to create, containing:
|
||||
* create_vals: The values used for the 'create' method.
|
||||
* to_reconcile: The journal items to perform the reconciliation.
|
||||
* batch: A python dict containing everything you want about the source journal items
|
||||
to which a payment will be created (see '_get_batches').
|
||||
:param edit_mode: Is the wizard in edition mode.
|
||||
"""
|
||||
domain = [('account_internal_type', 'in', ('receivable', 'payable')), ('reconciled', '=', False)]
|
||||
for payment, lines in zip(payments, to_reconcile):
|
||||
for vals in to_process:
|
||||
payment_lines = vals['payment'].line_ids.filtered_domain(domain)
|
||||
lines = vals['to_reconcile']
|
||||
|
||||
# When using the payment tokens, the payment could not be posted at this point (e.g. the transaction failed)
|
||||
# and then, we can't perform the reconciliation.
|
||||
if payment.state != 'posted':
|
||||
continue
|
||||
|
||||
payment_lines = payment.line_ids.filtered_domain(domain)
|
||||
for account in payment_lines.account_id:
|
||||
(payment_lines + lines)\
|
||||
.filtered_domain([('account_id', '=', account.id), ('reconciled', '=', False)])\
|
||||
.reconcile()
|
||||
|
||||
def _create_payments(self):
|
||||
self.ensure_one()
|
||||
batches = self._get_batches()
|
||||
edit_mode = self.can_edit_wizard and (len(batches[0]['lines']) == 1 or self.group_payment)
|
||||
to_process = []
|
||||
|
||||
if edit_mode:
|
||||
payment_vals = self._create_payment_vals_from_wizard()
|
||||
to_process.append({
|
||||
'create_vals': payment_vals,
|
||||
'to_reconcile': batches[0]['lines'],
|
||||
'batch': batches[0],
|
||||
})
|
||||
else:
|
||||
# Don't group payments: Create one batch per move.
|
||||
if not self.group_payment:
|
||||
new_batches = []
|
||||
for batch_result in batches:
|
||||
for line in batch_result['lines']:
|
||||
new_batches.append({
|
||||
**batch_result,
|
||||
'lines': line,
|
||||
})
|
||||
batches = new_batches
|
||||
|
||||
for batch_result in batches:
|
||||
to_process.append({
|
||||
'create_vals': self._create_payment_vals_from_batch(batch_result),
|
||||
'to_reconcile': batch_result['lines'],
|
||||
'batch': batch_result,
|
||||
})
|
||||
|
||||
payments = self._init_payments(to_process, edit_mode=edit_mode)
|
||||
self._post_payments(to_process, edit_mode=edit_mode)
|
||||
self._reconcile_payments(to_process, edit_mode=edit_mode)
|
||||
return payments
|
||||
|
||||
def action_create_payments(self):
|
||||
|
||||
@@ -178,10 +178,15 @@ var FieldOrgChart = AbstractField.extend({
|
||||
args: [employee_id],
|
||||
}).then(function(action) {
|
||||
action = _.extend(action, {
|
||||
'name': _t('Team'),
|
||||
'view_mode': 'kanban,list,form',
|
||||
'views': [[false, 'kanban'], [false, 'list'], [false, 'form']],
|
||||
'domain': domain,
|
||||
'context': {
|
||||
'default_parent_id': employee_id,
|
||||
}
|
||||
});
|
||||
delete action['res_id'];
|
||||
return self.do_action(action);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<a href="#"
|
||||
t-att-data-employee-id="self.id"
|
||||
t-att-data-employee-name="self.name"
|
||||
class="o_org_chart_show_more text-center o_employee_sub_redirect">…</a>
|
||||
class="o_org_chart_show_more text-center o_employee_sub_redirect">See All</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
@@ -218,7 +218,7 @@ base.tr,336,50000003503,55000003505,51600003503
|
||||
base.tv,517,50000005174,55000005176,51600005174
|
||||
base.ua,445,50000006049,55000006040,51600006049
|
||||
base.ug,142,50000001705,55000001707,51600001705
|
||||
base.uy,225,,55000000018,51600000016
|
||||
base.uy,225,50000000016,55000000018,51600000016
|
||||
base.uz,356,50000003562,55000003564,51600003562
|
||||
base.vu,505,50000005050,55000005052,51600005050
|
||||
base.ve,226,50000002264,55000002266,51600002264
|
||||
|
||||
|
@@ -10,7 +10,7 @@ class AccountBankStatement(models.Model):
|
||||
|
||||
def unlink(self):
|
||||
for statement in self:
|
||||
if not statement.company_id._is_accounting_unalterable() or not statement.s.journal_id.pos_payment_method_ids:
|
||||
if not statement.company_id._is_accounting_unalterable() or not statement.journal_id.pos_payment_method_ids:
|
||||
continue
|
||||
if statement.state != 'open':
|
||||
raise UserError(_('You cannot modify anything on a bank statement (name: %s) that was created by point of sale operations.') % (statement.name))
|
||||
|
||||
@@ -105,7 +105,7 @@ class AccountMove(models.Model):
|
||||
company_name=company_unit_partner.name,
|
||||
company_id=company_unit_partner.id
|
||||
))
|
||||
elif self.journal_id.type == 'purchase':
|
||||
elif move.journal_id.type == 'purchase':
|
||||
move.l10n_in_state_id = company_unit_partner.state_id
|
||||
|
||||
shipping_partner = move._l10n_in_get_shipping_partner()
|
||||
@@ -119,7 +119,7 @@ class AccountMove(models.Model):
|
||||
partner_id=shipping_partner.id,
|
||||
name=gst_treatment_name_mapping.get(move.l10n_in_gst_treatment)
|
||||
))
|
||||
if self.journal_id.type == 'sale':
|
||||
if move.journal_id.type == 'sale':
|
||||
move.l10n_in_state_id = self._l10n_in_get_indian_state(shipping_partner)
|
||||
if not move.l10n_in_state_id:
|
||||
move.l10n_in_state_id = self._l10n_in_get_indian_state(move.partner_id)
|
||||
|
||||
@@ -22,6 +22,7 @@ Italian accounting chart and localization.
|
||||
'data/l10n_it_chart_data.xml',
|
||||
'data/account.account.template.csv',
|
||||
'data/account.tax.group.csv',
|
||||
'data/account_tax_report_data.xml',
|
||||
'data/account_tax_template.xml',
|
||||
'data/account.fiscal.position.template.csv',
|
||||
'data/account.chart.template.csv',
|
||||
|
||||
189
addons/l10n_it/data/account_tax_report_data.xml
Normal file
189
addons/l10n_it/data/account_tax_report_data.xml
Normal file
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<flectra>
|
||||
|
||||
<record id="tax_report_vat" model="account.tax.report">
|
||||
<field name="name">VAT Report</field>
|
||||
<field name="country_id" ref="base.it"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_operazione_imponibile" model="account.tax.report.line">
|
||||
<field name="name">Operazione Imponibile</field>
|
||||
<field name="code">h1</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp2" model="account.tax.report.line">
|
||||
<field name="name">VP2 - Totale operazioni attive</field>
|
||||
<field name="code">VP2</field>
|
||||
<field name="parent_id" ref="tax_report_line_operazione_imponibile"/>
|
||||
<field name="tag_name">02</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp3" model="account.tax.report.line">
|
||||
<field name="name">VP3 - Totale operazioni passive</field>
|
||||
<field name="code">VP3</field>
|
||||
<field name="parent_id" ref="tax_report_line_operazione_imponibile"/>
|
||||
<field name="tag_name">03</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_iva" model="account.tax.report.line">
|
||||
<field name="name">IVA</field>
|
||||
<field name="code">h2</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp4" model="account.tax.report.line">
|
||||
<field name="name">VP4 - IVA esigibile</field>
|
||||
<field name="code">VP4</field>
|
||||
<field name="parent_id" ref="tax_report_line_iva"/>
|
||||
<field name="tag_name">4v</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp5" model="account.tax.report.line">
|
||||
<field name="name">VP5 - IVA detraibile</field>
|
||||
<field name="code">VP5</field>
|
||||
<field name="parent_id" ref="tax_report_line_iva"/>
|
||||
<field name="tag_name">5v</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_saldi_riporti_e_interessi" model="account.tax.report.line">
|
||||
<field name="name">Saldi, riporti e interessi</field>
|
||||
<field name="code">h3</field>
|
||||
<field name="sequence">3</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp6" model="account.tax.report.line">
|
||||
<field name="name">VP6 - IVA dovuta</field>
|
||||
<field name="code">VP6</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
<record id="tax_report_line_vp6a" model="account.tax.report.line">
|
||||
<field name="name">VP6a - IVA dovuta (debito)</field>
|
||||
<field name="code">VP6a</field>
|
||||
<field name="parent_id" ref="tax_report_line_vp6"/>
|
||||
<field name="formula">VP4>VP5 and VP4-VP5 or 0</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
<record id="tax_report_line_vp6b" model="account.tax.report.line">
|
||||
<field name="name">VP6b - IVA dovuta (credito)</field>
|
||||
<field name="code">VP6b</field>
|
||||
<field name="parent_id" ref="tax_report_line_vp6"/>
|
||||
<field name="formula">VP5>VP4 and VP5-VP4 or 0</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp7" model="account.tax.report.line">
|
||||
<field name="name">VP7 - Debito periodo precedente non superiore 25,82</field>
|
||||
<field name="code">VP7</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">2</field>
|
||||
<field name="tag_name">vp7</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp8" model="account.tax.report.line">
|
||||
<field name="name">VP8 - Credito periodo precedente</field>
|
||||
<field name="code">VP8</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">3</field>
|
||||
<field name="tag_name">vp8</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp9" model="account.tax.report.line">
|
||||
<field name="name">VP9 - Credito anno precedente</field>
|
||||
<field name="code">VP9</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">4</field>
|
||||
<field name="tag_name">vp9</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp10" model="account.tax.report.line">
|
||||
<field name="name">VP10 - Versamenti auto UE</field>
|
||||
<field name="code">VP10</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">5</field>
|
||||
<field name="tag_name">vp10</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp11" model="account.tax.report.line">
|
||||
<field name="name">VP11 - Credito d'imposta</field>
|
||||
<field name="code">VP11</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">6</field>
|
||||
<field name="tag_name">vp11</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp12" model="account.tax.report.line">
|
||||
<field name="name">VP12 - Interessi dovuti per liquidazioni trimestrali</field>
|
||||
<field name="code">VP12</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">7</field>
|
||||
<field name="tag_name">vp12</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_vp13" model="account.tax.report.line">
|
||||
<field name="name">VP13 - Acconto dovuto</field>
|
||||
<field name="code">VP13</field>
|
||||
<field name="parent_id" ref="tax_report_line_saldi_riporti_e_interessi"/>
|
||||
<field name="sequence">8</field>
|
||||
<field name="tag_name">vp13</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
<record id="tax_report_line_conto_corrente_iva" model="account.tax.report.line">
|
||||
<field name="name">Conto corrente IVA</field>
|
||||
<field name="code">h4</field>
|
||||
<field name="sequence">4</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
<record id="tax_report_line_vp14" model="account.tax.report.line">
|
||||
<field name="name">VP14 - IVA da versare</field>
|
||||
<field name="code">VP14</field>
|
||||
<field name="parent_id" ref="tax_report_line_conto_corrente_iva"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">None</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
<record id="tax_report_line_vp14a" model="account.tax.report.line">
|
||||
<field name="name">VP14a - IVA da versare (debito)</field>
|
||||
<field name="code">VP14a</field>
|
||||
<field name="parent_id" ref="tax_report_line_vp14"/>
|
||||
<field name="sequence">1</field>
|
||||
<field name="formula">max(((VP4>VP5 and VP4-VP5 or 0) + VP7 + VP12) - ((VP5>VP4 and VP5-VP4 or 0) + VP8 + VP9 + VP10 + VP11 + VP13), 0)</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
<record id="tax_report_line_vp14b" model="account.tax.report.line">
|
||||
<field name="name">VP14b - IVA da versare (credito)</field>
|
||||
<field name="code">VP14b</field>
|
||||
<field name="parent_id" ref="tax_report_line_vp14"/>
|
||||
<field name="sequence">2</field>
|
||||
<field name="formula">max(((VP5>VP4 and VP5-VP4 or 0) + VP8 + VP9 + VP10 + VP11 + VP13) - ((VP4>VP5 and VP4-VP5 or 0) + VP7 + VP12), 0)</field>
|
||||
<field name="report_id" ref="tax_report_vat"/>
|
||||
</record>
|
||||
|
||||
</flectra>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,7 @@ class StockPickingType(models.Model):
|
||||
return
|
||||
domains = {
|
||||
'count_mo_waiting': [('reservation_state', '=', 'waiting')],
|
||||
'count_mo_todo': [('state', 'in', ('confirmed', 'draft', 'progress'))],
|
||||
'count_mo_todo': [('state', 'in', ('confirmed', 'draft', 'progress', 'to_close'))],
|
||||
'count_mo_late': [('date_planned_start', '<', fields.Date.today()), ('state', '=', 'confirmed')],
|
||||
}
|
||||
for field in domains:
|
||||
|
||||
@@ -106,18 +106,26 @@ class AccountPayment(models.Model):
|
||||
# | Cancelled|<-----------------| cancel() |<-----
|
||||
# |__________| |__________|
|
||||
|
||||
# Create the missing payment transactions.
|
||||
payments_need_trans = self.filtered(lambda pay: pay.payment_token_id and not pay.payment_transaction_id)
|
||||
transactions = payments_need_trans._create_payment_transaction()
|
||||
|
||||
res = super(AccountPayment, self - payments_need_trans).action_post()
|
||||
payments_need_trans._create_payment_transaction()
|
||||
|
||||
# Process payment transactions directly.
|
||||
payments_with_trans = self.filtered('payment_transaction_id')
|
||||
transactions = payments_with_trans.payment_transaction_id
|
||||
transactions.s2s_do_transaction()
|
||||
|
||||
# Post payments for issued transactions.
|
||||
# Post payments.
|
||||
payments_to_post = self.filtered(lambda pay: not pay.payment_transaction_id
|
||||
or pay.payment_transaction_id.state == 'done')
|
||||
res = super(AccountPayment, payments_to_post).action_post()
|
||||
|
||||
# Post process transactions.
|
||||
transactions = payments_need_trans.payment_transaction_id.filtered(lambda x: x.state == 'done')
|
||||
transactions._post_process_after_done()
|
||||
payments_trans_done = payments_need_trans.filtered(lambda pay: pay.payment_transaction_id.state == 'done')
|
||||
super(AccountPayment, payments_trans_done).action_post()
|
||||
payments_trans_not_done = payments_need_trans.filtered(lambda pay: pay.payment_transaction_id.state != 'done')
|
||||
payments_trans_not_done.action_cancel()
|
||||
|
||||
# Cancel payments if the payment transactions failed.
|
||||
payments_to_cancel = payments_need_trans.payment_transaction_id.filtered(lambda x: x.state != 'done').payment_id
|
||||
payments_to_cancel.action_cancel()
|
||||
|
||||
return res
|
||||
|
||||
@@ -30,10 +30,10 @@ class AuthorizeAPI():
|
||||
|
||||
:param record acquirer: payment.acquirer account that will be contacted
|
||||
"""
|
||||
if acquirer.state == 'test':
|
||||
self.url = 'https://apitest.authorize.net/xml/v1/request.api'
|
||||
else:
|
||||
if acquirer.state == 'enabled':
|
||||
self.url = 'https://api.authorize.net/xml/v1/request.api'
|
||||
else:
|
||||
self.url = 'https://apitest.authorize.net/xml/v1/request.api'
|
||||
|
||||
self.state = acquirer.state
|
||||
self.name = acquirer.authorize_login
|
||||
|
||||
@@ -69,3 +69,30 @@ class AccountPaymentRegister(models.TransientModel):
|
||||
payment_vals = super()._create_payment_vals_from_wizard()
|
||||
payment_vals['payment_token_id'] = self.payment_token_id.id
|
||||
return payment_vals
|
||||
|
||||
def _init_payments(self, to_process, edit_mode=False):
|
||||
# OVERRIDE
|
||||
# Delay the reconciliation between payment & invoices when an electronic transaction is needed using a token.
|
||||
for vals in to_process:
|
||||
if vals['create_vals'].get('payment_token_id'):
|
||||
invoices = vals['to_reconcile'].move_id.filtered(lambda x: x.is_invoice(include_receipts=True))
|
||||
vals['transaction_invoices'] = invoices
|
||||
|
||||
return super()._init_payments(to_process, edit_mode=edit_mode)
|
||||
|
||||
def _post_payments(self, to_process, edit_mode=False):
|
||||
# OVERRIDE
|
||||
# Create a payment transaction for the newly created payments and link them to the related invoices.
|
||||
for vals in to_process:
|
||||
payment = vals['payment']
|
||||
if payment.payment_token_id:
|
||||
payment._create_payment_transaction({'invoice_ids': [(6, 0, vals['transaction_invoices'].ids)]})
|
||||
|
||||
return super()._post_payments(to_process, edit_mode=edit_mode)
|
||||
|
||||
def _reconcile_payments(self, to_process, edit_mode=False):
|
||||
# OVERRIDE
|
||||
# Don't reconcile payments for which the payment transactions failed.
|
||||
to_process = [x for x in to_process if x['payment'].state == 'posted']
|
||||
|
||||
return super()._reconcile_payments(to_process, edit_mode=edit_mode)
|
||||
|
||||
3
addons/payment_fix_register_token/tests/__init__.py
Normal file
3
addons/payment_fix_register_token/tests/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_account_payment_register
|
||||
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from flectra.tests import tagged
|
||||
|
||||
from flectra.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestAccountPaymentRegister(AccountTestInvoicingCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref=None):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
|
||||
cls.pay_method_electronic = cls.env.ref('payment.account_payment_method_electronic_in')
|
||||
|
||||
cls.partner_a.country_id = cls.env.ref('base.us')
|
||||
|
||||
cls.pay_acquirer = cls.env['payment.acquirer'].create({
|
||||
'name': "Dummy acquirer",
|
||||
'provider': 'manual',
|
||||
'company_id': cls.env.company.id,
|
||||
})
|
||||
|
||||
cls.pay_token = cls.env['payment.token'].create({
|
||||
'name': "Dummy Token",
|
||||
'partner_id': cls.partner_a.id,
|
||||
'acquirer_id': cls.pay_acquirer.id,
|
||||
'acquirer_ref': "TEST",
|
||||
})
|
||||
|
||||
def test_register_payment_electronic(self):
|
||||
|
||||
def _s2s_do_transaction_mock(_self, **_kwargs):
|
||||
_self.state = 'done'
|
||||
|
||||
invoice = self.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'date': '2017-01-01',
|
||||
'invoice_date': '2017-01-01',
|
||||
'partner_id': self.partner_a.id,
|
||||
'invoice_line_ids': [(0, 0, {'product_id': self.product_a.id, 'price_unit': 1000.0})],
|
||||
})
|
||||
invoice.action_post()
|
||||
self.assertRecordValues(invoice, [{'amount_residual': 1000.0}])
|
||||
|
||||
with patch(
|
||||
'flectra.addons.payment.models.payment_acquirer.PaymentTransaction.s2s_do_transaction',
|
||||
new=_s2s_do_transaction_mock,
|
||||
):
|
||||
payments = self.env['account.payment.register']\
|
||||
.with_context(active_model='account.move', active_ids=invoice.ids)\
|
||||
.create({
|
||||
'payment_method_id': self.pay_method_electronic.id,
|
||||
'payment_token_id': self.pay_token.id,
|
||||
})\
|
||||
._create_payments()
|
||||
|
||||
self.assertRecordValues(payments.payment_transaction_id, [{'invoice_ids': invoice.ids}])
|
||||
self.assertRecordValues(invoice, [{'amount_residual': 0.0}])
|
||||
@@ -28,7 +28,7 @@ var PaymentAdyen = PaymentInterface.extend({
|
||||
_reset_state: function () {
|
||||
this.was_cancelled = false;
|
||||
this.last_diagnosis_service_id = false;
|
||||
this.remaining_polls = 2;
|
||||
this.remaining_polls = 4;
|
||||
clearTimeout(this.polling);
|
||||
},
|
||||
|
||||
@@ -190,9 +190,13 @@ var PaymentAdyen = PaymentInterface.extend({
|
||||
timeout: 5000,
|
||||
shadow: true,
|
||||
}).catch(function (data) {
|
||||
reject();
|
||||
self.poll_error_order = self.pos.get_order();
|
||||
return self._handle_flectra_connection_failure(data);
|
||||
if (self.remaining_polls != 0) {
|
||||
self.remaining_polls--;
|
||||
} else {
|
||||
reject();
|
||||
self.poll_error_order = self.pos.get_order();
|
||||
return self._handle_flectra_connection_failure(data);
|
||||
}
|
||||
}).then(function (status) {
|
||||
var notification = status.latest_response;
|
||||
var last_diagnosis_service_id = status.last_received_diagnosis_id;
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
template.
|
||||
</p>
|
||||
<p class="text-muted">
|
||||
Titles with style <i>Heading 1</i> and
|
||||
<i>Heading 2</i> will be used to generate the
|
||||
Titles with style <i>Heading 2</i> and
|
||||
<i>Heading 3</i> will be used to generate the
|
||||
table of content automatically.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
@include o-stock-reports-lines($border-width: 1px, $font-weight: normal, $border-top-style: solid, $border-bottom-style: groove);
|
||||
}
|
||||
.o_stock_reports_table {
|
||||
thead {
|
||||
display: table-row-group;
|
||||
}
|
||||
white-space: nowrap;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
</div>
|
||||
</group>
|
||||
<group>
|
||||
<field name="lot_id" attrs="{'invisible': ['|',('product_id', '=', False),('tracking', '=', 'none')], 'required': [('tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="lot_id" context="{'default_product_id': product_id, 'default_company_id': company_id}" attrs="{'invisible': ['|',('product_id', '=', False),('tracking', '=', 'none')], 'required': [('tracking', '!=', 'none')]}" groups="stock.group_production_lot"/>
|
||||
<field name="tracking" invisible="1"/>
|
||||
<field name="package_id" groups="stock.group_tracking_lot"/>
|
||||
<field name="owner_id" groups="stock.group_tracking_owner"/>
|
||||
|
||||
@@ -315,8 +315,8 @@ var SnippetEditor = Widget.extend({
|
||||
for (var i in editor.styles) {
|
||||
editor.styles[i].onRemove();
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
onSuccess: resolve,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -518,8 +518,8 @@ var SnippetEditor = Widget.extend({
|
||||
isCurrent: ($snippet.is($clone)),
|
||||
});
|
||||
}
|
||||
resolve();
|
||||
},
|
||||
onSuccess: resolve,
|
||||
});
|
||||
});
|
||||
this.trigger_up('snippet_cloned', {$target: $clone, $origin: this.$target});
|
||||
@@ -2325,7 +2325,10 @@ var SnippetsMenu = Widget.extend({
|
||||
* @param {FlectraEvent} ev
|
||||
*/
|
||||
_onCallForEachChildSnippet: function (ev) {
|
||||
this._callForEachChildSnippet(ev.data.$snippet, ev.data.callback);
|
||||
const prom = this._callForEachChildSnippet(ev.data.$snippet, ev.data.callback);
|
||||
if (ev.data.onSuccess) {
|
||||
prom.then(() => ev.data.onSuccess());
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Called when the overlay dimensions/positions should be recomputed.
|
||||
|
||||
Reference in New Issue
Block a user