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
		Request r = getRequest(request.getId());
45

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

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

    
56
		if ( r == null){
57
			Date date = new Date();
58
			request.setDate(new Timestamp(date.getTime()));
59
		}
60
		getSession().saveOrUpdate(request);
61
	}
62

    
63

    
64
	public BigInteger getBankId() {
65
		return (BigInteger) getSession().createSQLQuery("select nextval('bank_id_seq') as id").list().get(0);
66
	}
67

    
68

    
69
	public List<RequestCoFunder> getCoFunders(final Request request) {
70
	    return request.getRequestCoFunders();
71
	}
72

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

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

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

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

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

    
114
		logger.debug("Comment : " + comment);
115

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

    
123
		List<Comment> cms = request.getRequestComments();
124
		cms.add(com);
125
		saveRequest(request);
126
	}
127

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

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

    
145
	}
146

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

    
156
		if (comment != null && !comment.isEmpty()) {
157
			saveComment(r, user, comment, template);
158
		}
159
	}
160

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

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

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

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

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

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

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

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

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

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

    
232
	public BigInteger getRequestId() {
233
		return (BigInteger) getSession().createSQLQuery("select nextval('request_id_seq') as id").list().get(0);
234
	}
235

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

    
266

    
267

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

    
274
		for(Object rs[] : resultSet){
275

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

    
305
		StringWriter sw = new StringWriter();
306
		CSVWriter csvWriter = new CSVWriter(sw);
307

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

    
314
		csvWriter.close();
315
		sw.close();
316

    
317
		return sw.toString();
318
	}
319

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

    
330
		Type[] t = new Type[types.size()];
331
		t = types.toArray(t);
332

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

    
345
		return page;
346
	}
347

    
348
	private String getCountQuery(String query) {
349
		StringBuilder sb = new StringBuilder();
350

    
351
		sb.append("select count(*) from (").append(query).append(") foo");
352

    
353
		return sb.toString();
354
	}
355

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

    
363
		String orderBy = null;
364

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

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

    
472
		}
473

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

    
486
					orderBy = " u.firstname, u.initials, u.lastname ";
487
					break;
488
				case PUBLICATION:
489
					if (joins.get("publication") == null)
490
						joins.put("publication", " left join publication pub on r.publication=pub.id ");
491

    
492
					orderBy = " pub.title ";
493
					break;
494
				case RESEARCHER:
495
					if (joins.get("researcher") == null)
496
						joins.put("researcher", " left join \"user\" res on res.email=r.researcher ");
497

    
498
					orderBy = " res.firstname, res.initials, res.lastname ";
499
					break;
500
				case PROJECT:
501
					if (joins.get("project") == null)
502
						joins.put("project", " left join project proj on proj.id=r.project ");
503

    
504
					orderBy = " proj.acronym ";
505
					break;
506
				case JOURNAL:
507
					if (joins.get("journal") == null)
508
						joins.put("journal", " left join journal j on j.id=r.journal ");
509

    
510
					orderBy = " j.title ";
511
					break;
512
				case PUBLISHER:
513
					if (joins.get("publisher") == null)
514
						joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
515

    
516
					orderBy = " publ.name ";
517
					break;
518
				case STATUS:
519
				default:
520
					orderBy = " r.status ";
521
					break;
522
			}
523
		}
524

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

    
539

    
540
		sb.append(" where ");
541

    
542
		if (email != null) {
543
			sb.append("r.\"user\"=? ");
544

    
545
			args.add(email);
546
			types.add(StringType.INSTANCE);
547
		} else if (organizationIds != null) {
548
			sb.append("(");
549

    
550
			for (int i = 0; i < organizationIds.size(); i++) {
551
				if (i > 0)
552
					sb.append(" or ");
553

    
554
				sb.append(" r.organization=? ");
555

    
556
				args.add(organizationIds.get(i));
557
				types.add(StringType.INSTANCE);
558
			}
559

    
560
			sb.append(")");
561

    
562
		} else if (publisherId != null) {
563

    
564
			if (joins.get("journal") == null) {
565
				sb.delete(sb.lastIndexOf("where"), sb.length());
566
				sb.append(" left join journal j on j.id=r.journal ");
567
				sb.append(" where ");
568
			}
569

    
570
			sb.append("(r.publisher=? or j.publisher=?)");
571

    
572
			args.add(publisherId);
573
			types.add(StringType.INSTANCE);
574
			args.add(publisherId);
575
			types.add(StringType.INSTANCE);
576
		}
577

    
578
		if (statusFilterCodes != null) {
579
			StringBuilder ssb = new StringBuilder();
580

    
581
			for (Integer code:statusFilterCodes) {
582
				String clause;
583

    
584
				switch (code) {
585
					default:
586
						clause = " (r.status = " + code + ")";
587
						break;
588
				}
589

    
590
				ssb.append(ssb.length()==0?clause:" or " + clause);
591
			}
592

    
593
			if (sb.toString().trim().endsWith("where"))
594
				sb.append("(").append(ssb.toString()).append(")");
595
			else
596
				sb.append(" and ").append("(").append(ssb.toString()).append(")");
597
		}
598

    
599
		if (whereClauses.size() > 0) {
600
			if (!sb.toString().trim().endsWith("where"))
601
				sb.append(" and ");
602
			sb.append("(");
603

    
604
			for (String clause : whereClauses) {
605
				sb.append(clause);
606
				sb.append(" or ");
607
			}
608

    
609
			sb.delete(sb.lastIndexOf("or"), sb.length());
610
			sb.append(") ");
611

    
612
			args.addAll(whereArgs);
613
			types.addAll(whereTypes);
614
		}
615

    
616
		if (sb.toString().trim().endsWith("where"))
617
			sb.delete(sb.lastIndexOf("where"), sb.length());
618

    
619
		if (orderBy != null) {
620
			sb.append(" order by ").append(orderBy);
621

    
622
			if (order == RequestSortOrder.ASCENDING)
623
				sb.append(" asc");
624
			else
625
				sb.append(" desc");
626
		}
627

    
628
		return sb.toString();
629
	}
630

    
631
	private String applyPaging(String query, int from, int to) {
632
		StringBuilder sb = new StringBuilder(query);
633

    
634
		if (from > 0 || to > 0) {
635
			sb.append(" limit ").append(to - from + 1);
636
			sb.append(" offset ").append(from);
637
		}
638

    
639
		return sb.toString();
640
	}
641

    
642
	private Integer[] getStatusFilter(Request.RequestStatus[] statuses) {
643
		if (statuses == null)
644
			return null;
645
		else {
646
			Integer[] res = new Integer[statuses.length];
647

    
648
			for (int i = 0; i < statuses.length; i++)
649
				res[i] = statuses[i].getCode();
650

    
651
			return res;
652
		}
653
	}
654

    
655
	public List<Comment> getComments(String id) {
656
		return getRequest(id).getRequestComments();
657
	}
658

    
659
	public void uploadBankTransferReceipt(final String requestid, final String contentType, InputStream inputStream) {
660
		try {
661
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
662
			Request r = getRequest(requestid);
663

    
664
			IOUtils.copy(inputStream, baos);
665
			IOUtils.closeQuietly(baos);
666
			r.setBankTransferReceipt(new BankTransferReceipt(contentType,baos.toByteArray()));
667
			saveRequest(r);
668
		} catch (Exception e) {
669
			e.printStackTrace();
670
		}
671
	}
672

    
673
	public BankTransferReceipt downloadBankTransferReceipt(String requestId) {
674
		Request r = getRequest(requestId);
675
		return r.getBankTransferReceipt();
676
	}
677

    
678
	@SuppressWarnings("unchecked")
679
	public List<CommentTemplate> getCommentTemplates(Request.RequestStatus requestStatus) {
680
		Criteria cr = getSession().createCriteria(CommentTemplate.class);
681
		return cr.list();
682
	}
683

    
684
    public BigInteger getActiveNumber() {
685

    
686
		String NUMBERS_REQUESTS = "select count(*) from request r where r.status in (" + Request.RequestStatus.APPROVED.getCode() + ", "
687
				+ Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", "
688
				+ Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ")" ;
689

    
690
		Query q = getSession().createSQLQuery(NUMBERS_REQUESTS);
691
		return ((BigInteger) q.list().get(0));
692
	}
693

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

    
697
		Query q = getSession().createSQLQuery(NUMBERS_PAID_REQUESTS);
698
		return ((BigInteger) q.list().get(0));
699
	}
700

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

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

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

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

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

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

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

    
758
	public BigInteger getNumberOfApprovedRequestsWithDOI() {
759
		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 (" +
760
				Request.RequestStatus.APPROVED.getCode() + ", " + Request.RequestStatus.ACCOUNTING_PROCESSING.getCode() + ", "
761
				+ Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode()
762
				+ ", " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + ", " + Request.RequestStatus.CONDITIONALLY_APPROVED.getCode() + ")";
763

    
764
		Query q = getSession().createSQLQuery(NUMBERS_APPROVED_REQUESTS_WITH_DOI);
765
		BigInteger result = (BigInteger) q.list().get(0);
766
		if(result == null) return BigInteger.valueOf(0);
767
		return result;
768
	}
769

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

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

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

    
797
	public Request getRequestFromCSV(User user, Project project, Publication publication, String acceptanceDate,
798
									 String identifierType, String identifierValue, String publicationLicense,
799
									 String apc, String apcCurrency, String discount) throws ParseException {
800

    
801
		Request request = new Request();
802
		request.setUser(user);
803
		request.setProject(project);
804

    
805
		publication.setAcceptancedate(new SimpleDateFormat("yyyy-MM-dd").parse(acceptanceDate));
806

    
807
		Identifier id = new Identifier();
808
		id.setType(identifierType);
809
		id.setValue(identifierValue);
810
		id.setId((BigInteger) getSession().createSQLQuery("select nextval('identifier_id_seq') as id").list().get(0));
811

    
812

    
813
		publication.getIdentifiers().add(id);
814
		publication.setLicense(publicationLicense);
815

    
816
		request.setApc(Float.parseFloat(apc));
817
		request.setCurrency(Currency.valueOf(apcCurrency));
818
		request.setDiscount(Float.parseFloat(discount));
819
		request.setPublication(publication);
820
		request.setStatus(Request.RequestStatus.LIBRARY_FUND_PAID);
821
		return request;
822
	}
823
}
(11-11/12)