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,j.issn as issn,(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[25];
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?rs[16].toString():null;
295
			objs[17] = rs[17]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[17]):null;
296
			objs[18] = rs[18]!=null?Float.toString(Float.parseFloat(rs[18].toString())):null;
297
			objs[19] = rs[19]!=null?rs[19].toString():null;
298
			objs[20] = rs[20]!=null?new SimpleDateFormat("yyyy/MM/dd").format(rs[20]):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
			objs[24] = rs[24]!=null?rs[24].toString():null;
303
			requests.add(objs);
304
		}
305

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

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

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

    
318
		return sw.toString();
319
	}
320

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

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

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

    
346
		return page;
347
	}
348

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

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

    
354
		return sb.toString();
355
	}
356

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

    
364
		String orderBy = null;
365

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

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

    
473
		}
474

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

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

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

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

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

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

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

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

    
540

    
541
		sb.append(" where ");
542

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

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

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

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

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

    
561
			sb.append(")");
562

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
629
		return sb.toString();
630
	}
631

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

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

    
640
		return sb.toString();
641
	}
642

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

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

    
652
			return res;
653
		}
654
	}
655

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

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

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

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

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

    
685
    public BigInteger getActiveNumber() {
686

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
813

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

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