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.domain.Currency;
6
import eu.dnetlib.goldoa.service.EligibilityManager;
7
import eu.dnetlib.goldoa.service.InvoiceManager;
8
import org.apache.commons.codec.digest.DigestUtils;
9
import org.apache.commons.io.IOUtils;
10
import org.apache.commons.logging.Log;
11
import org.apache.commons.logging.LogFactory;
12
import org.hibernate.Criteria;
13
import org.hibernate.Hibernate;
14
import org.hibernate.Query;
15
import org.hibernate.criterion.Restrictions;
16
import org.hibernate.type.StringType;
17
import org.hibernate.type.TextType;
18
import org.hibernate.type.Type;
19
import org.springframework.beans.factory.annotation.Autowired;
20
import org.springframework.stereotype.Repository;
21

    
22
import java.io.ByteArrayOutputStream;
23
import java.io.IOException;
24
import java.io.InputStream;
25
import java.io.StringWriter;
26
import java.math.BigInteger;
27
import java.sql.Timestamp;
28
import java.text.ParseException;
29
import java.text.SimpleDateFormat;
30
import java.util.*;
31

    
32
/*
33
 * Created by antleb on 3/30/15.
34
*/
35
@Repository
36
public class RequestDAO extends AbstractDao<String,Request>{
37

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

    
45
	public void saveRequest(final Request request) {
46

    
47

    
48
		if(request.getBankAccount()!=null){
49
			if(request.getBankAccount().getId() == null)
50
				request.getBankAccount().setId(getBankId());
51
		}
52

    
53
		if(request.getRequestCoFunders() !=null) {
54
			for (RequestCoFunder rc : request.getRequestCoFunders())
55
				rc.getPk().setRequest(request);
56
		}
57

    
58

    
59
		if ( getRequest(request.getId()) == null){
60
			Date date = new Date();
61
			request.setDate(new Timestamp(date.getTime()));
62
			persist(request);
63
		}
64

    
65
		//getSession().saveOrUpdate(request);
66
		Request persistened_request = (Request) getSession().merge(request);
67
	}
68

    
69

    
70
	public BigInteger getBankId() {
71
		return (BigInteger) getSession().createSQLQuery("select nextval('bank_id_seq') as id").list().get(0);
72
	}
73

    
74

    
75
	public List<RequestCoFunder> getCoFunders(final Request request) {
76
	    return request.getRequestCoFunders();
77
	}
78

    
79
	@SuppressWarnings("unchecked")
80
	public Request getRequest(String requestId) {
81
	   List<Request> r = createEntityCriteria().add(Restrictions.eq("id",requestId)).list();
82
	   if(r.size() > 0){
83
		   r.get(0).setEligibility(eligibilityManager.validate(r.get(0)));
84
		   return r.get(0);
85
	   }
86
	   return null;
87
	}
88

    
89
	public void submitRequest(Request r) {
90
        if(r.getStatus() != Request.RequestStatus.APPROVED && r.getStatus() != Request.RequestStatus.ACCOUNTING_PROCESSING &&
91
                r.getStatus() != Request.RequestStatus.ACCOUNTING_PAID && r.getStatus() != Request.RequestStatus.CONDITIONALLY_APPROVED){
92
            r.setStatus(Request.RequestStatus.SUBMITTED);
93
            r.setSubmissiondate(new Timestamp(new Date().getTime()));
94
            saveRequest(r);
95
        }
96
	}
97

    
98
	public void approveRequest(String requestId, User user, String comment, String template) {
99
		Request r = getRequest(requestId);
100
		r.setStatus(Request.RequestStatus.APPROVED);
101
		r.setApprovaldate(new Timestamp(new Date().getTime()));
102
		saveRequest(r);
103
		if (comment != null && !comment.isEmpty()) {
104
			saveComment(r, user, comment, template);
105
		}
106
	}
107

    
108
	public void conditionallyApproveRequest(String requestId, User user, String comment, String template) {
109
		Request r = getRequest(requestId);
110
		r.setStatus(Request.RequestStatus.CONDITIONALLY_APPROVED);
111
		saveRequest(r);
112
		if (comment != null && !comment.isEmpty()) {
113
			saveComment(r, user, comment, template);
114
		}
115
	}
116

    
117
	private void saveComment(Request request, User user, String comment, String template) {
118
		String commentId = "portal::" + DigestUtils.md5Hex(comment + new Date());
119

    
120
		logger.debug("Comment : " + comment);
121

    
122
		Comment com = new Comment();
123
		com.setComment(comment);
124
		com.setId(commentId);
125
		com.setPerson(user);
126
		com.setTemplate(null);
127
		com.setDate(new Timestamp(new Date().getTime()));
128

    
129
		List<Comment> cms = request.getRequestComments();
130
		cms.add(com);
131
		saveRequest(request);
132
	}
133

    
134
	public void rejectRequest(String requestId, User user, String comment, String template) {
135
		Request r = getRequest(requestId);
136
		r.setStatus(Request.RequestStatus.REJECTED);
137
		saveRequest(r);
138
		if (comment != null && !comment.isEmpty()) {
139
			saveComment(r, user, comment, template);
140
		}
141
	}
142

    
143
	public void processingRequest(String requestId, User user, String comment, String template) {
144
		Request r = getRequest(requestId);
145
		r.setStatus(Request.RequestStatus.ACCOUNTING_PROCESSING);
146
		saveRequest(r);
147
		if (comment != null && !comment.isEmpty()) {
148
			saveComment(r, user, comment, template);
149
		}
150

    
151
	}
152

    
153
	public void paidRequest(String requestId, User user, String comment, String template, float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
154
		Request r = getRequest(requestId);
155
		r.setStatus(Request.RequestStatus.ACCOUNTING_PAID);
156
		r.setApcPaid(apc_paid);
157
		r.setOtherCost(other_cost);
158
		r.setTransferCost(transfer_cost);
159
		r.setDatePaid(new Timestamp(datePaid.getTime()));
160
		saveRequest(r);
161

    
162
		if (comment != null && !comment.isEmpty()) {
163
			saveComment(r, user, comment, template);
164
		}
165
	}
166

    
167
	public void paidLibraryRequest(String requestId, User user, String comment, String template,
168
								   float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
169
		Request r = getRequest(requestId);
170
		r.setStatus(Request.RequestStatus.LIBRARY_FUND_PAID);
171
		r.setApcPaid(apc_paid);
172
		r.setTransferCost(transfer_cost);
173
		r.setOtherCost(other_cost);
174
		r.setDatePaid(new Timestamp(datePaid.getTime()));
175
		saveRequest(r);
176
		if (comment != null && !comment.isEmpty()) {
177
			saveComment(r, user, comment, template);
178
		}
179
	}
180

    
181
	public void paidPublisherRequest(String requestId, User user, String comment, String template,
182
									 float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
183
		Request r = getRequest(requestId);
184
		r.setStatus(Request.RequestStatus.PUBLISHER_FUND_PAID);
185
		r.setApcPaid(apc_paid);
186
		r.setTransferCost(transfer_cost);
187
		r.setOtherCost(other_cost);
188
		r.setDatePaid(new Timestamp(datePaid.getTime()));
189
		saveRequest(r);
190
		if (comment != null && !comment.isEmpty()) {
191
			saveComment(r, user, comment, template);
192
		}
193
	}
194

    
195
	public void onHoldRequest(String requestId, User user, String comment, String template) {
196
		Request r = getRequest(requestId);
197
		r.setStatus(Request.RequestStatus.ACCOUNTING_ON_HOLD);
198
		saveRequest(r);
199
		if (comment != null && !comment.isEmpty()) {
200
			saveComment(r, user, comment, template);
201
		}
202
	}
203

    
204
	public void deniedRequest(String requestId, User user, String comment, String template) {
205
		Request r = getRequest(requestId);
206
		r.setStatus(Request.RequestStatus.ACCOUNTING_DENIED);
207
		saveRequest(r);
208
		if (comment != null && !comment.isEmpty()) {
209
			saveComment(r, user, comment, template);
210
		}
211
	}
212

    
213
	@SuppressWarnings("unchecked")
214
	public List<Request> getForProject(String projectId) {
215
		return createEntityCriteria().add(Restrictions.eq("project.id",projectId)).list();
216
	}
217

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

    
222
    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) {
223
        return this.getRequestPage(null, organizationIds, null, requestSortBy, order, requestFilter, term, getStatusFilter(statusFilter), from, to);
224
    }
