Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions Models.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Models
## Models

## Datenbankeintrag für eine Transaktion
### Datenbankeintrag für eine Transaktion

```
{
'uuid': str,
'uuid': str, # (generated)
'date_tx': int, # (UTC)
'text_tx': str,
'betrag': float,
Expand All @@ -27,7 +27,7 @@
}
```

## Datenbankeintrag für User Settings
### Datenbankeintrag für User Settings

```
{
Expand All @@ -46,19 +46,39 @@
}
```

### Dictionary eines Rulesets
#### Dictionary eines Rulesets (Tag/Parse)

Regeln können Attribute einer Transaktion untersuchen und anhand dessen klassifizieren oder taggen. Zu den Werten kann nicht die primäre Kategorie zählen, wohl aber andere Tags, parsing Informationen oder Regexes auf den Buchungstext (und mehr).

```
{
'primary': str,
'regex': r-str( RegEx ), # (optional if parsed)
'parsed': dict( # (optional if regex)
str( parsed-Key ) : r-str( RegEx )
)
'uuid': str # (generated)
'metatype': str # (config|rule|parser)
'name': str,
'regex': r-str( RegEx ),

----------- bei Rules ----------

'primary': str | None,
'secondary': str | None,

----------- optional -----------

'secondary': str,
'prioriry': int
'prioriry': int,
'parsed': dict(
'multi': str, # (AND|OR)
'query': dict # (key=Name, val=Value)
)
}
```

## Handling von Prioritäten

Die Priorität wird zwischen 0 und 100 automatisch gesetzt, kann aber auch abgegen werden. 0 ist unwichtig, 100 ist wichtig.

Beim Tagging werden nur Einträge selektiert, die eine niedrigere Priorität haben als die akutelle Regel.

Es wird beim Taggen entweder die Priorität 1 (automatisches Taggen), die der Regel gesetzt (wenn diese höher ist) oder die explizit übermittelte. Ausnahmen sind:

- Das manuelle Taggen: Hier wird immer eine Priorität von 99 gesetzt.
- Das automatische Tagging mit einer explizit angegebenen Regel: Hier werden Einträge < 99 selektiert und überschrieben, dann aber wieder die Priorät der Regel (oder 1) gesetzt.
2 changes: 1 addition & 1 deletion app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ def create_app(config_path: str) -> Flask:
'config.py'
)
application = create_app(config)
application.run(host='0.0.0.0', port=8110, debug=True)
application.run(host='0.0.0.0', port=8110)
91 changes: 81 additions & 10 deletions app/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ function printResult(result){
* The file is selected via the file input element 'input_file'.
*/
function uploadFile() {
const iban = document.getElementById('input_iban').value;
const fileInput = document.getElementById('input_file');
if (fileInput.files.length === 0) {
alert('Please select a file to upload.');
return;
}

const params = { file: 'input_file' }; // The key 'file' corresponds to the input element's ID
apiSubmit('upload', params, function (responseText, error) {
apiSubmit('upload/' + iban, params, function (responseText, error) {
if (error) {
printResult('File upload failed: ' + '(' + error + ')' + responseText);

Expand All @@ -51,7 +52,7 @@ function uploadFile() {
function truncateDB() {
const iban = document.getElementById('input_iban').value;

apiGet('truncateDatabase/'+iban, {}, function (responseText, error) {
apiGet(iban + '/truncateDatabase', {}, function (responseText, error) {
if (error) {
printResult('Truncate failed: ' + '(' + error + ')' + responseText);

Expand All @@ -71,13 +72,55 @@ function truncateDB() {
* 'input_tagging_name' (more in the Future)
*/
function tagEntries() {
// TODO: Implement more, complex tagging rules
const rule_name = document.getElementById('input_tagging_name').value;
const rules = {
'rule_name': rule_name
const iban = document.getElementById('input_iban').value;
const rule_name = document.getElementById('tagging_name').value;
let rules = {}
if (rule_name) {
rules['rule_name'] = rule_name
}

apiSubmit('tag', rules, function (responseText, error) {
apiSubmit(iban + '/tag', rules, function (responseText, error) {
if (error) {
printResult('Tagging failed: ' + '(' + error + ')' + responseText);

} else {
alert('Entries tagged successfully!' + responseText);
window.location.reload();

}
}, false);
}


function removeTags() {
const iban = document.getElementById('input_iban').value;
const checkboxes = document.querySelectorAll('input[name="entry-select[]"]');
const t_ids = [];
checkboxes.forEach((checkbox) => {
if (checkbox.checked) {
t_ids.push(checkbox.value);
}
});

if (!iban) {
alert('Please provide an IBAN.');
return;
}
if (!t_ids) {
alert('Please provide a Transaction ID (checkbox).');
return;
}

let api_function;
let tags = {};
if (t_ids.length == 1) {
api_function = iban+'/removeTag/'+t_ids[0];
} else {
api_function = iban+'/removeTags';
tags['t_ids'] = t_ids;
};

apiSubmit(api_function, tags, function (responseText, error) {
if (error) {
printResult('Tagging failed: ' + '(' + error + ')' + responseText);

Expand Down Expand Up @@ -125,9 +168,9 @@ function manualTagEntries() {

let api_function;
if (t_ids.length == 1) {
api_function = 'setManualTag/'+iban+'/'+t_ids[0];
api_function = iban+'/setManualTag/'+t_ids[0];
} else {
api_function = 'setManualTags/' + iban;
api_function = iban+'/setManualTags';
tags['t_ids'] = t_ids;
};

Expand All @@ -144,10 +187,17 @@ function manualTagEntries() {
}


/**
* Fetches information based on the provided UUID and IBAN input value.
*
* @param {string} uuid - The unique identifier used to fetch specific information.
*
* This function retrieves the info for a given uuid from the server.
*/
function getInfo(uuid) {
const iban = document.getElementById('input_iban').value;

apiGet('getTx/'+iban+'/'+uuid, {}, function (responseText, error) {
apiGet('/'+iban+'/'+uuid, {}, function (responseText, error) {
if (error) {
printResult('getTx failed: ' + '(' + error + ')' + responseText);

Expand All @@ -157,3 +207,24 @@ function getInfo(uuid) {
}
});
}


function saveMeta() {
const meta_type = document.getElementById('select_meta').value;
const fileInput = document.getElementById('input-json');
if (fileInput.files.length === 0) {
alert('Please select a file to upload.');
return;
}

const params = { file: 'input_file' }; // The key 'file' corresponds to the input element's ID
apiSubmit('upload/metadata/'+meta_type, params, function (responseText, error) {
if (error) {
printResult('Rule saving failed: ' + '(' + error + ')' + responseText);

} else {
alert('Rule saved successfully!' + responseText);

}
}, true);
}
85 changes: 61 additions & 24 deletions app/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<td><input type="checkbox" name="entry-select[]" value="{{ entry.get('uuid') }}"></td>
{% for key in table_header %}
{% if key != 'parsed' %}
<td class="td-{{ key }}">{{ entry.get(key) }}</td>
<td class="td-{{ key }}">{{ entry.get(key) or '' }}</td>
{% endif %}
{% endfor %}
<td class="td-parsed">
Expand All @@ -37,41 +37,78 @@

</div>

<div class="container">

<h2>Input Forms</h2>
<ul>
<li>Filename: <input type="file" id="input_file"></li>
</ul>
<ul>
<li><input type="text" value="{{iban}}" id="input_iban" placeholder="IBAN"></li>
<li><input type="text" value="" id="input_t_id" placeholder="Transaction ID"></li>
</ul>
<ul>
<li><input type="text" value="" id="input_tagging_name" placeholder="Tagging Rule Name"></li>
</ul>
<ul>
<li><input type="text" value="" id="input_manual_primary" placeholder="Primary Manual Tag"></li>
<li><input type="text" value="" id="input_manual_secondary" placeholder="Secondary Manual Tag"></li>
</ul>

</div>

<div class="container">

<h2>Switches to Click</h2>
<a class="my-buttons" id="uploadButton" href="javascript:uploadFile();">Upload</a>
<a class="my-buttons" id="truncateButton" href="javascript:truncateDB();">truncate Database</a>
<a class="my-buttons" id="tagButton" href="javascript:tagEntries();">tag Entries</a>
<a class="my-buttons" id="manualTagButton" href="javascript:manualTagEntries();">tag Entries (manually)</a>
<h2>Actions for <input type="text" value="{{iban}}" id="input_iban" placeholder="IBAN"></h2>
<style>
.tile-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.tile {
border: 1px solid #ccc;
border-radius: 5px;
padding: 1rem;
width: 200px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
}
.tile h3 {
margin-top: 0;
font-size: 1.2rem;
}
.tile input, .tile button {
display: block;
margin: 0.5rem 0;
width: 100%;
}
</style>

<div class="tile-container">
<div class="tile">
<h3>Datenbank</h3>
<input type="file" name="input_file" id="input_file">
<button onclick="uploadFile()">Upload</button>
<button onclick="truncateDB()">DB leeren</button>
</div>
<div class="tile">
<h3>Tagging</h3>
<select name="tagging_name" id="tagging_name">
<option value=""></option>
{% for rule in rule_list %}
<option>{{ rule }}</option>
{% endfor %}
</select>
<button onclick="tagEntries()">Auto Tag</button>
<input type="text" value="" id="input_manual_primary" placeholder="Primary Manual Tag">
<input type="text" value="" id="input_manual_secondary" placeholder="Secondary Manual Tag">
<button onclick="manualTagEntries()">Manuelles Taggen</button>
<button onclick="removeTags()">Tags entfernen</button>
</div>
<div class="tile">
<h3>Metadata</h3>
<input type="file" name="input-json" id="input-json">
<select id="select_meta">
<option value="rule">Rule</option>
<option value="parser">Parser</option>
<option value="config">Config</option>
</select>
<button onclick="saveMeta()">Speichern</button>
</div>
</div>

</div>


<div class="container">

<h2>Message Box</h2>
<pre id="result-text">&nbsp;</pre>

</div>

<script src="{{ url_for('static', filename='js/index.js') }}"></script>

{% endblock %}
Loading