[hal_json] Add Action to delete multiple documents
/reviewed-on nexedi/erp5!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 Products.CMFCore.WorkflowCore import WorkflowException | ||
portal = context.getPortalObject() | ||
Base_translateString = portal.Base_translateString | ||
REQUEST = portal.REQUEST | ||
uids = portal.portal_selections.getSelectionCheckedUidsFor(selection_name) | ||
if portal.portal_selections.selectionHasChanged(md5_object_uid_list, uids): | ||
message = Base_translateString("Sorry, your selection has changed.") | ||
elif uids: | ||
# Check if there is some related objets. | ||
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 object_used > 0: | ||
if object_used == 1: | ||
message = Base_translateString("Sorry, 1 item is in use.") | ||
else: | ||
message = Base_translateString("Sorry, ${count} items are in use.", | ||
mapping={'count': repr(object_used)}) | ||
else: | ||
translate = Base_translateString | ||
REQUEST = kwargs.get("REQUEST", None) or portal.REQUEST | ||
if selection_name: | ||
uids = portal.portal_selections.getSelectionCheckedUidsFor(selection_name) | ||
if portal.portal_selections.selectionHasChanged(md5_object_uid_list, uids): | ||
return context.Base_redirect(keep_items={'portal_status_message': translate("Sorry, your selection has changed.")}) | ||
if not uids: | ||
return context.Base_redirect(keep_items={ | ||
'portal_status_message': translate("Please select one or more items first."), | ||
'portal_status_level': "warning"}) | ||
if True: | ||
# already filters out documents with relations that cannot be deleted | ||
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 | ||
object_to_remove_list = [] | ||
... | ... | @@ -54,9 +82,9 @@ elif uids: |
REQUEST=REQUEST) | ||
except ConflictError: | ||
raise | ||
except Exception, message: | ||
pass | ||
else: | ||
except Exception as error: | ||
return context.Base_renderMessage(str(error), "error") | ||
else: # in the case of no exception raised report sucess | ||
object_ids = [x.getId() for x in object_to_remove_list] | ||
comment = Base_translateString('Deleted objects: ${object_ids}', | ||
mapping={'object_ids': object_ids}) | ||
... | ... | @@ -70,10 +98,11 @@ elif uids: |
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 | ||
for object in object_to_delete_list: | ||
# Hidden transition (without a message displayed) | ||
# Hidden transition (without a message displayed) | ||
# are not returned by getActionsFor | ||
try: | ||
portal.portal_workflow.doActionFor(object, 'delete_action') | ||
... | ... | @@ -82,18 +111,8 @@ elif uids: |
except: | ||
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 | ||
portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ()) | ||
else: | ||
message = Base_translateString("Please select one or more items first.") | ||
if selection_name: | ||
portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ()) | ||
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)}) |