How to get yesterday for history function
I am trying to build a report macro that will grab medications for yesterday onwards.
If I use the following datasource expression
$P{dataSource}.getExpressionDataSource("history:medication(openvpms:get(., 'patient.entity'), java.sql.Date.valueOf('2010-01-01'),null)")
then the macro happily expands and dumps all medications since 1Jan2010.
However, if I change this to
$P{dataSource}.getExpressionDataSource("history:medication(openvpms:get(., 'patient.entity'),java.sql.Date($P{yesterday}.getTime()),null)")
where $P{yesterday} is a non-prompted for parameter of type java.util.Date with the expression
new Date($P{today}.getTime()-86400000)
and $P{today} is a non-prompted for parameter of type java.util.Date with the expression
new Date()
then the macro will not expand. [The reason for creating the parameter today, and then calculating yesterday from it is that I convinced myself by doing some testing that doing it this way stripped the time component out of the date - ie the $P{today}.getTime() generates the millisec time for 00:00:00 on today's date.]
How do I give the history:medication as parameter that evaluates to yeterday's date that it is happy with?
Regards, Tim G
Re: How to get yesterday for history function
I think:
java.sql.Date($P{yesterday}.getTime())
needs to be:
java.sql.Date.new($P{yesterday}.getTime())
Re: How to get yesterday for history function
Tim A - that didn't help. After much experimentation and testing I have a somewhat crude solution. I think that the underlying problem is that since what is being passed in the datasource expression is a quoted string, you cannot have parameters in it. ie if the expression is like
$P{dataSource}.getExpressionDataSource("history:medication(openvpms:get(., 'patient.entity'),new java.sql.Date($P{yesterday}.getTime()),null)")
the $P{yesterday} in the "history:m.... ...null)" string is not expanded.
So I changed the data source expression to
$P{dataSource}.getExpressionDataSource($P{parameter1})
and defined parameter1 as:
"history:medication(openvpms:get(., 'patient.entity'),java.sql.Date.valueOf('"+$P{yesterdayS}+"'),null)"
with yesterdayS as:
new java.sql.Date((new java.util.Date().getTime())-86400000).toString()
So yesterdayS evaluates to "2014-04-06" (today being 7April 2014), and parameter1 evaluates to
history:medication(openvpms:get(., 'patient.entity'),java.sql.Date.valueOf('2014-04-06'),null)
then everything works.
I suspect that it is possible to do things more cleanly than this, but I now have a recipe that works.
Regards, Tim G
Re: How to get yesterday for history function
Within xpath expressions, new objects are created using:
<fully qualified class name>.new(arguments)
The $P{ } is massaged by JasperReports, so it needs to be outside the xpath expression. Something like:
$P{dataSource}.getExpressionDataSource("history:medication(openvpms:get(., 'patient.entity'),java.sql.Date.new(" + $P{yesterday}.getTime() + "), null)")
Re: How to get yesterday for history function
Hi,
I think I understand that this expression only works in a jasper report??
Is there a way to get 'medications dispensed' into a patient letter (not a jasper report)?
We would like to insert, via expression, into a patient letter (ie transfer notes) the medications dispensed for a patient in within the last visit (or within a short date period if that's not possible).
Thanks,
Greta
Re: How to get yesterday for history function
This can be done in OpenVPMS 1.7 using Report Macros, although you will need a Jasper Report to list the medications dispensed.
The steps are as follows:
1. Create a Jasper Report and sub-report that list the medications for the most recent visit for a patient. I've attached a Patient Discharge Summary and Patient Discharge Summary Items as an example.
2. Go to Administration|Templates and load the two reports from 1.
3. Go to Aministration|Lookups and create a new Report Macro, to run the report
4. In your Patient Letter, include a field that runs the report macro. e.g.:
See the Test Letter.odt attached below.
In the above:
Re: How to get yesterday for history function
That's great. Works perfectly.
The next thing I can't figure out though is how to edit the jasper report. When I try to change the wording
'While in hospital' to 'Medications dispensed' (or even just delete the p in hospital), then re-upload the jrxml document to the Patient Discharge Summary Template (report) it gives me this:
Failed to read Patient Discharge Summary.jrxml. Please ensure it is saved to be compatible with JasperReports 3.7.6
Re: How to get yesterday for history function
OpenVPMS uses JasperReports 3.7.6, so you need to save your .jrxml files in a format compatible with this version. To do this in iReport, click on Tools -> Options and set the Compability to JasperReports3.7.5 as shown below:
Re: How to get yesterday for history function
Hi again,
I'm slowly progressing with having the medications dispensed printed in the patient documents, but I can't seem to get the expression for label to work. Does anyone have an idea what I'm doing wrong.
Thanks,
Greta
Re: How to get yesterday for history function
Greta - can you provide more information on what is going wrong.
Below is Max's medical record: (note that this is from my anonymised database so the medication names are scrambled)
The following is what came out:
So it retrieved the medication name and quantity, but got confused with the label.
Is this the problem that you are seeing?
If so - the problem lies in your sub-report field name - iReports shows:
Notice that you have used "label" - which looks different from all the other field names which all have the form "target.xxxxx"
So the problem is that the system cannot figure out what you mean by "label".
If you look at http://www.openvpms.org/documentation/csh/1.7/reference/reportsForms you will see that in a sub-report all the fields have names of the form target.xxxx where the xxxx bit depends on the data source.
In this case we are dealing with visit items ['items' because the subreport expression in the report is
$P{dataSource}.getDataSource("items", new String[]{"target.patient.entity.name", "target.startTime"})
ie pull all the items from the visit act.patientClinicalEvent, and if we look at thgis archetype we find that the items have archetype actRelationship.patientClinicalEventItem and if we look at this we find it contains all the things that can go into the medical record including act.patientMedication - and if we look at this we find:
so the label is there.
Hence we need to adjust the field name in the sub-report from "label" to "target.label"
Doing this we now get:
which is correct - but probaly should be reformatted to put the label in its own field.
Note that Max's visit shows other stuff like the invoice items and investigations. You could extract these, but in order to do so you need to be a little clever. The trick is to realise that the field target.displayName contains the name of the medical record item, (eg Medication, Weight, etc) and target.shortName contains the archetype name (act.patientMedication, act.patientWeight, etc) so you can extract the data for each of these.
Note that the Print When expression for the Detail1 band is set as follows:
ie the sub-report as written is only showing the Medication items.
If you want other stuff shown, then the easiest way is to add other details bands, one per type, and set each one to print only for its type. For each type, look at its archetype and get the field names, and use those.
Hope this helps.
Regards, Tim G
Re: How to get yesterday for history function
That helps so much Tim, thank you.
Could you possibly tell me how to make it so all the text in a large label would fit. It seems to be cutting off the text in the label if it is long.
I've attached the new document.
Greta
Re: How to get yesterday for history function
Greta - the following is my version
I have attached the items jrxml. You will see that rather than simply printing $target.label, I have used the expression $F{target.label}.replace("\n"," ") - ie I have replaced the new lines with spaces so as to coerce the label text into one line. The wrap that you see above is due to Open Office wrapping the text, and the only way to stop this is to increase the text that OO will fit on the line by either decreasing the font size, or decreasing the margins. The above may be enough for you because you don't need the dual language text.
Regards, Tim G
Re: How to get yesterday for history function
Actually, I think I just figured that out. It was in the archetype.
Thanks so much for your help.
Greta
Re: How to get yesterday for history function
Hi Tim and others,
I have one more question because I have tried font extensions and I keep stuffing it up. I would like the text in the label to be in italics. The document it is being inserted to has text in Verdana size 10.
Is there an easy way to do this within OpenOffice or do I need to keep trying with font extensions?
Thanks,
Greta
Re: How to get yesterday for history function
Greta - the font in iReports has no functional effect on the font in the Open Office document. The macro:eval call in the .odt document calls the maco which runs the jrxml file - and this just delivers text back to OO writer which uses the font specified for the field in .odt document. In your Test.odt - this is Arial 14 - as shown below.
You can change this to whatever you want. HOWEVER - if the jrxml report is delivering multi-column data there may be a problem. Let us say it returns:
dd/mm/yyyy col2 text col3 text
The date column is OK because all numbers are the same width, but the coln text will vary in width UNLESS you use a monospaced font such as courier or lucinda sans typewriter.
So if you use a proportional font (eg verdana) then col2 will be aligned as you want (because col1 is the date and thus always the same wdith) BUT col3 will not be aligned because where it starts depends on the characters in col2.
Hence the best approach is to do as much as possible in OpenOffice, and just use the macro report facility to return the information that you cannot get in OO. Below is Scattermoose's (the family test dog) vaccination certificate - as you can see all the information retrieval is done in OO except for the actual vaccation history - and this uses a 2 column display with the first being a date - so I can use a proportional font (its Times Roman) for the history text
and here is the OO document
I hope this clarifies things.
Regards, Tim G
Re: How to get yesterday for history function
Hi Tim G,
We have been using this report with hardly any issues, but I have been asked to try again to fix it so it doesn't cut off the text when the text is long in the label. I cannot figure it out, so I wonder if you could have another look and see if you can see what I need to change in the Jasper report.
In the screenshot below, the problem is shown for the drug Frusemide, where the label cuts off after May need
My document is attached.
Thanks so much,
Greta
Re: How to get yesterday for history function
Woops, this is the screenshot:
Re: How to get yesterday for history function
Greta - I also need the OO template that you are using and the text of the report macro.
Can you also tell me what version of OpenVPMS you are running - are you on 1.8 yet? [If not I need to do my testing on a 1.7 system.]
Regards, Tim G
Re: How to get yesterday for history function
Hi Tim,
Thank you so much. We are using 1.7.1.
The document is attached and the text of the macro is: party:getPatientVisit(openvpms:get(.,'patient.entity'))
Re: How to get yesterday for history function
Interesting.
Shows as:
but
shows as:
However, there is also a lenght limitation. If I set the label as:
(where the label text is just under the 300 character limit)
then it shows as:
Finally - if I just have a long line of text with no terminating new line, ie
then it shows as:
So there are two problems:
1) the code that transfers the text generated by the report macro is sensitive to the presence of new line characters. If the text does not have a new line at the end then it is not transferred in full.
2) the same code will not handle the full 300 characters that can be present in a label (I would not be surprised if the limit is 255 or 256)
So:
a) we appear to have a real bug - Tim A do you want me to Jira this? [Note I tested both in 1.7 and 1.8 - same problem.]
b) there is a work-around for the truncation problem that you are seeing - just hit Enter at the end of the text to add a terminating new-line.
By the way, the problem is not the jrxml subreport - I played with increasing the label text space in this and it had no effect.
Regards, Tim G
PS - I assume that the reason that you prompt for clinical notes rather than using the Notes text in the medical records is that you want to separate the 'external' clinical notes from the 'internal' medical records Notes text.
Re: How to get yesterday for history function
This is a feature of the JasperReports report -> text conversion.
Internally, JasperReports sizes elements on the page in terms of fractions of pixels.
When converting to text, it divides the page up into a grid, based on the character size (10 pixels in your case). It then maps elements into the grid. Those that don't fit are omitted.
Multi-line fields screw up the mapping e.g. a 9 line medication label is stored internally as having a height of 82.256836 pixels, for Monospaced font size 7. For a character size of 10, JasperReports decides that this takes up 8 lines, so the last line is truncated.
So the workaround is as Tim G says - add new lines until it exports correctly.
Regards,
-Tim A
Re: How to get yesterday for history function
Tim, that is awesome. Thanks for figuring it out. Until the bug is fixed, I have just asked everyone to press ENTER at the end of their labels before pressing OK.
I don't know about clinical notes vs medical records, didn't do whatever I did on purpose ;)
Thank you again so much,
Greta
Re: How to get yesterday for history function
I have been playing some more.
a) I can fix the 'user needs ensure that they press Enter at the end' problem - by adjusting the code to do this in the jrxml - ie print $F{target.label}+"\n\n" rather than just $F{target.label} [I found that I needed two new lines to reliably print all the label text.]
b) I experimented with medication with no label text - which should result in $F{target.label} being null - as all a result one normally copes with this by using the expression: ($F{target.label}==null)?"":($F{target.label}+"\n\n")
However, this fails with Expression Error when the label has no text. Checking the full log I find:
So there appears to be a problem if the medication has label text.
c) I also played with ammending the report to include any notes in the medical record. This does not work fully because of the 'things don't work if the text is too long' problem. That is with the visit as follows:
the referral letter comes out as: (as you can see the bottom half of the note is missing)
Tim A - any comments appreciated. I have attached the jrxml FYI, the odt letter is unaltered. [The above testing has been done with 1.7.1 and iReports 3.7.6]
Regards, Tim G
Re: How to get yesterday for history function
If I run this in 1.8, the problem can be traced to JasperReports:
This is being caused by the number of lines (39) in the output exceeding the calculated page height in characters (38). This is for an element height of 387 pixels, so JasperReports is rounding down when it should be rounding up.
I can't think of an easy workaround for this, as there doesn't appear to be a way to calculate how much vertical space a multi-line label will occupy. Ideally, it would be possible to select a font size + line spacing which corresponds exactly to the character size.
Using a font size of 8 with no line spacing seems to work best, but may not work for all input data, and may vary across hosts.
Re: How to get yesterday for history function
Hello,
Sorry to continue with this, but the issue with this is back for us. I am not sure how long the issue has been back for, but it has just been brought to my attention today.
Was it something that was fixed in 1.8, but now we're on 1.9 it's gone back?
Also, is it possible to make it so the [macro:eval('@dischargesummary',openvpms:get(.,'patient.entity'))] is editable within the OpenOffice document? Currently we can't edit the medications that are in our discharge letters and if you try it just deletes the whole lot (the whole merged dischargesummary). Which makes it a bit difficult if the label instructions are cut off.
Also, is it possible to have [macro:eval('@dischargesummary',openvpms:get(.,'patient.entity'))] in OpenOffice only print items that have a label? For example, a dog might get Cephazolin injectable (medication) when it's in hospital as part of it's surgery, but the owner doesn't need to see this on the discharge letter. The owner really only needs to see items that have been dispensed and sent home with (all these items will have a label). I thought there was something in Jasper Reports that stipulated that only printed items that had label, but maybe I'm making that up.
Greta
Re: How to get yesterday for history function
Your report macro may be incorrect, but I will contact you off list about it.
Regarding your other points:
1. Select the field and choose Edit - Cut.
2. Choose Edit - Paste Special.
3. Click "Unformatted text" in the Selection list, and then click OK
Change this to:
Re: How to get yesterday for history function
Hi Tim,
Perfect! All of that has fixed it. Thanks so much.
Greta