Warn against invalid column headers being used, fail gracefully if ones

are present
This commit is contained in:
Joshua Ramon Enslin 2022-11-29 18:41:41 +01:00
parent 5146305caf
commit c04d63e026
Signed by: jrenslin
GPG Key ID: 46016F84501B70AE
4 changed files with 20 additions and 5 deletions

View File

@ -44,6 +44,7 @@ class CsvxmlValidator {
validate() { validate() {
this.validateMandatoryTagsPresent(); this.validateMandatoryTagsPresent();
this.validateInvalidTagsPresent();
this.checkDuplicateInvNos(); this.checkDuplicateInvNos();
this.checkDependentColumns(); this.checkDependentColumns();
this.checkControlledLists(); this.checkControlledLists();
@ -73,6 +74,18 @@ class CsvxmlValidator {
} }
validateInvalidTagsPresent() {
const headers = Object.keys(this.toValidate[0]);
for (let header of headers) {
if (this.fieldList[header] === undefined) {
this.errors.parsing.push("Invalid column " + header + " detected! Please remove this column or use the appropriate name!");
}
}
}
checkDuplicateInvNos() { checkDuplicateInvNos() {
let invNoEncountered = []; let invNoEncountered = [];
@ -107,6 +120,7 @@ class CsvxmlValidator {
for (let fieldName in line) { for (let fieldName in line) {
if (line[fieldName] === '') continue; if (line[fieldName] === '') continue;
if (this.fieldList[fieldName] === undefined) continue; // This may be the case if invalid fields are present
const dependencies = this.fieldList[fieldName].dependsOn; const dependencies = this.fieldList[fieldName].dependsOn;
if (dependencies === undefined) continue; if (dependencies === undefined) continue;

View File

@ -2,14 +2,15 @@
class CsvxmlValidator{fieldList;toValidate;errors;constructor(fieldList,csvRaw){this.errors={parsing:[],mandatoryTags:[],duplicateInvNos:[],dependentColumns:[],controlledLists:[],mainImageResource:[],};this.fieldList=Object.freeze(fieldList);const data=Papa.parse(csvRaw.trim(),{header:true});if(data.errors.length!==0){window.alert(data.errors);} class CsvxmlValidator{fieldList;toValidate;errors;constructor(fieldList,csvRaw){this.errors={parsing:[],mandatoryTags:[],duplicateInvNos:[],dependentColumns:[],controlledLists:[],mainImageResource:[],};this.fieldList=Object.freeze(fieldList);const data=Papa.parse(csvRaw.trim(),{header:true});if(data.errors.length!==0){window.alert(data.errors);}
let toValidate=data.data;this.toValidate=toValidate;if(toValidate.length===0){alert("Error: No lines of content identified");} let toValidate=data.data;this.toValidate=toValidate;if(toValidate.length===0){alert("Error: No lines of content identified");}
this.validate();} this.validate();}
validate(){this.validateMandatoryTagsPresent();this.checkDuplicateInvNos();this.checkDependentColumns();this.checkControlledLists();} validate(){this.validateMandatoryTagsPresent();this.validateInvalidTagsPresent();this.checkDuplicateInvNos();this.checkDependentColumns();this.checkControlledLists();}
validateMandatoryTagsPresent(){let mandatoryFields=[];for(let fieldName in this.fieldList){if(this.fieldList[fieldName].required===true){mandatoryFields.push(fieldName);}} validateMandatoryTagsPresent(){let mandatoryFields=[];for(let fieldName in this.fieldList){if(this.fieldList[fieldName].required===true){mandatoryFields.push(fieldName);}}
console.log(this.toValidate);let lineCounter=1;for(let line of this.toValidate){for(let mandatoryField of mandatoryFields){if(line[mandatoryField]===undefined||line[mandatoryField]===null||line[mandatoryField]===''){this.errors.mandatoryTags.push("Missing or empty mandatory tag "+mandatoryField+" on line "+lineCounter);}} console.log(this.toValidate);let lineCounter=1;for(let line of this.toValidate){for(let mandatoryField of mandatoryFields){if(line[mandatoryField]===undefined||line[mandatoryField]===null||line[mandatoryField]===''){this.errors.mandatoryTags.push("Missing or empty mandatory tag "+mandatoryField+" on line "+lineCounter);}}
lineCounter++;}} lineCounter++;}}
validateInvalidTagsPresent(){const headers=Object.keys(this.toValidate[0]);for(let header of headers){if(this.fieldList[header]===undefined){this.errors.parsing.push("Invalid column "+header+" detected! Please remove this column or use the appropriate name!");}}}
checkDuplicateInvNos(){let invNoEncountered=[];let lineCounter=1;for(let line of this.toValidate){if(invNoEncountered.includes(line.inventory_number)){this.errors.duplicateInvNos.push("Duplicate inventory number "+line.inventory_number+" on line "+lineCounter);} checkDuplicateInvNos(){let invNoEncountered=[];let lineCounter=1;for(let line of this.toValidate){if(invNoEncountered.includes(line.inventory_number)){this.errors.duplicateInvNos.push("Duplicate inventory number "+line.inventory_number+" on line "+lineCounter);}
invNoEncountered.push(line.inventory_number);lineCounter++;}} invNoEncountered.push(line.inventory_number);lineCounter++;}}
checkDependentColumns(){const headers=Object.keys(this.toValidate[0]);for(let header of headers){if(this.fieldList[header]===undefined||this.fieldList[header].dependsOn===undefined||this.fieldList[header].dependsOn===null)continue;let dependencies=this.fieldList[header].dependsOn;for(let dep of dependencies){if(headers.includes(dep)===false){this.errors.dependentColumns.push("Dependency issue at column "+header+": Corresponding column "+dep+" is missing");}}} checkDependentColumns(){const headers=Object.keys(this.toValidate[0]);for(let header of headers){if(this.fieldList[header]===undefined||this.fieldList[header].dependsOn===undefined||this.fieldList[header].dependsOn===null)continue;let dependencies=this.fieldList[header].dependsOn;for(let dep of dependencies){if(headers.includes(dep)===false){this.errors.dependentColumns.push("Dependency issue at column "+header+": Corresponding column "+dep+" is missing");}}}
let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(line[fieldName]==='')continue;const dependencies=this.fieldList[fieldName].dependsOn;if(dependencies===undefined)continue;for(let dependency of dependencies){if(line[dependency]===''){this.errors.dependentColumns.push("Dependency issue at column "+fieldName+": Corresponding column "+dependency+" is empty");}}} let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(line[fieldName]==='')continue;if(this.fieldList[fieldName]===undefined)continue;const dependencies=this.fieldList[fieldName].dependsOn;if(dependencies===undefined)continue;for(let dependency of dependencies){if(line[dependency]===''){this.errors.dependentColumns.push("Dependency issue at column "+fieldName+": Corresponding column "+dependency+" is empty");}}}
lineCounter++;}} lineCounter++;}}
checkControlledLists(){let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(this.fieldList[fieldName]===undefined){console.log("Undefined but requested field "+fieldName);continue;} checkControlledLists(){let lineCounter=1;for(let line of this.toValidate){for(let fieldName in line){if(this.fieldList[fieldName]===undefined){console.log("Undefined but requested field "+fieldName);continue;}
const allowedValues=this.fieldList[fieldName].allowedValues;if(allowedValues===undefined||allowedValues===null)continue;if(Object.values(allowedValues).length===0||Object.values(allowedValues).includes(line[fieldName])){continue;} const allowedValues=this.fieldList[fieldName].allowedValues;if(allowedValues===undefined||allowedValues===null)continue;if(Object.values(allowedValues).length===0||Object.values(allowedValues).includes(line[fieldName])){continue;}

View File

@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="assets/css/csvxml.min.css?v000006" /> <link rel="stylesheet" type="text/css" href="assets/css/csvxml.min.css?v000008" />
<link rel="manifest" href="/manifest.json" /> <link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#aa4400" /> <meta name="theme-color" content="#aa4400" />
@ -27,7 +27,7 @@
</head> </head>
<body class="loading"> <body class="loading">
<script src="assets/js/csvxmlV2.min.js?v000006" type="text/javascript" async></script> <script src="assets/js/csvxmlV2.min.js?v000008" type="text/javascript" async></script>
</body> </body>
</html> </html>

View File

@ -7,7 +7,7 @@
declare(strict_types = 1); declare(strict_types = 1);
require_once __DIR__ . "/../functions/functions.php"; require_once __DIR__ . "/../functions/functions.php";
const GET_PARAM_JS_CSS = "v000006"; const GET_PARAM_JS_CSS = "v000008";
/** /**
* Generates the json for a translation file. * Generates the json for a translation file.