Pattern processing, pt. 1

This commit is contained in:
2016-07-19 15:33:51 +02:00
parent 610e77f7b9
commit 9a55fc9d0d
15 changed files with 268 additions and 25 deletions
+2 -2
View File
@@ -20,10 +20,10 @@ https://letsencrypt.org/getting-started/
# TODO # TODO
- Server: SSL und logs konfigurieren - Server: SSL und logs konfigurieren
- Transaktionen mit Passwort-Management ausstatten - Transaktionen mit Passwort-Management ausstatten, Usermanagement korrekt aufsetzen und Rollen durchreichen (derzeit noch inMemoryAuthentication)
- http://kielczewski.eu/2014/12/spring-boot-security-application/ - http://kielczewski.eu/2014/12/spring-boot-security-application/
- http://spr.com/part-5-integrating-spring-security-with-spring-boot-web/ - http://spr.com/part-5-integrating-spring-security-with-spring-boot-web/
- Metadaten für Icon einbauen - Metadaten für Icon einbauen (warum funktioniert das nicht?!?)
@@ -1,7 +1,10 @@
package de.tilman.transactions; package de.tilman.transactions;
import org.h2.server.web.WebServlet;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
@SpringBootApplication @SpringBootApplication
public class Application { public class Application {
@@ -16,8 +16,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication() auth.inMemoryAuthentication()
.withUser("adam@mail.com").password("test").roles("USER", "ADMIN").and() .withUser("adam").password("test").roles("USER", "ADMIN").and()
.withUser("betty@mail.com").password("test").roles("USER"); .withUser("betty").password("test").roles("USER");
} }
@Override @Override
@@ -29,7 +29,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.anyRequest().authenticated(); .anyRequest().authenticated();
http.httpBasic(); // XXX mit HTTP Basic Auth funktioniert der Logout nicht richtig http.httpBasic(); // XXX mit HTTP Basic Auth funktioniert der Logout nicht richtig
// http.formLogin(); http.formLogin();
http.csrf().disable(); // XXX später wieder aktivieren http.csrf().disable(); // XXX später wieder aktivieren
// http.headers().frameOptions().disable(); // for H2 console // http.headers().frameOptions().disable(); // for H2 console
@@ -0,0 +1,105 @@
package de.tilman.transactions.domain;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToOne;
@Entity
public class Pattern {
@Id
@GeneratedValue
private Long id;
@ManyToOne(optional = false, cascade = CascadeType.ALL)
private Account account;
private Integer position;
private String typePattern;
private String datePattern;
private String textPattern;
private String amountPattern;
@OneToOne
private Category targetCategory;
private String targetDescription;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public Category getTargetCategory() {
return targetCategory;
}
public void setTargetCategory(Category targetCategory) {
this.targetCategory = targetCategory;
}
public String getTargetDescription() {
return targetDescription;
}
public void setTargetDescription(String targetDescription) {
this.targetDescription = targetDescription;
}
public Integer getPosition() {
return position;
}
public void setPosition(Integer position) {
this.position = position;
}
public String getTypePattern() {
return typePattern;
}
public void setTypePattern(String typePattern) {
this.typePattern = typePattern;
}
public String getDatePattern() {
return datePattern;
}
public void setDatePattern(String datePattern) {
this.datePattern = datePattern;
}
public String getTextPattern() {
return textPattern;
}
public void setTextPattern(String textPattern) {
this.textPattern = textPattern;
}
public String getAmountPattern() {
return amountPattern;
}
public void setAmountPattern(String amountPattern) {
this.amountPattern = amountPattern;
}
}
@@ -0,0 +1,31 @@
package de.tilman.transactions.repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RestResource;
import org.springframework.security.access.prepost.PreAuthorize;
import de.tilman.transactions.domain.Pattern;
public interface PatternRepository extends PagingAndSortingRepository<Pattern, Long> {
@RestResource(path = "listForAccount")
List<Pattern> findByAccountIdOrderByPositionAsc(@Param("accountId") Long accountId);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
Pattern save(Pattern pattern);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
void delete(Pattern pattern);
@PreAuthorize("hasRole('ROLE_ADMIN')")
@Override
Page<Pattern> findAll(Pageable pageable);
}
+5
View File
@@ -11,6 +11,11 @@ INSERT INTO Category (id, name, account_id, position) VALUES
INSERT INTO Account_User (account_id, user_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1); INSERT INTO Account_User (account_id, user_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1);
INSERT INTO Pattern (id, account_id, position, type_pattern, date_pattern, text_pattern, amount_pattern, target_category_id, target_description) VALUES
(NULL, 1, 1, '', '', '*.LIDL*.', '', 1, 'Lidl'),
(NULL, 1, 1, null, null, '*.Buchungstext: none*.', -40.0, 4, '(in Rücklage)'),
(NULL, 1, 1, 'Kontoübertrag', null, 'Auftraggeber: Tilman Liero Kto/IBAN: DE44200411330649163305*.', null, 4, '(Entnahme aus Rücklagen)');
INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES INSERT INTO Transaction (id, amount, account_id, category_id, date, description, creditor_id) VALUES
(NULL, 1280.81, 1, 2, '2016-04-01 14:14:14', 'Gehalt', null), (NULL, 1280.81, 1, 2, '2016-04-01 14:14:14', 'Gehalt', null),
(NULL, -2.21, 1, 1, '2016-04-10', 'Brot', null), (NULL, -2.21, 1, 1, '2016-04-10', 'Brot', null),
+13
View File
@@ -73,6 +73,19 @@ label {
color: green; color: green;
} }
.importTable th, td {
font-size: 80%;
border: none;
border-bottom: 1px solid #ddd;
background-color: #fff;
padding: 1ex;
}
.importTable .spacer {
background-color: transparent;
border: none;
}
/* for angular-ui, see https://angular-ui.github.io/bootstrap/#/getting_started */ /* for angular-ui, see https://angular-ui.github.io/bootstrap/#/getting_started */
.nav, .pagination, .carousel, .panel-title a { cursor: pointer; } .nav, .pagination, .carousel, .panel-title a { cursor: pointer; }
+2 -1
View File
@@ -16,12 +16,13 @@
<script src="js/angular-animate.min.js"></script> <script src="js/angular-animate.min.js"></script>
<script src="js/angular-touch.min.js"></script> <script src="js/angular-touch.min.js"></script>
<script src="js/jquery-2.1.4.min.js"></script> <script src="js/jquery-2.1.4.min.js"></script>
<script src="bootstrap-3.3.6/js/bootstrap.min.js"></script> <script src="bootstrap-3.3.6/js/bootstrap.min.js"></script>
<script src="js/ui-bootstrap-custom-tpls-1.3.3.min.js"></script> <script src="js/ui-bootstrap-custom-tpls-1.3.3.min.js"></script>
<script src="js/papaparse.min.js"></script>
<script src="js/app.js"></script> <script src="js/app.js"></script>
<script src="js/controllers.js"></script> <script src="js/controllers.js"></script>
+6
View File
@@ -4,6 +4,12 @@ transactionsApp.config([ '$routeProvider', function($routeProvider) {
$routeProvider.when('/list', { $routeProvider.when('/list', {
templateUrl : 'partials/transaction-list.html', templateUrl : 'partials/transaction-list.html',
controller : 'TransactionListCtrl' controller : 'TransactionListCtrl'
}).when('/import', {
templateUrl : 'partials/import.html',
controller : 'ImportCtrl'
}).when('/importList', {
templateUrl : 'partials/import-list.html',
controller : 'ImportCtrl'
}).otherwise({ }).otherwise({
redirectTo : '/list' redirectTo : '/list'
}); });
@@ -358,3 +358,19 @@ transactionControllers.controller('OutstandingsModalCtrl', [ '$scope', '$uibModa
}); });
} }
} ]); } ]);
transactionControllers.controller('ImportCtrl', [ '$scope', '$location', 'ImportService', function($scope, $location, ImportService) {
$scope.importCSV = function () {
ImportService.saveData($scope.csvInput);
$location.path('importList');
}
$scope.processCSV = function () {
$scope.csv = Papa.parse("\"08.07.2016\";\"08.07.2016\";\"Übertrag/Überweisung\";\"Empfänger: Tilman Liero Kto/IBAN: DE44200411330649163305 BLZ/BIC: COBADEHD001 Buchungstext: none End-to-End-Ref.: nicht angegeben Ref. JK21619010302362/2\";\"-40,00\";\n\"07.07.2016\";\"07.07.2016\";\"Übertrag/Überweisung\";\"Empfänger: Tilman Liero Kto/IBAN: DE44200411330649163305 BLZ/BIC: COBADEHD001 Buchungstext: Uebertrag auf Tagesgeld PLUS-Konto End-to-End-Ref.: nicht angegeben Ref. J521618965322854/2\";\"-185,76\";\n\"06.07.2016\";\"06.07.2016\";\"Übertrag/Überweisung\";\"Auftraggeber: Bayer AG Buchungstext: /EDAM WORSHOP MIT/ Delaware (15.-16 End-to-End-Ref.: 8000012618 Ref. J321618880156700/705\";\"226,90\";\n\"01.07.2016\";\"01.07.2016\";\"Lastschrift/Belast.\";\"Auftraggeber: comdirect Visa-Monatsabrechnung Buchungstext: VISA-KARTE NR. 42635401XXXX5230 SUMME MONATSABRECHNUNG VISA TILMAN LIERO Ref. I421618341001491/75009\";\"-346,67\";\n");
// $scope.csv = Papa.parse(ImportService.getData());
console.log($scope.csv.meta.delimiter);
console.log($scope.csv);
}
} ]);
File diff suppressed because one or more lines are too long
+13
View File
@@ -10,3 +10,16 @@ transactionServices.factory('Transaction', [ '$resource', function($resource) {
} }
}); });
} ]); } ]);
transactionServices.factory('ImportService', function() {
var dataResponse = {};
return {
saveData: function(data) {
dataResponse = data;
console.log(data);
},
getData : function() {
return dataResponse;
}
};
});
@@ -0,0 +1,28 @@
<div class="container" ng-init="processCSV()">
<div class="row">
<table class="importTable">
<tr>
<th>Wertstellung</th>
<th>Typ</th>
<th>Text</th>
<th>Betrag</th>
<th class="spacer"></th>
<th>Kategorie</th>
<th>Notiz</th>
<th class="spacer"></th>
<th>Pattern</th>
</tr>
<tr ng-repeat="line in csv.data">
<td>{{line[1]}}</td>
<td>{{line[2]}}</td>
<td>{{line[3]}}</td>
<td align="right">{{line[4]}}</td>
<td class="spacer"></td>
<td></td>
<td></td>
<td class="spacer"></td>
<td></td>
</tr>
</table>
</div>
</div>
@@ -0,0 +1,14 @@
<div class="container">
<div class="row">
<form name="importForm" ng-submit="importCSV()" style="text-align: center;">
<textarea ng-model='csvInput' name="csvText" cols="140" rows="20"></textarea>
<div>
<button id="transactionSubmit" type="submit" class="btn btn-primary">
<span ng-show="waitingForImport"><i class="glyphicon glyphicon-refresh spinning"></i>&nbsp;</span>
Analyze
</button>
</div>
</form>
</div>
</div>
@@ -101,7 +101,9 @@
<div style="text-align: center; font-size: 80%" ng-show="nextPageAvailable"> <div style="text-align: center; font-size: 80%" ng-show="nextPageAvailable">
<a href="" ng-click="moreTransactions()">more</a> <a href="" ng-click="moreTransactions()">more</a>
</div> </div>
</div>
<div class="row">
<div ng-show="accountUsers.length > 1" style="margin-top: 2em; text-align: center;"> <div ng-show="accountUsers.length > 1" style="margin-top: 2em; text-align: center;">
<span ng-repeat="user in accountUsers" ng-click="openOutstandings(user)" class="clickable">{{user.name}} {{user.outstandingAmount}}&nbsp;<br/></span> <span ng-repeat="user in accountUsers" ng-click="openOutstandings(user)" class="clickable">{{user.name}} {{user.outstandingAmount}}&nbsp;<br/></span>
</div> </div>