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.Query;
14
import org.hibernate.criterion.Restrictions;
15
import org.hibernate.type.StringType;
16
import org.hibernate.type.Type;
17
import org.springframework.beans.factory.annotation.Autowired;
18
import org.springframework.stereotype.Repository;
19

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

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

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

    
43
	public void saveRequest(final Request request) {
44

    
45
		//Request r = getRequest(request.getId());
46

    
47
		System.out.println("Request on dao object -> " + request);
48

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

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

    
59
		/*if ( r == null){
60
			Date date = new Date();
61
			request.setDate(new Timestamp(date.getTime()));
62
		}*/
63
		getSession().saveOrUpdate(request);
64
	}
65

    
66

    
67
	public BigInteger getBankId() {
68
		return (BigInteger) getSession().createSQLQuery("select nextval('bank_id_seq') as id").list().get(0);
69
	}
70

    
71

    
72
	public List<RequestCoFunder> getCoFunders(final Request request) {
73
	    return request.getRequestCoFunders();
74
	}
75

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

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

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

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

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

    
117
		logger.debug("Comment : " + comment);
118

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

    
126
		List<Comment> cms = request.getRequestComments();
127
		cms.add(com);
128
		saveRequest(request);
129
	}
130

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

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

    
148
	}
149

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

    
159
		if (comment != null && !comment.isEmpty()) {
160
			saveComment(r, user, comment, template);
161
		}
162
	}
163

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

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

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

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

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

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

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

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

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

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

    
235
	public BigInteger getRequestId() {
236
		return (BigInteger) getSession().createSQLQuery("select nextval('request_id_seq') as id").list().get(0);
237
	}
238

    
239
	@SuppressWarnings("unchecked")
240
	public String getCSV(RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Integer[] statuses) throws IOException {
241
		List<Object> args = new ArrayList<Object>();
242
		List<Type> types = new ArrayList<>();
243
		String requestQuery = this.getQuery(null, null, null, requestSortBy, order, requestFilter, term, statuses, args, types);
244
		String query = "select r.id as rid, r.status, r.date, u.firstname, u.lastname, o.name as organization," +
245
				" c.name as country, p.id as pid, p.acronym, p.startdate, p.enddate, p.scientificarea, " +
246
				"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, " +
247
				" r.approvaldate as approvaldate, r.apc as apc,r.currency as currency,r.datepaid, r.apcpaid, r.transfercost, " +
248
				" r.othercost, comment.comment as comment from (" + requestQuery + ") r " +
249
				"left join \"user\" u on r.researcher = u.email " +
250
				"left join project p on r.project=p.id " +
251
				"left join publication pub on r.publication=pub.id " +
252
				"left join journal j on j.id=r.journal " +
253
				"left join publisher jp on j.publisher=jp.id " +
254
				"left join publisher mp on mp.id=r.publisher " +
255
				"left join organization o on o.id=r.organization " +
256
				"left join country c on c.id=o.country " +
257
				"left join (select rid , comments[1] as comment  " +
258
				"           from (select rid, array_agg(comments) as comments" +
259
				"                 from (select rc.request as rid, c.comment as comments " +
260
				"                       from comment c " +
261
				"                            join request_comment rc on rc.comment=c.id " +
262
				"                            join request r on r.id=rc.request " +
263
				"                            and r.status = 8  order by rid, c.date desc" +
264
				"                       ) foo " +
265
				"                       group by rid" +
266
				"                 ) bar order by rid \n" +
267
				"           ) as comment on r.id=comment.rid";
268

    
269

    
270

    
271
		List<String[]> requests = new ArrayList<>();
272
		Type[] t = new Type[types.size()];
273
		t = types.toArray(t);
274
		List<Object[]> resultSet = getSession().createSQLQuery(query)
275
				.setParameters(args.toArray(), t).list();
276

    
277
		for(Object rs[] : resultSet){
278

    
279
			String[] objs = new String[25];
280
			objs[0] = rs[0].toString();
281
			objs[1] = String.valueOf(Request.RequestStatus.forStatus(Integer.parseInt(rs[1].toString())));
282
			objs[2] = rs[2]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[2]):null;
283
			objs[3] = rs[3]!=null?rs[3].toString():null;
284
			objs[4] = rs[4]!=null?rs[4].toString():null;
285
			objs[5] = rs[5]!=null?rs[5].toString():null;
286
			objs[6] = rs[6]!=null?rs[6].toString():null;
287
			//project id
288
			objs[7] = rs[7]!=null?rs[7].toString():null;
289
			objs[8] = rs[8]!=null?rs[8].toString():null;
290
			objs[9] = rs[9]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[9]):null;
291
			objs[10] = rs[10]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[10]):null;
292
			objs[11] = rs[11]!=null?rs[11].toString():null;
293
			objs[12] = rs[12]!=null?rs[12].toString():null;
294
			objs[13] = rs[13]!=null?rs[13].toString():null;
295
			objs[14] = rs[14]!=null?rs[14].toString():null;
296
			objs[15] = rs[15]!=null?rs[15].toString():null;
297
			objs[16] = rs[16]!=null?rs[16].toString():null;
298
			objs[17] = rs[17]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[17]):null;
299
			objs[18] = rs[18]!=null?Float.toString(Float.parseFloat(rs[18].toString())):null;
300
			objs[19] = rs[19]!=null?rs[19].toString():null;
301
			objs[20] = rs[20]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[20]):null;
302
			objs[21] = rs[21]!=null?rs[21].toString() + "":null;
303
			objs[22] = rs[22]!=null?rs[22].toString() + "":null;
304
			objs[23] = rs[23]!=null?rs[23].toString() + "":null;
305
			objs[24] = rs[24]!=null?rs[24].toString():null;
306
			requests.add(objs);
307
		}
308

    
309
		StringWriter sw = new StringWriter();
310
		CSVWriter csvWriter = new CSVWriter(sw);
311

    
312
		csvWriter.writeNext(new String[]{"id", "Status", "Submission Date", "Firstname", "Lastname", "Organization",
313
				"Country", "Project id", "Acronym", "Start Date", "End Date", "Scientific Area", "Title", "Type",
314
				"Journal","Journal ISSN", "Publisher", "Date Approved", "APC requested", "Currency", "Date Paid", "APC paid",
315
				"Transfer Cost", "Other Expenses", "Rejection Reason"}, false);
316
		csvWriter.writeAll(requests, false);
317

    
318
		csvWriter.close();
319
		sw.close();
320

    
321
		return sw.toString();
322
	}
323

    
324
	@SuppressWarnings("unchecked")
325
	private RequestPage getRequestPage(String personId, List<String> organizationIds, String publisherId,
326
                                       RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter,
327
                                       String term, Integer[] statusFilterCodes, int from, int to) {
328
		RequestPage page = new RequestPage();
329
		List<Object> args = new ArrayList<Object>();
330
		List<Type> types = new ArrayList<>();
331
		String query = getQuery(personId, organizationIds, publisherId, requestSortBy, order,
332
				requestFilter, term, statusFilterCodes, args, types);
333

    
334
		Type[] t = new Type[types.size()];
335
		t = types.toArray(t);
336

    
337
		page.setRequests(getSession().createSQLQuery(applyPaging(query, from, to))
338
				.addEntity(Request.class)
339
				.setParameters(args.toArray(),t)
340
				.list());
341
		
342
		BigInteger bi = (BigInteger) getSession().createSQLQuery(getCountQuery(query))
343
				.setParameters(args.toArray(),t)
344
				.list().get(0);
345
		page.setTotal(bi.intValue());
346
		page.setFrom(from);
347
		page.setTo(to);
348

    
349
		return page;
350
	}
