diff --git a/app/config/schema/schema.json b/app/config/schema/schema.json
index f7e5b234e..8a46da7f2 100644
--- a/app/config/schema/schema.json
+++ b/app/config/schema/schema.json
@@ -36,10 +36,7 @@
"id": {},
"description": {},
"table_name": { "type": "string", "size": 128, "notnull": true },
- "status": {},
- "referenceid_method": { "type": "string", "size": 2 },
- "referenceid_start": { "type": "integer" },
- "referenceid_prefix": { "type": "string", "size": 32 }
+ "status": {}
},
"indexes": {
"matchgrids_i1": {
@@ -51,6 +48,23 @@
"changelog": false
},
+ "matchgrid_settings": {
+ "columns": {
+ "id": {},
+ "matchgrid_id": {},
+ "referenceid_method": { "type": "string", "size": 2 },
+ "referenceid_start": { "type": "integer" },
+ "referenceid_prefix": { "type": "string", "size": 32 },
+ "notification_email": { "type": "string", "size": 80 }
+ },
+ "indexes": {
+ "matchgrid_settings_i1": {
+ "columns": [ "matchgrid_id" ]
+ }
+ },
+ "changelog": false
+ },
+
"permissions": {
"columns": {
"id": {},
diff --git a/app/src/Controller/Component/AuthorizationComponent.php b/app/src/Controller/Component/AuthorizationComponent.php
index f90259ab8..92bc94896 100644
--- a/app/src/Controller/Component/AuthorizationComponent.php
+++ b/app/src/Controller/Component/AuthorizationComponent.php
@@ -184,18 +184,19 @@ public function menuPermissions($username, $matchgridId=null) {
return [
// Manage configuration of the current matchgrid
- 'api_users' => $platformAdmin || $mgAdmin,
- 'attribute_groups' => $platformAdmin || $mgAdmin,
- 'attribute_maps' => $platformAdmin || $mgAdmin,
- 'attributes' => $platformAdmin || $mgAdmin,
- 'rules' => $platformAdmin || $mgAdmin,
- 'systems_of_record' => $platformAdmin || $mgAdmin,
+ 'api_users' => $platformAdmin || $mgAdmin,
+ 'attribute_groups' => $platformAdmin || $mgAdmin,
+ 'attribute_maps' => $platformAdmin || $mgAdmin,
+ 'attributes' => $platformAdmin || $mgAdmin,
+ 'matchgrid_settings' => $platformAdmin || $mgAdmin,
+ 'rules' => $platformAdmin || $mgAdmin,
+ 'systems_of_record' => $platformAdmin || $mgAdmin,
// Permissions specific to a matchgrid
- 'gridroles' => $perms['matchgrids'],
+ 'gridroles' => $perms['matchgrids'],
// Overall permission to manage the matchgrids
- 'matchgrids' => $platformAdmin,
+ 'matchgrids' => $platformAdmin,
// Overall permission to manage permissions
- 'permissions' => $platformAdmin
+ 'permissions' => $platformAdmin
];
}
}
diff --git a/app/src/Controller/MatchgridSettingsController.php b/app/src/Controller/MatchgridSettingsController.php
new file mode 100644
index 000000000..8ddaee495
--- /dev/null
+++ b/app/src/Controller/MatchgridSettingsController.php
@@ -0,0 +1,101 @@
+ [
+ 'MatchgridSetting.matchgrid_id' => 'asc'
+ ]
+ ];
+
+ /**
+ * Callback run prior to the view rendering.
+ *
+ * @since COmanage Match v1.0.0
+ * @param Event $event Cake Event
+ */
+
+ public function beforeRender(\Cake\Event\Event $event) {
+ parent::beforeRender($event);
+
+ // Override page title
+ if($this->request->getParam('action') == 'edit') {
+ $this->set('vv_title', __("match.op.edit.a", [__("match.ct.matchgrid_settings", 1)]));
+ }
+ }
+
+ /**
+ * Handle an index request by checking for an existing CO Setting,
+ * creating it if not present, and then redirecting to edit.
+ *
+ * @since COmanage Match v1.0.0
+ */
+
+ public function index() {
+ if(empty($this->cur_mg->id)) {
+ throw new RuntimeException(__("match.er.mgid"));
+ }
+
+ // Let any exception pass up the stack
+ $id = $this->MatchgridSettings->getIdForMatchgrid($this->cur_mg->id);
+
+ return $this->redirect(['action' => 'edit', $id]);
+ }
+
+ /**
+ * Authorization for this Controller, called by Auth component
+ * - postcondition: $vv_permissions set with calculated permissions for this Controller
+ *
+ * @since COmanage Match v1.0.0
+ * @param Array $user Array of user data
+ * @return Boolean True if authorized for the current action, false otherwise
+ */
+
+ public function isAuthorized(Array $user) {
+ $mgid = isset($this->cur_mg->id) ? $this->cur_mg->id : null;
+
+ $platformAdmin = $this->Authorization->isPlatformAdmin($user['username']);
+
+ $mgAdmin = $this->Authorization->isMatchAdmin($user['username'], $mgid);
+
+ $p = [
+ // No add or delete here
+ 'add' => false,
+ 'delete' => false,
+ 'edit' => $platformAdmin || $mgAdmin,
+ 'index' => $platformAdmin || $mgAdmin,
+ 'view' => false
+ ];
+
+ $this->set('vv_permissions', $p);
+ return $p[$this->request->getParam('action')];
+ }
+}
\ No newline at end of file
diff --git a/app/src/Lib/Identifier/Sequence.php b/app/src/Lib/Identifier/Sequence.php
index 926d70881..aa4d855a8 100644
--- a/app/src/Lib/Identifier/Sequence.php
+++ b/app/src/Lib/Identifier/Sequence.php
@@ -41,13 +41,15 @@ class Sequence extends ReferenceIdService {
*/
public function generate(\App\Model\Entity\Matchgrid $mgConfig, \ADOConnection $dbc) {
+ $MatchgridSettings = TableRegistry::get('MatchgridSettings');
+
// We'll use the matchgrid ID rather than name in the sequence name to avoid
// issues if the matchgrid is renamed for some reason.
$seq = "mg_seq_" . (string)$mgConfig->id;
- $prefix = $mgConfig->referenceid_prefix ?: "";
+ $prefix = $MatchgridSettings->getReferenceIdPrefix($mgConfig->id);
- $refId = $prefix . (string)$dbc->genId($seq, $mgConfig->referenceid_start);
+ $refId = $prefix . (string)$dbc->genId($seq, $MatchgridSettings->getReferenceIdStart($mgConfig->id));
return $refId;
}
diff --git a/app/src/Lib/Match/MatchService.php b/app/src/Lib/Match/MatchService.php
index c5243ba2e..8a5ac52ce 100644
--- a/app/src/Lib/Match/MatchService.php
+++ b/app/src/Lib/Match/MatchService.php
@@ -105,7 +105,9 @@ public function attachReferenceId(string $sor, string $sorid, AttributeManager $
*/
protected function generateReferenceId() {
- if($this->mgConfig->referenceid_method == ReferenceIdEnum::Sequence) {
+ $MatchgridSettings = TableRegistry::get('MatchgridSettings');
+
+ if($MatchgridSettings->getReferenceIdMethod($this->mgConfig->id) == ReferenceIdEnum::Sequence) {
$IdService = new \App\Lib\Identifier\Sequence;
} else {
$IdService = new \App\Lib\Identifier\Uuid;
diff --git a/app/src/Locale/en_US/default.po b/app/src/Locale/en_US/default.po
index 7e81b0886..0171012c6 100644
--- a/app/src/Locale/en_US/default.po
+++ b/app/src/Locale/en_US/default.po
@@ -96,6 +96,9 @@ msgstr "{0,plural,=1{Attribute Map} other{Attribute Maps}}"
msgid "match.ct.attributes"
msgstr "{0,plural,=1{Attribute} other{Attributes}}"
+msgid "match.ct.matchgrid_settings"
+msgstr "{0,plural,=1{Matchgrid Settings} other{Matchgrid Settings}}"
+
msgid "match.ct.matchgrids"
msgstr "{0,plural,=1{Matchgrid} other{Matchgrids}}"
@@ -293,6 +296,15 @@ msgstr "Label"
msgid "match.fd.name"
msgstr "Name"
+msgid "match.fd.notification_email"
+msgstr "Notification Email"
+
+msgid "match.fd.notification_email.desc"
+msgstr "On potential match, notify this address of the request requiring resolution"
+
+msgid "match.fd.MatchgridSettings.notification_email.desc"
+msgstr "On potential match, notify this address of the request requiring resolution (used if no SOR specific value is set)"
+
msgid "match.fd.null_equivalents"
msgstr "Null Equivalents"
diff --git a/app/src/Model/Entity/MatchgridSetting.php b/app/src/Model/Entity/MatchgridSetting.php
new file mode 100644
index 000000000..3d7c02e0f
--- /dev/null
+++ b/app/src/Model/Entity/MatchgridSetting.php
@@ -0,0 +1,40 @@
+ true,
+ 'id' => false,
+ 'slug' => false,
+ ];
+}
\ No newline at end of file
diff --git a/app/src/Model/Table/MatchgridSettingsTable.php b/app/src/Model/Table/MatchgridSettingsTable.php
new file mode 100644
index 000000000..cdc595b01
--- /dev/null
+++ b/app/src/Model/Table/MatchgridSettingsTable.php
@@ -0,0 +1,215 @@
+ null,
+ 'referenceid_method' => ReferenceIdEnum::UUID,
+ 'referenceid_start' => 1,
+ 'referenceid_prefix' => "",
+ ];
+
+ /**
+ * Perform Cake Model initialization.
+ *
+ * @since COmanage Match v1.0.0
+ * @param array $config Configuration options passed to constructor
+ */
+
+ public function initialize(array $config) {
+ // Timestamp behavior handles created/modified updates
+ $this->addBehavior('Timestamp');
+
+ // Define associations
+ $this->belongsTo('Matchgrids');
+
+ $this->setDisplayField('matchgrid_id');
+
+ $this->setPrimaryLink('matchgrid_id');
+ $this->setRequiresMatchgrid(true);
+
+ $this->setAutoViewVars([
+ 'referenceidMethods' => [
+ 'type' => 'enum',
+ 'class' => 'ReferenceIdEnum'
+ ]
+ ]);
+ }
+
+ /**
+ * Get the MatchgridSetting row ID for a given Matchgrid, creating it if not
+ * already present.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ * @return int MatchgridSetting ID
+ */
+
+ public function getIdForMatchgrid(int $matchgridId) {
+ try {
+ $obj = $this->find()->where(["matchgrid_id" => $matchgridId])->firstOrFail();
+ }
+ catch(\Cake\Datasource\Exception\RecordNotFoundException $e) {
+ // No current Matchgrid Settings object for this Matchgrid, create one
+
+ $obj = $this->newEntity(["matchgrid_id" => $matchgridId]);
+
+ $this->MatchgridSettings->save($obj);
+ }
+
+ return $obj->id;
+ }
+
+ /**
+ * Get the Matchgrid notification email.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ */
+
+ public function getNotificationEmail(int $matchgridId) {
+ return $this->lookupValue($matchgridId, 'notification_email');
+ }
+
+ /**
+ * Get the Matchgrid Reference ID prefix.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ */
+
+ public function getReferenceIdPrefix(int $matchgridId) {
+ return $this->lookupValue($matchgridId, 'referenceid_prefix');
+ }
+
+ /**
+ * Get the Matchgrid Reference ID start.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ */
+
+ public function getReferenceIdStart(int $matchgridId) {
+ return $this->lookupValue($matchgridId, 'referenceid_start');
+ }
+
+ /**
+ * Get the Matchgrid Reference ID method.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ */
+
+ public function getReferenceIdMethod(int $matchgridId) {
+ return $this->lookupValue($matchgridId, 'referenceid_method');
+ }
+
+ /**
+ * Obtain a single Matchgrid setting.
+ *
+ * @since COmanage Match v1.0.0
+ * @param int $matchgridId Matchgrid ID
+ * @param string $field Field name to retrieve, corresponding to column/field name
+ */
+
+ protected function lookupValue(int $matchgridId, string $field) {
+ $value = null;
+
+ try {
+ $settings = $this->find()->where(["matchgrid_id" => $matchgridId])->firstOrFail();
+
+ if(isset($settings->$field)) {
+ return $settings->$field;
+ }
+ }
+ catch(\Cake\Datasource\Exception\RecordNotFoundException $e) {
+ // No settings for this Matchgrid, use default value
+ }
+ // Let other exceptions pass up the stack
+
+ return $this->defaultSettings[$field];
+ }
+
+ /**
+ * Set validation rules.
+ *
+ * @since COmanage Match v1.0.0
+ * @param Validator $validator Validator
+ * @return $validator Validator
+ */
+
+ public function validationDefault(Validator $validator) {
+ $validator->add(
+ 'matchgrid_id',
+ 'content',
+ [ 'rule' => 'isInteger' ]
+ );
+ $validator->notEmpty('matchgrid_id');
+
+ $validator->add(
+ 'referenceid_method',
+ 'content',
+ [ 'rule' => [ 'inList', [
+ ReferenceIdEnum::Sequence,
+ ReferenceIdEnum::UUID
+ ] ] ]
+ );
+ $validator->notEmpty('referenceid_method');
+
+ $validator->add(
+ 'referenceid_start',
+ 'content',
+ [ 'rule' => [ 'range', 1, null ] ]
+ );
+ $validator->allowEmpty('referenceid_start');
+
+ $validator->add(
+ 'referenceid_prefix',
+ 'content',
+ [ 'rule' => [ 'maxLength', 32 ] ]
+ );
+ $validator->allowEmpty('referenceid_prefix');
+
+ return $validator;
+ }
+}
\ No newline at end of file
diff --git a/app/src/Model/Table/MatchgridsTable.php b/app/src/Model/Table/MatchgridsTable.php
index 7835bfd2d..3cec24b1f 100644
--- a/app/src/Model/Table/MatchgridsTable.php
+++ b/app/src/Model/Table/MatchgridsTable.php
@@ -34,7 +34,6 @@
use Cake\Validation\Validator;
use \App\Lib\Enum\ConfidenceModeEnum;
-use \App\Lib\Enum\ReferenceIdEnum;
use \App\Lib\Enum\StatusEnum;
use \App\Lib\Match\MatchgridBuilder;
@@ -60,6 +59,8 @@ public function initialize(array $config) {
// since it uses deleteAll(). ->setCascadeCallbacks() loads associated data
// and can therefore reach lower levels of association. This is pretty poorly
// documented and explained.
+ $this->hasOne('MatchgridSettings')
+ ->setDependent(true);
$this->hasMany('ApiUsers')
->setDependent(true);
$this->hasMany('Attributes')
@@ -83,10 +84,6 @@ public function initialize(array $config) {
$this->setDisplayField('table_name');
$this->setAutoViewVars([
- 'referenceidMethods' => [
- 'type' => 'enum',
- 'class' => 'ReferenceIdEnum'
- ],
'statuses' => [
'type' => 'enum',
'class' => 'StatusEnum'
@@ -201,30 +198,6 @@ public function validationDefault(Validator $validator) {
);
$validator->notEmpty('status');
- $validator->add(
- 'referenceid_method',
- 'content',
- [ 'rule' => [ 'inList', [
- ReferenceIdEnum::Sequence,
- ReferenceIdEnum::UUID
- ] ] ]
- );
- $validator->notEmpty('referenceid_method');
-
- $validator->add(
- 'referenceid_start',
- 'content',
- [ 'rule' => [ 'range', 1, null ] ]
- );
- $validator->allowEmpty('referenceid_start');
-
- $validator->add(
- 'referenceid_prefix',
- 'content',
- [ 'rule' => [ 'maxLength', 32 ] ]
- );
- $validator->allowEmpty('referenceid_prefix');
-
return $validator;
}
}
\ No newline at end of file
diff --git a/app/src/Template/Element/menuMain.ctp b/app/src/Template/Element/menuMain.ctp
index d357af8e1..5cefc0753 100644
--- a/app/src/Template/Element/menuMain.ctp
+++ b/app/src/Template/Element/menuMain.ctp
@@ -34,12 +34,13 @@
// Matchgrid specific models
$models = [
- 'api_users' => 'vpn_key',
- 'attributes' => 'edit',
- 'attribute_groups' => 'storage',
- 'attribute_maps' => 'swap_horiz',
- 'rules' => 'assignment',
- 'systems_of_record' => 'gavel',
+ 'matchgrid_settings' => 'settings',
+ 'api_users' => 'vpn_key',
+ 'attributes' => 'edit',
+ 'attribute_groups' => 'storage',
+ 'attribute_maps' => 'swap_horiz',
+ 'rules' => 'assignment',
+ 'systems_of_record' => 'gavel',
];
foreach($models as $model => $icon) {
diff --git a/app/src/Template/Email/text/potential_match.ctp b/app/src/Template/Email/text/potential_match.ctp
new file mode 100644
index 000000000..c3771f956
--- /dev/null
+++ b/app/src/Template/Email/text/potential_match.ctp
@@ -0,0 +1,38 @@
+
+
+
+
+?>
+A new potential match is available for your review. You may access the
+pending request at this URL:
+
+= $vv_pending_url ?>
+
\ No newline at end of file
diff --git a/app/src/Template/MatchgridSettings/fields.inc b/app/src/Template/MatchgridSettings/fields.inc
new file mode 100644
index 000000000..809c6f281
--- /dev/null
+++ b/app/src/Template/MatchgridSettings/fields.inc
@@ -0,0 +1,66 @@
+
+
+Field->control('referenceid_method',
+ ['empty' => true,
+ 'onChange' => 'fields_update_gadgets();']);
+
+ print $this->Field->control('referenceid_start',
+ ['default' => 1001]);
+
+ print $this->Field->control('referenceid_prefix',
+ [],
+ false);
+
+ print $this->Field->control('notification_email', [], true);
+}
diff --git a/app/src/Template/Matchgrids/fields.inc b/app/src/Template/Matchgrids/fields.inc
index d39a8e65b..e8e992c2a 100644
--- a/app/src/Template/Matchgrids/fields.inc
+++ b/app/src/Template/Matchgrids/fields.inc
@@ -25,30 +25,6 @@
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/
-use \App\Lib\Enum\ReferenceIdEnum;
-?>
-
-Field->control('table_name');
@@ -57,15 +33,4 @@ if($action == 'add' || $action == 'edit') {
print $this->Field->control('status',
['empty' => false]);
-
- print $this->Field->control('referenceid_method',
- ['empty' => true,
- 'onChange' => 'fields_update_gadgets();']);
-
- print $this->Field->control('referenceid_start',
- ['default' => 1001]);
-
- print $this->Field->control('referenceid_prefix',
- [],
- false);
}