Project

General

Profile

1
package eu.dnetlib.goldoa.service.dao;
2

    
3
import com.opencsv.CSVWriter;
4
import eu.dnetlib.goldoa.domain.*;
5
import eu.dnetlib.goldoa.service.EligibilityManager;
6
import eu.dnetlib.goldoa.service.InvoiceManager;
7
import org.apache.commons.codec.digest.DigestUtils;
8
import org.apache.commons.io.IOUtils;
9
import org.apache.commons.logging.Log;
10
import org.apache.commons.logging.LogFactory;
11
import org.hibernate.Criteria;
12
import org.hibernate.Query;
13
import org.hibernate.criterion.Restrictions;
14
import org.hibernate.type.StringType;
15
import org.hibernate.type.Type;
16
import org.springframework.beans.factory.annotation.Autowired;
17
import org.springframework.stereotype.Repository;
18

    
19
import java.io.ByteArrayOutputStream;
20
import java.io.IOException;
21
import java.io.InputStream;
22
import java.io.StringWriter;
23
import java.math.BigInteger;
24
import java.sql.Timestamp;
25
import java.text.SimpleDateFormat;
26
import java.util.*;
27

    
28
/*
29
 * Created by antleb on 3/30/15.
30
*/
31
@Repository
32
public class RequestDAO extends AbstractDao<String,Request>{
33

    
34
	private Log logger = LogFactory.getLog(RequestDAO.class);
35
	private final static String GET_COMMENT_TEMPLATES = "select id, status, name, comment from commenttemplate where status=?";
36
	@Autowired
37
	private EligibilityManager eligibilityManager;
38
	@Autowired
39
	private InvoiceManager invoiceManager;
40

    
41
	public void saveRequest(final Request request) {
42
		Request r = getRequest(request.getId());
43
		Request r_merged = null;
44

    
45
		if(request.getRequestCoFunders().size() > 0  ){
46
			logger.debug("Submition request co funders list size -> " + request.getRequestCoFunders().size());
47
			for(RequestCoFunder rc:request.getRequestCoFunders())
48
				rc.getPk().setRequest(request);
49
		}
50

    
51
		if(r != null){
52
			logger.debug("Request submition with id -> " + r.getId());
53
			logger.debug("Submition request co funders list size -> " + r.getRequestCoFunders().size());
54

    
55
			System.out.println("Request submition with id -> " + r.getId());
56
			System.out.println("Submition request co funders list size -> " + r.getRequestCoFunders().size());
57

    
58
			for(RequestCoFunder rc:r.getRequestCoFunders())
59
				rc.getPk().setRequest(r);
60

    
61
			if(request.getBankAccount()!=null){
62
				if(request.getBankAccount().getId() == null )
63
					request.getBankAccount().setId(getBankId());
64
				if(r.getBankAccount() != null){
65
					r.getBankAccount().setAccountHolder(request.getBankAccount().getAccountHolder());
66
					r.getBankAccount().setBankAddress(request.getBankAccount().getBankAddress());
67
					r.getBankAccount().setBankCode(request.getBankAccount().getBankCode());
68
					r.getBankAccount().setBankName(request.getBankAccount().getBankName());
69
					r.getBankAccount().setIban(request.getBankAccount().getIban());
70
				}
71

    
72
			}
73

    
74
			r_merged = (Request)getSession().merge(request);
75
		}
76
		else{
77
			logger.debug("First save of request with id -> " + request.getId());
78
			logger.debug("Request co funders list size -> " + request.getRequestCoFunders().size());
79

    
80
			if(request.getBankAccount()!=null){
81
				if(request.getBankAccount().getId() == null)
82
					request.getBankAccount().setId(getBankId());
83
			}
84

    
85
			for(RequestCoFunder rc:request.getRequestCoFunders())
86
				rc.getPk().setRequest(request);
87

    
88
			Date date = new Date();
89
			request.setDate(new Timestamp(date.getTime()));
90

    
91
			persist(request);
92
		}
93
	}
94

    
95

    
96
	public BigInteger getBankId() {
97
		return (BigInteger) getSession().createSQLQuery("select nextval('bank_id_seq') as id").list().get(0);
98
	}
99

    
100

    
101
	public List<RequestCoFunder> getCoFunders(final Request request) {
102
	    return request.getRequestCoFunders();
103
	}
104

    
105
	@SuppressWarnings("unchecked")
106
	public Request getRequest(String requestId) {
107
	   List<Request> r = createEntityCriteria().add(Restrictions.eq("id",requestId)).list();
108
	   if(r.size() > 0){
109
		   r.get(0).setEligibility(eligibilityManager.validate(r.get(0)));
110
		   return r.get(0);
111
	   }
112
	   return null;
113
	}
114

    
115
	public void submitRequest(Request r) {
116
        if(r.getStatus() != Request.RequestStatus.APPROVED && r.getStatus() != Request.RequestStatus.ACCOUNTING_PROCESSING &&
117
                r.getStatus() != Request.RequestStatus.ACCOUNTING_PAID && r.getStatus() != Request.RequestStatus.CONDITIONALLY_APPROVED){
118
            r.setStatus(Request.RequestStatus.SUBMITTED);
119
            r.setSubmissiondate(new Timestamp(new Date().getTime()));
120

    
121
            saveRequest(r);
122
        }
123
	}
124

    
125
	public void approveRequest(String requestId, User user, String comment, String template) {
126
		Request r = getRequest(requestId);
127
		r.setStatus(Request.RequestStatus.APPROVED);
128
		r.setApprovaldate(new Timestamp(new Date().getTime()));
129
		saveRequest(r);
130

    
131
		if (comment != null && !comment.isEmpty()) {
132
			saveComment(requestId, user, comment, template);
133
		}
134
	}
135

    
136
	public void conditionallyApproveRequest(String requestId, User personId, String comment, String template) {
137
		Request r = getRequest(requestId);
138
		r.setStatus(Request.RequestStatus.CONDITIONALLY_APPROVED);
139
		saveRequest(r);
140
		if (comment != null && !comment.isEmpty()) {
141
			saveComment(requestId, personId, comment, template);
142
		}
143
	}
144

    
145
	private void saveComment(String requestId, User user, String comment, String template) {
146
		String commentId = "portal::" + DigestUtils.md5Hex(comment + new Date());
147
		Comment com = new Comment();
148
		com.setComment(comment);
149
		com.setId(commentId);
150
		com.setPerson(user);
151
		com.setTemplate(null);
152
		com.setDate(new Timestamp(new Date().getTime()));
153

    
154

    
155
		Request r = getRequest(requestId);
156
		List<Comment> cms = r.getRequestComments();
157
		cms.add(com);
158

    
159
		saveRequest(r);
160

    
161
	}
162

    
163
	public void rejectRequest(String requestId, User personId, String comment, String template) {
164
		Request r = getRequest(requestId);
165
		r.setStatus(Request.RequestStatus.REJECTED);
166

    
167
		if (comment != null && !comment.isEmpty()) {
168
			saveComment(requestId, personId, comment, template);
169
		}else
170
			saveRequest(r);
171
	}
172

    
173
	public void processingRequest(String requestId, User user, String comment, String template) {
174
		Request r = getRequest(requestId);
175
		r.setStatus(Request.RequestStatus.ACCOUNTING_PROCESSING);
176

    
177
		if (comment != null && !comment.isEmpty()) {
178
			saveComment(requestId, user, comment, template);
179
		}else
180
			saveRequest(r);
181
	}
182

    
183
	public void paidRequest(String requestId, User user, String comment, String template, float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
184
		Request r = getRequest(requestId);
185
		r.setStatus(Request.RequestStatus.ACCOUNTING_PAID);
186
		r.setApcPaid(apc_paid);
187
		r.setOtherCost(other_cost);
188
		r.setDatePaid(new Timestamp(datePaid.getTime()));
189

    
190
		if (comment != null && !comment.isEmpty()) {
191
			saveComment(requestId, user, comment, template);
192
		}else
193
			saveRequest(r);
194
	}
195

    
196
	public void paidLibraryRequest(String requestId, User user, String comment, String template,
197
								   float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
198
		Request r = getRequest(requestId);
199
		r.setStatus(Request.RequestStatus.LIBRARY_FUND_PAID);
200
		r.setApcPaid(apc_paid);
201
		r.setTransferCost(transfer_cost);
202
		r.setOtherCost(other_cost);
203
		r.setDatePaid(new Timestamp(datePaid.getTime()));
204

    
205
		if (comment != null && !comment.isEmpty()) {
206
			saveComment(requestId, user, comment, template);
207
		}else
208
			saveRequest(r);
209
	}
210

    
211
	public void paidPublisherRequest(String requestId, User user, String comment, String template,
212
									 float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
213
		Request r = getRequest(requestId);
214
		r.setStatus(Request.RequestStatus.PUBLISHER_FUND_PAID);
215
		r.setApcPaid(apc_paid);
216
		r.setTransferCost(transfer_cost);
217
		r.setOtherCost(other_cost);
218
		r.setDatePaid(new Timestamp(datePaid.getTime()));
219

    
220
		if (comment != null && !comment.isEmpty()) {
221
			saveComment(requestId, user, comment, template);
222
		}else
223
			saveRequest(r);
224
	}
225

    
226
	public void onHoldRequest(String requestId, User user, String comment, String template) {
227
		Request r = getRequest(requestId);
228
		r.setStatus(Request.RequestStatus.ACCOUNTING_ON_HOLD);
229

    
230
		if (comment != null && !comment.isEmpty()) {
231
			saveComment(requestId, user, comment, template);
232
		}else
233
			saveRequest(r);
234
	}
235

    
236
	public void deniedRequest(String requestId, User user, String comment, String template) {
237
		Request r = getRequest(requestId);
238
		r.setStatus(Request.RequestStatus.ACCOUNTING_DENIED);
239

    
240
		if (comment != null && !comment.isEmpty()) {
241
			saveComment(requestId, user, comment, template);
242
		}else
243
			saveRequest(r);
244
	}
245

    
246
	@SuppressWarnings("unchecked")
247
	public List<Request> getForProject(String projectId) {
248
		return createEntityCriteria().add(Restrictions.eq("project.id",projectId)).list();
249
	}
250

    
251
    public RequestPage getForUser(String personId, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
252
        return this.getRequestPage(personId, null, null, requestSortBy, order, requestFilter, term, getStatusFilter(statusFilter), from, to);
253
    }
254

    
255
    public RequestPage getForOrganization(List<String> organizationIds, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
256
        return this.getRequestPage(null, organizationIds, null, requestSortBy, order, requestFilter, term, getStatusFilter(statusFilter), from, to);
257
    }
258

    
259
    public RequestPage getForPublisher(String publisherId, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
260
        return this.getRequestPage(null, null, publisherId, requestSortBy, order, requestFilter, term, getStatusFilter(statusFilter), from, to);
261
    }
262

    
263
    public RequestPage getRequests(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
264
        return this.getRequestPage(null, null, null, requestSortBy, order, requestFilter, term, getStatusFilter(statusFilter), from, to);
265
    }
266

    
267
    public RequestPage getRequests(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Integer[] statusFilter, int from, int to) {
268
        return this.getRequestPage(null, null, null, requestSortBy, order, requestFilter, term, statusFilter, from, to);
269
    }
270

    
271
	public BigInteger getRequestId() {
272
		return (BigInteger) getSession().createSQLQuery("select nextval('request_id_seq') as id").list().get(0);
273
	}
274

    
275
	@SuppressWarnings("unchecked")
276
	public String getCSV(RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Integer[] statuses) throws IOException {
277
		List<Object> args = new ArrayList<Object>();
278
		List<Type> types = new ArrayList<>();
279
		String requestQuery = this.getQuery(null, null, null, requestSortBy, order, requestFilter, term, statuses, args, types);
280
		String query = "select r.id as rid, r.status, r.date, u.firstname, u.lastname, o.name as organization," +
281
				" c.name as country, p.id as pid, p.acronym, p.startdate, p.enddate, p.scientificarea, " +
282
				"pub.title, pub.type, j.title as journal,(case when jp.id is not null then jp.name else mp.name end) as publisher, " +
283
				" r.approvaldate as approvaldate, r.apc as apc,r.currency as currency,r.datepaid, r.apcpaid, r.transfercost, " +
284
				" r.othercost, comment.comment as comment from (" + requestQuery + ") r " +
285
				"left join \"user\" u on r.researcher = u.email " +
286
				"left join project p on r.project=p.id " +
287
				"left join publication pub on r.publication=pub.id " +
288
				"left join journal j on j.id=r.journal " +
289
				"left join publisher jp on j.publisher=jp.id " +
290
				"left join publisher mp on mp.id=r.publisher " +
291
				"left join organization o on o.id=r.organization " +
292
				"left join country c on c.id=o.country " +
293
				"left join (select rid , comments[1] as comment  " +
294
				"           from (select rid, array_agg(comments) as comments" +
295
				"                 from (select rc.request as rid, c.comment as comments " +
296
				"                       from comment c " +
297
				"                            join request_comment rc on rc.comment=c.id " +
298
				"                            join request r on r.id=rc.request " +
299
				"                            and r.status = 8  order by rid, c.date desc" +
300
				"                       ) foo " +
301
				"                       group by rid" +
302
				"                 ) bar order by rid \n" +
303
				"           ) as comment on r.id=comment.rid";
304

    
305

    
306

    
307
		System.out.println(query);
308
		List<String[]> requests = new ArrayList<>();
309
		Type[] t = new Type[types.size()];
310
		t = types.toArray(t);
311
		List<Object[]> resultSet = getSession().createSQLQuery(query)
312
				.setParameters(args.toArray(), t).list();
313

    
314
		for(Object rs[] : resultSet){
315

    
316
			String[] objs = new String[24];
317
			objs[0] = rs[0].toString();
318
			objs[1] = String.valueOf(Request.RequestStatus.forStatus(Integer.parseInt(rs[1].toString())));
319
			objs[2] = rs[2]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[2]):null;
320
			objs[3] = rs[3]!=null?rs[3].toString():null;
321
			objs[4] = rs[4]!=null?rs[4].toString():null;
322
			objs[5] = rs[5]!=null?rs[5].toString():null;
323
			objs[6] = rs[6]!=null?rs[6].toString():null;
324
			//project id
325
			objs[7] = rs[7]!=null?rs[7].toString():null;
326
			objs[8] = rs[8]!=null?rs[8].toString():null;
327
			objs[9] = rs[9]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[9]):null;
328
			objs[10] = rs[10]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[10]):null;