351

    
352
	private String getCountQuery(String query) {
353
		StringBuilder sb = new StringBuilder();
354

    
355
		sb.append("select count(*) from (").append(query).append(") foo");
356

    
357
		return sb.toString();
358
	}
359

    
360
	private String getQuery(String email, List<String> organizationIds, String publisherId, RequestSort requestSortBy, RequestSortOrder order,
361
							RequestFilter requestFilter, String term, Integer[] statusFilterCodes, List<Object> args, List<Type> types) {
362
		Map<String, String> joins = new HashMap<String, String>();
363
		List<String> whereClauses = new ArrayList<String>();
364
		List<Object> whereArgs = new ArrayList<Object>();
365
		List<Type> whereTypes = new ArrayList<>();
366

    
367
		String orderBy = null;
368

    
369
		if (term != null) {
370
			if (requestFilter != null) {
371
				switch (requestFilter) {
372
					case ID:
373
						whereClauses.add("(r.id like ? )");
374
						whereArgs.add("%" + term + "%");
375
						types.add(StringType.INSTANCE);
376
						break;
377
					case USER:
378
						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(?)) ");
379
						args.add("%" + term + "%");
380
						args.add("%" + term + "%");
381
						args.add("%" + term + "%");
382
						types.add(StringType.INSTANCE);
383
						types.add(StringType.INSTANCE);
384
						types.add(StringType.INSTANCE);
385
						break;
386
					case RESEARCHER:
387
						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(?)) ");
388
						args.add("%" + term + "%");
389
						args.add("%" + term + "%");
390
						args.add("%" + term + "%");
391
						types.add(StringType.INSTANCE);
392
						types.add(StringType.INSTANCE);
393
						types.add(StringType.INSTANCE);
394
						break;
395
					case PROJECT:
396
						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(?)) ");
397
						args.add("%" + term + "%");
398
						args.add("%" + term + "%");
399
						args.add("%" + term + "%");
400
						types.add(StringType.INSTANCE);
401
						types.add(StringType.INSTANCE);
402
						types.add(StringType.INSTANCE);
403
						break;
404
					case PUBLICATION:
405
						joins.put("publication", " join publication pub on pub.id=r.publication and (lower(pub.title) like lower(?)) ");
406
						args.add("%" + term + "%");
407
						types.add(StringType.INSTANCE);
408
						break;
409
					case JOURNAL:
410
						joins.put("journal", " join journal j on j.id=r.journal and (lower(j.title) like lower(?)) ");
411
						args.add("%" + term + "%");
412
						types.add(StringType.INSTANCE);
413
						break;
414
					case PUBLISHER:
415
						joins.put("publisher", " join publisher publ on publ.id=r.publisher and (lower(publ.name) like lower(?)) ");
416
						args.add("%" + term + "%");
417
						types.add(StringType.INSTANCE);
418
						break;
419
					case INVOICE:
420
						joins.put("invoice", "join invoice i on i.id=r.invoice and (lower(i.number) like lower(?) or lower(alternativeid) like lower(?))");
421
						args.add("%" + term + "%");
422
						args.add("%" + term + "%");
423
						types.add(StringType.INSTANCE);
424
						types.add(StringType.INSTANCE);
425
						break;
426
				}
