diff --git a/Application.php b/Application.php
index e5affe31..ce8e3b2d 100644
--- a/Application.php
+++ b/Application.php
@@ -92,14 +92,15 @@ public static function getEmailName($record) {
}
public static function getCitationFields($metadata) {
- $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
- $fields = ["record_id"];
- foreach (self::$citationFields as $field) {
- if (in_array($field, $metadataFields)) {
- $fields[] = $field;
- }
- }
- return $fields;
+ return REDCapManagement::screenForFields($metadata, self::$citationFields);
+ }
+
+ public static function getCustomFields($metadata) {
+ return REDCapManagement::screenForFields($metadata, self::$customFields);
+ }
+
+ public static function getExporterFields($metadata) {
+ return REDCapManagement::screenForFields($metadata, CareerDev::$exporterFields);
}
public static function getInstitution() {
@@ -431,6 +432,7 @@ public static function getIndividualKLength() {
"citation_month",
"citation_day",
"citation_pages",
+ "citation_abstract",
"citation_is_research",
"citation_num_citations",
"citation_citations_per_year",
@@ -438,6 +440,18 @@ public static function getIndividualKLength() {
"citation_field_citation_rate",
"citation_nih_percentile",
"citation_rcr",
+ "citation_icite_last_update",
+ "citation_altmetric_score",
+ "citation_altmetric_image",
+ "citation_altmetric_details_url",
+ "citation_altmetric_id",
+ "citation_altmetric_fbwalls_count",
+ "citation_altmetric_feeds_count",
+ "citation_altmetric_gplus_count",
+ "citation_altmetric_posts_count",
+ "citation_altmetric_tweeters_count",
+ "citation_altmetric_accounts_count",
+ "citation_altmetric_last_update",
);
public static $customFields = array(
diff --git a/CareerDev.php b/CareerDev.php
index e697e8d6..7047c6b6 100644
--- a/CareerDev.php
+++ b/CareerDev.php
@@ -10,7 +10,7 @@ class CareerDev {
public static $passedModule = NULL;
public static function getVersion() {
- return "2.29.0";
+ return "2.30.0";
}
public static function getLockFile($pid) {
@@ -690,32 +690,44 @@ public static function getMenu($menuName) {
return array();
}
- public static $citationFields = array(
- "record_id",
- "citation_doi",
- "citation_pmid",
- "citation_include",
- "citation_source",
- "citation_pmcid",
- "citation_authors",
- "citation_title",
- "citation_pub_types",
- "citation_mesh_terms",
- "citation_journal",
- "citation_volume",
- "citation_issue",
- "citation_year",
- "citation_month",
- "citation_day",
- "citation_pages",
- "citation_is_research",
- "citation_num_citations",
- "citation_citations_per_year",
- "citation_expected_per_year",
- "citation_field_citation_rate",
- "citation_nih_percentile",
- "citation_rcr",
- );
+ public static $citationFields = [
+ "record_id",
+ "citation_pmid",
+ "citation_include",
+ "citation_source",
+ "citation_pmcid",
+ "citation_authors",
+ "citation_title",
+ "citation_pub_types",
+ "citation_mesh_terms",
+ "citation_journal",
+ "citation_volume",
+ "citation_issue",
+ "citation_year",
+ "citation_month",
+ "citation_day",
+ "citation_pages",
+ "citation_abstract",
+ "citation_is_research",
+ "citation_num_citations",
+ "citation_citations_per_year",
+ "citation_expected_per_year",
+ "citation_field_citation_rate",
+ "citation_nih_percentile",
+ "citation_rcr",
+ "citation_icite_last_update",
+ "citation_altmetric_score",
+ "citation_altmetric_image",
+ "citation_altmetric_details_url",
+ "citation_altmetric_id",
+ "citation_altmetric_fbwalls_count",
+ "citation_altmetric_feeds_count",
+ "citation_altmetric_gplus_count",
+ "citation_altmetric_posts_count",
+ "citation_altmetric_tweeters_count",
+ "citation_altmetric_accounts_count",
+ "citation_altmetric_last_update",
+ ];
public static $smallCitationFields = array(
"record_id",
@@ -820,6 +832,7 @@ public static function getMenu($menuName) {
"exporter_indirect_cost_amt",
"exporter_total_cost",
"exporter_total_cost_sub_project",
+ "exporter_abstract",
"exporter_last_update",
);
diff --git a/FlightTrackerExternalModule.php b/FlightTrackerExternalModule.php
index 83c657d0..aa54b27a 100755
--- a/FlightTrackerExternalModule.php
+++ b/FlightTrackerExternalModule.php
@@ -21,6 +21,7 @@
require_once(dirname(__FILE__)."/classes/Download.php");
require_once(dirname(__FILE__)."/classes/NameMatcher.php");
require_once(dirname(__FILE__)."/cronLoad.php");
+require_once(APP_PATH_DOCROOT."Classes/System.php");
class FlightTrackerExternalModule extends AbstractExternalModule
{
@@ -397,6 +398,8 @@ private function shareDataInternally($pids) {
}
function cron() {
+ \System::increaseMaxExecTime(7200); // 2 hours
+
$this->setupApplication();
$pids = $this->framework->getProjectsWithModuleEnabled();
CareerDev::log($this->getName()." running for pids ".json_encode($pids));
diff --git a/bulkImport.php b/bulkImport.php
index 6258d840..c048338f 100644
--- a/bulkImport.php
+++ b/bulkImport.php
@@ -45,6 +45,7 @@
$unmatchedLines = [];
$maxInstances = [];
$i = 0;
+ $customFields = Application::getCustomFields($metadata);
foreach ($lines as $line) {
$firstName = $line[0];
$lastName = $line[1];
@@ -81,6 +82,9 @@
"custom_last_update" => date("Y-m-d"),
"custom_grant_complete" => "2",
];
+ if (in_array("custom_costs_total", $customFields)) {
+ $uploadRow["custom_costs_total"] = $line[11];
+ }
$upload[] = $uploadRow;
} else if ($title == "Positions") {
list($department, $other) = findDepartment($line[8], $choices, "promotion_department");
diff --git a/charts/makeCDATable.php b/charts/makeCDATable.php
index c1f59d6a..29e4647f 100755
--- a/charts/makeCDATable.php
+++ b/charts/makeCDATable.php
@@ -99,7 +99,7 @@ function getTimeSpan($row, $i) {
$start = $row['summary_award_date_'.$i];
$end = $row['summary_award_date_'.($i + 1)];
if ($start && $end) {
- return floor(REDCapManagement::datediff($start, $end, "y") * 10) / 10;
+ return round(REDCapManagement::datediff($start, $end, "y") * 10) / 10;
}
return "";
}
@@ -370,14 +370,16 @@ function appendCitationLabel($num) {
}
}
} else {
- # main path
- echo "
$type$date$mech$budget$link | ";
- $ts = getTimeSpan($normativeRow, $i);
- if ($ts !== "") {
- echo "$ts years b/w starts | ";
- } else {
- echo " | ";
- }
+ if (!in_array($grant->getVariable("type"), ["Research Fellowship"])) {
+ # main path
+ echo "$type$date$mech$budget$link | ";
+ $ts = getTimeSpan($normativeRow, $i);
+ if ($ts !== "") {
+ echo "$ts years b/w starts | ";
+ } else {
+ echo " | ";
+ }
+ }
}
}
$i++;
diff --git a/classes/Crons.php b/classes/Crons.php
index ffd32164..968862b2 100644
--- a/classes/Crons.php
+++ b/classes/Crons.php
@@ -43,26 +43,38 @@ public function addCron($file, $method, $dayOfWeek, $records = []) {
if (!empty($records)) {
$cronjob->setRecords($records);
}
- // Application::log("Has day of week $dayOfWeek and timestamp for ".date("Y-m-d", $dateTs));
+ if ($this->isDebug) {
+ Application::log("Has day of week $dayOfWeek and timestamp for ".date("Y-m-d", $dateTs));
+ }
if (in_array($dayOfWeek, $possibleDays)) {
# Weekday
if (!isset($this->crons[$dayOfWeek])) {
$this->crons[$dayOfWeek] = [];
- // Application::log("Reset cron list for $dayOfWeek");
+ if ($this->isDebug) {
+ Application::log("Reset cron list for $dayOfWeek");
+ }
}
$this->crons[$dayOfWeek][] = $cronjob;
- // Application::log("Assigned cron for $dayOfWeek");
+ if ($this->isDebug) {
+ Application::log("Assigned cron for $dayOfWeek");
+ }
} else if ($dateTs) {
# Y-M-D
$date = date(self::getDateFormat(), $dateTs);
if (!isset($this->crons[$date])) {
$this->crons[$date] = [];
- // Application::log("Reset cron list for $date");
+ if ($this->isDebug) {
+ Application::log("Reset cron list for $date");
+ }
}
$this->crons[$date][] = $cronjob;
- // Application::log("Assigned cron for $date");
+ if ($this->isDebug) {
+ Application::log("Assigned cron for $date");
+ }
}
- // Application::log("Added cron $method: ".$this->getNumberOfCrons()." total crons now");
+ if ($this->isDebug) {
+ Application::log("Added cron $method: ".$this->getNumberOfCrons()." total crons now");
+ }
}
private static function getDaysOfWeek() {
@@ -138,13 +150,15 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = ""
$records = $recordsToRun;
}
}
- Application::log("Running ".$cronjob->getTitle());
+ Application::log("Running ".$cronjob->getTitle()." with ".count($records)." records");
$run[$cronjob->getTitle()] = array("text" => "Attempted", "ts" => self::getTimestamp());
try {
if (!$this->token || !$this->server) {
throw new \Exception("Could not pass token '".$this->token."' or server '".$this->server."' to cron job");
}
- $cronjob->run($this->token, $this->server, $this->pid, $records);
+ if (!$this->isDebug) {
+ $cronjob->run($this->token, $this->server, $this->pid, $records);
+ }
$run[$cronjob->getTitle()] = array("text" => "Succeeded", "ts" => self::getTimestamp());
} catch(\Throwable $e) {
$this->handle($e, $adminEmail, $cronjob);
@@ -153,6 +167,13 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = ""
}
}
if (count($toRun) > 0) {
+ if ($this->isDebug) {
+ Application::log("Attempting to save current date");
+ Application::saveCurrentDate("Test", $this->pid);
+ Application::removeCurrentDate("Test", $this->pid);
+ Application::log("Done attempting to save current date");
+ }
+
$text = $tokenName." ".$this->server."
";
foreach ($run as $title => $mssgAry) {
$mssg = $mssgAry['text'];
@@ -168,12 +189,18 @@ public function run($adminEmail = "", $tokenName = "", $additionalEmailText = ""
}
if (!class_exists("\REDCap") || !method_exists("\REDCap", "email")) {
throw new \Exception("Could not instantiate REDCap class!");
- }
- Application::log("Sending ".Application::getProgramName()." email for pid ".$this->pid." to $adminEmail");
- \REDCap::email($adminEmail, "noreply@vumc.org", Application::getProgramName()." Cron Report", $text);
+ }
+ if (!$this->isDebug) {
+ Application::log("Sending ".Application::getProgramName()." email for pid ".$this->pid." to $adminEmail");
+ \REDCap::email($adminEmail, "noreply@vumc.org", Application::getProgramName()." Cron Report", $text);
+ }
}
}
+ public function setDebug($isDebug) {
+ $this->isDebug = $isDebug;
+ }
+
public function handle($e, $adminEmail, $cronjob) {
Application::log("Exception ".json_encode($e));
if (!class_exists("\REDCap") || !method_exists("\REDCap", "email")) {
@@ -200,6 +227,7 @@ public function handle($e, $adminEmail, $cronjob) {
private $sendErrorLogs;
private static $lastAdminEmail;
private static $lastSendErrorLogs;
+ private $isDebug = FALSE;
}
class CronJob {
diff --git a/classes/Download.php b/classes/Download.php
index 31579aed..68c162f3 100644
--- a/classes/Download.php
+++ b/classes/Download.php
@@ -180,9 +180,12 @@ public static function primaryMentors($token, $server) {
return $mentors;
}
- public static function trainingGrants($token, $server, $fields = array(), $traineeTypes = array(5, 6, 7), $records = []) {
+ public static function trainingGrants($token, $server, $fields = [], $traineeTypes = [5, 6, 7], $records = [], $metadata = []) {
if (empty($fields)) {
- $fields = Application::$customFields; // default
+ if (empty($metadata)) {
+ $metadata = self::metadata($token, $server);
+ }
+ $fields = Application::getCustomFields($metadata); // default
}
if (empty($records)) {
$records = self::recordIds($token, $server);
@@ -203,8 +206,8 @@ public static function trainingGrants($token, $server, $fields = array(), $train
return $filteredData;
}
- public static function appointmentsForRecord($token, $server, $record, $traineeTypes = [5, 6, 7]) {
- $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, [$record]);
+ public static function appointmentsForRecord($token, $server, $record, $traineeTypes = [5, 6, 7], $metadata = []) {
+ $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, [$record], $metadata);
$types = [];
foreach ($redcapData as $row) {
$roleType = $row['custom_role'];
@@ -215,8 +218,8 @@ public static function appointmentsForRecord($token, $server, $record, $traineeT
return $types;
}
- public static function recordsWithTrainees($token, $server, $traineeTypes = array(5, 6, 7)) {
- $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes);
+ public static function recordsWithTrainees($token, $server, $traineeTypes = [5, 6, 7], $metadata = []) {
+ $redcapData = self::trainingGrants($token, $server, array("record_id", "custom_role"), $traineeTypes, $metadata);
$records = array();
foreach ($redcapData as $row) {
$recordId = $row['record_id'];
diff --git a/classes/Grant.php b/classes/Grant.php
index fdb98d6d..dc479e4f 100644
--- a/classes/Grant.php
+++ b/classes/Grant.php
@@ -1287,6 +1287,11 @@ private function getCurrentType()
$specs = $this->specs;
$awardNo = $this->getNumber();
+ if ($specs['pi_flag'] == 'N') {
+ if (SHOW_GRANT_DEBUG) { Application::log($awardNo.": pi_flag is N"); }
+ return "N/A";
+ }
+
if (SHOW_GRANT_DEBUG) { Application::log($awardNo.": First Pass"); }
if ($type = $this->lexicallyTranslate($awardNo)) {
return $type;
@@ -1322,8 +1327,8 @@ public static function calculateAwardType($specs, $awardNo) {
return "K Equivalent";
} else if (preg_match("/^\d?[Rr]00/", $awardNo) || preg_match("/^\d?[Kk]\s*99/", $awardNo)) {
return "K99/R00";
- } else if (preg_match("/^\d?[Rr]01/", $awardNo)) {
- return "R01";
+ } else if (preg_match("/^\d?[Rr]01/", $awardNo)) {
+ return "R01";
} else if (preg_match("/^\d?[Tt]\d\d/", $awardNo) || preg_match("/^\d?[Dd]43/", $awardNo)) {
return "Training Grant Admin";
} else if ($specs['direct_budget'] && ($specs['direct_budget'] >= 750000)) {
@@ -1368,6 +1373,10 @@ public static function calculateAwardType($specs, $awardNo) {
return "R01 Equivalent";
} else if (preg_match("/^\d?R35/", $awardNo)) {
return "R01 Equivalent";
+ } else if (preg_match("/^\d?[Dd][Pp]1/", $awardNo)) {
+ return "R01 Equivalent";
+ } else if (preg_match("/^\d?DP7/", $awardNo) || preg_match("/^\d?[Rr]25/", $awardNo) || preg_match("/^\d?[Tt]90/", $awardNo)) {
+ return "Training Grant Admin";
} else if (preg_match("/Internal K/", $awardNo)) {
return "Internal K";
} else if (preg_match("/K12\/KL2/", $awardNo)) {
diff --git a/classes/GrantFactory.php b/classes/GrantFactory.php
index 46c75e2a..3d1e40fd 100644
--- a/classes/GrantFactory.php
+++ b/classes/GrantFactory.php
@@ -713,36 +713,50 @@ class CustomGrantFactory extends GrantFactory {
public function processRow($row, $token = "") {
list($pid, $event_id) = self::getProjectIdentifiers($token);
$awardNo = self::cleanAwardNo($row['custom_number']);
+ $directCosts = $row['custom_costs'];
+ if ($row['custom_costs_total']) {
+ $totalCosts = $row['custom_costs_total'];
+ if (!$directCosts) {
+ $directCosts = Grants::directCostsFromTotal($totalCosts, $awardNo, $row['custom_start']);
+ }
+ } else {
+ if ($directCosts) {
+ $totalCosts = Grants::totalCostsFromDirect($directCosts, $awardNo, $row['custom_start']);
+ } else {
+ $totalCosts = '';
+ }
+ }
$grant = new Grant($this->lexicalTranslator);
$grant->setVariable('start', $row['custom_start']);
$grant->setVariable('end', $row['custom_end']);
$grant->setVariable('title', $row['custom_title']);
- $grant->setVariable('budget', Grants::totalCostsFromDirect($row['custom_costs'], $awardNo, $row['custom_start']));
+ $grant->setVariable('budget', $totalCosts);
// $grant->setVariable('fAndA', Grants::getFAndA($awardNo, $row['custom_start']));
$grant->setVariable('finance_type', Grants::getFinanceType($awardNo));
- $grant->setVariable('direct_budget', $row['custom_costs']);
+ $grant->setVariable('direct_budget', $directCosts);
$grant->setVariable('sponsor', $row['custom_org']);
$grant->setVariable('original_award_number', $row['custom_number']);
$grant->setNumber($awardNo);
$grant->setVariable('source', "custom");
if (($row['custom_role'] == 1) || ($row['custom_role'] == 2) || ($row['custom_role'] == '')) {
$grant->setVariable('pi_flag', 'Y');
+ $type = $row['custom_type'];
+ $reverseAwardTypes = Grant::getReverseAwardTypes();
+ if ($reverseAwardTypes[$type]) {
+ $grant->setVariable("type", $reverseAwardTypes[$type]);
+ } else {
+ $grant->putInBins();
+ }
} else {
$grant->setVariable('pi_flag', 'N');
+ $grant->putInBins();
}
$grant->setVariable("role", $this->choices["custom_role"][$row["custom_role"]]);
$grant->setVariable('nih_mechanism', Grant::getActivityCode($awardNo));
$grant->setVariable('link', Links::makeLink(APP_PATH_WEBROOT."DataEntry/index.php?pid=$pid&id={$row['record_id']}&event_id=$event_id&page=custom_grant&instance={$row['redcap_repeat_instance']}", "See Grant"));
$grant->setVariable('last_update', $row['custom_last_update']);
- $type = $row['custom_type'];
- $reverseAwardTypes = Grant::getReverseAwardTypes();
- if ($reverseAwardTypes[$type]) {
- $grant->setVariable("type", $reverseAwardTypes[$type]);
- } else {
- $grant->putInBins();
- }
array_push($this->grants, $grant);
}
}
diff --git a/classes/NIHTables.php b/classes/NIHTables.php
index 13c23a8f..6eb685f8 100644
--- a/classes/NIHTables.php
+++ b/classes/NIHTables.php
@@ -373,7 +373,7 @@ private function get6IIData($table, $yearspan, $records = []) {
$doctorateInstitutions = Download::doctorateInstitutions($this->token, $this->server, $this->metadata);
$trainingTypes = self::getTrainingTypes($table);
if (!empty($names)) {
- $trainingGrantData = Download::trainingGrants($this->token, $this->server, array(), $trainingTypes);
+ $trainingGrantData = Download::trainingGrants($this->token, $this->server, [], $trainingTypes, [], $this->metadata);
} else {
$trainingGrantData = array();
}
@@ -1311,7 +1311,7 @@ public function get8Data($table, $records = []) {
$firstNames = Download::firstnames($this->token, $this->server);
$lastNames = Download::lastnames($this->token, $this->server);
$mentors = Download::primaryMentors($this->token, $this->server);
- $trainingGrants = Download::trainingGrants($this->token, $this->server);
+ $trainingGrants = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata);
$hasSupportSummary = $this->hasSupportSummary();
if ($hasSupportSummary) {
$supportSummaries = Download::oneField($this->token, $this->server, "identifier_support_summary");
@@ -1721,7 +1721,7 @@ private function downloadRelevantNames($table, $records) {
$thisGrantType = self::getTrainingType();
$internalKType = 1;
if (in_array($part, [1, 3])) {
- $trainingData = Download::trainingGrants($this->token, $this->server);
+ $trainingData = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata);
foreach ($names as $recordId => $name) {
$currentGrants = self::getTrainingGrantsForRecord($trainingData, $recordId);
foreach ($currentGrants as $row) {
@@ -1831,7 +1831,7 @@ public function get5Data($table, $records = []) {
$lastNames = Download::lastNames($this->token, $this->server);
$firstNames = Download::firstNames($this->token, $this->server);
$mentors = Download::primaryMentors($this->token, $this->server);
- $trainingData = Download::trainingGrants($this->token, $this->server);
+ $trainingData = Download::trainingGrants($this->token, $this->server, [], [5, 6, 7], [], $this->metadata);
$trainingStarts = Download::oneField($this->token, $this->server, "summary_training_start");
}
$fields = array_unique(array_merge(Application::getCitationFields($this->metadata), array("record_id")));
diff --git a/classes/Publications.php b/classes/Publications.php
index 16e96a77..7f82db6f 100644
--- a/classes/Publications.php
+++ b/classes/Publications.php
@@ -493,10 +493,12 @@ public static function uploadBlankPMCsAndPMIDs($token, $server, $recordId, $meta
}
public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $recordId = 0, $startInstance = 1, $confirmedPMIDs = array(), $pid = NULL) {
- $upload = array();
+ $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
+ $hasAbstract = in_array("citation_abstract", $metadataFields);
+
+ $upload = [];
$instance = $startInstance;
$pullSize = self::getPMIDLimit();
- $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
for ($i = 0; $i < count($pmids); $i += $pullSize) {
$pmidsToPull = array();
for ($j = $i; ($j < count($pmids)) && ($j < $i + $pullSize); $j++) {
@@ -519,7 +521,11 @@ public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $rec
$pmidsPulled = [];
foreach ($xml->PubmedArticle as $medlineCitation) {
$article = $medlineCitation->MedlineCitation->Article;
- $authors = array();
+ $abstract = "";
+ if ($article->Abstract && $article->Abstract->AbstractText) {
+ $abstract = strval($article->Abstract->AbstractText);
+ }
+ $authors = [];
if ($article->AuthorList->Author) {
foreach ($article->AuthorList->Author as $authorXML) {
$author = $authorXML->LastName . " " . $authorXML->Initials;
@@ -632,6 +638,10 @@ public static function getCitationsFromPubMed($pmids, $metadata, $src = "", $rec
"citation_icite_last_update" => date("Y-m-d"),
"citation_complete" => "2",
];
+ if ($hasAbstract) {
+ $row['citation_abstract'] = $abstract;
+ }
+
$altmetricRow = self::getAltmetricRow($iCite->getVariable($pmid, "doi"), $metadataFields);
$row = array_merge($row, $altmetricRow);
if (in_array($pmid, $confirmedPMIDs)) {
@@ -1260,10 +1270,10 @@ public function getVariable($var) {
private function autoSuggestCategoryAndScore() {
$pubAry = $this->toArray();
if (is_array($pubAry['Publication Types']) && !empty($pubAry['Publication Types'])) {
- $cat = Citation::suggestCategoryFromPubTypes($pubAry['Publication Types'], $pubAry['Title']);
- if ($cat) {
- return array($cat, 100);
- }
+ // $cat = Citation::suggestCategoryFromPubTypes($pubAry['Publication Types'], $pubAry['Title']);
+ // if ($cat) {
+ // return array($cat, 100);
+ // }
}
if (isset($pubAry['Abstract'])) {
return self::analyzeAbstractAndTitle($pubAry['Abstract'], $pubAry['Title']);
diff --git a/classes/REDCapManagement.php b/classes/REDCapManagement.php
index e84cbbe0..2d972c6d 100644
--- a/classes/REDCapManagement.php
+++ b/classes/REDCapManagement.php
@@ -1264,6 +1264,17 @@ public static function splitURL($fullURL) {
return [$url, $params];
}
+ public static function screenForFields($metadata, $possibleFields) {
+ $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
+ $fields = ["record_id"];
+ foreach ($possibleFields as $field) {
+ if (in_array($field, $metadataFields)) {
+ $fields[] = $field;
+ }
+ }
+ return $fields;
+ }
+
public static function dedup1DArray($ary) {
$newAry = [];
foreach ($ary as $item) {
diff --git a/classes/Upload.php b/classes/Upload.php
index a5ff6d12..ce42f445 100644
--- a/classes/Upload.php
+++ b/classes/Upload.php
@@ -64,6 +64,16 @@ public static function deleteField($token, $server, $pid, $field, $recordId, $in
}
}
+ public static function copyRecord($token, $server, $oldRecordId, $newRecordId) {
+ $oldRecordData = Download::records($token, $server, [$oldRecordId]);
+ $newRecordData = [];
+ foreach ($oldRecordData as $row) {
+ $row['record_id'] = $newRecordId;
+ $newRecordData[] = $row;
+ }
+ return self::rows($newRecordData, $token, $server);
+ }
+
public static function deleteForm($token, $server, $pid, $prefix, $recordId, $instance = NULL) {
$records = Download::recordIds($token, $server);
if (Download::isCurrentServer($server)) {
diff --git a/classes/WebOfScience.php b/classes/WebOfScience.php
index 1be09e31..7a15035c 100644
--- a/classes/WebOfScience.php
+++ b/classes/WebOfScience.php
@@ -37,45 +37,49 @@ public function getData($pmids) {
$data = [];
foreach ($batchedPmids as $pmids) {
- Application::log("Downloading for ".count($pmids)." PMIDs");
- $xml = $this->makeXML($pmids);
- // Application::log("Uploading ".$xml);
- $url = 'https://ws.isiknowledge.com/cps/xrpc';
+ if (empty($pmids)) {
+ Application::log("No PMIDs");
+ } else {
+ Application::log("Downloading for ".count($pmids)." PMIDs");
+ $xml = $this->makeXML($pmids);
+ // Application::log("Uploading ".$xml);
+ $url = 'https://ws.isiknowledge.com/cps/xrpc';
- $curl = curl_init($url);
- curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- $result = curl_exec($curl);
- if (curl_errno($curl)) {
- throw new Exception(curl_error($curl));
- }
- curl_close($curl);
- Application::log("Got ".strlen($result)." bytes from ".$url);
- // Application::log($result);
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ $result = curl_exec($curl);
+ if (curl_errno($curl)) {
+ throw new Exception(curl_error($curl));
+ }
+ curl_close($curl);
+ Application::log("Got ".strlen($result)." bytes from ".$url);
+ // Application::log($result);
- $maxTries = 5;
- $tryNum = 0;
- $done = FALSE;
- while (($tryNum < $maxTries) && !$done) {
- $tryNum++;
- try {
- $values = $this->parseXML($result);
- Application::log("On try $tryNum, got ".count($values)." values from XML");
- $done = TRUE;
- } catch (\Exception $e) {
- Application::log("parseXML try $tryNum: ".$e->getMessage());
- sleep(120); // "wait a couple of minutes in case of error"
+ $maxTries = 5;
+ $tryNum = 0;
+ $done = FALSE;
+ while (($tryNum < $maxTries) && !$done) {
+ $tryNum++;
+ try {
+ $values = $this->parseXML($result);
+ Application::log("On try $tryNum, got ".count($values)." values from XML");
+ $done = TRUE;
+ } catch (\Exception $e) {
+ Application::log("parseXML try $tryNum: ".$e->getMessage());
+ sleep(120); // "wait a couple of minutes in case of error"
+ }
}
+ if ($tryNum > $maxTries) {
+ throw new \Exception("Exceeded maximum of $maxTries tries");
+ }
+ foreach ($values as $key => $value) {
+ $data[$key] = $value;
+ }
+ sleep(1); // rate-limiter
}
- if ($tryNum > $maxTries) {
- throw new \Exception("Exceeded maximum of $maxTries tries");
- }
- foreach ($values as $key => $value) {
- $data[$key] = $value;
- }
- sleep(1); // rate-limiter
}
return $data;
} else {
diff --git a/clean/remap.php b/clean/remap.php
new file mode 100644
index 00000000..83480405
--- /dev/null
+++ b/clean/remap.php
@@ -0,0 +1,109 @@
+ $tmpRecordId) {
+ $tmpRecordId *= 10;
+}
+
+if ($_POST) {
+ $toDelete = [];
+ $toChange = [];
+ foreach ($_POST as $key => $value) {
+ if (preg_match("/^record_\d+$/", $key) && $value) {
+ $oldRecordId = preg_replace("/^record_/", "", $key);
+ $newRecordId = $value;
+ if ($oldRecordId != $newRecordId) {
+ $newTmpRecordId = $tmpRecordId + $newRecordId;
+ Upload::copyRecord($token, $server, $oldRecordId, $newTmpRecordId);
+ $toDelete[] = $oldRecordId;
+ $toChange[$newTmpRecordId] = $newRecordId;
+ }
+ }
+ }
+ if (empty($toDelete) && empty($toChange)) {
+ echo "No records requested to change.
";
+ } else {
+ $records = Download::recordIds($token, $server);
+ $numAffected = count($toChange);
+ foreach ($toDelete as $recordId) {
+ Upload::deleteRecords($token, $server, [$recordId]);
+ }
+ foreach ($toChange as $oldRecordId => $newRecordId) {
+ if (in_array($newRecordId, $records)) {
+ Upload::deleteRecords($token, $server, [$newRecordId]);
+ }
+ Upload::copyRecord($token, $server, $oldRecordId, $newRecordId);
+ Upload::deleteRecords($token, $server, [$oldRecordId]);
+ }
+ echo "$numAffected records affected.
";
+ }
+} else {
+ $names = Download::names($token, $server);
+ $link = Application::link("clean/remap.php");
+ echo "Change Record IDs
";
+ echo "Please be patient...
";
+ echo "";
+}
+
diff --git a/cronLoad.php b/cronLoad.php
index 2e647663..7c49402e 100644
--- a/cronLoad.php
+++ b/cronLoad.php
@@ -21,11 +21,11 @@ function loadCrons(&$manager, $specialOnly = FALSE, $token = "", $server = "") {
// $manager->addCron("drivers/2o_updateCoeus.php", "processCoeus", date("Y-m-d"));
// $manager->addCron("publications/getAllPubs_func.php", "getPubs", date("Y-m-d"));
// $manager->addCron("drivers/6d_makeSummary.php", "makeSummary", date("Y-m-d"));
- $manager->addCron("publications/updateBibliometricsForOneRecord.php", "updateBibliometrics", date("Y-m-d"));
+ $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", date("Y-m-d"));
} else if ($token && $server) {
$has = checkMetadataForFields($token, $server);
- $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", "Monday");
+ $manager->addCron("drivers/2m_updateExPORTER.php", "updateExPORTER", "Monday");
$manager->addCron("drivers/2n_updateReporters.php", "updateReporter", "Tuesday");
if ($has['coeus']) {
$manager->addCron("drivers/2o_updateCoeus.php", "processCoeus", "Thursday");
@@ -43,16 +43,12 @@ function loadCrons(&$manager, $specialOnly = FALSE, $token = "", $server = "") {
}
}
$manager->addCron("drivers/13_pullOrcid.php", "pullORCIDs", "Friday");
- $manager->addCron("publications/getAllPubs_func.php", "getPubs", "Saturday");
+ $manager->addCron("publications/getAllPubs_func.php", "getPubs", "Saturday");
# limited group because bibliometric updates take a lot of time due to rate limiters
$bibliometricRecordsToUpdate = getRecordsToUpdateBibliometrics($token, $server, date("d"), date("t"));
if (!empty($bibliometricRecordsToUpdate)) {
- if ((Application::getPid($token) == "112169") && CareerDev::isVanderbilt() && (date("Y-m-d") == "2021-01-23")) {
- $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d"));
- } else {
- $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d"), $bibliometricRecordsToUpdate);
- }
+ $manager->addCron("publications/updateBibliometrics.php", "updateBibliometrics", date("Y-m-d"), $bibliometricRecordsToUpdate);
}
$manager->addCron("drivers/6d_makeSummary.php", "makeSummary", "Monday");
$manager->addCron("drivers/6d_makeSummary.php", "makeSummary", "Tuesday");
diff --git a/customGrants.php b/customGrants.php
index 188dd542..ef501cc4 100644
--- a/customGrants.php
+++ b/customGrants.php
@@ -2,18 +2,21 @@
use \Vanderbilt\CareerDevLibrary\Links;
use \Vanderbilt\CareerDevLibrary\Download;
+use \Vanderbilt\CareerDevLibrary\Application;
use \Vanderbilt\FlightTrackerExternalModule\CareerDev;
require_once(dirname(__FILE__)."/charts/baseWeb.php");
require_once(dirname(__FILE__)."/classes/Links.php");
require_once(dirname(__FILE__)."/classes/Download.php");
require_once(dirname(__FILE__)."/CareerDev.php");
+require_once(dirname(__FILE__)."/Application.php");
if ($_GET['record']) {
$record = $_GET['record'];
$pid = $_GET['pid'];
- $redcapData = Download::fieldsForRecords($token, $server, CareerDev::$customFields, array($record));
+ $metadata = Download::metadata($token, $server);
+ $redcapData = Download::fieldsForRecords($token, $server, Application::getCustomFields($metadata), [$record]);
$max = 0;
foreach ($redcapData as $row) {
if (($row['redcap_repeat_instrument'] == "custom_grant") && ($row['redcap_repeat_instance'] > $max)) {
diff --git a/drivers/2m_updateExPORTER.php b/drivers/2m_updateExPORTER.php
index d64e969e..b6b3aeb3 100644
--- a/drivers/2m_updateExPORTER.php
+++ b/drivers/2m_updateExPORTER.php
@@ -3,14 +3,18 @@
use \Vanderbilt\CareerDevLibrary\Download;
use \Vanderbilt\CareerDevLibrary\Upload;
use \Vanderbilt\CareerDevLibrary\NameMatcher;
+use \Vanderbilt\CareerDevLibrary\Application;
+use \Vanderbilt\CareerDevLibrary\REDCapManagement;
use \Vanderbilt\FlightTrackerExternalModule\CareerDev;
define('NOAUTH', true);
require_once(dirname(__FILE__)."/../small_base.php");
require_once(dirname(__FILE__)."/../CareerDev.php");
+require_once(dirname(__FILE__)."/../Application.php");
require_once(dirname(__FILE__)."/../classes/Download.php");
require_once(dirname(__FILE__)."/../classes/NameMatcher.php");
require_once(dirname(__FILE__)."/../classes/Upload.php");
+require_once(dirname(__FILE__)."/../classes/REDCapManagement.php");
require_once(dirname(__FILE__)."/../../../redcap_connect.php");
/**
@@ -108,25 +112,70 @@ function downloadURLAndUnzip($file) {
* @param $headers array read from CSV that consist of the headers for each row
* constraint: count($line) == count($headers)
*/
-function makeUploadHoldingQueue($line, $headers) {
+function makeUploadHoldingQueue($line, $headers, $abstracts) {
$j = 0;
$dates = array("exporter_budget_start", "exporter_budget_end", "exporter_project_start", "exporter_project_end");
$uploadLineHoldingQueue = array();
foreach ($line as $item) {
$field = "exporter_".strtolower($headers[$j]);
if (in_array($field, $dates)) {
- $item = \Vanderbilt\FlightTrackerExternalModule\MDY2YMD($item);
+ $item = REDCapManagement::MDY2YMD($item);
}
$uploadLineHoldingQueue[$field] = convert_from_latin1_to_utf8_recursively($item);
$j++;
}
- $uploadLineHoldingQueue['exporter_last_update'] = date("Y-m-d");
+ if ($uploadLineHoldingQueue['exporter_application_id']) {
+ $uploadLineHoldingQueue['exporter_abstract'] = $abstracts[$uploadLineHoldingQueue['exporter_application_id']];
+ }
+ $uploadLineHoldingQueue['exporter_last_update'] = date("Y-m-d");
$uploadLineHoldingQueue['exporter_complete'] = '2';
return $uploadLineHoldingQueue;
}
+function updateAbstracts($token, $server, $pid) {
+ $records = Download::recordIds($token, $server);
+ $files = [];
+ $abstractFiles = [];
+
+ # find relevant zips
+ # download relevent zips into APP_PATH_TEMP
+ # unzip zip files
+ for ($year = 2009; $year <= date("Y"); $year++) {
+ $url = "RePORTER_PRJ_C_FY".$year.".zip";
+ $file = downloadURLAndUnzip($url);
+ if ($file) {
+ $files[$file] = $year;
+ }
+
+ $abstractURL = "RePORTER_PRJABS_C_FY".$year.".zip";
+ $abstractFile = downloadURLAndUnzip($abstractURL);
+ if ($abstractFile) {
+ $abstractFiles[$file] = $abstractFile;
+ }
+ }
+ for ($year = date("Y") - 1; $year <= date("Y") + 1; $year++) {
+ for ($week = 1; $week <= 53; $week++) {
+ $weekWithLeading0s = sprintf('%03d', $week);
+ $url = "RePORTER_PRJ_C_FY".$year."_".$weekWithLeading0s.".zip";
+ $file = downloadURLAndUnzip($url);
+ if ($file) {
+ $files[$file] = $year;
+ }
+
+ $abstractURL = "RePORTER_PRJABS_C_FY".$year."_".$weekWithLeading0s.".zip";
+ $abstractFile = downloadURLAndUnzip($abstractURL);
+ if ($abstractFile) {
+ $abstractFiles[$file] = $abstractFile;
+ }
+ }
+ }
+
+ uploadBlankAbstracts($token, $server, $records, $abstractFiles);
+}
+
function updateExPORTER($token, $server, $pid, $records) {
- $files = array();
+ $files = [];
+ $abstractFiles = [];
# find relevant zips
# download relevent zips into APP_PATH_TEMP
@@ -137,6 +186,12 @@ function updateExPORTER($token, $server, $pid, $records) {
if ($file) {
$files[$file] = $year;
}
+
+ $abstractURL = "RePORTER_PRJABS_C_FY".$year.".zip";
+ $abstractFile = downloadURLAndUnzip($abstractURL);
+ if ($abstractFile) {
+ $abstractFiles[$file] = $abstractFile;
+ }
}
for ($year = date("Y") - 1; $year <= date("Y") + 1; $year++) {
for ($week = 1; $week <= 53; $week++) {
@@ -146,16 +201,25 @@ function updateExPORTER($token, $server, $pid, $records) {
if ($file) {
$files[$file] = $year;
}
+
+ $abstractURL = "RePORTER_PRJABS_C_FY".$year."_".$weekWithLeading0s.".zip";
+ $abstractFile = downloadURLAndUnzip($abstractURL);
+ if ($abstractFile) {
+ $abstractFiles[$file] = $abstractFile;
+ }
}
}
-
CareerDev::log("Downloading REDCap");
echo "Downloading REDCap\n";
+ $metadata = Download::metadata($token, $server);
+ $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
+ $hasAbstract = in_array("exporter_abstract", $metadataFields);
+
$redcapData = array();
foreach ($records as $recordId) {
- $redcapData[$recordId] = Download::fieldsForRecords($token, $server, array_unique(array_merge(CareerDev::$customFields, CareerDev::$exporterFields)), array($recordId));
+ $redcapData[$recordId] = Download::fieldsForRecords($token, $server, array_unique(array_merge(Application::getCustomFields($metadata), Application::getExporterFields($metadata))), array($recordId));
}
echo "Downloaded ".count($redcapData)." records\n";
@@ -175,6 +239,8 @@ function updateExPORTER($token, $server, $pid, $records) {
$upload = array();
$newUploads = array(); // new records
foreach ($files as $file => $year) {
+ $abstracts = readAbstracts($abstractFiles[$file]);
+
CareerDev::log("Reading $file");
echo "Reading $file\n";
$fp = fopen($file, "r");
@@ -243,14 +309,27 @@ function updateExPORTER($token, $server, $pid, $records) {
if ($recordId && $firstNames[$k] && $lastNames[$k]) {
# upload line
$uploadLine = array("record_id" => $recordId, "redcap_repeat_instrument" => "exporter", "exporter_complete" => '2');
- $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers);
+ $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers, $abstracts);
list($uploadLine["redcap_repeat_instance"], $isNew) = getExPORTERInstance($recordId, $redcapData[$recordId], $upload, $uploadLineHoldingQueue);
if ($isNew) {
$uploadLine = array_merge($uploadLine, $uploadLineHoldingQueue);
CareerDev::log("Matched name {$recordId} {$firstNames[$k]} {$lastNames[$k]} = {$uploadLine['exporter_pi_names']}");
echo "Matched name {$recordId} {$firstNames[$k]} {$lastNames[$k]} = {$uploadLine['exporter_pi_names']}\n";
+ if ($hasAbstract && $uploadLine['exporter_application_id']) {
+ $uploadLine['exporter_abstract'] = $abstracts[$uploadLine['exporter_application_id']];
+ }
$upload[] = $uploadLine;
- }
+ } else {
+ $currRow = REDCapManagement::getRow($redcapData[$recordId], $recordId, "exporter", $uploadLine['redcap_repeat_instance']);
+ if (!$currRow['exporter_abstract'] && $currRow['export_application_id'] && $hasAbstract) {
+ $upload[] = [
+ "record_id" => $recordId,
+ "redcap_repeat_instrument" => "exporter",
+ "redcap_repeat_instance" => $uploadLine["redcap_repeat_instance"],
+ "exporter_abstract" => $abstracts[$uploadLine['exporter_application_id']],
+ ];
+ }
+ }
} else if (!$recordId && $firstNames[$k] && $lastNames[$k] && $year >= date("Y")) {
# new person?
$j = 0;
@@ -271,7 +350,7 @@ function updateExPORTER($token, $server, $pid, $records) {
$j++;
}
if ($isK && $isSupportYear1) {
- $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers);
+ $uploadLineHoldingQueue = makeUploadHoldingQueue($line, $headers, $abstracts);
$newUploads[$firstNames[$k]." ".$lastNames[$k]] = $uploadLineHoldingQueue;
}
}
@@ -304,6 +383,9 @@ function updateExPORTER($token, $server, $pid, $records) {
list($firstName, $lastName) = preg_split("/\s/", $fullName);
$upload[] = array("record_id" => $maxRecordId, "redcap_repeat_instrument" => "", "redcap_repeat_instance" => "", "identifier_first_name" => ucfirst(strtolower($firstName)), "identifier_last_name" => ucfirst(strtolower($lastName)));
+ if ($hasAbstract && $uploadLine['exporter_application_id']) {
+ $uploadLine['exporter_abstract'] = $abstracts[$uploadLine['exporter_application_id']];
+ }
$upload[] = $uploadLine;
}
@@ -315,8 +397,70 @@ function updateExPORTER($token, $server, $pid, $records) {
echo json_encode($feedback)."\n";
}
+ if ($hasAbstract) {
+ uploadBlankAbstracts($token, $server, $records, $abstractFiles);
+ }
+
// $mssg = "NIH Exporter run\n\n".count($upload)." rows\n".$output."\n\n";
// \REDCap::email($adminEmail, "no-reply@vanderbilt.edu", "CareerDev NIH Exporter", $mssg);
CareerDev::saveCurrentDate("Last NIH ExPORTER Download", $pid);
}
+
+function readAbstracts($file) {
+ $data = [];
+ if (file_exists($file)) {
+ $fp = fopen($file, "r");
+ $headers = fgetcsv($fp);
+ while ($line = fgetcsv($fp)) {
+ $appId = $line[0];
+ $abstract = $line[1];
+ if ($appId && $abstract) {
+ $data[$appId] = $abstract;
+ }
+ }
+ fclose($fp);
+ }
+ return $data;
+}
+
+function uploadBlankAbstracts($token, $server, $records, $abstractFiles) {
+ foreach ($records as $recordId) {
+ $fields = ["record_id", "exporter_application_id", "exporter_abstract"];
+ $redcapData = Download::fieldsForRecords($token, $server, $fields, [$recordId]);
+ $blankApplicationIds = [];
+ foreach ($redcapData as $row) {
+ if ($row['redcap_repeat_instrument'] == "exporter") {
+ if ($row['exporter_abstract'] == "") {
+ $blankApplicationIds[$row['redcap_repeat_instance']] = $row['exporter_application_id'];
+ }
+ }
+ }
+
+ $upload = [];
+ foreach ($blankApplicationIds as $instance => $applicationId) {
+ $found = FALSE;
+ foreach ($abstractFiles as $dataFile => $abstractFile) {
+ $fp = fopen($abstractFile, "r");
+ while (!$found && ($line = fgetcsv($fp))) {
+ if ($line[1] && ($line[0] == $applicationId)) {
+ $upload[] = [
+ "record_id" => $recordId,
+ "redcap_repeat_instrument" => "exporter",
+ "redcap_repeat_instance" => $instance,
+ "exporter_abstract" => $line[1],
+ ];
+ $found = TRUE;
+ }
+ }
+ fclose($fp);
+ if ($found) {
+ break; // inner
+ }
+ }
+ }
+ if (!empty($upload)) {
+ Upload::rows($upload, $token, $server);
+ }
+ }
+}
diff --git a/emailMgmt/viewQueue.php b/emailMgmt/viewQueue.php
new file mode 100644
index 00000000..ddfc8a93
--- /dev/null
+++ b/emailMgmt/viewQueue.php
@@ -0,0 +1,45 @@
+getQueue($startTs);
+
+echo "Email Queue
";
+echo "Current Date and Time: ".date("m-d-Y H:i", $startTs)."
";
+
+if (empty($queue)) {
+ echo "No emails are presently enqueued.
";
+} else {
+ echo "Pending Emails
";
+ echo "";
+ echo "";
+ echo "";
+ echo "Email Name | Date/Time to Send | From | Subject | To | ";
+ echo "
";
+ echo "";
+ echo "";
+ $rowNum = 0;
+ foreach ($queue as $row) {
+ echo "";
+ echo "".$row['name']." | ";
+ echo "".REDCapManagement::YMD2MDY($row['date'])." ".$row['time']." | ";
+ echo "".$row['from']." | ";
+ echo "".$row['subject']." | ";
+ echo "".$row['to_count']." recipients ".implode(" ", $row['to'])." | ";
+ echo "
";
+ $rowNum++;
+ }
+ echo "
";
+}
diff --git a/getAbstracts.php b/getAbstracts.php
new file mode 100644
index 00000000..33af58d3
--- /dev/null
+++ b/getAbstracts.php
@@ -0,0 +1,56 @@
+ $row) {
+ fputcsv($fp, $row);
+}
+fclose($fp);
\ No newline at end of file
diff --git a/help/Codebook.docx b/help/Codebook.docx
index db2f5b0a..9f7782bb 100644
Binary files a/help/Codebook.docx and b/help/Codebook.docx differ
diff --git a/help/Codebook.pdf b/help/Codebook.pdf
index 17ed467f..b70315b4 100644
Binary files a/help/Codebook.pdf and b/help/Codebook.pdf differ
diff --git a/img/flight_tracker_logo_medium_white_bg.png b/img/flight_tracker_logo_medium_white_bg.png
new file mode 100644
index 00000000..03ab9592
Binary files /dev/null and b/img/flight_tracker_logo_medium_white_bg.png differ
diff --git a/import.csv b/import.csv
index 6f13109f..7921fc61 100644
--- a/import.csv
+++ b/import.csv
@@ -1 +1 @@
-First Name,Last Name,Grant Title,Grant Number or Funding Mechanism or Funding Mechanism (e.g. 1R01HL1234...),Grant Type (Internal K; K12/KL2; Individual K; K Equivalent; R01; R01 Equivalent; Research Fellowship; Training Grant Admin; K99/R00),Sponsoring Organization (e.g. NIH; CDC; VA),Recipient Organization (e.g. Vanderbilt),Role on Grant (PI; Co-PI; Co-I; Other; Trainee; Pre-Doctoral Trainee; Post-Doctoral Trainee),Start Date (YYYY-MM-DD or MM-DD-YYYY),End Date (YYYY-MM-DD or MM-DD-YYYY),Direct costs from start date to end date
+First Name,Last Name,Grant Title,Grant Number or Funding Mechanism or Funding Mechanism (e.g. 1R01HL1234...),Grant Type (Internal K; K12/KL2; Individual K; K Equivalent; R01; R01 Equivalent; Research Fellowship; Training Grant Admin; K99/R00),Sponsoring Organization (e.g. NIH; CDC; VA),Recipient Organization (e.g. Vanderbilt),Role on Grant (PI; Co-PI; Co-I; Other; Trainee; Pre-Doctoral Trainee; Post-Doctoral Trainee),Start Date (YYYY-MM-DD or MM-DD-YYYY),End Date (YYYY-MM-DD or MM-DD-YYYY),Direct costs from start date to end date,Total costs from start date to end date
diff --git a/metadata.json b/metadata.json
index 8102d069..e4b78518 100644
--- a/metadata.json
+++ b/metadata.json
@@ -789,6 +789,7 @@
{"field_name":"custom_start","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Start Date of Funding","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_mdy","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"y","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"custom_end","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"End Date of Funding","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_mdy","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"custom_costs","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Direct costs from start date to end date","select_choices_or_calculations":"","field_note":"A whole number without a dollar sign and without commas","text_validation_type_or_show_slider_number":"number","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
+{"field_name":"custom_costs_total","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Total costs from start date to end date","select_choices_or_calculations":"","field_note":"A whole number without a dollar sign and without commas","text_validation_type_or_show_slider_number":"number","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"custom_last_update","form_name":"custom_grant","section_header":"","field_type":"text","field_label":"Last Updated","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"date_ymd","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"reporter_projectnumber","form_name":"reporter","section_header":"","field_type":"text","field_label":"projectNumber","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"reporter_fy","form_name":"reporter","section_header":"","field_type":"text","field_label":"fy","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
@@ -1111,6 +1112,7 @@
{"field_name":"exporter_indirect_cost_amt","form_name":"exporter","section_header":"","field_type":"text","field_label":"Indirect Cost Amt","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"exporter_total_cost","form_name":"exporter","section_header":"","field_type":"text","field_label":"Total Cost","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"exporter_total_cost_sub_project","form_name":"exporter","section_header":"","field_type":"text","field_label":"Total Cost Sub Project","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
+{"field_name":"exporter_abstract","form_name":"exporter","section_header":"","field_type":"notes","field_label":"Abstract","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"exporter_last_update","form_name":"exporter","section_header":"","field_type":"text","field_label":"Last Updated","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_pmid","form_name":"citation","section_header":"","field_type":"text","field_label":"PubMed ID (PMID)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"y","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_include","form_name":"citation","section_header":"","field_type":"yesno","field_label":"Include?","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
@@ -1129,6 +1131,7 @@
{"field_name":"citation_day","form_name":"citation","section_header":"","field_type":"text","field_label":"Day","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_pages","form_name":"citation","section_header":"","field_type":"text","field_label":"Pages","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_grants","form_name":"citation","section_header":"","field_type":"notes","field_label":"Associated Grants","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
+{"field_name":"citation_abstract","form_name":"citation","section_header":"","field_type":"notes","field_label":"Abstract","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_is_research","form_name":"citation","section_header":"iCite terms","field_type":"yesno","field_label":"Is Research? (from iCite)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_is_research_override","form_name":"citation","section_header":"","field_type":"radio","field_label":"Override iCite's designation","select_choices_or_calculations":"1, Original Research | 2, Not Original Research","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
{"field_name":"citation_num_citations","form_name":"citation","section_header":"","field_type":"text","field_label":"Number of Citations by Other Papers (from iCite)","select_choices_or_calculations":"","field_note":"","text_validation_type_or_show_slider_number":"","text_validation_min":"","text_validation_max":"","identifier":"","branching_logic":"","required_field":"","custom_alignment":"","question_number":"","matrix_group_name":"","matrix_ranking":"","field_annotation":""},
diff --git a/publications/getAllPubs_func.php b/publications/getAllPubs_func.php
index 79a133df..4f999280 100644
--- a/publications/getAllPubs_func.php
+++ b/publications/getAllPubs_func.php
@@ -23,9 +23,11 @@
function getPubs($token, $server, $pid, $records) {
$cleanOldData = FALSE;
- $metadata = Download::metadata($token, $server);
+ $metadata = Download::metadata($token, $server);
+ $metadataFields = REDCapManagement::getFieldsFromMetadata($metadata);
+ $hasAbstract = in_array("citation_abstract", $metadataFields);
- $records = Download::recordIds($token, $server);
+ $records = Download::recordIds($token, $server);
$citationIds = array();
$pullSize = 1;
@@ -55,8 +57,22 @@ function getPubs($token, $server, $pid, $records) {
if (!isset($maxInstances[$recordId]) || ($instance > $maxInstances[$recordId])) {
$maxInstances[$recordId] = $instance;
}
+ if (!$row['citation_abstract'] && $hasAbstract) {
+ $pubmedMatch = Publications::downloadPMID($row['citation_pmid']);
+ $abstract = $pubmedMatch->getVariable("Abstract");
+ if ($abstract) {
+ $uploadRow = [
+ "record_id" => $recordId,
+ "redcap_repeat_instrument" => "citation",
+ "redcap_repeat_instance" => $instance,
+ "citation_abstract" => $abstract,
+ ];
+ Upload::oneRow($uploadRow, $token, $server);
+ }
+ }
}
}
+
Publications::uploadBlankPMCsAndPMIDs($token, $server, $recordId, $metadata, $redcapData);
binREDCapRows($redcapData, $citationIds);
}
@@ -117,7 +133,7 @@ function removeDuplicates($token, $server, $rows, $recordId) {
"redcap_repeat_instance" => $row['redcap_repeat_instance'],
"citation_include" => "0",
);
- upload(array($uploadRow), $token, $server);
+ upload([$uploadRow], $token, $server);
} else {
array_push($alreadySeen, $pmid);
}
diff --git a/reporting/addAppointment.php b/reporting/addAppointment.php
index 91a1eebb..f0e161d7 100644
--- a/reporting/addAppointment.php
+++ b/reporting/addAppointment.php
@@ -22,7 +22,8 @@
die("Invalid record");
}
-$redcapData = Download::fieldsForRecords($token, $server, Application::$customFields, [$recordId]);
+$metadata = Download::metadata($token, $server);
+$redcapData = Download::fieldsForRecords($token, $server, Application::getCustomFields($metadata), [$recordId]);
$max = REDCapManagement::getMaxInstance($redcapData, "custom_grant", $recordId);
if ($start && !REDCapManagement::isDate($start)) {