329
			objs[11] = rs[11]!=null?rs[11].toString():null;
330
			objs[12] = rs[12]!=null?rs[12].toString():null;
331
			objs[13] = rs[13]!=null?rs[13].toString():null;
332
			objs[14] = rs[14]!=null?rs[14].toString():null;
333
			objs[15] = rs[15]!=null?rs[15].toString():null;
334
			objs[16] = rs[16]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[16]):null;
335
			objs[17] = rs[20]!=null?Float.toString(Float.parseFloat(rs[17].toString())):null;
336
			objs[18] = rs[18]!=null?rs[18].toString():null;
337
			objs[19] = rs[19]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[19]):null;
338
			objs[20] = rs[20]!=null?rs[20].toString() + "":null;
339
			objs[21] = rs[21]!=null?rs[21].toString() + "":null;
340
			objs[22] = rs[22]!=null?rs[22].toString() + "":null;
341
			objs[23] = rs[23]!=null?rs[23].toString():null;
342
			requests.add(objs);
343
		}
344

    
345
		StringWriter sw = new StringWriter();
346
		CSVWriter csvWriter = new CSVWriter(sw);
347

    
348
		csvWriter.writeNext(new String[]{"id", "Status", "Submission Date", "Firstname", "Lastname", "Organization",
349
				"Country", "Project id", "Acronym", "Start Date", "End Date", "Scientific Area", "Title", "Type",
350
				"Journal", "Publisher", "Date Approved", "APC requested", "Currency", "Date Paid", "APC paid",
351
				"Transfer Cost", "Other Expenses", "Rejection Reason"}, false);