427
			} else {
428
				whereClauses.add("(r.id like ? )");
429
				whereArgs.add("%" + term + "%");
430
				types.add(StringType.INSTANCE);
431

    
432
				joins.put("user", " left join \"user\" u on u.email=r.user ");
433
				whereClauses.add("(lower(u.firstname) like lower(?) or lower(u.initials) like lower(?) or lower(u.lastname) like lower(?))");
434
				whereArgs.add("%" + term + "%");
435
				whereArgs.add("%" + term + "%");
436
				whereArgs.add("%" + term + "%");
437
				whereTypes.add(StringType.INSTANCE);
438
				whereTypes.add(StringType.INSTANCE);
439
				whereTypes.add(StringType.INSTANCE);
440
				joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
441
				whereClauses.add("(lower(res.firstname) like lower(?) or lower(res.initials) like lower(?) or lower(res.lastname) like lower(?))");
442
				whereArgs.add("%" + term + "%");
443
				whereArgs.add("%" + term + "%");
444
				whereArgs.add("%" + term + "%");
445
				whereTypes.add(StringType.INSTANCE);
446
				whereTypes.add(StringType.INSTANCE);
447
				whereTypes.add(StringType.INSTANCE);
448
				joins.put("project", " left join project proj on proj.id=r.project ");
449
				whereClauses.add("(lower(proj.acronym) like lower(?) or lower(proj.title) like lower(?) or lower(proj.grant) like lower(?))");
450
				whereArgs.add("%" + term + "%");
451
				whereArgs.add("%" + term + "%");
452
				whereArgs.add("%" + term + "%");
453
				whereTypes.add(StringType.INSTANCE);
454
				whereTypes.add(StringType.INSTANCE);
455
				whereTypes.add(StringType.INSTANCE);
456
				joins.put("publication", " left join publication pub on pub.id=r.publication ");
457
				whereClauses.add("(lower(pub.title) like lower(?))");
458
				whereArgs.add("%" + term + "%");
459
				whereTypes.add(StringType.INSTANCE);
460
				joins.put("journal", " left join journal j on j.id=r.journal ");
461
				whereClauses.add("(lower(j.title) like lower(?))");
462
				whereArgs.add("%" + term + "%");
463
				whereTypes.add(StringType.INSTANCE);
464
				joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
465
				whereClauses.add("(lower(publ.name) like lower(?))");
466
				whereArgs.add("%" + term + "%");
467
				whereTypes.add(StringType.INSTANCE);
468
				joins.put("invoice", " left join invoice i on i.id=r.invoice ");
469
				whereClauses.add("(lower(i.number) like lower(?) or lower(alternativeid) like lower(?))");
470
				whereArgs.add("%" + term + "%");
471
				whereArgs.add("%" + term + "%");
472
				whereTypes.add(StringType.INSTANCE);
473
				whereTypes.add(StringType.INSTANCE);
474
			}
475

    
476
		}
477

    
478
		if (requestSortBy != null) {
479
			switch (requestSortBy) {
480
				case DATE:
481
					orderBy = " r.date ";
482
					break;
483
				case FUNDING_REQUESTED:
484
					orderBy = " r.fundingrequested ";
485
					break;
486
				case USER:
487
					if (joins.get("user") == null)
488
						joins.put("user", " left join \"user\" u on u.email=r.user ");
489

    
490
					orderBy = " u.firstname, u.initials, u.lastname ";
491
					break;
492
				case PUBLICATION:
493
					if (joins.get("publication") == null)
494
						joins.put("publication", " left join publication pub on r.publication=pub.id ");
495

    
496
					orderBy = " pub.title ";
497
					break;
498
				case RESEARCHER:
499
					if (joins.get("researcher") == null)
500
						joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
501

    
502
					orderBy = " res.firstname, res.initials, res.lastname ";
503
					break;
504
				case PROJECT:
505
					if (joins.get("project") == null)
506
						joins.put("project", " left join project proj on proj.id=r.project ");
507

    
508
					orderBy = " proj.acronym ";
509
					break;
510
				case JOURNAL:
511
					if (joins.get("journal") == null)
512
						joins.put("journal", " left join journal j on j.id=r.journal ");
513

    
514
					orderBy = " j.title ";
515
					break;
516
				case PUBLISHER:
517
					if (joins.get("publisher") == null)
518
						joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
519

    
520
					orderBy = " publ.name ";
521
					break;
522
				case STATUS:
523
				default:
524
					orderBy = " r.status ";
525
					break;
526
			}
527
		}
528

    
529
		//TODO fix bank fields and publisher_email
530
		//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 ");
