Created
October 21, 2016 22:41
-
-
Save bonetechnologies/190a6904eaa1e63620cad9d36f8cfd30 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package controllers; | |
import com.google.common.base.Optional; | |
import com.google.common.collect.Lists; | |
import com.google.common.collect.Maps; | |
import models.*; | |
import org.apache.commons.lang3.StringUtils; | |
import org.apache.pdfbox.exceptions.COSVisitorException; | |
import org.apache.pdfbox.pdmodel.PDDocument; | |
import org.apache.pdfbox.pdmodel.PDDocumentCatalog; | |
import org.apache.pdfbox.pdmodel.PDPage; | |
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream; | |
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg; | |
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm; | |
import org.apache.pdfbox.pdmodel.interactive.form.PDCheckbox; | |
import org.apache.pdfbox.pdmodel.interactive.form.PDField; | |
import org.imgscalr.Scalr; | |
import play.Logger; | |
import play.mvc.Result; | |
import securesocial.core.java.SecureSocial; | |
import securesocial.core.java.SecuredAction; | |
import service.PDFUtil; | |
import service.SiteLogItemManager; | |
import javax.imageio.ImageIO; | |
import java.awt.image.BufferedImage; | |
import java.io.ByteArrayInputStream; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.text.DateFormat; | |
import java.text.DecimalFormat; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.*; | |
import java.util.stream.Collectors; | |
import static play.mvc.Controller.ctx; | |
import static play.mvc.Controller.response; | |
import static play.mvc.Results.ok; | |
public class PdfController { | |
public static Logger.ALogger logger = Logger.of("PdfController"); | |
@SecuredAction | |
public static Result buildPdf(Long serviceCallId, boolean isFlatten) throws IOException, COSVisitorException, ParseException, InterruptedException { | |
Employee employee = (Employee) ctx().args.get(SecureSocial.USER_KEY); | |
ServiceCall serviceCall = ServiceCall.find.byId(serviceCallId); | |
SiteLogItemManager.createSiteLogItem(SiteLogItem.SiteLogItemType.GENERATE_PDF, employee.name, "Generated PDF for Service Call Id: " + serviceCallId, Optional.of(serviceCall.serviceCallNumber)); | |
InputStream origPdfInputStream = PdfController.class.getResourceAsStream("/orig_pdf.pdf"); | |
PDDocument load = PDDocument.load(origPdfInputStream); | |
response().setContentType("application/pdf"); | |
return ok(buildReport(serviceCall, load, isFlatten)); | |
} | |
private static byte[] buildReport(ServiceCall serviceCall, PDDocument pdDocument, boolean isFlatten) throws IOException, COSVisitorException, ParseException, InterruptedException { | |
if (serviceCall.serviceCallLink != null) { | |
ServiceCall serviceCallLink = ServiceCall.find.where().eq("service_call_number", serviceCall.serviceCallLink).findUnique(); | |
setFieldValue(pdDocument, "S", String.valueOf(serviceCallLink.serviceCallNumber)); | |
} | |
setFieldValue(pdDocument, "S", String.valueOf(serviceCall.serviceCallNumber)); | |
Date dateOfCall = getDateFromString(serviceCall.dateOfCall); | |
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy"); | |
String dayOfCall = simpleDateFormat.format(dateOfCall); | |
simpleDateFormat = new SimpleDateFormat("hh:mm a"); | |
String timeOfCall = simpleDateFormat.format(dateOfCall); | |
setFieldValue(pdDocument, "Date of Call", dayOfCall); | |
setFieldValue(pdDocument, "Time of Call", timeOfCall); | |
setFieldValue(pdDocument, "PO", serviceCall.purchaseOrderNumber); | |
setFieldValue(pdDocument, "Call Taken By", getShortName(serviceCall.callTakenBy)); | |
setFieldValue(pdDocument, "Account Rep", getShortName(serviceCall.accountRep)); | |
setFieldValue(pdDocument, "Customer Name", serviceCall.customer.name); | |
setFieldValue(pdDocument, "Job Location", serviceCall.jobSite.name); | |
setFieldValue(pdDocument, "Job Address", buildJobSiteAddress(serviceCall)); | |
setFieldValue(pdDocument, "Office", serviceCall.customer.phoneNumber); | |
setFieldValue(pdDocument, "Jobsite", serviceCall.jobSite.phoneNumber); | |
setFieldValue(pdDocument, "Office Contact", serviceCall.customer.primaryContact); | |
setFieldValue(pdDocument, "Jobsite Contact", serviceCall.jobSite.primaryContact); | |
checkRoofTypeBox(pdDocument, serviceCall.roofType); | |
checkJobTypeBox(pdDocument, serviceCall.jobType); | |
fillOutServiceRequestDetailLines(pdDocument, serviceCall); | |
fillOutCauseWorkPerformed(pdDocument, serviceCall); | |
populateHours(pdDocument, serviceCall); | |
setFieldValue(pdDocument, "Date of Service", getTimeOfService(serviceCall)); | |
populateSignature(pdDocument, serviceCall); | |
fillOutMaterialsUsed(pdDocument, serviceCall); | |
fillOurHoursForBilling(pdDocument, serviceCall); | |
fillOutTotalAmountToBill(pdDocument, serviceCall); | |
addAerialPhoto(pdDocument, serviceCall); | |
setFieldValue(pdDocument, "Jobsite Notes", serviceCall.jobSite.notes); | |
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); | |
if (isFlatten) { | |
PDFUtil.makeAllWidgetsReadOnly(pdDocument); | |
PDFUtil.flattenPDF(pdDocument); | |
} | |
pdDocument.save(byteArrayOutputStream); | |
pdDocument.close(); | |
return byteArrayOutputStream.toByteArray(); | |
} | |
static class BasicTextSorter implements Comparator<FieldTechWorkPerformed> { | |
public int compare(FieldTechWorkPerformed p1, FieldTechWorkPerformed p2) { | |
Date p1Date = null; | |
Date p2Date = null; | |
p1Date = getDateFromString(p1.timeOut); | |
p2Date = getDateFromString(p2.timeOut); | |
assert p1Date != null; | |
assert p2Date != null; | |
return p2Date.compareTo(p1Date); | |
} | |
} | |
private static String getTimeOfService(ServiceCall serviceCall) throws ParseException { | |
List<FieldTechWorkPerformed> fieldTechWorkPerformedItems = serviceCall.fieldTechWorkPerformedItems; | |
Collections.sort(fieldTechWorkPerformedItems, new BasicTextSorter()); | |
if (fieldTechWorkPerformedItems.size() > 0) { | |
Date dateFromString = getDateFromString(fieldTechWorkPerformedItems.get(0).timeOut); | |
SimpleDateFormat formatter | |
= new SimpleDateFormat("MM/dd/yyyy"); | |
return formatter.format(dateFromString); | |
} else { | |
return ""; | |
} | |
} | |
private static void fillOutServiceRequestDetailLines(PDDocument pdDocument, ServiceCall serviceCall) throws IOException { | |
String details = "(Requested: " + serviceCall.dateOfService + ") " + serviceCall.serviceRequestDetails; | |
List<String> strings = splitString(details, 78); | |
String join = StringUtils.join(strings, "\r\n"); | |
setFieldValue(pdDocument, "Service Request Details", join); | |
} | |
private static List<String> splitString(String input, int maxLineLength) { | |
StringTokenizer tok = new StringTokenizer(input, " "); | |
StringBuilder output = new StringBuilder(input.length()); | |
int lineLen = 0; | |
while (tok.hasMoreTokens()) { | |
String word = tok.nextToken(); | |
if (lineLen + word.length() > maxLineLength) { | |
output.append("\n"); | |
lineLen = 0; | |
} | |
output.append(word).append(" "); | |
lineLen += word.length(); | |
} | |
String[] split = output.toString().split("\\r?\\n"); | |
return new ArrayList<>(Arrays.asList(split)); | |
} | |
private static void addAerialPhoto(PDDocument pdDocument, ServiceCall serviceCall) throws IOException, InterruptedException { | |
if (serviceCall.serviceCallPhotos == null) { | |
return; | |
} | |
ServiceCallPhoto serviceCallP = null; | |
for (ServiceCallPhoto serviceCallPhoto : serviceCall.serviceCallPhotos) { | |
if (serviceCallPhoto.photoType.equals(ServiceCallPhotoType.AERIAL.getType())) { | |
serviceCallP = serviceCallPhoto; | |
} | |
} | |
if (serviceCallP == null) { | |
return; | |
} | |
PDPage pdPage = (PDPage) pdDocument.getDocumentCatalog().getAllPages().get(1); | |
PDPageContentStream stream = new PDPageContentStream(pdDocument, pdPage, true, true); | |
byte[] large = serviceCallP.getLarge(); | |
final byte[] bytes = ServiceCallPhotosController.convertToJpg(large, 463, 210, Scalr.Mode.FIT_EXACT); | |
InputStream in = new ByteArrayInputStream(bytes); | |
BufferedImage bImageFromConvert = ImageIO.read(in); | |
PDJpeg img = new PDJpeg(pdDocument, bImageFromConvert); | |
stream.drawImage(img, 72, 538); | |
stream.close(); | |
} | |
private static void fillOutMaterialsUsed(PDDocument pdDocument, ServiceCall serviceCall) throws IOException { | |
DecimalFormat df = new DecimalFormat(); | |
df.setMaximumFractionDigits(2); | |
df.setMinimumFractionDigits(2); | |
int i = 1; | |
float totalCostToBeBilled = 0; | |
for (MaterialUsed materialUsed : ServiceCallController.getMaterialUsed(serviceCall)) { | |
String materialUsedField = "Material UsedRow" + i; | |
String amountUsedField = "Amount UsedRow" + i; | |
String itemCostField = "Item CostRow" + i; | |
String totalCostField = "Total CostRow" + i; | |
String materialUsedName = materialUsed.materialName; | |
if (isLinked(serviceCall)) { | |
materialUsedName = materialUsedName + " (SC" + serviceCall.serviceCallNumber + ")"; | |
} | |
setFieldValue(pdDocument, materialUsedField, materialUsedName); | |
setFieldValue(pdDocument, amountUsedField, String.valueOf(materialUsed.materialAmount)); | |
setFieldValue(pdDocument, itemCostField, "$" + df.format(materialUsed.itemCost)); | |
float totalCost = materialUsed.itemCost * materialUsed.materialAmount; | |
totalCostToBeBilled += totalCost; | |
setFieldValue(pdDocument, totalCostField, "$" + df.format(totalCost)); | |
i++; | |
} | |
if (serviceCall.serviceCallLink != null) { | |
ServiceCall serviceCallLinked = ServiceCall.find.byId(serviceCall.serviceCallLink); | |
if (serviceCallLinked != null) { | |
for (MaterialUsed materialUsed : ServiceCallController.getMaterialUsed(serviceCallLinked)) { | |
String materialUsedField = "Material UsedRow" + i; | |
String amountUsedField = "Amount UsedRow" + i; | |
String itemCostField = "Item CostRow" + i; | |
String totalCostField = "Total CostRow" + i; | |
setFieldValue(pdDocument, materialUsedField, materialUsed.materialName + " (SC" + serviceCallLinked.serviceCallNumber + ")"); | |
setFieldValue(pdDocument, amountUsedField, String.valueOf(materialUsed.materialAmount)); | |
setFieldValue(pdDocument, itemCostField, "$" + df.format(materialUsed.itemCost)); | |
float totalCost = materialUsed.itemCost * materialUsed.materialAmount; | |
totalCostToBeBilled += totalCost; | |
setFieldValue(pdDocument, totalCostField, "$" + df.format(totalCost)); | |
i++; | |
} | |
} | |
} | |
setFieldValue(pdDocument, "Total CostAmt", "$" + df.format(totalCostToBeBilled)); | |
} | |
private static HoursAndMins getHoursAndMins(FieldTechWorkPerformed fieldTechWorkPerformed) throws ParseException { | |
Date timeIN = getDateFromString(fieldTechWorkPerformed.timeIn); | |
Date timeOUT = getDateFromString(fieldTechWorkPerformed.timeOut); | |
int secsForRate = (int) (timeOUT.getTime() - timeIN.getTime()) / 1000; | |
int minutesForRate = secsForRate / 60; | |
float minuteRate = fieldTechWorkPerformed.hourlyWage / 60; | |
float totalCost = minutesForRate * minuteRate; | |
int secs = (int) (timeOUT.getTime() - timeIN.getTime()) / 1000; | |
int hours = (int) (secs / 3600); | |
secs = secs % 3600; | |
int mins = (int) (secs / 60); | |
return new HoursAndMins(hours, mins, totalCost); | |
} | |
private static void fillOurHoursForBilling(PDDocument pdDocument, ServiceCall serviceCall) throws IOException, ParseException { | |
DecimalFormat df = new DecimalFormat(); | |
df.setMaximumFractionDigits(2); | |
df.setMinimumFractionDigits(2); | |
float totalCostToBeBilled = 0; | |
totalCostToBeBilled += populateLaborRows(serviceCall, pdDocument, false); | |
if (serviceCall.serviceCallLink != null) { | |
ServiceCall serviceCallLinked = ServiceCall.find.where().eq("service_call_number", serviceCall.serviceCallLink).findUnique(); | |
totalCostToBeBilled += populateLaborRows(serviceCallLinked, pdDocument, true); | |
} | |
setFieldValue(pdDocument, "Total CostAmt Labor", "$" + df.format(totalCostToBeBilled)); | |
} | |
private static Map<String, List<FieldTechWorkPerformed>> getEmployeeWorkMap(List<FieldTechWorkPerformed> fieldTechWorkPerformedItems) { | |
Map<String, List<FieldTechWorkPerformed>> employeeWorkItemsMap = Maps.newLinkedHashMap(); | |
for (FieldTechWorkPerformed fieldTechWorkPerformed : fieldTechWorkPerformedItems) { | |
if (!employeeWorkItemsMap.containsKey(fieldTechWorkPerformed.employeeName)) { | |
employeeWorkItemsMap.put(fieldTechWorkPerformed.employeeName, Lists.newArrayList()); | |
} | |
employeeWorkItemsMap.get(fieldTechWorkPerformed.employeeName).add(fieldTechWorkPerformed); | |
} | |
return employeeWorkItemsMap; | |
} | |
private static float populateLaborRows(ServiceCall serviceCall, PDDocument pdDocument, boolean isLinked) throws IOException, ParseException { | |
DecimalFormat df = new DecimalFormat(); | |
df.setMaximumFractionDigits(2); | |
df.setMinimumFractionDigits(2); | |
Map<String, List<FieldTechWorkPerformed>> employeeWorkItemsMap = getEmployeeWorkMap(ServiceCallController.getFieldTechWorkPerformedItems(serviceCall)); | |
int i = 1; | |
float totalCostToBeBilled = 0; | |
for (Map.Entry<String, List<FieldTechWorkPerformed>> entry : employeeWorkItemsMap.entrySet()) { | |
List<FieldTechWorkPerformed> workPerformeds = entry.getValue(); | |
String employeeName = entry.getKey(); | |
String technicianNameField = "Technicians " + i; | |
String technicianHoursField = "HoursRow" + i; | |
String technicianRatePerHour = "Rate per HourRow" + i; | |
String techniciantotalCostRow = "Total CostRow" + i + "_2"; | |
float rowCost = 0; | |
int hours = 0; | |
int mins = 0; | |
float hourlyWage = 0; | |
for (FieldTechWorkPerformed workPerformed : workPerformeds) { | |
hourlyWage = workPerformed.hourlyWage; | |
HoursAndMins hoursAndMins = getHoursAndMins(workPerformed); | |
rowCost += hoursAndMins.getTotalCost(); | |
hours += hoursAndMins.getHours(); | |
mins += hoursAndMins.getMinutes(); | |
} | |
if (isLinked(serviceCall)) { | |
employeeName = employeeName + " (SC" + serviceCall.serviceCallNumber + ")"; | |
} | |
if (isLinked) { | |
setFieldValue(pdDocument, technicianNameField, employeeName + " (SC" + serviceCall.serviceCallNumber + ")"); | |
} else { | |
setFieldValue(pdDocument, technicianNameField, employeeName); | |
} | |
setFieldValue(pdDocument, technicianHoursField, hours + "h " + mins + "m"); | |
setFieldValue(pdDocument, technicianRatePerHour, "$" + df.format(hourlyWage)); | |
totalCostToBeBilled += rowCost; | |
setFieldValue(pdDocument, techniciantotalCostRow, "$" + df.format(rowCost)); | |
i++; | |
} | |
return totalCostToBeBilled; | |
} | |
private static void setFieldValue(PDDocument pdDocument, String fieldName, String value) throws IOException { | |
if (value == null) { | |
return; | |
} | |
PDDocumentCatalog docCatalog = pdDocument.getDocumentCatalog(); | |
PDAcroForm acroForm = docCatalog.getAcroForm(); | |
acroForm.getField(fieldName).setValue(value); | |
} | |
private static void checkRoofTypeBox(PDDocument pdDocument, String type) throws IOException { | |
PDAcroForm form = pdDocument.getDocumentCatalog().getAcroForm(); | |
RoofType roofType = RoofType.getFromString(type); | |
PDField field = form.getField(roofType.getPdfFieldName()); | |
((PDCheckbox) field).check(); | |
} | |
private static void checkJobTypeBox(PDDocument pdDocument, String type) throws IOException { | |
PDAcroForm form = pdDocument.getDocumentCatalog().getAcroForm(); | |
JobType jobType = JobType.getFromString(type); | |
PDField field = form.getField(jobType.getPdfFieldName()); | |
((PDCheckbox) field).check(); | |
} | |
private static void fillOutCauseWorkPerformed(PDDocument pdDocument, ServiceCall serviceCall) throws IOException { | |
List<FieldTechWorkPerformed> fieldTechWorkPerformedItems = ServiceCallController.getFieldTechWorkPerformedItems(serviceCall); | |
Set<String> workCauseDescriptions = fieldTechWorkPerformedItems.stream().map(sc -> sc.fieldTechWorkPerformedDescription).collect(Collectors.toSet()); | |
fieldTechWorkPerformedItems.stream().map(sc -> sc.fieldTechWorkPerformedDescription).collect(Collectors.toSet()); | |
int i = 1; | |
for (String description : workCauseDescriptions) { | |
String currentField = "Work Performed " + i; | |
i++; | |
if (isLinked(serviceCall)) { | |
description = description + " (SC" + serviceCall.serviceCallNumber + ")"; | |
} | |
setFieldValue(pdDocument, currentField, description); | |
} | |
if (serviceCall.serviceCallLink != null) { | |
ServiceCall serviceCallLinked = ServiceCall.find.byId(serviceCall.serviceCallLink); | |
if (serviceCallLinked != null) { | |
for (String description : ServiceCallController.getFieldTechWorkPerformedItems(serviceCallLinked).stream().map(sc -> sc.fieldTechWorkPerformedDescription).collect(Collectors.toSet())) { | |
String currentField = "Work Performed " + i; | |
i++; | |
setFieldValue(pdDocument, currentField, description + " (SC" + serviceCallLinked.serviceCallNumber + ")"); | |
} | |
} | |
} | |
} | |
private static boolean isLinked(ServiceCall serviceCall) { | |
if (serviceCall.serviceCallLink != null) { | |
return true; | |
} | |
return false; | |
} | |
private static String getShortName(String fullName) { | |
List<String> split = Arrays.asList(fullName.split("\\s+")); | |
if (split.size() > 1) { | |
String lastName = split.get(split.size() - 1); | |
String firstInitial = String.valueOf(split.get(0).toCharArray()[0]); | |
return firstInitial + " " + lastName; | |
} else { | |
return fullName; | |
} | |
} | |
public static Date getDateFromString(String stringDate) { | |
Date returnDate = new Date(0); | |
try { | |
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a"); | |
returnDate = format.parse(stringDate); | |
} catch (Exception e) { | |
logger.error("Unable to parse date, or empty."); | |
} | |
return returnDate; | |
} | |
private static HoursAndMins getHoursAndMinsForType(List<FieldTechWorkPerformed> fieldTechWorkPerformeds, String type) throws ParseException { | |
int totalHours = 0; | |
int totalMins = 0; | |
for (FieldTechWorkPerformed fieldTechWorkPerformed : fieldTechWorkPerformeds) { | |
if (fieldTechWorkPerformed.workType.equalsIgnoreCase(type)) { | |
HoursAndMins hoursAndMins = getHoursAndMins(fieldTechWorkPerformed); | |
totalHours += hoursAndMins.getHours(); | |
totalMins += hoursAndMins.getMinutes(); | |
} | |
} | |
return new HoursAndMins(totalHours, totalMins, 0); | |
} | |
private static void filloutHours(PDDocument pdDocument, ServiceCall serviceCall, boolean isLinked) throws ParseException, IOException { | |
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm a"); | |
int i = 1; | |
Map<String, List<FieldTechWorkPerformed>> employeeWorkMap = getEmployeeWorkMap(ServiceCallController.getFieldTechWorkPerformedItems(serviceCall)); | |
for (Map.Entry<String, List<FieldTechWorkPerformed>> entry : employeeWorkMap.entrySet()) { | |
int totalHours = 0; | |
int totalMins = 0; | |
Date oldest = getOldestdate(entry.getValue()); | |
Date newest = getNewestdate(entry.getValue()); | |
Set<String> workTypes = entry.getValue().stream().map(f -> f.workType).collect(Collectors.toSet()); | |
Map<String, HoursAndMins> hoursAndMinsByType = Maps.newLinkedHashMap(); | |
for (String type : workTypes) { | |
HoursAndMins hoursAndMinsForType = getHoursAndMinsForType(entry.getValue(), type); | |
hoursAndMinsByType.put(type, hoursAndMinsForType); | |
} | |
if (isLinked(serviceCall) || isLinked) { | |
setFieldValue(pdDocument, "Page 1 Technicians " + i, entry.getKey() + " (SC" + serviceCall.serviceCallNumber + ")"); | |
} else { | |
setFieldValue(pdDocument, "Page 1 Technicians " + i, entry.getKey()); | |
} | |
String timeIn = simpleDateFormat.format(oldest); | |
setFieldValue(pdDocument, "Time In " + i, timeIn); | |
String timeOut = simpleDateFormat.format(newest); | |
setFieldValue(pdDocument, "Time Out " + i, timeOut); | |
for (Map.Entry<String, HoursAndMins> e : hoursAndMinsByType.entrySet()) { | |
HoursAndMins hoursAndMins = e.getValue(); | |
totalHours += hoursAndMins.getHours(); | |
totalMins += hoursAndMins.getMinutes(); | |
FieldTechWorkPerformedTimeType byType = FieldTechWorkPerformedTimeType.getByType(e.getKey()); | |
setFieldValue(pdDocument, byType.getPdfFieldName() + " " + i, hoursAndMins.getHours() + "h " + hoursAndMins.getMinutes() + "m"); | |
} | |
totalMins += (totalHours * 60); | |
int hours = totalMins / 60; //since both are ints, you get an int | |
int minutes = totalMins % 60; | |
setFieldValue(pdDocument, "Total time row" + " " + i, hours + "h " + minutes + "m"); | |
i++; | |
} | |
} | |
private static void populateHours(PDDocument pdDocument, ServiceCall serviceCall) throws IOException, ParseException { | |
filloutHours(pdDocument, serviceCall, false); | |
if (serviceCall.serviceCallLink != null) { | |
ServiceCall serviceCallLinked = ServiceCall.find.where().eq("service_call_number", serviceCall.serviceCallLink).findUnique(); | |
filloutHours(pdDocument, serviceCallLinked, true); | |
} | |
} | |
private static void populateSignature(PDDocument pdDocument, ServiceCall serviceCall) throws IOException { | |
if (serviceCall.signature == null) { | |
return; | |
} | |
PDPage pdPage = (PDPage) pdDocument.getDocumentCatalog().getAllPages().get(0); | |
PDPageContentStream stream = new PDPageContentStream(pdDocument, pdPage, true, true); | |
byte[] signatureImageThumbJpeg = serviceCall.signature.getSignatureImageThumbJpeg(); | |
InputStream in = new ByteArrayInputStream(signatureImageThumbJpeg); | |
BufferedImage bImageFromConvert = ImageIO.read(in); | |
PDJpeg img = new PDJpeg(pdDocument, bImageFromConvert); | |
stream.drawImage(img, 310, 30); | |
stream.close(); | |
} | |
private static void fillOutTotalAmountToBill(PDDocument pdDocument, ServiceCall serviceCall) throws ParseException, IOException { | |
DecimalFormat df = new DecimalFormat(); | |
df.setMaximumFractionDigits(2); | |
df.setMinimumFractionDigits(2); | |
float totalToBill = 0; | |
for (MaterialUsed materialUsed : ServiceCallController.getMaterialUsed(serviceCall)) { | |
totalToBill += materialUsed.itemCost * materialUsed.materialAmount; | |
} | |
for (FieldTechWorkPerformed fieldTechWorkPerformed : ServiceCallController.getFieldTechWorkPerformedItems(serviceCall)) { | |
Date timeIN = getDateFromString(fieldTechWorkPerformed.timeIn); | |
Date timeOUT = getDateFromString(fieldTechWorkPerformed.timeOut); | |
int secsForRate = (int) (timeOUT.getTime() - timeIN.getTime()) / 1000; | |
int minutesForRate = secsForRate / 60; | |
float minuteRate = fieldTechWorkPerformed.hourlyWage / 60; | |
totalToBill += minutesForRate * minuteRate; | |
} | |
setFieldValue(pdDocument, "Amount to Bill", "$" + df.format(totalToBill)); | |
} | |
private static Date getOldestdate(List<FieldTechWorkPerformed> workPerformeds) throws ParseException { | |
Date oldest = null; | |
List<String> timeInDateStrings = workPerformeds.stream().map(w -> w.timeIn).collect(Collectors.toList()); | |
for (String dateString : timeInDateStrings) { | |
Date dateFromString = getDateFromString(dateString); | |
if (oldest == null) { | |
oldest = dateFromString; | |
} else { | |
Date least = least(dateFromString, oldest); | |
oldest = least; | |
} | |
} | |
return oldest; | |
} | |
public static Date least(Date a, Date b) { | |
return a == null ? b : (b == null ? a : (a.before(b) ? a : b)); | |
} | |
private static Date getNewestdate(List<FieldTechWorkPerformed> workPerformeds) throws ParseException { | |
List<String> timeOutStrings = workPerformeds.stream().map(d -> d.timeOut).collect(Collectors.toList()); | |
List<Date> dates = Lists.newArrayList(); | |
for (String d: timeOutStrings) { | |
Date dateFromString = getDateFromString(d); | |
dates.add(dateFromString); | |
} | |
Collections.sort(dates); | |
return dates.get(dates.size() - 1); | |
} | |
private static String buildJobSiteAddress(ServiceCall serviceCall) { | |
String streetAddress = serviceCall.jobSite.streetAddress; | |
String city = serviceCall.jobSite.city; | |
String zipCode = serviceCall.jobSite.zipCode; | |
String state = serviceCall.jobSite.state; | |
return streetAddress + " " + city + ", " + state + " " + zipCode; | |
} | |
public static class HoursAndMins { | |
private final int hours; | |
private final int minutes; | |
private final float totalCost; | |
public HoursAndMins(int hours, int minutes, float totalCost) { | |
this.hours = hours; | |
this.minutes = minutes; | |
this.totalCost = totalCost; | |
} | |
public int getHours() { | |
return hours; | |
} | |
public int getMinutes() { | |
return minutes; | |
} | |
public float getTotalCost() { | |
return totalCost; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment