Commit 746dce16 authored by Georgios Dagkakis's avatar Georgios Dagkakis

erp5_core: Fixes in Folder delete

See merge request nexedi/erp5!1381
parents 66e43d73 17cb437c
Pipeline #14464 failed with stage
in 0 seconds
...@@ -8254,6 +8254,9 @@ msgstr "Sans comptes non mouvementés" ...@@ -8254,6 +8254,9 @@ msgstr "Sans comptes non mouvementés"
msgid "On <a href=\"${decision_url}\">${decision_type} ${decision_title}</a> of <a href=\"${delivery_url}\">${delivery_title}</a> :" msgid "On <a href=\"${decision_url}\">${decision_type} ${decision_title}</a> of <a href=\"${delivery_url}\">${delivery_title}</a> :"
msgstr "<a href=\"${decision_url}\">${decision_type} ${decision_title}</a> de <a href=\"${delivery_url}\">${delivery_title}</a>: " msgstr "<a href=\"${decision_url}\">${decision_type} ${decision_title}</a> de <a href=\"${delivery_url}\">${delivery_title}</a>: "
msgid "One or more documents could not be deleted."
msgstr "Un ou plusieurs documents n'ont pas pu être supprimés."
msgid "Online Content:" msgid "Online Content:"
msgstr "Contenu en ligne:" msgstr "Contenu en ligne:"
...@@ -13894,6 +13897,9 @@ msgstr "Effectuez une recherche pour afficher le contenu." ...@@ -13894,6 +13897,9 @@ msgstr "Effectuez une recherche pour afficher le contenu."
msgid "To reset your password, please enter your login below. An email will be sent to your address with a link to enter your new password." msgid "To reset your password, please enter your login below. An email will be sent to your address with a link to enter your new password."
msgstr "Afin de changer votre mot de passe, entrez votre nom d'utilisateur ci-dessous. Un email contenant des explications sur la marche à suivre sera envoyé à votre adresse." msgstr "Afin de changer votre mot de passe, entrez votre nom d'utilisateur ci-dessous. Un email contenant des explications sur la marche à suivre sera envoyé à votre adresse."
msgid "Too many documents selected."
msgstr "Trop de documents sélectionnés."
msgid "Too many documents were found." msgid "Too many documents were found."
msgstr "Trop de possibilités trouvées." msgstr "Trop de possibilités trouvées."
......
...@@ -187,9 +187,8 @@ It contains the same columns ...@@ -187,9 +187,8 @@ It contains the same columns
</tr> </tr>
<tr> <tr>
<td>assertTextPresent</td> <td>assertTextPresent</td>
<td>Deleted.</td> <td>One or more documents could not be deleted.</td>
<td></td> <td></td>
<td>We used to report error on user deleting deleted document ... but user does not care, does she?</td>
</tr> </tr>
<tr> <tr>
<td>clickAndWait</td> <td>clickAndWait</td>
......
...@@ -15,6 +15,7 @@ the selection. ...@@ -15,6 +15,7 @@ the selection.
""" """
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
from Products.CMFCore.WorkflowCore import WorkflowException from Products.CMFCore.WorkflowCore import WorkflowException
from Products.ERP5Type.Message import Message
portal = context.getPortalObject() portal = context.getPortalObject()
Base_translateString = portal.Base_translateString Base_translateString = portal.Base_translateString
...@@ -32,86 +33,119 @@ if not listbox_uid: ...@@ -32,86 +33,119 @@ if not listbox_uid:
'portal_status_level': "warning"}) 'portal_status_level': "warning"})
if True: # already filters out documents with relations that cannot be deleted
# already filters out documents with relations that cannot be deleted object_list = context.Folder_getDeleteObjectList(uid=listbox_uid)
object_list = context.Folder_getDeleteObjectList(uid=listbox_uid) if len(object_list) > 1000:
object_not_deletable_len = len(listbox_uid) - len(object_list) return context.Base_redirect(
keep_items={
# some documents cannot be deleted thus we stop and warn the user 'portal_status_message': translate("Too many documents selected."),
if object_not_deletable_len == 1: 'portal_status_level': "warning",
return context.Base_redirect(keep_items={ }
'portal_status_message': translate("Sorry, 1 item is in use."), )
'portal_status_level': "warning"}) object_not_deletable_len = len(listbox_uid) - len(object_list)
elif object_not_deletable_len > 1:
return context.Base_redirect(keep_items={ # some documents cannot be deleted thus we stop and warn the user
'portal_status_message': translate("Sorry, ${count} items are in use.", mapping={'count': str(object_not_deletable_len)}), if object_not_deletable_len == 1:
'portal_status_level': "warning"}) return context.Base_redirect(keep_items={
'portal_status_message': translate("Sorry, 1 item is in use."),
if True: 'portal_status_level': "warning"})
elif object_not_deletable_len > 1:
# Do not delete objects which have a workflow history return context.Base_redirect(keep_items={
object_to_remove_list = [] 'portal_status_message': translate("Sorry, ${count} items are in use.", mapping={'count': str(object_not_deletable_len)}),
object_to_delete_list = [] 'portal_status_level': "warning"})
for obj in object_list: # Do not delete objects which have a workflow history
object_to_remove_list = []
history_dict = obj.Base_getWorkflowHistory() object_to_delete_list = []
history_dict.pop('edit_workflow', None)
if history_dict == {} or obj.aq_parent.portal_type=='Preference': for obj in object_list:
# templates inside preference will be unconditionnaly physically
# deleted history_dict = obj.Base_getWorkflowHistory()
object_to_remove_list.append(obj) history_dict.pop('edit_workflow', None)
else: if history_dict == {} or obj.aq_parent.portal_type=='Preference':
# If a workflow manage a history, # templates inside preference will be unconditionnaly physically
# object should not be removed, but only put in state deleted # deleted
object_to_delete_list.append(obj) object_to_remove_list.append(obj)
else:
# Remove some objects # If a workflow manage a history,
# object should not be removed, but only put in state deleted
object_to_delete_list.append(obj)
# Remove some objects
if object_to_remove_list:
if context.getPortalType() != 'Preference':
# Use uids so that we can delete from listboxs showing documents
# that are not sub-objects of the current document
try: try:
if object_to_remove_list: context.manage_delObjects(
if context.portal_type == 'Preference': uids=[x.getUid() for x in object_to_remove_list],
# Templates inside preference are not indexed, so we cannot pass REQUEST=REQUEST,
# uids= to manage_delObjects and have to use ids= )
context.manage_delObjects(
ids=[x.getId() for x in object_to_remove_list],
REQUEST=REQUEST)
portal.portal_caches.clearCacheFactory('erp5_ui_medium')
else:
context.manage_delObjects(
uids=[x.getUid() for x in object_to_remove_list],
REQUEST=REQUEST)
except ConflictError: except ConflictError:
raise raise
except Exception as error: except Exception as error:
# Note, this does not rollback transaction, so in case manage_delObjects
# did delete some objects these will be deleted.
# This may be considered a feature of user point of view
# (something went wrong with some documents, but some where deleted)
return context.Base_renderMessage(str(error), "error") return context.Base_renderMessage(str(error), "error")
else: # in the case of no exception raised report sucess else:
object_ids = [x.getId() for x in object_to_remove_list] # Templates inside preference are not indexed, so we cannot pass
comment = Base_translateString('Deleted objects: ${object_ids}', # uids= to manage_delObjects and have to use ids=
mapping={'object_ids': object_ids}) for document in object_to_remove_list:
try: try:
# record object deletion in workflow history document.getParentValue().manage_delObjects(
portal.portal_workflow.doActionFor(context, 'edit_action', ids=[document.getId()]
comment=comment) )
except WorkflowException: # Clear cache to recalculate the list of possible templates in case one was deleted
# no 'edit_action' transition for this container portal.portal_caches.clearCacheFactory('erp5_ui_medium')
pass except ConflictError:
raise
message = Base_translateString("Deleted.") except Exception as error:
# Note, this does not rollback transaction, so in case manage_delObjects
# Try to call "delete_action" workflow transition on documents which defined it # did delete some objects these will be deleted.
# Failure of such a call is not a failure globally. The document was deleted anyway # This may be considered a feature of user point of view
for obj in object_to_delete_list: # (something went wrong with some documents, but some where deleted)
# Hidden transition (without a message displayed) return context.Base_renderMessage(str(error), "error")
# are not returned by getActionsFor try:
try: # record object deletion in workflow history
portal.portal_workflow.doActionFor(obj, 'delete_action') portal.portal_workflow.doActionFor(
except ConflictError: context,
raise 'edit_action',
except Exception: comment=Message(
pass domain='ui',
message='Deleted objects: ${object_ids}',
# make sure nothing is checked after mapping={'object_ids': [x.getId() for x in object_to_remove_list]},
if selection_name: ),
portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ()) )
except WorkflowException:
return context.Base_redirect(form_id, keep_items={"portal_status_message": str(message)}) # no 'edit_action' transition for this container
pass
message = Base_translateString("Deleted.")
portal_status_level = "success"
# Try to call "delete_action" workflow transition on documents which defined it
for obj in object_to_delete_list:
# Hidden transition (without a message displayed)
# are not returned by getActionsFor
try:
portal.portal_workflow.doActionFor(obj, 'delete_action')
except WorkflowException:
# The user does not have rights to invoke delete action.
# Do not raise since delete_action may succeed for other selected documents
# Do give a warning though
message = Base_translateString("One or more documents could not be deleted.")
portal_status_level = "warning"
# make sure nothing is checked after
if selection_name:
portal.portal_selections.setSelectionCheckedUidsFor(selection_name, ())
return context.Base_redirect(
form_id,
keep_items={
"portal_status_message": str(message),
"portal_status_level": portal_status_level,
},
)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment