Commit b644ccc6 authored by Jerome Boucher's avatar Jerome Boucher
Browse files

Merge branch 'feat/13448_discovering' into 'develop'

Feat/13448 discovering

See merge request !686
parents 743f3603 b00c3289
Pipeline #14103 canceled with stages
in 23 seconds
This diff is collapsed.
......@@ -28,3 +28,4 @@ WITH (
);
ALTER TABLE "recordsManagement"."archivalProfile" ADD COLUMN "isRetentionLastDeposit" boolean default false;
ALTER TABLE "recordsManagement"."archivalProfile" ADD COLUMN "isDiscoverable" boolean default false;
......@@ -680,7 +680,7 @@ class userAccount
*/
public function readUserPositions($accountId)
{
$users = $this->sdoFactory->find("organization/userPosition", "accountId = '$accountId'");
$users = $this->sdoFactory->find("organization/userPosition", "userAccountId = '$accountId'");
$users = \laabs::castMessageCollection($users, 'organization/userPositionTree');
foreach ($users as $user) {
......
......@@ -240,26 +240,26 @@ trait archiveAccessTrait
$processingStatus = null
) {
$archiveArgs = [
'archiveId' => $archiveId,
'profileReference' => $profileReference,
'status' => $status,
'archiveName' => $archiveName,
'agreementReference' => $agreementReference,
'archiveExpired' => $archiveExpired,
'finalDisposition' => $finalDisposition,
'archiveId' => $archiveId,
'profileReference' => $profileReference,
'status' => $status,
'archiveName' => $archiveName,
'agreementReference' => $agreementReference,
'archiveExpired' => $archiveExpired,
'finalDisposition' => $finalDisposition,
'originatorOrgRegNumber' => $originatorOrgRegNumber,
'originatorOwnerOrgId' => $originatorOwnerOrgId,
'originatorArchiveId' => $originatorArchiveId,
'originatingDate' => $originatingDate,
'filePlanPosition' => $filePlanPosition,
'hasParent' => $hasParent,
'partialRetentionRule' => $partialRetentionRule,
'retentionRuleCode' => $retentionRuleCode,
'depositStartDate' => $depositStartDate,
'depositEndDate' => $depositEndDate,
'originatingDate' => [$originatingStartDate, $originatingEndDate], // [0] startDate, [1] endDate
'archiverArchiveId' => $archiverArchiveId,
'processingStatus' => $processingStatus
'originatorOwnerOrgId' => $originatorOwnerOrgId,
'originatorArchiveId' => $originatorArchiveId,
'originatingDate' => $originatingDate,
'filePlanPosition' => $filePlanPosition,
'hasParent' => $hasParent,
'partialRetentionRule' => $partialRetentionRule,
'retentionRuleCode' => $retentionRuleCode,
'depositStartDate' => $depositStartDate,
'depositEndDate' => $depositEndDate,
'originatingDate' => [$originatingStartDate, $originatingEndDate], // [0] startDate, [1] endDate
'archiverArchiveId' => $archiverArchiveId,
'processingStatus' => $processingStatus
];
if (!$filePlanPosition) {
......@@ -977,11 +977,11 @@ trait archiveAccessTrait
$queryParts = [];
if (!empty($args['archiveName'])) {
$queryParts[] = "archiveName='*".$args['archiveName']."*'";
$queryParts[] = "archiveName='*" . $args['archiveName'] . "*'";
}
if (!empty($args['profileReference'])) {
$queryParts['archivalProfileReference'] = "archivalProfileReference = :archivalProfileReference";
$queryParams['archivalProfileReference']=$args['profileReference'];
$queryParams['archivalProfileReference'] = $args['profileReference'];
}
if (!empty($args['agreementReference'])) {
$queryParts['archivalAgreementReference'] = "archivalAgreementReference=:archivalAgreementReference";
......@@ -1016,7 +1016,7 @@ trait archiveAccessTrait
}
if (!empty($args['finalDisposition'])) {
$queryParts['finalDisposition'] = "finalDisposition= :finalDisposition";
$queryParams['finalDisposition'] =$args['finalDisposition'];
$queryParams['finalDisposition'] = $args['finalDisposition'];
}
if (!empty($args['originatorOrgRegNumber'])) {
$queryParts[] = "originatorOrgRegNumber= :originatorOrgRegNumber";
......@@ -1136,15 +1136,32 @@ trait archiveAccessTrait
}
}
$queryParts['originator'] = "originatorOrgRegNumber=['".implode("', '", $userServiceOrgRegNumbers)."']";
$queryParts['archiver'] = "archiverOrgRegNumber=['".implode("', '", $userServiceOrgRegNumbers)."']";
$queryParts['user'] = "(userOrgRegNumbers = '".$currentService->registrationNumber."' OR userOrgRegNumbers = '".$currentService->registrationNumber." *' OR userOrgRegNumbers = '* ".$currentService->registrationNumber." *' OR userOrgRegNumbers = '* ".$currentService->registrationNumber."')";
$queryParts['originator'] = "originatorOrgRegNumber=['" . implode("', '", $userServiceOrgRegNumbers) . "']";
$queryParts['archiver'] = "archiverOrgRegNumber=['" . implode("', '", $userServiceOrgRegNumbers) . "']";
$queryParts['user'] = "(userOrgRegNumbers = '" . $currentService->registrationNumber .
"' OR userOrgRegNumbers = '" . $currentService->registrationNumber .
" *' OR userOrgRegNumbers = '* " . $currentService->registrationNumber .
" *' OR userOrgRegNumbers = '* " . $currentService->registrationNumber . "')";
//$queryParts['depositor'] = "depositorOrgRegNumber=['". implode("', '", $userServiceOrgRegNumbers) ."']";
$queryParts['accessRule'] = "(originatorOwnerOrgId = '".$currentService->ownerOrgId
."' AND (accessRuleComDate <= '$currentDateString'))";
$discoverableProfiles = $this->archivalProfileController->index(null, 'isDiscoverable=true');
return "(".implode(" OR ", $queryParts).")";
$discoverableProfilesIdentifiers = array_map(
function ($profile) {
return "'" . $profile->reference . "'";
},
$discoverableProfiles
);
$queryParts['accessRule'] = "(originatorOwnerOrgId = '" . $currentService->ownerOrgId
. "' AND (
(accessRuleComDate <= '$currentDateString')
OR (archivalProfileReference = [" . \laabs\implode(", ", $discoverableProfilesIdentifiers) . "])
)
)";
return "(" . implode(" OR ", $queryParts) . ")";
}
/**
......@@ -1353,15 +1370,19 @@ trait archiveAccessTrait
$userServices[] = $currentUserService->registrationNumber;
// OWNER access
if (!is_null($currentUserService->orgRoleCodes)
&& \laabs\in_array('owner', $currentUserService->orgRoleCodes)) {
if (
!is_null($currentUserService->orgRoleCodes)
&& \laabs\in_array('owner', $currentUserService->orgRoleCodes)
) {
return true;
}
// ARCHIVER access
if (!is_null($currentUserService->orgRoleCodes)
if (
!is_null($currentUserService->orgRoleCodes)
&& \laabs\in_array('archiver', $currentUserService->orgRoleCodes)
&& $archive->archiverOrgRegNumber === $currentUserService->registrationNumber) {
&& $archive->archiverOrgRegNumber === $currentUserService->registrationNumber
) {
return true;
}
......@@ -1373,9 +1394,13 @@ trait archiveAccessTrait
}
// COMMUNICATION ACCESS
if (!is_null($archive->accessRuleComDate)
&& ($isCommunication)
&& ($archive->accessRuleComDate <= $currentDate)) {
if (
$isCommunication
&& (
is_null($archive->accessRuleComDate)
|| $archive->accessRuleComDate <= $currentDate
)
) {
return true;
}
......
......@@ -140,4 +140,11 @@ class archivalProfile
* @var json
*/
public $processingStatuses;
/**
* Is property discoverable by services outside of owner service
*
* @var boolean
*/
public $isDiscoverable;
}
......@@ -158,6 +158,13 @@ class archivalProfile
*/
public $processingStatuses;
/**
* Is property discoverable by services outside of owner service
*
* @var boolean
*/
public $isDiscoverable;
/**
* Get the properties
* @return array
......@@ -176,4 +183,4 @@ class archivalProfile
return $this->name;
}
}
\ No newline at end of file
}
......@@ -60,6 +60,7 @@ CREATE TABLE "recordsManagement"."archivalProfile"
"fileplanLevel" text,
"processingStatuses" jsonb,
"isRetentionLastDeposit" boolean default false,
"isDiscoverable" boolean default false,
PRIMARY KEY ("archivalProfileId"),
UNIQUE ("reference"),
FOREIGN KEY ("accessRuleCode")
......
......@@ -205,8 +205,12 @@ class archive
$archive->disposable = true;
}
if (empty($archive->disposalDate)
&& (empty($archive->retentionRuleCode) || empty($archive->retentionDuration))
if (
empty($archive->disposalDate)
&& (
empty($archive->retentionRuleCode)
|| empty($archive->retentionDuration)
)
) {
$archive->noRetention = true;
}
......@@ -215,7 +219,8 @@ class archive
$archive->originatorOrgName = $orgsByRegNumber[$archive->originatorOrgRegNumber]->displayName;
try {
if ($archive->status == 'disposed'
if (
$archive->status == 'disposed'
|| $archive->status == 'error'
|| $archive->status == 'restituted'
|| $archive->status == 'transfered'
......@@ -228,7 +233,6 @@ class archive
$archive->hasRights = false;
}
}
$archive->isCommunicable = '2';
if ($archive->accessRuleComDate) {
$communicationDelay = $archive->accessRuleComDate->diff(\laabs::newTimestamp());
......@@ -248,8 +252,10 @@ class archive
}
$hasReachMaxResults = false;
if (isset(\laabs::configuration('presentation.maarchRM')['maxResults'])
&& count($archives) >= \laabs::configuration('presentation.maarchRM')['maxResults']) {
if (
isset(\laabs::configuration('presentation.maarchRM')['maxResults'])
&& count($archives) >= \laabs::configuration('presentation.maarchRM')['maxResults']
) {
$hasReachMaxResults = true;
}
......
......@@ -279,4 +279,7 @@ msgid "cannot be recursively called"
msgstr "ne peut pas être appelé récursivement"
msgid "Update when a file is added"
msgstr "Mettre à jour au versement d'une pièce"
\ No newline at end of file
msgstr "Mettre à jour au versement d'une pièce"
msgid "Discoverable"
msgstr "Autorise la découverte (hors producteur)"
......@@ -1337,3 +1337,6 @@ msgstr "Veuillez choisir le type de critère supplémentaire à ajouter"
msgid "Add filter"
msgstr "Ajouter le filtre"
msgid "Search in other services"
msgstr "Rechercher dans d'autres services"
......@@ -3119,7 +3119,8 @@ tbody.collapse.in {
overflow: hidden;
background-color: #e5e5e5;
}
.dropdown-menu > li > a {
.dropdown-menu > li > a,
.dropdown-menu > span > li > a {
display: block;
padding: 3px 20px;
clear: both;
......@@ -3129,14 +3130,19 @@ tbody.collapse.in {
white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
.dropdown-menu > li > a:focus,
.dropdown-menu > span > li > a:hover,
.dropdown-menu > span > li > a:focus {
text-decoration: none;
color: #262626;
background-color: #f5f5f5;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
.dropdown-menu > .active > a:focus,
.dropdown-menu > .active > span > a,
.dropdown-menu > .active > span > a:hover,
.dropdown-menu > .active > span > a:focus {
color: #ffffff;
text-decoration: none;
outline: 0;
......@@ -3144,11 +3150,16 @@ tbody.collapse.in {
}
.dropdown-menu > .disabled > a,
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
.dropdown-menu > .disabled > a:focus,
.dropdown-menu > .disabled > span > a,
.dropdown-menu > .disabled > span > a:hover,
.dropdown-menu > .disabled > span > a:focus {
color: #999999;
}
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
.dropdown-menu > .disabled > a:focus,
.dropdown-menu > .disabled > span > a:hover,
.dropdown-menu > .disabled > span > a:focus {
text-decoration: none;
background-color: transparent;
background-image: none;
......
......@@ -189,4 +189,10 @@
return false;
});
$('#acceptArchiveWithoutProfile').bootstrapToggle({
on: 'Oui',
off: 'Non',
});
</script>
......@@ -111,6 +111,11 @@
});
$('#allowUserIndexes').bootstrapToggle({
on: 'Oui',
off: 'Non',
});
// Properties list
$('#archiveDescription').on('click', '.deleteProperty', function(e) {
//e.preventDefault();
......
......@@ -33,7 +33,9 @@ file that was distributed with this source code.
<div class="form-group">
<label class="col-md-3 control-label">Identifier <span style="color: red">*</span></label>
<div class="col-md-9">
<input type="text" class="form-control" id="reference" name="reference" placeholder="Reference" disabled="[?merge archivalProfile.reference.ifne('').then('disabled') ?]"/>
<input type="text" class="form-control" id="reference" name="reference"
placeholder="Reference"
disabled="[?merge archivalProfile.reference.ifne('').then('disabled') ?]" />
</div>
</div>
<div class="form-group">
......@@ -45,7 +47,8 @@ file that was distributed with this source code.
<div class="form-group">
<label class="col-md-3 control-label">Description</label>
<div class="col-md-9">
<textarea class="form-control" id="description" name="description" placeholder="Description"></textarea>
<textarea class="form-control" id="description" name="description"
placeholder="Description"></textarea>
</div>
</div>
<?merge archivalProfile.type.ifeq('1').not() ?>
......@@ -56,13 +59,24 @@ file that was distributed with this source code.
<input type="checkbox" id="fileplanLevelToggle">
</div>
</div>
<div class="form-group">
<label class="col-md-3 control-label"
title="Permet aux utilisateurs des services autres que producteurs et gestionnaires de rechercher les archives du profil, sans pour autant pourvoir les consulter">Discoverable
<span style="font-size:16px;color:#199cd5">&#x1F6C8</span>
</label>
<div class="col-md-9">
<input type='hidden' id="isDiscoverable" name="isDiscoverable">
<input type="checkbox" data-toggle="toggle" id="isDiscoverableToggle">
</div>
</div>
</div>
<?hinclude recordsManagement/archivalProfile/tabs.html ?>
</div>
<div class="clearfix">
<div class="pull-right">
<button type="button" id="archivalProfileCancelBtn" class="btn btn-warning"><i class="fa fa-undo">&nbsp;</i>Cancel</button>
<button type="button" id="archivalProfileCancelBtn" class="btn btn-warning"><i
class="fa fa-undo">&nbsp;</i>Cancel</button>
<button type="button" id="save" class="btn btn-success" title="Save">
<?merge archivalProfile.archivalProfileId.ifne('') ?>
<span><i class="fa fa-save">&nbsp;</i>Save</span>
......@@ -168,7 +182,7 @@ file that was distributed with this source code.
}
//RegExp identifier field ( = ArchivalProfile.reference)
var reg =/^[A-Za-z][A-Za-z0-9_-]*$/;
var reg = /^[A-Za-z][A-Za-z0-9_-]*$/;
var identifier = parameters.archivalProfile.reference;
if (!reg.test(identifier)) {
gritter.show($("#identifier_format_error").text(), false);
......@@ -200,6 +214,7 @@ file that was distributed with this source code.
reference: $('#reference').val(),
name: $('#name').val(),
fileplanLevel: $("#fileplanLevel").val(),
isDiscoverable: $("#isDiscoverableToggle").prop("checked"),
descriptionClass: $('#descriptionClass').val(),
retentionStartDate: $('#startDate option:selected').val(),
description: $('#description').val(),
......@@ -215,9 +230,11 @@ file that was distributed with this source code.
serializedObject.processingStatuses = {};
var lists = $('#processingStatuses').find("[name='processingStatus']");
lists.each(function (index, value) {
serializedObject.processingStatuses[$(value).find("[name='statuscode']").text().trim()] =
serializedObject.processingStatuses[$(value).find("[name='statuscode']").text()
.trim()] =
JSON.parse($(value).find("[name='statusinfo']").text().trim());
serializedObject.processingStatuses[$(value).find("[name='statuscode']").text().trim()].position =
serializedObject.processingStatuses[$(value).find("[name='statuscode']").text()
.trim()].position =
index;
});
......@@ -234,9 +251,9 @@ file that was distributed with this source code.
}
serializedObject.archiveDescription = PropertiesList.serialize();
if ($("#fileplanLevel").val() != 'item') {
serializedObject.acceptArchiveWithoutProfile = $('#acceptArchiveWithoutProfile').prop("checked");
serializedObject.acceptArchiveWithoutProfile = $('#acceptArchiveWithoutProfile').prop(
"checked");
serializedObject.containedProfiles = ArchiveStructure.serialize();
} else {
serializedObject.acceptArchiveWithoutProfile = false;
......@@ -251,6 +268,11 @@ file that was distributed with this source code.
load('/archivalProfiles');
});
$('#isDiscoverableToggle').bootstrapToggle({
on: 'Oui',
off: 'Non',
});
$("#contain").ready(function () {
$('#fileplanLevelToggle').bootstrapToggle({
on: $('#text_item'),
......@@ -262,6 +284,9 @@ file that was distributed with this source code.
$("#contentsTabBtn").addClass('hide');
}
if ($('#isDiscoverable').val() == '1') {
$('#isDiscoverableToggle').bootstrapToggle('on');
}
$("#archivalProfileNavControl").find('a').first().click();
ArchivalProfile.loadRetentionRule();
......@@ -344,4 +369,8 @@ file that was distributed with this source code.
$('#updateRetentionRuleOnDeposit').removeClass('hide');
}
});
</script>
$('#isDiscoverableToggle').on('change', function (e) {
$("#isDiscoverable").val($(this).prop('checked'));
});
</script>
\ No newline at end of file
......@@ -71,4 +71,10 @@
</small>
</div>
</div>
</div>
\ No newline at end of file
</div>
<script type="text/javascript">
$('#isRetentionLastDepositToggle').bootstrapToggle({
on: 'Oui',
off: 'Non',
});
</script>
\ No newline at end of file
......@@ -115,6 +115,7 @@ var ArchivesAction = {
var relevant = null;
var ids = [];
var names = [];
var hasNoRightsCount = 0;
if (status == '') {
dataSelector.push('[data-archive-status]');
......@@ -146,6 +147,9 @@ var ArchivesAction = {
$.each(relevant, function () {
ids.push($(this).val());
id = '#'+ $(this).val();
if ($(id).attr('data-hasRights') == 'false') {
hasNoRightsCount++;
}
names.push($(id).attr('name'));
});
......@@ -153,7 +157,8 @@ var ArchivesAction = {
selected: $('input[data-archive-status]:checked').length,
relevant: relevant.length,
ids: ids,
names: names
names: names,
hasNoRightsCount: hasNoRightsCount
};
if (selectedArchives.selected == 0) {
......
<ul data-translate-catalog="recordsManagement/messages" class="dropdown-menu actionMenu" data-archiveid='[?merge .archiveId?]' aria-labelledby="actionsModify">
<?merge hasModificationPrivilege.bool() ?>
<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 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() ?>
<li class="unfreeze [?merge .status.ifne('frozen').then('hide', '') ?]" data-type="unfreeze"><a href="#"><i class="fa fa-unlock">&nbsp;</i>&nbsp;Unfreeze</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="divider"></li>
<?merge hasDeliveryPrivilege.bool() ?>
<?merge .hasRights.bool() ?>
<span>
<?merge hasModificationPrivilege.bool() ?>
<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 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() ?>
<li class="unfreeze [?merge .status.ifne('frozen').then('hide', '') ?]" data-type="unfreeze"><a href="#"><i class="fa fa-unlock">&nbsp;</i>&nbsp;Unfreeze</a></li>
<?merge hasModificationPrivilege.bool() ?>
<li class="divider"></li>
<?merge hasModificationRequestPrivilege.bool() ?>
<li class="requestModification" data-type="requestModification"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Request a modification</a></li>
<?merge hasRestitutionPrivilege.bool() ?>
<li class="flagForRestitution" data-type="flagForRestitution"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Flag for restitution</a></li>
<?merge hasDestructionPrivilege.bool() ?>
<li class="flagForDestruction [?merge .status.ifeq('disposable').then('hide', '') ?]" data-type="flagForDestruction"><a href="#"><i class="fa fa-trash">&nbsp;</i>&nbsp;Flag for destruction</a></li>
<?merge hasDestructionCancelPrivilege.bool() ?>
<li class="cancelDestruction [?merge .status.ifne('disposable').then('hide', '') ?]" data-type="cancelDestruction"><a href="#"><i class="fa fa-undo">&nbsp;</i>&nbsp;Cancel destruction request</a></li>
<?merge hasTransferPrivilege.bool() ?>
<li class="flagForTransfer" data-type="flagForTransfer"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Flag for transfer</a></li>
<li class="divider"></li>
<?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>
<?merge hasModificationRequestPrivilege.bool() ?>
<li class="requestModification" data-type="requestModification"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Request a modification</a></li>
<?merge hasRestitutionPrivilege.bool() ?>
<li class="flagForRestitution" data-type="flagForRestitution"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Flag for restitution</a></li>
<?merge hasDestructionPrivilege.bool() ?>
<li class="flagForDestruction [?merge .status.ifeq('disposable').then('hide', '') ?]" data-type="flagForDestruction"><a href="#"><i class="fa fa-trash">&nbsp;</i>&nbsp;Flag for destruction</a></li>
<?merge hasDestructionCancelPrivilege.bool() ?>
<li class="cancelDestruction [?merge .status.ifne('disposable').then('hide', '') ?]" data-type="cancelDestruction"><a href="#"><i class="fa fa-undo">&nbsp;</i>&nbsp;Cancel destruction request</a></li>
<?merge hasTransferPrivilege.bool() ?>
<li class="flagForTransfer" data-type="flagForTransfer"><a href="#"><i class="fa fa-upload">&nbsp;</i>&nbsp;Flag for transfer</a></li>
<li class="divider"></li>
<?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>
</ul>