531
		StringBuilder sb = new StringBuilder("select r.id as id, " +
532
				"r.\"user\" as \"user\", r.date as date, r.researcher as researcher, r.organization as organization, " +
533
				"r.project as project, r.publication as publication, r.journal as journal, r.publisher as publisher,  " +
534
				"r.budget as budget, r.invoice as invoice , r.apc as apc, r.discount as discount, " +
535
				"r.projectparticipation as projectparticipation, r.fundingrequested as fundingrequested, r.currency as currency, " +
536
				"r.apcPaid as apcPaid, r.transferCost as transferCost, r.otherCost as otherCost, r.datePaid as datePaid, " +
537
				"r.submissiondate as submissiondate, r.approvaldate as approvaldate, r.status as status ," +
538
				"r.bankAccount as bankAccount , r.bankTransferReceipt as bankTransferReceipt ," +
539
				"r.publisher_email as publisher_email from request r ");
540
		for (String join : joins.values())
541
			sb.append(" ").append(join).append(" ");
542

    
543

    
544
		sb.append(" where ");
545

    
546
		if (email != null) {
547
			sb.append("r.\"user\"=? ");
548

    
549
			args.add(email);
550
			types.add(StringType.INSTANCE);
551
		} else if (organizationIds != null) {
552
			sb.append("(");
553

    
554
			for (int i = 0; i < organizationIds.size(); i++) {
555
				if (i > 0)
556
					sb.append(" or ");
557

    
558
				sb.append(" r.organization=? ");
559

    
560
				args.add(organizationIds.get(i));
561
				types.add(StringType.INSTANCE);
562
			}
563

    
564
			sb.append(")");
565

    
566
		} else if (publisherId != null) {
567

    
568
			if (joins.get("journal") == null) {
569
				sb.delete(sb.lastIndexOf("where"), sb.length());
570
				sb.append(" left join journal j on j.id=r.journal ");
571
				sb.append(" where ");
572
			}
573

    
574
			sb.append("(r.publisher=? or j.publisher=?)");
575

    
576
			args.add(publisherId);
577
			types.add(StringType.INSTANCE);
578
			args.add(publisherId);
579
			types.add(StringType.INSTANCE);
580
		}
581

    
582
		if (statusFilterCodes != null) {
583
			StringBuilder ssb = new StringBuilder();
584

    
585
			for (Integer code:statusFilterCodes) {
586
				String clause;
587

    
588
				switch (code) {
589
					default:
590
						clause = " (r.status = " + code + ")";
591
						break;
592
				}
593

    
594
				ssb.append(ssb.length()==0?clause:" or " + clause);
595
			}
596

    
597
			if (sb.toString().trim().endsWith("where"))
598
				sb.append("(").append(ssb.toString()).append(")");
599
			else
600
				sb.append(" and ").append("(").append(ssb.toString()).append(")");
601
		}
602

    
603
		if (whereClauses.size() > 0) {
604
			if (!sb.toString().trim().endsWith("where"))
605
				sb.append(" and ");
606
			sb.append("(");
607

    
608
			for (String clause : whereClauses) {
609
				sb.append(clause);
610
				sb.append(" or ");
611
			}
612

    
613
			sb.delete(sb.lastIndexOf("or"), sb.length());
614
			sb.append(") ");
615

    
616
			args.addAll(whereArgs);
617
			types.addAll(whereTypes);
618
		}
619

    
620
		if (sb.toString().trim().endsWith("where"))
621
			sb.delete(sb.lastIndexOf("where"), sb.length());
622

    
623
		if (orderBy != null) {
624
			sb.append(" order by ").append(orderBy);
625

    
626
			if (order == RequestSortOrder.ASCENDING)
627
				sb.append(" asc");
628
			else
629
				sb.append(" desc");
630
		}
631

    
632
		return sb.toString();
633
	}
