Skip to content

Commit

Permalink
Merge 6189ada into b2d9fe3
Browse files Browse the repository at this point in the history
  • Loading branch information
Q-gabe committed Nov 9, 2019
2 parents b2d9fe3 + 6189ada commit 0635e9b
Show file tree
Hide file tree
Showing 15 changed files with 623 additions and 170 deletions.
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
** Can't remember when your next appointment is? VISIT reminds you when your next consultation is.
* *Alias / Macro command support* 🔤
** No need to type the same commands over and over, simply add an alias from within the CLI!
* *Save patient information as a .pdf file* 📄
** VISIT allows you to export and store a patient's profile as a .pdf in your own file system!
* *Save patient information as a text file* 📄
** VISIT allows you to export and store a patient's profile in your own file system!
* *Sleek and modern UI* 💼
* *Tagging and Search functionality* 🔎
* *Cross platform* 🖥️
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/unrealunity/visit/commons/util/FileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,13 @@ public static void writeToFile(Path file, String content) throws IOException {
Files.write(file, content.getBytes(CHARSET));
}

/**
* Writes given string to a file.
* Will create the file if it does not exist yet.
*/
public static void writeToProtectedFile(Path file, String content) throws IOException {
Files.write(file, content.getBytes(CHARSET));
file.toFile().setReadOnly();
}

}
186 changes: 145 additions & 41 deletions src/main/java/unrealunity/visit/commons/util/ProfileUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static java.util.Objects.requireNonNull;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Set;

Expand All @@ -14,28 +16,51 @@
import unrealunity.visit.model.tag.Tag;

/**
* Helper functions for handling Person data for displaying in ProfileWindow.
* Helper functions for handling various {@code Person} data for displaying in {@code ProfileWindow}.
*/
public class ProfileUtil {

// Strings for formatting of .txt Profile generation
public static final String BREAKLINE = "=======================================================================\n";
public static final String HEADER = BREAKLINE + "=========================== Patient Profile =============="
+ "=============\n" + BREAKLINE + "\n";
public static final String FOOTER = BREAKLINE + BREAKLINE + BREAKLINE;

// Header Strings for Patient Attributes
public static final String HEADER_NAME = "Name:";
public static final String HEADER_TAG = "Tags:";
public static final String HEADER_PHONE = "Contact Number:";
public static final String HEADER_EMAIL = "Email:";
public static final String HEADER_ADDRESS = "Address:";
public static final String HEADER_VISIT = "Visits:";

// Header Strings for Visit Report
public static final String HEADER_DIAG = "*Diagnosis*";
public static final String HEADER_MED = "*Medication*";
public static final String HEADER_REMARK = "*Remarks*";


/**
* Returns the String representation of the Person's Name attribute.
* @param name a Name instance of a Person. Cannot be null
* @return a String representing the Person's Name attribute
* Returns the {@code String} representation of a {@code Name} instance.
*
* @param name a {@code Name} instance to be shown as a {@code String}. Cannot be null
* @return a {@code String} representing the {@code Name} instance
*/
public static String stringifyName(Name name) {
requireNonNull(name);
requireNonNull(name, "Name cannot be null.");

return name.fullName;
}

/**
* Returns the String representation of the tags associated with a Person from their <SetTag> attribute.
* @param tagSet Set of Tag objects attributed to the Person instance called in setup. Cannot be null
* @return a String representing all Tags in the Person's Tag attribute
* Returns the {@code String} representation of {@code Set<Tag>} instance.
* Each {@code Tag} is separated with a ";" in the returned String representation.
*
* @param tagSet {@code Set} of {@code Tag} instances to be represented as a {@code String}. Cannot be null
* @return a {@code String} representing the {@code Set<Tag>}
*/
public static String stringifyTags(Set<Tag> tagSet) {
requireNonNull(tagSet);
requireNonNull(tagSet, "Set<Tag> cannot be null.");

StringBuilder sb = new StringBuilder();

Expand All @@ -44,79 +69,87 @@ public static String stringifyTags(Set<Tag> tagSet) {
sb.append(tag.tagName);
sb.append("; ");
}
} else {
return "-";
}

return sb.toString();
}

