commit
906948cb8d
|
@ -123,7 +123,7 @@ class email_template(osv.osv):
|
|||
|
||||
_columns = {
|
||||
'name' : fields.char('Name', size=100, required=True),
|
||||
'object_name':fields.many2one('ir.model', 'Model'),
|
||||
'object_name':fields.many2one('ir.model', 'Resource'),
|
||||
'model_int_name':fields.char('Model Internal Name', size=200,),
|
||||
'from_account':fields.many2one(
|
||||
'email_template.account',
|
||||
|
@ -132,7 +132,7 @@ class email_template(osv.osv):
|
|||
'def_to':fields.char(
|
||||
'Recipient (To)',
|
||||
size=250,
|
||||
help="The default recipient of email."
|
||||
help="The Recipient of email. "
|
||||
"Placeholders can be used here."),
|
||||
'def_cc':fields.char(
|
||||
'CC',
|
||||
|
@ -151,12 +151,12 @@ class email_template(osv.osv):
|
|||
" Placeholders can be used here."),
|
||||
'message_id':fields.char('Message-ID',
|
||||
size=250,
|
||||
help="The Message-ID header value, if you need to"
|
||||
"specify it, for example to automatically recognize the replies later."
|
||||
" Placeholders can be used here."),
|
||||
'track_campaign_item':fields.boolean('Track campaign items',
|
||||
help="Enable this if you want the outgoing e-mails to include a tracking"
|
||||
" marker that makes it possible to identify the replies an link them back to the campaign item"),
|
||||
help="Specify the Message-ID SMTP header to use in outgoing emails. Please note that this overrides the Resource tracking option! Placeholders can be used here."),
|
||||
'track_campaign_item':fields.boolean('Resource Tracking',
|
||||
help="Enable this is you wish to include a special \
|
||||
tracking marker in outgoing emails so you can identify replies and link \
|
||||
them back to the corresponding resource record. \
|
||||
This is useful for CRM leads for example"),
|
||||
'lang':fields.char(
|
||||
'Language',
|
||||
size=250,
|
||||
|
@ -164,9 +164,9 @@ class email_template(osv.osv):
|
|||
" Placeholders can be used here. "
|
||||
"eg. ${object.partner_id.lang}"),
|
||||
'def_subject':fields.char(
|
||||
'Default Subject',
|
||||
'Subject',
|
||||
size=200,
|
||||
help="The default subject of email."
|
||||
help="The subject of email."
|
||||
" Placeholders can be used here.",
|
||||
translate=True),
|
||||
'def_body_text':fields.text(
|
||||
|
@ -201,10 +201,12 @@ class email_template(osv.osv):
|
|||
'ref_ir_act_window':fields.many2one(
|
||||
'ir.actions.act_window',
|
||||
'Window Action',
|
||||
help="Action that will open this email template on Resource records",
|
||||
readonly=True),
|
||||
'ref_ir_value':fields.many2one(
|
||||
'ir.values',
|
||||
'Wizard Button',
|
||||
help="Button in the side bar of the form view of this Resource that will invoke the Window Action",
|
||||
readonly=True),
|
||||
'allowed_groups':fields.many2many(
|
||||
'res.groups',
|
||||
|
@ -636,9 +638,13 @@ class email_template(osv.osv):
|
|||
'mail_type':'multipart/alternative',
|
||||
}
|
||||
|
||||
if template['message_id']:
|
||||
# use provided message_id with placeholders
|
||||
mailbox_values.update({'message_id': get_value(cursor, user, record_id, template['message_id'], template, context)})
|
||||
|
||||
if template['track_campaign_item']:
|
||||
# get appropriate message-id
|
||||
mailbox_values.update(message_id=tools.misc.generate_tracking_message_id(record_id))
|
||||
mailbox_values.update({'message_id': tools.misc.generate_tracking_message_id(record_id)})
|
||||
|
||||
if not mailbox_values['account_id']:
|
||||
raise Exception("Unable to send the mail. No account linked to the template.")
|
||||
|
|
|
@ -80,7 +80,12 @@ class email_template_account(osv.osv):
|
|||
'name': fields.char('Description',
|
||||
size=64, required=True,
|
||||
readonly=True, select=True,
|
||||
help="The description is used as the Sender name along with the provided From Email, \
|
||||
unless it is already specified in the From Email, e.g: John Doe <john@doe.com>",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'auto_delete': fields.boolean('Auto Delete', size=64, readonly=True,
|
||||
help="Permanently delete emails after sending",
|
||||
states={'draft':[('readonly', False)]}),
|
||||
'user':fields.many2one('res.users',
|
||||
'Related User', required=True,
|
||||
readonly=True, states={'draft':[('readonly', False)]}),
|
||||
|
@ -133,7 +138,7 @@ class email_template_account(osv.osv):
|
|||
('suspended', 'Suspended'),
|
||||
('approved', 'Approved')
|
||||
],
|
||||
'Status', required=True, readonly=True),
|
||||
'State', required=True, readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -189,25 +194,7 @@ class email_template_account(osv.osv):
|
|||
'Error: You are not allowed to have more than 1 account.',
|
||||
[])
|
||||
]
|
||||
|
||||
def on_change_emailid(self, cursor, user, ids, name=None, email_id=None, context=None):
|
||||
"""
|
||||
Called when the email ID field changes.
|
||||
|
||||
UI enhancement
|
||||
Writes the same email value to the smtpusername
|
||||
and incoming username
|
||||
"""
|
||||
#TODO: Check and remove the write. Is it needed?
|
||||
self.write(cursor, user, ids, {'state':'draft'}, context=context)
|
||||
return {
|
||||
'value': {
|
||||
'state': 'draft',
|
||||
'smtpuname':email_id,
|
||||
'isuser':email_id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def get_outgoing_server(self, cursor, user, ids, context=None):
|
||||
"""
|
||||
Returns the Out Going Connection (SMTP) object
|
||||
|
|
|
@ -18,16 +18,17 @@
|
|||
<notebook colspan="4">
|
||||
<page string="Outgoing">
|
||||
<separator string="Server Information" colspan="4" />
|
||||
<group colspan="4">
|
||||
<field name="smtpserver" select="1" colspan="2" />
|
||||
<field name="smtpport" select="2" colspan="2" />
|
||||
<field name="smtpssl" select="2" colspan="2" />
|
||||
<field name="smtptls" select="2" colspan="2" />
|
||||
<group colspan="4" col="4">
|
||||
<field name="smtpserver" select="1"/>
|
||||
<field name="smtpport" select="2" />
|
||||
<field name="smtpssl" select="2" />
|
||||
<field name="smtptls" select="2" />
|
||||
<field name="auto_delete" />
|
||||
</group>
|
||||
<button name="check_outgoing_connection" type="object" string="Test Outgoing Connection" />
|
||||
<separator string="User Information" colspan="4" />
|
||||
<group col="2" colspan="2">
|
||||
<field name="email_id" select="1" on_change="on_change_emailid(name,email_id)" colspan="2" />
|
||||
<field name="email_id" select="1" colspan="2" />
|
||||
<field name="smtppass" password="True" colspan="2" />
|
||||
<field name="company" select="2" colspan="2" />
|
||||
</group>
|
||||
|
@ -72,15 +73,16 @@
|
|||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Accounts">
|
||||
<filter icon="terp-personal" string="My Accounts" name="my" domain="[('user','=',uid)]"/>
|
||||
<filter icon="terp-personal+" string="Personal Accounts" domain="[('company','=','no')]"/>
|
||||
<filter icon="terp-go-home" string="Company Accounts" domain="[('company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-document-new" string="Draft" name="draft" domain="[('state','=','draft')]"/>
|
||||
<filter icon="terp-camera_test" string="Approved" domain="[('state','=','approved')]"/>
|
||||
<filter icon="terp-emblem-important" string="Suspended" domain="[('state','=','suspended')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-home" string="Company Accounts" domain="[('company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="user" select="1">
|
||||
<filter icon="terp-personal" help="My Accounts" name="my" domain="[('user','=',uid)]"/>
|
||||
</field>
|
||||
<field name="name" select="1"/>
|
||||
<field name="user" select="1"/>
|
||||
<field name="email_id" select="1"/>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -97,11 +99,25 @@
|
|||
</record>
|
||||
|
||||
<menuitem name="Configuration" parent="base.marketing_menu"
|
||||
id="base.menu_marketing_config_root" sequence="20" groups="base.group_system"/>
|
||||
<menuitem name="Emails" id="menu_email_template_configuration" parent="base.menu_marketing_config_root" />
|
||||
id="base.menu_marketing_config_root" sequence="20" groups="base.group_system"/>
|
||||
|
||||
<menuitem name="Email Template" id="menu_email_template_configuration" parent="base.menu_marketing_config_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_template_account_all" parent="menu_email_template_configuration" action="action_email_template_account_tree_all"/>
|
||||
|
||||
<!-- Email Template account menu in Tools -->
|
||||
|
||||
<menuitem name="Tools" id="base.menu_tools" icon="STOCK_PREFERENCES" sequence="28"/>
|
||||
|
||||
<menuitem name="Configuration" parent="base.menu_tools"
|
||||
id="base.menu_lunch_survey_root" sequence="20" />
|
||||
|
||||
<menuitem name="Email Template" id="menu_email_template_config_tools"
|
||||
parent="base.menu_lunch_survey_root" />
|
||||
|
||||
<menuitem name="Email Accounts" id="menu_email_account_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_account_tree_all" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@ class email_template_mailbox(osv.osv):
|
|||
|
||||
def send_this_mail(self, cr, uid, ids=None, context=None):
|
||||
result = True
|
||||
attachment_pool = self.pool.get('ir.attachment')
|
||||
for id in (ids or []):
|
||||
try:
|
||||
account_obj = self.pool.get('email_template.account')
|
||||
|
@ -70,7 +71,7 @@ class email_template_mailbox(osv.osv):
|
|||
payload = {}
|
||||
if values['attachments_ids']:
|
||||
for attid in values['attachments_ids']:
|
||||
attachment = self.pool.get('ir.attachment').browse(cr, uid, attid, context)#,['datas_fname','datas'])
|
||||
attachment = attachment_pool.browse(cr, uid, attid, context)#,['datas_fname','datas'])
|
||||
payload[attachment.datas_fname] = attachment.datas
|
||||
result = account_obj.send_mail(cr, uid,
|
||||
[values['account_id'][0]],
|
||||
|
@ -84,8 +85,15 @@ class email_template_mailbox(osv.osv):
|
|||
message_id=values['message_id'],
|
||||
context=context)
|
||||
if result == True:
|
||||
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
self.historise(cr, uid, [id], "Email sent successfully", context)
|
||||
account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
|
||||
if account.auto_delete:
|
||||
self.write(cr, uid, id, {'folder': 'trash'}, context=context)
|
||||
self.unlink(cr, uid, [id], context=context)
|
||||
# Remove attachments for this mail
|
||||
attachment_pool.unlink(cr, uid, values['attachments_ids'], context=context)
|
||||
else:
|
||||
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context)
|
||||
self.historise(cr, uid, [id], "Email sent successfully", context)
|
||||
else:
|
||||
error = result['error_msg']
|
||||
self.historise(cr, uid, [id], error, context)
|
||||
|
@ -100,7 +108,7 @@ class email_template_mailbox(osv.osv):
|
|||
def historise(self, cr, uid, ids, message='', context=None):
|
||||
for id in ids:
|
||||
history = self.read(cr, uid, id, ['history'], context).get('history', '')
|
||||
self.write(cr, uid, id, {'history':history or '' + "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
|
||||
self.write(cr, uid, id, {'history': (history or '' )+ "\n" + time.strftime("%Y-%m-%d %H:%M:%S") + ": " + tools.ustr(message)}, context)
|
||||
|
||||
_columns = {
|
||||
'email_from':fields.char(
|
||||
|
@ -171,8 +179,7 @@ class email_template_mailbox(osv.osv):
|
|||
('na', 'Not Applicable'),
|
||||
('sending', 'Sending'),
|
||||
], 'Status', required=True),
|
||||
'date_mail':fields.datetime(
|
||||
'Rec/Sent Date'),
|
||||
'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
|
||||
'history':fields.text(
|
||||
'History',
|
||||
readonly=True,
|
||||
|
@ -184,6 +191,24 @@ class email_template_mailbox(osv.osv):
|
|||
'folder': lambda * a: 'outbox',
|
||||
}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
It just changes the folder of the item to "Trash", if it is no in Trash folder yet,
|
||||
or completely deletes it if it is already in Trash.
|
||||
"""
|
||||
if not context:
|
||||
context = {}
|
||||
to_update = []
|
||||
to_remove = []
|
||||
for mail in self.browse(cr, uid, ids, context=context):
|
||||
if mail.folder == 'trash':
|
||||
to_remove.append(mail.id)
|
||||
else:
|
||||
to_update.append(mail.id)
|
||||
# Changes the folder to trash
|
||||
self.write(cr, uid, to_update, {'folder': 'trash'}, context=context)
|
||||
return super(email_template_mailbox, self).unlink(cr, uid, to_remove, context=context)
|
||||
|
||||
email_template_mailbox()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Outbox">
|
||||
<form string="Emails">
|
||||
<group col="4" colspan="4" name="headers">
|
||||
<field name="email_from" select="1"/>
|
||||
<field name="email_to" required="1" select="1" />
|
||||
|
@ -28,32 +28,27 @@
|
|||
<field name="body_html" nolabel="1" colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
<separator colspan="4" string="" />
|
||||
<group col="4" colspan="4">
|
||||
<field name="state" readonly="1" string="State"/>
|
||||
<button name="send_this_mail" type="object" string="Send Mail" icon="terp-mail-message-new"/>
|
||||
</group>
|
||||
</page>
|
||||
|
||||
<page string="Attachments">
|
||||
<group col="4">
|
||||
<separator colspan="4" string="Attachments" />
|
||||
<field name="attachments_ids" colspan="4" nolabel="1" />
|
||||
</group>
|
||||
<separator colspan="4" string="Attachments" />
|
||||
<field name="attachments_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Advanced">
|
||||
<group col="4">
|
||||
<field name="account_id" colspan="2" />
|
||||
<field name="server_ref" colspan="2" />
|
||||
<field name="mail_type" colspan="2" />
|
||||
<field name="folder" colspan="2" select="2"/>
|
||||
<field name="message_id" select="2"/>
|
||||
<separator string="History" colspan="4" />
|
||||
<field name="history" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
<field name="account_id" colspan="2" />
|
||||
<field name="server_ref" colspan="2" />
|
||||
<field name="mail_type" colspan="2" />
|
||||
<field name="folder" colspan="2" select="2"/>
|
||||
<field name="message_id" select="2"/>
|
||||
<separator string="History" colspan="4" />
|
||||
<field name="history" nolabel="1" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
<separator colspan="4" string="" />
|
||||
<group col="4" colspan="4">
|
||||
<field name="state" readonly="1" />
|
||||
<button name="complete_mail" type="object" string="Download Full Mail" states="read,unread" />
|
||||
<button name="send_this_mail" type="object" string="Send Mail" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -64,12 +59,14 @@
|
|||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Drafts">
|
||||
<tree string="Emails" colors="blue:folder=='drafts';grey:folder=='trash'">
|
||||
<field name="subject" select="1" />
|
||||
<field name="user" />
|
||||
<field name="email_from" select="1" />
|
||||
<field name="subject" select="1" />
|
||||
<field name="attachments_ids" select="2" />
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail" select="2" />
|
||||
<field name="attachments_ids" select="2" />
|
||||
<field name="folder" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -79,37 +76,54 @@
|
|||
<field name="model">email_template.mailbox</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Mailboxes">
|
||||
<filter icon="terp-mail-message-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
|
||||
<search string="Emails">
|
||||
<filter icon="terp-document-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
|
||||
<filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-gtk-jump-to-ltr" string="Sent" domain="[('folder','=','sent')]"/>
|
||||
<filter icon="terp-camera_test" string="Sent" domain="[('folder','=','sent')]"/>
|
||||
<filter icon="terp-mail_delete" string="Trash" domain="[('folder','=','trash')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-gtk-stop" string="Not Applicable" domain="[('state','=','na')]"/>
|
||||
<filter icon="terp-gtk-jump-to-ltr" string="Sending" domain="[('state','=','sending')]"/>
|
||||
<filter icon="terp-personal+" string="Personal Emails" name="personal" domain="[('account_id.company','=','no')]"/>
|
||||
<filter icon="terp-go-home" string="Company Emails" name="company" domain="[('account_id.company','=','yes')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="email_from" select="1"/>
|
||||
<field name="email_to" select="1"/>
|
||||
<field name="subject" select="1"/>
|
||||
<field name="subject"/>
|
||||
<field name="email_from"/>
|
||||
<field name="user">
|
||||
<filter icon="terp-personal"
|
||||
string="My Emails" name="myemails"
|
||||
domain="[('account_id.user','=', uid)]" />
|
||||
</field>
|
||||
<newline/>
|
||||
<field name="email_to"/>
|
||||
<field name="date_mail"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_email_template_mailbox">
|
||||
<field name="name">Mailbox</field>
|
||||
<field name="name">Emails</field>
|
||||
<field name="res_model">email_template.mailbox</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form,tree</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_email_template_mailbox_tree" />
|
||||
<field name="context">{'group_by': [], 'search_default_draft': 1, 'search_default_outbox': 1}</field>
|
||||
<field name="context">{'group_by': [], 'search_default_outbox': 1}</field>
|
||||
<field name="search_view_id" ref="view_email_template_mailbox_search"/>
|
||||
</record>
|
||||
|
||||
<!--======================================== MENUS ========================================-->
|
||||
<menuitem name="MailBox" id="menu_email_template_mailbox_all_main2" parent="menu_email_template" />
|
||||
<menuitem name="Personal Mails" id="menu_email_template_personal_mails" parent="menu_email_template_mailbox_all_main2" action="action_email_template_mailbox"/>
|
||||
<menuitem name="Company Mails" id="menu_email_template_company_mails" parent="menu_email_template_mailbox_all_main2" action="action_email_template_mailbox"/>
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_personal_mails"
|
||||
parent="menu_email_template"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
<!-- Mailbox menu in Tools -->
|
||||
<menuitem name="Email Template" id="menu_email_template_tools"
|
||||
parent="base.menu_tools" />
|
||||
|
||||
<menuitem name="Emails"
|
||||
id="menu_email_template_mails_tools"
|
||||
parent="menu_email_template_tools"
|
||||
action="action_email_template_mailbox" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<record forcecreate="True" id="ir_cron_mail_scheduler_action" model="ir.cron">
|
||||
<record forcecreate="True" id="ir_cron_mail_scheduler_action" model="ir.cron">
|
||||
<field name="name">Email Template scheduler</field>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="interval_type">hours</field>
|
||||
<field name="numbercall">12</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field eval="False" name="doall"/>
|
||||
<field eval="'email_template.mailbox'" name="model"/>
|
||||
<field eval="'run_mail_scheduler'" name="function"/>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- Email Template PReview -->
|
||||
|
||||
<!-- Email Template Preview -->
|
||||
<record model="ir.ui.view" id="email_template_preview_form">
|
||||
<field name="name">email_template.preview.form</field>
|
||||
<field name="model">email_template.preview</field>
|
||||
|
@ -67,25 +68,26 @@
|
|||
<field name="reply_to"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Email Data" colspan="2"/>
|
||||
<field name="def_subject" colspan="4" required="1" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<separator string="Options" colspan="2"/>
|
||||
<field name="lang" colspan="4" />
|
||||
<field name="use_sign" colspan="4" />
|
||||
<field name="track_campaign_item" colspan="4"/>
|
||||
</group>
|
||||
<separator colspan="3" string="Standard Body" />
|
||||
<separator colspan="1" string="Expression Builder" />
|
||||
|
||||
<notebook>
|
||||
<page string="Body (Text)">
|
||||
<field name="def_body_text" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Body (Raw HTML)">
|
||||
<field name="def_body_html" colspan="4" nolabel="1" />
|
||||
<label string="Note: This is Raw HTML." colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
<group col="4">
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Email Content " />
|
||||
<field name="def_subject" colspan="4" required="1" />
|
||||
<notebook>
|
||||
<page string="Body (Text)">
|
||||
<field name="def_body_text" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Body (Raw HTML)">
|
||||
<field name="def_body_html" colspan="4" nolabel="1" />
|
||||
<label string="Note: This is Raw HTML." colspan="4" />
|
||||
</page>
|
||||
</notebook>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<separator colspan="4" string="Expression Builder" />
|
||||
<field name="template_language"
|
||||
on_change="onchange_null_value(model_object_field,sub_model_object_field,null_value,template_language,context)" />
|
||||
<notebook>
|
||||
|
@ -112,17 +114,23 @@
|
|||
</page>
|
||||
<page string="Advanced">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Actions" colspan="2"/>
|
||||
<button name="create_action" string="Create Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False), ('ref_ir_value','!=',False)]}"/>
|
||||
<field name="ref_ir_act_window"/>
|
||||
<field name="ref_ir_value"/>
|
||||
<button name="delete_action" string="Delete Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False), ('ref_ir_value','=',False)]}"/>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Actions" colspan="2"/>
|
||||
<button name="create_action" string="Create Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False), ('ref_ir_value','!=',False)]}"/>
|
||||
<field name="ref_ir_act_window"/>
|
||||
<field name="ref_ir_value"/>
|
||||
<button name="delete_action" string="Delete Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False), ('ref_ir_value','=',False)]}"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Advanced Options" colspan="2"/>
|
||||
<field name="message_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Attachments" colspan="2"/>
|
||||
<notebook>
|
||||
<page string="Existing files">
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
<field name="attachment_ids" colspan="4" nolabel="1" height="350"/>
|
||||
</page>
|
||||
<page string="Report">
|
||||
<field name="file_name" colspan="4" />
|
||||
|
@ -183,9 +191,12 @@
|
|||
<field name="search_view_id" ref="view_email_template_search"/>
|
||||
</record>
|
||||
|
||||
<menuitem name="E-MAIL Templates" id="menu_email_template_all"
|
||||
<menuitem name="Email Templates" id="menu_email_template_all"
|
||||
parent="menu_email_template_configuration" action="action_email_template_tree_all" />
|
||||
|
||||
<!-- Email Template menu in Tools -->
|
||||
<menuitem name="Email Templates" id="menu_email_template_all_tools"
|
||||
parent="menu_email_template_config_tools" action="action_email_template_tree_all" />
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
|
|
|
@ -335,11 +335,6 @@ msgstr ""
|
|||
msgid "Send/Receive"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_mailbox_all_main2
|
||||
msgid "MailBox"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
|
||||
msgid "Template Preview"
|
||||
|
|
|
@ -174,8 +174,8 @@ msgstr "Approve Account"
|
|||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_all
|
||||
msgid "E-MAIL Templates"
|
||||
msgstr "E-MAIL Templates"
|
||||
msgid "Email Templates"
|
||||
msgstr "Email Templates"
|
||||
|
||||
#. module: email_template
|
||||
#: field:email_template.preview,rel_model_ref:0
|
||||
|
@ -221,8 +221,8 @@ msgstr "Download Full Mail"
|
|||
|
||||
#. module: email_template
|
||||
#: help:email.template,def_to:0
|
||||
msgid "The default recipient of email.Placeholders can be used here."
|
||||
msgstr "The default recipient of email.Placeholders can be used here."
|
||||
msgid "The recipient of email.Placeholders can be used here."
|
||||
msgstr "The recipient of email.Placeholders can be used here."
|
||||
|
||||
#. module: email_template
|
||||
#: view:email_template.mailbox:0
|
||||
|
@ -258,8 +258,8 @@ msgstr "Accounts"
|
|||
|
||||
#. module: email_template
|
||||
#: field:email.template,track_campaign_item:0
|
||||
msgid "Track campaign items"
|
||||
msgstr "Track campaign items"
|
||||
msgid "Resource Tracking"
|
||||
msgstr "Resource Tracking"
|
||||
|
||||
#. module: email_template
|
||||
#: view:email_template.preview:0
|
||||
|
@ -335,11 +335,6 @@ msgstr "Body(Html)"
|
|||
msgid "Send/Receive"
|
||||
msgstr "Send/Receive"
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_mailbox_all_main2
|
||||
msgid "MailBox"
|
||||
msgstr "MailBox"
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
|
||||
msgid "Template Preview"
|
||||
|
@ -762,8 +757,8 @@ msgstr "Save in Drafts"
|
|||
|
||||
#. module: email_template
|
||||
#: help:email.template,def_subject:0
|
||||
msgid "The default subject of email. Placeholders can be used here."
|
||||
msgstr "The default subject of email. Placeholders can be used here."
|
||||
msgid "The subject of email. Placeholders can be used here."
|
||||
msgstr "The subject of email. Placeholders can be used here."
|
||||
|
||||
#. module: email_template
|
||||
#: field:email_template.account,smtptls:0
|
||||
|
@ -772,8 +767,8 @@ msgstr "TLS"
|
|||
|
||||
#. module: email_template
|
||||
#: view:email_template.send.wizard:0
|
||||
msgid "Add here all attachments of the current document you want to include in the e-mail."
|
||||
msgstr "Add here all attachments of the current document you want to include in the e-mail."
|
||||
msgid "Add here all attachments of the current document you want to include in the Email."
|
||||
msgstr "Add here all attachments of the current document you want to include in the Email."
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.model,name:email_template.model_email_template_send_wizard
|
||||
|
@ -786,6 +781,8 @@ msgstr "This is the wizard for sending mail"
|
|||
#: code:addons/email_template/email_template_mailbox.py:0
|
||||
#: code:addons/email_template/wizard/email_template_send_wizard.py:0
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_config_tools
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_configuration
|
||||
#, python-format
|
||||
msgid "Email Template"
|
||||
msgstr "Email Template"
|
||||
|
@ -1023,8 +1020,8 @@ msgstr "Password"
|
|||
#: help:email.template,message_id:0
|
||||
#: help:email_template.preview,message_id:0
|
||||
#: help:email_template.send.wizard,message_id:0
|
||||
msgid "The Message-ID header value, if you need tospecify it, for example to automatically recognize the replies later. Placeholders can be used here."
|
||||
msgstr "The Message-ID header value, if you need tospecify it, for example to automatically recognize the replies later. Placeholders can be used here."
|
||||
msgid "Specify the Message-ID SMTP header to use in outgoing emails. Please note that this overrides the Resource tracking option! Placeholders can be used here."
|
||||
msgstr "Specify the Message-ID SMTP header to use in outgoing emails. Please note that this overrides the Resource tracking option! Placeholders can be used here."
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_configuration
|
||||
|
@ -1113,11 +1110,6 @@ msgstr "Corporate"
|
|||
msgid "Enter name of outgoing server, eg:smtp.gmail.com "
|
||||
msgstr "Enter name of outgoing server, eg:smtp.gmail.com "
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_company_mails
|
||||
msgid "Company Mails"
|
||||
msgstr "Company Mails"
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Addresses"
|
||||
|
@ -1130,8 +1122,8 @@ msgstr "Emails will be sent from this approved account."
|
|||
|
||||
#. module: email_template
|
||||
#: field:email.template,def_subject:0
|
||||
msgid "Default Subject"
|
||||
msgstr "Default Subject"
|
||||
msgid "Subject"
|
||||
msgstr "Subject"
|
||||
|
||||
#. module: email_template
|
||||
#: help:email.template,def_bcc:0
|
||||
|
@ -1182,8 +1174,8 @@ msgstr "Has Attachments"
|
|||
|
||||
#. module: email_template
|
||||
#: help:email.template,track_campaign_item:0
|
||||
msgid "Enable this if you want the outgoing e-mails to include a tracking marker that makes it possible to identify the replies an link them back to the campaign item"
|
||||
msgstr "Enable this if you want the outgoing e-mails to include a tracking marker that makes it possible to identify the replies an link them back to the campaign item"
|
||||
msgid "Enable this is you wish to include a special tracking marker in outgoing emails so you can identify replies and link them back to the corresponding resource record. This is useful for CRM leads for example"
|
||||
msgstr "Enable this is you wish to include a special tracking marker in outgoing emails so you can identify replies and link them back to the corresponding resource record. This is useful for CRM leads for example"
|
||||
|
||||
#. module: email_template
|
||||
#: code:addons/email_template/email_template.py:0
|
||||
|
|
|
@ -348,11 +348,6 @@ msgstr ""
|
|||
msgid "Send/Receive"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_mailbox_all_main2
|
||||
msgid "MailBox"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
|
||||
msgid "Template Preview"
|
||||
|
@ -1145,11 +1140,6 @@ msgstr ""
|
|||
msgid "Enter name of outgoing server, eg:smtp.gmail.com "
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: model:ir.ui.menu,name:email_template.menu_email_template_company_mails
|
||||
msgid "Company Mails"
|
||||
msgstr ""
|
||||
|
||||
#. module: email_template
|
||||
#: view:email.template:0
|
||||
msgid "Addresses"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<field name="body_html" select="2" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
<page string="Attachments">
|
||||
<label string="Add here all attachments of the current document you want to include in the e-mail." colspan="4"/>
|
||||
<label string="Add here all attachments of the current document you want to include in the Email." colspan="4"/>
|
||||
<field name="attachment_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
|
|
@ -101,7 +101,7 @@
|
|||
-
|
||||
!python {model: hr.sign.in.project}: |
|
||||
uid = ref('res_users_user0')
|
||||
new_id = self.create(cr, uid, {'emp_id': 'hr_employee_fracline1', 'name': 'Francline', 'server_date': '2010-06-08 19:50:54', 'state': 'absent'})
|
||||
new_id = self.create(cr, uid, {'emp_id': ref('hr_employee_fracline1'), 'name': 'Francline', 'server_date': '2010-06-08 19:50:54', 'state': 'absent'})
|
||||
self.sign_in_result(cr, uid, [new_id], context)
|
||||
|
||||
-
|
||||
|
|
|
@ -32,7 +32,7 @@ class marketing_installer(osv.osv_memory):
|
|||
'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration',
|
||||
help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."),
|
||||
'crm_profiling':fields.boolean('Profiling Tools',
|
||||
help="Helps you to perform segmentation within partners and design questionaires.")
|
||||
help="Helps you to perform segmentation within partners and design segmentation questionnaires")
|
||||
}
|
||||
marketing_installer()
|
||||
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
"author" : "OpenERP SA",
|
||||
"category": 'Generic Modules/Marketing',
|
||||
"description": """
|
||||
Allows you to setup leads automation through marketing campaigns. The campaigns
|
||||
are dynamic and multi-channels. The process:
|
||||
* Design marketing campaigns that incluces mail templates, reports to print,
|
||||
miscelleanous actions, etc.
|
||||
* Define segments that are selections of target people
|
||||
* Launch your campaign to automate communications.
|
||||
|
||||
If you need demo data, you can install the module marketing_campaign_crm_demo.
|
||||
This module provides leads automation through marketing campaigns (campaigns can in fact be defined on any resource, not just CRM Leads).
|
||||
The campaigns are dynamic and multi-channels. The process is as follows:
|
||||
* Design marketing campaigns like workflows, including email templates to send, reports to print and send by email, custom actions, etc.
|
||||
* Define input segments that will select the items that should enter the campaign (e.g leads from certain countries, etc.)
|
||||
* Run you campaign in simulation mode to test it real-time or accelerated, and fine-tune it
|
||||
* You may also start the real campaign in manual mode, where each action requires manual validation
|
||||
* Finally launch your campaign live, and watch the statistics as the campaign does everything fully automatically.
|
||||
While the campaign runs you can of course continue to fine-tune the parameters, input segments, workflow, etc.
|
||||
|
||||
Note: If you need demo data, you can install the marketing_campaign_crm_demo module, but this will also install the CRM application as it depends on CRM Leads.
|
||||
""",
|
||||
'website': 'http://www.openerp.com',
|
||||
'init_xml': [],
|
||||
|
|
|
@ -1,914 +0,0 @@
|
|||
# Translation of OpenERP Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * marketing_campaign
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 6.0dev\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2010-08-20 07:30:00+0000\n"
|
||||
"PO-Revision-Date: 2010-08-20 07:30:00+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: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The current step for this item has no email or report to preview."
|
||||
msgstr "The current step for this item has no email or report to preview."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,trigger:0
|
||||
msgid "Time"
|
||||
msgstr "Time"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: view:marketing.campaign:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Group By..."
|
||||
msgstr "Group By..."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.transition,trigger:0
|
||||
msgid "Trigger"
|
||||
msgstr "Trigger"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Invalid model name in the action definition."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:campaign.analysis,count:0
|
||||
msgid "# of Actions"
|
||||
msgstr "# of Actions"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
msgid "Campaign Editor"
|
||||
msgstr "Campaign Editor"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
msgid "Today"
|
||||
msgstr "Today"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "March"
|
||||
msgstr "March"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,object_id:0
|
||||
#: field:marketing.campaign.segment,object_id:0
|
||||
#: field:marketing.campaign.workitem,object_id:0
|
||||
msgid "Object"
|
||||
msgstr "Object"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Set to Draft"
|
||||
msgstr "Set to Draft"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,to_ids:0
|
||||
msgid "Next Activities"
|
||||
msgstr "Next Activities"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Synchronization"
|
||||
msgstr "Synchronization"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
msgid "This Year"
|
||||
msgstr "This Year"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign,partner_field_id:0
|
||||
msgid "The generated workitems will be linked to the partner related to the record. If the record is the partner itself left this field empty."
|
||||
msgstr "The generated workitems will be linked to the partner related to the record. If the record is the partner itself left this field empty."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "No preview"
|
||||
msgstr "No preview"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.activity:0
|
||||
msgid "Outgoing Transitions"
|
||||
msgstr "Outgoing Transitions"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Reset"
|
||||
msgstr "Reset"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,type:0
|
||||
msgid "Describe type of action to be performed on the Activity.Eg : Send email,Send paper.."
|
||||
msgstr "Describe type of action to be performed on the Activity.Eg : Send email,Send paper.."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,interval_type:0
|
||||
msgid "Year(s)"
|
||||
msgstr "Year(s)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,report_directory_id:0
|
||||
msgid "This folder is used to store the generated reports"
|
||||
msgstr "This folder is used to store the generated reports"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: selection:marketing.campaign,state:0
|
||||
#: selection:marketing.campaign.segment,state:0
|
||||
#: selection:marketing.campaign.workitem,state:0
|
||||
msgid "Cancelled"
|
||||
msgstr "Cancelled"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,trigger:0
|
||||
msgid "Automatic"
|
||||
msgstr "Automatic"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.activity:0
|
||||
msgid "Activity Definition"
|
||||
msgstr "Activity Definition"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,keep_if_condition_not_met:0
|
||||
msgid "Keep as cancelled when condition not met"
|
||||
msgstr "Keep as cancelled when condition not met"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign,mode:0
|
||||
msgid "Test - It creates and process all the activities directly (without waiting for the delay on transitions) but does not send emails or produce reports.\n"
|
||||
"Test in Realtime - It creates and processes all the activities directly but does not send emails or produce reports.\n"
|
||||
"With Manual Confirmation - the campaigns runs normally, but the user has to validate all workitem manually.\n"
|
||||
"Normal - the campaign runs normally and automatically sends all emails and reports (be very careful with this mode, you're live!)"
|
||||
msgstr "Test - It creates and process all the activities directly (without waiting for the delay on transitions) but does not send emails or produce reports.\n"
|
||||
"Test in Realtime - It creates and processes all the activities directly but does not send emails or produce reports.\n"
|
||||
"With Manual Confirmation - the campaigns runs normally, but the user has to validate all workitem manually.\n"
|
||||
"Normal - the campaign runs normally and automatically sends all emails and reports (be very careful with this mode, you're live!)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,campaign_id:0
|
||||
#: view:marketing.campaign:0
|
||||
#: field:marketing.campaign.activity,campaign_id:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: field:marketing.campaign.segment,campaign_id:0
|
||||
#: field:marketing.campaign.workitem,campaign_id:0
|
||||
msgid "Campaign"
|
||||
msgstr "Campaign"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,start:0
|
||||
msgid "Start"
|
||||
msgstr "Start"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,segment_id:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: field:marketing.campaign.workitem,segment_id:0
|
||||
msgid "Segment"
|
||||
msgstr "Segment"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.segment,sync_mode:0
|
||||
msgid "Workitem creation mode"
|
||||
msgstr "Workitem creation mode"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,interval_type:0
|
||||
msgid "Month(s)"
|
||||
msgstr "Month(s)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The campaign hasn't any starting activity nor any activity with a signal and no previous activity."
|
||||
msgstr "The campaign hasn't any starting activity nor any activity with a signal and no previous activity."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,partner_id:0
|
||||
#: model:ir.model,name:marketing_campaign.model_res_partner
|
||||
#: field:marketing.campaign.workitem,partner_id:0
|
||||
msgid "Partner"
|
||||
msgstr "Partner"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.segment,sync_mode:0
|
||||
msgid "If record created after last sync"
|
||||
msgstr "If record created after last sync"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.activity:0
|
||||
msgid "Transitions"
|
||||
msgstr "Transitions"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Create After Sync"
|
||||
msgstr "Create After Sync"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Dates"
|
||||
msgstr "Dates"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.segment,sync_mode:0
|
||||
msgid "Determines when new workitems should be created for records matching a segment."
|
||||
msgstr "Determines when new workitems should be created for records matching a segment."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: view:marketing.campaign:0
|
||||
#: field:marketing.campaign,state:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: field:marketing.campaign.segment,state:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: field:marketing.campaign.workitem,state:0
|
||||
msgid "State"
|
||||
msgstr "State"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.module.module,description:marketing_campaign.module_meta_information
|
||||
msgid "\n"
|
||||
"Allows you to setup leads automation through marketing campaigns. The campaigns\n"
|
||||
"are dynamic and multi-channels. The process:\n"
|
||||
"* Design marketing campaigns that incluces mail templates, reports to print,\n"
|
||||
" miscelleanous actions, etc.\n"
|
||||
"* Define segments that are selections of target people\n"
|
||||
"* Launch your campaign to automate communications.\n"
|
||||
"\n"
|
||||
"If you need demo data, you can install the module marketing_campaign_crm_demo.\n"
|
||||
" "
|
||||
msgstr "\n"
|
||||
"Allows you to setup leads automation through marketing campaigns. The campaigns\n"
|
||||
"are dynamic and multi-channels. The process:\n"
|
||||
"* Design marketing campaigns that incluces mail templates, reports to print,\n"
|
||||
" miscelleanous actions, etc.\n"
|
||||
"* Define segments that are selections of target people\n"
|
||||
"* Launch your campaign to automate communications.\n"
|
||||
"\n"
|
||||
"If you need demo data, you can install the module marketing_campaign_crm_demo.\n"
|
||||
" "
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,condition:0
|
||||
msgid "Python expression to decide whether the activity can be executed, otherwise it will be deleted or cancelled.The expression may use the following [browsable] variables:\n"
|
||||
" - activity: the campaign activity\n"
|
||||
" - workitem: the campaign workitem\n"
|
||||
" - object: the object this campaign item represents\n"
|
||||
" - transitions: list of campaign transitions outgoing from this activity\n"
|
||||
"...- re: Python regular expression module"
|
||||
msgstr "Python expression to decide whether the activity can be executed, otherwise it will be deleted or cancelled.The expression may use the following [browsable] variables:\n"
|
||||
" - activity: the campaign activity\n"
|
||||
" - workitem: the campaign workitem\n"
|
||||
" - object: the object this campaign item represents\n"
|
||||
" - transitions: list of campaign transitions outgoing from this activity\n"
|
||||
"...- re: Python regular expression module"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
msgid "Marketing Reports"
|
||||
msgstr "Marketing Reports"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,type:0
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.workitem,res_name:0
|
||||
msgid "Resource Name"
|
||||
msgstr "Resource Name"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Run"
|
||||
msgstr "Run"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The campaign cannot be started: an email account is missing in the email activity '%s'"
|
||||
msgstr "The campaign cannot be started: an email account is missing in the email activity '%s'"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,from_ids:0
|
||||
msgid "Previous Activities"
|
||||
msgstr "Previous Activities"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.transition,activity_from_id:0
|
||||
msgid "Previous Activity"
|
||||
msgstr "Previous Activity"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Marketing Campaign Activities"
|
||||
msgstr "Marketing Campaign Activities"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: field:marketing.campaign.workitem,error_msg:0
|
||||
msgid "Error Message"
|
||||
msgstr "Error Message"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.actions.act_window,name:marketing_campaign.action_campaign_analysis_all
|
||||
#: model:ir.actions.act_window,name:marketing_campaign.action_marketing_campaign_form
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_action_campaign_analysis_all
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_marketing_campaign
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_marketing_campaign_form
|
||||
#: view:marketing.campaign:0
|
||||
msgid "Campaigns"
|
||||
msgstr "Campaigns"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.transition,interval_type:0
|
||||
msgid "Interval Unit"
|
||||
msgstr "Interval Unit"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:campaign.analysis,country_id:0
|
||||
msgid "Country"
|
||||
msgstr "Country"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "July"
|
||||
msgstr "July"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_marketing_configuration
|
||||
msgid "Configuration"
|
||||
msgstr "Configuration"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: constraint:ir.cron:0
|
||||
msgid "Invalid arguments"
|
||||
msgstr "Invalid arguments"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "Invalid XML for View Architecture!"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,interval_type:0
|
||||
msgid "Hour(s)"
|
||||
msgstr "Hour(s)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_marketing_campaign_segment
|
||||
msgid "Campaign Segment"
|
||||
msgstr "Campaign Segment"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,keep_if_condition_not_met:0
|
||||
msgid "By activating this option, workitems that aren't executed because the condition is not met are marked as cancelled instead of being deleted."
|
||||
msgstr "By activating this option, workitems that aren't executed because the condition is not met are marked as cancelled instead of being deleted."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
msgid "Exceptions"
|
||||
msgstr "Exceptions"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:res.partner,workitem_ids:0
|
||||
msgid "Workitems"
|
||||
msgstr "Workitems"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign,fixed_cost:0
|
||||
msgid "Fixed Cost"
|
||||
msgstr "Fixed Cost"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.transition,interval_nbr:0
|
||||
msgid "Interval Value"
|
||||
msgstr "Interval Value"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:campaign.analysis,revenue:0
|
||||
#: field:marketing.campaign.activity,revenue:0
|
||||
msgid "Revenue"
|
||||
msgstr "Revenue"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "September"
|
||||
msgstr "September"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "December"
|
||||
msgstr "December"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,month:0
|
||||
msgid "Month"
|
||||
msgstr "Month"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.transition,activity_to_id:0
|
||||
msgid "Next Activity"
|
||||
msgstr "Next Activity"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,email_template_id:0
|
||||
msgid "The e-mail to send when this activity is activated"
|
||||
msgstr "The e-mail to send when this activity is activated"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
msgid "This Month"
|
||||
msgstr "This Month"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
msgid "Test Mode"
|
||||
msgstr "Test Mode"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_ir_actions_report_xml
|
||||
msgid "ir.actions.report.xml"
|
||||
msgstr "ir.actions.report.xml"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
msgid "Manual Mode"
|
||||
msgstr "Manual Mode"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,server_action_id:0
|
||||
msgid "The action to perform when this activity is activated"
|
||||
msgstr "The action to perform when this activity is activated"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign,partner_field_id:0
|
||||
msgid "Partner Field"
|
||||
msgstr "Partner Field"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_campaign_analysis
|
||||
msgid "Campaign Analysis"
|
||||
msgstr "Campaign Analysis"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign,mode:0
|
||||
msgid "Test in Realtime"
|
||||
msgstr "Test in Realtime"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign,mode:0
|
||||
msgid "Test Directly"
|
||||
msgstr "Test Directly"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,report_directory_id:0
|
||||
msgid "Directory"
|
||||
msgstr "Directory"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.segment,sync_last_date:0
|
||||
msgid "Latest Synchronization"
|
||||
msgstr "Latest Synchronization"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: selection:marketing.campaign,state:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: selection:marketing.campaign.segment,state:0
|
||||
msgid "Draft"
|
||||
msgstr "Draft"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: constraint:ir.ui.menu:0
|
||||
msgid "Error ! You can not create recursive Menu."
|
||||
msgstr "Error ! You can not create recursive Menu."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.segment,date_run:0
|
||||
msgid "Launching Date"
|
||||
msgstr "Launching Date"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: constraint:ir.model:0
|
||||
msgid "The Object name must start with x_ and not contain any special character !"
|
||||
msgstr "The Object name must start with x_ and not contain any special character !"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Preview"
|
||||
msgstr "Preview"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Run Date"
|
||||
msgstr "Run Date"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Related Resource"
|
||||
msgstr "Related Resource"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "August"
|
||||
msgstr "August"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign,mode:0
|
||||
msgid "Normal"
|
||||
msgstr "Normal"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,start:0
|
||||
msgid "This activity is launched when the campaign starts."
|
||||
msgstr "This activity is launched when the campaign starts."
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.activity,signal:0
|
||||
msgid "An activity with a signal can be called programmatically. Be careful, the workitem is always created when a signal is sent"
|
||||
msgstr "An activity with a signal can be called programmatically. Be careful, the workitem is always created when a signal is sent"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "June"
|
||||
msgstr "June"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.segment,sync_mode:0
|
||||
msgid "All records (no duplicates)"
|
||||
msgstr "All records (no duplicates)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,date:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Date"
|
||||
msgstr "Date"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "November"
|
||||
msgstr "November"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,condition:0
|
||||
msgid "Condition"
|
||||
msgstr "Condition"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,report_id:0
|
||||
msgid "The report to generate when this activity is activated"
|
||||
msgstr "The report to generate when this activity is activated"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: selection:marketing.campaign.workitem,state:0
|
||||
msgid "Exception"
|
||||
msgstr "Exception"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "October"
|
||||
msgstr "October"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign,fixed_cost:0
|
||||
msgid "Fixed cost for the campaign (used for campaign analysis), see also variable cost on activities"
|
||||
msgstr "Fixed cost for the campaign (used for campaign analysis), see also variable cost on activities"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "January"
|
||||
msgstr "January"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: field:marketing.campaign.workitem,date:0
|
||||
msgid "Execution Date"
|
||||
msgstr "Execution Date"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_marketing_campaign_workitem
|
||||
msgid "Campaign Workitem"
|
||||
msgstr "Campaign Workitem"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.segment,ir_filter_id:0
|
||||
msgid "Filter"
|
||||
msgstr "Filter"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Synchronize"
|
||||
msgstr "Synchronize"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.activity:0
|
||||
#: field:marketing.campaign.activity,server_action_id:0
|
||||
#: selection:marketing.campaign.activity,type:0
|
||||
msgid "Action"
|
||||
msgstr "Action"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "Automatic transition"
|
||||
msgstr "Automatic transition"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:res.partner:0
|
||||
msgid "History"
|
||||
msgstr "History"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign,object_id:0
|
||||
msgid "Choose the model on which you want this campaign to be run"
|
||||
msgstr "Choose the model on which you want this campaign to be run"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.module.module,shortdesc:marketing_campaign.module_meta_information
|
||||
msgid "marketing_campaign"
|
||||
msgstr "marketing_campaign"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Process"
|
||||
msgstr "Process"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#: selection:marketing.campaign.transition,trigger:0
|
||||
#, python-format
|
||||
msgid "Cosmetic"
|
||||
msgstr "Cosmetic"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.transition,trigger:0
|
||||
msgid "How is the destination workitem triggered"
|
||||
msgstr "How is the destination workitem triggered"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: selection:marketing.campaign,state:0
|
||||
#: selection:marketing.campaign.segment,state:0
|
||||
#: selection:marketing.campaign.workitem,state:0
|
||||
msgid "Done"
|
||||
msgstr "Done"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_email_template
|
||||
msgid "Email Templates for Models"
|
||||
msgstr "Email Templates for Models"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Close"
|
||||
msgstr "Close"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The campaign cannot be marked as done before all segments are done"
|
||||
msgstr "The campaign cannot be marked as done before all segments are done"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.workitem,res_id:0
|
||||
msgid "Resource ID"
|
||||
msgstr "Resource ID"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_marketing_campaign_transition
|
||||
msgid "Campaign Transition"
|
||||
msgstr "Campaign Transition"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: selection:marketing.campaign.workitem,state:0
|
||||
msgid "To Do"
|
||||
msgstr "To Do"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.workitem:0
|
||||
msgid "Campaign Step"
|
||||
msgstr "Campaign Step"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.actions.act_window,name:marketing_campaign.action_marketing_campaign_segment_form
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_marketing_campaign_segment_form
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Segments"
|
||||
msgstr "Segments"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.actions.act_window,name:marketing_campaign.act_marketing_campaing_segment_opened
|
||||
msgid "All Segments"
|
||||
msgstr "All Segments"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.activity:0
|
||||
msgid "Incoming Transitions"
|
||||
msgstr "Incoming Transitions"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.activity,type:0
|
||||
msgid "E-mail"
|
||||
msgstr "E-mail"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The campaign cannot be started: the email account is not approved in the email activity '%s'"
|
||||
msgstr "The campaign cannot be started: the email account is not approved in the email activity '%s'"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.transition,interval_type:0
|
||||
msgid "Day(s)"
|
||||
msgstr "Day(s)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign,activity_ids:0
|
||||
#: view:marketing.campaign.activity:0
|
||||
msgid "Activities"
|
||||
msgstr "Activities"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "May"
|
||||
msgstr "May"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign.segment:0
|
||||
msgid "Modified after Sync"
|
||||
msgstr "Modified after Sync"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: selection:marketing.campaign,state:0
|
||||
#: view:marketing.campaign.segment:0
|
||||
#: selection:marketing.campaign.segment,state:0
|
||||
msgid "Running"
|
||||
msgstr "Running"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.activity,type:0
|
||||
msgid "Paper"
|
||||
msgstr "Paper"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "After %(interval_nbr)d %(interval_type)s"
|
||||
msgstr "After %(interval_nbr)d %(interval_type)s"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_marketing_campaign
|
||||
msgid "Marketing Campaign"
|
||||
msgstr "Marketing Campaign"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.segment,date_done:0
|
||||
msgid "End Date"
|
||||
msgstr "End Date"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "February"
|
||||
msgstr "February"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: field:marketing.campaign,object_id:0
|
||||
msgid "Resource"
|
||||
msgstr "Resource"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign,name:0
|
||||
#: field:marketing.campaign.activity,name:0
|
||||
#: field:marketing.campaign.segment,name:0
|
||||
#: field:marketing.campaign.transition,name:0
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "Email Preview"
|
||||
msgstr "Email Preview"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,signal:0
|
||||
msgid "Signal"
|
||||
msgstr "Signal"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: help:marketing.campaign.workitem,date:0
|
||||
msgid "If date is not set, this workitem have to be run manually"
|
||||
msgstr "If date is not set, this workitem have to be run manually"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: code:addons/marketing_campaign/marketing_campaign.py:0
|
||||
#, python-format
|
||||
msgid "The campaign cannot be started: there are no activities in it"
|
||||
msgstr "The campaign cannot be started: there are no activities in it"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:campaign.analysis,month:0
|
||||
msgid "April"
|
||||
msgstr "April"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:marketing.campaign:0
|
||||
#: field:marketing.campaign,mode:0
|
||||
msgid "Mode"
|
||||
msgstr "Mode"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:campaign.analysis,activity_id:0
|
||||
#: view:marketing.campaign.workitem:0
|
||||
#: field:marketing.campaign.workitem,activity_id:0
|
||||
msgid "Activity"
|
||||
msgstr "Activity"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.actions.act_window,name:marketing_campaign.action_marketing_campaign_workitem
|
||||
#: model:ir.ui.menu,name:marketing_campaign.menu_action_marketing_campaign_workitem
|
||||
msgid "Campaign Followup"
|
||||
msgstr "Campaign Followup"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: model:ir.model,name:marketing_campaign.model_marketing_campaign_activity
|
||||
msgid "Campaign Activity"
|
||||
msgstr "Campaign Activity"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: field:marketing.campaign.activity,variable_cost:0
|
||||
msgid "Variable Cost"
|
||||
msgstr "Variable Cost"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign.segment,sync_mode:0
|
||||
msgid "If record modified after last sync (no duplicates)"
|
||||
msgstr "If record modified after last sync (no duplicates)"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: selection:marketing.campaign,mode:0
|
||||
msgid "With Manual Confirmation"
|
||||
msgstr "With Manual Confirmation"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,total_cost:0
|
||||
msgid "Cost"
|
||||
msgstr "Cost"
|
||||
|
||||
#. module: marketing_campaign
|
||||
#: view:campaign.analysis:0
|
||||
#: field:campaign.analysis,year:0
|
||||
msgid "Year"
|
||||
msgstr "Year"
|
||||
|
|
@ -91,7 +91,7 @@ class marketing_campaign(osv.osv):
|
|||
this campaign to be run"),
|
||||
'partner_field_id': fields.many2one('ir.model.fields', 'Partner Field',
|
||||
domain="[('model_id', '=', object_id), ('ttype', '=', 'many2one'), ('relation', '=', 'res.partner')]",
|
||||
help="The generated workitems will be linked to the partner related to the record. If the record is the partner itself left this field empty."),
|
||||
help="The generated workitems will be linked to the partner related to the record. If the record is the partner itself leave this field empty."),
|
||||
'mode': fields.selection([('test', 'Test Directly'),
|
||||
('test_realtime', 'Test in Realtime'),
|
||||
('manual', 'With Manual Confirmation'),
|
||||
|
@ -108,7 +108,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
|
|||
'State',),
|
||||
'activity_ids': fields.one2many('marketing.campaign.activity',
|
||||
'campaign_id', 'Activities'),
|
||||
'fixed_cost': fields.float('Fixed Cost', help="Fixed cost for the campaign (used for campaign analysis), see also variable cost on activities"),
|
||||
'fixed_cost': fields.float('Fixed Cost', help="Fixed cost for running this campaign. You may also specify variable cost and revenue on each campaign activity. Cost and Revenue statistics are included in Campaign Reporting."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -220,20 +220,20 @@ class marketing_campaign_segment(osv.osv):
|
|||
'object_id': fields.related('campaign_id','object_id',
|
||||
type='many2one', relation='ir.model',
|
||||
string='Object'),
|
||||
'ir_filter_id': fields.many2one('ir.filters', 'Filter', help=""),
|
||||
'sync_last_date': fields.datetime('Latest Synchronization'),
|
||||
'ir_filter_id': fields.many2one('ir.filters', 'Filter', help="Filter to select the matching resource records that belong to this segment. New filters can be created and saved using the advanced search on the list view of the Resource"),
|
||||
'sync_last_date': fields.datetime('Last Synchronization', help="Date on which this segment was synchronized last time (automatically or manually)"),
|
||||
'sync_mode': fields.selection([('create_date', 'If record created after last sync'),
|
||||
('write_date', 'If record modified after last sync (no duplicates)'),
|
||||
('all', 'All records (no duplicates)')],
|
||||
'Workitem creation mode',
|
||||
help="Determines when new workitems should be created for records matching a segment."),
|
||||
help="Determines how new campaign workitems are created for resource records matching this segment. This is used when segments are synchronized manually, or automatically via the scheduled job."),
|
||||
'state': fields.selection([('draft', 'Draft'),
|
||||
('running', 'Running'),
|
||||
('done', 'Done'),
|
||||
('cancelled', 'Cancelled')],
|
||||
'State',),
|
||||
'date_run': fields.datetime('Launching Date'),
|
||||
'date_done': fields.datetime('End Date'),
|
||||
'date_run': fields.datetime('Launching Date', help="Initial start date of this segment."),
|
||||
'date_done': fields.datetime('End Date', help="Date this segment was last closed or cancelled."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
|
@ -241,6 +241,34 @@ class marketing_campaign_segment(osv.osv):
|
|||
'sync_mode': lambda *a: 'create_date',
|
||||
}
|
||||
|
||||
def _check_model(self, cr, uid, ids, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if not obj.ir_filter_id:
|
||||
return True
|
||||
if obj.campaign_id.object_id.model != obj.ir_filter_id.model_id:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_model, _('Model of filter must be same as resource model of Campaign '), ['ir_filter_id,campaign_id']),
|
||||
]
|
||||
|
||||
def onchange_campaign_id(self, cr, uid, ids, campaign_id):
|
||||
res = {'domain':{'ir_filter_id':[]}}
|
||||
campaign_pool = self.pool.get('marketing.campaign')
|
||||
if campaign_id:
|
||||
campaign = campaign_pool.browse(cr, uid, campaign_id)
|
||||
model_name = self.pool.get('ir.model').read(cr, uid, [campaign.object_id.id], ['model'])
|
||||
if model_name:
|
||||
mod_name = model_name[0]['model']
|
||||
res['domain'] = {'ir_filter_id': [('model_id', '=', mod_name)]}
|
||||
res['context'] = {'default_model_id': model_name[0]['model']}
|
||||
else:
|
||||
res['value'] = {'ir_filter_id': False}
|
||||
return res
|
||||
|
||||
def state_running_set(self, cr, uid, ids, *args):
|
||||
segment = self.browse(cr, uid, ids[0])
|
||||
vals = {'state': 'running'}
|
||||
|
@ -325,8 +353,8 @@ class marketing_campaign_activity(osv.osv):
|
|||
|
||||
_action_types = [
|
||||
('email', 'E-mail'),
|
||||
('paper', 'Paper'),
|
||||
('action', 'Action'),
|
||||
('report', 'Report'),
|
||||
('action', 'Custom Action'),
|
||||
# TODO implement the subcampaigns.
|
||||
# TODO implement the subcampaign out. disallow out transitions from
|
||||
# subcampaign activities ?
|
||||
|
@ -346,13 +374,17 @@ class marketing_campaign_activity(osv.osv):
|
|||
"The expression may use the following [browsable] variables:\n"
|
||||
" - activity: the campaign activity\n"
|
||||
" - workitem: the campaign workitem\n"
|
||||
" - object: the object this campaign item represents\n"
|
||||
" - resource: the resource object this campaign item represents\n"
|
||||
" - transitions: list of campaign transitions outgoing from this activity\n"
|
||||
"...- re: Python regular expression module"),
|
||||
'type': fields.selection(_action_types, 'Type', required=True,
|
||||
help="Describe type of action to be performed on the Activity.Eg : Send email,Send paper.."),
|
||||
'email_template_id': fields.many2one('email.template','The e-mail to send when this activity is activated'),
|
||||
'report_id': fields.many2one('ir.actions.report.xml', 'The report to generate when this activity is activated', ),
|
||||
help="""The type of action to execute when an item enters this activity, such as:
|
||||
- Email: send an email using a predefined email template
|
||||
- Report: print an existing Report defined on the resource item and save it into a specific directory
|
||||
- Custom Action: execute a predefined action, e.g. to modify the fields of the resource record
|
||||
"""),
|
||||
'email_template_id': fields.many2one('email.template', "Email Template", help='The e-mail to send when this activity is activated'),
|
||||
'report_id': fields.many2one('ir.actions.report.xml', "Report", help='The report to generate when this activity is activated', ),
|
||||
'report_directory_id': fields.many2one('document.directory','Directory',
|
||||
help="This folder is used to store the generated reports"),
|
||||
'server_action_id': fields.many2one('ir.actions.server', string='Action',
|
||||
|
@ -363,11 +395,11 @@ class marketing_campaign_activity(osv.osv):
|
|||
'from_ids': fields.one2many('marketing.campaign.transition',
|
||||
'activity_to_id',
|
||||
'Previous Activities'),
|
||||
'variable_cost': fields.float('Variable Cost'),
|
||||
'revenue': fields.float('Revenue'),
|
||||
'variable_cost': fields.float('Variable Cost', help="Set a variable cost if you consider that every campaign item that has reached this point has entailed a certain cost. You can get cost statistics in the Reporting section"),
|
||||
'revenue': fields.float('Revenue', help="Set an expected revenue if you consider that every campaign item that has reached this point has generated a certain revenue. You can get revenue statistics in the Reporting section"),
|
||||
'signal': fields.char('Signal', size=128,
|
||||
help='An activity with a signal can be called programmatically. Be careful, the workitem is always created when a signal is sent'),
|
||||
'keep_if_condition_not_met': fields.boolean('Keep as cancelled when condition not met',
|
||||
'keep_if_condition_not_met': fields.boolean("Don't delete workitems",
|
||||
help="By activating this option, workitems that aren't executed because the condition is not met are marked as cancelled instead of being deleted.")
|
||||
}
|
||||
|
||||
|
@ -390,7 +422,7 @@ class marketing_campaign_activity(osv.osv):
|
|||
return super(marketing_campaign_activity, self).search(cr, uid, args,
|
||||
offset, limit, order, context, count)
|
||||
|
||||
def _process_wi_paper(self, cr, uid, activity, workitem, context=None):
|
||||
def _process_wi_report(self, cr, uid, activity, workitem, context=None):
|
||||
service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
|
||||
(report_data, format) = service.create(cr, uid, [], {}, {})
|
||||
attach_vals = {
|
||||
|
@ -517,23 +549,50 @@ class marketing_campaign_workitem(osv.osv):
|
|||
res[wi.id] = ng[0][1]
|
||||
return res
|
||||
|
||||
def _resource_search(self, cr, uid, obj, name, args, domain=None, context=None):
|
||||
"""Returns id of workitem whose resource_name matches with the given name"""
|
||||
if context is None:
|
||||
context = {}
|
||||
if not len(args):
|
||||
return []
|
||||
|
||||
condition = []
|
||||
final_ids = []
|
||||
|
||||
cr.execute("""select w.id, w.res_id, m.model \
|
||||
from marketing_campaign_workitem w \
|
||||
left join marketing_campaign_activity a on (a.id=w.activity_id)\
|
||||
left join marketing_campaign c on (c.id=a.campaign_id)\
|
||||
left join ir_model m on (m.id=c.object_id)
|
||||
""")
|
||||
res = cr.fetchall()
|
||||
for id, res_id, model in res:
|
||||
model_pool = self.pool.get(model)
|
||||
for arg in args:
|
||||
if arg[1] == 'ilike':
|
||||
condition.append((model_pool._rec_name, 'ilike', arg[2]))
|
||||
res_ids = model_pool.search(cr, uid, condition, context=context)
|
||||
if res_id in res_ids:
|
||||
final_ids.append(id)
|
||||
return [('id', 'in', final_ids)]
|
||||
|
||||
_columns = {
|
||||
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment'),
|
||||
'segment_id': fields.many2one('marketing.campaign.segment', 'Segment', readonly=True),
|
||||
'activity_id': fields.many2one('marketing.campaign.activity','Activity',
|
||||
required=True),
|
||||
required=True, readonly=True),
|
||||
'campaign_id': fields.related('activity_id', 'campaign_id',
|
||||
type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
|
||||
'object_id': fields.related('activity_id', 'campaign_id', 'object_id',
|
||||
type='many2one', relation='ir.model', string='Object', select=1),
|
||||
'res_id': fields.integer('Resource ID', select=1, readonly=1),
|
||||
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64),
|
||||
'date': fields.datetime('Execution Date', help='If date is not set, this workitem have to be run manually'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', select=1),
|
||||
type='many2one', relation='ir.model', string='Resource', select=1, readonly=True),
|
||||
'res_id': fields.integer('Resource ID', select=1, readonly=True),
|
||||
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', fnct_search=_resource_search, type="char", size=64),
|
||||
'date': fields.datetime('Execution Date', help='If date is not set, this workitem has to be run manually', readonly=True),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', select=1, readonly=True),
|
||||
'state': fields.selection([('todo', 'To Do'),
|
||||
('exception', 'Exception'), ('done', 'Done'),
|
||||
('cancelled', 'Cancelled')], 'State'),
|
||||
('cancelled', 'Cancelled')], 'State', readonly=True),
|
||||
|
||||
'error_msg' : fields.text('Error Message')
|
||||
'error_msg' : fields.text('Error Message', readonly=True)
|
||||
}
|
||||
_defaults = {
|
||||
'state': lambda *a: 'todo',
|
||||
|
@ -564,6 +623,7 @@ class marketing_campaign_workitem(osv.osv):
|
|||
'activity': activity,
|
||||
'workitem': workitem,
|
||||
'object': object_id,
|
||||
'resource': object_id,
|
||||
'transitions': activity.to_ids,
|
||||
're': re,
|
||||
}
|
||||
|
@ -688,7 +748,7 @@ class marketing_campaign_workitem(osv.osv):
|
|||
wi_obj.res_id)
|
||||
}
|
||||
|
||||
elif wi_obj.activity_id.type == 'paper':
|
||||
elif wi_obj.activity_id.type == 'report':
|
||||
datas = {
|
||||
'ids': [wi_obj.res_id],
|
||||
'model': wi_obj.object_id.model
|
||||
|
|
|
@ -17,16 +17,25 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Campaign">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="object_id" select="1"/>
|
||||
<field name="mode"/>
|
||||
<field name="fixed_cost"/>
|
||||
<field name="partner_field_id"/>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Campaign" colspan="2" />
|
||||
<field name="name" select="1"/>
|
||||
<field name="mode"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Resource" colspan="2" />
|
||||
<field name="object_id"/>
|
||||
<field name="partner_field_id"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Cost" colspan="2" />
|
||||
<field name="fixed_cost"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="activity_ids" nolabel = "1" colspan="4" default_get="{'default_object_id': object_id}" />
|
||||
<separator string="Status" colspan="4" />
|
||||
<separator string="" colspan="4" />
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1" select="2" nolabel="1"/>
|
||||
<field name="state" readonly="1" />
|
||||
<button name="state_running_set" string="Run" states="draft,done,cancelled" icon="gtk-apply"/>
|
||||
<button name="state_draft_set" string="Set to Draft" states="done,cancelled" icon="gtk-convert"/>
|
||||
<button name="state_done_set" string="Close" states="running" icon="terp-dialog-close"/>
|
||||
|
@ -45,6 +54,7 @@
|
|||
<field name="name" select="1"/>
|
||||
<field name="object_id" select="1"/>
|
||||
<field name="mode"/>
|
||||
<field name="fixed_cost"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -125,27 +135,31 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Segments">
|
||||
<group colspan="4" col="6">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Segment" colspan="4"/>
|
||||
<field name="name"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
<field name="ir_filter_id" select="1"/>
|
||||
<field name="object_id" invisible="1" readonly="True"/>
|
||||
<field name="campaign_id" select="1" on_change="onchange_campaign_id(campaign_id)"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Synchronization" colspan="2"/>
|
||||
<separator string="Filter" colspan="4"/>
|
||||
<field name="ir_filter_id" select="1"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Synchronization" colspan="4"/>
|
||||
<field name="sync_mode" required="True"/>
|
||||
<field name="sync_last_date"/>
|
||||
<label string="" colspan="1"/>
|
||||
<button string="Synchronize" states="running" name="synchroniz" icon="gtk-apply" type="object"/>
|
||||
<button string="Synchronize" states="running" name="synchroniz" icon="terp-project" type="object"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Dates" colspan="2"/>
|
||||
<separator string="History" colspan="2"/>
|
||||
<field name="date_run" readonly="1"/>
|
||||
<field name="date_done" readonly="1"/>
|
||||
</group>
|
||||
<separator string="Status" colspan="4"/>
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1" select="2" nolabel="1"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group col="6" colspan="4">
|
||||
<field name="state" readonly="1"/>
|
||||
<button name="state_running_set" string="Run" states="draft" icon="gtk-apply"/>
|
||||
<button name="state_done_set" string="Close" states="running" icon="terp-dialog-close"/>
|
||||
<button name="state_cancel_set" string="Cancel" states="running" icon="terp-gtk-stop"/>
|
||||
|
@ -179,8 +193,9 @@
|
|||
<filter icon="terp-check" string="Running" name="running" domain="[('state','=','running')]"/>
|
||||
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-month" string="Create After Sync" domain="[('sync_mode','=','create_date')]"/>
|
||||
<filter icon="terp-go-month" string="Modified after Sync" domain="[('sync_mode','=','write_date')]"/>
|
||||
<filter icon="terp-project" string="Newly Created" domain="[('sync_mode','=','create_date')]"/>
|
||||
<filter icon="terp-project" string="Newly Modified" domain="[('sync_mode','=','write_date')]"/>
|
||||
<filter icon="terp-project" string="All" domain="[('sync_mode','=','all')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="campaign_id" select="1"/>
|
||||
|
@ -225,36 +240,38 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Activities">
|
||||
<field name="object_id" invisible="1"/>
|
||||
<separator string="Activity Definition" colspan="4"/>
|
||||
<field name="name" select="1" colspan='4' />
|
||||
<field name="signal"/>
|
||||
<field name="start"/>
|
||||
<field name="variable_cost" select="1"/>
|
||||
<group colspan='2' col='2'>
|
||||
<separator string="Activity" colspan="4"/>
|
||||
<field name="name" select="1" colspan='4' />
|
||||
<field name="signal" groups="base.group_extended"/>
|
||||
<field name="start"/>
|
||||
<field name="object_id" invisible="1"/>
|
||||
</group>
|
||||
<group colspan='2' col='2'>
|
||||
<separator string="Cost / Revenue" colspan="4"/>
|
||||
<field name="variable_cost"/>
|
||||
<field name="revenue"/>
|
||||
</group>
|
||||
<newline/>
|
||||
|
||||
<separator string="Action" colspan="4"/>
|
||||
<group colspan='4' col='2'>
|
||||
<separator string="Condition" colspan="4"/>
|
||||
<field name="condition" widget="char" colspan="2"/>
|
||||
<field name="keep_if_condition_not_met"/>
|
||||
</group>
|
||||
<group colspan='4' col='4'>
|
||||
<group colspan="4" col="6">
|
||||
<field name="condition" colspan="5" widget="char"/>
|
||||
<group col='2'>
|
||||
<field name="keep_if_condition_not_met" />
|
||||
</group>
|
||||
</group>
|
||||
<field name="type" width='100'/>
|
||||
<separator string="Action" colspan="4"/>
|
||||
<field name="type"/>
|
||||
<group colspan='2' col='1'>
|
||||
<field name="email_template_id" attrs="{'required':[('type','=','email')], 'invisible':[('type','!=','email')]}"
|
||||
context="{'default_object_name':object_id}" />
|
||||
<group attrs="{'invisible':[('type','!=','paper')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','paper')]}" context="{'object_id':object_id}"/>
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" />
|
||||
<group attrs="{'invisible':[('type','!=','report')]}" >
|
||||
<field name="report_id" attrs="{'required':[('type','=','report')]}" context="{'object_id':object_id}"/>
|
||||
<field name="report_directory_id" attrs="{'required':[('type','=','report')]}" />
|
||||
</group>
|
||||
<field name="server_action_id" attrs="{'required':[('type','=','action')],'invisible':[('type','!=','action')]}" domain="[('model_id','=',object_id)]" />
|
||||
</group>
|
||||
</group>
|
||||
<newline/>
|
||||
|
||||
<group colspan="4" col="2" expand="1">
|
||||
<group colspan="4" col="2">
|
||||
<separator string="Transitions" colspan="2"/>
|
||||
<field name="from_ids" nolabel="1" mode="tree,form" default_get="{'default_activity_to_id': active_id}">
|
||||
<tree string="Incoming Transitions" editable="bottom">
|
||||
|
@ -296,9 +313,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<tree string="Activities">
|
||||
<field name="name" select="1"/>
|
||||
<field name="start"/>
|
||||
<field name="condition"/>
|
||||
<field name="type"/>
|
||||
<field name="start"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -322,6 +339,7 @@
|
|||
<field name="partner_id"/>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<button string="Preview" states="todo" name="preview" icon="gtk-zoom-fit" type="object"/>
|
||||
<button string="Process" states="todo" name="process" type="object" icon="terp-gtk-go-back-rtl"/>
|
||||
<button string="Cancel" states="todo" name="button_cancel" type="object" icon="terp-gtk-stop"/>
|
||||
|
@ -358,9 +376,9 @@
|
|||
<separator string="Error Message" colspan="4"/>
|
||||
<field name="error_msg" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
<separator string="Status" colspan="4"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="4" col="11">
|
||||
<field name="state" nolabel="1" readonly="True" select="1"/>
|
||||
<field name="state" readonly="True"/>
|
||||
<button string="Reset" states="exception,cancelled" name="button_draft" type="object" icon="gtk-undo"/>
|
||||
<button string="Process" states="todo" name="process" type="object" icon="terp-gtk-go-back-rtl"/>
|
||||
<button string="Cancel" states="todo,exception" name="button_cancel" type="object" icon="terp-gtk-stop"/>
|
||||
|
@ -375,17 +393,21 @@
|
|||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Marketing Campaign Activities">
|
||||
<filter icon="terp-gtk-go-back-rtl" string="To Do" name = "todo" domain="[('state','=','todo')]"/>
|
||||
<filter icon="terp-go-today" string="Today" name="today" domain="[('date','<', time.strftime('%%Y-%%m-%%d 23:59:59')), ('date','>=', time.strftime('%%Y-%%m-%%d 00:00:00'))]"/>
|
||||
<filter icon="terp-gtk-go-back-rtl" string="To Do" name="todo" domain="[('state','=','todo')]"/>
|
||||
<filter icon="terp-emblem-important" string="Exception" domain="[('state','=','exception')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="segment_id" select="1"/>
|
||||
<field name="object_id" select="1"/>
|
||||
<field name="res_name" select="1"/>
|
||||
<field name="res_id" select="1"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
<field name="date" select="1"/>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." colspan="10" col="12">
|
||||
<filter string="Segment" name="Segment" icon="terp-stock_symbol-selection" context="{'group_by':'segment_id'}" />
|
||||
<filter string="Activity" name="Activity" icon="terp-stock_align_left_24" context="{'group_by':'activity_id'}" />
|
||||
<!--filter string="Campaign" name="campaign" icon="terp-gtk-jump-to-rtl" context="{'group_by':'campaign_id'}" /-->
|
||||
<filter string="Segment" name="segment" icon="terp-stock_symbol-selection" context="{'group_by':'segment_id'}" />
|
||||
<filter string="Activity" name="activity" icon="terp-stock_align_left_24" context="{'group_by':'activity_id'}" />
|
||||
<filter string="Resource" name="resource" icon="terp-accessories-archiver" context="{'group_by':'res_id'}" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="State" name="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}" />
|
||||
<separator orientation="vertical"/>
|
||||
|
@ -417,5 +439,19 @@
|
|||
domain="[('campaign_id','=',active_id)]"
|
||||
/>
|
||||
|
||||
<!-- Campaign Followups -->
|
||||
<act_window domain="[('campaign_id', '=', active_id)]"
|
||||
id="act_marketing_campaing_followup"
|
||||
name="Campaign Follow-ups" res_model="marketing.campaign.workitem"
|
||||
src_model="marketing.campaign" view_mode="tree,form"
|
||||
view_type="form" />
|
||||
|
||||
<!-- Campaign Statistics -->
|
||||
<act_window domain="[('campaign_id', '=', active_id)]"
|
||||
id="act_marketing_campaing_stat"
|
||||
name="Campaign Statistics" res_model="campaign.analysis"
|
||||
src_model="marketing.campaign" view_mode="tree,form"
|
||||
view_type="form" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -38,10 +38,11 @@ class campaign_analysis(osv.osv):
|
|||
wi_ids = self.pool.get('marketing.campaign.workitem').search(cr, uid,
|
||||
[('segment_id.campaign_id', '=', ca_obj.campaign_id.id)])
|
||||
total_cost = ca_obj.activity_id.variable_cost + \
|
||||
(ca_obj.campaign_id.fixed_cost / len(wi_ids))
|
||||
((ca_obj.campaign_id.fixed_cost or 0.00) / len(wi_ids))
|
||||
result[ca_obj.id] = total_cost
|
||||
return result
|
||||
_columns = {
|
||||
'res_id' : fields.integer('Resource', readonly=True),
|
||||
'year': fields.char('Year', size=4, readonly=True),
|
||||
'month':fields.selection([('01','January'), ('02','February'),
|
||||
('03','March'), ('04','April'),('05','May'), ('06','June'),
|
||||
|
@ -69,6 +70,7 @@ class campaign_analysis(osv.osv):
|
|||
create or replace view campaign_analysis as (
|
||||
select
|
||||
min(wi.id) as id,
|
||||
min(wi.res_id) as res_id,
|
||||
to_char(wi.date::date, 'YYYY') as year,
|
||||
to_char(wi.date::date, 'MM') as month,
|
||||
wi.date::date as date,
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<field name="segment_id" invisible="1"/>
|
||||
<field name="partner_id" invisible="1"/>
|
||||
<field name="country_id" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="count"/>
|
||||
<field name="total_cost" string="Cost"/><!-- sum="Cost"/-->
|
||||
<field name="revenue"/>
|
||||
|
@ -35,7 +36,7 @@
|
|||
<filter icon="terp-go-month"
|
||||
string="This Month"
|
||||
domain="[('month','=',time.strftime('%%m'))]"/>
|
||||
<filter icon="terp-go-month"
|
||||
<filter icon="terp-go-today"
|
||||
string="Today"
|
||||
domain="[('date','=',time.strftime('%%Y/%%m/%%d'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
|
@ -59,7 +60,9 @@
|
|||
<group expand="0" string="Group By..." colspan="10" col="12">
|
||||
<filter string="Campaign" name="Campaign" icon="terp-gtk-jump-to-rtl" context="{'group_by':'campaign_id'}" />
|
||||
<filter string="Segment" name ="Segment" icon="terp-stock_symbol-selection" context="{'group_by':'segment_id'}" />
|
||||
<filter string="State" icon="terp-stock_symbol-selection" context="{'group_by':'state'}"/>
|
||||
<filter string="Activity" name ="activity" icon="terp-stock_align_left_24" context="{'group_by':'activity_id'}" />
|
||||
<filter string="Resource" icon="terp-accessories-archiver" context="{'group_by':'res_id'}"/>
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
|
|
|
@ -191,7 +191,7 @@
|
|||
<field name="server_action_id" ref="action_dummy"/>
|
||||
<field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
|
||||
<field name="report_directory_id" ref="document_directory_campaign1"/>
|
||||
<field name="type">paper</field>
|
||||
<field name="type">report</field>
|
||||
<field eval="1" name="start"/>
|
||||
<field name="report_id" ref="mc_crm_lead_demo_report"/>
|
||||
</record>
|
||||
|
@ -220,7 +220,7 @@
|
|||
<field name="server_action_id" ref="action_dummy"/>
|
||||
<field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
|
||||
<field name="report_directory_id" ref="document_directory_campaign1"/>
|
||||
<field name="type">paper</field>
|
||||
<field name="type">report</field>
|
||||
<field name="report_id" ref="mc_crm_lead_demo_report"/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -26,11 +26,13 @@
|
|||
"depends" : ['marketing_campaign'],
|
||||
"author" : "OpenERP SA",
|
||||
"category": 'Generic Modules/Marketing',
|
||||
"description": """
|
||||
""",
|
||||
"description": """
|
||||
This module provides integration of the mailchimp.com marketing campaign and mailing-list service, connecting via Mailchimp's WebServices API.
|
||||
You can define multiple Mailchimp accounts and then use them as you wish through a new type of activity, providing direct connection to your Mailchimp Lists.""",
|
||||
'website': 'http://www.openerp.com',
|
||||
'init_xml': [],
|
||||
'update_xml': [
|
||||
"security/ir.model.access.csv",
|
||||
'marketing_campaign_mailchimp_view.xml',
|
||||
'wizard/create_list_view.xml',
|
||||
],
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
-->
|
||||
|
||||
<menuitem name="Tools" id="base.menu_tools" icon="STOCK_PREFERENCES" sequence="28"/>
|
||||
<menuitem name="Mailchimps" id="menu_action_mailchimp" parent="base.menu_emails" />
|
||||
<menuitem name="Mailchimp" id="menu_action_mailchimp" parent="base.menu_emails" />
|
||||
|
||||
<record model="ir.ui.view" id="view_mailchimp_account_tree">
|
||||
<field name="name">mailchimp.account.tree</field>
|
||||
<field name="model">mailchimp.account</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state in ('draft');black:state in ('approved');gray:state in ('cancelled')" string="All Accounts">
|
||||
<tree colors="blue:state in ('draft');black:state in ('approved');gray:state in ('cancelled')" string="Accounts">
|
||||
<field name="name"/>
|
||||
<field name="username" />
|
||||
<field name="data_center"/>
|
||||
|
@ -70,7 +70,7 @@
|
|||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_mailchimp_account">
|
||||
<field name="name">All Mailchimp Accounts</field>
|
||||
<field name="name">Mailchimp Accounts</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">mailchimp.account</field>
|
||||
<field name="view_type">form</field>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_mailchimp_account_user","mailchimp.account.user","marketing_campaign_mailchimp.model_mailchimp_account","base.res_groups_email_template_admin",1,1,1,1
|
||||
"access_mailchimp_account_system","mailchimp.account.user","marketing_campaign_mailchimp.model_mailchimp_account","base.groups_system",1,0,0,0
|
||||
"access_email_template_account_system","email_template_account_user","marketing_campaign_mailchimp.model_email_template_account","base.res_groups_email_template_admin",1,1,1,1
|
||||
"access_email_template_campaign","email_template_campaign","model_email_template","base.res_groups_email_template_admin",1,1,1,1
|
||||
"access_mailchimp_account_system","mailchimp.account.user","marketing_campaign_mailchimp.model_mailchimp_account","base.res_groups_email_template_admin",1,0,0,0
|
||||
"access_mailchimp_account_user","mailchimp_account_user","model_mailchimp_account","base.res_groups_email_template_admin",1,1,1,1
|
||||
|
|
|
|
@ -5,7 +5,8 @@
|
|||
<field name="model">create.list</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Update List">
|
||||
<form string="Update List Manually">
|
||||
<separator string="Update List Manually" colspan="4"/>
|
||||
<field name="mailchimp_account_id" on_change = "onchange_mailchimp_account_id(mailchimp_account_id,action)"/>
|
||||
<field name="list_name" />
|
||||
<newline/>
|
||||
|
@ -19,14 +20,18 @@
|
|||
</field>
|
||||
</record>
|
||||
<record id="action_create_list" model="ir.actions.act_window">
|
||||
<field name="name">Update List</field>
|
||||
<field name="name">Manual Mailchimp List Update</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">create.list</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_create_list"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
<menuitem id="menu_action_mailchimp_create_list" parent="menu_action_mailchimp" action="action_create_list" sequence="40"/>
|
||||
|
||||
<menuitem id="menu_action_mailchimp_create_list"
|
||||
name="Manual Mailchimp List Update"
|
||||
parent="menu_action_mailchimp" action="action_create_list"
|
||||
sequence="40" />
|
||||
|
||||
</data>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
work done on tasks, eso. It is able to render planning, order tasks, eso.
|
||||
Dashboard for project members that includes:
|
||||
* List of my open tasks
|
||||
* List of messages
|
||||
* Members list of project
|
||||
* Issues
|
||||
""",
|
||||
"init_xml": [],
|
||||
"update_xml": [
|
||||
"security/project_security.xml",
|
||||
"wizard/project_task_delegate_view.xml",
|
||||
"wizard/project_task_close_view.xml",
|
||||
"wizard/project_task_reevaluate_view.xml",
|
||||
"security/ir.model.access.csv",
|
||||
"project_data.xml",
|
||||
"project_view.xml",
|
||||
|
@ -46,7 +46,6 @@ work done on tasks, eso. It is able to render planning, order tasks, eso.
|
|||
"project_installer.xml",
|
||||
"res_partner_view.xml",
|
||||
"report/project_report_view.xml",
|
||||
"wizard/project_close_task_view.xml",
|
||||
"board_project_view.xml",
|
||||
'board_project_manager_view.xml'
|
||||
],
|
||||
|
|
|
@ -78,17 +78,6 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('type','=','Project')]</field>
|
||||
</record>
|
||||
|
||||
<!--Actions for deshboard -->
|
||||
|
||||
<record id="action_view_project_editable_messages_tree" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">project.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="project.view_project_message_tree"/>
|
||||
</record>
|
||||
|
||||
<record id="board_project_form" model="ir.ui.view">
|
||||
<field name="name">board.project.form</field>
|
||||
<field name="model">board.board</field>
|
||||
|
|
|
@ -25,6 +25,7 @@ from datetime import datetime, date
|
|||
|
||||
from tools.translate import _
|
||||
from osv import fields, osv
|
||||
from tools import email_send as email
|
||||
|
||||
class project_task_type(osv.osv):
|
||||
_name = 'project.task.type'
|
||||
|
@ -171,7 +172,7 @@ class project(osv.osv):
|
|||
'planned_hours': fields.function(_progress_rate, multi="progress", method=True, string='Planned Time', help="Sum of planned hours of all tasks related to this project and its child projects."),
|
||||
'effective_hours': fields.function(_progress_rate, multi="progress", method=True, string='Time Spent', help="Sum of spent hours of all tasks related to this project and its child projects."),
|
||||
'total_hours': fields.function(_progress_rate, multi="progress", method=True, string='Total Time', help="Sum of total hours of all tasks related to this project and its child projects."),
|
||||
'progress_rate': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', help="Percent of tasks closed according to the total of tasks todo."),
|
||||
'progress_rate': fields.function(_progress_rate, multi="progress", method=True, string='Progress', type='float', group_operator="avg", help="Percent of tasks closed according to the total of tasks todo."),
|
||||
'warn_customer': fields.boolean('Warn Partner', help="If you check this, the user will have a popup when closing a task that propose a message to send by email to the customer.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
|
||||
'warn_header': fields.text('Mail Header', help="Header added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
|
||||
'warn_footer': fields.text('Mail Footer', help="Footer added at the beginning of the email for the warning message sent to the customer when a task is closed.", states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
|
||||
|
@ -427,7 +428,7 @@ class task(osv.osv):
|
|||
'effective_hours': fields.function(_hours_get, method=True, string='Hours Spent', multi='hours', store=True, help="Computed using the sum of the task work done."),
|
||||
'remaining_hours': fields.float('Remaining Hours', digits=(16,2), help="Total remaining time, can be re-estimated periodically by the assignee of the task."),
|
||||
'total_hours': fields.function(_hours_get, method=True, string='Total Hours', multi='hours', store=True, help="Computed as: Time Spent + Remaining Time."),
|
||||
'progress': fields.function(_hours_get, method=True, string='Progress (%)', multi='hours', store=True, help="Computed as: Time Spent / Total Time."),
|
||||
'progress': fields.function(_hours_get, method=True, string='Progress (%)', multi='hours', group_operator="avg", store=True, help="Computed as: Time Spent / Total Time."),
|
||||
'delay_hours': fields.function(_hours_get, method=True, string='Delay Hours', multi='hours', store=True, help="Computed as difference of the time estimated by the project manager and the real time to close the task."),
|
||||
|
||||
'user_id': fields.many2one('res.users', 'Assigned to'),
|
||||
|
@ -486,18 +487,17 @@ class task(osv.osv):
|
|||
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
|
||||
return res
|
||||
|
||||
def do_close(self, cr, uid, ids, *args):
|
||||
mail_send = False
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
def do_close(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Close Task
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
request = self.pool.get('res.request')
|
||||
tasks = self.browse(cr, uid, ids)
|
||||
task_id = ids[0]
|
||||
cntx = {}
|
||||
if len(args):
|
||||
cntx = args[0]
|
||||
for task in tasks:
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
project = task.project_id
|
||||
if project:
|
||||
# Send request to project manager
|
||||
if project.warn_manager and project.user_id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
'name': _("Task '%s' closed") % task.name,
|
||||
|
@ -508,12 +508,7 @@ class task(osv.osv):
|
|||
'ref_doc1': 'project.task,%d'% (task.id,),
|
||||
'ref_doc2': 'project.project,%d'% (project.id,),
|
||||
})
|
||||
elif (project.warn_manager or project.warn_customer) and cntx.get('mail_send',True):
|
||||
cntx.update({'send_manager': project.warn_manager, 'send_partner': project.warn_customer})
|
||||
mail_send = True
|
||||
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
|
||||
self.log(cr, uid, task.id, message)
|
||||
|
||||
|
||||
for parent_id in task.parent_ids:
|
||||
if parent_id.state in ('pending','draft'):
|
||||
reopen = True
|
||||
|
@ -522,29 +517,16 @@ class task(osv.osv):
|
|||
reopen = False
|
||||
if reopen:
|
||||
self.do_reopen(cr, uid, [parent_id.id])
|
||||
if mail_send:
|
||||
model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_project_close_task')])
|
||||
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id']
|
||||
cntx.update({'task_id': task_id})
|
||||
return {
|
||||
'name': _('Email Send to Customer'),
|
||||
'view_type': 'form',
|
||||
'context': cntx, # improve me
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'close.task',
|
||||
'views': [(resource_id,'form')],
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'nodestroy': True
|
||||
}
|
||||
else:
|
||||
self.write(cr, uid, [task_id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
|
||||
return False
|
||||
self.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
|
||||
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
|
||||
self.log(cr, uid, task.id, message)
|
||||
return True
|
||||
|
||||
def do_reopen(self, cr, uid, ids, *args):
|
||||
def do_reopen(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
request = self.pool.get('res.request')
|
||||
tasks = self.browse(cr, uid, ids)
|
||||
for task in tasks:
|
||||
for task in self.browse(cr, uid, ids, context=context):
|
||||
project = task.project_id
|
||||
if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
|
@ -592,6 +574,40 @@ class task(osv.osv):
|
|||
self.write(cr, uid, ids, {'state': 'draft'})
|
||||
return True
|
||||
|
||||
def do_delegate(self, cr, uid, task_id, delegate_data={}, context=None):
|
||||
"""
|
||||
Delegate Task to another users.
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
task = self.browse(cr, uid, task_id, context=context)
|
||||
new_task_id = self.copy(cr, uid, task.id, {
|
||||
'name': delegate_data['name'],
|
||||
'user_id': delegate_data['user_id'],
|
||||
'planned_hours': delegate_data['planned_hours'],
|
||||
'remaining_hours': delegate_data['planned_hours'],
|
||||
'parent_ids': [(6, 0, [task.id])],
|
||||
'state': 'draft',
|
||||
'description': delegate_data['new_task_description'] or '',
|
||||
'child_ids': [],
|
||||
'work_ids': []
|
||||
}, context)
|
||||
newname = delegate_data['prefix'] or ''
|
||||
self.write(cr, uid, [task.id], {
|
||||
'remaining_hours': delegate_data['planned_hours_me'],
|
||||
'planned_hours': delegate_data['planned_hours_me'] + (task.effective_hours or 0.0),
|
||||
'name': newname,
|
||||
}, context)
|
||||
if delegate_data['state'] == 'pending':
|
||||
self.do_pending(cr, uid, [task.id], context)
|
||||
else:
|
||||
self.do_close(cr, uid, [task.id], context)
|
||||
user_pool = self.pool.get('res.users')
|
||||
delegrate_user = user_pool.browse(cr, uid, delegate_data['user_id'], context=context)
|
||||
message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
|
||||
self.log(cr, uid, task.id, message)
|
||||
return True
|
||||
|
||||
def do_pending(self, cr, uid, ids, *args):
|
||||
self.write(cr, uid, ids, {'state': 'pending'})
|
||||
for (id, name) in self.name_get(cr, uid, ids):
|
||||
|
@ -691,105 +707,6 @@ class project_work(osv.osv):
|
|||
|
||||
project_work()
|
||||
|
||||
class config_compute_remaining(osv.osv_memory):
|
||||
_name='config.compute.remaining'
|
||||
|
||||
def _get_remaining(self,cr, uid, context=None):
|
||||
if context and 'active_id' in context:
|
||||
return self.pool.get('project.task').browse(cr, uid, context['active_id'], context=context).remaining_hours
|
||||
return False
|
||||
|
||||
_columns = {
|
||||
'remaining_hours' : fields.float('Remaining Hours', digits=(16,2), help="Put here the remaining hours required to close the task."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'remaining_hours': _get_remaining
|
||||
}
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
users_obj = self.pool.get('res.users')
|
||||
obj_tm = users_obj.browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
tm = obj_tm and obj_tm.name or 'Hours'
|
||||
|
||||
res = super(config_compute_remaining, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu=submenu)
|
||||
|
||||
if tm in ['Hours','Hour']:
|
||||
return res
|
||||
|
||||
eview = etree.fromstring(res['arch'])
|
||||
|
||||
def _check_rec(eview):
|
||||
if eview.attrib.get('widget','') == 'float_time':
|
||||
eview.set('widget','float')
|
||||
for child in eview:
|
||||
_check_rec(child)
|
||||
return True
|
||||
|
||||
_check_rec(eview)
|
||||
|
||||
res['arch'] = etree.tostring(eview)
|
||||
|
||||
for f in res['fields']:
|
||||
if 'Hours' in res['fields'][f]['string']:
|
||||
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
|
||||
return res
|
||||
|
||||
def compute_hours(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
task_obj = self.pool.get('project.task')
|
||||
request = self.pool.get('res.request')
|
||||
if 'active_id' in context:
|
||||
remaining_hrs = self.browse(cr,uid,ids)[0].remaining_hours
|
||||
task_obj.write(cr,uid,context['active_id'],{'remaining_hours':remaining_hrs})
|
||||
if context.get('button_reactivate', False):
|
||||
tasks = task_obj.browse(cr, uid, [context['active_id']], context=context)
|
||||
for task in tasks:
|
||||
project = task.project_id
|
||||
if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid):
|
||||
request.create(cr, uid, {
|
||||
'name': _("Task '%s' set in progress") % task.name,
|
||||
'state': 'waiting',
|
||||
'act_from': uid,
|
||||
'act_to': project.user_id.id,
|
||||
'ref_partner_id': task.partner_id.id,
|
||||
'ref_doc1': 'project.task,%d' % task.id,
|
||||
'ref_doc2': 'project.project,%d' % project.id,
|
||||
})
|
||||
task_obj.write(cr, uid, [task.id], {'state': 'open'})
|
||||
return {
|
||||
'type': 'ir.actions.act_window_close',
|
||||
}
|
||||
|
||||
config_compute_remaining()
|
||||
|
||||
class message(osv.osv):
|
||||
_name = "project.message"
|
||||
_description = "Message"
|
||||
|
||||
_columns = {
|
||||
'subject': fields.char('Subject', size=128, required="True"),
|
||||
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
|
||||
'date': fields.date('Date', required=1),
|
||||
'user_id': fields.many2one('res.users', 'User', required="True"),
|
||||
'description': fields.text('Description'),
|
||||
}
|
||||
|
||||
def _default_project(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'project_id' in context and context['project_id']:
|
||||
return int(context['project_id'])
|
||||
return False
|
||||
|
||||
_defaults = {
|
||||
'user_id': lambda self,cr,uid,ctx: uid,
|
||||
'date': time.strftime('%Y-%m-%d'),
|
||||
'project_id': _default_project
|
||||
}
|
||||
|
||||
message()
|
||||
class account_analytic_account(osv.osv):
|
||||
|
||||
_inherit = 'account.analytic.account'
|
||||
|
|
|
@ -254,15 +254,5 @@
|
|||
<field name="project_id" ref="project_project_22"/>
|
||||
<field name="name">Latest in house tests</field>
|
||||
</record>
|
||||
<record id="project_message_1" model="project.message">
|
||||
<field name="project_id" ref="project.project_project_23"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="description">Follow the procedure of Configuration wizard.
|
||||
- Add all required modules
|
||||
- Add chat of accounts
|
||||
- Create Users</field>
|
||||
<field name="subject">Configuration steps</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -109,7 +109,7 @@
|
|||
</group>
|
||||
<newline />
|
||||
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended">
|
||||
<filter string="User" name="Users" icon="terp-personal" domain = "[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Manager" name="Manager" icon="terp-personal" domain = "[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Partner" name="Partner" icon="terp-personal" domain = "[]" context="{'group_by':'partner_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Parent" name="Parent" icon="terp-folder-blue" domain = "[]" context="{'group_by':'parent_id'}"/>
|
||||
|
@ -189,33 +189,6 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_config_compute_remaining" model="ir.ui.view">
|
||||
<field name="name">Compute Remaining Hours </field>
|
||||
<field name="model">config.compute.remaining</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reevaluate Hours">
|
||||
<separator colspan="4" string="Change Remaining Time"/>
|
||||
<newline/>
|
||||
<field name="remaining_hours" widget="float_time"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group col="4" colspan="4">
|
||||
<button icon="gtk-cancel" special="cancel" string="Cancel"/>
|
||||
<button icon="gtk-apply" name="compute_hours" string="Update" type="object" default_focus="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_config_compute_remaining" model="ir.actions.act_window">
|
||||
<field name="name">Compute Remaining Hours</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">config.compute.remaining</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<!-- Task -->
|
||||
<record id="view_task_form2" model="ir.ui.view">
|
||||
<field name="name">project.task.form</field>
|
||||
|
@ -244,7 +217,7 @@
|
|||
</group>
|
||||
<group col="3" colspan="2">
|
||||
<field name="remaining_hours" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" colspan="2"/>
|
||||
<button name="%(action_config_compute_remaining)d" string="Reevaluate" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/>
|
||||
<button name="%(action_project_task_reevaluate)d" string="Reevaluate" type="action" colspan="1" target="new" states="open,pending" icon="gtk-edit"/>
|
||||
|
||||
<field name="delay_hours" widget="float_time"/>
|
||||
</group>
|
||||
|
@ -263,10 +236,10 @@
|
|||
<field name="state" select="1"/>
|
||||
<button name="do_draft" states="open" string="Draft" type="object" icon="gtk-indent"/>
|
||||
<button name="do_open" states="pending,draft" string="Start Task" type="object" icon="gtk-execute"/>
|
||||
<button name="%(action_config_compute_remaining)d" states="done,cancelled" string="Reactivate" type="action" icon="gtk-convert" context="{'button_reactivate':True}" />
|
||||
<button name="%(action_project_task_reevaluate)d" states="done,cancelled" string="Reactivate" type="action" icon="gtk-convert" context="{'button_reactivate':True}" />
|
||||
<button name="do_pending" states="open" string="Pending" type="object" icon="gtk-media-pause"/>
|
||||
<button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open" string="Delegate" type="action" icon="gtk-sort-descending"/>
|
||||
<button name="do_close" states="pending,open" string="Done" type="object" icon="gtk-apply"/>
|
||||
<button name="%(action_project_task_close)d" states="pending,open" string="Done" type="action" icon="gtk-apply"/>
|
||||
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/>
|
||||
</group>
|
||||
</page>
|
||||
|
@ -343,7 +316,7 @@
|
|||
<field name="state" invisible="context.get('set_visible',False)"/>
|
||||
<button name="do_open" states="pending,draft,done,cancel" string="Start Task" type="object" icon="gtk-execute" help="For changing to open state" invisible="context.get('set_visible',False)"/>
|
||||
<button groups="base.group_extended" name="%(action_project_task_delegate)d" states="pending,open,draft" string="Delegate" type="action" icon="gtk-sort-descending" help="For changing to delegate state"/>
|
||||
<button name="do_close" states="draft,pending,open" string="Done" type="object" icon="gtk-apply" help="For changing to done state"/>
|
||||
<button name="%(action_project_task_close)d" states="draft,pending,open" string="Done" type="action" icon="gtk-apply" help="For changing to done state"/>
|
||||
<button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -421,7 +394,7 @@
|
|||
<separator orientation="vertical"/>
|
||||
<filter string="Project" name="group_project_id" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Stage" name="group_stage_id" icon="terp-stage" domain="[]" context="{'group_by':'type_id'}"/>
|
||||
<filter string="Stages" name="group_stage_id" icon="terp-stage" domain="[]" context="{'group_by':'type_id'}"/>
|
||||
<filter string="State" name="group_state" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}"/>
|
||||
|
@ -564,82 +537,7 @@ Issues like bugs in a system, client complain, materials breakdown are collected
|
|||
</page>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--- Messages-->
|
||||
<record id="view_project_message_form" model="ir.ui.view">
|
||||
<field name="name">project.message.form</field>
|
||||
<field name="model">project.message</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Messages">
|
||||
<group colspan="6">
|
||||
<field name="subject" select="1"/>
|
||||
<field name="project_id"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="date"/>
|
||||
</group>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_message_tree" model="ir.ui.view">
|
||||
<field name="name">project.message.tree</field>
|
||||
<field name="model">project.message</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Messages">
|
||||
<field name="date" select="1"/>
|
||||
<field name="subject" select="1"/>
|
||||
<field name="project_id" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_project_message_search" model="ir.ui.view">
|
||||
<field name="name">project.message.search</field>
|
||||
<field name="model">project.message</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Messages">
|
||||
<group col="20" colspan="4">
|
||||
<filter domain="[('date','>=',time.strftime('%%Y-%%m-01'))]" icon="terp-go-month" string="This Month" />
|
||||
<filter domain="[('date', '=', time.strftime('%%Y-%%m-%%d'))]" icon="terp-go-today" string="Today" />
|
||||
<separator orientation="vertical"/>
|
||||
<field name="subject"/>
|
||||
<field name="project_id" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." colspan="4" col="20">
|
||||
<filter string="Project" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
|
||||
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Date" icon="terp-go-month" domain="[]" context="{'group_by':'date'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_project_messages_tree" model="ir.actions.act_window">
|
||||
<field name="name">Project Messages</field>
|
||||
<field name="res_model">project.message</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_project_message_tree"/>
|
||||
<field name="context">{"search_default_project_id":project_id, "search_default_user_id":uid}</field>
|
||||
<field name="search_view_id" ref="view_project_message_search"/>
|
||||
<field name="help">An in-project messagery system permits an efficient and trackable communication between project members. The messages are kept in the system and can then be used for post-analysis.</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_view_project_messages_tree" id="menu_message_tree" parent="menu_project_management" sequence="11"/>
|
||||
|
||||
<act_window domain="[('user_id', '=', active_id),('state', '<>', 'cancelled'),('state', '<>', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form,gantt,calendar,graph" view_type="form"/>
|
||||
|
||||
<act_window domain="[('user_id', '=', active_id),('date', '>=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
|
||||
|
||||
<act_window domain="[('project_id', '=', active_id)]" id="act_project_messages" name="Messages" res_model="project.message" src_model="project.project"/>
|
||||
|
||||
<act_window domain="[('user_id', '=', active_id),('state', '<>', 'cancelled'),('state', '<>', 'done')]" id="act_res_users_2_project_task_opened" name="Assigned tasks" res_model="project.task" src_model="res.users" view_mode="tree,form,gantt,calendar,graph" view_type="form"/>
|
||||
<act_window domain="[('user_id', '=', active_id),('date', '>=', time.strftime('%Y-%m-01'))]" id="act_res_users_2_project_task_work_month" name="Month works" res_model="project.task.work" src_model="res.users" view_mode="tree,form" view_type="form"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
"access_project_project_manager","project.project manager","model_project_project","project.group_project_manager",1,0,0,0
|
||||
"access_project_project_manager","project.project manager","model_project_project","project.group_project_manager",1,1,1,1
|
||||
"access_account_analytic_account_manager","account.analytic.account","analytic.model_account_analytic_account","project.group_project_manager",1,0,0,0
|
||||
"access_project_project","project.project","model_project_project","project.group_project_user",1,1,1,1
|
||||
"access_account_analytic_account","account.analytic.account","analytic.model_account_analytic_account","project.group_project_user",1,1,1,1
|
||||
"access_project_task_type_user","project.task.type user","model_project_task_type","project.group_project_user",1,1,1,1
|
||||
"access_project_task_type","project.task.type","model_project_task_type","project.group_project_manager",1,1,1,1
|
||||
"access_project_task_manager","project.task manager","model_project_task","project.group_project_manager",1,0,0,0
|
||||
"access_project_task_manager","project.task manager","model_project_task","project.group_project_manager",1,1,1,1
|
||||
"access_project_task","project.task","model_project_task","project.group_project_user",1,1,1,1
|
||||
"access_project_task_work","project.task.work","model_project_task_work","project.group_project_user",1,1,1,1
|
||||
"access_project_task_work_manager","project.task.work.manager","model_project_task_work","project.group_project_manager",1,1,1,1
|
||||
"access_project_message","project.message","model_project_message","project.group_project_user",1,1,1,1
|
||||
"access_report_project_task_user","report.project.task.user","model_report_project_task_user","project.group_project_manager",1,1,1,1
|
||||
"access_project_vs_hours","project.vs.hours","model_project_vs_hours","project.group_project_user",1,1,1,1
|
||||
"access_task_by_days","task.by.days","model_task_by_days","project.group_project_user",1,1,1,1
|
||||
|
@ -19,8 +18,6 @@
|
|||
"access_partner_address_task manager","base.res.partner.address manager","base.model_res_partner_address","project.group_project_manager",1,0,0,0
|
||||
"access_task_on_partner","project.task on partners","model_project_task","base.group_user",1,0,0,0
|
||||
"access_project_on_partner","project.project on partners","model_project_project","base.group_user",1,0,0,0
|
||||
"access_project_message_manager","project.message manager","model_project_message","project.group_project_manager",1,0,0,0
|
||||
"access_project_message_system","project.message system","model_project_message","base.group_system",1,0,0,0
|
||||
"access_project_task_system","project.task system","model_project_task","base.group_system",1,0,0,0
|
||||
"access_project_project_system","project.project system","model_project_project","base.group_system",1,1,1,1
|
||||
"access_project_task_work_system","project.task.work system","model_project_task_work","base.group_system",1,0,0,0
|
||||
|
|
|
|
@ -122,12 +122,12 @@
|
|||
-
|
||||
Now in order to reactivate the task 'Technical Training', i click on the "Reactivate" button and fill the remaining hour field
|
||||
-
|
||||
!record {model: config.compute.remaining, id: project_task_technicaltraining_remainingwiz0}:
|
||||
!record {model: project.task.reevaluate, id: project_task_technicaltraining_remainingwiz0}:
|
||||
remaining_hours: 30.0
|
||||
- |
|
||||
I click the apply button
|
||||
-
|
||||
!python {model: config.compute.remaining}: |
|
||||
!python {model: project.task.reevaluate}: |
|
||||
self.compute_hours(cr, uid, [ref('project_task_technicaltraining_remainingwiz0')], {'active_id': ref("project_task_technicaltraining0"),'button_reactivate': True})
|
||||
- |
|
||||
Check if task 'Technical Training' in open state and for other initial values
|
||||
|
@ -193,12 +193,12 @@
|
|||
-
|
||||
Set remaining hours of 10 hours for reevaluating the task
|
||||
-
|
||||
!record {model: config.compute.remaining, id: config_compute_remaining_0}:
|
||||
!record {model: project.task.reevaluate, id: config_compute_remaining_0}:
|
||||
remaining_hours: 10.0
|
||||
-
|
||||
Reevaluate the task
|
||||
-
|
||||
!python {model: config.compute.remaining}: |
|
||||
!python {model: project.task.reevaluate}: |
|
||||
self.compute_hours(cr, uid, [ref("config_compute_remaining_0")], {"lang": "en_US",
|
||||
"project_id": False, "tz": False, "active_model": "project.task", "search_default_project_id":
|
||||
False, "search_default_user_id": 1, "search_default_current": 1, "active_ids":
|
||||
|
@ -248,12 +248,12 @@
|
|||
-
|
||||
Reactivate task
|
||||
-
|
||||
!record {model: config.compute.remaining, id: config_compute_remaining_1}:
|
||||
!record {model: project.task.reevaluate, id: config_compute_remaining_1}:
|
||||
remaining_hours: 10.0
|
||||
-
|
||||
Reevaluate the task with 10 hours remaining
|
||||
-
|
||||
!python {model: config.compute.remaining}: |
|
||||
!python {model: project.task.reevaluate}: |
|
||||
self.compute_hours(cr, uid, [ref("config_compute_remaining_1")], {"lang": "en_US",
|
||||
"project_id": False, "tz": False, "button_reactivate": True, "active_model":
|
||||
"project.task", "search_default_project_id": False, "search_default_user_id":
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
Validating the delegate task
|
||||
-
|
||||
!python {model: project.task.delegate}: |
|
||||
self.validate(cr, uid, [ref("project_task_publish_book_delegate")],
|
||||
self.delegate(cr, uid, [ref("project_task_publish_book_delegate")],
|
||||
{"lang": "en_US", "active_model": "project.task", "tz": False, "record_id":
|
||||
4, "active_ids": [ref("project_task_publish_book")], "active_id": ref("project_task_publish_book"),
|
||||
})
|
||||
|
@ -227,4 +227,4 @@
|
|||
Parent task 'Develop book for Technical and Functional reference' must be now in open state
|
||||
-
|
||||
!assert {model: project.task, id: project_task_documentation_book, severity: error, string: Task is in done state}:
|
||||
- state == "open"
|
||||
- state == "open"
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
import project_close_task
|
||||
import project_task_close
|
||||
import project_task_delegate
|
||||
import project_task_reevaluate
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -1,133 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 time
|
||||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
from tools import email_send as email
|
||||
|
||||
class project_close_task(osv.osv_memory):
|
||||
"""
|
||||
Close Task
|
||||
"""
|
||||
_name = "close.task"
|
||||
_description = "Project Close Task"
|
||||
_columns = {
|
||||
'manager_email': fields.char('Manager E-Mail ID', size=64, help="Email Address of Project's Manager"),
|
||||
'partner_email': fields.char('Partner E-Mail ID', size=64, help="Email Address of Partner"),
|
||||
'description': fields.text('Description'),
|
||||
}
|
||||
|
||||
def _get_manager_email(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
email = ''
|
||||
if context.get('send_manager', False) and ('task_id' in context):
|
||||
project_id = self.pool.get('project.task').read(cr, uid, context['task_id'], ['project_id'])['project_id'][0]
|
||||
project = self.pool.get('project.project').browse(cr, uid, project_id)
|
||||
manager_id = project.user_id or False
|
||||
if manager_id and manager_id.user_email:
|
||||
email = manager_id.user_email
|
||||
return email
|
||||
|
||||
def _get_partner_email(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
email = ''
|
||||
if context.get('send_partner', False) and ('task_id' in context):
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['task_id'])
|
||||
partner_id = task.partner_id or task.project_id.partner_id
|
||||
if partner_id and len(partner_id.address) and partner_id.address[0].email:
|
||||
email = partner_id.address[0].email
|
||||
return email
|
||||
|
||||
def _get_desc(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'task_id' in context:
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['task_id'])
|
||||
return task.description or task.name
|
||||
return ''
|
||||
|
||||
_defaults = {
|
||||
'manager_email': _get_manager_email,
|
||||
'partner_email': _get_partner_email,
|
||||
'description': _get_desc,
|
||||
}
|
||||
|
||||
def close(self, cr, uid, ids, context=None):
|
||||
if 'task_id' in context:
|
||||
self.pool.get('project.task').write(cr, uid, [context['task_id']], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
|
||||
return {}
|
||||
|
||||
def confirm(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if not 'task_id' in context:
|
||||
return {}
|
||||
close_task = self.read(cr, uid, ids[0], [])
|
||||
to_adr = []
|
||||
description = close_task['description']
|
||||
|
||||
if 'task_id' in context:
|
||||
if context.get('send_manager', False) and not close_task.get('manager_email', False):
|
||||
raise osv.except_osv(_('Error'), _("Please specify the email address of Project Manager."))
|
||||
|
||||
elif context.get('send_partner', False) and not close_task.get('partner_email', False):
|
||||
raise osv.except_osv(_('Error'), _("Please specify the email address of partner."))
|
||||
|
||||
else:
|
||||
task_obj = self.pool.get('project.task')
|
||||
task = task_obj.browse(cr, uid, context['task_id'], context=context)
|
||||
project = task.project_id
|
||||
subject = "Task '%s' closed" % task.name
|
||||
if task.user_id and task.user_id.address_id and task.user_id.address_id.email:
|
||||
from_adr = task.user_id.address_id.email
|
||||
signature = task.user_id.signature
|
||||
else:
|
||||
raise osv.except_osv(_('Error'), _("Couldn't send mail because your email address is not configured!"))
|
||||
val = {
|
||||
'name': task.name,
|
||||
'user_id': task.user_id.name,
|
||||
'task_id': "%d/%d" % (project.id, task.id),
|
||||
'date_start': task.date_start,
|
||||
'date_end': task.date_end,
|
||||
'state': task.state
|
||||
}
|
||||
|
||||
header = (project.warn_header or '') % val
|
||||
footer = (project.warn_footer or '') % val
|
||||
body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
|
||||
to_adr.append(context.get('send_manager', '') and close_task.get('manager_email', '') or '')
|
||||
to_adr.append(context.get('send_partner', '') and close_task.get('partner_email', '') or '')
|
||||
mail_id = email(from_adr, to_adr, subject, body.encode('utf-8'), email_bcc=[from_adr])
|
||||
if not mail_id:
|
||||
raise osv.except_osv(_('Error'), _("Couldn't send mail! Check the email ids and smtp configuration settings"))
|
||||
task_obj.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
|
||||
message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
|
||||
self.log(cr, uid, task.id, message)
|
||||
|
||||
return {}
|
||||
|
||||
project_close_task()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,43 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_project_close_task" model="ir.ui.view">
|
||||
<field name="name">Project Close Task</field>
|
||||
<field name="model">close.task</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project Close Task" >
|
||||
<label string="Send mail to the specified email address"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="4" col="6">
|
||||
<newline/>
|
||||
<field name="manager_email" invisible="not context.get('send_manager',False)"/>
|
||||
<newline/>
|
||||
<field name="partner_email" invisible="not context.get('send_partner',False)"/>
|
||||
<newline/>
|
||||
<field name="description" />
|
||||
</group>
|
||||
<separator string="" colspan="6"/>
|
||||
<group colspan="6" col="6">
|
||||
<button icon="gtk-ok" name="confirm" string="Send and Close" type="object"/>
|
||||
<button icon="gtk-ok" string="Close" name="close" type="object"/>
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_project_close_task" model="ir.actions.act_window">
|
||||
<field name="name">Project Close Task</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">close.task</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_project_close_task"/>
|
||||
<field name="context">{'record_id' : active_id}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,126 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 time
|
||||
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
from tools import email_send as email
|
||||
|
||||
class project_task_close(osv.osv_memory):
|
||||
"""
|
||||
Close Task
|
||||
"""
|
||||
_name = "project.task.close"
|
||||
_description = "Project Close Task"
|
||||
_columns = {
|
||||
'manager_warn': fields.boolean("Warn Manager", help="Warn Manager by Email"),
|
||||
'partner_warn': fields.boolean("Warn Customer", help="Warn Customer by Email"),
|
||||
'manager_email': fields.char('Manager Email', size=128, help="Email Address of Project's Manager"),
|
||||
'partner_email': fields.char('Customer Email', size=128, help="Email Address of Customer"),
|
||||
'description': fields.text('Description'),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
record_id = context and context.get('active_id', False) or False
|
||||
task_pool = self.pool.get('project.task')
|
||||
project_pool = self.pool.get('project.project')
|
||||
|
||||
res = super(project_task_close, self).default_get(cr, uid, fields, context=context)
|
||||
task = task_pool.browse(cr, uid, record_id, context=context)
|
||||
project = task.project_id
|
||||
manager = project.user_id or False
|
||||
partner = task.partner_id or task.project_id.partner_id
|
||||
|
||||
if 'description' in fields:
|
||||
res.update({'description': task.description})
|
||||
if 'manager_warn' in fields:
|
||||
res.update({'manager_warn': project.warn_manager})
|
||||
if 'partner_warn' in fields:
|
||||
res.update({'partner_warn': project.warn_customer})
|
||||
if 'manager_email' in fields:
|
||||
res.update({'manager_email': manager and manager.user_email or False})
|
||||
if partner and len(partner.address) and 'partner_email' in fields:
|
||||
res.update({'partner_email': partner.address[0].email})
|
||||
return res
|
||||
|
||||
def done(self, cr, uid, ids, context=None):
|
||||
task_pool = self.pool.get('project.task')
|
||||
task_id = context.get('active_id', False)
|
||||
res = task_pool.do_close(cr, uid, [task_id], context=context)
|
||||
return res
|
||||
|
||||
def confirm(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
task_pool = self.pool.get('project.task')
|
||||
task_id = context.get('active_id', False)
|
||||
if not task_id:
|
||||
return {}
|
||||
task = task_pool.browse(cr, uid, task_id, context=context)
|
||||
for data in self.browse(cr, uid, ids, context=context):
|
||||
res = task_pool.do_close(cr, uid, [task.id], context=context)
|
||||
if res:
|
||||
# Send Warn Message by Email to Manager and Customer
|
||||
if data.manager_warn and not data.manager_email:
|
||||
raise osv.except_osv(_('Error'), _("Please specify the email address of Project Manager."))
|
||||
|
||||
elif data.partner_warn and not data.partner_email:
|
||||
raise osv.except_osv(_('Error'), _("Please specify the email address of Customer."))
|
||||
|
||||
elif data.manager_warn or data.partner_warn:
|
||||
project = task.project_id
|
||||
subject = _("Task '%s' Closed") % task.name
|
||||
if task.user_id and task.user_id.address_id and task.user_id.address_id.email:
|
||||
from_adr = task.user_id.address_id.email
|
||||
signature = task.user_id.signature
|
||||
else:
|
||||
raise osv.except_osv(_('Error'), _("Couldn't send mail because your email address is not configured!"))
|
||||
val = {
|
||||
'name': task.name,
|
||||
'user_id': task.user_id.name,
|
||||
'task_id': "%d/%d" % (project.id, task.id),
|
||||
'date_start': task.date_start,
|
||||
'date_end': task.date_end,
|
||||
'state': task.state
|
||||
}
|
||||
|
||||
header = (project.warn_header or '') % val
|
||||
footer = (project.warn_footer or '') % val
|
||||
body = u'%s\n%s\n%s\n\n-- \n%s' % (header, description, footer, signature)
|
||||
if data.manager_warn and data.manager_email:
|
||||
to_adr.append(data.manager_email)
|
||||
if data.partner_warn and data.partner_email:
|
||||
to_adr.append(data.partner_email)
|
||||
mail_id = email(from_adr, to_adr, subject, tools.ustr(body), email_bcc=[from_adr])
|
||||
if not mail_id:
|
||||
raise osv.except_osv(_('Error'), _("Couldn't send mail! Check the email ids and smtp configuration settings"))
|
||||
return {}
|
||||
|
||||
project_task_close()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_project_task_close" model="ir.ui.view">
|
||||
<field name="name">Done Task</field>
|
||||
<field name="model">project.task.close</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Done Task" >
|
||||
<separator string="Done Task and Inform to Project Manager or Customer by Email " colspan="4"/>
|
||||
<group colspan="4" col="4">
|
||||
<field name="manager_warn" invisible="1"/>
|
||||
<field name="manager_email" widget="email" attrs="{'invisible':[('manager_warn','=',False)], 'required':[('manager_warn','=',True)]}"/>
|
||||
<field name="partner_warn" invisible="1"/>
|
||||
<field name="partner_email" widget="email" attrs="{'invisible':[('partner_warn','=',False)], 'required':[('partner_warn','=',True)]}"/>
|
||||
<separator string="Warn Message" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="2" col="2">
|
||||
</group>
|
||||
<group colspan="2" col="3">
|
||||
<button icon="gtk-close" special="cancel" string="_Close"/>
|
||||
<button icon="gtk-jump-to" string="_Done" special="cancel" name="done" type="object"/>
|
||||
<button icon="terp-mail-message-new" string="_Send+Done" name="confirm" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_project_task_close" model="ir.actions.act_window">
|
||||
<field name="name">Done Task</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">project.task.close</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_project_task_close"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -38,67 +38,54 @@ class project_task_delegate(osv.osv_memory):
|
|||
'state': fields.selection([('pending','Pending'), ('done','Done'), ], 'Validation State', required=True, help="New state of your own task. Pending will be reopened automatically when the delegated task is closed")
|
||||
}
|
||||
|
||||
def _get_name(self, cr, uid, context=None):
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
"""
|
||||
This function gets default values
|
||||
"""
|
||||
res = super(project_task_delegate, self).default_get(cr, uid, fields, context=context)
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'active_id' in context:
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['active_id'])
|
||||
record_id = context and context.get('active_id', False) or False
|
||||
task_pool = self.pool.get('project.task')
|
||||
task = task_pool.browse(cr, uid, record_id, context=context)
|
||||
project = task.project_id
|
||||
manager = project.user_id or False
|
||||
partner = task.partner_id or task.project_id.partner_id
|
||||
|
||||
if 'name' in fields:
|
||||
if task.name.startswith(_('CHECK: ')):
|
||||
newname = str(task.name).replace(_('CHECK: '), '')
|
||||
else:
|
||||
newname = task.name or ''
|
||||
return newname
|
||||
return ''
|
||||
|
||||
def _get_plan_hour(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'active_id' in context:
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['active_id'])
|
||||
return task.remaining_hours
|
||||
return 0.0
|
||||
|
||||
def _get_prefix(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'active_id' in context:
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['active_id'])
|
||||
res.update({'name': newname})
|
||||
if 'planned_hours' in fields:
|
||||
res.update({'planned_hours': task.remaining_hours or 0.0})
|
||||
if 'prefix' in fields:
|
||||
if task.name.startswith(_('CHECK: ')):
|
||||
newname = str(task.name).replace(_('CHECK: '), '')
|
||||
else:
|
||||
newname = task.name or ''
|
||||
return _('CHECK: ') + newname
|
||||
return ''
|
||||
prefix = _('CHECK: ') + newname
|
||||
res.update({'prefix': prefix})
|
||||
if 'new_task_description' in fields:
|
||||
res.update({'new_task_description': task.description})
|
||||
return res
|
||||
|
||||
def _get_new_desc(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if 'active_id' in context:
|
||||
task = self.pool.get('project.task').browse(cr, uid, context['active_id'])
|
||||
return task.description
|
||||
return ''
|
||||
|
||||
_defaults = {
|
||||
'name': _get_name,
|
||||
'planned_hours': _get_plan_hour,
|
||||
'planned_hours_me': 1.0,
|
||||
'prefix': _get_prefix,
|
||||
'new_task_description': _get_new_desc,
|
||||
'state': 'pending',
|
||||
}
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
users_obj = self.pool.get('res.users')
|
||||
obj_tm = users_obj.browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
tm = obj_tm and obj_tm.name or 'Hours'
|
||||
|
||||
res = super(project_task_delegate, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu=submenu)
|
||||
|
||||
users_pool = self.pool.get('res.users')
|
||||
obj_tm = users_pool.browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
tm = obj_tm and obj_tm.name or 'Hours'
|
||||
if tm in ['Hours','Hour']:
|
||||
return res
|
||||
|
||||
eview = etree.fromstring(res['arch'])
|
||||
|
||||
def _check_rec(eview):
|
||||
if eview.attrib.get('widget','') == 'float_time':
|
||||
eview.set('widget','float')
|
||||
|
@ -107,47 +94,19 @@ class project_task_delegate(osv.osv_memory):
|
|||
return True
|
||||
|
||||
_check_rec(eview)
|
||||
|
||||
res['arch'] = etree.tostring(eview)
|
||||
|
||||
for f in res['fields']:
|
||||
if 'Hours' in res['fields'][f]['string']:
|
||||
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
|
||||
|
||||
for field in res['fields']:
|
||||
if 'Hours' in res['fields'][field]['string']:
|
||||
res['fields'][field]['string'] = res['fields'][field]['string'].replace('Hours',tm)
|
||||
return res
|
||||
|
||||
def validate(self, cr, uid, ids, context=None):
|
||||
def delegate(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
task_obj = self.pool.get('project.task')
|
||||
user_obj = self.pool.get('res.users')
|
||||
task_id = context.get('active_id', False)
|
||||
task_pool = self.pool.get('project.task')
|
||||
delegate_data = self.read(cr, uid, ids, context=context)[0]
|
||||
task = task_obj.browse(cr, uid, context['active_id'], context=context)
|
||||
newname = delegate_data['prefix'] or ''
|
||||
new_task_id = task_obj.copy(cr, uid, task.id, {
|
||||
'name': delegate_data['name'],
|
||||
'user_id': delegate_data['user_id'],
|
||||
'planned_hours': delegate_data['planned_hours'],
|
||||
'remaining_hours': delegate_data['planned_hours'],
|
||||
'parent_ids': [(6, 0, [task.id])],
|
||||
'state': 'draft',
|
||||
'description': delegate_data['new_task_description'] or '',
|
||||
'child_ids': [],
|
||||
'work_ids': []
|
||||
}, context)
|
||||
task_obj.write(cr, uid, [task.id], {
|
||||
'remaining_hours': delegate_data['planned_hours_me'],
|
||||
'planned_hours': delegate_data['planned_hours_me'] + (task.effective_hours or 0.0),
|
||||
'name': newname,
|
||||
}, context)
|
||||
if delegate_data['state'] == 'pending':
|
||||
task_obj.do_pending(cr, uid, [task.id], context)
|
||||
else:
|
||||
context.update({'mail_send': False} )
|
||||
task_obj.do_close(cr, uid, [task.id], context)
|
||||
delegrate_user = user_obj.browse(cr, uid, delegate_data['user_id'], context=context)
|
||||
message = _('Task ') + " '" + delegate_data['name'] + "' "+ _("is Delegated to User:") +" '"+ delegrate_user.name +"' "
|
||||
self.log(cr, uid, task.id, message)
|
||||
task_pool.do_delegate(cr, uid, task_id, delegate_data, context=context)
|
||||
return {}
|
||||
|
||||
project_task_delegate()
|
||||
|
|
|
@ -8,25 +8,25 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Project Task Delegate">
|
||||
<separator string="Delegated Task" colspan="4"/>
|
||||
<field name="user_id"/>
|
||||
<newline/>
|
||||
<field name="planned_hours" widget="float_time"/>
|
||||
<newline/>
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="new_task_description"/>
|
||||
<newline/>
|
||||
<separator string="Validation Task" colspan="4"/>
|
||||
<field name="planned_hours_me" widget="float_time"/>
|
||||
<newline/>
|
||||
<field name="prefix" />
|
||||
<newline/>
|
||||
<field name="state" />
|
||||
<newline/>
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button icon="gtk-ok" name="validate" string="Approve" type="object"/>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Delegated Task" colspan="4"/>
|
||||
<field name="user_id" colspan="4"/>
|
||||
<field name="planned_hours" widget="float_time" colspan="4"/>
|
||||
<field name="name" colspan="4"/>
|
||||
<field name="new_task_description" colspan="4" />
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Validation Task" colspan="4"/>
|
||||
<field name="planned_hours_me" widget="float_time" colspan="4"/>
|
||||
<field name="prefix" colspan="4"/>
|
||||
<field name="state" colspan="4"/>
|
||||
</group>
|
||||
<separator string="" colspan="4"/>
|
||||
<group colspan="2" col="2">
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<button icon="gtk-close" special="cancel" string="_Close"/>
|
||||
<button icon="gtk-ok" name="delegate" string="_Delegate" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 lxml import etree
|
||||
from osv import fields, osv
|
||||
from tools.translate import _
|
||||
|
||||
class project_task_reevaluate(osv.osv_memory):
|
||||
_name = 'project.task.reevaluate'
|
||||
|
||||
def _get_remaining(self,cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
active_id = context.get('active_id', False)
|
||||
res = False
|
||||
if active_id:
|
||||
res = self.pool.get('project.task').browse(cr, uid, active_id, context=context).remaining_hours
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'remaining_hours' : fields.float('Remaining Hours', digits=(16,2), help="Put here the remaining hours required to close the task."),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'remaining_hours': _get_remaining,
|
||||
}
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
res = super(project_task_reevaluate, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu=submenu)
|
||||
users_pool = self.pool.get('res.users')
|
||||
time_mode = users_pool.browse(cr, uid, uid, context).company_id.project_time_mode_id
|
||||
time_mode_name = time_mode and time_mode.name or 'Hours'
|
||||
if time_mode_name in ['Hours','Hour']:
|
||||
return res
|
||||
|
||||
eview = etree.fromstring(res['arch'])
|
||||
|
||||
def _check_rec(eview):
|
||||
if eview.attrib.get('widget','') == 'float_time':
|
||||
eview.set('widget','float')
|
||||
for child in eview:
|
||||
_check_rec(child)
|
||||
return True
|
||||
|
||||
_check_rec(eview)
|
||||
|
||||
res['arch'] = etree.tostring(eview)
|
||||
|
||||
for field in res['fields']:
|
||||
if 'Hours' in res['fields'][field]['string']:
|
||||
res['fields'][field]['string'] = res['fields'][field]['string'].replace('Hours',time_mode_name)
|
||||
return res
|
||||
|
||||
def compute_hours(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
data = self.browse(cr, uid, ids, context=context)[0]
|
||||
task_pool = self.pool.get('project.task')
|
||||
task_id = context.get('active_id', False)
|
||||
if task_id:
|
||||
task_pool.write(cr, uid, task_id, {'remaining_hours': data.remaining_hours})
|
||||
if context.get('button_reactivate', False):
|
||||
task_pool.do_reopen(cr, uid, [task_id], context=context)
|
||||
return {}
|
||||
project_task_reevaluate()
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_project_task_reevaluate" model="ir.ui.view">
|
||||
<field name="name">Re-evaluate Task</field>
|
||||
<field name="model">project.task.reevaluate</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Reevaluate Task">
|
||||
<separator colspan="4" string="Reevaluation Task"/>
|
||||
<field name="remaining_hours" widget="float_time"/>
|
||||
<separator string="" colspan="4"/>
|
||||
<group col="2" colspan="2">
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<button icon="gtk-close" special="cancel" string="_Close"/>
|
||||
<button icon="gtk-apply" name="compute_hours" string="_Evaluate" type="object" default_focus="1"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_project_task_reevaluate" model="ir.actions.act_window">
|
||||
<field name="name">Re-evaluate Task</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">project.task.reevaluate</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -86,6 +86,7 @@
|
|||
<field name="view_id" ref="board_project_issue_form"/>
|
||||
</record>
|
||||
<menuitem id="menu_deshboard_project_issue" name="Project Issue Dashboard" parent="project.next_id_86"
|
||||
icon="terp-graph"
|
||||
action="open_board_project_issue"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -63,10 +63,10 @@
|
|||
<separator colspan="4"/>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" />
|
||||
<button name="case_close" string="Done" states="open,draft,pending" type="object" icon="gtk-jump-to"/>
|
||||
<button name="case_open" string="Open" states="draft,pending" type="object" icon="gtk-go-forward"/>
|
||||
<button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/>
|
||||
<button name="case_close" string="Close" states="open,draft,pending" type="object" icon="gtk-jump-to"/>
|
||||
<button name="case_pending" string="Pending" states="draft,open" type="object" icon="gtk-media-pause"/>
|
||||
<button name="case_cancel" string="Cancel" states="draft,open,pending" type="object" icon="gtk-cancel"/>
|
||||
<button name="case_escalate" string="Escalate" states="open,draft,pending" type="object" icon="gtk-go-up"/>
|
||||
<button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert"/>
|
||||
</group>
|
||||
|
|
|
@ -27,14 +27,14 @@
|
|||
"category": "Generic Modules/Projects & Services",
|
||||
"depends": ["resource", "project"],
|
||||
"description": """
|
||||
|
||||
Long Term Project management module that tracks planning, scheduling, resources allocation.
|
||||
Mainly used with Big project management.
|
||||
- Project Phases will be maintained by Manager of the project
|
||||
- Compute Phase Scheduling: Compute start date and end date of the phases which are in draft,open and pending state of the project given.
|
||||
If no project given then all the draft,open and pending state phases will be taken
|
||||
- Compute Task Scheduling: This works same as the scheduler button on project.phase. It takes the project as argument and computes all the open,draft and pending tasks
|
||||
- Schedule Tasks: All the tasks which are in draft,pending and open state are scheduled with taking the phase's start date
|
||||
Long Term Project management module that tracks planning, scheduling, resources allocation.
|
||||
Features.
|
||||
- Manage Big project.
|
||||
- Define various Phases of Project.
|
||||
- Compute Phase Scheduling: Compute start date and end date of the phases which are in draft,open and pending state of the project given.
|
||||
If no project given then all the draft,open and pending state phases will be taken
|
||||
- Compute Task Scheduling: This works same as the scheduler button on project.phase. It takes the project as argument and computes all the open,draft and pending tasks
|
||||
- Schedule Tasks: All the tasks which are in draft,pending and open state are scheduled with taking the phase's start date
|
||||
|
||||
""",
|
||||
"init_xml": [],
|
||||
|
|
|
@ -72,9 +72,9 @@
|
|||
<field name="name">Resource Allocations</field>
|
||||
<field name="res_model">project.resource.allocation</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">gantt,tree,form</field>
|
||||
<field name="view_mode">tree,form,gantt</field>
|
||||
<field name="context">{}</field>
|
||||
<!--<field name="search_view_id" ref="view_project_phase_search"/>-->
|
||||
<field name="search_view_id" ref="view_project_resource_allocation_search"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
@ -254,7 +254,7 @@
|
|||
<field name="name">Project Phases</field>
|
||||
<field name="res_model">project.phase</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">gantt,tree,form,calendar</field>
|
||||
<field name="view_mode">tree,form,gantt,calendar</field>
|
||||
<field name="context">{'search_default_responsible_id':uid}</field>
|
||||
<field name="search_view_id" ref="view_project_phase_search"/>
|
||||
<field name="help">You can subdivide your larger projects into several phases. For each phase, you can define your resources allocation (humans or engine), describe de differend task and link your phase with previous and next one, add constraints date and scheduling. A gantt view of your project phase is also available from this menu. Gantt view is a graphically draw of the project plan; it includes any task dependencies by visually adjusting task durations and priorities, and by linking tasks to each other.</field>
|
||||
|
@ -314,13 +314,13 @@
|
|||
|
||||
<menuitem action="act_project_phase"
|
||||
groups="base.group_extended"
|
||||
id="menu_project_phase" parent="base.menu_project_long_term" sequence="1"/>
|
||||
id="menu_project_phase" parent="base.menu_project_long_term" sequence="1"/>
|
||||
|
||||
<menuitem id="menu_resouce_allocation" action="act_resouce_allocation"
|
||||
name="Resource Allocations" parent="base.menu_project_long_term" sequence="2"/>
|
||||
|
||||
<menuitem id="menu_pm_resources_project1"
|
||||
groups="base.group_extended"
|
||||
groups="base.group_extended"
|
||||
name="Resources" parent="project.menu_definitions" sequence="3"/>
|
||||
|
||||
<menuitem id="menu_phase_schedule" name="Scheduling" parent="base.menu_project_long_term" sequence="4" groups="project.group_project_user,project.group_project_manager,base.group_system"/>
|
||||
|
|
|
@ -8,20 +8,16 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Compute Scheduling of Phases">
|
||||
<group width="380" height="180">
|
||||
<group colspan="4" col="4">
|
||||
<label colspan="4" string="This wizard will schedule phases for all or specified project" />
|
||||
<newline />
|
||||
<field name="target_project" colspan="4"/>
|
||||
</group>
|
||||
<newline />
|
||||
<group colspan="4" col="6" attrs="{'invisible':[('target_project','=','all')]}">
|
||||
<field name="project_id"/>
|
||||
</group>
|
||||
<group colspan="4" col="4">
|
||||
<separator colspan="4" string="Compute Scheduling of phases for all or specified project" />
|
||||
<field name="target_project" colspan="4"/>
|
||||
<field name="project_id" widget="selection" colspan="4" attrs="{'invisible':[('target_project','=','all')], 'required':[('target_project','!=','all')]}"/>
|
||||
<separator colspan="4"/>
|
||||
<group colspan="4" col="6"> <!-- Improve me -->
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button icon="gtk-ok" name="check_selection" string="_Compute" type="object"/>
|
||||
<group colspan="2" col="2">
|
||||
</group>
|
||||
<group colspan="2" col="2"> <!-- Improve me -->
|
||||
<button icon="gtk-close" special="cancel" string="_Close"/>
|
||||
<button icon="gtk-ok" name="check_selection" string="C_ompute" type="object"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
|
|
|
@ -7,12 +7,16 @@
|
|||
<field name="model">project.compute.tasks</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Compute Scheduling of Phases">
|
||||
<group colspan="4" height="100" width="500">
|
||||
<field name="project_id"/>
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button icon="gtk-ok" name="compute_date" string="Compute" type="object"/>
|
||||
<form string="Compute Scheduling of Task">
|
||||
<group colspan="4">
|
||||
<separator colspan="4" string="Compute Scheduling of Task for specified project." />
|
||||
<field name="project_id" widget="selection" colspan="4"/>
|
||||
<separator colspan="4"/>
|
||||
<group colspan="2" col="2">
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<button icon="gtk-close" special="cancel" string="_Close"/>
|
||||
<button icon="gtk-ok" name="compute_date" string="C_ompute" type="object"/>
|
||||
</group>
|
||||
</group>
|
||||
</form>
|
||||
|
|
|
@ -55,9 +55,7 @@ class project_with_message(osv.osv):
|
|||
_inherit = 'project.project'
|
||||
|
||||
_columns = {
|
||||
'message_ids':fields.one2many(
|
||||
'project.messages', 'project_id', 'Messages',
|
||||
),
|
||||
'message_ids':fields.one2many('project.messages', 'project_id', 'Messages'),
|
||||
}
|
||||
project_with_message()
|
||||
|
||||
|
|
|
@ -90,8 +90,20 @@
|
|||
<field name="search_view_id" ref="view_project_messages_search"/>
|
||||
<field name="context">{"search_default_to_id":uid}</field>
|
||||
<field name="view_id" ref="view_project_message_tree"/>
|
||||
<field name="help">An in-project messagery system permits an efficient and trackable communication between project members. The messages are kept in the system and can then be used for post-analysis.</field>
|
||||
</record>
|
||||
|
||||
|
||||
<act_window domain="[('project_id', '=', active_id)]" id="act_project_messages" name="Messages" res_model="project.messages" src_model="project.project"/>
|
||||
|
||||
<!--Actions for deshboard -->
|
||||
|
||||
<record id="action_view_project_editable_messages_tree" model="ir.actions.act_window">
|
||||
<field name="name">Messages</field>
|
||||
<field name="res_model">project.messages</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="project_messages.view_project_message_tree"/>
|
||||
</record>
|
||||
<menuitem action="messages_form" id="menu_messages_form" parent="project.menu_project_management"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<menuitem
|
||||
id="menu_deshboard_scurm"
|
||||
name="Scrum Dashboard" parent="project.next_id_86"
|
||||
icon="terp-graph"
|
||||
action="open_board_project_scrum"/>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -45,49 +45,29 @@ class project_scrum_sprint(osv.osv):
|
|||
_name = 'project.scrum.sprint'
|
||||
_description = 'Project Scrum Sprint'
|
||||
|
||||
def _calc_progress(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
def _compute(self, cr, uid, ids, fields, arg, context=None):
|
||||
res = {}.fromkeys(ids, 0.0)
|
||||
progress = {}
|
||||
if not ids:
|
||||
return res
|
||||
if context is None:
|
||||
context = {}
|
||||
for sprint in self.browse(cr, uid, ids):
|
||||
for sprint in self.browse(cr, uid, ids, context=context):
|
||||
tot = 0.0
|
||||
prog = 0.0
|
||||
effective = 0.0
|
||||
progress = 0.0
|
||||
for bl in sprint.backlog_ids:
|
||||
tot += bl.expected_hours
|
||||
effective += bl.effective_hours
|
||||
prog += bl.expected_hours * bl.progress / 100.0
|
||||
res.setdefault(sprint.id, 0.0)
|
||||
if tot>0:
|
||||
res[sprint.id] = round(prog/tot*100)
|
||||
return res
|
||||
|
||||
def _calc_effective(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
for sprint in self.browse(cr, uid, ids):
|
||||
res.setdefault(sprint.id, 0.0)
|
||||
for bl in sprint.backlog_ids:
|
||||
res[sprint.id] += bl.effective_hours
|
||||
return res
|
||||
|
||||
def _calc_planned(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
for sprint in self.browse(cr, uid, ids):
|
||||
res.setdefault(sprint.id, 0.0)
|
||||
for bl in sprint.backlog_ids:
|
||||
res[sprint.id] += bl.expected_hours
|
||||
return res
|
||||
|
||||
def _calc_expected(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
for sprint in self.browse(cr, uid, ids):
|
||||
res.setdefault(sprint.id, 0.0)
|
||||
for bl in sprint.backlog_ids:
|
||||
res[sprint.id] += bl.expected_hours
|
||||
progress = round(prog/tot*100)
|
||||
res[sprint.id] = {
|
||||
'progress' : progress,
|
||||
'expected_hours' : tot,
|
||||
'effective_hours': effective,
|
||||
}
|
||||
return res
|
||||
|
||||
def button_cancel(self, cr, uid, ids, context=None):
|
||||
|
@ -137,9 +117,9 @@ class project_scrum_sprint(osv.osv):
|
|||
'review': fields.text('Sprint Review'),
|
||||
'retrospective': fields.text('Sprint Retrospective'),
|
||||
'backlog_ids': fields.one2many('project.scrum.product.backlog', 'sprint_id', 'Sprint Backlog'),
|
||||
'progress': fields.function(_calc_progress, method=True, string='Progress (0-100)', help="Computed as: Time Spent / Total Time."),
|
||||
'effective_hours': fields.function(_calc_effective, method=True, string='Effective hours', help="Computed using the sum of the task work done."),
|
||||
'expected_hours': fields.function(_calc_expected, method=True, string='Planned Hours', help='Estimated time to do the task.'),
|
||||
'progress': fields.function(_compute, group_operator="avg", type='float', multi="progress", method=True, string='Progress (0-100)', help="Computed as: Time Spent / Total Time."),
|
||||
'effective_hours': fields.function(_compute, multi="effective_hours", method=True, string='Effective hours', help="Computed using the sum of the task work done."),
|
||||
'expected_hours': fields.function(_compute, multi="expected_hours", method=True, string='Planned Hours', help='Estimated time to do the task.'),
|
||||
'state': fields.selection([('draft','Draft'),('open','Open'),('pending','Pending'),('cancel','Cancelled'),('done','Done')], 'State', required=True),
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -188,39 +168,31 @@ class project_scrum_product_backlog(osv.osv):
|
|||
return self.name_get(cr, uid, ids, context=context)
|
||||
return super(project_scrum_product_backlog, self).name_search(cr, uid, name, args, operator,context, limit=limit)
|
||||
|
||||
def _calc_progress(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
def _compute(self, cr, uid, ids, fields, arg, context=None):
|
||||
res = {}.fromkeys(ids, 0.0)
|
||||
progress = {}
|
||||
if not ids:
|
||||
return res
|
||||
if context is None:
|
||||
context = {}
|
||||
for bl in self.browse(cr, uid, ids):
|
||||
for backlog in self.browse(cr, uid, ids, context=context):
|
||||
tot = 0.0
|
||||
prog = 0.0
|
||||
for task in bl.tasks_id:
|
||||
effective = 0.0
|
||||
task_hours = 0.0
|
||||
progress = 0.0
|
||||
for task in backlog.tasks_id:
|
||||
task_hours += task.total_hours
|
||||
effective += task.effective_hours
|
||||
tot += task.planned_hours
|
||||
prog += task.planned_hours * task.progress / 100.0
|
||||
res.setdefault(bl.id, 0.0)
|
||||
if tot>0:
|
||||
res[bl.id] = round(prog/tot*100)
|
||||
return res
|
||||
|
||||
def _calc_effective(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
for bl in self.browse(cr, uid, ids):
|
||||
res.setdefault(bl.id, 0.0)
|
||||
for task in bl.tasks_id:
|
||||
res[bl.id] += task.effective_hours
|
||||
return res
|
||||
|
||||
def _calc_task(self, cr, uid, ids, name, args, context=None):
|
||||
res = {}
|
||||
if context is None:
|
||||
context = {}
|
||||
for bl in self.browse(cr, uid, ids):
|
||||
res.setdefault(bl.id, 0.0)
|
||||
for task in bl.tasks_id:
|
||||
res[bl.id] += task.total_hours
|
||||
progress = round(prog/tot*100)
|
||||
res[backlog.id] = {
|
||||
'progress' : progress,
|
||||
'effective_hours': effective,
|
||||
'task_hours' : task_hours
|
||||
}
|
||||
return res
|
||||
|
||||
def button_cancel(self, cr, uid, ids, context=None):
|
||||
|
@ -291,11 +263,11 @@ class project_scrum_product_backlog(osv.osv):
|
|||
'sequence' : fields.integer('Sequence', help="Gives the sequence order when displaying a list of product backlog."),
|
||||
'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'),
|
||||
'state': fields.selection([('draft','Draft'),('open','Open'),('pending','Pending'),('done','Done'),('cancel','Cancelled')], 'State', required=True),
|
||||
'progress': fields.function(_calc_progress, method=True, string='Progress', help="Computed as: Time Spent / Total Time."),
|
||||
'effective_hours': fields.function(_calc_effective, method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks"),
|
||||
'progress': fields.function(_compute, multi="progress", group_operator="avg", type='float', method=True, string='Progress', help="Computed as: Time Spent / Total Time."),
|
||||
'effective_hours': fields.function(_compute, multi="effective_hours", method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks"),
|
||||
'expected_hours': fields.float('Planned Hours', help='Estimated total time to do the Backlog'),
|
||||
'create_date': fields.datetime("Creation Date", readonly=True),
|
||||
'task_hours': fields.function(_calc_task, method=True, string='Task Hours', help='Estimated time of the total hours of the tasks')
|
||||
'task_hours': fields.function(_compute, multi="task_hours", method=True, string='Task Hours', help='Estimated time of the total hours of the tasks')
|
||||
}
|
||||
_defaults = {
|
||||
'state': 'draft',
|
||||
|
|
|
@ -24,7 +24,7 @@ class backlog_create_task(osv.osv_memory):
|
|||
_name = 'project.scrum.backlog.create.task'
|
||||
_description = 'Create Tasks from Product Backlogs'
|
||||
_columns = {
|
||||
'user_id': fields.many2one('res.users', 'Assign To')
|
||||
'user_id': fields.many2one('res.users', 'Assign To', help="Resposible user who can work on task")
|
||||
}
|
||||
|
||||
def do_create(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -7,21 +7,22 @@
|
|||
<field name="model">project.scrum.backlog.create.task</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Create Tasks">
|
||||
<group col="4" colspan="6">
|
||||
<field name="user_id"/>
|
||||
</group>
|
||||
<form string="Convert into Tasks">
|
||||
<separator string="Convert into Tasks" colspan="4"/>
|
||||
<field name="user_id"/>
|
||||
<separator colspan="4"/>
|
||||
<group col="2" colspan="4">
|
||||
<button special="cancel" string="Cancel" icon='gtk-cancel'/>
|
||||
<button name="do_create" string="Create Tasks" colspan="1" type="object" icon="gtk-execute"/>
|
||||
<group col="2" colspan="2">
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<button special="cancel" string="_Close" icon='gtk-close'/>
|
||||
<button name="do_create" string="Co_nvert" colspan="1" type="object" icon="gtk-execute"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_scrum_backlog_to_task" model="ir.actions.act_window">
|
||||
<field name="name">Create Tasks</field>
|
||||
<field name="name">Convert into Tasks</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">project.scrum.backlog.create.task</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -32,7 +33,7 @@
|
|||
<record model="ir.values" id="scrum_backlog_to_task_values">
|
||||
<field name="model_id" ref="model_project_scrum_product_backlog" />
|
||||
<field name="object" eval="1" />
|
||||
<field name="name">Create Tasks</field>
|
||||
<field name="name">Convert into Tasks</field>
|
||||
<field name="key2">client_action_multi</field>
|
||||
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_scrum_backlog_to_task'))" />
|
||||
<field name="key">action</field>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<separator string="Are you sure you want to merge these Backlogs?" colspan="4"/>
|
||||
<label colspan="4" string="This wizard merge backlogs and create one new backlog with draft state (Old backlogs Will be deleted). And it also merge old tasks from backlogs" />
|
||||
<separator colspan="4"/>
|
||||
<button colspan="2" special="cancel" string="Cancel" icon="gtk-cancel"/>
|
||||
<button colspan="2" special="cancel" string="Close" icon="gtk-close"/>
|
||||
<button colspan="2" default_focus="1" name="check_backlogs" string="Merge" type="object" icon="gtk-execute"/>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -25,8 +25,8 @@ class backlog_sprint_assign(osv.osv_memory):
|
|||
_name = 'project.scrum.backlog.assign.sprint'
|
||||
_description = 'Assign sprint to backlogs'
|
||||
_columns = {
|
||||
'sprint_id': fields.many2one('project.scrum.sprint', 'Sprint Name', required=True),
|
||||
'state_open': fields.boolean('Set Open', help="Change the state of product backlogs to open if its in draft state"),
|
||||
'sprint_id': fields.many2one('project.scrum.sprint', 'Sprint', required=True, help="Select Sprint to assign backlog."),
|
||||
'state_open': fields.boolean('Open Backlog', help="Change the state of product backlogs to open if its in draft state"),
|
||||
'convert_to_task': fields.boolean('Convert To Task', help="Create Task for Product Backlog")
|
||||
}
|
||||
_defaults = {
|
||||
|
|
|
@ -8,20 +8,16 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Assign Sprint">
|
||||
<group col="4" colspan="6">
|
||||
<field name="sprint_id" colspan="2"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<separator colspan="2"/>
|
||||
<newline/>
|
||||
<group>
|
||||
<field name="state_open" colspan="1"/>
|
||||
<field name="convert_to_task" colspan="1"/>
|
||||
</group>
|
||||
<separator string="Assign Sprint" colspan="4"/>
|
||||
<field name="sprint_id" colspan="4"/>
|
||||
<field name="state_open" />
|
||||
<field name="convert_to_task"/>
|
||||
<separator colspan="4"/>
|
||||
<group col="2" colspan="4">
|
||||
<button special="cancel" string="Cancel" icon='gtk-cancel'/>
|
||||
<button name="assign_sprint" string="Assign Sprint" colspan="1" type="object" icon="gtk-execute"/>
|
||||
<group col="2" colspan="2">
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<button special="cancel" string="_Close" icon='gtk-close'/>
|
||||
<button name="assign_sprint" string="_Assign" colspan="1" type="object" icon="gtk-execute"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -47,4 +43,4 @@
|
|||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</openerp>
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
|
||||
import purchase_requisition
|
||||
import wizard
|
||||
import report
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
|
|
@ -32,7 +32,9 @@
|
|||
"init_xml" : [],
|
||||
"demo_xml" : [],
|
||||
"update_xml" : ["wizard/purchase_requisition_partner_view.xml",
|
||||
"purchase_requisition_data.xml",
|
||||
"purchase_requisition_view.xml",
|
||||
"purchase_requisition_report.xml",
|
||||
"security/ir.model.access.csv","purchase_requisition_sequence.xml"
|
||||
],
|
||||
"active": False,
|
||||
|
|
|
@ -40,6 +40,7 @@ class purchase_requisition(osv.osv):
|
|||
'company_id': fields.many2one('res.company', 'Company', required=True),
|
||||
'purchase_ids' : fields.one2many('purchase.order','requisition_id','Purchase Orders',states={'done': [('readonly', True)]}),
|
||||
'line_ids' : fields.one2many('purchase.requisition.line','requisition_id','Products to Purchase',states={'done': [('readonly', True)]}),
|
||||
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse'),
|
||||
'state': fields.selection([('draft','Draft'),('in_progress','In Progress'),('cancel','Cancelled'),('done','Done')], 'State', required=True)
|
||||
}
|
||||
_defaults = {
|
||||
|
@ -51,6 +52,15 @@ class purchase_requisition(osv.osv):
|
|||
'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'purchase.order.requisition'),
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None,context={}):
|
||||
if not default:
|
||||
default = {}
|
||||
default.update({
|
||||
'state':'draft',
|
||||
'purchase_ids':[],
|
||||
'name': self.pool.get('ir.sequence').get(cr, uid, 'purchase.order.requisition'),
|
||||
})
|
||||
return super(purchase_requisition, self).copy(cr, uid, id, default, context)
|
||||
def tender_cancel(self, cr, uid, ids, context=None):
|
||||
purchase_order_obj = self.pool.get('purchase.order')
|
||||
for purchase in self.browse(cr, uid, ids):
|
||||
|
@ -64,9 +74,6 @@ class purchase_requisition(osv.osv):
|
|||
return True
|
||||
|
||||
def tender_in_progress(self, cr, uid, ids, context=None):
|
||||
for quotations in self.browse(cr, uid, ids):
|
||||
if not quotations.purchase_ids:
|
||||
raise osv.except_osv(_('Purchase order required'),('You should have atleast one purchase order line defined for this tender'))
|
||||
self.write(cr, uid, ids, {'state':'in_progress'} ,context=context)
|
||||
for (id,name) in self.name_get(cr, uid, ids):
|
||||
message = _('Tender') + " '" + name + "' "+ _(" is In Progress")
|
||||
|
@ -172,6 +179,8 @@ class procurement_order(osv.osv):
|
|||
'name': sequence_obj.get(cr, uid, 'purchase.order.requisition'),
|
||||
'origin': procurement.name,
|
||||
'date_end': procurement.date_planned,
|
||||
'warehouse_id':procurement.purchase_id and procurement.purchase_id.warehouse_id.id,
|
||||
'company_id':procurement.company_id.id,
|
||||
'line_ids': [(0,0,{
|
||||
'product_id': procurement.product_id.id,
|
||||
'product_uom_id': procurement.product_uom.id,
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data noupdate="1">
|
||||
<function
|
||||
eval="('default',False,'warehouse_id', [('purchase.requisition', False)], ref('stock.warehouse0'), True, False, False, False, True)"
|
||||
id="purchase_default_set"
|
||||
model="ir.values"
|
||||
name="set"/>
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<report auto="False" id="report_purchase_requisition" model="purchase.requisition" name="purchase.requisition" rml="purchase_requisition/report/purchase_requisition.rml" string="Purchase Requisition"/>
|
||||
</data>
|
||||
</openerp>
|
|
@ -2,17 +2,6 @@
|
|||
<openerp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_order_tree_inherit">
|
||||
<field name="name">purchase.order.tree.inherit</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="after">
|
||||
<field name="requisition_id" groups="base.group_extended"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_order_form_inherit">
|
||||
<field name="name">purchase.order.form.inherit</field>
|
||||
|
@ -20,12 +9,23 @@
|
|||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.purchase_order_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="partner_ref" position="after">
|
||||
<field name="shipped" position="after">
|
||||
<field name="requisition_id" groups="base.group_extended"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_order_search_inherit">
|
||||
<field name="name">purchase.order.list.select.inherit</field>
|
||||
<field name="type">form</field>
|
||||
<field name="model">purchase.order</field>
|
||||
<field name="inherit_id" ref="purchase.view_purchase_order_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/search/group/filter[@string='To Invoice']" position="after">
|
||||
<filter icon="terp-gtk-jump-to-rtl" string="Requisition" domain="[('requisition_id','!=',False)]" separator="1"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_purchase_requisition_form">
|
||||
<field name="name">purchase.requisition.form</field>
|
||||
<field name="type">form</field>
|
||||
|
@ -39,6 +39,7 @@
|
|||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="origin"/>
|
||||
<field name="warehouse_id" groups="base.group_extended" widget="selection"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
|
@ -77,12 +78,15 @@
|
|||
<field name="minimum_planned_date"/>
|
||||
<field name="origin"/>
|
||||
<field name="state"/>
|
||||
<button name="purchase_confirm" states="draft" string="Confirm Purchase Order" icon="gtk-apply"/>
|
||||
<button name="purchase_approve" states="confirmed" string="Approved by Supplier" icon="gtk-ok"/>
|
||||
<button name="purchase_cancel" states="draft,confirmed,wait_auth" string="Cancel Purchase Order" icon="gtk-cancel"/>
|
||||
</tree>
|
||||
</field>
|
||||
<separator colspan="4" string=""/>
|
||||
<group col="8" colspan="4">
|
||||
<label colspan="6" string=""/>
|
||||
<button name="%(action_purchase_requisition_partner)d" string="Requests for Quotation" type="action" icon="gtk-execute"
|
||||
<button name="%(action_purchase_requisition_partner)d" string="Request a Quotation" type="action" icon="gtk-execute"
|
||||
attrs="{'readonly': [('state', '=', 'done')]}" />
|
||||
</group>
|
||||
</page>
|
||||
|
@ -123,6 +127,7 @@
|
|||
<separator orientation="vertical"/>
|
||||
<field name="name"/>
|
||||
<field name="user_id" />
|
||||
<filter icon="terp-personal-" string="Unassigned" domain="[('user_id','=', False)]" help="Unassigned Requisition"/>
|
||||
<field name="exclusive" />
|
||||
</group>
|
||||
<newline/>
|
||||
|
@ -181,5 +186,12 @@
|
|||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
<act_window
|
||||
domain="[('requisition_id', '=', active_id)]"
|
||||
id="act_res_partner_2_purchase_order"
|
||||
name="Purchase orders"
|
||||
res_model="purchase.order"
|
||||
src_model="purchase.requisition"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 requisition
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
<?xml version="1.0"?>
|
||||
<document filename="test.pdf">
|
||||
<template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
|
||||
<pageTemplate id="first">
|
||||
<frame id="first" x1="34.0" y1="28.0" width="530" height="786"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<blockTableStyle id="Standard_Outline">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Table1">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,0" stop="-1,0"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,2" stop="-1,-1"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Table2">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,0" stop="-1,0"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,2" stop="-1,-1"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Table3">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,0" stop="-1,0"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="0,0" stop="0,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="0,0" stop="0,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="0,-1" stop="0,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="1,0" stop="1,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="1,0" stop="1,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="1,-1" stop="1,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="2,0" stop="2,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="2,0" stop="2,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="2,-1" stop="2,-1"/>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEAFTER" colorName="#e6e6e6" start="3,0" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#e6e6e6" start="3,0" stop="3,0"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#e6e6e6" start="3,-1" stop="3,-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#cccccc" start="0,2" stop="-1,-1"/>
|
||||
</blockTableStyle>
|
||||
<initialize>
|
||||
<paraStyle name="all" alignment="justify"/>
|
||||
</initialize>
|
||||
<paraStyle name="P1" fontName="Helvetica" fontSize="12.0" leading="15" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P2" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P3" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P4" fontName="Helvetica-Bold" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0" textColor="#008000"/>
|
||||
<paraStyle name="Standard" fontName="Helvetica"/>
|
||||
<paraStyle name="Text body" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="List" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Table Contents" fontName="Helvetica" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Table Heading" fontName="Helvetica" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Caption" fontName="Helvetica" fontSize="10.0" leading="13" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Index" fontName="Helvetica"/>
|
||||
<paraStyle name="Heading" fontName="Helvetica" fontSize="15.0" leading="19" spaceBefore="12.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_header" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_default_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="Footer" fontName="Helvetica"/>
|
||||
<paraStyle name="Horizontal Line" fontName="Helvetica" fontSize="6.0" leading="8" spaceBefore="0.0" spaceAfter="14.0"/>
|
||||
<paraStyle name="Heading 9" fontName="Helvetica-Bold" fontSize="75%" leading="NaN" spaceBefore="12.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_tblheader_General" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_tblheader_Details" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_default_Bold_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_tblheader_General_Centre" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_tblheader_General_Right" fontName="Helvetica-Bold" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_tblheader_Details_Centre" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_tblheader_Details_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_default_Right_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="8.0" leading="10" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_Centre_8" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_header_Right" fontName="Helvetica-Bold" fontSize="15.0" leading="19" alignment="LEFT" spaceBefore="12.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_default_address" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_Bold_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_Centre_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_Right_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_Bold_Right_9" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_2" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="terp_default_White_2" rightIndent="0.0" leftIndent="0.0" fontName="Helvetica" fontSize="2.0" leading="3" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0" textColor="#ffffff"/>
|
||||
<paraStyle name="terp_default_Note" rightIndent="0.0" leftIndent="9.0" fontName="Helvetica-Oblique" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/>
|
||||
<paraStyle name="Table" fontName="Helvetica" fontSize="10.0" leading="13" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="terp_header_left" fontName="Helvetica-Bold" fontSize="10.0" leading="15" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<images/>
|
||||
</stylesheet>
|
||||
<story>
|
||||
<para style="terp_header_Centre">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="terp_default_8">[[ repeatIn(objects,'requisition') ]]</para>
|
||||
<para style="P3">Purchase for Requisitions [[ requisition.name ]]</para>
|
||||
<para style="terp_header_Centre">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<blockTable colWidths="159.0,159.0,106.0,106.0" style="Table1">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Requisition Reference</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Requisition Date</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Type</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_General_Centre">Origin</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ requisition.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ requisition.date_start ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ requisition.exclusive=='multiple' and 'Multiple Requisitions' or requisition.exclusive=='exclusive' and 'Purchase Requisitions (exclusive)' ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ requisition.origin ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="terp_default_Centre_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="terp_default_Centre_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<section>
|
||||
<para style="terp_header_left">Product Detail</para>
|
||||
<blockTable colWidths="177.0,177.0,177.0" style="Table2">[[ requisition.line_ids or removeParentNode('section') ]]
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Description</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Qty</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Product UoM</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><para style="terp_default_8">[[ repeatIn(requisition.line_ids,'line_ids') ]]</para>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ line_ids.product_id.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ line_ids.product_qty ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ line_ids.product_uom_id.category_id.name ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
</section>
|
||||
<para style="terp_default_Centre_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="terp_default_Centre_8">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<section>
|
||||
<para style="terp_header_left">Quotation Detail</para>
|
||||
<blockTable colWidths="133.0,163.0,235.0" style="Table3">[[ requisition.purchase_ids or removeParentNode('section') ]]
|
||||
<tr>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Order Reference</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Date Ordered</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_tblheader_Details_Centre">Supplier</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><para style="P2">[[ repeatIn(requisition.purchase_ids,'purchase_ids') ]]</para>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ purchase_ids.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ purchase_ids.date_order ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Centre_8">[[ purchase_ids.partner_address_id.partner_id.name ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
</section>
|
||||
<para style="P3">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="P4">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</story>
|
||||
</document>
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# 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 time
|
||||
from report import report_sxw
|
||||
from osv import osv
|
||||
import pooler
|
||||
|
||||
class requisition(report_sxw.rml_parse):
|
||||
def __init__(self, cr, uid, name, context):
|
||||
super(requisition, self).__init__(cr, uid, name, context=context)
|
||||
self.localcontext.update({
|
||||
'time': time,
|
||||
})
|
||||
|
||||
report_sxw.report_sxw('report.purchase.requisition','purchase.requisition','addons/purchase_requisition/report/purchase_requisition.rml',parser=requisition)
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -92,7 +92,7 @@ class purchase_requisition_partner(osv.osv_memory):
|
|||
pricelist_id = partner.property_product_pricelist_purchase and partner.property_product_pricelist_purchase.id or False
|
||||
price = pricelist_obj.price_get(cr, uid, [pricelist_id], line.product_id.id, line.product_qty, False, {'uom': uom_id})[pricelist_id]
|
||||
product = prod_obj.browse(cr, uid, line.product_id.id, context=context)
|
||||
|
||||
location_id = self.pool.get('stock.warehouse').read(cr, uid, [tender.warehouse_id.id], ['lot_input_id'])[0]['lot_input_id'][0]
|
||||
|
||||
purchase_order_line= {
|
||||
'name': product.partner_ref,
|
||||
|
@ -118,6 +118,10 @@ class purchase_requisition_partner(osv.osv_memory):
|
|||
'company_id': tender.company_id.id,
|
||||
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
|
||||
'requisition_id':tender.id,
|
||||
'notes':tender.description,
|
||||
'warehouse_id':tender.warehouse_id.id and tender.warehouse_id.id ,
|
||||
'location_id':location_id,
|
||||
'company_id':tender.company_id.id,
|
||||
})
|
||||
order_ids=[]
|
||||
for order_line in list_line:
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<separator string="" colspan="4" />
|
||||
<group colspan="4" col="6">
|
||||
<button icon="gtk-cancel" special="cancel" string="_Cancel"/>
|
||||
<button icon="gtk-ok" name="create_order" string="Create Orders" type="object"/>
|
||||
<button icon="gtk-ok" name="create_order" string="Create Quotation" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
|
Loading…
Reference in New Issue