352
		csvWriter.writeAll(requests, false);
353

    
354
		csvWriter.close();
355
		sw.close();
356

    
357
		return sw.toString();
358
	}
359

    
360
	@SuppressWarnings("unchecked")
361
	private RequestPage getRequestPage(String personId, List<String> organizationIds, String publisherId,
362
                                       RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter,
363
                                       String term, Integer[] statusFilterCodes, int from, int to) {
364
		RequestPage page = new RequestPage();
365
		List<Object> args = new ArrayList<Object>();
366
		List<Type> types = new ArrayList<>();
367
		String query = getQuery(personId, organizationIds, publisherId, requestSortBy, order,
368
				requestFilter, term, statusFilterCodes, args, types);
369

    
370
		Type[] t = new Type[types.size()];
371
		t = types.toArray(t);
372

    
373
		page.setRequests(getSession().createSQLQuery(applyPaging(query, from, to))
374
				.addEntity(Request.class)
375
				.setParameters(args.toArray(),t)
376
				.list());
377
		
378
		BigInteger bi = (BigInteger) getSession().createSQLQuery(getCountQuery(query))
379
				.setParameters(args.toArray(),t)
380
				.list().get(0);
381
		page.setTotal(bi.intValue());
382
		page.setFrom(from);
383
		page.setTo(to);
384

    
385
		return page;
386
	}