/**
* Returns the String representation of the Phone instance associated with a Person.
* @param phone Phone attribute of the Person in called in setup. Cannot be null
* @return a String representing the Person's Phone attribute
* Returns the {@code String} representation of a {@code Phone} instance.
*
* @param phone {@code Phone} instance to be shown as a {@code String}. Cannot be null
* @return a {@code String} representing the {@code Phone} instance
*/
public static String stringifyPhone(Phone phone) {
requireNonNull(phone);
requireNonNull(phone, "Phone cannot be null.");
return phone.value;
}

/**
* Returns the String representation of the Email instance associated with a Person.
* @param email Email attribute of the Person in called in setup. Cannot be null
* @return a String representing the Person's Email attribute
* Returns the {@code String} representation of a {@code Email} instance. Returns "-" if blank.
*
* @param email {@code Email} instance to be shown as a {@code String}. Cannot be null
* @return a {@code String} representing the {@code Email} instance
*/
public static String stringifyEmail(Email email) {
requireNonNull(email);
requireNonNull(email, "Email cannot be null.");
return email.value;
}

/**
* Returns the String representation of the Address instance associated with a Person.
* @param address Phone attribute of the Person in called in setup. Cannot be null
* @return a String representing the Person's Phone attribute
* Returns the {@code String} representation of a {@code Address} instance.
*
* @param address {@code Address} instance to be shown as a {@code String}. Cannot be null
* @return a {@code String} representing the {@code Address} instance
*/
public static String stringifyAddress(Address address) {
requireNonNull(address);
requireNonNull(address, "Address cannot be null.");
return address.value;
}

/**
* Returns the String representation of the VisitList instance associated with a Person.
* Visits are separated with a line of '=', each block detailing the full 'Diagnosis',
* 'Medication' and 'Remarks' fields from the VisitReport instance. Returns "-" if null.
* @param visitList VisitList attribute of a Person containing VisitReports
* @return a String representing the entire VisitList
* Returns the {@code String} representation of a {@code VisitList} instance. Each {@code VisitReport} in contained
* in the {@code VisitList} is represented in a {@code String} separated with a breakline of '='.
* Returns "-" if null.
*
* @param visitList {@code VisitList} instance to be shown as a {@code String}
* @return a {@code String} representing the {@code VisitList} instance
*/
public static String stringifyVisit(VisitList visitList) {
if (visitList == null) {
return "-";
}

String line = "==================================================================\n";
// Get each all VisitReport instances
ArrayList<VisitReport> visits = visitList.getRecords();

if (visits.size() == 0) {
return "-";
}

// Build String by iterating through all VisitReports
StringBuilder output = new StringBuilder();

for (VisitReport visit : visits) {
output.append(BREAKLINE);
output.append(stringifyVisitReport(visit));
output.append(line);
output.append("\n");
}

return output.toString();
}

