[hal_json] Add Action to delete multiple documents
/reviewed-on !655
Showing
"""Script to remove Documents inside a Folder. | |||
The new UI does not make any exceptions and treat this script as a generic Dialog Form Method. | |||
Thus it receives form_id of previous form, dialog_id of current dialog and uids of objects from | |||
previous Listbox. | |||
The distinction between XHTML resp. RSJS interface is that in the later, this script receives | |||
`uids` directly whether in XHTML it is given `selection_name` and must extract the uids from | |||
the selection. | |||
:param form_id: {str} Form ID of the previous View's FormBox | |||
:param dialog_id: {str} current dialog's Form ID | |||
:param uids: {list[int]} list of "selected" uids from the previous View (only in JS UI) | |||
:param selection_name: {str} if present then user is using XHTML UI | |||
""" | |||
from ZODB.POSException import ConflictError | from ZODB.POSException import ConflictError | ||
from Products.CMFCore.WorkflowCore import WorkflowException | from Products.CMFCore.WorkflowCore import WorkflowException | ||
portal = context.getPortalObject() | portal = context.getPortalObject() | ||
Base_translateString = portal.Base_translateString | Base_translateString = portal.Base_translateString | ||
REQUEST = portal.REQUEST | translate = Base_translateString | ||
REQUEST = kwargs.get("REQUEST", None) or portal.REQUEST | |||
uids = portal.portal_selections.getSelectionCheckedUidsFor(selection_name) | |||
if portal.portal_selections.selectionHasChanged(md5_object_uid_list, uids): | if selection_name: | ||
message = Base_translateString("Sorry, your selection has changed.") | uids = portal.portal_selections.getSelectionCheckedUidsFor(selection_name) | ||
elif uids: | if portal.portal_selections.selectionHasChanged(md5_object_uid_list, uids): | ||
# Check if there is some related objets. | return context.Base_redirect(keep_items={'portal_status_message': translate("Sorry, your selection has changed.")}) | ||
object_list = [x.getObject() for x in context.Folder_getDeleteObjectList(uid=uids)] | |||
object_used = sum([x.getRelationCountForDeletion() and 1 for x in object_list]) | if not uids: | ||
return context.Base_redirect(keep_items={ | |||
if object_used > 0: | 'portal_status_message': translate("Please select one or more items first."), | ||
if object_used == 1: | 'portal_status_level': "warning"}) | ||
message = Base_translateString("Sorry, 1 item is in use.") | |||
else: | |||
message = Base_translateString("Sorry, ${count} items are in use.", | if True: | ||
mapping={'count': repr(object_used)}) | # already filters out documents with relations that cannot be deleted | ||
else: | object_list = context.Folder_getDeleteObjectList(uid=uids) | ||
object_not_deletable_len = len(uids) - len(object_list) | |||
# some documents cannot be deleted thus we stop and warn the user | |||
if object_not_deletable_len == 1: | |||
return context.Base_redirect(keep_items={ | |||
'portal_status_message': translate("Sorry, 1 item is in use."), | |||
'portal_status_level': "warning"}) | |||
elif object_not_deletable_len > 1: | |||
return context.Base_redirect(keep_items={ | |||
'portal_status_message': translate("Sorry, ${count} items are in use.", mapping={'count': str(object_not_deletable_len)}), | |||
'portal_status_level': "warning"}) | |||
if True: | |||
# Do not delete objects which have a workflow history | # Do not delete objects which have a workflow history | ||
object_to_remove_list = [] | object_to_remove_list = [] | ||
... | @@ -54,9 +82,9 @@ elif uids: | ... | @@ -54,9 +82,9 @@ elif uids: |
REQUEST=REQUEST) | REQUEST=REQUEST) | ||
except ConflictError: | except ConflictError: | ||
raise | raise | ||
except Exception, message: | except Exception as error: | ||
pass | return context.Base_renderMessage(str(error), "error") | ||
else: | else: # in the case of no exception raised report sucess | ||
object_ids = [x.getId() for x in object_to_remove_list] | object_ids = [x.getId() for x in object_to_remove_list] | ||
comment = Base_translateString('Deleted objects: ${object_ids}', | comment = Base_translateString('Deleted objects: ${object_ids}', | ||
mapping={'object_ids': object_ids}) | mapping={'object_ids': object_ids}) | ||
... | @@ -70,10 +98,11 @@ elif uids: | ... | @@ -70,10 +98,11 @@ elif uids: |
message = Base_translateString("Deleted.") | message = Base_translateString("Deleted.") | ||
# Change workflow state of others objects | # Try to call "delete_action" workflow transition on documents which defined it | ||
# Failure of such a call is not a failure globally. The document was deleted anyway | |||
not_deleted_count = 0 | not_deleted_count = 0 | ||
for object in object_to_delete_list: | for object in object_to_delete_list: | ||
# Hidden transition (without a message displayed) | # Hidden transition (without a message displayed) | ||
# are not returned by getActionsFor | # are not returned by getActionsFor | ||
try: | try: | ||
portal.portal_workflow.doActionFor(object, 'delete_action') | portal.portal_workflow.doActionFor(object, 'delete_action') | ||
... | @@ -82,18 +111,8 @@ elif uids: | ... | @@ -82,18 +111,8 @@ elif uids: |
except: | except: | ||
not_deleted_count += 1 | not_deleted_count += 1 | ||
# Generate message | |||
if not_deleted_count == 1: | |||
message = Base_translateString("Sorry, you can not delete ${count} item.", | |||
mapping={'count': not_deleted_count}) | |||
elif not_deleted_count > 1: | |||
message = Base_translateString("Sorry, you can not delete ${count} items.", | |||
mapping={'count': not_deleted_count}) | |||
|
|||
qs = '?portal_status_message=%s' % message | |||
# make sure nothing is checked after | # make sure nothing is checked after | ||
portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ()) | if selection_name: | ||
else: | portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ()) | ||
message = Base_translateString("Please select one or more items first.") | |||
return context.Base_redirect(form_id, keep_items={"portal_status_message":message}) | return context.Base_redirect(form_id, keep_items={"portal_status_message": str(message)}) |