Update patches to new version

This commit is contained in:
Sergi Almacellas Abellana 2016-04-07 14:39:44 +02:00
commit c492164290
65 changed files with 1983 additions and 4096 deletions

View File

@ -1,389 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619588 -3600
# Wed Dec 03 16:13:08 2014 +0100
# Node ID 42b9acc4c201b883197c3ebc8385f6e1072cd076
# Parent d57626d6cf3e20cd28861a1d5c37cc7c064bd21c
# Add missing company domain/field
# issue4311
# review7691002
diff -r d57626d6cf3e -r 42b9acc4c201 fiscalyear.py
--- .a/trytond/trytond/modules/account/fiscalyear.py Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/fiscalyear.py Wed Dec 03 16:13:08 2014 +0100
@@ -326,6 +326,8 @@
__name__ = 'account.fiscalyear.balance_non_deferral.start'
fiscalyear = fields.Many2One('account.fiscalyear', 'Fiscal Year',
required=True, domain=[('state', '=', 'open')])
+ company = fields.Function(fields.Many2One('company.company', 'Company'),
+ 'on_change_with_company')
journal = fields.Many2One('account.journal', 'Journal', required=True,
domain=[
('type', '=', 'situation'),
@@ -340,16 +342,23 @@
required=True,
domain=[
('kind', '!=', 'view'),
- ('company', '=', Eval('context', {}).get('company', -1)),
+ ('company', '=', Eval('company', -1)),
('deferral', '=', True),
- ])
+ ],
+ depends=['company'])
debit_account = fields.Many2One('account.account', 'Debit Account',
required=True,
domain=[
('kind', '!=', 'view'),
- ('company', '=', Eval('context', {}).get('company', -1)),
+ ('company', '=', Eval('company', -1)),
('deferral', '=', True),
- ])
+ ],
+ depends=['company'])
+
+ @fields.depends('fiscalyear')
+ def on_change_with_company(self, name=None):
+ if self.fiscalyear:
+ return self.fiscalyear.company.id
class BalanceNonDeferral(Wizard):
diff -r d57626d6cf3e -r 42b9acc4c201 move.py
--- .a/trytond/trytond/modules/account/move.py Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/move.py Wed Dec 03 16:13:08 2014 +0100
@@ -49,8 +49,12 @@
number = fields.Char('Number', required=True, readonly=True)
post_number = fields.Char('Post Number', readonly=True,
help='Also known as Folio Number')
+ company = fields.Many2One('company.company', 'Company', required=True)
period = fields.Many2One('account.period', 'Period', required=True,
- states=_MOVE_STATES, depends=_MOVE_DEPENDS, select=True)
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ states=_MOVE_STATES, depends=_MOVE_DEPENDS + ['company'], select=True)
journal = fields.Many2One('account.journal', 'Journal', required=True,
states=_MOVE_STATES, depends=_MOVE_DEPENDS)
date = fields.Date('Effective Date', required=True, states=_MOVE_STATES,
@@ -65,7 +69,10 @@
('posted', 'Posted'),
], 'State', required=True, readonly=True, select=True)
lines = fields.One2Many('account.move.line', 'move', 'Lines',
- states=_MOVE_STATES, depends=_MOVE_DEPENDS,
+ domain=[
+ ('account.company', '=', Eval('company', -1)),
+ ],
+ states=_MOVE_STATES, depends=_MOVE_DEPENDS + ['company'],
context={
'journal': Eval('journal'),
'period': Eval('period'),
@@ -87,8 +94,6 @@
'"%(move)s" to draft in journal "%(journal)s".'),
'modify_posted_move': ('You can not modify move "%s" because '
'it is already posted.'),
- 'company_in_move': ('You can not create lines on accounts'
- 'of different companies in move "%s".'),
'date_outside_period': ('You can not create move "%(move)s" '
'because it\'s date is outside its period.'),
'draft_closed_period': ('You can not set to draft move '
@@ -111,6 +116,12 @@
TableHandler = backend.get('TableHandler')
cursor = Transaction().cursor
table = TableHandler(cursor, cls, module_name)
+ sql_table = cls.__table__()
+ pool = Pool()
+ Period = pool.get('account.period')
+ period = Period.__table__()
+ FiscalYear = pool.get('account.fiscalyear')
+ fiscalyear = FiscalYear.__table__()
# Migration from 2.4:
# - name renamed into number
@@ -120,8 +131,19 @@
if table.column_exist('reference'):
table.column_rename('reference', 'post_number')
+ created_company = not table.column_exist('company')
+
super(Move, cls).__register__(module_name)
+ # Migration from 3.4: new company field
+ if created_company:
+ # Don't use UPDATE FROM because SQLite nor MySQL support it.
+ value = period.join(fiscalyear,
+ condition=period.fiscalyear == fiscalyear.id).select(
+ fiscalyear.company,
+ where=period.id == sql_table.period)
+ cursor.execute(*sql_table.update([sql_table.company], [value]))
+
table = TableHandler(cursor, cls, module_name)
table.index_action(['journal', 'period'], 'add')
@@ -129,6 +151,10 @@
table.index_action('create_date', action='add')
@staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
+ @staticmethod
def default_period():
Period = Pool().get('account.period')
return Period.find(Transaction().context.get('company'),
@@ -181,17 +207,8 @@
def validate(cls, moves):
super(Move, cls).validate(moves)
for move in moves:
- move.check_company()
move.check_date()
- def check_company(self):
- company_id = -1
- for line in self.lines:
- if company_id < 0:
- company_id = line.account.company.id
- if line.account.company.id != company_id:
- self.raise_user_error('company_in_move', (self.rec_name,))
-
def check_date(self):
if (self.date < self.period.start_date
or self.date > self.period.end_date):
@@ -285,17 +302,10 @@
'''
pool = Pool()
MoveLine = pool.get('account.move.line')
- User = pool.get('res.user')
line = MoveLine.__table__()
cursor = Transaction().cursor
- if (Transaction().user == 0
- and Transaction().context.get('user')):
- user = Transaction().context.get('user')
- else:
- user = Transaction().user
- company = User(user).company
amounts = {}
move2draft_lines = {}
for sub_move_ids in grouped_slice([m.id for m in moves]):
@@ -326,7 +326,7 @@
if not isinstance(amount, Decimal):
amount = Decimal(amount)
draft_lines = MoveLine.browse(move2draft_lines.get(move.id, []))
- if not company.currency.is_zero(amount):
+ if not move.company.currency.is_zero(amount):
draft_moves.append(move.id)
continue
if not draft_lines:
@@ -1147,6 +1157,7 @@
fiscalyears = FiscalYear.search([
('start_date', '<=', Transaction().context['date']),
('end_date', '>=', Transaction().context['date']),
+ ('company', '=', Transaction().context.get('company')),
], limit=1)
fiscalyear_id = fiscalyears and fiscalyears[0].id or 0
@@ -1193,6 +1204,7 @@
if not Transaction().context.get('fiscalyear'):
fiscalyears = FiscalYear.search([
('state', '=', 'open'),
+ ('company', '=', Transaction().context.get('company')),
])
fiscalyear_ids = [f.id for f in fiscalyears] or [0]
else:
diff -r d57626d6cf3e -r 42b9acc4c201 period.py
--- .a/trytond/trytond/modules/account/period.py Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/period.py Wed Dec 03 16:13:08 2014 +0100
@@ -34,7 +34,14 @@
('close', 'Close'),
], 'State', readonly=True, required=True)
post_move_sequence = fields.Many2One('ir.sequence', 'Post Move Sequence',
- domain=[('code', '=', 'account.move')],
+ domain=[
+ ('code', '=', 'account.move'),
+ ['OR',
+ ('company', '=', None),
+ ('company', '=', Eval('company', -1)),
+ ],
+ ],
+ depends=['company'],
context={'code': 'account.move'})
type = fields.Selection([
('standard', 'Standard'),
@@ -42,7 +49,7 @@
], 'Type', required=True,
states=_STATES, depends=_DEPENDS, select=True)
company = fields.Function(fields.Many2One('company.company', 'Company',),
- 'get_company', searcher='search_company')
+ 'on_change_with_company', searcher='search_company')
@classmethod
def __register__(cls, module_name):
@@ -78,9 +85,6 @@
'overlap.'),
'check_move_sequence': ('Period "%(first)s" and "%(second)s" '
'have the same sequence.'),
- 'check_move_sequence_company': ('Company of sequence '
- '"%(sequence)s" does not match the company of period '
- '"%(period)s" to which it is assigned to.'),
'fiscalyear_dates': ('Dates of period "%s" are outside '
'are outside it\'s fiscal year dates.'),
})
@@ -93,8 +97,10 @@
def default_type():
return 'standard'
- def get_company(self, name):
- return self.fiscalyear.company.id
+ @fields.depends('fiscalyear')
+ def on_change_with_company(self, name=None):
+ if self.fiscalyear:
+ return self.fiscalyear.company.id
@classmethod
def search_company(cls, name, clause):
@@ -148,12 +154,6 @@
'first': self.rec_name,
'second': periods[0].rec_name,
})
- if (self.post_move_sequence.company and
- self.post_move_sequence.company != self.fiscalyear.company):
- self.raise_user_error('check_move_sequence_company', {
- 'sequence': self.post_move_sequence.rec_name,
- 'period': self.rec_name,
- })
@classmethod
def find(cls, company_id, date=None, exception=True, test_state=True):
diff -r d57626d6cf3e -r 42b9acc4c201 tax.py
--- .a/trytond/trytond/modules/account/tax.py Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/tax.py Wed Dec 03 16:13:08 2014 +0100
@@ -627,9 +627,13 @@
depends=['company', 'type'])
invoice_base_code = fields.Many2One('account.tax.code',
'Invoice Base Code',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'readonly': Eval('type') == 'none',
- }, depends=['type'])
+ },
+ depends=['type', 'company'])
invoice_base_sign = fields.Numeric('Invoice Base Sign', digits=(2, 0),
help='Usualy 1 or -1',
states={
@@ -638,9 +642,13 @@
}, depends=['type'])
invoice_tax_code = fields.Many2One('account.tax.code',
'Invoice Tax Code',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'readonly': Eval('type') == 'none',
- }, depends=['type'])
+ },
+ depends=['type', 'company'])
invoice_tax_sign = fields.Numeric('Invoice Tax Sign', digits=(2, 0),
help='Usualy 1 or -1',
states={
@@ -654,15 +662,23 @@
}, depends=['type'])
credit_note_base_sign = fields.Numeric('Credit Note Base Sign',
digits=(2, 0), help='Usualy 1 or -1',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'required': Eval('type') != 'none',
'readonly': Eval('type') == 'none',
- }, depends=['type'])
+ },
+ depends=['type', 'company'])
credit_note_tax_code = fields.Many2One('account.tax.code',
'Credit Note Tax Code',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'readonly': Eval('type') == 'none',
- }, depends=['type'])
+ },
+ depends=['type', 'company'])
credit_note_tax_sign = fields.Numeric('Credit Note Tax Sign',
digits=(2, 0), help='Usualy 1 or -1',
states={
@@ -919,11 +935,21 @@
amount = fields.Numeric('Amount', digits=(16, Eval('currency_digits', 2)),
required=True, depends=['currency_digits'])
code = fields.Many2One('account.tax.code', 'Code', select=True,
- required=True)
+ required=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
tax = fields.Many2One('account.tax', 'Tax', select=True,
- ondelete='RESTRICT')
+ ondelete='RESTRICT',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
move_line = fields.Many2One('account.move.line', 'Move Line',
required=True, select=True, ondelete='CASCADE')
+ company = fields.Function(fields.Many2One('company.company', 'Company'),
+ 'on_change_with_company')
@fields.depends('move_line')
def on_change_with_currency_digits(self, name=None):
@@ -935,6 +961,11 @@
def on_change_tax(self):
self.code = None
+ @fields.depends('_parent_move_line.account')
+ def on_change_with_company(self, name=None):
+ if self.move_line:
+ return self.move_line.account.company.id
+
class TaxRuleTemplate(ModelSQL, ModelView):
'Tax Rule Template'
diff -r d57626d6cf3e -r 42b9acc4c201 view/move_form.xml
--- .a/trytond/trytond/modules/account/view/move_form.xml Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/view/move_form.xml Wed Dec 03 16:13:08 2014 +0100
@@ -2,6 +2,9 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<form string="Account Move" cursor="journal">
+ <label name="company"/>
+ <field name="company"/>
+ <newline/>
<label name="number"/>
<field name="number"/>
<label name="post_number"/>
diff -r d57626d6cf3e -r 42b9acc4c201 view/move_tree.xml
--- .a/trytond/trytond/modules/account/view/move_tree.xml Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/view/move_tree.xml Wed Dec 03 16:13:08 2014 +0100
@@ -2,6 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree string="Account Moves">
+ <field name="company"/>
<field name="number"/>
<field name="post_number"/>
<field name="journal"/>
diff -r d57626d6cf3e -r 42b9acc4c201 view/period_tree.xml
--- .a/trytond/trytond/modules/account/view/period_tree.xml Tue Dec 02 12:54:29 2014 +0100
+++ .b/trytond/trytond/modules/account/view/period_tree.xml Wed Dec 03 16:13:08 2014 +0100
@@ -2,6 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree string="Periods">
+ <field name="company"/>
<field name="name"/>
<field name="code"/>
<field name="type"/>

View File

@ -1,79 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619589 -3600
# Wed Dec 03 16:13:09 2014 +0100
# Node ID 78bda42be4643d7e59bf838f229fe689d0fdbf18
# Parent 288b4d6b861b9e6dafea942bb03e4f8300db8514
# Add missing company domain/field
# issue4311
# review7691002
diff -r 288b4d6b861b -r 78bda42be464 asset.py
--- .a/trytond/trytond/modules/account_asset/asset.py Wed Dec 03 13:58:43 2014 +0100
+++ .b/trytond/trytond/modules/account_asset/asset.py Wed Dec 03 16:13:09 2014 +0100
@@ -44,11 +44,15 @@
('product', '=', Eval('product', -1)),
),
('invoice.type', '=', 'in_invoice'),
+ ['OR',
+ ('company', '=', Eval('company', -1)),
+ ('invoice.company', '=', Eval('company', -1)),
+ ],
],
states={
'readonly': (Eval('lines', [0]) | (Eval('state') != 'draft')),
},
- depends=['product', 'state'])
+ depends=['product', 'state', 'company'])
customer_invoice_line = fields.Function(fields.Many2One(
'account.invoice.line', 'Customer Invoice Line'),
'get_customer_invoice_line')
@@ -141,12 +145,20 @@
], 'State', readonly=True)
lines = fields.One2Many('account.asset.line', 'asset', 'Lines',
readonly=True)
- move = fields.Many2One('account.move', 'Account Move', readonly=True)
+ move = fields.Many2One('account.move', 'Account Move', readonly=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
update_moves = fields.Many2Many('account.asset-update-account.move',
'asset', 'move', 'Update Moves', readonly=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'invisible': ~Eval('update_moves'),
- })
+ },
+ depends=['company'])
comment = fields.Text('Comment')
@classmethod
@@ -437,6 +449,7 @@
)
return Move(
+ company=self.company,
origin=line,
period=period_id,
journal=self.account_journal,
@@ -509,6 +522,7 @@
)
lines.append(counter_part_line)
return Move(
+ company=self.company,
origin=self,
period=period_id,
journal=self.account_journal,
@@ -746,6 +760,7 @@
Move = pool.get('account.move')
period_id = Period.find(asset.company.id, self.show_move.date)
return Move(
+ company=asset.company,
origin=asset,
journal=asset.account_journal.id,
period=period_id,

File diff suppressed because it is too large Load Diff

View File

@ -1,289 +0,0 @@
diff -r 4e1ac035ae80 invoice.py
--- .a/trytond/trytond/modules/account_invoice/invoice.py Mon Oct 20 14:37:24 2014 +0200
+++ .b/trytond/trytond/modules/account_invoice/invoice.py Tue Dec 09 18:52:31 2014 +0100
@@ -114,15 +114,23 @@
'on_change_with_currency_date')
journal = fields.Many2One('account.journal', 'Journal', required=True,
states=_STATES, depends=_DEPENDS)
- move = fields.Many2One('account.move', 'Move', readonly=True)
+ move = fields.Many2One('account.move', 'Move', readonly=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
cancel_move = fields.Many2One('account.move', 'Cancel Move', readonly=True,
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
states={
'invisible': Eval('type').in_(['out_invoice', 'out_credit_note']),
- })
+ },
+ depends=['company'])
account = fields.Many2One('account.account', 'Account', required=True,
- states=_STATES, depends=_DEPENDS + ['type'],
+ states=_STATES, depends=_DEPENDS + ['type', 'company'],
domain=[
- ('company', '=', Eval('context', {}).get('company', -1)),
+ ('company', '=', Eval('company', -1)),
If(Eval('type').in_(['out_invoice', 'out_credit_note']),
('kind', '=', 'receivable'),
('kind', '=', 'payable')),
@@ -130,7 +138,10 @@
payment_term = fields.Many2One('account.invoice.payment_term',
'Payment Term', required=True, states=_STATES, depends=_DEPENDS)
lines = fields.One2Many('account.invoice.line', 'invoice', 'Lines',
- states=_STATES, depends=['state', 'currency_date'])
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ states=_STATES, depends=['state', 'currency_date', 'company'])
taxes = fields.One2Many('account.invoice.tax', 'invoice', 'Tax Lines',
states=_STATES, depends=_DEPENDS)
comment = fields.Text('Comment', states=_STATES, depends=_DEPENDS)
@@ -151,10 +162,13 @@
'Lines to Pay'), 'get_lines_to_pay')
payment_lines = fields.Many2Many('account.invoice-account.move.line',
'invoice', 'line', readonly=True, string='Payment Lines',
+ domain=[
+ ('move.company', '=', Eval('company', -1)),
+ ],
states={
'invisible': (Eval('state') == 'paid') | ~Eval('payment_lines'),
},
- depends=['state'])
+ depends=['state', 'company'])
amount_to_pay_today = fields.Function(fields.Numeric('Amount to Pay Today',
digits=(16, Eval('currency_digits', 2)),
depends=['currency_digits']), 'get_amount_to_pay')
@@ -194,10 +208,6 @@
'account.'),
'missing_credit_account': ('The credit account on journal %s" '
'is missing.'),
- 'account_different_company': ('You can not create invoice '
- '"%(invoice)s" on company "%(invoice_company)s because '
- 'account "%(account)s has a different company '
- '(%(account_company)s.)'),
'same_account_on_line': ('Invoice "%(invoice)s" uses the same '
'account "%(account)s" for the invoice and in line '
'"%(line)s".'),
@@ -1001,6 +1011,7 @@
'period': period_id,
'date': accounting_date,
'origin': str(self),
+ 'company': self.company.id,
'lines': [('create', move_lines)],
}])
self.write([self], {
@@ -1117,19 +1128,9 @@
def validate(cls, invoices):
super(Invoice, cls).validate(invoices)
for invoice in invoices:
- invoice.check_account()
invoice.check_same_account()
invoice.check_cancel_move()
- def check_account(self):
- if self.account.company != self.company:
- self.raise_user_error('check_account', {
- 'invoice': self.rec_name,
- 'invoice_company': self.company.rec_name,
- 'account': self.account.rec_name,
- 'account_company': self.account.company.rec_name,
- })
-
def check_same_account(self):
for line in self.lines:
if (line.type == 'line'
@@ -1279,6 +1280,7 @@
'journal': journal.id,
'period': period_id,
'date': date,
+ 'company': self.company.id,
'lines': [('create', lines)],
}])
Move.post([move])
@@ -1493,16 +1495,11 @@
depends=['invoice'])
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
- company = fields.Many2One('company.company', 'Company',
- states={
- 'required': ~Eval('invoice'),
- },
+ company = fields.Many2One('company.company', 'Company', required=True,
domain=[
('id', If(Eval('context', {}).contains('company'), '=', '!='),
Eval('context', {}).get('company', -1)),
- ],
- depends=['invoice'], select=True)
-
+ ], select=True)
sequence = fields.Integer('Sequence',
states={
'invisible': Bool(Eval('context', {}).get('standalone')),
@@ -1545,8 +1542,7 @@
'on_change_with_product_uom_category')
account = fields.Many2One('account.account', 'Account',
domain=[
- ('company', '=', Eval('_parent_invoice', {}).get('company',
- Eval('context', {}).get('company', -1))),
+ ('company', '=', Eval('company', -1)),
If(Bool(Eval('_parent_invoice')),
If(Eval('_parent_invoice', {}).get('type').in_(['out_invoice',
'out_credit_note']),
@@ -1561,7 +1557,7 @@
'invisible': Eval('type') != 'line',
'required': Eval('type') == 'line',
},
- depends=['type', 'invoice_type'])
+ depends=['type', 'invoice_type', 'company'])
unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
states={
'invisible': Eval('type') != 'line',
@@ -1592,11 +1588,12 @@
['sale', 'both'],
['purchase', 'both']))
)],
+ ('company', '=', Eval('company', -1)),
],
states={
'invisible': Eval('type') != 'line',
},
- depends=['type', 'invoice_type'])
+ depends=['type', 'invoice_type', 'company'])
invoice_taxes = fields.Function(fields.One2Many('account.invoice.tax',
None, 'Invoice Taxes'), 'get_invoice_taxes')
origin = fields.Reference('Origin', selection='get_origin', select=True,
@@ -1624,11 +1621,6 @@
'"%(invoice)s" that is posted or paid.'),
'create': ('You can not add a line to invoice "%(invoice)s" '
'that is posted, paid or cancelled.'),
- 'account_different_company': (
- 'You can not create invoice line '
- '"%(line)s" on invoice "%(invoice)s of company '
- '"%(invoice_line_company)s because account "%(account)s '
- 'has company "%(account_company)s".'),
'same_account_on_invoice': ('You can not create invoice line '
'"%(line)s" on invoice "%(invoice)s" because the invoice '
'uses the same account (%(account)s).'),
@@ -1636,7 +1628,11 @@
@classmethod
def __register__(cls, module_name):
+ pool = Pool()
+ Invoice = pool.get('account.invoice')
+ invoice = Invoice.__table__()
TableHandler = backend.get('TableHandler')
+ sql_table = cls.__table__()
super(InvoiceLine, cls).__register__(module_name)
cursor = Transaction().cursor
table = TableHandler(cursor, cls, module_name)
@@ -1647,6 +1643,15 @@
# Migration from 2.4: drop required on sequence
table.not_null_action('sequence', action='remove')
+ # Migration from 3.4: company is required
+ cursor.execute(*sql_table.join(invoice,
+ condition=sql_table.invoice == invoice.id
+ ).select(sql_table.id, invoice.company,
+ where=sql_table.company == None))
+ for line_id, company_id in cursor.fetchall():
+ cursor.execute(*sql_table.update([sql_table.company], [company_id],
+ where=sql_table.id == line_id))
+
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
@@ -1977,31 +1982,8 @@
def validate(cls, lines):
super(InvoiceLine, cls).validate(lines)
for line in lines:
- line.check_account_company()
line.check_same_account()
- def check_account_company(self):
- if self.type == 'line':
- if self.invoice:
- if self.account.company != self.invoice.company:
- self.raise_user_error('account_different_company', {
- 'line': self.rec_name,
- 'invoice': self.invoice.rec_name,
- 'invoice_line_company':
- self.invoice.company.rec_name,
- 'account': self.account.rec_name,
- 'account_company': self.account.company.rec_name,
- })
- elif self.company:
- if self.account.company != self.company:
- self.raise_user_error('account_different_company', {
- 'line': self.rec_name,
- 'invoice': '/',
- 'invoice_line_company': self.company.rec_name,
- 'account': self.account.rec_name,
- 'account_company': self.account.company.rec_name,
- })
-
def check_same_account(self):
if self.type == 'line':
if (self.invoice
@@ -2155,6 +2137,9 @@
])
tax_sign = fields.Numeric('Tax Sign', digits=(2, 0), required=True)
tax = fields.Many2One('account.tax', 'Tax',
+ domain=[
+ ('company', '=', Eval('_parent_invoice', {}).get('company', 0)),
+ ],
states={
'readonly': ~Eval('manual', False),
},
@@ -2169,10 +2154,6 @@
'"%(invoice)s" because it is posted or paid.'),
'create': ('You can not add line "%(line)s" to invoice '
'"%(invoice)s" because it is posted, paid or canceled.'),
- 'invalid_account_company': ('You can not create invoice '
- '"%(invoice)s" on company "%(invoice_company)s" using '
- 'account "%(account)s" from company '
- '"%(account_company)s".'),
'invalid_base_code_company': ('You can not create invoice '
'"%(invoice)s" on company "%(invoice_company)s" '
'using base tax code "%(base_code)s" from company '
@@ -2305,38 +2286,6 @@
cls.raise_user_error('create')
return super(InvoiceTax, cls).create(vlist)
- @classmethod
- def validate(cls, taxes):
- super(InvoiceTax, cls).validate(taxes)
- for tax in taxes:
- tax.check_company()
-
- def check_company(self):
- company = self.invoice.company
- if self.account.company != company:
- self.raise_user_error('invalid_account_company', {
- 'invoice': self.invoice.rec_name,
- 'invoice_company': self.invoice.company.rec_name,
- 'account': self.account.rec_name,
- 'account_company': self.account.company.rec_name,
- })
- if self.base_code:
- if self.base_code.company != company:
- self.raise_user_error('invalid_base_code_company', {
- 'invoice': self.invoice.rec_name,
- 'invoice_company': self.invoice.company.rec_name,
- 'base_code': self.base_code.rec_name,
- 'base_code_company': self.base_code.company.rec_name,
- })
- if self.tax_code:
- if self.tax_code.company != company:
- self.raise_user_error('invalid_tax_code_company', {
- 'invoice': self.invoice.rec_name,
- 'invoice_company': self.invoice.company.rec_name,
- 'tax_code': self.tax_code.rec_name,
- 'tax_code_company': self.tax_code.company.rec_name,
- })
-
def get_move_line(self):
'''
Return a list of move lines values for invoice tax

View File

@ -4,13 +4,13 @@ diff -r 32ceadcd01cd move.xml
@@ -259,6 +259,15 @@
<field name="perm_delete" eval="True"/>
</record>
+ <record model="ir.rule.group" id="rule_group_move_line">
+ <field name="model" search="[('model', '=', 'account.move.line')]"/>
+ <field name="global_p" eval="True"/>
+ </record>
+ <record model="ir.rule" id="rule_move_line1">
+ <field name="domain">[('account.company', 'in', [c.id for c in user.companies])]</field>
+ <field name="domain" eval="[('account.company', 'in', Eval('user', {}).get('companies', []))]" pyson="1"/>
+ <field name="rule_group" ref="rule_group_move_line"/>
+ </record>
+

View File

@ -1,44 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619600 -3600
# Wed Dec 03 16:13:20 2014 +0100
# Node ID 5dd8c0c2a04ce36ae50b07ace37a3c032d975f7d
# Parent 0feef65b0f4ece82ace16996c05c82ac254c677a
# Add missing company domain/field
# issue4311
# review7691002
diff -r 0feef65b0f4e -r 5dd8c0c2a04c account.py
--- .a/trytond/trytond/modules/account_payment/account.py Tue Dec 02 12:54:44 2014 +0100
+++ .b/trytond/trytond/modules/account_payment/account.py Wed Dec 03 16:13:20 2014 +0100
@@ -148,6 +148,7 @@
kind = 'payable'
return Payment(
+ company=line.move.company,
journal=self.start.journal,
party=line.party,
kind=kind,
diff -r 0feef65b0f4e -r 5dd8c0c2a04c payment.py
--- .a/trytond/trytond/modules/account_payment/payment.py Tue Dec 02 12:54:44 2014 +0100
+++ .b/trytond/trytond/modules/account_payment/payment.py Wed Dec 03 16:13:20 2014 +0100
@@ -118,6 +118,7 @@
depends=_DEPENDS + ['currency_digits'])
line = fields.Many2One('account.move.line', 'Line', ondelete='RESTRICT',
domain=[
+ ('move.company', '=', Eval('company', -1)),
If(Eval('kind') == 'receivable',
['OR', ('debit', '>', 0), ('credit', '<', 0)],
['OR', ('credit', '>', 0), ('debit', '<', 0)],
@@ -138,7 +139,8 @@
],
('move_state', '=', 'posted'),
],
- states=_STATES, depends=_DEPENDS + ['party', 'currency', 'kind'])
+ states=_STATES, depends=_DEPENDS + ['party', 'currency', 'kind',
+ 'company'])
description = fields.Char('Description', states=_STATES, depends=_DEPENDS)
group = fields.Many2One('account.payment.group', 'Group', readonly=True,
ondelete='RESTRICT',

View File

@ -1,42 +0,0 @@
diff -r 05f736458b5e account.py
--- .a/trytond/trytond/modules/account_payment_sepa/account.py Thu Dec 04 23:35:03 2014 +0100
+++ .b/trytond/trytond/modules/account_payment_sepa/account.py Tue Dec 09 18:39:58 2014 +0100
@@ -2,6 +2,7 @@
#this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta
from trytond.model import fields
+from trytond.pyson import Eval
__all__ = ['Configuration']
__metaclass__ = PoolMeta
@@ -12,4 +13,6 @@
sepa_mandate_sequence = fields.Property(fields.Many2One('ir.sequence',
'SEPA Mandate Sequence', domain=[
('code', '=', 'account.payment.sepa.mandate'),
+ ('company', 'in', [Eval('context', {}).get('company', -1),
+ None]),
]))
diff -r 05f736458b5e payment.py
--- .a/trytond/trytond/modules/account_payment_sepa/payment.py Thu Dec 04 23:35:03 2014 +0100
+++ .b/trytond/trytond/modules/account_payment_sepa/payment.py Tue Dec 09 18:39:58 2014 +0100
@@ -157,7 +157,8 @@
self.sepa_messages = ()
message = tmpl.generate(group=self,
datetime=datetime).filter(remove_comment).render()
- message = Message(message=message, type='out', state='waiting')
+ message = Message(message=message, type='out', state='waiting',
+ company=self.company)
self.sepa_messages += (message,)
@property
@@ -192,8 +193,9 @@
ondelete='RESTRICT',
domain=[
('party', '=', Eval('party', -1)),
+ ('company', '=', Eval('company', -1)),
],
- depends=['party'])
+ depends=['party', 'company'])
sepa_mandate_sequence_type = fields.Char('Mandate Sequence Type',
readonly=True)
sepa_return_reason_code = fields.Char('Return Reason Code', readonly=True,

View File

@ -1,50 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619605 -3600
# Wed Dec 03 16:13:25 2014 +0100
# Node ID 2642b961c2bfcf69b078d81dc552650aa84df261
# Parent 23e4eaac8bff56366f2b52a10fe13953b2528f39
# Add missing company domain/field
# issue4311
# review7691002
diff -r 23e4eaac8bff -r 2642b961c2bf statement.py
--- .a/trytond/trytond/modules/account_statement/statement.py Tue Dec 02 12:54:50 2014 +0100
+++ .b/trytond/trytond/modules/account_statement/statement.py Wed Dec 03 16:13:25 2014 +0100
@@ -66,12 +66,12 @@
journal = fields.Many2One('account.statement.journal', 'Journal',
required=True, select=True,
domain=[
- ('company', '=', Eval('context', {}).get('company', -1)),
+ ('company', '=', Eval('company', -1)),
],
states={
'readonly': (Eval('state') != 'draft') | Eval('lines', [0]),
},
- depends=['state'])
+ depends=['state', 'company'])
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
date = fields.Date('Date', required=True, states=_STATES, depends=_DEPENDS,
@@ -435,7 +435,10 @@
('kind', '!=', 'view'),
])
description = fields.Char('Description')
- move = fields.Many2One('account.move', 'Account Move', readonly=True)
+ move = fields.Many2One('account.move', 'Account Move', readonly=True,
+ domain=[
+ ('company', '=', Eval('_parent_statement', {}).get('company', -1)),
+ ])
invoice = fields.Many2One('account.invoice', 'Invoice',
domain=[
If(Bool(Eval('party')), [('party', '=', Eval('party'))], []),
@@ -571,6 +574,7 @@
journal=self.statement.journal.journal,
date=self.date,
origin=self,
+ company=self.statement.company,
lines=move_lines,
)
move.save()

150
analytic_account.diff Normal file
View File

@ -0,0 +1,150 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Add company domain
issue5104
review19141003
Index: trytond/trytond/modules/analytic_account/account.py
===================================================================
--- a/trytond/trytond/modules/analytic_account/account.py
+++ b/trytond/trytond/modules/analytic_account/account.py
@@ -8,7 +8,7 @@
from trytond import backend
from trytond.model import ModelView, ModelSQL, fields, Unique
from trytond.wizard import Wizard, StateView, StateAction, Button
-from trytond.pyson import Eval, PYSONEncoder
+from trytond.pyson import Eval, If, PYSONEncoder, PYSONDecoder
from trytond.transaction import Transaction
from trytond.pool import Pool
@@ -22,7 +22,7 @@
name = fields.Char('Name', required=True, translate=True, select=True)
code = fields.Char('Code', select=True)
active = fields.Boolean('Active', select=True)
- company = fields.Many2One('company.company', 'Company')
+ company = fields.Many2One('company.company', 'Company', required=True)
currency = fields.Many2One('currency.currency', 'Currency', required=True)
currency_digits = fields.Function(fields.Integer('Currency Digits'),
'on_change_with_currency_digits')
@@ -311,19 +311,26 @@
__name__ = 'analytic.account.entry'
origin = fields.Reference('Origin', selection='get_origin', select=True)
root = fields.Many2One('analytic_account.account', 'Root Analytic',
- domain=[('type', '=', 'root')])
+ domain=[
+ ('company', '=', Eval('company')),
+ ('type', '=', 'root'),
+ ],
+ depends=['company'])
account = fields.Many2One('analytic_account.account', 'Account',
ondelete='RESTRICT',
states={
'required': Eval('required', False),
},
domain=[
+ ('company', '=', Eval('company')),
('root', '=', Eval('root')),
('type', '=', 'normal'),
],
- depends=['root', 'required'])
+ depends=['root', 'required', 'company'])
required = fields.Function(fields.Boolean('Required'),
'on_change_with_required')
+ company = fields.Function(fields.Many2One('company.company', 'Company'),
+ 'on_change_with_company', searcher='search_company')
@classmethod
def __register__(cls, module_name):
@@ -386,12 +393,27 @@
return self.root.mandatory
return False
+ @classmethod
+ def default_company(cls):
+ return Transaction().context.get('company')
+
+ def on_change_with_company(self, name=None):
+ return Transaction().context.get('company')
+
+ @classmethod
+ def search_company(cls, name, clause):
+ raise NotImplementedError()
+
class AnalyticMixin(ModelSQL):
analytic_accounts = fields.One2Many('analytic.account.entry', 'origin',
'Analytic Accounts',
size=Eval('analytic_accounts_size', 0),
+ domain=[
+ ('company', If(Eval('context', {}).contains('company'), '=', '!='),
+ Eval('context', {}).get('company', -1)),
+ ],
depends=['analytic_accounts_size'])
analytic_accounts_size = fields.Function(fields.Integer(
'Analytic Accounts Size'), 'get_analytic_accounts_size')
@@ -427,13 +449,19 @@
where=entry.selection == selection_id))
handler.drop_column('analytic_accounts')
- @staticmethod
- def default_analytic_accounts():
+ @classmethod
+ def analytic_accounts_domain(cls):
+ return PYSONDecoder(Transaction().context).decode(
+ PYSONEncoder().encode(cls.analytic_accounts.domain))
+
+ @classmethod
+ def default_analytic_accounts(cls):
pool = Pool()
AnalyticAccount = pool.get('analytic_account.account')
accounts = []
- root_accounts = AnalyticAccount.search([
+ root_accounts = AnalyticAccount.search(
+ cls.analytic_accounts_domain() + [
('parent', '=', None),
])
for account in root_accounts:
@@ -443,11 +471,14 @@
})
return accounts
- @staticmethod
- def default_analytic_accounts_size():
+ @classmethod
+ def default_analytic_accounts_size(cls):
pool = Pool()
AnalyticAccount = pool.get('analytic_account.account')
- return len(AnalyticAccount.search([('type', '=', 'root')]))
+ return len(AnalyticAccount.search(
+ cls.analytic_accounts_domain() + [
+ ('type', '=', 'root'),
+ ]))
@classmethod
def get_analytic_accounts_size(cls, records, name):
@@ -464,12 +495,17 @@
"Check that all mandatory root entries are defined in entries"
pool = Pool()
Account = pool.get('analytic_account.account')
- mandatory_roots = {a for a in Account.search([
+ all_mandatory_roots = {a for a in Account.search([
('type', '=', 'root'),
('mandatory', '=', True),
])}
for analytic in analytics:
analytic_roots = {e.root for e in analytic.analytic_accounts}
+ companies = {e.company for e in analytic.analytic_accounts}
+ mandatory_roots = set()
+ for mandatory in all_mandatory_roots:
+ if mandatory.company in companies:
+ mandatory_roots.add(mandatory)
if not mandatory_roots <= analytic_roots:
cls.raise_user_error('root_account', {
'name': analytic.rec_name,

48
analytic_invoice.diff Normal file
View File

@ -0,0 +1,48 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Add company domain on analytic entries
issue5104
review24081002
Index: trytond/trytond/modules/analytic_invoice/invoice.py
===================================================================
--- a/trytond/trytond/modules/analytic_invoice/invoice.py
+++ b/trytond/trytond/modules/analytic_invoice/invoice.py
@@ -1,5 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
from trytond.pool import PoolMeta, Pool
from trytond.modules.analytic_account import AnalyticMixin
@@ -61,3 +62,24 @@
def _get_origin(cls):
origins = super(AnalyticAccountEntry, cls)._get_origin()
return origins + ['account.invoice.line']
+
+ @fields.depends('origin')
+ def on_change_with_company(self, name=None):
+ pool = Pool()
+ InvoiceLine = pool.get('account.invoice.line')
+ company = super(AnalyticAccountEntry, self).on_change_with_company(
+ name)
+ if isinstance(self.origin, InvoiceLine):
+ if self.origin.invoice:
+ return self.origin.invoice.company.id
+ elif self.origin.company:
+ return self.origin.company.id
+ return company
+
+ @classmethod
+ def search_company(cls, name, clause):
+ return ['OR',
+ [('origin.company',) + tuple(clause[1:]) +
+ tuple(('account.invoice.line',))],
+ [('origin.invoice.company',) + tuple(clause[1:]) +
+ tuple(('account.invoice.line',))]]

37
analytic_purchase.diff Normal file
View File

@ -0,0 +1,37 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Add company domain on analytic entries
issue5104
review17201002
Index: trytond/trytond/modules/analytic_purchase/purchase.py
===================================================================
--- a/trytond/trytond/modules/analytic_purchase/purchase.py
+++ b/trytond/trytond/modules/analytic_purchase/purchase.py
@@ -79,3 +79,22 @@
and self.origin.purchase.state in ['cancel', 'draft']):
return False
return required
+
+ @fields.depends('origin')
+ def on_change_with_company(self, name=None):
+ pool = Pool()
+ PurchaseLine = pool.get('purchase.line')
+ company = super(AnalyticAccountEntry, self).on_change_with_company(
+ name)
+ if isinstance(self.origin, PurchaseLine):
+ if self.origin.purchase:
+ return self.origin.purchase.company.id
+ return company
+
+ @classmethod
+ def search_company(cls, name, clause):
+ domain = super(AnalyticAccountEntry, cls).search_company(name, clause)
+ return ['OR',
+ domain,
+ [('origin.purchase.company',) + tuple(clause[1:]) +
+ tuple(('purchase.line',))]]

45
analytic_sale.diff Normal file
View File

@ -0,0 +1,45 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Add company domain on analytic entries
issue5104
review17991002
Index: trytond/trytond/modules/analytic_sale/sale.py
===================================================================
--- a/trytond/trytond/modules/analytic_sale/sale.py
+++ b/trytond/trytond/modules/analytic_sale/sale.py
@@ -1,5 +1,6 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.modules.analytic_account import AnalyticMixin
@@ -32,3 +33,22 @@
def _get_origin(cls):
origins = super(AnalyticAccountEntry, cls)._get_origin()
return origins + ['sale.line']
+
+ @fields.depends('origin')
+ def on_change_with_company(self, name=None):
+ pool = Pool()
+ SaleLine = pool.get('sale.line')
+ company = super(AnalyticAccountEntry, self).on_change_with_company(
+ name)
+ if isinstance(self.origin, SaleLine):
+ if self.origin.sale:
+ return self.origin.sale.company.id
+ return company
+
+ @classmethod
+ def search_company(cls, name, clause):
+ domain = super(AnalyticAccountEntry, cls).search_company(name, clause)
+ return ['OR',
+ domain,
+ [('origin.sale.company',) + tuple(clause[1:]) +
+ tuple(('sale.line',))]]

View File

@ -1,23 +1,24 @@
diff -r 75c44f5a88e0 trytond/trytond/protocols/dispatcher.py
--- a/trytond/trytond/protocols/dispatcher.py Mon Jul 20 09:50:24 2015 +0200
+++ b/trytond/trytond/protocols/dispatcher.py Mon Jul 20 10:21:09 2015 +0200
@@ -138,7 +138,18 @@
with Transaction().start(database_name, user,
readonly=True) as transaction:
pool.init()
- obj = pool.get(object_name, type=object_type)
@@ -157,7 +157,19 @@
type, _ = method.split('.', 1)
name = '.'.join(method.split('.')[1:-1])
method = method.split('.')[-1]
- return pool.get(name, type=type), method
+ try:
+ obj = pool.get(object_name, type=object_type)
+ obj = pool.get(name, type=type)
+ except KeyError:
+ if object_name[:15] == 'babi_execution_':
+ with Transaction().start(database_name, user,
+ readonly=False) as transaction:
+ if name[:15] == 'babi_execution_':
+ with Transaction().start(pool.database_name, request.user_id,
+ readonly=False):
+ Execution = pool.get('babi.report.execution')
+ execution = Execution(int(object_name[15:]))
+ execution = Execution(int(name[15:]))
+ execution.validate_model()
+ obj = pool.get(object_name, type=object_type)
+ obj = pool.get(name, type=type)
+ else:
+ raise
+ return obj, method
if method in obj.__rpc__:
rpc = obj.__rpc__[method]
@app.auth_required

View File

@ -1,491 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
# Date 1444057776 -7200
# Mon Oct 05 17:09:36 2015 +0200
# Node ID 53e93ecd5aee050604a332dbee4b76c9e53e9a28
# Parent 72937562d4c14d890bcd5a12d3a29c833775e08f
Make chart of accounts not translatable
issue3432
review21431002
diff -r 72937562d4c1 -r 53e93ecd5aee trytond/trytond/modules/account/account.py
--- a/trytond/trytond/modules/account/account.py Sat Oct 03 12:02:12 2015 +0200
+++ b/trytond/trytond/modules/account/account.py Mon Oct 05 17:09:36 2015 +0200
@@ -43,7 +43,7 @@
class TypeTemplate(ModelSQL, ModelView):
'Account Type Template'
__name__ = 'account.account.type.template'
- name = fields.Char('Name', required=True, translate=True)
+ name = fields.Char('Name', required=True)
parent = fields.Many2One('account.account.type.template', 'Parent',
ondelete="RESTRICT")
childs = fields.One2Many('account.account.type.template', 'parent',
@@ -129,8 +129,6 @@
'''
pool = Pool()
Type = pool.get('account.account.type')
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2type is None:
template2type = {}
@@ -142,24 +140,6 @@
new_type, = Type.create([vals])
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- template = self.__class__(self.id)
- data = {}
- for field_name, field in template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(template, field_name)
- if data:
- Type.write([new_type], data)
template2type[self.id] = new_type.id
new_id = template2type[self.id]
@@ -173,7 +153,7 @@
class Type(ModelSQL, ModelView):
'Account Type'
__name__ = 'account.account.type'
- name = fields.Char('Name', size=None, required=True, translate=True)
+ name = fields.Char('Name', size=None, required=True)
parent = fields.Many2One('account.account.type', 'Parent',
ondelete="RESTRICT", domain=[
('company', '=', Eval('company')),
@@ -294,9 +274,6 @@
value, used to convert template id into type. The dictionary is filled
with new types
'''
- pool = Pool()
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2type is None:
template2type = {}
@@ -306,26 +283,6 @@
if vals:
self.write([self], vals)
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self.template._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self.template, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- type_ = self.__class__(self.id)
- data = {}
- for field_name, field in (
- type_.template._fields.iteritems()):
- if (getattr(field, 'translate', False)
- and (getattr(type_.template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(type_.template,
- field_name)
- if data:
- self.write([type_], data)
template2type[self.template.id] = self.id
for child in self.childs:
@@ -354,8 +311,7 @@
class AccountTemplate(ModelSQL, ModelView):
'Account Template'
__name__ = 'account.account.template'
- name = fields.Char('Name', size=None, required=True, translate=True,
- select=True)
+ name = fields.Char('Name', size=None, required=True, select=True)
code = fields.Char('Code', size=None, select=True)
type = fields.Many2One('account.account.type.template', 'Type',
ondelete="RESTRICT",
@@ -480,8 +436,6 @@
'''
pool = Pool()
Account = pool.get('account.account')
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2account is None:
template2account = {}
@@ -498,24 +452,6 @@
new_account, = Account.create([vals])
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- template = self.__class__(self.id)
- data = {}
- for field_name, field in self._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(template, field_name)
- if data:
- Account.write([new_account], data)
template2account[self.id] = new_account.id
new_id = template2account[self.id]
@@ -562,8 +498,7 @@
class Account(ModelSQL, ModelView):
'Account'
__name__ = 'account.account'
- name = fields.Char('Name', size=None, required=True, translate=True,
- select=True)
+ name = fields.Char('Name', size=None, required=True, select=True)
code = fields.Char('Code', size=None, select=True)
active = fields.Boolean('Active', select=True)
company = fields.Many2One('company.company', 'Company', required=True,
@@ -918,9 +853,6 @@
template2type is a dictionary with type template id as key and type id
as value, used to convert type template id into type.
'''
- pool = Pool()
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2account is None:
template2account = {}
@@ -938,26 +870,6 @@
if vals:
self.write([self], vals)
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self.template._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self.template, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- account = self.__class__(self.id)
- data = {}
- for field_name, field in (
- account.template._fields.iteritems()):
- if (getattr(field, 'translate', False)
- and (getattr(account.template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(account.template,
- field_name)
- if data:
- self.write([account], data)
template2account[self.template.id] = self.id
for child in self.childs:
diff -r 72937562d4c1 -r 53e93ecd5aee trytond/trytond/modules/account/tax.py
--- a/trytond/trytond/modules/account/tax.py Sat Oct 03 12:02:12 2015 +0200
+++ b/trytond/trytond/modules/account/tax.py Mon Oct 05 17:09:36 2015 +0200
@@ -34,7 +34,7 @@
class TaxGroup(ModelSQL, ModelView):
'Tax Group'
__name__ = 'account.tax.group'
- name = fields.Char('Name', size=None, required=True, translate=True)
+ name = fields.Char('Name', size=None, required=True)
code = fields.Char('Code', size=None, required=True)
kind = fields.Selection(KINDS, 'Kind', required=True)
@@ -56,13 +56,13 @@
class TaxCodeTemplate(ModelSQL, ModelView):
'Tax Code Template'
__name__ = 'account.tax.code.template'
- name = fields.Char('Name', required=True, translate=True)
+ name = fields.Char('Name', required=True)
code = fields.Char('Code')
parent = fields.Many2One('account.tax.code.template', 'Parent')
childs = fields.One2Many('account.tax.code.template', 'parent', 'Children')
account = fields.Many2One('account.account.template', 'Account Template',
domain=[('parent', '=', None)], required=True)
- description = fields.Text('Description', translate=True)
+ description = fields.Text('Description')
@classmethod
def __setup__(cls):
@@ -101,8 +101,6 @@
'''
pool = Pool()
TaxCode = pool.get('account.tax.code')
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2tax_code is None:
template2tax_code = {}
@@ -114,24 +112,9 @@
new_tax_code, = TaxCode.create([vals])
- prev_lang = self._context.get('language') or Config.get_language()
prev_data = {}
for field_name, field in self._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- template = self.__class__(self.id)
- data = {}
- for field_name, field in template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(template, field_name)
- if data:
- TaxCode.write([new_tax_code], data)
+ prev_data[field_name] = getattr(self, field_name)
template2tax_code[self.id] = new_tax_code.id
new_id = template2tax_code[self.id]
@@ -145,8 +128,7 @@
class TaxCode(ModelSQL, ModelView):
'Tax Code'
__name__ = 'account.tax.code'
- name = fields.Char('Name', size=None, required=True, select=True,
- translate=True)
+ name = fields.Char('Name', size=None, required=True, select=True)
code = fields.Char('Code', size=None, select=True)
active = fields.Boolean('Active', select=True)
company = fields.Many2One('company.company', 'Company', required=True,
@@ -161,7 +143,7 @@
digits=(16, Eval('currency_digits', 2)), depends=['currency_digits']),
'get_sum')
template = fields.Many2One('account.tax.code.template', 'Template')
- description = fields.Text('Description', translate=True)
+ description = fields.Text('Description')
@classmethod
def __setup__(cls):
@@ -259,9 +241,6 @@
tax code id as value, used to convert template id into tax code. The
dictionary is filled with new tax codes
'''
- pool = Pool()
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2tax_code is None:
template2tax_code = {}
@@ -270,26 +249,6 @@
vals = self.template._get_tax_code_value(code=self)
if vals:
self.write([self], vals)
-
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self.template._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self.template, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- code = self.__class__(self.id)
- data = {}
- for field_name, field in code.template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(code.template, field_name) !=
- prev_data[field_name])):
- data[field_name] = getattr(code.template,
- field_name)
- if data:
- self.write([code], data)
template2tax_code[self.template.id] = self.id
for child in self.childs:
@@ -353,8 +312,8 @@
class TaxTemplate(ModelSQL, ModelView):
'Account Tax Template'
__name__ = 'account.tax.template'
- name = fields.Char('Name', required=True, translate=True)
- description = fields.Char('Description', required=True, translate=True)
+ name = fields.Char('Name', required=True)
+ description = fields.Char('Description', required=True)
group = fields.Many2One('account.tax.group', 'Group')
sequence = fields.Integer('Sequence')
start_date = fields.Date('Starting Date')
@@ -514,8 +473,6 @@
'''
pool = Pool()
Tax = pool.get('account.tax')
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2tax is None:
template2tax = {}
@@ -557,24 +514,6 @@
new_tax, = Tax.create([vals])
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- template = self.__class__(self.id)
- data = {}
- for field_name, field in template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(template, field_name)
- != prev_data[field_name])):
- data[field_name] = getattr(template, field_name)
- if data:
- Tax.write([new_tax], data)
template2tax[self.id] = new_tax.id
new_id = template2tax[self.id]
@@ -596,8 +535,8 @@
none: tax = none
'''
__name__ = 'account.tax'
- name = fields.Char('Name', required=True, translate=True)
- description = fields.Char('Description', required=True, translate=True,
+ name = fields.Char('Name', required=True)
+ description = fields.Char('Description', required=True,
help="The name that will be used in reports")
group = fields.Many2One('account.tax.group', 'Group',
states={
@@ -945,9 +884,6 @@
value, used to convert template id into tax. The dictionary is filled
with new taxes.
'''
- pool = Pool()
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2tax is None:
template2tax = {}
@@ -1018,25 +954,6 @@
if vals:
self.write([self], vals)
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self.template._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self.template, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- tax = self.__class__(self.id)
- data = {}
- for field_name, field in tax.template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(tax.template, field_name)
- != prev_data[field_name])):
- data[field_name] = getattr(tax.template,
- field_name)
- if data:
- self.write([tax], data)
template2tax[self.template.id] = self.id
for child in self.childs:
@@ -1195,7 +1112,7 @@
class TaxRuleTemplate(ModelSQL, ModelView):
'Tax Rule Template'
__name__ = 'account.tax.rule.template'
- name = fields.Char('Name', required=True, translate=True)
+ name = fields.Char('Name', required=True)
kind = fields.Selection(KINDS, 'Kind', required=True)
lines = fields.One2Many('account.tax.rule.line.template', 'rule', 'Lines')
account = fields.Many2One('account.account.template', 'Account Template',
@@ -1228,8 +1145,6 @@
'''
pool = Pool()
Rule = pool.get('account.tax.rule')
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2rule is None:
template2rule = {}
@@ -1239,24 +1154,6 @@
vals['company'] = company_id
new_rule, = Rule.create([vals])
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- template = self.__class__(self.id)
- data = {}
- for field_name, field in template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(self, field_name)
- != prev_data[field_name])):
- data[field_name] = getattr(self, field_name)
- if data:
- Rule.write([new_rule], data)
template2rule[self.id] = new_rule.id
return template2rule[self.id]
@@ -1264,7 +1161,7 @@
class TaxRule(ModelSQL, ModelView):
'Tax Rule'
__name__ = 'account.tax.rule'
- name = fields.Char('Name', required=True, translate=True)
+ name = fields.Char('Name', required=True)
kind = fields.Selection(KINDS, 'Kind', required=True)
company = fields.Many2One('company.company', 'Company', required=True,
select=True, domain=[
@@ -1305,9 +1202,6 @@
rule id as value, used to convert template id into tax rule. The
dictionary is filled with new tax rules.
'''
- pool = Pool()
- Lang = pool.get('ir.lang')
- Config = pool.get('ir.configuration')
if template2rule is None:
template2rule = {}
@@ -1317,25 +1211,6 @@
if vals:
self.write([self], vals)
- prev_lang = self._context.get('language') or Config.get_language()
- prev_data = {}
- for field_name, field in self.template._fields.iteritems():
- if getattr(field, 'translate', False):
- prev_data[field_name] = getattr(self.template, field_name)
- for lang in Lang.get_translatable_languages():
- if lang == prev_lang:
- continue
- with Transaction().set_context(language=lang):
- rule = self.__class__(self.id)
- data = {}
- for field_name, field in rule.template._fields.iteritems():
- if (getattr(field, 'translate', False)
- and (getattr(rule.template, field_name)
- != prev_data[field_name])):
- data[field_name] = getattr(rule.template,
- field_name)
- if data:
- self.write([rule], data)
template2rule[self.template.id] = self.id

View File

@ -1,21 +0,0 @@
diff -r 072562663a50 tryton/gui/main.py
--- ./tryton/tryton/gui/main.py Fri May 09 10:13:53 2014 +0200
+++ ./tryton/tryton/gui/main.py Sat May 24 18:14:02 2014 +0200
@@ -1420,10 +1420,12 @@
if not urlp.scheme == 'tryton':
return
urlp = urlparse('http' + url[6:])
- hostname, port = map(urllib.unquote,
- (urlp.netloc.split(':', 1) + [CONFIG.defaults['login.port']])[:2])
- database, path = map(urllib.unquote,
- (urlp.path[1:].split('/', 1) + [None])[:2])
+ hostname = urllib.unquote(urlp.hostname or
+ CONFIG.defaults['login.server'])
+ port = urlp.port or str(CONFIG.defaults['login.port'])
+ path = urlp.path[1:].split('/', 1)
+ database = urllib.unquote(path.pop(0))
+ path = path and urllib.unquote(path[0]) or ""
if (not path or
hostname != rpc._HOST or
int(port) != rpc._PORT or
)

View File

@ -1,190 +0,0 @@
# Issue: #022388: Correcció subdivisió Vizcaya.
diff -r 9f01290c6922 country.xml
--- .a/trytond/trytond/modules/country/country.xml Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/country.xml Wed Jan 28 00:16:10 2015 +0100
@@ -30397,7 +30397,7 @@
</record>
<record model="country.subdivision" id="es-bi">
- <field name="name">Vizcayaa / Bizkaia</field>
+ <field name="name">Vizcaya / Bizkaia</field>
<field name="code">ES-BI</field>
<field name="type">province</field>
<field name="parent" ref="es-pv"/>
diff -r 9f01290c6922 locale/bg_BG.po
--- .a/trytond/trytond/modules/country/locale/bg_BG.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/bg_BG.po Wed Jan 28 00:16:10 2015 +0100
@@ -5709,8 +5709,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/ca_ES.po
--- .a/trytond/trytond/modules/country/locale/ca_ES.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/ca_ES.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/cs_CZ.po
--- .a/trytond/trytond/modules/country/locale/cs_CZ.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/cs_CZ.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/de_DE.po
--- .a/trytond/trytond/modules/country/locale/de_DE.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/de_DE.po Wed Jan 28 00:16:10 2015 +0100
@@ -5697,8 +5697,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/es_AR.po
--- .a/trytond/trytond/modules/country/locale/es_AR.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/es_AR.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/es_CO.po
--- .a/trytond/trytond/modules/country/locale/es_CO.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/es_CO.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/es_EC.po
--- .a/trytond/trytond/modules/country/locale/es_EC.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/es_EC.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/es_ES.po
--- .a/trytond/trytond/modules/country/locale/es_ES.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/es_ES.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/fr_FR.po
--- .a/trytond/trytond/modules/country/locale/fr_FR.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/fr_FR.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,7 +5699,7 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
msgstr "Biscaye"
msgctxt "model:country.subdivision,name:es-bu"
diff -r 9f01290c6922 locale/lt_LT.po
--- .a/trytond/trytond/modules/country/locale/lt_LT.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/lt_LT.po Wed Jan 28 00:16:10 2015 +0100
@@ -5697,8 +5697,8 @@
msgstr "Badachoso provincija"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"
diff -r 9f01290c6922 locale/nl_NL.po
--- .a/trytond/trytond/modules/country/locale/nl_NL.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/nl_NL.po Wed Jan 28 00:16:10 2015 +0100
@@ -5713,7 +5713,7 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
msgstr "Biskaje / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
diff -r 9f01290c6922 locale/ru_RU.po
--- .a/trytond/trytond/modules/country/locale/ru_RU.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/ru_RU.po Wed Jan 28 00:16:10 2015 +0100
@@ -5709,7 +5709,7 @@
msgstr ""
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
msgstr ""
msgctxt "model:country.subdivision,name:es-bu"
diff -r 9f01290c6922 locale/sl_SI.po
--- .a/trytond/trytond/modules/country/locale/sl_SI.po Mon Oct 20 14:50:30 2014 +0200
+++ .b/trytond/trytond/modules/country/locale/sl_SI.po Wed Jan 28 00:16:10 2015 +0100
@@ -5699,8 +5699,8 @@
msgstr "Badajoz"
msgctxt "model:country.subdivision,name:es-bi"
-msgid "Vizcayaa / Bizkaia"
-msgstr "Vizcayaa / Bizkaia"
+msgid "Vizcaya / Bizkaia"
+msgstr "Vizcaya / Bizkaia"
msgctxt "model:country.subdivision,name:es-bu"
msgid "Burgos"

View File

@ -1,24 +0,0 @@
diff --git a/modules/purchase_shipment_cost/tests/test_purchase_shipment_cost.py b/modules/purchase_shipment_cost/tests/test_purchase_shipment_cost.py
--- .a/trytond/trytond/modules/purchase_shipment_cost/tests/test_purchase_shipment_cost.py
+++ .b/trytond/trytond/modules/purchase_shipment_cost/tests/test_purchase_shipment_cost.py
@@ -30,12 +30,12 @@
suite.addTests(doctest.DocFileSuite('scenario_purchase_shipment_cost.rst',
setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_purchase_shipment_cost_with_account_stock.rst',
- setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
- suite.addTests(doctest.DocFileSuite(
- 'scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst',
- setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
- optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+# suite.addTests(doctest.DocFileSuite(
+# 'scenario_purchase_shipment_cost_with_account_stock.rst',
+# setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
+# optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
+# suite.addTests(doctest.DocFileSuite(
+# 'scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst',
+# setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
+# optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite

View File

@ -1,10 +1,10 @@
diff -r 1a22411f9264 trytond/trytond/model/fields/many2many.py
--- a/trytond/trytond/model/fields/many2many.py Thu Jul 16 01:13:45 2015 +0200
+++ b/trytond/trytond/model/fields/many2many.py Mon Jul 20 14:20:18 2015 +0200
@@ -270,6 +270,9 @@
transaction = Transaction()
@@ -287,6 +287,9 @@
table, _ = tables[None]
name, operator, value = domain[:3]
assert operator not in {'where', 'not where'} or '.' not in name
+ method = getattr(Model, 'domain_%s' % name, None)
+ if method:
+ return method(domain, tables)
@ -14,7 +14,7 @@ diff -r 1a22411f9264 trytond/trytond/model/fields/many2many.py
diff -r 1a22411f9264 trytond/trytond/model/fields/many2one.py
--- a/trytond/trytond/model/fields/many2one.py Thu Jul 16 01:13:45 2015 +0200
+++ b/trytond/trytond/model/fields/many2one.py Mon Jul 20 14:20:18 2015 +0200
@@ -141,6 +141,9 @@
@@ -159,6 +159,9 @@
table, _ = tables[None]
name, operator, value = domain[:3]
@ -23,14 +23,14 @@ diff -r 1a22411f9264 trytond/trytond/model/fields/many2one.py
+ return method(domain, tables)
column = self.sql_column(table)
if '.' not in name:
if operator in ('child_of', 'not child_of'):
if operator.endswith('child_of') or operator.endswith('parent_of'):
diff -r 1a22411f9264 trytond/trytond/model/fields/one2many.py
--- a/trytond/trytond/model/fields/one2many.py Thu Jul 16 01:13:45 2015 +0200
+++ b/trytond/trytond/model/fields/one2many.py Mon Jul 20 14:20:18 2015 +0200
@@ -231,6 +231,9 @@
transaction = Transaction()
@@ -232,6 +232,9 @@
table, _ = tables[None]
name, operator, value = domain[:3]
assert operator not in {'where', 'not where'} or '.' not in name
+ method = getattr(Model, 'domain_%s' % name, None)
+ if method:
+ return method(domain, tables)
@ -41,7 +41,7 @@ diff -r 1a22411f9264 trytond/trytond/model/fields/property.py
--- a/trytond/trytond/model/fields/property.py Thu Jul 16 01:13:45 2015 +0200
+++ b/trytond/trytond/model/fields/property.py Mon Jul 20 14:20:18 2015 +0200
@@ -72,6 +72,9 @@
cursor = Transaction().cursor
cursor = Transaction().connection.cursor()
name, operator, value = domain
+ method = getattr(Model, 'domain_%s' % name, None)
@ -53,7 +53,7 @@ diff -r 1a22411f9264 trytond/trytond/model/fields/property.py
diff -r 1a22411f9264 trytond/trytond/model/fields/reference.py
--- a/trytond/trytond/model/fields/reference.py Thu Jul 16 01:13:45 2015 +0200
+++ b/trytond/trytond/model/fields/reference.py Mon Jul 20 14:20:18 2015 +0200
@@ -125,6 +125,9 @@
@@ -124,6 +124,9 @@
return super(Reference, self).convert_domain(domain, tables, Model)
pool = Pool()
name, operator, value, target = domain[:4]

View File

@ -1,16 +1,7 @@
diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
--- a/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 16:46:50 2015 +0200
+++ b/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 17:12:14 2015 +0200
@@ -852,7 +852,7 @@
if line.type != 'line':
continue
with Transaction().set_context(**context):
- tax_list = Tax.compute(Tax.browse(line.taxes),
+ tax_list = Tax.compute(line.taxes,
line.unit_price, line.quantity,
date=self.accounting_date or self.invoice_date)
for tax in tax_list:
@@ -944,33 +944,35 @@
@@ -859,34 +859,35 @@
'''
Return move line
'''
@ -25,23 +16,25 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
- res['amount_second_currency'] = Currency.compute(
+ line.amount_second_currency = Currency.compute(
self.company.currency, amount, self.currency)
- res['amount_second_currency'] = abs(res['amount_second_currency'])
- res['second_currency'] = self.currency.id
+ line.amount_second_currency = abs(line.amount_second_currency)
+ line.amount_second_currency = -line.amount_second_currency
+ line.second_currency = self.currency.id
else:
- res['amount_second_currency'] = None
- res['second_currency'] = None
- if amount <= 0:
- res['debit'], res['credit'] = -amount, 0
+ line.amount_second_currency = None
+ line.second_currency = None
if amount >= Decimal('0.0'):
- res['debit'] = Decimal('0.0')
- res['credit'] = amount
+ if amount >= Decimal('0.0'):
+ line.debit = Decimal('0.0')
+ line.credit = amount
else:
- res['debit'] = - amount
- res['credit'] = Decimal('0.0')
- res['debit'], res['credit'] = 0, amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = (
- res['amount_second_currency'].copy_sign(
- res['debit'] - res['credit']))
- res['account'] = self.account.id
+ line.debit = - amount
+ line.credit = Decimal('0.0')
@ -64,22 +57,20 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
'''
pool = Pool()
Move = pool.get('account.move')
@@ -986,10 +988,10 @@
@@ -902,9 +903,9 @@
total = Decimal('0.0')
total_currency = Decimal('0.0')
for line in move_lines:
- total += line['debit'] - line['credit']
- if line['amount_second_currency']:
- total_currency += line['amount_second_currency'].copy_sign(
- line['debit'] - line['credit'])
- total_currency += line['amount_second_currency']
+ total += line.debit - line.credit
+ if line.amount_second_currency:
+ total_currency += line.amount_second_currency.copy_sign(
+ line.debit - line.credit)
+ total_currency += line.amount_second_currency
term_lines = self.payment_term.compute(total, self.company.currency,
self.invoice_date)
@@ -997,28 +999,23 @@
@@ -912,28 +913,23 @@
if not term_lines:
term_lines = [(Date.today(), total)]
for date, amount in term_lines:
@ -120,21 +111,20 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
return move
def set_number(self):
@@ -1050,11 +1047,10 @@
@@ -970,10 +966,9 @@
with Transaction().set_context(
date=self.invoice_date or Date.today()):
number = Sequence.get_id(sequence.id)
- vals = {'number': number}
+ self.number = number
if (not self.invoice_date
and self.type in ('out_invoice', 'out_credit_note')):
if not self.invoice_date and self.type == 'out':
- vals['invoice_date'] = Transaction().context['date']
- self.write([self], vals)
+ self.invoice_date = Transaction().context['date']
@classmethod
def check_modify(cls, invoices):
@@ -1109,7 +1105,7 @@
@@ -1033,7 +1028,7 @@
all_invoices += invoices
update_tax = [i for i in all_invoices if i.state == 'draft']
super(Invoice, cls).write(*args)
@ -143,7 +133,7 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
cls.update_taxes(update_tax)
@classmethod
@@ -1340,18 +1336,16 @@
@@ -1201,18 +1196,16 @@
'''
MoveLine = Pool().get('account.move.line')
@ -167,13 +157,13 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
return new_invoices
@classmethod
@@ -1371,10 +1365,16 @@
@@ -1232,10 +1225,16 @@
@ModelView.button
@Workflow.transition('validated')
def validate_invoice(cls, invoices):
+ to_write = []
for invoice in invoices:
if invoice.type in ('in_invoice', 'in_credit_note'):
if invoice.type == 'in':
invoice.set_number()
- invoice.create_move()
+ move = invoice.get_move()
@ -185,7 +175,7 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
@classmethod
@ModelView.button
@@ -1382,14 +1382,29 @@
@@ -1243,14 +1242,29 @@
def post(cls, invoices):
Move = Pool().get('account.move')
@ -219,9 +209,9 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
+ cls.write(invoices, {'state': 'posted'})
+ Move.post([i.move for i in invoices if i.move.state != 'posted'])
for invoice in invoices:
if invoice.type in ('out_invoice', 'out_credit_note'):
if invoice.type == 'out':
invoice.print_invoice()
@@ -1428,14 +1443,17 @@
@@ -1289,14 +1303,17 @@
cancel_moves = []
delete_moves = []
@ -240,44 +230,25 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
if delete_moves:
Move.delete(delete_moves)
if cancel_moves:
@@ -1754,8 +1772,7 @@
context = self.invoice.get_tax_context()
taxes_keys = []
with Transaction().set_context(**context):
- taxes = Tax.compute(Tax.browse(self.taxes),
- self.unit_price, self.quantity)
+ taxes = Tax.compute(self.taxes, self.unit_price, self.quantity)
for tax in taxes:
key, _ = Invoice._compute_tax(tax, self.invoice.type)
taxes_keys.append(key)
@@ -2003,14 +2020,14 @@
@@ -1852,6 +1869,7 @@
def _compute_taxes(self):
pool = Pool()
Tax = pool.get('account.tax')
Currency = pool.get('currency.currency')
+ TaxLine = pool.get('account.tax.line')
context = self.invoice.get_tax_context()
res = []
if self.type != 'line':
return res
with Transaction().set_context(**context):
- taxes = Tax.compute(Tax.browse(self.taxes),
- self.unit_price, self.quantity)
+ taxes = Tax.compute(self.taxes, self.unit_price, self.quantity)
for tax in taxes:
if self.invoice.type in ('out_invoice', 'in_invoice'):
base_code_id = (tax['tax'].invoice_base_code.id
@@ -2025,59 +2042,61 @@
@@ -1869,53 +1887,61 @@
date=self.invoice.currency_date):
amount = Currency.compute(self.invoice.currency,
amount, self.invoice.company.currency)
- res.append({
- 'code': base_code_id,
- 'code': base_code,
- 'amount': amount,
- 'tax': tax['tax'].id if tax['tax'] else None,
- 'tax': tax['tax'],
- })
+ tax_line = TaxLine()
+ tax_line.code = base_code_id
+ tax_line.code = base_code
+ tax_line.amount = amount
+ tax_line.tax = tax['tax']
+ res.append(tax_line)
@ -310,40 +281,37 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
amount = self.amount
- res['amount_second_currency'] = None
- res['second_currency'] = None
- if amount >= 0:
- if self.invoice.type == 'out':
- res['debit'], res['credit'] = 0, amount
+ line.amount_second_currency = None
+ line.second_currency = None
if self.invoice.type in ('in_invoice', 'out_credit_note'):
if amount >= Decimal('0.0'):
- res['debit'] = amount
- res['credit'] = Decimal('0.0')
+ if self.invoice.type in ('in_invoice', 'out_credit_note'):
+ if amount >= Decimal('0.0'):
+ line.debit = amount
+ line.credit = Decimal('0.0')
else:
- res['debit'] = Decimal('0.0')
- res['credit'] = - amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = \
- - res['amount_second_currency']
- res['debit'], res['credit'] = amount, 0
+ line.debit = Decimal('0.0')
+ line.credit = -amount
+ if line.amount_second_currency:
+ line.amount_second_currency = \
+ - line.amount_second_currency
else:
if amount >= Decimal('0.0'):
- res['debit'] = Decimal('0.0')
- res['credit'] = amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = \
- - res['amount_second_currency']
- if self.invoice.type == 'out':
- res['debit'], res['credit'] = -amount, 0
+ if amount >= Decimal('0.0'):
+ line.debit = Decimal('0.0')
+ line.credit = amount
+ if line.amount_second_currency:
+ line.amount_second_currency = \
+ - line.amount_second_currency
else:
- res['debit'] = - amount
- res['credit'] = Decimal('0.0')
- res['debit'], res['credit'] = 0, -amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = (
- res['amount_second_currency'].copy_sign(
- res['debit'] - res['credit']))
- res['account'] = self.account.id
+ line.debit = -amount
+ line.credit = Decimal('0.0')
@ -360,7 +328,7 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
def _credit(self):
'''
@@ -2293,53 +2312,56 @@
@@ -2131,47 +2157,56 @@
def get_move_line(self):
'''
@ -390,40 +358,37 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
amount = self.amount
- res['amount_second_currency'] = None
- res['second_currency'] = None
- if amount >= 0:
- if self.invoice.type == 'out':
- res['debit'], res['credit'] = 0, amount
+ line.amount_second_currency = None
+ line.second_currency = None
if self.invoice.type in ('in_invoice', 'out_credit_note'):
if amount >= Decimal('0.0'):
- res['debit'] = amount
- res['credit'] = Decimal('0.0')
+ if self.invoice.type in ('in_invoice', 'out_credit_note'):
+ if amount >= Decimal('0.0'):
+ line.debit = amount
+ line.credit = Decimal('0.0')
else:
- res['debit'] = Decimal('0.0')
- res['credit'] = - amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = \
- - res['amount_second_currency']
- res['debit'], res['credit'] = amount, 0
+ line.debit = Decimal('0.0')
+ line.credit = -amount
+ if line.amount_second_currency:
+ line.amount_second_currency = \
+ - line.amount_second_currency
else:
if amount >= Decimal('0.0'):
- res['debit'] = Decimal('0.0')
- res['credit'] = amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = \
- - res['amount_second_currency']
- if self.invoice.type == 'out':
- res['debit'], res['credit'] = -amount, 0
+ if amount >= Decimal('0.0'):
+ line.debit = Decimal('0.0')
+ line.credit = amount
+ if line.amount_second_currency:
+ line.amount_second_currency = \
+ - line.amount_second_currency
else:
- res['debit'] = - amount
- res['credit'] = Decimal('0.0')
- res['debit'], res['credit'] = 0, -amount
- if res['amount_second_currency']:
- res['amount_second_currency'] = (
- res['amount_second_currency'].copy_sign(
- res['debit'] - res['credit']))
- res['account'] = self.account.id
+ line.debit = -amount
+ line.credit = Decimal('0.0')
@ -450,8 +415,8 @@ diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py
diff -r 0e69764f2826 trytond/trytond/modules/account_payment_type/invoice.py
--- a/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 10:10:50 2015 +0200
+++ b/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 17:06:02 2015 +0200
@@ -59,10 +59,10 @@
return res
@@ -82,7 +82,7 @@
return self.company.party.customer_payment_type.id
def _get_move_line(self, date, amount):
- res = super(Invoice, self)._get_move_line(date, amount)
@ -461,9 +426,6 @@ diff -r 0e69764f2826 trytond/trytond/modules/account_payment_type/invoice.py
- return res
+ line.payment_type = self.payment_type
+ return line
@classmethod
def compute_default_payment_type(cls, values):
diff -r 6429c9c53cb8 trytond/trytond/modules/account_bank/account.py
--- a/trytond/trytond/modules/account_bank/account.py Tue May 05 14:36:02 2015 +0200
+++ b/trytond/trytond/modules/account_bank/account.py Tue Jul 07 15:36:26 2015 +0200
@ -484,46 +446,56 @@ diff -r 6429c9c53cb8 trytond/trytond/modules/account_bank/account.py
diff -r 95d77335bdd5 trytond/trytond/modules/analytic_invoice/invoice.py
--- a/trytond/trytond/modules/analytic_invoice/invoice.py Sun Mar 01 15:34:41 2015 +0100
+++ b/trytond/trytond/modules/analytic_invoice/invoice.py Mon Nov 30 14:24:25 2015 +0100
@@ -192,26 +192,25 @@
@@ -26,32 +26,32 @@
return result
- def get_analytic_entry(self, entry, value):
- analytic_entry = {}
- analytic_entry['name'] = self.description
- analytic_entry['debit'] = value['debit']
- analytic_entry['credit'] = value['credit']
- analytic_entry['account'] = entry.account.id
- analytic_entry['journal'] = self.invoice.journal.id
- analytic_entry['date'] = (self.invoice.accounting_date or
- self.invoice.invoice_date)
- analytic_entry['reference'] = self.invoice.reference
- analytic_entry['party'] = self.invoice.party.id
- return analytic_entry
+ def get_analytic_entry(self, entry, line):
+ pool = Pool()
+ AnalyticLine = pool.get('analytic_account.line')
+ analytic_line = AnalyticLine()
+ analytic_line.name = self.description
+ analytic_line.debit = line.debit
+ analytic_line.credit = line.credit
+ analytic_line.account = entry.account
+ analytic_line.journal = self.invoice.journal
+ analytic_line.date = (self.invoice.accounting_date
+ or self.invoice.invoice_date)
+ analytic_line.reference = self.invoice.reference
+ analytic_line.party = self.invoice.party
+ return analytic_line
def get_move_line(self):
- values = super(InvoiceLine, self).get_move_line()
+ pool = Pool()
+ AnalyticLine = pool.get('analytic_account.line')
+ lines = super(InvoiceLine, self).get_move_line()
if self.analytic_accounts and self.analytic_accounts.accounts:
if self.analytic_accounts:
- for value in values:
- value['analytic_lines'] = []
- to_create = []
+ for line in lines:
+ line.analytic_lines = []
for account in self.analytic_accounts.accounts:
- vals = {}
- vals['name'] = self.description
- vals['debit'] = value['debit']
- vals['credit'] = value['credit']
- vals['account'] = account.id
- vals['journal'] = self.invoice.journal.id
- vals['date'] = (self.invoice.accounting_date
+ analytic_line = AnalyticLine()
+ analytic_line.name = self.description
+ analytic_line.debit = line.debit
+ analytic_line.credit = line.credit
+ analytic_line.account = account
+ analytic_line.journal = self.invoice.journal
+ analytic_line.date = (self.invoice.accounting_date
or self.invoice.invoice_date)
- vals['reference'] = self.invoice.reference
- vals['party'] = self.invoice.party.id
- to_create.append(vals)
for entry in self.analytic_accounts:
if not entry.account:
continue
- to_create.append(self.get_analytic_entry(entry, value))
- if to_create:
- value['analytic_lines'] = [('create', to_create)]
- return values
+ analytic_line.reference = self.invoice.reference
+ analytic_line.party = self.invoice.party
+ line.analytic_lines.append(analytic_line)
+ line.analytic_lines.append(self.get_analytic_entry(entry,
+ line))
+ return lines
class Account(ModelSQL, ModelView):
class AnalyticAccountEntry:

View File

@ -1,84 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Allow to apply inheritance in calendar view
review10061002
Index: trytond/trytond/ir/ui/calendar.rnc
===================================================================
--- a/trytond/trytond/ir/ui/calendar.rnc
+++ b/trytond/trytond/ir/ui/calendar.rnc
@@ -9,4 +9,14 @@
[ a:defaultValue = "Unknown" ] attribute string { text }?
field = element field { attlist.field, empty }
attlist.field &= attribute name { text }
-start = calendar
+data = element data { attlist.data, xpath* }
+attlist.data &= empty
+
+xpath = element xpath { attlist.xpath, ( field )*
+ }
+attlist.xpath &= attribute expr { text }
+attlist.xpath &=
+ [ a:defaultValue = "inside" ]
+ attribute position { "inside" | "replace" | "replace_attributes" | "after" | "before" }?
+
+start = data | calendar
Index: trytond/trytond/ir/ui/calendar.rng
===================================================================
--- a/trytond/trytond/ir/ui/calendar.rng
+++ b/trytond/trytond/ir/ui/calendar.rng
@@ -30,7 +30,47 @@
<define name="attlist.field" combine="interleave">
<attribute name="name"/>
</define>
+ <define name="data">
+ <element name="data">
+ <ref name="attlist.data"/>
+ <zeroOrMore>
+ <ref name="xpath"/>
+ </zeroOrMore>
+ </element>
+ </define>
+ <define name="attlist.data" combine="interleave">
+ <empty/>
+ </define>
+ <define name="xpath">
+ <element name="xpath">
+ <ref name="attlist.xpath"/>
+ <zeroOrMore>
+ <choice>
+ <ref name="field"/>
+ </choice>
+ </zeroOrMore>
+ </element>
+ </define>
+ <define name="attlist.xpath" combine="interleave">
+ <attribute name="expr"/>
+ </define>
+ <define name="attlist.xpath" combine="interleave">
+ <optional>
+ <attribute name="position" a:defaultValue="inside">
+ <choice>
+ <value>inside</value>
+ <value>replace</value>
+ <value>replace_attributes</value>
+ <value>after</value>
+ <value>before</value>
+ </choice>
+ </attribute>
+ </optional>
+ </define>
<start>
- <ref name="calendar"/>
+ <choice>
+ <ref name="data"/>
+ <ref name="calendar"/>
+ </choice>
</start>
</grammar>

View File

@ -1,35 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Remove all the view elements which the user doesn't have access
issue4487
review10071002
Index: trytond/trytond/model/modelview.py
===================================================================
--- a/trytond/trytond/model/modelview.py
+++ b/trytond/trytond/model/modelview.py
@@ -399,14 +399,15 @@
# Remove field without read access
for field in fields_to_remove:
for element in tree.xpath(
- '//field[@name="%s"] | //label[@name="%s"]'
- % (field, field)):
- if type == 'form':
+ ('//field[@name="%s"] | //label[@name="%s"]'
+ ' | //page[@name="%s"] | //separator[@name="%s"]'
+ ' | //group[@name="%s"]') % ((field,) * 5)):
+ if type == 'tree' or element.tag in ('page', 'group'):
+ parent = element.getparent()
+ parent.remove(element)
+ elif type == 'form':
element.tag = 'label'
element.attrib.clear()
- elif type == 'tree':
- parent = element.getparent()
- parent.remove(element)
if type == 'tree':
ViewTreeWidth = pool.get('ir.ui.view_tree_width')

View File

@ -13,11 +13,11 @@ Index: invoice.xml
@@ -38,6 +38,17 @@
<field name="act_window" ref="act_invoice_form"/>
</record>
+ <record model="ir.action.act_window" id="act_credit_notes_form">
+ <field name="name">Credit Notes</field>
+ <field name="res_model">account.invoice</field>
+ <field name="domain">[('lines.origin.invoice', 'in', Eval('active_ids'), 'account.invoice.line')]</field>
+ <field name="domain" eval="[('lines.origin.invoice', 'in', Eval('active_ids'), 'account.invoice.line')]" pyson="1"/>
+ </record>
+ <record model="ir.action.keyword" id="act_open_credit_notes_keyword1">
+ <field name="keyword">form_relate</field>
@ -25,8 +25,8 @@ Index: invoice.xml
+ <field name="action" ref="act_credit_notes_form"/>
+ </record>
+
<record model="ir.action.act_window" id="act_invoice_out_invoice_form">
<field name="name">Invoices</field>
<record model="ir.action.act_window" id="act_invoice_out_form">
<field name="name">Customer Invoices</field>
<field name="res_model">account.invoice</field>
@ -38,7 +38,7 @@ Index: ca_ES.xml
@@ -1053,6 +1053,10 @@
msgid "Invoices"
msgstr "Factures"
+msgctxt "model:ir.action,name:act_credit_notes_form"
+msgid "Credit Notes"
+msgstr "Abonaments"
@ -56,7 +56,7 @@ Index: ca_ES.xml
@@ -1045,6 +1045,10 @@
msgid "Invoices"
msgstr "Todas las facturas"
+msgctxt "model:ir.action,name:act_credit_notes_form"
+msgid "Credit Notes"
+msgstr "Abonos"

View File

@ -3,13 +3,12 @@ Index: line.py
--- ./trytond/trytond/modules/analytic_account/line.py
+++ ./trytond/trytond/modules/analytic_account/line.py
@@ -27,7 +27,7 @@
@@ -28,7 +28,7 @@
'on_change_with_company')
account = fields.Many2One('analytic_account.account', 'Account',
required=True, select=True, domain=[
required=True, select=True, domain=[
- ('type', '!=', 'view'),
+ ('type', 'not in', ['view', 'root']),
['OR',
('company', '=', None),
('company', '=', Eval('company', -1)),

View File

@ -1,46 +1,34 @@
diff -r bfa6bee1a9e0 trytond/protocols/jsonrpc.py
--- a/trytond/trytond/protocols/jsonrpc.py Mon Oct 20 14:30:02 2014 +0200
+++ b/trytond/trytond/protocols/jsonrpc.py Mon Nov 03 13:32:30 2014 +0100
@@ -27,6 +27,7 @@
diff -r dfbbed6b42d5 trytond/trytond/protocols/dispatcher.py
--- a/trytond/trytond/protocols/dispatcher.py Thu Apr 07 00:04:01 2016 +0200
+++ b/trytond/trytond/protocols/dispatcher.py Thu Apr 07 10:50:57 2016 +0200
@@ -212,7 +212,7 @@
logger.error(log_message, *log_args, exc_info=True)
raise
except (ConcurrencyException, UserError, UserWarning):
- logger.debug(log_message, *log_args, exc_info=True)
+ logger.warning(log_message, *log_args, exc_info=True)
raise
except Exception:
logger.error(log_message, *log_args, exc_info=True)
diff -r dfbbed6b42d5 trytond/protocols/jsonrpc.py
--- a/trytond/trytond/protocols/jsonrpc.py Thu Apr 07 00:04:01 2016 +0200
+++ b/trytond/trytond/protocols/jsonrpc.py Thu Apr 07 10:50:57 2016 +0200
@@ -9,6 +9,7 @@
except ImportError:
import json
import base64
import encodings
+import logging
try:
from cStringIO import StringIO
except ImportError:
@@ -136,7 +137,14 @@
existing method through subclassing is the prefered means
of changing method dispatch behavior.
"""
- rawreq = json.loads(data, object_hook=JSONDecoder())
+ try:
+ rawreq = json.loads(data, object_hook=JSONDecoder())
+ except:
+ exc_type, exc_value = sys.exc_info()[:2]
+ logging.getLogger('jsonrpc').warning(
+ 'Exception in JSONRPC dispatcher: %s (%s)\n %s'
+ % (exc_value, exc_type, traceback.format_exc()))
+ raise
req_id = rawreq.get('id', 0)
method = rawreq['method']
@@ -152,11 +160,18 @@
response['result'] = self._dispatch(method, params)
except (UserError, UserWarning, NotLogged,
ConcurrencyException), exception:
+ logging.getLogger('jsonrpc').warning('User Error: %s (%s)'
+ % (method, params))
+ traceback.print_exc()
response['error'] = exception.args
except Exception:
+ exc_type, exc_value = sys.exc_info()[:2]
tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
for path in sys.path:
tb_s = tb_s.replace(path, '')
+ logging.getLogger('jsonrpc').warning(
+ 'Exception in JSONRPC response generation: %s (%s)\n %s'
+ % (exc_value, exc_type, tb_s))
# report exception back to server
response['error'] = (str(sys.exc_value), tb_s)
from werkzeug.wrappers import Response
from werkzeug.utils import cached_property
@@ -123,6 +124,10 @@
try:
return json.loads(self.decoded_data, object_hook=JSONDecoder())
except Exception:
+ exc_type, exc_value = sys.exc_info()[:2]
+ logger = logging.getLogger(__name__)
+ logger.warning('Exception while parsing json: %s (%s)\n %s'
+ % (exc_value, exc_type, traceback.format_exc()))
raise BadRequest('Unable to read JSON request')
else:
raise BadRequest('Not a JSON request')

View File

@ -1,315 +0,0 @@
diff -r 694d32df45f1 inventory.py
--- a/trytond/trytond/modules/stock/inventory.py Wed Jun 17 12:08:14 2015 +0200
+++ b/trytond/trytond/modules/stock/inventory.py Wed Jun 17 12:14:25 2015 +0200
@@ -1,6 +1,6 @@
#This file is part of Tryton. The COPYRIGHT file at the top level
#of this repository contains the full copyright notices and license terms.
-from trytond.model import Workflow, ModelView, ModelSQL, fields
+from trytond.model import Workflow, Model, ModelView, ModelSQL, fields
from trytond.pyson import Not, Equal, Eval, Or, Bool
from trytond import backend
from trytond.transaction import Transaction
@@ -166,7 +166,12 @@
return new_inventories
@staticmethod
- def complete_lines(inventories):
+ def grouping():
+ return ('product',)
+
+ @classmethod
+ @ModelView.button
+ def complete_lines(cls, inventories):
'''
Complete or update the inventories
'''
@@ -174,25 +179,21 @@
Line = pool.get('stock.inventory.line')
Product = pool.get('product.product')
+ grouping = cls.grouping()
to_create = []
for inventory in inventories:
# Compute product quantities
with Transaction().set_context(stock_date_end=inventory.date):
- pbl = Product.products_by_location([inventory.location.id])
+ pbl = Product.products_by_location(
+ [inventory.location.id], grouping=grouping)
# Index some data
- product2uom = {}
product2type = {}
product2consumable = {}
for product in Product.browse([line[1] for line in pbl]):
- product2uom[product.id] = product.default_uom.id
product2type[product.id] = product.type
product2consumable[product.id] = product.consumable
- product_qty = {}
- for (location, product), quantity in pbl.iteritems():
- product_qty[product] = (quantity, product2uom[product])
-
# Update existing lines
for line in inventory.lines:
if not (line.product.active and
@@ -200,26 +201,28 @@
and not line.product.consumable):
Line.delete([line])
continue
- if line.product.id in product_qty:
- quantity, uom_id = product_qty.pop(line.product.id)
- elif line.product.id in product2uom:
- quantity, uom_id = 0.0, product2uom[line.product.id]
+
+ key = (inventory.location.id,) + line.unique_key
+ if key in pbl:
+ quantity = pbl.pop(key)
else:
- quantity, uom_id = 0.0, line.product.default_uom.id
- values = line.update_values4complete(quantity, uom_id)
+ quantity = 0.0
+ values = line.update_values4complete(quantity)
if values:
Line.write([line], values)
# Create lines if needed
- for product_id in product_qty:
+ for key, quantity in pbl.iteritems():
+ product_id = key[grouping.index('product') + 1]
if (product2type[product_id] != 'goods'
or product2consumable[product_id]):
continue
- quantity, uom_id = product_qty[product_id]
if not quantity:
continue
- values = Line.create_values4complete(product_id, inventory,
- quantity, uom_id)
+
+ values = Line.create_values4complete(inventory, quantity)
+ for i, fname in enumerate(grouping, 1):
+ values[fname] = key[i]
to_create.append(values)
if to_create:
Line.create(to_create)
@@ -310,7 +313,13 @@
@property
def unique_key(self):
- return (self.product,)
+ key = []
+ for fname in self.inventory.grouping():
+ value = getattr(self, fname)
+ if isinstance(value, Model):
+ value = value.id
+ key.append(value)
+ return tuple(key)
@classmethod
def cancel_move(cls, lines):
@@ -349,31 +358,27 @@
origin=self,
)
- def update_values4complete(self, quantity, uom_id):
+ def update_values4complete(self, quantity):
'''
Return update values to complete inventory
'''
values = {}
# if nothing changed, no update
- if self.quantity == self.expected_quantity == quantity \
- and self.uom.id == uom_id:
+ if self.quantity == self.expected_quantity == quantity:
return values
values['expected_quantity'] = quantity
- values['uom'] = uom_id
# update also quantity field if not edited
if self.quantity == self.expected_quantity:
values['quantity'] = max(quantity, 0.0)
return values
@classmethod
- def create_values4complete(cls, product_id, inventory, quantity, uom_id):
+ def create_values4complete(cls, inventory, quantity):
'''
Return create values to complete inventory
'''
return {
'inventory': inventory.id,
- 'product': product_id,
'expected_quantity': quantity,
'quantity': max(quantity, 0.0),
- 'uom': uom_id,
}
diff -r 694d32df45f1 tests/scenario_stock_inventory.rst
--- a/trytond/trytond/modules/stock/tests/scenario_stock_inventory.rst Wed Jun 17 12:08:14 2015 +0200
+++ b/trytond/trytond/modules/stock/tests/scenario_stock_inventory.rst Wed Jun 17 12:14:25 2015 +0200
@@ -64,13 +64,11 @@
>>> storage_loc, = Location.find([('code', '=', 'STO')])
>>> customer_loc, = Location.find([('code', '=', 'CUS')])
-Create product::
+Create products::
>>> ProductUom = Model.get('product.uom')
>>> ProductTemplate = Model.get('product.template')
- >>> Product = Model.get('product.product')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
- >>> product = Product()
>>> template = ProductTemplate()
>>> template.name = 'Product'
>>> template.default_uom = unit
@@ -79,8 +77,18 @@
>>> template.cost_price = Decimal('80')
>>> template.cost_price_method = 'average'
>>> template.save()
- >>> product.template = template
- >>> product.save()
+ >>> product, = template.products
+
+ >>> kg, = ProductUom.find([('name', '=', 'Kilogram')])
+ >>> template2 = ProductTemplate()
+ >>> template2.name = 'Product'
+ >>> template2.default_uom = kg
+ >>> template2.type = 'goods'
+ >>> template2.list_price = Decimal('140')
+ >>> template2.cost_price = Decimal('60')
+ >>> template2.cost_price_method = 'average'
+ >>> template2.save()
+ >>> product2, = template2.products
Fill storage::
@@ -96,7 +104,19 @@
>>> incoming_move.company = company
>>> incoming_move.unit_price = Decimal('100')
>>> incoming_move.currency = currency
- >>> incoming_move.save()
+ >>> incoming_move.click('do')
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product2
+ >>> incoming_move.uom = kg
+ >>> incoming_move.quantity = 2.5
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = storage_loc
+ >>> incoming_move.planned_date = today
+ >>> incoming_move.effective_date = today
+ >>> incoming_move.company = company
+ >>> incoming_move.unit_price = Decimal('70')
+ >>> incoming_move.currency = company.currency
>>> incoming_move.click('do')
Create an inventory::
@@ -106,28 +126,81 @@
>>> inventory.location = storage_loc
>>> inventory.save()
>>> inventory.click('complete_lines')
- >>> line, = inventory.lines
- >>> line.expected_quantity == 1
- True
- >>> line.quantity = 2
+ >>> line_by_product = {l.product.id: l for l in inventory.lines}
+ >>> line_p1 = line_by_product[product.id]
+ >>> line_p1.expected_quantity
+ 1.0
+ >>> line_p1.quantity = 3
+ >>> line_p2 = line_by_product[product2.id]
+ >>> line_p2.expected_quantity
+ 2.5
+ >>> line_p2.quantity
+ 2.5
>>> inventory.save()
+
+Fill storage with more quantities::
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product
+ >>> incoming_move.uom = unit
+ >>> incoming_move.quantity = 1
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = storage_loc
+ >>> incoming_move.planned_date = today
+ >>> incoming_move.effective_date = today
+ >>> incoming_move.company = company
+ >>> incoming_move.unit_price = Decimal('100')
+ >>> incoming_move.currency = company.currency
+ >>> incoming_move.click('do')
+
+ >>> incoming_move = StockMove()
+ >>> incoming_move.product = product2
+ >>> incoming_move.uom = kg
+ >>> incoming_move.quantity = 1.3
+ >>> incoming_move.from_location = supplier_loc
+ >>> incoming_move.to_location = storage_loc
+ >>> incoming_move.planned_date = today
+ >>> incoming_move.effective_date = today
+ >>> incoming_move.company = company
+ >>> incoming_move.unit_price = Decimal('70')
+ >>> incoming_move.currency = company.currency
+ >>> incoming_move.click('do')
+
+Update the inventory::
+
+ >>> inventory.click('complete_lines')
+ >>> line_p1.reload()
+ >>> line_p1.expected_quantity
+ 2.0
+ >>> line_p1.quantity
+ 3.0
+ >>> line_p2.reload()
+ >>> line_p2.expected_quantity
+ 3.8
+ >>> line_p2.quantity
+ 3.8
+
+Confirm the inventory::
+
>>> inventory.click('confirm')
- >>> line.reload()
- >>> move, = line.moves
- >>> move.quantity == 1
- True
+ >>> line_p1.reload()
+ >>> move, = line_p1.moves
+ >>> move.quantity
+ 1.0
>>> move.from_location == inventory.lost_found
True
>>> move.to_location == inventory.location
True
+ >>> line_p2.reload()
+ >>> len(line_p2.moves)
+ 0
Empty storage::
- >>> StockMove = Model.get('stock.move')
>>> outgoing_move = StockMove()
>>> outgoing_move.product = product
>>> outgoing_move.uom = unit
- >>> outgoing_move.quantity = 2
+ >>> outgoing_move.quantity = 3
>>> outgoing_move.from_location = storage_loc
>>> outgoing_move.to_location = customer_loc
>>> outgoing_move.planned_date = today
@@ -137,6 +210,19 @@
>>> outgoing_move.currency = currency
>>> outgoing_move.click('do')
+ >>> outgoing_move = StockMove()
+ >>> outgoing_move.product = product2
+ >>> outgoing_move.uom = kg
+ >>> outgoing_move.quantity = 3.8
+ >>> outgoing_move.from_location = storage_loc
+ >>> outgoing_move.to_location = customer_loc
+ >>> outgoing_move.planned_date = today
+ >>> outgoing_move.effective_date = today
+ >>> outgoing_move.company = company
+ >>> outgoing_move.unit_price = Decimal('140')
+ >>> outgoing_move.currency = company.currency
+ >>> outgoing_move.click('do')
+
Create an inventory that should be empty after completion::
>>> Inventory = Model.get('stock.inventory')

View File

@ -19,7 +19,7 @@ Index: trytond/trytond/modules/stock/inventory.xml
+ <field name="global_p" eval="True"/>
+ </record>
+ <record model="ir.rule" id="rule_inventory">
+ <field name="domain">[('company', '=', user.company.id if user.company else None)]</field>
+ <field name="domain" eval="[('company', 'in', Eval('user', {}).get('companies', []))]" pyson="1"/>
+ <field name="rule_group" ref="rule_group_inventory"/>
+ </record>
+

View File

@ -1,82 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Speedup fiscalyear closing process
issue4443
review14841002
Index: trytond/trytond/modules/account/fiscalyear.py
===================================================================
--- a/trytond/trytond/modules/account/fiscalyear.py
+++ b/trytond/trytond/modules/account/fiscalyear.py
@@ -4,7 +4,7 @@
from trytond.model import ModelView, ModelSQL, fields
from trytond.wizard import Wizard, StateView, StateTransition, StateAction, \
Button
-from trytond.tools import datetime_strftime
+from trytond.tools import datetime_strftime, grouped_slice
from trytond.pyson import Eval, If, PYSONEncoder
from trytond.transaction import Transaction
from trytond.pool import Pool
@@ -231,26 +231,33 @@
return None
return fiscalyears[0].id
- def _process_account(self, account):
+ def _process_accounts(self, accounts):
'''
Process account for a fiscal year closed
'''
- Currency = Pool().get('currency.currency')
- Deferral = Pool().get('account.account.deferral')
+ pool = Pool()
+ Currency = pool.get('currency.currency')
+ Deferral = pool.get('account.account.deferral')
- if account.kind == 'view':
- return
- if not account.deferral:
- if not Currency.is_zero(self.company.currency, account.balance):
- self.raise_user_error('account_balance_not_zero',
- error_args=(account.rec_name,))
- else:
- Deferral.create([{
- 'account': account.id,
- 'fiscalyear': self.id,
- 'debit': account.debit,
- 'credit': account.credit,
- }])
+ for sub_accounts in grouped_slice(accounts):
+ to_create = []
+ for account in sub_accounts:
+ if account.kind == 'view':
+ continue
+ if not account.deferral:
+ if not Currency.is_zero(self.company.currency,
+ account.balance):
+ self.raise_user_error('account_balance_not_zero',
+ error_args=(account.rec_name,))
+ else:
+ to_create.append({
+ 'account': account.id,
+ 'fiscalyear': self.id,
+ 'debit': account.debit,
+ 'credit': account.credit,
+ })
+ if to_create:
+ Deferral.create(to_create)
@classmethod
@ModelView.button
@@ -285,8 +292,7 @@
accounts = Account.search([
('company', '=', fiscalyear.company.id),
])
- for account in accounts:
- fiscalyear._process_account(account)
+ fiscalyear._process_accounts(accounts)
@classmethod
@ModelView.button

View File

@ -1,89 +0,0 @@
diff -r e9a7f9fd73aa stock.py
--- a/trytond/trytond/modules/stock_lot/stock.py Wed Jun 17 11:46:34 2015 +0200
+++ b/trytond/trytond/modules/stock_lot/stock.py Wed Jun 17 11:47:43 2015 +0200
@@ -1,7 +1,6 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
import datetime
-from collections import defaultdict
from trytond.model import ModelView, ModelSQL, Workflow, fields
from trytond.pyson import PYSONEncoder, Eval
@@ -200,64 +199,8 @@
__name__ = 'stock.inventory'
@classmethod
- def complete_lines(cls, inventories):
- pool = Pool()
- Product = pool.get('product.product')
- Line = pool.get('stock.inventory.line')
-
- super(Inventory, cls).complete_lines(inventories)
-
- # Create and/or update lines with product that will require lot for
- # their moves.
- to_create = []
- for inventory in inventories:
- product2lines = defaultdict(list)
- for line in inventory.lines:
- if (line.product.lot_is_required(inventory.location,
- inventory.lost_found)
- or line.product.lot_is_required(inventory.lost_found,
- inventory.location)):
- product2lines[line.product.id].append(line)
- if product2lines:
- with Transaction().set_context(stock_date_end=inventory.date):
- pbl = Product.products_by_location([inventory.location.id],
- product_ids=product2lines.keys(),
- grouping=('product', 'lot'))
- product_qty = defaultdict(dict)
- for (location_id, product_id, lot_id), quantity \
- in pbl.iteritems():
- product_qty[product_id][lot_id] = quantity
-
- products = Product.browse(product_qty.keys())
- product2uom = dict((p.id, p.default_uom.id) for p in products)
-
- for product_id, lines in product2lines.iteritems():
- quantities = product_qty[product_id]
- uom_id = product2uom[product_id]
- for line in lines:
- lot_id = line.lot.id if line.lot else None
- if lot_id in quantities:
- quantity = quantities.pop(lot_id)
- elif lot_id is None and quantities:
- lot_id = quantities.keys()[0]
- quantity = quantities.pop(lot_id)
- else:
- lot_id = None
- quantity = 0.0
-
- values = line.update_values4complete(quantity, uom_id)
- if (values or lot_id != (line.lot.id
- if line.lot else None)):
- values['lot'] = lot_id
- Line.write([line], values)
- if quantities:
- for lot_id, quantity in quantities.iteritems():
- values = Line.create_values4complete(product_id,
- inventory, quantity, uom_id)
- values['lot'] = lot_id
- to_create.append(values)
- if to_create:
- Line.create(to_create)
+ def grouping(cls):
+ return super(Inventory, cls).grouping() + ('lot', )
class InventoryLine:
@@ -279,10 +222,6 @@
rec_name += ' - %s' % self.lot.rec_name
return rec_name
- @property
- def unique_key(self):
- return super(InventoryLine, self).unique_key + (self.lot,)
-
def get_move(self):
move = super(InventoryLine, self).get_move()
if move:

71
issue17881002_1.diff Normal file
View File

@ -0,0 +1,71 @@
# HG changeset patch
# User Cédric Krier <cedric.krier@b2ck.com>
Disable button during click processing
The click event must be blocked when the screen method is called to limit
double execution. A double execution is still possible if the execution of the
action, which is asynchronous, is not started fast enough.
issue5362
review17881002
Index: src/view/form.js
===================================================================
--- a/public_data/sao/src/view/form.js
+++ b/public_data/sao/src/view/form.js
@@ -361,7 +361,12 @@
},
button_clicked: function(event) {
var button = event.data;
- this.screen.button(button.attributes);
+ button.el.prop('disabled', true);
+ try {
+ this.screen.button(button.attributes);
+ } finally {
+ button.el.prop('disabled', false);
+ }
},
selected_records: function() {
if (this.screen.current_record) {
Index: src/view/tree.js
===================================================================
--- a/public_data/sao/src/view/tree.js
+++ b/public_data/sao/src/view/tree.js
@@ -1509,7 +1509,7 @@
},
render: function(record) {
var button = new Sao.common.Button(this.attributes);
- button.el.click(record, this.button_clicked.bind(this));
+ button.el.click([record, button], this.button_clicked.bind(this));
var fields = jQuery.map(this.screen.model.fields,
function(field, name) {
if ((field.description.loading || 'eager') ==
@@ -1526,7 +1526,8 @@
return button.el;
},
button_clicked: function(event) {
- var record = event.data;
+ var record = event.data[0];
+ var button = event.data[1];
if (record != this.screen.current_record) {
return;
}
@@ -1534,7 +1535,12 @@
if (states.invisible || states.readonly) {
return;
}
- this.screen.button(this.attributes);
+ button.el.prop('disabled', true);
+ try {
+ this.screen.button(this.attributes);
+ } finally {
+ button.el.prop('disabled', false);
+ }
}
});

View File

@ -1,65 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
Allow to change the destination of internal shipment's moves
issue4828
review18361002
Index: shipment.py
===================================================================
--- a/trytond/trytond/modules/stock/shipment.py
+++ b/trytond/trytond/modules/stock/shipment.py
@@ -1784,9 +1784,15 @@
| ~Eval('from_location') | ~Eval('to_location')),
},
domain=[
- ('from_location', 'child_of', [Eval('from_location', -1)],
- 'parent'),
- ('to_location', '=', Eval('to_location')),
+ If(Eval('state') == 'draft', [
+ ('from_location', '=', Eval('from_location')),
+ ('to_location', '=', Eval('to_location')),
+ ], [
+ ('from_location', 'child_of', [Eval('from_location', -1)],
+ 'parent'),
+ ('to_location', 'child_of', [Eval('to_location', -1)],
+ 'parent'),
+ ]),
('company', '=', Eval('company')),
],
depends=['state', 'from_location', 'to_location', 'planned_date',
@@ -1934,13 +1940,6 @@
@Workflow.transition('draft')
def draft(cls, shipments):
Move = Pool().get('stock.move')
- Move.draft([m for s in shipments for m in s.moves])
-
- @classmethod
- @ModelView.button
- @Workflow.transition('waiting')
- def wait(cls, shipments):
- Move = Pool().get('stock.move')
# First reset state to draft to allow update from and to location
Move.draft([m for s in shipments for m in s.moves])
for shipment in shipments:
@@ -1952,6 +1951,18 @@
})
@classmethod
+ @ModelView.button
+ @Workflow.transition('waiting')
+ def wait(cls, shipments):
+ Move = Pool().get('stock.move')
+ Move.draft([m for s in shipments for m in s.moves])
+ for shipment in shipments:
+ for move in shipment.moves:
+ if move.state != 'done':
+ move.planned_date = shipment.planned_date
+ move.save()
+
+ @classmethod
@Workflow.transition('assigned')
def assign(cls, shipments):
pass

View File

@ -1,24 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
remove digits attribute from internal quantity fields
issue4741
review19281002
Index: move.py
===================================================================
--- a/trytond/trytond/modules/product_cost_fifo/move.py
+++ b/trytond/trytond/modules/product_cost_fifo/move.py
@@ -11,9 +11,7 @@
class Move:
__name__ = 'stock.move'
- fifo_quantity = fields.Float('FIFO Quantity',
- digits=(16, Eval('unit_digits', 2)),
- depends=['unit_digits'])
+ fifo_quantity = fields.Float('FIFO Quantity')
@classmethod
def __setup__(cls):

View File

@ -1,40 +0,0 @@
diff -r dba965a72938 sale.py
--- a/trytond/trytond/modules/sale/sale.py Tue Oct 06 10:07:07 2015 +0200
+++ b/trytond/trytond/modules/sale/sale.py Tue Oct 06 10:09:08 2015 +0200
@@ -1132,7 +1132,6 @@
return 2
def get_move_done(self, name):
- Uom = Pool().get('product.uom')
done = True
if not self.product:
return True
@@ -1146,7 +1145,7 @@
and move.id not in skip_ids:
done = False
break
- quantity -= Uom.compute_qty(move.uom, move.quantity, self.unit)
+ quantity -= move.origin_quantity
if done:
if quantity > 0.0:
done = False
@@ -1356,8 +1355,7 @@
quantity = 0.0
for move in self.moves:
if move.state == 'done':
- quantity += Uom.compute_qty(move.uom, move.quantity,
- self.unit)
+ quantity += move.origin_quantity
if move.invoiced_quantity < move.quantity:
stock_moves.append(move)
if self.sale.shipment_method == 'order':
@@ -1371,8 +1369,7 @@
if old_invoice_line.id not in skip_ids:
sign = (1.0 if invoice_type == old_invoice_line.invoice_type
else -1.0)
- quantity -= Uom.compute_qty(old_invoice_line.unit,
- sign * old_invoice_line.quantity, self.unit)
+ quantity -= sign * old_invoice_line.origin_quantity
rounding = self.unit.rounding if self.unit else 0.01
invoice_line.quantity = Uom.round(quantity, rounding)

View File

@ -1,23 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
Allow to modify internal shipment moves in waiting state
issue4827
review20301003
Index: shipment.py
===================================================================
--- a/trytond/trytond/modules/stock/shipment.py
+++ b/trytond/trytond/modules/stock/shipment.py
@@ -1784,7 +1784,7 @@
], depends=['state'])
moves = fields.One2Many('stock.move', 'shipment', 'Moves',
states={
- 'readonly': ((Eval('state') != 'draft')
+ 'readonly': (Eval('state').in_(['cancel', 'assigned', 'done'])
| ~Eval('from_location') | ~Eval('to_location')),
},
domain=[

View File

@ -1,50 +0,0 @@
diff -r 8ba590e21c94 purchase.py
--- a/trytond/trytond/modules/purchase/purchase.py Tue Oct 06 10:09:51 2015 +0200
+++ b/trytond/trytond/modules/purchase/purchase.py Tue Oct 06 10:16:28 2015 +0200
@@ -1048,7 +1048,6 @@
return 'line'
def get_move_done(self, name):
- Uom = Pool().get('product.uom')
done = True
if not self.product:
return True
@@ -1062,7 +1061,7 @@
and move.id not in skip_ids:
done = False
break
- quantity -= Uom.compute_qty(move.uom, move.quantity, self.unit)
+ quantity -= move.origin_quantity
if done:
if quantity > 0.0:
done = False
@@ -1281,8 +1280,7 @@
quantity = 0.0
for move in self.moves:
if move.state == 'done':
- quantity += Uom.compute_qty(move.uom, move.quantity,
- self.unit)
+ quantity += move.origin_quantity
if move.invoiced_quantity < move.quantity:
stock_moves.append(move)
invoice_line.stock_moves = stock_moves
@@ -1293,8 +1291,7 @@
if old_invoice_line.type != 'line':
continue
if old_invoice_line.id not in skip_ids:
- quantity -= Uom.compute_qty(old_invoice_line.unit,
- old_invoice_line.quantity, self.unit)
+ quantity -= old_invoice_line.origin_quantity
rounding = self.unit.rounding if self.unit else 0.01
invoice_line.quantity = Uom.round(quantity, rounding)
@@ -1352,8 +1349,7 @@
quantity = abs(self.quantity)
for move in self.moves:
if move not in skip:
- quantity -= Uom.compute_qty(move.uom, move.quantity,
- self.unit)
+ quantity -= move.origin_quantity
quantity = Uom.round(quantity, self.unit.rounding)
if quantity <= 0:

75
issue23901002_1.diff Normal file
View File

@ -0,0 +1,75 @@
# HG changeset patch
# User Cédric Krier <cedric.krier@b2ck.com>
Execute action synchronously
The clicked event must be blocked when the action is started, so the retrieval
of the action definition should be synchronous to be done inside the
try/finally.
issue5362
review23901002
Index: tryton/action/main.py
===================================================================
--- a/tryton/tryton/action/main.py
+++ b/tryton/tryton/action/main.py
@@ -54,31 +54,16 @@
@staticmethod
def execute(act_id, data, action_type=None, context=None):
- def get_action_type(actions):
- try:
- action, = actions()
- except RPCException:
- return
+ # Must be executed synchronously to avoid double execution
+ # on double click.
+ if not action_type:
+ action, = RPCExecute('model', 'ir.action', 'read', [act_id],
+ ['type'], context=context)
action_type = action['type']
- exec_action(action_type)
-
- def exec_action(action_type):
- def callback(actions):
- try:
- action, = actions()
- except RPCException:
- return
- Action._exec_action(action, data, context=context)
-
- RPCExecute('model', action_type, 'search_read',
- [('action', '=', act_id)], 0, 1, None, None,
- context=context, callback=callback)
-
- if not action_type:
- RPCExecute('model', 'ir.action', 'read', [act_id],
- ['type'], context=context, callback=get_action_type)
- else:
- exec_action(action_type)
+ action, = RPCExecute('model', action_type, 'search_read',
+ [('action', '=', act_id)], 0, 1, None, None,
+ context=context)
+ Action._exec_action(action, data, context=context)
@staticmethod
def _exec_action(action, data=None, context=None):
Index: tryton/gui/window/view_form/view/list_gtk/widget.py
===================================================================
--- a/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
+++ b/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
@@ -909,4 +909,8 @@
if state_changes.get('invisible') \
or state_changes.get('readonly'):
return True
- self.view.screen.button(self.attrs)
+ widget.handler_block_by_func(self.button_clicked)
+ try:
+ self.view.screen.button(self.attrs)
+ finally:
+ widget.handler_unblock_by_func(self.button_clicked)

View File

@ -1,7 +1,7 @@
diff -r a0ccc84aaa24 location.py
--- a/trytond/trytond/modules/stock/location.py Mon Oct 20 15:08:22 2014 +0200
+++ b/trytond/trytond/modules/stock/location.py Mon Nov 03 13:36:23 2014 +0100
@@ -161,6 +161,11 @@
diff -r ad935d7f423e trytond/trytond/modules/stock/location.py
--- a/trytond/trytond/modules/stock/location.py Mon Mar 28 10:34:04 2016 +0200
+++ b/trytond/trytond/modules/stock/location.py Thu Apr 07 11:25:56 2016 +0200
@@ -224,6 +224,11 @@
return [(cls._rec_name,) + tuple(clause[1:])]
@classmethod
@ -13,7 +13,7 @@ diff -r a0ccc84aaa24 location.py
def get_quantity(cls, locations, name):
pool = Pool()
Product = pool.get('product.product')
@@ -192,12 +197,13 @@
@@ -255,12 +260,13 @@
pbl = {}
for sub_locations in grouped_slice(locations):
location_ids = [l.id for l in sub_locations]

View File

@ -1,8 +1,6 @@
Index: __init__.py
===================================================================
--- .a/trytond/trytond/modules/stock_lot/__init__.py
+++ .b/trytond/trytond/modules/stock_lot/__init__.py
diff -r 8513232c6649 trytond/trytond/modules/stock_lot/__init__.py
--- a/trytond/trytond/modules/stock_lot/__init__.py Sat Feb 27 00:34:46 2016 +0100
+++ b/trytond/trytond/modules/stock_lot/__init__.py Thu Apr 07 11:02:06 2016 +0200
@@ -21,4 +21,9 @@
Template,
Product,
@ -13,36 +11,191 @@ Index: __init__.py
+ Pool.register(
+ LotByLocation,
+ module='stock_lot', type_='wizard')
diff -r 8513232c6649 locale/ca_ES.po
--- a/trytond/trytond/modules/stock_lot/locale/ca_ES.po Sat Feb 27 00:34:46 2016 +0100
+++ b/trytond/trytond/modules/stock_lot/locale/ca_ES.po Thu Apr 07 11:02:06 2016 +0200
@@ -86,6 +86,14 @@
msgid "Write User"
msgstr "Usuari modificació"
Index: stock.py
===================================================================
+msgctxt "field:stock.lot.by_location.start,forecast_date:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lot.by_location.start,id:"
+msgid "ID"
+msgstr "Identificador"
+
msgctxt "field:stock.lot.type,code:"
msgid "Code"
msgstr "Codi"
@@ -174,6 +182,16 @@
msgid "The type of location for which lot is required"
msgstr "Tipus d'ubicació per la qual el lot és obligatori."
--- .a/trytond/trytond/modules/stock_lot/stock.py
+++ .b/trytond/trytond/modules/stock_lot/stock.py
@@ -1,17 +1,20 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
+msgctxt "help:stock.lot.by_location.start,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet calcular les quantitats previstes d'estoc per a aquesta data.\n"
+"* Un valor buit és un data infinita en el futur.\n"
+"* Una data en el passat proporcionarà valors històrics."
+
msgctxt "model:ir.action,name:act_lot_form"
msgid "Lots"
msgstr "Lots"
@@ -182,6 +200,10 @@
msgid "Moves"
msgstr "Moviments"
+msgctxt "model:ir.action,name:wizard_lot_by_location"
+msgid "Lot by Locations"
+msgstr "Lots per ubicació"
+
msgctxt "model:ir.ui.menu,name:menu_lot_form"
msgid "Lots"
msgstr "Lots"
@@ -194,6 +216,10 @@
msgid "Stock Lot"
msgstr "Lot"
+msgctxt "model:stock.lot.by_location.start,name:"
+msgid "Lot by Location"
+msgstr "Lot per ubicació"
+
msgctxt "model:stock.lot.type,name:"
msgid "Stock Lot Type"
msgstr "Tipus de lot"
@@ -226,6 +252,10 @@
msgid "Lots"
msgstr "Lots"
+msgctxt "view:stock.lot.by_location.start:"
+msgid "Lot by Location"
+msgstr "Lot per ubicació"
+
msgctxt "view:stock.lot:"
msgid "Lot"
msgstr "Lot"
@@ -241,3 +271,11 @@
msgctxt "view:stock.period.cache.lot:"
msgid "Period Lot Caches"
msgstr "Períodes d'estoc precalculat "
+
+msgctxt "wizard_button:stock.lot.by_location,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.lot.by_location,start,open:"
+msgid "Open"
+msgstr "Obre"
diff -r 8513232c6649 trytond/trytond/modules/stock_lot/locale/es_ES.po
--- a/trytond/trytond/modules/stock_lot/locale/es_ES.po Sat Feb 27 00:34:46 2016 +0100
+++ b/trytond/trytond/modules/stock_lot/locale/es_ES.po Thu Apr 07 11:02:06 2016 +0200
@@ -86,6 +86,14 @@
msgid "Write User"
msgstr "Usuario modificación"
+msgctxt "field:stock.lot.by_location.start,forecast_date:"
+msgid "At Date"
+msgstr "A fecha"
+
+msgctxt "field:stock.lot.by_location.start,id:"
+msgid "ID"
+msgstr "Identificador"
+
msgctxt "field:stock.lot.type,code:"
msgid "Code"
msgstr "Código"
@@ -174,6 +182,16 @@
msgid "The type of location for which lot is required"
msgstr "El tipo de ubicación en la que el lote es obligatorio."
+msgctxt "help:stock.lot.by_location.start,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite calcular las cantidades previstas de stock para esta fecha.\n"
+"* Un valor vacío es un fecha infinita en el futuro.\n"
+"* Una fecha en el pasado proporcionará valores históricos."
+
msgctxt "model:ir.action,name:act_lot_form"
msgid "Lots"
msgstr "Lotes"
@@ -182,6 +200,10 @@
msgid "Moves"
msgstr "Movimientos"
+msgctxt "model:ir.action,name:wizard_lot_by_location"
+msgid "Lot by Locations"
+msgstr "Lotes por ubicación"
+
msgctxt "model:ir.ui.menu,name:menu_lot_form"
msgid "Lots"
msgstr "Lotes"
@@ -194,6 +216,10 @@
msgid "Stock Lot"
msgstr "Lote stock"
+msgctxt "model:stock.lot.by_location.start,name:"
+msgid "Lot by Location"
+msgstr "Lote por ubicación"
+
msgctxt "model:stock.lot.type,name:"
msgid "Stock Lot Type"
msgstr "Tipo lote stock"
@@ -226,6 +252,10 @@
msgid "Lots"
msgstr "Lotes"
+msgctxt "view:stock.lot.by_location.start:"
+msgid "Lot by Location"
+msgstr "Lote por ubicación"
+
msgctxt "view:stock.lot:"
msgid "Lot"
msgstr "Lote"
@@ -241,3 +271,11 @@
msgctxt "view:stock.period.cache.lot:"
msgid "Period Lot Caches"
msgstr "Período lote precalculados"
+
+msgctxt "wizard_button:stock.lot.by_location,start,end:"
+msgid "Cancel"
+msgstr "Cancel·lar"
+
+msgctxt "wizard_button:stock.lot.by_location,start,open:"
+msgid "Open"
+msgstr "Abrir"
diff -r 8513232c6649 trytond/trytond/modules/stock_lot/stock.py
--- a/trytond/trytond/modules/stock_lot/stock.py Sat Feb 27 00:34:46 2016 +0100
+++ b/trytond/trytond/modules/stock_lot/stock.py Thu Apr 07 11:02:06 2016 +0200
@@ -1,15 +1,18 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+import datetime
from collections import defaultdict
from trytond.model import ModelView, ModelSQL, Workflow, fields
from trytond.model import ModelView, ModelSQL, fields
-from trytond.pyson import Eval
+from trytond.pyson import PYSONEncoder, Eval
+from trytond.pyson import Eval, PYSONEncoder
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
+from trytond.wizard import Wizard, StateView, StateAction, Button
from trytond.modules.stock import StockMixin
__all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut',
'ShipmentOutReturn',
'Period', 'PeriodCacheLot',
- 'Inventory', 'InventoryLine']
+ 'Inventory', 'InventoryLine',
+ 'Location', 'LotByLocation', 'LotByLocationStart']
__metaclass__ = PoolMeta
@@ -294,3 +297,73 @@
+ 'Inventory', 'InventoryLine', 'Location', 'LotByLocationStart',
+ 'LotByLocation']
class Lot(ModelSQL, ModelView, StockMixin):
@@ -216,3 +219,74 @@
if move:
move.lot = self.lot
return move
@ -50,6 +203,7 @@ Index: stock.py
+
+class Location:
+ __name__ = 'stock.location'
+ __metaclass__ = PoolMeta
+
+ @classmethod
+ def _quantity_grouping_and_key(cls):
@ -116,16 +270,13 @@ Index: stock.py
+ action['name'] += ' - %s (%s) @ %s' % (lot.rec_name,
+ lot.product.default_uom.rec_name, date)
+ return action, {}
Index: stock.xml
===================================================================
--- .a/trytond/trytond/modules/stock_lot/stock.xml
+++ .b/trytond/trytond/modules/stock_lot/stock.xml
@@ -48,6 +48,28 @@
<field name="perm_delete" eval="True"/>
diff -r 8513232c6649 trytond/trytond/modules/stock_lot/stock.xml
--- a/trytond/trytond/modules/stock_lot/stock.xml Sat Feb 27 00:34:46 2016 +0100
+++ b/trytond/trytond/modules/stock_lot/stock.xml Thu Apr 07 11:02:06 2016 +0200
@@ -62,6 +62,28 @@
<field name="action" ref="act_move_form_relate_lot"/>
</record>
+ <record model="ir.action.wizard" id="wizard_lot_by_location">
+ <field name="name">Lot by Locations</field>
+ <field name="wiz_name">stock.lot.by_location</field>
@ -151,184 +302,3 @@ Index: stock.xml
<record model="stock.lot.type" id="type_supplier">
<field name="code">supplier</field>
<field name="name">Supplier</field>
Index: view/lot_by_location_start_form.xml
===================================================================
new file mode 100644
--- /dev/null
+++ .b/trytond/trytond/modules/stock_lot/view/lot_by_location_start_form.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<form string="Lot by Location">
+ <label name="forecast_date"/>
+ <field name="forecast_date"/>
+</form>
Index: locale/ca_ES.po
===================================================================
--- .a/trytond/trytond/modules/stock_lot/locale/ca_ES.po
+++ .b/trytond/trytond/modules/stock_lot/locale/ca_ES.po
@@ -86,6 +86,14 @@
msgid "Write User"
msgstr "Usuari modificació"
+msgctxt "field:stock.lot.by_location.start,forecast_date:"
+msgid "At Date"
+msgstr "A data"
+
+msgctxt "field:stock.lot.by_location.start,id:"
+msgid "ID"
+msgstr "Identificador"
+
msgctxt "field:stock.lot.type,code:"
msgid "Code"
msgstr "Codi"
@@ -174,6 +182,16 @@
msgid "The type of location for which lot is required"
msgstr "Tipus d'ubicació per la qual el lot és obligatori."
+msgctxt "help:stock.lot.by_location.start,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permet calcular les quantitats previstes d'estoc per a aquesta data.\n"
+"* Un valor buit és un data infinita en el futur.\n"
+"* Una data en el passat proporcionarà valors històrics."
+
msgctxt "model:ir.action,name:act_lot_form"
msgid "Lots"
msgstr "Lots"
@@ -182,6 +200,10 @@
msgid "Moves"
msgstr "Moviments"
+msgctxt "model:ir.action,name:wizard_lot_by_location"
+msgid "Lot by Locations"
+msgstr "Lots per ubicació"
+
msgctxt "model:ir.ui.menu,name:menu_lot_form"
msgid "Lots"
msgstr "Lots"
@@ -194,6 +216,10 @@
msgid "Stock Lot"
msgstr "Lot"
+msgctxt "model:stock.lot.by_location.start,name:"
+msgid "Lot by Location"
+msgstr "Lot per ubicació"
+
msgctxt "model:stock.lot.type,name:"
msgid "Stock Lot Type"
msgstr "Tipus de lot"
@@ -230,6 +256,10 @@
msgid "Lots"
msgstr "Lots"
+msgctxt "view:stock.lot.by_location.start:"
+msgid "Lot by Location"
+msgstr "Lot per ubicació"
+
msgctxt "view:stock.lot:"
msgid "Lot"
msgstr "Lot"
@@ -245,3 +275,11 @@
msgctxt "view:stock.period.cache.lot:"
msgid "Period Lot Caches"
msgstr "Períodes d'estoc precalculat "
+
+msgctxt "wizard_button:stock.lot.by_location,start,end:"
+msgid "Cancel"
+msgstr "Cancel·la"
+
+msgctxt "wizard_button:stock.lot.by_location,start,open:"
+msgid "Open"
+msgstr "Obre"
Index: locale/es_ES.po
===================================================================
--- .a/trytond/trytond/modules/stock_lot/locale/es_ES.po
+++ .b/trytond/trytond/modules/stock_lot/locale/es_ES.po
@@ -86,6 +86,14 @@
msgid "Write User"
msgstr "Usuario modificación"
+msgctxt "field:stock.lot.by_location.start,forecast_date:"
+msgid "At Date"
+msgstr "A fecha"
+
+msgctxt "field:stock.lot.by_location.start,id:"
+msgid "ID"
+msgstr "Identificador"
+
msgctxt "field:stock.lot.type,code:"
msgid "Code"
msgstr "Código"
@@ -174,6 +182,16 @@
msgid "The type of location for which lot is required"
msgstr "El tipo de ubicación por cada lote es requerido."
+msgctxt "help:stock.lot.by_location.start,forecast_date:"
+msgid ""
+"Allow to compute expected stock quantities for this date.\n"
+"* An empty value is an infinite date in the future.\n"
+"* A date in the past will provide historical values."
+msgstr ""
+"Permite calcular las cantidades previstas de stock para esta fecha.\n"
+"* Un valor vacío es un fecha infinita en el futuro.\n"
+"* Una fecha en el pasado proporcionará valores históricos."
+
msgctxt "model:ir.action,name:act_lot_form"
msgid "Lots"
msgstr "Lotes"
@@ -182,6 +200,10 @@
msgid "Moves"
msgstr "Movimientos"
+msgctxt "model:ir.action,name:wizard_lot_by_location"
+msgid "Lot by Locations"
+msgstr "Lotes por ubicación"
+
msgctxt "model:ir.ui.menu,name:menu_lot_form"
msgid "Lots"
msgstr "Lotes"
@@ -194,6 +216,10 @@
msgid "Stock Lot"
msgstr "Lote stock"
+msgctxt "model:stock.lot.by_location.start,name:"
+msgid "Lot by Location"
+msgstr "Lote por ubicación"
+
msgctxt "model:stock.lot.type,name:"
msgid "Stock Lot Type"
msgstr "Tipo lote stock"
@@ -230,6 +256,10 @@
msgid "Lots"
msgstr "Lotes"
+msgctxt "view:stock.lot.by_location.start:"
+msgid "Lot by Location"
+msgstr "Lote por ubicación"
+
msgctxt "view:stock.lot:"
msgid "Lot"
msgstr "Lote"
@@ -245,3 +275,11 @@
msgctxt "view:stock.period.cache.lot:"
msgid "Period Lot Caches"
msgstr "Período lote precalculados"
+
+msgctxt "wizard_button:stock.lot.by_location,start,end:"
+msgid "Cancel"
+msgstr "Cancel·lar"
+
+msgctxt "wizard_button:stock.lot.by_location,start,open:"
+msgid "Open"
+msgstr "Abrir"

View File

@ -1,22 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
Use None for empty value on reference fields
issue4898
review24271002
Index: trytond/trytond/modules/account/move.py
===================================================================
--- a/trytond/trytond/modules/account/move.py
+++ b/trytond/trytond/modules/account/move.py
@@ -207,7 +207,7 @@
models = Model.search([
('model', 'in', models),
])
- return [('', '')] + [(m.model, m.name) for m in models]
+ return [(None, '')] + [(m.model, m.name) for m in models]
@classmethod
def validate(cls, moves):

View File

@ -1,217 +0,0 @@
Index: trytond/trytond/modules/account_invoice/invoice.py
===================================================================
--- a/trytond/trytond/modules/account_invoice/invoice.py
+++ b/trytond/trytond/modules/account_invoice/invoice.py
@@ -19,6 +19,8 @@
from trytond.transaction import Transaction
from trytond.pool import Pool
from trytond.rpc import RPC
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Invoice', 'InvoicePaymentLine', 'InvoiceLine',
'InvoiceLineTax', 'InvoiceTax',
@@ -1541,7 +1543,7 @@
'required': Eval('type') == 'line',
},
depends=['type', 'invoice_type'])
- unit_price = fields.Numeric('Unit Price', digits=(16, 4),
+ unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
states={
'invisible': Eval('type') != 'line',
'required': Eval('type') == 'line',
Index: trytond/trytond/modules/product/product.py
===================================================================
--- a/trytond/trytond/modules/product/product.py
+++ b/trytond/trytond/modules/product/product.py
@@ -6,6 +6,8 @@
from trytond.pool import Pool
from trytond import backend
from trytond.const import OPERATORS
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Template', 'Product']
@@ -36,9 +38,9 @@
category = fields.Many2One('product.category', 'Category',
states=STATES, depends=DEPENDS)
list_price = fields.Property(fields.Numeric('List Price', states=STATES,
- digits=(16, 4), depends=DEPENDS, required=True))
+ digits=(16, DIGITS), depends=DEPENDS, required=True))
cost_price = fields.Property(fields.Numeric('Cost Price',
- states=STATES, digits=(16, 4), depends=DEPENDS, required=True))
+ states=STATES, digits=(16, DIGITS), depends=DEPENDS, required=True))
cost_price_method = fields.Property(fields.Selection([
("fixed", "Fixed"),
("average", "Average")
@@ -131,9 +133,9 @@
on_change_with=['template']),
'on_change_with_type', searcher='search_type')
list_price_uom = fields.Function(fields.Numeric('List Price',
- digits=(16, 4)), 'get_price_uom')
+ digits=(16, DIGITS)), 'get_price_uom')
cost_price_uom = fields.Function(fields.Numeric('Cost Price',
- digits=(16, 4)), 'get_price_uom')
+ digits=(16, DIGITS)), 'get_price_uom')
@classmethod
def order_rec_name(cls, tables):
Index: trytond/trytond/modules/production/production.py
===================================================================
--- a/trytond/trytond/modules/production/production.py
+++ b/trytond/trytond/modules/production/production.py
@@ -7,6 +7,8 @@
from trytond.pyson import Eval, Bool, If, Id
from trytond.pool import Pool
from trytond.transaction import Transaction
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Production', 'AssignFailed', 'Assign']
@@ -98,7 +100,7 @@
'invisible': ~Eval('product'),
},
depends=['unit_digits'])
- cost = fields.Function(fields.Numeric('Cost', digits=(16, 4),
+ cost = fields.Function(fields.Numeric('Cost', digits=(16, DIGITS),
readonly=True), 'get_cost')
inputs = fields.One2Many('stock.move', 'production_input', 'Inputs',
domain=[
Index: trytond/trytond/modules/purchase/product.py
===================================================================
--- a/trytond/trytond/modules/purchase/product.py
+++ b/trytond/trytond/modules/purchase/product.py
@@ -9,6 +9,8 @@
from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
from trytond import backend
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Template', 'Product', 'ProductSupplier', 'ProductSupplierPrice']
__metaclass__ = PoolMeta
@@ -264,7 +266,8 @@
product_supplier = fields.Many2One('purchase.product_supplier',
'Supplier', required=True, ondelete='CASCADE')
quantity = fields.Float('Quantity', required=True, help='Minimal quantity')
- unit_price = fields.Numeric('Unit Price', required=True, digits=(16, 4))
+ unit_price = fields.Numeric('Unit Price', required=True, digits=(16,
+ DIGITS))
sequence = fields.Integer('Sequence')
@classmethod
Index: trytond/trytond/modules/purchase/purchase.py
===================================================================
--- a/trytond/trytond/modules/purchase/purchase.py
+++ b/trytond/trytond/modules/purchase/purchase.py
@@ -15,6 +15,8 @@
from trytond.pyson import Eval, Bool, If, PYSONEncoder, Id
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Purchase', 'PurchaseInvoice', 'PurchaseIgnoredInvoice',
'PurchaseRecreadtedInvoice', 'PurchaseLine', 'PurchaseLineTax',
@@ -870,7 +872,7 @@
fields.Many2One('product.uom.category', 'Product Uom Category',
on_change_with=['product']),
'on_change_with_product_uom_category')
- unit_price = fields.Numeric('Unit Price', digits=(16, 4),
+ unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
states={
'invisible': Eval('type') != 'line',
'required': Eval('type') == 'line',
Index: trytond/trytond/modules/purchase/stock.py
===================================================================
--- a/trytond/trytond/modules/purchase/stock.py
+++ b/trytond/trytond/modules/purchase/stock.py
@@ -10,6 +10,8 @@
from trytond.transaction import Transaction
from trytond.pyson import PYSONDecoder, PYSONEncoder
from trytond import backend
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['ShipmentIn', 'ShipmentInReturn', 'Move',
'OpenProductQuantitiesByWarehouse']
@@ -152,7 +154,7 @@
purchase_unit_digits = fields.Function(fields.Integer(
'Purchase Unit Digits'), 'get_purchase_fields')
purchase_unit_price = fields.Function(fields.Numeric('Purchase Unit Price',
- digits=(16, 4), states={
+ digits=(16, DIGITS), states={
'invisible': ~Eval('purchase_visible', False),
}, depends=['purchase_visible']), 'get_purchase_fields')
purchase_currency = fields.Function(fields.Many2One('currency.currency',
Index: trytond/trytond/modules/sale/sale.py
===================================================================
--- a/trytond/trytond/modules/sale/sale.py
+++ b/trytond/trytond/modules/sale/sale.py
@@ -15,6 +15,8 @@
from trytond.pyson import If, Eval, Bool, PYSONEncoder, Id
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['Sale', 'SaleInvoice', 'SaleIgnoredInvoice', 'SaleRecreatedInvoice',
'SaleLine', 'SaleLineTax', 'SaleLineIgnoredMove',
@@ -979,7 +981,7 @@
fields.Many2One('product.uom.category', 'Product Uom Category',
on_change_with=['product']),
'on_change_with_product_uom_category')
- unit_price = fields.Numeric('Unit Price', digits=(16, 4),
+ unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
states={
'invisible': Eval('type') != 'line',
'required': Eval('type') == 'line',
Index: trytond/trytond/modules/stock/move.py
===================================================================
--- a/trytond/trytond/modules/stock/move.py
+++ b/trytond/trytond/modules/stock/move.py
@@ -12,6 +12,8 @@
from trytond.pyson import In, Eval, Not, Equal, If, Get, Bool
from trytond.transaction import Transaction
from trytond.pool import Pool
+from trytond.config import config
+DIGITS = config.getint('digits', 'unit_price_digits', 4)
__all__ = ['StockMixin', 'Move']
@@ -197,14 +199,15 @@
Eval('context', {}).get('company', -1)),
],
depends=['state'])
- unit_price = fields.Numeric('Unit Price', digits=(16, 4),
+ unit_price = fields.Numeric('Unit Price', digits=(16, DIGITS),
states={
'invisible': Not(Bool(Eval('unit_price_required'))),
'required': Bool(Eval('unit_price_required')),
'readonly': Not(Equal(Eval('state'), 'draft')),
},
depends=['unit_price_required', 'state'])
- cost_price = fields.Numeric('Cost Price', digits=(16, 4), readonly=True)
+ cost_price = fields.Numeric('Cost Price', digits=(16, DIGITS),
+ readonly=True)
currency = fields.Many2One('currency.currency', 'Currency',
states={
'invisible': Not(Bool(Eval('unit_price_required'))),

View File

@ -1,124 +0,0 @@
diff -r 06cf10aa7502 tax.py
--- a/trytond/trytond/modules/account/tax.py Tue Nov 10 15:00:44 2015 +0100
+++ b/trytond/trytond/modules/account/tax.py Tue Nov 10 16:38:26 2015 +0100
@@ -3,6 +3,7 @@
import datetime
from decimal import Decimal
from sql.aggregate import Sum
+from itertools import groupby
from trytond.model import ModelView, ModelSQL, MatchMixin, fields
from trytond.wizard import Wizard, StateView, StateAction, Button
@@ -366,6 +367,7 @@
('fixed', 'Fixed'),
('none', 'None'),
], 'Type', required=True)
+ update_unit_price = fields.Boolean('Update Unit Price')
parent = fields.Many2One('account.tax.template', 'Parent')
childs = fields.One2Many('account.tax.template', 'parent', 'Children')
invoice_account = fields.Many2One('account.account.template',
@@ -445,6 +447,10 @@
def default_credit_note_tax_sign():
return Decimal('1')
+ @staticmethod
+ def default_update_unit_price():
+ return False
+
def _get_tax_value(self, tax=None):
'''
Set values for tax creation.
@@ -453,7 +459,7 @@
for field in ('name', 'description', 'sequence', 'amount',
'rate', 'type', 'invoice_base_sign', 'invoice_tax_sign',
'credit_note_base_sign', 'credit_note_tax_sign',
- 'start_date', 'end_date'):
+ 'start_date', 'end_date', 'update_unit_price'):
if not tax or getattr(tax, field) != getattr(self, field):
res[field] = getattr(self, field)
for field in ('group',):
@@ -595,6 +601,9 @@
('fixed', 'Fixed'),
('none', 'None'),
], 'Type', required=True)
+ update_unit_price = fields.Boolean('Update Unit Price',
+ help=('If checked then the unit price for further tax computation will'
+ 'be modified by this tax'))
parent = fields.Many2One('account.tax', 'Parent', ondelete='CASCADE')
childs = fields.One2Many('account.tax', 'parent', 'Children')
company = fields.Many2One('company.company', 'Company', required=True,
@@ -745,6 +754,10 @@
return Decimal('1')
@staticmethod
+ def default_update_unit_price():
+ return False
+
+ @staticmethod
def default_company():
return Transaction().context.get('company')
@@ -770,18 +783,28 @@
'tax': self,
}
+ def _group_taxes(self):
+ 'Key method used to group taxes'
+ return (self.sequence,)
+
@classmethod
def _unit_compute(cls, taxes, price_unit, date):
res = []
- for tax in taxes:
- start_date = tax.start_date or datetime.date.min
- end_date = tax.end_date or datetime.date.max
- if not (start_date <= date <= end_date):
- continue
- if tax.type != 'none':
- res.append(tax._process_tax(price_unit))
- if len(tax.childs):
- res.extend(cls._unit_compute(tax.childs, price_unit, date))
+ for _, group_taxes in groupby(taxes, key=cls._group_taxes):
+ unit_price_variation = 0
+ for tax in group_taxes:
+ start_date = tax.start_date or datetime.date.min
+ end_date = tax.end_date or datetime.date.max
+ if not (start_date <= date <= end_date):
+ continue
+ if tax.type != 'none':
+ value = tax._process_tax(price_unit)
+ res.append(value)
+ if tax.update_unit_price:
+ unit_price_variation += value['amount']
+ if len(tax.childs):
+ res.extend(cls._unit_compute(tax.childs, price_unit, date))
+ price_unit += unit_price_variation
return res
@classmethod
diff -r 06cf10aa7502 view/tax_form.xml
--- a/trytond/trytond/modules/account/view/tax_form.xml Tue Nov 10 15:00:44 2015 +0100
+++ b/trytond/trytond/modules/account/view/tax_form.xml Tue Nov 10 16:38:26 2015 +0100
@@ -34,6 +34,9 @@
<label name="company"/>
<field name="company"/>
<newline/>
+ <label name="update_unit_price"/>
+ <field name="update_unit_price"/>
+ <newline/>
<label name="invoice_account"/>
<field name="invoice_account"/>
<newline/>
diff -r 06cf10aa7502 view/tax_template_form.xml
--- a/trytond/trytond/modules/account/view/tax_template_form.xml Tue Nov 10 15:00:44 2015 +0100
+++ b/trytond/trytond/modules/account/view/tax_template_form.xml Tue Nov 10 16:38:26 2015 +0100
@@ -32,6 +32,9 @@
</group>
</group>
<newline/>
+ <label name="update_unit_price"/>
+ <field name="update_unit_price"/>
+ <newline/>
<label name="invoice_account"/>
<field name="invoice_account"/>
<newline/>

View File

@ -1,38 +0,0 @@
# HG changeset patch
# User Sergi Almacellas Abellana <sergi@koolpi.com>
# Date 1434356341 -7200
# Mon Jun 15 10:19:01 2015 +0200
# Node ID a4d2cf773eb206a9e842736318112d214d61ad11
# Parent a92088860973665945b42472c2bddb8138ac5b69
Only return default record if no domain supplied on ModelSingleton search
issue4766
review15401002
diff -r a92088860973 -r a4d2cf773eb2 trytond/model/modelsingleton.py
--- a/trytond/trytond/model/modelsingleton.py Mon Jun 15 02:19:49 2015 +0200
+++ b/trytond/trytond/model/modelsingleton.py Mon Jun 15 10:19:01 2015 +0200
@@ -76,7 +76,7 @@
def search(cls, domain, offset=0, limit=None, order=None, count=False):
res = super(ModelSingleton, cls).search(domain, offset=offset,
limit=limit, order=order, count=count)
- if not res:
+ if not res and not domain:
if count:
return 1
return [cls(1)]
diff -r a92088860973 -r a4d2cf773eb2 trytond/tests/test_modelsingleton.py
--- a/trytond/trytond/tests/test_modelsingleton.py Mon Jun 15 02:19:49 2015 +0200
+++ b/trytond/trytond/tests/test_modelsingleton.py Mon Jun 15 10:19:01 2015 +0200
@@ -121,6 +121,11 @@
count = self.singleton.search([], count=True)
self.assertEqual(count, 1)
+ self.singleton.create([{'name': 'foo'}])
+ singleton, = self.singleton.search([('name', '=', 'foo')])
+ self.assertEqual(singleton.name, 'foo')
+ singletons = self.singleton.search([('name', '=', 'bar')])
+ self.assertEqual(singletons, [])
transaction.cursor.rollback()

View File

@ -2,13 +2,13 @@ diff -r f9ff7d1399d1 stock.py
--- a/trytond/trytond/modules/sale/stock.py Fri Sep 04 16:30:54 2015 +0200
+++ b/trytond/trytond/modules/sale/stock.py Fri Sep 04 16:31:35 2015 +0200
@@ -1,5 +1,6 @@
#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from itertools import ifilter
from sql import Null
from sql.operators import Concat
from trytond.model import Workflow, ModelView, fields
@@ -60,6 +61,35 @@
@@ -61,6 +62,35 @@
return super(ShipmentOut, cls).draft(shipments)
@ -44,7 +44,7 @@ diff -r f9ff7d1399d1 stock.py
class ShipmentOutReturn:
__name__ = 'stock.shipment.out.return'
@@ -146,6 +176,7 @@
@@ -147,6 +177,7 @@
@classmethod
def _get_origin(cls):
models = super(Move, cls)._get_origin()

View File

@ -1,7 +1,7 @@
diff -r 8684df73e037 shipment.py
--- a/trytond/trytond/modules/stock/shipment.py Fri Sep 04 16:29:38 2015 +0200
+++ b/trytond/trytond/modules/stock/shipment.py Fri Sep 04 16:30:32 2015 +0200
@@ -1111,6 +1111,14 @@
@@ -1118,6 +1118,14 @@
unit_price=move.unit_price,
)
@ -14,9 +14,9 @@ diff -r 8684df73e037 shipment.py
+ return move.product.id
+
@classmethod
def _sync_inventory_to_outgoing(cls, shipments):
def _sync_inventory_to_outgoing(cls, shipments, create=True, write=True):
'Synchronise outgoing moves with inventory moves'
@@ -1125,8 +1133,10 @@
@@ -1132,8 +1140,10 @@
continue
quantity = Uom.compute_qty(move.uom, move.quantity,
move.product.default_uom, round=False)
@ -29,7 +29,7 @@ diff -r 8684df73e037 shipment.py
to_create = []
for move in shipment.inventory_moves:
@@ -1134,19 +1144,20 @@
@@ -1141,19 +1151,20 @@
continue
qty_default_uom = Uom.compute_qty(move.uom, move.quantity,
move.product.default_uom, round=False)
@ -56,7 +56,7 @@ diff -r 8684df73e037 shipment.py
else:
out_quantity = move.quantity
@@ -1164,16 +1175,18 @@
@@ -1171,9 +1182,11 @@
for move in shipment.outgoing_moves:
if move.state == 'cancel':
continue
@ -70,9 +70,10 @@ diff -r 8684df73e037 shipment.py
removed_qty = Uom.compute_qty(move.uom,
min(exc_qty, move.quantity), move.product.default_uom,
round=False)
Move.write([move], {
'quantity': max(0.0, move.quantity - exc_qty),
})
@@ -1181,7 +1194,7 @@
Move.write([move], {
'quantity': max(0.0, move.quantity - exc_qty),
})
- outgoing_qty[move.product.id] -= removed_qty
+ outgoing_qty[key] -= removed_qty

View File

@ -1,19 +1,19 @@
diff -r 90cc3f4c20c9 trytond/trytond/model/modelstorage.py
--- a/trytond/trytond/model/modelstorage.py Tue Sep 22 16:39:45 2015 +0200
+++ b/trytond/trytond/model/modelstorage.py Tue Sep 22 16:40:32 2015 +0200
@@ -928,10 +928,11 @@
else:
relations = records
@@ -952,10 +952,11 @@
if relations:
- finds = Relation.search(['AND',
- [('id', 'in', [r.id for r in relations])],
- domain,
- ])
+ with Transaction().set_user(0):
+ finds = Relation.search(['AND',
+ [('id', 'in', [r.id for r in relations])],
+ domain,
+ ])
if set(relations) != set(finds):
cls.raise_user_error('domain_validation_record',
error_args=cls._get_error_args(field.name))
for sub_relations in grouped_slice(relations):
sub_relations = set(sub_relations)
- finds = Relation.search(['AND',
- [('id', 'in', [r.id for r in sub_relations])],
- domain,
- ])
+ with Transaction().set_user(0):
+ finds = Relation.search(['AND',
+ [('id', 'in', [r.id for r in sub_relations])],
+ domain,
+ ])
if sub_relations != set(finds):
cls.raise_user_error('domain_validation_record',
error_args=cls._get_error_args(field.name))

View File

@ -1,16 +0,0 @@
Index: tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
===================================================================
--- a/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
+++ b/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
@@ -530,7 +530,8 @@
else:
value = field.get_data(record)
pixbuf = data2pixbuf(value)
- if self.attrs['width'] != -1 or self.attrs['height'] != -1:
+ if (self.attrs.get('width', -1) != -1 or
+ self.attrs.get('height', -1) != -1):
pixbuf = common.resize_pixbuf(pixbuf,
self.attrs['width'], self.attrs['height'])
cell.set_property('pixbuf', pixbuf)

View File

@ -1,23 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
Allow to change the carrier until the shipment is done
issue4413
review5881002
Index: modules/sale_shipment_cost/stock.py
===================================================================
--- .a/trytond/trytond/modules/sale_shipment_cost/stock.py
+++ .b/trytond/trytond/modules/sale_shipment_cost/stock.py
@@ -12,7 +12,8 @@
class ShipmentOut:
__name__ = 'stock.shipment.out'
carrier = fields.Many2One('carrier', 'Carrier', states={
- 'readonly': Eval('state') != 'draft',
+ 'readonly': ~Eval('state').in_(['draft', 'waiting', 'assigned',
+ 'packed']),
},
depends=['state'])
cost_currency = fields.Many2One('currency.currency',

View File

@ -19,19 +19,19 @@ Index: account.py
- Account = pool.get('account.account')
- Company = pool.get('company.company')
Currency = pool.get('currency.currency')
cursor = Transaction().cursor
cursor = Transaction().connection.cursor()
- table = cls.__table__()
- line = Line.__table__()
- move_line = MoveLine.__table__()
- a_account = Account.__table__()
- company = Company.__table__()
ids = [a.id for a in accounts]
childs = cls.search([('parent', 'child_of', ids)])
@@ -145,25 +136,12 @@
for account in all_accounts:
id2account[account.id] = account
- line_query = Line.query_get(line)
- cursor.execute(*table.join(line, 'LEFT',
- condition=table.id == line.account
@ -46,7 +46,7 @@ Index: account.py
- company.currency,
- where=(table.type != 'view')
- & table.id.in_(all_ids)
- & table.active & line_query,
- & (table.active == True) & line_query,
- group_by=(table.id, company.currency)))
+ query = cls.query_get(all_ids, [name])
+ cursor.execute(*query)
@ -67,19 +67,19 @@ Index: account.py
- Account = pool.get('account.account')
- Company = pool.get('company.company')
Currency = pool.get('currency.currency')
cursor = Transaction().cursor
cursor = Transaction().connection.cursor()
- table = cls.__table__()
- line = Line.__table__()
- move_line = MoveLine.__table__()
- a_account = Account.__table__()
- company = Company.__table__()
result = {}
ids = [a.id for a in accounts]
@@ -223,23 +192,8 @@
for account in accounts:
id2account[account.id] = account
- line_query = Line.query_get(line)
- columns = [table.id, company.currency]
- for name in names:
@ -95,17 +95,17 @@ Index: account.py
- ).select(*columns,
- where=(table.type != 'view')
- & table.id.in_(ids)
- & table.active & line_query,
- & (table.active == True) & line_query,
- group_by=(table.id, company.currency)))
+ query = cls.query_get(ids, names)
+ cursor.execute(*query)
id2currency = {}
for row in cursor.fetchall():
@@ -263,6 +217,43 @@
result[name][account.id] += account.currency.round(sum)
return result
+ @classmethod
+ def query_get(cls, ids, names):
+ pool = Pool()
@ -146,4 +146,3 @@ Index: account.py
def get_rec_name(self, name):
if self.code:
return self.code + ' - ' + unicode(self.name)

View File

@ -3,7 +3,7 @@ Index: trytond/trytond/modules/account_asset/asset.xml
--- a/trytond/trytond/modules/account_asset/asset.xml
+++ b/trytond/trytond/modules/account_asset/asset.xml
@@ -130,6 +130,15 @@
@@ -139,6 +139,16 @@
<field name="name">asset_line_tree</field>
</record>
@ -12,11 +12,11 @@ Index: trytond/trytond/modules/account_asset/asset.xml
+ <field name="global_p" eval="True"/>
+ </record>
+ <record model="ir.rule" id="rule_asset_line1">
+ <field name="domain">[('asset.company', '=', user.company.id if user.company else None)]</field>
+ <field name="domain" eval="[('asset.company', 'in', Eval('user', {}).get('companies', []))]" pyson="1"/>
+ <field name="rule_group" ref="rule_group_asset_line"/>
+ </record>
+
<record model="ir.model.access" id="access_asset_line_account_admin">
+
<record model="ir.model.access" id="access_asset_line">
<field name="model" search="[('model', '=', 'account.asset.line')]"/>
<field name="group" ref="account.group_account_admin"/>
<field name="perm_read" eval="False"/>

View File

@ -1,42 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
allow to provide ssl_context to set_xmlrpc()issue4592
review6951002
Index: proteus/config.py
===================================================================
--- a/proteus/proteus/config.py
+++ b/proteus/proteus/config.py
@@ -286,10 +286,14 @@
class XmlrpcConfig(Config):
'Configuration for XML-RPC'
- def __init__(self, url):
+ def __init__(self, url, **kwargs):
super(XmlrpcConfig, self).__init__()
self.url = url
- self.server = xmlrpclib.ServerProxy(url, allow_none=1, use_datetime=1)
+ if 'allow_none' not in kwargs:
+ kwargs['allow_none'] = 1
+ if 'use_datetime' not in kwargs:
+ kwargs['use_datetime'] = 1
+ self.server = xmlrpclib.ServerProxy(url, **kwargs)
# TODO add user
self.user = None
self._context = self.server.model.res.user.get_preferences(True, {})
@@ -320,9 +324,9 @@
and '.' not in x[len(object_) + 1:]]
-def set_xmlrpc(url):
+def set_xmlrpc(url, **kwargs):
'Set XML-RPC as backend'
- _CONFIG.current = XmlrpcConfig(url)
+ _CONFIG.current = XmlrpcConfig(url, **kwargs)
return _CONFIG.current

View File

@ -1,31 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
recover uninstall modules feature
issue322
review7881002
Index: trytond/trytond/modules/__init__.py
===================================================================
--- a/trytond/trytond/modules/__init__.py
+++ b/trytond/trytond/modules/__init__.py
@@ -222,7 +222,7 @@
if package_state not in ('to install', 'to upgrade'):
if package_state == 'installed':
package_state = 'to upgrade'
- else:
+ elif package_state != 'to remove':
package_state = 'to install'
for child in package.childs:
module2state[child.name] = package_state
@@ -258,6 +258,8 @@
Translation = pool.get('ir.translation')
Translation.translation_import(lang2, module, filename)
+ if package_state == 'to remove':
+ continue
cursor.execute(*ir_module.select(ir_module.id,
where=(ir_module.name == package.name)))
try:

View File

@ -1,34 +0,0 @@
diff -r 1612dc06414e account.py
--- a/trytond/trytond/modules/account/account.py Tue Oct 06 15:47:15 2015 +0200
+++ b/trytond/trytond/modules/account/account.py Tue Oct 06 15:50:07 2015 +0200
@@ -4,6 +4,7 @@
import datetime
import operator
from itertools import izip, groupby
+from functools import wraps
from sql import Column, Literal
from sql.aggregate import Sum
from sql.conditionals import Coalesce
@@ -30,6 +31,14 @@
'OpenAgedBalanceStart', 'OpenAgedBalance', 'AgedBalance']
+def inactive_records(func):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ with Transaction().set_context(active_test=False):
+ return func(*args, **kwargs)
+ return wrapper
+
+
class TypeTemplate(ModelSQL, ModelView):
'Account Type Template'
__name__ = 'account.account.type.template'
@@ -1793,6 +1802,7 @@
Button('Ok', 'end', 'tryton-ok', default=True),
])
+ @inactive_records
def transition_update(self):
pool = Pool()
TaxCode = pool.get('account.tax.code')

View File

@ -1,85 +0,0 @@
Index: trytond/trytond/tests/test_tools.py
===================================================================
--- a/trytond/trytond/tests/test_tools.py
+++ b/trytond/tests/test_tools.py
@@ -3,12 +3,13 @@
#this repository contains the full copyright notices and license terms.
import unittest
+import doctest
import datetime
import sql
import sql.operators
from trytond.tools import reduce_ids, safe_eval, datetime_strftime, \
- reduce_domain
+ reduce_domain, decimal_
class ToolsTestCase(unittest.TestCase):
@@ -117,4 +118,5 @@
suite = unittest.TestSuite()
for testcase in (ToolsTestCase,):
suite.addTests(func(testcase))
+ suite.addTest(doctest.DocTestSuite(decimal_))
return suite
Index: trytond/trytond/tools/__init__.py
===================================================================
--- a/trytond/trytond/tools/__init__.py
+++ b/trytond/trytond/tools/__init__.py
@@ -2,6 +2,7 @@
#this repository contains the full copyright notices and license terms.
from .misc import *
from .datetime_strftime import *
+from .decimal_ import *
class ClassProperty(property):
Index: trytond/trytond/tools/decimal_.py
===================================================================
new file mode 100644
--- /dev/null
+++ b/trytond/trytond/tools/decimal_.py
@@ -0,0 +1,36 @@
+# This file is part of Tryton. The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import tokenize
+from io import StringIO
+
+# code snippet taken from http://docs.python.org/library/tokenize.html
+
+
+def decistmt(s):
+ """Substitute Decimals for floats in a string of statements.
+
+ >>> from decimal import Decimal
+ >>> s = 'print +21.3e-5*-.1234/81.7'
+ >>> decistmt(s)
+ u"print +Decimal (u'21.3e-5')*-Decimal (u'.1234')/Decimal (u'81.7')"
+
+ >>> exec(s)
+ -3.21716034272e-07
+ >>> exec(decistmt(s))
+ -3.217160342717258261933904529E-7
+ """
+ result = []
+ # tokenize the string
+ g = tokenize.generate_tokens(StringIO(s.decode('utf-8')).readline)
+ for toknum, tokval, _, _, _ in g:
+ # replace NUMBER tokens
+ if toknum == tokenize.NUMBER and '.' in tokval:
+ result.extend([
+ (tokenize.NAME, 'Decimal'),
+ (tokenize.OP, '('),
+ (tokenize.STRING, repr(tokval)),
+ (tokenize.OP, ')')
+ ])
+ else:
+ result.append((toknum, tokval))
+ return tokenize.untokenize(result)

View File

@ -1,81 +0,0 @@
# HG changeset patch
# User Guillem Barba <guillembarba@gmail.com>
Add warning message for late production
issue4375
review9911002
Index: modules/stock_supply_production/production.py
===================================================================
--- .a/trytond/trytond/modules/stock_supply_production/production.py
+++ .b/trytond/trytond/modules/stock_supply_production/production.py
@@ -212,13 +212,33 @@
])
create_ = StateAction('stock_supply_production.act_production_request')
+ @classmethod
+ def __setup__(cls):
+ super(CreateProductionRequest, cls).__setup__()
+ cls._error_messages.update({
+ 'late_productions': 'There are some late productions.',
+ })
+
@property
def _requests_parameters(self):
return {}
def do_create_(self, action):
pool = Pool()
+ Date = pool.get('ir.date')
+ Move = pool.get('stock.move')
Production = pool.get('production')
+
+ today = Date.today()
+ if Move.search([
+ ('from_location.type', '=', 'production'),
+ ('to_location.type', '=', 'storage'),
+ ('state', '=', 'draft'),
+ ('planned_date', '<', today),
+ ], order=[]):
+ self.raise_user_warning('%s@%s' % (self.__name__, today),
+ 'late_productions')
+
Production.generate_requests(**self._requests_parameters)
return action, {}
Index: modules/stock_supply_production/locale/ca_ES.po
===================================================================
--- a/trytond/trytond/modules/stock_supply_production/locale/ca_ES.po Tue Feb 17 21:08:47 2015 +0100
+++ b/trytond/trytond/modules/stock_supply_production/locale/ca_ES.po Wed Mar 04 11:16:09 2015 +0100
@@ -2,6 +2,10 @@
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
+msgctxt "error:production.create_request:"
+msgid "There are some late productions."
+msgstr "Hi ha algunes produccions endarrerides."
+
msgctxt "field:production.configuration,supply_period:"
msgid "Supply Period"
msgstr "Període de subministre"
Index: modules/stock_supply_production/locale/es_ES.po
===================================================================
--- a/trytond/trytond/modules/stock_supply_production/locale/es_ES.po Tue Feb 17 21:08:47 2015 +0100
+++ b/trytond/trytond/modules/stock_supply_production/locale/es_ES.po Wed Mar 04 11:16:09 2015 +0100
@@ -2,6 +2,10 @@
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
+msgctxt "error:production.create_request:"
+msgid "There are some late productions."
+msgstr "Hay algunas producciones retrasadas."
+
msgctxt "field:production.configuration,supply_period:"
msgid "Supply Period"
msgstr "Período de suministro"

View File

@ -1,39 +0,0 @@
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1418659399 -3600
# Mon Dec 15 17:03:19 2014 +0100
# Node ID b03d02a0f664a87fa2bb77021a2654bcc39a2c26
# Parent 31de0a6f728459962f36db68456cfc6ed619b99b
Move party after account
Since changeset b122de923ef9, party visiblity depends on the account so it is
better to move the field after the account.
review5851002
diff -r 31de0a6f7284 -r b03d02a0f664 view/move_line_tree.xml
--- a/trytond/trytond/modules/account/view/move_line_tree.xml Mon Dec 08 16:18:41 2014 +0100
+++ b/trytond/trytond/modules/account/view/move_line_tree.xml Mon Dec 15 17:03:19 2014 +0100
@@ -9,8 +9,8 @@
<field name="description"/>
<field name="move_description"/>
<field name="date"/>
+ <field name="account"/>
<field name="party"/>
- <field name="account"/>
<field name="debit" sum="Debit"/>
<field name="credit" sum="Credit"/>
<field name="tax_lines"/>
diff -r 31de0a6f7284 -r b03d02a0f664 view/move_line_tree_move.xml
--- a/trytond/trytond/modules/account/view/move_line_tree_move.xml Mon Dec 08 16:18:41 2014 +0100
+++ b/trytond/trytond/modules/account/view/move_line_tree_move.xml Mon Dec 15 17:03:19 2014 +0100
@@ -4,8 +4,8 @@
<tree string="Account Move Lines" editable="top">
<field name="move"/>
<field name="description"/>
+ <field name="account"/>
<field name="party"/>
- <field name="account"/>
<field name="debit" sum="Debit"/>
<field name="credit" sum="Credit"/>
<field name="tax_lines"/>

View File

@ -1,34 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619627 -3600
# Wed Dec 03 16:13:47 2014 +0100
# Node ID c1cc3484518d4d296c10019d1ee54c709cf8b996
# Parent ca47fe15e8b29f309952f0f0207fc990b0336971
# Add missing company domain/field
# issue4311
# review7691002
diff -r ca47fe15e8b2 -r c1cc3484518d configuration.py
--- .a/trytond/trytond/modules/party/configuration.py Tue Dec 02 12:55:24 2014 +0100
+++ .b/trytond/trytond/modules/party/configuration.py Wed Dec 03 16:13:47 2014 +0100
@@ -1,6 +1,7 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, ModelSingleton, fields
+from trytond.pyson import Eval
__all__ = ['Configuration']
@@ -12,6 +13,10 @@
party_sequence = fields.Property(fields.Many2One('ir.sequence',
'Party Sequence', domain=[
('code', '=', 'party.party'),
+ ['OR',
+ ('company', '=', Eval('context', {}).get('company', -1)),
+ ('company', '=', None),
+ ],
]))
party_lang = fields.Property(fields.Many2One("ir.lang", 'Party Language',
help=('The value set on this field will preset the language on new '

View File

@ -1,42 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619637 -3600
# Wed Dec 03 16:13:57 2014 +0100
# Node ID b50beae497b9daa73ac31cc02eafbc54b91c0851
# Parent 7bf478a06a93e766297c0488f0606b90201c0a37
# Add missing company domain/field
# issue4311
# review7691002
diff -r 7bf478a06a93 -r b50beae497b9 production.py
--- .a/trytond/trytond/modules/production/production.py Tue Dec 02 12:55:39 2014 +0100
+++ .b/trytond/trytond/modules/production/production.py Wed Dec 03 16:13:57 2014 +0100
@@ -104,22 +104,24 @@
domain=[
('from_location', 'child_of', [Eval('warehouse')], 'parent'),
('to_location', '=', Eval('location')),
+ ('company', '=', Eval('company', -1)),
],
states={
'readonly': (~Eval('state').in_(['request', 'draft', 'waiting'])
| ~Eval('warehouse') | ~Eval('location')),
},
- depends=['warehouse', 'location'])
+ depends=['warehouse', 'location', 'company'])
outputs = fields.One2Many('stock.move', 'production_output', 'Outputs',
domain=[
('from_location', '=', Eval('location')),
('to_location', 'child_of', [Eval('warehouse')], 'parent'),
+ ('company', '=', Eval('company', -1)),
],
states={
'readonly': (Eval('state').in_(['done', 'cancel'])
| ~Eval('warehouse') | ~Eval('location')),
},
- depends=['warehouse', 'location'])
+ depends=['warehouse', 'location', 'company'])
state = fields.Selection([
('request', 'Request'),
('draft', 'Draft'),

View File

@ -1,24 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619642 -3600
# Wed Dec 03 16:14:02 2014 +0100
# Node ID 5b0d2d2727a6a3e9d23b0eb2d0470aa21b2e7949
# Parent fd68d64d6d766a52c88579f362bafa6d425fa119
# Add missing company domain/field
# issue4311
# review7691002
diff -r fd68d64d6d76 -r 5b0d2d2727a6 purchase.py
--- .a/trytond/trytond/modules/purchase/purchase.py Tue Dec 02 12:55:47 2014 +0100
+++ .b/trytond/trytond/modules/purchase/purchase.py Wed Dec 03 16:14:02 2014 +0100
@@ -951,6 +951,8 @@
domain=[('parent', '=', None), ['OR',
('group', '=', None),
('group.kind', 'in', ['purchase', 'both'])],
+ ('company', '=',
+ Eval('_parent_purchase', {}).get('company', -1)),
],
states={
'invisible': Eval('type') != 'line',

View File

@ -1,21 +0,0 @@
diff a/locale/ca_ES.po b/locale/ca_ES.po
--- .a/trytond/trytond/modules/purchase/locale/ca_ES.po
+++ .b/trytond/trytond/modules/purchase/locale/ca_ES.po
@@ -131,7 +131,7 @@
msgctxt "field:purchase.line,amount:"
msgid "Amount"
-msgstr "Quantitat"
+msgstr "Import"
msgctxt "field:purchase.line,create_date:"
msgid "Create Date"
@@ -863,7 +863,7 @@
msgctxt "odt:purchase.purchase:"
msgid "Amount"
-msgstr "Quantitat"
+msgstr "Import"
msgctxt "odt:purchase.purchase:"
msgid "Date:"

View File

@ -1,24 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619645 -3600
# Wed Dec 03 16:14:05 2014 +0100
# Node ID 23d0b5a3ceb170f5b2e4d67ec42db93f3e98e5b3
# Parent fde9b7af345d6ea9dccf77b5ea2201ac5d506fc7
# Add missing company domain/field
# issue4311
# review7691002
diff -r fde9b7af345d -r 23d0b5a3ceb1 sale.py
--- .a/trytond/trytond/modules/sale/sale.py Tue Dec 02 12:55:52 2014 +0100
+++ .b/trytond/trytond/modules/sale/sale.py Wed Dec 03 16:14:05 2014 +0100
@@ -1023,6 +1023,8 @@
domain=[('parent', '=', None), ['OR',
('group', '=', None),
('group.kind', 'in', ['sale', 'both'])],
+ ('company', '=',
+ Eval('_parent_sale', {}).get('company', -1)),
],
states={
'invisible': Eval('type') != 'line',

View File

@ -1,17 +0,0 @@
# http://codereview.tryton.org/5871002/
diff -r 46c9a4316548 sale.py
--- .a/trytond/trytond/modules/sale/sale.py Thu Dec 04 23:41:16 2014 +0100
+++ .b/trytond/trytond/modules/sale/sale.py Wed Dec 17 21:27:11 2014 +0100
@@ -1365,8 +1369,10 @@
if old_invoice_line.type != 'line':
continue
if old_invoice_line.id not in skip_ids:
+ sign = (1.0 if invoice_type == old_invoice_line.invoice_type
+ else -1.0)
quantity -= Uom.compute_qty(old_invoice_line.unit,
- old_invoice_line.quantity, self.unit)
+ sign * old_invoice_line.quantity, self.unit)
rounding = self.unit.rounding if self.unit else 0.01
invoice_line.quantity = Uom.round(quantity, rounding)

57
series
View File

@ -1,82 +1,37 @@
stock_lot_expand_lot_required.diff
account_move_line_rule.diff
issue154_316.diff
issue10467.diff
issue130_392_10919.diff
issue239_630.diff
issue240_631.diff
issue306_799.diff
disable_tests.diff
client-open_url.diff
fix_wizard_copy.diff
issue6341003_1.diff
issue10391004_1.diff
issue5731002_1.diff
issue5881002_1.diff
issue14841002_1.diff
issue10061002_1.diff
issue13891002_20001.diff
issue10071002_1.diff
# Multicompanyia! no borrar, no descomentar
account_42b9acc4c201.patch
account_asset_78bda42be464.patch
account_invoice_51e5f7fb547b.patch
account_payment_5dd8c0c2a04c.patch
account_payment_sepa_f69c5ffa5f79.patch
account_statement_2642b961c2bf.patch
party_c1cc3484518d.patch
production_b50beae497b9.patch
purchase_5b0d2d2727a6.patch
sale_23d0b5a3ceb1.patch
stock_supply_780a8aaeaa78.patch
timesheet_f8c45f1b4d7d.patch
sale_fix_invoiced_quantity_calculation.diff
issue7881002_1.diff
country.diff
issue10091002_1.diff
issue9911002_80001.diff
issue6021003_1.diff
issue6951002_20001.diff
stock_supply_production-performance-improvement.diff
top.diff
issue15211002-sale-confirmed-to-done.diff
purchase_translation.diff
issue9801002_40001.diff
issue19281002_1.diff
issue13181002_1.diff
issue13211002_190001.diff
issue17281002_20001.diff
issue20301003_1.diff
invoice_speedup.diff
babi_multiprocess.diff
domain_field.diff
issue18361002_40001.diff
issue24271002_1.diff
issue18481003_1.diff
issue4766.diff
issue4950_stock.diff
issue4950_sale.diff
party_after_account.diff
issue4986.diff
issue16661002_1.diff
issue19491002_1.diff
issue20451002_1.diff
issue7961002_40001.diff
issue4115.diff
issue5118.diff
issue18801002_1.diff
workflow-performance.diff
analytic_account.diff
analytic_invoice.diff
analytic_sale.diff
analytic_purchase.diff
# Ignore next patches
#incremental_wait_in_retries.diff
# Uncomment in calfruitos and basidelta
#account_chart_speedup.diff
# Uncomment in calfruitos
#fix_rounding_in_sync_inventory_to_outgoing.patch
#chart_not_translatable.diff
#024726_account_bank_remove_company.diff
#024726_account_payment_type_remove_company.diff
#stock_lot_improve_sync_inventory_to_outgoing.diff

View File

@ -1,12 +0,0 @@
diff -r fdfe606e6b87 view/template_form.xml
--- a/trytond/trytond/modules/stock_lot/view/template_form.xml Thu Feb 19 00:04:21 2015 +0100
+++ b/trytond/trytond/modules/stock_lot/view/template_form.xml Mon Apr 13 13:27:44 2015 +0200
@@ -6,7 +6,7 @@
<page string="Lots" id="lots"
states="{'invisible': ~Eval('type').in_(['goods', 'assets'])}">
<label name="lot_required"/>
- <field name="lot_required" widget="multiselection" yexpand="0"/>
+ <field name="lot_required" widget="multiselection" yexpand="1"/>
</page>
</xpath>
</data>

View File

@ -1,23 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619662 -3600
# Wed Dec 03 16:14:22 2014 +0100
# Node ID 780a8aaeaa78e174b990de11de88e7db9a441492
# Parent 6c18a72971b16133ef5feaba2ad2c1f1e2677bf5
# Add missing company domain/field
# issue4311
# review7691002
diff -r 6c18a72971b1 -r 780a8aaeaa78 purchase_request.py
--- .a/trytond/trytond/modules/stock_supply/purchase_request.py Tue Dec 02 12:56:15 2014 +0100
+++ .b/trytond/trytond/modules/stock_supply/purchase_request.py Wed Dec 03 16:14:22 2014 +0100
@@ -176,6 +176,7 @@
# fetch order points
order_points = OrderPoint.search([
('type', '=', 'purchase'),
+ ('company', '=', company.id if company else None),
])
# index them by product
product2ops = {}

View File

@ -1,161 +0,0 @@
# exporting patch:
# HG changeset patch
# User Cédric Krier <ced@b2ck.com>
# Date 1417619666 -3600
# Wed Dec 03 16:14:26 2014 +0100
# Node ID f8c45f1b4d7d9f49af3b04d2263acfde2c6653de
# Parent 9b27753b51889fc5dfc8a1cc9cad391ab1730199
# Add missing company domain/field
# issue4311
# review7691002
diff -r 9b27753b5188 -r f8c45f1b4d7d line.py
--- .a/trytond/trytond/modules/timesheet/line.py Tue Dec 02 12:56:21 2014 +0100
+++ .b/trytond/trytond/modules/timesheet/line.py Wed Dec 03 16:14:26 2014 +0100
@@ -10,6 +10,7 @@
from trytond.pyson import Eval, PYSONEncoder, Date
from trytond.transaction import Transaction
from trytond.pool import Pool
+from trytond import backend
__all__ = ['Line', 'EnterLinesStart', 'EnterLines',
'HoursEmployee',
@@ -20,14 +21,17 @@
class Line(ModelSQL, ModelView):
'Timesheet Line'
__name__ = 'timesheet.line'
+ company = fields.Many2One('company.company', 'Company', required=True)
employee = fields.Many2One('company.employee', 'Employee', required=True,
select=True, domain=[
- ('company', '=', Eval('context', {}).get('company', -1)),
- ])
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
date = fields.Date('Date', required=True, select=True)
hours = fields.Float('Hours', digits=(16, 2), required=True)
work = fields.Many2One('timesheet.work', 'Work',
required=True, select=True, domain=[
+ ('company', '=', Eval('company', -1)),
('timesheet_available', '=', True),
['OR',
('timesheet_start_date', '=', None),
@@ -38,7 +42,7 @@
('timesheet_end_date', '>=', Eval('date')),
],
],
- depends=['date'])
+ depends=['date', 'company'])
description = fields.Char('Description')
@classmethod
@@ -50,6 +54,31 @@
'CHECK(hours >= 0.0)', 'Hours field must be positive'),
]
+ @classmethod
+ def __register__(cls, module_name):
+ TableHandler = backend.get('TableHandler')
+ cursor = Transaction().cursor
+ table = TableHandler(cursor, cls, module_name)
+ sql_table = cls.__table__()
+ pool = Pool()
+ Work = pool.get('timesheet.work')
+ work = Work.__table__()
+
+ created_company = not table.column_exist('company')
+
+ super(Line, cls).__register__(module_name)
+
+ # Migration from 3.4: new company field
+ if created_company:
+ # Don't use FROM because SQLite nor MySQL support it.
+ cursor.execute(*sql_table.update(
+ [sql_table.company], [work.select(work.company,
+ where=work.id == sql_table.work)]))
+
+ @staticmethod
+ def default_company():
+ return Transaction().context.get('company')
+
@staticmethod
def default_employee():
User = Pool().get('res.user')
diff -r 9b27753b5188 -r f8c45f1b4d7d view/line_form.xml
--- .a/trytond/trytond/modules/timesheet/view/line_form.xml Tue Dec 02 12:56:21 2014 +0100
+++ .b/trytond/trytond/modules/timesheet/view/line_form.xml Wed Dec 03 16:14:26 2014 +0100
@@ -3,7 +3,9 @@
this repository contains the full copyright notices and license terms. -->
<form string="Timesheet Line">
<label name="employee"/>
- <field name="employee" colspan="3"/>
+ <field name="employee"/>
+ <label name="company"/>
+ <field name="company"/>
<label name="date"/>
<field name="date"/>
<label name="hours"/>
diff -r 9b27753b5188 -r f8c45f1b4d7d view/line_tree.xml
--- .a/trytond/trytond/modules/timesheet/view/line_tree.xml Tue Dec 02 12:56:21 2014 +0100
+++ .b/trytond/trytond/modules/timesheet/view/line_tree.xml Wed Dec 03 16:14:26 2014 +0100
@@ -2,6 +2,7 @@
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tree string="Timesheet Lines" editable="bottom">
+ <field name="company"/>
<field name="employee"/>
<field name="date"/>
<field name="hours" widget="float_time" float_time="company_work_time"
diff -r 9b27753b5188 -r f8c45f1b4d7d work.py
--- .a/trytond/trytond/modules/timesheet/work.py Tue Dec 02 12:56:21 2014 +0100
+++ .b/trytond/trytond/modules/timesheet/work.py Wed Dec 03 16:14:26 2014 +0100
@@ -19,10 +19,18 @@
name = fields.Char('Name', required=True)
active = fields.Boolean('Active')
parent = fields.Many2One('timesheet.work', 'Parent', left="left",
- right="right", select=True, ondelete="RESTRICT")
+ right="right", select=True, ondelete="RESTRICT",
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
left = fields.Integer('Left', required=True, select=True)
right = fields.Integer('Right', required=True, select=True)
- children = fields.One2Many('timesheet.work', 'parent', 'Children')
+ children = fields.One2Many('timesheet.work', 'parent', 'Children',
+ domain=[
+ ('company', '=', Eval('company', -1)),
+ ],
+ depends=['company'])
hours = fields.Function(fields.Float('Timesheet Hours', digits=(16, 2),
help="Total time spent on this work"), 'get_hours')
timesheet_available = fields.Boolean('Available on timesheets',
@@ -51,9 +59,6 @@
def __setup__(cls):
super(Work, cls).__setup__()
cls._error_messages.update({
- 'invalid_parent_company': ('Every work must be in the same '
- 'company as it\'s parent work but "%(child)s" and '
- '"%(parent)s" are in different companies.'),
'change_timesheet_available': ('You can not unset "Available '
'on timesheets" for work "%s" because it already has '
'timesheets.'),
@@ -83,17 +88,6 @@
def validate(cls, works):
super(Work, cls).validate(works)
cls.check_recursion(works, rec_name='name')
- for work in works:
- work.check_parent_company()
-
- def check_parent_company(self):
- if not self.parent:
- return
- if self.parent.company != self.company:
- self.raise_user_error('invalid_parent_company', {
- 'child': self.rec_name,
- 'parent': self.parent.rec_name,
- })
@classmethod
def get_hours(cls, works, name):

View File

@ -1,49 +1,49 @@
diff -r 649b0805fa93 trytond/protocols/dispatcher.py
--- a/trytond/trytond/protocols/dispatcher.py Fri Feb 20 09:11:59 2015 +0100
+++ b/trytond/trytond/protocols/dispatcher.py Sun Apr 19 03:17:46 2015 +0200
@@ -19,6 +19,8 @@
ConcurrencyException
from trytond.rpc import RPC
@@ -20,6 +20,8 @@
from trytond.tools import is_instance_method
from trytond.wsgi import app
+import top
+
logger = logging.getLogger(__name__)
ir_configuration = Table('ir_configuration')
@@ -153,6 +155,16 @@
with Transaction().start(database_name, user,
@@ -190,6 +192,16 @@
with Transaction().start(pool.database_name, user,
readonly=rpc.readonly) as transaction:
Cache.clean(database_name)
Cache.clean(pool.database_name)
+ action_id = top.add({
+ 'host': host,
+ 'port': port,
+ 'protocol': protocol,
+ 'database_name': database_name,
+ 'host': request.host,
+ 'port': '',
+ 'protocol': '',
+ 'database_name': pool.database_name,
+ 'user': user,
+ 'object_name': object_name,
+ 'object_name': obj.__name__,
+ 'method': method,
+ 'args': repr(args)[:30],
+ })
try:
c_args, c_kwargs, transaction.context, transaction.timestamp \
= rpc.convert(obj, *args, **kwargs)
@@ -182,6 +194,8 @@
logger.error(exception_message, exc_info=sys.exc_info())
transaction.cursor.rollback()
@@ -217,6 +229,8 @@
except Exception:
logger.error(log_message, *log_args, exc_info=True)
raise
+ finally:
+ top.remove(action_id)
Cache.resets(database_name)
with Transaction().start(database_name, 0) as transaction:
pool = Pool(database_name)
Cache.resets(pool.database_name)
if request.authorization.type == 'session':
try:
diff -r 649b0805fa93 trytond/protocols/top.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/trytond/trytond/protocols/top.py Sun Apr 19 03:18:20 2015 +0200
@@ -0,0 +1,89 @@
@@ -0,0 +1,90 @@
+import random
+import signal
+import locale
+import sys
+import faulthandler
+from operator import itemgetter
+from datetime import datetime
+
@ -89,7 +89,7 @@ diff -r 649b0805fa93 trytond/protocols/top.py
+ print
+
+# End Printing Tables
+
+
+def signal_user_handler(signal, frame):
+ print '-' * 30
+ if current_actions:
@ -99,7 +99,7 @@ diff -r 649b0805fa93 trytond/protocols/top.py
+ 'timestamp', 'elapsed', 'object_name', 'method', 'args')
+ table = []
+ table.append([x.upper() for x in header])
+
+
+ for action in sorted(current_actions.values(), key=itemgetter('timestamp')):
+ row = []
+ for key in header:
@ -112,8 +112,9 @@ diff -r 649b0805fa93 trytond/protocols/top.py
+ table.append(row)
+ pprint_table(table)
+ print '=' * 30
+
+
+signal.signal(signal.SIGUSR1, signal_user_handler)
+faulthandler.register(signal.SIGUSR2)
+
+
+def add(value):