[MERGE] forward port branch 9.0 up to f10ef71f06
This commit is contained in:
@@ -978,7 +978,7 @@ class AccountInvoice(models.Model):
|
||||
|
||||
values['invoice_line_ids'] = self._refund_cleanup_lines(invoice.invoice_line_ids)
|
||||
|
||||
tax_lines = filter(lambda l: l.manual, invoice.tax_line_ids)
|
||||
tax_lines = invoice.tax_line_ids
|
||||
values['tax_line_ids'] = self._refund_cleanup_lines(tax_lines)
|
||||
|
||||
if journal_id:
|
||||
|
||||
@@ -58,7 +58,6 @@ class AccountInvoiceRefund(models.TransientModel):
|
||||
date = form.date or False
|
||||
description = form.description or inv.name
|
||||
refund = inv.refund(form.date_invoice, date, description, inv.journal_id.id)
|
||||
refund.compute_taxes()
|
||||
|
||||
created_inv.append(refund.id)
|
||||
if mode in ('cancel', 'modify'):
|
||||
|
||||
@@ -562,7 +562,7 @@ class PosOrder(models.Model):
|
||||
'location_id': location_id,
|
||||
'location_dest_id': destination_id,
|
||||
}
|
||||
pos_qty = any([x.qty >= 0 for x in order.lines])
|
||||
pos_qty = any([x.qty > 0 for x in order.lines])
|
||||
if pos_qty:
|
||||
order_picking = Picking.create(picking_vals.copy())
|
||||
neg_qty = any([x.qty < 0 for x in order.lines])
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<field name="user_id" />
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="User" domain="[]" context="{'group_by' : 'user_id'}" />
|
||||
<filter string="Point of Sale" domain="[]" context="{'group_by': 'user_id'}" />
|
||||
<filter string="Point of Sale" domain="[]" context="{'group_by': 'config_id'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -13,7 +13,19 @@ class SaleOrderLine(models.Model):
|
||||
lines = {}
|
||||
if not domain:
|
||||
# To filter on analyic lines linked to an expense
|
||||
domain = [('so_line', 'in', self.ids), ('amount', '<=', 0.0)]
|
||||
expense_type_id = self.env.ref('account.data_account_type_expenses', raise_if_not_found=False)
|
||||
expense_type_id = expense_type_id and expense_type_id.id
|
||||
domain = [
|
||||
('so_line', 'in', self.ids),
|
||||
'|',
|
||||
('amount', '<', 0),
|
||||
'&',
|
||||
('amount', '=', 0),
|
||||
'|',
|
||||
('move_id', '=', False),
|
||||
('move_id.account_id.user_type_id', '=', expense_type_id)
|
||||
]
|
||||
|
||||
data = self.env['account.analytic.line'].read_group(
|
||||
domain,
|
||||
['so_line', 'unit_amount', 'product_uom_id'], ['product_uom_id', 'so_line'], lazy=False
|
||||
|
||||
@@ -251,7 +251,20 @@ class SaleOrderLine(models.Model):
|
||||
def _compute_analytic(self, domain=None):
|
||||
if not domain:
|
||||
# To filter on analyic lines linked to an expense
|
||||
domain = [('so_line', 'in', self.ids), '|', ('amount', '<=', 0.0), ('project_id', '!=', False)]
|
||||
expense_type_id = self.env.ref('account.data_account_type_expenses', raise_if_not_found=False)
|
||||
expense_type_id = expense_type_id and expense_type_id.id
|
||||
domain = [
|
||||
('so_line', 'in', self.ids),
|
||||
'|',
|
||||
'|',
|
||||
('amount', '<', 0.0),
|
||||
('project_id', '!=', False),
|
||||
'&',
|
||||
('amount', '=', 0),
|
||||
'|',
|
||||
('move_id', '=', False),
|
||||
('move_id.account_id.user_type_id', '=', expense_type_id)
|
||||
]
|
||||
return super(SaleOrderLine, self)._compute_analytic(domain=domain)
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Vietnam, 2017-04-10
|
||||
|
||||
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||
Agreement v1.0.
|
||||
|
||||
I declare that I am authorized and able to make this agreement and sign this
|
||||
declaration.
|
||||
|
||||
Signed,
|
||||
|
||||
Tran Thanh Phuc ttp.phuctran@gmail.com https://github.com/ttpphuctran
|
||||
@@ -101,9 +101,8 @@ class IrRule(models.Model):
|
||||
group_domains = defaultdict(list) # {group: list of domains}
|
||||
for rule in rules.sudo():
|
||||
dom = expression.normalize_domain(rule_domain[rule.id])
|
||||
for group in rule.groups:
|
||||
if group in user.groups_id:
|
||||
group_domains[group].append(dom)
|
||||
if rule.groups & user.groups_id:
|
||||
group_domains[rule.groups[0]].append(dom)
|
||||
if not rule.groups:
|
||||
global_domains.append(dom)
|
||||
|
||||
|
||||
@@ -13,3 +13,4 @@ access_test_function_counter,access_test_function_counter,model_test_old_api_fun
|
||||
access_domain_bool,access_domain_bool,model_domain_bool,,1,1,1,1
|
||||
access_test_new_api_foo,access_test_new_api_foo,model_test_new_api_foo,,1,1,1,1
|
||||
access_test_new_api_bar,access_test_new_api_bar,model_test_new_api_bar,,1,1,1,1
|
||||
access_test_new_api_recursive,access_test_new_api_recursive,model_test_new_api_recursive,,1,1,1,1
|
||||
|
||||
|
@@ -321,3 +321,19 @@ class Bar(models.Model):
|
||||
def _compute_foo(self):
|
||||
for bar in self:
|
||||
bar.foo = self.env['test_new_api.foo'].search([('name', '=', bar.name)], limit=1)
|
||||
|
||||
|
||||
class ComputeRecursive(models.Model):
|
||||
_name = 'test_new_api.recursive'
|
||||
|
||||
name = fields.Char(required=True)
|
||||
parent = fields.Many2one('test_new_api.recursive')
|
||||
display_name = fields.Char(compute='_compute_display_name', store=True)
|
||||
|
||||
@api.depends('name', 'parent.display_name')
|
||||
def _compute_display_name(self):
|
||||
for rec in self:
|
||||
if rec.parent:
|
||||
rec.display_name = rec.parent.display_name + " / " + rec.name
|
||||
else:
|
||||
rec.display_name = rec.name
|
||||
|
||||
@@ -180,6 +180,29 @@ class TestNewFields(common.TransactionCase):
|
||||
cath.parent = finn
|
||||
self.assertEqual(ewan.display_name, "Gabriel / Finnley / Catherine / Ewan")
|
||||
|
||||
def test_12_recursive_recompute(self):
|
||||
""" test recomputation on recursively dependent field """
|
||||
a = self.env['test_new_api.recursive'].create({'name': 'A'})
|
||||
b = self.env['test_new_api.recursive'].create({'name': 'B', 'parent': a.id})
|
||||
c = self.env['test_new_api.recursive'].create({'name': 'C', 'parent': b.id})
|
||||
d = self.env['test_new_api.recursive'].create({'name': 'D', 'parent': c.id})
|
||||
self.assertEqual(a.display_name, 'A')
|
||||
self.assertEqual(b.display_name, 'A / B')
|
||||
self.assertEqual(c.display_name, 'A / B / C')
|
||||
self.assertEqual(d.display_name, 'A / B / C / D')
|
||||
|
||||
b.parent = False
|
||||
self.assertEqual(a.display_name, 'A')
|
||||
self.assertEqual(b.display_name, 'B')
|
||||
self.assertEqual(c.display_name, 'B / C')
|
||||
self.assertEqual(d.display_name, 'B / C / D')
|
||||
|
||||
b.name = 'X'
|
||||
self.assertEqual(a.display_name, 'A')
|
||||
self.assertEqual(b.display_name, 'X')
|
||||
self.assertEqual(c.display_name, 'X / C')
|
||||
self.assertEqual(d.display_name, 'X / C / D')
|
||||
|
||||
def test_12_cascade(self):
|
||||
""" test computed field depending on computed field """
|
||||
message = self.env.ref('test_new_api.message_0_0')
|
||||
|
||||
+2
-1
@@ -639,7 +639,8 @@ class Field(object):
|
||||
|
||||
if field in fields:
|
||||
self.recursive = True
|
||||
continue
|
||||
if not i:
|
||||
continue # self directly depends on self, give up
|
||||
|
||||
# add trigger on field and its inverses to recompute self
|
||||
model._field_triggers.add(field, (self, '.'.join(path[:i] or ['id'])))
|
||||
|
||||
Reference in New Issue
Block a user