diff --git a/product/CMFActivity/ActiveObject.py b/product/CMFActivity/ActiveObject.py index 171834b4482ae574fdfc3312c16516b04e2b4db6..1b9e90ecf1eefabc40e627847f9e32fba0f11ece 100755 --- a/product/CMFActivity/ActiveObject.py +++ b/product/CMFActivity/ActiveObject.py @@ -76,6 +76,10 @@ class ActiveObject(ExtensionClass.Base): # a queue can be provided as well as extra parameters # which can be used for example to define deferred tasks try: + # This volatile variable '_v_activate_kw' can be used to pass parameters + # automatically to activate. + if hasattr(self, '_v_activate_kw'): + kw.update(self._v_activate_kw) return activity_tool.activate(self, activity, active_process, **kw) except ConflictError: raise diff --git a/product/CMFActivity/Activity/SQLDict.py b/product/CMFActivity/Activity/SQLDict.py index 42c0d1eb8db6cf9eb3b9caee10c3b87541c5dce1..e7dd61ccaa0735482bb1082b5943466351df7c21 100755 --- a/product/CMFActivity/Activity/SQLDict.py +++ b/product/CMFActivity/Activity/SQLDict.py @@ -69,7 +69,8 @@ class SQLDict(RAMDict): broadcast = m.activity_kw.get('broadcast', 0), message = self.dumpMessage(m), date = m.activity_kw.get('at_date', DateTime()), - group_method_id = m.activity_kw.get('group_method_id', '')) + group_method_id = m.activity_kw.get('group_method_id', ''), + tag = m.activity_kw.get('tag', '')) # Also store uid of activity def prepareQueueMessageList(self, activity_tool, message_list): @@ -87,13 +88,15 @@ class SQLDict(RAMDict): datetime = DateTime() date_list = [message.activity_kw.get('at_date', datetime) for message in registered_message_list] group_method_id_list = [message.activity_kw.get('group_method_id', '') for message in registered_message_list] + tag_list = [message.activity_kw.get('tag', '') for message in registered_message_list] activity_tool.SQLDict_writeMessageList( path_list = path_list, method_id_list = method_id_list, priority_list = priority_list, broadcast_list = broadcast_list, message_list = dumped_message_list, date_list = date_list, - group_method_id_list = group_method_id_list) + group_method_id_list = group_method_id_list, + tag_list = tag_list) def prepareDeleteMessage(self, activity_tool, m): # Erase all messages in a single transaction @@ -465,6 +468,31 @@ class SQLDict(RAMDict): return INVALID_ORDER return VALID + def _validate_after_tag(self, activity_tool, message, value): + # Count number of occurances of tag + if type(value) == type(''): + value = [value] + result = activity_tool.SQLDict_validateMessageList(method_id=None, message_uid=None, tag=value) + if result[0].uid_count > 0: + return INVALID_ORDER + return VALID + + def _validate_after_tag_and_method_id(self, activity_tool, message, value): + # Count number of occurances of tag and method_id + if (type(value) != type ( (0,) ) and type(value) != type([])) or len(value)<2: + LOG('CMFActivity WARNING :', 0, 'unable to recognize value for after_tag_and_method_id : %s' % repr(value)) + return VALID + tag = value[0] + method = value[1] + if type(tag) == type(''): + tag = [tag] + if type(method) == type(''): + method = [method] + result = activity_tool.SQLDict_validateMessageList(method_id=method, message_uid=None, tag=tag) + if result[0].uid_count > 0: + return INVALID_ORDER + return VALID + # Required for tests (time shift) def timeShift(self, activity_tool, delay): """ diff --git a/product/CMFActivity/Activity/SQLQueue.py b/product/CMFActivity/Activity/SQLQueue.py index 5b1a1ea925a430cbbf57add88f5a1656b03ae518..54e6c643bf7fbdfbf5eb7a0dc7b801ee9258b9f4 100755 --- a/product/CMFActivity/Activity/SQLQueue.py +++ b/product/CMFActivity/Activity/SQLQueue.py @@ -66,7 +66,8 @@ class SQLQueue(RAMQueue): priority = m.activity_kw.get('priority', 1), broadcast = m.activity_kw.get('broadcast', 0), message = self.dumpMessage(m), - date = m.activity_kw.get('at_date', DateTime())) + date = m.activity_kw.get('at_date', DateTime()), + tag = m.activity_kw.get('tag', '')) def prepareDeleteMessage(self, activity_tool, m): # Erase all messages in a single transaction @@ -286,6 +287,31 @@ class SQLQueue(RAMQueue): if result[0].uid_count > 0: return INVALID_ORDER return VALID + + def _validate_after_tag(self, activity_tool, message, value): + # Count number of occurances of tag + if type(value) == type(''): + value = [value] + result = activity_tool.SQLQueue_validateMessageList(method_id=None, message_uid=None, tag=value) + if result[0].uid_count > 0: + return INVALID_ORDER + return VALID + + def _validate_after_tag_and_method_id(self, activity_tool, message, value): + # Count number of occurances of tag and method_id + if (type(value) != type ( (0,) ) and type(value) != type([])) or len(value)<2: + LOG('CMFActivity WARNING :', 0, 'unable to recognize value for after_tag_and_method_id : %s' % repr(value)) + return VALID + tag = value[0] + method = value[1] + if type(tag) == type(''): + tag = [tag] + if type(method) == type(''): + method = [method] + result = activity_tool.SQLQueue_validateMessageList(method_id=method, message_uid=None, tag=tag) + if result[0].uid_count > 0: + return INVALID_ORDER + return VALID # Required for tests (time shift) def timeShift(self, activity_tool, delay): diff --git a/product/CMFActivity/skins/activity/SQLDict_createMessageTable.zsql b/product/CMFActivity/skins/activity/SQLDict_createMessageTable.zsql index 3d3baf09f9919288c13dacb4c2d848a7a1154c39..cc2ab582ec4cc5aceb21dcf4591084074eed2d14 100755 --- a/product/CMFActivity/skins/activity/SQLDict_createMessageTable.zsql +++ b/product/CMFActivity/skins/activity/SQLDict_createMessageTable.zsql @@ -19,6 +19,7 @@ CREATE TABLE `message` ( `priority` TINYINT DEFAULT 0, `broadcast` TINYINT DEFAULT 0, `group_method_id` VARCHAR(255) DEFAULT '', + `tag` VARCHAR(255), `message` BLOB, PRIMARY KEY (`uid`), KEY `date` (`date`), @@ -27,5 +28,6 @@ CREATE TABLE `message` ( KEY `processing_node` (`processing_node`), KEY `processing` (`processing`), KEY `processing_date` (`processing_date`), - KEY `priority` (`priority`) + KEY `priority` (`priority`), + KEY `tag` (`tag`) ) TYPE = InnoDB; diff --git a/product/CMFActivity/skins/activity/SQLDict_validateMessageList.zsql b/product/CMFActivity/skins/activity/SQLDict_validateMessageList.zsql index 4c79317be907e5229b423e02cfcd063b87d131d3..3f8ac6d4915055079ed188ab18ce8c29c956acb5 100755 --- a/product/CMFActivity/skins/activity/SQLDict_validateMessageList.zsql +++ b/product/CMFActivity/skins/activity/SQLDict_validateMessageList.zsql @@ -10,6 +10,7 @@ class_file: <params>method_id message_uid path +tag </params> SELECT COUNT(DISTINCT uid) as uid_count @@ -32,3 +33,10 @@ WHERE </dtml-in> ) </dtml-if> +<dtml-if tag> + AND ( +<dtml-in tag> + tag = <dtml-sqlvar sequence-item type="string"><dtml-if sequence-end><dtml-else> OR </dtml-if> +</dtml-in> + ) +</dtml-if> diff --git a/product/CMFActivity/skins/activity/SQLDict_writeMessage.zsql b/product/CMFActivity/skins/activity/SQLDict_writeMessage.zsql index 52a1d2de3817446d0f74334cba0109d0308061c1..1f72be1907a2e5608a0df417eb7311e636a87cc5 100755 --- a/product/CMFActivity/skins/activity/SQLDict_writeMessage.zsql +++ b/product/CMFActivity/skins/activity/SQLDict_writeMessage.zsql @@ -14,7 +14,8 @@ priority broadcast date processing_node=-1 -group_method_id</params> +group_method_id +tag</params> INSERT INTO message SET path = <dtml-sqlvar path type="string">, @@ -25,4 +26,5 @@ SET priority = <dtml-sqlvar priority type="int">, broadcast = <dtml-sqlvar broadcast type="int">, group_method_id = <dtml-sqlvar group_method_id type="string">, + tag = <dtml-sqlvar tag type="string">, message = <dtml-sqlvar message type="string"> diff --git a/product/CMFActivity/skins/activity/SQLDict_writeMessageList.zsql b/product/CMFActivity/skins/activity/SQLDict_writeMessageList.zsql index 66a81a85f23a78178c5d4c30a7a0ea24df2ecd3d..17a9b38cc34df71bf30961b88aa80a871ae4f6f2 100755 --- a/product/CMFActivity/skins/activity/SQLDict_writeMessageList.zsql +++ b/product/CMFActivity/skins/activity/SQLDict_writeMessageList.zsql @@ -14,9 +14,10 @@ priority_list broadcast_list date_list processing_node_list -group_method_id_list</params> +group_method_id_list +tag_list</params> INSERT INTO message -(path, date, method_id, processing_node, processing, priority, broadcast, group_method_id, message) +(path, date, method_id, processing_node, processing, priority, broadcast, group_method_id, tag, message) VALUES <dtml-in prefix="loop" expr="_.range(_.len(path_list))"> <dtml-if sequence-start><dtml-else>,</dtml-if> @@ -29,6 +30,7 @@ VALUES <dtml-sqlvar expr="priority_list[loop_item]" type="int">, <dtml-sqlvar expr="broadcast_list[loop_item]" type="int">, <dtml-sqlvar expr="group_method_id_list[loop_item]" type="string">, + <dtml-sqlvar expr="tag_list[loop_item]" type="string">, <dtml-sqlvar expr="message_list[loop_item]" type="string"> ) </dtml-in> diff --git a/product/CMFActivity/skins/activity/SQLQueue_createMessageTable.zsql b/product/CMFActivity/skins/activity/SQLQueue_createMessageTable.zsql index 20a88e99a6346c964c678c062a223ed39471d85f..6d00582520937c4d15e0a55659be6ff5aeabb9a9 100755 --- a/product/CMFActivity/skins/activity/SQLQueue_createMessageTable.zsql +++ b/product/CMFActivity/skins/activity/SQLQueue_createMessageTable.zsql @@ -18,6 +18,7 @@ CREATE TABLE `message_queue` ( `processing_date` datetime, `priority` INT DEFAULT 0, `broadcast` INT DEFAULT 0, + `tag` VARCHAR(255), `message` BLOB, PRIMARY KEY (`uid`), KEY `date` (`date`), @@ -26,5 +27,6 @@ CREATE TABLE `message_queue` ( KEY `processing_node` (`processing_node`), KEY `processing` (`processing`), KEY `processing_date` (`processing_date`), - KEY `priority` (`priority`) + KEY `priority` (`priority`), + KEY `tag` (`tag`) ) TYPE = InnoDB; diff --git a/product/CMFActivity/skins/activity/SQLQueue_validateMessageList.zsql b/product/CMFActivity/skins/activity/SQLQueue_validateMessageList.zsql index 13c2207e4e67713d446632b87d17e7784368b201..9fc103e8d2de01789fc99e52b2e102398b740c59 100755 --- a/product/CMFActivity/skins/activity/SQLQueue_validateMessageList.zsql +++ b/product/CMFActivity/skins/activity/SQLQueue_validateMessageList.zsql @@ -10,6 +10,7 @@ class_file: <params>method_id message_uid path +tag </params> SELECT COUNT(DISTINCT uid) as uid_count @@ -32,3 +33,10 @@ WHERE </dtml-in> ) </dtml-if> +<dtml-if tag> + AND ( +<dtml-in tag> + tag = <dtml-sqlvar sequence-item type="string"><dtml-if sequence-end><dtml-else> OR </dtml-if> +</dtml-in> + ) +</dtml-if> diff --git a/product/CMFActivity/skins/activity/SQLQueue_writeMessage.zsql b/product/CMFActivity/skins/activity/SQLQueue_writeMessage.zsql index a782c2b1e514eef82caf16b967e83a05b8823071..56bcb9b537fea047b683e2bddfd532c104616861 100755 --- a/product/CMFActivity/skins/activity/SQLQueue_writeMessage.zsql +++ b/product/CMFActivity/skins/activity/SQLQueue_writeMessage.zsql @@ -13,7 +13,8 @@ message priority broadcast processing_node=-1 -date</params> +date +tag</params> INSERT INTO message_queue SET path = <dtml-sqlvar path type="string">, @@ -23,4 +24,5 @@ SET broadcast = <dtml-sqlvar broadcast type="int">, processing = -1, priority = <dtml-sqlvar priority type="int">, + tag = <dtml-sqlvar tag type="string">, message = <dtml-sqlvar message type="string"> diff --git a/product/CMFActivity/tests/testCMFActivity.py b/product/CMFActivity/tests/testCMFActivity.py index 01f3abff0ba4aa05a91bda4684bd802ef86df32a..f15a95a29f52da28613f23d56edd08a31f55485c 100755 --- a/product/CMFActivity/tests/testCMFActivity.py +++ b/product/CMFActivity/tests/testCMFActivity.py @@ -546,6 +546,37 @@ class TestCMFActivity(ERP5TypeTestCase): message_list = portal.portal_activities.getMessageList() self.assertEquals(len(message_list),1) + def TryAfterTag(self, activity): + """ + Ensure the order of an execution by a tag + """ + portal = self.getPortal() + organisation_module = self.getOrganisationModule() + if not organisation_module.hasContent(self.company_id): + organisation_module.newContent(id=self.company_id) + o = portal.organisation._getOb(self.company_id) + + o.setTitle('?') + self.assertEquals(o.getTitle(), '?') + get_transaction().commit() + self.tic() + + o.activate(after_tag = 'toto', activity = activity).setTitle('b') + o.activate(tag = 'toto', activity = activity).setTitle('a') + get_transaction().commit() + self.tic() + self.assertEquals(o.getTitle(), 'b') + + o._v_activate_kw = {'tag':'toto'} + def titi(self): + self.setCorporateName(self.getTitle() + 'd') + o.__class__.titi = titi + o.activate(after_tag_and_method_id=('toto', 'setTitle'), activity = activity).titi() + o.activate(activity = activity).setTitle('c') + get_transaction().commit() + self.tic() + self.assertEquals(o.getCorporateName(), 'cd') + def test_01_DeferedSetTitleSQLDict(self, quiet=0, run=run_all_test): # Test if we can add a complete sales order if not run: return @@ -1088,6 +1119,25 @@ class TestCMFActivity(ERP5TypeTestCase): LOG('Testing... ',0,message) self.ExpandedMethodWithDeletedObject('SQLDict') + def test_59_TryAfterTagWithSQLDict(self, quiet=0, run=run_all_test): + # Test if after_tag can be used + if not run: return + if not quiet: + message = '\nTry After Tag With SQL Dict' + ZopeTestCase._print(message) + LOG('Testing... ',0,message) + self.TryAfterTag('SQLDict') + + def test_60_TryAfterTagWithSQLDict(self, quiet=0, run=run_all_test): + # Test if after_tag can be used + if not run: return + if not quiet: + message = '\nTry After Tag With SQL Queue' + ZopeTestCase._print(message) + LOG('Testing... ',0,message) + self.TryAfterTag('SQLQueue') + + if __name__ == '__main__': framework() else: