Pattern processing, pt. 3
http://stackoverflow.com/a/23287265/3761783 http://docs.spring.io/spring-data/rest/docs/current/reference/html/#projections-excerpts.projections
This commit is contained in:
+21
-21
@@ -8,7 +8,7 @@ import javax.persistence.ManyToOne;
|
|||||||
import javax.persistence.OneToOne;
|
import javax.persistence.OneToOne;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Pattern {
|
public class Matcher {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
@@ -19,10 +19,10 @@ public class Pattern {
|
|||||||
|
|
||||||
private Integer position;
|
private Integer position;
|
||||||
|
|
||||||
private String typePattern;
|
private String typeMatcherCode;
|
||||||
private String datePattern;
|
private String dateMatcherCode;
|
||||||
private String textPattern;
|
private String textMatcherCode;
|
||||||
private String amountPattern;
|
private String amountMatcherCode;
|
||||||
|
|
||||||
@OneToOne
|
@OneToOne
|
||||||
private Category targetCategory;
|
private Category targetCategory;
|
||||||
@@ -70,36 +70,36 @@ public class Pattern {
|
|||||||
this.position = position;
|
this.position = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTypePattern() {
|
public String getTypeMatcherCode() {
|
||||||
return typePattern;
|
return typeMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTypePattern(String typePattern) {
|
public void setTypeMatcherCode(String typeMatcherCode) {
|
||||||
this.typePattern = typePattern;
|
this.typeMatcherCode = typeMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDatePattern() {
|
public String getDateMatcherCode() {
|
||||||
return datePattern;
|
return dateMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDatePattern(String datePattern) {
|
public void setDateMatcherCode(String dateMatcherCode) {
|
||||||
this.datePattern = datePattern;
|
this.dateMatcherCode = dateMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTextPattern() {
|
public String getTextMatcherCode() {
|
||||||
return textPattern;
|
return textMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTextPattern(String textPattern) {
|
public void setTextMatcherCode(String textMatcherCode) {
|
||||||
this.textPattern = textPattern;
|
this.textMatcherCode = textMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAmountPattern() {
|
public String getAmountMatcherCode() {
|
||||||
return amountPattern;
|
return amountMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmountPattern(String amountPattern) {
|
public void setAmountMatcherCode(String amountMatcherCode) {
|
||||||
this.amountPattern = amountPattern;
|
this.amountMatcherCode = amountMatcherCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package de.tilman.transactions.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.rest.core.config.Projection;
|
||||||
|
|
||||||
|
import de.tilman.transactions.domain.Category;
|
||||||
|
import de.tilman.transactions.domain.Matcher;
|
||||||
|
|
||||||
|
@Projection(name = "fullMatchers", types = Matcher.class)
|
||||||
|
public interface FullMatcher {
|
||||||
|
Category getCategory();
|
||||||
|
}
|
||||||
+6
-6
@@ -9,23 +9,23 @@ import org.springframework.data.repository.query.Param;
|
|||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
|
||||||
import de.tilman.transactions.domain.Pattern;
|
import de.tilman.transactions.domain.Matcher;
|
||||||
|
|
||||||
public interface PatternRepository extends PagingAndSortingRepository<Pattern, Long> {
|
public interface MatcherRepository extends PagingAndSortingRepository<Matcher, Long> {
|
||||||
|
|
||||||
@RestResource(path = "listForAccount")
|
@RestResource(path = "listForAccount")
|
||||||
List<Pattern> findByAccountIdOrderByPositionAsc(@Param("accountId") Long accountId);
|
List<Matcher> findByAccountIdOrderByPositionAsc(@Param("accountId") Long accountId);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
Pattern save(Pattern pattern);
|
Matcher save(Matcher pattern);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
void delete(Pattern pattern);
|
void delete(Matcher pattern);
|
||||||
|
|
||||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||||
@Override
|
@Override
|
||||||
Page<Pattern> findAll(Pageable pageable);
|
Page<Matcher> findAll(Pageable pageable);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,14 @@ 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
|
INSERT INTO Matcher (id, account_id, position, type_matcher_code, date_matcher_code, text_matcher_code, amount_matcher_code, target_category_id, target_description) VALUES
|
||||||
(NULL, 1, 1, '', '', '*.LIDL*.', '', 1, 'Lidl'),
|
(NULL, 1, 1, null, null, 'return /\bnone\b/.test(x)', 'return (x == -40)', 4, 'Sparplan (in Rücklage)'),
|
||||||
(NULL, 1, 1, null, null, '*.Buchungstext: none*.', -40.0, 4, '(in Rücklage)'),
|
(NULL, 1, 1, null, null, 'return /\bLIDL\b/.test(x)', null, 1, 'Lidl');
|
||||||
(NULL, 1, 1, 'Kontoübertrag', null, 'Auftraggeber: Tilman Liero Kto/IBAN: DE44200411330649163305*.', null, 4, '(Entnahme aus Rücklagen)');
|
|
||||||
|
--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),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ transactionsApp.config([ '$routeProvider', function($routeProvider) {
|
|||||||
controller : 'ImportCtrl'
|
controller : 'ImportCtrl'
|
||||||
}).when('/importList', {
|
}).when('/importList', {
|
||||||
templateUrl : 'partials/import-list.html',
|
templateUrl : 'partials/import-list.html',
|
||||||
controller : 'ImportCtrl'
|
controller : 'ImportListCtrl'
|
||||||
}).otherwise({
|
}).otherwise({
|
||||||
redirectTo : '/list'
|
redirectTo : '/list'
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -367,20 +367,13 @@ transactionControllers.controller('OutstandingsModalCtrl', [ '$scope', '$uibModa
|
|||||||
transactionControllers.controller('ImportCtrl', [ '$scope', '$resource', '$location', 'ImportService', function($scope, $resource, $location, ImportService) {
|
transactionControllers.controller('ImportCtrl', [ '$scope', '$resource', '$location', 'ImportService', function($scope, $resource, $location, ImportService) {
|
||||||
|
|
||||||
$scope.importCSV = function () {
|
$scope.importCSV = function () {
|
||||||
ImportService.saveData($scope.csvInput);
|
ImportService.setAccount($scope.account);
|
||||||
|
ImportService.setCategories($scope.categories);
|
||||||
|
ImportService.setCSV($scope.csvInput);
|
||||||
$location.path('importList');
|
$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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// COPIED CODE from TransactionListCtrl.initList, needs to be moved into a Service
|
|
||||||
$scope.initPage = function () {
|
$scope.initPage = function () {
|
||||||
console.log('aloha');
|
|
||||||
var userinfo = $resource('/user').get();
|
var userinfo = $resource('/user').get();
|
||||||
userinfo.$promise.then(function(data) {
|
userinfo.$promise.then(function(data) {
|
||||||
$scope.userid = userinfo.name;
|
$scope.userid = userinfo.name;
|
||||||
@@ -392,17 +385,8 @@ transactionControllers.controller('ImportCtrl', [ '$scope', '$resource', '$locat
|
|||||||
|
|
||||||
var accountInfo = $resource('/accounts/search/findByUserName', { username: $scope.userid }).get();
|
var accountInfo = $resource('/accounts/search/findByUserName', { username: $scope.userid }).get();
|
||||||
accountInfo.$promise.then(function(data) {
|
accountInfo.$promise.then(function(data) {
|
||||||
console.log(accountInfo._embedded.accounts);
|
|
||||||
$scope.accounts = accountInfo._embedded.accounts;
|
$scope.accounts = accountInfo._embedded.accounts;
|
||||||
if ($scope.account == undefined) {
|
$scope.account = $scope.accounts[0];
|
||||||
$scope.account = $scope.accounts[0];
|
|
||||||
if ($routeParams.account != undefined) {
|
|
||||||
for (i = 0; i < $scope.accounts.length; i++) {
|
|
||||||
if ($scope.accounts[i].name == $routeParams.account)
|
|
||||||
$scope.account = $scope.accounts[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var categories = $resource('/categories/search/listForAccount', { accountId: $scope.account.id }).get();
|
var categories = $resource('/categories/search/listForAccount', { accountId: $scope.account.id }).get();
|
||||||
categories.$promise.then(function(data) {
|
categories.$promise.then(function(data) {
|
||||||
@@ -415,8 +399,75 @@ transactionControllers.controller('ImportCtrl', [ '$scope', '$resource', '$locat
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
$scope.csvInput = "\"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\"27.06.2016\";\"27.06.2016\";\"Lastschrift/Belast.\";\"Auftraggeber: DANKE, IHR LIDL Kto/IBAN: DE61300500000008000119 Buchungstext: Kartenzahlung DANKE, IHR LIDL//Berlin/DE 2016-06-25T09:47:08 KFN 2 VJ 1912 Ref. 6GL16179A2640086/6763\";\"-70,17\";\n\"24.06.2016\";\"24.06.2016\";\"Übertrag/Überweisung\";\"Auftraggeber: Tilman Liero Buchungstext: Uebertrag comdirect bank End-to-End-Ref.: nicht angegeben Ref. IX216176F0205292/1\";\"200,00\";\n\"24.06.2016\";\"24.06.2016\";\"Übertrag/Überweisung\";\"Auftraggeber: Wohnungsbau-Verein Neukölln eG Buchungstext: Mg.-Nr. 35823, Walther, Tilman - 4, Dividende 2015 End-to-End-Ref.: nicht angegeben Ref. H221617674648332/35629\";\"4,42\";";
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.initPage();
|
$scope.initPage();
|
||||||
|
|
||||||
} ]);
|
} ]);
|
||||||
|
|
||||||
|
transactionControllers.controller('ImportListCtrl', [ '$scope', '$resource', '$location', 'ImportService', function($scope, $resource, $location, ImportService) {
|
||||||
|
|
||||||
|
$scope.processCSV = function () {
|
||||||
|
$scope.account = ImportService.getAccount();
|
||||||
|
$scope.categories = ImportService.getCategories();
|
||||||
|
$scope.csv = Papa.parse(ImportService.getCSV()).data;
|
||||||
|
|
||||||
|
var matcherData = $resource('/matchers/search/listForAccount', { accountId: $scope.account.id }).get();
|
||||||
|
matcherData.$promise.then(function(data) {
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
console.log(matcherData);
|
||||||
|
|
||||||
|
|
||||||
|
matcherData = matcherData._embedded.matchers;
|
||||||
|
var matchers = new Array(matcherData.length);
|
||||||
|
|
||||||
|
for (i = 0; i < matchers.length; i++) {
|
||||||
|
matchers[i] = {};
|
||||||
|
|
||||||
|
if (matcherData[i].dateMatcherCode != null)
|
||||||
|
matchers[i].dateMatcher = new Function('x', matcherData[i].dateMatcherCode);
|
||||||
|
if (matcherData[i].typeMatcherCode != null)
|
||||||
|
matchers[i].typeMatcher = new Function('x', matcherData[i].typeMatcherCode);
|
||||||
|
if (matcherData[i].textMatcherCode != null)
|
||||||
|
matchers[i].textMatcher = new Function('x', matcherData[i].textMatcherCode);
|
||||||
|
if (matcherData[i].amountMatcherCode != null)
|
||||||
|
matchers[i].amountMatcher = new Function('x', matcherData[i].amountMatcherCode);
|
||||||
|
|
||||||
|
matchers[i].targetDescription = matcherData[i].targetDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
console.log(matchers);
|
||||||
|
|
||||||
|
for (i = 0; i < $scope.csv.length; i++) {
|
||||||
|
var matched = false;
|
||||||
|
var j = 0;
|
||||||
|
|
||||||
|
while (!matched && j < matchers.length) {
|
||||||
|
var match = true;
|
||||||
|
|
||||||
|
if (match && matchers[j].dateMatcher)
|
||||||
|
match = matchers[j].dateMatcher($scope.csv[i][1]);
|
||||||
|
if (match && matchers[j].typeMatcher)
|
||||||
|
match = matchers[j].typeMatcher($scope.csv[i][2]);
|
||||||
|
if (match && matchers[j].textMatcher)
|
||||||
|
match = matchers[j].textMatcher($scope.csv[i][3]);
|
||||||
|
if (match && matchers[j].amountMatcher)
|
||||||
|
match = matchers[j].amountMatcher(amountToNumber($scope.csv[i][4]));
|
||||||
|
|
||||||
|
if (match) {
|
||||||
|
$scope.csv[i].targetDescription = matchers[j].targetDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} ]);
|
||||||
|
|
||||||
|
|||||||
@@ -12,14 +12,28 @@ transactionServices.factory('Transaction', [ '$resource', function($resource) {
|
|||||||
} ]);
|
} ]);
|
||||||
|
|
||||||
transactionServices.factory('ImportService', function() {
|
transactionServices.factory('ImportService', function() {
|
||||||
var dataResponse = {};
|
var account = {};
|
||||||
|
var categories = {};
|
||||||
|
var csvData = {};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
saveData: function(data) {
|
setAccount: function(data) {
|
||||||
dataResponse = data;
|
account = data;
|
||||||
console.log(data);
|
|
||||||
},
|
},
|
||||||
getData : function() {
|
getAccount : function() {
|
||||||
return dataResponse;
|
return account;
|
||||||
|
},
|
||||||
|
setCategories: function(data) {
|
||||||
|
categories = data;
|
||||||
|
},
|
||||||
|
getCategories : function() {
|
||||||
|
return categories;
|
||||||
|
},
|
||||||
|
setCSV: function(data) {
|
||||||
|
csvData = data;
|
||||||
|
},
|
||||||
|
getCSV : function() {
|
||||||
|
return csvData;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Wertstellung</th>
|
<th>Wertstellung</th>
|
||||||
<th>Typ</th>
|
<th>Typ</th>
|
||||||
<th>Text</th>
|
<th style="width: 25%;">Text</th>
|
||||||
<th>Betrag</th>
|
<th>Betrag</th>
|
||||||
<th class="spacer"></th>
|
<th class="spacer"></th>
|
||||||
<th>Kategorie</th>
|
<th>Kategorie</th>
|
||||||
@@ -12,14 +12,14 @@
|
|||||||
<th class="spacer"></th>
|
<th class="spacer"></th>
|
||||||
<th>Pattern</th>
|
<th>Pattern</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-repeat="line in csv.data">
|
<tr ng-repeat="line in csv">
|
||||||
<td>{{line[1]}}</td>
|
<td>{{line[1]}}</td>
|
||||||
<td>{{line[2]}}</td>
|
<td>{{line[2]}}</td>
|
||||||
<td>{{line[3]}}</td>
|
<td>{{line[3]}}</td>
|
||||||
<td align="right">{{line[4]}}</td>
|
<td align="right">{{line[4]}}</td>
|
||||||
<td class="spacer"></td>
|
<td class="spacer"></td>
|
||||||
<td></td>
|
<td>{{line.targetCategory}}</td>
|
||||||
<td></td>
|
<td>{{line.targetDescription}}</td>
|
||||||
<td class="spacer"></td>
|
<td class="spacer"></td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user