bzr revid: hmo@tinyerp.com-20100831101152-pxx8ef3lpyfq4flz
This commit is contained in:
Harry (OpenERP) 2010-08-31 15:41:52 +05:30
commit 906948cb8d
67 changed files with 1276 additions and 1874 deletions

View File

@ -123,7 +123,7 @@ class email_template(osv.osv):
_columns = { _columns = {
'name' : fields.char('Name', size=100, required=True), '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,), 'model_int_name':fields.char('Model Internal Name', size=200,),
'from_account':fields.many2one( 'from_account':fields.many2one(
'email_template.account', 'email_template.account',
@ -132,7 +132,7 @@ class email_template(osv.osv):
'def_to':fields.char( 'def_to':fields.char(
'Recipient (To)', 'Recipient (To)',
size=250, size=250,
help="The default recipient of email." help="The Recipient of email. "
"Placeholders can be used here."), "Placeholders can be used here."),
'def_cc':fields.char( 'def_cc':fields.char(
'CC', 'CC',
@ -151,12 +151,12 @@ class email_template(osv.osv):
" Placeholders can be used here."), " Placeholders can be used here."),
'message_id':fields.char('Message-ID', 'message_id':fields.char('Message-ID',
size=250, size=250,
help="The Message-ID header value, if you need to" 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."),
"specify it, for example to automatically recognize the replies later." 'track_campaign_item':fields.boolean('Resource Tracking',
" Placeholders can be used here."), help="Enable this is you wish to include a special \
'track_campaign_item':fields.boolean('Track campaign items', tracking marker in outgoing emails so you can identify replies and link \
help="Enable this if you want the outgoing e-mails to include a tracking" them back to the corresponding resource record. \
" marker that makes it possible to identify the replies an link them back to the campaign item"), This is useful for CRM leads for example"),
'lang':fields.char( 'lang':fields.char(
'Language', 'Language',
size=250, size=250,
@ -164,9 +164,9 @@ class email_template(osv.osv):
" Placeholders can be used here. " " Placeholders can be used here. "
"eg. ${object.partner_id.lang}"), "eg. ${object.partner_id.lang}"),
'def_subject':fields.char( 'def_subject':fields.char(
'Default Subject', 'Subject',
size=200, size=200,
help="The default subject of email." help="The subject of email."
" Placeholders can be used here.", " Placeholders can be used here.",
translate=True), translate=True),
'def_body_text':fields.text( 'def_body_text':fields.text(
@ -201,10 +201,12 @@ class email_template(osv.osv):
'ref_ir_act_window':fields.many2one( 'ref_ir_act_window':fields.many2one(
'ir.actions.act_window', 'ir.actions.act_window',
'Window Action', 'Window Action',
help="Action that will open this email template on Resource records",
readonly=True), readonly=True),
'ref_ir_value':fields.many2one( 'ref_ir_value':fields.many2one(
'ir.values', 'ir.values',
'Wizard Button', 'Wizard Button',
help="Button in the side bar of the form view of this Resource that will invoke the Window Action",
readonly=True), readonly=True),
'allowed_groups':fields.many2many( 'allowed_groups':fields.many2many(
'res.groups', 'res.groups',
@ -636,9 +638,13 @@ class email_template(osv.osv):
'mail_type':'multipart/alternative', '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']: if template['track_campaign_item']:
# get appropriate message-id # 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']: if not mailbox_values['account_id']:
raise Exception("Unable to send the mail. No account linked to the template.") raise Exception("Unable to send the mail. No account linked to the template.")

View File

@ -80,7 +80,12 @@ class email_template_account(osv.osv):
'name': fields.char('Description', 'name': fields.char('Description',
size=64, required=True, size=64, required=True,
readonly=True, select=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)]}), 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', 'user':fields.many2one('res.users',
'Related User', required=True, 'Related User', required=True,
readonly=True, states={'draft':[('readonly', False)]}), readonly=True, states={'draft':[('readonly', False)]}),
@ -133,7 +138,7 @@ class email_template_account(osv.osv):
('suspended', 'Suspended'), ('suspended', 'Suspended'),
('approved', 'Approved') ('approved', 'Approved')
], ],
'Status', required=True, readonly=True), 'State', required=True, readonly=True),
} }
_defaults = { _defaults = {
@ -189,25 +194,7 @@ class email_template_account(osv.osv):
'Error: You are not allowed to have more than 1 account.', '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): def get_outgoing_server(self, cursor, user, ids, context=None):
""" """
Returns the Out Going Connection (SMTP) object Returns the Out Going Connection (SMTP) object

View File

@ -18,16 +18,17 @@
<notebook colspan="4"> <notebook colspan="4">
<page string="Outgoing"> <page string="Outgoing">
<separator string="Server Information" colspan="4" /> <separator string="Server Information" colspan="4" />
<group colspan="4"> <group colspan="4" col="4">
<field name="smtpserver" select="1" colspan="2" /> <field name="smtpserver" select="1"/>
<field name="smtpport" select="2" colspan="2" /> <field name="smtpport" select="2" />
<field name="smtpssl" select="2" colspan="2" /> <field name="smtpssl" select="2" />
<field name="smtptls" select="2" colspan="2" /> <field name="smtptls" select="2" />
<field name="auto_delete" />
</group> </group>
<button name="check_outgoing_connection" type="object" string="Test Outgoing Connection" /> <button name="check_outgoing_connection" type="object" string="Test Outgoing Connection" />
<separator string="User Information" colspan="4" /> <separator string="User Information" colspan="4" />
<group col="2" colspan="2"> <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="smtppass" password="True" colspan="2" />
<field name="company" select="2" colspan="2" /> <field name="company" select="2" colspan="2" />
</group> </group>
@ -72,15 +73,16 @@
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Accounts"> <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-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')]"/> <filter icon="terp-emblem-important" string="Suspended" domain="[('state','=','suspended')]"/>
<separator orientation="vertical"/> <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="name" select="1"/>
<field name="user" select="1"/>
<field name="email_id" select="1"/> <field name="email_id" select="1"/>
</search> </search>
</field> </field>
@ -97,11 +99,25 @@
</record> </record>
<menuitem name="Configuration" parent="base.marketing_menu" <menuitem name="Configuration" parent="base.marketing_menu"
id="base.menu_marketing_config_root" sequence="20" groups="base.group_system"/> 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" />
<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"/> <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> </data>
</openerp> </openerp>

View File

@ -63,6 +63,7 @@ class email_template_mailbox(osv.osv):
def send_this_mail(self, cr, uid, ids=None, context=None): def send_this_mail(self, cr, uid, ids=None, context=None):
result = True result = True
attachment_pool = self.pool.get('ir.attachment')
for id in (ids or []): for id in (ids or []):
try: try:
account_obj = self.pool.get('email_template.account') account_obj = self.pool.get('email_template.account')
@ -70,7 +71,7 @@ class email_template_mailbox(osv.osv):
payload = {} payload = {}
if values['attachments_ids']: if values['attachments_ids']:
for attid in 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 payload[attachment.datas_fname] = attachment.datas
result = account_obj.send_mail(cr, uid, result = account_obj.send_mail(cr, uid,
[values['account_id'][0]], [values['account_id'][0]],
@ -84,8 +85,15 @@ class email_template_mailbox(osv.osv):
message_id=values['message_id'], message_id=values['message_id'],
context=context) context=context)
if result == True: if result == True:
self.write(cr, uid, id, {'folder':'sent', 'state':'na', 'date_mail':time.strftime("%Y-%m-%d %H:%M:%S")}, context) account = account_obj.browse(cr, uid, values['account_id'][0], context=context)
self.historise(cr, uid, [id], "Email sent successfully", 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: else:
error = result['error_msg'] error = result['error_msg']
self.historise(cr, uid, [id], error, context) 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): def historise(self, cr, uid, ids, message='', context=None):
for id in ids: for id in ids:
history = self.read(cr, uid, id, ['history'], context).get('history', '') 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 = { _columns = {
'email_from':fields.char( 'email_from':fields.char(
@ -171,8 +179,7 @@ class email_template_mailbox(osv.osv):
('na', 'Not Applicable'), ('na', 'Not Applicable'),
('sending', 'Sending'), ('sending', 'Sending'),
], 'Status', required=True), ], 'Status', required=True),
'date_mail':fields.datetime( 'date_mail':fields.datetime('Rec/Sent Date', help="Date on which Email Sent or Received"),
'Rec/Sent Date'),
'history':fields.text( 'history':fields.text(
'History', 'History',
readonly=True, readonly=True,
@ -184,6 +191,24 @@ class email_template_mailbox(osv.osv):
'folder': lambda * a: 'outbox', '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() email_template_mailbox()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -7,7 +7,7 @@
<field name="model">email_template.mailbox</field> <field name="model">email_template.mailbox</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Outbox"> <form string="Emails">
<group col="4" colspan="4" name="headers"> <group col="4" colspan="4" name="headers">
<field name="email_from" select="1"/> <field name="email_from" select="1"/>
<field name="email_to" required="1" select="1" /> <field name="email_to" required="1" select="1" />
@ -28,32 +28,27 @@
<field name="body_html" nolabel="1" colspan="4" /> <field name="body_html" nolabel="1" colspan="4" />
</page> </page>
</notebook> </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>
<page string="Attachments"> <page string="Attachments">
<group col="4"> <separator colspan="4" string="Attachments" />
<separator colspan="4" string="Attachments" /> <field name="attachments_ids" colspan="4" nolabel="1" />
<field name="attachments_ids" colspan="4" nolabel="1" />
</group>
</page> </page>
<page string="Advanced"> <page string="Advanced">
<group col="4"> <field name="account_id" colspan="2" />
<field name="account_id" colspan="2" /> <field name="server_ref" colspan="2" />
<field name="server_ref" colspan="2" /> <field name="mail_type" colspan="2" />
<field name="mail_type" colspan="2" /> <field name="folder" colspan="2" select="2"/>
<field name="folder" colspan="2" select="2"/> <field name="message_id" select="2"/>
<field name="message_id" select="2"/> <separator string="History" colspan="4" />
<separator string="History" colspan="4" /> <field name="history" nolabel="1" colspan="4"/>
<field name="history" nolabel="1" colspan="4"/>
</group>
</page> </page>
</notebook> </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> </form>
</field> </field>
</record> </record>
@ -64,12 +59,14 @@
<field name="model">email_template.mailbox</field> <field name="model">email_template.mailbox</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="arch" type="xml"> <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="user" />
<field name="email_from" select="1" /> <field name="email_from" select="1" />
<field name="subject" select="1" /> <field name="email_to"/>
<field name="attachments_ids" select="2" />
<field name="date_mail" select="2" /> <field name="date_mail" select="2" />
<field name="attachments_ids" select="2" />
<field name="folder" invisible="1"/>
</tree> </tree>
</field> </field>
</record> </record>
@ -79,37 +76,54 @@
<field name="model">email_template.mailbox</field> <field name="model">email_template.mailbox</field>
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Mailboxes"> <search string="Emails">
<filter icon="terp-mail-message-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/> <filter icon="terp-document-new" string="Drafts" name="draft" domain="[('folder','=','drafts')]"/>
<filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/> <filter icon="terp-mail-" string="Outbox" name="outbox" domain="[('folder','=','outbox')]"/>
<separator orientation="vertical"/> <filter icon="terp-camera_test" string="Sent" domain="[('folder','=','sent')]"/>
<filter icon="terp-gtk-jump-to-ltr" string="Sent" domain="[('folder','=','sent')]"/>
<filter icon="terp-mail_delete" string="Trash" domain="[('folder','=','trash')]"/> <filter icon="terp-mail_delete" string="Trash" domain="[('folder','=','trash')]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter icon="terp-gtk-stop" string="Not Applicable" domain="[('state','=','na')]"/> <filter icon="terp-personal+" string="Personal Emails" name="personal" domain="[('account_id.company','=','no')]"/>
<filter icon="terp-gtk-jump-to-ltr" string="Sending" domain="[('state','=','sending')]"/> <filter icon="terp-go-home" string="Company Emails" name="company" domain="[('account_id.company','=','yes')]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="email_from" select="1"/> <field name="subject"/>
<field name="email_to" select="1"/> <field name="email_from"/>
<field name="subject" select="1"/> <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> </search>
</field> </field>
</record> </record>
<record model="ir.actions.act_window" id="action_email_template_mailbox"> <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="res_model">email_template.mailbox</field>
<field name="view_type">form</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="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"/> <field name="search_view_id" ref="view_email_template_mailbox_search"/>
</record> </record>
<!--======================================== MENUS ========================================--> <!--======================================== 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="Emails"
<menuitem name="Company Mails" id="menu_email_template_company_mails" parent="menu_email_template_mailbox_all_main2" action="action_email_template_mailbox"/> 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> </data>
</openerp> </openerp>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<openerp> <openerp>
<data noupdate="1"> <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="name">Email Template scheduler</field>
<field name="user_id" ref="base.user_root"/> <field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field> <field name="interval_number">1</field>
<field name="interval_type">hours</field> <field name="interval_type">hours</field>
<field name="numbercall">12</field> <field name="numbercall">-1</field>
<field eval="False" name="doall"/> <field eval="False" name="doall"/>
<field eval="'email_template.mailbox'" name="model"/> <field eval="'email_template.mailbox'" name="model"/>
<field eval="'run_mail_scheduler'" name="function"/> <field eval="'run_mail_scheduler'" name="function"/>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<openerp> <openerp>
<data> <data>
<!-- Email Template PReview -->
<!-- Email Template Preview -->
<record model="ir.ui.view" id="email_template_preview_form"> <record model="ir.ui.view" id="email_template_preview_form">
<field name="name">email_template.preview.form</field> <field name="name">email_template.preview.form</field>
<field name="model">email_template.preview</field> <field name="model">email_template.preview</field>
@ -67,25 +68,26 @@
<field name="reply_to"/> <field name="reply_to"/>
</group> </group>
<group col="2" colspan="2"> <group col="2" colspan="2">
<separator string="Email Data" colspan="2"/> <separator string="Options" colspan="2"/>
<field name="def_subject" colspan="4" required="1" />
<field name="use_sign" colspan="4" />
<field name="lang" colspan="4" /> <field name="lang" colspan="4" />
<field name="use_sign" colspan="4" />
<field name="track_campaign_item" colspan="4"/> <field name="track_campaign_item" colspan="4"/>
</group> </group>
<separator colspan="3" string="Standard Body" /> <group col="2" colspan="2">
<separator colspan="1" string="Expression Builder" /> <separator colspan="2" string="Email Content " />
<field name="def_subject" colspan="4" required="1" />
<notebook> <notebook>
<page string="Body (Text)"> <page string="Body (Text)">
<field name="def_body_text" colspan="4" nolabel="1" /> <field name="def_body_text" colspan="4" nolabel="1" />
</page> </page>
<page string="Body (Raw HTML)"> <page string="Body (Raw HTML)">
<field name="def_body_html" colspan="4" nolabel="1" /> <field name="def_body_html" colspan="4" nolabel="1" />
<label string="Note: This is Raw HTML." colspan="4" /> <label string="Note: This is Raw HTML." colspan="4" />
</page> </page>
</notebook> </notebook>
<group col="4"> </group>
<group col="4" colspan="2">
<separator colspan="4" string="Expression Builder" />
<field name="template_language" <field name="template_language"
on_change="onchange_null_value(model_object_field,sub_model_object_field,null_value,template_language,context)" /> on_change="onchange_null_value(model_object_field,sub_model_object_field,null_value,template_language,context)" />
<notebook> <notebook>
@ -112,17 +114,23 @@
</page> </page>
<page string="Advanced"> <page string="Advanced">
<group colspan="2" col="2"> <group colspan="2" col="2">
<separator string="Actions" colspan="2"/> <group colspan="2" col="2">
<button name="create_action" string="Create Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','!=',False), ('ref_ir_value','!=',False)]}"/> <separator string="Actions" colspan="2"/>
<field name="ref_ir_act_window"/> <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_value"/> <field name="ref_ir_act_window"/>
<button name="delete_action" string="Delete Action" type="object" colspan="2" attrs="{'invisible':[('ref_ir_act_window','=',False), ('ref_ir_value','=',False)]}"/> <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>
<group colspan="2" col="2"> <group colspan="2" col="2">
<separator string="Attachments" colspan="2"/> <separator string="Attachments" colspan="2"/>
<notebook> <notebook>
<page string="Existing files"> <page string="Existing files">
<field name="attachment_ids" colspan="4" nolabel="1"/> <field name="attachment_ids" colspan="4" nolabel="1" height="350"/>
</page> </page>
<page string="Report"> <page string="Report">
<field name="file_name" colspan="4" /> <field name="file_name" colspan="4" />
@ -183,9 +191,12 @@
<field name="search_view_id" ref="view_email_template_search"/> <field name="search_view_id" ref="view_email_template_search"/>
</record> </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" /> 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> </data>
</openerp> </openerp>

View File

@ -335,11 +335,6 @@ msgstr ""
msgid "Send/Receive" msgid "Send/Receive"
msgstr "" msgstr ""
#. module: email_template
#: model:ir.ui.menu,name:email_template.menu_email_template_mailbox_all_main2
msgid "MailBox"
msgstr ""
#. module: email_template #. module: email_template
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview #: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
msgid "Template Preview" msgid "Template Preview"

View File

@ -174,8 +174,8 @@ msgstr "Approve Account"
#. module: email_template #. module: email_template
#: model:ir.ui.menu,name:email_template.menu_email_template_all #: model:ir.ui.menu,name:email_template.menu_email_template_all
msgid "E-MAIL Templates" msgid "Email Templates"
msgstr "E-MAIL Templates" msgstr "Email Templates"
#. module: email_template #. module: email_template
#: field:email_template.preview,rel_model_ref:0 #: field:email_template.preview,rel_model_ref:0
@ -221,8 +221,8 @@ msgstr "Download Full Mail"
#. module: email_template #. module: email_template
#: help:email.template,def_to:0 #: help:email.template,def_to:0
msgid "The default recipient of email.Placeholders can be used here." msgid "The recipient of email.Placeholders can be used here."
msgstr "The default recipient of email.Placeholders can be used here." msgstr "The recipient of email.Placeholders can be used here."
#. module: email_template #. module: email_template
#: view:email_template.mailbox:0 #: view:email_template.mailbox:0
@ -258,8 +258,8 @@ msgstr "Accounts"
#. module: email_template #. module: email_template
#: field:email.template,track_campaign_item:0 #: field:email.template,track_campaign_item:0
msgid "Track campaign items" msgid "Resource Tracking"
msgstr "Track campaign items" msgstr "Resource Tracking"
#. module: email_template #. module: email_template
#: view:email_template.preview:0 #: view:email_template.preview:0
@ -335,11 +335,6 @@ msgstr "Body(Html)"
msgid "Send/Receive" msgid "Send/Receive"
msgstr "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 #. module: email_template
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview #: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
msgid "Template Preview" msgid "Template Preview"
@ -762,8 +757,8 @@ msgstr "Save in Drafts"
#. module: email_template #. module: email_template
#: help:email.template,def_subject:0 #: help:email.template,def_subject:0
msgid "The default subject of email. Placeholders can be used here." msgid "The subject of email. Placeholders can be used here."
msgstr "The default subject of email. Placeholders can be used here." msgstr "The subject of email. Placeholders can be used here."
#. module: email_template #. module: email_template
#: field:email_template.account,smtptls:0 #: field:email_template.account,smtptls:0
@ -772,8 +767,8 @@ msgstr "TLS"
#. module: email_template #. module: email_template
#: view:email_template.send.wizard:0 #: view:email_template.send.wizard:0
msgid "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 e-mail." msgstr "Add here all attachments of the current document you want to include in the Email."
#. module: email_template #. module: email_template
#: model:ir.model,name:email_template.model_email_template_send_wizard #: 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/email_template_mailbox.py:0
#: code:addons/email_template/wizard/email_template_send_wizard.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
#: 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 #, python-format
msgid "Email Template" msgid "Email Template"
msgstr "Email Template" msgstr "Email Template"
@ -1023,8 +1020,8 @@ msgstr "Password"
#: help:email.template,message_id:0 #: help:email.template,message_id:0
#: help:email_template.preview,message_id:0 #: help:email_template.preview,message_id:0
#: help:email_template.send.wizard,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." 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 "The Message-ID header value, if you need tospecify it, for example to automatically recognize the replies later. 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 #. module: email_template
#: model:ir.ui.menu,name:email_template.menu_email_template_configuration #: 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 " msgid "Enter name of outgoing server, eg:smtp.gmail.com "
msgstr "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 #. module: email_template
#: view:email.template:0 #: view:email.template:0
msgid "Addresses" msgid "Addresses"
@ -1130,8 +1122,8 @@ msgstr "Emails will be sent from this approved account."
#. module: email_template #. module: email_template
#: field:email.template,def_subject:0 #: field:email.template,def_subject:0
msgid "Default Subject" msgid "Subject"
msgstr "Default Subject" msgstr "Subject"
#. module: email_template #. module: email_template
#: help:email.template,def_bcc:0 #: help:email.template,def_bcc:0
@ -1182,8 +1174,8 @@ msgstr "Has Attachments"
#. module: email_template #. module: email_template
#: help:email.template,track_campaign_item:0 #: 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" 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 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 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 #. module: email_template
#: code:addons/email_template/email_template.py:0 #: code:addons/email_template/email_template.py:0

View File

@ -348,11 +348,6 @@ msgstr ""
msgid "Send/Receive" msgid "Send/Receive"
msgstr "" msgstr ""
#. module: email_template
#: model:ir.ui.menu,name:email_template.menu_email_template_mailbox_all_main2
msgid "MailBox"
msgstr ""
#. module: email_template #. module: email_template
#: model:ir.actions.act_window,name:email_template.wizard_email_template_preview #: model:ir.actions.act_window,name:email_template.wizard_email_template_preview
msgid "Template Preview" msgid "Template Preview"
@ -1145,11 +1140,6 @@ msgstr ""
msgid "Enter name of outgoing server, eg:smtp.gmail.com " msgid "Enter name of outgoing server, eg:smtp.gmail.com "
msgstr "" msgstr ""
#. module: email_template
#: model:ir.ui.menu,name:email_template.menu_email_template_company_mails
msgid "Company Mails"
msgstr ""
#. module: email_template #. module: email_template
#: view:email.template:0 #: view:email.template:0
msgid "Addresses" msgid "Addresses"

View File

@ -33,7 +33,7 @@
<field name="body_html" select="2" colspan="4" nolabel="1" /> <field name="body_html" select="2" colspan="4" nolabel="1" />
</page> </page>
<page string="Attachments"> <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"/> <field name="attachment_ids" colspan="4" nolabel="1"/>
</page> </page>
</notebook> </notebook>

View File

@ -101,7 +101,7 @@
- -
!python {model: hr.sign.in.project}: | !python {model: hr.sign.in.project}: |
uid = ref('res_users_user0') 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) self.sign_in_result(cr, uid, [new_id], context)
- -

View File

@ -32,7 +32,7 @@ class marketing_installer(osv.osv_memory):
'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration', 'marketing_campaign_mailchimp':fields.boolean('Mailchimp Integration',
help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."), help="This modules integrate mailchimp.com's service with OpenERP to automate mass mailings."),
'crm_profiling':fields.boolean('Profiling Tools', '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() marketing_installer()

View File

@ -30,14 +30,16 @@
"author" : "OpenERP SA", "author" : "OpenERP SA",
"category": 'Generic Modules/Marketing', "category": 'Generic Modules/Marketing',
"description": """ "description": """
Allows you to setup leads automation through marketing campaigns. The campaigns This module provides leads automation through marketing campaigns (campaigns can in fact be defined on any resource, not just CRM Leads).
are dynamic and multi-channels. The process: The campaigns are dynamic and multi-channels. The process is as follows:
* Design marketing campaigns that incluces mail templates, reports to print, * Design marketing campaigns like workflows, including email templates to send, reports to print and send by email, custom actions, etc.
miscelleanous actions, etc. * Define input segments that will select the items that should enter the campaign (e.g leads from certain countries, etc.)
* Define segments that are selections of target people * Run you campaign in simulation mode to test it real-time or accelerated, and fine-tune it
* Launch your campaign to automate communications. * 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.
If you need demo data, you can install the module marketing_campaign_crm_demo. 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', 'website': 'http://www.openerp.com',
'init_xml': [], 'init_xml': [],

View File

@ -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"

View File

@ -91,7 +91,7 @@ class marketing_campaign(osv.osv):
this campaign to be run"), this campaign to be run"),
'partner_field_id': fields.many2one('ir.model.fields', 'Partner Field', 'partner_field_id': fields.many2one('ir.model.fields', 'Partner Field',
domain="[('model_id', '=', object_id), ('ttype', '=', 'many2one'), ('relation', '=', 'res.partner')]", 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'), 'mode': fields.selection([('test', 'Test Directly'),
('test_realtime', 'Test in Realtime'), ('test_realtime', 'Test in Realtime'),
('manual', 'With Manual Confirmation'), ('manual', 'With Manual Confirmation'),
@ -108,7 +108,7 @@ Normal - the campaign runs normally and automatically sends all emails and repor
'State',), 'State',),
'activity_ids': fields.one2many('marketing.campaign.activity', 'activity_ids': fields.one2many('marketing.campaign.activity',
'campaign_id', 'Activities'), '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 = { _defaults = {
@ -220,20 +220,20 @@ class marketing_campaign_segment(osv.osv):
'object_id': fields.related('campaign_id','object_id', 'object_id': fields.related('campaign_id','object_id',
type='many2one', relation='ir.model', type='many2one', relation='ir.model',
string='Object'), string='Object'),
'ir_filter_id': fields.many2one('ir.filters', 'Filter', help=""), '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('Latest Synchronization'), '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'), 'sync_mode': fields.selection([('create_date', 'If record created after last sync'),
('write_date', 'If record modified after last sync (no duplicates)'), ('write_date', 'If record modified after last sync (no duplicates)'),
('all', 'All records (no duplicates)')], ('all', 'All records (no duplicates)')],
'Workitem creation mode', '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'), 'state': fields.selection([('draft', 'Draft'),
('running', 'Running'), ('running', 'Running'),
('done', 'Done'), ('done', 'Done'),
('cancelled', 'Cancelled')], ('cancelled', 'Cancelled')],
'State',), 'State',),
'date_run': fields.datetime('Launching Date'), 'date_run': fields.datetime('Launching Date', help="Initial start date of this segment."),
'date_done': fields.datetime('End Date'), 'date_done': fields.datetime('End Date', help="Date this segment was last closed or cancelled."),
} }
_defaults = { _defaults = {
@ -241,6 +241,34 @@ class marketing_campaign_segment(osv.osv):
'sync_mode': lambda *a: 'create_date', '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): def state_running_set(self, cr, uid, ids, *args):
segment = self.browse(cr, uid, ids[0]) segment = self.browse(cr, uid, ids[0])
vals = {'state': 'running'} vals = {'state': 'running'}
@ -325,8 +353,8 @@ class marketing_campaign_activity(osv.osv):
_action_types = [ _action_types = [
('email', 'E-mail'), ('email', 'E-mail'),
('paper', 'Paper'), ('report', 'Report'),
('action', 'Action'), ('action', 'Custom Action'),
# TODO implement the subcampaigns. # TODO implement the subcampaigns.
# TODO implement the subcampaign out. disallow out transitions from # TODO implement the subcampaign out. disallow out transitions from
# subcampaign activities ? # subcampaign activities ?
@ -346,13 +374,17 @@ class marketing_campaign_activity(osv.osv):
"The expression may use the following [browsable] variables:\n" "The expression may use the following [browsable] variables:\n"
" - activity: the campaign activity\n" " - activity: the campaign activity\n"
" - workitem: the campaign workitem\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" " - transitions: list of campaign transitions outgoing from this activity\n"
"...- re: Python regular expression module"), "...- re: Python regular expression module"),
'type': fields.selection(_action_types, 'Type', required=True, 'type': fields.selection(_action_types, 'Type', required=True,
help="Describe type of action to be performed on the Activity.Eg : Send email,Send paper.."), help="""The type of action to execute when an item enters this activity, such as:
'email_template_id': fields.many2one('email.template','The e-mail to send when this activity is activated'), - Email: send an email using a predefined email template
'report_id': fields.many2one('ir.actions.report.xml', 'The report to generate when this activity is activated', ), - 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', 'report_directory_id': fields.many2one('document.directory','Directory',
help="This folder is used to store the generated reports"), help="This folder is used to store the generated reports"),
'server_action_id': fields.many2one('ir.actions.server', string='Action', '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', 'from_ids': fields.one2many('marketing.campaign.transition',
'activity_to_id', 'activity_to_id',
'Previous Activities'), 'Previous Activities'),
'variable_cost': fields.float('Variable Cost'), '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'), '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, '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'), 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.") 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, return super(marketing_campaign_activity, self).search(cr, uid, args,
offset, limit, order, context, count) 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) service = netsvc.LocalService('report.%s'%activity.report_id.report_name)
(report_data, format) = service.create(cr, uid, [], {}, {}) (report_data, format) = service.create(cr, uid, [], {}, {})
attach_vals = { attach_vals = {
@ -517,23 +549,50 @@ class marketing_campaign_workitem(osv.osv):
res[wi.id] = ng[0][1] res[wi.id] = ng[0][1]
return res 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 = { _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', 'activity_id': fields.many2one('marketing.campaign.activity','Activity',
required=True), required=True, readonly=True),
'campaign_id': fields.related('activity_id', 'campaign_id', 'campaign_id': fields.related('activity_id', 'campaign_id',
type='many2one', relation='marketing.campaign', string='Campaign', readonly=True), type='many2one', relation='marketing.campaign', string='Campaign', readonly=True),
'object_id': fields.related('activity_id', 'campaign_id', 'object_id', 'object_id': fields.related('activity_id', 'campaign_id', 'object_id',
type='many2one', relation='ir.model', string='Object', select=1), type='many2one', relation='ir.model', string='Resource', select=1, readonly=True),
'res_id': fields.integer('Resource ID', select=1, readonly=1), 'res_id': fields.integer('Resource ID', select=1, readonly=True),
'res_name': fields.function(_res_name_get, method=True, string='Resource Name', type="char", size=64), '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 have to be run manually'), '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), 'partner_id': fields.many2one('res.partner', 'Partner', select=1, readonly=True),
'state': fields.selection([('todo', 'To Do'), 'state': fields.selection([('todo', 'To Do'),
('exception', 'Exception'), ('done', 'Done'), ('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 = { _defaults = {
'state': lambda *a: 'todo', 'state': lambda *a: 'todo',
@ -564,6 +623,7 @@ class marketing_campaign_workitem(osv.osv):
'activity': activity, 'activity': activity,
'workitem': workitem, 'workitem': workitem,
'object': object_id, 'object': object_id,
'resource': object_id,
'transitions': activity.to_ids, 'transitions': activity.to_ids,
're': re, 're': re,
} }
@ -688,7 +748,7 @@ class marketing_campaign_workitem(osv.osv):
wi_obj.res_id) wi_obj.res_id)
} }
elif wi_obj.activity_id.type == 'paper': elif wi_obj.activity_id.type == 'report':
datas = { datas = {
'ids': [wi_obj.res_id], 'ids': [wi_obj.res_id],
'model': wi_obj.object_id.model 'model': wi_obj.object_id.model

View File

@ -17,16 +17,25 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Campaign"> <form string="Campaign">
<group colspan="4" col="6"> <group colspan="4" col="6">
<field name="name" select="1"/> <group colspan="2" col="2">
<field name="object_id" select="1"/> <separator string="Campaign" colspan="2" />
<field name="mode"/> <field name="name" select="1"/>
<field name="fixed_cost"/> <field name="mode"/>
<field name="partner_field_id"/> </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> </group>
<field name="activity_ids" nolabel = "1" colspan="4" default_get="{'default_object_id': object_id}" /> <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"> <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_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_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"/> <button name="state_done_set" string="Close" states="running" icon="terp-dialog-close"/>
@ -45,6 +54,7 @@
<field name="name" select="1"/> <field name="name" select="1"/>
<field name="object_id" select="1"/> <field name="object_id" select="1"/>
<field name="mode"/> <field name="mode"/>
<field name="fixed_cost"/>
<field name="state"/> <field name="state"/>
</tree> </tree>
</field> </field>
@ -125,27 +135,31 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Segments"> <form string="Segments">
<group colspan="4" col="6"> <group colspan="2" col="2">
<separator string="Segment" colspan="4"/>
<field name="name"/> <field name="name"/>
<field name="campaign_id" select="1"/> <field name="campaign_id" select="1" on_change="onchange_campaign_id(campaign_id)"/>
<field name="ir_filter_id" select="1"/>
<field name="object_id" invisible="1" readonly="True"/>
</group> </group>
<group colspan="2" col="2"> <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_mode" required="True"/>
<field name="sync_last_date"/> <field name="sync_last_date"/>
<label string="" colspan="1"/> <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>
<group colspan="2" col="2"> <group colspan="2" col="2">
<separator string="Dates" colspan="2"/> <separator string="History" colspan="2"/>
<field name="date_run" readonly="1"/> <field name="date_run" readonly="1"/>
<field name="date_done" readonly="1"/> <field name="date_done" readonly="1"/>
</group> </group>
<separator string="Status" colspan="4"/> <separator string="" colspan="4"/>
<group col="10" colspan="4"> <group col="6" 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" icon="gtk-apply"/> <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_done_set" string="Close" states="running" icon="terp-dialog-close"/>
<button name="state_cancel_set" string="Cancel" states="running" icon="terp-gtk-stop"/> <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-check" string="Running" name="running" domain="[('state','=','running')]"/>
<filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]"/> <filter icon="terp-document-new" string="Draft" domain="[('state','=','draft')]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter icon="terp-go-month" string="Create After Sync" domain="[('sync_mode','=','create_date')]"/> <filter icon="terp-project" string="Newly Created" 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 Modified" domain="[('sync_mode','=','write_date')]"/>
<filter icon="terp-project" string="All" domain="[('sync_mode','=','all')]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="name" select="1"/> <field name="name" select="1"/>
<field name="campaign_id" select="1"/> <field name="campaign_id" select="1"/>
@ -225,36 +240,38 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Activities"> <form string="Activities">
<field name="object_id" invisible="1"/> <group colspan='2' col='2'>
<separator string="Activity Definition" colspan="4"/> <separator string="Activity" colspan="4"/>
<field name="name" select="1" colspan='4' /> <field name="name" select="1" colspan='4' />
<field name="signal"/> <field name="signal" groups="base.group_extended"/>
<field name="start"/> <field name="start"/>
<field name="variable_cost" select="1"/> <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/> <newline/>
<group colspan='4' col='2'>
<separator string="Action" colspan="4"/> <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='4'>
<group colspan="4" col="6"> <separator string="Action" colspan="4"/>
<field name="condition" colspan="5" widget="char"/> <field name="type"/>
<group col='2'>
<field name="keep_if_condition_not_met" />
</group>
</group>
<field name="type" width='100'/>
<group colspan='2' col='1'> <group colspan='2' col='1'>
<field name="email_template_id" attrs="{'required':[('type','=','email')], 'invisible':[('type','!=','email')]}" <field name="email_template_id" attrs="{'required':[('type','=','email')], 'invisible':[('type','!=','email')]}"
context="{'default_object_name':object_id}" /> context="{'default_object_name':object_id}" />
<group attrs="{'invisible':[('type','!=','paper')]}" > <group attrs="{'invisible':[('type','!=','report')]}" >
<field name="report_id" attrs="{'required':[('type','=','paper')]}" context="{'object_id':object_id}"/> <field name="report_id" attrs="{'required':[('type','=','report')]}" context="{'object_id':object_id}"/>
<field name="report_directory_id" attrs="{'required':[('type','=','paper')]}" /> <field name="report_directory_id" attrs="{'required':[('type','=','report')]}" />
</group> </group>
<field name="server_action_id" attrs="{'required':[('type','=','action')],'invisible':[('type','!=','action')]}" domain="[('model_id','=',object_id)]" /> <field name="server_action_id" attrs="{'required':[('type','=','action')],'invisible':[('type','!=','action')]}" domain="[('model_id','=',object_id)]" />
</group> </group>
</group> </group>
<newline/> <group colspan="4" col="2">
<group colspan="4" col="2" expand="1">
<separator string="Transitions" colspan="2"/> <separator string="Transitions" colspan="2"/>
<field name="from_ids" nolabel="1" mode="tree,form" default_get="{'default_activity_to_id': active_id}"> <field name="from_ids" nolabel="1" mode="tree,form" default_get="{'default_activity_to_id': active_id}">
<tree string="Incoming Transitions" editable="bottom"> <tree string="Incoming Transitions" editable="bottom">
@ -296,9 +313,9 @@
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Activities"> <tree string="Activities">
<field name="name" select="1"/> <field name="name" select="1"/>
<field name="start"/>
<field name="condition"/> <field name="condition"/>
<field name="type"/> <field name="type"/>
<field name="start"/>
</tree> </tree>
</field> </field>
</record> </record>
@ -322,6 +339,7 @@
<field name="partner_id"/> <field name="partner_id"/>
<field name="date"/> <field name="date"/>
<field name="state"/> <field name="state"/>
<field name="res_id" invisible="1"/>
<button string="Preview" states="todo" name="preview" icon="gtk-zoom-fit" type="object"/> <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="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"/> <button string="Cancel" states="todo" name="button_cancel" type="object" icon="terp-gtk-stop"/>
@ -358,9 +376,9 @@
<separator string="Error Message" colspan="4"/> <separator string="Error Message" colspan="4"/>
<field name="error_msg" nolabel="1" colspan="4"/> <field name="error_msg" nolabel="1" colspan="4"/>
</group> </group>
<separator string="Status" colspan="4"/> <separator string="" colspan="4"/>
<group colspan="4" col="11"> <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="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="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"/> <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="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Marketing Campaign Activities"> <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','&lt;', time.strftime('%%Y-%%m-%%d 23:59:59')), ('date','&gt;=', 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')]"/> <filter icon="terp-emblem-important" string="Exception" domain="[('state','=','exception')]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="segment_id" select="1"/> <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="partner_id" select="1"/>
<field name="date" select="1"/> <field name="date" select="1"/>
<newline/> <newline/>
<group expand="0" string="Group By..." colspan="10" col="12"> <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="Campaign" name="campaign" icon="terp-gtk-jump-to-rtl" context="{'group_by':'campaign_id'}" /-->
<filter string="Activity" name="Activity" icon="terp-stock_align_left_24" context="{'group_by':'activity_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"/> <separator orientation="vertical"/>
<filter string="State" name="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}" /> <filter string="State" name="State" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}" />
<separator orientation="vertical"/> <separator orientation="vertical"/>
@ -417,5 +439,19 @@
domain="[('campaign_id','=',active_id)]" 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> </data>
</openerp> </openerp>

View File

@ -38,10 +38,11 @@ class campaign_analysis(osv.osv):
wi_ids = self.pool.get('marketing.campaign.workitem').search(cr, uid, wi_ids = self.pool.get('marketing.campaign.workitem').search(cr, uid,
[('segment_id.campaign_id', '=', ca_obj.campaign_id.id)]) [('segment_id.campaign_id', '=', ca_obj.campaign_id.id)])
total_cost = ca_obj.activity_id.variable_cost + \ 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 result[ca_obj.id] = total_cost
return result return result
_columns = { _columns = {
'res_id' : fields.integer('Resource', readonly=True),
'year': fields.char('Year', size=4, readonly=True), 'year': fields.char('Year', size=4, readonly=True),
'month':fields.selection([('01','January'), ('02','February'), 'month':fields.selection([('01','January'), ('02','February'),
('03','March'), ('04','April'),('05','May'), ('06','June'), ('03','March'), ('04','April'),('05','May'), ('06','June'),
@ -69,6 +70,7 @@ class campaign_analysis(osv.osv):
create or replace view campaign_analysis as ( create or replace view campaign_analysis as (
select select
min(wi.id) as id, 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, 'YYYY') as year,
to_char(wi.date::date, 'MM') as month, to_char(wi.date::date, 'MM') as month,
wi.date::date as date, wi.date::date as date,

View File

@ -15,6 +15,7 @@
<field name="segment_id" invisible="1"/> <field name="segment_id" invisible="1"/>
<field name="partner_id" invisible="1"/> <field name="partner_id" invisible="1"/>
<field name="country_id" invisible="1"/> <field name="country_id" invisible="1"/>
<field name="res_id" invisible="1"/>
<field name="count"/> <field name="count"/>
<field name="total_cost" string="Cost"/><!-- sum="Cost"/--> <field name="total_cost" string="Cost"/><!-- sum="Cost"/-->
<field name="revenue"/> <field name="revenue"/>
@ -35,7 +36,7 @@
<filter icon="terp-go-month" <filter icon="terp-go-month"
string="This Month" string="This Month"
domain="[('month','=',time.strftime('%%m'))]"/> domain="[('month','=',time.strftime('%%m'))]"/>
<filter icon="terp-go-month" <filter icon="terp-go-today"
string="Today" string="Today"
domain="[('date','=',time.strftime('%%Y/%%m/%%d'))]"/> domain="[('date','=',time.strftime('%%Y/%%m/%%d'))]"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
@ -59,7 +60,9 @@
<group expand="0" string="Group By..." colspan="10" col="12"> <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="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="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"/> <separator orientation="vertical"/>
<filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/> <filter string="Partner" icon="terp-personal" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>

View File

@ -191,7 +191,7 @@
<field name="server_action_id" ref="action_dummy"/> <field name="server_action_id" ref="action_dummy"/>
<field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/> <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
<field name="report_directory_id" ref="document_directory_campaign1"/> <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 eval="1" name="start"/>
<field name="report_id" ref="mc_crm_lead_demo_report"/> <field name="report_id" ref="mc_crm_lead_demo_report"/>
</record> </record>
@ -220,7 +220,7 @@
<field name="server_action_id" ref="action_dummy"/> <field name="server_action_id" ref="action_dummy"/>
<field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/> <field model="marketing.campaign" name="campaign_id" ref="marketing_campaign_openerpondemandfreetrial0"/>
<field name="report_directory_id" ref="document_directory_campaign1"/> <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"/> <field name="report_id" ref="mc_crm_lead_demo_report"/>
</record> </record>

View File

@ -26,11 +26,13 @@
"depends" : ['marketing_campaign'], "depends" : ['marketing_campaign'],
"author" : "OpenERP SA", "author" : "OpenERP SA",
"category": 'Generic Modules/Marketing', "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', 'website': 'http://www.openerp.com',
'init_xml': [], 'init_xml': [],
'update_xml': [ 'update_xml': [
"security/ir.model.access.csv",
'marketing_campaign_mailchimp_view.xml', 'marketing_campaign_mailchimp_view.xml',
'wizard/create_list_view.xml', 'wizard/create_list_view.xml',
], ],

View File

@ -31,14 +31,14 @@
--> -->
<menuitem name="Tools" id="base.menu_tools" icon="STOCK_PREFERENCES" sequence="28"/> <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"> <record model="ir.ui.view" id="view_mailchimp_account_tree">
<field name="name">mailchimp.account.tree</field> <field name="name">mailchimp.account.tree</field>
<field name="model">mailchimp.account</field> <field name="model">mailchimp.account</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="arch" type="xml"> <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="name"/>
<field name="username" /> <field name="username" />
<field name="data_center"/> <field name="data_center"/>
@ -70,7 +70,7 @@
</record> </record>
<record model="ir.actions.act_window" id="action_mailchimp_account"> <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="type">ir.actions.act_window</field>
<field name="res_model">mailchimp.account</field> <field name="res_model">mailchimp.account</field>
<field name="view_type">form</field> <field name="view_type">form</field>

View File

@ -1,5 +1,4 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "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_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_mailchimp_account_system","mailchimp.account.user","marketing_campaign_mailchimp.model_mailchimp_account","base.res_groups_email_template_admin",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_mailchimp_account_user","mailchimp_account_user","model_mailchimp_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

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_mailchimp_account_user mailchimp.account.user marketing_campaign_mailchimp.model_mailchimp_account base.res_groups_email_template_admin 1 1 1 1
3 access_mailchimp_account_system mailchimp.account.user marketing_campaign_mailchimp.model_mailchimp_account base.groups_system base.res_groups_email_template_admin 1 0 0 0
4 access_email_template_account_system access_mailchimp_account_user email_template_account_user mailchimp_account_user marketing_campaign_mailchimp.model_email_template_account model_mailchimp_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

View File

@ -5,7 +5,8 @@
<field name="model">create.list</field> <field name="model">create.list</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <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="mailchimp_account_id" on_change = "onchange_mailchimp_account_id(mailchimp_account_id,action)"/>
<field name="list_name" /> <field name="list_name" />
<newline/> <newline/>
@ -19,14 +20,18 @@
</field> </field>
</record> </record>
<record id="action_create_list" model="ir.actions.act_window"> <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="type">ir.actions.act_window</field>
<field name="res_model">create.list</field> <field name="res_model">create.list</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_id" ref="view_create_list"/> <field name="view_id" ref="view_create_list"/>
<field name="target">new</field> <field name="target">new</field>
</record> </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> </openerp>

View File

@ -31,14 +31,14 @@
work done on tasks, eso. It is able to render planning, order tasks, eso. work done on tasks, eso. It is able to render planning, order tasks, eso.
Dashboard for project members that includes: Dashboard for project members that includes:
* List of my open tasks * List of my open tasks
* List of messages
* Members list of project * Members list of project
* Issues
""", """,
"init_xml": [], "init_xml": [],
"update_xml": [ "update_xml": [
"security/project_security.xml", "security/project_security.xml",
"wizard/project_task_delegate_view.xml", "wizard/project_task_delegate_view.xml",
"wizard/project_task_close_view.xml",
"wizard/project_task_reevaluate_view.xml",
"security/ir.model.access.csv", "security/ir.model.access.csv",
"project_data.xml", "project_data.xml",
"project_view.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", "project_installer.xml",
"res_partner_view.xml", "res_partner_view.xml",
"report/project_report_view.xml", "report/project_report_view.xml",
"wizard/project_close_task_view.xml",
"board_project_view.xml", "board_project_view.xml",
'board_project_manager_view.xml' 'board_project_manager_view.xml'
], ],

View File

@ -78,17 +78,6 @@
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
<field name="domain">[('type','=','Project')]</field> <field name="domain">[('type','=','Project')]</field>
</record> </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"> <record id="board_project_form" model="ir.ui.view">
<field name="name">board.project.form</field> <field name="name">board.project.form</field>
<field name="model">board.board</field> <field name="model">board.board</field>

View File

@ -25,6 +25,7 @@ from datetime import datetime, date
from tools.translate import _ from tools.translate import _
from osv import fields, osv from osv import fields, osv
from tools import email_send as email
class project_task_type(osv.osv): class project_task_type(osv.osv):
_name = 'project.task.type' _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."), '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."), '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."), '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_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_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)]}), '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."), '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."), '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."), '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."), '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'), '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) res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
return res return res
def do_close(self, cr, uid, ids, *args): def do_close(self, cr, uid, ids, context=None):
mail_send = False """
mod_obj = self.pool.get('ir.model.data') Close Task
"""
if context is None:
context = {}
request = self.pool.get('res.request') request = self.pool.get('res.request')
tasks = self.browse(cr, uid, ids) for task in self.browse(cr, uid, ids, context=context):
task_id = ids[0]
cntx = {}
if len(args):
cntx = args[0]
for task in tasks:
project = task.project_id project = task.project_id
if project: if project:
# Send request to project manager
if project.warn_manager and project.user_id and (project.user_id.id != uid): if project.warn_manager and project.user_id and (project.user_id.id != uid):
request.create(cr, uid, { request.create(cr, uid, {
'name': _("Task '%s' closed") % task.name, 'name': _("Task '%s' closed") % task.name,
@ -508,12 +508,7 @@ class task(osv.osv):
'ref_doc1': 'project.task,%d'% (task.id,), 'ref_doc1': 'project.task,%d'% (task.id,),
'ref_doc2': 'project.project,%d'% (project.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: for parent_id in task.parent_ids:
if parent_id.state in ('pending','draft'): if parent_id.state in ('pending','draft'):
reopen = True reopen = True
@ -522,29 +517,16 @@ class task(osv.osv):
reopen = False reopen = False
if reopen: if reopen:
self.do_reopen(cr, uid, [parent_id.id]) self.do_reopen(cr, uid, [parent_id.id])
if mail_send: self.write(cr, uid, [task.id], {'state': 'done', 'date_end':time.strftime('%Y-%m-%d %H:%M:%S'), 'remaining_hours': 0.0})
model_data_ids = mod_obj.search(cr,uid,[('model','=','ir.ui.view'),('name','=','view_project_close_task')]) message = _('Task ') + " '" + task.name + "' "+ _("is Done.")
resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id'] self.log(cr, uid, task.id, message)
cntx.update({'task_id': task_id}) return True
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
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') request = self.pool.get('res.request')
tasks = self.browse(cr, uid, ids) for task in self.browse(cr, uid, ids, context=context):
for task in tasks:
project = task.project_id project = task.project_id
if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid): if project and project.warn_manager and project.user_id.id and (project.user_id.id != uid):
request.create(cr, uid, { request.create(cr, uid, {
@ -592,6 +574,40 @@ class task(osv.osv):
self.write(cr, uid, ids, {'state': 'draft'}) self.write(cr, uid, ids, {'state': 'draft'})
return True 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): def do_pending(self, cr, uid, ids, *args):
self.write(cr, uid, ids, {'state': 'pending'}) self.write(cr, uid, ids, {'state': 'pending'})
for (id, name) in self.name_get(cr, uid, ids): for (id, name) in self.name_get(cr, uid, ids):
@ -691,105 +707,6 @@ class project_work(osv.osv):
project_work() 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): class account_analytic_account(osv.osv):
_inherit = 'account.analytic.account' _inherit = 'account.analytic.account'

View File

@ -254,15 +254,5 @@
<field name="project_id" ref="project_project_22"/> <field name="project_id" ref="project_project_22"/>
<field name="name">Latest in house tests</field> <field name="name">Latest in house tests</field>
</record> </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> </data>
</openerp> </openerp>

View File

@ -109,7 +109,7 @@
</group> </group>
<newline /> <newline />
<group expand="0" string="Group By..." colspan="4" col="20" groups="base.group_extended"> <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'}"/> <filter string="Partner" name="Partner" icon="terp-personal" domain = "[]" context="{'group_by':'partner_id'}"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter string="Parent" name="Parent" icon="terp-folder-blue" domain = "[]" context="{'group_by':'parent_id'}"/> <filter string="Parent" name="Parent" icon="terp-folder-blue" domain = "[]" context="{'group_by':'parent_id'}"/>
@ -189,33 +189,6 @@
</field> </field>
</record> </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 --> <!-- Task -->
<record id="view_task_form2" model="ir.ui.view"> <record id="view_task_form2" model="ir.ui.view">
<field name="name">project.task.form</field> <field name="name">project.task.form</field>
@ -244,7 +217,7 @@
</group> </group>
<group col="3" colspan="2"> <group col="3" colspan="2">
<field name="remaining_hours" widget="float_time" attrs="{'readonly':[('state','!=','draft')]}" 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"/> <field name="delay_hours" widget="float_time"/>
</group> </group>
@ -263,10 +236,10 @@
<field name="state" select="1"/> <field name="state" select="1"/>
<button name="do_draft" states="open" string="Draft" type="object" icon="gtk-indent"/> <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="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 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 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"/> <button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel"/>
</group> </group>
</page> </page>
@ -343,7 +316,7 @@
<field name="state" invisible="context.get('set_visible',False)"/> <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 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 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"/> <button name="do_cancel" states="draft,open,pending" string="Cancel" type="object" icon="gtk-cancel" help="For cancelling the task"/>
</tree> </tree>
</field> </field>
@ -421,7 +394,7 @@
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter string="Project" name="group_project_id" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/> <filter string="Project" name="group_project_id" icon="terp-folder-blue" domain="[]" context="{'group_by':'project_id'}"/>
<separator orientation="vertical"/> <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'}"/> <filter string="State" name="group_state" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter string="Start Date" icon="terp-go-month" domain="[]" context="{'group_by':'date_start'}"/> <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> </page>
</field> </field>
</record> </record>
<act_window domain="[('user_id', '=', active_id),('state', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', '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"/>
<!--- Messages--> <act_window domain="[('user_id', '=', active_id),('date', '&gt;=', 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"/>
<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','&gt;=',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', '&lt;&gt;', 'cancelled'),('state', '&lt;&gt;', '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', '&gt;=', 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"/>
</data> </data>
</openerp> </openerp>

View File

@ -1,15 +1,14 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" "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_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_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_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_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_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","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","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_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_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_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 "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_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_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_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_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_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 "access_project_task_work_system","project.task.work system","model_project_task_work","base.group_system",1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_project_project_manager project.project manager model_project_project project.group_project_manager 1 0 1 0 1 0 1
3 access_account_analytic_account_manager account.analytic.account analytic.model_account_analytic_account project.group_project_manager 1 0 0 0
4 access_project_project project.project model_project_project project.group_project_user 1 1 1 1
5 access_account_analytic_account account.analytic.account analytic.model_account_analytic_account project.group_project_user 1 1 1 1
6 access_project_task_type_user project.task.type user model_project_task_type project.group_project_user 1 1 1 1
7 access_project_task_type project.task.type model_project_task_type project.group_project_manager 1 1 1 1
8 access_project_task_manager project.task manager model_project_task project.group_project_manager 1 0 1 0 1 0 1
9 access_project_task project.task model_project_task project.group_project_user 1 1 1 1
10 access_project_task_work project.task.work model_project_task_work project.group_project_user 1 1 1 1
11 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
12 access_report_project_task_user report.project.task.user model_report_project_task_user project.group_project_manager 1 1 1 1
13 access_project_vs_hours project.vs.hours model_project_vs_hours project.group_project_user 1 1 1 1
14 access_task_by_days task.by.days model_task_by_days project.group_project_user 1 1 1 1
18 access_partner_address_task manager base.res.partner.address manager base.model_res_partner_address project.group_project_manager 1 0 0 0
19 access_task_on_partner project.task on partners model_project_task base.group_user 1 0 0 0
20 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
21 access_project_task_system project.task system model_project_task base.group_system 1 0 0 0
22 access_project_project_system project.project system model_project_project base.group_system 1 1 1 1
23 access_project_task_work_system project.task.work system model_project_task_work base.group_system 1 0 0 0

View File

@ -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 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 remaining_hours: 30.0
- | - |
I click the apply button 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}) 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 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 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 remaining_hours: 10.0
- -
Reevaluate the task 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", 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": "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": False, "search_default_user_id": 1, "search_default_current": 1, "active_ids":
@ -248,12 +248,12 @@
- -
Reactivate task 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 remaining_hours: 10.0
- -
Reevaluate the task with 10 hours remaining 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", self.compute_hours(cr, uid, [ref("config_compute_remaining_1")], {"lang": "en_US",
"project_id": False, "tz": False, "button_reactivate": True, "active_model": "project_id": False, "tz": False, "button_reactivate": True, "active_model":
"project.task", "search_default_project_id": False, "search_default_user_id": "project.task", "search_default_project_id": False, "search_default_user_id":

View File

@ -61,7 +61,7 @@
Validating the delegate task Validating the delegate task
- -
!python {model: project.task.delegate}: | !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": {"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"), 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 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}: !assert {model: project.task, id: project_task_documentation_book, severity: error, string: Task is in done state}:
- state == "open" - state == "open"

View File

@ -19,8 +19,9 @@
# #
############################################################################## ##############################################################################
import project_close_task import project_task_close
import project_task_delegate import project_task_delegate
import project_task_reevaluate
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -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:

View File

@ -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>

View File

@ -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:

View File

@ -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>

View File

@ -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") '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: if context is None:
context = {} context = {}
if 'active_id' in context: record_id = context and context.get('active_id', False) or False
task = self.pool.get('project.task').browse(cr, uid, context['active_id']) 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: ')): if task.name.startswith(_('CHECK: ')):
newname = str(task.name).replace(_('CHECK: '), '') newname = str(task.name).replace(_('CHECK: '), '')
else: else:
newname = task.name or '' newname = task.name or ''
return newname res.update({'name': newname})
return '' if 'planned_hours' in fields:
res.update({'planned_hours': task.remaining_hours or 0.0})
def _get_plan_hour(self, cr, uid, context=None): if 'prefix' in fields:
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'])
if task.name.startswith(_('CHECK: ')): if task.name.startswith(_('CHECK: ')):
newname = str(task.name).replace(_('CHECK: '), '') newname = str(task.name).replace(_('CHECK: '), '')
else: else:
newname = task.name or '' newname = task.name or ''
return _('CHECK: ') + newname prefix = _('CHECK: ') + newname
return '' 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 = { _defaults = {
'name': _get_name,
'planned_hours': _get_plan_hour,
'planned_hours_me': 1.0, 'planned_hours_me': 1.0,
'prefix': _get_prefix,
'new_task_description': _get_new_desc,
'state': 'pending', 'state': 'pending',
} }
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): 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) 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']: if tm in ['Hours','Hour']:
return res return res
eview = etree.fromstring(res['arch']) eview = etree.fromstring(res['arch'])
def _check_rec(eview): def _check_rec(eview):
if eview.attrib.get('widget','') == 'float_time': if eview.attrib.get('widget','') == 'float_time':
eview.set('widget','float') eview.set('widget','float')
@ -107,47 +94,19 @@ class project_task_delegate(osv.osv_memory):
return True return True
_check_rec(eview) _check_rec(eview)
res['arch'] = etree.tostring(eview) res['arch'] = etree.tostring(eview)
for field in res['fields']:
for f in res['fields']: if 'Hours' in res['fields'][field]['string']:
if 'Hours' in res['fields'][f]['string']: res['fields'][field]['string'] = res['fields'][field]['string'].replace('Hours',tm)
res['fields'][f]['string'] = res['fields'][f]['string'].replace('Hours',tm)
return res return res
def validate(self, cr, uid, ids, context=None): def delegate(self, cr, uid, ids, context=None):
if context is None: if context is None:
context = {} context = {}
task_obj = self.pool.get('project.task') task_id = context.get('active_id', False)
user_obj = self.pool.get('res.users') task_pool = self.pool.get('project.task')
delegate_data = self.read(cr, uid, ids, context=context)[0] delegate_data = self.read(cr, uid, ids, context=context)[0]
task = task_obj.browse(cr, uid, context['active_id'], context=context) task_pool.do_delegate(cr, uid, task_id, delegate_data, 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)
return {} return {}
project_task_delegate() project_task_delegate()

View File

@ -8,25 +8,25 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Project Task Delegate"> <form string="Project Task Delegate">
<separator string="Delegated Task" colspan="4"/> <group colspan="2" col="2">
<field name="user_id"/> <separator string="Delegated Task" colspan="4"/>
<newline/> <field name="user_id" colspan="4"/>
<field name="planned_hours" widget="float_time"/> <field name="planned_hours" widget="float_time" colspan="4"/>
<newline/> <field name="name" colspan="4"/>
<field name="name"/> <field name="new_task_description" colspan="4" />
<newline/> </group>
<field name="new_task_description"/> <group colspan="2" col="2">
<newline/> <separator string="Validation Task" colspan="4"/>
<separator string="Validation Task" colspan="4"/> <field name="planned_hours_me" widget="float_time" colspan="4"/>
<field name="planned_hours_me" widget="float_time"/> <field name="prefix" colspan="4"/>
<newline/> <field name="state" colspan="4"/>
<field name="prefix" /> </group>
<newline/> <separator string="" colspan="4"/>
<field name="state" /> <group colspan="2" col="2">
<newline/> </group>
<group colspan="4" col="6"> <group colspan="2" col="2">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/> <button icon="gtk-close" special="cancel" string="_Close"/>
<button icon="gtk-ok" name="validate" string="Approve" type="object"/> <button icon="gtk-ok" name="delegate" string="_Delegate" type="object"/>
</group> </group>
</form> </form>
</field> </field>

View File

@ -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()

View File

@ -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>

View File

@ -86,6 +86,7 @@
<field name="view_id" ref="board_project_issue_form"/> <field name="view_id" ref="board_project_issue_form"/>
</record> </record>
<menuitem id="menu_deshboard_project_issue" name="Project Issue Dashboard" parent="project.next_id_86" <menuitem id="menu_deshboard_project_issue" name="Project Issue Dashboard" parent="project.next_id_86"
icon="terp-graph"
action="open_board_project_issue"/> action="open_board_project_issue"/>
</data> </data>
</openerp> </openerp>

View File

@ -63,10 +63,10 @@
<separator colspan="4"/> <separator colspan="4"/>
<group col="8" colspan="4"> <group col="8" colspan="4">
<field name="state" /> <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_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_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_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"/> <button name="case_reset" string="Reset to Draft" states="done,cancel" type="object" icon="gtk-convert"/>
</group> </group>

View File

@ -27,14 +27,14 @@
"category": "Generic Modules/Projects & Services", "category": "Generic Modules/Projects & Services",
"depends": ["resource", "project"], "depends": ["resource", "project"],
"description": """ "description": """
Long Term Project management module that tracks planning, scheduling, resources allocation.
Long Term Project management module that tracks planning, scheduling, resources allocation. Features.
Mainly used with Big project management. - Manage Big project.
- Project Phases will be maintained by Manager of the 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. - 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 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 - 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 - Schedule Tasks: All the tasks which are in draft,pending and open state are scheduled with taking the phase's start date
""", """,
"init_xml": [], "init_xml": [],

View File

@ -72,9 +72,9 @@
<field name="name">Resource Allocations</field> <field name="name">Resource Allocations</field>
<field name="res_model">project.resource.allocation</field> <field name="res_model">project.resource.allocation</field>
<field name="view_type">form</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="context">{}</field>
<!--<field name="search_view_id" ref="view_project_phase_search"/>--> <field name="search_view_id" ref="view_project_resource_allocation_search"/>
</record> </record>
@ -254,7 +254,7 @@
<field name="name">Project Phases</field> <field name="name">Project Phases</field>
<field name="res_model">project.phase</field> <field name="res_model">project.phase</field>
<field name="view_type">form</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="context">{'search_default_responsible_id':uid}</field>
<field name="search_view_id" ref="view_project_phase_search"/> <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> <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" <menuitem action="act_project_phase"
groups="base.group_extended" 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" <menuitem id="menu_resouce_allocation" action="act_resouce_allocation"
name="Resource Allocations" parent="base.menu_project_long_term" sequence="2"/> name="Resource Allocations" parent="base.menu_project_long_term" sequence="2"/>
<menuitem id="menu_pm_resources_project1" <menuitem id="menu_pm_resources_project1"
groups="base.group_extended" groups="base.group_extended"
name="Resources" parent="project.menu_definitions" sequence="3"/> 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"/> <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"/>

View File

@ -8,20 +8,16 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Compute Scheduling of Phases"> <form string="Compute Scheduling of Phases">
<group width="380" height="180"> <group colspan="4" col="4">
<group colspan="4" col="4"> <separator colspan="4" string="Compute Scheduling of phases for all or specified project" />
<label colspan="4" string="This wizard will schedule phases for all or specified project" /> <field name="target_project" colspan="4"/>
<newline /> <field name="project_id" widget="selection" colspan="4" attrs="{'invisible':[('target_project','=','all')], 'required':[('target_project','!=','all')]}"/>
<field name="target_project" colspan="4"/>
</group>
<newline />
<group colspan="4" col="6" attrs="{'invisible':[('target_project','=','all')]}">
<field name="project_id"/>
</group>
<separator colspan="4"/> <separator colspan="4"/>
<group colspan="4" col="6"> <!-- Improve me --> <group colspan="2" col="2">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/> </group>
<button icon="gtk-ok" name="check_selection" string="_Compute" type="object"/> <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>
</group> </group>
</form> </form>

View File

@ -7,12 +7,16 @@
<field name="model">project.compute.tasks</field> <field name="model">project.compute.tasks</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Compute Scheduling of Phases"> <form string="Compute Scheduling of Task">
<group colspan="4" height="100" width="500"> <group colspan="4">
<field name="project_id"/> <separator colspan="4" string="Compute Scheduling of Task for specified project." />
<group colspan="4" col="6"> <field name="project_id" widget="selection" colspan="4"/>
<button icon="gtk-cancel" special="cancel" string="_Cancel"/> <separator colspan="4"/>
<button icon="gtk-ok" name="compute_date" string="Compute" type="object"/> <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>
</group> </group>
</form> </form>

View File

@ -55,9 +55,7 @@ class project_with_message(osv.osv):
_inherit = 'project.project' _inherit = 'project.project'
_columns = { _columns = {
'message_ids':fields.one2many( 'message_ids':fields.one2many('project.messages', 'project_id', 'Messages'),
'project.messages', 'project_id', 'Messages',
),
} }
project_with_message() project_with_message()

View File

@ -90,8 +90,20 @@
<field name="search_view_id" ref="view_project_messages_search"/> <field name="search_view_id" ref="view_project_messages_search"/>
<field name="context">{"search_default_to_id":uid}</field> <field name="context">{"search_default_to_id":uid}</field>
<field name="view_id" ref="view_project_message_tree"/> <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> </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"/> <menuitem action="messages_form" id="menu_messages_form" parent="project.menu_project_management"/>
</data> </data>
</openerp> </openerp>

View File

@ -58,6 +58,7 @@
<menuitem <menuitem
id="menu_deshboard_scurm" id="menu_deshboard_scurm"
name="Scrum Dashboard" parent="project.next_id_86" name="Scrum Dashboard" parent="project.next_id_86"
icon="terp-graph"
action="open_board_project_scrum"/> action="open_board_project_scrum"/>
</data> </data>
</openerp> </openerp>

View File

@ -45,49 +45,29 @@ class project_scrum_sprint(osv.osv):
_name = 'project.scrum.sprint' _name = 'project.scrum.sprint'
_description = 'Project Scrum Sprint' _description = 'Project Scrum Sprint'
def _calc_progress(self, cr, uid, ids, name, args, context=None): def _compute(self, cr, uid, ids, fields, arg, context=None):
res = {} res = {}.fromkeys(ids, 0.0)
progress = {}
if not ids:
return res
if context is None: if context is None:
context = {} context = {}
for sprint in self.browse(cr, uid, ids): for sprint in self.browse(cr, uid, ids, context=context):
tot = 0.0 tot = 0.0
prog = 0.0 prog = 0.0
effective = 0.0
progress = 0.0
for bl in sprint.backlog_ids: for bl in sprint.backlog_ids:
tot += bl.expected_hours tot += bl.expected_hours
effective += bl.effective_hours
prog += bl.expected_hours * bl.progress / 100.0 prog += bl.expected_hours * bl.progress / 100.0
res.setdefault(sprint.id, 0.0)
if tot>0: if tot>0:
res[sprint.id] = round(prog/tot*100) progress = round(prog/tot*100)
return res res[sprint.id] = {
'progress' : progress,
def _calc_effective(self, cr, uid, ids, name, args, context=None): 'expected_hours' : tot,
res = {} 'effective_hours': effective,
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
return res return res
def button_cancel(self, cr, uid, ids, context=None): def button_cancel(self, cr, uid, ids, context=None):
@ -137,9 +117,9 @@ class project_scrum_sprint(osv.osv):
'review': fields.text('Sprint Review'), 'review': fields.text('Sprint Review'),
'retrospective': fields.text('Sprint Retrospective'), 'retrospective': fields.text('Sprint Retrospective'),
'backlog_ids': fields.one2many('project.scrum.product.backlog', 'sprint_id', 'Sprint Backlog'), '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."), '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(_calc_effective, method=True, string='Effective hours', help="Computed using the sum of the task work done."), '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(_calc_expected, method=True, string='Planned Hours', help='Estimated time to do the task.'), '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), 'state': fields.selection([('draft','Draft'),('open','Open'),('pending','Pending'),('cancel','Cancelled'),('done','Done')], 'State', required=True),
} }
_defaults = { _defaults = {
@ -188,39 +168,31 @@ class project_scrum_product_backlog(osv.osv):
return self.name_get(cr, uid, ids, context=context) 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) 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): def _compute(self, cr, uid, ids, fields, arg, context=None):
res = {} res = {}.fromkeys(ids, 0.0)
progress = {}
if not ids:
return res
if context is None: if context is None:
context = {} context = {}
for bl in self.browse(cr, uid, ids): for backlog in self.browse(cr, uid, ids, context=context):
tot = 0.0 tot = 0.0
prog = 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 tot += task.planned_hours
prog += task.planned_hours * task.progress / 100.0 prog += task.planned_hours * task.progress / 100.0
res.setdefault(bl.id, 0.0)
if tot>0: if tot>0:
res[bl.id] = round(prog/tot*100) progress = round(prog/tot*100)
return res res[backlog.id] = {
'progress' : progress,
def _calc_effective(self, cr, uid, ids, name, args, context=None): 'effective_hours': effective,
res = {} 'task_hours' : task_hours
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
return res return res
def button_cancel(self, cr, uid, ids, context=None): 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."), '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'), '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), '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."), '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(_calc_effective, method=True, string='Spent Hours', help="Computed using the sum of the time spent on every related tasks"), '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'), 'expected_hours': fields.float('Planned Hours', help='Estimated total time to do the Backlog'),
'create_date': fields.datetime("Creation Date", readonly=True), '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 = { _defaults = {
'state': 'draft', 'state': 'draft',

View File

@ -24,7 +24,7 @@ class backlog_create_task(osv.osv_memory):
_name = 'project.scrum.backlog.create.task' _name = 'project.scrum.backlog.create.task'
_description = 'Create Tasks from Product Backlogs' _description = 'Create Tasks from Product Backlogs'
_columns = { _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): def do_create(self, cr, uid, ids, context=None):

View File

@ -7,21 +7,22 @@
<field name="model">project.scrum.backlog.create.task</field> <field name="model">project.scrum.backlog.create.task</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Create Tasks"> <form string="Convert into Tasks">
<group col="4" colspan="6"> <separator string="Convert into Tasks" colspan="4"/>
<field name="user_id"/> <field name="user_id"/>
</group>
<separator colspan="4"/> <separator colspan="4"/>
<group col="2" colspan="4"> <group col="2" colspan="2">
<button special="cancel" string="Cancel" icon='gtk-cancel'/> </group>
<button name="do_create" string="Create Tasks" colspan="1" type="object" icon="gtk-execute"/> <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> </group>
</form> </form>
</field> </field>
</record> </record>
<record id="action_scrum_backlog_to_task" model="ir.actions.act_window"> <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="type">ir.actions.act_window</field>
<field name="res_model">project.scrum.backlog.create.task</field> <field name="res_model">project.scrum.backlog.create.task</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -32,7 +33,7 @@
<record model="ir.values" id="scrum_backlog_to_task_values"> <record model="ir.values" id="scrum_backlog_to_task_values">
<field name="model_id" ref="model_project_scrum_product_backlog" /> <field name="model_id" ref="model_project_scrum_product_backlog" />
<field name="object" eval="1" /> <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="key2">client_action_multi</field>
<field name="value" eval="'ir.actions.act_window,' + str(ref('action_scrum_backlog_to_task'))" /> <field name="value" eval="'ir.actions.act_window,' + str(ref('action_scrum_backlog_to_task'))" />
<field name="key">action</field> <field name="key">action</field>

View File

@ -10,7 +10,7 @@
<separator string="Are you sure you want to merge these Backlogs?" colspan="4"/> <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" /> <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"/> <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"/> <button colspan="2" default_focus="1" name="check_backlogs" string="Merge" type="object" icon="gtk-execute"/>
</form> </form>
</field> </field>

View File

@ -25,8 +25,8 @@ class backlog_sprint_assign(osv.osv_memory):
_name = 'project.scrum.backlog.assign.sprint' _name = 'project.scrum.backlog.assign.sprint'
_description = 'Assign sprint to backlogs' _description = 'Assign sprint to backlogs'
_columns = { _columns = {
'sprint_id': fields.many2one('project.scrum.sprint', 'Sprint Name', required=True), 'sprint_id': fields.many2one('project.scrum.sprint', 'Sprint', required=True, help="Select Sprint to assign backlog."),
'state_open': fields.boolean('Set Open', help="Change the state of product backlogs to open if its in draft state"), '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") 'convert_to_task': fields.boolean('Convert To Task', help="Create Task for Product Backlog")
} }
_defaults = { _defaults = {

View File

@ -8,20 +8,16 @@
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Assign Sprint"> <form string="Assign Sprint">
<group col="4" colspan="6"> <separator string="Assign Sprint" colspan="4"/>
<field name="sprint_id" colspan="2"/> <field name="sprint_id" colspan="4"/>
</group> <field name="state_open" />
<newline/> <field name="convert_to_task"/>
<separator colspan="2"/>
<newline/>
<group>
<field name="state_open" colspan="1"/>
<field name="convert_to_task" colspan="1"/>
</group>
<separator colspan="4"/> <separator colspan="4"/>
<group col="2" colspan="4"> <group col="2" colspan="2">
<button special="cancel" string="Cancel" icon='gtk-cancel'/> </group>
<button name="assign_sprint" string="Assign Sprint" colspan="1" type="object" icon="gtk-execute"/> <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> </group>
</form> </form>
</field> </field>
@ -47,4 +43,4 @@
</record> </record>
</data> </data>
</openerp> </openerp>

View File

@ -20,5 +20,6 @@
import purchase_requisition import purchase_requisition
import wizard import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -32,7 +32,9 @@
"init_xml" : [], "init_xml" : [],
"demo_xml" : [], "demo_xml" : [],
"update_xml" : ["wizard/purchase_requisition_partner_view.xml", "update_xml" : ["wizard/purchase_requisition_partner_view.xml",
"purchase_requisition_data.xml",
"purchase_requisition_view.xml", "purchase_requisition_view.xml",
"purchase_requisition_report.xml",
"security/ir.model.access.csv","purchase_requisition_sequence.xml" "security/ir.model.access.csv","purchase_requisition_sequence.xml"
], ],
"active": False, "active": False,

View File

@ -40,6 +40,7 @@ class purchase_requisition(osv.osv):
'company_id': fields.many2one('res.company', 'Company', required=True), 'company_id': fields.many2one('res.company', 'Company', required=True),
'purchase_ids' : fields.one2many('purchase.order','requisition_id','Purchase Orders',states={'done': [('readonly', 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)]}), '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) 'state': fields.selection([('draft','Draft'),('in_progress','In Progress'),('cancel','Cancelled'),('done','Done')], 'State', required=True)
} }
_defaults = { _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'), '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): def tender_cancel(self, cr, uid, ids, context=None):
purchase_order_obj = self.pool.get('purchase.order') purchase_order_obj = self.pool.get('purchase.order')
for purchase in self.browse(cr, uid, ids): for purchase in self.browse(cr, uid, ids):
@ -64,9 +74,6 @@ class purchase_requisition(osv.osv):
return True return True
def tender_in_progress(self, cr, uid, ids, context=None): 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) self.write(cr, uid, ids, {'state':'in_progress'} ,context=context)
for (id,name) in self.name_get(cr, uid, ids): for (id,name) in self.name_get(cr, uid, ids):
message = _('Tender') + " '" + name + "' "+ _(" is In Progress") message = _('Tender') + " '" + name + "' "+ _(" is In Progress")
@ -172,6 +179,8 @@ class procurement_order(osv.osv):
'name': sequence_obj.get(cr, uid, 'purchase.order.requisition'), 'name': sequence_obj.get(cr, uid, 'purchase.order.requisition'),
'origin': procurement.name, 'origin': procurement.name,
'date_end': procurement.date_planned, '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,{ 'line_ids': [(0,0,{
'product_id': procurement.product_id.id, 'product_id': procurement.product_id.id,
'product_uom_id': procurement.product_uom.id, 'product_uom_id': procurement.product_uom.id,

View File

@ -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>

View File

@ -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>

View File

@ -2,17 +2,6 @@
<openerp> <openerp>
<data> <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"> <record model="ir.ui.view" id="purchase_order_form_inherit">
<field name="name">purchase.order.form.inherit</field> <field name="name">purchase.order.form.inherit</field>
@ -20,12 +9,23 @@
<field name="model">purchase.order</field> <field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/> <field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml"> <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 name="requisition_id" groups="base.group_extended"/>
</field> </field>
</field> </field>
</record> </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"> <record model="ir.ui.view" id="view_purchase_requisition_form">
<field name="name">purchase.requisition.form</field> <field name="name">purchase.requisition.form</field>
<field name="type">form</field> <field name="type">form</field>
@ -39,6 +39,7 @@
<field name="date_start"/> <field name="date_start"/>
<field name="date_end"/> <field name="date_end"/>
<field name="origin"/> <field name="origin"/>
<field name="warehouse_id" groups="base.group_extended" widget="selection"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"/> <field name="company_id" groups="base.group_multi_company" widget="selection"/>
</group> </group>
<notebook colspan="4"> <notebook colspan="4">
@ -77,12 +78,15 @@
<field name="minimum_planned_date"/> <field name="minimum_planned_date"/>
<field name="origin"/> <field name="origin"/>
<field name="state"/> <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> </tree>
</field> </field>
<separator colspan="4" string=""/> <separator colspan="4" string=""/>
<group col="8" colspan="4"> <group col="8" colspan="4">
<label colspan="6" string=""/> <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')]}" /> attrs="{'readonly': [('state', '=', 'done')]}" />
</group> </group>
</page> </page>
@ -123,6 +127,7 @@
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="name"/> <field name="name"/>
<field name="user_id" /> <field name="user_id" />
<filter icon="terp-personal-" string="Unassigned" domain="[('user_id','=', False)]" help="Unassigned Requisition"/>
<field name="exclusive" /> <field name="exclusive" />
</group> </group>
<newline/> <newline/>
@ -181,5 +186,12 @@
</xpath> </xpath>
</field> </field>
</record> </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> </data>
</openerp> </openerp>

View File

@ -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:

View File

@ -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>

View File

@ -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:

View File

@ -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 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] 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) 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= { purchase_order_line= {
'name': product.partner_ref, 'name': product.partner_ref,
@ -118,6 +118,10 @@ class purchase_requisition_partner(osv.osv_memory):
'company_id': tender.company_id.id, 'company_id': tender.company_id.id,
'fiscal_position': partner.property_account_position and partner.property_account_position.id or False, 'fiscal_position': partner.property_account_position and partner.property_account_position.id or False,
'requisition_id':tender.id, '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=[] order_ids=[]
for order_line in list_line: for order_line in list_line:

View File

@ -12,7 +12,7 @@
<separator string="" colspan="4" /> <separator string="" colspan="4" />
<group colspan="4" col="6"> <group colspan="4" col="6">
<button icon="gtk-cancel" special="cancel" string="_Cancel"/> <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> </group>
</form> </form>
</field> </field>