225

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

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

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

    
238
	public BigInteger getRequestId() {
239
		return (BigInteger) getSession().createSQLQuery("select nextval('request_id_seq') as id").list().get(0);
240
	}
241

    
242
	@SuppressWarnings("unchecked")
243
	public String getCSV(RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Integer[] statuses) throws IOException {
244
		List<Object> args = new ArrayList<Object>();
245
		List<Type> types = new ArrayList<>();
246
		String requestQuery = this.getQuery(null, null, null, requestSortBy, order, requestFilter, term, statuses, args, types);
247
		String query = "select r.id as rid, r.status, r.date, u.firstname, u.lastname, o.name as organization," +
248
				" c.name as country, p.id as pid, p.acronym, p.startdate, p.enddate, p.scientificarea, " +
249
				"pub.title, pub.type, j.title as journal,j.issn as issn,(case when jp.id is not null then jp.name else mp.name end) as publisher, " +
250
				" r.approvaldate as approvaldate, r.apc as apc,r.currency as currency,r.datepaid, r.apcpaid, r.transfercost, " +
251
				" r.othercost, comment.comment as comment, " +
252
				" pub.license as license , pub.doi as doi , pub.repository as repository  , f.identifiers as identifiers " +
253
				"from (" + requestQuery + ") r " +
254
				"left join \"user\" u on r.researcher = u.email " +
255
				"left join project p on r.project=p.id " +
256
				"left join publication pub on r.publication=pub.id " +
257
				"left join (select publication,array_to_string ( array_agg(concat_ws('#', type, value)),'@') as identifiers" +
258
				"			from publication_identifier pi, identifier i " +
259
				"			where pi.identifier = i.id" +
260
				"			group by pi.publication" +
261
				"			) as f  on r.publication = f.publication " +
262
				"left join journal j on j.id=r.journal " +
263
				"left join publisher jp on j.publisher=jp.id " +
264
				"left join publisher mp on mp.id=r.publisher " +
265
				"left join organization o on o.id=r.organization " +
266
				"left join country c on c.id=o.country " +
267
				"left join (select rid , comments[1] as comment  " +
268
				"           from (select rid, array_agg(comments) as comments" +
269
				"                 from (select rc.request as rid, c.comment as comments " +
270
				"                       from comment c " +
271
				"                            join request_comment rc on rc.comment=c.id " +
272
				"                            join request r on r.id=rc.request " +
273
				"                            and r.status = 8  order by rid, c.date desc" +
274
				"                       ) foo " +
275
				"                       group by rid" +
276
				"                 ) bar order by rid \n" +
277
				"           ) as comment on r.id=comment.rid";
278

    
279

    
280

    
281
		List<String[]> requests = new ArrayList<>();
282
		Type[] t = new Type[types.size()];
283
		t = types.toArray(t);
284

    
285

    
286
		List<Object[]> resultSet = getSession().createSQLQuery(query)
287
				.setParameters(args.toArray(), t).list();
288

    
289
		for(Object rs[] : resultSet){
290

    
291
			String[] objs = new String[28];
292
			objs[0] = rs[0].toString();
293
			objs[1] = String.valueOf(Request.RequestStatus.forStatus(Integer.parseInt(rs[1].toString())));
294
			objs[2] = rs[2]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[2]):null;
295
			objs[3] = rs[3]!=null?rs[3].toString():null;
296
			objs[4] = rs[4]!=null?rs[4].toString():null;
297
			objs[5] = rs[5]!=null?rs[5].toString():null;
298
			objs[6] = rs[6]!=null?rs[6].toString():null;
299
			objs[7] = rs[7]!=null?rs[7].toString().split("::")[1]:null;
300
			objs[8] = rs[8]!=null?rs[8].toString():null;
301
			objs[9] = rs[9]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[9]):null;
302
			objs[10] = rs[10]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[10]):null;
303
			objs[11] = rs[11]!=null?rs[11].toString():null;
304
			objs[12] = rs[12]!=null?rs[12].toString():null;
305
			objs[13] = rs[13]!=null?rs[13].toString():null;
306
			objs[14] = rs[14]!=null?rs[14].toString():null;
307
			objs[15] = rs[15]!=null?rs[15].toString():null;
308
			objs[16] = rs[16]!=null?rs[16].toString():null;
309
			objs[17] = rs[17]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[17]):null;
310
			objs[18] = rs[18]!=null?Float.toString(Float.parseFloat(rs[18].toString())):null;
311
			objs[19] = rs[19]!=null?rs[19].toString():null;
312
			objs[20] = rs[20]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[20]):null;
313
			objs[21] = rs[21]!=null?rs[21].toString() + "":null;
314
			objs[22] = rs[22]!=null?rs[22].toString() + "":null;
315
			objs[23] = rs[23]!=null?rs[23].toString() + "":null;
316
			objs[24] = rs[24]!=null?rs[24].toString():null;
317
			objs[25] = rs[25]!=null?rs[25].toString():null;
318

    
319
			objs[26] = rs[26]!=null?"Doi: " + rs[26].toString() + ";":"";