634

    
635
	private String applyPaging(String query, int from, int to) {
636
		StringBuilder sb = new StringBuilder(query);
637

    
638
		if (from > 0 || to > 0) {
639
			sb.append(" limit ").append(to - from + 1);
640
			sb.append(" offset ").append(from);
641
		}
642

    
643
		return sb.toString();
644
	}
645

    
646
	private Integer[] getStatusFilter(Request.RequestStatus[] statuses) {
647
		if (statuses == null)
648
			return null;
649
		else {
650
			Integer[] res = new Integer[statuses.length];
651

    
652
			for (int i = 0; i < statuses.length; i++)
653
				res[i] = statuses[i].getCode();
654

    
655
			return res;
656
		}
657
	}
658

    
659
	public List<Comment> getComments(String id) {
660
		return getRequest(id).getRequestComments();
661
	}
662

    
663
	public void uploadBankTransferReceipt(final String requestid, final String contentType, InputStream inputStream) {
664
		try {
665
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
666
			Request r = getRequest(requestid);
667

    
668
			IOUtils.copy(inputStream, baos);
669
			IOUtils.closeQuietly(baos);
670
			r.setBankTransferReceipt(new BankTransferReceipt(contentType,baos.toByteArray()));
671
			saveRequest(r);
672
		} catch (Exception e) {
673
			e.printStackTrace();
674
		}
675
	}
676

    
677
	public BankTransferReceipt downloadBankTransferReceipt(String requestId) {
678
		Request r = getRequest(requestId);
679
		return r.getBankTransferReceipt();
680
	}
681

    
682
	@SuppressWarnings("unchecked")
683
	public List<CommentTemplate> getCommentTemplates(Request.RequestStatus requestStatus) {
684
		Criteria cr = getSession().createCriteria(CommentTemplate.class);
685
		return cr.list();
686
	}
687

    
688
    public BigInteger getActiveNumber() {
689

    
690
		String NUMBERS_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
691
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", "
692
				+ Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")" ;
693

    
694
		Query q = getSession().createSQLQuery(NUMBERS_REQUESTS);
695
		return ((BigInteger) q.list().get(0));
696
	}
697

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

    
701
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS);
702
		return ((BigInteger) q.list().get(0));
703
	}
704

    
705
	public BigInteger getNumberOfProjects() {
706
		String NUMBERS_PROJECTS = "select count(distinct project) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
707
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode()
708
				+ ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")";
709
		Query q = getSession().createSQLQuery(NUMBERS_PROJECTS);
710
		return ((BigInteger) q.list().get(0));
711
	}
712

    
713
	public Float getTotalAmount() {
714
		String NUMBERS_TOTAL_AMOUNT = "select sum(apcPaid) from request r";
715
		Query q = getSession().createSQLQuery(NUMBERS_TOTAL_AMOUNT);
716
		Float result = (Float) q.list().get(0);
717
		if(result == null) return Float.valueOf(0);
718
		return result;
719
	}
720

    
721
	public Double getAverageAmount() {
722
		String NUMBERS_AVERAGE_AMOUNT = "select avg(apcPaid) from request r";
723
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_AMOUNT);
724
		Double result = (Double) q.list().get(0);
725
		if(result == null) return Double.valueOf(0);
726
		return result;
727
	}
728

    
729
	public Double getAverageAmountPerArticle(){
730
		String NUMBERS_AVERAGE_PER_ARTICLE = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='ARTICLE'";
731
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_ARTICLE);
732
		Double result = (Double) q.list().get(0);
733
		if(result == null) return Double.valueOf(0);
734
		return result;
735
	}
736

    
737
	public Double getAverageAmountPerMonograph(){
738
		String NUMBERS_AVERAGE_PER_MONOGRAPH = "select avg(apcPaid) from request r join publication p on r.publication=p.id where p.type='MONOGRAPH'";
739
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_MONOGRAPH);
740
		Double result = (Double) q.list().get(0);
741
		if(result == null) return Double.valueOf(0);
742
		return result;
743
	}
