[MERGE] Forward-port of latest saas-2 (incl. 7.0) bugfixes, up to rev. 9127 odo@openerp.com-20140212122042-3m2tysmr31mtecnc
bzr revid: odo@openerp.com-20140212175141-i9yz8zlseglrk8sb
This commit is contained in:
commit
bbd813e76e
|
@ -114,7 +114,7 @@ class account_invoice(osv.osv):
|
|||
#we check if the invoice is partially reconciled and if there are other invoices
|
||||
#involved in this partial reconciliation (and we sum these invoices)
|
||||
for line in aml.reconcile_partial_id.line_partial_ids:
|
||||
if line.invoice:
|
||||
if line.invoice and invoice.type == line.invoice.type:
|
||||
nb_inv_in_partial_rec += 1
|
||||
#store the max invoice id as for this invoice we will make a balance instead of a simple division
|
||||
max_invoice_id = max(max_invoice_id, line.invoice.id)
|
||||
|
|
|
@ -1453,7 +1453,7 @@
|
|||
<act_window
|
||||
id="act_account_move_to_account_move_line_open"
|
||||
name="Journal Items"
|
||||
context="{'search_default_journal_id': active_id, 'default_journal_id': active_id}"
|
||||
context="{'search_default_move_id': active_id, 'default_move_id': active_id}"
|
||||
res_model="account.move.line"
|
||||
src_model="account.move"/>
|
||||
|
||||
|
|
|
@ -664,13 +664,20 @@ class account_analytic_account(osv.osv):
|
|||
|
||||
partner_payment_term = contract.partner_id.property_payment_term and contract.partner_id.property_payment_term.id or False
|
||||
|
||||
currency_id = False
|
||||
if contract.pricelist_id:
|
||||
currency_id = contract.pricelist_id.currency_id.id
|
||||
elif contract.partner_id.property_product_pricelist:
|
||||
currency_id = contract.partner_id.property_product_pricelist.currency_id.id
|
||||
elif contract.company_id:
|
||||
currency_id = contract.company_id.currency_id.id
|
||||
|
||||
inv_data = {
|
||||
'reference': contract.code or False,
|
||||
'account_id': contract.partner_id.property_account_receivable.id,
|
||||
'type': 'out_invoice',
|
||||
'partner_id': contract.partner_id.id,
|
||||
'currency_id': contract.partner_id.property_product_pricelist.id or False,
|
||||
'currency_id': currency_id,
|
||||
'journal_id': len(journal_ids) and journal_ids[0] or False,
|
||||
'date_invoice': contract.recurring_next_date,
|
||||
'origin': contract.name,
|
||||
|
|
|
@ -1366,6 +1366,7 @@ class account_voucher(osv.osv):
|
|||
move_pool = self.pool.get('account.move')
|
||||
move_line_pool = self.pool.get('account.move.line')
|
||||
for voucher in self.browse(cr, uid, ids, context=context):
|
||||
local_context = dict(context, force_company=voucher.journal_id.company_id.id)
|
||||
if voucher.move_id:
|
||||
continue
|
||||
company_currency = self._get_company_currency(cr, uid, voucher.id, context)
|
||||
|
@ -1380,7 +1381,7 @@ class account_voucher(osv.osv):
|
|||
# Get the name of the account_move just created
|
||||
name = move_pool.browse(cr, uid, move_id, context=context).name
|
||||
# Create the first line of the voucher
|
||||
move_line_id = move_line_pool.create(cr, uid, self.first_move_line_get(cr,uid,voucher.id, move_id, company_currency, current_currency, context), context)
|
||||
move_line_id = move_line_pool.create(cr, uid, self.first_move_line_get(cr,uid,voucher.id, move_id, company_currency, current_currency, local_context), local_context)
|
||||
move_line_brw = move_line_pool.browse(cr, uid, move_line_id, context=context)
|
||||
line_total = move_line_brw.debit - move_line_brw.credit
|
||||
rec_list_ids = []
|
||||
|
@ -1392,9 +1393,9 @@ class account_voucher(osv.osv):
|
|||
line_total, rec_list_ids = self.voucher_move_line_create(cr, uid, voucher.id, line_total, move_id, company_currency, current_currency, context)
|
||||
|
||||
# Create the writeoff line if needed
|
||||
ml_writeoff = self.writeoff_move_line_get(cr, uid, voucher.id, line_total, move_id, name, company_currency, current_currency, context)
|
||||
ml_writeoff = self.writeoff_move_line_get(cr, uid, voucher.id, line_total, move_id, name, company_currency, current_currency, local_context)
|
||||
if ml_writeoff:
|
||||
move_line_pool.create(cr, uid, ml_writeoff, context)
|
||||
move_line_pool.create(cr, uid, ml_writeoff, local_context)
|
||||
# We post the voucher.
|
||||
self.write(cr, uid, [voucher.id], {
|
||||
'move_id': move_id,
|
||||
|
@ -1605,7 +1606,11 @@ class account_bank_statement(osv.osv):
|
|||
bank_st_line_obj = self.pool.get('account.bank.statement.line')
|
||||
st_line = bank_st_line_obj.browse(cr, uid, st_line_id, context=context)
|
||||
if st_line.voucher_id:
|
||||
voucher_obj.write(cr, uid, [st_line.voucher_id.id], {'number': next_number}, context=context)
|
||||
voucher_obj.write(cr, uid, [st_line.voucher_id.id],
|
||||
{'number': next_number,
|
||||
'date': st_line.date,
|
||||
'period_id': st_line.statement_id.period_id.id},
|
||||
context=context)
|
||||
if st_line.voucher_id.state == 'cancel':
|
||||
voucher_obj.action_cancel_draft(cr, uid, [st_line.voucher_id.id], context=context)
|
||||
voucher_obj.signal_proforma_voucher(cr, uid, [st_line.voucher_id.id])
|
||||
|
|
|
@ -94,7 +94,7 @@ class account_statement_from_invoice_lines(osv.osv_memory):
|
|||
'account_id': result['value'].get('account_id', statement.journal_id.default_credit_account_id.id),
|
||||
'company_id': statement.company_id.id,
|
||||
'currency_id': statement.currency.id,
|
||||
'date': line.date,
|
||||
'date': statement.date,
|
||||
'amount': sign*amount,
|
||||
'payment_rate': result['value']['payment_rate'],
|
||||
'payment_rate_currency_id': result['value']['payment_rate_currency_id'],
|
||||
|
@ -119,7 +119,7 @@ class account_statement_from_invoice_lines(osv.osv_memory):
|
|||
'statement_id': statement_id,
|
||||
'ref': line.ref,
|
||||
'voucher_id': voucher_id,
|
||||
'date': time.strftime('%Y-%m-%d'),
|
||||
'date': statement.date,
|
||||
}, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
|
|
@ -268,10 +268,14 @@ def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw):
|
|||
new_values = get_data(cr, uid_orig, pool, res_ids, model, method)
|
||||
elif method == 'read':
|
||||
res = fct_src(cr, uid_orig, model.model, method, *args, **kw)
|
||||
if isinstance(res, dict):
|
||||
records = [res]
|
||||
else:
|
||||
records = res
|
||||
# build the res_ids and the old_values dict. Here we don't use get_data() to
|
||||
# avoid performing an additional read()
|
||||
res_ids = []
|
||||
for record in res:
|
||||
for record in records:
|
||||
res_ids.append(record['id'])
|
||||
old_values[(model.id, record['id'])] = {'value': record, 'text': record}
|
||||
# log only the fields read
|
||||
|
@ -279,7 +283,9 @@ def log_fct(cr, uid_orig, model, method, fct_src, *args, **kw):
|
|||
elif method == 'unlink':
|
||||
res_ids = args[0]
|
||||
old_values = get_data(cr, uid_orig, pool, res_ids, model, method)
|
||||
res = fct_src(cr, uid_orig, model.model, method, *args, **kw)
|
||||
# process_data first as fct_src will unlink the record
|
||||
self.process_data(cr, uid_orig, pool, res_ids, model, method, old_values, new_values, field_list)
|
||||
return fct_src(cr, uid_orig, model.model, method, *args, **kw)
|
||||
else: # method is write, action or workflow action
|
||||
res_ids = []
|
||||
if args:
|
||||
|
@ -322,7 +328,7 @@ def get_data(cr, uid, pool, res_ids, model, method):
|
|||
data = {}
|
||||
resource_pool = pool[model.model]
|
||||
# read all the fields of the given resources in super admin mode
|
||||
for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids):
|
||||
for resource in resource_pool.read(cr, SUPERUSER_ID, res_ids, resource_pool._all_columns):
|
||||
values = {}
|
||||
values_text = {}
|
||||
resource_id = resource['id']
|
||||
|
@ -456,7 +462,9 @@ def process_data(cr, uid, pool, res_ids, model, method, old_values=None, new_val
|
|||
|
||||
# if at least one modification has been found
|
||||
for model_id, resource_id in lines:
|
||||
name = pool[model.model].name_get(cr, uid, [resource_id])[0][1]
|
||||
line_model = pool.get('ir.model').browse(cr, SUPERUSER_ID, model_id).model
|
||||
name = pool.get(line_model).name_get(cr, uid, [resource_id])[0][1]
|
||||
|
||||
vals = {
|
||||
'method': method,
|
||||
'object_id': model_id,
|
||||
|
|
|
@ -275,6 +275,13 @@ class base_action_rule(osv.osv):
|
|||
if action.filter_id:
|
||||
domain = eval(action.filter_id.domain)
|
||||
ctx.update(eval(action.filter_id.context))
|
||||
if 'lang' not in ctx:
|
||||
# Filters might be language-sensitive, attempt to reuse creator lang
|
||||
# as we are usually running this as super-user in background
|
||||
[filter_meta] = action.filter_id.perm_read()
|
||||
user_id = filter_meta['write_uid'] and filter_meta['write_uid'][0] or \
|
||||
filter_meta['create_uid'][0]
|
||||
ctx['lang'] = self.pool['res.users'].browse(cr, uid, user_id).lang
|
||||
record_ids = model.search(cr, uid, domain, context=ctx)
|
||||
|
||||
# determine when action should occur for the records
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
<h3>Body</h3>
|
||||
<field name="body_html" width="250" height="450"
|
||||
placeholder="Rich-text/HTML content of the message (placeholders may be used here)"/>
|
||||
<field name="attachment_ids" nolabel="1" widget="many2many_binary"/>
|
||||
<field name="attachment_ids" widget="many2many_binary"/>
|
||||
</page>
|
||||
<page string="Advanced Settings">
|
||||
<group>
|
||||
|
|
|
@ -369,10 +369,11 @@ class mail_thread(osv.AbstractModel):
|
|||
track_ctx = dict(context)
|
||||
if 'lang' not in track_ctx:
|
||||
track_ctx['lang'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).lang
|
||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
||||
if tracked_fields:
|
||||
initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
|
||||
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
|
||||
if not context.get('mail_notrack'):
|
||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=track_ctx)
|
||||
if tracked_fields:
|
||||
initial_values = {thread_id: dict((item, False) for item in tracked_fields)}
|
||||
self.message_track(cr, uid, [thread_id], tracked_fields, initial_values, context=track_ctx)
|
||||
return thread_id
|
||||
|
||||
def write(self, cr, uid, ids, values, context=None):
|
||||
|
@ -393,7 +394,11 @@ class mail_thread(osv.AbstractModel):
|
|||
result = super(mail_thread, self).write(cr, uid, ids, values, context=context)
|
||||
self.message_auto_subscribe(cr, uid, ids, values.keys(), context=context, values=values)
|
||||
|
||||
# Perform the tracking
|
||||
if not context.get('mail_notrack'):
|
||||
# Perform the tracking
|
||||
tracked_fields = self._get_tracked_fields(cr, uid, values.keys(), context=context)
|
||||
else:
|
||||
tracked_fields = None
|
||||
if tracked_fields:
|
||||
self.message_track(cr, uid, ids, tracked_fields, initial_values, context=track_ctx)
|
||||
return result
|
||||
|
@ -414,6 +419,9 @@ class mail_thread(osv.AbstractModel):
|
|||
return res
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
# avoid tracking multiple temporary changes during copy
|
||||
context = dict(context or {}, mail_notrack=True)
|
||||
|
||||
default = default or {}
|
||||
default['message_ids'] = []
|
||||
default['message_follower_ids'] = []
|
||||
|
@ -1549,18 +1557,23 @@ class mail_thread(osv.AbstractModel):
|
|||
""" Add partners to the records followers. """
|
||||
if context is None:
|
||||
context = {}
|
||||
# not necessary for computation, but saves an access right check
|
||||
if not partner_ids:
|
||||
return True
|
||||
|
||||
mail_followers_obj = self.pool.get('mail.followers')
|
||||
subtype_obj = self.pool.get('mail.message.subtype')
|
||||
|
||||
user_pid = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
if set(partner_ids) == set([user_pid]):
|
||||
if context.get('operation', '') != 'create':
|
||||
try:
|
||||
self.check_access_rights(cr, uid, 'read')
|
||||
try:
|
||||
self.check_access_rights(cr, uid, 'read')
|
||||
if context.get('operation', '') == 'create':
|
||||
self.check_access_rule(cr, uid, ids, 'create')
|
||||
else:
|
||||
self.check_access_rule(cr, uid, ids, 'read')
|
||||
except (osv.except_osv, orm.except_orm):
|
||||
return False
|
||||
except (osv.except_osv, orm.except_orm):
|
||||
return False
|
||||
else:
|
||||
self.check_access_rights(cr, uid, 'write')
|
||||
self.check_access_rule(cr, uid, ids, 'write')
|
||||
|
@ -1605,6 +1618,9 @@ class mail_thread(osv.AbstractModel):
|
|||
|
||||
def message_unsubscribe(self, cr, uid, ids, partner_ids, context=None):
|
||||
""" Remove partners from the records followers. """
|
||||
# not necessary for computation, but saves an access right check
|
||||
if not partner_ids:
|
||||
return True
|
||||
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
|
||||
if set(partner_ids) == set([user_pid]):
|
||||
self.check_access_rights(cr, uid, 'read')
|
||||
|
|
|
@ -197,6 +197,7 @@ openerp_mail_followers = function(session, mail) {
|
|||
// clean and display title
|
||||
var node_user_list = this.$('.oe_follower_list').empty();
|
||||
this.$('.oe_follower_title').html(this._format_followers(this.followers.length));
|
||||
self.message_is_follower = _.indexOf(this.followers.map(function (rec) { return rec[2]['is_uid']}), true) != -1;
|
||||
// truncate number of displayed followers
|
||||
var truncated = this.followers.slice(0, this.displayed_nb);
|
||||
_(truncated).each(function (record) {
|
||||
|
@ -207,9 +208,6 @@ openerp_mail_followers = function(session, mail) {
|
|||
'is_editable': record[2]['is_editable'],
|
||||
'avatar_url': mail.ChatterUtils.get_image(self.session, 'res.partner', 'image_small', record[0]),
|
||||
}
|
||||
if (partner.is_uid) {
|
||||
self.message_is_follower = partner.is_uid;
|
||||
}
|
||||
$(session.web.qweb.render('mail.followers.partner', {'record': partner, 'widget': self})).appendTo(node_user_list);
|
||||
// On mouse-enter it will show the edit_subtype pencil.
|
||||
if (partner.is_editable) {
|
||||
|
|
|
@ -135,14 +135,14 @@
|
|||
<t t-if="widget.is_private or (widget.user_pid != partner[0])">
|
||||
<t t-if="!widget.is_private and inc==0"> and </t>
|
||||
<span t-attf-class="oe_partner_follower #{inc>=3?'oe_hidden':''}"><t t-if="inc" t-raw="', '"/>
|
||||
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&id=#{partner[0]}"><t t-raw="partner[1]"/></a>
|
||||
<t t-if="!widget.options.show_link" t-raw="partner[1]"/>
|
||||
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&id=#{partner[0]}"><t t-esc="partner[1]"/></a>
|
||||
<t t-if="!widget.options.show_link" t-esc="partner[1]"/>
|
||||
</span>
|
||||
<t t-set="inc" t-value="inc+1"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="widget.partner_ids.length > 3">
|
||||
<span class="oe_more">, <a><t t-raw="widget.partner_ids.length - 3"/> others...</a></span>
|
||||
<span class="oe_more">, <a><t t-esc="widget.partner_ids.length - 3"/> others...</a></span>
|
||||
<a class="oe_more_hidden"><<<</a>
|
||||
</t>
|
||||
</div>
|
||||
|
@ -150,8 +150,8 @@
|
|||
<t t-foreach='widget.recipients' t-as='recipient'>
|
||||
<label t-attf-title="Add as recipient and follower (reason: #{recipient.reason})">
|
||||
<input type="checkbox" t-att-checked="recipient.checked ? 'checked' : undefined" t-att-data="recipient.full_name"/>
|
||||
<t t-raw="recipient.name"/>
|
||||
<t t-if="recipient.email_address">(<t t-raw="recipient.email_address"/>)</t>
|
||||
<t t-esc="recipient.name"/>
|
||||
<t t-if="recipient.email_address">(<t t-esc="recipient.email_address"/>)</t>
|
||||
<t t-if="!recipient.email_address">(no email address)</t>
|
||||
</label>
|
||||
</t>
|
||||
|
@ -177,7 +177,7 @@
|
|||
<td colspan="2">
|
||||
<h2 class="oe_view_title">
|
||||
<span class="oe_view_title_text">
|
||||
<t t-raw="widget.action.name"/>
|
||||
<t t-esc="widget.action.name"/>
|
||||
</span>
|
||||
</h2>
|
||||
<t t-if="widget.action.params.header_description">
|
||||
|
@ -263,11 +263,11 @@
|
|||
<div class="oe_msg_content">
|
||||
<h1 t-if="(widget.show_record_name or widget.subject) and !widget.thread_level" class="oe_msg_title">
|
||||
<a t-if="widget.options.show_link and widget.show_record_name" class="oe_mail_action_model" t-attf-href="#model=#{widget.model}&id=#{widget.res_id}">
|
||||
<t t-raw="widget.record_name"/>
|
||||
<t t-esc="widget.record_name"/>
|
||||
</a>
|
||||
<span t-if="!widget.options.show_link and widget.show_record_name"><t t-raw="widget.record_name"/></span>
|
||||
<span t-if="!widget.options.show_link and widget.show_record_name"><t t-esc="widget.record_name"/></span>
|
||||
<t t-if="widget.show_record_name and widget.subject">: </t>
|
||||
<t t-if="widget.subject" t-raw="widget.subject"/>
|
||||
<t t-if="widget.subject" t-esc="widget.subject"/>
|
||||
</h1>
|
||||
<div class="oe_msg_body">
|
||||
<t t-if="widget.body_short">
|
||||
|
@ -283,8 +283,8 @@
|
|||
<t t-if="widget.attachment_ids.length > 0">
|
||||
<div class="oe_msg_attachment_list"></div>
|
||||
</t>
|
||||
<a t-if="widget.author_id and widget.options.show_link and widget.author_id[0]" t-attf-href="#model=res.partner&id=#{widget.author_id[0]}"><t t-raw="widget.author_id[2]"/></a>
|
||||
<span t-if="widget.author_id and (!widget.options.show_link or !widget.author_id[0])"><t t-raw="widget.author_id[2]"/></span>
|
||||
<a t-if="widget.author_id and widget.options.show_link and widget.author_id[0]" t-attf-href="#model=res.partner&id=#{widget.author_id[0]}"><t t-esc="widget.author_id[2]"/></a>
|
||||
<span t-if="widget.author_id and (!widget.options.show_link or !widget.author_id[0])"><t t-esc="widget.author_id[2]"/></span>
|
||||
<t t-if="widget.type == 'notification'">
|
||||
updated document
|
||||
<t t-if="widget.partner_ids.length > 0">
|
||||
|
@ -303,20 +303,20 @@
|
|||
<t t-if="widget.type == 'notification' or ( (widget.type == 'email' or widget.type == 'comment') and (widget.subtype or widget.partner_ids.length > 0))"
|
||||
t-foreach="widget.partner_ids.slice(0, 3)" t-as="partner">
|
||||
<span t-attf-class="oe_partner_follower">
|
||||
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&id=#{partner[0]}"><t t-raw="partner[1]"/></a>
|
||||
<t t-if="!widget.options.show_link" t-raw="partner[1]"/>
|
||||
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&id=#{partner[0]}"><t t-esc="partner[1]"/></a>
|
||||
<t t-if="!widget.options.show_link" t-esc="partner[1]"/>
|
||||
</span>
|
||||
<t t-if="!partner_last">,</t>
|
||||
</t>
|
||||
<t t-if="widget.partner_ids.length > 3">
|
||||
<span t-att-title="widget.extra_partners_str">and <t t-raw="widget.extra_partners_nbr"/> more</span>
|
||||
<span t-att-title="widget.extra_partners_str">and <t t-esc="widget.extra_partners_nbr"/> more</span>
|
||||
</t>
|
||||
<t t-if="widget.type == 'notification' and widget.partner_ids.length > 0">
|
||||
notified
|
||||
</t>
|
||||
<span class='oe_subtle'>•</span>
|
||||
<span t-att-title="widget.date">
|
||||
<t t-if="widget.timerelative" t-raw="widget.timerelative"/>
|
||||
<t t-if="widget.timerelative" t-esc="widget.timerelative"/>
|
||||
<t t-if="!widget.timerelative" t-raw="widget.display_date"/>
|
||||
</span>
|
||||
<span t-if="!widget.options.readonly" class='oe_subtle'>•</span>
|
||||
|
@ -333,7 +333,7 @@
|
|||
<div class='oe_separator'></div>
|
||||
<a t-if="widget.nb_messages <= 0" class="oe_msg_fetch_more">show more message</a>
|
||||
<a t-if="widget.nb_messages === 1" class="oe_msg_fetch_more">show one more message</a>
|
||||
<a t-if="widget.nb_messages > 1" class="oe_msg_fetch_more">show <t t-raw="widget.nb_messages" /> more messages</a>
|
||||
<a t-if="widget.nb_messages > 1" class="oe_msg_fetch_more">show <t t-esc="widget.nb_messages" /> more messages</a>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
@ -353,7 +353,7 @@
|
|||
-->
|
||||
<span t-name="mail.thread.message.vote">
|
||||
<span class="oe_mail_vote_count" t-if='widget.vote_nb > 0'>
|
||||
<t t-raw='widget.vote_nb' />
|
||||
<t t-esc='widget.vote_nb' />
|
||||
<span class='oe_e'>8</span>
|
||||
</span>
|
||||
<a href='#' class="oe_msg_vote">
|
||||
|
|
|
@ -43,13 +43,13 @@
|
|||
<table class='oe_subtype'>
|
||||
<tr>
|
||||
<td width="10%"><input type="checkbox" t-att-checked="record.followed" t-att-id="'input_mail_followers_subtype_'+record.id" t-att-data-id="record.id" t-att-name="record.name" class="oe_msg_subtype_check"/></td>
|
||||
<td><label t-att-for="'input_mail_followers_subtype_'+record.id"><t t-raw="record.name"/></label></td>
|
||||
<td><label t-att-for="'input_mail_followers_subtype_'+record.id"><t t-esc="record.name"/></label></td>
|
||||
</tr>
|
||||
</table>
|
||||
</t>
|
||||
|
||||
<t t-name="mail.followers.show_more">
|
||||
<div class="oe_partner oe_show_more">And <t t-raw="number"/> more.</div>
|
||||
<div class="oe_partner oe_show_more">And <t t-esc="number"/> more.</div>
|
||||
</t>
|
||||
|
||||
</template>
|
||||
|
|
|
@ -130,7 +130,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
'wizard_id', 'attachment_id', 'Attachments'),
|
||||
'filter_id': fields.many2one('ir.filters', 'Filters'),
|
||||
}
|
||||
|
||||
#TODO change same_thread to False in trunk (Require view update)
|
||||
_defaults = {
|
||||
'composition_mode': 'comment',
|
||||
'body': lambda self, cr, uid, ctx={}: '',
|
||||
|
@ -268,6 +268,8 @@ class mail_compose_message(osv.TransientModel):
|
|||
'mail.message', 0,
|
||||
context=context)
|
||||
mail_values['attachment_ids'] = m2m_attachment_ids
|
||||
if not mail_values.get('reply_to'):
|
||||
mail_values['reply_to'] = mail_values['email_from']
|
||||
self.pool.get('mail.mail').create(cr, uid, mail_values, context=context)
|
||||
else:
|
||||
subtype = 'mail.mt_comment'
|
||||
|
@ -321,10 +323,10 @@ class mail_compose_message(osv.TransientModel):
|
|||
if email_dict.get('email_from'):
|
||||
mail_values['email_from'] = email_dict.pop('email_from')
|
||||
# replies redirection: mass mailing only
|
||||
if not wizard.same_thread:
|
||||
mail_values['reply_to'] = email_dict.pop('reply_to', None)
|
||||
else:
|
||||
if wizard.same_thread and wizard.post:
|
||||
email_dict.pop('reply_to', None)
|
||||
else:
|
||||
mail_values['reply_to'] = email_dict.pop('reply_to', None)
|
||||
mail_values.update(email_dict)
|
||||
# mass mailing without post: mail_mail values
|
||||
if mass_mail_mode and not wizard.post:
|
||||
|
|
|
@ -47,10 +47,10 @@
|
|||
<field name="notify"
|
||||
attrs="{'invisible':['|', ('post', '!=', True), ('composition_mode', '!=', 'mass_mail')]}"/>
|
||||
<field name="same_thread"
|
||||
attrs="{'invisible':[('composition_mode', '!=', 'mass_mail')]}"/>
|
||||
attrs="{'invisible':['|', ('composition_mode', '!=', 'mass_mail'), ('post', '=', False)]}"/>
|
||||
<field name="reply_to" placeholder="Email address te redirect replies..."
|
||||
attrs="{'invisible':['|', ('same_thread', '=', True), ('composition_mode', '!=', 'mass_mail')],
|
||||
'required':[('same_thread', '!=', True)]}"/>
|
||||
attrs="{'invisible':['|', '&', ('same_thread', '=', True), ('post', '=', True), ('composition_mode', '!=', 'mass_mail')],
|
||||
'required':['&', '|', ('post', '=', False), ('same_thread', '=', False), ('composition_mode', '=', 'mass_mail')]}"/>
|
||||
</group>
|
||||
<field name="body"/>
|
||||
<field name="attachment_ids" widget="many2many_binary" string="Attach a file"/>
|
||||
|
|
|
@ -48,6 +48,7 @@ class MailThread(osv.Model):
|
|||
if bounce_alias in email_to:
|
||||
bounce_match = tools.bounce_re.search(email_to)
|
||||
if bounce_match:
|
||||
bounced_model, bounced_thread_id = None, False
|
||||
bounced_mail_id = bounce_match.group(1)
|
||||
stat_ids = self.pool['mail.mail.statistics'].set_bounced(cr, uid, mail_mail_ids=[bounced_mail_id], context=context)
|
||||
for stat in self.pool['mail.mail.statistics'].browse(cr, uid, stat_ids, context=context):
|
||||
|
@ -55,7 +56,7 @@ class MailThread(osv.Model):
|
|||
bounced_thread_id = stat.res_id
|
||||
_logger.info('Routing mail from %s to %s with Message-Id %s: bounced mail from mail %s, model: %s, thread_id: %s',
|
||||
email_from, email_to, message_id, bounced_mail_id, bounced_model, bounced_thread_id)
|
||||
if bounced_model and bounced_model in self.pool and hasattr(self.pool[bounced_model], 'message_receive_bounce'):
|
||||
if bounced_model and bounced_model in self.pool and hasattr(self.pool[bounced_model], 'message_receive_bounce') and bounced_thread_id:
|
||||
self.pool[bounced_model].message_receive_bounce(cr, uid, [bounced_thread_id], mail_id=bounced_mail_id, context=context)
|
||||
return False
|
||||
|
||||
|
|
|
@ -111,9 +111,6 @@ class procurement_order(osv.osv):
|
|||
bom_result = production_obj.action_compute(cr, uid,
|
||||
[produce_id], properties=[x.id for x in procurement.property_ids])
|
||||
production_obj.signal_button_confirm(cr, uid, [produce_id])
|
||||
if res_id:
|
||||
move_obj.write(cr, uid, [res_id],
|
||||
{'location_id': procurement.location_id.id})
|
||||
self.production_order_create_note(cr, uid, ids, context=context)
|
||||
return res
|
||||
|
||||
|
|
|
@ -474,11 +474,12 @@ class pos_session(osv.osv):
|
|||
account_move_obj = self.pool.get('account.move')
|
||||
pos_order_obj = self.pool.get('pos.order')
|
||||
for session in self.browse(cr, uid, ids, context=context):
|
||||
local_context = dict(context or {}, force_company=session.config_id.journal_id.company_id.id)
|
||||
order_ids = [order.id for order in session.order_ids if order.state == 'paid']
|
||||
|
||||
move_id = account_move_obj.create(cr, uid, {'ref' : session.name, 'journal_id' : session.config_id.journal_id.id, }, context=context)
|
||||
move_id = account_move_obj.create(cr, uid, {'ref' : session.name, 'journal_id' : session.config_id.journal_id.id, }, context=local_context)
|
||||
|
||||
pos_order_obj._create_account_move_line(cr, uid, order_ids, session, move_id, context=context)
|
||||
pos_order_obj._create_account_move_line(cr, uid, order_ids, session, move_id, context=local_context)
|
||||
|
||||
for order in session.order_ids:
|
||||
if order.state not in ('paid', 'invoiced'):
|
||||
|
@ -948,22 +949,16 @@ class pos_order(osv.osv):
|
|||
# Tricky, via the workflow, we only have one id in the ids variable
|
||||
"""Create a account move line of order grouped by products or not."""
|
||||
account_move_obj = self.pool.get('account.move')
|
||||
account_move_line_obj = self.pool.get('account.move.line')
|
||||
account_period_obj = self.pool.get('account.period')
|
||||
account_tax_obj = self.pool.get('account.tax')
|
||||
user_proxy = self.pool.get('res.users')
|
||||
property_obj = self.pool.get('ir.property')
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
|
||||
period = account_period_obj.find(cr, uid, context=context)[0]
|
||||
|
||||
#session_ids = set(order.session_id for order in self.browse(cr, uid, ids, context=context))
|
||||
|
||||
if session and not all(session.id == order.session_id.id for order in self.browse(cr, uid, ids, context=context)):
|
||||
raise osv.except_osv(_('Error!'), _('Selected orders do not have the same session!'))
|
||||
|
||||
current_company = user_proxy.browse(cr, uid, uid, context=context).company_id
|
||||
|
||||
grouped_data = {}
|
||||
have_to_group_by = session and session.config_id.group_by or False
|
||||
|
||||
|
@ -983,7 +978,7 @@ class pos_order(osv.osv):
|
|||
if order.state != 'paid':
|
||||
continue
|
||||
|
||||
user_company = user_proxy.browse(cr, order.user_id.id, order.user_id.id).company_id
|
||||
current_company = order.sale_journal.company_id
|
||||
|
||||
group_tax = {}
|
||||
account_def = property_obj.get(cr, uid, 'property_account_receivable', 'res.partner', context=context)
|
||||
|
@ -1004,6 +999,7 @@ class pos_order(osv.osv):
|
|||
# if have_to_group_by:
|
||||
|
||||
sale_journal_id = order.sale_journal.id
|
||||
period = account_period_obj.find(cr, uid, context=dict(context or {}, company_id=current_company.id))[0]
|
||||
|
||||
# 'quantity': line.qty,
|
||||
# 'product_id': line.product_id.id,
|
||||
|
@ -1013,7 +1009,7 @@ class pos_order(osv.osv):
|
|||
'journal_id' : sale_journal_id,
|
||||
'period_id' : period,
|
||||
'move_id' : move_id,
|
||||
'company_id': user_company and user_company.id or False,
|
||||
'company_id': current_company.id,
|
||||
})
|
||||
|
||||
if data_type == 'product':
|
||||
|
@ -1054,7 +1050,10 @@ class pos_order(osv.osv):
|
|||
cur = order.pricelist_id.currency_id
|
||||
for line in order.lines:
|
||||
tax_amount = 0
|
||||
taxes = [t for t in line.product_id.taxes_id]
|
||||
taxes = []
|
||||
for t in line.product_id.taxes_id:
|
||||
if t.company_id.id == current_company.id:
|
||||
taxes.append(t)
|
||||
computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit * (100.0-line.discount) / 100.0, line.qty)['taxes']
|
||||
|
||||
for tax in computed_taxes:
|
||||
|
|
|
@ -99,13 +99,10 @@ class pos_details_summary(report_sxw.rml_parse):
|
|||
|
||||
def _get_tax_amount(self, objects):
|
||||
res = {}
|
||||
list_ids = []
|
||||
for order in objects:
|
||||
for line in order.lines:
|
||||
if len(line.product_id.taxes_id):
|
||||
tax = line.product_id.taxes_id[0]
|
||||
res[tax.name] = (line.price_unit * line.qty * (1-(line.discount or 0.0) / 100.0)) + (tax.id in list_ids and res[tax.name] or 0)
|
||||
list_ids.append(tax.id)
|
||||
for tax in line.product_id.taxes_id:
|
||||
res[tax.name] = res.setdefault(tax.name, 0.0) + (line.price_subtotal_incl - line.price_subtotal)
|
||||
return res
|
||||
|
||||
def _get_sales_total(self, objects):
|
||||
|
|
|
@ -232,7 +232,7 @@
|
|||
<blockTable colWidths="255.0,255.0" style="Table11">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="P2">[[ t[0] ]]</para>
|
||||
<para style="P2">[[ t[0].name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9_Bold">[[ formatLang(t[1], currency_obj=company.currency_id) ]]</para>
|
||||
|
|
|
@ -244,13 +244,15 @@ class product_pricelist(osv.osv):
|
|||
for seller in product.seller_ids:
|
||||
if (not partner) or (seller.name.id<>partner):
|
||||
continue
|
||||
product_default_uom = product.uom_id.id
|
||||
qty_in_seller_uom = qty
|
||||
from_uom = context.get('uom') or product.uom_id.id
|
||||
seller_uom = seller.product_uom and seller.product_uom.id or False
|
||||
if seller_uom and product_default_uom and product_default_uom != seller_uom:
|
||||
if seller_uom and from_uom and from_uom != seller_uom:
|
||||
qty_in_seller_uom = product_uom_obj._compute_qty(cr, uid, from_uom, qty, to_uom_id=seller_uom)
|
||||
else:
|
||||
uom_price_already_computed = True
|
||||
qty = product_uom_obj._compute_qty(cr, uid, product_default_uom, qty, to_uom_id=seller_uom)
|
||||
for line in seller.pricelist_ids:
|
||||
if line.min_quantity <= qty:
|
||||
if line.min_quantity <= qty_in_seller_uom:
|
||||
price = line.price
|
||||
|
||||
else:
|
||||
|
|
|
@ -358,6 +358,11 @@ class project(osv.osv):
|
|||
default['state'] = 'open'
|
||||
default['line_ids'] = []
|
||||
default['tasks'] = []
|
||||
|
||||
# Don't prepare (expensive) data to copy children (analytic accounts),
|
||||
# they are discarded in analytic.copy(), and handled in duplicate_template()
|
||||
default['child_ids'] = []
|
||||
|
||||
proj = self.browse(cr, uid, id, context=context)
|
||||
if not default.get('name', False):
|
||||
default.update(name=_("%s (copy)") % (proj.name))
|
||||
|
@ -690,23 +695,13 @@ class task(osv.osv):
|
|||
return {'value': vals}
|
||||
|
||||
def duplicate_task(self, cr, uid, map_ids, context=None):
|
||||
for new in map_ids.values():
|
||||
task = self.browse(cr, uid, new, context)
|
||||
child_ids = [ ch.id for ch in task.child_ids]
|
||||
if task.child_ids:
|
||||
for child in task.child_ids:
|
||||
if child.id in map_ids.keys():
|
||||
child_ids.remove(child.id)
|
||||
child_ids.append(map_ids[child.id])
|
||||
|
||||
parent_ids = [ ch.id for ch in task.parent_ids]
|
||||
if task.parent_ids:
|
||||
for parent in task.parent_ids:
|
||||
if parent.id in map_ids.keys():
|
||||
parent_ids.remove(parent.id)
|
||||
parent_ids.append(map_ids[parent.id])
|
||||
#FIXME why there is already the copy and the old one
|
||||
self.write(cr, uid, new, {'parent_ids':[(6,0,set(parent_ids))], 'child_ids':[(6,0, set(child_ids))]})
|
||||
mapper = lambda t: map_ids.get(t.id, t.id)
|
||||
for task in self.browse(cr, uid, map_ids.values(), context):
|
||||
new_child_ids = set(map(mapper, task.child_ids))
|
||||
new_parent_ids = set(map(mapper, task.parent_ids))
|
||||
if new_child_ids or new_parent_ids:
|
||||
task.write({'parent_ids': [(6,0,list(new_parent_ids))],
|
||||
'child_ids': [(6,0,list(new_child_ids))]})
|
||||
|
||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
|
|
|
@ -176,7 +176,7 @@
|
|||
<button name="invoice_ok" states="except_invoice" string="Manually Corrected"/>
|
||||
<button name="purchase_approve" states="confirmed" string="Approve Order" class="oe_highlight" groups="purchase.group_purchase_manager"/>
|
||||
<button name="view_picking" string="Receive Products" type="object" attrs="{'invisible': ['|', ('shipped','=',True), ('state','!=', 'approved')]}" class="oe_highlight"/>
|
||||
<button name="view_invoice" string="Receive Invoice" type="object" attrs="{'invisible': ['|', ('invoice_method','=','picking'), '|', ('state','!=', 'approved'), ('invoiced','=',True) ]}" class="oe_highlight"/>
|
||||
<button name="view_invoice" string="Receive Invoice" type="object" attrs="{'invisible': ['|', ('invoice_method','in', ['picking', 'manual']), '|', ('state','!=', 'approved'), ('invoiced','=',True) ]}" class="oe_highlight"/>
|
||||
<button name="action_cancel_draft" states="cancel,confirmed" string="Set to Draft" type="object" />
|
||||
<button name="purchase_cancel" states="draft,confirmed,sent" string="Cancel"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,approved,done" statusbar_colors='{"except_picking":"red","except_invoice":"red","confirmed":"blue"}' readonly="1"/>
|
||||
|
|
|
@ -77,9 +77,9 @@
|
|||
<button name="invoice_recreate" states="invoice_except" string="Recreate Invoice" groups="base.group_user"/>
|
||||
<button name="invoice_corrected" states="invoice_except" string="Ignore Exception" groups="base.group_user"/>
|
||||
<button name="action_quotation_send" string="Send by Email" type="object" states="draft" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="action_quotation_send" string="Send by Email" type="object" states="sent" groups="base.group_user"/>
|
||||
<button name="action_quotation_send" string="Send by Email" type="object" states="sent,progress,manual" groups="base.group_user"/>
|
||||
<button name="print_quotation" string="Print" type="object" states="draft" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="print_quotation" string="Print" type="object" states="sent" groups="base.group_user"/>
|
||||
<button name="print_quotation" string="Print" type="object" states="sent,progress,manual" groups="base.group_user"/>
|
||||
<button name="action_button_confirm" states="draft" string="Confirm Sale" type="object" groups="base.group_user"/>
|
||||
<button name="action_button_confirm" states="sent" string="Confirm Sale" class="oe_highlight" type="object" groups="base.group_user"/>
|
||||
<button name="action_view_invoice" string="View Invoice" type="object" class="oe_highlight"
|
||||
|
@ -90,7 +90,7 @@
|
|||
<button name="cancel" states="draft,sent" string="Cancel Quotation" groups="base.group_user"/>
|
||||
<button name="action_cancel" states="manual,progress" string="Cancel Order" type="object" groups="base.group_user"/>
|
||||
<button name="invoice_cancel" states="invoice_except" string="Cancel Order" groups="base.group_user"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,invoiced,done" statusbar_colors='{"invoice_except":"red","waiting_date":"blue"}'/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,progress,done" statusbar_colors='{"invoice_except":"red","waiting_date":"blue"}'/>
|
||||
</header>
|
||||
<sheet>
|
||||
<h1>
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
<xpath expr="//button[@name='action_cancel']" position="after">
|
||||
<button name="ship_cancel" states="shipping_except" string="Cancel Order"/>
|
||||
</xpath>
|
||||
<field name="state" position="replace">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,sent,progress,invoiced,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
|
||||
<field name="state" position="attributes">
|
||||
<attribute name="statusbar_colors">{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}</attribute>
|
||||
</field>
|
||||
<field name="company_id" position="replace">
|
||||
<field name="company_id" readonly="True"/>
|
||||
|
|
|
@ -379,8 +379,6 @@ class product_product(osv.osv):
|
|||
"In a context with a single Warehouse, this includes "
|
||||
"goods stored in the Stock Location of this Warehouse, or any "
|
||||
"of its children.\n"
|
||||
"stored in the Stock Location of the Warehouse of this Shop, "
|
||||
"or any of its children.\n"
|
||||
"Otherwise, this includes goods stored in any Stock Location "
|
||||
"with 'internal' type."),
|
||||
'incoming_qty': fields.function(_product_available, multi='qty_available',
|
||||
|
@ -392,9 +390,6 @@ class product_product(osv.osv):
|
|||
"In a context with a single Warehouse, this includes "
|
||||
"goods arriving to the Stock Location of this Warehouse, or "
|
||||
"any of its children.\n"
|
||||
"In a context with a single Shop, this includes goods "
|
||||
"arriving to the Stock Location of the Warehouse of this "
|
||||
"Shop, or any of its children.\n"
|
||||
"Otherwise, this includes goods arriving to any Stock "
|
||||
"Location with 'internal' type."),
|
||||
'outgoing_qty': fields.function(_product_available, multi='qty_available',
|
||||
|
@ -406,9 +401,6 @@ class product_product(osv.osv):
|
|||
"In a context with a single Warehouse, this includes "
|
||||
"goods leaving the Stock Location of this Warehouse, or "
|
||||
"any of its children.\n"
|
||||
"In a context with a single Shop, this includes goods "
|
||||
"leaving the Stock Location of the Warehouse of this "
|
||||
"Shop, or any of its children.\n"
|
||||
"Otherwise, this includes goods leaving any Stock "
|
||||
"Location with 'internal' type."),
|
||||
'track_production': fields.boolean('Track Manufacturing Lots', help="Forces to specify a Serial Number for all moves containing this product and generated by a Manufacturing Order"),
|
||||
|
|
Loading…
Reference in New Issue