diff --git a/CANCELED b/CANCELED
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a4fc1151955..b9c75f69d4c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,7 @@ changes in the following format: PR #1234***
#### Bug Fixes
- Fix examiner site display (PR #8967)
- bvl_feedback updates in real-time (PR #8966)
+- DoB and DoD format respected in candidate parameters (PR #9001)
## LORIS 25.0 (Release Date: ????-??-??)
### Core
diff --git a/SQL/0000-00-00-schema.sql b/SQL/0000-00-00-schema.sql
index 5e15eba00d9..979a87e47c3 100644
--- a/SQL/0000-00-00-schema.sql
+++ b/SQL/0000-00-00-schema.sql
@@ -2278,7 +2278,7 @@ CREATE TABLE `consent` (
CREATE TABLE `candidate_consent_rel` (
`CandidateID` int(6) NOT NULL,
`ConsentID` integer unsigned NOT NULL,
- `Status` enum('yes','no') DEFAULT NULL,
+ `Status` enum('yes','no', 'not_applicable') DEFAULT NULL,
`DateGiven` date DEFAULT NULL,
`DateWithdrawn` date DEFAULT NULL,
CONSTRAINT `PK_candidate_consent_rel` PRIMARY KEY (`CandidateID`,`ConsentID`),
@@ -2294,7 +2294,7 @@ CREATE TABLE `candidate_consent_history` (
`PSCID` varchar(255) NOT NULL,
`ConsentName` varchar(255) NOT NULL,
`ConsentLabel` varchar(255) NOT NULL,
- `Status` enum('yes','no') DEFAULT NULL,
+ `Status` enum('yes','no', 'not_applicable') DEFAULT NULL,
`EntryStaff` varchar(255) DEFAULT NULL,
CONSTRAINT `PK_candidate_consent_history` PRIMARY KEY (`CandidateConsentHistoryID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/SQL/New_patches/2023-06-06-add_NA_to_consent_status.sql b/SQL/New_patches/2023-06-06-add_NA_to_consent_status.sql
new file mode 100644
index 00000000000..185e13b8a06
--- /dev/null
+++ b/SQL/New_patches/2023-06-06-add_NA_to_consent_status.sql
@@ -0,0 +1,2 @@
+ALTER TABLE candidate_consent_rel MODIFY COLUMN `Status` enum('yes', 'no', 'not_applicable') DEFAULT NULL;
+ALTER TABLE candidate_consent_history MODIFY COLUMN `Status` enum('yes', 'no', 'not_applicable') DEFAULT NULL;
\ No newline at end of file
diff --git a/a b/a
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/modules/candidate_list/php/candidatelistrowprovisioner.class.inc b/modules/candidate_list/php/candidatelistrowprovisioner.class.inc
index 33d2a799411..55ce300b407 100644
--- a/modules/candidate_list/php/candidatelistrowprovisioner.class.inc
+++ b/modules/candidate_list/php/candidatelistrowprovisioner.class.inc
@@ -30,6 +30,7 @@ namespace LORIS\candidate_list;
*/
class CandidateListRowProvisioner extends \LORIS\Data\Provisioners\DBRowProvisioner
{
+ private string $dobFormat;
/**
* Create a CandidateListRowProvisioner, which gets rows for
* the candidate_list menu table.
@@ -43,6 +44,8 @@ class CandidateListRowProvisioner extends \LORIS\Data\Provisioners\DBRowProvisio
if ($config->getSetting("useEDC") === "true") {
$maybeEDC = ", DATE_FORMAT((c.EDC),'%Y-%m-%d') AS EDC";
}
+ $this->dobFormat = $config->getSetting("dobFormat");
+
parent::__construct(
"SELECT
c.PSCID,
@@ -98,6 +101,19 @@ class CandidateListRowProvisioner extends \LORIS\Data\Provisioners\DBRowProvisio
// one of the user's sites.
$cid = new \CenterID($row['RegistrationCenterID']);
$pid = new \ProjectID($row['RegistrationProjectID']);
+ if ($row['DoB'] !== null) {
+ $dob = new \DateTimeImmutable($row['DoB']);
+ switch ($this->dobFormat) {
+ case 'Ym':
+ $row['DoB'] = $dob->format('Y-m');
+ break;
+ case 'Ymd':
+ $row['DoB'] = $dob->format('Y-m-d');
+ break;
+ default:
+ throw new \Exception("Unhandled DoB format: $this->dobFormat");
+ }
+ }
unset($row['RegistrationCenterID']);
unset($row['RegistrationProjectID']);
return new CandidateListRow($row, $cid, $pid);
diff --git a/modules/candidate_parameters/ajax/formHandler.php b/modules/candidate_parameters/ajax/formHandler.php
index f600bfe247f..70783909eac 100644
--- a/modules/candidate_parameters/ajax/formHandler.php
+++ b/modules/candidate_parameters/ajax/formHandler.php
@@ -501,6 +501,10 @@ function editConsentStatusFields(\Database $db)
) { // Withdrawing from 'yes' status required consent date
// and withdrawal date
$validated = true;
+ } else if ($oldStatus === 'not_applicable' && !empty($date)
+ && empty($withdrawal)
+ ) { // Add N/A option
+ $validated = true;
} else {
http_response_code(400);
echo('Data failed validation. Resolve errors and try again.');
@@ -508,6 +512,19 @@ function editConsentStatusFields(\Database $db)
}
}
break;
+ case 'not_applicable':
+ // If status is N/A, date is not required.
+ if (empty($date) && empty($withdrawal)
+ && ($oldStatus !== 'yes' || $oldStatus !== 'no')
+ ) {
+ $validated = true;
+ } else {
+ http_response_code(400);
+ echo('Answering not applicable to a consent type
+ does not require a date of consent.');
+ return;
+ }
+ break;
default:
// If status is empty, and date fields are also empty,
// validated is still false
diff --git a/modules/candidate_parameters/ajax/getData.php b/modules/candidate_parameters/ajax/getData.php
index d641c730a78..b3fadc87803 100644
--- a/modules/candidate_parameters/ajax/getData.php
+++ b/modules/candidate_parameters/ajax/getData.php
@@ -524,10 +524,22 @@ function getDOBFields(): array
);
$pscid = $candidateData['PSCID'] ?? null;
$dob = $candidateData['DoB'] ?? null;
- $result = [
- 'pscid' => $pscid,
- 'candID' => $candID->__toString(),
- 'dob' => $dob,
+
+ // Get DoB format
+ $factory = \NDB_Factory::singleton();
+ $config = $factory->config();
+
+ $dobFormat = $config->getSetting('dobFormat');
+
+ $dobProcessedFormat = implode("-", str_split($dobFormat, 1));
+ $dobDate = DateTime::createFromFormat('Y-m-d', $dob);
+ $formattedDate = $dobDate ? $dobDate->format($dobProcessedFormat) : null;
+
+ $result = [
+ 'pscid' => $pscid,
+ 'candID' => $candID->__toString(),
+ 'dob' => $formattedDate,
+ 'dobFormat' => $dobFormat,
];
return $result;
}
@@ -549,11 +561,30 @@ function getDODFields(): array
if ($candidateData === null) {
throw new \LorisException("Invalid candidate");
}
+
+ $factory = \NDB_Factory::singleton();
+ $config = $factory->config();
+
+ // Get formatted dod
+ $dodFormat = $config->getSetting('dodFormat');
+
+ $dodProcessedFormat = implode("-", str_split($dodFormat, 1));
+ $dodDate = DateTime::createFromFormat('Y-m-d', $candidateData['DoD']);
+ $dod = $dodDate ? $dodDate->format($dodProcessedFormat) : null;
+
+ // Get formatted dob
+ $dobFormat = $config->getSetting('dobFormat');
+
+ $dobProcessedFormat = implode("-", str_split($dobFormat, 1));
+ $dobDate = DateTime::createFromFormat('Y-m-d', $candidateData['DoB']);
+ $dob = $dobDate ? $dobDate->format($dobProcessedFormat) : null;
+
$result = [
- 'pscid' => $candidateData['PSCID'],
- 'candID' => $candID->__toString(),
- 'dod' => $candidateData['DoD'],
- 'dob' => $candidateData['DoB'],
+ 'pscid' => $candidateData['PSCID'],
+ 'candID' => $candID->__toString(),
+ 'dod' => $dod,
+ 'dob' => $dob,
+ 'dodFormat' => $config->getSetting('dodFormat'),
];
return $result;
}
diff --git a/modules/candidate_parameters/jsx/CandidateDOB.js b/modules/candidate_parameters/jsx/CandidateDOB.js
index 2cda15a7c06..e0914da8a7d 100644
--- a/modules/candidate_parameters/jsx/CandidateDOB.js
+++ b/modules/candidate_parameters/jsx/CandidateDOB.js
@@ -85,6 +85,7 @@ class CandidateDOB extends Component {
return