Skip to content

Commit

Permalink
[MERGE] forward port branch 10.0 up to 6466aa4
Browse files Browse the repository at this point in the history
  • Loading branch information
KangOl committed Oct 19, 2016
2 parents 1f9e92d + 6466aa4 commit 938ffb9
Show file tree
Hide file tree
Showing 80 changed files with 956 additions and 408 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[![Build Status](http://runbot.odoo.com/runbot/badge/flat/1/master.svg)](http://runbot.odoo.com/runbot)
[![Tech Doc](http://img.shields.io/badge/master-docs-8f8f8f.svg?style=flat)](http://www.odoo.com/documentation/master)
[![Help](http://img.shields.io/badge/master-help-8f8f8f.svg?style=flat)](https://www.odoo.com/forum/help-1)
[![Nightly Builds](http://img.shields.io/badge/master-nightly-8f8f8f.svg?style=flat)](http://nightly.odoo.com/)
[![Tech Doc](http://img.shields.io/badge/master-docs-875A7B.svg?style=flat)](http://www.odoo.com/documentation/master)
[![Help](http://img.shields.io/badge/master-help-875A7B.svg?style=flat)](https://www.odoo.com/forum/help-1)
[![Nightly Builds](http://img.shields.io/badge/master-nightly-875A7B.svg?style=flat)](http://nightly.odoo.com/)

Odoo
----
Expand All @@ -27,14 +27,14 @@ a full-featured <a href="https://www.odoo.com">Open Source ERP</a> when you inst

Getting started with Odoo
-------------------------
For a standard installation please follow the <a href="https://www.odoo.com/documentation/9.0/setup/install.html">Setup instructions</a>
For a standard installation please follow the <a href="https://www.odoo.com/documentation/master/setup/install.html">Setup instructions</a>
from the documentation.

If you are a developer you may type the following command at your terminal:

wget -O- https://raw.githubusercontent.com/odoo/odoo/10.0/setup/setup_dev.py | python
wget -O- https://raw.githubusercontent.com/odoo/odoo/master/setup/setup_dev.py | python

Then follow <a href="https://www.odoo.com/documentation/9.0/tutorials.html">the developer tutorials</a>
Then follow <a href="https://www.odoo.com/documentation/master/tutorials.html">the developer tutorials</a>


For Odoo employees
Expand Down
4 changes: 4 additions & 0 deletions addons/account/models/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -731,13 +731,17 @@ def compute_all(self, price_unit, currency=None, quantity=1.0, product=None, par
else:
total_included += tax_amount

# Keep base amount used for the current tax
tax_base = base

if tax.include_base_amount:
base += tax_amount

taxes.append({
'id': tax.id,
'name': tax.with_context(**{'lang': partner.lang} if partner else {}).name,
'amount': tax_amount,
'base': tax_base,
'sequence': tax.sequence,
'account_id': tax.account_id.id,
'refund_account_id': tax.refund_account_id.id,
Expand Down
7 changes: 4 additions & 3 deletions addons/account/models/account_bank_statement.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ def button_journal_entries(self):
context = dict(self._context or {})
context['journal_id'] = self.journal_id.id
return {
'name': _('Journal Items'),
'name': _('Journal Entries'),
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move.line',
'res_model': 'account.move',
'view_id': False,
'type': 'ir.actions.act_window',
'domain': [('statement_id', 'in', self.ids)],
'domain': [('id', 'in', self.mapped('move_line_ids').mapped('move_id').ids)],
'context': context,
}

Expand Down Expand Up @@ -366,6 +366,7 @@ class AccountBankStatementLine(models.Model):
journal_entry_ids = fields.One2many('account.move', 'statement_line_id', 'Journal Entries', copy=False, readonly=True)
amount_currency = fields.Monetary(help="The amount expressed in an optional other currency if it is a multi-currency entry.")
currency_id = fields.Many2one('res.currency', string='Currency', help="The optional other currency if it is a multi-currency entry.")
state = fields.Selection(related='statement_id.state' , string='Status', readonly=True)
move_name = fields.Char(string='Journal Entry Name', readonly=True,
default=False, copy=False,
help="Technical field holding the number given to the journal entry, automatically set when the statement line is reconciled then stored to set the same number again if the line is cancelled, set to draft and re-processed again.")
Expand Down
54 changes: 36 additions & 18 deletions addons/account/models/account_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from odoo.exceptions import UserError, RedirectWarning, ValidationError

import odoo.addons.decimal_precision as dp
import logging

_logger = logging.getLogger(__name__)

# mapping invoice type to journal type
TYPE2JOURNAL = {
Expand Down Expand Up @@ -592,23 +595,33 @@ def get_formview_id(self):
else:
return self.env.ref('account.invoice_form').id

def _prepare_tax_line_vals(self, line, tax):
""" Prepare values to create an account.invoice.tax line
The line parameter is an account.invoice.line, and the
tax parameter is the output of account.tax.compute_all().
"""
vals = {
'invoice_id': self.id,
'name': tax['name'],
'tax_id': tax['id'],
'amount': tax['amount'],
'base': tax['base'],
'manual': False,
'sequence': tax['sequence'],
'account_analytic_id': tax['analytic'] and line.account_analytic_id.id or False,
'account_id': self.type in ('out_invoice', 'in_invoice') and (tax['account_id'] or line.account_id.id) or (tax['refund_account_id'] or line.account_id.id),
}
return vals

@api.multi
def get_taxes_values(self):
tax_grouped = {}
for line in self.invoice_line_ids:
price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
taxes = line.invoice_line_tax_ids.compute_all(price_unit, self.currency_id, line.quantity, line.product_id, self.partner_id)['taxes']
for tax in taxes:
val = {
'invoice_id': self.id,
'name': tax['name'],
'tax_id': tax['id'],
'amount': tax['amount'],
'manual': False,
'sequence': tax['sequence'],
'account_analytic_id': tax['analytic'] and line.account_analytic_id.id or False,
'account_id': self.type in ('out_invoice', 'in_invoice') and (tax['account_id'] or line.account_id.id) or (tax['refund_account_id'] or line.account_id.id),
}
val = self._prepare_tax_line_vals(line, tax)

# If the taxes generate moves on the same financial account as the invoice line,
# propagate the analytic account from the invoice line to the tax line.
Expand All @@ -623,6 +636,7 @@ def get_taxes_values(self):
tax_grouped[key] = val
else:
tax_grouped[key]['amount'] += val['amount']
tax_grouped[key]['base'] += val['base']
return tax_grouped

@api.multi
Expand Down Expand Up @@ -1336,15 +1350,19 @@ class AccountInvoiceTax(models.Model):

@api.depends('invoice_id.invoice_line_ids')
def _compute_base_amount(self):
tax_grouped = {}
for invoice in self.mapped('invoice_id'):
tax_grouped[invoice.id] = invoice.get_taxes_values()
for tax in self:
base = 0.0
for line in tax.invoice_id.invoice_line_ids:
if tax.tax_id in line.invoice_line_tax_ids:
price_unit = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
base += (line.invoice_line_tax_ids - tax.tax_id).compute_all(
price_unit, line.invoice_id.currency_id, line.quantity, line.product_id, line.invoice_id.partner_id
)['base']
tax.base = base
key = self.env['account.tax'].browse(tax.tax_id.id).get_grouping_key({
'tax_id': tax.tax_id.id,
'account_id': tax.account_id.id,
'account_analytic_id': tax.account_analytic_id.id,
})
if tax.invoice_id and key in tax_grouped[tax.invoice_id.id]:
tax.base = tax_grouped[tax.invoice_id.id][key]['base']
else:
_logger.warning('Tax Base Amount not computable probably due to a change in an underlying tax (%s).', tax.tax_id.name)

invoice_id = fields.Many2one('account.invoice', string='Invoice', ondelete='cascade', index=True)
name = fields.Char(string='Tax Description', required=True)
Expand Down
11 changes: 7 additions & 4 deletions addons/account/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -1037,10 +1037,13 @@ def create(self, vals):
# the provided values were not already multi-currency
if account.currency_id and 'amount_currency' not in vals and account.currency_id.id != account.company_id.currency_id.id:
vals['currency_id'] = account.currency_id.id
ctx = {}
if 'date' in vals:
ctx['date'] = vals['date']
vals['amount_currency'] = account.company_id.currency_id.with_context(ctx).compute(amount, account.currency_id)
if self._context.get('skip_full_reconcile_check') == 'amount_currency_excluded':
vals['amount_currency'] = 0.0
else:
ctx = {}
if 'date' in vals:
ctx['date'] = vals['date']
vals['amount_currency'] = account.company_id.currency_id.with_context(ctx).compute(amount, account.currency_id)

if not ok:
raise UserError(_('You cannot use this general account in this journal, check the tab \'Entry Controls\' on the related journal.'))
Expand Down
6 changes: 4 additions & 2 deletions addons/account/models/chart_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def migrate_tags_on_taxes(cr, registry):
('description', '=', tax_template.description)
])
if len(tax_id.ids) == 1:
tax_id.sudo().write({'tag_ids': [(6, 0, [tax_template.tag_ids.ids])]})
tax_id.sudo().write({'tag_ids': [(6, 0, tax_template.tag_ids.ids)]})

# ---------------------------------------------------------------
# Account Templates: Account, Tax, Tax Code and chart. + Wizard
Expand Down Expand Up @@ -399,7 +399,9 @@ def generate_account_reconcile_model(self, tax_template_ref, acc_template_ref, c
:rtype: dict
"""
self.ensure_one()
account_reconcile_models = self.env['account.reconcile.model.template'].search([])
account_reconcile_models = self.env['account.reconcile.model.template'].search([
('account_id.chart_template_id', '=', self.id)
])
for account_reconcile_model in account_reconcile_models:
vals = {
'name': account_reconcile_model.name,
Expand Down
2 changes: 1 addition & 1 deletion addons/account/models/partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,5 +445,5 @@ def open_partner_history(self):
'''
action = self.env.ref('account.action_invoice_refund_out_tree')
result = action.read()[0]
result['domain'] = "[('id','in',[" + ','.join(map(str, self.ids)) + "])]"
result['domain'] = [('partner_id', 'in', self.ids)]
return result
62 changes: 62 additions & 0 deletions addons/account/tests/test_account_supplier_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,65 @@ def test_supplier_invoice(self):
#I cancel the account move which is in posted state and verifies that it gives warning message
with self.assertRaises(Warning):
invoice.move_id.button_cancel()

def test_supplier_invoice2(self):
tax_fixed = self.env['account.tax'].create({
'sequence': 10,
'name': 'Tax 10.0 (Fixed)',
'amount': 10.0,
'amount_type': 'fixed',
'include_base_amount': True,
})
tax_percent_included_base_incl = self.env['account.tax'].create({
'sequence': 20,
'name': 'Tax 50.0% (Percentage of Price Tax Included)',
'amount': 50.0,
'amount_type': 'division',
'include_base_amount': True,
})
tax_percentage = self.env['account.tax'].create({
'sequence': 30,
'name': 'Tax 20.0% (Percentage of Price)',
'amount': 20.0,
'amount_type': 'percent',
'include_base_amount': False,
})
analytic_account = self.env['account.analytic.account'].create({
'name': 'test account',
})

# Should be changed by automatic on_change later
invoice_account = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_receivable').id)], limit=1).id
invoice_line_account = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_expenses').id)], limit=1).id

invoice = self.env['account.invoice'].create({'partner_id': self.env.ref('base.res_partner_2').id,
'account_id': invoice_account,
'type': 'in_invoice',
})

invoice_line = self.env['account.invoice.line'].create({'product_id': self.env.ref('product.product_product_4').id,
'quantity': 5.0,
'price_unit': 100.0,
'invoice_id': invoice.id,
'name': 'product that cost 100',
'account_id': invoice_line_account,
'invoice_line_tax_ids': [(6, 0, [tax_fixed.id, tax_percent_included_base_incl.id, tax_percentage.id])],
'account_analytic_id': analytic_account.id,
})
invoice.compute_taxes()

# check that Initially supplier bill state is "Draft"
self.assertTrue((invoice.state == 'draft'), "Initially vendor bill state is Draft")

#change the state of invoice to open by clicking Validate button
invoice.signal_workflow('invoice_open')

# Check if amount and corresponded base is correct for all tax scenarios given on a computational base
# Keep in mind that tax amount can be changed by the user at any time before validating (based on the invoice and tax laws applicable)
invoice_tax = invoice.tax_line_ids.sorted(key=lambda r: r.sequence)
self.assertEquals(invoice_tax.mapped('amount'), [50.0, 550.0, 220.0])
self.assertEquals(invoice_tax.mapped('base'), [500.0, 550.0, 1100.0])

#I cancel the account move which is in posted state and verifies that it gives warning message
with self.assertRaises(Warning):
invoice.move_id.button_cancel()
3 changes: 2 additions & 1 deletion addons/account/views/account_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@
<sheet>
<div class="oe_button_box" name="button_box">
<button class="oe_stat_button" name="button_journal_entries"
string="Journal Items" type="object"
string="Journal Entries" type="object"
attrs="{'invisible':[('move_line_ids','=',[])]}" icon="fa-bars"/>
<field name="move_line_ids" invisible="1"/>
</div>
Expand Down Expand Up @@ -884,6 +884,7 @@
<field name="type"/>
</group>
<group>
<field name="include_initial_balance"/>
</group>
</group>
<separator string="Description"/>
Expand Down
2 changes: 1 addition & 1 deletion addons/account/views/partner_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
icon="fa-pencil-square-o"
name="open_partner_history"
attrs="{'invisible': [('customer', '=', False)]}"
context="{'search_default_partner_id': active_id,'default_partner_id': active_id}">
context="{'default_partner_id': active_id}">
<div class="o_form_field o_stat_info">
<span class="o_stat_value"><field name="total_invoiced" widget='monetary' options="{'currency_field': 'currency_id'}"/></span>
<span class="o_stat_text">Invoiced</span>
Expand Down
2 changes: 1 addition & 1 deletion addons/account/views/web_planner_data.xml
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@
<span class="fa fa-copy fa-4x"></span>
<h3><strong>Contracts &amp; Subscriptions</strong></h3>
<p>Manage time &amp; material contracts or fixed-price recurring subscriptions.</p>
<a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'account_analytic_analysis')"
<a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'sale_contract')"
class="btn odoo_purple">
<span class="fa fa-arrow-circle-o-down"/> Install Now
</a>
Expand Down
6 changes: 3 additions & 3 deletions addons/account_asset/models/account_asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def _compute_board_amount(self, sequence, residual_amount, amount_to_depr, undon
else:
if self.method == 'linear':
amount = amount_to_depr / (undone_dotation_number - len(posted_depreciation_line_ids))
if self.prorata and self.category_id.type == 'purchase':
if self.prorata:
amount = amount_to_depr / self.method_number
if sequence == 1:
days = (self.company_id.compute_fiscalyear_dates(depreciation_date)['date_to'] - depreciation_date).days + 1
Expand All @@ -174,7 +174,7 @@ def _compute_board_undone_dotation_nb(self, depreciation_date, total_days):
while depreciation_date <= end_date:
depreciation_date = date(depreciation_date.year, depreciation_date.month, depreciation_date.day) + relativedelta(months=+self.method_period)
undone_dotation_number += 1
if self.prorata and self.category_id.type == 'purchase':
if self.prorata:
undone_dotation_number += 1
return undone_dotation_number

Expand Down Expand Up @@ -378,7 +378,7 @@ def copy_data(self, default=None):

@api.multi
def _compute_entries(self, date, group_entries=False):
depreciation_ids = self.env['account.asset.depreciation.line'].with_context(depreciation_date=date).search([
depreciation_ids = self.env['account.asset.depreciation.line'].search([
('asset_id', 'in', self.ids), ('depreciation_date', '<=', date),
('move_check', '=', False)])
if group_entries:
Expand Down
3 changes: 2 additions & 1 deletion addons/account_cancel/views/account_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@
<attribute name="options">{'reload_on_button': true}</attribute>
</field>
<xpath expr="//field[@name='bank_account_id']" position="after">
<button name="button_cancel_reconciliation" attrs="{'invisible': [('journal_entry_ids', '=', [])]}" string="Cancel" type="object" icon="fa-undo text-warning"/>
<field name="state" invisible="1"/>
<button name="button_cancel_reconciliation" attrs="{'invisible': ['|',('journal_entry_ids', '=', []), ('state', '=', 'confirm')]}" string="Cancel" type="object" icon="fa fa-undo text-warning"/>
</xpath>
</field>
</record>
Expand Down
Loading

0 comments on commit 938ffb9

Please sign in to comment.