merge from 8.0
This commit is contained in:
commit
e26623da01
|
@ -98,7 +98,7 @@ class account_invoice(models.Model):
|
|||
def _compute_reconciled(self):
|
||||
self.reconciled = self.test_paid()
|
||||
if not self.reconciled and self.state == 'paid':
|
||||
self.signal_open_test()
|
||||
self.signal_workflow('open_test')
|
||||
|
||||
@api.model
|
||||
def _get_reference_type(self):
|
||||
|
|
|
@ -104,7 +104,7 @@ class account_fiscal_position(osv.osv):
|
|||
|
||||
# partner manually set fiscal position always win
|
||||
if partner.property_account_position:
|
||||
return part.property_account_position.id
|
||||
return partner.property_account_position.id
|
||||
|
||||
# if no delivery use invocing
|
||||
if delivery_id:
|
||||
|
|
|
@ -98,6 +98,24 @@ class account_invoice_report(osv.osv):
|
|||
}
|
||||
_order = 'date desc'
|
||||
|
||||
_depends = {
|
||||
'account.invoice': [
|
||||
'account_id', 'amount_total', 'commercial_partner_id', 'company_id',
|
||||
'currency_id', 'date_due', 'date_invoice', 'fiscal_position',
|
||||
'journal_id', 'partner_bank_id', 'partner_id', 'payment_term',
|
||||
'period_id', 'residual', 'state', 'type', 'user_id',
|
||||
],
|
||||
'account.invoice.line': [
|
||||
'account_id', 'invoice_id', 'price_subtotal', 'product_id',
|
||||
'quantity', 'uos_id',
|
||||
],
|
||||
'product.product': ['product_tmpl_id'],
|
||||
'product.template': ['categ_id'],
|
||||
'product.uom': ['category_id', 'factor', 'name', 'uom_type'],
|
||||
'res.currency.rate': ['currency_id', 'name'],
|
||||
'res.partner': ['country_id'],
|
||||
}
|
||||
|
||||
def _select(self):
|
||||
select_str = """
|
||||
SELECT sub.id, sub.date, sub.product_id, sub.partner_id, sub.country_id,
|
||||
|
|
|
@ -804,6 +804,12 @@ class account_analytic_account_summary_user(osv.osv):
|
|||
'user': fields.many2one('res.users', 'User'),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'res.users': ['id'],
|
||||
'account.analytic.line': ['account_id', 'journal_id', 'unit_amount', 'user_id'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_user')
|
||||
cr.execute('''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS (
|
||||
|
@ -837,6 +843,11 @@ class account_analytic_account_summary_month(osv.osv):
|
|||
'month': fields.char('Month', size=32, readonly=True),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'account.analytic.line': ['account_id', 'date', 'journal_id', 'unit_amount'],
|
||||
'account.analytic.journal': ['type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
openerp.tools.sql.drop_view_if_exists(cr, 'account_analytic_analysis_summary_month')
|
||||
cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \
|
||||
|
|
|
@ -42,6 +42,14 @@ class account_followup_stat_by_partner(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'account.move.line': [
|
||||
'account_id', 'company_id', 'credit', 'date', 'debit',
|
||||
'followup_date', 'followup_line_id', 'partner_id', 'reconcile_id',
|
||||
],
|
||||
'account.account': ['active', 'type'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
tools.drop_view_if_exists(cr, 'account_followup_stat_by_partner')
|
||||
# Here we don't have other choice but to create a virtual ID based on the concatenation
|
||||
|
|
|
@ -24,6 +24,7 @@ import crm_segmentation
|
|||
import crm_lead
|
||||
import sales_team
|
||||
import calendar_event
|
||||
import ir_http
|
||||
import crm_phonecall
|
||||
import report
|
||||
import wizard
|
||||
|
|
|
@ -19,13 +19,8 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import calendar
|
||||
from datetime import date, datetime
|
||||
from dateutil import relativedelta
|
||||
|
||||
from openerp import tools
|
||||
from openerp.osv import fields
|
||||
from openerp.osv import osv
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.http import request
|
||||
|
||||
AVAILABLE_PRIORITIES = [
|
||||
('0', 'Very Low'),
|
||||
|
@ -35,8 +30,10 @@ AVAILABLE_PRIORITIES = [
|
|||
('4', 'Very High'),
|
||||
]
|
||||
|
||||
class crm_case_channel(osv.osv):
|
||||
_name = "crm.case.channel"
|
||||
|
||||
class crm_tracking_medium(osv.Model):
|
||||
# OLD crm.case.channel
|
||||
_name = "crm.tracking.medium"
|
||||
_description = "Channels"
|
||||
_order = 'name'
|
||||
_columns = {
|
||||
|
@ -47,6 +44,67 @@ class crm_case_channel(osv.osv):
|
|||
'active': lambda *a: 1,
|
||||
}
|
||||
|
||||
|
||||
class crm_tracking_campaign(osv.Model):
|
||||
# OLD crm.case.resource.type
|
||||
_name = "crm.tracking.campaign"
|
||||
_description = "Campaign"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Campaign Name', required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
|
||||
}
|
||||
|
||||
|
||||
class crm_tracking_source(osv.Model):
|
||||
_name = "crm.tracking.source"
|
||||
_description = "Source"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Source Name', required=True, translate=True),
|
||||
}
|
||||
|
||||
|
||||
class crm_tracking_mixin(osv.AbstractModel):
|
||||
"""Mixin class for objects which can be tracked by marketing. """
|
||||
_name = 'crm.tracking.mixin'
|
||||
|
||||
_columns = {
|
||||
'campaign_id': fields.many2one('crm.tracking.campaign', 'Campaign', # old domain ="['|',('section_id','=',section_id),('section_id','=',False)]"
|
||||
help="This is a name that helps you keep track of your different campaign efforts Example: Fall_Drive, Christmas_Special"),
|
||||
'source_id': fields.many2one('crm.tracking.source', 'Source', help="This is the source of the link Example: Search Engine, another domain, or name of email list"),
|
||||
'medium_id': fields.many2one('crm.tracking.medium', 'Channel', help="This is the method of delivery. EX: Postcard, Email, or Banner Ad"),
|
||||
}
|
||||
|
||||
def tracking_fields(self):
|
||||
return [('utm_campaign', 'campaign_id'), ('utm_source', 'source_id'), ('utm_medium', 'medium_id')]
|
||||
|
||||
def tracking_get_values(self, cr, uid, vals, context=None):
|
||||
for key, field in self.tracking_fields():
|
||||
column = self._all_columns[field].column
|
||||
value = vals.get(field) or (request and request.session.get(key)) # params.get sould be always in session by the dispatch from ir_http
|
||||
if column._type in ['many2one'] and isinstance(value, basestring): # if we receive a string for a many2one, we search / create the id
|
||||
if value:
|
||||
Model = self.pool[column._obj]
|
||||
rel_id = Model.name_search(cr, uid, value, context=context)
|
||||
if not rel_id:
|
||||
rel_id = Model.create(cr, uid, {'name': value}, context=context)
|
||||
vals[field] = rel_id
|
||||
# Here the code for other cases that many2one
|
||||
else:
|
||||
vals[field] = value
|
||||
return vals
|
||||
|
||||
def _get_default_track(self, cr, uid, field, context=None):
|
||||
return self.tracking_get_values(cr, uid, {}, context=context).get(field)
|
||||
|
||||
_defaults = {
|
||||
'source_id': lambda self, cr, uid, ctx: self._get_default_track(cr, uid, 'source_id', ctx),
|
||||
'campaign_id': lambda self, cr, uid, ctx: self._get_default_track(cr, uid, 'campaign_id', ctx),
|
||||
'medium_id': lambda self, cr, uid, ctx: self._get_default_track(cr, uid, 'medium_id', ctx),
|
||||
}
|
||||
|
||||
|
||||
class crm_case_stage(osv.osv):
|
||||
""" Model for case stages. This models the main stages of a document
|
||||
management flow. Main CRM objects (leads, opportunities, project
|
||||
|
@ -106,16 +164,6 @@ class crm_case_categ(osv.osv):
|
|||
'object_id' : _find_object_id
|
||||
}
|
||||
|
||||
class crm_case_resource_type(osv.osv):
|
||||
""" Resource Type of case """
|
||||
_name = "crm.case.resource.type"
|
||||
_description = "Campaign"
|
||||
_rec_name = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Campaign Name', required=True, translate=True),
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
|
||||
}
|
||||
|
||||
class crm_payment_mode(osv.osv):
|
||||
""" Payment Mode for Fund """
|
||||
_name = "crm.payment.mode"
|
||||
|
|
|
@ -13,18 +13,35 @@
|
|||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.channel" id="crm_case_channel_website">
|
||||
|
||||
<!-- Crm Source -->
|
||||
<record model="crm.tracking.source" id="crm_source_search_engine">
|
||||
<field name="name">Search engine</field>
|
||||
</record>
|
||||
<record model="crm.tracking.source" id="crm_source_mailing">
|
||||
<field name="name">Mailing Partner</field>
|
||||
</record>
|
||||
<record model="crm.tracking.source" id="crm_source_newsletter">
|
||||
<field name="name">Newsletter</field>
|
||||
</record>
|
||||
|
||||
<!-- Crm Medium -->
|
||||
<record model="crm.tracking.medium" id="crm_medium_website">
|
||||
<field name="name">Website</field>
|
||||
</record>
|
||||
<record model="crm.case.channel" id="crm_case_channel_phone">
|
||||
<record model="crm.tracking.medium" id="crm_medium_phone">
|
||||
<field name="name">Phone</field>
|
||||
</record>
|
||||
<record model="crm.case.channel" id="crm_case_channel_direct">
|
||||
<record model="crm.tracking.medium" id="crm_medium_direct">
|
||||
<field name="name">Direct</field>
|
||||
</record>
|
||||
<record model="crm.case.channel" id="crm_case_channel_email">
|
||||
<record model="crm.tracking.medium" id="crm_medium_email">
|
||||
<field name="name">Email</field>
|
||||
</record>
|
||||
<record model="crm.tracking.medium" id="crm_medium_banner">
|
||||
<field name="name">Banner Ad</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="crm.case.section" id="sales_team.section_sales_department">
|
||||
<field name="use_leads">True</field>
|
||||
|
|
|
@ -32,13 +32,14 @@ from openerp.tools.translate import _
|
|||
|
||||
CRM_LEAD_FIELDS_TO_MERGE = ['name',
|
||||
'partner_id',
|
||||
'channel_id',
|
||||
'campaign_id',
|
||||
'company_id',
|
||||
'country_id',
|
||||
'section_id',
|
||||
'state_id',
|
||||
'stage_id',
|
||||
'type_id',
|
||||
'medium_id',
|
||||
'source_id',
|
||||
'user_id',
|
||||
'title',
|
||||
'city',
|
||||
|
@ -67,7 +68,7 @@ class crm_lead(format_address, osv.osv):
|
|||
_name = "crm.lead"
|
||||
_description = "Lead/Opportunity"
|
||||
_order = "priority,date_action,id desc"
|
||||
_inherit = ['mail.thread', 'ir.needaction_mixin']
|
||||
_inherit = ['mail.thread', 'ir.needaction_mixin', 'crm.tracking.mixin']
|
||||
|
||||
_track = {
|
||||
'stage_id': {
|
||||
|
@ -214,9 +215,6 @@ class crm_lead(format_address, osv.osv):
|
|||
'write_date': fields.datetime('Update Date', readonly=True),
|
||||
'categ_ids': fields.many2many('crm.case.categ', 'crm_lead_category_rel', 'lead_id', 'category_id', 'Tags', \
|
||||
domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", help="Classify and analyze your lead/opportunity categories like: Training, Service"),
|
||||
'type_id': fields.many2one('crm.case.resource.type', 'Campaign', \
|
||||
domain="['|',('section_id','=',section_id),('section_id','=',False)]", help="From which campaign (seminar, marketing campaign, mass mailing, ...) did this contact come from?"),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel (mail, direct, phone, ...)"),
|
||||
'contact_name': fields.char('Contact Name', size=64),
|
||||
'partner_name': fields.char("Customer Name", size=64,help='The name of the future partner company that will be created while converting the lead into opportunity', select=1),
|
||||
'opt_out': fields.boolean('Opt-Out', oldname='optout',
|
||||
|
|
|
@ -68,39 +68,6 @@
|
|||
(4, ref('stage_lead7'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Crm campain -->
|
||||
<record model="crm.case.resource.type" id="type_lead1">
|
||||
<field name="name">Telesales</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead2">
|
||||
<field name="name">Email Campaign - Services</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead3">
|
||||
<field name="name">Email Campaign - Products</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead4">
|
||||
<field name="name">Twitter Ads</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead5">
|
||||
<field name="name">Google Adwords</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead6">
|
||||
<field name="name">Banner Ads</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead7">
|
||||
<field name="name">Television</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
<record model="crm.case.resource.type" id="type_lead8">
|
||||
<field name="name">Newsletter</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
|
||||
<!-- crm categories -->
|
||||
<record model="crm.case.categ" id="categ_oppor1">
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
<field name="city">Paris</field>
|
||||
<field name="zip">93190</field>
|
||||
<field name="phone">+33 1 25 54 45 69</field>
|
||||
<field name="type_id" ref="type_lead2"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor6])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_email"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -51,9 +49,7 @@ Could you please send me the details ?</field>
|
|||
<field name="function">Purchase Manager</field>
|
||||
<field name="country_id" ref="base.fr"/>
|
||||
<field name="city">Bordeaux</field>
|
||||
<field name="type_id" ref="type_lead7"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -80,9 +76,7 @@ Could you please send me the details ?</field>
|
|||
<field name="partner_id" ref=""/>
|
||||
<field name="country_id" ref="base.us"/>
|
||||
<field name="city">New-York</field>
|
||||
<field name="type_id" ref="type_lead5"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor4])]"/>
|
||||
<field name="channel_id" ref=""/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_1"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
|
@ -101,9 +95,7 @@ Could you please send me the details ?</field>
|
|||
<field name="partner_id" ref=""/>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Drury</field>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor5])]"/>
|
||||
<field name="channel_id" ref=""/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
|
@ -126,9 +118,7 @@ Could you please send me the details ?</field>
|
|||
<field name="city">Franklinville</field>
|
||||
<field name="zip">NJ 08322</field>
|
||||
<field name="phone">+1 813 494 5005</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_1"/>
|
||||
<field name="user_id" ref=""/>
|
||||
|
@ -153,9 +143,7 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="function">Consultant</field>
|
||||
<field name="country_id" ref="base.it"/>
|
||||
<field name="city">Roma</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor3,categ_oppor4])]"/>
|
||||
<field name="channel_id" ref=""/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref=""/>
|
||||
|
@ -171,9 +159,7 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="function">Journalist</field>
|
||||
<field name="country_id" ref="base.ua"/>
|
||||
<field name="city">Kiev</field>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor4])]"/>
|
||||
<field name="channel_id" ref=""/>
|
||||
<field name="priority">0</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -190,9 +176,7 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="function">Sales</field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Cambridge</field>
|
||||
<field name="type_id" ref="type_lead5"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor6,categ_oppor8])]"/>
|
||||
<field name="channel_id" ref=""/>
|
||||
<field name="priority">1</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -209,9 +193,7 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="function">Sales</field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Oxford</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_phone"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
|
@ -227,9 +209,7 @@ Contact: +1 813 494 5005</field>
|
|||
<field name="function">Medical illustrator</field>
|
||||
<field name="country_id" ref="base.es"/>
|
||||
<field name="city">Sevilla</field>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_email"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
|
@ -250,9 +230,7 @@ Andrew</field>
|
|||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="function">Functional Consultant</field>
|
||||
<field name="country_id" ref=""/>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_direct"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_1"/>
|
||||
<field name="user_id" ref=""/>
|
||||
|
@ -268,9 +246,7 @@ Andrew</field>
|
|||
<field name="partner_id" ref="base.res_partner_1"/>
|
||||
<field name="country_id" ref="base.cn"/>
|
||||
<field name="city">Shenzhen</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref=""/>
|
||||
|
@ -303,9 +279,7 @@ Andrew</field>
|
|||
<field name="street">1 rue Rockfeller</field>
|
||||
<field name="country_id" ref="base.at"/>
|
||||
<field name="city">Melbourne</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_email"/>
|
||||
<field name="priority">1</field>
|
||||
<field eval="time.strftime('%Y-%m-25')" name="date_deadline"/>
|
||||
<field eval="time.strftime('%Y-%m-12')" name="date_action"/>
|
||||
|
@ -328,9 +302,7 @@ Andrew</field>
|
|||
<field name="country_id" ref="base.be"/>
|
||||
<field name="city">Wavre</field>
|
||||
<field name="zip">1300</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">2</field>
|
||||
<field eval="time.strftime('%Y-%m-23')" name="date_deadline"/>
|
||||
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
|
||||
|
@ -350,7 +322,6 @@ Andrew</field>
|
|||
<field name="city">Wavre</field>
|
||||
<field name="email_from">virginie@agrolait.com</field>
|
||||
<field name="partner_id" ref="base.res_partner_2"/>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field eval="time.strftime('%Y-%m-12')" name="date_deadline"/>
|
||||
|
@ -377,7 +348,6 @@ Andrew</field>
|
|||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Liverpool</field>
|
||||
<field name="zip">L25 4RL</field>
|
||||
<field name="type_id" ref="type_lead5"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor5])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field eval="time.strftime('%Y-%m-28')" name="date_deadline"/>
|
||||
|
@ -401,9 +371,7 @@ Andrew</field>
|
|||
<field name="street">Rue des Palais 51, bte 33</field>
|
||||
<field name="country_id" ref="base.be"/>
|
||||
<field name="city">Brussels</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor3,categ_oppor4])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">1</field>
|
||||
<field eval="time.strftime('%Y-%m-8')" name="date_deadline"/>
|
||||
<field eval="time.strftime('%Y-%m-3')" name="date_action"/>
|
||||
|
@ -429,7 +397,6 @@ Andrew</field>
|
|||
<field name="street">3661 Station Street</field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="partner_id" ref="base.res_partner_4"/>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor4,categ_oppor6])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field eval="time.strftime('%Y-%m-13')" name="date_deadline"/>
|
||||
|
@ -456,7 +423,6 @@ Andrew</field>
|
|||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Liverpool</field>
|
||||
<field name="zip">L25 4RL</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor1])]"/>
|
||||
<field name="priority">1</field>
|
||||
<field eval="time.strftime('%Y-%m-10')" name="date_deadline"/>
|
||||
|
@ -476,7 +442,6 @@ Andrew</field>
|
|||
<field name="partner_name">Epic Technologies</field>
|
||||
<field name="email_from">john.b@tech.info</field>
|
||||
<field name="partner_id" ref="base.res_partner_5"/>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor4,categ_oppor8])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_1"/>
|
||||
|
@ -489,9 +454,7 @@ Andrew</field>
|
|||
<field name="name">“Resource Planning” project develpment</field>
|
||||
<field eval="350" name="planned_revenue"/>
|
||||
<field name="partner_id" ref="base.res_partner_7"/>
|
||||
<field name="type_id" ref="type_lead2"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_phone"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -507,9 +470,7 @@ Andrew</field>
|
|||
<field name="contact_name">Benjamin Flores</field>
|
||||
<field name="partner_name">Nebula Business</field>
|
||||
<field name="partner_id" ref="base.res_partner_17"/>
|
||||
<field name="type_id" ref="type_lead7"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor3])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_email"/>
|
||||
<field name="priority">1</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
|
@ -522,9 +483,7 @@ Andrew</field>
|
|||
<field eval="2000" name="planned_revenue"/>
|
||||
<field eval="80.0" name="probability"/>
|
||||
<field name="partner_id" ref="base.res_partner_18"/>
|
||||
<field name="type_id" ref="type_lead5"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor3])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_direct"/>
|
||||
<field name="priority">0</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
|
@ -540,9 +499,7 @@ Andrew</field>
|
|||
<field name="email_from">info@mycompany.net</field>
|
||||
<field name="country_id" ref="base.pe"/>
|
||||
<field name="city">Lima</field>
|
||||
<field name="type_id" ref="type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor7])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">0</field>
|
||||
<field eval="time.strftime('%Y-%m-6')" name="date_deadline"/>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
|
@ -564,7 +521,6 @@ Andrew</field>
|
|||
<field name="country_id" ref="base.ar"/>
|
||||
<field name="city">Buenos Aires</field>
|
||||
<field name="zip">B7313</field>
|
||||
<field name="type_id" ref="type_lead4"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor4])]"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="title_action">Conf call with technical service</field>
|
||||
|
@ -585,9 +541,7 @@ Andrew</field>
|
|||
<field name="country_id" ref="base.be"/>
|
||||
<field name="city">Wavre</field>
|
||||
<field name="zip">1300</field>
|
||||
<field name="type_id" ref="type_lead3"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [categ_oppor2])]"/>
|
||||
<field name="channel_id" ref="crm_case_channel_website"/>
|
||||
<field name="priority">2</field>
|
||||
<field eval="time.strftime('%Y-%m-23')" name="date_deadline"/>
|
||||
<field eval="time.strftime('%Y-%m-10')" name="date_action"/>
|
||||
|
|
|
@ -230,9 +230,9 @@
|
|||
<field name="partner_id" invisible="1"/>
|
||||
<field name="section_id" groups="base.group_multi_salesteams"/>
|
||||
<field name="probability" invisible="1"/>
|
||||
<field name="type_id" invisible="1"/>
|
||||
<field name="campaign_id" invisible="1"/>
|
||||
<field name="referred" invisible="1"/>
|
||||
<field name="channel_id" invisible="1"/>
|
||||
<field name="medium_id" invisible="1"/>
|
||||
<field name="message_unread" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -513,8 +513,9 @@
|
|||
<field name="country_id"/>
|
||||
<field name="date_action"/>
|
||||
<field name="title_action"/>
|
||||
<field name="channel_id" invisible="1"/>
|
||||
<field name="type_id" invisible="1"/>
|
||||
<field name="medium_id" invisible="1"/>
|
||||
<field name="campaign_id" invisible="1"/>
|
||||
<field name="source_id" invisible="1"/>
|
||||
<field name="stage_id"/>
|
||||
<field name="planned_revenue" sum="Expected Revenues"/>
|
||||
<field name="probability" avg="Avg. of Probability"/>
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
<menuitem id="base.next_id_64" name="Sales"
|
||||
parent="base.menu_reporting" sequence="1"/>
|
||||
|
||||
<!-- crm.case.channel -->
|
||||
<record id="crm_case_channel_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.case.channel.tree</field>
|
||||
<field name="model">crm.case.channel</field>
|
||||
<!-- crm.tracking.medium -->
|
||||
<record id="crm_tracking_medium_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.tracking.medium.tree</field>
|
||||
<field name="model">crm.tracking.medium</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Channels">
|
||||
<field name="name"/>
|
||||
|
@ -37,9 +37,9 @@
|
|||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_channel_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.case.channel.form</field>
|
||||
<field name="model">crm.case.channel</field>
|
||||
<record id="crm_tracking_medium_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.tracking.medium.form</field>
|
||||
<field name="model">crm.tracking.medium</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Channel">
|
||||
<group>
|
||||
|
@ -49,26 +49,66 @@
|
|||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_case_channel_action" model="ir.actions.act_window">
|
||||
<record id="crm_tracking_medium_action" model="ir.actions.act_window">
|
||||
<field name="name">Channels</field>
|
||||
<field name="res_model">crm.case.channel</field>
|
||||
<field name="res_model">crm.tracking.medium</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to define a new channel.
|
||||
</p><p>
|
||||
Use channels to track the soure of your leads and opportunities. Channels
|
||||
Use channels to track the type of source of your leads and opportunities. Channels
|
||||
are mostly used in reporting to analyse sales performance
|
||||
related to marketing efforts.
|
||||
</p><p>
|
||||
Some examples of channels: company website, phone call
|
||||
campaign, reseller, etc.
|
||||
campaign, reseller, banner, etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="crm_case_channel_action" id="menu_crm_case_channel" parent="base.menu_crm_config_lead" sequence="4" groups="base.group_no_one"/>
|
||||
<!-- crm.tracking.source -->
|
||||
<record id="crm_tracking_source_view_tree" model="ir.ui.view">
|
||||
<field name="name">crm.tracking.source.tree</field>
|
||||
<field name="model">crm.tracking.source</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Channels">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_tracking_source_view_form" model="ir.ui.view">
|
||||
<field name="name">crm.tracking.source.form</field>
|
||||
<field name="model">crm.tracking.source</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Channel">
|
||||
<group>
|
||||
<field name="name"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="crm_tracking_source_action" model="ir.actions.act_window">
|
||||
<field name="name">Source</field>
|
||||
<field name="res_model">crm.tracking.source</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to define a new source.
|
||||
</p><p>
|
||||
Use channels to track the source of your leads and opportunities. Channels
|
||||
are mostly used in reporting to analyse sales performance
|
||||
related to marketing efforts.
|
||||
</p><p>
|
||||
Some examples of channels: partner's website, google.com,
|
||||
email list name, etc.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="crm_tracking_source_action" id="menu_crm_tracking_source" parent="base.menu_crm_config_lead" sequence="4" groups="base.group_no_one"/>
|
||||
|
||||
<!-- CRM Stage Tree View -->
|
||||
|
||||
|
@ -155,9 +195,9 @@
|
|||
|
||||
<!-- Resource Type of case Tree View -->
|
||||
|
||||
<record model="ir.ui.view" id="crm_case_resource_type_tree">
|
||||
<field name="name">crm.case.resource.type.tree</field>
|
||||
<field name="model">crm.case.resource.type</field>
|
||||
<record model="ir.ui.view" id="crm_tracking_campaign_tree">
|
||||
<field name="name">crm.tracking.campaign.tree</field>
|
||||
<field name="model">crm.tracking.campaign</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Campaign">
|
||||
<field name="name"/>
|
||||
|
@ -168,9 +208,9 @@
|
|||
|
||||
<!-- Resource Type of case Form View -->
|
||||
|
||||
<record model="ir.ui.view" id="crm_case_resource_type_form">
|
||||
<field name="name">crm.case.resource.type.form</field>
|
||||
<field name="model">crm.case.resource.type</field>
|
||||
<record model="ir.ui.view" id="crm_tracking_campaign_form">
|
||||
<field name="name">crm.tracking.campaign.form</field>
|
||||
<field name="model">crm.tracking.campaign</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Campaign">
|
||||
<group>
|
||||
|
@ -183,15 +223,15 @@
|
|||
|
||||
<!-- Resource Type of case Action -->
|
||||
|
||||
<record id="crm_case_resource_type_act" model="ir.actions.act_window">
|
||||
<record id="crm_tracking_campaign_act" model="ir.actions.act_window">
|
||||
<field name="name">Campaigns</field>
|
||||
<field name="res_model">crm.case.resource.type</field>
|
||||
<field name="res_model">crm.tracking.campaign</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="crm_case_resource_type_tree"/>
|
||||
<field name="view_id" ref="crm_tracking_campaign_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem action="crm_case_resource_type_act"
|
||||
id="menu_crm_case_resource_type_act" sequence="4"
|
||||
<menuitem action="crm_tracking_campaign_act"
|
||||
id="menu_crm_tracking_campaign_act" sequence="4"
|
||||
groups="base.group_no_one"
|
||||
parent="base.menu_crm_config_lead"/>
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from openerp.http import request
|
||||
from openerp.osv import orm
|
||||
|
||||
|
||||
class ir_http(orm.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
def _dispatch(self):
|
||||
for var, dummy in self.pool['crm.tracking.mixin'].tracking_fields():
|
||||
if var in request.params and (var not in request.session or request.session[var] != request.params[var]):
|
||||
request.session[var] = request.params[var]
|
||||
return super(ir_http, self)._dispatch()
|
|
@ -44,6 +44,7 @@ class crm_lead_report(osv.osv):
|
|||
_auto = False
|
||||
_description = "CRM Lead Analysis"
|
||||
_rec_name = 'date_deadline'
|
||||
_inherit = ["crm.tracking.mixin"]
|
||||
|
||||
_columns = {
|
||||
'date_deadline': fields.date('Exp. Closing', readonly=True, help="Expected Closing"),
|
||||
|
@ -58,10 +59,8 @@ class crm_lead_report(osv.osv):
|
|||
'delay_expected': fields.float('Overpassed Deadline',digits=(16,2),readonly=True, group_operator="avg"),
|
||||
|
||||
'user_id':fields.many2one('res.users', 'User', readonly=True),
|
||||
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
|
||||
'country_id':fields.many2one('res.country', 'Country', readonly=True),
|
||||
'section_id':fields.many2one('crm.case.section', 'Sales Team', readonly=True),
|
||||
'channel_id':fields.many2one('crm.case.channel', 'Channel', readonly=True),
|
||||
'type_id':fields.many2one('crm.case.resource.type', 'Campaign', readonly=True),
|
||||
'company_id': fields.many2one('res.company', 'Company', readonly=True),
|
||||
'probability': fields.float('Probability',digits=(16,2),readonly=True, group_operator="avg"),
|
||||
'planned_revenue': fields.float('Planned Revenue',digits=(16,2),readonly=True),
|
||||
|
@ -101,8 +100,9 @@ class crm_lead_report(osv.osv):
|
|||
c.company_id,
|
||||
c.priority,
|
||||
c.section_id,
|
||||
c.channel_id,
|
||||
c.type_id,
|
||||
c.campaign_id,
|
||||
c.source_id,
|
||||
c.medium_id,
|
||||
c.partner_id,
|
||||
c.country_id,
|
||||
c.planned_revenue,
|
||||
|
|
|
@ -74,13 +74,15 @@
|
|||
<group expand="0" string="Extended Filters">
|
||||
<field name="partner_id" filter_domain="[('partner_id','child_of',self)]"/>
|
||||
<field name="stage_id" domain="[('section_ids', '=', 'section_id')]" />
|
||||
<field name="type_id"/>
|
||||
<field name="channel_id"/>
|
||||
<field name="campaign_id"/>
|
||||
<field name="medium_id"/>
|
||||
<field name="source_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="stage_id" widget="selection" domain="[('section_ids', '=', 'section_id')]" />
|
||||
<field name="type_id" widget="selection"/>
|
||||
<field name="channel_id" widget="selection"/>
|
||||
<field name="campaign_id" widget="selection"/>
|
||||
<field name="medium_id" widget="selection"/>
|
||||
<field name="source_id" widget="selection"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
<newline/>
|
||||
|
|
|
@ -3,8 +3,10 @@ access_crm_segmentation_user,crm.segmentation user,model_crm_segmentation,base.g
|
|||
access_crm_segmentation_line_user,crm.segmentation.line user,model_crm_segmentation_line,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_segmentation,crm.segmentation,model_crm_segmentation,base.group_sale_manager,1,1,1,1
|
||||
access_crm_segmentation_line,crm.segmentation.line,model_crm_segmentation_line,base.group_sale_manager,1,1,1,1
|
||||
access_crm_case_channel_user,crm.case.channel user,model_crm_case_channel,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_case_channel_manager,crm.case.channel manager,model_crm_case_channel,base.group_sale_manager,1,1,1,1
|
||||
access_crm_tracking_medium_user,crm.tracking.medium user,model_crm_tracking_medium,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_tracking_medium_manager,crm.tracking.medium manager,model_crm_tracking_medium,base.group_sale_manager,1,1,1,1
|
||||
access_crm_tracking_source_user,crm.tracking.source user,model_crm_tracking_source,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_tracking_source_manager,crm.tracking.source manager,model_crm_tracking_source,base.group_sale_manager,1,1,1,1
|
||||
access_crm_case_categ,crm.case.categ,model_crm_case_categ,base.group_sale_salesman,1,1,1,0
|
||||
access_crm_lead_manager,crm.lead.manager,model_crm_lead,base.group_sale_manager,1,1,1,1
|
||||
access_crm_phonecall_manager,crm.phonecall.manager,model_crm_phonecall,base.group_sale_manager,1,1,1,1
|
||||
|
@ -13,8 +15,8 @@ access_crm_lead,crm.lead,model_crm_lead,base.group_sale_salesman,1,1,1,0
|
|||
access_crm_phonecall,crm.phonecall,model_crm_phonecall,base.group_sale_salesman,1,1,1,0
|
||||
access_crm_case_stage,crm.case.stage,model_crm_case_stage,,1,0,0,0
|
||||
access_crm_case_stage_manager,crm.case.stage,model_crm_case_stage,base.group_sale_manager,1,1,1,1
|
||||
access_crm_case_resource_type_user,crm_case_resource_type user,model_crm_case_resource_type,base.group_sale_salesman,1,1,1,0
|
||||
access_crm_case_resource_type_manager,crm_case_resource_type manager,model_crm_case_resource_type,base.group_sale_manager,1,1,1,1
|
||||
access_crm_tracking_campaign_user,crm_tracking_campaign user,model_crm_tracking_campaign,base.group_sale_salesman,1,1,1,0
|
||||
access_crm_tracking_campaign_manager,crm_tracking_campaign manager,model_crm_tracking_campaign,base.group_sale_manager,1,1,1,1
|
||||
access_crm_phonecall_report_user,crm.phonecall.report.user,model_crm_phonecall_report,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_phonecall_report_manager,crm.phonecall.report,model_crm_phonecall_report,base.group_sale_manager,1,1,1,1
|
||||
access_res_partner_manager,res.partner.crm.manager,base.model_res_partner,base.group_sale_manager,1,0,0,0
|
||||
|
@ -29,4 +31,4 @@ access_res_partner_bank_type_crm_user,res.partner.bank.type.crm.user,base.model_
|
|||
access_crm_lead_partner_manager,crm.lead.partner.manager,model_crm_lead,base.group_partner_manager,1,0,0,0
|
||||
access_crm_phonecall_partner_manager,crm.phonecall.partner.manager,model_crm_phonecall,base.group_partner_manager,1,1,1,1
|
||||
access_crm_payment_mode_user,crm.payment.mode,model_crm_payment_mode,base.group_sale_salesman,1,0,0,0
|
||||
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
|
||||
access_crm_payment_mode,crm.payment.mode,model_crm_payment_mode,base.group_sale_manager,1,1,1,1
|
|
|
@ -28,12 +28,12 @@
|
|||
Case Category2
|
||||
-->
|
||||
|
||||
<record model="crm.case.resource.type" id="type_claim1">
|
||||
<record model="crm.tracking.campaign" id="claim_source1">
|
||||
<field name="name">Corrective</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
|
||||
<record model="crm.case.resource.type" id="type_claim2">
|
||||
<record model="crm.tracking.campaign" id="claim_source2">
|
||||
<field name="name">Preventive</field>
|
||||
<field name="section_id" ref="sales_team.section_sales_department"/>
|
||||
</record>
|
||||
|
|
|
@ -56,7 +56,7 @@ class crm_helpdesk(osv.osv):
|
|||
'date': fields.datetime('Date'),
|
||||
'ref': fields.reference('Reference', selection=openerp.addons.base.res.res_request.referencable_models),
|
||||
'ref2': fields.reference('Reference 2', selection=openerp.addons.base.res.res_request.referencable_models),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel', help="Communication channel."),
|
||||
'channel_id': fields.many2one('crm.tracking.medium', 'Channel', help="Communication channel."),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'planned_cost': fields.float('Planned Costs'),
|
||||
'priority': fields.selection([('0','Low'), ('1','Normal'), ('2','High')], 'Priority'),
|
||||
|
|
|
@ -56,7 +56,7 @@ class crm_helpdesk_report(osv.osv):
|
|||
'date_deadline': fields.date('Deadline', select=True),
|
||||
'priority': fields.selection([('5', 'Lowest'), ('4', 'Low'), \
|
||||
('3', 'Normal'), ('2', 'High'), ('1', 'Highest')], 'Priority'),
|
||||
'channel_id': fields.many2one('crm.case.channel', 'Channel'),
|
||||
'channel_id': fields.many2one('crm.tracking.medium', 'Channel'),
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import mass_mailing
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
'name': 'Campaign in Mass Mailing',
|
||||
'version': '1.0',
|
||||
'summary': 'This module allow to specify a campaign, a source and a channel for a mass mailing campaign.',
|
||||
'author': 'OpenERP SA',
|
||||
'description': """
|
||||
Mass Mailing with Crm Marketing
|
||||
================================
|
||||
|
||||
Link module mass mailing with the marketing mixin from crm.
|
||||
""",
|
||||
'depends': ['crm', 'mass_mailing'],
|
||||
'data': [
|
||||
'mass_mailing.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': True,
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
from openerp.osv import osv
|
||||
|
||||
|
||||
class MassMailing(osv.Model):
|
||||
_name = 'mail.mass_mailing'
|
||||
_inherit = ['mail.mass_mailing', 'crm.tracking.mixin']
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="view_tracking_mass_mailing_form">
|
||||
<field name="name">mail.mass_mailing.inherit.form</field>
|
||||
<field name="model">mail.mass_mailing</field>
|
||||
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_form"/>
|
||||
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook/page[@string='Options']" position="after">
|
||||
<page string="Tracking">
|
||||
<group>
|
||||
<field name="campaign_id" />
|
||||
<field name="medium_id" />
|
||||
<field name="source_id" />
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
@ -12,9 +12,7 @@
|
|||
<field name="function">Reseller</field>
|
||||
<field name="country_id" ref="base.uk"/>
|
||||
<field name="city">Edinburgh</field>
|
||||
<field name="type_id" ref="crm.type_lead8"/>
|
||||
<field name="categ_ids" eval="[(6, 0, [ref('crm.categ_oppor1')])]"/>
|
||||
<field name="channel_id" ref="crm.crm_case_channel_email"/>
|
||||
<field name="priority">2</field>
|
||||
<field name="section_id" ref="sales_team.crm_case_section_2"/>
|
||||
<field name="user_id" ref=""/>
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
<field name="email_from"/>
|
||||
<field name="phone"/>
|
||||
<field name="stage_id" invisible="1"/>
|
||||
<field name="type_id" invisible="1"/>
|
||||
<field name="campaign_id" invisible="1"/>
|
||||
<field name="referred" invisible="1"/>
|
||||
<field name="channel_id" invisible="1"/>
|
||||
<field name="medium_id" invisible="1"/>
|
||||
<field name="section_id" invisible="context.get('invisible_section', True)" groups="base.group_multi_salesteams"/>
|
||||
|
||||
<button string="I'm interested" name="case_interested" icon="gtk-index" type="object"/>
|
||||
|
@ -80,8 +80,8 @@
|
|||
<field name="country_id" invisible="context.get('invisible_country', True)" />
|
||||
<field name="date_action"/>
|
||||
<field name="title_action" />
|
||||
<field name="channel_id" invisible="1"/>
|
||||
<field name="type_id" invisible="1"/>
|
||||
<field name="medium_id" invisible="1"/>
|
||||
<field name="campaign_id" invisible="1"/>
|
||||
<field name="planned_revenue" sum="Expected Revenues"/>
|
||||
<field name="probability" widget="progressbar" avg="Avg. of Probability"/>
|
||||
<field name="section_id" groups="base.group_multi_salesteams" invisible="context.get('invisible_section', True)" />
|
||||
|
@ -140,8 +140,8 @@
|
|||
</group>
|
||||
<group col="2">
|
||||
<separator string="Categorization" colspan="2"/>
|
||||
<field name="type_id" readonly="1"/>
|
||||
<field name="channel_id" readonly="1"/>
|
||||
<field name="campaign_id" readonly="1"/>
|
||||
<field name="medium_id" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Details" />
|
||||
|
|
|
@ -35,7 +35,7 @@ import base64
|
|||
from openerp import addons
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
from openerp import tools
|
||||
from openerp import tools, api
|
||||
from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
@ -129,6 +129,7 @@ openerp_mailgate: "|/path/to/openerp-mailgate.py --host=localhost -u %(uid)d -p
|
|||
self.write(cr, uid, ids , {'state':'draft'})
|
||||
return True
|
||||
|
||||
@api.cr_uid_ids_context
|
||||
def connect(self, cr, uid, server_id, context=None):
|
||||
if isinstance(server_id, (list,tuple)):
|
||||
server_id = server_id[0]
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
.oe_systray #oe_attendance_sign_in_out_icon {
|
||||
font-color: white;
|
||||
color: white;
|
||||
}
|
|
@ -59,6 +59,14 @@ class hr_evaluation_report(osv.Model):
|
|||
}
|
||||
_order = 'create_date desc'
|
||||
|
||||
_depends = {
|
||||
'hr.evaluation.interview': ['evaluation_id', 'id', 'request_id'],
|
||||
'hr_evaluation.evaluation': [
|
||||
'create_date', 'date', 'date_close', 'employee_id', 'plan_id',
|
||||
'rating', 'state',
|
||||
],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
tools.drop_view_if_exists(cr, 'hr_evaluation_report')
|
||||
cr.execute("""
|
||||
|
|
|
@ -532,6 +532,11 @@ class hr_timesheet_sheet_sheet_day(osv.osv):
|
|||
'total_attendance': fields.float('Attendance', readonly=True),
|
||||
'total_difference': fields.float('Difference', readonly=True),
|
||||
}
|
||||
_depends = {
|
||||
'account.analytic.line': ['date', 'unit_amount'],
|
||||
'hr.analytic.timesheet': ['line_id', 'sheet_id'],
|
||||
'hr.attendance': ['action', 'name', 'sheet_id'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
cr.execute("""create or replace view hr_timesheet_sheet_sheet_day as
|
||||
|
@ -602,6 +607,12 @@ class hr_timesheet_sheet_sheet_account(osv.osv):
|
|||
'invoice_rate': fields.many2one('hr_timesheet_invoice.factor', 'Invoice rate', readonly=True),
|
||||
}
|
||||
|
||||
_depends = {
|
||||
'account.analytic.line': ['account_id', 'date', 'to_invoice', 'unit_amount', 'user_id'],
|
||||
'hr.analytic.timesheet': ['line_id'],
|
||||
'hr_timesheet_sheet.sheet': ['date_from', 'date_to', 'user_id'],
|
||||
}
|
||||
|
||||
def init(self, cr):
|
||||
cr.execute("""create or replace view hr_timesheet_sheet_sheet_account as (
|
||||
select
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
/* button */
|
||||
.oe_systray #oe_topbar_imbutton_icon {
|
||||
color: white;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.oe_topbar_item.oe_topbar_imbutton .oe_e {
|
||||
position: relative;
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
<attribute name="groups"></attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='company_id']" position="after">
|
||||
<field name="type_id"/>
|
||||
<field name="channel_id" widget="selection"/>
|
||||
<field name="campaign_id" />
|
||||
<field name="medium_id"/>
|
||||
<field name="source_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -25,8 +26,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='mailings']" position="before">
|
||||
<group string="Marketing">
|
||||
<field name="type_id" />
|
||||
<field name="channel_id" widget="selection"/>
|
||||
<field name="campaign_id" />
|
||||
<field name="medium_id" />
|
||||
<field name="source_id" />
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
|
|
|
@ -144,7 +144,6 @@ class MassMailingCampaign(osv.Model):
|
|||
row['replied_ratio'] = 100.0 * row['replied'] / total
|
||||
return results
|
||||
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', required=True),
|
||||
'stage_id': fields.many2one('mail.mass_mailing.stage', 'Stage', required=True),
|
||||
|
@ -326,7 +325,6 @@ class MassMailing(osv.Model):
|
|||
row['replied_ratio'] = 100.0 * row['replied'] / total
|
||||
return results
|
||||
|
||||
|
||||
def _get_mailing_model(self, cr, uid, context=None):
|
||||
res = []
|
||||
for model_name in self.pool:
|
||||
|
|
|
@ -884,7 +884,7 @@ class mrp_production(osv.osv):
|
|||
production = self.browse(cr, uid, production_id, context=context)
|
||||
if not production.move_lines and production.state == 'ready':
|
||||
# trigger workflow if not products to consume (eg: services)
|
||||
self.signal_button_produce(cr, uid, [production_id])
|
||||
self.signal_workflow(cr, uid, [production_id], 'button_produce')
|
||||
|
||||
produced_qty = self._get_produced_qty(cr, uid, production, context=context)
|
||||
|
||||
|
@ -944,7 +944,7 @@ class mrp_production(osv.osv):
|
|||
stock_mov_obj.action_done(cr, uid, [extra_move_id], context=context)
|
||||
|
||||
self.message_post(cr, uid, production_id, body=_("%s produced") % self._description, context=context)
|
||||
self.signal_button_produce_done(cr, uid, [production_id])
|
||||
self.signal_workflow(cr, uid, [production_id], 'button_produce_done')
|
||||
return True
|
||||
|
||||
def _costs_generate(self, cr, uid, production):
|
||||
|
|
|
@ -114,7 +114,7 @@ class procurement_order(osv.osv):
|
|||
procurement.refresh()
|
||||
self.production_order_create_note(cr, uid, procurement, context=context)
|
||||
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])
|
||||
production_obj.signal_workflow(cr, uid, [produce_id], 'button_confirm')
|
||||
else:
|
||||
res[procurement.id] = False
|
||||
self.message_post(cr, uid, [procurement.id], body=_("No BoM exists for this product!"), context=context)
|
||||
|
|
|
@ -159,7 +159,7 @@ class StockMove(osv.osv):
|
|||
'consumed_for': consumed_for}, context=context)
|
||||
self.action_done(cr, uid, res, context=context)
|
||||
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
|
||||
production_obj.signal_button_produce(cr, uid, production_ids)
|
||||
production_obj.signal_workflow(cr, uid, production_ids, 'button_produce')
|
||||
for new_move in res:
|
||||
if new_move != move.id:
|
||||
#This move is not already there in move lines of production order
|
||||
|
@ -181,7 +181,7 @@ class StockMove(osv.osv):
|
|||
#If we are not scrapping our whole move, tracking and lot references must not be removed
|
||||
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
|
||||
for prod_id in production_ids:
|
||||
production_obj.signal_button_produce(cr, uid, [prod_id])
|
||||
production_obj.signal_workflow(cr, uid, [prod_id], 'button_produce')
|
||||
for new_move in new_moves:
|
||||
production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
|
||||
res.append(new_move)
|
||||
|
|
|
@ -497,7 +497,7 @@ class pos_session(osv.osv):
|
|||
_('Error!'),
|
||||
_("You cannot confirm all orders of this session, because they have not the 'paid' status"))
|
||||
else:
|
||||
pos_order_obj.signal_done(cr, uid, [order.id])
|
||||
pos_order_obj.signal_workflow(cr, uid, [order.id], 'done')
|
||||
|
||||
return True
|
||||
|
||||
|
@ -581,14 +581,14 @@ class pos_order(osv.osv):
|
|||
order_ids.append(order_id)
|
||||
|
||||
try:
|
||||
self.signal_paid(cr, uid, [order_id])
|
||||
self.signal_workflow(cr, uid, [order_id], 'paid')
|
||||
except Exception as e:
|
||||
_logger.error('Could not fully process the POS Order: %s', tools.ustr(e))
|
||||
|
||||
if to_invoice:
|
||||
self.action_invoice(cr, uid, [order_id], context)
|
||||
order_obj = self.browse(cr, uid, order_id, context)
|
||||
self.pool['account.invoice'].signal_invoice_open(cr, uid, [order_obj.invoice_id.id])
|
||||
self.pool['account.invoice'].signal_workflow(cr, uid, [order_obj.invoice_id.id], 'invoice_open')
|
||||
|
||||
return order_ids
|
||||
|
||||
|
@ -933,8 +933,8 @@ class pos_order(osv.osv):
|
|||
inv_line['invoice_line_tax_id'] = [(6, 0, [x.id for x in line.product_id.taxes_id] )]
|
||||
inv_line_ref.create(cr, uid, inv_line, context=context)
|
||||
inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context)
|
||||
self.signal_invoice(cr, uid, [order.id])
|
||||
inv_ref.signal_validate(cr, uid, [inv_id])
|
||||
self.signal_workflow(cr, uid, [order.id], 'invoice')
|
||||
inv_ref.signal_workflow(cr, uid, [inv_id], 'validate')
|
||||
|
||||
if not inv_ids: return {}
|
||||
|
||||
|
|
|
@ -328,7 +328,7 @@ class purchase_order(osv.osv):
|
|||
raise osv.except_osv(_('Invalid Action!'), _('In order to delete a purchase order, you must cancel it first.'))
|
||||
|
||||
# automatically sending subflow.delete upon deletion
|
||||
self.signal_purchase_cancel(cr, uid, unlink_ids)
|
||||
self.signal_workflow(cr, uid, unlink_ids, 'purchase_cancel')
|
||||
|
||||
return super(purchase_order, self).unlink(cr, uid, unlink_ids, context=context)
|
||||
|
||||
|
@ -519,7 +519,7 @@ class purchase_order(osv.osv):
|
|||
This function prints the request for quotation and mark it as sent, so that we can see more easily the next step of the workflow
|
||||
'''
|
||||
assert len(ids) == 1, 'This option should only be used for a single id at a time'
|
||||
self.signal_send_rfq(cr, uid, ids)
|
||||
self.signal_workflow(cr, uid, ids, 'send_rfq')
|
||||
return self.pool['report'].get_action(cr, uid, ids, 'purchase.report_purchasequotation', context=context)
|
||||
|
||||
def wkf_confirm_order(self, cr, uid, ids, context=None):
|
||||
|
@ -680,19 +680,19 @@ class purchase_order(osv.osv):
|
|||
_('Unable to cancel the purchase order %s.') % (purchase.name),
|
||||
_('First cancel all receptions related to this purchase order.'))
|
||||
self.pool.get('stock.picking') \
|
||||
.signal_button_cancel(cr, uid, map(attrgetter('id'), purchase.picking_ids))
|
||||
.signal_workflow(cr, uid, map(attrgetter('id'), purchase.picking_ids), 'button_cancel')
|
||||
for inv in purchase.invoice_ids:
|
||||
if inv and inv.state not in ('cancel', 'draft'):
|
||||
raise osv.except_osv(
|
||||
_('Unable to cancel this purchase order.'),
|
||||
_('You must first cancel all invoices related to this purchase order.'))
|
||||
self.pool.get('account.invoice') \
|
||||
.signal_invoice_cancel(cr, uid, map(attrgetter('id'), purchase.invoice_ids))
|
||||
.signal_workflow(cr, uid, map(attrgetter('id'), purchase.invoice_ids), 'invoice_cancel')
|
||||
self.pool['purchase.order.line'].write(cr, uid, [l.id for l in purchase.order_line],
|
||||
{'state': 'cancel'})
|
||||
self.write(cr, uid, ids, {'state': 'cancel'})
|
||||
self.set_order_line_status(cr, uid, ids, 'cancel', context=context)
|
||||
self.signal_purchase_cancel(cr, uid, ids)
|
||||
self.signal_workflow(cr, uid, ids, 'purchase_cancel')
|
||||
return True
|
||||
|
||||
def _prepare_order_line_move(self, cr, uid, order, order_line, picking_id, group_id, context=None):
|
||||
|
@ -933,7 +933,7 @@ class purchase_order(osv.osv):
|
|||
# make triggers pointing to the old orders point to the new order
|
||||
for old_id in old_ids:
|
||||
self.redirect_workflow(cr, uid, [(old_id, neworder_id)])
|
||||
self.signal_purchase_cancel(cr, uid, [old_id])
|
||||
self.signal_workflow(cr, uid, [old_id], 'purchase_cancel')
|
||||
|
||||
return orders_info
|
||||
|
||||
|
@ -1370,7 +1370,7 @@ class mail_mail(osv.Model):
|
|||
if mail_sent and mail.model == 'purchase.order':
|
||||
obj = self.pool.get('purchase.order').browse(cr, uid, mail.res_id, context=context)
|
||||
if obj.state == 'draft':
|
||||
self.pool.get('purchase.order').signal_send_rfq(cr, uid, [mail.res_id])
|
||||
self.pool.get('purchase.order').signal_workflow(cr, uid, [mail.res_id], 'send_rfq')
|
||||
return super(mail_mail, self)._postprocess_sent_message(cr, uid, mail=mail, context=context, mail_sent=mail_sent)
|
||||
|
||||
|
||||
|
@ -1423,7 +1423,7 @@ class mail_compose_message(osv.Model):
|
|||
context = context or {}
|
||||
if context.get('default_model') == 'purchase.order' and context.get('default_res_id'):
|
||||
context = dict(context, mail_post_autofollow=True)
|
||||
self.pool.get('purchase.order').signal_send_rfq(cr, uid, [context['default_res_id']])
|
||||
self.pool.get('purchase.order').signal_workflow(cr, uid, [context['default_res_id']], 'send_rfq')
|
||||
return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)
|
||||
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ class purchase_requisition(osv.osv):
|
|||
for quotation in tender.purchase_ids:
|
||||
if (self.check_valid_quotation(cr, uid, quotation, context=context)):
|
||||
#use workflow to set PO state to confirm
|
||||
po.signal_purchase_confirm(cr, uid, [quotation.id])
|
||||
po.signal_workflow(cr, uid, [quotation.id], 'purchase_confirm')
|
||||
|
||||
#get other confirmed lines per supplier
|
||||
for po_line in tender.po_line_ids:
|
||||
|
@ -268,13 +268,13 @@ class purchase_requisition(osv.osv):
|
|||
vals = self._prepare_po_line_from_tender(cr, uid, tender, line, new_po, context=context)
|
||||
poline.copy(cr, uid, line.id, default=vals, context=context)
|
||||
#use workflow to set new PO state to confirm
|
||||
po.signal_purchase_confirm(cr, uid, [new_po])
|
||||
po.signal_workflow(cr, uid, [new_po], 'purchase_confirm')
|
||||
|
||||
#cancel other orders
|
||||
self.cancel_unconfirmed_quotations(cr, uid, tender, context=context)
|
||||
|
||||
#set tender to state done
|
||||
self.signal_done(cr, uid, [tender.id])
|
||||
self.signal_workflow(cr, uid, [tender.id], 'done')
|
||||
return True
|
||||
|
||||
def cancel_unconfirmed_quotations(self, cr, uid, tender, context=None):
|
||||
|
@ -282,7 +282,7 @@ class purchase_requisition(osv.osv):
|
|||
po = self.pool.get('purchase.order')
|
||||
for quotation in tender.purchase_ids:
|
||||
if quotation.state in ['draft', 'sent', 'bid']:
|
||||
self.pool.get('purchase.order').signal_purchase_cancel(cr, uid, [quotation.id])
|
||||
self.pool.get('purchase.order').signal_workflow(cr, uid, [quotation.id], 'purchase_cancel')
|
||||
po.message_post(cr, uid, [quotation.id], body=_('Cancelled by the call for bids associated to this request for quotation.'), context=context)
|
||||
return True
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ class account_invoice_report(osv.osv):
|
|||
_columns = {
|
||||
'section_id': fields.many2one('crm.case.section', 'Sales Team'),
|
||||
}
|
||||
_depends = {
|
||||
'account.invoice': ['section_id'],
|
||||
}
|
||||
|
||||
def _select(self):
|
||||
return super(account_invoice_report, self)._select() + ", sub.section_id as section_id"
|
||||
|
|
|
@ -60,7 +60,7 @@ class sale_make_invoice(osv.osv_memory):
|
|||
for i in o.invoice_ids:
|
||||
newinv.append(i.id)
|
||||
# Dummy call to workflow, will not create another invoice but bind the new invoice to the subflow
|
||||
order_obj.signal_manual_invoice(cr, uid, [o.id for o in orders if o.order_policy == 'manual'])
|
||||
order_obj.signal_workflow(cr, uid, [o.id for o in orders if o.order_policy == 'manual'], 'manual_invoice')
|
||||
result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1')
|
||||
id = result and result[1] or False
|
||||
result = act_obj.read(cr, uid, [id], context=context)[0]
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
from openerp.osv import osv, fields
|
||||
|
||||
class sale_order(osv.osv):
|
||||
_inherit = 'sale.order'
|
||||
_name = "sale.order"
|
||||
_inherit = ['sale.order', 'crm.tracking.mixin']
|
||||
_columns = {
|
||||
'categ_ids': fields.many2many('crm.case.categ', 'sale_order_category_rel', 'order_id', 'category_id', 'Tags', \
|
||||
domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}")
|
||||
|
|
|
@ -29,6 +29,12 @@
|
|||
<field name="user_id" position="after">
|
||||
<field name="categ_ids" widget="many2many_tags"/>
|
||||
</field>
|
||||
<field name="origin" position="after">
|
||||
<field name="campaign_id" />
|
||||
<field name="medium_id" />
|
||||
<field name="source_id" />
|
||||
</field>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
|
|
|
@ -159,7 +159,7 @@ class sale_order(osv.osv):
|
|||
raise osv.except_osv(
|
||||
_('Cannot cancel sales order!'),
|
||||
_('You must first cancel all delivery order(s) attached to this sales order.'))
|
||||
stock_obj.signal_button_cancel(cr, uid, [p.id for p in sale.picking_ids])
|
||||
stock_obj.signal_workflow(cr, uid, [p.id for p in sale.picking_ids], 'button_cancel')
|
||||
return super(sale_order, self).action_cancel(cr, uid, ids, context=context)
|
||||
|
||||
def action_wait(self, cr, uid, ids, context=None):
|
||||
|
@ -356,7 +356,7 @@ class stock_move(osv.osv):
|
|||
if move.procurement_id and move.procurement_id.sale_line_id:
|
||||
sale_ids.append(move.procurement_id.sale_line_id.order_id.id)
|
||||
if sale_ids:
|
||||
self.pool.get('sale.order').signal_ship_except(cr, uid, sale_ids)
|
||||
self.pool.get('sale.order').signal_workflow(cr, uid, sale_ids, 'ship_except')
|
||||
return super(stock_move, self).action_cancel(cr, uid, ids, context=context)
|
||||
|
||||
def _create_invoice_line_from_vals(self, cr, uid, move, invoice_line_vals, context=None):
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
!python {model: sale.order}: |
|
||||
invoice_ids = self.browse(cr, uid, ref("sale.sale_order_8")).invoice_ids
|
||||
first_invoice_id = invoice_ids[0]
|
||||
self.pool.get('account.invoice').signal_invoice_cancel(cr, uid, [first_invoice_id.id])
|
||||
self.pool.get('account.invoice').signal_workflow(cr, uid, [first_invoice_id.id], 'invoice_cancel')
|
||||
-
|
||||
I check order status in "Invoice Exception" and related invoice is in cancel state.
|
||||
-
|
||||
|
|
|
@ -190,7 +190,7 @@
|
|||
so = self.browse(cr, uid, ref("sale_order_service"))
|
||||
account_invoice_obj = self.pool.get('account.invoice')
|
||||
for invoice in so.invoice_ids:
|
||||
account_invoice_obj.signal_invoice_open(cr, uid, [invoice.id])
|
||||
account_invoice_obj.signal_workflow(cr, uid, [invoice.id], 'invoice_open')
|
||||
-
|
||||
I pay the invoice
|
||||
-
|
||||
|
|
|
@ -77,7 +77,7 @@ class make_procurement(osv.osv_memory):
|
|||
'location_id': wh.lot_stock_id.id,
|
||||
'company_id': wh.company_id.id,
|
||||
})
|
||||
procurement_obj.signal_button_confirm(cr, uid, [procure_id])
|
||||
procurement_obj.signal_workflow(cr, uid, [procure_id], 'button_confirm')
|
||||
|
||||
id2 = data_obj._get_id(cr, uid, 'procurement', 'procurement_tree_view')
|
||||
id3 = data_obj._get_id(cr, uid, 'procurement', 'procurement_form_view')
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "EntypoRegular";
|
||||
src: url("/web/static/src/font/entypo-webfont.eot") format("eot");
|
||||
|
@ -19,7 +18,6 @@
|
|||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
#oe_main_menu_navbar {
|
||||
min-height: 34px;
|
||||
z-index: 1001;
|
||||
|
@ -39,6 +37,39 @@
|
|||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.oe_systray {
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
|
||||
.oe_notification {
|
||||
z-index: 1600;
|
||||
}
|
||||
|
||||
.oe_webclient_timezone_notification a {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.oe_webclient_timezone_notification p {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.oe_webclient_timezone_notification dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.oe_timezone_systray span {
|
||||
margin-top: 1px;
|
||||
background-color: #f6cf3b;
|
||||
}
|
||||
|
||||
.navbar .oe_topbar_name {
|
||||
max-width: 150px;
|
||||
display: inline-block;
|
||||
height: 15px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.openerp {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
@ -800,23 +831,6 @@
|
|||
border-bottom-right-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
}
|
||||
.openerp .oe_notification {
|
||||
z-index: 1500;
|
||||
}
|
||||
.openerp .oe_webclient_timezone_notification a {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.openerp .oe_webclient_timezone_notification p {
|
||||
margin-top: 1em;
|
||||
}
|
||||
.openerp .oe_webclient_timezone_notification dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
.openerp .oe_timezone_systray span {
|
||||
margin-top: 1px;
|
||||
background-color: #f6cf3b;
|
||||
}
|
||||
.openerp .oe_dialog_warning {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -847,133 +861,6 @@
|
|||
.openerp .oe_content_full_screen .oe_topbar, .openerp .oe_content_full_screen .oe_leftbar {
|
||||
display: none;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_anonymous_login {
|
||||
background-color: #dc5f59;
|
||||
color: #eeeeee;
|
||||
background-color: #be4343;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fc8787), to(maroon));
|
||||
background-image: -webkit-linear-gradient(top, #fc8787, maroon);
|
||||
background-image: -moz-linear-gradient(top, #fc8787, maroon);
|
||||
background-image: -ms-linear-gradient(top, #fc8787, maroon);
|
||||
background-image: -o-linear-gradient(top, #fc8787, maroon);
|
||||
background-image: linear-gradient(to bottom, #fc8787, #800000);
|
||||
}
|
||||
.openerp .navbar .oe_topbar_anonymous_login a {
|
||||
display: block;
|
||||
padding: 5px 10px 7px;
|
||||
line-height: 20px;
|
||||
height: 30px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
background: transparent;
|
||||
-webkit-transition: all 0.2s ease-out;
|
||||
-moz-transition: all 0.2s ease-out;
|
||||
-ms-transition: all 0.2s ease-out;
|
||||
-o-transition: all 0.2s ease-out;
|
||||
transition: all 0.2s ease-out;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_anonymous_login a:hover {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
color: white;
|
||||
text-shadow: 0px 0px 3px rgba(0, 0, 0, 0.2);
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2) inset;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_item {
|
||||
display: block;
|
||||
padding: 5px 10px 26px;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
text-decoration: none;
|
||||
color: #eeeeee;
|
||||
vertical-align: top;
|
||||
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-transition: all 0.2s ease-out;
|
||||
-moz-transition: all 0.2s ease-out;
|
||||
-ms-transition: all 0.2s ease-out;
|
||||
-o-transition: all 0.2s ease-out;
|
||||
transition: all 0.2s ease-out;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_item:hover {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
text-shadow: black 0px 0px 3px;
|
||||
color: white;
|
||||
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4) inset;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin: -2px 2px 0 0;
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_avatar {
|
||||
vertical-align: top;
|
||||
}
|
||||
.openerp .navbar .oe_dropdown_arrow:after {
|
||||
border-top: 4px solid white;
|
||||
}
|
||||
.openerp .navbar .dropdown_menu {
|
||||
top: 32px;
|
||||
background: #333333;
|
||||
background: rgba(37, 37, 37, 0.9);
|
||||
border-color: #999999;
|
||||
border-color: rgba(0, 0, 0, 0.2);
|
||||
border-style: solid;
|
||||
border-width: 0 2px 1px;
|
||||
-moz-border-radius: 0 0 6px 6px;
|
||||
-webkit-border-radius: 0 0 6px 6px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
-webkit-background-clip: padding-box;
|
||||
-moz-background-clip: padding-box;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
.openerp .navbar .dropdown_menu li {
|
||||
float: none;
|
||||
padding: 3px 12px;
|
||||
}
|
||||
.openerp .navbar .dropdown_menu li a {
|
||||
color: #eeeeee;
|
||||
}
|
||||
.openerp .navbar .dropdown_menu li:hover {
|
||||
background-color: #212121;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#292929), to(#191919));
|
||||
background-image: -webkit-linear-gradient(top, #292929, #191919);
|
||||
background-image: -moz-linear-gradient(top, #292929, #191919);
|
||||
background-image: -ms-linear-gradient(top, #292929, #191919);
|
||||
background-image: -o-linear-gradient(top, #292929, #191919);
|
||||
background-image: linear-gradient(to bottom, #292929, #191919);
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
.openerp .navbar .oe_topbar_name {
|
||||
max-width: 150px;
|
||||
display: inline-block;
|
||||
height: 15px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.openerp .nav li a {
|
||||
padding: 6px 8px 4px 8px;
|
||||
}
|
||||
.openerp .oe_user_menu {
|
||||
float: right;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.openerp .oe_user_menu li {
|
||||
list-style-type: none;
|
||||
float: left;
|
||||
}
|
||||
.openerp .oe_user_menu .oe_dropdown_menu {
|
||||
right: -1px;
|
||||
}
|
||||
.openerp .oe_leftbar {
|
||||
display: none;
|
||||
width: 220px;
|
||||
|
@ -3114,7 +3001,6 @@
|
|||
top: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.kitten-mode-activated {
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
|
|
|
@ -158,6 +158,37 @@ $sheet-padding: 16px
|
|||
#oe_main_menu_navbar.navbar
|
||||
margin-bottom: 0px
|
||||
|
||||
.oe_systray
|
||||
margin-right: 0px !important
|
||||
|
||||
// Notifications {{{
|
||||
.oe_notification
|
||||
z-index: 1600
|
||||
|
||||
.oe_webclient_timezone_notification
|
||||
a
|
||||
color: white
|
||||
text-decoration: underline
|
||||
p
|
||||
margin-top: 1em
|
||||
dt
|
||||
font-weight: bold
|
||||
.oe_timezone_systray
|
||||
span
|
||||
margin-top: 1px
|
||||
background-color: #f6cf3b
|
||||
// }}}
|
||||
// Top Menu {{{
|
||||
.navbar
|
||||
.oe_topbar_name
|
||||
max-width: 150px
|
||||
display: inline-block
|
||||
height: 15px // Customize to manage caret when topbar_name is over sized.
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
overflow: hidden // Customize to bring ellipsis when topbar_name is over sized.
|
||||
// }}}
|
||||
|
||||
.openerp
|
||||
// Global style {{{
|
||||
padding: 0
|
||||
|
@ -690,23 +721,6 @@ $sheet-padding: 16px
|
|||
border-bottom-right-radius: 8px
|
||||
border-bottom-left-radius: 8px
|
||||
// }}}
|
||||
// Notifications {{{
|
||||
.oe_notification
|
||||
z-index: 1500
|
||||
|
||||
.oe_webclient_timezone_notification
|
||||
a
|
||||
color: white
|
||||
text-decoration: underline
|
||||
p
|
||||
margin-top: 1em
|
||||
dt
|
||||
font-weight: bold
|
||||
.oe_timezone_systray
|
||||
span
|
||||
margin-top: 1px
|
||||
background-color: #f6cf3b
|
||||
// }}}
|
||||
// CrashManager {{{
|
||||
.oe_dialog_warning
|
||||
width: 100%
|
||||
|
@ -738,95 +752,6 @@ $sheet-padding: 16px
|
|||
.oe_topbar, .oe_leftbar
|
||||
display: none
|
||||
// }}}
|
||||
// Top Menu {{{
|
||||
.navbar
|
||||
.oe_topbar_anonymous_login
|
||||
background-color: #dc5f59
|
||||
color: #eeeeee
|
||||
@include vertical-gradient(#FC8787, #800000)
|
||||
a
|
||||
display: block
|
||||
padding: 5px 10px 7px
|
||||
line-height: 20px
|
||||
height: 30px
|
||||
text-decoration: none
|
||||
color: white
|
||||
background: transparent
|
||||
@include transition(all 0.2s ease-out)
|
||||
a:hover
|
||||
background: rgba(0,0,0,0.1)
|
||||
color: white
|
||||
text-shadow: 0px 0px 3px rgba(0,0,0,0.2)
|
||||
@include box-shadow(0 1px 2px rgba(0,0,0,0.2) inset)
|
||||
.oe_topbar_item
|
||||
display: block
|
||||
padding: 5px 10px 26px
|
||||
line-height: 20px
|
||||
height: 20px
|
||||
text-decoration: none
|
||||
color: #eee
|
||||
vertical-align: top
|
||||
text-shadow: 0 1px 1px rgba(0,0,0,0.2)
|
||||
@include transition(all 0.2s ease-out)
|
||||
&:hover
|
||||
background: rgba(0,0,0,0.2)
|
||||
text-shadow: black 0px 0px 3px
|
||||
color: white
|
||||
@include box-shadow(0 1px 2px rgba(0,0,0,0.4) inset)
|
||||
|
||||
.oe_topbar_avatar
|
||||
width: 24px
|
||||
height: 24px
|
||||
margin: -2px 2px 0 0
|
||||
@include radius(3px)
|
||||
.oe_topbar_avatar
|
||||
vertical-align: top
|
||||
.oe_dropdown_arrow:after
|
||||
border-top: 4px solid white
|
||||
.dropdown_menu
|
||||
top: 32px
|
||||
background: #333
|
||||
background: rgba(37,37,37,0.9)
|
||||
border-color: #999
|
||||
border-color: rgba(0, 0, 0, 0.2)
|
||||
border-style: solid
|
||||
border-width: 0 2px 1px
|
||||
@include radius(0 0 6px 6px)
|
||||
@include background-clip()
|
||||
li
|
||||
float: none
|
||||
padding: 3px 12px
|
||||
a
|
||||
color: #eee
|
||||
&:hover
|
||||
@include vertical-gradient(#292929, #191919)
|
||||
@include box-shadow(none)
|
||||
.oe_topbar_name
|
||||
max-width: 150px
|
||||
display: inline-block
|
||||
height: 15px // Customize to manage caret when topbar_name is over sized.
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
overflow: hidden // Customize to bring ellipsis when topbar_name is over sized.
|
||||
|
||||
// oe menu is the list of the buttons on the left side of the bar.
|
||||
// So why aren't the buttons oe_topbar_items ? This sad state of affairs
|
||||
// is a leftover from an uncomplete refactoring when the left and top menu
|
||||
// were merged. You are welcome to refactor and clean this up
|
||||
.nav li a
|
||||
padding: 6px 8px 4px 8px
|
||||
|
||||
.oe_user_menu
|
||||
float: right
|
||||
padding: 0
|
||||
margin: 0
|
||||
li
|
||||
list-style-type: none
|
||||
float: left
|
||||
.oe_dropdown_menu
|
||||
right: -1px
|
||||
|
||||
// }}}
|
||||
// Webclient.leftbar {{{
|
||||
.oe_leftbar
|
||||
display: none
|
||||
|
|
|
@ -76,7 +76,7 @@ class ir_http(orm.AbstractModel):
|
|||
if self.geo_ip_resolver and request.httprequest.remote_addr:
|
||||
record = self.geo_ip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
|
||||
request.session['geoip'] = record
|
||||
|
||||
|
||||
if request.website_enabled:
|
||||
if func:
|
||||
self._authenticate(func.routing['auth'])
|
||||
|
|
|
@ -62,7 +62,7 @@ class contactus(http.Controller):
|
|||
return request.website.render("website.contactus", values)
|
||||
|
||||
try:
|
||||
values['channel_id'] = request.registry['ir.model.data'].get_object_reference(request.cr, SUPERUSER_ID, 'crm', 'crm_case_channel_website')[1]
|
||||
values['medium_id'] = request.registry['ir.model.data'].get_object_reference(request.cr, SUPERUSER_ID, 'crm', 'crm_tracking_medium_website')[1]
|
||||
values['section_id'] = request.registry['ir.model.data'].xmlid_to_res_id(request.cr, SUPERUSER_ID, 'website.salesteam_website_sales')
|
||||
except ValueError:
|
||||
pass
|
||||
|
|
|
@ -65,7 +65,7 @@ class sale_quote(http.Controller):
|
|||
if token != order.access_token:
|
||||
return request.website.render('website.404')
|
||||
attachments=sign and [('signature.png', sign.decode('base64'))] or []
|
||||
order_obj.signal_order_confirm(request.cr, SUPERUSER_ID, [order_id], context=request.context)
|
||||
order_obj.signal_workflow(request.cr, SUPERUSER_ID, [order_id], 'order_confirm', context=request.context)
|
||||
message = _('Order signed by %s') % (signer,)
|
||||
self.__message_post(message, order_id, type='comment', subtype='mt_comment', attachments=attachments)
|
||||
return True
|
||||
|
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
|
||||
"PO-Revision-Date: 2013-11-24 14:57+0000\n"
|
||||
"Last-Translator: krnkris <Unknown>\n"
|
||||
"Last-Translator: krnkris <krnkris@freemail.hu>\n"
|
||||
"Language-Team: Hungarian <openerp-hungarian-team@lists.launchpad.net>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
@ -103,7 +103,7 @@ msgstr "Indiai bérszámfejtés"
|
|||
#: help:ir.cron,model:0
|
||||
msgid ""
|
||||
"Model name on which the method to be called is located, e.g. 'res.partner'."
|
||||
msgstr "Modell név ahogyan az megnevezve megtalálható, p.l. 'res.partner'."
|
||||
msgstr "Modell név elnevezése szerint megtalálható, p.l. 'res.partner'."
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
|
@ -4000,7 +4000,7 @@ msgstr "Időszakos értékelések, Felbecsülések, Felmérések"
|
|||
#: model:ir.actions.act_window,name:base.ir_property_form
|
||||
#: model:ir.ui.menu,name:base.menu_ir_property_form_all
|
||||
msgid "Configuration Parameters"
|
||||
msgstr "Konfiguráció Paraméterek"
|
||||
msgstr "Beállítási Paaraméterek"
|
||||
|
||||
#. module: base
|
||||
#: constraint:ir.cron:0
|
||||
|
@ -4171,9 +4171,9 @@ msgid ""
|
|||
"separated list of valid field names (optionally followed by asc/desc for the "
|
||||
"direction)"
|
||||
msgstr ""
|
||||
"Invalid \"order\" specified. A valid \"order\" specification is a comma-"
|
||||
"separated list of valid field names (optionally followed by asc/desc for the "
|
||||
"direction)"
|
||||
"Érvénytelen \"megrendelés\" meghatározás. Az érvénnyes \"megrendelés\" egy vesszővel"
|
||||
"elválasztott lista érvényes mező nevekkel (választhatóan növekvő/csökkenő sorrendbe "
|
||||
"állítva)"
|
||||
|
||||
#. module: base
|
||||
#: model:ir.model,name:base.model_ir_module_module_dependency
|
||||
|
@ -4217,7 +4217,7 @@ msgstr ""
|
|||
#. module: base
|
||||
#: model:res.groups,name:base.group_survey_user
|
||||
msgid "Survey / User"
|
||||
msgstr "Felmérés / felhasználó"
|
||||
msgstr "Felmérés / Felhasználó"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.module.module:0
|
||||
|
|
|
@ -848,9 +848,9 @@ class ir_actions_server(osv.osv):
|
|||
def run_action_trigger(self, cr, uid, action, eval_context=None, context=None):
|
||||
""" Trigger a workflow signal, depending on the use_relational_model:
|
||||
|
||||
- `base`: base_model_pool.signal_<TRIGGER_NAME>(cr, uid, context.get('active_id'))
|
||||
- `base`: base_model_pool.signal_workflow(cr, uid, context.get('active_id'), <TRIGGER_NAME>)
|
||||
- `relational`: find the related model and object, using the relational
|
||||
field, then target_model_pool.signal_<TRIGGER_NAME>(cr, uid, target_id)
|
||||
field, then target_model_pool.signal_workflow(cr, uid, target_id, <TRIGGER_NAME>)
|
||||
"""
|
||||
obj_pool = self.pool[action.model_id.model]
|
||||
if action.use_relational_model == 'base':
|
||||
|
|
|
@ -177,8 +177,13 @@ class module(osv.osv):
|
|||
element.set('src', "/%s/static/description/%s" % (module.name, element.get('src')))
|
||||
res[module.id] = lxml.html.tostring(html)
|
||||
else:
|
||||
overrides = dict(embed_stylesheet=False, doctitle_xform=False, output_encoding='unicode')
|
||||
output = publish_string(source=module.description, settings_overrides=overrides, writer=MyWriter())
|
||||
overrides = {
|
||||
'embed_stylesheet': False,
|
||||
'doctitle_xform': False,
|
||||
'output_encoding': 'unicode',
|
||||
'xml_declaration': False,
|
||||
}
|
||||
output = publish_string(source=module.description or '', settings_overrides=overrides, writer=MyWriter())
|
||||
res[module.id] = output
|
||||
return res
|
||||
|
||||
|
|
|
@ -756,7 +756,7 @@ class Environment(object):
|
|||
"""
|
||||
if not spec:
|
||||
return
|
||||
for env in list(self.all):
|
||||
for env in list(iter(self.all)):
|
||||
c = env.cache
|
||||
for field, ids in spec:
|
||||
if ids is None:
|
||||
|
@ -769,7 +769,7 @@ class Environment(object):
|
|||
|
||||
def invalidate_all(self):
|
||||
""" Clear the cache of all environments. """
|
||||
for env in list(self.all):
|
||||
for env in list(iter(self.all)):
|
||||
env.cache.clear()
|
||||
env.prefetch.clear()
|
||||
env.computed.clear()
|
||||
|
|
|
@ -366,9 +366,17 @@ class Field(object):
|
|||
else:
|
||||
self._setup_regular(env)
|
||||
|
||||
# put invalidation/recomputation triggers on dependencies
|
||||
# put invalidation/recomputation triggers on field dependencies
|
||||
model = env[self.model_name]
|
||||
for path in self.depends:
|
||||
self._setup_dependency([], env[self.model_name], path.split('.'))
|
||||
self._setup_dependency([], model, path.split('.'))
|
||||
|
||||
# put invalidation triggers on model dependencies
|
||||
for dep_model_name, field_names in model._depends.iteritems():
|
||||
dep_model = env[dep_model_name]
|
||||
for field_name in field_names:
|
||||
field = dep_model._fields[field_name]
|
||||
field._triggers.add((self, None))
|
||||
|
||||
#
|
||||
# Setup of related fields
|
||||
|
@ -800,7 +808,7 @@ class Field(object):
|
|||
# invalidate the fields that depend on self, and prepare recomputation
|
||||
spec = [(self, records._ids)]
|
||||
for field, path in self._triggers:
|
||||
if field.store:
|
||||
if path and field.store:
|
||||
# don't move this line to function top, see log
|
||||
env = records.env(user=SUPERUSER_ID, context={'active_test': False})
|
||||
target = env[field.model_name].search([(path, 'in', records.ids)])
|
||||
|
@ -824,10 +832,13 @@ class Field(object):
|
|||
computed = target.browse(env.computed[field])
|
||||
if path == 'id':
|
||||
target = records - computed
|
||||
elif path:
|
||||
target = (target.browse(env.cache[field]) - computed).filtered(
|
||||
lambda rec: rec._mapped_cache(path) & records
|
||||
)
|
||||
else:
|
||||
for record in target.browse(env.cache[field]) - computed:
|
||||
if record._mapped_cache(path) & records:
|
||||
target += record
|
||||
target = target.browse(env.cache[field]) - computed
|
||||
|
||||
if target:
|
||||
spec.append((field, target._ids))
|
||||
|
||||
|
@ -1542,6 +1553,9 @@ class Id(Field):
|
|||
store = True
|
||||
readonly = True
|
||||
|
||||
def __init__(self, string=None, **kwargs):
|
||||
super(Id, self).__init__(type='integer', string=string, **kwargs)
|
||||
|
||||
def to_column(self):
|
||||
return fields.integer('ID')
|
||||
|
||||
|
|
|
@ -1145,11 +1145,14 @@ class Root(object):
|
|||
"""Root WSGI application for the OpenERP Web Client.
|
||||
"""
|
||||
def __init__(self):
|
||||
self._loaded = False
|
||||
|
||||
@lazy_property
|
||||
def session_store(self):
|
||||
# Setup http sessions
|
||||
path = openerp.tools.config.session_dir
|
||||
_logger.debug('HTTP sessions stored in: %s', path)
|
||||
self.session_store = werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession)
|
||||
self._loaded = False
|
||||
return werkzeug.contrib.sessions.FilesystemSessionStore(path, session_class=OpenERPSession)
|
||||
|
||||
@lazy_property
|
||||
def nodb_routing_map(self):
|
||||
|
|
|
@ -326,6 +326,10 @@ class BaseModel(object):
|
|||
_log_create = False
|
||||
_sql_constraints = []
|
||||
|
||||
# model dependencies, for models backed up by sql views:
|
||||
# {model_name: field_names, ...}
|
||||
_depends = {}
|
||||
|
||||
CONCURRENCY_CHECK_FIELD = '__last_update'
|
||||
|
||||
def log(self, cr, uid, id, message, secondary=False, context=None):
|
||||
|
@ -585,6 +589,10 @@ class BaseModel(object):
|
|||
inherits = dict(parent_class._inherits)
|
||||
inherits.update(cls._inherits)
|
||||
|
||||
depends = dict(parent_class._depends)
|
||||
for m, fs in cls._depends.iteritems():
|
||||
depends.setdefault(m, []).extend(fs)
|
||||
|
||||
old_constraints = parent_class._constraints
|
||||
new_constraints = cls._constraints
|
||||
# filter out from old_constraints the ones overridden by a
|
||||
|
@ -604,6 +612,7 @@ class BaseModel(object):
|
|||
'_columns': columns,
|
||||
'_defaults': defaults,
|
||||
'_inherits': inherits,
|
||||
'_depends': depends,
|
||||
'_constraints': constraints,
|
||||
'_sql_constraints': sql_constraints,
|
||||
}
|
||||
|
@ -617,6 +626,7 @@ class BaseModel(object):
|
|||
'_columns': dict(cls._columns),
|
||||
'_defaults': dict(cls._defaults),
|
||||
'_inherits': dict(cls._inherits),
|
||||
'_depends': dict(cls._depends),
|
||||
'_constraints': list(cls._constraints),
|
||||
'_sql_constraints': list(cls._sql_constraints),
|
||||
'_original_module': original_module,
|
||||
|
@ -629,76 +639,8 @@ class BaseModel(object):
|
|||
if col._type == 'float':
|
||||
cls._columns[key] = copy.copy(col)
|
||||
|
||||
# link the class to the registry, and update the registry
|
||||
cls.pool = pool
|
||||
# Note: we have to insert an instance into the registry now, because it
|
||||
# can trigger some stuff on other models which expect this new instance
|
||||
# (like method _inherits_reload_src())
|
||||
# instantiate the model, and initialize it
|
||||
model = object.__new__(cls)
|
||||
cls._model = model # backward compatibility
|
||||
pool.add(name, model)
|
||||
|
||||
# determine description, table, sequence and log_access
|
||||
if not cls._description:
|
||||
cls._description = cls._name
|
||||
if not cls._table:
|
||||
cls._table = cls._name.replace('.', '_')
|
||||
if not cls._sequence:
|
||||
cls._sequence = cls._table + '_id_seq'
|
||||
if not hasattr(cls, '_log_access'):
|
||||
# If _log_access is not specified, it is the same value as _auto.
|
||||
cls._log_access = cls._auto
|
||||
|
||||
# Transience
|
||||
if cls.is_transient():
|
||||
cls._transient_check_count = 0
|
||||
cls._transient_max_count = config.get('osv_memory_count_limit')
|
||||
cls._transient_max_hours = config.get('osv_memory_age_limit')
|
||||
assert cls._log_access, \
|
||||
"TransientModels must have log_access turned on, " \
|
||||
"in order to implement their access rights policy"
|
||||
|
||||
# retrieve new-style fields and duplicate them (to avoid clashes with
|
||||
# inheritance between different models)
|
||||
cls._fields = {}
|
||||
for attr, field in getmembers(cls, Field.__instancecheck__):
|
||||
if not field._origin:
|
||||
cls._add_field(attr, field.copy())
|
||||
|
||||
# introduce magic fields
|
||||
cls._add_magic_fields()
|
||||
|
||||
# register stuff about low-level function fields and custom fields
|
||||
cls._init_function_fields(pool, cr)
|
||||
cls._init_manual_fields(pool, cr)
|
||||
|
||||
# process _inherits
|
||||
cls._inherits_check()
|
||||
cls._inherits_reload()
|
||||
|
||||
# register constraints and onchange methods
|
||||
cls._init_constraints_onchanges()
|
||||
|
||||
# check defaults
|
||||
for k in cls._defaults:
|
||||
assert k in cls._fields, \
|
||||
"Model %s has a default for nonexiting field %s" % (cls._name, k)
|
||||
|
||||
# restart columns
|
||||
for column in cls._columns.itervalues():
|
||||
column.restart()
|
||||
|
||||
# validate rec_name
|
||||
if cls._rec_name:
|
||||
assert cls._rec_name in cls._fields, \
|
||||
"Invalid rec_name %s for model %s" % (cls._rec_name, cls._name)
|
||||
elif 'name' in cls._fields:
|
||||
cls._rec_name = 'name'
|
||||
|
||||
# prepare ormcache, which must be shared by all instances of the model
|
||||
cls._ormcache = {}
|
||||
|
||||
# complete the initialization of model
|
||||
model.__init__(pool, cr)
|
||||
return model
|
||||
|
||||
|
@ -818,8 +760,81 @@ class BaseModel(object):
|
|||
return None
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
# this method no longer does anything; kept for backward compatibility
|
||||
pass
|
||||
""" Initialize a model and make it part of the given registry.
|
||||
|
||||
- copy the stored fields' functions in the registry,
|
||||
- retrieve custom fields and add them in the model,
|
||||
- ensure there is a many2one for each _inherits'd parent,
|
||||
- update the children's _columns,
|
||||
- give a chance to each field to initialize itself.
|
||||
|
||||
"""
|
||||
cls = type(self)
|
||||
|
||||
# link the class to the registry, and update the registry
|
||||
cls.pool = pool
|
||||
cls._model = self # backward compatibility
|
||||
pool.add(cls._name, self)
|
||||
|
||||
# determine description, table, sequence and log_access
|
||||
if not cls._description:
|
||||
cls._description = cls._name
|
||||
if not cls._table:
|
||||
cls._table = cls._name.replace('.', '_')
|
||||
if not cls._sequence:
|
||||
cls._sequence = cls._table + '_id_seq'
|
||||
if not hasattr(cls, '_log_access'):
|
||||
# If _log_access is not specified, it is the same value as _auto.
|
||||
cls._log_access = cls._auto
|
||||
|
||||
# Transience
|
||||
if cls.is_transient():
|
||||
cls._transient_check_count = 0
|
||||
cls._transient_max_count = config.get('osv_memory_count_limit')
|
||||
cls._transient_max_hours = config.get('osv_memory_age_limit')
|
||||
assert cls._log_access, \
|
||||
"TransientModels must have log_access turned on, " \
|
||||
"in order to implement their access rights policy"
|
||||
|
||||
# retrieve new-style fields and duplicate them (to avoid clashes with
|
||||
# inheritance between different models)
|
||||
cls._fields = {}
|
||||
for attr, field in getmembers(cls, Field.__instancecheck__):
|
||||
if not field._origin:
|
||||
cls._add_field(attr, field.copy())
|
||||
|
||||
# introduce magic fields
|
||||
cls._add_magic_fields()
|
||||
|
||||
# register stuff about low-level function fields and custom fields
|
||||
cls._init_function_fields(pool, cr)
|
||||
cls._init_manual_fields(pool, cr)
|
||||
|
||||
# process _inherits
|
||||
cls._inherits_check()
|
||||
cls._inherits_reload()
|
||||
|
||||
# register constraints and onchange methods
|
||||
cls._init_constraints_onchanges()
|
||||
|
||||
# check defaults
|
||||
for k in cls._defaults:
|
||||
assert k in cls._fields, \
|
||||
"Model %s has a default for nonexiting field %s" % (cls._name, k)
|
||||
|
||||
# restart columns
|
||||
for column in cls._columns.itervalues():
|
||||
column.restart()
|
||||
|
||||
# validate rec_name
|
||||
if cls._rec_name:
|
||||
assert cls._rec_name in cls._fields, \
|
||||
"Invalid rec_name %s for model %s" % (cls._rec_name, cls._name)
|
||||
elif 'name' in cls._fields:
|
||||
cls._rec_name = 'name'
|
||||
|
||||
# prepare ormcache, which must be shared by all instances of the model
|
||||
cls._ormcache = {}
|
||||
|
||||
def __export_xml_id(self):
|
||||
""" Return a valid xml_id for the record `self`. """
|
||||
|
@ -3013,7 +3028,7 @@ class BaseModel(object):
|
|||
if not fields:
|
||||
fields = filter(valid, self._fields)
|
||||
else:
|
||||
invalid_fields = list(set(filter(lambda name: not valid(name), fields)))
|
||||
invalid_fields = set(filter(lambda name: not valid(name), fields))
|
||||
if invalid_fields:
|
||||
_logger.warning('Access Denied by ACLs for operation: %s, uid: %s, model: %s, fields: %s',
|
||||
operation, user, self._name, ', '.join(invalid_fields))
|
||||
|
@ -3281,7 +3296,7 @@ class BaseModel(object):
|
|||
self._cr.execute(query, (self._name, tuple(self.ids)))
|
||||
res = self._cr.dictfetchall()
|
||||
|
||||
uids = list(set(r[k] for r in res for k in ['write_uid', 'create_uid'] if r.get(k)))
|
||||
uids = set(r[k] for r in res for k in ['write_uid', 'create_uid'] if r.get(k))
|
||||
names = dict(self.env['res.users'].browse(uids).name_get())
|
||||
|
||||
for r in res:
|
||||
|
@ -3504,7 +3519,7 @@ class BaseModel(object):
|
|||
|
||||
for order, obj_name, store_ids, fields in result_store:
|
||||
if obj_name == self._name:
|
||||
effective_store_ids = list(set(store_ids) - set(ids))
|
||||
effective_store_ids = set(store_ids) - set(ids)
|
||||
else:
|
||||
effective_store_ids = store_ids
|
||||
if effective_store_ids:
|
||||
|
@ -4945,19 +4960,6 @@ class BaseModel(object):
|
|||
""" stuff to do right after the registry is built """
|
||||
pass
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name.startswith('signal_'):
|
||||
# self.signal_XXX() sends signal XXX to the record's workflow
|
||||
signal_name = name[7:]
|
||||
assert signal_name
|
||||
return (lambda *args, **kwargs:
|
||||
self.signal_workflow(*args, signal=signal_name, **kwargs))
|
||||
|
||||
get = getattr(super(BaseModel, self), '__getattr__', None)
|
||||
if get is None:
|
||||
raise AttributeError("%r has no attribute %r" % (type(self).__name__, name))
|
||||
return get(name)
|
||||
|
||||
def _patch_method(self, name, method):
|
||||
""" Monkey-patch a method for all instances of this model. This replaces
|
||||
the method called `name` by `method` in `self`'s class.
|
||||
|
@ -5415,7 +5417,7 @@ class BaseModel(object):
|
|||
""" If `field` must be recomputed on some record in `self`, return the
|
||||
corresponding records that must be recomputed.
|
||||
"""
|
||||
for env in [self.env] + list(self.env.all):
|
||||
for env in [self.env] + list(iter(self.env.all)):
|
||||
if env.todo.get(field) and env.todo[field] & self:
|
||||
return env.todo[field]
|
||||
|
||||
|
@ -5437,7 +5439,7 @@ class BaseModel(object):
|
|||
""" Recompute stored function fields. The fields and records to
|
||||
recompute have been determined by method :meth:`modified`.
|
||||
"""
|
||||
for env in list(self.env.all):
|
||||
for env in list(iter(self.env.all)):
|
||||
while env.todo:
|
||||
field, recs = next(env.todo.iteritems())
|
||||
# evaluate the fields to recompute, and save them to database
|
||||
|
|
|
@ -43,7 +43,7 @@ MANIFEST = '__openerp__.py'
|
|||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# addons path as a list
|
||||
ad_paths = [tools.config.addons_data_dir]
|
||||
ad_paths = []
|
||||
hooked = False
|
||||
|
||||
# Modules already loaded
|
||||
|
@ -89,6 +89,10 @@ def initialize_sys_path():
|
|||
global ad_paths
|
||||
global hooked
|
||||
|
||||
dd = tools.config.addons_data_dir
|
||||
if dd not in ad_paths:
|
||||
ad_paths.append(dd)
|
||||
|
||||
for ad in tools.config['addons_path'].split(','):
|
||||
ad = os.path.abspath(tools.ustr(ad.strip()))
|
||||
if ad not in ad_paths:
|
||||
|
|
|
@ -30,7 +30,7 @@ RELEASE_LEVELS_DISPLAY = {ALPHA: ALPHA,
|
|||
# properly comparable using normal operarors, for example:
|
||||
# (6,1,0,'beta',0) < (6,1,0,'candidate',1) < (6,1,0,'candidate',2)
|
||||
# (6,1,0,'candidate',2) < (6,1,0,'final',0) < (6,1,2,'final',0)
|
||||
version_info = (8, 0, 0, ALPHA, 1)
|
||||
version_info = (8, 0, 0, RELEASE_CANDIDATE, 1)
|
||||
version = '.'.join(map(str, version_info[:2])) + RELEASE_LEVELS_DISPLAY[version_info[3]] + str(version_info[4] or '')
|
||||
series = serie = major_version = '.'.join(map(str, version_info[:2]))
|
||||
|
||||
|
|
|
@ -61,7 +61,10 @@ def check_ssl():
|
|||
DEFAULT_LOG_HANDLER = [':INFO']
|
||||
|
||||
def _get_default_datadir():
|
||||
return appdirs.user_data_dir(appname='OpenERP', appauthor=release.author)
|
||||
home = os.path.expanduser('~')
|
||||
func = appdirs.user_data_dir if os.path.exists(home) else appdirs.site_data_dir
|
||||
# No "version" kwarg as session and filestore paths are shared against series
|
||||
return func(appname='Odoo', appauthor=release.author)
|
||||
|
||||
class configmanager(object):
|
||||
def __init__(self, fname=None):
|
||||
|
@ -649,7 +652,7 @@ class configmanager(object):
|
|||
|
||||
@property
|
||||
def session_dir(self):
|
||||
d = os.path.join(self['data_dir'], 'sessions', release.series)
|
||||
d = os.path.join(self['data_dir'], 'sessions')
|
||||
if not os.path.exists(d):
|
||||
os.makedirs(d, 0700)
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue