Skip to content

Commit

Permalink
Feriennet: Fixes export of invoice items
Browse files Browse the repository at this point in the history
Prevents double entries by joining on activity and invoice references.

Type: Bugfix
  • Loading branch information
Lukas Burkhard committed Jun 16, 2021
1 parent 27a7c6f commit f3caf5e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 10 deletions.
27 changes: 20 additions & 7 deletions src/onegov/feriennet/exports/invoiceitem.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from onegov.activity import Invoice, InvoiceItem, InvoiceReference, Activity
from onegov.activity import Invoice, InvoiceItem, Activity, \
Occasion
from onegov.core.security import Secret
from onegov.feriennet import FeriennetApp, _
from onegov.feriennet.exports.base import FeriennetExport
from onegov.feriennet.forms import PeriodExportForm
from onegov.user import User
from sqlalchemy.orm import contains_eager
from sqlalchemy import distinct


@FeriennetApp.export(
Expand All @@ -24,16 +26,27 @@ def rows(self, session, period):
yield ((k, v) for k, v in self.fields(item, tags))

def query(self, session, period):
q = session.query(InvoiceItem, Activity._tags)
q = q.join(Invoice).join(User).join(InvoiceReference)
q = q.join(Activity, InvoiceItem.text == Activity.title, isouter=True)

# There might be activities with same title from other periods
# resulting in double entries of invoice items
# We filter by the period in order to get the correct tags
activities = session.query(
distinct(Activity.title).label('title'),
Activity._tags.label('tags')
).join(Occasion).filter(
Occasion.period_id == period.id
)
activities = activities.subquery()

q = session.query(InvoiceItem, activities.c.tags)
q = q.join(Invoice).join(User)
q = q.join(
activities, InvoiceItem.text == activities.c.title, isouter=True
)
q = q.options(
contains_eager(InvoiceItem.invoice)
.contains_eager(Invoice.user)
.undefer(User.data))
q = q.options(
contains_eager(InvoiceItem.invoice)
.contains_eager(Invoice.references))
q = q.filter(Invoice.period_id == period.id)
q = q.order_by(
User.username,
Expand Down
50 changes: 47 additions & 3 deletions tests/onegov/feriennet/test_export.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
from onegov.activity import InvoiceCollection, PeriodCollection
from onegov.activity import InvoiceCollection, PeriodCollection, \
InvoiceReference
from onegov.core.utils import Bunch
from onegov.feriennet.collections import BillingCollection
from onegov.feriennet.exports.booking import BookingExport
from onegov.feriennet.exports.invoiceitem import InvoiceItemExport


def test_exports(client, scenario):
# add old period
scenario.add_period(
confirmed=True,
all_inclusive=False,
active=False
)

# We simulate the creation of the same activity in another period earlier
# The db constraints a unique name, but by changing the title later,
# we end up with the situation we test here
scenario.add_activity(
title="Foobar",
name='foofoobar',
state='accepted', tags=['CAMP']
)

scenario.add_period(
confirmed=True,
all_inclusive=False
Expand All @@ -21,6 +38,11 @@ def test_exports(client, scenario):
scenario.add_activity(
title="Foobar", state='accepted', tags=['CAMP', 'Family Camp'])
scenario.add_occasion()

# Adding another occasion in the same period for the activity to test
# export of InvoiceItems when joined with activities filtered by the occ
# occasion of that period
scenario.add_occasion()
scenario.add_booking(state='accepted', cost=250)
scenario.commit()
scenario.refresh()
Expand Down Expand Up @@ -62,7 +84,7 @@ def request(admin):
form=Bunch(selected_period=scenario.latest_period),
session=session
)
data = {k: v for k, v in list(rows)[0]}
data = dict(list(rows)[0])
assert data['Activity Tags'] == "CAMP\nFamily Camp"

# Create invoices
Expand All @@ -78,5 +100,27 @@ def request(admin):
form=Bunch(selected_period=scenario.latest_period),
session=session
)
data = {k: v for k, v in list(items)[0]}
data = dict(list(items)[0])
assert data['Activity Tags'] == "CAMP\nFamily Camp"

invoices = InvoiceCollection(session, scenario.latest_period.id)
invoice = invoices.query().first()
invoice.references.append(InvoiceReference(
reference='zzzzzAAAAaaaa',
schema='esr-v1',
bucket='esr-v1'
))

# Export invoice items with tags
items = list(InvoiceItemExport().run(
form=Bunch(selected_period=scenario.latest_period),
session=session
))

# Prevent double exporting each invoice item when joined with the
# references on invoice if there are multiple references which is
# not an edge case
assert len(items) == 1
data = dict(items[0])
assert len(data['Invoice Item References'].splitlines()) == 2

0 comments on commit f3caf5e

Please sign in to comment.