From b14169a2b7bfcaecaa0f5ea9baafad4e7e4f1ae2 Mon Sep 17 00:00:00 2001 From: Abyss777 Date: Wed, 23 Nov 2016 11:41:11 +0500 Subject: [PATCH] - Pass client timezone to excel template - Templates: adjust timezone, use "https" in links --- .../traccar/api/resource/ReportResource.java | 12 ++++-------- src/org/traccar/helper/DateUtil.java | 6 ++++++ src/org/traccar/reports/Events.java | 9 +++++++-- src/org/traccar/reports/Route.java | 10 ++++++++-- src/org/traccar/reports/Summary.java | 9 +++++++-- src/org/traccar/reports/Trips.java | 9 +++++++-- templates/export/events.xlsx | Bin 12307 -> 12346 bytes templates/export/route.xlsx | Bin 12806 -> 13042 bytes templates/export/summary.xlsx | Bin 12330 -> 12315 bytes templates/export/trips.xlsx | Bin 13161 -> 13197 bytes 10 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/org/traccar/api/resource/ReportResource.java b/src/org/traccar/api/resource/ReportResource.java index 2717fe01e..e8e80fa2f 100644 --- a/src/org/traccar/api/resource/ReportResource.java +++ b/src/org/traccar/api/resource/ReportResource.java @@ -50,8 +50,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); - Route.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); + Route.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); return Response.ok(stream.toByteArray()) .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); @@ -76,8 +75,7 @@ public class ReportResource extends BaseResource { @QueryParam("type") final List types, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); - Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, - DateUtil.parseDate(from), DateUtil.parseDate(to)); + Events.getExcel(stream, getUserId(), deviceIds, groupIds, types, from, to); return Response.ok(stream.toByteArray()) .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); @@ -100,8 +98,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); - Summary.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); + Summary.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); return Response.ok(stream.toByteArray()) .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); @@ -124,8 +121,7 @@ public class ReportResource extends BaseResource { @QueryParam("deviceId") final List deviceIds, @QueryParam("groupId") final List groupIds, @QueryParam("from") String from, @QueryParam("to") String to) throws SQLException, IOException { ByteArrayOutputStream stream = new ByteArrayOutputStream(); - Trips.getExcel(stream, getUserId(), deviceIds, groupIds, - DateUtil.parseDate(from), DateUtil.parseDate(to)); + Trips.getExcel(stream, getUserId(), deviceIds, groupIds, from, to); return Response.ok(stream.toByteArray()) .header(HttpHeaders.CONTENT_DISPOSITION, CONTENT_DISPOSITION_VALUE_XLSX).build(); diff --git a/src/org/traccar/helper/DateUtil.java b/src/org/traccar/helper/DateUtil.java index ad8534eb8..840f37a7a 100644 --- a/src/org/traccar/helper/DateUtil.java +++ b/src/org/traccar/helper/DateUtil.java @@ -18,12 +18,14 @@ package org.traccar.helper; import java.util.Calendar; import java.util.Date; +import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; public final class DateUtil { private static final DateTimeFormatter DATE_FORMAT = ISODateTimeFormat.dateTime(); + private static final DateTimeFormatter DATE_FORMAT_NOMILLIS = ISODateTimeFormat.dateTimeNoMillis(); private DateUtil() { } @@ -64,4 +66,8 @@ public final class DateUtil { return DATE_FORMAT.parseDateTime(value).toDate(); } + public static DateTime parseDateTime(String value) { + return DATE_FORMAT_NOMILLIS.withOffsetParsed().parseDateTime(value); + } + } diff --git a/src/org/traccar/reports/Events.java b/src/org/traccar/reports/Events.java index 9d82b97a5..ada1580d9 100644 --- a/src/org/traccar/reports/Events.java +++ b/src/org/traccar/reports/Events.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import org.joda.time.DateTime; import org.jxls.area.Area; import org.jxls.builder.xls.XlsCommentAreaBuilder; import org.jxls.common.CellRef; @@ -36,6 +37,7 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.helper.DateUtil; import org.traccar.model.Device; import org.traccar.model.Event; import org.traccar.model.Geofence; @@ -68,13 +70,15 @@ public final class Events { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Collection types, Date from, Date to) throws SQLException, IOException { + Collection types, String fromString, String toString) throws SQLException, IOException { ArrayList devicesEvents = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); + DateTime from = DateUtil.parseDateTime(fromString); + DateTime to = DateUtil.parseDateTime(toString); HashMap geofenceNames = new HashMap<>(); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection events = Context.getDataManager().getEvents(deviceId, from, to); + Collection events = Context.getDataManager().getEvents(deviceId, from.toDate(), to.toDate()); boolean all = types.isEmpty() || types.contains(Event.ALL_EVENTS); for (Iterator iterator = events.iterator(); iterator.hasNext();) { Event event = iterator.next(); @@ -118,6 +122,7 @@ public final class Events { jxlsContext.putVar("to", to); jxlsContext.putVar("distanceUnit", ReportUtils.getDistanceUnit(userId)); jxlsContext.putVar("speedUnit", ReportUtils.getSpeedUnit(userId)); + jxlsContext.putVar("timezone", from.getZone()); jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream); List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); diff --git a/src/org/traccar/reports/Route.java b/src/org/traccar/reports/Route.java index b29e04b2e..f438c8f4d 100644 --- a/src/org/traccar/reports/Route.java +++ b/src/org/traccar/reports/Route.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import org.joda.time.DateTime; import org.jxls.area.Area; import org.jxls.builder.xls.XlsCommentAreaBuilder; import org.jxls.common.CellRef; @@ -34,6 +35,7 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.helper.DateUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -56,12 +58,15 @@ public final class Route { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { + String fromString, String toString) throws SQLException, IOException { ArrayList devicesRoutes = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); + DateTime from = DateUtil.parseDateTime(fromString); + DateTime to = DateUtil.parseDateTime(toString); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection positions = Context.getDataManager().getPositions(deviceId, from, to); + Collection positions = Context.getDataManager() + .getPositions(deviceId, from.toDate(), to.toDate()); DeviceReport deviceRoutes = new DeviceReport(); Device device = Context.getIdentityManager().getDeviceById(deviceId); deviceRoutes.setDeviceName(device.getName()); @@ -85,6 +90,7 @@ public final class Route { jxlsContext.putVar("to", to); jxlsContext.putVar("distanceUnit", ReportUtils.getDistanceUnit(userId)); jxlsContext.putVar("speedUnit", ReportUtils.getSpeedUnit(userId)); + jxlsContext.putVar("timezone", from.getZone()); jxlsContext.putVar("bracketsRegex", "[\\{\\}\"]"); Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream); List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); diff --git a/src/org/traccar/reports/Summary.java b/src/org/traccar/reports/Summary.java index 95a3737a1..d7d8ab417 100644 --- a/src/org/traccar/reports/Summary.java +++ b/src/org/traccar/reports/Summary.java @@ -25,9 +25,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Date; +import org.joda.time.DateTime; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.JxlsHelper; import org.traccar.Context; +import org.traccar.helper.DateUtil; import org.traccar.model.Position; import org.traccar.reports.model.SummaryReport; @@ -82,8 +84,10 @@ public final class Summary { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { - Collection summaries = getObjects(userId, deviceIds, groupIds, from, to); + String fromString, String toString) throws SQLException, IOException { + DateTime from = DateUtil.parseDateTime(fromString); + DateTime to = DateUtil.parseDateTime(toString); + Collection summaries = getObjects(userId, deviceIds, groupIds, from.toDate(), to.toDate()); String templatePath = Context.getConfig().getString("report.templatesPath", "templates/export/"); try (InputStream inputStream = new FileInputStream(templatePath + "/summary.xlsx")) { @@ -93,6 +97,7 @@ public final class Summary { jxlsContext.putVar("to", to); jxlsContext.putVar("distanceUnit", ReportUtils.getDistanceUnit(userId)); jxlsContext.putVar("speedUnit", ReportUtils.getSpeedUnit(userId)); + jxlsContext.putVar("timezone", from.getZone()); JxlsHelper.getInstance().setUseFastFormulaProcessor(false) .processTemplate(inputStream, outputStream, jxlsContext); } diff --git a/src/org/traccar/reports/Trips.java b/src/org/traccar/reports/Trips.java index 91a080d45..c31eaac83 100644 --- a/src/org/traccar/reports/Trips.java +++ b/src/org/traccar/reports/Trips.java @@ -26,6 +26,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; +import org.joda.time.DateTime; import org.jxls.area.Area; import org.jxls.builder.xls.XlsCommentAreaBuilder; import org.jxls.common.CellRef; @@ -34,6 +35,7 @@ import org.jxls.transform.Transformer; import org.jxls.transform.poi.PoiTransformer; import org.jxls.util.TransformerFactory; import org.traccar.Context; +import org.traccar.helper.DateUtil; import org.traccar.model.Device; import org.traccar.model.Group; import org.traccar.model.Position; @@ -175,12 +177,14 @@ public final class Trips { public static void getExcel(OutputStream outputStream, long userId, Collection deviceIds, Collection groupIds, - Date from, Date to) throws SQLException, IOException { + String fromString, String toString) throws SQLException, IOException { ArrayList devicesTrips = new ArrayList<>(); ArrayList sheetNames = new ArrayList<>(); + DateTime from = DateUtil.parseDateTime(fromString); + DateTime to = DateUtil.parseDateTime(toString); for (long deviceId: ReportUtils.getDeviceList(deviceIds, groupIds)) { Context.getPermissionsManager().checkDevice(userId, deviceId); - Collection trips = detectTrips(deviceId, from, to); + Collection trips = detectTrips(deviceId, from.toDate(), to.toDate()); DeviceReport deviceTrips = new DeviceReport(); Device device = Context.getIdentityManager().getDeviceById(deviceId); deviceTrips.setDeviceName(device.getName()); @@ -204,6 +208,7 @@ public final class Trips { jxlsContext.putVar("to", to); jxlsContext.putVar("distanceUnit", ReportUtils.getDistanceUnit(userId)); jxlsContext.putVar("speedUnit", ReportUtils.getSpeedUnit(userId)); + jxlsContext.putVar("timezone", from.getZone()); Transformer transformer = TransformerFactory.createTransformer(inputStream, outputStream); List xlsAreas = new XlsCommentAreaBuilder(transformer).build(); for (Area xlsArea : xlsAreas) { diff --git a/templates/export/events.xlsx b/templates/export/events.xlsx index f0ff05a23ff9c9907b6508ad93e0d8db11620a70..80a54fa57e81916ef5b80184249fae4a93496e46 100644 GIT binary patch delta 2680 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 delta 2657 zcmV-n3ZC`4V3T05XA22AVfAxyTx)=nQpMq3fT z9~5!(LBxmH-gUtysmblw82)!}Rvp^Tmy_h4b8Hr||)-G}#U(=RrM*UiaXzgU>^c zYJ(Z``Q_c1l~cc2R)9&rCmAl zMd^jUo)N(%ZXF6UCnCJ?#K~7emMWGM?cT+y+O# z?)yQ*XVYL`h1bv)Z#(sk@BX7~y;0yegS6=E%$nCFl>{1p1|0iwrdbK^fC7HKp6Skq zwBi@@+_6S&Y7_&q%%Utm;w=*786-Rp$jUFXEX~W}z-*Dp9tqDqGAaBt&WbXcaHe}C zJom^f^RpsMra*|u$_# zcw{RT?~hr3dn;*>EzR>u6KOh~L~XdY22(3zSXx73iU;105_Dx93D;|LaHGLSH55%k zw>&SxdGHJ^K=ugJC^dpuj)>?Sac?<{5Ub2F1gpKV22!l98?d6>sl6-OXp#TD%CZ!B)$LPlW^5B)5P$|wrsB#+|| z+=0KAbM@9DZ2nsHBURhc8}UfRBl``v5eU6IWkRa2u=r)$ugv$zp{ax&2HAhNE*Or@n2Iwn=-e9B_hL!y)4&w4Z)w3{A3i)3k0+ z8zR9upU-#aAAcojOGWTgHEf^Kovv7u6{6(LxRjZO1~z7#LCN-|qOV`|p71kI*lc7b zn0p-8w7;-Mw3$$Jh5IDHnu6Ct@dwx$vVUiyH7OOjG~KkFmwCzSvl)_e!&4g2X%}L8 z7Gss{T}bm#3nKHB-nKqow)fDzHUJ6jCfOWy_MBi ziH%{iXgP`JwHb^CY8Fkb;UIHUupnMcLi^K3EQH(^hJ|70@Hm!LE?O3h>~Ywl`>r&G zYrHiaQo2@<-5=Y6mE>?BP<6e?K!1U@J{)}rteb471)f~r5gXDV7;9*|9Y~VP{ZN*j z7;`1J6|;qmR>>4+T_)4>bxF&vl|6^I$Pf9jzQdk>?z;aTOn;^Xo!-G-e37QO7D_c8 zV^~$oJ|Q*Fn6Ij=0PPYZp+|xs@`&$|g-2!{S;lC=J5Hu8J9Wi?S33hYQh%w{4Oflm z90rSRq}}r)99F)av4g>QjmKA3&fbr^#-rP@KKE+$D4k=}17fL(pQYx<$k=_(unBuC zdZWc=HhZEbn#Ua?JuuPY44CjgFcz34@`8`KM{p1!GdOwyF2P^KW&T237XEi46QJ-M zWhPpL2+x2^>?CIpnAynUw>QBzrWcHh4PF`Qp%a|JI*S%_9(}9P|DYP73N2B5mdFHK_!sCn_OP1mb4wZE8py%XXXg_iU0jO+_!~(=0JNy2(s@eWR*UeS1kQ6Uc~NOd$pIXhXSX*qVG>bUc(IiM>lL^Fm9$HQNy)~0 zlThl!21@QCWM~A}m47X{$I|B1aPh-)prbgR(h@wE+;iFphNf2}M@cDqNwc*@D=% zeE|Rf1d~ZEQvnE*oh?uTM-G#54i%H;FA$RyE*b$elP@kH9LQ^?n!N)60Llsg02lxO z00000000000000p8`7SFP?5M1OYykiO*8%_l5dZ)H0000000000004B8KQBH37n6Q3Q~{Qg(=R;% PG?Ni9BL)gA00000+&j{3 diff --git a/templates/export/route.xlsx b/templates/export/route.xlsx index 24027523d91530a2c264778d17bca85630be679f..79a2649b71c59f144b9ed58ede560ac4878dcfcc 100644 GIT binary patch delta 4873 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 delta 4611 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 diff --git a/templates/export/summary.xlsx b/templates/export/summary.xlsx index 88788f82ac15c7ba225bc77f0f298f5eb98f608e..53539ed8b90c0a4fdf93f08e7a48f70830ae0616 100644 GIT binary patch delta 2032 zcmVd>= z)RzHTw+9|ga@&~Jc4j-%D#X9zv=wwos_kKU%enU)-*bKBWcn!A@PNh&ttKR-0RdE* z&V^b|$ldLivoQhdxXSrjE1ZxGS~5-FzDcZg;JM09Na0)=GiI{_CAUfCGIQyyaytZCRU`0OK-5$#(~?E7$?l7 z39Ip4ZC**q&87)|Mb}GWkzup>+s|K^xh8rkYS-=VTU~-J5%VVDlV2iVVt4UM zErmju>B`t9@!fB`b3ya%d|$c5KkcS`e?QQj5{}}1#n-k+q#%8m0wHv_?H+kg!v%Qw z1N>9n6X65`8u--@!t+tshZs5~)e+4aKQ0=bUtC0^TC_RKN*pdtuP8k<4$j?gYv4L_%2ni=BuUmLNafM zv`&Bf1mia6+nBTQ@S{&#;4{~8$qS<;b$afMe`tE-hyUpHHO+IF&0;BIYf1l09KQ&8zO&?+cprr7wCTwbdU9ENfvAe zS=&PQ&>-lxz0(q96Dx@-Nw0VF>oX+vNjr#pvE;|6na9WBkn7Lyb!EL_#tCgUwzqI? z3pY6}NORiQ|NNbON^FY@)D)gO1NZBJXXjzgR?`eLiaU*mPhASjM zKR=U}_tD;qhvF3sU16@ho{7Z09vR|!;f=nUDOtePq z_0oQVz%5MfNGc*e)O2mD&eP{pLm4_&up;kXi1L4lN^~3kah(upyDkWLD+|J6xZK!Z zyflk#XS-G__bc{K(_Ur()uMw75*xhz5>jJqLSrur1VvO{tQGH z@^JN;%!6`4-tZ1rK!5U~;{H>a;T6(4L*D6ouOU+f_KjHuF43hDf6?n7n4Hc65--6P z=}v!IeC#pLp_Q)3D2H6&k6HTIpH}F7RhoMMv0*=>X`5xr*SuF+)vmA zH9a|*&cx9cDfjnCpzWH`s|C9Xyy7jAd)|LbA<=z{!CT4wBFXX-X}JWRG@w>i0Xq!@ z17mLj2NTF9fCHiiWwLZ0Rwl`6GEfy9%JFUMuAMiivAmb68L%t^!<#d9nlaIC0tXYw zCcsQP)XC%8C3)tm1}3g*V4}gXg&0> zU+pg$1^kA!8|(}W!|zZ`!!>0!39_6A+21mvIpc84i06##mXQpMnKjUyOlv&2i2P4$ zWE8Mwx_?)OHNU3pItsL$v0jZvvG0F4uzDlMXcdQh9Aj(1F{>0qix}gKtEny0$DwY> zHD)JuY;r577kRw-(8va~JHMm!No^DpkJBer>dqKuyKd15|B2X%G~B9isZPw;O`^yP zy*TjwBnV^B$Mg{kN8jz3pshS-<1ldpFI+`#!wF;IE|#8` zc%JJAk?*^Z4)T?hik}U_(IQp9U~y@!7PXkYkneCaf^sei`2c%0IfB;W(xml{4Ikw?C602^EutE)bKW zE*rD#AJ7B^y>>F9akIfBBmsYnQp--mFc7>W@eh&jspAwXh>}zS)DxAEC<1Xa_O>-7 zj%B;Azh@J-X)Ai*=G_^OW_C9pZ|f>rgLSIW1!04PM4&|@m0lF&Z8nMTNaQ@%l2?s} zg6zPNad~}}3zLb)!i#MTSg*iEsH9ycOhK03n~YK?mQZsyK!!$e-q?Sddo1mO8ZLhL z0%)2fBU*#!l6y{D!PxYQWG^X2FKJe`>I9^qP(cmaJIV%(9=RTD?Jj=kkP~LD{LWye zz1>r7DFWEDw@&rM&1N&$3_Ba>pV5!$^J^D1R=S;)08-{sWM26S%A6jb_;RbSZxBAT z`vL)Bf&0b=pf3=R;Dl{e#^Z(pc-Fu@RNVO~u57MAKJ1Wlp@%ICYt^o~WF4a~(P}rD z-~eQVS+g*i1M)t6e40&2nI>!$GZwRSmW;BS+bq5NZ1bJ{Z?lI+y*Kp_#dO#zruW(K zRPi9tjkDrr0ezDnE+88w9BpCd0{{S43jhEZ0000000000000000E3fSE=2*Klb|k0 z0aBCcE-M?ob~2)I0RRBk0ssIJ0000000000000000Gg98FFpZ6lWs3m0l|~QFFgS| OlL0Uz1`;d)0000K8pb#P delta 2043 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