2010-02-10 09:54:34 +00:00
# -*- 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/>.
#
##############################################################################
2010-02-02 13:47:02 +00:00
import time
import mx . DateTime
2010-02-04 07:26:45 +00:00
import re
2010-02-02 13:47:02 +00:00
2010-02-03 10:28:09 +00:00
import tools
2010-02-02 13:47:02 +00:00
from osv import fields , osv , orm
from osv . orm import except_orm
2010-02-08 10:34:14 +00:00
from tools . translate import _
2010-02-02 13:47:02 +00:00
class base_action_rule ( osv . osv ) :
_name = ' base.action.rule '
2010-02-15 14:42:24 +00:00
_description = ' Action Rules '
2010-02-08 10:34:14 +00:00
2010-02-02 13:47:02 +00:00
_columns = {
2010-02-15 14:42:24 +00:00
' name ' : fields . many2one ( ' ir.model ' , ' Model ' , required = True ) ,
' max_level ' : fields . integer ( ' Max Level ' , help = ' Specifies maximum level. ' ) ,
' rule_lines ' : fields . one2many ( ' base.action.rule.line ' , ' rule_id ' , ' Rule Lines ' ) ,
2010-02-08 10:34:14 +00:00
' create_date ' : fields . datetime ( ' Create Date ' , readonly = 1 ) ,
2010-02-15 14:42:24 +00:00
' active ' : fields . boolean ( ' Active ' )
2010-02-08 10:34:14 +00:00
}
_defaults = {
2010-02-15 14:42:24 +00:00
' active ' : lambda * a : True ,
' max_level ' : lambda * a : 15 ,
2010-02-02 13:47:02 +00:00
}
2010-02-08 10:34:14 +00:00
2010-02-15 14:42:24 +00:00
def format_body ( self , body ) :
return body and tools . ustr ( body ) or ' '
def format_mail ( self , obj , body ) :
data = {
' object_id ' : obj . id ,
' object_subject ' : hasattr ( obj , ' name ' ) and obj . name or False ,
' object_date ' : hasattr ( obj , ' date ' ) and obj . date or False ,
' object_description ' : hasattr ( obj , ' description ' ) and obj . description or False ,
' object_user ' : hasattr ( obj , ' user_id ' ) and ( obj . user_id and obj . user_id . name ) or ' / ' ,
' object_user_email ' : hasattr ( obj , ' user_id ' ) and ( obj . user_id and obj . user_id . address_id and obj . user_id . address_id . email ) or ' / ' ,
' object_user_phone ' : hasattr ( obj , ' user_id ' ) and ( obj . user_id and obj . user_id . address_id and obj . user_id . address_id . phone ) or ' / ' ,
' partner ' : hasattr ( obj , ' partner_id ' ) and ( obj . partner_id and obj . partner_id . name ) or ' / ' ,
' partner_email ' : hasattr ( obj , ' partner_address_id ' ) and ( obj . partner_address_id and obj . partner_address_id . email ) or ' / ' ,
}
2010-02-17 13:40:45 +00:00
return self . format_body ( body % data )
2010-02-15 14:42:24 +00:00
def email_send ( self , cr , uid , obj , emails , body , emailfrom = tools . config . get ( ' email_from ' , False ) , context = { } ) :
body = self . format_mail ( obj , body )
if not emailfrom :
if hasattr ( obj , ' user_id ' ) and obj . user_id and obj . user_id . address_id and obj . user_id . address_id . email :
emailfrom = obj . user_id . address_id . email
name = ' [ %d ] %s ' % ( obj . id , tools . ustr ( obj . name ) )
emailfrom = tools . ustr ( emailfrom )
reply_to = emailfrom
if not emailfrom :
raise osv . except_osv ( _ ( ' Error! ' ) ,
_ ( " No E-Mail ID Found for your Company address! " ) )
return tools . email_send ( emailfrom , emails , name , body , reply_to = reply_to , openobject_id = str ( obj . id ) )
2010-02-08 10:34:14 +00:00
2010-02-15 14:42:24 +00:00
def do_check ( self , cr , uid , action , obj , context = { } ) :
ok = True
if hasattr ( obj , ' user_id ' ) :
ok = ok and ( not action . trg_user_id . id or action . trg_user_id . id == obj . user_id . id )
if hasattr ( obj , ' partner_id ' ) :
ok = ok and ( not action . trg_partner_id . id or action . trg_partner_id . id == obj . partner_id . id )
ok = ok and (
not action . trg_partner_categ_id . id or
(
obj . partner_id . id and
( action . trg_partner_categ_id . id in map ( lambda x : x . id , obj . partner_id . category_id or [ ] ) )
)
)
state_to = context . get ( ' state_to ' , False )
if hasattr ( obj , ' state ' ) :
ok = ok and ( not action . trg_state_from or action . trg_state_from == obj . state )
if state_to :
ok = ok and ( not action . trg_state_to or action . trg_state_to == state_to )
if hasattr ( obj , ' priority ' ) :
ok = ok and ( not action . trg_priority_from or action . trg_priority_from > = obj . priority )
ok = ok and ( not action . trg_priority_to or action . trg_priority_to < = obj . priority )
reg_name = action . regex_name
result_name = True
if reg_name :
ptrn = re . compile ( str ( reg_name ) )
_result = ptrn . search ( str ( obj . name ) )
if not _result :
result_name = False
regex_n = not reg_name or result_name
ok = ok and regex_n
return ok
def do_action ( self , cr , uid , action , model_obj , obj , context = { } ) :
if action . server_action_id :
context . update ( { ' active_id ' : obj . id , ' active_ids ' : [ obj . id ] } )
self . pool . get ( ' ir.actions.server ' ) . run ( cr , uid , [ action . server_action_id . id ] , context )
write = { }
if hasattr ( obj , ' user_id ' ) and action . act_user_id :
obj . user_id = action . act_user_id
write [ ' user_id ' ] = action . act_user_id . id
if hasattr ( obj , ' date_action_last ' ) :
write [ ' date_action_last ' ] = time . strftime ( ' % Y- % m- %d % H: % M: % S ' )
if hasattr ( obj , ' state ' ) and action . act_state :
obj . state = action . act_state
write [ ' state ' ] = action . act_state
2010-03-03 05:57:06 +00:00
if hasattr ( obj , ' categ_id ' ) and action . act_categ_id :
obj . categ_id = action . act_categ_id
write [ ' categ_id ' ] = action . act_categ_id . id
2010-02-15 14:42:24 +00:00
if hasattr ( obj , ' priority ' ) and action . act_priority :
obj . priority = action . act_priority
write [ ' priority ' ] = action . act_priority
model_obj . write ( cr , uid , [ obj . id ] , write , context )
if hasattr ( model_obj , ' remind_user ' ) and action . act_remind_user :
model_obj . remind_user ( cr , uid , [ obj . id ] , context , attach = action . act_remind_attach )
if hasattr ( model_obj , ' remind_partner ' ) and action . act_remind_partner :
model_obj . remind_partner ( cr , uid , [ obj . id ] , context , attach = action . act_remind_attach )
if action . act_method :
getattr ( model_obj , ' act_method ' ) ( cr , uid , [ obj . id ] , action , context )
emails = [ ]
if hasattr ( obj , ' user_id ' ) and action . act_mail_to_user :
if obj . user_id and obj . user_id . address_id :
emails . append ( obj . user_id . address_id . email )
if action . act_mail_to_watchers :
emails + = ( action . act_email_cc or ' ' ) . split ( ' , ' )
if action . act_mail_to_email :
emails + = ( action . act_mail_to_email or ' ' ) . split ( ' , ' )
emails = filter ( None , emails )
if len ( emails ) and action . act_mail_body :
emails = list ( set ( emails ) )
self . email_send ( cr , uid , obj , emails , action . act_mail_body )
2010-02-08 10:34:14 +00:00
return True
2010-02-15 14:42:24 +00:00
def _action ( self , cr , uid , ids , objects , scrit = None , context = { } ) :
2010-02-02 13:47:02 +00:00
if not scrit :
scrit = [ ]
2010-02-15 14:42:24 +00:00
rule_line_obj = self . pool . get ( ' base.action.rule.line ' )
for rule in self . browse ( cr , uid , ids ) :
level = rule . max_level
if not level :
break
newactions = [ ]
scrit + = [ ( ' rule_id ' , ' = ' , rule . id ) ]
line_ids = rule_line_obj . search ( cr , uid , scrit )
actions = rule_line_obj . browse ( cr , uid , line_ids , context = context )
model_obj = self . pool . get ( rule . name . model )
for obj in objects :
for action in actions :
ok = self . do_check ( cr , uid , action , obj , context = context )
2010-02-03 10:28:09 +00:00
if not ok :
continue
2010-02-15 14:42:24 +00:00
2010-02-03 10:28:09 +00:00
base = False
2010-02-15 14:42:24 +00:00
if hasattr ( obj , ' create_date ' ) and action . trg_date_type == ' create ' :
base = mx . DateTime . strptime ( obj . create_date [ : 19 ] , ' % Y- % m- %d % H: % M: % S ' )
elif hasattr ( obj , ' create_date ' ) and action . trg_date_type == ' action_last ' :
if hasattr ( obj , ' date_action_last ' ) and obj . date_action_last :
base = mx . DateTime . strptime ( obj . date_action_last , ' % Y- % m- %d % H: % M: % S ' )
else :
base = mx . DateTime . strptime ( obj . create_date [ : 19 ] , ' % Y- % m- %d % H: % M: % S ' )
elif hasattr ( obj , ' date_deadline ' ) and action . trg_date_type == ' deadline ' and obj . date_deadline :
base = mx . DateTime . strptime ( obj . date_deadline , ' % Y- % m- %d % H: % M: % S ' )
elif hasattr ( obj , ' date ' ) and action . trg_date_type == ' date ' and obj . date :
base = mx . DateTime . strptime ( obj . date , ' % Y- % m- %d % H: % M: % S ' )
2010-02-03 10:28:09 +00:00
if base :
fnct = {
' minutes ' : lambda interval : mx . DateTime . RelativeDateTime ( minutes = interval ) ,
' day ' : lambda interval : mx . DateTime . RelativeDateTime ( days = interval ) ,
' hour ' : lambda interval : mx . DateTime . RelativeDateTime ( hours = interval ) ,
' month ' : lambda interval : mx . DateTime . RelativeDateTime ( months = interval ) ,
}
d = base + fnct [ action . trg_date_range_type ] ( action . trg_date_range )
dt = d . strftime ( ' % Y- % m- %d % H: % M: % S ' )
2010-02-15 14:42:24 +00:00
ok = False
if hasattr ( obj , ' date_action_last ' ) and hasattr ( obj , ' date_action_next ' ) :
2010-02-03 10:28:09 +00:00
ok = ( dt < = time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ) and \
2010-02-15 14:42:24 +00:00
( ( not obj . date_action_next ) or \
( dt > = obj . date_action_next and \
obj . date_action_last < obj . date_action_next ) )
2010-02-03 10:28:09 +00:00
if not ok :
2010-02-15 14:42:24 +00:00
if not obj . date_action_next or dt < obj . date_action_next :
obj . date_action_next = dt
model_obj . write ( cr , uid , [ obj . id ] , { ' date_action_next ' : dt } , context )
2010-02-03 10:28:09 +00:00
else :
ok = action . trg_date_type == ' none '
if ok :
2010-02-15 14:42:24 +00:00
self . do_action ( cr , uid , action , model_obj , obj , context )
break
level - = 1
2010-02-02 13:47:02 +00:00
return True
base_action_rule ( )
class base_action_rule_line ( osv . osv ) :
_name = ' base.action.rule.line '
_description = ' Action Rule Lines '
2010-02-15 14:42:24 +00:00
def _state_get ( self , cr , uid , context = { } ) :
return self . state_get ( cr , uid , context = context )
def _priority_get ( self , cr , uid , context = { } ) :
return self . priority_get ( cr , uid , context = context )
def state_get ( self , cr , uid , context = { } ) :
return [ ( ' ' , ' ' ) ]
def priority_get ( self , cr , uid , context = { } ) :
return [ ( ' ' , ' ' ) ]
2010-02-02 13:47:02 +00:00
_columns = {
' name ' : fields . char ( ' Rule Name ' , size = 64 , required = True ) ,
' rule_id ' : fields . many2one ( ' base.action.rule ' , ' Rule ' ) ,
2010-02-15 14:42:24 +00:00
' active ' : fields . boolean ( ' Active ' , help = " If the active field is set to true, it will allow you to hide the rule without removing it. " ) ,
' sequence ' : fields . integer ( ' Sequence ' , help = " Gives the sequence order when displaying a list of rules. " ) ,
2010-02-02 13:47:02 +00:00
' trg_date_type ' : fields . selection ( [
( ' none ' , ' None ' ) ,
( ' create ' , ' Creation Date ' ) ,
( ' action_last ' , ' Last Action Date ' ) ,
( ' date ' , ' Date ' ) ,
] , ' Trigger Date ' , size = 16 ) ,
' trg_date_range ' : fields . integer ( ' Delay after trigger date ' , help = " Delay After Trigger Date, specifies you can put a negative number " \
" if you need a delay before the trigger date, like sending a reminder 15 minutes before a meeting. " ) ,
' trg_date_range_type ' : fields . selection ( [ ( ' minutes ' , ' Minutes ' ) , ( ' hour ' , ' Hours ' ) , ( ' day ' , ' Days ' ) , ( ' month ' , ' Months ' ) ] , ' Delay type ' ) ,
' trg_user_id ' : fields . many2one ( ' res.users ' , ' Responsible ' ) ,
' trg_partner_id ' : fields . many2one ( ' res.partner ' , ' Partner ' ) ,
' trg_partner_categ_id ' : fields . many2one ( ' res.partner.category ' , ' Partner Category ' ) ,
2010-02-15 14:42:24 +00:00
' trg_state_from ' : fields . selection ( _state_get , ' State ' , size = 16 ) ,
' trg_state_to ' : fields . selection ( _state_get , ' Button Pressed ' , size = 16 ) ,
' trg_priority_from ' : fields . selection ( _priority_get , ' Minimum Priority ' ) ,
' trg_priority_to ' : fields . selection ( _priority_get , ' Maximum Priority ' ) ,
' act_method ' : fields . char ( ' Call Object Method ' , size = 64 ) ,
' act_user_id ' : fields . many2one ( ' res.users ' , ' Set responsible to ' ) ,
' act_state ' : fields . selection ( _state_get , ' Set state to ' , size = 16 ) ,
' act_priority ' : fields . selection ( _priority_get , ' Set priority to ' ) ,
2010-02-02 13:47:02 +00:00
' act_email_cc ' : fields . char ( ' Add watchers (Cc) ' , size = 250 , help = " These people will receive a copy of the future communication between partner and users by email " ) ,
' act_remind_partner ' : fields . boolean ( ' Remind Partner ' , help = " Check this if you want the rule to send a reminder by email to the partner. " ) ,
' act_remind_user ' : fields . boolean ( ' Remind responsible ' , help = " Check this if you want the rule to send a reminder by email to the user. " ) ,
2010-02-08 10:34:14 +00:00
' act_reply_to ' : fields . char ( ' Reply-To ' , size = 64 ) ,
2010-02-15 14:42:24 +00:00
' act_remind_attach ' : fields . boolean ( ' Remind with attachment ' , help = " Check this if you want that all documents attached to the object be attached to the reminder email sent. " ) ,
2010-02-02 13:47:02 +00:00
2010-02-15 14:42:24 +00:00
' act_mail_to_user ' : fields . boolean ( ' Mail to responsible ' , help = " Check this if you want the rule to send an email to the responsible person. " ) ,
2010-02-02 13:47:02 +00:00
' act_mail_to_watchers ' : fields . boolean ( ' Mail to watchers (CC) ' , help = " Check this if you want the rule to mark CC(mail to any other person defined in actions). " ) ,
' act_mail_to_email ' : fields . char ( ' Mail to these emails ' , size = 128 , help = " Email-id of the persons whom mail is to be sent " ) ,
' act_mail_body ' : fields . text ( ' Mail body ' , help = " Content of mail " ) ,
2010-02-03 10:28:09 +00:00
' regex_name ' : fields . char ( ' Regular Expression on Model Name ' , size = 128 ) ,
2010-02-02 13:47:02 +00:00
' server_action_id ' : fields . many2one ( ' ir.actions.server ' , ' Server Action ' , help = " Describes the action name. " \
2010-02-03 10:28:09 +00:00
" eg:on which object which action to be taken on basis of which condition " ) ,
2010-02-02 13:47:02 +00:00
}
_defaults = {
' active ' : lambda * a : 1 ,
' trg_date_type ' : lambda * a : ' none ' ,
' trg_date_range_type ' : lambda * a : ' day ' ,
' act_mail_to_user ' : lambda * a : 0 ,
' act_remind_partner ' : lambda * a : 0 ,
2010-02-15 14:42:24 +00:00
' act_remind_user ' : lambda * a : 0 ,
2010-02-02 13:47:02 +00:00
' act_mail_to_watchers ' : lambda * a : 0 ,
}
2010-02-15 14:42:24 +00:00
_order = ' sequence '
2010-02-02 13:47:02 +00:00
2010-02-03 10:28:09 +00:00
2010-02-02 13:47:02 +00:00
def _check_mail ( self , cr , uid , ids , context = None ) :
2010-02-15 14:42:24 +00:00
empty = orm . browse_null ( )
rule_obj = self . pool . get ( ' base.action.rule ' )
2010-02-02 13:47:02 +00:00
for rule in self . browse ( cr , uid , ids ) :
if rule . act_mail_body :
try :
2010-02-15 14:42:24 +00:00
rule_obj . format_mail ( empty , rule . act_mail_body )
2010-02-02 13:47:02 +00:00
except ( ValueError , KeyError , TypeError ) :
return False
return True
_constraints = [
( _check_mail , ' Error: The mail is not well formated ' , [ ' act_mail_body ' ] ) ,
]
base_action_rule_line ( )
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: