Project

General

Profile

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

    
3
import eu.dnetlib.goldoa.domain.BankAccount;
4
import eu.dnetlib.goldoa.domain.BankTransferReceipt;
5
import eu.dnetlib.goldoa.domain.Comment;
6
import eu.dnetlib.goldoa.domain.Currency;
7
import eu.dnetlib.goldoa.domain.Funder;
8
import eu.dnetlib.goldoa.domain.Person;
9
import eu.dnetlib.goldoa.domain.Request;
10
import eu.dnetlib.goldoa.domain.RequestCoFunder;
11
import eu.dnetlib.goldoa.domain.RequestFilter;
12
import eu.dnetlib.goldoa.domain.RequestSort;
13
import eu.dnetlib.goldoa.domain.RequestSortOrder;
14
import org.apache.commons.codec.digest.DigestUtils;
15
import org.apache.commons.io.IOUtils;
16
import org.apache.commons.lang3.ArrayUtils;
17
import org.springframework.beans.factory.annotation.Autowired;
18
import org.springframework.dao.EmptyResultDataAccessException;
19
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
20
import org.springframework.jdbc.core.JdbcTemplate;
21
import org.springframework.jdbc.core.PreparedStatementSetter;
22
import org.springframework.jdbc.core.RowMapper;
23

    
24
import javax.sql.DataSource;
25
import java.io.ByteArrayOutputStream;
26
import java.io.InputStream;
27
import java.sql.PreparedStatement;
28
import java.sql.ResultSet;
29
import java.sql.SQLException;
30
import java.sql.Types;
31
import java.util.ArrayList;
32
import java.util.Date;
33
import java.util.HashMap;
34
import java.util.List;
35
import java.util.Map;
36

    
37
/**
38
 * Created by antleb on 3/30/15.
39
 */
40
public class RequestDAO {
41

    
42
	@Autowired
43
	private DataSource dataSource;
44

    
45
	private final static String GET_FOR_PROJECT = "select id, \"user\", date, researcher, organization, project, publication, journal, publisher, publisher_email, budget, invoice, apc, discount, projectparticipation, fundingrequested, currency, status, bank_name, bank_address, bank_code, bank_holder, bank_iban, apc_paid, transfer_cost, other_cost, date_paid from request where project=?";
46

    
47
	private final static String GET_BY_ID = "select id, \"user\", date, researcher, organization, project, publication, journal, publisher_email, publisher, budget, invoice, apc, discount, projectparticipation, fundingrequested, currency, status, bank_name, bank_address, bank_code, bank_holder, bank_iban, apc_paid, transfer_cost, other_cost, date_paid from request where id=?";
48

    
49
	private final static String UPDATE_REQUEST = "update request set \"user\"=?, date=?, researcher=?, organization=?, project=?, publication=?, journal=?, publisher=?, publisher_email=?, budget=?, invoice = ?, apc=?, discount=?, projectparticipation=?, fundingrequested=?, currency=?, status=?, bank_name=?, bank_address=?, bank_code=?, bank_holder=?, bank_iban=?, apc_paid=?, transfer_cost=?, other_cost=?, date_paid=? where id = ?";
50

    
51
	private final static String INSERT_REQUEST = "insert into request (\"user\", date, researcher, organization, project, publication, journal, publisher, publisher_email, budget, invoice, apc, discount, projectparticipation, fundingrequested, currency, status, bank_name, bank_address, bank_code, bank_holder, bank_iban, apc_paid, transfer_cost, other_cost, date_paid, id) values (?, ?, ?, ?, ?, ? ,? ,? ,? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
52

    
53
	private final static String APPROVE_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.REJECTED.getCode() | Request.RequestStatus.INITIALLY_APPROVED.getCode()) + ") | " + Request.RequestStatus.APPROVED.getCode() + " where id=?";
54

    
55
	private final static String INITIALLY_APPROVE_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.REJECTED.getCode() | Request.RequestStatus.APPROVED.getCode()) + ") | " + Request.RequestStatus.INITIALLY_APPROVED.getCode() + " where id=?";
56

    
57
	private final static String REJECT_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.APPROVED.getCode() | Request.RequestStatus.INITIALLY_APPROVED.getCode()) + ") | " + Request.RequestStatus.REJECTED.getCode() + " where id=?";
58

    
59
	private final static String PAID_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() | Request.RequestStatus.ACCOUNTING_DENIED.getCode()) + ") | " + Request.RequestStatus.ACCOUNTING_PAID.getCode() + ", apc_paid=?, transfer_cost=?, other_cost=?, date_paid=? where id=?";
60

    
61
	private final static String ONHOLD_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.ACCOUNTING_PAID.getCode() | Request.RequestStatus.ACCOUNTING_DENIED.getCode()) + ") | " + Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() + " where id=?";
62

    
63
	private final static String DENIED_REQUEST = "update request set status = (status & ~" + (Request.RequestStatus.ACCOUNTING_ON_HOLD.getCode() | Request.RequestStatus.ACCOUNTING_PAID.getCode()) + ") | " + Request.RequestStatus.ACCOUNTING_DENIED.getCode() + " where id=?";
64

    
65
	private final static String INVOICE_UPLOADED = "update request set invoice=?, status = status | " + Request.RequestStatus.INVOICE_UPLOADED.getCode() + " where id=?";
66

    
67
	private RowMapper<Request> requestRowMapper = new RowMapper<Request>() {
68
		@Override
69
		public Request mapRow(ResultSet rs, int rowNum) throws SQLException {
70
			BankAccount bankAccount = new BankAccount(rs.getString("bank_name"), rs.getString("bank_address"), rs.getString("bank_code"), rs.getString("bank_holder"), rs.getString("bank_iban"));
71

    
72
			Request request = new Request(
73
					rs.getString("id"), rs.getString("user"), rs.getTimestamp("date"), rs.getString("researcher"), rs.getString("organization"),
74
					rs.getString("project"), rs.getString("publication"), rs.getString("journal"), rs.getString("publisher"), rs.getString("publisher_email"),
75
					rs.getString("budget"), rs.getString("invoice"), rs.getFloat("apc"), rs.getFloat("discount"), rs.getFloat("projectparticipation"),
76
					rs.getFloat("fundingrequested"), null, bankAccount, new ArrayList<RequestCoFunder>(), rs.getFloat("apc_paid"), rs.getFloat("transfer_cost"), rs.getFloat("other_cost"), rs.getTimestamp("date_paid"), rs.getInt("status"));
77

    
78
			String currency = rs.getString("currency");
79
			if (rs.wasNull())
80
				request.setCurrency(null);
81
			else
82
				request.setCurrency(Currency.valueOf(currency));
83

    
84
			rs.getFloat("apc");
85
			if (rs.wasNull())
86
				request.setApc(null);
87
			rs.getFloat("discount");
88
			if (rs.wasNull())
89
				request.setDiscount(null);
90
			rs.getFloat("projectparticipation");
91
			if (rs.wasNull())
92
				request.setProjectParticipation(null);
93
			rs.getFloat("fundingrequested");
94
			if (rs.wasNull())
95
				request.setFundingRequested(null);
96
			rs.getFloat("apc_paid");
97
			if (rs.wasNull())
98
				request.setApc_paid(null);
99
			rs.getFloat("transfer_cost");
100
			if (rs.wasNull())
101
				request.setTransfer_cost(null);
102
			rs.getFloat("other_cost");
103
			if (rs.wasNull())
104
				request.setOther_cost(null);
105

    
106
			return request;
107
		}
108
	};
109

    
110

    
111
	public void saveRequest(final Request request) {
112
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
113
		Object[] args;
114
		int[] types = new int[]{Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
115
				Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.REAL, Types.REAL, Types.REAL,
116
				Types.REAL, Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
117
				Types.VARCHAR, Types.REAL, Types.REAL, Types.REAL, Types.TIMESTAMP, Types.VARCHAR};
118

    
119
		String currency = request.getCurrency() != null ? request.getCurrency().name() : null;
120

    
121
		if (request.getBankAccount() != null) {
122
			args = new Object[]{request.getUser(), request.getDate(), request.getResearcher(), request.getOrganization(), request.getProject(),
123
					request.getPublication(), request.getJournal(), request.getPublisher(), request.getPublisherEmail(), request.getBudget(), request.getInvoice(),
124
					request.getApc(), request.getDiscount(), request.getProjectParticipation(), request.getFundingRequested(), currency,
125
					request.getStatus(), request.getBankAccount().getBankName(), request.getBankAccount().getBankAddress(), request.getBankAccount().getBankCode(), request.getBankAccount().getAccountHolder(),
126
					request.getBankAccount().getIban(), request.getApc_paid(), request.getTransfer_cost(), request.getOther_cost(), request.getDate_paid(), request.getId()};
127
		} else {
128
			args = new Object[]{request.getUser(), request.getDate(), request.getResearcher(), request.getOrganization(), request.getProject(),
129
					request.getPublication(), request.getJournal(), request.getPublisher(), request.getPublisherEmail(), request.getBudget(), request.getInvoice(),
130
					request.getApc(), request.getDiscount(), request.getProjectParticipation(), request.getFundingRequested(), currency, request.getStatus(), null, null, null, null, null,
131
					request.getApc_paid(), request.getTransfer_cost(), request.getOther_cost(), request.getDate_paid(), request.getId()};
132
		}
133

    
134
		if (jdbcTemplate.update(UPDATE_REQUEST, args, types) == 0) {
135
			jdbcTemplate.update(INSERT_REQUEST, args, types);
136
		}
137
	}
138

    
139
	public void saveCoFunders(final Request request) {
140
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
141
		jdbcTemplate.update("delete from request_cofunder where request=?", new String[]{request.getId()}, new int[]{Types.VARCHAR});
142
		jdbcTemplate.batchUpdate("insert into request_cofunder (request, funder, percentage) values (?,?,?)", new BatchPreparedStatementSetter() {
143

    
144
			@Override
145
			public void setValues(PreparedStatement ps, int i) throws SQLException {
146
				ps.setString(1, request.getId());
147
				ps.setString(2, request.getCoFunders().get(i).getFunder().getId());
148
				ps.setFloat(3, request.getCoFunders().get(i).getPercentage());
149
			}
150

    
151
			@Override
152
			public int getBatchSize() {
153
				if (request.getCoFunders() != null)
154
					return request.getCoFunders().size();
155
				else
156
					return 0;
157
			}
158
		});
159
	}
160

    
161
	public List<RequestCoFunder> getCoFunders(final Request request) {
162
		return new JdbcTemplate(dataSource).query("select rf.percentage, f.id, f.name, f.url, f.source from request_cofunder rf join funder f on rf.funder=f.id where rf.request=?", new String[]{request.getId()}, new int[]{Types.VARCHAR}, new RowMapper<RequestCoFunder>() {
163
			@Override
164
			public RequestCoFunder mapRow(ResultSet rs, int rowNum) throws SQLException {
165
				Funder funder = new Funder(rs.getString("id"), rs.getString("name"), rs.getString("url"), rs.getString("source"));
166

    
167
				return new RequestCoFunder(request, funder, rs.getFloat("percentage"));
168
			}
169
		});
170
	}
171

    
172
	public Request getRequest(String requestId) {
173
		return new JdbcTemplate(dataSource).queryForObject(GET_BY_ID, new String[]{requestId}, new int[]{
174
				Types.VARCHAR}, requestRowMapper);
175
	}
176

    
177
	public List<Request> getForUser(String personId, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
178
		List<Object> args = new ArrayList<Object>();
179
		List<Integer> types = new ArrayList<Integer>();
180

    
181
		String query = getQuery(personId, null, null, requestSortBy, order, requestFilter, term, statusFilter, args, types, from, to);
182

    
183
		return new JdbcTemplate(dataSource).query(query, args.toArray(), ArrayUtils.toPrimitive(types.toArray(new Integer[0])), requestRowMapper);
184
	}
185

    
186
	public List<Request> getForOrganization(List<String> organizationIds, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
187
		List<Object> args = new ArrayList<Object>();
188
		List<Integer> types = new ArrayList<Integer>();
189

    
190
		String query = getQuery(null, organizationIds, null, requestSortBy, order, requestFilter, term, statusFilter, args, types, from, to);
191

    
192
		return new JdbcTemplate(dataSource).query(query, args.toArray(), ArrayUtils.toPrimitive(types.toArray(new Integer[0])), requestRowMapper);
193
	}
194

    
195
	public List<Request> getForPublisher(String publisherId, Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
196
		List<Object> args = new ArrayList<Object>();
197
		List<Integer> types = new ArrayList<Integer>();
198

    
199
		String query = getQuery(null, null, publisherId, requestSortBy, order, requestFilter, term, statusFilter, args, types, from, to);
200
//        System.out.println(query);
201
		return new JdbcTemplate(dataSource).query(query, args.toArray(), ArrayUtils.toPrimitive(types.toArray(new Integer[0])), requestRowMapper);
202
	}
203

    
204
	public List<Request> getForProject(String projectId) {
205
		return new JdbcTemplate(dataSource).query(GET_FOR_PROJECT, new String[]{projectId}, new int[]{
206
				Types.VARCHAR}, requestRowMapper);
207
	}
208

    
209
	public List<Request> getRequests(Date fromDate, Date toDate, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilter, int from, int to) {
210
		List<Object> args = new ArrayList<Object>();
211
		List<Integer> types = new ArrayList<Integer>();
212

    
213
		String query = getQuery(null, null, null, requestSortBy, order, requestFilter, term, statusFilter, args, types, from, to);
214

    
215
		return new JdbcTemplate(dataSource).query(query, args.toArray(), ArrayUtils.toPrimitive(types.toArray(new Integer[0])), requestRowMapper);
216
	}
217

    
218
	public void approveRequest(String requestId, String personId, String comment) {
219
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
220

    
221
		jdbcTemplate.update(APPROVE_REQUEST, new String[]{requestId}, new int[]{Types.VARCHAR});
222

    
223
		if (comment != null && !comment.isEmpty()) {
224
			saveComment(requestId, personId, comment);
225
		}
226
	}
227

    
228
	public void initiallyApproveRequest(String requestId, String personId, String comment) {
229
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
230

    
231
		jdbcTemplate.update(INITIALLY_APPROVE_REQUEST, new String[]{requestId}, new int[]{Types.VARCHAR});
232

    
233
		if (comment != null && !comment.isEmpty()) {
234
			saveComment(requestId, personId, comment);
235
		}
236
	}
237

    
238
	private void saveComment(String requestId, String personId, String comment) {
239
		String commentId = "portal::" + DigestUtils.md5Hex(comment + new Date());
240

    
241
		new JdbcTemplate(dataSource).update("with comm as ( insert into comment (id, person, comment, date) values (?, ?, ?, ?) returning id) insert into request_comment (request, comment) select ?, comm.id from comm",
242
				new Object[]{commentId, personId, comment, new Date(), requestId}, new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.VARCHAR});
243
	}
244

    
245
	public void rejectRequest(String requestId, String personId, String comment) {
246
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
247

    
248
		jdbcTemplate.update(REJECT_REQUEST, new String[]{requestId}, new int[]{Types.VARCHAR});
249

    
250
		if (comment != null && !comment.isEmpty()) {
251
			saveComment(requestId, personId, comment);
252
		}
253
	}
254

    
255
	public void paidRequest(String requestId, String personId, String comment, float apc_paid, float transfer_cost, float other_cost, Date datePaid) {
256
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
257

    
258
		jdbcTemplate.update(PAID_REQUEST, new Object[]{apc_paid, transfer_cost, other_cost, datePaid, requestId}, new int[]{Types.REAL, Types.REAL, Types.REAL, Types.TIMESTAMP, Types.VARCHAR});
259

    
260
		if (comment != null && !comment.isEmpty()) {
261
			saveComment(requestId, personId, comment);
262
		}
263
	}
264

    
265
	public void onHoldRequest(String requestId, String personId, String comment) {
266
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
267

    
268
		jdbcTemplate.update(ONHOLD_REQUEST, new String[]{requestId}, new int[]{Types.VARCHAR});
269

    
270
		if (comment != null && !comment.isEmpty()) {
271
			saveComment(requestId, personId, comment);
272
		}
273
	}
274

    
275
	public void deniedRequest(String requestId, String personId, String comment) {
276
		JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
277

    
278
		jdbcTemplate.update(DENIED_REQUEST, new String[]{requestId}, new int[]{Types.VARCHAR});
279

    
280
		if (comment != null && !comment.isEmpty()) {
281
			saveComment(requestId, personId, comment);
282
		}
283
	}
284

    
285
	public void invoiceUploaded(String requestId, String invoiceId) {
286
		new JdbcTemplate(dataSource).update(INVOICE_UPLOADED, new String[]{invoiceId, requestId}, new int[]{Types.VARCHAR, Types.VARCHAR});
287
	}
288

    
289
	public int getRequestId() {
290
		return new JdbcTemplate(dataSource).queryForObject("select nextval('request_id_seq') as id", new RowMapper<Integer>() {
291
			@Override
292
			public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
293
				return rs.getInt("id");
294
			}
295
		});
296
	}
297

    
298
	private String getQuery(String personId, List<String> organizationIds, String publisherId, RequestSort requestSortBy, RequestSortOrder order, RequestFilter requestFilter, String term, Request.RequestStatus[] statusFilters, List<Object> args, List<Integer> types, int from, int to) {
299
		Map<String, String> joins = new HashMap<String, String>();
300
		List<String> whereClauses = new ArrayList<String>();
301
		List<Object> whereArgs = new ArrayList<Object>();
302
		List<Integer> whereTypes = new ArrayList<Integer>();
303

    
304
		String orderBy = null;
305

    
306
		if (term != null) {
307
			if (requestFilter != null) {
308
				switch (requestFilter) {
309
					case USER:
310
						joins.put("user", " join person u on u.id=r.user and (lower(u.firstname) like lower(?) or lower(u.initials) like lower(?) or lower(u.lastname) like lower(?)) ");
311
						args.add("%" + term + "%");
312
						args.add("%" + term + "%");
313
						args.add("%" + term + "%");
314
						types.add(Types.VARCHAR);
315
						types.add(Types.VARCHAR);
316
						types.add(Types.VARCHAR);
317
						break;
318
					case RESEARCHER:
319
						joins.put("researcher", " join person res on res.id=r.researcher and (lower(res.firstname) like lower(?) or lower(res.initials) like lower(?) or lower(res.lastname) like lower(?)) ");
320
						args.add("%" + term + "%");
321
						args.add("%" + term + "%");
322
						args.add("%" + term + "%");
323
						types.add(Types.VARCHAR);
324
						types.add(Types.VARCHAR);
325
						types.add(Types.VARCHAR);
326
						break;
327
					case PROJECT:
328
						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(?)) ");
329
						args.add("%" + term + "%");
330
						args.add("%" + term + "%");
331
						args.add("%" + term + "%");
332
						types.add(Types.VARCHAR);
333
						types.add(Types.VARCHAR);
334
						types.add(Types.VARCHAR);
335
						break;
336
					case PUBLICATION:
337
						joins.put("publication", " join publication pub on pub.id=r.publication and (lower(pub.title) like lower(?)) ");
338
						args.add("%" + term + "%");
339
						types.add(Types.VARCHAR);
340
						break;
341
					case JOURNAL:
342
						joins.put("journal", " join journal j on j.id=r.journal and (lower(j.title) like lower(?)) ");
343
						args.add("%" + term + "%");
344
						types.add(Types.VARCHAR);
345
						break;
346
					case PUBLISHER:
347
						joins.put("publisher", " join publisher publ on publ.id=r.publisher and (lower(publ.name) like lower(?)) ");
348
						args.add("%" + term + "%");
349
						types.add(Types.VARCHAR);
350
						break;
351
				}
352
			} else {
353
				joins.put("user", " left join person u on u.id=r.user ");
354
				whereClauses.add("(lower(u.firstname) like lower(?) or lower(u.initials) like lower(?) or lower(u.lastname) like lower(?))");
355
				whereArgs.add("%" + term + "%");
356
				whereArgs.add("%" + term + "%");
357
				whereArgs.add("%" + term + "%");
358
				whereTypes.add(Types.VARCHAR);
359
				whereTypes.add(Types.VARCHAR);
360
				whereTypes.add(Types.VARCHAR);
361
				joins.put("researcher", " left join person res on res.id=r.researcher ");
362
				whereClauses.add("(lower(res.firstname) like lower(?) or lower(res.initials) like lower(?) or lower(res.lastname) like lower(?))");
363
				whereArgs.add("%" + term + "%");
364
				whereArgs.add("%" + term + "%");
365
				whereArgs.add("%" + term + "%");
366
				whereTypes.add(Types.VARCHAR);
367
				whereTypes.add(Types.VARCHAR);
368
				whereTypes.add(Types.VARCHAR);
369
				joins.put("project", " left join project proj on proj.id=r.project ");
370
				whereClauses.add("(lower(proj.acronym) like lower(?) or lower(proj.title) like lower(?) or lower(proj.grant) like lower(?))");
371
				whereArgs.add("%" + term + "%");
372
				whereArgs.add("%" + term + "%");
373
				whereArgs.add("%" + term + "%");
374
				whereTypes.add(Types.VARCHAR);
375
				whereTypes.add(Types.VARCHAR);
376
				whereTypes.add(Types.VARCHAR);
377
				joins.put("publication", " left join publication pub on pub.id=r.publication ");
378
				whereClauses.add("(lower(pub.title) like lower(?))");
379
				whereArgs.add("%" + term + "%");
380
				whereTypes.add(Types.VARCHAR);
381
				joins.put("journal", " left join journal j on j.id=r.journal ");
382
				whereClauses.add("(lower(j.title) like lower(?))");
383
				whereArgs.add("%" + term + "%");
384
				whereTypes.add(Types.VARCHAR);
385
				joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
386
				whereClauses.add("(lower(publ.name) like lower(?))");
387
				whereArgs.add("%" + term + "%");
388
				whereTypes.add(Types.VARCHAR);
389
			}
390

    
391
		}
392

    
393
		if (requestSortBy != null) {
394
			switch (requestSortBy) {
395
				case DATE:
396
					orderBy = " r.date ";
397
					break;
398
				case FUNDING_REQUESTED:
399
					orderBy = " r.fundingrequested ";
400
					break;
401
				case USER:
402
					if (joins.get("user") == null)
403
						joins.put("user", " left join person u on u.id=r.user ");
404

    
405
					orderBy = " u.firstname, u.initials, u.lastname ";
406
					break;
407
				case PUBLICATION:
408
					if (joins.get("publication") == null)
409
						joins.put("publication", " left join publication pub on r.publication=pub.id ");
410

    
411
					orderBy = " pub.title ";
412
					break;
413
				case RESEARCHER:
414
					if (joins.get("researcher") == null)
415
						joins.put("researcher", " left join person res on res.id=r.researcher ");
416

    
417
					orderBy = " res.firstname, res.initials, res.lastname ";
418
					break;
419
				case PROJECT:
420
					if (joins.get("project") == null)
421
						joins.put("project", " left join project proj on proj.id=r.project ");
422

    
423
					orderBy = " proj.acronym ";
424
					break;
425
				case JOURNAL:
426
					if (joins.get("journal") == null)
427
						joins.put("journal", " left join journal j on j.id=r.journal ");
428

    
429
					orderBy = " j.title ";
430
					break;
431
				case PUBLISHER:
432
					if (joins.get("publisher") == null)
433
						joins.put("publisher", " left join publisher publ on publ.id=r.publisher ");
434

    
435
					orderBy = " publ.name ";
436
					break;
437
				case STATUS:
438
				default:
439
					orderBy = " r.status ";
440
					break;
441
			}
442
		}
443

    
444
		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.status from request r ");
445

    
446
		for (String join : joins.values())
447
			sb.append(" ").append(join).append(" ");
448

    
449

    
450
		sb.append(" where ");
451

    
452
		if (personId != null) {
453
			sb.append("r.\"user\"=? ");
454

    
455
			args.add(personId);
456
			types.add(Types.VARCHAR);
457
		} else if (organizationIds != null) {
458
			sb.append("(");
459

    
460
			for (int i = 0; i < organizationIds.size(); i++) {
461
				if (i > 0)
462
					sb.append(" or ");
463

    
464
				sb.append(" r.organization=? ");
465

    
466
				args.add(organizationIds.get(i));
467
				types.add(Types.VARCHAR);
468
			}
469

    
470
			sb.append(")");
471

    
472
		} else if (publisherId != null) {
473

    
474
			if (joins.get("journal") == null) {
475
				sb.delete(sb.lastIndexOf("where"), sb.length());
476
				sb.append(" left join journal j on j.id=r.journal ");
477
				sb.append(" where ");
478
			}
479

    
480
			sb.append("(r.publisher=? or j.publisher=?)");
481

    
482
			args.add(publisherId);
483
			types.add(Types.VARCHAR);
484
			args.add(publisherId);
485
			types.add(Types.VARCHAR);
486
		} else
487
			sb.append(" 1 = 1  ");
488

    
489
		if (statusFilters != null) {
490
			sb.append(" and ");
491

    
492
			if (statusFilters.length == 1) {
493
				switch (statusFilters[0]) {
494
					case INCOMPLETE:
495
						sb.append(" r.status = 0 ");
496
						break;
497
					case SUBMITTED:
498
						sb.append(" r.status=" + Request.RequestStatus.SUBMITTED.getCode());
499
						break;
500
					default:
501
						sb.append(" r.status&" + statusFilters[0].getCode() + " = " + statusFilters[0].getCode());
502
						break;
503
				}
504
			} else {
505
				int status = 0;
506

    
507
				for (int i = 0; i < statusFilters.length; i++) {
508
					status |= statusFilters[i].getCode();
509
				}
510

    
511
				sb.append(" r.status&" + status + " = " + status);
512
			}
513
		}
514

    
515
		if (whereClauses.size() > 0) {
516
			sb.append(" and (");
517

    
518
			for (String clause : whereClauses) {
519
				sb.append(clause);
520
				sb.append(" or ");
521
			}
522

    
523
			sb.delete(sb.lastIndexOf("or"), sb.length());
524
			sb.append(") ");
525

    
526
			args.addAll(whereArgs);
527
			types.addAll(whereTypes);
528
		}
529

    
530
		if (orderBy != null) {
531
			sb.append(" order by ").append(orderBy);
532

    
533
			if (order == RequestSortOrder.ASCENDING)
534
				sb.append(" asc");
535
			else
536
				sb.append(" desc");
537
		}
538

    
539
		if (from > 0 && to > 0) {
540
			sb.append(" limit ").append(to - from + 1);
541
			sb.append(" offset ").append(from - 1);
542
		}
543

    
544
		return sb.toString();
545
	}
546

    
547
	public List<Comment> getComments(String id) {
548
		try {
549
			return new JdbcTemplate(dataSource).query("select c.comment, c.date, c.person from comment c join request_comment rc on rc.comment=c.id and rc.request=? order by date",
550
					new String[]{id}, new int[]{Types.VARCHAR}, new RowMapper<Comment>() {
551
						@Override
552
						public Comment mapRow(ResultSet rs, int rowNum) throws SQLException {
553
							return new Comment(new Person(rs.getString("person")), rs.getTimestamp("date"), rs.getString("comment"));
554
						}
555
					});
556
		} catch (EmptyResultDataAccessException e) {
557
			return null;
558
		}
559
	}
560

    
561
	public void uploadBankTransferReceipt(final String requestid, final String contentType, InputStream inputStream) {
562
		try {
563
			final ByteArrayOutputStream baos = new ByteArrayOutputStream();
564
			final JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
565

    
566
			IOUtils.copy(inputStream, baos);
567
			IOUtils.closeQuietly(baos);
568

    
569
			final PreparedStatementSetter pss = new PreparedStatementSetter() {
570
				@Override
571
				public void setValues(PreparedStatement ps) throws SQLException {
572
					ps.setString(1, contentType);
573
					ps.setBytes(2, baos.toByteArray());
574
					ps.setString(3, requestid);
575
				}
576
			};
577

    
578
			jdbcTemplate.update("update request set bank_receipt_contenttype=?, bank_receipt=? where id=?", pss);
579

    
580
		} catch (Exception e) {
581
			e.printStackTrace();
582
		}
583
	}
584

    
585
	public BankTransferReceipt downloadBankTransferReceipt(String requestId) {
586
		return new JdbcTemplate(dataSource).queryForObject("select bank_receipt_contenttype, bank_receipt from request where id=?", new String[]{requestId}, new int[]{Types.VARCHAR}, new RowMapper<BankTransferReceipt>() {
587
			@Override
588
			public BankTransferReceipt mapRow(ResultSet rs, int rowNum) throws SQLException {
589
				return new BankTransferReceipt(rs.getString("bank_receipt_contenttype"), rs.getBytes("bank_receipt"));
590
			}
591
		});
592
	}
593
}
(9-9/9)