387

    
388
	private String getCountQuery(String query) {
389
		StringBuilder sb = new StringBuilder();
390

    
391
		sb.append("select count(*) from (").append(query).append(") foo");
392

    
393
		return sb.toString();
394
	}
395

    
396
	private String getQuery(String email, List<String> organizationIds, String publisherId, RequestSort requestSortBy, RequestSortOrder order,
397
							RequestFilter requestFilter, String term, Integer[] statusFilterCodes, List<Object> args, List<Type> types) {
398
		Map<String, String> joins = new HashMap<String, String>();
399
		List<String> whereClauses = new ArrayList<String>();
400
		List<Object> whereArgs = new ArrayList<Object>();
401
		List<Type> whereTypes = new ArrayList<>();
402

    
403
		String orderBy = null;
404

    
405
		if (term != null) {
406
			if (requestFilter != null) {
407
				switch (requestFilter) {
408
					case ID:
409
						whereClauses.add("(r.id like ? )");
410
						whereArgs.add("%" + term + "%");
411
						types.add(StringType.INSTANCE);
412
						break;
413
					case USER:
414
						joins.put("user", " join \"user\" u on u.email=r.user and (lower(u.firstname) like lower(?) or lower(u.initials) like lower(?) or lower(u.lastname) like lower(?)) ");
415
						args.add("%" + term + "%");
416
						args.add("%" + term + "%");
417
						args.add("%" + term + "%");
418
						types.add(StringType.INSTANCE);
419
						types.add(StringType.INSTANCE);
420
						types.add(StringType.INSTANCE);
421
						break;
422
					case RESEARCHER:
423
						joins.put("researcher", " join \"user\" res on res.email=r.researcher and (lower(res.firstname) like lower(?) or lower(res.initials) like lower(?) or lower(res.lastname) like lower(?)) ");
424
						args.add("%" + term + "%");
425
						args.add("%" + term + "%");
426
						args.add("%" + term + "%");
427
						types.add(StringType.INSTANCE);
428
						types.add(StringType.INSTANCE);
429
						types.add(StringType.INSTANCE);
430
						break;
431
					case PROJECT:
432
						joins.put("project", " join project proj on proj.id=r.project and (lower(proj.acronym) like lower(?) or lower(proj.title) like lower(?) or lower(proj.grant) like lower(?)) ");
433
						args.add("%" + term + "%");
434
						args.add("%" + term + "%");
435
						args.add("%" + term + "%");
436
						types.add(StringType.INSTANCE);
437
						types.add(StringType.INSTANCE);
438
						types.add(StringType.INSTANCE);
439
						break;
440
					case PUBLICATION:
441
						joins.put("publication", " join publication pub on pub.id=r.publication and (lower(pub.title) like lower(?)) ");
442
						args.add("%" + term + "%");
443
						types.add(StringType.INSTANCE);
444
						break;
445
					case JOURNAL:
446
						joins.put("journal", " join journal j on j.id=r.journal and (lower(j.title) like lower(?)) ");
447
						args.add("%" + term + "%");
448
						types.add(StringType.INSTANCE);
449
						break;
450
					case PUBLISHER:
451
						joins.put("publisher", " join publisher publ on publ.id=r.publisher and (lower(publ.name) like lower(?)) ");
452
						args.add("%" + term + "%");
453
						types.add(StringType.INSTANCE);
454
						break;
455
					case INVOICE:
456
						joins.put("invoice", "join invoice i on i.id=r.invoice and (lower(i.number) like lower(?) or lower(alternativeid) like lower(?))");
457
						args.add("%" + term + "%");
458
						args.add("%" + term + "%");
459
						types.add(StringType.INSTANCE);
460
						types.add(StringType.INSTANCE);
461
						break;
462
				}
463
			} else {
464
				whereClauses.add("(r.id like ? )");
465
				whereArgs.add("%" + term + "%");
466
				types.add(StringType.INSTANCE);
467

    
468
				joins.put("user", " left join \"user\" u on u.email=r.user ");
469
				whereClauses.add("(lower(u.firstname) like lower(?) or lower(u.initials) like lower(?) or lower(u.lastname) like lower(?))");
470
				whereArgs.add("%" + term + "%");
471
				whereArgs.add("%" + term + "%");
472
				whereArgs.add("%" + term + "%");
473
				whereTypes.add(StringType.INSTANCE);
474
				whereTypes.add(StringType.INSTANCE);
475
				whereTypes.add(StringType.INSTANCE);
476
				joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
477
				whereClauses.add("(lower(res.firstname) like lower(?) or lower(res.initials) like lower(?) or lower(res.lastname) like lower(?))");
478
				whereArgs.add("%" + term + "%");
479
				whereArgs.add("%" + term + "%");
480
				whereArgs.add("%" + term + "%");
481
				whereTypes.add(StringType.INSTANCE);
482
				whereTypes.add(StringType.INSTANCE);
483
				whereTypes.add(StringType.INSTANCE);
484
				joins.put("project", " left join project proj on proj.id=r.project ");
485
				whereClauses.add("(lower(proj.acronym) like lower(?) or lower(proj.title) like lower(?) or lower(proj.grant) like lower(?))");
486
				whereArgs.add("%" + term + "%");
487
				whereArgs.add("%" + term + "%");
488
				whereArgs.add("%" + term + "%");
489
				whereTypes.add(StringType.INSTANCE);
490
				whereTypes.add(StringType.INSTANCE);
491
				whereTypes.add(StringType.INSTANCE);
492
				joins.put("publication", " left join publication pub on pub.id=r.publication ");
493
				whereClauses.add("(lower(pub.title) like lower(?))");
494
				whereArgs.add("%" + term + "%");
495
				whereTypes.add(StringType.INSTANCE);
496
				joins.put("journal", " left join journal j on j.id=r.journal ");
497
				whereClauses.add("(lower(j.title) like lower(?))");
498
				whereArgs.add("%" + term + "%");
499
				whereTypes.add(StringType.INSTANCE);
500
				joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
501
				whereClauses.add("(lower(publ.name) like lower(?))");
502
				whereArgs.add("%" + term + "%");
503
				whereTypes.add(StringType.INSTANCE);
504
				joins.put("invoice", " left join invoice i on i.id=r.invoice ");
505
				whereClauses.add("(lower(i.number) like lower(?) or lower(alternativeid) like lower(?))");
506
				whereArgs.add("%" + term + "%");
507
				whereArgs.add("%" + term + "%");
508
				whereTypes.add(StringType.INSTANCE);
509
				whereTypes.add(StringType.INSTANCE);
510
			}
511

    
512
		}
513

    
514
		if (requestSortBy != null) {
515
			switch (requestSortBy) {
516
				case DATE:
517
					orderBy = " r.date ";
518
					break;
519
				case FUNDING_REQUESTED:
520
					orderBy = " r.fundingrequested ";
521
					break;
522
				case USER:
523
					if (joins.get("user") == null)
524
						joins.put("user", " left join \"user\" u on u.email=r.user ");
525

    
526
					orderBy = " u.firstname, u.initials, u.lastname ";
527
					break;
528
				case PUBLICATION:
529
					if (joins.get("publication") == null)
530
						joins.put("publication", " left join publication pub on r.publication=pub.id ");
531

    
532
					orderBy = " pub.title ";
533
					break;
534
				case RESEARCHER:
535
					if (joins.get("researcher") == null)
536
						joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
537

    
538
					orderBy = " res.firstname, res.initials, res.lastname ";
539
					break;
540
				case PROJECT:
541
					if (joins.get("project") == null)
542
						joins.put("project", " left join project proj on proj.id=r.project ");
543

    
544
					orderBy = " proj.acronym ";
545
					break;
546
				case JOURNAL:
547
					if (joins.get("journal") == null)
548
						joins.put("journal", " left join journal j on j.id=r.journal ");
549

    
550
					orderBy = " j.title ";
551
					break;
552
				case PUBLISHER:
553
					if (joins.get("publisher") == null)
554
						joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
555

    
556
					orderBy = " publ.name ";
557
					break;
558
				case STATUS:
559
				default:
560
					orderBy = " r.status ";
561
					break;
562
			}
563
		}
564

    
565
		//TODO fix bank fields and publisher_email
566
		//StringBuilder sb = new StringBuilder("select r.id, r.\"user\", r.date, r.researcher, r.organization, r.project, r.publication, r.journal, r.publisher, r.publisher_email, r.budget, r.invoice, r.apc, r.discount, r.projectparticipation, r.fundingrequested, r.currency, r.bank_name, r.bank_address, r.bank_code, r.bank_holder, r.bank_iban, r.apc_paid, r.transfer_cost, r.other_cost, r.date_paid, r.submissiondate, r.approvaldate, r.status from request r ");
567
		StringBuilder sb = new StringBuilder("select r.id as id, " +
568
				"r.\"user\" as \"user\", r.date as date, r.researcher as researcher, r.organization as organization, " +
569
				"r.project as project, r.publication as publication, r.journal as journal, r.publisher as publisher,  " +
570
				"r.budget as budget, r.invoice as invoice , r.apc as apc, r.discount as discount, " +
571
				"r.projectparticipation as projectparticipation, r.fundingrequested as fundingrequested, r.currency as currency, " +
572
				"r.apcPaid as apcPaid, r.transferCost as transferCost, r.otherCost as otherCost, r.datePaid as datePaid, " +
573
				"r.submissiondate as submissiondate, r.approvaldate as approvaldate, r.status as status ," +
574
				"r.bankAccount as bankAccount , r.bankTransferReceipt as bankTransferReceipt ," +
575
				"r.publisher_email as publisher_email from request r ");
576
		for (String join : joins.values())
577
			sb.append(" ").append(join).append(" ");
578

    
579

    
580
		sb.append(" where ");
581

    
582
		if (email != null) {
583
			sb.append("r.\"user\"=? ");
584

    
585
			args.add(email);
586
			types.add(StringType.INSTANCE);
587
		} else if (organizationIds != null) {
588
			sb.append("(");
589

    
590
			for (int i = 0; i < organizationIds.size(); i++) {
591
				if (i > 0)
592
					sb.append(" or ");
593

    
594
				sb.append(" r.organization=? ");
595

    
596
				args.add(organizationIds.get(i));
597
				types.add(StringType.INSTANCE);
598
			}
599

    
600
			sb.append(")");
601

    
602
		} else if (publisherId != null) {
603

    
604
			if (joins.get("journal") == null) {
605
				sb.delete(sb.lastIndexOf("where"), sb.length());
606
				sb.append(" left join journal j on j.id=r.journal ");
607
				sb.append(" where ");
608
			}
609

    
610
			sb.append("(r.publisher=? or j.publisher=?)");
611

    
612
			args.add(publisherId);
613
			types.add(StringType.INSTANCE);
614
			args.add(publisherId);
615
			types.add(StringType.INSTANCE);
616
		}
617

    
618
		if (statusFilterCodes != null) {
619
			StringBuilder ssb = new StringBuilder();
620

    
621
			for (Integer code:statusFilterCodes) {
622
				String clause;
623

    
624
				switch (code) {
625
					default:
626
						clause = " (r.status = " + code + ")";
627
						break;
628
				}
629

    
630
				ssb.append(ssb.length()==0?clause:" or " + clause);
631
			}
632

    
633
			if (sb.toString().trim().endsWith("where"))
634
				sb.append("(").append(ssb.toString()).append(")");
635
			else
636
				sb.append(" and ").append("(").append(ssb.toString()).append(")");
637
		}
638

    
639
		if (whereClauses.size() > 0) {
640
			if (!sb.toString().trim().endsWith("where"))
641
				sb.append(" and ");
642
			sb.append("(");
643

    
644
			for (String clause : whereClauses) {
645
				sb.append(clause);
646
				sb.append(" or ");
647
			}
648

    
649
			sb.delete(sb.lastIndexOf("or"), sb.length());
650
			sb.append(") ");
651

    
652
			args.addAll(whereArgs);
653
			types.addAll(whereTypes);
654
		}
655

    
656
		if (sb.toString().trim().endsWith("where"))
657
			sb.delete(sb.lastIndexOf("where"), sb.length());
658

    
659
		if (orderBy != null) {
660
			sb.append(" order by ").append(orderBy);
661

    
662
			if (order == RequestSortOrder.ASCENDING)
663
				sb.append(" asc");
664
			else
665
				sb.append(" desc");
666
		}
667

    
668
		return sb.toString();
669
	}
670

    
671
	private String applyPaging(String query, int from, int to) {
672
		StringBuilder sb = new StringBuilder(query);
673

    
674
		if (from > 0 || to > 0) {
675
			sb.append(" limit ").append(to - from + 1);
676
			sb.append(" offset ").append(from);
677
		}
678

    
679
		return sb.toString();
680
	}
681

    
682
	private Integer[] getStatusFilter(Request.RequestStatus[] statuses) {
683
		if (statuses == null)
684
			return null;
685
		else {
686
			Integer[] res = new Integer[statuses.length];
687

    
688
			for (int i = 0; i < statuses.length; i++)
689
				res[i] = statuses[i].getCode();
690

    
691
			return res;
692
		}
693
	}
694

    
695
	public List<Comment> getComments(String id) {
696
		return getRequest(id).getRequestComments();
697
	}
698

    
699
	public void uploadBankTransferReceipt(final String requestid, final String contentType, InputStream inputStream) {
700
		try {
701
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
702
			Request r = getRequest(requestid);
703

    
704
			IOUtils.copy(inputStream, baos);
705
			IOUtils.closeQuietly(baos);
706
			r.setBankTransferReceipt(new BankTransferReceipt(contentType,baos.toByteArray()));
707
			saveRequest(r);
708
		} catch (Exception e) {
709
			e.printStackTrace();
710
		}
711
	}
712

    
713
	public BankTransferReceipt downloadBankTransferReceipt(String requestId) {
714
		Request r = getRequest(requestId);
715
		return r.getBankTransferReceipt();
716
	}
717

    
718
	@SuppressWarnings("unchecked")
719
	public List<CommentTemplate> getCommentTemplates(Request.RequestStatus requestStatus) {
720
		Criteria cr = getSession().createCriteria(CommentTemplate.class);
721
		return cr.list();
722
	}
723

    
724
    public BigInteger getActiveNumber() {
725

    
726
		String NUMBERS_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
727
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", "
728
				+ Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")" ;
729

    
730
		Query q = getSession().createSQLQuery(NUMBERS_REQUESTS);
731
		return ((BigInteger) q.list().get(0));
732
	}
733

    
734
	public BigInteger getPaidNumber() {
735
		String NUMBERS_PAID_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ")" ;
736

    
737
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS);
738
		return ((BigInteger) q.list().get(0));
739
	}
740

    
741
	public BigInteger getNumberOfProjects() {
742
		String NUMBERS_PROJECTS = "select count(distinct project) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
743
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode()
744
				+ ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")";
745
		Query q = getSession().createSQLQuery(NUMBERS_PROJECTS);
746
		return ((BigInteger) q.list().get(0));
747
	}
