[PATCH] Upstream patch - 21092021

This commit is contained in:
Parthiv Patel
2021-09-21 09:35:49 +00:00
parent d236c59a5c
commit fbdac5593b
25 changed files with 528 additions and 1381 deletions

View File

@@ -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):

View File

@@ -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))

View File

@@ -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)

View File

@@ -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:

View File

@@ -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,
},
])

View File

@@ -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):

View File

@@ -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);
});
});

View File

@@ -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">&#8230;</a>
class="o_org_chart_show_more text-center o_employee_sub_redirect">See All</a>
</div>
</div>
</t>

View File

@@ -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
1 id l10n_ar_afip_code l10n_ar_natural_vat l10n_ar_legal_entity_vat l10n_ar_other_vat
218 base.tv 517 50000005174 55000005176 51600005174
219 base.ua 445 50000006049 55000006040 51600006049
220 base.ug 142 50000001705 55000001707 51600001705
221 base.uy 225 50000000016 55000000018 51600000016
222 base.uz 356 50000003562 55000003564 51600003562
223 base.vu 505 50000005050 55000005052 51600005050
224 base.ve 226 50000002264 55000002266 51600002264

View File

@@ -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))

View File

@@ -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)

View File

@@ -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',

View 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&gt;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&gt;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&gt;VP5 and VP4-VP5 or 0) + VP7 + VP12) - ((VP5&gt;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&gt;VP4 and VP5-VP4 or 0) + VP8 + VP9 + VP10 + VP11 + VP13) - ((VP4&gt;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

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

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

View File

@@ -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}])

View File

@@ -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;

View File

@@ -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>

View File

@@ -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;
}

View File

@@ -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"/>

View File

@@ -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.