[MERGE] forward port branch 9.0 up to af87c57
This commit is contained in:
@@ -273,7 +273,7 @@
|
||||
<field name="code" attrs="{'readonly': ['|',('type', 'in', ['bank','cash']),('sequence_id','!=',False)], 'required': [('type', 'not in', ['bank', 'cash'])]}"/>
|
||||
<field name="refund_sequence" attrs="{'invisible': [('type', 'not in', ['sale', 'purchase'])]}"/>
|
||||
<field name="sequence_id" required="0" attrs="{'readonly': 1}" groups="base.group_no_one"/>
|
||||
<field name="refund_sequence_id" attrs="{'invisible': ['|',('type', 'not in', ['sale', 'purchase']), ('refund_sequence', '!=', True)]}" required="0" groups="base.group_no_one"/>
|
||||
<field name="refund_sequence_id" attrs="{'invisible': ['|',('type', 'not in', ['sale', 'purchase']), ('refund_sequence', '!=', True)], 'required': [('type', 'in', ['sale', 'purchase']), ('refund_sequence', '=', True)]}" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="default_debit_account_id" domain="[('deprecated', '=', False)]" />
|
||||
|
||||
@@ -411,7 +411,7 @@ class AccountAssetDepreciationLine(models.Model):
|
||||
current_currency = line.asset_id.currency_id
|
||||
amount = current_currency.compute(line.amount, company_currency)
|
||||
sign = (line.asset_id.category_id.journal_id.type == 'purchase' or line.asset_id.category_id.journal_id.type == 'sale' and 1) or -1
|
||||
asset_name = line.asset_id.name + ' (%s/%s)' % (line.sequence, line.asset_id.method_number)
|
||||
asset_name = line.asset_id.name + ' (%s/%s)' % (line.sequence, len(line.asset_id.depreciation_line_ids))
|
||||
reference = line.asset_id.code
|
||||
journal_id = line.asset_id.category_id.journal_id.id
|
||||
partner_id = line.asset_id.partner_id.id
|
||||
|
||||
@@ -51,15 +51,15 @@ class AccountInvoiceLine(models.Model):
|
||||
|
||||
@api.one
|
||||
def asset_create(self):
|
||||
if self.asset_category_id and self.asset_category_id.method_number > 1:
|
||||
if self.asset_category_id:
|
||||
vals = {
|
||||
'name': self.name,
|
||||
'code': self.invoice_id.number or False,
|
||||
'category_id': self.asset_category_id.id,
|
||||
'value': self.price_subtotal,
|
||||
'value': self.price_subtotal_signed,
|
||||
'partner_id': self.invoice_id.partner_id.id,
|
||||
'company_id': self.invoice_id.company_id.id,
|
||||
'currency_id': self.invoice_id.currency_id.id,
|
||||
'currency_id': self.invoice_id.company_currency_id.id,
|
||||
'date': self.asset_start_date or self.invoice_id.date_invoice,
|
||||
'invoice_id': self.invoice_id.id,
|
||||
}
|
||||
|
||||
@@ -35,30 +35,57 @@ class ResCompany(models.Model):
|
||||
class AccountPartialReconcileCashBasis(models.Model):
|
||||
_inherit = 'account.partial.reconcile'
|
||||
|
||||
def create_tax_cash_basis_entry(self, value_before_reconciliation):
|
||||
#Search in account_move if we have any taxes account move lines
|
||||
def _check_tax_exigible(self, line):
|
||||
""" Function overwritten in account_tax_exigible to make sure we consider only the lines having tax_exigible set to False """
|
||||
return False
|
||||
|
||||
def _get_tax_cash_basis_lines(self, value_before_reconciliation):
|
||||
# Search in account_move if we have any taxes account move lines
|
||||
tax_group = {}
|
||||
total_by_cash_basis_account = {}
|
||||
for move in (self.debit_move_id.move_id, self.credit_move_id.move_id):
|
||||
for line in move.line_ids:
|
||||
if line.tax_line_id and line.tax_line_id.use_cash_basis:
|
||||
#amount to write is the current cash_basis amount minus the one before the reconciliation
|
||||
matched_percentage = value_before_reconciliation[move.id]
|
||||
amount = (line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage
|
||||
#group by line account
|
||||
acc = line.account_id.id
|
||||
if tax_group.get(acc, False):
|
||||
tax_group[acc] += amount
|
||||
else:
|
||||
tax_group[acc] = amount
|
||||
#Group by cash basis account
|
||||
acc = line.tax_line_id.cash_basis_account.id
|
||||
if total_by_cash_basis_account.get(acc, False):
|
||||
total_by_cash_basis_account[acc] += amount
|
||||
else:
|
||||
total_by_cash_basis_account[acc] = amount
|
||||
line_to_create = []
|
||||
for k,v in tax_group.items():
|
||||
move_date = self.debit_move_id.date
|
||||
for move in (self.debit_move_id.move_id, self.credit_move_id.move_id):
|
||||
if move_date < move.date:
|
||||
move_date = move.date
|
||||
for line in move.line_ids:
|
||||
#TOCHECK: normal and cash basis taxes shoudn't be mixed together (on the same invoice line for example) as it will
|
||||
#create reporting issues. Not sure of the behavior to implement in that case, though.
|
||||
# amount to write is the current cash_basis amount minus the one before the reconciliation
|
||||
matched_percentage = value_before_reconciliation[move.id]
|
||||
amount = (line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage
|
||||
if not self._check_tax_exigible(line):
|
||||
if line.tax_line_id and line.tax_line_id.use_cash_basis:
|
||||
# group by line account
|
||||
acc = line.account_id.id
|
||||
if tax_group.get(acc, False):
|
||||
tax_group[acc] += amount
|
||||
else:
|
||||
tax_group[acc] = amount
|
||||
# Group by cash basis account and tax
|
||||
acc = line.tax_line_id.cash_basis_account.id
|
||||
key = (acc, line.tax_line_id.id)
|
||||
if key in total_by_cash_basis_account:
|
||||
total_by_cash_basis_account[key] += amount
|
||||
else:
|
||||
total_by_cash_basis_account[key] = amount
|
||||
if any([tax.use_cash_basis for tax in line.tax_ids]):
|
||||
for tax in line.tax_ids:
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': line.debit_cash_basis - line.debit * matched_percentage,
|
||||
'credit': line.credit_cash_basis - line.credit * matched_percentage,
|
||||
'account_id': line.account_id.id,
|
||||
'tax_ids': [(6, 0, [tax.id])],
|
||||
}))
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'credit': line.debit_cash_basis - line.debit * matched_percentage,
|
||||
'debit': line.credit_cash_basis - line.credit * matched_percentage,
|
||||
'account_id': line.account_id.id,
|
||||
}))
|
||||
|
||||
for k, v in tax_group.items():
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': v if v > 0 else 0.0,
|
||||
@@ -66,27 +93,39 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
'account_id': k,
|
||||
}))
|
||||
|
||||
#Create counterpart vals
|
||||
for k,v in total_by_cash_basis_account.items():
|
||||
# Create counterpart vals
|
||||
for key, v in total_by_cash_basis_account.items():
|
||||
k, tax_id = key
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': abs(v) if v < 0 else 0.0,
|
||||
'credit': v if v > 0 else 0.0,
|
||||
'account_id': k,
|
||||
'tax_line_id': tax_id,
|
||||
}))
|
||||
return line_to_create, move_date
|
||||
|
||||
#Create move
|
||||
def create_tax_cash_basis_entry(self, value_before_reconciliation):
|
||||
line_to_create, move_date = self._get_tax_cash_basis_lines(value_before_reconciliation)
|
||||
if len(line_to_create) > 0:
|
||||
#Check if company_journal for cash basis is set if not, raise exception
|
||||
# Check if company_journal for cash basis is set if not, raise exception
|
||||
if not self.company_id.tax_cash_basis_journal_id:
|
||||
raise UserError(_('There is no tax cash basis journal defined ' \
|
||||
'for this company: "%s" \nConfigure it in Accounting/Configuration/Settings') % \
|
||||
(self.company_id.name))
|
||||
move = self.env['account.move'].create({
|
||||
move_vals = {
|
||||
'journal_id': self.company_id.tax_cash_basis_journal_id.id,
|
||||
'line_ids': line_to_create,
|
||||
'tax_cash_basis_rec_id': self.id})
|
||||
#post move
|
||||
'tax_cash_basis_rec_id': self.id
|
||||
}
|
||||
# The move date should be the maximum date between payment and invoice (in case
|
||||
# of payment in advance). However, we should make sure the move date is not
|
||||
# recorded after the period lock date as the tax statement for this period is
|
||||
# probably already sent to the estate.
|
||||
if move_date > self.company_id.period_lock_date:
|
||||
move_vals['date'] = move_date
|
||||
move = self.env['account.move'].with_context(dont_create_taxes=True).create(move_vals)
|
||||
# post move
|
||||
move.post()
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import models
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
def _migration_script(cr, registry):
|
||||
#1. set the tax_exigible at True on all account.move lines not related to a tax in cash basis
|
||||
cr.execute('''UPDATE account_move_line SET tax_exigible='t' ''')
|
||||
|
||||
cr.execute('''SELECT id FROM account_tax WHERE use_cash_basis = 't' ''')
|
||||
tax_ids = tuple([x[0] for x in cr.fetchall()])
|
||||
if tax_ids:
|
||||
cr.execute('''UPDATE account_move_line SET tax_exigible='f' WHERE id IN (SELECT id FROM account_move_line WHERE tax_line_id IN %s OR id IN (SELECT account_move_line_id FROM account_move_line_account_tax_rel WHERE account_tax_id IN %s))''', (tax_ids, tax_ids))
|
||||
|
||||
#2. Fix the moves already created by the tax case based feature
|
||||
# create account.move.lines for tax_line_id and tax_ids that weren't correctly set/created at the time of reconciliation
|
||||
existing_move = registry['account.move'].search(cr, SUPERUSER_ID, [('tax_cash_basis_rec_id', '!=', False)])
|
||||
for m in registry['account.move'].browse(cr, SUPERUSER_ID, existing_move):
|
||||
partial_rec = m.tax_cash_basis_rec_id
|
||||
for move in (partial_rec.debit_move_id.move_id, partial_rec.credit_move_id.move_id):
|
||||
matched_percentage = partial_rec.amount and (partial_rec.amount / move.amount) or 0.0
|
||||
for l in move.line_ids:
|
||||
if l.tax_exigible:
|
||||
continue
|
||||
|
||||
move_to_fix = registry['account.move'].search(cr, SUPERUSER_ID, [('tax_cash_basis_rec_id', '=', partial_rec.id)])[0]
|
||||
amount = (l.debit - l.credit) * matched_percentage
|
||||
|
||||
registry['account.move.line'].create(cr, SUPERUSER_ID, {
|
||||
'name': '/',
|
||||
'debit': amount > 0 and amount or 0.0,
|
||||
'credit': amount < 0 and -amount or 0.0,
|
||||
'account_id': l.account_id.id,
|
||||
'tax_line_id': l.tax_line_id and l.tax_line_id.id or False,
|
||||
'tax_ids': l.tax_ids and [(6, 0, l.tax_ids.ids)] or [],
|
||||
'tax_exigible': True,
|
||||
'move_id': move_to_fix,
|
||||
}, apply_taxes=False, context={'check_move_validity': False})
|
||||
registry['account.move.line'].create(cr, SUPERUSER_ID, {
|
||||
'name': '/',
|
||||
'debit': -amount > 0 and -amount or 0.0,
|
||||
'credit': -amount < 0 and amount or 0.0,
|
||||
'account_id': l.account_id.id,
|
||||
'move_id': move_to_fix,
|
||||
'tax_exigible': True,
|
||||
}, context={'check_move_validity': False})
|
||||
return
|
||||
@@ -0,0 +1,17 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
{
|
||||
'name': 'Tax exigible',
|
||||
'version': '1.0',
|
||||
'category': 'Accounting',
|
||||
'description': """
|
||||
This is a bugfix-module backporting 39d68ac and adding the concept of tax exigibility on journal items.
|
||||
""",
|
||||
'depends': ['account_tax_cash_basis'],
|
||||
'data': [],
|
||||
'test': [],
|
||||
'demo': [],
|
||||
'auto_install': True,
|
||||
'installable': True,
|
||||
'post_init_hook': '_migration_script',
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
import account_move
|
||||
@@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import fields, models, api
|
||||
|
||||
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = "account.move.line"
|
||||
tax_exigible = fields.Boolean(string='Appears in VAT report', default=True,
|
||||
help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the module account_tax_cash_basis, some will become exigible only when the payment is recorded.")
|
||||
|
||||
@api.model
|
||||
def create(self, vals, apply_taxes=True):
|
||||
taxes = False
|
||||
if vals.get('tax_line_id'):
|
||||
taxes = [{'use_cash_basis': self.env['account.tax'].browse(vals['tax_line_id']).use_cash_basis}]
|
||||
if vals.get('tax_ids'):
|
||||
taxes = self.env['account.move.line'].resolve_2many_commands('tax_ids', vals['tax_ids'])
|
||||
if taxes and any([tax['use_cash_basis'] for tax in taxes]) and not vals.get('tax_exigible'):
|
||||
vals['tax_exigible'] = False
|
||||
return super(AccountMoveLine, self).create(vals, apply_taxes=apply_taxes)
|
||||
|
||||
class AccountPartialReconcileCashBasis(models.Model):
|
||||
_inherit = 'account.partial.reconcile'
|
||||
|
||||
def _check_tax_exigible(self, line):
|
||||
return line.tax_exigible
|
||||
|
||||
def _get_tax_cash_basis_lines(self, value_before_reconciliation):
|
||||
lines, move_date = super(AccountPartialReconcileCashBasis, self)._get_tax_cash_basis_lines(value_before_reconciliation)
|
||||
for i in range(len(lines)):
|
||||
vals = lines[i][2]
|
||||
vals['tax_exigible'] = True
|
||||
lines[i] = (0, 0, vals)
|
||||
return lines, move_date
|
||||
@@ -8,6 +8,7 @@ from openerp.http import request
|
||||
class link_tracker(http.Controller):
|
||||
@http.route('/r/<string:code>', type='http', auth='none', website=True)
|
||||
def full_url_redirect(self, code, **post):
|
||||
request.env['link.tracker.click'].add_click(code, request.httprequest.remote_addr, request.session['geoip'].get('country_code'), stat_id=False)
|
||||
country_code = request.session.geoip and request.session.geoip.get('country_code') or False
|
||||
request.env['link.tracker.click'].add_click(code, request.httprequest.remote_addr, country_code, stat_id=False)
|
||||
redirect_url = request.env['link.tracker'].get_url_from_code(code)
|
||||
return werkzeug.utils.redirect(redirect_url or '', 301)
|
||||
|
||||
@@ -639,7 +639,7 @@ var chat_manager = {
|
||||
// post a message in a channel
|
||||
return ChannelModel.call('message_post', [options.channel_id], _.extend(msg, {
|
||||
message_type: 'comment',
|
||||
content_subtype: 'plaintext',
|
||||
content_subtype: 'html',
|
||||
subtype: 'mail.mt_comment',
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import api, _
|
||||
from openerp.osv import fields, osv
|
||||
import openerp.addons.decimal_precision as dp
|
||||
|
||||
@@ -104,3 +105,27 @@ class mrp_product_produce(osv.osv_memory):
|
||||
self.pool.get('mrp.production').action_produce(cr, uid, production_id,
|
||||
data.product_qty, data.mode, data, context=context)
|
||||
return {}
|
||||
|
||||
@api.onchange('consume_lines')
|
||||
def _onchange_consume_lines(self):
|
||||
'''
|
||||
The purpose of the method is to warn the user if we plan to consume more than one unit of
|
||||
a product with unique serial number.
|
||||
'''
|
||||
for product in self.consume_lines.mapped('product_id'):
|
||||
if product.tracking != 'serial':
|
||||
continue
|
||||
|
||||
qty_by_lot = {}
|
||||
lines = self.consume_lines.filtered(lambda r: r.product_id == product)
|
||||
for line in lines:
|
||||
qty_by_lot.setdefault(line.lot_id, 0.0)
|
||||
qty_by_lot[line.lot_id] += line.product_qty
|
||||
|
||||
if qty_by_lot[line.lot_id] > 1.0:
|
||||
warning_mess = {
|
||||
'title': _('Issue with lot quantity!'),
|
||||
'message' : _('You plan to consume more than 1.00 unit of product %s with unique lot number %s') % \
|
||||
(product.name, line.lot_id.name)
|
||||
}
|
||||
return {'warning': warning_mess}
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
<field name="open"/>
|
||||
<field name="memo"/>
|
||||
<field name="date_done"/>
|
||||
<field name="message_follower_ids"/>
|
||||
<field name="message_partner_ids"/>
|
||||
<field name="tag_ids"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
@@ -76,9 +76,9 @@
|
||||
<!-- title -->
|
||||
<field name="name"/>
|
||||
</span>
|
||||
<t t-if="record.message_follower_ids.raw_value.length > 1">
|
||||
<t t-if="record.message_partner_ids.raw_value.length > 1">
|
||||
<div class="clearfix"></div>
|
||||
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
|
||||
<t t-foreach="record.message_partner_ids.raw_value" t-as="follower">
|
||||
<img t-att-src="kanban_image('res.partner', 'image_small', follower)" width="24" height="24" class="oe_kanban_avatar pull-right" t-att-data-member_id="follower"/>
|
||||
</t>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
@@ -36,9 +36,9 @@ class AcquirerAdyen(osv.Model):
|
||||
return providers
|
||||
|
||||
_columns = {
|
||||
'adyen_merchant_account': fields.char('Merchant Account', required_if_provider='adyen'),
|
||||
'adyen_skin_code': fields.char('Skin Code', required_if_provider='adyen'),
|
||||
'adyen_skin_hmac_key': fields.char('Skin HMAC Key', required_if_provider='adyen'),
|
||||
'adyen_merchant_account': fields.char('Merchant Account', required_if_provider='adyen', groups='base.group_user'),
|
||||
'adyen_skin_code': fields.char('Skin Code', required_if_provider='adyen', groups='base.group_user'),
|
||||
'adyen_skin_hmac_key': fields.char('Skin HMAC Key', required_if_provider='adyen', groups='base.group_user'),
|
||||
}
|
||||
|
||||
def _adyen_generate_merchant_sig_sha256(self, acquirer, inout, values):
|
||||
|
||||
@@ -30,8 +30,8 @@ class PaymentAcquirerAuthorize(models.Model):
|
||||
providers.append(['authorize', 'Authorize.Net'])
|
||||
return providers
|
||||
|
||||
authorize_login = fields.Char(string='API Login Id', required_if_provider='authorize')
|
||||
authorize_transaction_key = fields.Char(string='API Transaction Key', required_if_provider='authorize')
|
||||
authorize_login = fields.Char(string='API Login Id', required_if_provider='authorize', groups='base.group_user')
|
||||
authorize_transaction_key = fields.Char(string='API Transaction Key', required_if_provider='authorize', groups='base.group_user')
|
||||
|
||||
def _authorize_generate_hashing(self, values):
|
||||
data = '^'.join([
|
||||
|
||||
@@ -44,8 +44,8 @@ class AcquirerBuckaroo(osv.Model):
|
||||
return providers
|
||||
|
||||
_columns = {
|
||||
'brq_websitekey': fields.char('WebsiteKey', required_if_provider='buckaroo'),
|
||||
'brq_secretkey': fields.char('SecretKey', required_if_provider='buckaroo'),
|
||||
'brq_websitekey': fields.char('WebsiteKey', required_if_provider='buckaroo', groups='base.group_user'),
|
||||
'brq_secretkey': fields.char('SecretKey', required_if_provider='buckaroo', groups='base.group_user'),
|
||||
}
|
||||
|
||||
def _buckaroo_generate_digital_sign(self, acquirer, inout, values):
|
||||
|
||||
@@ -47,11 +47,11 @@ class PaymentAcquirerOgone(osv.Model):
|
||||
return providers
|
||||
|
||||
_columns = {
|
||||
'ogone_pspid': fields.char('PSPID', required_if_provider='ogone'),
|
||||
'ogone_userid': fields.char('API User ID', required_if_provider='ogone'),
|
||||
'ogone_password': fields.char('API User Password', required_if_provider='ogone'),
|
||||
'ogone_shakey_in': fields.char('SHA Key IN', size=32, required_if_provider='ogone'),
|
||||
'ogone_shakey_out': fields.char('SHA Key OUT', size=32, required_if_provider='ogone'),
|
||||
'ogone_pspid': fields.char('PSPID', required_if_provider='ogone', groups='base.group_user'),
|
||||
'ogone_userid': fields.char('API User ID', required_if_provider='ogone', groups='base.group_user'),
|
||||
'ogone_password': fields.char('API User Password', required_if_provider='ogone', groups='base.group_user'),
|
||||
'ogone_shakey_in': fields.char('SHA Key IN', size=32, required_if_provider='ogone', groups='base.group_user'),
|
||||
'ogone_shakey_out': fields.char('SHA Key OUT', size=32, required_if_provider='ogone', groups='base.group_user'),
|
||||
'ogone_alias_usage': fields.char('Alias Usage', help="""If you want to use Ogone Aliases,
|
||||
this default Alias Usage will be presented to
|
||||
the customer as the reason you want to
|
||||
|
||||
@@ -39,17 +39,17 @@ class AcquirerPaypal(osv.Model):
|
||||
return providers
|
||||
|
||||
_columns = {
|
||||
'paypal_email_account': fields.char('Paypal Email ID', required_if_provider='paypal'),
|
||||
'paypal_email_account': fields.char('Paypal Email ID', required_if_provider='paypal', groups='base.group_user'),
|
||||
'paypal_seller_account': fields.char(
|
||||
'Paypal Merchant ID',
|
||||
'Paypal Merchant ID', groups='base.group_user',
|
||||
help='The Merchant ID is used to ensure communications coming from Paypal are valid and secured.'),
|
||||
'paypal_use_ipn': fields.boolean('Use IPN', help='Paypal Instant Payment Notification'),
|
||||
'paypal_use_ipn': fields.boolean('Use IPN', help='Paypal Instant Payment Notification', groups='base.group_user'),
|
||||
# Server 2 server
|
||||
'paypal_api_enabled': fields.boolean('Use Rest API'),
|
||||
'paypal_api_username': fields.char('Rest API Username'),
|
||||
'paypal_api_password': fields.char('Rest API Password'),
|
||||
'paypal_api_access_token': fields.char('Access Token'),
|
||||
'paypal_api_access_token_validity': fields.datetime('Access Token Validity'),
|
||||
'paypal_api_username': fields.char('Rest API Username', groups='base.group_user'),
|
||||
'paypal_api_password': fields.char('Rest API Password', groups='base.group_user'),
|
||||
'paypal_api_access_token': fields.char('Access Token', groups='base.group_user'),
|
||||
'paypal_api_access_token_validity': fields.datetime('Access Token Validity', groups='base.group_user'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
||||
@@ -32,7 +32,7 @@ class SipsController(http.Controller):
|
||||
|
||||
sips = acquirer_obj.search([('provider', '=', 'sips')], limit=1)
|
||||
|
||||
security = sips._sips_generate_shasign(post)
|
||||
security = sips.sudo()._sips_generate_shasign(post)
|
||||
if security == post['Seal']:
|
||||
_logger.debug('Sips: validated data')
|
||||
res = tx_obj.sudo().form_feedback(post, 'sips')
|
||||
|
||||
@@ -38,8 +38,8 @@ class AcquirerSips(models.Model):
|
||||
_inherit = 'payment.acquirer'
|
||||
# Fields
|
||||
sips_merchant_id = fields.Char('SIPS API User Password',
|
||||
required_if_provider='sips')
|
||||
sips_secret = fields.Char('SIPS Secret', size=64, required_if_provider='sips')
|
||||
required_if_provider='sips', groups='base.group_user')
|
||||
sips_secret = fields.Char('SIPS Secret', size=64, required_if_provider='sips', groups='base.group_user')
|
||||
|
||||
# Methods
|
||||
def _get_sips_urls(self, environment):
|
||||
|
||||
@@ -1337,13 +1337,14 @@ exports.Orderline = Backbone.Model.extend({
|
||||
},
|
||||
compute_all: function(taxes, price_unit, quantity, currency_rounding) {
|
||||
var self = this;
|
||||
var total_excluded = round_pr(price_unit * quantity, currency_rounding);
|
||||
var total_included = total_excluded;
|
||||
var base = total_excluded;
|
||||
var list_taxes = [];
|
||||
var currency_rounding_bak = currency_rounding;
|
||||
if (this.pos.company.tax_calculation_rounding_method == "round_globally"){
|
||||
currency_rounding = currency_rounding * 0.00001;
|
||||
}
|
||||
var total_excluded = round_pr(price_unit * quantity, currency_rounding);
|
||||
var total_included = total_excluded;
|
||||
var base = total_excluded;
|
||||
_(taxes).each(function(tax) {
|
||||
tax = self._map_tax_fiscal_position(tax);
|
||||
if (tax.amount_type === 'group'){
|
||||
@@ -1377,7 +1378,11 @@ exports.Orderline = Backbone.Model.extend({
|
||||
}
|
||||
}
|
||||
});
|
||||
return {taxes: list_taxes, total_excluded: total_excluded, total_included: total_included};
|
||||
return {
|
||||
taxes: list_taxes,
|
||||
total_excluded: round_pr(total_excluded, currency_rounding_bak),
|
||||
total_included: round_pr(total_included, currency_rounding_bak)
|
||||
};
|
||||
},
|
||||
get_all_prices: function(){
|
||||
var price_unit = this.get_unit_price() * (1.0 - (this.get_discount() / 100.0));
|
||||
|
||||
@@ -232,6 +232,7 @@ class sale_order_line(osv.osv):
|
||||
result['warning'] = warning
|
||||
return result
|
||||
|
||||
@api.multi
|
||||
@api.onchange('product_id')
|
||||
def product_id_change(self):
|
||||
warning = self.onchange_product_id_warning()
|
||||
|
||||
@@ -98,7 +98,7 @@ def ensure_db(redirect='/web/database/selector'):
|
||||
# If the db is taken out of a query parameter, it will be checked against
|
||||
# `http.db_filter()` in order to ensure it's legit and thus avoid db
|
||||
# forgering that could lead to xss attacks.
|
||||
db = request.params.get('db')
|
||||
db = request.params.get('db') and request.params.get('db').strip()
|
||||
|
||||
# Ensure db is legit
|
||||
if db and db not in http.db_filter([db]):
|
||||
|
||||
@@ -710,6 +710,13 @@ var DataSetSearch = DataSet.extend({
|
||||
this._length -= (before - this.ids.length);
|
||||
}
|
||||
},
|
||||
add_ids: function(ids, at) {
|
||||
var before = this.ids.length;
|
||||
this._super(ids, at);
|
||||
if(this._length){
|
||||
this._length += (this.ids.length - before);
|
||||
}
|
||||
},
|
||||
unlink: function(ids, callback, error_callback) {
|
||||
var self = this;
|
||||
return this._super(ids).done(function() {
|
||||
|
||||
@@ -116,6 +116,7 @@ var KanbanColumn = Widget.extend({
|
||||
} else {
|
||||
// adding record to this column
|
||||
self.records.push(record);
|
||||
self.dataset.add_ids([record.id]);
|
||||
record.setParent(self);
|
||||
ui.item.addClass('o_updating');
|
||||
self.trigger_up('kanban_column_add_record', {record: record});
|
||||
|
||||
@@ -527,9 +527,7 @@ var KanbanView = View.extend({
|
||||
active_ids: [event.target.id],
|
||||
active_model: this.dataset.model,
|
||||
});
|
||||
this.do_execute_action(event.data, this.dataset, event.target.id).then(function () {
|
||||
self.reload_record(event.target);
|
||||
});
|
||||
this.do_execute_action(event.data, this.dataset, event.target.id, _.bind(self.reload_record, this, event.target));
|
||||
},
|
||||
|
||||
/*
|
||||
|
||||
@@ -106,35 +106,30 @@ options.registry.slider = options.Class.extend({
|
||||
},0);
|
||||
return $clone;
|
||||
},
|
||||
remove_slide: function (type, value) {
|
||||
if(type !== "click") return;
|
||||
|
||||
if (this.remove_process) {
|
||||
return;
|
||||
}
|
||||
remove_slide: function (type) {
|
||||
if (type !== "click" || this.remove_process) return;
|
||||
var self = this;
|
||||
var new_index = 0;
|
||||
var cycle = this.$inner.find('.item').length - 1;
|
||||
var index = this.$inner.find('.item.active').index();
|
||||
|
||||
var $items = this.$inner.find('.item');
|
||||
var cycle = $items.length - 1;
|
||||
var $active = $items.filter('.active');
|
||||
var index = $active.index();
|
||||
|
||||
if (cycle > 0) {
|
||||
this.remove_process = true;
|
||||
var $el = this.$inner.find('.item.active');
|
||||
self.$target.on('slid.bs.carousel', function (event) {
|
||||
$el.remove();
|
||||
this.$target.on('slid.bs.carousel.slide_removal', function (event) {
|
||||
$active.remove();
|
||||
self.$indicators.find("li:last").remove();
|
||||
self.$target.off('slid.bs.carousel');
|
||||
self.$target.off('slid.bs.carousel.slide_removal');
|
||||
self.rebind_event();
|
||||
self.remove_process = false;
|
||||
if (cycle == 1) {
|
||||
self.on_remove_slide(event);
|
||||
if (cycle === 1) {
|
||||
self.$target.find('.carousel-control, .carousel-indicators').addClass("hidden");
|
||||
}
|
||||
});
|
||||
setTimeout(function () {
|
||||
self.$target.carousel( index > 0 ? --index : cycle );
|
||||
}, 500);
|
||||
} else {
|
||||
this.$target.find('.carousel-control, .carousel-indicators').addClass("hidden");
|
||||
_.defer(function () {
|
||||
self.$target.carousel(index > 0 ? --index : cycle);
|
||||
});
|
||||
}
|
||||
},
|
||||
interval : function (type, value) {
|
||||
|
||||
@@ -46,7 +46,7 @@ class website_payment(http.Controller):
|
||||
|
||||
partner_id = user.partner_id.id if user.partner_id.id != request.website.partner_id.id else False
|
||||
|
||||
payment_form = acquirer.render(reference, float(amount), currency.id, values={'return_url': '/website_payment/confirm', 'partner_id': partner_id})[0]
|
||||
payment_form = acquirer.sudo().render(reference, float(amount), currency.id, values={'return_url': '/website_payment/confirm', 'partner_id': partner_id})[0]
|
||||
values = {
|
||||
'reference': reference,
|
||||
'acquirer': acquirer,
|
||||
|
||||
@@ -97,6 +97,9 @@ $('.oe_website_sale').each(function () {
|
||||
$inputs.each(function () {
|
||||
$(this).val( data[$(this).attr("name")] || "" );
|
||||
});
|
||||
|
||||
$selects.filter('[name="shipping_country_id"]').val(data['shipping_country_id']).change();
|
||||
$selects.filter('[name="shipping_state_id"]').val(data['shipping_state_id']);
|
||||
});
|
||||
|
||||
$(oe_website_sale).on("change", 'input[name="add_qty"]', function (event) {
|
||||
@@ -332,7 +335,7 @@ $('.oe_website_sale').each(function () {
|
||||
$('input.js_variant_change, select.js_variant_change', this).first().trigger('change');
|
||||
});
|
||||
|
||||
var state_options = $("select[name='state_id']:enabled option:not(:first)");
|
||||
var state_options = $("select[name='state_id'] option:not(:first)");
|
||||
$(oe_website_sale).on('change', "select[name='country_id']", function () {
|
||||
var select = $("select[name='state_id']");
|
||||
state_options.detach();
|
||||
@@ -342,7 +345,7 @@ $('.oe_website_sale').each(function () {
|
||||
});
|
||||
$(oe_website_sale).find("select[name='country_id']").change();
|
||||
|
||||
var shipping_state_options = $("select[name='shipping_state_id']:enabled option:not(:first)");
|
||||
var shipping_state_options = $("select[name='shipping_state_id'] option:not(:first)");
|
||||
$(oe_website_sale).on('change', "select[name='shipping_country_id']", function () {
|
||||
var select = $("select[name='shipping_state_id']");
|
||||
shipping_state_options.detach();
|
||||
|
||||
+2
-2
@@ -1460,7 +1460,7 @@ class BaseModel(object):
|
||||
|
||||
def _get_default_form_view(self, cr, user, context=None):
|
||||
""" Generates a default single-line form view using all fields
|
||||
of the current model except the m2m and o2m ones.
|
||||
of the current model.
|
||||
|
||||
:param cr: database cursor
|
||||
:param int user: user id
|
||||
@@ -1471,7 +1471,7 @@ class BaseModel(object):
|
||||
view = etree.Element('form', string=self._description)
|
||||
group = etree.SubElement(view, 'group', col="4")
|
||||
for fname, field in self._fields.iteritems():
|
||||
if field.automatic or field.type in ('one2many', 'many2many'):
|
||||
if field.automatic:
|
||||
continue
|
||||
|
||||
etree.SubElement(group, 'field', name=fname)
|
||||
|
||||
Reference in New Issue
Block a user