[MERGE] forward port of fixes made in version 7
bzr revid: qdp-launchpad@openerp.com-20130214100628-0eaudbqhflpmjjyf
This commit is contained in:
commit
3fe67314cc
|
@ -39,6 +39,8 @@ class account_financial_report(osv.osv):
|
|||
_description = "Account Report"
|
||||
|
||||
def _get_level(self, cr, uid, ids, field_name, arg, context=None):
|
||||
'''Returns a dictionary with key=the ID of a record and value = the level of this
|
||||
record in the tree structure.'''
|
||||
res = {}
|
||||
for report in self.browse(cr, uid, ids, context=context):
|
||||
level = 0
|
||||
|
@ -48,6 +50,8 @@ class account_financial_report(osv.osv):
|
|||
return res
|
||||
|
||||
def _get_children_by_order(self, cr, uid, ids, context=None):
|
||||
'''returns a dictionary with the key= the ID of a record and value = all its children,
|
||||
computed recursively, and sorted by sequence. Ready for the printing'''
|
||||
res = []
|
||||
for id in ids:
|
||||
res.append(id)
|
||||
|
@ -56,6 +60,12 @@ class account_financial_report(osv.osv):
|
|||
return res
|
||||
|
||||
def _get_balance(self, cr, uid, ids, field_names, args, context=None):
|
||||
'''returns a dictionary with key=the ID of a record and value=the balance amount
|
||||
computed for this record. If the record is of type :
|
||||
'accounts' : it's the sum of the linked accounts
|
||||
'account_type' : it's the sum of leaf accoutns with such an account_type
|
||||
'account_report' : it's the amount of the related report
|
||||
'sum' : it's the sum of the children of this record (aka a 'view' record)'''
|
||||
account_obj = self.pool.get('account.account')
|
||||
res = {}
|
||||
for report in self.browse(cr, uid, ids, context=context):
|
||||
|
|
|
@ -1390,7 +1390,12 @@ class account_invoice_line(osv.osv):
|
|||
# XXX this gets the default account for the user's company,
|
||||
# it should get the default account for the invoice's company
|
||||
# however, the invoice's company does not reach this point
|
||||
prop = self.pool.get('ir.property').get(cr, uid, 'property_account_income_categ', 'product.category', context=context)
|
||||
if context is None:
|
||||
context = {}
|
||||
if context.get('type') in ('out_invoice','out_refund'):
|
||||
prop = self.pool.get('ir.property').get(cr, uid, 'property_account_income_categ', 'product.category', context=context)
|
||||
else:
|
||||
prop = self.pool.get('ir.property').get(cr, uid, 'property_account_expense_categ', 'product.category', context=context)
|
||||
return prop and prop.id or False
|
||||
|
||||
_defaults = {
|
||||
|
|
|
@ -151,12 +151,12 @@ class account_config_settings(osv.osv_memory):
|
|||
self.write(cr, uid, [id], vals, context)
|
||||
return id
|
||||
|
||||
def onchange_company_id(self, cr, uid, ids, company_id):
|
||||
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
|
||||
# update related fields
|
||||
values = {}
|
||||
values['currency_id'] = False
|
||||
if company_id:
|
||||
company = self.pool.get('res.company').browse(cr, uid, company_id)
|
||||
company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
|
||||
has_chart_of_accounts = company_id not in self.pool.get('account.installer').get_unconfigured_cmp(cr, uid)
|
||||
fiscalyear_count = self.pool.get('account.fiscalyear').search_count(cr, uid,
|
||||
[('date_start', '<=', time.strftime('%Y-%m-%d')), ('date_stop', '>=', time.strftime('%Y-%m-%d')),
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<label for="company_id" string="Select Company"/>
|
||||
<field name="company_id"
|
||||
widget="selection"
|
||||
on_change="onchange_company_id(company_id)"
|
||||
on_change="onchange_company_id(company_id, context)"
|
||||
class="oe_inline"/>
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -331,6 +331,9 @@ class account_asset_asset(osv.osv):
|
|||
depreciation_obj = self.pool.get('account.asset.depreciation.line')
|
||||
period = period_obj.browse(cr, uid, period_id, context=context)
|
||||
depreciation_ids = depreciation_obj.search(cr, uid, [('asset_id', 'in', ids), ('depreciation_date', '<=', period.date_stop), ('depreciation_date', '>=', period.date_start), ('move_check', '=', False)], context=context)
|
||||
if context is None:
|
||||
context = {}
|
||||
context.update({'depreciation_date':period.date_stop})
|
||||
return depreciation_obj.create_move(cr, uid, depreciation_ids, context=context)
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
|
@ -388,7 +391,7 @@ class account_asset_depreciation_line(osv.osv):
|
|||
created_move_ids = []
|
||||
asset_ids = []
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
depreciation_date = time.strftime('%Y-%m-%d')
|
||||
depreciation_date = context.get('depreciation_date') or time.strftime('%Y-%m-%d')
|
||||
period_ids = period_obj.find(cr, uid, depreciation_date, context=context)
|
||||
company_currency = line.asset_id.company_id.currency_id.id
|
||||
current_currency = line.asset_id.currency_id.id
|
||||
|
|
|
@ -238,7 +238,12 @@ class res_partner(osv.osv):
|
|||
from report import account_followup_print
|
||||
|
||||
assert len(ids) == 1
|
||||
if context is None:
|
||||
context = {}
|
||||
partner = self.browse(cr, uid, ids[0], context=context)
|
||||
#copy the context to not change global context. Overwrite it because _() looks for the lang in local variable 'context'.
|
||||
#Set the language to use = the partner language
|
||||
context = dict(context, lang=partner.lang)
|
||||
followup_table = ''
|
||||
if partner.unreconciled_aml_ids:
|
||||
company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
|
||||
|
@ -251,13 +256,14 @@ class res_partner(osv.osv):
|
|||
followup_table += '''
|
||||
<table border="2" width=100%%>
|
||||
<tr>
|
||||
<td>Invoice date</td>
|
||||
<td>Reference</td>
|
||||
<td>Due date</td>
|
||||
<td>Amount (%s)</td>
|
||||
<td>Lit.</td>
|
||||
<td>''' + _("Invoice Date") + '''</td>
|
||||
<td>''' + _("Description") + '''</td>
|
||||
<td>''' + _("Reference") + '''</td>
|
||||
<td>''' + _("Due Date") + '''</td>
|
||||
<td>''' + _("Amount") + " (%s)" % (currency.symbol) + '''</td>
|
||||
<td>''' + _("Lit.") + '''</td>
|
||||
</tr>
|
||||
''' % (currency.symbol)
|
||||
'''
|
||||
total = 0
|
||||
for aml in currency_dict['line']:
|
||||
block = aml['blocked'] and 'X' or ' '
|
||||
|
@ -268,13 +274,28 @@ class res_partner(osv.osv):
|
|||
if date <= current_date and aml['balance'] > 0:
|
||||
strbegin = "<TD><B>"
|
||||
strend = "</B></TD>"
|
||||
followup_table +="<TR>" + strbegin + str(aml['date']) + strend + strbegin + aml['ref'] + strend + strbegin + str(date) + strend + strbegin + str(aml['balance']) + strend + strbegin + block + strend + "</TR>"
|
||||
followup_table +="<TR>" + strbegin + str(aml['date']) + strend + strbegin + aml['name'] + strend + strbegin + aml['ref'] + strend + strbegin + str(date) + strend + strbegin + str(aml['balance']) + strend + strbegin + block + strend + "</TR>"
|
||||
total = rml_parse.formatLang(total, dp='Account', currency_obj=currency)
|
||||
followup_table += '''<tr> </tr>
|
||||
</table>
|
||||
<center>Amount due: %s </center>''' % (total)
|
||||
<center>''' + _("Amount due") + ''' : %s </center>''' % (total)
|
||||
return followup_table
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if vals.get("payment_responsible_id", False):
|
||||
for part in self.browse(cr, uid, ids, context=context):
|
||||
if part.payment_responsible_id <> vals["payment_responsible_id"]:
|
||||
#Find partner_id of user put as responsible
|
||||
responsible_partner_id = self.pool.get("res.users").browse(cr, uid, vals['payment_responsible_id'], context=context).partner_id.id
|
||||
self.pool.get("mail.thread").message_post(cr, uid, 0,
|
||||
body = _("You became responsible to do the next action for the payment follow-up of") + " <b><a href='#id=" + str(part.id) + "&view_type=form&model=res.partner'> " + part.name + " </a></b>",
|
||||
type = 'comment',
|
||||
subtype = "mail.mt_comment", context = context,
|
||||
model = 'res.partner', res_id = part.id,
|
||||
notified_partner_ids = [(6, 0, [responsible_partner_id])],
|
||||
partner_ids = [(6, 0, [responsible_partner_id])])
|
||||
return super(res_partner, self).write(cr, uid, ids, vals, context=context)
|
||||
|
||||
def action_done(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'payment_next_action_date': False, 'payment_next_action':'', 'payment_responsible_id': False}, context=context)
|
||||
|
||||
|
@ -408,13 +429,16 @@ class res_partner(osv.osv):
|
|||
_inherit = "res.partner"
|
||||
_columns = {
|
||||
'payment_responsible_id':fields.many2one('res.users', ondelete='set null', string='Follow-up Responsible',
|
||||
help="Optionally you can assign a user to this field, which will make him responsible for the action."),
|
||||
'payment_note':fields.text('Customer Payment Promise', help="Payment Note"),
|
||||
help="Optionally you can assign a user to this field, which will make him responsible for the action.",
|
||||
track_visibility="onchange"),
|
||||
'payment_note':fields.text('Customer Payment Promise', help="Payment Note", track_visibility="onchange"),
|
||||
'payment_next_action':fields.text('Next Action',
|
||||
help="This is the next action to be taken. It will automatically be set when the partner gets a follow-up level that requires a manual action. "),
|
||||
help="This is the next action to be taken. It will automatically be set when the partner gets a follow-up level that requires a manual action. ",
|
||||
track_visibility="onchange"),
|
||||
'payment_next_action_date':fields.date('Next Action Date',
|
||||
help="This is when the manual follow-up is needed. " \
|
||||
"The date will be set to the current date when the partner gets a follow-up level that requires a manual action. Can be practical to set manually e.g. to see if he keeps his promises."),
|
||||
"The date will be set to the current date when the partner gets a follow-up level that requires a manual action. "\
|
||||
"Can be practical to set manually e.g. to see if he keeps his promises."),
|
||||
'unreconciled_aml_ids':fields.one2many('account.move.line', 'partner_id', domain=['&', ('reconcile_id', '=', False), '&',
|
||||
('account_id.active','=', True), '&', ('account_id.type', '=', 'receivable'), ('state', '!=', 'draft')]),
|
||||
'latest_followup_date':fields.function(_get_latest, method=True, type='date', string="Latest Follow-up Date",
|
||||
|
|
|
@ -35,10 +35,10 @@
|
|||
<filter string="Follow-ups To Do" domain="[('payment_next_action_date', '<=', time.strftime('%%Y-%%m-%%d')), ('payment_amount_overdue', '>', 0.0)]" name="todo"/>
|
||||
<separator/>
|
||||
<filter string="No Responsible" domain="[('payment_responsible_id', '=', False)]"/>
|
||||
<filter string="My Follow-ups" domain="[('payment_responsible_id','=', uid)]"/>
|
||||
<filter string="My Follow-ups" domain="[('payment_responsible_id','=', uid)]" name="my"/>
|
||||
</group>
|
||||
<group expand="1" string="Group By...">
|
||||
<filter string="Responsible" context="{'group_by':'payment_responsible_id'}"/>
|
||||
<filter string="Follow-up Responsible" context="{'group_by':'payment_responsible_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -132,6 +132,18 @@
|
|||
<!-- Menus about followup of customers -->
|
||||
<menuitem id="account_followup_s" action="action_customer_followup"
|
||||
parent="menu_finance_followup" name="Do Manual Follow-Ups" sequence="3"/>
|
||||
|
||||
<record id="action_customer_my_followup" model="ir.actions.act_window">
|
||||
<field name="name">My Follow-Ups</field>
|
||||
<field name="view_id" ref="customer_followup_tree"/>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('payment_amount_due', '>', 0.0)]</field>
|
||||
<field name="context">{'Followupfirst':True, 'search_default_todo': True, 'search_default_my': True} </field>
|
||||
<field name="search_view_id" ref="customer_followup_search_view"/>
|
||||
</record>
|
||||
<menuitem id="base.menu_sales_followup" parent="base.menu_base_partner" name="Payment Follow-up" groups="account.group_account_invoice" sequence="2"/>
|
||||
<menuitem id="menu_sale_followup" parent="base.menu_sales_followup" sequence="10"
|
||||
action="action_customer_my_followup" groups="account.group_account_invoice"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -26,6 +26,8 @@ from openerp import tools
|
|||
from openerp.osv import fields, osv
|
||||
from openerp.tools.translate import _
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
class account_followup_stat_by_partner(osv.osv):
|
||||
_name = "account_followup.stat.by.partner"
|
||||
_description = "Follow-up Statistics by Partner"
|
||||
|
@ -127,7 +129,7 @@ class account_followup_print(osv.osv_memory):
|
|||
'email_body': fields.text('Email Body'),
|
||||
'summary': fields.text('Summary', readonly=True),
|
||||
'test_print': fields.boolean('Test Print',
|
||||
help='Check if you want to print follow-ups without changing follow-ups level.'),
|
||||
help='Check if you want to print follow-ups without changing follow-up level.'),
|
||||
}
|
||||
|
||||
def _get_followup(self, cr, uid, context=None):
|
||||
|
@ -204,7 +206,7 @@ class account_followup_print(osv.osv_memory):
|
|||
if not part.unreconciled_aml_ids:
|
||||
partners_to_clear.append(part.id)
|
||||
self.pool.get('res.partner').action_done(cr, uid, partners_to_clear, context=context)
|
||||
return len(ids)
|
||||
return len(partners_to_clear)
|
||||
|
||||
def do_process(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
|
@ -313,6 +315,13 @@ class account_followup_print(osv.osv_memory):
|
|||
if stat_line_id not in partner_list:
|
||||
partner_list.append(stat_line_id)
|
||||
to_update[str(id)]= {'level': fups[followup_line_id][1], 'partner_id': stat_line_id}
|
||||
#Remove partners that are other companies in OpenERP
|
||||
comp_obj = self.pool.get("res.company")
|
||||
comp_ids = comp_obj.search(cr, SUPERUSER_ID, [], context=context)
|
||||
for comp in comp_obj.browse(cr, SUPERUSER_ID, comp_ids, context=context):
|
||||
company_partner_wiz_id = comp.partner_id.id * 10000 + company_id
|
||||
if company_partner_wiz_id in partner_list:
|
||||
partner_list.remove(company_partner_wiz_id)
|
||||
return {'partner_ids': partner_list, 'to_update': to_update}
|
||||
|
||||
account_followup_print()
|
||||
|
|
|
@ -49,13 +49,25 @@ class account_config_settings(osv.osv_memory):
|
|||
'company_id', 'income_currency_exchange_account_id',
|
||||
type='many2one',
|
||||
relation='account.account',
|
||||
string="Gain Exchange Rate Account"),
|
||||
string="Gain Exchange Rate Account",
|
||||
domain="[('type', '=', 'other')]"),
|
||||
'expense_currency_exchange_account_id': fields.related(
|
||||
'company_id', 'expense_currency_exchange_account_id',
|
||||
type="many2one",
|
||||
relation='account.account',
|
||||
string="Loss Exchange Rate Account"),
|
||||
string="Loss Exchange Rate Account",
|
||||
domain="[('type', '=', 'other')]"),
|
||||
}
|
||||
def onchange_company_id(self, cr, uid, ids, company_id, context=None):
|
||||
res = super(account_config_settings, self).onchange_company_id(cr, uid, ids, company_id, context=context)
|
||||
if company_id:
|
||||
company = self.pool.get('res.company').browse(cr, uid, company_id, context=context)
|
||||
res['value'].update({'income_currency_exchange_account_id': company.income_currency_exchange_account_id and company.income_currency_exchange_account_id.id or False,
|
||||
'expense_currency_exchange_account_id': company.expense_currency_exchange_account_id and company.expense_currency_exchange_account_id.id or False})
|
||||
else:
|
||||
res['value'].update({'income_currency_exchange_account_id': False,
|
||||
'expense_currency_exchange_account_id': False})
|
||||
return res
|
||||
|
||||
class account_voucher(osv.osv):
|
||||
def _check_paid(self, cr, uid, ids, name, args, context=None):
|
||||
|
|
|
@ -307,8 +307,9 @@
|
|||
</group>
|
||||
<group>
|
||||
<field name="date" invisible="context.get('line_type', False)" on_change="onchange_date(date, currency_id, payment_rate_currency_id, amount, company_id, context)"/>
|
||||
<field name="period_id"/>
|
||||
<field name="reference" invisible="context.get('line_type', False)" string="Payment Ref" placeholder="e.g. 003/10"/>
|
||||
<field name="name" colspan="2" invisible="context.get('line_type', False)" placeholder="e.g. Invoice SAJ/0042"/>
|
||||
<field name="name" invisible="context.get('line_type', False)" placeholder="e.g. Invoice SAJ/0042"/>
|
||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
|
||||
<field name="account_id"
|
||||
|
|
|
@ -2,8 +2,10 @@ import functools
|
|||
import logging
|
||||
|
||||
import simplejson
|
||||
import werkzeug.utils
|
||||
from werkzeug.exceptions import BadRequest
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
import openerp.addons.web.http as oeweb
|
||||
from openerp.addons.web.controllers.main import db_monodb, set_cookie_and_redirect, login_and_redirect
|
||||
|
@ -69,6 +71,13 @@ class OAuthController(oeweb.Controller):
|
|||
# auth_signup is not installed
|
||||
_logger.error("auth_signup not installed on database %s: oauth sign up cancelled." % (dbname,))
|
||||
url = "/#action=login&oauth_error=1"
|
||||
except openerp.exceptions.AccessDenied:
|
||||
# oauth credentials not valid, user could be on a temporary session
|
||||
_logger.info('OAuth2: access denied, redirect to main page in case a valid session exists, without setting cookies')
|
||||
url = "/#action=login&oauth_error=3"
|
||||
redirect = werkzeug.utils.redirect(url, 303)
|
||||
redirect.autocorrect_location_header = False
|
||||
return redirect
|
||||
except Exception, e:
|
||||
# signup error
|
||||
_logger.exception("OAuth2: %s" % str(e))
|
||||
|
|
|
@ -36,6 +36,8 @@ class res_users(osv.Model):
|
|||
login = super(res_users, self)._auth_oauth_signin(cr, uid, provider, validation, params, context=context)
|
||||
|
||||
except openerp.exceptions.AccessDenied:
|
||||
if context and context.get('no_user_creation'):
|
||||
return None
|
||||
state = simplejson.loads(params['state'])
|
||||
token = state.get('t')
|
||||
oauth_uid = validation['user_id']
|
||||
|
|
|
@ -234,11 +234,12 @@
|
|||
<field name="arch" type="xml">
|
||||
<search string="Search Meetings">
|
||||
<field name="name" string="Meeting" filter_domain="[('name','ilike',self)]"/>
|
||||
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/>
|
||||
<field name="partner_ids"/>
|
||||
<field name="categ_ids"/>
|
||||
<field name="user_id"/>
|
||||
<separator/>
|
||||
<filter string="My Meetings" help="My Meetings" domain="[('user_id','=',uid)]"/>
|
||||
<field name="user_id"/>
|
||||
<field name="partner_ids"/>
|
||||
<filter string="Unread Messages" name="message_unread" domain="[('message_unread','=',True)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -567,7 +567,8 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
for opportunity in opportunities:
|
||||
subject.append(opportunity.name)
|
||||
title = "%s : %s" % (opportunity.type == 'opportunity' and _('Merged opportunity') or _('Merged lead'), opportunity.name)
|
||||
details.append(self._mail_body(cr, uid, opportunity, CRM_LEAD_FIELDS_TO_MERGE, title=title, context=context))
|
||||
fields = list(CRM_LEAD_FIELDS_TO_MERGE)
|
||||
details.append(self._mail_body(cr, uid, opportunity, fields, title=title, context=context))
|
||||
|
||||
# Chatter message's subject
|
||||
subject = subject[0] + ": " + ", ".join(subject[1:])
|
||||
|
@ -627,7 +628,10 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
opportunities = self.browse(cr, uid, ids, context=context)
|
||||
sequenced_opps = []
|
||||
for opportunity in opportunities:
|
||||
sequenced_opps.append((opportunity.stage_id and opportunity.stage_id.state != 'cancel' and opportunity.stage_id.sequence or 0, opportunity))
|
||||
if opportunity.stage_id and opportunity.stage_id.state != 'cancel':
|
||||
sequenced_opps.append((opportunity.stage_id.sequence, opportunity))
|
||||
else:
|
||||
sequenced_opps.append((-1, opportunity))
|
||||
sequenced_opps.sort(key=lambda tup: tup[0], reverse=True)
|
||||
opportunities = [opportunity for sequence, opportunity in sequenced_opps]
|
||||
ids = [opportunity.id for opportunity in opportunities]
|
||||
|
@ -636,7 +640,8 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
|
||||
tail_opportunities = opportunities_rest
|
||||
|
||||
merged_data = self._merge_data(cr, uid, ids, highest, CRM_LEAD_FIELDS_TO_MERGE, context=context)
|
||||
fields = list(CRM_LEAD_FIELDS_TO_MERGE)
|
||||
merged_data = self._merge_data(cr, uid, ids, highest, fields, context=context)
|
||||
|
||||
# Merge messages and attachements into the first opportunity
|
||||
self._merge_opportunity_history(cr, uid, highest.id, tail_opportunities, context=context)
|
||||
|
@ -651,7 +656,7 @@ class crm_lead(base_stage, format_address, osv.osv):
|
|||
section_stages = self.pool.get('crm.case.section').read(cr, uid, merged_data['section_id'], ['stage_ids'], context=context)
|
||||
if merged_data.get('stage_id') not in section_stages['stage_ids']:
|
||||
stages_sequences = self.pool.get('crm.case.stage').search(cr, uid, [('id','in',section_stages['stage_ids'])], order='sequence', limit=1, context=context)
|
||||
merged_data['stage_id'] = stages_sequences[0]
|
||||
merged_data['stage_id'] = stages_sequences and stages_sequences[0] or False
|
||||
# Write merged data into first opportunity
|
||||
self.write(cr, uid, [highest.id], merged_data, context=context)
|
||||
# Delete tail opportunities
|
||||
|
|
|
@ -327,6 +327,7 @@
|
|||
<field name="categ_ids" string="Category" filter_domain="[('categ_ids','ilike',self)]"/>
|
||||
<field name="section_id" context="{'invisible_section': False, 'default_section_id': self}"/>
|
||||
<field name="user_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="country_id" context="{'invisible_country': False}"/>
|
||||
<separator/>
|
||||
|
|
|
@ -58,11 +58,11 @@ class crm_lead2opportunity_partner(osv.osv_memory):
|
|||
|
||||
if partner_id:
|
||||
# Search for opportunities that have the same partner and that arent done or cancelled
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id)])
|
||||
ids = lead_obj.search(cr, uid, [('partner_id', '=', partner_id), ('state', '!=', 'done')])
|
||||
for id in ids:
|
||||
tomerge.add(id)
|
||||
if email:
|
||||
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0])])
|
||||
ids = lead_obj.search(cr, uid, [('email_from', 'ilike', email[0]), ('state', '!=', 'done')])
|
||||
for id in ids:
|
||||
tomerge.add(id)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -67,7 +67,7 @@
|
|||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="user_id"/>
|
||||
<field name="section_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
|
|
@ -62,5 +62,66 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_crm_lead_geo_assign_form" model="ir.ui.view">
|
||||
<field name="name">crm.lead.lead.geo_assign.inherit</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_form_view_leads"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//notebook/page[@string='Extra Info']" position="after">
|
||||
<page string="Assignation">
|
||||
<group name="partner_assign_group">
|
||||
<group string="Partner Assignation">
|
||||
<field name="partner_assigned_id" on_change="onchange_assign_id(partner_assigned_id)" domain="[('grade_id','<>',False)]"/>
|
||||
<label for="date_assign"/>
|
||||
<div>
|
||||
<field name="date_assign"/>
|
||||
<button string="Forward"
|
||||
attrs="{'invisible':[('partner_assigned_id','=',False)]}"
|
||||
name="%(crm_lead_forward_to_partner_act)d"
|
||||
icon="terp-mail-forward" type="action"
|
||||
context="{'default_composition_mode': 'forward', 'default_partner_ids': [partner_assigned_id]}"/>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Geo Assignation">
|
||||
<field name="partner_latitude"/>
|
||||
<field name="partner_longitude"/>
|
||||
<span/>
|
||||
<button string="Geo Assign" name="action_assign_partner" type="object" colspan="1"
|
||||
icon="gtk-apply"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_crm_lead_geo_assign_tree" model="ir.ui.view">
|
||||
<field name="name">crm.lead.lead.geo_assign.tree.inherit</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.crm_case_tree_view_leads"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="partner_id" position="after">
|
||||
<field name="partner_assigned_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="crm_lead_partner_filter">
|
||||
<field name="name">crm.lead.partner.filter.assigned</field>
|
||||
<field name="model">crm.lead</field>
|
||||
<field name="inherit_id" ref="crm.view_crm_case_leads_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter string="Team" position="after">
|
||||
<filter string="Assigned Partner" icon="terp-personal" domain="[]" context="{'group_by':'partner_assigned_id'}"/>
|
||||
</filter>
|
||||
|
||||
<field name="partner_id" position="after">
|
||||
<field name="partner_assigned_id"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import simplejson
|
||||
import urllib
|
||||
|
||||
import openerp.addons.web.http as openerpweb
|
||||
import openerp.addons.web.controllers.main as webmain
|
||||
|
@ -14,11 +15,15 @@ class EDI(openerpweb.Controller):
|
|||
modules_json = simplejson.dumps(modules)
|
||||
js = "\n ".join('<script type="text/javascript" src="%s"></script>' % i for i in webmain.manifest_list(req, modules_str, 'js'))
|
||||
css = "\n ".join('<link rel="stylesheet" href="%s">' % i for i in webmain.manifest_list(req, modules_str, 'css'))
|
||||
|
||||
# `url` may contain a full URL with a valid query string, we basically want to watch out for XML brackets and double-quotes
|
||||
safe_url = urllib.quote_plus(url,':/?&;=')
|
||||
|
||||
return webmain.html_template % {
|
||||
'js': js,
|
||||
'css': css,
|
||||
'modules': modules_json,
|
||||
'init': 's.edi.edi_import("%s");' % url,
|
||||
'init': 's.edi.edi_import("%s");' % safe_url,
|
||||
}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
|
|
|
@ -371,7 +371,6 @@ class hr_applicant(base_stage, osv.Model):
|
|||
update_vals = {}
|
||||
|
||||
update_vals.update({
|
||||
'description': msg.get('body'),
|
||||
'email_from': msg.get('from'),
|
||||
'email_cc': msg.get('cc'),
|
||||
})
|
||||
|
|
|
@ -187,6 +187,8 @@
|
|||
domain="[('date_action','<>',False)]" help="Filter and view on next actions and date"/>
|
||||
<field name="job_id"/>
|
||||
<field name="user_id"/>
|
||||
<separator/>
|
||||
<field name="categ_ids"/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Responsible" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Department" domain="[]" context="{'group_by':'department_id'}"/>
|
||||
|
|
|
@ -310,8 +310,8 @@ class mail_message(osv.Model):
|
|||
partner_tree = dict((partner[0], partner) for partner in partners)
|
||||
|
||||
# 2. Attachments as SUPERUSER, because could receive msg and attachments for doc uid cannot see
|
||||
attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname'], context=context)
|
||||
attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname']}) for attachment in attachments)
|
||||
attachments = ir_attachment_obj.read(cr, SUPERUSER_ID, list(attachment_ids), ['id', 'datas_fname', 'name'], context=context)
|
||||
attachments_tree = dict((attachment['id'], {'id': attachment['id'], 'filename': attachment['datas_fname'], 'name': attachment['name']}) for attachment in attachments)
|
||||
|
||||
# 3. Update message dictionaries
|
||||
for message_dict in messages:
|
||||
|
|
|
@ -773,7 +773,7 @@ class mail_thread(osv.AbstractModel):
|
|||
msg_dict['author_id'] = author_ids[0]
|
||||
else:
|
||||
msg_dict['email_from'] = message.get('from')
|
||||
partner_ids = self._message_find_partners(cr, uid, message, ['From', 'To', 'Cc'], context=context)
|
||||
partner_ids = self._message_find_partners(cr, uid, message, ['To', 'Cc'], context=context)
|
||||
msg_dict['partner_ids'] = [(4, partner_id) for partner_id in partner_ids]
|
||||
|
||||
if 'Date' in message:
|
||||
|
|
|
@ -104,8 +104,8 @@ openerp.mail = function (session) {
|
|||
// returns the file type of a file based on its extension
|
||||
// As it only looks at the extension it is quite approximative.
|
||||
filetype: function(url){
|
||||
url = url.filename || url;
|
||||
var tokens = (url+'').split('.');
|
||||
var url = url && url.filename || url;
|
||||
var tokens = typeof url == 'string' ? url.split('.') : [];
|
||||
if(tokens.length <= 1){
|
||||
return 'unknown';
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ class procurement_order(osv.osv):
|
|||
readonly=True, required=True, help="If you encode manually a Procurement, you probably want to use" \
|
||||
" a make to order method."),
|
||||
'note': fields.text('Note'),
|
||||
'message': fields.char('Latest error', help="Exception occurred while computing procurement orders."),
|
||||
'message': fields.text('Latest error', help="Exception occurred while computing procurement orders."),
|
||||
'state': fields.selection([
|
||||
('draft','Draft'),
|
||||
('cancel','Cancelled'),
|
||||
|
|
|
@ -875,7 +875,7 @@ class sale_order_line(osv.osv):
|
|||
date_order = time.strftime(DEFAULT_SERVER_DATE_FORMAT)
|
||||
|
||||
result = {}
|
||||
warning_msgs = {}
|
||||
warning_msgs = ''
|
||||
product_obj = product_obj.browse(cr, uid, product, context=context_partner)
|
||||
|
||||
uom2 = False
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
import base64
|
||||
import urllib2
|
||||
from urlparse import urlparse, urlunparse
|
||||
|
||||
import openerp
|
||||
from openerp.osv import fields, osv
|
||||
|
@ -30,11 +31,12 @@ class Binary(openerp.addons.web.http.Controller):
|
|||
|
||||
@openerp.addons.web.http.jsonrequest
|
||||
def url2binary(self, req, url):
|
||||
if not url.startswith("http"):
|
||||
raise Exception("Not allowed to load a file using this protocol")
|
||||
if url.count("?") > 0 or url.count("&") > 0 or url.count("=") > 0:
|
||||
raise Exception("Not allowed to use GET parameters")
|
||||
"""Used exclusively to load images from LinkedIn profiles, must not be used for anything else."""
|
||||
req.session.assert_valid(force=True)
|
||||
_scheme, _netloc, path, params, query, fragment = urlparse(url)
|
||||
# media.linkedin.com is the master domain for LinkedIn media (replicated to CDNs),
|
||||
# so forcing it should always work and prevents abusing this method to load arbitrary URLs
|
||||
url = urlunparse(('http', 'media.linkedin.com', path, params, query, fragment))
|
||||
bfile = urllib2.urlopen(url)
|
||||
return base64.b64encode(bfile.read())
|
||||
|
||||
|
|
Loading…
Reference in New Issue