320
			objs[27] = rs[27]!=null?rs[27].toString():null;
321

    
322

    
323
			String[] identifiers = rs[28]!=null?rs[28].toString().split("@"):null;
324

    
325
			if (identifiers != null){
326
				for(String identifier : identifiers){
327
					String[] type_values = identifier.split("#");
328
					String type = type_values[0];
329
					String value = type_values[1];
330
					objs[26] += type + ":" + value;
331
				}
332
			}
333
			requests.add(objs);
334
		}
335

    
336
		StringWriter sw = new StringWriter();
337
		CSVWriter csvWriter = new CSVWriter(sw);
338

    
339
		csvWriter.writeNext(new String[]{"id", "Status", "Submission Date", "Firstname", "Lastname", "Organization",
340
				"Country", "Project id", "Acronym", "Start Date", "End Date", "Scientific Area", "Title", "Type",
341
				"Journal","Journal ISSN", "Publisher", "Date Approved", "APC requested", "Currency", "Date Paid", "APC paid",
342
				"Transfer Cost", "Other Expenses", "Rejection Reason", "License" , "Identifiers", "Repository"}, false);
343
		csvWriter.writeAll(requests, false);
344

    
345
		csvWriter.close();
346
		sw.close();
347

    
348
		return sw.toString();
349
	}
350

    
351
	@SuppressWarnings("unchecked")
352
	private RequestPage getRequestPage(String personId, List<String> organizationIds, String publisherId,
353
                                       RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter,
354
                                       String term, Integer[] statusFilterCodes, int from, int to) {
355
		RequestPage page = new RequestPage();
356
		List<Object> args = new ArrayList<Object>();
357
		List<Type> types = new ArrayList<>();
358
		String query = getQuery(personId, organizationIds, publisherId, requestSortBy, order,
359
				requestFilter, term, statusFilterCodes, args, types);
360

    
361
		Type[] t = new Type[types.size()];
362
		t = types.toArray(t);
363

    
364
		page.setRequests(getSession().createSQLQuery(applyPaging(query, from, to))
365
				.addEntity(Request.class)
366
				.setParameters(args.toArray(),t)
367
				.list());
368
		
369
		BigInteger bi = (BigInteger) getSession().createSQLQuery(getCountQuery(query))
370
				.setParameters(args.toArray(),t)
371
				.list().get(0);
372
		page.setTotal(bi.intValue());
373
		page.setFrom(from);
374
		page.setTo(to);
375

    
376
		return page;
377
	}
