|
1 | 1 | from Acquisition import aq_inContextOf |
2 | 2 | from Acquisition import aq_inner |
| 3 | +from opengever.base.interfaces import IDataCollector |
3 | 4 | from opengever.base.json_response import JSONResponse |
4 | 5 | from opengever.base.security import elevated_privileges |
5 | 6 | from opengever.base.transport import PrivilegedReceiveObject |
6 | 7 | from opengever.base.transport import Transporter |
| 8 | +from opengever.document.versioner import Versioner |
| 9 | +from opengever.journal.handlers import journal_entry_factory |
| 10 | +from opengever.ogds.base.utils import encode_after_json |
| 11 | +from opengever.ris import _ |
7 | 12 | from plone import api |
8 | 13 | from plone.protect.interfaces import IDisableCSRFProtection |
9 | 14 | from plone.restapi.deserializer import json_body |
10 | 15 | from plone.restapi.services import Service |
11 | 16 | from z3c.relationfield.relation import RelationValue |
12 | 17 | from zExceptions import BadRequest |
| 18 | +from zope.component import getAdapters |
13 | 19 | from zope.component import getUtility |
14 | 20 | from zope.interface import alsoProvides |
15 | 21 | from zope.intid.interfaces import IIntIds |
@@ -52,6 +58,39 @@ def reply(self): |
52 | 58 | return result |
53 | 59 |
|
54 | 60 |
|
| 61 | +class RISUpdateExcerptService(Service): |
| 62 | + |
| 63 | + def reply(self): |
| 64 | + alsoProvides(self.request, IDisableCSRFProtection) |
| 65 | + |
| 66 | + if not api.user.has_permission("View", obj=self.context): |
| 67 | + return JSONResponse(self.request).error("Forbidden", status=403).dump() |
| 68 | + |
| 69 | + data = json_body(self.request) or {} |
| 70 | + target_cid = data.get("target_admin_unit_id") |
| 71 | + container_path = data.get("target_doc_relative_path") |
| 72 | + |
| 73 | + if not target_cid or not container_path: |
| 74 | + return ( |
| 75 | + JSONResponse(self.request) |
| 76 | + .error( |
| 77 | + "Target admin_unit_id and paths are required.", |
| 78 | + status=400, |
| 79 | + ) |
| 80 | + .dump() |
| 81 | + ) |
| 82 | + |
| 83 | + container_path = container_path.lstrip("/") |
| 84 | + |
| 85 | + result = Transporter().transport_to( |
| 86 | + obj=self.context, |
| 87 | + target_cid=target_cid, |
| 88 | + container_path=container_path, |
| 89 | + view="receive-ris-update-excerpt", |
| 90 | + ) |
| 91 | + return result |
| 92 | + |
| 93 | + |
55 | 94 | class RISReturnExcerptReceive(PrivilegedReceiveObject): |
56 | 95 | """Receiver on the target dossier. Runs with elevated privileges.""" |
57 | 96 |
|
@@ -127,3 +166,56 @@ def receive(self): |
127 | 166 | pass |
128 | 167 |
|
129 | 168 | return document |
| 169 | + |
| 170 | + |
| 171 | +class RISUpdateExcerptReceive(RISReturnExcerptReceive): |
| 172 | + """Receiver on the target dossier. Runs with elevated privileges.""" |
| 173 | + |
| 174 | + def _apply_payload_as_new_version(self, gever_doc, payload): |
| 175 | + Versioner(gever_doc).create_initial_version() |
| 176 | + |
| 177 | + data = encode_after_json(payload) |
| 178 | + |
| 179 | + for name, collector in getAdapters((gever_doc,), IDataCollector): |
| 180 | + if name in data: |
| 181 | + collector.insert(data[name]) |
| 182 | + |
| 183 | + file = data["field-data"]["IDocumentSchema"].get("file") |
| 184 | + if file: |
| 185 | + gever_doc.update_file( |
| 186 | + file["data"], |
| 187 | + content_type=file.get("content-type"), |
| 188 | + filename=file.get("filename"), |
| 189 | + create_version=True, |
| 190 | + ) |
| 191 | + |
| 192 | + journal_entry_factory( |
| 193 | + context=gever_doc, |
| 194 | + action="Update proposal excerpt from SPV", |
| 195 | + title=_("excerpt_was_replaced", default="Excerpt was replaced"), |
| 196 | + ) |
| 197 | + api.content.transition(obj=gever_doc, transition="document-transition-finalize") |
| 198 | + |
| 199 | + return gever_doc |
| 200 | + |
| 201 | + def receive(self): |
| 202 | + document = self.container |
| 203 | + transporter = Transporter() |
| 204 | + payload = transporter._extract_data(self.request) |
| 205 | + |
| 206 | + if document is None: |
| 207 | + raise BadRequest("Invalid 'doc_relative_path' (object not found).") |
| 208 | + |
| 209 | + try: |
| 210 | + with elevated_privileges(): |
| 211 | + if document.is_final_document(): |
| 212 | + api.content.transition( |
| 213 | + obj=document, transition="document-transition-reopen" |
| 214 | + ) |
| 215 | + |
| 216 | + document = self._apply_payload_as_new_version(document, payload) |
| 217 | + |
| 218 | + except Exception: |
| 219 | + pass |
| 220 | + |
| 221 | + return document |
0 commit comments