[ADD] Add the website_links module.

This module tracks clicks in mass mailing mails and allow the generation of trackable links in a website interface.

Modules modifications
---------------------
Refractoring of the crm_tracking_* classes in a new module.

* Extract the crm_tracking_* from the crm module into a new module "utm"
* Remove the crm_mass_mailing bridge module
* New dependencies of mass_mailing and website_links to utm.
This commit is contained in:
Julien De Coster
2014-12-17 17:14:33 +01:00
parent 7f97bf4ec0
commit ddac26cdbb
73 changed files with 4524 additions and 1550 deletions
-78
View File
@@ -29,84 +29,6 @@ AVAILABLE_PRIORITIES = [
('3', 'Very High'),
]
class crm_tracking_medium(osv.Model):
# OLD crm.case.channel
_name = "crm.tracking.medium"
_description = "Channels"
_order = 'name'
_columns = {
'name': fields.char('Channel Name', required=True),
'active': fields.boolean('Active'),
}
_defaults = {
'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),
'team_id': fields.many2one('crm.team', 'Sales Team', oldname='section_id'),
}
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 ="['|',('team_id','=',team_id),('team_id','=',False)]"
help="This is a name that helps you keep track of your different campaign efforts Ex: Fall_Drive, Christmas_Special"),
'source_id': fields.many2one('crm.tracking.source', 'Source', help="This is the source of the link Ex: 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", oldname='channel_id'),
}
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, fname in self.tracking_fields():
field = self._fields[fname]
value = vals.get(fname) or (request and request.httprequest.cookies.get(key)) # params.get should be always in session by the dispatch from ir_http
if field.type == 'many2one' and isinstance(value, basestring):
# if we receive a string for a many2one, we search/create the id
if value:
Model = self.pool[field.comodel_name]
rel_id = Model.name_search(cr, uid, value, context=context)
if rel_id:
rel_id = rel_id[0][0]
else:
rel_id = Model.create(cr, uid, {'name': value}, context=context)
vals[fname] = rel_id
else:
# Here the code for others cases that many2one
vals[fname] = 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_stage(osv.Model):
""" Model for case stages. This models the main stages of a document
management flow. Main CRM objects (leads, opportunities, project
-39
View File
@@ -13,45 +13,6 @@
<field name="state">open</field>
</record>
<!-- 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.tracking.medium" id="crm_medium_phone">
<field name="name">Phone</field>
</record>
<record model="crm.tracking.medium" id="crm_medium_direct">
<field name="name">Direct</field>
</record>
<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.tracking.medium" id="crm_medium_twitter">
<field name="name">Twitter Ads</field>
</record>
<record model="crm.tracking.medium" id="crm_medium_television">
<field name="name">Television</field>
</record>
<record model="crm.tracking.medium" id="crm_medium_google_adwords">
<field name="name">Google Adwords</field>
</record>
<record model="crm.team" id="sales_team.team_sales_department">
<field name="use_leads">True</field>
<field name="alias_name">sales</field>
+1 -1
View File
@@ -70,7 +70,7 @@ class crm_lead(format_address, osv.osv):
_name = "crm.lead"
_description = "Lead/Opportunity"
_order = "priority desc,date_action,id desc"
_inherit = ['mail.thread', 'ir.needaction_mixin', 'crm.tracking.mixin']
_inherit = ['mail.thread', 'ir.needaction_mixin', 'utm.mixin']
_track = {
'stage_id': {
+1 -18
View File
@@ -67,24 +67,7 @@
(4, ref('stage_lead5')), (4, ref('stage_lead6')),
(4, ref('stage_lead7'))]"/>
</record>
<!-- Crm Campain -->
<record model="crm.tracking.campaign" id="crm_campaign_fall_drive">
<field name="name">Fall Drive</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<record model="crm.tracking.campaign" id="crm_campaign_christmas_special">
<field name="name">Christmas Special</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<record model="crm.tracking.campaign" id="crm_campaign_email_campaign_services">
<field name="name">Email Campaign - Services</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<record model="crm.tracking.campaign" id="crm_campaign_email_campaign_products">
<field name="name">Email Campaign - Products</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<!-- crm categories -->
<record model="crm.lead.tag" id="categ_oppor1">
<field name="name">Product</field>
+72 -72
View File
@@ -25,9 +25,9 @@
I am Jacques from Le Club SARL.
I am interested to attend a training organized in your company.
Could you please send me the details ?</field>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_1" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
@@ -57,9 +57,9 @@ Could you please send me the details ?</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_christmas_special"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_christmas_special"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
@@ -87,9 +87,9 @@ Could you please send me the details ?</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_google_adwords"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_google_adwords"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
@@ -109,9 +109,9 @@ Could you please send me the details ?</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead6"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_banner"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_banner"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_2" model="crm.lead">
<field name="create_date" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
@@ -143,9 +143,9 @@ Purchase Manager
Stonage IT,
Franklinville
Contact: +1 813 494 5005</field>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_6" model="crm.lead">
@@ -163,9 +163,9 @@ Contact: +1 813 494 5005</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_7" model="crm.lead">
@@ -183,9 +183,9 @@ Contact: +1 813 494 5005</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_8" model="crm.lead">
@@ -203,9 +203,9 @@ Contact: +1 813 494 5005</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_google_adwords"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_google_adwords"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_9" model="crm.lead">
@@ -223,9 +223,9 @@ Contact: +1 813 494 5005</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_10" model="crm.lead">
@@ -247,9 +247,9 @@ I would like to know more about specification and cost of laptops of your compan
Thanks,
Andrew</field>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_11" model="crm.lead">
@@ -266,9 +266,9 @@ Andrew</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_direct"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_direct"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_12" model="crm.lead">
@@ -285,9 +285,9 @@ Andrew</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref=""/>
<field name="stage_id" ref="stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<!-- Call Function to Cancel the leads (set as Dead) -->
@@ -324,9 +324,9 @@ Andrew</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead1"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_14" model="crm.lead">
@@ -350,9 +350,9 @@ Andrew</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_15" model="crm.lead">
@@ -374,8 +374,8 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=2)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_15" model="crm.lead">
<field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
@@ -402,8 +402,8 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead3"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_17" model="crm.lead">
@@ -427,9 +427,9 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_17" model="crm.lead">
<field name="message_follower_ids" eval="[(3, ref('base.partner_root')), (4, ref('base.partner_demo'))]"/>
@@ -456,8 +456,8 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field eval="1" name="active"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_18" model="crm.lead">
<field name="message_follower_ids" eval="[(4, ref('base.partner_demo'))]"/>
@@ -484,8 +484,8 @@ Andrew</field>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=3)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_20" model="crm.lead">
@@ -501,8 +501,8 @@ Andrew</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="source_id" ref="crm_source_mailing"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="source_id" ref="utm.utm_source_mailing"/>
</record>
<record id="crm_case_21" model="crm.lead">
@@ -516,9 +516,9 @@ Andrew</field>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead4"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(months=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_services"/>
<field name="medium_id" ref="crm_medium_phone"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="medium_id" ref="utm.utm_medium_phone"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_22" model="crm.lead">
@@ -534,9 +534,9 @@ Andrew</field>
<field name="team_id" ref="sales_team.crm_team_2"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_services"/>
<field name="medium_id" ref="crm_medium_email"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_23" model="crm.lead">
@@ -551,9 +551,9 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_fall_drive"/>
<field name="medium_id" ref="crm_medium_direct"/>
<field name="source_id" ref="crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_fall_drive"/>
<field name="medium_id" ref="utm.utm_medium_direct"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
<record id="crm_case_24" model="crm.lead">
@@ -571,9 +571,9 @@ Andrew</field>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field name="date_closed" eval="(DateTime.today() - relativedelta(month=1)).strftime('%Y-%m-%d %H:%M')"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_services"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_25" model="crm.lead">
@@ -595,8 +595,8 @@ Andrew</field>
<field name="team_id" ref="sales_team.crm_team_1"/>
<field name="user_id" ref="base.user_root"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<field name="campaign_id" ref="crm_campaign_email_campaign_services"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_services"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_26" model="crm.lead">
@@ -620,9 +620,9 @@ Andrew</field>
<field name="user_id" ref="base.user_demo"/>
<field name="stage_id" ref="crm.stage_lead5"/>
<!-- <field name="date_closed" eval="(DateTime.today() - relativedelta(hours=1)).strftime('%Y-%m-%d %H:%M')"/> -->
<field name="campaign_id" ref="crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm_medium_website"/>
<field name="source_id" ref="crm_source_search_engine"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_website"/>
<field name="source_id" ref="utm.utm_source_search_engine"/>
</record>
<record id="crm_case_27" model="crm.lead">
-128
View File
@@ -23,90 +23,6 @@
<menuitem id="menu_crm_config_phonecall" name="Phone Calls"
parent="base.menu_base_config" sequence="45" groups="base.group_sale_salesman"/>
<!-- 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"/>
<field name="active"/>
</tree>
</field>
</record>
<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>
<field name="name"/>
<field name="active"/>
</group>
</form>
</field>
</record>
<record id="crm_tracking_medium_action" model="ir.actions.act_window">
<field name="name">Channels</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 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, banner, etc.
</p>
</field>
</record>
<!-- 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.LOST.REASON VIEWS -->
<record id="crm_lost_reason_view_form" model="ir.ui.view">
<field name="name">crm.lost.reason.form</field>
@@ -180,55 +96,11 @@
</record>
<!-- CRM Stage Action -->
<record id="crm_stage_act" model="ir.actions.act_window">
<field name="name">Stages</field>
<field name="res_model">crm.stage</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_stage_tree"/>
</record>
<!-- Resource Type of case Tree View -->
<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"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</tree>
</field>
</record>
<!-- Resource Type of case Form View -->
<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>
<field name="name"/>
<field name="team_id" groups="base.group_multi_salesteams"/>
</group>
</form>
</field>
</record>
<!-- Resource Type of case Action -->
<record id="crm_tracking_campaign_act" model="ir.actions.act_window">
<field name="name">Campaigns</field>
<field name="res_model">crm.tracking.campaign</field>
<field name="view_type">form</field>
<field name="view_id" ref="crm_tracking_campaign_tree"/>
</record>
<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"/>
</data>
</openerp>
+1 -1
View File
@@ -11,7 +11,7 @@ class ir_http(orm.AbstractModel):
def _dispatch(self):
response = super(ir_http, self)._dispatch()
for var, dummy in self.pool['crm.tracking.mixin'].tracking_fields():
for var, dummy in self.pool['utm.mixin'].tracking_fields():
if var in request.params and (var not in request.session or request.session[var] != request.params[var]):
response.set_cookie(var, request.params[var], domain=self.get_utm_domain_cookies())
return response
+1 -1
View File
@@ -29,7 +29,7 @@ class crm_lead_report(osv.Model):
_auto = False
_description = "CRM Lead Analysis"
_rec_name = 'date_deadline'
_inherit = ["crm.tracking.mixin"]
_inherit = ["utm.mixin"]
_columns = {
'date_deadline': fields.date('Expected Closing', readonly=True),
+1 -1
View File
@@ -30,7 +30,7 @@ class crm_opportunity_report(osv.Model):
_auto = False
_description = "CRM Opportunity Analysis"
_rec_name = 'date_deadline'
_inherit = ["crm.tracking.mixin"]
_inherit = ["utm.mixin"]
_columns = {
'date_deadline': fields.date('Expected Closing', readonly=True),
-6
View File
@@ -1,16 +1,10 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
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_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
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_stage,crm.stage,model_crm_stage,,1,0,0,0
access_crm_stage_manager,crm.stage,model_crm_stage,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
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
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
2 access_crm_lead_manager crm.lead.manager model_crm_lead base.group_sale_manager 1 1 1 1
3 access_crm_phonecall_manager crm.phonecall.manager model_crm_phonecall base.group_sale_manager 1 1 1 1
4 access_crm_lead crm.lead model_crm_lead base.group_sale_salesman 1 1 1 0
5 access_crm_phonecall crm.phonecall model_crm_phonecall base.group_sale_salesman 1 1 1 0
6 access_crm_stage crm.stage model_crm_stage 1 0 0 0
7 access_crm_stage_manager crm.stage model_crm_stage 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
8 access_crm_phonecall_report_user crm.phonecall.report.user model_crm_phonecall_report base.group_sale_salesman 1 0 0 0
9 access_crm_phonecall_report_manager crm.phonecall.report model_crm_phonecall_report base.group_sale_manager 1 1 1 1
10 access_res_partner_manager res.partner.crm.manager base.model_res_partner base.group_sale_manager 1 0 0 0
+2 -4
View File
@@ -25,14 +25,12 @@
Case Category2
-->
<record model="crm.tracking.campaign" id="claim_source1">
<record model="utm.campaign" id="claim_source1">
<field name="name">Corrective</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<record model="crm.tracking.campaign" id="claim_source2">
<record model="utm.campaign" id="claim_source2">
<field name="name">Preventive</field>
<field name="team_id" ref="sales_team.team_sales_department"/>
</record>
<!--
+1 -1
View File
@@ -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.tracking.medium', 'Channel', help="Communication channel."),
'channel_id': fields.many2one('utm.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'),
@@ -50,7 +50,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.tracking.medium', 'Channel'),
'channel_id': fields.many2one('utm.medium', 'Channel'),
'categ_id': fields.many2one('crm.helpdesk.category', 'Category'),
'planned_cost': fields.float('Planned Costs'),
'create_date': fields.datetime('Creation Date' , readonly=True, select=True),
-22
View File
@@ -1,22 +0,0 @@
# -*- 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
-18
View File
@@ -1,18 +0,0 @@
{
'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,
}
-62
View File
@@ -1,62 +0,0 @@
# Arabic translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-11-14 18:16+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-11-15 07:01+0000\n"
"X-Generator: Launchpad (build 17241)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr ""
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr ""
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr ""
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr ""
-62
View File
@@ -1,62 +0,0 @@
# Bulgarian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-11-18 14:41+0000\n"
"Last-Translator: Dimitar Dimitrov <dimitrovden@gmail.com>\n"
"Language-Team: Bulgarian <bg@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-11-19 06:42+0000\n"
"X-Generator: Launchpad (build 17252)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Кампания"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Канал"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Изпращане на масови имейл съобщения"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Източник"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Проследяване"
@@ -1,57 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * crm_mass_mailing
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-08-14 13:09+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr ""
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr ""
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr ""
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid "This is a name that helps you keep track of your different campaign efforts Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid "This is the source of the link Ex: Search Engine, another domain, or name of email list"
msgstr ""
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr ""
-68
View File
@@ -1,68 +0,0 @@
# German translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-08-28 10:06+0000\n"
"Last-Translator: Thorsten Vocks (OpenBig.org) <thorsten.vocks@big-"
"consulting.net>\n"
"Language-Team: German <de@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-08-30 08:37+0000\n"
"X-Generator: Launchpad (build 17176)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampagne"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Vertriebsweg"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Massenmailing"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Herkunft"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Diese Bezeichnung hilft Ihnen bei der Analyse Ihres Kampagnenerfolgs, z.B.: "
"Herbstangebot, Weihnachtsangebot"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
"Dies ist die Kommunikationsmethode: z.B. Postkarte, E-Mail oder Bannerwerbung"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Dies zeigt die Herkunft für neue Interessenten: Suchmaschine, andere "
"Webdomäne, E-Mail Liste"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Verfolgung"
-68
View File
@@ -1,68 +0,0 @@
# Spanish translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-08-18 11:59+0000\n"
"Last-Translator: Pedro Manuel Baeza <pedro.baeza@gmail.com>\n"
"Language-Team: Spanish <es@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-08-19 07:04+0000\n"
"X-Generator: Launchpad (build 17156)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Campaña"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Canal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Envío masivo"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Origen"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Éste es un nombre que facilita la búsqueda de los diferentes esfuerzos de "
"campañas. Por ejemplo: campaña de Navidad, rebajas de otoño"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
"Éste es el método de envío. Por ejemplo: carta postal, correo electrónico, "
"publicidad web"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Ésta es la fuente del enlace. Por ejemplo: motor de búsqueda, otro dominio o "
"nombre de unos lista de correos"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Seguimiento"
-62
View File
@@ -1,62 +0,0 @@
# Croatian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-09-01 08:24+0000\n"
"Last-Translator: Goran Kliska <gkliska@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-09-02 07:33+0000\n"
"X-Generator: Launchpad (build 17192)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampanja"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Grupna e-pošta"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Izvori"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Praćenje"
-66
View File
@@ -1,66 +0,0 @@
# Hungarian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-06 21:19+0000\n"
"Last-Translator: krnkris <Unknown>\n"
"Language-Team: Hungarian <hu@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-07 07:02+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampány"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Csatorna"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Tömeges email küldés"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Forrás"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Ez a név ami segít követni a különböző kampány törekvéseit. Pl: "
"Őszi_árhullás, Karácsonyi_speciál"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Ez a kivitelezés módja. Ex: Posta, Email, vagy Transzparens hirdetés"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Ez az elérési út forrása. Pl: Kereső motor, másik domain, vagy email lista "
"neve"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Nyomonkövetés"
-67
View File
@@ -1,67 +0,0 @@
# Italian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-01 20:16+0000\n"
"Last-Translator: Nicola Riolini - Micronaet <nicola.riolini@gmail.com>\n"
"Language-Team: Italian <it@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-02 06:42+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Campagna"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Canale"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Mailing di Massa"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Sorgente"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Questo nome puo' aiutarti a tenere traccia di differenti campagne di "
"vendita. Es. Sconti natalizi, saldi autunnali, ecc.."
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
"Rappresenta il metodo di consegna. Es: email, banner, volantini, ecc.."
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Questo è il sorgente del link, es.: Motore di ricerca, altro dominio o nome "
"della e-mail list"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Tracciabilità"
-63
View File
@@ -1,63 +0,0 @@
# Korean translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-09-02 08:30+0000\n"
"Last-Translator: Josh Kim <joshkkim@gmail.com>\n"
"Language-Team: Korean <ko@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-09-03 07:29+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "캠페인"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "채널"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "대량 메일 발송"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "소스"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"이것은 다른 캠페인 노력을 추적할 때 도움을 주는 이름입니다. 예시: Fall_Drive, Christmas_Special"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "이것은 전달방식입니다. 예시: 엽서, 이메일 또는 배너광고"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr "이것은 링크의 소스입니다. 예시: 검색엔진, 다른 도메인 또는 이메일 목록의 이름"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "추적"
-62
View File
@@ -1,62 +0,0 @@
# Latvian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-23 11:32+0000\n"
"Last-Translator: Vladimirs Kuzmins <Unknown>\n"
"Language-Team: Latvian <lv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-24 07:05+0000\n"
"X-Generator: Launchpad (build 17203)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampaņa"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanāls"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Masveida e-pastu sūtīšana"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Avots"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Izsekošana"
-65
View File
@@ -1,65 +0,0 @@
# Macedonian translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-17 08:36+0000\n"
"Last-Translator: Tome Barbov <tome.barbov@eskon.com.mk>\n"
"Language-Team: Macedonian <mk@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-18 07:21+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Кампања"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Канал"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Масовно праќање пошта"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Извор"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Ова е име што ви помага да следите резултати од различни кампањи пр. : "
"Fall_Drive, Christmas_Special"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Ова е начин на испорака. Пр. Честитка, Е-маил или онлајн реклама"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"ова е извор на врската пр. : пребарувач, друг домен или име од е-маил листа"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Следење"
-68
View File
@@ -1,68 +0,0 @@
# Dutch translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-08-14 19:27+0000\n"
"Last-Translator: Erwin van der Ploeg (BAS Solutions) <Unknown>\n"
"Language-Team: Dutch <nl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-08-15 07:03+0000\n"
"X-Generator: Launchpad (build 17156)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Campagne"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanaal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Bulk-mailing"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Bron"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Dit is de naam welke u helpt om uw verschillende campagnes te volgen. Zoals "
"bijvoorbeeld: Fall_drive, Christmas_Special"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr ""
"Dit is de methode van afleveren. Bijvoorbeeld, Brief, E-mail of Banner "
"advertantie"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Dit is de bron van de link. Bijvoorbeeld: Search engine, ander domein of de "
"naam van de e-mail lijst"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Volgen"
-62
View File
@@ -1,62 +0,0 @@
# Polish translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-08-29 14:57+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-08-30 08:37+0000\n"
"X-Generator: Launchpad (build 17176)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampania"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanał"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Poczta masowa"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Źródło"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Metoda dostawy. Np: pocztówka, e-mail, lub baner"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr "Źródło adresu np: wyszukiwarka, inna domena lub e-mail"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Śledzenie"
-66
View File
@@ -1,66 +0,0 @@
# Portuguese translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-15 15:51+0000\n"
"Last-Translator: Daniel Santos - ThinkOpen <dcs@thinkopensolutions.pt>\n"
"Language-Team: Portuguese <pt@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-16 05:52+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Campanha"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Canal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Emails em Massa"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Origem"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Este é um nome que o ajuda a acompanhar os seus esforços das diferentes "
"campanhas Ex: Natal_Especial, etc.."
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Este é o método de entrega. Ex: Cartão postal, e-mail ou anúncio web"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Esta é a origem do link Ex: Motor de Busca, um outro domínio ou nome de "
"lista de e-mail"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Rastrear"
-67
View File
@@ -1,67 +0,0 @@
# Brazilian Portuguese translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-09-06 02:02+0000\n"
"Last-Translator: Fábio Martinelli - http://zupy.com.br "
"<webmaster@zupy.com.br>\n"
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-09-06 08:25+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Campanha"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Canal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Email em Massa"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Origem"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Este é o nome que te ajuda a rastrear as diferentes campanhas Ex: Especial "
"de Natal, Páscoa"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Este é o método de entrega. Ex: Cartão Postal, Email, Banner"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Esta é a origem do link. Ex: Site de Busca, outro domínio, ou nome da lista "
"de emails"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Rastreamento"
-66
View File
@@ -1,66 +0,0 @@
# Swedish translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-20 19:27+0000\n"
"Last-Translator: Fredrik Arvas <fredrik.arvas@smart-eu.org>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-21 07:53+0000\n"
"X-Generator: Launchpad (build 17203)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampanj"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Massutskick"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Källa"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Det här är ett namn som hjälper dig hålla ordning på olika kampanjer. Ex. "
"Höst_körning, Jul_Special"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Det här är leverensmetoden. Ex. Vykort, Epost eller Banner"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Det här är källan till länken. Ex: Sökmotor, en annan domän eller namn på "
"mailinglista"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "Spårning"
-66
View File
@@ -1,66 +0,0 @@
# Turkish translation for openobject-addons
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
msgid ""
msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2014-08-14 13:09+0000\n"
"PO-Revision-Date: 2014-10-28 09:41+0000\n"
"Last-Translator: Ayhan KIZILTAN <Unknown>\n"
"Language-Team: Turkish <tr@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-10-29 07:47+0000\n"
"X-Generator: Launchpad (build 17203)\n"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,campaign_id:0
msgid "Campaign"
msgstr "Kampanya"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,medium_id:0
msgid "Channel"
msgstr "Kanal"
#. module: crm_mass_mailing
#: model:ir.model,name:crm_mass_mailing.model_mail_mass_mailing
msgid "Mass Mailing"
msgstr "Toplu Mail"
#. module: crm_mass_mailing
#: field:mail.mass_mailing,source_id:0
msgid "Source"
msgstr "Kaynak"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,campaign_id:0
msgid ""
"This is a name that helps you keep track of your different campaign efforts "
"Ex: Fall_Drive, Christmas_Special"
msgstr ""
"Farklı kampanya çalışmalarınızı kaydını tutmaya yarayan bir isimdir. Örn: "
"Güz_Sürüşü, Yılbaşı_Özel"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,medium_id:0
msgid "This is the method of delivery. Ex: Postcard, Email, or Banner Ad"
msgstr "Bu teslimat yöntemidir. Örn: Postakartı, Eposta yada Reklam Afişi"
#. module: crm_mass_mailing
#: help:mail.mass_mailing,source_id:0
msgid ""
"This is the source of the link Ex: Search Engine, another domain, or name of "
"email list"
msgstr ""
"Bu, bağlantının kaynağıdır. Örn: Arama Motoru, başka alan adı yada bir "
"eposta listesi adı"
#. module: crm_mass_mailing
#: view:mail.mass_mailing:crm_mass_mailing.view_tracking_mass_mailing_form
msgid "Tracking"
msgstr "İzleme"
-6
View File
@@ -1,6 +0,0 @@
from openerp.osv import osv
class MassMailing(osv.Model):
_name = 'mail.mass_mailing'
_inherit = ['mail.mass_mailing', 'crm.tracking.mixin']
-23
View File
@@ -1,23 +0,0 @@
<?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>
+3 -3
View File
@@ -25,9 +25,9 @@
Steve</field>
<field eval="1" name="active"/>
<field name="partner_assigned_id" ref="portal.partner_demo_portal"/>
<field name="campaign_id" ref="crm.crm_campaign_email_campaign_products"/>
<field name="medium_id" ref="crm.crm_medium_email"/>
<field name="source_id" ref="crm.crm_source_newsletter"/>
<field name="campaign_id" ref="utm.utm_campaign_email_campaign_products"/>
<field name="medium_id" ref="utm.utm_medium_email"/>
<field name="source_id" ref="utm.utm_source_newsletter"/>
</record>
</data>
</openerp>
+1 -1
View File
@@ -181,7 +181,7 @@ class mail_mail(osv.Model):
def send_get_mail_body(self, cr, uid, mail, partner=None, context=None):
"""Return a specific ir_email body. The main purpose of this method
is to be inherited to add custom content depending on some module."""
body = mail.body_html
body = mail.body_html or ''
# generate access links for notifications or emails linked to a specific document with auto threading
link = None
+2
View File
@@ -38,6 +38,8 @@ professional emails and reuse templates in a few clicks.
'web_kanban_gauge',
'web_kanban_sparkline',
'website_mail',
'website_links',
'utm',
],
'data': [
'data/mail_data.xml',
+10 -3
View File
@@ -15,9 +15,10 @@ class MassMailController(http.Controller):
response = werkzeug.wrappers.Response()
response.mimetype = 'image/gif'
response.data = 'R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='.decode('base64')
return response
@http.route(['/mail/mailing/<int:mailing_id>/unsubscribe'], type='http', auth='none')
@http.route('/mail/mailing/<int:mailing_id>/unsubscribe', type='http', auth='none')
def mailing(self, mailing_id, email=None, res_id=None, **post):
cr, uid, context = request.cr, request.uid, request.context
MassMailing = request.registry['mail.mass_mailing']
@@ -42,7 +43,7 @@ class MassMailController(http.Controller):
model.write(cr, SUPERUSER_ID, record_ids, {'opt_out': True}, context=context)
return 'OK'
@http.route(['/website_mass_mailing/is_subscriber'], type='json', auth="public", website=True)
@http.route('/website_mass_mailing/is_subscriber', type='json', auth="public", website=True)
def is_subscriber(self, list_id, **post):
cr, uid, context = request.cr, request.uid, request.context
Contacts = request.registry['mail.mass_mailing.contact']
@@ -61,7 +62,7 @@ class MassMailController(http.Controller):
return {'is_subscriber': is_subscriber, 'email': email}
@http.route(['/website_mass_mailing/subscribe'], type='json', auth="public", website=True)
@http.route('/website_mass_mailing/subscribe', type='json', auth="public", website=True)
def subscribe(self, list_id, email, **post):
cr, uid, context = request.cr, request.uid, request.context
Contacts = request.registry['mail.mass_mailing.contact']
@@ -75,3 +76,9 @@ class MassMailController(http.Controller):
# add email to session
request.session['mass_mailing_email'] = email
return True
@http.route('/r/<string:code>/m/<int:stat_id>', type='http', auth="none")
def full_url_redirect(self, code, stat_id, **post):
cr, uid, context = request.cr, request.uid, request.context
request.registry['website.links.click'].add_click(cr, uid, code, request.httprequest.remote_addr, request.session['geoip'].get('country_code'), stat_id=stat_id, context=context)
return werkzeug.utils.redirect(request.registry['website.links'].get_url_from_code(cr, uid, code, context=context), 301)
@@ -97,6 +97,9 @@
<field name="stage_id" ref="mass_mailing.campaign_stage_1"/>
<field name="user_id" eval="ref('base.user_root')"/>
<field name="category_ids" eval="[(6,0,[ref('mass_mailing.mass_mail_category_1')])]"/>
<field name="campaign_id" eval="ref('utm.utm_campaign_email_campaign_products')"/>
<field name="medium_id" eval="ref('utm.utm_medium_email')"/>
<field name="source_id" eval="ref('utm.utm_source_mailing')"/>
</record>
<record id="mass_mail_1" model="mail.mass_mailing">
+1
View File
@@ -6,3 +6,4 @@ import mail_mail
import mail_thread
import res_config
import mass_mailing_report
import website_links_click
+131 -2
View File
@@ -4,14 +4,17 @@ from datetime import datetime
from dateutil import relativedelta
import json
import random
import re
from openerp import tools
from openerp import models, api, _
from openerp.exceptions import Warning
from openerp.tools.safe_eval import safe_eval as eval
from openerp.tools.translate import _
from openerp.tools import ustr
from openerp.osv import osv, fields
URL_REGEX = r'https?://[^\s<>"]+|www\.[^\s<>"]+'
class MassMailingCategory(osv.Model):
"""Model of categories of mass mailing, i.e. marketing, newsletter, ... """
@@ -148,6 +151,9 @@ class MassMailingCampaign(osv.Model):
_name = "mail.mass_mailing.campaign"
_description = 'Mass Mailing Campaign'
_inherit = ['utm.mixin']
_inherits = {'utm.campaign': 'campaign_id'}
def _get_statistics(self, cr, uid, ids, name, arg, context=None):
""" Compute statistics of the mass mailing campaign """
results = {}
@@ -181,6 +187,21 @@ class MassMailingCampaign(osv.Model):
row['replied_ratio'] = 100.0 * row['replied'] / total
return results
def _get_clicks_ratio(self, cr, uid, ids, name, arg, context=None):
res = dict.fromkeys(ids, 0)
cr.execute("""
SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mail_stat_id)) AS nb_clicks, stats.mass_mailing_campaign_id AS id
FROM mail_mail_statistics AS stats
LEFT OUTER JOIN website_links_click AS clicks ON clicks.mail_stat_id = stats.id
WHERE stats.mass_mailing_campaign_id IN %s
GROUP BY stats.mass_mailing_campaign_id
""", (tuple(ids), ))
for record in cr.dictfetchall():
res[record['id']] = 100 * record['nb_clicks'] / record['nb_mails']
return res
_columns = {
'name': fields.char('Name', required=True),
'stage_id': fields.many2one('mail.mass_mailing.stage', 'Stage', required=True),
@@ -188,6 +209,8 @@ class MassMailingCampaign(osv.Model):
'res.users', 'Responsible',
required=True,
),
'campaign_id': fields.many2one('utm.campaign', 'campaign_id',
required=True, ondelete='cascade'),
'category_ids': fields.many2many(
'mail.mass_mailing.category', 'mail_mass_mailing_category_rel',
'category_id', 'campaign_id', string='Categories'),
@@ -201,6 +224,10 @@ class MassMailingCampaign(osv.Model):
'various mailings in a single campaign to test the effectiveness'
'of the mailings.'),
'color': fields.integer('Color Index'),
'clicks_ratio': fields.function(
_get_clicks_ratio, string="Number of clicks",
type="integer",
),
# stat fields
'total': fields.function(
_get_statistics, string='Total',
@@ -252,11 +279,24 @@ class MassMailingCampaign(osv.Model):
stage_ids = self.pool['mail.mass_mailing.stage'].search(cr, uid, [], limit=1, context=context)
return stage_ids and stage_ids[0] or False
def _get_source_id(self, cr, uid, context=None):
return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'utm.utm_source_newsletter')
def _get_medium_id(self, cr, uid, context=None):
return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, 'utm.utm_medium_email')
_defaults = {
'user_id': lambda self, cr, uid, ctx=None: uid,
'stage_id': lambda self, *args: self._get_default_stage_id(*args),
'source_id': lambda self, *args: self._get_source_id(*args),
'medium_id': lambda self,*args: self._get_medium_id(*args),
}
def mass_mailing_statistics_action(self, cr, uid, ids, context=None):
res = self.pool['ir.actions.act_window'].for_xml_id(cr, uid, 'mass_mailing', 'action_view_mass_mailing_statistics', context=context)
res['domain'] = [('mass_mailing_campaign_id', 'in', ids)]
return res
def get_recipients(self, cr, uid, ids, model=None, context=None):
"""Return the recipients of a mailing campaign. This is based on the statistics
build for each mailing. """
@@ -270,6 +310,17 @@ class MassMailingCampaign(osv.Model):
res[cid] = set(stat.res_id for stat in Statistics.browse(cr, uid, stat_ids, context=context))
return res
def on_change_campaign_name(self, cr, uid, ids, name, context=None):
if name:
mass_mailing_campaign = self.browse(cr, uid, ids, context=context)
if mass_mailing_campaign.campaign_id:
utm_campaign_id = mass_mailing_campaign.campaign_id.id
self.pool['utm.campaign'].write(cr, uid, [utm_campaign_id], {'name': name}, context=context)
else:
utm_campaign_id = self.pool['utm.campaign'].create(cr, uid, {'name': name}, context=context)
return {'value': {'campaign_id': utm_campaign_id}}
class MassMailing(osv.Model):
""" MassMailing models a wave of emails for a mass mailign campaign.
@@ -281,6 +332,8 @@ class MassMailing(osv.Model):
_period_number = 6
_order = 'sent_date DESC'
_inherit = ['utm.mixin']
def __get_bar_values(self, cr, uid, obj, domain, read_fields, value_field, groupby_field, date_begin, context=None):
""" Generic method to generate data for bar chart values using SparklineBarWidget.
This method performs obj.read_group(cr, uid, domain, read_fields, groupby_field).
@@ -370,6 +423,21 @@ class MassMailing(osv.Model):
res.append(('mail.mass_mailing.contact', _('Mailing List')))
return res
def _get_clicks_ratio(self, cr, uid, ids, name, arg, context=None):
res = dict.fromkeys(ids, 0)
cr.execute("""
SELECT COUNT(DISTINCT(stats.id)) AS nb_mails, COUNT(DISTINCT(clicks.mail_stat_id)) AS nb_clicks, stats.mass_mailing_id AS id
FROM mail_mail_statistics AS stats
LEFT OUTER JOIN website_links_click AS clicks ON clicks.mail_stat_id = stats.id
WHERE stats.mass_mailing_id IN %s
GROUP BY stats.mass_mailing_id
""", (tuple(ids), ))
for record in cr.dictfetchall():
res[record['id']] = 100 * record['nb_clicks'] / record['nb_mails']
return res
# indirections for inheritance
_mailing_model = lambda self, *args, **kwargs: self._get_mailing_model(*args, **kwargs)
@@ -388,6 +456,10 @@ class MassMailing(osv.Model):
'mail.mass_mailing.campaign', 'Mass Mailing Campaign',
ondelete='set null',
),
'clicks_ratio': fields.function(
_get_clicks_ratio, string="Number of Clicks",
type="integer",
),
'state': fields.selection(
[('draft', 'Draft'), ('test', 'Tested'), ('done', 'Sent')],
string='Status', required=True, copy=False,
@@ -473,6 +545,12 @@ class MassMailing(osv.Model):
)
}
def mass_mailing_statistics_action(self, cr, uid, ids, context=None):
res = self.pool['ir.actions.act_window'].for_xml_id(cr, uid, 'mass_mailing', 'action_view_mass_mailing_statistics', context=context)
link_click_ids = self.pool['website.links.click'].search(cr, uid, [('mass_mailing_id', 'in', ids)], context=context)
res['domain'] = [('id', 'in', link_click_ids)]
return res
def default_get(self, cr, uid, fields, context=None):
res = super(MassMailing, self).default_get(cr, uid, fields, context=context)
if 'reply_to_mode' in fields and not 'reply_to_mode' in res and res.get('mailing_model'):
@@ -490,6 +568,16 @@ class MassMailing(osv.Model):
'contact_ab_pc': 100,
}
def onchange_mass_mailing_campaign_id(self, cr, uid, id, mass_mailing_campaign_ids, context=None):
if mass_mailing_campaign_ids:
mass_mailing_campaign = self.pool['mail.mass_mailing.campaign'].browse(cr, uid, mass_mailing_campaign_ids, context=context)
dic = {'campaign_id': mass_mailing_campaign[0].campaign_id.id,
'source_id': mass_mailing_campaign[0].source_id.id,
'medium_id': mass_mailing_campaign[0].medium_id.id}
print dic
return {'value': dic}
#------------------------------------------------------
# Technical stuff
#------------------------------------------------------
@@ -559,6 +647,7 @@ class MassMailing(osv.Model):
'res_model': 'mail.mass_mailing',
'res_id': copy_id,
'context': context,
'flags': {'initial_mode': 'edit'},
}
return False
@@ -622,7 +711,7 @@ class MassMailing(osv.Model):
composer_values = {
'author_id': author_id,
'attachment_ids': [(4, attachment.id) for attachment in mailing.attachment_ids],
'body': mailing.body_html,
'body': self.convert_link(cr, uid, [mailing.id], context=context)[mailing.id],
'subject': mailing.name,
'model': mailing.mailing_model,
'email_from': mailing.email_from,
@@ -638,3 +727,43 @@ class MassMailing(osv.Model):
self.pool['mail.compose.message'].send_mail(cr, uid, [composer_id], context=comp_ctx)
self.write(cr, uid, [mailing.id], {'sent_date': fields.datetime.now(), 'state': 'done'}, context=context)
return True
def convert_link(self, cr, uid, ids, context=None):
website_links = self.pool['website.links']
res = {}
for mass_mailing in self.browse(cr, uid, ids, context=context):
res[mass_mailing.id] = mass_mailing.body_html if mass_mailing.body_html else ''
for long_url in re.findall(URL_REGEX, res[mass_mailing.id]):
utm_object = mass_mailing.mass_mailing_campaign_id if mass_mailing.mass_mailing_campaign_id else mass_mailing
vals = {'url': long_url}
if utm_object.campaign_id:
vals['campaign_id'] = utm_object.campaign_id.id
if utm_object.source_id:
vals['source_id'] = utm_object.source_id.id
if utm_object.medium_id:
vals['medium_id'] = utm_object.medium_id.id
link_id = website_links.create(cr, uid, vals, context=context)
shorten_url = website_links.browse(cr, uid, link_id, context=context)[0].short_url
if shorten_url:
res[mass_mailing.id] = res[mass_mailing.id].replace(long_url, shorten_url)
return res
class MailMail(models.Model):
_inherit = ['mail.mail']
@api.model
def send_get_mail_body(self, mail, partner=None):
"""Override to add Statistic_id in shorted urls """
if mail.mailing_id and mail.body_html:
urls = re.findall(URL_REGEX, mail.body_html)
for url in urls:
mail.body_html = mail.body_html.replace(url, url + '/m/' + str(mail.statistics_ids[0].id))
return super(MailMail, self).send_get_mail_body(mail, partner=partner)
@@ -19,7 +19,9 @@
#
##############################################################################
from openerp.osv import osv, fields
import openerp
from openerp.osv import fields, osv
from openerp import models, api, _
class MailMailStats(osv.Model):
@@ -63,6 +65,7 @@ class MailMailStats(osv.Model):
'opened': fields.datetime('Opened', help='Date when the email has been opened the first time'),
'replied': fields.datetime('Replied', help='Date when this email has been replied for the first time.'),
'bounced': fields.datetime('Bounced', help='Date when this email has bounced.'),
'links_click_ids': fields.one2many('website.links.click', 'mail_stat_id', 'Links click'),
}
_defaults = {
@@ -0,0 +1,10 @@
from openerp import fields
from openerp import models
class website_links_click(models.Model):
_inherit = "website.links.click"
mail_stat_id = fields.Many2one('mail.mail.statistics', string='Mail Statistics')
mass_mailing_id = fields.Many2one('mail.mass_mailing', string='Mass Mailing')
mass_mailing_campaign_id = fields.Many2one('mail.mass_mailing.campaign', string='Mass Mailing Campaign')
+53 -21
View File
@@ -161,6 +161,12 @@
</field>
</record>
<record model="ir.actions.act_window" id="action_view_mass_mailing_statistics">
<field name="name">Statistics of Clicks</field>
<field name="res_model">website.links.click</field>
<field name="view_mode">graph</field>
</record>
<record model="ir.actions.act_window" id="action_view_mass_mailing_contacts">
<field name="name">Mailing List Subscribers</field>
<field name="res_model">mail.mass_mailing.contact</field>
@@ -183,7 +189,7 @@
</record>
<menuitem name="Contacts" id="menu_email_mass_mailing_contacts"
parent="mass_mailing_campaign" sequence="4"
parent="mass_mailing_campaign" sequence="4" groups="base.group_no_one"
action="action_view_mass_mailing_contacts"/>
<!-- MASS MAILING LIST -->
@@ -337,8 +343,11 @@
type="action" class="oe_stat_button">
<field name="replied_ratio" string="Replied" widget="percentpie"/>
</button>
<button name="%(action_view_mail_mail_statistics_mailing)d"
type="action" class="oe_stat_button oe_inline">
<button name="mass_mailing_statistics_action"
type="object" class="oe_stat_button">
<field name="clicks_ratio" string="clicks" widget="percentpie"/>
</button>
<button name="%(action_view_mass_mailing_contacts)d" type="action" class="oe_stat_button oe_inline">
<field name="opened_daily" string="Opened Daily" widget="barchart"/>
</button>
<button name="%(action_view_mail_mail_statistics_mailing)d"
@@ -405,7 +414,7 @@
<field name="sent_date" readonly="1"/>
</group>
<group string="Campaign">
<field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign"/>
<field name="mass_mailing_campaign_id" groups="mass_mailing.group_mass_mailing_campaign" string="Campaign" on_change="onchange_mass_mailing_campaign_id(mass_mailing_campaign_id)"/>
<label for="contact_ab_pc"/>
<div>
<field name="contact_ab_pc" class="oe_inline"/> %
@@ -413,6 +422,13 @@
</group>
</group>
</page>
<page string="Tracking" groups="base.group_no_one">
<group>
<field name="campaign_id" attrs="{'invisible': True}" />
<field name="medium_id" />
<field name="source_id" />
</group>
</page>
</notebook>
</sheet>
</form>
@@ -450,7 +466,8 @@
</div>
<div style="display: inline-block; vertical-align: top;">
<strong>Opened</strong> <field name="opened_ratio"/> %<br />
<strong>Replied</strong> <field name="replied_ratio"/> %
<strong>Replied</strong> <field name="replied_ratio"/> % <br />
<strong>Clicks</strong> <field name="clicks_ratio"/> % <br />
</div>
</div>
</div>
@@ -551,7 +568,7 @@
<field name="model">mail.mass_mailing.campaign</field>
<field name="arch" type="xml">
<search string="Mass Mailing Campaigns">
<field name="name" string="Campaigns"/>
<field name="name"/>
<field name="category_ids"/>
<field name="user_id"/>
<group expand="0" string="Group By">
@@ -589,7 +606,7 @@
<sheet>
<group>
<group>
<field name="name"/>
<field name="name" string="Campaign Name" on_change="on_change_campaign_name(name)"/>
<field name="user_id"/>
<field name="category_ids" widget="many2many_tags"/>
</group>
@@ -609,22 +626,36 @@
type="action" class="oe_stat_button oe_inline">
<field name="replied_ratio" widget="percentpie" string="Replied"/>
</button>
<button name="mass_mailing_statistics_action"
type="object" class="oe_stat_button">
<field name="clicks_ratio" string="clicks" widget="percentpie"/>
</button>
</div>
</group>
</group>
<strong>Related Mailing(s)</strong>
<field name="mass_mailing_ids" readonly="1" string="Related Mailing(s)">
<tree>
<field name="name"/>
<field name="sent_date"/>
<field name="state"/>
<field name="delivered"/>
<field name="opened"/>
<field name="replied"/>
<field name="bounced"/>
<button name="action_duplicate" type="object" string="Duplicate"/>
</tree>
</field>
<notebook>
<page string="Related Mailing(s)">
<field name="mass_mailing_ids" readonly="1" string="Related Mailing(s)">
<tree>
<field name="name"/>
<field name="sent_date"/>
<field name="state"/>
<field name="delivered"/>
<field name="opened"/>
<field name="replied"/>
<field name="bounced"/>
<button name="action_duplicate" type="object" string="Duplicate"/>
</tree>
</field>
</page>
<page string="Tracking">
<group>
<field name="campaign_id" attrs="{'invisible': True}"/>
<field name="medium_id" />
<field name="source_id" />
</group>
</page>
</notebook>
</sheet>
</form>
</field>
@@ -673,7 +704,8 @@
</div>
<div style="display: inline-block; vertical-align: top;">
<strong>Opened</strong> <field name="opened_ratio"/> %<br />
<strong>Replied</strong> <field name="replied_ratio"/> %
<strong>Replied</strong> <field name="replied_ratio"/> % <br />
<strong>Clicks</strong> <field name="clicks_ratio"/> % <br />
</div>
</div>
</div>
+1 -1
View File
@@ -23,7 +23,7 @@ from openerp.osv import osv, fields
class sale_order(osv.osv):
_name = "sale.order"
_inherit = ['sale.order', 'crm.tracking.mixin']
_inherit = ['sale.order', 'utm.mixin']
_columns = {
'tag_ids': fields.many2many('crm.lead.tag', 'sale_order_tag_rel', 'order_id', 'tag_id', 'Tags'),
'opportunity_id': fields.many2one('crm.lead', 'Opportunity', domain="[('type', '=', 'opportunity')]")
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import models
+16
View File
@@ -0,0 +1,16 @@
{
'name': 'UTM Trackers',
'category': 'Hidden',
'description': """
Enable UTM trackers in shared links.
=====================================================
""",
'version': '1.0',
'depends':['marketing'],
'data' : [
'security/ir.model.access.csv',
'views/utm.xml',
],
'demo': ['utm_demo.xml'],
'auto_install': True,
}
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import utm
+99
View File
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-today Odoo SA (<http://www.odoo.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/>.
#
##############################################################################
from openerp.osv import osv, fields
from openerp.http import request
class utm_medium(osv.Model):
# OLD crm.case.channel
_name = "utm.medium"
_description = "Channels"
_order = 'name'
_columns = {
'name': fields.char('Channel Name', required=True),
'active': fields.boolean('Active'),
}
_defaults = {
'active': lambda *a: 1,
}
class utm_campaign(osv.Model):
# OLD crm.case.resource.type
_name = "utm.campaign"
_description = "Campaign"
_rec_name = "name"
_columns = {
'name': fields.char('Campaign Name', required=True, translate=True),
}
class utm_source(osv.Model):
_name = "utm.source"
_description = "Source"
_rec_name = "name"
_columns = {
'name': fields.char('Source Name', required=True, translate=True),
}
class utm_mixin(osv.AbstractModel):
"""Mixin class for objects which can be tracked by marketing. """
_name = 'utm.mixin'
_columns = {
'campaign_id': fields.many2one('utm.campaign', 'Campaign', # old domain ="['|',('team_id','=',team_id),('team_id','=',False)]"
help="This is a name that helps you keep track of your different campaign efforts Ex: Fall_Drive, Christmas_Special"),
'source_id': fields.many2one('utm.source', 'Source', help="This is the source of the link Ex: Search Engine, another domain, or name of email list"),
'medium_id': fields.many2one('utm.medium', 'Medium', help="This is the method of delivery. Ex: Postcard, Email, or Banner Ad", oldname='channel_id'),
}
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, fname in self.tracking_fields():
field = self._fields[fname]
value = vals.get(fname) or (request and request.httprequest.cookies.get(key)) # params.get should be always in session by the dispatch from ir_http
if field.type == 'many2one' and isinstance(value, basestring):
# if we receive a string for a many2one, we search/create the id
if value:
Model = self.pool[field.comodel_name]
rel_id = Model.name_search(cr, uid, value, context=context)
if rel_id:
rel_id = rel_id[0][0]
else:
rel_id = Model.create(cr, uid, {'name': value}, context=context)
vals[fname] = rel_id
else:
# Here the code for others cases that many2one
vals[fname] = 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),
}
+4
View File
@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_utm_campaign,access_utm_campaign,model_utm_campaign,,1,1,1,1
access_utm_medium,access_utm_medium,model_utm_medium,,1,1,1,1
access_utm_source,access_utm_source,model_utm_source,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_utm_campaign access_utm_campaign model_utm_campaign 1 1 1 1
3 access_utm_medium access_utm_medium model_utm_medium 1 1 1 1
4 access_utm_source access_utm_source model_utm_source 1 1 1 1
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- UTM Campain -->
<record model="utm.campaign" id="utm_campaign_fall_drive">
<field name="name">Fall Drive</field>
</record>
<record model="utm.campaign" id="utm_campaign_christmas_special">
<field name="name">Christmas Special</field>
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_services">
<field name="name">Email Campaign - Services</field>
</record>
<record model="utm.campaign" id="utm_campaign_email_campaign_products">
<field name="name">Email Campaign - Products</field>
</record>
<!-- UTM Source -->
<record model="utm.source" id="utm_source_search_engine">
<field name="name">Search engine</field>
</record>
<record model="utm.source" id="utm_source_mailing">
<field name="name">Mailing Partner</field>
</record>
<record model="utm.source" id="utm_source_newsletter">
<field name="name">Newsletter</field>
</record>
<record model="utm.source" id="utm_source_facebook">
<field name="name">Facebook</field>
</record>
<record model="utm.source" id="utm_source_twitter">
<field name="name">Twitter</field>
</record>
<!-- UTM Medium -->
<record model="utm.medium" id="utm_medium_website">
<field name="name">Website</field>
</record>
<record model="utm.medium" id="utm_medium_phone">
<field name="name">Phone</field>
</record>
<record model="utm.medium" id="utm_medium_direct">
<field name="name">Direct</field>
</record>
<record model="utm.medium" id="utm_medium_email">
<field name="name">Email</field>
</record>
<record model="utm.medium" id="utm_medium_banner">
<field name="name">Banner Ads</field>
</record>
<record model="utm.medium" id="utm_medium_twitter">
<field name="name">Twitter Ads</field>
</record>
<record model="utm.medium" id="utm_medium_facebook">
<field name="name">Facebook Ads</field>
</record>
<record model="utm.medium" id="utm_medium_television">
<field name="name">Television</field>
</record>
<record model="utm.medium" id="utm_medium_google_adwords">
<field name="name">Google Adwords</field>
</record>
</data>
</openerp>
+112
View File
@@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<menuitem name="UTMs" id="marketing_utm"
parent="base.marketing_menu" sequence="99"/>
<!-- utm.campaign -->
<record model="ir.ui.view" id="utm_campaign_tree">
<field name="name">utm.campaign.tree</field>
<field name="model">utm.campaign</field>
<field name="arch" type="xml">
<tree string="Campaign">
<field name="name"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="utm_campaign_form">
<field name="name">utm.campaign.form</field>
<field name="model">utm.campaign</field>
<field name="arch" type="xml">
<form string="Campaign">
<group>
<field name="name"/>
</group>
</form>
</field>
</record>
<record id="utm_campaign_act" model="ir.actions.act_window">
<field name="name">Campaigns</field>
<field name="res_model">utm.campaign</field>
<field name="view_type">form</field>
<field name="view_id" ref="utm_campaign_tree"/>
</record>
<menuitem action="utm_campaign_act" id="menu_utm_campaign_act" sequence="4"
groups="base.group_no_one" parent="marketing_utm"/>
<!-- utm.medium -->
<record id="utm_medium_view_tree" model="ir.ui.view">
<field name="name">utm.medium.tree</field>
<field name="model">utm.medium</field>
<field name="arch" type="xml">
<tree string="Medium">
<field name="name"/>
<field name="active"/>
</tree>
</field>
</record>
<record id="utm_medium_view_form" model="ir.ui.view">
<field name="name">utm.medium.form</field>
<field name="model">utm.medium</field>
<field name="arch" type="xml">
<form string="Channel">
<group>
<field name="name"/>
<field name="active"/>
</group>
</form>
</field>
</record>
<record id="utm_medium_action" model="ir.actions.act_window">
<field name="name">Medium</field>
<field name="res_model">utm.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 medium.
</p>
</field>
</record>
<menuitem action="utm_medium_action" id="menu_utm_medium" parent="marketing_utm" sequence="4" groups="base.group_no_one"/>
<!-- utm.source -->
<record id="utm_source_view_tree" model="ir.ui.view">
<field name="name">utm.source.tree</field>
<field name="model">utm.source</field>
<field name="arch" type="xml">
<tree string="Medium">
<field name="name"/>
</tree>
</field>
</record>
<record id="utm_source_view_form" model="ir.ui.view">
<field name="name">utm.source.form</field>
<field name="model">utm.source</field>
<field name="arch" type="xml">
<form string="Channel">
<group>
<field name="name"/>
</group>
</form>
</field>
</record>
<record id="utm_source_action" model="ir.actions.act_window">
<field name="name">Sources</field>
<field name="res_model">utm.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>
</field>
</record>
<menuitem action="utm_source_action" id="menu_utm_source" parent="marketing_utm" sequence="4" groups="base.group_no_one"/>
</data>
</openerp>
@@ -9,7 +9,7 @@
website.EditorBarContent = openerp.Widget.extend({
start: function() {
var self = this;
self.$el.on('click', 'a', function(ev) {
self.$el.on('click', 'a[data-action]', function(ev) {
ev.preventDefault();
var $content_item = $(this);
self[$content_item.data('action')]();
+3
View File
@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
import models
import controller
+19
View File
@@ -0,0 +1,19 @@
{
'name': 'Link Tracker',
'category': 'Hidden',
'description': """
Create short and trackable URLs.
=====================================================
""",
'version': '1.0',
'depends':['website','marketing', 'utm'],
'data' : [
'views/website_links.xml',
'views/website_links_template.xml',
'views/website_links_graphs.xml',
'security/ir.model.access.csv',
],
'qweb': ['static/src/xml/*.xml'],
'auto_install': True,
}
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import main
+45
View File
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
import werkzeug
from openerp.addons.web import http
from openerp.http import request
class Website_Url(http.Controller):
@http.route('/website_links/new', type='json', auth='user', methods=['POST'])
def create_shorten_url(self, **post):
if 'url' not in post or post['url'] == '':
return {'error': 'empty_url'}
return request.env['website.links'].create(post).read()
@http.route('/r', type='http', auth='user', website=True)
def shorten_url(self, **post):
return request.website.render("website_links.page_shorten_url", post)
@http.route('/website_links/add_code', type='json', auth='user')
def add_code(self, **post):
link_id = request.env['website.links.code'].search([('code', '=', post['init_code'])], limit=1).link_id.id
new_code = request.env['website.links.code'].search_count([('code', '=', post['new_code']), ('link_id', '=', link_id)])
if new_code > 0:
return new_code.read()
else:
return request.env['website.links.code'].create({'code': post['new_code'], 'link_id': link_id})[0].read()
@http.route('/website_links/recent_links', type='json', auth='user')
def recent_links(self, **post):
return request.env['website.links'].recent_links(post['filter'], post['limit'])
@http.route('/r/<string:code>+', type='http', auth="user", website=True)
def statistics_shorten_url(self, code, **post):
code = request.env['website.links.code'].search([('code', '=', code)], limit=1)
if code:
return request.website.render("website_links.graphs", code.link_id.read()[0])
else:
return werkzeug.utils.redirect('', 301)
@http.route('/r/<string:code>', type='http', auth='none', website=True)
def full_url_redirect(self, code, **post):
request.env['website.links.click'].add_click(code, request.httprequest.remote_addr, request.session['geoip'].get('country_code'), stat_id=False)
redirect_url = request.env['website.links'].get_url_from_code(code)
return werkzeug.utils.redirect(redirect_url or '', 301)
+2
View File
@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
import website_links
@@ -0,0 +1,237 @@
# -*- coding: utf-8 -*-
import datetime
import random
import string
from lxml.html import parse
from urllib import urlencode
from urllib2 import urlopen
from urlparse import urljoin
from urlparse import urlparse
from openerp import models, fields, api, _
def VALIDATE_URL(url):
if urlparse(url).scheme not in ('http', 'https', 'ftp', 'ftps'):
return 'http://' + url
return url
class website_links(models.Model):
"""website_links allow users to wrap any URL into a short and trackable URL
via a frontend and backend interface. website_links counts clicks on each tracked link.
This module is also used by mass_mailing, where each link in mail_mail html_body are converted into
a trackable link to get the click-through rate of each mass_mailing."""
_name = "website.links"
_rec_name = "short_url"
_inherit = ['utm.mixin']
url = fields.Char(string='Target URL', required=True)
count = fields.Integer(string='Number of Clicks', compute='_compute_count', store=True)
short_url = fields.Char(string='Tracked URL', compute='_compute_short_url')
link_click_ids = fields.One2many('website.links.click', 'link_id', string='Clicks')
title = fields.Char(string='Page Title', store=True)
favicon = fields.Char(string='Favicon', compute='_compute_favicon', store=True)
link_code_ids = fields.One2many('website.links.code', 'link_id', string='Codes')
code = fields.Char(string='Short URL code', compute='_compute_code')
redirected_url = fields.Char(string='Redirected URL', compute='_compute_redirected_url')
short_url_host = fields.Char(string='Host of the short URL', compute='_compute_short_url_host')
icon_src = fields.Char(string='Favicon Source', compute='_compute_icon_src')
@api.one
@api.depends('link_click_ids.link_id')
def _compute_count(self):
self.count = len(self.link_click_ids)
@api.one
@api.depends('code')
def _compute_short_url(self):
base_url = self.env['ir.config_parameter'].get_param('web.base.url')
self.short_url = urljoin(base_url, '/r/%(code)s' % {'code': self.code})
@api.one
def _compute_short_url_host(self):
self.short_url_host = self.env['ir.config_parameter'].get_param('web.base.url') + '/r/'
@api.one
def _compute_code(self):
record = self.env['website.links.code'].search([('link_id', '=', self.id)], limit=1, order='id DESC')
self.code = record.code
@api.one
@api.depends('favicon')
def _compute_icon_src(self):
self.icon_src = 'data:image/png;base64,' + self.favicon
@api.one
@api.depends('url')
def _compute_redirected_url(self):
parsed = urlparse(self.url)
utms = {}
for key, field in self.env['utm.mixin'].tracking_fields():
attr = getattr(self, field).name
if attr:
utms[key] = attr
self.redirected_url = '%s://%s%s?%s%s#%s' % (parsed.scheme, parsed.netloc, parsed.path, urlencode(utms), parsed.query, parsed.fragment)
@api.model
@api.depends('url')
def _get_title_from_url(self, url):
try:
page = urlopen(url, timeout=5)
p = parse(page)
title = p.find('.//title').text
except:
title = url
return title
@api.one
@api.depends('url')
def _compute_favicon(self):
try:
icon = urlopen('http://www.google.com/s2/favicons?domain=' + self.url, timeout=5).read()
icon_base64 = icon.encode('base64').replace("\n", "")
except:
icon_base64 = 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAACiElEQVQ4EaVTzU8TURCf2tJuS7tQtlRb6UKBIkQwkRRSEzkQgyEc6lkOKgcOph78Y+CgjXjDs2i44FXY9AMTlQRUELZapVlouy3d7kKtb0Zr0MSLTvL2zb75eL838xtTvV6H/xELBptMJojeXLCXyobnyog4YhzXYvmCFi6qVSfaeRdXdrfaU1areV5KykmX06rcvzumjY/1ggkR3Jh+bNf1mr8v1D5bLuvR3qDgFbvbBJYIrE1mCIoCrKxsHuzK+Rzvsi29+6DEbTZz9unijEYI8ObBgXOzlcrx9OAlXyDYKUCzwwrDQx1wVDGg089Dt+gR3mxmhcUnaWeoxwMbm/vzDFzmDEKMMNhquRqduT1KwXiGt0vre6iSeAUHNDE0d26NBtAXY9BACQyjFusKuL2Ry+IPb/Y9ZglwuVscdHaknUChqLF/O4jn3V5dP4mhgRJgwSYm+gV0Oi3XrvYB30yvhGa7BS70eGFHPoTJyQHhMK+F0ZesRVVznvXw5Ixv7/C10moEo6OZXbWvlFAF9FVZDOqEABUMRIkMd8GnLwVWg9/RkJF9sA4oDfYQAuzzjqzwvnaRUFxn/X2ZlmGLXAE7AL52B4xHgqAUqrC1nSNuoJkQtLkdqReszz/9aRvq90NOKdOS1nch8TpL555WDp49f3uAMXhACRjD5j4ykuCtf5PP7Fm1b0DIsl/VHGezzP1KwOiZQobFF9YyjSRYQETRENSlVzI8iK9mWlzckpSSCQHVALmN9Az1euDho9Xo8vKGd2rqooA8yBcrwHgCqYR0kMkWci08t/R+W4ljDCanWTg9TJGwGNaNk3vYZ7VUdeKsYJGFNkfSzjXNrSX20s4/h6kB81/271ghG17l+rPTAAAAAElFTkSuQmCC'
self.favicon = icon_base64
@api.multi
def action_view_statistics(self):
action = self.env['ir.actions.act_window'].for_xml_id('website_links', 'action_view_click_statistics')
action['domain'] = [('link_id', '=', self.id)]
return action
@api.multi
def action_visit_page(self):
return {
'name': _("Visit Webpage"),
'type': 'ir.actions.act_url',
'url': self.url,
'target': 'new',
}
@api.model
def recent_links(self, filter, limit):
if filter == 'newest':
return self.search_read([], order='create_date DESC', limit=limit)
elif filter == 'most-clicked':
return self.search_read([('count', '!=', 0)], order='count DESC', limit=limit)
elif filter == 'recently-used':
return self.search_read([('count', '!=', 0)], order='write_date DESC', limit=limit)
else:
return {'Error': "This filter doesn't exist."}
@api.model
def create(self, vals):
if 'url' not in vals:
raise ValueError('URL field required')
else:
vals['url'] = VALIDATE_URL(vals['url'])
search_domain = [('url', '=', vals['url'])]
if 'campaign_id' in vals:
search_domain.append(('campaign_id', '=', vals['campaign_id']))
if 'channel_id' in vals:
search_domain.append(('channel_id', '=', vals['channel_id']))
if 'source_id' in vals:
search_domain.append(('source_id', '=', vals['source_id']))
result = self.search(search_domain, limit=1)
if result:
return result
if not vals.get('title'):
vals['title'] = self._get_title_from_url(vals['url'])
link = super(website_links, self).create(vals)
code = self.env['website.links.code'].get_random_code_string()
self.env['website.links.code'].create({'code': code, 'link_id': link.id})
return link
@api.model
def get_url_from_code(self, code, context=None):
code_rec = self.env['website.links.code'].sudo().search([('code', '=', code)])
if not code_rec:
return None
return code_rec.link_id.redirected_url
sql_constraints = [
('url_utms_uniq', 'unique (url, campaign_id, medium_id, source_id)', 'The URL and the UTM combination must be unique')
]
class website_links_code(models.Model):
_name = "website.links.code"
code = fields.Char(string='Short URL Code', store=True)
link_id = fields.Many2one('website.links', 'Link', required=True, ondelete='cascade')
@api.model
def get_random_code_string(self):
size = 3
while True:
code_proposition = ''.join(random.choice(string.letters + string.digits) for _ in range(size))
if self.search([('code', '=', code_proposition)]):
size += 1
else:
return code_proposition
_sql_constraints = [
('code', 'unique( code )', 'Code must be unique.')
]
class website_links_click(models.Model):
_name = "website.links.click"
_rec_name = "link_id"
click_date = fields.Date(string='Create Date')
link_id = fields.Many2one('website.links', 'Link', required=True, ondelete='cascade')
ip = fields.Char(string='Internet Protocol')
country_id = fields.Many2one('res.country', 'Country')
@api.model
def add_click(self, code, ip, country_code, stat_id=False):
self = self.sudo()
code_rec = self.env['website.links.code'].search([('code', '=', code)])
if not code_rec:
return None
again = self.search_count([('link_id', '=', code_rec.link_id.id), ('ip', '=', ip)])
if not again:
country_record = self.env['res.country'].search([('code', '=', country_code)], limit=1)
vals = {
'link_id': code_rec.link_id.id,
'create_date': datetime.date.today(),
'ip': ip,
'country_id': country_record.id,
'mail_stat_id': stat_id
}
if stat_id:
mail_stat = self.env['mail.mail.statistics'].search([('id', '=', stat_id)])
if mail_stat.mass_mailing_campaign_id:
vals['mass_mailing_campaign_id'] = mail_stat.mass_mailing_campaign_id.id
if mail_stat.mass_mailing_id:
vals['mass_mailing_id'] = mail_stat.mass_mailing_id.id
self.create(vals)
@@ -0,0 +1,10 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_website_links_user,website.links,model_website_links,base.group_user,1,0,0,0
access_website_links_manager,website.links,model_website_links,base.group_erp_manager,1,1,1,1
access_website_links_public,website.links,model_website_links,base.group_public,1,0,0,0
access_website_links_code_user,website.links.code,model_website_links_code,base.group_user,1,0,0,0
access_website_links_code_manager,website.links.code,model_website_links_code,base.group_erp_manager,1,1,1,1
access_website_links_code_public,website.links.code,model_website_links_code,base.group_public,1,0,0,0
access_website_links_click_user,website.links.click,model_website_links_click,base.group_user,1,0,0,0
access_website_links_click_manager,website.links.click,model_website_links_click,base.group_erp_manager,1,1,1,1
access_website_links_click_public,website.links.click,model_website_links_click,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_website_links_user website.links model_website_links base.group_user 1 0 0 0
3 access_website_links_manager website.links model_website_links base.group_erp_manager 1 1 1 1
4 access_website_links_public website.links model_website_links base.group_public 1 0 0 0
5 access_website_links_code_user website.links.code model_website_links_code base.group_user 1 0 0 0
6 access_website_links_code_manager website.links.code model_website_links_code base.group_erp_manager 1 1 1 1
7 access_website_links_code_public website.links.code model_website_links_code base.group_public 1 0 0 0
8 access_website_links_click_user website.links.click model_website_links_click base.group_user 1 0 0 0
9 access_website_links_click_manager website.links.click model_website_links_click base.group_erp_manager 1 1 1 1
10 access_website_links_click_public website.links.click model_website_links_click base.group_public 1 0 0 0
@@ -0,0 +1,57 @@
.no-link-style {
color: black;
text-decoration: none;
}
.required-form-control {
background-color: #CECDFF;
}
#filters li a,
#filters li.active a,
#filters li.active a.active,
#filters li.active a:hover,
#filters li.active a:focus,
#filters li a:hover {
padding: 0px 5px;
border-radius: 0px;
border: 0px;
border-color: transparent;
border-right: 1px solid #999;
padding-bottom: 0;
background-color: #FFFFFF;
}
#filters li.active a {
color: #999;
}
#filters li:last-child a,
#filters li:last-child a:hover,
#filters li:last-child a:focus {
border-right: 0px;
}
.nav-tabs-inline {
float: left;
display: inline;
font-size: 14px;
border-color: transparent;
}
#o_website_links_recent_links {
min-height:30em;
}
.o_website_links_code_error {
display:none;
color:red;
font-weight:bold;
}
.truncate_text {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 500px;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,377 @@
(function () {
'use strict';
openerp.website.if_dom_contains('div.o_website_links_create_tracked_url', function() {
var QWeb = openerp.qweb;
var _t = openerp._t;
openerp.website_links = {};
openerp.website_links.SelectBox = openerp.Widget.extend({
init: function(obj) {
this.obj = openerp.website.session.model(obj);
},
start: function(element, placeholder) {
var self = this;
this.element = element;
this.placeholder = placeholder;
this.fetch_objects().then(function(results) {
self.objects = results;
element.select2({
placeholder: self.placeholder,
allowClear: true,
createSearchChoice:function(term, data) {
if(self.object_exists(term)) { return null; }
return {id:term, text:_.str.sprintf("Create '%s'", term)};
},
createSearchChoicePosition: 'bottom',
multiple: false,
data: self.objects,
});
element.on('change', function(e) {
self.on_change(e);
});
});
},
fetch_objects: function() {
return this.obj.call('search_read', [[]]).then(function(result) {
return _.map(result, function(val) {
return {id: val.id, text:val.name};
})
});
},
object_exists: function(query) {
return _.find(this.objects, function(val) {
return val.text.toLowerCase() == query.toLowerCase();
}) != undefined;
},
on_change: function(e) {
if(e.added && _.isString(e.added.id)) {
this.create_object(e.added.id);
}
},
create_object: function(name) {
var self = this;
return this.obj.call('create', [{name:name}]).then(function(record) {
self.element.attr('value', record);
})
},
});
openerp.website_links.RecentLinkBox = openerp.Widget.extend({
template: 'website_links.RecentLink',
events: {
'click .btn_shorten_url_clipboard':'toggle_copy_button',
'click .o_website_links_edit_code':'edit_code',
'click .o_website_links_ok_edit':function(e) {
e.preventDefault();
this.submit_code();
},
'click .o_website_links_cancel_edit':function(e) {
e.preventDefault();
this.cancel_edit();
},
'submit #o_website_links_edit_code_form':function(e) {
e.preventDefault();
this.submit_code();
},
},
init: function(parent, link_obj) {
this._super(parent);
this.link_obj = link_obj;
this.animating_copy = false;
},
start: function() {
new ZeroClipboard(this.$('.btn_shorten_url_clipboard'));
},
toggle_copy_button: function() {
var self = this;
if(!this.animating_copy) {
this.animating_copy = true;
var top = this.$('.o_website_links_short_url').position().top;
this.$('.o_website_links_short_url').clone()
.css('position', 'absolute')
.css('left', 15)
.css('top', top-2)
.css('z-index', 2)
.removeClass('o_website_links_short_url')
.addClass('animated-link')
.insertAfter(this.$('.o_website_links_short_url'))
.animate({
opacity: 0,
top: "-=20",
}, 500, function() {
self.$('.animated-link').remove();
self.animating_copy = false;
});
}
},
remove: function() {
this.getParent().remove_link(this);
},
notification: function(message) {
this.$('.notification').append('<strong>' + message + '</strong>');
},
edit_code: function() {
var init_code = this.$('#o_website_links_code').html();
this.$('#o_website_links_code').html("<form style='display:inline;' id='o_website_links_edit_code_form'><input type='hidden' id='init_code' value='" + init_code + "'/><input type='text' id='new_code' value='" + init_code + "'/></form>");
this.$('.o_website_links_edit_code').hide();
this.$('.copy-to-clipboard').hide();
this.$('.o_website_links_edit_tools').show();
},
cancel_edit: function() {
this.$('.o_website_links_edit_code').show();
this.$('.copy-to-clipboard').show();
this.$('.o_website_links_edit_tools').hide();
self.$('.o_website_links_code_error').hide();
var old_code = this.$('#o_website_links_edit_code_form #init_code').val();
this.$('#o_website_links_code').html(old_code);
this.$('#code-error').remove();
this.$('#o_website_links_code form').remove();
},
submit_code: function() {
var self = this;
var init_code = this.$('#o_website_links_edit_code_form #init_code').val();
var new_code = this.$('#o_website_links_edit_code_form #new_code').val();
function show_new_code(new_code) {
self.$('.o_website_links_code_error').html('');
self.$('.o_website_links_code_error').hide();
self.$('#o_website_links_code form').remove();
// Show new code
var host = self.$('#o_website_links_host').html();
self.$('#o_website_links_code').html(new_code);
// Update button copy to clipboard
self.$('.btn_shorten_url_clipboard').attr('data-clipboard-text', host + new_code)
// Show action again
self.$('.o_website_links_edit_code').show();
self.$('.copy-to-clipboard').show();
self.$('.o_website_links_edit_tools').hide();
}
if(init_code == new_code) {
show_new_code(new_code);
}
else {
openerp.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
.then(function(result) {
show_new_code(result[0].code);
})
.fail(function(error) {
self.$('.o_website_links_code_error').show();
self.$('.o_website_links_code_error').html("This code is already taken");
}) ;
}
},
});
openerp.website_links.RecentLinks = openerp.Widget.extend({
init: function($element) {
this._super();
},
get_recent_links: function(filter) {
var self = this;
var nb_links = this.getChildren().length;
openerp.jsonRpc('/website_links/recent_links', 'call', {'filter':filter, 'limit':20})
.then(function(result) {
_.each(result.reverse(), function(link) {
self.add_link(link);
});
self.update_notification();
})
.fail(function() {
var message = _t("Unable to get recent links");
self.$el.append("<div class='alert alert-danger'>" + message + "</div>");
});
},
add_link: function(link) {
var nb_links = this.getChildren().length;
var recent_link_box = new openerp.website_links.RecentLinkBox(this, link);
recent_link_box.prependTo(this.$el);
$('.link-tooltip').tooltip();
if(nb_links == 0) {
this.update_notification();
}
},
remove_links: function() {
_.invoke(this.getChildren(), 'remove');
},
remove_link: function(link) {
link.destroy();
},
update_notification: function() {
if(this.getChildren().length == 0) {
var message = _t("You don't have any recent links.");
$('.o_website_links_recent_links_notification').html("<div class='alert alert-info'>" + message + "</div>");
}
else {
$('.o_website_links_recent_links_notification').empty();
}
},
});
openerp.website.ready().done(function() {
ZeroClipboard.config({swfPath: location.origin + "/website_links/static/src/js/ZeroClipboard.swf" });
// UTMS selects widgets
var campaign_select = new openerp.website_links.SelectBox('utm.campaign');
campaign_select.start($("#campaign-select"), 'e.g. Promotion of June, Winter Newsletter, ..');
var medium_select = new openerp.website_links.SelectBox('utm.medium');
medium_select.start($("#channel-select"), 'e.g. Newsletter, Social Network, ..');
var source_select = new openerp.website_links.SelectBox('utm.source');
source_select.start($("#source-select"), 'e.g. Search Engine, Website page, ..');
// Recent Links Widgets
var recent_links;
openerp.website.add_template_file('/website_links/static/src/xml/recent_link.xml')
.then(function() {
recent_links = new openerp.website_links.RecentLinks();
recent_links.appendTo($("#o_website_links_recent_links"));
recent_links.get_recent_links('newest');
$('#filter-newest-links').click(function() {
recent_links.remove_links();
recent_links.get_recent_links('newest');
});
$('#filter-most-clicked-links').click(function() {
recent_links.remove_links();
recent_links.get_recent_links('most-clicked');
});
$('#filter-recently-used-links').click(function() {
recent_links.remove_links();
recent_links.get_recent_links('recently-used');
});
});
// Clipboard Library
var client = new ZeroClipboard($("#btn_shorten_url"));
$("#generated_tracked_link a").click(function() {
$("#generated_tracked_link a").text("Copied").removeClass("btn-primary").addClass("btn-success");
setTimeout(function() {
$("#generated_tracked_link a").text("Copy").removeClass("btn-success").addClass("btn-primary");
}, '5000');
});
$('#url').on('keyup', function(e) {
if($('#btn_shorten_url').hasClass('btn-copy') && e.which != 13) {
$('#btn_shorten_url').removeClass('btn-success btn-copy').addClass('btn-primary').html('Get tracked link');
$('#generated_tracked_link').css('display', 'none');
}
});
var url_copy_animating = false;
$('#btn_shorten_url').click(function() {
if($('#btn_shorten_url').hasClass('btn-copy')) {
if(!url_copy_animating) {
url_copy_animating = true;
$('#generated_tracked_link').clone()
.css('position', 'absolute')
.css('left', '78px')
.css('bottom', '8px')
.css('z-index', 2)
.removeClass('#generated_tracked_link')
.addClass('url-animated-link')
.appendTo($('#generated_tracked_link'))
.animate({
opacity: 0,
bottom: "+=20",
}, 500, function() {
$('.url-animated-link').remove();
url_copy_animating = false;
});
}
}
})
// Add the RecentLinkBox widget and send the form when the user generate the link
$("#o_website_links_link_tracker_form").submit(function(event) {
if($('#btn_shorten_url').hasClass('btn-copy')) {
event.preventDefault();
return;
}
event.preventDefault();
event.stopPropagation();
// Get URL and UTMs
var url = $("#url").val();
var campaign_id = $('#campaign-select').attr('value');
var medium_id = $('#channel-select').attr('value');
var source_id = $('#source-select').attr('value');
var params = {};
params.url = $("#url").val();
if(campaign_id != '') { params.campaign_id = campaign_id; }
if(medium_id != '') { params.medium_id = medium_id; }
if(source_id != '') { params.source_id = source_id; }
$('#btn_shorten_url').text('Generating link...');
openerp.jsonRpc("/website_links/new", 'call', params)
.then(function (result) {
if('error' in result) {
// Handle errors
if(result['error'] == 'empty_url') {
$('.notification').html("<div class='alert alert-danger'>The URL is empty.</div>");
}
else if(result['error'] == 'url_not_found') {
$('.notification').html("<div class='alert alert-danger'>URL not found (404)</div>");
}
else {
$('.notification').html("<div class='alert alert-danger'>An error occur while trying to generate your link. Try again later.</div>");
}
}
else {
// Link generated, clean the form and show the link
var link = result[0];
$('#btn_shorten_url').removeClass('btn-primary').addClass('btn-success btn-copy').html('Copy');
$('#btn_shorten_url').attr('data-clipboard-text', link.short_url);
$('.notification').html('');
$('#generated_tracked_link').html(link.short_url);
$('#generated_tracked_link').css('display', 'inline');
recent_links.add_link(link);
// Clean URL and UTM selects
$('#campaign-select').select2('val', '');
$('#channel-select').select2('val', '');
$('#source-select').select2('val', '');
}
});
});
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
});
});
})();
@@ -0,0 +1,249 @@
(function () {
'use strict';
openerp.website.if_dom_contains('div.o_website_links_chart', function() {
var QWeb = openerp.qweb;
var website = openerp.website;
openerp.website_links_chart = {};
openerp.website_links_chart.BarChart = openerp.Widget.extend({
init: function($element, begin_date, end_date, dates) {
this.$element = $element;
this.begin_date = begin_date;
this.end_date = end_date;
this.number_of_days = this.end_date.diff(this.begin_date, 'days') + 2;
this.dates = dates;
},
start: function() {
var self = this;
// Accessor functions
function getDate(d) { return new Date(d[0]); }
function getNbClicks(d) { return d[1]; }
// Prune tick values for visibility purpose
function getPrunedTickValues(ticks, nb_desired_ticks) {
var nb_values = ticks.length;
var keep_one_of = Math.max(1, Math.floor(nb_values / nb_desired_ticks));
return _.filter(ticks, function(d, i) {
return i % keep_one_of == 0;
});
}
// Fill data for each day (with 0 click for days without data)
var clicks_array = [];
var begin_date_copy = this.begin_date;
for(var i = 0 ; i < this.number_of_days ; i++) {
var date_key = begin_date_copy.format('YYYY-MM-DD');
clicks_array.push([date_key, (date_key in this.dates) ? this.dates[date_key] : 0]);
begin_date_copy.add(1, 'days');
}
// Set title
var nb_clicks = _.reduce(clicks_array, function(total, val) { return total + val[1] ; }, 0);
$(this.$element + ' .title').html(nb_clicks + ' clicks');
// Fit data into the NVD3 scheme
var chart_data = [{}];
chart_data[0]['key'] = '# of clicks';
chart_data[0]['values'] = clicks_array;
nv.addGraph(function() {
var chart = nv.models.lineChart()
.x(function(d) { return getDate(d); })
.y(function(d) { return getNbClicks(d); })
.tooltips(true)
.transitionDuration(0)
.showYAxis(true)
.showXAxis(true);
// Reduce the number of labels on the X axis for visibility
var tick_values = getPrunedTickValues(chart_data[0]['values'], 10);
chart.xAxis
.tickFormat(function(d) { return d3.time.format("%d/%m/%y")(new Date(d)); })
.tickValues(_.map(tick_values, function(d) { return getDate(d).getTime(); }))
.rotateLabels(55);
chart.yAxis
.tickFormat(d3.format("d"))
.ticks(chart_data[0]['values'].length - 1)
d3.select(self.$element + ' svg')
.datum(chart_data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
},
});
openerp.website_links_chart.PieChart = openerp.Widget.extend({
init: function($element, data) {
this.data = data;
this.$element = $element;
},
start: function() {
var self = this;
// Process country data to fit into the NVD3 scheme
var processed_data = [];
for(var i = 0 ; i < this.data.length ; i++) {
var country_name = this.data[i]['country_id'] ? this.data[i]['country_id'][1] : 'Undefined';
processed_data.push({'label':country_name + ' (' + this.data[i]['country_id_count'] + ')', 'value':this.data[i]['country_id_count']});
}
// Set title
$(this.$element + ' .title').html(this.data.length + ' countries');
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.showLabels(true);
d3.select(self.$element + ' svg')
.datum(processed_data)
.transition().duration(1200)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
},
});
website.ready().done(function() {
var self = this;
// Resize the chart when a tab is opened, because NVD3 automatically reduce the size
// of the chart to 5px width when the bootstrap tab is closed.
$(".graph-tabs li a").click(function (e) {
e.preventDefault();
$(this).tab('show');
$(window).trigger('resize'); // Force NVD3 to redraw the chart
});
// Get the code of the link
var code = $('#code').val();
var link_id = $('#link_id').val();
var clicks = website.session.model('website.links.click');
var links_domain = ['link_id', '=', parseInt(link_id)];
var total_clicks = function() {
return clicks.call('search_count', [[links_domain]]);
};
var clicks_by_day = function() {
return clicks.call('read_group', [[links_domain], ['create_date']],
{'groupby':'create_date:day'});
};
var clicks_by_country = function() {
return clicks.call('read_group', [[links_domain], ['country_id']],
{'groupby':'country_id'});
};
var last_week_clicks_by_country = function() {
var interval = moment().subtract(7, 'days').format("YYYY-MM-DD");
return clicks.call('read_group', [[links_domain, ['create_date', '>', interval]], ['country_id']],
{'groupby':'country_id'});
};
var last_month_clicks_by_country = function() {
var interval = moment().subtract(30, 'days').format("YYYY-MM-DD");
return clicks.call('read_group', [[links_domain, ['create_date', '>', interval]], ['country_id']],
{'groupby':'country_id'});
};
$.when(total_clicks(),
clicks_by_day(),
clicks_by_country(),
last_week_clicks_by_country(),
last_month_clicks_by_country())
.done(function(total_clicks, clicks_by_day, clicks_by_country, last_week_clicks_by_country, last_month_clicks_by_country) {
if(total_clicks) {
var formatted_clicks_by_day = {};
var begin_date, end_date;
for(var i = 0 ; i < clicks_by_day.length ; i++) {
var date = moment(clicks_by_day[i]['create_date:day'], "DD MMMM YYYY");
if (i == 0) { begin_date = date; }
if (i == clicks_by_day.length - 1) { end_date = date; }
formatted_clicks_by_day[date.format("YYYY-MM-DD")] = clicks_by_day[i]['create_date_count'];
}
// Process all time line chart data
var now = moment();
var all_time_chart = new openerp.website_links_chart.BarChart('#all_time_clicks_chart', begin_date, now, formatted_clicks_by_day);
all_time_chart.start();
// Process month line chart data
var begin_date = moment().subtract(30, 'days');
var month_chart = new openerp.website_links_chart.BarChart('#last_month_clicks_chart', begin_date, now, formatted_clicks_by_day);
month_chart.start();
// Process week line chart data
var begin_date = moment().subtract(7, 'days');
var week_chart = new openerp.website_links_chart.BarChart('#last_week_clicks_chart', begin_date, now, formatted_clicks_by_day);
week_chart.start();
// Process pie charts
var all_time_pie_chart = new openerp.website_links_chart.PieChart('#all_time_countries_charts', clicks_by_country);
all_time_pie_chart.start();
var last_month_pie_chart = new openerp.website_links_chart.PieChart('#last_month_countries_charts', last_month_clicks_by_country);
last_month_pie_chart.start();
var last_week_pie_chart = new openerp.website_links_chart.PieChart('#last_week_countries_charts', last_week_clicks_by_country);
last_week_pie_chart.start();
}
else {
$('#all_time_charts').prepend('There is no data to show');
$('#last_month_charts').prepend('There is no data to show');
$('#last_week_charts').prepend('There is no data to show');
}
});
// Copy to clipboard link
ZeroClipboard.config({swfPath: location.origin + "/website_links/static/src/js/ZeroClipboard.swf" });
new ZeroClipboard($('.copy-to-clipboard'));
var animating_copy = false;
$('.copy-to-clipboard').on('click', function(e) {
e.preventDefault();
if(!animating_copy) {
animating_copy = true;
$('.o_website_links_short_url').clone()
.css('position', 'absolute')
.css('left', '15px')
.css('bottom', '10px')
.css('z-index', 2)
.removeClass('.o_website_links_short_url')
.addClass('animated-link')
.appendTo($('.o_website_links_short_url'))
.animate({
opacity: 0,
bottom: "+=20",
}, 500, function() {
$('.animated-link').remove();
animating_copy = false;
});
}
});
});
});
})();
@@ -0,0 +1,83 @@
(function () {
'use strict';
openerp.website.ready().done(function() {
openerp.website.if_dom_contains('.o_website_links_edit_code', function() {
// Edit the short URL code
$('.o_website_links_edit_code').on('click', function(e) {
e.preventDefault();
var init_code = $('#o_website_links_code').html();
$('#o_website_links_code').html("<form style='display:inline;' id='edit-code-form'><input type='hidden' id='init_code' value='" + init_code + "'/><input type='text' id='new_code' value='" + init_code + "'/></form>");
$('.o_website_links_edit_code').hide();
$('.copy-to-clipboard').hide();
$('.o_website_links_edit_tools').show();
$('.o_website_links_cancel_edit').on('click', function(e) {
e.preventDefault();
$('.o_website_links_edit_code').show();
$('.copy-to-clipboard').show();
$('.o_website_links_edit_tools').hide();
$('.o_website_links_code_error').hide();
var old_code = $('#edit-code-form #init_code').val();
$('#o_website_links_code').html(old_code);
$('#code-error').remove();
$('#o_website_links_code form').remove();
});
function submit_code() {
var init_code = $('#edit-code-form #init_code').val();
var new_code = $('#edit-code-form #new_code').val();
function show_new_code(new_code) {
$('.o_website_links_code_error').html('');
$('.o_website_links_code_error').hide();
$('#o_website_links_code form').remove();
// Show new code
var host = $('#short-url-host').html();
$('#o_website_links_code').html(new_code);
// Update button copy to clipboard
$('.copy-to-clipboard').attr('data-clipboard-text', host + new_code)
// Show action again
$('.o_website_links_edit_code').show();
$('.copy-to-clipboard').show();
$('.o_website_links_edit_tools').hide();
}
if(init_code == new_code) {
show_new_code(new_code);
}
else {
openerp.jsonRpc('/website_links/add_code', 'call', {'init_code':init_code, 'new_code':new_code})
.then(function(result) {
show_new_code(result[0].code);
})
.fail(function(error) {
$('.o_website_links_code_error').show();
$('.o_website_links_code_error').html("This code is already taken");
}) ;
}
};
$('#edit-code-form').submit(function(e) {
e.preventDefault();
submit_code();
});
$('.o_website_links_ok_edit').click(function(e) {
e.preventDefault();
submit_code();
});
});
});
});
})();
@@ -0,0 +1,12 @@
/* The purpose of this script is to copy the current URL of the website
* into the URL form of the URL shortener (module website_links)
* when the user click the link "Share this page" on top of the page.
*/
(function () {
'use strict';
$(document).ready(function () {
$('#o_website_links_share_page').attr('href', '/r?u=' + encodeURIComponent(window.location.href));
});
})();
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website_links.RecentLink">
<div class="row mb16">
<div class="col-sm-1 col-xs-2 text-center">
<h4><t t-esc="widget.link_obj.count"/></h4>
<p class="text-muted" style="margin-top: -5px;">clicks</p>
</div>
<div class="col-sm-7 col-xs-7">
<h4 class="truncate_text">
<img t-att-src="widget.link_obj.icon_src"/>
<a class="no-link-style" t-att-href="widget.link_obj.url"><t t-esc="widget.link_obj.title"/></a>
</h4>
<p class="text-muted mb0" style="margin-top: -5px;">
<span class="o_website_links_short_url text-muted" style="position:relative;">
<span id="o_website_links_host"><t t-esc="widget.link_obj.short_url_host"/></span><span id="o_website_links_code"><t t-esc="widget.link_obj.code"/></span>
</span>
<span class="o_website_links_edit_tools" style="display:none;">
<a class="o_website_links_ok_edit btn btn-xs btn-primary" href="#">ok</a> or
<a class="o_website_links_cancel_edit" href="#">cancel</a>
</span>
<a class="o_website_links_edit_code"><span class="fa fa-pencil gray"></span></a>
<br/>
<span class="label label-success"><t t-esc="widget.link_obj.campaign_id[1]"/></span>
<span class="label label-success"><t t-esc="widget.link_obj.medium_id[1]"/></span>
<span class="label label-success"><t t-esc="widget.link_obj.source_id[1]"/></span>
</p>
<p class='o_website_links_code_error' style='color:red;font-weight:bold;'></p>
</div>
<div class="col-sm-4 col-xs-2">
<button class="btn btn-info btn_shorten_url_clipboard mt8" t-att-data-clipboard-text="widget.link_obj.short_url">Copy</button>
<a t-attf-href="{{widget.link_obj.short_url}}+" class="btn btn-warning mt8">Stats</a>
</div>
</div>
</t>
</templates>
@@ -0,0 +1,169 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.actions.act_window" id="action_view_click_statistics">
<field name="name">Statistics of Clicks</field>
<field name="res_model">website.links.click</field>
<field name="view_mode">graph</field>
<field name="domain">[('link_id', 'IN', ids)]</field>
</record>
<!-- Search -->
<record id="view_website_links_filter" model="ir.ui.view">
<field name="name">Links</field>
<field name="model">website.links</field>
<field name="arch" type="xml">
<search string="Tracked Link">
<field name="title"/>
<field name="url" string="Title and URL" filter_domain="['|', ('title', 'ilike', self), ('url', 'ilike', self)]"/>
</search>
</field>
</record>
<!-- Website links views -->
<record id="view_website_links_form" model="ir.ui.view">
<field name="name">website.links.form</field>
<field name="model">website.links</field>
<field name="arch" type="xml">
<form string="Website Link">
<sheet>
<div class="oe_button_box pull-right">
<button type="object" icon="fa-sign-out" name="action_visit_page"
string="Visit Page" class="oe_stat_button"/>
<button type="object" class="oe_stat_button" name="action_view_statistics" icon="fa-bar-chart">
<field name="count" string="Clicks" widget="statinfo"/>
</button>
</div>
<group>
<field name="title"/>
<field name="url"/>
<field name="short_url"/>
</group>
<group>
<field name="campaign_id"/>
<field name="medium_id"/>
<field name="source_id"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_website_links_form_stats" model="ir.ui.view">
<field name="name">website.links.my.form</field>
<field name="model">website.links</field>
<field name="arch" type="xml">
<form string="Website Link Graph">
<sheet>
<field name="link_click_ids">
<graph>
<field name="link_id"/>
<field name="ip"/>
<field name="country_id"/>
</graph>
</field>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_website_links_stats">
<field name="name">website.links.form.graph.action</field>
<field name="res_model">website.links</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_website_links_form_stats"/>
</record>
<record id="view_website_links_tree" model="ir.ui.view">
<field name="name">website.links.tree</field>
<field name="model">website.links</field>
<field name="arch" type="xml">
<tree string="Website Links">
<field name="create_date"/>
<field name="title"/>
<field name="url"/>
<field name="short_url"/>
<field name="count"/>
</tree>
</field>
</record>
<record id="view_website_links_graph" model="ir.ui.view" >
<field name="name">website.links.graph</field>
<field name="model">website.links</field>
<field name="arch" type="xml">
<graph string="Website Links" type="bar">
<field name="url" type="row"/>
<field name="count" type="measure"/>
</graph>
</field>
</record>
<!-- Action for website links-->
<record model="ir.actions.act_window" id="action_website_links">
<field name="name">Link Tracker</field>
<field name="res_model">website.links</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
</record>
<!-- Website links click views -->
<record id="view_website_links_click_form" model="ir.ui.view">
<field name="name">website.links.click.form</field>
<field name="model">website.links.click</field>
<field name="arch" type="xml">
<form string="Website Link Clicks">
<header>
</header>
<sheet>
<group>
<field name="link_id"/>
<field name="ip"/>
<field name="country_id"/>
</group>
</sheet>
</form>
</field>
</record>
<record id="view_website_links_click_tree" model="ir.ui.view">
<field name="name">website.links.click.tree</field>
<field name="model">website.links.click</field>
<field name="arch" type="xml">
<tree string="Website Links Clicks">
<field name="link_id"/>
<field name="ip"/>
<field name="country_id"/>
</tree>
</field>
</record>
<record id="view_website_links_click_graph" model="ir.ui.view" >
<field name="name">website.links.click.graph</field>
<field name="model">website.links.click</field>
<field name="arch" type="xml">
<graph string="Website Link Clicks">
<field name="link_id"/>
<field name="ip"/>
<field name="country_id"/>
</graph>
</field>
</record>
<!-- Action for website links click-->
<record model="ir.actions.act_window" id="action_website_links_click">
<field name="name">Tracked Links</field>
<field name="res_model">website.links.click</field>
<field name="view_type">form</field>
<field name="view_mode">graph,tree,form</field>
</record>
<menuitem id="menu_url_shortener_main" name="Link Tracker" parent="base.marketing_menu" groups="base.group_no_one"/>
<menuitem id="menu_url_shortener_links" name="Tracked Links" parent="menu_url_shortener_main" action="action_website_links"/>
</data>
</openerp>
@@ -0,0 +1,179 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="assets_website_links_charts" inherit_id="website.assets_frontend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web/static/lib/moment/moment.js"/>
<script type="text/javascript" src="/website_links/static/src/js/website_links_charts.js"/>
<script type="text/javascript" src="/website_links/static/src/js/ZeroClipboard.js"/>
<link rel="stylesheet" type="text/css" href="/website_links/static/src/css/website_links.css" />
</xpath>
</template>
<template id="assets_nvd3">
<link href="/web_graph/static/src/css/nv.d3.css" rel="stylesheet" type="text/css"></link>
<script src="/web_graph/static/lib/nvd3/d3.v3.js"></script>
<script src="/web_graph/static/lib/nvd3/nv.d3.js"></script>
</template>
<template id="graphs" name="Link Statistics">
<t t-call="website.layout">
<t t-set="head">
<t t-call-assets="website_links.assets_nvd3"/>
</t>
<div class="o_website_links_chart">
<div class="container">
<div class="row mt8">
<div class="col-sm-12">
<ol class="breadcrumb">
<li><a href="/r">Link Tracker</a></li>
<li class="active"><t t-esc="title"/></li>
</ol>
</div>
</div>
<input type="hidden" id="code" t-att-value="code" />
<input type="hidden" id="link_id" t-att-value="id" />
<h1 class="page-header mt0"><t t-esc="title"/></h1>
<div class="row">
<div class="col-sm-8">
<div class="row">
<div class="col-sm-4 col-xs-11">
<p><strong>Original URL</strong></p>
</div>
<div class="col-sm-8 col-xs-11">
<p class="truncate_text"><a t-att-href="url"><t t-esc="url"/></a></p>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<p><strong>Tracked Link</strong></p>
</div>
<div class="col-sm-8">
<p>
<span class="o_website_links_short_url" id="short_url"><span id="short-url-host"><t t-esc="short_url_host"/></span><span id="o_website_links_code"><t t-esc="code"/></span></span>
<span class="o_website_links_edit_tools" style="display:none;">
<a class="o_website_links_ok_edit btn btn-xs btn-primary" href="#">ok</a> or
<a class="o_website_links_cancel_edit" href="#">cancel</a>
</span>
<a class="o_website_links_edit_code"><span class="fa fa-pencil gray"></span></a>
<a class="copy-to-clipboard" t-att-data-clipboard-text="short_url">copy</a>
</p>
<p class='o_website_links_code_error' style='color:red;font-weight:bold;display:none'></p>
</div>
</div>
<div class="row">
<div class="col-sm-4 col-xs-12">
<p><strong>Redirected URL</strong></p>
</div>
<div class="col-sm-8 col-xs-11" style="word-wrap:break-word;">
<t t-esc="redirected_url"/>
</div>
</div>
</div>
<div class="col-sm-4">
<t t-if="campaign_id">
<div class="row">
<div class="col-sm-4">
<p><strong>Campaign</strong></p>
</div>
<div class="col-sm-8">
<p><t t-esc="campaign_id[1]"/></p>
</div>
</div>
</t>
<t t-if="medium_id">
<div class="row">
<div class="col-sm-4">
<p><strong>Medium</strong></p>
</div>
<div class="col-sm-8">
<p><t t-esc="medium_id[1]"/></p>
</div>
</div>
</t>
<t t-if="source_id">
<div class="row">
<div class="col-sm-4">
<p><strong>Source</strong></p>
</div>
<div class="col-sm-8">
<p><t t-esc="source_id[1]"/></p>
</div>
</div>
</t>
</div>
</div>
<h1 class="page-header">Statistics
<small class="pull-right hidden-xs mt16" id="filters">
<ul class="nav nav-tabs nav-tabs-inline graph-tabs" role="tablist">
<li class="active"><a href="#all_time_charts" role="tab" data-toggle="tab">All Time</a></li>
<li><a href="#last_month_charts" role="tab" data-toggle="tab">Last Month</a></li>
<li><a href="#last_week_charts" role="tab" data-toggle="tab">Last Week</a></li>
</ul>
</small>
</h1>
<div class="row">
<div class="col-sm-12 mb8">
<div class="tab-content">
<!-- All Time Charts -->
<div class="tab-pane active" id="all_time_charts">
<div class="row">
<div class="col-sm-7 website_links_click_chart" id="all_time_clicks_chart">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
<div class="col-sm-5 website_links_click_chart" id="all_time_countries_charts">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
</div>
</div>
<!-- Last Month Charts -->
<div class="tab-pane" id="last_month_charts">
<div class="row">
<div class="col-sm-7 website_links_click_chart" id="last_month_clicks_chart">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
<div class="col-sm-5 website_links_click_chart" id="last_month_countries_charts">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
</div>
</div>
<!-- Last Week Charts -->
<div class="tab-pane" id="last_week_charts">
<div class="row">
<div class="col-sm-7 website_links_click_chart" id="last_week_clicks_chart">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
<div class="col-sm-5 website_links_click_chart" id="last_week_countries_charts">
<h3 class="title"></h3>
<svg style="height:20em;"></svg>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</template>
</data>
</openerp>
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="assets_website_links" inherit_id="website.assets_frontend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/website_links/static/src/js/website_links.js"/>
<script type="text/javascript" src="/website_links/static/src/js/ZeroClipboard.js"/>
<link rel="stylesheet" type="text/css" href="/website_links/static/src/css/website_links.css" />
<script type="text/javascript" src="/website_links/static/src/js/website_links_code_editor.js"/>
</xpath>
</template>
<template id="share_page_menu" inherit_id="website.user_navbar">
<xpath expr="//li[@groups='base.group_website_designer']" position="replace">
<li groups="base.group_website_designer">
<a id="promote-menu-button" class="dropdown-toggle" data-toggle="dropdown" href="#">
Promote <span class="caret"></span>
</a>
<ul class="dropdown-menu oe_content_menu" role="menu">
<li>
<a data-action="promote-current-page" href="#">
<span title="Promote page on the web">Optimise SEO...</span>
</a>
</li>
<li>
<a href="/r" id="o_website_links_share_page">
<span title="Track this page to count clicks">Share this Page</span>
</a>
</li>
</ul>
</li>
</xpath>
</template>
<template id="asset_website_links_menu" inherit_id="website.assets_editor">
<xpath expr="." position="inside">
<script type="text/javascript" src="/website_links/static/src/js/website_links_menu.js"></script>
</xpath>
</template>
<template id="create_shorten_url">
<div class="o_website_links_create_tracked_url">
<div class="container">
<h1 class="page-header">Link Tracker</h1>
<div class="notification"></div>
<div class="row">
<div class="col-sm-7">
<form class="form-horizontal" id="o_website_links_link_tracker_form">
<div class="form-group" id="url-form-group">
<label class="col-sm-3 control-label text-left">URL</label>
<div class="col-sm-9">
<input type="text" id="url" class="form-control required-form-control" required="True" placeholder="e.g. https://www.odoo.com/page/contactus" t-att-value="u"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Campaign <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="top" title="Defines the context of your link. It might be an event you want to promote or a special promotion."></i></label>
<div class="col-sm-9">
<input type="hidden" class="form-control" id="campaign-select"/>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Medium <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="top" title="Defines the medium used to share your link. It might be an email, or a Facebook Ads for instance."></i></label>
<div class="col-sm-9">
<input type="hidden" class="form-control" id="channel-select" />
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">Source <i class="fa fa-info-circle" data-toggle="tooltip" data-placement="top" title="Defines the source from which your traffic will come from, Facebook or Twitter for instance."></i></label>
<div class="col-sm-9">
<input type="hidden" class="form-control" id="source-select" />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" class="btn btn-primary" id="btn_shorten_url" data-clipboard-text="">Get tracked link</button>
<span id="generated_tracked_link" style="display:none;" class="text-muted"></span>
</div>
</div>
</form>
</div>
<div class="col-sm-offset-1 col-sm-3 hidden-xs">
<p class="text-muted text-justify">Share this page with a <strong>short link</strong> that includes <strong>analytics trackers</strong>.</p>
<p class="text-muted text-justify">Thoses trackers can be used in Google Analytics to track clicks and visitors, or in Odoo reports to track opportunities and related revenues.</p>
</div>
</div>
<h2 class="page-header">Your tracked links
<small class="pull-right hidden-xs mt16" id="filters">
<ul class="nav nav-tabs nav-tabs-inline graph-tabs" role="tablist">
<li class="active"><a href="#" id="filter-newest-links" role="tab" data-toggle="tab">Newest</a></li>
<li><a href="#" id="filter-most-clicked-links" role="tab" data-toggle="tab">Most Clicked</a></li>
<li><a href="#" id="filter-recently-used-links" role="tab" data-toggle="tab">Recently Used</a></li>
</ul>
</small>
</h2>
<div id="o_website_links_recent_links">
<div class="o_website_links_recent_links_notification"></div>
</div>
</div>
</div>
</template>
<template id="page_shorten_url" name="Link Tracker">
<t t-call="website.layout">
<t t-call="website_links.create_shorten_url"/>
</t>
</template>
</data>
</openerp>