Skip to content

Commit 2c56207

Browse files
authored
Merge pull request #200 from rambo/ndaparser_metadata_frommaster
Keep track of uploaded Nordea transaction files and store last upload time
2 parents 436c28f + 431eda9 commit 2c56207

File tree

9 files changed

+133
-6
lines changed

9 files changed

+133
-6
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import migrations, models
5+
import asylum.mixins
6+
import ndaparser.models
7+
from django.conf import settings
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
dependencies = [
13+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='UploadedTransaction',
19+
fields=[
20+
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
21+
('file', models.FileField(upload_to=ndaparser.models.datestamped_and_normalized)),
22+
('stamp', models.DateTimeField(auto_now_add=True)),
23+
('last_transaction', models.DateField()),
24+
('user', models.ForeignKey(on_delete=models.SET(ndaparser.models.get_sentinel_user), to=settings.AUTH_USER_MODEL)),
25+
],
26+
options={
27+
'verbose_name': 'Uploaded transaction',
28+
'verbose_name_plural': 'Uploaded transaction',
29+
'ordering': ['-stamp'],
30+
},
31+
bases=(asylum.mixins.AtomicVersionMixin, asylum.mixins.CleanSaveMixin, models.Model),
32+
),
33+
]

project/ndaparser/models.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
# -*- coding: utf-8 -*-
2+
import datetime
3+
import slugify as unicodeslugify
4+
25
from django.db import models, transaction
6+
from django.conf import settings
7+
from django.contrib.auth import get_user_model
8+
from django.utils.translation import ugettext_lazy as _
9+
310

411
from asylum.models import AsylumModel
512

6-
# Create your models here.
13+
14+
15+
def get_sentinel_user():
16+
"""Gets a "sentinel" user ("deleted") and for assigning as uploader"""
17+
return get_user_model().objects.get_or_create(username='deleted')[0]
18+
19+
20+
21+
def datestamped_and_normalized(instance, filename):
22+
"""Normalized filename and places in datestamped path"""
23+
file_parts = filename.split('.')
24+
if len(file_parts) > 1:
25+
name = '.'.join(file_parts[:-1])
26+
ext = '.' + file_parts[-1]
27+
else:
28+
ext = ''
29+
name = filename
30+
filename_normalized = unicodeslugify.slugify(
31+
name, only_ascii=True, lower=True,
32+
spaces=False, space_replacement='_'
33+
) + ext
34+
return datetime.datetime.now().strftime("ndaparser/%Y/%m/%d/{}").format(filename_normalized)
35+
36+
37+
38+
class UploadedTransaction(AsylumModel):
39+
"""Track uploaded transaction files"""
40+
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user))
41+
file = models.FileField(upload_to=datestamped_and_normalized)
42+
stamp = models.DateTimeField(auto_now_add=True, editable=False)
43+
last_transaction = models.DateField()
44+
45+
class Meta:
46+
verbose_name = _('Uploaded transaction')
47+
verbose_name_plural = _('Uploaded transaction')
48+
ordering = [ '-stamp' ]

project/ndaparser/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def ascii2scandic(string):
128128

129129
if __name__ == "__main__":
130130
transactions = []
131-
with open("./testdata.nda") as f:
131+
with open("./tests/testdata.nda") as f:
132132
for line in f:
133133
transaction = parseLine(line)
134134
if transaction is not None:

project/ndaparser/tests.py

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# -*- coding: utf-8 -*-
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# -*- coding: utf-8 -*-
2+
import os
3+
4+
import pytest
5+
from ndaparser.parser import parseLine
6+
7+
8+
def test_parser():
9+
transactions = []
10+
with open(os.path.join(os.path.dirname(__file__), "testdata.nda")) as f:
11+
for line in f:
12+
transaction = parseLine(line)
13+
if transaction is not None:
14+
transactions.append(transaction)
15+
assert len(transactions) == 12
16+
assert transactions[2].amount == 40
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf-8 -*-
2+
import datetime
3+
import os
4+
5+
import pytest
6+
from django.core.files.uploadedfile import SimpleUploadedFile
7+
from ndaparser.models import UploadedTransaction
8+
9+
10+
@pytest.mark.django_db
11+
def test_model_can_be_saved(admin_user):
12+
with open(os.path.join(os.path.dirname(__file__), "testdata.nda"), 'rb') as f:
13+
ut = UploadedTransaction(
14+
last_transaction=datetime.datetime.now().date(),
15+
user=admin_user,
16+
file=SimpleUploadedFile('pytest.nda', f.read())
17+
)
18+
ut.save()
19+
assert ut.pk > 0
File renamed without changes.

project/ndaparser/views.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
from .forms import UploadForm
99
from .importer import NDAImporter
10+
from .parser import parseLine
11+
from .models import UploadedTransaction
1012

1113

1214
class NordeaUploadView(FormView):
@@ -32,6 +34,24 @@ def form_valid(self, form):
3234
h = NDAImporter(f)
3335
transactions = h.import_transactions(transactions_handler)
3436

37+
# parse the file again for the last transaction timestamp
38+
last_stamp = None
39+
with open(tmp.name) as fp:
40+
for line in fp:
41+
nt = parseLine(line)
42+
if not nt:
43+
continue
44+
if not last_stamp:
45+
last_stamp = nt.timestamp
46+
if nt.timestamp > last_stamp:
47+
last_stamp = nt.timestamp
48+
49+
UploadedTransaction(
50+
last_transaction = last_stamp,
51+
file = self.request.FILES['ndafile'],
52+
user = self.request.user
53+
).save()
54+
3555
# Done with the temp file, get rid of it
3656
os.unlink(tmp.name)
3757

0 commit comments

Comments
 (0)