378

    
379
	private String getCountQuery(String query) {
380
		StringBuilder sb = new StringBuilder();
381

    
382
		sb.append("select count(*) from (").append(query).append(") foo");
383

    
384
		return sb.toString();
385
	}
386

    
387
	private String getQuery(String email, List<String> organizationIds, String publisherId, RequestSort requestSortBy, RequestSortOrder order,
388
							RequestFilter requestFilter, String term, Integer[] statusFilterCodes, List<Object> args, List<Type> types) {
389
		Map<String, String> joins = new HashMap<String, String>();
390
		List<String> whereClauses = new ArrayList<String>();
391
		List<Object> whereArgs = new ArrayList<Object>();
392
		List<Type> whereTypes = new ArrayList<>();
393

    
394
		String orderBy = null;
395

    
396
		if (term != null) {
397
			if (requestFilter != null) {
398
				switch (requestFilter) {
399
					case ID:
400
						whereClauses.add("(r.id like ? )");
401
						whereArgs.add("%" + term + "%");
402
						types.add(StringType.INSTANCE);
403
						break;
404
					case USER:
405
						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(?)) ");
406
						args.add("%" + term + "%");
407
						args.add("%" + term + "%");
408
						args.add("%" + term + "%");
409
						types.add(StringType.INSTANCE);
410
						types.add(StringType.INSTANCE);
411
						types.add(StringType.INSTANCE);
412
						break;
413
					case RESEARCHER:
414
						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(?)) ");
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 PROJECT:
423
						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(?)) ");
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 PUBLICATION:
432
						joins.put("publication", " join publication pub on pub.id=r.publication and (lower(pub.title) like lower(?)) ");
433
						args.add("%" + term + "%");
434
						types.add(StringType.INSTANCE);
435
						break;
436
					case JOURNAL:
437
						joins.put("journal", " join journal j on j.id=r.journal and (lower(j.title) like lower(?)) ");
438
						args.add("%" + term + "%");
439
						types.add(StringType.INSTANCE);
440
						break;
441
					case PUBLISHER:
442
						joins.put("publisher", " join publisher publ on publ.id=r.publisher and (lower(publ.name) like lower(?)) ");
443
						args.add("%" + term + "%");
444
						types.add(StringType.INSTANCE);
445
						break;
446
					case INVOICE:
447
						joins.put("invoice", "join invoice i on i.id=r.invoice and (lower(i.number) like lower(?) or lower(alternativeid) like lower(?))");
448
						args.add("%" + term + "%");
449
						args.add("%" + term + "%");
450
						types.add(StringType.INSTANCE);
451
						types.add(StringType.INSTANCE);
452
						break;
453
				}
454
			} else {
455
				whereClauses.add("(r.id like ? )");
456
				whereArgs.add("%" + term + "%");
457
				types.add(StringType.INSTANCE);
458

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

    
503
		}
