Problems in retrieving upcoming appointments within future 30 days in backend - flutter

I had a workable API backend design which can retrieve a user's all appointments, which are shown below. Now, instead of retrieve all, I'm planning to retrieve a user's appointments within future 30 days (from current time) from database, but I have no idea how to set limit to achieve this. Can anyone please help me with this?
Database.java
public List<Appointment> listUserAppointments(
String uid,
#Nullable String since,
#Nullable String until,
#Nullable AppointmentStatus status){
try {
AppointmentMapper mapper = session.getMapper(AppointmentMapper.class);
return mapper.getAppointmentsByUserId(uid, since, until, status);
} finally {
if (!keepAlive) close();
}
}
public Appointment getAppointment(String appointment_id) {
try {
AppointmentMapper mapper = session.getMapper(AppointmentMapper.class);
return mapper.getAppointmentById(appointment_id);
} finally {
if (!keepAlive) close();
}
}
AppointmentMapper.java
public interface AppointmentMapper {
/*
You can pass multiple parameters to a mapper method.
If you do, they will be named by the literal "param" followed
by their position in the parameter list by default,
for example: #{param1}, #{param2} etc.
If you wish to change the name of the parameters (multiple only),
then you can use the #Param("paramName") annotation on the parameter.
*/
Appointment getAppointmentById(String id);
List<Appointment> getAppointmentsByUserId(
#Param("uid") String uid,
#Param("since") String since,
#Param("until") String until,
#Param("status") AppointmentStatus status);
void updateUserNoteById(Appointment appointment);
void updateStatusById(Appointment appointment);
void insertAppointment(Appointment appointment);
void updateAppointment(Appointment appointment);
}
AppointmentAPI.java
#GET
#Path("me/appointments")
#Secured(UserRole.PATIENT)
#JSONP(queryParam = "callback")
#Produces(MediaType.APPLICATION_JSON)
public Response listMyAppointments(
#Context SecurityContext sc,
#QueryParam("since") String since,
#QueryParam("until") String until,
#QueryParam("is_confirmed") Boolean is_confirmed) {
String uid = sc.getUserPrincipal().getName();
List<Appointment> results = retrieveUserAppointments(uid, since, until, is_confirmed);
return Response.ok(results).build();
}
AppointmentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sec.lib.AppointmentMapper">
<select id="getAppointmentById" parameterType="String" resultType="com.sec.entity.Appointment">
SELECT * FROM Appointment WHERE id= #{id}
</select>
<select id="getAppointmentsByUserId" resultType="com.sec.entity.Appointment">
SELECT *
FROM Appointment
WHERE uid= #{uid}
<choose>
<when test="since != null and until != null">
AND date BETWEEN #{since} AND #{until}
</when>
<when test="since != null and until == null">
AND date > #{since}
</when>
<when test="since == null and until != null">
<![CDATA[
AND date < #{until}
]]>
</when>
</choose>
<choose>
<when test="status == null">
AND status != 'CANCELLED'
</when>
<otherwise>
AND status = #{status}
</otherwise>
</choose>
</select>
<update id="updateUserNoteById" parameterType="com.sec.entity.Appointment">
UPDATE Appointment SET
user_note= #{user_note}
WHERE id= #{id}
</update>
<update id="updateStatusById" parameterType="com.sec.entity.Appointment">
UPDATE Appointment SET
status= #{status}
WHERE id= #{id}
</update>
<insert id="insertAppointment" parameterType="com.sec.entity.Appointment">
INSERT INTO Appointment (id, uid, did, title, detail, date_create, date_change, date, duration, note, status)
VALUES (#{id}, #{uid}, #{did}, #{title}, #{detail}, #{date_create}, #{date_change}, #{date}, #{duration}, #{note}, #{status});
</insert>
<update id="updateAppointment" parameterType="com.sec.entity.Appointment">
UPDATE Appointment SET
did= #{did},
title= #{title},
detail= #{detail},
date_create= #{date_create},
date_change= #{date_change},
date= #{date},
duration= #{duration},
note= #{note},
status= #{status}
WHERE id= #{id}
</update>
</mapper>

Related

Right way to use same page for new / edit bean with f:viewParam?

I've been using JSF for a couple of months.
My bean Person has a lot of fields (about 50) and some sub-beans (4 Addresses, 2 Contacts..): the related form is big and managed with some ajax actions. I would use that form for "new" Person and also for "edit" Person.
Following Creating master-detail pages for entities, how to link them and which bean scope to choose now I have a form for person.xhtml, a search page search_p.xhtml where I choose Person and go to edit_person.xhtml.
search_p.xhtml has a list of Person, each person has this link
<h:link value="Open" outcome="person">
<f:param name="id_p" value="#{person.id}"/>
</h:link>
person.xhtml contains
<f:metadata>
<f:viewParam name="id_p" value="#{editPerson.person}"
converter="#{personConverter}"
converterMessage="Person unknown, please use a link from within the system."
required="true" requiredMessage="Bad request, please use a link from within the system." />
</f:metadata>
PersonConverter has
#ManagedBean
#RequestScoped
public class PersonConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.isEmpty()) return null;
try {
if(value.equals("new")) return new Person(); //used for link to new
else {
Integer id = Integer.valueOf(value);
return PersonDAO.getById(id.intValue());
}
} catch (NumberFormatException e) { throw new ConverterException("Not valid Person ID: " + value, e); }
}
#Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) return "";
if (value instanceof Ordine) {
Integer id = ((Ordine) value).getId();
return (id != null) ? String.valueOf(id.intValue()) : null;
} else {
throw new ConverterException("Not valid Person ID: " + value);}
}
}
side_menu.xhtml is part of template, here it calls "New Person"
<li><h:link value="New" outcome="person">
<f:param name="id_p" value="new" />
</h:link></li>
EditPerson bean is
#ManagedBean
#ViewScoped
public class EditPerson implements Serializable {
private static final long serialVersionUID = 1768587713177545840L;
private Person person;
public Person getPerson() {return person;}
public void setPerson(Person person) {this.person = person;}
public String save() {
PersonDAO.addOrUpdate(person);
return "/search_p?faces-redirect=true";
}
So, when in person.xhtml I click on
Contact 2
<h:selectBooleanCheckbox value="#{editPerson.person.enable_c2}" id="flag_c2">
<f:ajax event="click" execute="flag_c2" render="div_c2"></f:ajax>
</h:selectBooleanCheckbox>
a popup appears:
serverError: class javax.faces.component.UpdateModelException /include/person/tab_anag.xhtml #372,26 value="#{editPerson.person.enable_f2}": Target Unreachable, 'person' returned null. PersonConverter has been fired, i suppose because of f:metadata is in the page code: can i avoid to call PersonConverter when ajax is fired? I need f:metadata only for passing id from search_p page.

Why my mybatis query result is null?

I am completely new here.Could anyone please give me some help?My Syntax is as following.
PO:
package com.cabr.po;
public class InputVAT {
private String dept;
private String period;
private String tax;
private String type;
}
toString and get,set methods are ommited here.
Aliases in configuration:
<typeAliases>
<package name="com.cabr.po" />
</typeAliases>
DaoImplement:
#Override
public InputVAT findInputVATByPeriod(String period) {
SqlSession sqlSession = sqlSessionFactory.openSession();
InputVAT inputVAT = sqlSession.selectOne("com.cabr.findInputVATByPeriod", period);
return inputVAT;
}
mapper:
<mapper namespace="com.cabr">
<select id="findInputVATByPeriod" parameterType="string"
resultType="InputVAT">
SELECT * FROM input_vat WHERE period = #{period}
</select>
test:
#Test
public void testFindInputVATByPeriod() {
InputVATDao dao = new InputVATDaoImpl(sqlSessionFactory);
InputVAT inputVAT = dao.findInputVATByPeriod("201607");
System.out.println(inputVAT);
}
database:
CREATE TABLE `input_vat` (
`id` varchar(32) NOT NULL,
`dept` varchar(10) NOT NULL,
`period` varchar(6) NOT NULL,
`tax` varchar(10) NOT NULL,
`type` varchar(128) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
When I try to run this test,the console shows:
2016-08-22 15:54:08,282 [main] [com.cabr.findInputVATByPeriod]-[DEBUG] ==>
Preparing: SELECT * FROM input_vat WHERE period = ?
2016-08-22 15:54:08,360 [main] [com.cabr.findInputVATByPeriod]-[DEBUG] ==>
Parameters: 201607(String)
2016-08-22 15:54:08,462 [main] [com.cabr.findInputVATByPeriod]-[DEBUG] <==
Total: 0
null
I wish I have descripted my problem clearly.I wonder why the result is null while there is actually data in the database.
Well...I found some answers noticing that this may work:
<select id="findInputVATByPeriod" parameterType="string"
resultMap="MyresultMap">
SELECT * FROM input_vat WHERE period = #{period}
</select>
<ResultMap id="MyresultMap" type="InputVAT">
<id column="id" property="id">
</ResultMap>
In fact I didn't save the data in my database correctly.What a shame!

can't change grid's ui when reload data in grid into zkoss

i have a datebox
<datebox id="infrom" style ="z-index: 100000;" format="yyyy-MM-dd" value ="#bind(vm.date)"
onChange="#global-command('dataChanged', indate = infrom.value)" />
default value of date is now -1
and have a button search
<button id="searchButton" label="Search" image="/img/search.png" onClick="#command('listCars', indate = infrom.value)"/>
and grid will load data of yesterday
when i choose another day
grid will load data of chose day
and there is my grid
<listbox id="carListbox" height="" emptyMessage="No data found in the result" model="#bind(vm.cars)" >
<listhead>
<listheader label="Date" />
<listheader label="Actionid" />
<listheader label="Num user" />
<listheader label="Total action" />
</listhead>
<template name="model" >
<listitem>
<listcell label="#bind(each.date)"></listcell>
<listcell label ="#bind(each.action)"></listcell>
<listcell label="#bind(each.user)"></listcell>
<listcell label="#bind(each.total)"></listcell>
</listitem>
</template>
</listbox>
and there are my code
private List<Car> cars;
public List<Car> getCars()
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.setTime(new Date()); // Now use today date.
c.add(Calendar.DATE, -1);
String output = sdf.format(c.getTime());
final StringBuilder builder = new StringBuilder("");
for (final Action action : getActions()) {
if (action.getChecked()) {
builder.append(';');
builder.append(action.getActionid());
}
}
String lstAction = builder.toString();
lstAction = lstAction.substring(1);
String[] arrAction = lstAction.split(";");
cars = carService.search(output, arrAction);
return cars;
}
#Command
#NotifyChange("cars")
public void listCars(#BindingParam("indate") Date indate){
SimpleDateFormat dt1 = new SimpleDateFormat("yyyy-MM-dd");
String date = dt1.format(indate);
final StringBuilder builder = new StringBuilder("");
for (final Action action : actions) {
if (action.getChecked()) {
builder.append(';');
builder.append(action.getActionid());
}
}
String lstAction = builder.toString();
lstAction = lstAction.substring(1);
String[] arrAction = lstAction.split(";");
cars = carService.search(date, arrAction);
//return result;
//carListbox.setModel(new ListModelList<Car>(result));
}
but i can't reload grid when i choose another day
please give me any way to slove them
thanks all
Why do you bind param to function with #BindingParam("indate")?
If you bind date value with this:
<datebox style ="z-index: 100000;" format="yyyy-MM-dd" value ="#bind(vm.date)"
onChange="#global-command('dataChanged', indate = infrom.value)" />
so you may not use
String date = dt1.format(indate);
in listCars function, and not use #BindingParam in it.
Instead, you need to declare
private Date date;
in the viewmodel, with his getter and setter.

Prevent form resubmit on refresh in struts2 (with action messages and fields messages preservation)

I got a simple form validation and submission that works great
Here is my struts.xml :
<action name="register" class="registerAction">
<interceptor-ref name="defaultWithoutAuthenticationStack"/>
<result type="tiles" name="input">
<param name="titleKey">global.title.register</param>
<param name="location">register</param>
</result>
<result type="tiles" name="success">register.success</result>
</action>
My jsp form :
<s:form method="post" action="register.action" validate="true">
<s:textfield name="usernameRegister" id="usernameRegister" key="global.username" labelposition="left" />
<s:password name="passwordRegister" id="passwordRegister" key="global.password" labelposition="left" />
<s:password name="passwordConfirmRegister" id="passwordConfirmRegister" key="global.password.confirm" labelposition="left" />
<s:textfield name="emailRegister" id="emailRegister" key="global.email" labelposition="left" />
<s:submit key="global.register" name="submitRegister" method="goRegister"></s:submit>
</s:form>
And my submit function :
public String goRegister(){
user.setUsername(getUsernameRegister());
user.setPassword(getPasswordRegister());
user.setEmail(getEmailRegister());
userService.addUser(user);
ArrayList<String> successMessageUsername = new ArrayList<String>();
successMessageUsername.add(getUsernameRegister());
this.addActionSuccess(getText("global.register.success", successMessageUsername));
return SUCCESS;
}
Nothing fancy !
The problem is I got a windows asking for resubmit form informations when I refresh my page on success page or form page (when validation failed)
How can I prevent that ?
Thx
EDIT : I add the action messages and fields messages preservation to my question
How to preserve the actions messages and fields messages (validation) with a redirection ?
Use the post-redirect-get pattern.
On success, redirect to the "you've registered" page. That way if the user refreshes, they just get that same page again.
Oki after Dave Newton's suggestion I dig up a little to complete the correct way to do so :)
Here is my answer so far, no more refresh, backward or forward resubmission of your form and preserve the ValidationAware messages (errors and messages)
My struts.xml :
<action name="register" class="registerAction">
<interceptor-ref name="defaultWithoutAuthenticationStack"/>
<result type="tiles" name="input">
<param name="titleKey">global.title.register</param>
<param name="location">register</param>
</result>
<result name="success" type="redirectAction">index</result>
</action>
<action name="goRegister" class="registerAction">
<interceptor-ref name="defaultWithoutAuthenticationStack"/>
<result name="input" type="redirectAction">register</result>
<result name="success" type="redirectAction">index</result>
</action>
And my jsp :
<s:form method="post" action="goRegister" validate="true">
<s:textfield name="usernameRegister" id="usernameRegister" key="global.username" labelposition="left" />
<s:password name="passwordRegister" id="passwordRegister" key="global.password" labelposition="left" />
<s:password name="passwordConfirmRegister" id="passwordConfirmRegister" key="global.password.confirm" labelposition="left" />
<s:textfield name="emailRegister" id="emailRegister" key="global.email" labelposition="left" />
<s:submit key="global.register" name="submitRegister" method="goRegister"></s:submit>
</s:form>
I found the answer to messages preservation here, the guy store the differents action messages (messages, errors, fields error) in session when we are in a redirect situation and push them to the action messages otherwise
Here is my implementation (you will find I add success messages to the default messages and errors messages) :
public class MessagesInterceptor extends AbstractInterceptor {
/**
*
*/
private static final long serialVersionUID = -6230422534075664728L;
private Map<String, Object> session;
#Override
public String intercept(ActionInvocation invocation) throws Exception {
session = invocation.getInvocationContext().getSession();
MyAction action = (MyAction) invocation.getAction();
this.addSessionMessagesInActionMessages(action);
String output = invocation.invoke();
Result result = invocation.getResult();
// If it's a redirection, store the messages in session
if(result instanceof ServletRedirectResult || result instanceof ServletActionRedirectResult)
this.addActionMessagesInSessionMessages(action);
return output;
}
#SuppressWarnings("unchecked")
private void addSessionMessagesInActionMessages(MyAction action) {
Object messagesObject = getSession().remove(SESSION_ACTION_MESSAGES);
if (messagesObject != null) {
List<String> sessionMessages = (List<String>)messagesObject;
for (String sessionMessage : sessionMessages) {
action.addActionMessage(sessionMessage);
}
}
Object errorsObject = getSession().remove(SESSION_ACTION_ERRORS);
if (errorsObject != null) {
List<String> sessionErrors = (List<String>)errorsObject;
for (String sessionError : sessionErrors) {
action.addActionError(sessionError);
}
}
Object successObject = getSession().remove(SESSION_ACTION_SUCCESS);
if (successObject != null) {
List<String> sessionSuccessList = (List<String>)successObject;
for (String sessionSuccess : sessionSuccessList) {
action.addActionSuccess(sessionSuccess);
}
}
#SuppressWarnings("rawtypes")
Map<String, List<String>> fieldErrors = (Map) session.remove(SESSION_FIELD_ERRORS);
if (fieldErrors != null && fieldErrors.size() > 0){
for (Map.Entry<String, List<String>> fieldError : fieldErrors.entrySet()){
for (String message : fieldError.getValue()){
action.addFieldError(fieldError.getKey(), message);
}
}
}
}
protected void addActionMessagesInSessionMessages(MyAction action) throws Exception{
Collection<String> actionErrors = action.getActionErrors();
if (actionErrors != null && actionErrors.size() > 0){
session.put(SESSION_ACTION_ERRORS, actionErrors);
}
Collection<String> actionMessages = action.getActionMessages();
if (actionMessages != null && actionMessages.size() > 0){
session.put(SESSION_ACTION_MESSAGES, actionMessages);
}
Collection<String> actionSuccess = action.getActionSuccess();
if (actionSuccess != null && actionSuccess.size() > 0){
session.put(SESSION_ACTION_SUCCESS, actionSuccess);
}
Map<String, List<String>> fieldErrors = action.getFieldErrors();
if (fieldErrors != null && fieldErrors.size() > 0){
session.put(SESSION_FIELD_ERRORS, fieldErrors);
}
}
public Map<String, Object> getSession() {
return session;
}
public void setSession(Map<String, Object> session) {
this.session = session;
}
}
MyAction inherits ActionSupport
Hope this will help someone ;)
Action mesages and field validation message are now preserved with no refresh problem
But my fields values are now blank, how do I retrieve / store them to repopulate my fields ?

Spring MVC form:select selected value?

Is there any way to select current value in dropdown list by Spring MVC by <form:options>?
No need to use if else
Example:
Student student = new Student();
student.gender = "F";
model.addObject("student", student);
Map<String, String> genders = new LinkedHashMap<String, String>();
genders.put("M", "Male");
genders.put("F", "Female");
model.addObject("genders", genders);
JSP Code
modelAttribute & commandName are interchangeable
<c:url value="/Student/Edit" var="editstudenturl"/>
<form:form method="post" action="${editstudenturl}" modelAttribute="student" class="form-horizontal">
<form:select path="gender" class="form-control" id="gender" >
<form:options items="${genders}" />
</form:select>
</form:form>
Sets 'selected' as appropriate based on bound value.
http://static.springsource.org/spring/docs/2.0.x/reference/spring-form.tld.html#spring-form.tld.options
Here's my fix to this problem. Its massive, but it works
genders: qualifier from java model
// model.addAttribute("genders", genders);
account: binded modelattribute for spring forms
fmt:message: translates m to "Mees" (Estonian)
<form:select path="cfGender">
<c:forEach var="item" items="${genders}">
<c:choose>
<c:when test="${account.getCfGender().getCfGender()==item.getCfGender()}">
<form:option selected="true" value="${item.getCfGender()}">
<fmt:message key="cf_gender.${item.getCfGender()}" />
</form:option>
</c:when>
<c:otherwise>
<form:option value="${item.getCfGender()}">
<fmt:message key="cf_gender.${item.getCfGender()}" />
</form:option>
</c:otherwise>
</c:choose>
</c:forEach>
</form:select>
Try this, it works for me
<form:select path="size">
<c:forEach items="${sizeList}" var="s" varStatus="status">
<c:choose>
<c:when test="${s eq 25}">
<option value="${s}" selected="true">${s}</option>
</c:when>
<c:otherwise>
<option value="${s}">${s}</option>
</c:otherwise>
</c:choose>
</c:forEach>
</form:select>
I had similar problem and after several days of battling with it, I was able to fix it by implementing hash and equal methods in my model class. The problem is that spring was not able to determine where an item in the drop down is equals to a value in the model. But after implementing the hash and equals in the model object, everything worked fine.
#Entity
#Table(name = "BANKS")
public class Bank implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -8928809572705999915L;
private Long id;
private String bankCode;
private String bankName;
...........
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((bankCode == null) ? 0 : bankCode.hashCode());
result = prime * result
+ ((bankName == null) ? 0 : bankName.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bank other = (Bank) obj;
if (bankCode == null) {
if (other.bankCode != null)
return false;
} else if (!bankCode.equals(other.bankCode))
return false;
if (bankName == null) {
if (other.bankName != null)
return false;
} else if (!bankName.equals(other.bankName))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
And in the view i have something like this
<form:select path="bank" cssClass="form-control" required="true">
<form:option value="">--Select--</form:option>
<form:options items="${banks}" itemLabel="bankName"
itemValue="bankCode" />
</form:select>
prior to binding the form to the model, you should set whatever variable you want to be selected to the desired value in the controller of your jsp.
Form form = new Form();
form.setFoo("bar");
model.addAttribute("form", form);
When the form is built in the jsp, that form variable will be the default selected value in your options list.
Need to set both these attributes itemLabel and itemValue to preselect the value
eg: <form:options items="${subCategoryList}" itemLabel="name" itemValue="id"/>
The name and ids are the fields from the SubCategory object and subCategoryList is List<Subcategory>