[IMP] point_of_sale: Use the cash rounding in the pos
Because of the law of the 1st december 2019, we can't pay with 1 or 2 cents anymore. We have to round the total price to the 0.05 unit. If the customer pay without rounding values, it triggers an error. Before the order is finalized, we add a line with a product rounding to round the total amount. Task-id: 2035010 X-original-commit: 58477e5503a18cc98fe686f8857233063eb26f4c
This commit is contained in:
committed by
Pierre Masereel
parent
aab5cab129
commit
42425996e3
@@ -214,6 +214,9 @@ class PosConfig(models.Model):
|
||||
company_has_template = fields.Boolean(string="Company has chart of accounts", compute="_compute_company_has_template")
|
||||
current_user_id = fields.Many2one('res.users', string='Current Session Responsible', compute='_compute_current_session_user')
|
||||
other_devices = fields.Boolean(string="Other Devices", help="Connect devices to your PoS without an IoT Box.")
|
||||
rounding_method = fields.Many2one('account.cash.rounding', string="Cash rounding")
|
||||
cash_rounding = fields.Boolean(string="Cash Rounding")
|
||||
only_round_cash_method = fields.Boolean(string="Only apply rounding on cash")
|
||||
|
||||
@api.depends('use_pricelist', 'available_pricelist_ids')
|
||||
def _compute_allowed_pricelist_ids(self):
|
||||
@@ -307,6 +310,11 @@ class PosConfig(models.Model):
|
||||
if open_session:
|
||||
raise ValidationError(_("You are not allowed to change the cash control status while a session is already opened."))
|
||||
|
||||
@api.constrains('rounding_method')
|
||||
def _check_rounding_method_strategy(self):
|
||||
if self.cash_rounding and self.rounding_method.strategy != 'add_invoice_line':
|
||||
raise ValidationError(_("Cash rounding strategy must be: 'Add a rounding line'"))
|
||||
|
||||
@api.constrains('company_id', 'journal_id')
|
||||
def _check_company_journal(self):
|
||||
if self.journal_id and self.journal_id.company_id.id != self.company_id.id:
|
||||
|
||||
@@ -8,8 +8,8 @@ import psycopg2
|
||||
import pytz
|
||||
|
||||
from odoo import api, fields, models, tools, _
|
||||
from odoo.tools import float_is_zero
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_is_zero, float_round
|
||||
from odoo.exceptions import ValidationError, UserError
|
||||
from odoo.http import request
|
||||
from odoo.osv.expression import AND
|
||||
import base64
|
||||
@@ -271,7 +271,6 @@ class PosOrder(models.Model):
|
||||
for order in self:
|
||||
order.currency_rate = self.env['res.currency']._get_conversion_rate(order.company_id.currency_id, order.currency_id, order.company_id, order.date_order)
|
||||
|
||||
|
||||
@api.onchange('payment_ids', 'lines')
|
||||
def _onchange_amount_all(self):
|
||||
for order in self:
|
||||
@@ -358,8 +357,15 @@ class PosOrder(models.Model):
|
||||
|
||||
def action_pos_order_paid(self):
|
||||
self.ensure_one()
|
||||
if not float_is_zero(self.amount_total - self.amount_paid, precision_rounding=self.currency_id.rounding):
|
||||
|
||||
if not self.config_id.cash_rounding:
|
||||
total = self.amount_total
|
||||
else:
|
||||
total = float_round(self.amount_total, precision_rounding=self.config_id.rounding_method.rounding, rounding_method=self.config_id.rounding_method.rounding_method)
|
||||
|
||||
if not float_is_zero(total - self.amount_paid, precision_rounding=self.currency_id.rounding):
|
||||
raise UserError(_("Order %s is not fully paid.") % self.name)
|
||||
|
||||
self.write({'state': 'paid'})
|
||||
return True
|
||||
|
||||
@@ -389,6 +395,7 @@ class PosOrder(models.Model):
|
||||
'invoice_date': order.date_order.date(),
|
||||
'fiscal_position_id': order.fiscal_position_id.id,
|
||||
'invoice_line_ids': [(0, None, order._prepare_invoice_line(line)) for line in order.lines],
|
||||
'invoice_cash_rounding_id': order.config_id.rounding_method.id if order.config_id.cash_rounding else False
|
||||
}
|
||||
new_move = moves.sudo()\
|
||||
.with_company(order.company_id)\
|
||||
@@ -824,3 +831,13 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
configs = self.env['pos.config'].browse(data['config_ids'])
|
||||
data.update(self.get_sale_details(data['date_start'], data['date_stop'], configs))
|
||||
return data
|
||||
|
||||
class AccountCashRounding(models.Model):
|
||||
_inherit = 'account.cash.rounding'
|
||||
|
||||
@api.constrains('rounding', 'rounding_method', 'strategy')
|
||||
def _check_session_state(self):
|
||||
open_session = self.env['pos.session'].search([('config_id.rounding_method', '=', self.id), ('state', '!=', 'closed')])
|
||||
if open_session:
|
||||
raise ValidationError(
|
||||
_("You are not allowed to change the cash rounding configuration while a pos session using it is already opened."))
|
||||
|
||||
@@ -6,7 +6,7 @@ from datetime import timedelta
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import float_is_zero
|
||||
from odoo.tools import float_is_zero, float_compare
|
||||
|
||||
|
||||
class PosSession(models.Model):
|
||||
@@ -375,6 +375,7 @@ class PosSession(models.Model):
|
||||
taxes = defaultdict(tax_amounts)
|
||||
stock_expense = defaultdict(amounts)
|
||||
stock_output = defaultdict(amounts)
|
||||
rounding_difference = {'amount': 0.0, 'amount_converted': 0.0}
|
||||
# Track the receivable lines of the invoiced orders' account moves for reconciliation
|
||||
# These receivable lines are reconciled to the corresponding invoice receivable lines
|
||||
# of this session's move_id.
|
||||
@@ -400,7 +401,10 @@ class PosSession(models.Model):
|
||||
if order.is_invoiced:
|
||||
# Combine invoice receivable lines
|
||||
key = order.partner_id.property_account_receivable_id.id
|
||||
invoice_receivables[key] = self._update_amounts(invoice_receivables[key], {'amount': order.amount_total}, order.date_order)
|
||||
if self.config_id.cash_rounding:
|
||||
invoice_receivables[key] = self._update_amounts(invoice_receivables[key], {'amount': order.amount_paid}, order.date_order)
|
||||
else:
|
||||
invoice_receivables[key] = self._update_amounts(invoice_receivables[key], {'amount': order.amount_total}, order.date_order)
|
||||
# side loop to gather receivable lines by account for reconciliation
|
||||
for move_line in order.account_move.line_ids.filtered(lambda aml: aml.account_id.internal_type == 'receivable'):
|
||||
order_account_move_receivable_lines[move_line.account_id.id] |= move_line
|
||||
@@ -447,6 +451,10 @@ class PosSession(models.Model):
|
||||
stock_expense[exp_key] = self._update_amounts(stock_expense[exp_key], {'amount': amount}, move.picking_id.date)
|
||||
stock_output[out_key] = self._update_amounts(stock_output[out_key], {'amount': amount}, move.picking_id.date)
|
||||
|
||||
if self.config_id.cash_rounding:
|
||||
diff = order.amount_paid - order.amount_total
|
||||
rounding_difference = self._update_amounts(rounding_difference, {'amount': diff}, order.date_order)
|
||||
|
||||
if self.company_id.anglo_saxon_accounting:
|
||||
global_session_pickings = self.picking_ids.filtered(lambda p: not p.pos_order_id)
|
||||
if global_session_pickings:
|
||||
@@ -480,6 +488,10 @@ class PosSession(models.Model):
|
||||
'Please set corresponding tax account in each repartition line of the following taxes: \n%s'
|
||||
) % ', '.join(tax_names_no_account)
|
||||
raise UserError(error_message)
|
||||
rounding_vals = []
|
||||
|
||||
if not float_is_zero(rounding_difference['amount'], precision_rounding=self.currency_id.rounding) or not float_is_zero(rounding_difference['amount_converted'], precision_rounding=self.currency_id.rounding):
|
||||
rounding_vals = [self._get_rounding_difference_vals(rounding_difference['amount'], rounding_difference['amount_converted'])]
|
||||
|
||||
MoveLine.create(
|
||||
tax_vals
|
||||
@@ -487,6 +499,7 @@ class PosSession(models.Model):
|
||||
+ [self._get_stock_expense_vals(key, amounts['amount'], amounts['amount_converted']) for key, amounts in stock_expense.items()]
|
||||
+ [self._get_split_receivable_vals(key, amounts['amount'], amounts['amount_converted']) for key, amounts in split_receivables.items()]
|
||||
+ [self._get_combine_receivable_vals(key, amounts['amount'], amounts['amount_converted']) for key, amounts in combine_receivables.items()]
|
||||
+ rounding_vals
|
||||
)
|
||||
|
||||
## SECTION: Create cash statement lines and cash move lines
|
||||
@@ -603,6 +616,20 @@ class PosSession(models.Model):
|
||||
'taxes': taxes,
|
||||
}
|
||||
|
||||
def _get_rounding_difference_vals(self, amount, amount_converted):
|
||||
if self.config_id.cash_rounding:
|
||||
partial_args = {
|
||||
'name': 'Rounding line',
|
||||
'move_id': self.move_id.id,
|
||||
}
|
||||
if float_compare(0.0, amount, precision_rounding=self.currency_id.rounding) > 0: # loss
|
||||
partial_args['account_id'] = self.config_id.rounding_method.loss_account_id.id
|
||||
return self._debit_amounts(partial_args, -amount, -amount_converted)
|
||||
|
||||
if float_compare(0.0, amount, precision_rounding=self.currency_id.rounding) < 0: # profit
|
||||
partial_args['account_id'] = self.config_id.rounding_method.profit_account_id.id
|
||||
return self._credit_amounts(partial_args, amount, amount_converted)
|
||||
|
||||
def _get_split_receivable_vals(self, payment, amount, amount_converted):
|
||||
partial_vals = {
|
||||
'account_id': payment.payment_method_id.receivable_account_id.id,
|
||||
|
||||
@@ -419,6 +419,13 @@ exports.PosModel = Backbone.Model.extend({
|
||||
return new exports.Product({}, product);
|
||||
}));
|
||||
},
|
||||
},{
|
||||
model: 'account.cash.rounding',
|
||||
fields: ['name', 'rounding', 'rounding_method'],
|
||||
domain: function(self){return [['id', '=', self.config.rounding_method[0]]]; },
|
||||
loaded: function(self, cash_rounding) {
|
||||
self.cash_rounding = cash_rounding;
|
||||
}
|
||||
},{
|
||||
model: 'pos.payment.method',
|
||||
fields: ['name', 'is_cash_count', 'use_payment_terminal'],
|
||||
@@ -2446,10 +2453,12 @@ exports.Order = Backbone.Model.extend({
|
||||
paymentlines: paymentlines,
|
||||
subtotal: this.get_subtotal(),
|
||||
total_with_tax: this.get_total_with_tax(),
|
||||
total_rounded: this.get_total_with_tax() + this.get_rounding_applied(),
|
||||
total_without_tax: this.get_total_without_tax(),
|
||||
total_tax: this.get_total_tax(),
|
||||
total_paid: this.get_total_paid(),
|
||||
total_discount: this.get_total_discount(),
|
||||
rounding_applied: this.get_rounding_applied(),
|
||||
tax_details: this.get_tax_details(),
|
||||
change: this.get_change(),
|
||||
name : this.get_name(),
|
||||
@@ -2734,7 +2743,7 @@ exports.Order = Backbone.Model.extend({
|
||||
this.assert_editable();
|
||||
var newPaymentline = new exports.Paymentline({},{order: this, payment_method:payment_method, pos: this.pos});
|
||||
if(!payment_method.is_cash_count || this.pos.config.iface_precompute_cash){
|
||||
newPaymentline.set_amount( this.get_due() );
|
||||
newPaymentline.set_amount(this.get_due() );
|
||||
};
|
||||
this.paymentlines.add(newPaymentline);
|
||||
this.select_paymentline(newPaymentline);
|
||||
@@ -2812,7 +2821,7 @@ exports.Order = Backbone.Model.extend({
|
||||
}
|
||||
},
|
||||
/* ---- Payment Status --- */
|
||||
get_subtotal : function(){
|
||||
get_subtotal: function(){
|
||||
return round_pr(this.orderlines.reduce((function(sum, orderLine){
|
||||
return sum + orderLine.get_display_price();
|
||||
}), 0), this.pos.currency.rounding);
|
||||
@@ -2942,7 +2951,7 @@ exports.Order = Backbone.Model.extend({
|
||||
},
|
||||
get_change: function(paymentline) {
|
||||
if (!paymentline) {
|
||||
var change = this.get_total_paid() - this.get_total_with_tax();
|
||||
var change = this.get_total_paid() - this.get_total_with_tax() - this.get_rounding_applied();
|
||||
} else {
|
||||
var change = -this.get_total_with_tax();
|
||||
var lines = this.paymentlines.models;
|
||||
@@ -2957,7 +2966,7 @@ exports.Order = Backbone.Model.extend({
|
||||
},
|
||||
get_due: function(paymentline) {
|
||||
if (!paymentline) {
|
||||
var due = this.get_total_with_tax() - this.get_total_paid();
|
||||
var due = this.get_total_with_tax() - this.get_total_paid() + this.get_rounding_applied();
|
||||
} else {
|
||||
var due = this.get_total_with_tax();
|
||||
var lines = this.paymentlines.models;
|
||||
@@ -2971,6 +2980,35 @@ exports.Order = Backbone.Model.extend({
|
||||
}
|
||||
return round_pr(due, this.pos.currency.rounding);
|
||||
},
|
||||
get_rounding_applied: function() {
|
||||
if(this.pos.config.cash_rounding) {
|
||||
var total = round_pr(this.get_total_with_tax(), this.pos.cash_rounding[0].rounding);
|
||||
|
||||
var rounding_applied = total - (this.pos.config['iface_tax_included'] === "total"? this.get_subtotal(): this.get_total_with_tax());
|
||||
// because floor and ceil doesn't include decimals in calculation, we reuse the value of the half-up and adapt it.
|
||||
if(this.pos.cash_rounding[0].rounding_method === "UP" && rounding_applied < 0) {
|
||||
rounding_applied += this.pos.cash_rounding[0].rounding;
|
||||
}
|
||||
else if(this.pos.cash_rounding[0].rounding_method === "DOWN" && rounding_applied > 0){
|
||||
rounding_applied -= this.pos.cash_rounding[0].rounding;
|
||||
}
|
||||
return rounding_applied;
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
has_not_valid_rounding: function() {
|
||||
if(!this.pos.config.cash_rounding)
|
||||
return false;
|
||||
|
||||
var lines = this.paymentlines.models;
|
||||
|
||||
for(var i = 0; i < lines.length; i++) {
|
||||
var line = lines[i];
|
||||
if(!utils.float_is_zero(line.amount - round_pr(line.amount, this.pos.cash_rounding[0].rounding), 6))
|
||||
return line;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
is_paid: function(){
|
||||
return this.get_due() <= 0;
|
||||
},
|
||||
|
||||
@@ -2093,7 +2093,7 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
var extradue = this.compute_extradue(order);
|
||||
|
||||
this.$('.paymentlines-container').empty();
|
||||
var lines = $(QWeb.render('PaymentScreen-Paymentlines', {
|
||||
var lines = $(QWeb.render('PaymentScreen-Paymentlines', {
|
||||
widget: this,
|
||||
order: order,
|
||||
paymentlines: lines,
|
||||
@@ -2302,6 +2302,15 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
return false;
|
||||
}
|
||||
|
||||
if(order.has_not_valid_rounding()) {
|
||||
var line = order.has_not_valid_rounding();
|
||||
this.gui.show_popup('error',{
|
||||
title: _t('Incorrect rounding'),
|
||||
body: _t('You have to round your payments lines.' + line.amount + ' is not rounded.'),
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
// The exact amount must be paid if there is no cash payment method defined.
|
||||
if (Math.abs(order.get_total_with_tax() - order.get_total_paid()) > 0.00001) {
|
||||
var cash = false;
|
||||
|
||||
@@ -658,7 +658,7 @@
|
||||
<t t-if="!paymentlines.length">
|
||||
<div class='paymentlines-empty'>
|
||||
<div class='total'>
|
||||
<t t-esc="widget.format_currency(order.get_total_with_tax())"/>
|
||||
<t t-esc="widget.format_currency(order.get_total_with_tax() + order.get_rounding_applied())"/>
|
||||
</div>
|
||||
<div class='message'>
|
||||
Please select a payment method.
|
||||
@@ -678,7 +678,7 @@
|
||||
<div class="payment-status-total-due">
|
||||
<span class="label">Total Due</span>
|
||||
<span>
|
||||
<t t-esc="widget.format_currency(order.get_total_with_tax())" />
|
||||
<t t-esc="widget.format_currency(order.get_total_with_tax() + order.get_rounding_applied())" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -994,6 +994,12 @@
|
||||
TOTAL
|
||||
<span t-esc='widget.format_currency(receipt.total_with_tax)' class="pos-receipt-right-align"/>
|
||||
</div>
|
||||
<t t-if="receipt.total_rounded != receipt.total_with_tax">
|
||||
<div class="pos-receipt-amount">
|
||||
ROUNDED
|
||||
<span t-esc='widget.format_currency(receipt.total_rounded)' class="pos-receipt-right-align"/>
|
||||
</div>
|
||||
</t>
|
||||
<br/><br/>
|
||||
|
||||
<!-- Payment Lines -->
|
||||
|
||||
@@ -21,6 +21,7 @@ class TestPoSBasicConfig(TestPoSCommon):
|
||||
self.product1 = self.create_product('Product 1', self.categ_basic, 10.0, 5)
|
||||
self.product2 = self.create_product('Product 2', self.categ_basic, 20.0, 10)
|
||||
self.product3 = self.create_product('Product 3', self.categ_basic, 30.0, 15)
|
||||
self.product4 = self.create_product('Product_4', self.categ_basic, 9.96, 4.98)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def test_orders_no_invoiced(self):
|
||||
@@ -441,3 +442,79 @@ class TestPoSBasicConfig(TestPoSCommon):
|
||||
|
||||
for line in cash_receivable_lines:
|
||||
self.assertTrue(line.full_reconcile_id, msg='Each cash receivable line should be fully-reconciled.')
|
||||
|
||||
def test_rounding_method(self):
|
||||
# set the cash rounding method
|
||||
self.config.cash_rounding = True
|
||||
self.config.rounding_method = self.env['account.cash.rounding'].create({
|
||||
'name': 'add_invoice_line',
|
||||
'rounding': 0.05,
|
||||
'strategy': 'add_invoice_line',
|
||||
'profit_account_id': self.company['default_cash_difference_income_account_id'].copy().id,
|
||||
'loss_account_id': self.company['default_cash_difference_expense_account_id'].copy().id,
|
||||
'rounding_method': 'HALF-UP',
|
||||
})
|
||||
|
||||
self.open_new_session()
|
||||
|
||||
""" Test for orders: one with invoice
|
||||
|
||||
3 orders
|
||||
- order 1, paid by cash
|
||||
- order 2, paid by bank
|
||||
- order 3, paid by bank, invoiced
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 1 | bank | no | product1 | 6 | 60 |
|
||||
| | | | product4 | 4 | 39.84 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 2 | bank | yes | product4 | 3 | 29.88 |
|
||||
| | | | product2 | 20 | 400 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale | -596,56 |
|
||||
| pos receivable bank | 516,64 |
|
||||
| Rounding applied | -0,01 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product4, 3), (self.product2, 20)],
|
||||
payments=[(self.bank_pm, 429.90)]
|
||||
))
|
||||
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 6), (self.product4, 4)],
|
||||
payments=[(self.bank_pm, 99.85)]
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
self.assertEqual(orders[0]['data']['amount_return'], 0, msg='The amount return should be 0')
|
||||
self.assertEqual(orders[1]['data']['amount_return'], 0, msg='The amount return should be 0')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_account_move = self.pos_session.move_id
|
||||
|
||||
rounding_line = session_account_move.line_ids.filtered(lambda line: line.name == 'Rounding line')
|
||||
self.assertAlmostEqual(rounding_line.credit, 0.03, msg='The credit should be equals to 0.03')
|
||||
|
||||
@@ -342,6 +342,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box" groups="account.group_cash_rounding">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="cash_rounding"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="cash_rounding"/>
|
||||
<div class="text-muted">
|
||||
Define the smallest coinage of the currency used to pay
|
||||
</div>
|
||||
<div class="content-group mt16" attrs="{'invisible': [('cash_rounding', '=', False)]}">
|
||||
<div class="row mt16">
|
||||
<label string="Rounding Method" for="rounding_method" class="col-lg-3 o_light_label" />
|
||||
<field name="rounding_method" attrs="{'required' : [('cash_rounding', '=', True)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="cash_control"/>
|
||||
|
||||
@@ -84,6 +84,11 @@
|
||||
nolabel="1"
|
||||
class="oe_subtotal_footer_separator"
|
||||
widget="monetary"/>
|
||||
<field name="amount_paid"
|
||||
string="Total Paid (with rounding)"
|
||||
class="oe_subtotal_footer_separator"
|
||||
widget="monetary"
|
||||
attrs="{'invisible': [('amount_paid','=', 'amount_total')]}"/>
|
||||
</group>
|
||||
<div class="oe_clear"/>
|
||||
</page>
|
||||
@@ -347,4 +352,17 @@
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="pos_rounding_form_view_inherited" model="ir.ui.view">
|
||||
<field name="name">pos.cash.rounding.form.inherited</field>
|
||||
<field name="model">account.cash.rounding</field>
|
||||
<field name="inherit_id" ref="account.rounding_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[hasclass('oe_title')]" position="before">
|
||||
<div class="o_notification_alert alert alert-warning" role="alert">
|
||||
The Point of Sale only support the "add a rounding line" rounding strategy.
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -83,6 +83,25 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Payments</h2>
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-12 col-lg-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_cash_rounding"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="group_cash_rounding"/>
|
||||
<div class="text-muted">
|
||||
Define the smallest coinage of the currency used to pay by cash
|
||||
</div>
|
||||
<div class="mt8">
|
||||
<button name="%(account.rounding_list_action)d" icon="fa-arrow-right"
|
||||
type="action" string="Cash Roundings" class="btn-link"
|
||||
attrs="{'invisible': [('group_cash_rounding', '=', False)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2>Payment Terminals</h2>
|
||||
<div class="row mt16 o_settings_container" id="o_settings_use_payment_terminals">
|
||||
<div class="col-12 col-lg-6 o_setting_box" title="The transactions are processed by Vantiv. Set your Vantiv credentials on the related payment method.">
|
||||
|
||||
Reference in New Issue
Block a user