504

    
505
		if (requestSortBy != null) {
506
			switch (requestSortBy) {
507
				case DATE:
508
					orderBy = " r.date ";
509
					break;
510
				case FUNDING_REQUESTED:
511
					orderBy = " r.fundingrequested ";
512
					break;
513
				case USER:
514
					if (joins.get("user") == null)
515
						joins.put("user", " left join \"user\" u on u.email=r.user ");
516

    
517
					orderBy = " u.firstname, u.initials, u.lastname ";
518
					break;
519
				case PUBLICATION:
520
					if (joins.get("publication") == null)
521
						joins.put("publication", " left join publication pub on r.publication=pub.id ");
522

    
523
					orderBy = " pub.title ";
524
					break;
525
				case RESEARCHER:
526
					if (joins.get("researcher") == null)
527
						joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
528

    
529
					orderBy = " res.firstname, res.initials, res.lastname ";
530
					break;
531
				case PROJECT:
532
					if (joins.get("project") == null)
533
						joins.put("project", " left join project proj on proj.id=r.project ");
534

    
535
					orderBy = " proj.acronym ";
536
					break;
537
				case JOURNAL:
538
					if (joins.get("journal") == null)
539
						joins.put("journal", " left join journal j on j.id=r.journal ");
540

    
541
					orderBy = " j.title ";
542
					break;
543
				case PUBLISHER:
544
					if (joins.get("publisher") == null)
545
						joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
546

    
547
					orderBy = " publ.name ";
548
					break;
549
				case STATUS:
550
				default:
551
					orderBy = " r.status ";
552
					break;
553
			}
554
		}
555

    
556
		//TODO fix bank fields and publisher_email
557
		//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 ");
558
		StringBuilder sb = new StringBuilder("select r.id as id, " +
559
				"r.\"user\" as \"user\", r.date as date, r.researcher as researcher, r.organization as organization, " +
560
				"r.project as project, r.publication as publication, r.journal as journal, r.publisher as publisher,  " +
561
				"r.budget as budget, r.invoice as invoice , r.apc as apc, r.discount as discount, " +
562
				"r.projectparticipation as projectparticipation, r.fundingrequested as fundingrequested, r.currency as currency, " +
563
				"r.apcPaid as apcPaid, r.transferCost as transferCost, r.otherCost as otherCost, r.datePaid as datePaid, " +
564
				"r.submissiondate as submissiondate, r.approvaldate as approvaldate, r.status as status ," +
565
				"r.bankAccount as bankAccount , r.bankTransferReceipt as bankTransferReceipt ," +
566
				"r.publisher_email as publisher_email from request r ");
567
		for (String join : joins.values())
568
			sb.append(" ").append(join).append(" ");
569

    
570

    
571
		sb.append(" where ");
572

    
573
		if (email != null) {
574
			sb.append("r.\"user\"=? ");
575

    
576
			args.add(email);
577
			types.add(StringType.INSTANCE);
578
		} else if (organizationIds != null) {
579
			sb.append("(");
580

    
581
			for (int i = 0; i < organizationIds.size(); i++) {
582
				if (i > 0)
583
					sb.append(" or ");
584

    
585
				sb.append(" r.organization=? ");
586

    
587
				args.add(organizationIds.get(i));
588
				types.add(StringType.INSTANCE);
589
			}
590

    
591
			sb.append(")");
592

    
593
		} else if (publisherId != null) {
594

    
595
			if (joins.get("journal") == null) {
596
				sb.delete(sb.lastIndexOf("where"), sb.length());
597
				sb.append(" left join journal j on j.id=r.journal ");
598
				sb.append(" where ");
599
			}
600

    
601
			sb.append("(r.publisher=? or j.publisher=?)");
602

    
603
			args.add(publisherId);
604
			types.add(StringType.INSTANCE);
605
			args.add(publisherId);
606
			types.add(StringType.INSTANCE);
607
		}
608

    
609
		if (statusFilterCodes != null) {
610
			StringBuilder ssb = new StringBuilder();
611

    
612
			for (Integer code:statusFilterCodes) {
613
				String clause;
614

    
615
				switch (code) {
616
					default:
617
						clause = " (r.status = " + code + ")";
618
						break;
619
				}
620

    
621
				ssb.append(ssb.length()==0?clause:" or " + clause);
622
			}
623

    
624
			if (sb.toString().trim().endsWith("where"))
625
				sb.append("(").append(ssb.toString()).append(")");
626
			else
627
				sb.append(" and ").append("(").append(ssb.toString()).append(")");
628
		}