748

    
749
	public Float getTotalAmount() {
750
		String NUMBERS_TOTAL_AMOUNT = "select sum(apcPaid) from request r";
751
		Query q = getSession().createSQLQuery(NUMBERS_TOTAL_AMOUNT);
752
		Float result = (Float) q.list().get(0);
753
		if(result == null) return Float.valueOf(0);
754
		return result;
755
	}
756

    
757
	public Double getAverageAmount() {
758
		String NUMBERS_AVERAGE_AMOUNT = "select avg(apcPaid) from request r";
759
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_AMOUNT);
760
		Double result = (Double) q.list().get(0);
761
		if(result == null) return Double.valueOf(0);
762
		return result;
763
	}
764

    
765
	public Double getAverageAmountPerArticle(){
766
		String NUMBERS_AVERAGE_PER_ARTICLE = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='ARTICLE'";
767
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_ARTICLE);
768
		Double result = (Double) q.list().get(0);
769
		if(result == null) return Double.valueOf(0);
770
		return result;
771
	}
772

    
773
	public Double getAverageAmountPerMonograph(){
774
		String NUMBERS_AVERAGE_PER_MONOGRAPH = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='MONOGRAPH'";
775
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_MONOGRAPH);
776
		Double result = (Double) q.list().get(0);
777
		if(result == null) return Double.valueOf(0);
