Commit 101d4ebd authored by Arnaud Pauget's avatar Arnaud Pauget
Browse files

Merge branch 'feat/18079_originating_service_change' into 'develop'

Feat/18079 originating service change

See merge request !697
parents 33d2b7f0 8ce3f34a
Pipeline #14605 failed with stages
in 58 seconds
......@@ -71,7 +71,7 @@ class organization
*
* @return organization/organization[] An array of organization whith service
*/
public function todisplay($ownerOrg, $orgUnit, $term)
public function todisplay($ownerOrg = false, $orgUnit = false, $term = "")
{
$authController = \laabs::newController("auth/userAccount");
$user = $authController->get(\laabs::getToken('AUTH')->accountId);
......
......@@ -975,4 +975,111 @@ trait archiveModificationTrait
return true;
}
/**
* Get available originators for an archive
* @param string $archiveId The archive identifier
*
* @return array $availableOriginatingServices array of organization
*/
public function indexAvailableOriginators($archiveIds)
{
$availableOriginatingServices = null;
foreach($archiveIds as $archiveId) {
$archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
if (is_null($availableOriginatingServices)){
$availableOriginatingServices = $this->getDescendantServices($archive->originatorOwnerOrgId, $archive->archivalAgreementReference);
} else {
array_uintersect($availableOriginatingServices, $this->getDescendantServices($archive->originatorOwnerOrgId, $archive->archivalAgreementReference), function($a, $b) {
return strcmp(spl_object_hash($a), spl_object_hash($b));
});
}
}
return $availableOriginatingServices;
}
protected function getDescendantServices($orgId, $archivalAgreementReference)
{
$archivalAgreementController = \laabs::newController('medona/archivalAgreement');
$organizationController = \laabs::newController('organization/organization');
$orgs = [];
if (!is_null($archivalAgreementReference)) {
$archivalAgreement = $archivalAgreementController->getByReference($archivalAgreementReference);
foreach ($archivalAgreement->originatorOrgIds as $originatorOrgId) {
$orgs[] = $organizationController->read((string) $originatorOrgId);
array_merge($organizationController->readDescendantServices((string) $originatorOrgId), $orgs);
}
} else {
$orgs = $organizationController->readDescendantServices($orgId);
}
$descendantServices = [];
foreach ($orgs as $key => $org) {
// May be empty if archivalAgreement originatorOrgId has no descendant service
if (!empty($org)) {
$descendantServices[$key] = new \stdClass();
$descendantServices[$key]->orgId = (string) $org->orgId;
$descendantServices[$key]->displayName = $org->displayName;
}
}
// sort by alphabetical order of displayName (php 8)
usort($descendantServices, function ($a, $b) {
return $a->displayName <=> $b->displayName;
});
return $descendantServices;
}
/**
* Update originator service of an array of archives
*
* @param array $archiveIds Array of archive identifiers
* @param string $orgId Organization identified destined to be new originator of archive
*
*/
public function updateOriginator($archiveIds, $orgId)
{
if (!is_array($archiveIds)) {
$archiveIds = [$archiveIds];
}
$result = [];
$result["success"] = [];
$result["error"] = [];
$newOriginatorOrg = $this->sdoFactory->read('organization/organization', $orgId);
if ($newOriginatorOrg->enabled == false) {
throw new \bundle\recordsManagement\Exception\organizationException(
"This organization is disabled."
);
}
foreach ($archiveIds as $archiveId) {
$archive = $this->sdoFactory->read('recordsManagement/archive', $archiveId);
$currentOwnerOrgId = $archive->originatorOwnerOrgId;
if ($currentOwnerOrgId != $newOriginatorOrg->ownerOrgId) {
$result["error"][] = $archiveId;
continue;
}
$isAvailableOriginator = array_search($newOriginatorOrg->orgId, array_column($this->getDescendantServices($archive->originatorOwnerOrgId, $archive->archivalAgreementReference), 'orgId'));
if (!$isAvailableOriginator) {
$result["error"][] = $archiveId;
}
$archive->originatorOrgRegNumber = $newOriginatorOrg->registrationNumber;
$archive->lastModificationDate = \laabs::newTimestamp();
$this->sdoFactory->update($archive,'recordsManagement/archive');
$result["success"][] = $archiveId;
}
return $result;
}
}
<?php
/*
* Copyright (C) 2015 Maarch
*
* This file is part of bundle recordsManagement.
*
* Bundle recordsManagement is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Bundle recordsManagement is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with bundle recordsManagement. If not, see <http://www.gnu.org/licenses/>.
*/
namespace bundle\recordsManagement\Model;
/**
* Class model that represents an archive
*
* @package RecordsManagement
* @author Charlotte Bataille (Maarch) <charlotte.bataille@maarch.org>
*
* @substitution recordsManagement/archive
*
* @pkey [archiveId]
*/
class archiveOriginator
{
/**
* The archive identifier
*
* @var string
* @notempty
*/
public $archiveId;
/**
* The registration number of the originator organization
*
* @var string
* @notempty
*/
public $originatorOrgRegNumber;
/**
* @var timestamp
*/
public $lastModificationDate;
} // END class archive
......@@ -135,6 +135,13 @@ interface archiveInterface
*/
public function read_archiveId_Retentionrule();
/**
* Get available orignators for an archive before to modify
*
* @action recordsManagement/archive/indexAvailableOriginators
*/
public function readAvailableoriginators($archiveIds);
/**
* Read the access rule of archive
*
......
......@@ -469,4 +469,14 @@ interface archivesInterface
* @action recordsManagement/archive/extractFulltext
*/
public function readExtractfulltext($maxResults = null, $timeLimit = null);
/**
* Update originator service or archives
*
* @param array $archiveIds Array of archiveIdentifiers
* @param string $orgId Organization identifier
*
* @action recordsManagement/archive/updateOriginator
*/
public function updateOriginator($archiveIds, $orgId);
}
......@@ -1351,6 +1351,7 @@ class archive
protected function readPrivilegesOnArchives()
{
$hasModificationPrivilege = \laabs::callService('auth/userAccount/readHasprivilege', "archiveManagement/modify");
$hasModificationOriginatorPrivilege = \laabs::callService('auth/userAccount/readHasprivilege', "archiveManagement/adminOriginator");
$hasIntegrityCheckPrivilege = \laabs::callService('auth/userAccount/readHasprivilege', "archiveManagement/checkIntegrity");
$hasDestructionPrivilege = \laabs::callService('auth/userAccount/readHasprivilege', "destruction/destructionRequest");
$hasRestitutionPrivilege = $this->transaction && \laabs::callService('auth/userAccount/readHasprivilege', "restitution/restitutionRequest");
......@@ -1359,6 +1360,7 @@ class archive
$hasModificationRequestPrivilege = $this->transaction && \laabs::callService('auth/userAccount/readHasprivilege', "archiveManagement/modificationRequestSend");
$this->view->setSource('hasModificationPrivilege', $hasModificationPrivilege);
$this->view->setSource('hasModificationOriginatorPrivilege', $hasModificationOriginatorPrivilege);
$this->view->setSource('hasIntegrityCheckPrivilege', $hasIntegrityCheckPrivilege);
$this->view->setSource('hasDestructionPrivilege', $hasDestructionPrivilege);
$this->view->setSource('hasRestitutionPrivilege', $hasRestitutionPrivilege);
......@@ -1430,4 +1432,30 @@ class archive
return $file;
}
/**
* Serializer JSON for changing originator method
* @param array $result
*
* @return object JSON object with a status and message parameters
*/
public function setOriginator($result)
{
$success = count($result['success']);
$echec = count($result['error']);
$this->json->message = '%1$s archive(s) modified.';
$this->json->message = $this->translator->getText($this->json->message);
$this->json->message = sprintf($this->json->message, $success);
if ($echec > 0) {
$message = '%1$s archive(s) can not be modified.';
$message = $this->translator->getText($message);
$message = sprintf($message, $echec);
$this->json->message .= ' '.$message;
}
return $this->json->save();
}
}
......@@ -876,6 +876,10 @@ msgid "importUserAccount"
msgstr "Comptes utilisateurs"
msgctxt "userStory"
msgid "adminOriginator"
msgstr "Modifier le service producteur des archives"
msgctxt "userStory"
msgid "exportOrganization"
msgstr "Organisations"
msgctxt "userStory"
......
......@@ -272,6 +272,12 @@ msgstr "Une archive gelée ne peut pas être modifiée."
msgid "An archive that does not have the status 'preserved' can't be modified."
msgstr "Une archive n'ayant pas le statut 'Conservée' ne peut pas être modifiée"
msgid "The new originator organization of the archive must have the same owner organization as the current one."
msgstr "Le nouveau service producteur de l'archive doit avoir la même organisation racine que le service producteur actuel."
msgid "This organization is disabled."
msgstr "Ce service est inactif."
msgid "An action is already in progress on this archive."
msgstr "Une action est déjà en cours sur cette archive."
......
......@@ -378,6 +378,9 @@ msgstr "Demander une modification"
msgid "Edit access rule"
msgstr "Modifier la règle de communicabilité"
msgid "Modify originator service"
msgstr "Modifier le service producteur"
msgid "You not have the permission to view the documents of archive"
msgstr "Vous n'avez pas la permission de visualiser les documents de cette archive"
......@@ -1340,3 +1343,6 @@ msgstr "Ajouter le filtre"
msgid "Search in other services"
msgstr "Rechercher dans d'autres services"
msgid "New originating service"
msgstr "Nouveau service producteur"
......@@ -105,7 +105,8 @@ var ArchivesAction = {
requestCommunication : ['preserved', 'frozen'],
flagForRestitution : ['preserved'],
flagForTransfer : ['preserved'],
addToCollection : ['preserved', 'frozen', 'restituable', 'disposable', 'transferable']
addToCollection : ['preserved', 'frozen', 'restituable', 'disposable', 'transferable'],
editOriginator : ['preserved']
},
getSelectedArchives : function(type) {
......
......@@ -19,6 +19,7 @@
<?hinclude recordsManagement/archive/archiveModificationModal/retentionRule.html?>
<?hinclude recordsManagement/archive/archiveModificationModal/requestCommunication.html?>
<?hinclude recordsManagement/archive/archiveModificationModal/archiveTransfer.html?>
<?hinclude recordsManagement/archive/archiveModificationModal/originatorModification.html?>
</div>
</div>
</div>
......@@ -29,6 +30,7 @@
<span id="mtext_flagForRestitution">Flag for restitution</span>
<span id="mtext_cancelRestitution">Cancel restitution</span>
<span id="mtext_validateRestitution">Validate restitution</span>
<span id="mtext_editOriginator">New originating service</span>
<span id="restituable_text">restituable</span>
......@@ -79,15 +81,24 @@
var transaction = false;
$("#transaction").val() ? transaction = true : transaction = false;
if (type === "accessRule" || type === "retentionRule" || type === "requestCommunication") {
parameter = eval(type+"_serialize()");
} else if (type === "flagForTransfer") {
if ($('#archivalAgencySelect').find('option:selected').val()) {
parameter.archiverOrgRegNumber = $('#archivalAgencySelect').find('option:selected').val();
}
switch (type) {
case "accessRule":
case "retentionRule":
case "requestCommunication":
case "editOriginator":
parameter = eval(type+"_serialize()");
break;
case "flagForTransfer":
if ($('#archivalAgencySelect').find('option:selected').val()) {
parameter.archiverOrgRegNumber = $('#archivalAgencySelect').find('option:selected').val();
}
break;
default:
break;
}
if (transaction) {
if (transaction && type != "editOriginator") {
parameter.identifier = this.modal.find('[name="identifier"]').val();
parameter.comment = this.modal.find('[name="comment"]').val();
parameter.format = this.modal.find('[name="format"]').val()
......
<script>
var editOriginator_load = function (archiveId, archiveName, type) {
var url = '/recordsManagement/archive/availableoriginators';
var type = 'GET';
let parameters = {
archiveIds : [archiveId]
}
$.ajax({
url : url,
type : type,
data : parameters,
dataType : 'json',
success : function (response) {
displayOrignator(response);
},
error : function(response) {
gritter.show(response.responseJSON.message, response.responseJSON.status, response.responseJSON.errors);
}
});
}
var editOriginator_loadMultiple = function (archiveIds) {
var url = '/recordsManagement/archive/availableoriginators';
var type = 'GET';
let parameters = {
archiveIds : archiveIds
}
$.ajax({
url : url,
type : type,
data : parameters,
dataType : 'json',
success : function (response) {
displayOrignator(response);
},
error : function(response) {
gritter.show(response.responseJSON.message, response.responseJSON.status, response.responseJSON.errors);
}
});
}
var displayOrignator = function(originatorTab) {
$('#selectedOriginator').remove();
var selectedOriginatorTr = $('<tr>').attr('id', "selectedOriginator");
selectedOriginatorTr.append($('<td>').append($('<strong>').text($('#mtext_editOriginator').text())));
var td = $('<td>');
var availableOriginatingServices = originatorTab;
var select = $('<select>').attr('name', "originatorList").attr("id", "originatorList").addClass('form-control');
availableOriginatingServices.forEach(org => {
select.append($('<option>').val(org.orgId).text(org.displayName));
});
td.append(select);
selectedOriginatorTr.append(td);
$('#modificationModal table tbody').append(selectedOriginatorTr);
$('#modificationModal').modal();
}
var editOriginator_serialize = function () {
var parameter = {};
parameter.orgId = $('#originatorList').val();
parameter.archiveIds = [];
parameter.archiveIds.push($('#selectedArchiveId').val());
return parameter;
}
</script>
......@@ -30,6 +30,7 @@
<span id="mtext_flagForTransfer">Flag for transfer</span>
<span id="mtext_retentionRule">Change disposal rule</span>
<span id="mtext_accessRule">Edit access rule</span>
<span id="mtext_editOriginator">Edit Originating service</span>
<span id="mtext_flagForDestruction">Flag for destruction</span>
<span id="mtext_requestModification">Request a modification</span>
<span id="mtext_cancelDestruction">Cancel destruction</span>
......@@ -95,7 +96,8 @@
requestModification : '/modificationRequest',
cancelDestruction : '/recordsManagement/cancelDestruction',
freeze : '/recordsManagement/archive/freeze',
unfreeze : '/recordsManagement/archive/unfreeze'
unfreeze : '/recordsManagement/archive/unfreeze',
editOriginator : '/recordsManagement/archive/originator',
},
actionsType : {},
modal : $('#modificationModal'),
......@@ -117,19 +119,25 @@
this.modal.modal();
}
if (type === 'requestCommunication' && $('#' +archiveId).data('iscommunicable') === 1) {
$('#derogationTr').show();
$('#derogationInputTr').show();
$("#derogationTr .toggle").removeClass('btn-default off');
$("#derogationTr .toggle").addClass('btn-info');
$('#derogationTr').hide();
$('#derogationInputTr').hide();
} else {
$('#derogationTr').hide();
$('#derogationInputTr').hide();
}
if (type === 'requestModification') {
$('#messageFormatTr').hide();
switch (type) {
case 'requestCommunication':
if ($('#' +archiveId).data('iscommunicable') === 1) {
$('#derogationTr').show();
$('#derogationInputTr').show();
$("#derogationTr .toggle").removeClass('btn-default off');
$("#derogationTr .toggle").addClass('btn-info');
}
break;
case 'requestModification':
$('#messageFormatTr').hide();
break;
case 'editOriginator':
$('#message').hide();
break;
default:
}
if (!transaction) {
......@@ -231,7 +239,7 @@
$('#archiveModificationForm').find('.modificationForm').css('display', 'none');
try {
eval(type+"_loadMultiple()");
eval(type+"_loadMultiple(ids)");
$('#archiveModificationForm').css('display', '');
}
catch(err) {
......@@ -291,8 +299,6 @@
type = 'PUT';
}
console.log(this.actionsList[this.modalType]);
$.ajax({
url : this.actionsList[this.modalType],
type : type,
......
......@@ -5,6 +5,8 @@
<li class="editRetentionRule" data-type="retentionRule"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify retention rule</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="editAccessRule" data-type="accessRule"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify access rule</a></li>
<?merge hasModificationOriginatorPrivilege.bool() ?>
<li class="editOriginator" data-type="editOriginator"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify originator service</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="freeze [?merge .status.ifeq('frozen').then('hide', '') ?]" data-type="freeze"><a href="#"><i class="fa fa-lock">&nbsp;</i>&nbsp;Freeze</a></li>
<?merge hasModificationPrivilege.bool() ?>
......@@ -25,6 +27,7 @@
<?merge hasIntegrityCheckPrivilege.bool() ?>
<li class="checkHash" data-type="checkHash"><a href="#"><i class="fa fa-database">&nbsp;</i>&nbsp;Verify integrity</a></li>
<li class="divider"></li>
</span>
<li class="requestDelivery" data-type="requestCommunication"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Request of communication</a></li>
</ul>
......@@ -4,6 +4,8 @@
<li class="editRetentionRule toto" data-type="retentionRule"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify retention rule</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="editAccessRule" data-type="accessRule"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify access rule</a></li>
<?merge hasModificationOriginatorPrivilege.bool() ?>
<li class="editOriginator" data-type="editOriginator"><a href="#"><i class="fa fa-edit">&nbsp;</i>&nbsp;Modify originator service</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="freeze" data-type="freeze"><a href="#"><i class="fa fa-lock">&nbsp;</i>&nbsp;Freeze</a></li>
<?merge hasModificationPrivilege.bool() ?>
......
<?php
/*
* Copyright (C) 2021 Maarch
*
* This file is part of bundle recordsManagement.
*
* Bundle recordsManagement is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Bundle recordsManagement is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with bundle recordsManagement. If not, see <http://www.gnu.org/licenses/>.
*/
namespace presentation\maarchRM\UserStory\archiveManagement;
/**
* Interface for management of description fields
*
* @package adminArchive
* @author Jerome Boucher <alexis.ragot@maarch.org>
*/
interface adminOriginatorInterface