629

    
630
		if (whereClauses.size() > 0) {
631
			if (!sb.toString().trim().endsWith("where"))
632
				sb.append(" and ");
633
			sb.append("(");
634

    
635
			for (String clause : whereClauses) {
636
				sb.append(clause);
637
				sb.append(" or ");
638
			}
639

    
640
			sb.delete(sb.lastIndexOf("or"), sb.length());
641
			sb.append(") ");
642

    
643
			args.addAll(whereArgs);
644
			types.addAll(whereTypes);
645
		}
646

    
647
		if (sb.toString().trim().endsWith("where"))
648
			sb.delete(sb.lastIndexOf("where"), sb.length());
649

    
650
		if (orderBy != null) {
651
			sb.append(" order by ").append(orderBy);
652

    
653
			if (order == RequestSortOrder.ASCENDING)
654
				sb.append(" asc");
655
			else
656
				sb.append(" desc");
657
		}
658

    
659
		return sb.toString();
660
	}
661

    
662
	private String applyPaging(String query, int from, int to) {
663
		StringBuilder sb = new StringBuilder(query);
664

    
665
		if (from > 0 || to > 0) {
666
			sb.append(" limit ").append(to - from + 1);
667
			sb.append(" offset ").append(from);
668
		}
669

    
670
		return sb.toString();
671
	}
672

    
673
	private Integer[] getStatusFilter(Request.RequestStatus[] statuses) {
674
		if (statuses == null)
675
			return null;
676
		else {
677
			Integer[] res = new Integer[statuses.length];
678

    
679
			for (int i = 0; i < statuses.length; i++)
680
				res[i] = statuses[i].getCode();
681

    
682
			return res;
683
		}
684
	}
685

    
686
	public List<Comment> getComments(String id) {
687
		return getRequest(id).getRequestComments();
688
	}
689

    
690
	public void uploadBankTransferReceipt(final String requestid, final String contentType, InputStream inputStream) {
691
		try {
692
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
693
			Request r = getRequest(requestid);
694

    
695
			IOUtils.copy(inputStream, baos);
696
			IOUtils.closeQuietly(baos);
697
			r.setBankTransferReceipt(new BankTransferReceipt(contentType,baos.toByteArray()));
698
			saveRequest(r);
699
		} catch (Exception e) {
700
			e.printStackTrace();
701
		}
702
	}
703

    
704
	public BankTransferReceipt downloadBankTransferReceipt(String requestId) {
705
		Request r = getRequest(requestId);
706
		return r.getBankTransferReceipt();
707
	}
708

    
709
	@SuppressWarnings("unchecked")
710
	public List<CommentTemplate> getCommentTemplates(Request.RequestStatus requestStatus) {
711
		Criteria cr = getSession().createCriteria(CommentTemplate.class);
712
		return cr.list();
713
	}
714

    
715
    public BigInteger getActiveNumber() {
716

    
717
		String NUMBERS_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
718
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", "
719
				+ Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")" ;
720

    
721
		Query q = getSession().createSQLQuery(NUMBERS_REQUESTS);
722
		return ((BigInteger) q.list().get(0));
723
	}
724

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

    
728
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS);
729
		return ((BigInteger) q.list().get(0));
730
	}
731

    
732
	public BigInteger getNumberOfProjects() {
733
		String NUMBERS_PROJECTS = "select count(distinct project) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
734
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode()
735
				+ ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")";
736
		Query q = getSession().createSQLQuery(NUMBERS_PROJECTS);
737
		return ((BigInteger) q.list().get(0));
738
	}
739

    
740
	public Float getTotalAmount() {
741
		String NUMBERS_TOTAL_AMOUNT = "select sum(apcPaid) from request r";
742
		Query q = getSession().createSQLQuery(NUMBERS_TOTAL_AMOUNT);
743
		Float result = (Float) q.list().get(0);
744
		if(result == null) return Float.valueOf(0);
745
		return result;
746
	}
747

    
748
	public Double getAverageAmount() {
749
		String NUMBERS_AVERAGE_AMOUNT = "select avg(apcPaid) from request r";
750
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_AMOUNT);
751
		Double result = (Double) q.list().get(0);