778
		return result;
779
	}
780

    
781
	public Double getAverageAmountPerBookChapter(){
782
		String NUMBERS_AVERAGE_PER_BOOK_CHAPTER = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='BOOK_CHAPTER'";
783
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_BOOK_CHAPTER);
784
		Double result = (Double) q.list().get(0);
785
		if(result == null) return Double.valueOf(0);
786
		return result;
787
	}
788

    
789
	public BigInteger getNumberOfPaidRequestsWithDOI() {
790
		String NUMBERS_PAID_REQUESTS_WITH_DOI = "select count(*) from request r join publication p on r.publication=p.id where p.doi is not null " +
791
				"and r.status=" + Request.RequestStatus.ACCOUNTING_PAID.getCode();
792
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS_WITH_DOI);
793
		BigInteger result = (BigInteger) q.list().get(0);
794
		if(result == null) return BigInteger.valueOf(0);
795
		return result;
796
	}
797

    
798
	public BigInteger getNumberOfApprovedRequestsWithDOI() {
799
		String NUMBERS_APPROVED_REQUESTS_WITH_DOI = "select count(*) from request r join publication p on r.publication=p.id where p.doi is not null and r.status in (" +
800
				Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", "
801
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode()
802
				+ ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ")";
803

    
804
		Query q = getSession().createSQLQuery(NUMBERS_APPROVED_REQUESTS_WITH_DOI);
805
		BigInteger result = (BigInteger) q.list().get(0);
806
		if(result == null) return BigInteger.valueOf(0);
807
		return result;
808
	}
809

    
810
	public BigInteger getNumberOfPaidPublicationPerArticle(){
811
		String NUMBERS_PAID_ARTICLE_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
812
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='ARTICLE'" ;
813
		Query q = getSession().createSQLQuery(NUMBERS_PAID_ARTICLE_REQUESTS);
814
		BigInteger result = (BigInteger) q.list().get(0);
815
		if(result == null) return BigInteger.valueOf(0);
816
		return result;
817
	}
818

    
819
	public BigInteger getNumberOfPaidPublicationPerMonograph(){
820
		String NUMBERS_PAID_MONOGRAPH_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
821
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='MONOGRAPH'" ;
822
		Query q = getSession().createSQLQuery(NUMBERS_PAID_MONOGRAPH_REQUESTS);
823
		BigInteger result = (BigInteger) q.list().get(0);
824
		if(result == null) return BigInteger.valueOf(0);
825
		return result;
826
	}
827

    
828
	public BigInteger getNumberOfPaidPublicationPerBookChapter(){
829
		String NUMBERS_PAID_BOOK_CHAPTER_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
830
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='BOOK_CHAPTER'" ;
831
		Query q = getSession().createSQLQuery(NUMBERS_PAID_BOOK_CHAPTER_REQUESTS);
832
		BigInteger result = (BigInteger) q.list().get(0);
833
		if(result == null) return BigInteger.valueOf(0);
834
		return result;
835
	}
836

    
837
}
(11-11/12)