[MERGE] forward port branch saas-11 up to 1730dca101
This commit is contained in:
@@ -414,12 +414,11 @@ class AccountBankStatementLine(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def button_cancel_reconciliation(self):
|
def button_cancel_reconciliation(self):
|
||||||
moves_to_unbind = self.env['account.move']
|
|
||||||
moves_to_cancel = self.env['account.move']
|
moves_to_cancel = self.env['account.move']
|
||||||
payment_to_unreconcile = self.env['account.payment']
|
payment_to_unreconcile = self.env['account.payment']
|
||||||
payment_to_cancel = self.env['account.payment']
|
payment_to_cancel = self.env['account.payment']
|
||||||
for st_line in self:
|
for st_line in self:
|
||||||
moves_to_unbind |= st_line.journal_entry_ids
|
moves_to_unbind = st_line.journal_entry_ids
|
||||||
for move in st_line.journal_entry_ids:
|
for move in st_line.journal_entry_ids:
|
||||||
for line in move.line_ids:
|
for line in move.line_ids:
|
||||||
payment_to_unreconcile |= line.payment_id
|
payment_to_unreconcile |= line.payment_id
|
||||||
@@ -427,13 +426,15 @@ class AccountBankStatementLine(models.Model):
|
|||||||
#there can be several moves linked to a statement line but maximum one created by the line itself
|
#there can be several moves linked to a statement line but maximum one created by the line itself
|
||||||
moves_to_cancel |= st_line.journal_entry_ids
|
moves_to_cancel |= st_line.journal_entry_ids
|
||||||
payment_to_cancel |= line.payment_id
|
payment_to_cancel |= line.payment_id
|
||||||
moves_to_unbind = moves_to_unbind - moves_to_cancel
|
|
||||||
payment_to_unreconcile = payment_to_unreconcile - payment_to_cancel
|
|
||||||
|
|
||||||
if moves_to_unbind:
|
moves_to_unbind = moves_to_unbind - moves_to_cancel
|
||||||
moves_to_unbind.write({'statement_line_id': False})
|
|
||||||
for move in moves_to_unbind:
|
if moves_to_unbind:
|
||||||
move.line_ids.filtered(lambda x:x.statement_id == st_line.statement_id).write({'statement_id': False})
|
moves_to_unbind.write({'statement_line_id': False})
|
||||||
|
for move in moves_to_unbind:
|
||||||
|
move.line_ids.filtered(lambda x: x.statement_id == st_line.statement_id).write({'statement_id': False})
|
||||||
|
|
||||||
|
payment_to_unreconcile = payment_to_unreconcile - payment_to_cancel
|
||||||
if payment_to_unreconcile:
|
if payment_to_unreconcile:
|
||||||
payment_to_unreconcile.unreconcile()
|
payment_to_unreconcile.unreconcile()
|
||||||
|
|
||||||
@@ -755,7 +756,7 @@ class AccountBankStatementLine(models.Model):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
def _prepare_reconciliation_move_line(self, move, amount):
|
def _prepare_reconciliation_move_line(self, move, amount):
|
||||||
""" Prepare the dict of values to create the move line from a statement line.
|
""" Prepare the dict of values to balance the move.
|
||||||
|
|
||||||
:param recordset move: the account.move to link the move line
|
:param recordset move: the account.move to link the move line
|
||||||
:param float amount: the amount of transaction that wasn't already reconciled
|
:param float amount: the amount of transaction that wasn't already reconciled
|
||||||
@@ -763,25 +764,29 @@ class AccountBankStatementLine(models.Model):
|
|||||||
company_currency = self.journal_id.company_id.currency_id
|
company_currency = self.journal_id.company_id.currency_id
|
||||||
statement_currency = self.journal_id.currency_id or company_currency
|
statement_currency = self.journal_id.currency_id or company_currency
|
||||||
st_line_currency = self.currency_id or statement_currency
|
st_line_currency = self.currency_id or statement_currency
|
||||||
|
|
||||||
amount_currency = False
|
amount_currency = False
|
||||||
if statement_currency != company_currency or st_line_currency != company_currency:
|
st_line_currency_rate = self.currency_id and (self.amount_currency / self.amount) or False
|
||||||
# First get the ratio total mount / amount not already reconciled
|
# We have several use case here to compure the currency and amount currency of counterpart line to balance the move:
|
||||||
if statement_currency == company_currency:
|
if st_line_currency != company_currency and st_line_currency == statement_currency:
|
||||||
total_amount = self.amount
|
# company in currency A, statement in currency B and transaction in currency B
|
||||||
elif st_line_currency == company_currency:
|
# counterpart line must have currency B and correct amount is inverse of already existing lines
|
||||||
total_amount = self.amount_currency
|
amount_currency = -sum([x.amount_currency for x in move.line_ids])
|
||||||
else:
|
elif st_line_currency != company_currency and statement_currency == company_currency:
|
||||||
total_amount = statement_currency.with_context({'date': self.date}).compute(self.amount, company_currency, round=False)
|
# company in currency A, statement in currency A and transaction in currency B
|
||||||
if float_compare(total_amount, amount, precision_digits=company_currency.rounding) == 0:
|
# counterpart line must have currency B and correct amount is inverse of already existing lines
|
||||||
ratio = 1.0
|
amount_currency = -sum([x.amount_currency for x in move.line_ids])
|
||||||
else:
|
elif st_line_currency != company_currency and st_line_currency != statement_currency:
|
||||||
ratio = total_amount / amount
|
# company in currency A, statement in currency B and transaction in currency C
|
||||||
# Then use it to adjust the statement.line field that correspond to the move.line amount_currency
|
# counterpart line must have currency B and use rate between B and C to compute correct amount
|
||||||
if statement_currency != company_currency:
|
amount_currency = -sum([x.amount_currency for x in move.line_ids])/st_line_currency_rate
|
||||||
amount_currency = self.amount * ratio
|
elif st_line_currency == company_currency and statement_currency != company_currency:
|
||||||
elif st_line_currency != company_currency:
|
# company in currency A, statement in currency B and transaction in currency A
|
||||||
amount_currency = self.amount_currency * ratio
|
# counterpart line must have currency B and amount is computed using the rate between A and B
|
||||||
|
amount_currency = amount/st_line_currency_rate
|
||||||
|
|
||||||
|
# last case is company in currency A, statement in currency A and transaction in currency A
|
||||||
|
# and in this case counterpart line does not need any second currency nor amount_currency
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'move_id': move.id,
|
'move_id': move.id,
|
||||||
@@ -985,8 +990,7 @@ class AccountBankStatementLine(models.Model):
|
|||||||
|
|
||||||
(new_aml | counterpart_move_line).reconcile()
|
(new_aml | counterpart_move_line).reconcile()
|
||||||
|
|
||||||
# Create the move line for the statement line using the bank statement line as the remaining amount
|
# Balance the move
|
||||||
# This leaves out the amount already reconciled and avoids rounding errors from currency conversion
|
|
||||||
st_line_amount = -sum([x.balance for x in move.line_ids])
|
st_line_amount = -sum([x.balance for x in move.line_ids])
|
||||||
aml_dict = self._prepare_reconciliation_move_line(move, st_line_amount)
|
aml_dict = self._prepare_reconciliation_move_line(move, st_line_amount)
|
||||||
aml_dict['payment_id'] = payment and payment.id or False
|
aml_dict['payment_id'] = payment and payment.id or False
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class AccountInvoice(models.Model):
|
|||||||
_order = "date_invoice desc, number desc, id desc"
|
_order = "date_invoice desc, number desc, id desc"
|
||||||
|
|
||||||
@api.one
|
@api.one
|
||||||
@api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'currency_id', 'company_id', 'date_invoice')
|
@api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'currency_id', 'company_id', 'date_invoice', 'type')
|
||||||
def _compute_amount(self):
|
def _compute_amount(self):
|
||||||
self.amount_untaxed = sum(line.price_subtotal for line in self.invoice_line_ids)
|
self.amount_untaxed = sum(line.price_subtotal for line in self.invoice_line_ids)
|
||||||
self.amount_tax = sum(line.amount for line in self.tax_line_ids)
|
self.amount_tax = sum(line.amount for line in self.tax_line_ids)
|
||||||
@@ -74,7 +74,7 @@ class AccountInvoice(models.Model):
|
|||||||
@api.model
|
@api.model
|
||||||
def _default_currency(self):
|
def _default_currency(self):
|
||||||
journal = self._default_journal()
|
journal = self._default_journal()
|
||||||
return journal.currency_id or journal.company_id.currency_id
|
return journal.currency_id or journal.company_id.currency_id or self.env.user.company_id.currency_id
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _get_reference_type(self):
|
def _get_reference_type(self):
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class account_abstract_payment(models.AbstractModel):
|
|||||||
|
|
||||||
def _compute_total_invoices_amount(self):
|
def _compute_total_invoices_amount(self):
|
||||||
""" Compute the sum of the residual of invoices, expressed in the payment currency """
|
""" Compute the sum of the residual of invoices, expressed in the payment currency """
|
||||||
payment_currency = self.currency_id or self.journal_id.currency_id or self.journal_id.company_id.currency_id
|
payment_currency = self.currency_id or self.journal_id.currency_id or self.journal_id.company_id.currency_id or self.env.user.company_id.currency_id
|
||||||
invoices = self._get_invoices()
|
invoices = self._get_invoices()
|
||||||
|
|
||||||
if all(inv.currency_id == payment_currency for inv in invoices):
|
if all(inv.currency_id == payment_currency for inv in invoices):
|
||||||
|
|||||||
@@ -402,3 +402,75 @@ class TestReconciliation(AccountingTestCase):
|
|||||||
self.assertTrue(aml.reconciled, 'The journal item should be totally reconciled')
|
self.assertTrue(aml.reconciled, 'The journal item should be totally reconciled')
|
||||||
self.assertEquals(aml.amount_residual, 0, 'The journal item should be totally reconciled')
|
self.assertEquals(aml.amount_residual, 0, 'The journal item should be totally reconciled')
|
||||||
self.assertEquals(aml.amount_residual_currency, 0, 'The journal item should be totally reconciled')
|
self.assertEquals(aml.amount_residual_currency, 0, 'The journal item should be totally reconciled')
|
||||||
|
|
||||||
|
def test_reconcile_bank_statement_with_payment_and_writeoff(self):
|
||||||
|
# Use case:
|
||||||
|
# Company is in EUR, create a bill for 80 USD and register payment of 80 USD.
|
||||||
|
# create a bank statement in USD bank journal with a bank statement line of 85 USD
|
||||||
|
# Reconcile bank statement with payment and put the remaining 5 USD in bank fees or another account.
|
||||||
|
|
||||||
|
invoice = self.create_invoice(type='out_invoice', invoice_amount=80, currency_id=self.currency_usd_id)
|
||||||
|
# register payment on invoice
|
||||||
|
payment = self.env['account.payment'].create({'payment_type': 'inbound',
|
||||||
|
'payment_method_id': self.env.ref('account.account_payment_method_manual_in').id,
|
||||||
|
'partner_type': 'customer',
|
||||||
|
'partner_id': self.partner_agrolait_id,
|
||||||
|
'amount': 80,
|
||||||
|
'currency_id': self.currency_usd_id,
|
||||||
|
'payment_date': time.strftime('%Y') + '-07-15',
|
||||||
|
'journal_id': self.bank_journal_usd.id,
|
||||||
|
})
|
||||||
|
payment.post()
|
||||||
|
payment_move_line = False
|
||||||
|
bank_move_line = False
|
||||||
|
for l in payment.move_line_ids:
|
||||||
|
if l.account_id.id == self.account_rcv.id:
|
||||||
|
payment_move_line = l
|
||||||
|
else:
|
||||||
|
bank_move_line = l
|
||||||
|
invoice.register_payment(payment_move_line)
|
||||||
|
|
||||||
|
# create bank statement
|
||||||
|
bank_stmt = self.acc_bank_stmt_model.create({
|
||||||
|
'journal_id': self.bank_journal_usd.id,
|
||||||
|
'date': time.strftime('%Y') + '-07-15',
|
||||||
|
})
|
||||||
|
|
||||||
|
bank_stmt_line = self.acc_bank_stmt_line_model.create({'name': 'payment',
|
||||||
|
'statement_id': bank_stmt.id,
|
||||||
|
'partner_id': self.partner_agrolait_id,
|
||||||
|
'amount': 85,
|
||||||
|
'date': time.strftime('%Y') + '-07-15',})
|
||||||
|
|
||||||
|
#reconcile the statement with invoice and put remaining in another account
|
||||||
|
bank_stmt_line.process_reconciliation(payment_aml_rec= bank_move_line, new_aml_dicts=[{
|
||||||
|
'account_id': self.diff_income_account.id,
|
||||||
|
'debit': 0,
|
||||||
|
'credit': 5,
|
||||||
|
'name': 'bank fees',
|
||||||
|
}])
|
||||||
|
|
||||||
|
# Check that move lines associated to bank_statement are correct
|
||||||
|
bank_stmt_aml = self.env['account.move.line'].search([('statement_id', '=', bank_stmt.id)])
|
||||||
|
bank_stmt_aml |= bank_stmt_aml.mapped('move_id').mapped('line_ids')
|
||||||
|
self.assertEquals(len(bank_stmt_aml), 4, "The bank statement should have 4 moves lines")
|
||||||
|
lines = {
|
||||||
|
self.account_usd.id: [
|
||||||
|
{'debit': 3.27, 'credit': 0.0, 'amount_currency': 5, 'currency_id': self.currency_usd_id},
|
||||||
|
{'debit': 52.33, 'credit': 0, 'amount_currency': 80, 'currency_id': self.currency_usd_id}
|
||||||
|
],
|
||||||
|
self.diff_income_account.id: {'debit': 0.0, 'credit': 3.27, 'amount_currency': -5, 'currency_id': self.currency_usd_id},
|
||||||
|
self.account_rcv.id: {'debit': 0.0, 'credit': 52.33, 'amount_currency': -80, 'currency_id': self.currency_usd_id},
|
||||||
|
}
|
||||||
|
for aml in bank_stmt_aml:
|
||||||
|
line = lines[aml.account_id.id]
|
||||||
|
if type(line) == list:
|
||||||
|
# find correct line inside the list
|
||||||
|
if line[0]['debit'] == round(aml.debit, 2):
|
||||||
|
line = line[0]
|
||||||
|
else:
|
||||||
|
line = line[1]
|
||||||
|
self.assertEquals(round(aml.debit, 2), line['debit'])
|
||||||
|
self.assertEquals(round(aml.credit, 2), line['credit'])
|
||||||
|
self.assertEquals(round(aml.amount_currency, 2), line['amount_currency'])
|
||||||
|
self.assertEquals(aml.currency_id.id, line['currency_id'])
|
||||||
@@ -257,6 +257,7 @@ class AccountVoucher(models.Model):
|
|||||||
'date': self.account_date,
|
'date': self.account_date,
|
||||||
'tax_ids': [(4,t.id) for t in line.tax_ids],
|
'tax_ids': [(4,t.id) for t in line.tax_ids],
|
||||||
'amount_currency': line.price_subtotal if current_currency != company_currency else 0.0,
|
'amount_currency': line.price_subtotal if current_currency != company_currency else 0.0,
|
||||||
|
'currency_id': company_currency != current_currency and current_currency or False,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.env['account.move.line'].with_context(apply_taxes=True).create(move_line)
|
self.env['account.move.line'].with_context(apply_taxes=True).create(move_line)
|
||||||
@@ -282,7 +283,7 @@ class AccountVoucher(models.Model):
|
|||||||
move = self.env['account.move'].create(voucher.account_move_get())
|
move = self.env['account.move'].create(voucher.account_move_get())
|
||||||
# Get the name of the account_move just created
|
# Get the name of the account_move just created
|
||||||
# Create the first line of the voucher
|
# Create the first line of the voucher
|
||||||
move_line = self.env['account.move.line'].with_context(ctx).create(voucher.first_move_line_get(move.id, company_currency, current_currency))
|
move_line = self.env['account.move.line'].with_context(ctx).create(voucher.with_context(ctx).first_move_line_get(move.id, company_currency, current_currency))
|
||||||
line_total = move_line.debit - move_line.credit
|
line_total = move_line.debit - move_line.credit
|
||||||
if voucher.voucher_type == 'sale':
|
if voucher.voucher_type == 'sale':
|
||||||
line_total = line_total - voucher._convert_amount(voucher.tax_amount)
|
line_total = line_total - voucher._convert_amount(voucher.tax_amount)
|
||||||
|
|||||||
@@ -404,7 +404,9 @@ class HrPayslip(models.Model):
|
|||||||
def _sum_salary_rule_category(localdict, category, amount):
|
def _sum_salary_rule_category(localdict, category, amount):
|
||||||
if category.parent_id:
|
if category.parent_id:
|
||||||
localdict = _sum_salary_rule_category(localdict, category.parent_id, amount)
|
localdict = _sum_salary_rule_category(localdict, category.parent_id, amount)
|
||||||
localdict['categories'].dict[category.code] = category.code in localdict['categories'].dict and localdict['categories'].dict[category.code] + amount or amount
|
if category.code in localdict['categories'].dict:
|
||||||
|
amount += localdict['categories'].dict[category.code]
|
||||||
|
localdict['categories'].dict[category.code] = amount
|
||||||
return localdict
|
return localdict
|
||||||
|
|
||||||
class BrowsableObject(object):
|
class BrowsableObject(object):
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<field name="bank_account_code_prefix">1</field>
|
<field name="bank_account_code_prefix">1</field>
|
||||||
<field name="cash_account_code_prefix">1</field>
|
<field name="cash_account_code_prefix">1</field>
|
||||||
<field name="code_digits">6</field>
|
<field name="code_digits">6</field>
|
||||||
<field name="currency_id" ref="base.EGP"/>
|
<field name="currency_id" ref="base.SAR"/>
|
||||||
<field name="transfer_account_id" ref="transfer_account"/>
|
<field name="transfer_account_id" ref="transfer_account"/>
|
||||||
<field name="spoken_languages" eval="'en_US;ar_EG;ar_SY'"/>
|
<field name="spoken_languages" eval="'en_US;ar_EG;ar_SY'"/>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from lxml import html
|
|||||||
from urllib2 import urlopen
|
from urllib2 import urlopen
|
||||||
from urlparse import urljoin
|
from urlparse import urljoin
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
from werkzeug import url_encode
|
from werkzeug import url_encode, unescape
|
||||||
|
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.tools import ustr
|
from odoo.tools import ustr
|
||||||
@@ -56,7 +56,7 @@ class link_tracker(models.Model):
|
|||||||
href = match[0]
|
href = match[0]
|
||||||
long_url = match[1]
|
long_url = match[1]
|
||||||
|
|
||||||
vals['url'] = long_url
|
vals['url'] = unescape(long_url)
|
||||||
|
|
||||||
if not blacklist or not [s for s in blacklist if s in long_url] and not long_url.startswith(short_schema):
|
if not blacklist or not [s for s in blacklist if s in long_url] and not long_url.startswith(short_schema):
|
||||||
link = self.create(vals)
|
link = self.create(vals)
|
||||||
|
|||||||
@@ -746,7 +746,7 @@ class PosOrderLine(models.Model):
|
|||||||
return line
|
return line
|
||||||
|
|
||||||
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id)
|
company_id = fields.Many2one('res.company', string='Company', required=True, default=lambda self: self.env.user.company_id)
|
||||||
name = fields.Char(string='Line No', required=True, copy=False, default=lambda self: self.env['ir.sequence'].next_by_code('pos.order.line'))
|
name = fields.Char(string='Line No', required=True, copy=False)
|
||||||
notice = fields.Char(string='Discount Notice')
|
notice = fields.Char(string='Discount Notice')
|
||||||
product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], required=True, change_default=True)
|
product_id = fields.Many2one('product.product', string='Product', domain=[('sale_ok', '=', True)], required=True, change_default=True)
|
||||||
price_unit = fields.Float(string='Unit Price', digits=0)
|
price_unit = fields.Float(string='Unit Price', digits=0)
|
||||||
@@ -760,6 +760,31 @@ class PosOrderLine(models.Model):
|
|||||||
tax_ids_after_fiscal_position = fields.Many2many('account.tax', compute='_get_tax_ids_after_fiscal_position', string='Taxes')
|
tax_ids_after_fiscal_position = fields.Many2many('account.tax', compute='_get_tax_ids_after_fiscal_position', string='Taxes')
|
||||||
pack_lot_ids = fields.One2many('pos.pack.operation.lot', 'pos_order_line_id', string='Lot/serial Number')
|
pack_lot_ids = fields.One2many('pos.pack.operation.lot', 'pos_order_line_id', string='Lot/serial Number')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def create(self, values):
|
||||||
|
if values.get('order_id') and not values.get('name'):
|
||||||
|
# set name based on the sequence specified on the config
|
||||||
|
config_id = self.env['pos.order'].browse(values['order_id']).session_id.config_id.id
|
||||||
|
# HACK: sequence created in the same transaction as the config
|
||||||
|
# cf TODO master is pos.config create
|
||||||
|
# remove me saas-15
|
||||||
|
self.env.cr.execute("""
|
||||||
|
SELECT s.id
|
||||||
|
FROM ir_sequence s
|
||||||
|
JOIN pos_config c
|
||||||
|
ON s.create_date=c.create_date
|
||||||
|
WHERE c.id = %s
|
||||||
|
AND s.code = 'pos.order.line'
|
||||||
|
LIMIT 1
|
||||||
|
""", (config_id,))
|
||||||
|
sequence = self.env.cr.fetchone()
|
||||||
|
if sequence:
|
||||||
|
values['name'] = self.env['ir.sequence'].browse(sequence[0])._next()
|
||||||
|
if not values.get('name'):
|
||||||
|
# fallback on any pos.order sequence
|
||||||
|
values['name'] = self.env['ir.sequence'].next_by_code('pos.order.line')
|
||||||
|
return super(PosOrderLine, self).create(values)
|
||||||
|
|
||||||
@api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'product_id')
|
@api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'product_id')
|
||||||
def _compute_amount_line_all(self):
|
def _compute_amount_line_all(self):
|
||||||
for line in self:
|
for line in self:
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 357 B |
Binary file not shown.
|
After Width: | Height: | Size: 303 B |
@@ -30,7 +30,7 @@ class ProductTemplate(models.Model):
|
|||||||
def action_view_sales(self):
|
def action_view_sales(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
action = self.env.ref('sale.action_product_sale_list')
|
action = self.env.ref('sale.action_product_sale_list')
|
||||||
product_ids = self.product_variant_ids.ids
|
product_ids = self.with_context(active_test=False).product_variant_ids.ids
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': action.name,
|
'name': action.name,
|
||||||
|
|||||||
@@ -905,13 +905,18 @@ class SaleOrderLine(models.Model):
|
|||||||
PricelistItem = self.env['product.pricelist.item']
|
PricelistItem = self.env['product.pricelist.item']
|
||||||
field_name = 'lst_price'
|
field_name = 'lst_price'
|
||||||
currency_id = None
|
currency_id = None
|
||||||
|
product_currency = None
|
||||||
if rule_id:
|
if rule_id:
|
||||||
pricelist_item = PricelistItem.browse(rule_id)
|
pricelist_item = PricelistItem.browse(rule_id)
|
||||||
if pricelist_item.base == 'standard_price':
|
if pricelist_item.base == 'standard_price':
|
||||||
field_name = 'standard_price'
|
field_name = 'standard_price'
|
||||||
|
if pricelist_item.base == 'pricelist' and pricelist_item.base_pricelist_id:
|
||||||
|
field_name = 'price'
|
||||||
|
product = product.with_context(pricelist=pricelist_item.base_pricelist_id.id)
|
||||||
|
product_currency = pricelist_item.base_pricelist_id.currency_id
|
||||||
currency_id = pricelist_item.pricelist_id.currency_id
|
currency_id = pricelist_item.pricelist_id.currency_id
|
||||||
|
|
||||||
product_currency = (product.company_id and product.company_id.currency_id) or self.env.user.company_id.currency_id
|
product_currency = product_currency or(product.company_id and product.company_id.currency_id) or self.env.user.company_id.currency_id
|
||||||
if not currency_id:
|
if not currency_id:
|
||||||
currency_id = product_currency
|
currency_id = product_currency
|
||||||
cur_factor = 1.0
|
cur_factor = 1.0
|
||||||
|
|||||||
@@ -1,5 +1,20 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
import models
|
from functools import partial
|
||||||
import report
|
import openerp
|
||||||
|
from openerp import api, SUPERUSER_ID
|
||||||
|
|
||||||
|
import models # noqa
|
||||||
|
import report # noqa
|
||||||
|
|
||||||
|
|
||||||
|
def uninstall_hook(cr, registry):
|
||||||
|
def recreate_view(dbname):
|
||||||
|
db_registry = openerp.modules.registry.RegistryManager.new(dbname)
|
||||||
|
with api.Environment.manage(), db_registry.cursor() as cr:
|
||||||
|
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||||
|
if 'sale.report' in env:
|
||||||
|
env['sale.report'].init()
|
||||||
|
|
||||||
|
cr.after("commit", partial(recreate_view, cr.dbname))
|
||||||
|
|||||||
@@ -15,4 +15,5 @@ Price and Cost Price.
|
|||||||
'depends':['sale'],
|
'depends':['sale'],
|
||||||
'demo':['data/sale_margin_demo.xml'],
|
'demo':['data/sale_margin_demo.xml'],
|
||||||
'data':['security/ir.model.access.csv','views/sale_margin_view.xml'],
|
'data':['security/ir.model.access.csv','views/sale_margin_view.xml'],
|
||||||
|
'uninstall_hook': "uninstall_hook",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -822,7 +822,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
<t t-name="FieldBinaryImage-img">
|
<t t-name="FieldBinaryImage-img">
|
||||||
<img t-att-src='url'
|
<img class="img img-responsive"
|
||||||
|
t-att-src='url'
|
||||||
t-att-border="widget.readonly ? 0 : 1"
|
t-att-border="widget.readonly ? 0 : 1"
|
||||||
t-att-name="widget.name"
|
t-att-name="widget.name"
|
||||||
t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
|
t-att-width="widget.node.attrs.img_width || widget.node.attrs.width"
|
||||||
|
|||||||
@@ -123,19 +123,28 @@ var KanbanView = View.extend({
|
|||||||
var self = this;
|
var self = this;
|
||||||
var group_by_field = group_by[0] || this.default_group_by;
|
var group_by_field = group_by[0] || this.default_group_by;
|
||||||
var field = this.fields_view.fields[group_by_field];
|
var field = this.fields_view.fields[group_by_field];
|
||||||
var grouped_by_m2o = field && (field.type === 'many2one');
|
var options = {};
|
||||||
|
var fields_def;
|
||||||
var options = {
|
if (field === undefined) {
|
||||||
search_domain: domain,
|
fields_def = data_manager.load_fields(this.dataset).then(function (fields) {
|
||||||
search_context: context,
|
self.fields = fields;
|
||||||
group_by_field: group_by_field,
|
field = self.fields[group_by_field];
|
||||||
grouped: group_by.length || this.default_group_by,
|
});
|
||||||
grouped_by_m2o: grouped_by_m2o,
|
}
|
||||||
relation: (grouped_by_m2o ? field.relation : undefined),
|
var load_def = $.when(fields_def).then(function() {
|
||||||
};
|
var grouped_by_m2o = field && (field.type === 'many2one');
|
||||||
|
options = _.extend(options, {
|
||||||
|
search_domain: domain,
|
||||||
|
search_context: context,
|
||||||
|
group_by_field: group_by_field,
|
||||||
|
grouped: group_by.length || self.default_group_by,
|
||||||
|
grouped_by_m2o: grouped_by_m2o,
|
||||||
|
relation: (grouped_by_m2o ? field.relation : undefined),
|
||||||
|
});
|
||||||
|
return options.grouped ? self.load_groups(options) : self.load_records();
|
||||||
|
});
|
||||||
return this.search_orderer
|
return this.search_orderer
|
||||||
.add(options.grouped ? this.load_groups(options) : this.load_records())
|
.add(load_def)
|
||||||
.then(function (data) {
|
.then(function (data) {
|
||||||
_.extend(self, options);
|
_.extend(self, options);
|
||||||
if (options.grouped) {
|
if (options.grouped) {
|
||||||
@@ -183,14 +192,7 @@ var KanbanView = View.extend({
|
|||||||
var group_by_field = options.group_by_field;
|
var group_by_field = options.group_by_field;
|
||||||
var fields_keys = _.uniq(this.fields_keys.concat(group_by_field));
|
var fields_keys = _.uniq(this.fields_keys.concat(group_by_field));
|
||||||
|
|
||||||
var fields_def;
|
return new Model(this.model, options.search_context, options.search_domain)
|
||||||
if (this.fields_view.fields[group_by_field] === undefined) {
|
|
||||||
fields_def = data_manager.load_fields(this.dataset).then(function (fields) {
|
|
||||||
self.fields = fields;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
var load_groups_def = new Model(this.model, options.search_context, options.search_domain)
|
|
||||||
.query(fields_keys)
|
.query(fields_keys)
|
||||||
.group_by([group_by_field])
|
.group_by([group_by_field])
|
||||||
.then(function (groups) {
|
.then(function (groups) {
|
||||||
@@ -293,7 +295,6 @@ var KanbanView = View.extend({
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return $.when(load_groups_def, fields_def);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
is_action_enabled: function(action) {
|
is_action_enabled: function(action) {
|
||||||
|
|||||||
@@ -710,7 +710,7 @@ Model Reference
|
|||||||
.. automethod:: fields_get
|
.. automethod:: fields_get
|
||||||
.. automethod:: fields_view_get
|
.. automethod:: fields_view_get
|
||||||
|
|
||||||
.. rubric:: ???
|
.. rubric:: Miscellaneous methods
|
||||||
|
|
||||||
.. automethod:: default_get
|
.. automethod:: default_get
|
||||||
.. automethod:: copy
|
.. automethod:: copy
|
||||||
|
|||||||
@@ -772,8 +772,6 @@ class IrModelRelation(models.Model):
|
|||||||
self._cr.execute('DROP TABLE %s CASCADE' % table,)
|
self._cr.execute('DROP TABLE %s CASCADE' % table,)
|
||||||
_logger.info('Dropped table %s', table)
|
_logger.info('Dropped table %s', table)
|
||||||
|
|
||||||
self._cr.commit()
|
|
||||||
|
|
||||||
|
|
||||||
class IrModelAccess(models.Model):
|
class IrModelAccess(models.Model):
|
||||||
_name = 'ir.model.access'
|
_name = 'ir.model.access'
|
||||||
@@ -1311,7 +1309,6 @@ class IrModelData(models.Model):
|
|||||||
|
|
||||||
undeletable += unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model')
|
undeletable += unlink_if_refcount(item for item in to_unlink if item[0] == 'ir.model')
|
||||||
|
|
||||||
self._cr.commit()
|
|
||||||
|
|
||||||
(datas - undeletable).unlink()
|
(datas - undeletable).unlink()
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ class Company(models.Model):
|
|||||||
for company in self.filtered(lambda company: company.partner_id):
|
for company in self.filtered(lambda company: company.partner_id):
|
||||||
address_data = company.partner_id.sudo().address_get(adr_pref=['contact'])
|
address_data = company.partner_id.sudo().address_get(adr_pref=['contact'])
|
||||||
if address_data['contact']:
|
if address_data['contact']:
|
||||||
partner = company.partner_id.browse(address_data['contact'])
|
partner = company.partner_id.browse(address_data['contact']).sudo()
|
||||||
company.street = partner.street
|
company.street = partner.street
|
||||||
company.street2 = partner.street2
|
company.street2 = partner.street2
|
||||||
company.city = partner.city
|
company.city = partner.city
|
||||||
|
|||||||
+6
-5
@@ -1219,13 +1219,14 @@ class Monetary(Field):
|
|||||||
_description_currency_field = property(attrgetter('currency_field'))
|
_description_currency_field = property(attrgetter('currency_field'))
|
||||||
_description_group_operator = property(attrgetter('group_operator'))
|
_description_group_operator = property(attrgetter('group_operator'))
|
||||||
|
|
||||||
def _setup_regular_base(self, model):
|
|
||||||
super(Monetary, self)._setup_regular_base(model)
|
|
||||||
if not self.currency_field:
|
|
||||||
self.currency_field = 'currency_id'
|
|
||||||
|
|
||||||
def _setup_regular_full(self, model):
|
def _setup_regular_full(self, model):
|
||||||
super(Monetary, self)._setup_regular_full(model)
|
super(Monetary, self)._setup_regular_full(model)
|
||||||
|
if not self.currency_field:
|
||||||
|
# pick a default, trying in order: 'currency_id', 'x_currency_id'
|
||||||
|
if 'currency_id' in model._fields:
|
||||||
|
self.currency_field = 'currency_id'
|
||||||
|
elif 'x_currency_id' in model._fields:
|
||||||
|
self.currency_field = 'x_currency_id'
|
||||||
assert self.currency_field in model._fields, \
|
assert self.currency_field in model._fields, \
|
||||||
"Field %s with unknown currency_field %r" % (self, self.currency_field)
|
"Field %s with unknown currency_field %r" % (self, self.currency_field)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user