752
		if(result == null) return Double.valueOf(0);
753
		return result;
754
	}
755

    
756
	public Double getAverageAmountPerArticle(){
757
		String NUMBERS_AVERAGE_PER_ARTICLE = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='ARTICLE'";
758
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_ARTICLE);
759
		Double result = (Double) q.list().get(0);
760
		if(result == null) return Double.valueOf(0);
761
		return result;
762
	}
763

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

    
772
	public Double getAverageAmountPerBookChapter(){
773
		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'";
774
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_BOOK_CHAPTER);
775
		Double result = (Double) q.list().get(0);
776
		if(result == null) return Double.valueOf(0);
777
		return result;
778
	}
779

    
780
	public BigInteger getNumberOfPaidRequestsWithDOI() {
781
		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 " +
782
				"and r.status=" + Request.RequestStatus.ACCOUNTING_PAID.getCode();
783
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS_WITH_DOI);
784
		BigInteger result = (BigInteger) q.list().get(0);
785
		if(result == null) return BigInteger.valueOf(0);
786
		return result;
787
	}
788

    
789
	public BigInteger getNumberOfApprovedRequestsWithDOI() {
790
		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 (" +
791
				Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", "
792
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode()
793
				+ ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ")";
794

    
795
		Query q = getSession().createSQLQuery(NUMBERS_APPROVED_REQUESTS_WITH_DOI);
796
		BigInteger result = (BigInteger) q.list().get(0);
797
		if(result == null) return BigInteger.valueOf(0);
798
		return result;
799
	}
800

    
801
	public BigInteger getNumberOfPaidPublicationPerArticle(){
802
		String NUMBERS_PAID_ARTICLE_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
803
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='ARTICLE'" ;
804
		Query q = getSession().createSQLQuery(NUMBERS_PAID_ARTICLE_REQUESTS);
805
		BigInteger result = (BigInteger) q.list().get(0);
806
		if(result == null) return BigInteger.valueOf(0);
807
		return result;
808
	}
809

    
810
	public BigInteger getNumberOfPaidPublicationPerMonograph(){
811
		String NUMBERS_PAID_MONOGRAPH_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='MONOGRAPH'" ;
813
		Query q = getSession().createSQLQuery(NUMBERS_PAID_MONOGRAPH_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 getNumberOfPaidPublicationPerBookChapter(){
820
		String NUMBERS_PAID_BOOK_CHAPTER_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='BOOK_CHAPTER'" ;
822
		Query q = getSession().createSQLQuery(NUMBERS_PAID_BOOK_CHAPTER_REQUESTS);
823
		BigInteger result = (BigInteger) q.list().get(0);
824
		if(result == null) return BigInteger.valueOf(0);
825
		return result;
826
	}
827

    
828
	public Request getRequestFromCSV(User user, Project project, Publication publication, String acceptanceDate,
829
									 String identifierType, String identifierValue, String publicationLicense,
830
									 String apc, String apcCurrency, String discount) throws ParseException {
831

    
832
		Request request = new Request();
833
		request.setUser(user);
834
		request.setProject(project);
835

    
836
		publication.setAcceptancedate(new SimpleDateFormat("yyyy-MM-dd").parse(acceptanceDate));
837

    
838
		Identifier id = new Identifier();
839
		id.setType(identifierType);
840
		id.setValue(identifierValue);
841
		id.setId((BigInteger) getSession().createSQLQuery("select nextval('identifier_id_seq') as id").list().get(0));
842

    
843

    
844
		publication.getIdentifiers().add(id);
845
		publication.setLicense(publicationLicense);
846

    
847
		request.setApc(Float.parseFloat(apc));
848
		request.setCurrency(Currency.valueOf(apcCurrency));
849
		request.setDiscount(Float.parseFloat(discount));
850
		request.setPublication(publication);
851
		request.setStatus(Request.RequestStatus.LIBRARY_FUND_PAID);
852
		return request;
853
	}
854
}
(11-11/12)