/**
* Returns the String representation of a VisitReport, detailing the full 'Diagnosis',
* 'Medication' and 'Remarks' fields from the VisitReport instance.
* @param report the VisitReport instance to be represented. Cannot be null
* @return a String representing the VisitReport
* Returns the {@code String} representation of a {@code VisitReport}, detailing the full 'Diagnosis',
* 'Medication' and 'Remarks' fields from the {@code VisitReport} instance.
*
* @param report {@code VisitReport} instance to be shown as a {@code String}
* @return a {@code String} representing the {@code VisitReport} instance
*/
public static String stringifyVisitReport(VisitReport report) {
requireNonNull(report);
requireNonNull(report, "VisitReport cannot be null.");

String date = report.date;
String diagnosis = report.getDiagnosis();
Expand All @@ -125,19 +158,90 @@ public static String stringifyVisitReport(VisitReport report) {

StringBuilder output = new StringBuilder();

// [Report on the XX/XX/2XXX]
output.append("[ Report on the " + date + "]\n\n");
// Date Stamp for Visit
output.append("[ Report on the " + date + " ]\n\n");

// Appending all report details
output.append(paragraph(HEADER_DIAG, diagnosis));
output.append(paragraph(HEADER_MED, medication));
output.append(paragraph(HEADER_REMARK, remarks));

return output.toString();
}

// *Diagnosis*: DIAGNOSIS
output.append("*Diagnosis*:\n" + diagnosis + "\n\n");
/**
* Returns the {@code String} representation of a {@code LocalDateTime} instance in the "dd-MM-yyyy HH-mm-ss"
* format. The resulting {@code String} is file system friendly (No illegal characters for file naming).
*
* @param time {@code LocalDateTime} instance to be represented as a {@code String}.
* @return {@code String} representation of a {@code LocalDateTime} instance in the "dd-MM-yyyy HH-mm-ss"
* format.
*/
public static String stringifyDate(LocalDateTime time) {
requireNonNull(time, "LocalDateTime time cannot be null.");

// *Medication prescribed*: MEDICATION
output.append("*Medication prescribed*:\n" + medication + "\n\n");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy HH-mm-ss"); // Windows Unix naming safe
return time.format(formatter);
}

// *Remarks*: REMARKS
output.append("*Remarks*:\n" + remarks + "\n\n");
/**
* Builds content of a Profile Report given the following fields. The content is assembled as a {@code String}.
*
* @param name {@code String} representing the {@code Name} on the report.
* @param tags {@code String} representing the {@code Tag} instances on the report.
* @param phone {@code String} representing the {@code Phone} number on the report.
* @param email {@code String} representing the {@code Email} on the report.
* @param address {@code String} representing the {@code Address} on the report.
* @param visits {@code String} representing the {@code VisitList} on the report.
* @param time {@code String} representing the {@code LocalDateTime} in which the report is generated.
* @return {@code String} representing entire content of the report.
*/
public static String buildProfileReport(String name, String tags, String phone, String email,
String address, String visits, String time) {
assert StringUtil.allStringsNotNullOrBlank(name, tags, phone, email,
address, visits, time) : "All fields should not be blank or null";
CollectionUtil.requireAllNonNull(name, tags, phone, email, address, visits, time);

StringBuilder output = new StringBuilder();

output.append(HEADER);
output.append("[Profile generated at " + time + ".]\n\n");

output.append(paragraph(HEADER_NAME, name));
output.append(paragraph(HEADER_TAG, tags));
output.append(paragraph(HEADER_PHONE, phone));
output.append(paragraph(HEADER_EMAIL, email));
output.append(paragraph(HEADER_ADDRESS, address));

output.append("\n");

output.append(paragraph(HEADER_VISIT, visits));

output.append(FOOTER);

return output.toString();
}

/**
* Arranges two {@code String} instances in a paragraph format. Where:<br>
* Example:<pre>
* header
* content
* // Break line
* </pre>
*
* @param header {@code String} representing the header or title of the section/paragraph
* @param content {@code String} representing the content of the section/paragraph
* @return {@code String} representing a complete paragraph composed of {@code header} and {@code content}
*/
public static String paragraph(String header, String content) {
assert StringUtil.allStringsNotNullOrBlank(header, content) : "Header or content should not be null/blank";
StringBuilder paragraph = new StringBuilder();

paragraph.append(header + "\n");
paragraph.append(content + "\n\n");

return paragraph.toString();
}

}
18 changes: 17 additions & 1 deletion src/main/java/unrealunity/visit/commons/util/StringUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ public class StringUtil {
/**
* Returns true if the {@code sentence} contains the {@code word}.
* Ignores case, but a full word match is required.
* <br>examples:<pre>
* <br>Examples:<pre>
* containsWordIgnoreCase("ABc def", "abc") == true
* containsWordIgnoreCase("ABc def", "DEF") == true
* containsWordIgnoreCase("ABc def", "AB") == false //not a full word match
* </pre>
* @param sentence cannot be null
* @param word cannot be null, cannot be empty, must be a single word
* @return boolean for whether the sentence contains a match for the word
*/
public static boolean containsWordIgnoreCase(String sentence, String word) {
requireNonNull(sentence);
Expand Down Expand Up @@ -89,4 +90,19 @@ public static boolean isNonZeroUnsignedInteger(String s) {
return false;
}
}

/**
* Returns false if any Strings are null or blank. Utility function to check a variable number of Strings.
*
* @param strings variable number of Strings
* @return {@code boolean} representing if any Strings are null or blank
*/
public static boolean allStringsNotNullOrBlank (String ...strings) {
for (String str : strings) {
if (str == null || str.isBlank()) {
return false;
}
}
return true;
}
}
Loading

0 comments on commit 0635e9b

Please sign in to comment.