744

    
745
	public Double getAverageAmountPerBookChapter(){
746
		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'";
747
		Query q = getSession().createSQLQuery(NUMBERS_AVERAGE_PER_BOOK_CHAPTER);
748
		Double result = (Double) q.list().get(0);
749
		if(result == null) return Double.valueOf(0);
750
		return result;
751
	}
752

    
753
	public BigInteger getNumberOfPaidRequestsWithDOI() {
754
		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 " +
755
				"and r.status=" + Request.RequestStatus.ACCOUNTING_PAID.getCode();
756
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS_WITH_DOI);
757
		BigInteger result = (BigInteger) q.list().get(0);
758
		if(result == null) return BigInteger.valueOf(0);
759
		return result;
760
	}
761

    
762
	public BigInteger getNumberOfApprovedRequestsWithDOI() {
763
		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 (" +
764
				Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", "
765
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode()
766
				+ ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ")";
767

    
768
		Query q = getSession().createSQLQuery(NUMBERS_APPROVED_REQUESTS_WITH_DOI);
769
		BigInteger result = (BigInteger) q.list().get(0);
770
		if(result == null) return BigInteger.valueOf(0);
771
		return result;
772
	}
773

    
774
	public BigInteger getNumberOfPaidPublicationPerArticle(){
775
		String NUMBERS_PAID_ARTICLE_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
776
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='ARTICLE'" ;
777
		Query q = getSession().createSQLQuery(NUMBERS_PAID_ARTICLE_REQUESTS);
778
		BigInteger result = (BigInteger) q.list().get(0);
779
		if(result == null) return BigInteger.valueOf(0);
780
		return result;
781
	}
782

    
783
	public BigInteger getNumberOfPaidPublicationPerMonograph(){
784
		String NUMBERS_PAID_MONOGRAPH_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
785
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='MONOGRAPH'" ;
786
		Query q = getSession().createSQLQuery(NUMBERS_PAID_MONOGRAPH_REQUESTS);
787
		BigInteger result = (BigInteger) q.list().get(0);
788
		if(result == null) return BigInteger.valueOf(0);
789
		return result;
790
	}
791

    
792
	public BigInteger getNumberOfPaidPublicationPerBookChapter(){
793
		String NUMBERS_PAID_BOOK_CHAPTER_REQUESTS = "select count(*) from request r join publication p on r.publication=p.id where r.status in ("
794
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ") and p.type='BOOK_CHAPTER'" ;
795
		Query q = getSession().createSQLQuery(NUMBERS_PAID_BOOK_CHAPTER_REQUESTS);
796
		BigInteger result = (BigInteger) q.list().get(0);
797
		if(result == null) return BigInteger.valueOf(0);
798
		return result;
799
	}
800

    
801
	public Request getRequestFromCSV(User user, Project project, Publication publication, String acceptanceDate,
802
									 String identifierType, String identifierValue, String publicationLicense,
803
									 String apc, String apcCurrency, String discount) throws ParseException {
804

    
805
		Request request = new Request();
806
		request.setUser(user);
807
		request.setProject(project);
808

    
809
		publication.setAcceptancedate(new SimpleDateFormat("yyyy-MM-dd").parse(acceptanceDate));
810

    
811
		Identifier id = new Identifier();
812
		id.setType(identifierType);
813
		id.setValue(identifierValue);
814
		id.setId((BigInteger) getSession().createSQLQuery("select nextval('identifier_id_seq') as id").list().get(0));
815

    
816

    
817
		publication.getIdentifiers().add(id);
818
		publication.setLicense(publicationLicense);
819

    
820
		request.setApc(Float.parseFloat(apc));
821
		request.setCurrency(Currency.valueOf(apcCurrency));
822
		request.setDiscount(Float.parseFloat(discount));
823
		request.setPublication(publication);
824
		request.setStatus(Request.RequestStatus.LIBRARY_FUND_PAID);
825
		return request;
826
	}
827
}
(11-11/12)