wbaccounting 2.2.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wbaccounting/__init__.py +1 -0
- wbaccounting/admin/__init__.py +5 -0
- wbaccounting/admin/booking_entry.py +53 -0
- wbaccounting/admin/entry_accounting_information.py +10 -0
- wbaccounting/admin/invoice.py +26 -0
- wbaccounting/admin/invoice_type.py +8 -0
- wbaccounting/admin/transactions.py +16 -0
- wbaccounting/apps.py +5 -0
- wbaccounting/dynamic_preferences_registry.py +107 -0
- wbaccounting/factories/__init__.py +10 -0
- wbaccounting/factories/booking_entry.py +21 -0
- wbaccounting/factories/entry_accounting_information.py +46 -0
- wbaccounting/factories/invoice.py +43 -0
- wbaccounting/factories/transactions.py +32 -0
- wbaccounting/files/__init__.py +0 -0
- wbaccounting/files/invoice_document_file.py +134 -0
- wbaccounting/files/utils.py +331 -0
- wbaccounting/generators/__init__.py +6 -0
- wbaccounting/generators/base.py +120 -0
- wbaccounting/io/handlers/__init__.py +0 -0
- wbaccounting/io/handlers/transactions.py +32 -0
- wbaccounting/io/parsers/__init__.py +0 -0
- wbaccounting/io/parsers/societe_generale_lux.py +49 -0
- wbaccounting/io/parsers/societe_generale_lux_prenotification.py +60 -0
- wbaccounting/migrations/0001_initial_squashed_squashed_0005_alter_bookingentry_counterparty_and_more.py +284 -0
- wbaccounting/migrations/0006_alter_invoice_status.py +30 -0
- wbaccounting/migrations/0007_alter_invoice_options.py +23 -0
- wbaccounting/migrations/0008_alter_invoice_options.py +20 -0
- wbaccounting/migrations/0009_invoicetype_alter_bookingentry_options_and_more.py +366 -0
- wbaccounting/migrations/0010_alter_bookingentry_options.py +20 -0
- wbaccounting/migrations/0011_transaction.py +103 -0
- wbaccounting/migrations/0012_entryaccountinginformation_external_invoice_users.py +25 -0
- wbaccounting/migrations/__init__.py +0 -0
- wbaccounting/models/__init__.py +6 -0
- wbaccounting/models/booking_entry.py +167 -0
- wbaccounting/models/entry_accounting_information.py +157 -0
- wbaccounting/models/invoice.py +467 -0
- wbaccounting/models/invoice_type.py +30 -0
- wbaccounting/models/model_tasks.py +71 -0
- wbaccounting/models/transactions.py +112 -0
- wbaccounting/permissions.py +6 -0
- wbaccounting/processors/__init__.py +0 -0
- wbaccounting/processors/dummy_processor.py +5 -0
- wbaccounting/serializers/__init__.py +12 -0
- wbaccounting/serializers/booking_entry.py +78 -0
- wbaccounting/serializers/consolidated_invoice.py +109 -0
- wbaccounting/serializers/entry_accounting_information.py +149 -0
- wbaccounting/serializers/invoice.py +95 -0
- wbaccounting/serializers/invoice_type.py +16 -0
- wbaccounting/serializers/transactions.py +50 -0
- wbaccounting/tests/__init__.py +0 -0
- wbaccounting/tests/conftest.py +65 -0
- wbaccounting/tests/test_displays/__init__.py +0 -0
- wbaccounting/tests/test_displays/test_booking_entries.py +1 -0
- wbaccounting/tests/test_models/__init__.py +0 -0
- wbaccounting/tests/test_models/test_booking_entries.py +119 -0
- wbaccounting/tests/test_models/test_entry_accounting_information.py +81 -0
- wbaccounting/tests/test_models/test_invoice_types.py +21 -0
- wbaccounting/tests/test_models/test_invoices.py +73 -0
- wbaccounting/tests/test_models/test_transactions.py +40 -0
- wbaccounting/tests/test_processors.py +28 -0
- wbaccounting/tests/test_serializers/__init__.py +0 -0
- wbaccounting/tests/test_serializers/test_booking_entries.py +69 -0
- wbaccounting/tests/test_serializers/test_entry_accounting_information.py +64 -0
- wbaccounting/tests/test_serializers/test_invoice_types.py +35 -0
- wbaccounting/tests/test_serializers/test_transactions.py +72 -0
- wbaccounting/urls.py +68 -0
- wbaccounting/viewsets/__init__.py +12 -0
- wbaccounting/viewsets/booking_entry.py +61 -0
- wbaccounting/viewsets/buttons/__init__.py +3 -0
- wbaccounting/viewsets/buttons/booking_entry.py +15 -0
- wbaccounting/viewsets/buttons/entry_accounting_information.py +100 -0
- wbaccounting/viewsets/buttons/invoice.py +65 -0
- wbaccounting/viewsets/cashflows.py +124 -0
- wbaccounting/viewsets/display/__init__.py +8 -0
- wbaccounting/viewsets/display/booking_entry.py +58 -0
- wbaccounting/viewsets/display/cashflows.py +58 -0
- wbaccounting/viewsets/display/entry_accounting_information.py +91 -0
- wbaccounting/viewsets/display/invoice.py +218 -0
- wbaccounting/viewsets/display/invoice_type.py +19 -0
- wbaccounting/viewsets/display/transactions.py +35 -0
- wbaccounting/viewsets/endpoints/__init__.py +1 -0
- wbaccounting/viewsets/endpoints/invoice.py +6 -0
- wbaccounting/viewsets/entry_accounting_information.py +143 -0
- wbaccounting/viewsets/invoice.py +277 -0
- wbaccounting/viewsets/invoice_type.py +25 -0
- wbaccounting/viewsets/menu/__init__.py +6 -0
- wbaccounting/viewsets/menu/booking_entry.py +15 -0
- wbaccounting/viewsets/menu/cashflows.py +10 -0
- wbaccounting/viewsets/menu/entry_accounting_information.py +11 -0
- wbaccounting/viewsets/menu/invoice.py +15 -0
- wbaccounting/viewsets/menu/invoice_type.py +15 -0
- wbaccounting/viewsets/menu/transactions.py +15 -0
- wbaccounting/viewsets/titles/__init__.py +4 -0
- wbaccounting/viewsets/titles/booking_entry.py +12 -0
- wbaccounting/viewsets/titles/entry_accounting_information.py +12 -0
- wbaccounting/viewsets/titles/invoice.py +23 -0
- wbaccounting/viewsets/titles/invoice_type.py +12 -0
- wbaccounting/viewsets/transactions.py +34 -0
- wbaccounting-2.2.1.dist-info/METADATA +8 -0
- wbaccounting-2.2.1.dist-info/RECORD +102 -0
- wbaccounting-2.2.1.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from django.core.exceptions import FieldError
|
|
4
|
+
from django.db.models import (
|
|
5
|
+
CharField,
|
|
6
|
+
Count,
|
|
7
|
+
DecimalField,
|
|
8
|
+
ExpressionWrapper,
|
|
9
|
+
F,
|
|
10
|
+
IntegerField,
|
|
11
|
+
Q,
|
|
12
|
+
QuerySet,
|
|
13
|
+
Sum,
|
|
14
|
+
Value,
|
|
15
|
+
)
|
|
16
|
+
from django.db.models.functions import Concat
|
|
17
|
+
from dynamic_preferences.registries import global_preferences_registry
|
|
18
|
+
from rest_framework import filters, status
|
|
19
|
+
from rest_framework.decorators import action
|
|
20
|
+
from rest_framework.request import Request
|
|
21
|
+
from rest_framework.response import Response
|
|
22
|
+
from wbaccounting.models import Invoice, submit_invoices_as_task
|
|
23
|
+
from wbaccounting.models.model_tasks import (
|
|
24
|
+
approve_invoices_as_task,
|
|
25
|
+
pay_invoices_as_task,
|
|
26
|
+
)
|
|
27
|
+
from wbaccounting.permissions import IsInvoiceAdmin
|
|
28
|
+
from wbaccounting.serializers import (
|
|
29
|
+
ConsolidatedInvoiceSerializer,
|
|
30
|
+
InvoiceModelSerializer,
|
|
31
|
+
InvoiceRepresentationSerializer,
|
|
32
|
+
)
|
|
33
|
+
from wbaccounting.viewsets.buttons import (
|
|
34
|
+
ConsolidatedInvoiceButtonConfig,
|
|
35
|
+
InvoiceButtonConfig,
|
|
36
|
+
)
|
|
37
|
+
from wbaccounting.viewsets.display import (
|
|
38
|
+
ConsolidatedInvoiceDisplayConfig,
|
|
39
|
+
InvoiceDisplayConfig,
|
|
40
|
+
)
|
|
41
|
+
from wbaccounting.viewsets.endpoints import ConsolidatedInvoiceEndpointConfig
|
|
42
|
+
from wbaccounting.viewsets.titles import (
|
|
43
|
+
ConsolidatedInvoiceTitleConfig,
|
|
44
|
+
InvoiceTitleConfig,
|
|
45
|
+
)
|
|
46
|
+
from wbcore import viewsets
|
|
47
|
+
from wbcore.contrib.currency.models import Currency, CurrencyFXRates
|
|
48
|
+
from wbcore.filters import DjangoFilterBackend
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class InvoiceRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
52
|
+
serializer_class = InvoiceRepresentationSerializer
|
|
53
|
+
filter_backends = (filters.OrderingFilter,)
|
|
54
|
+
queryset = Invoice.objects.all()
|
|
55
|
+
ordering_fields = ["invoice_date"]
|
|
56
|
+
ordering = ["invoice_date"]
|
|
57
|
+
|
|
58
|
+
def get_queryset(self):
|
|
59
|
+
return Invoice.objects.filter_for_user(self.request.user) # type: ignore
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class InvoiceModelViewSet(viewsets.ModelViewSet):
|
|
63
|
+
serializer_class = InvoiceModelSerializer
|
|
64
|
+
|
|
65
|
+
filterset_fields = {
|
|
66
|
+
"counterparty": ["exact"],
|
|
67
|
+
"status": ["exact"],
|
|
68
|
+
"title": ["exact", "icontains"],
|
|
69
|
+
"invoice_date": ["gte", "exact", "lte"],
|
|
70
|
+
"invoice_type": ["exact"],
|
|
71
|
+
"reference_date": ["gte", "exact", "lte"],
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
search_fields = ["counterparty__computed_str", "title", "invoice_type__name"]
|
|
75
|
+
ordering_fields = (
|
|
76
|
+
"invoice_date",
|
|
77
|
+
"counterparty__computed_str",
|
|
78
|
+
"invoice_type__name",
|
|
79
|
+
"reference_date",
|
|
80
|
+
"gross_value",
|
|
81
|
+
"net_value",
|
|
82
|
+
)
|
|
83
|
+
ordering = (
|
|
84
|
+
"-invoice_date",
|
|
85
|
+
"id",
|
|
86
|
+
)
|
|
87
|
+
queryset = Invoice.objects.all()
|
|
88
|
+
|
|
89
|
+
button_config_class = InvoiceButtonConfig
|
|
90
|
+
display_config_class = InvoiceDisplayConfig
|
|
91
|
+
title_config_class = InvoiceTitleConfig
|
|
92
|
+
|
|
93
|
+
def get_queryset(self) -> QuerySet[Invoice]:
|
|
94
|
+
invoices = Invoice.objects.filter_for_user(self.request.user) # type: ignore
|
|
95
|
+
|
|
96
|
+
if eai_id := self.kwargs.get("entry_accounting_information_id", None):
|
|
97
|
+
invoices = invoices.filter(counterparty__entry_accounting_information__id=eai_id)
|
|
98
|
+
|
|
99
|
+
return invoices.select_related(
|
|
100
|
+
"counterparty",
|
|
101
|
+
"invoice_currency",
|
|
102
|
+
"invoice_type",
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class ConsolidatedInvoiceViewSet(viewsets.ViewSet):
|
|
107
|
+
IDENTIFIER = "wbaccounting:consolidated-invoice"
|
|
108
|
+
title_config_class = ConsolidatedInvoiceTitleConfig
|
|
109
|
+
serializer_class = ConsolidatedInvoiceSerializer
|
|
110
|
+
permission_classes = []
|
|
111
|
+
display_config_class = ConsolidatedInvoiceDisplayConfig
|
|
112
|
+
button_config_class = ConsolidatedInvoiceButtonConfig
|
|
113
|
+
filterset_fields = {"status": ["exact"]}
|
|
114
|
+
filter_backends = (DjangoFilterBackend,)
|
|
115
|
+
endpoint_config_class = ConsolidatedInvoiceEndpointConfig
|
|
116
|
+
queryset = Invoice.objects.none()
|
|
117
|
+
|
|
118
|
+
def list(self, request):
|
|
119
|
+
queryset = self.get_queryset()
|
|
120
|
+
if serializer := self.get_serializer_class():
|
|
121
|
+
serializer = serializer(queryset, many=True, context={"request": request, "view": self})
|
|
122
|
+
return Response({"results": serializer.data})
|
|
123
|
+
return Response({"results": {}})
|
|
124
|
+
|
|
125
|
+
def get_lookup(self) -> dict:
|
|
126
|
+
lookup = {}
|
|
127
|
+
if (request := getattr(self, "request")) and (lookup_str := request.GET.get("lookup")):
|
|
128
|
+
lookup = dict(map(lambda x: x.split(":"), lookup_str.split(",")))
|
|
129
|
+
return lookup
|
|
130
|
+
|
|
131
|
+
def get_lookup_mapping(self, currency_symbol: str = "") -> "list[tuple]":
|
|
132
|
+
return [
|
|
133
|
+
("reference_date", "reference_date", "gross_value_default_currency", Value(currency_symbol)),
|
|
134
|
+
("invoice_type", "invoice_type__name", "gross_value_default_currency", Value(currency_symbol)),
|
|
135
|
+
("invoice_currency", "invoice_currency__symbol", "gross_value", F("invoice_currency__symbol")),
|
|
136
|
+
("counterparty", "counterparty__computed_str", "gross_value", F("invoice_currency__symbol")),
|
|
137
|
+
("id", "title", "gross_value", F("invoice_currency__symbol")),
|
|
138
|
+
(
|
|
139
|
+
"booking_entries",
|
|
140
|
+
"booking_entries__title",
|
|
141
|
+
"booking_entries__gross_value",
|
|
142
|
+
F("booking_entries__currency__symbol"),
|
|
143
|
+
),
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
def get_queryset(self):
|
|
147
|
+
# We get the default currency id, as we potentially need it to convert some aggregates
|
|
148
|
+
default_currency = Currency.objects.get(
|
|
149
|
+
key=global_preferences_registry.manager()["currency__default_currency"]
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# lookup is a GET parameter in the format of ?lookup=key1:param1,key2:param2
|
|
153
|
+
# we convert it to a dictionairy for easier access
|
|
154
|
+
lookup = self.get_lookup()
|
|
155
|
+
|
|
156
|
+
# the number of items in the lookup dictionairy define the depth of the treeview, e.g
|
|
157
|
+
# depth 0 means the first level, depth 1 the second, and so on
|
|
158
|
+
depth = len(lookup.keys())
|
|
159
|
+
|
|
160
|
+
# if there is a status GET parameter, we add it to make sure we only look at aggregated invoices
|
|
161
|
+
# with that status
|
|
162
|
+
status_filter = {}
|
|
163
|
+
if status := self.request.GET.get("status"):
|
|
164
|
+
status_filter["status"] = status
|
|
165
|
+
|
|
166
|
+
# We filter the queryset with the lookup dictionairy and the status dictionairy
|
|
167
|
+
# In case a wrong lookup was parsed in here a FieldError is raised and we return
|
|
168
|
+
# an empty queryset
|
|
169
|
+
try:
|
|
170
|
+
queryset = Invoice.objects.filter_for_user(self.request.user).filter(**lookup, **status_filter) # type: ignore
|
|
171
|
+
except FieldError:
|
|
172
|
+
return Invoice.objects.none()
|
|
173
|
+
|
|
174
|
+
# Filter out all invoice that do not have a reference date.
|
|
175
|
+
queryset = queryset.exclude(reference_date__isnull=True)
|
|
176
|
+
|
|
177
|
+
# Depending on the depth and the default currency we get a tuple with the following elements
|
|
178
|
+
# 0: reference to the field that will be used as an id
|
|
179
|
+
# 1: reference to the name of the group
|
|
180
|
+
# 2: reference to which field is used to sum up the invoices
|
|
181
|
+
# 3: reference to which currency is used
|
|
182
|
+
group_by = self.get_lookup_mapping(default_currency.symbol or "USD")[depth]
|
|
183
|
+
|
|
184
|
+
# If the depth is smaller than 2, this means we have to convert the values to the default
|
|
185
|
+
# currency FX Rate. This is because the first 2 levels (level 0 and 1) are group by date
|
|
186
|
+
# and group by invoice type, which are currency agnostic. The third level (level 2) is by
|
|
187
|
+
# currency, so we don't have to convert the invoice currency anymore
|
|
188
|
+
if depth < 2:
|
|
189
|
+
queryset = queryset.annotate(
|
|
190
|
+
fx_rate_default_currency=CurrencyFXRates.get_fx_rates_subquery_for_two_currencies(
|
|
191
|
+
"reference_date", "invoice_currency", default_currency
|
|
192
|
+
),
|
|
193
|
+
gross_value_default_currency=ExpressionWrapper(
|
|
194
|
+
F("gross_value") * F("fx_rate_default_currency"),
|
|
195
|
+
output_field=DecimalField(decimal_places=2, max_digits=15),
|
|
196
|
+
),
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# if the id reference is not id (or level 4), we annotate the field as the id field
|
|
200
|
+
# we cannot do this for level 4 (or when the id field is id) because django will
|
|
201
|
+
# crash otherwise.
|
|
202
|
+
if group_by[0] != "id":
|
|
203
|
+
queryset = queryset.values(group_by[0]).annotate(id=F(group_by[0]))
|
|
204
|
+
|
|
205
|
+
# We annotate all values received from the get_lookup_mapping
|
|
206
|
+
queryset = queryset.annotate(
|
|
207
|
+
currency_symbol=group_by[3],
|
|
208
|
+
value=Sum(group_by[2]),
|
|
209
|
+
group=F(group_by[1]),
|
|
210
|
+
_group_key=Value(None, output_field=CharField(max_length=255)),
|
|
211
|
+
depth=Value(depth, output_field=IntegerField()),
|
|
212
|
+
num_draft=Count("pk", filter=Q(status="DRAFT")),
|
|
213
|
+
num_submitted=Count("pk", filter=Q(status="SUBMITTED")),
|
|
214
|
+
num_sent=Count("pk", filter=Q(status="SENT")),
|
|
215
|
+
num_paid=Count("pk", filter=Q(status="PAID")),
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# If the group_by id field is not booking entries (or not the last level), then we annotate a _group_key
|
|
219
|
+
# We do this to give the frontend an understanding on how to open the next row. We don't do this on the
|
|
220
|
+
# last level, to ensure that the last group cannot be further extended
|
|
221
|
+
if group_by[0] != "booking_entries":
|
|
222
|
+
queryset = queryset.annotate(
|
|
223
|
+
_group_key=Concat(Value(group_by[0] + ":"), F(group_by[0]), output_field=CharField(max_length=255)),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
return queryset.order_by("-reference_date").values(
|
|
227
|
+
"id",
|
|
228
|
+
"reference_date",
|
|
229
|
+
"value",
|
|
230
|
+
"currency_symbol",
|
|
231
|
+
"_group_key",
|
|
232
|
+
"group",
|
|
233
|
+
"depth",
|
|
234
|
+
"num_draft",
|
|
235
|
+
"num_submitted",
|
|
236
|
+
"num_sent",
|
|
237
|
+
"num_paid",
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
def get_underlying_invoices(self, request: Request, pk: Any, source_status: Invoice.Status) -> QuerySet[Invoice]:
|
|
241
|
+
"""Returns all of the current row's underlying invoices filtered by `source_status`.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
request: HttpRequest
|
|
245
|
+
pk: Pk of the current row. Type varies accordingly.
|
|
246
|
+
source_status (Invoice.Status): We need to filter by the state where a certain transition is allowed
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
QuerySet(Invoice): A queryset of invoices
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
lookup = self.get_lookup()
|
|
253
|
+
depth = len(lookup.keys())
|
|
254
|
+
status_filter = request.GET.get("status", "")
|
|
255
|
+
pk_filter = self.get_lookup_mapping()[depth][0]
|
|
256
|
+
if depth < 5 and (not status_filter or status_filter == source_status.value):
|
|
257
|
+
return Invoice.objects.filter(**lookup | {pk_filter: pk}, status=source_status)
|
|
258
|
+
|
|
259
|
+
return Invoice.objects.none()
|
|
260
|
+
|
|
261
|
+
@action(detail=True, methods=["PATCH"])
|
|
262
|
+
def submit(self, request: Request, pk: Any):
|
|
263
|
+
underlying_invoices = self.get_underlying_invoices(request, pk, Invoice.Status.DRAFT)
|
|
264
|
+
submit_invoices_as_task.delay(underlying_invoices.values_list("id", flat=True)) # type: ignore
|
|
265
|
+
return Response(status=status.HTTP_200_OK)
|
|
266
|
+
|
|
267
|
+
@action(detail=True, methods=["PATCH"], permission_classes=[IsInvoiceAdmin])
|
|
268
|
+
def approve(self, request: Request, pk: Any):
|
|
269
|
+
underlying_invoices = self.get_underlying_invoices(request, pk, Invoice.Status.SUBMITTED)
|
|
270
|
+
approve_invoices_as_task.delay(underlying_invoices.values_list("id", flat=True)) # type: ignore
|
|
271
|
+
return Response(status=status.HTTP_200_OK)
|
|
272
|
+
|
|
273
|
+
@action(detail=True, methods=["PATCH"], permission_classes=[IsInvoiceAdmin])
|
|
274
|
+
def pay(self, request: Request, pk: Any):
|
|
275
|
+
underlying_invoices = self.get_underlying_invoices(request, pk, Invoice.Status.SENT)
|
|
276
|
+
pay_invoices_as_task.delay(underlying_invoices.values_list("id", flat=True)) # type: ignore
|
|
277
|
+
return Response(status=status.HTTP_200_OK)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from wbaccounting.models import InvoiceType
|
|
2
|
+
from wbaccounting.serializers import (
|
|
3
|
+
InvoiceTypeModelSerializer,
|
|
4
|
+
InvoiceTypeRepresentationSerializer,
|
|
5
|
+
)
|
|
6
|
+
from wbaccounting.viewsets.display import InvoiceTypeDisplayConfig
|
|
7
|
+
from wbaccounting.viewsets.titles import InvoiceTypeTitleConfig
|
|
8
|
+
from wbcore import viewsets
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class InvoiceTypeModelViewSet(viewsets.ModelViewSet):
|
|
12
|
+
queryset = InvoiceType.objects.all()
|
|
13
|
+
serializer_class = InvoiceTypeModelSerializer
|
|
14
|
+
search_fields = ordering_fields = ("name", "processor")
|
|
15
|
+
ordering = ("name", "id")
|
|
16
|
+
display_config_class = InvoiceTypeDisplayConfig
|
|
17
|
+
filterset_fields = {"name": ["exact", "icontains"], "processor": ["exact", "icontains"]}
|
|
18
|
+
title_config_class = InvoiceTypeTitleConfig
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class InvoiceTypeRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
22
|
+
serializer_class = InvoiceTypeRepresentationSerializer
|
|
23
|
+
queryset = InvoiceType.objects.all()
|
|
24
|
+
search_fields = ordering_fields = ("name",)
|
|
25
|
+
ordering = ("name", "id")
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from .booking_entry import BOOKINGENTRY_MENUITEM
|
|
2
|
+
from .entry_accounting_information import ENTRYACCOUNTINGINFORMATION_MENUITEM
|
|
3
|
+
from .invoice import INVOICE_MENUITEM
|
|
4
|
+
from .invoice_type import INVOICETYPE_MENUITEM
|
|
5
|
+
from .transactions import TRANSACTION_MENUITEM
|
|
6
|
+
from .cashflows import CASHFLOW_MENUITEM
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
BOOKINGENTRY_MENUITEM = MenuItem(
|
|
5
|
+
label="Bookings",
|
|
6
|
+
endpoint="wbaccounting:bookingentry-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbaccounting.view_bookingentry"]
|
|
9
|
+
),
|
|
10
|
+
add=MenuItem(
|
|
11
|
+
label="Create Booking",
|
|
12
|
+
endpoint="wbaccounting:bookingentry-list",
|
|
13
|
+
permission=ItemPermission(permissions=["wbaccounting.add_bookingentry"]),
|
|
14
|
+
),
|
|
15
|
+
)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
CASHFLOW_MENUITEM = MenuItem(
|
|
5
|
+
label="Cashflow",
|
|
6
|
+
endpoint="wbaccounting:futurecashflow-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbaccounting.view_transaction"]
|
|
9
|
+
),
|
|
10
|
+
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
ENTRYACCOUNTINGINFORMATION_MENUITEM = MenuItem(
|
|
5
|
+
label="Counterparties",
|
|
6
|
+
endpoint="wbaccounting:entryaccountinginformation-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user),
|
|
9
|
+
permissions=["wbaccounting.view_entryaccountinginformation"],
|
|
10
|
+
),
|
|
11
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
INVOICE_MENUITEM = MenuItem(
|
|
5
|
+
label="Invoices",
|
|
6
|
+
endpoint="wbaccounting:invoice-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbaccounting.view_invoice"]
|
|
9
|
+
),
|
|
10
|
+
add=MenuItem(
|
|
11
|
+
label="Create Invoice",
|
|
12
|
+
endpoint="wbaccounting:invoice-list",
|
|
13
|
+
permission=ItemPermission(permissions=["wbaccounting.add_invoice"]),
|
|
14
|
+
),
|
|
15
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
INVOICETYPE_MENUITEM = MenuItem(
|
|
5
|
+
label="Invoice Types",
|
|
6
|
+
endpoint="wbaccounting:invoicetype-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbaccounting.view_invoicetype"]
|
|
9
|
+
),
|
|
10
|
+
add=MenuItem(
|
|
11
|
+
label="Create Invoice Type",
|
|
12
|
+
endpoint="wbaccounting:invoicetype-list",
|
|
13
|
+
permission=ItemPermission(permissions=["wbaccounting.add_invoicetype"]),
|
|
14
|
+
),
|
|
15
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
2
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
3
|
+
|
|
4
|
+
TRANSACTION_MENUITEM = MenuItem(
|
|
5
|
+
label="Transactions",
|
|
6
|
+
endpoint="wbaccounting:transaction-list",
|
|
7
|
+
permission=ItemPermission(
|
|
8
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbaccounting.view_transaction"]
|
|
9
|
+
),
|
|
10
|
+
add=MenuItem(
|
|
11
|
+
label="Create Transaction",
|
|
12
|
+
endpoint="wbaccounting:transaction-list",
|
|
13
|
+
permission=ItemPermission(permissions=["wbaccounting.add_transaction"]),
|
|
14
|
+
),
|
|
15
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from wbcore.metadata.configs.titles import TitleViewConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BookingEntryTitleConfig(TitleViewConfig):
|
|
5
|
+
def get_instance_title(self):
|
|
6
|
+
return "Booking: {{title}}"
|
|
7
|
+
|
|
8
|
+
def get_list_title(self):
|
|
9
|
+
return "Booking"
|
|
10
|
+
|
|
11
|
+
def get_create_title(self):
|
|
12
|
+
return "New Booking"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from wbcore.metadata.configs.titles import TitleViewConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class EntryAccountingInformationTitleConfig(TitleViewConfig):
|
|
5
|
+
def get_instance_title(self):
|
|
6
|
+
return "Counterparty: {{ _entry.computed_str }}"
|
|
7
|
+
|
|
8
|
+
def get_list_title(self):
|
|
9
|
+
return "Counterparties"
|
|
10
|
+
|
|
11
|
+
def get_create_title(self):
|
|
12
|
+
return "New Counterparty"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from wbcore.metadata.configs.titles import TitleViewConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class InvoiceTitleConfig(TitleViewConfig):
|
|
5
|
+
def get_instance_title(self):
|
|
6
|
+
return "Invoice {{title}}"
|
|
7
|
+
|
|
8
|
+
def get_list_title(self):
|
|
9
|
+
return "Invoices"
|
|
10
|
+
|
|
11
|
+
def get_create_title(self):
|
|
12
|
+
return "New Invoice"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ConsolidatedInvoiceTitleConfig(TitleViewConfig):
|
|
16
|
+
def get_instance_title(self):
|
|
17
|
+
return "Consolidated Invoice"
|
|
18
|
+
|
|
19
|
+
def get_list_title(self):
|
|
20
|
+
return "Consolidated Invoices"
|
|
21
|
+
|
|
22
|
+
def get_create_title(self):
|
|
23
|
+
return "New Consolidated Invoice"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from wbcore.metadata.configs.titles import TitleViewConfig
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class InvoiceTypeTitleConfig(TitleViewConfig):
|
|
5
|
+
def get_instance_title(self):
|
|
6
|
+
return "Invoice Type"
|
|
7
|
+
|
|
8
|
+
def get_list_title(self):
|
|
9
|
+
return "Invoice Types"
|
|
10
|
+
|
|
11
|
+
def get_create_title(self):
|
|
12
|
+
return "New Invoice Type"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from django.db.models import F, QuerySet
|
|
2
|
+
from wbaccounting.models import Transaction
|
|
3
|
+
from wbaccounting.serializers import (
|
|
4
|
+
TransactionModelSerializer,
|
|
5
|
+
TransactionRepresentationSerializer,
|
|
6
|
+
)
|
|
7
|
+
from wbaccounting.viewsets.display import TransactionDisplayConfig
|
|
8
|
+
from wbcore import viewsets
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TransactionModelViewSet(viewsets.ModelViewSet):
|
|
12
|
+
queryset = Transaction.objects.all()
|
|
13
|
+
serializer_class = TransactionModelSerializer
|
|
14
|
+
search_fields = ("bank_account__isin", "from_bank_account__isin", "to_bank_account__isin")
|
|
15
|
+
ordering = ordering_fields = ("booking_date", "value", "id")
|
|
16
|
+
display_config_class = TransactionDisplayConfig
|
|
17
|
+
|
|
18
|
+
def get_queryset(self) -> QuerySet[Transaction]:
|
|
19
|
+
return (
|
|
20
|
+
super()
|
|
21
|
+
.get_queryset()
|
|
22
|
+
.filter_for_user(user=self.request.user)
|
|
23
|
+
.annotate(bank_account_currency_symbol=F("bank_account__currency__symbol"))
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TransactionRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
28
|
+
serializer_class = TransactionRepresentationSerializer
|
|
29
|
+
queryset = Transaction.objects.all()
|
|
30
|
+
search_fields = ("bank_account__isin", "from_bank_account__isin", "to_bank_account__isin")
|
|
31
|
+
ordering = ordering_fields = ("booking_date", "value", "id")
|
|
32
|
+
|
|
33
|
+
def get_queryset(self) -> QuerySet[Transaction]:
|
|
34
|
+
return super().get_queryset().filter_for_user(user=self.request.user)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: wbaccounting
|
|
3
|
+
Version: 2.2.1
|
|
4
|
+
Summary: A workbench module for managing invoicing and simple accounting.
|
|
5
|
+
Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
|
|
6
|
+
Requires-Dist: reportlab==3.*
|
|
7
|
+
Requires-Dist: schwifty==2024.5.*
|
|
8
|
+
Requires-Dist: wbcore
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
wbaccounting/__init__.py,sha256=J-j-u0itpEFT6irdmWmixQqYMadNl1X91TxUmoiLHMI,22
|
|
2
|
+
wbaccounting/apps.py,sha256=g0CDsvZoOQFiCiWg9v-DJv99oPpm4LTQYunOZ5n2gTM,99
|
|
3
|
+
wbaccounting/dynamic_preferences_registry.py,sha256=yT-fTQ_v_BCYhpZO-ARUdZ2XMQVIIyNORKRY3l3Fba0,3356
|
|
4
|
+
wbaccounting/permissions.py,sha256=QE9SOnkq3vbra9VGdgDSn93NtYHNjvTzl-6XhUN9XK0,213
|
|
5
|
+
wbaccounting/urls.py,sha256=YysjpJjtUXw7SvthS2kCKxBhVZLXsRHC4Thg_nuOIRs,3000
|
|
6
|
+
wbaccounting/admin/__init__.py,sha256=klh0BoNdyTz54qRp1a1PSP0u7G4LbgQE_m3C68Z-ObE,284
|
|
7
|
+
wbaccounting/admin/booking_entry.py,sha256=DYjOTEeO7AtRBDpdNs50Vcs-M83PwyTcSpxWDQ0L1nI,1890
|
|
8
|
+
wbaccounting/admin/entry_accounting_information.py,sha256=kct4dNJ6UpsHOAZIvvblHpXuH1Q32cIIkh3TNDcaGrc,423
|
|
9
|
+
wbaccounting/admin/invoice.py,sha256=X_6VhGIUDTkDW4SlKsefZUY_1cGzuWYR5C6klyAUqyg,762
|
|
10
|
+
wbaccounting/admin/invoice_type.py,sha256=FeTTvWyXnKcLdIZmHV0Ak4Y6THIbh44zur8stsh6Lug,244
|
|
11
|
+
wbaccounting/admin/transactions.py,sha256=crnJ2OyusszSZQJO3Ehc63NAy_dNHALXcp78cszr5Z0,423
|
|
12
|
+
wbaccounting/factories/__init__.py,sha256=3F29_EXN8nmuI-sbhpc8gzTksdQ9QRnLfyGw8Hfua4M,309
|
|
13
|
+
wbaccounting/factories/booking_entry.py,sha256=7btt5pbbkubNJqtyxKIQ8ybK9Wl6S8NhmFJRkF3JRRs,927
|
|
14
|
+
wbaccounting/factories/entry_accounting_information.py,sha256=9Y7zLFutAEXuAO1R2ZtRKVeBtTunRchOtFJw_RV003c,1728
|
|
15
|
+
wbaccounting/factories/invoice.py,sha256=0GwLv3-aCi6iVsEVdXWYScEEKIGsZnGPizNKHXuGwk4,1717
|
|
16
|
+
wbaccounting/factories/transactions.py,sha256=aY8nMGpixlBRNLOUS9SagtBJgdJSxYvv_F1jgElcvxA,1231
|
|
17
|
+
wbaccounting/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
wbaccounting/files/invoice_document_file.py,sha256=kPgYYrjIly8fIP-ezddnzyOlySsfV7BG2VzUQRiG46U,4258
|
|
19
|
+
wbaccounting/files/utils.py,sha256=p1EpTFKhlw8vKtHQW7BZ32nCaeOqP0KEHsAe6Rn5ko0,14111
|
|
20
|
+
wbaccounting/generators/__init__.py,sha256=HMzN5HbicO03Ji5YabzVUScI7UWkC-VfdwaWeEvtplg,138
|
|
21
|
+
wbaccounting/generators/base.py,sha256=RJrQ6XAhyDVuJ5PmD_2BNGUCe9FS_b8sHtlnsweXaeI,4621
|
|
22
|
+
wbaccounting/io/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
wbaccounting/io/handlers/transactions.py,sha256=wu_25akE-J-LKvs-1-erjtON2ffnkhsX0grTF5vfa6o,1415
|
|
24
|
+
wbaccounting/io/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
|
+
wbaccounting/io/parsers/societe_generale_lux.py,sha256=nbNDnM6S886GLLh3USPrqWwBINW2ZG2jl6dzvG8VRUw,1692
|
|
26
|
+
wbaccounting/io/parsers/societe_generale_lux_prenotification.py,sha256=45C3zKyYLo1oTjnGxNCdit9ipYF7r7VF2j1BV7yaZ_I,2327
|
|
27
|
+
wbaccounting/migrations/0001_initial_squashed_squashed_0005_alter_bookingentry_counterparty_and_more.py,sha256=3bGsMTmv-4XABUuazo3FIxOKIuHg0obHC19NGWSzqQs,11449
|
|
28
|
+
wbaccounting/migrations/0006_alter_invoice_status.py,sha256=b0cTeDaRbNyp9s1DLP75Vxy2O0FIRU366Mref7MrxY4,859
|
|
29
|
+
wbaccounting/migrations/0007_alter_invoice_options.py,sha256=vvHUwv2WSjDINnuyzoxoXDrG5tRlEiGxOzPwdL_VgC8,634
|
|
30
|
+
wbaccounting/migrations/0008_alter_invoice_options.py,sha256=q8d_MFIgJNTwZlAntMNqXfsWBDw3VjhljeWeS3Cg-HQ,528
|
|
31
|
+
wbaccounting/migrations/0009_invoicetype_alter_bookingentry_options_and_more.py,sha256=LcvrkJmWoAN55dBTKt0kXpsgmqBgAT3ozCV4BOFeCwA,14023
|
|
32
|
+
wbaccounting/migrations/0010_alter_bookingentry_options.py,sha256=MubJcJ864jphINUO3EbDf5IJ9D-HqTRqA_3PsNf9HKg,564
|
|
33
|
+
wbaccounting/migrations/0011_transaction.py,sha256=CAFDQiZFIP-xJ__GqCyvsmMUazgMUGw_cR7H40GWxz0,4085
|
|
34
|
+
wbaccounting/migrations/0012_entryaccountinginformation_external_invoice_users.py,sha256=4uGToqhfM5VGMgHNnBgvASjoVTox1sYvjx0RY_mgbDA,815
|
|
35
|
+
wbaccounting/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
wbaccounting/models/__init__.py,sha256=qk2F9CHovzTR-opHJpPpp9HbblLX95izFNfL0FnQCts,263
|
|
37
|
+
wbaccounting/models/booking_entry.py,sha256=usKjt_g_4Y9dfS7-7DYzB7zxJ1eQ3UW5PwIFOSruBtQ,6655
|
|
38
|
+
wbaccounting/models/entry_accounting_information.py,sha256=UtA3r-VJveMXYL580cu60JPsSY7gYfw890ELzxsg8Zk,5778
|
|
39
|
+
wbaccounting/models/invoice.py,sha256=ry8KeEnjI9Sjaq4NwmUsrRXiEiFvUlBabmPrQfFoWM4,18521
|
|
40
|
+
wbaccounting/models/invoice_type.py,sha256=SMYKJGyL7rm4_7Sb6yaLT88ZIqXDmh9LA2KpyELsDBg,855
|
|
41
|
+
wbaccounting/models/model_tasks.py,sha256=lBB8fN9VL2Ib12Chx5mHnYlm01xUPQE5-OZdrhk4GCY,2165
|
|
42
|
+
wbaccounting/models/transactions.py,sha256=nzOLRFO3Slf-XaEMqlUB0AtiW9hR7gdQCdYEchOfWsk,3874
|
|
43
|
+
wbaccounting/processors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
|
+
wbaccounting/processors/dummy_processor.py,sha256=eHeH6IeUlPHcN1vggzmtVcffH0xgYFqAmA4CycVOK2I,158
|
|
45
|
+
wbaccounting/serializers/__init__.py,sha256=GPDCuRvKe8k203tq_6hxzWDqmq_WoHTEolstkbBDmi0,576
|
|
46
|
+
wbaccounting/serializers/booking_entry.py,sha256=_JwxbzOHjDLp0qLwg4DCdAA5n_zxAbRIG57yWU_Y8Ao,2723
|
|
47
|
+
wbaccounting/serializers/consolidated_invoice.py,sha256=EoyHhfJ23eC1LNuCaISvhTZbfO1QA_YhmQoduMNT5Eo,4346
|
|
48
|
+
wbaccounting/serializers/entry_accounting_information.py,sha256=iHr2oTnAG_Y_GUW8Av77brsQos5lh8O7kn3stONxYy4,6045
|
|
49
|
+
wbaccounting/serializers/invoice.py,sha256=GnuYUcey9tZp6sGvvT16Uj_UXRsBb5VwXDVnRoYNcdc,3581
|
|
50
|
+
wbaccounting/serializers/invoice_type.py,sha256=I_gKHC6CaEHlAghAKv4PPqYAZZJWrCzEZhTxZqA8hxQ,489
|
|
51
|
+
wbaccounting/serializers/transactions.py,sha256=CEKHkK1SYkWb72BLgketLsLRKJ74GPp8VOkPSIRRwAA,1975
|
|
52
|
+
wbaccounting/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
53
|
+
wbaccounting/tests/conftest.py,sha256=wKMgjTqQNvkbgZVf_RtNhVEf8Y1XXUZetjVqBI-M2uA,1874
|
|
54
|
+
wbaccounting/tests/test_processors.py,sha256=_ux2EJJ6XDTfZg9_UACrjAIEXVDHVwao6ydBzliBYi4,761
|
|
55
|
+
wbaccounting/tests/test_displays/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
wbaccounting/tests/test_displays/test_booking_entries.py,sha256=Z1qDAsYhkHRs2PwinGGG8R-1MUIYsg0bdCkgMBpJW3U,14
|
|
57
|
+
wbaccounting/tests/test_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
+
wbaccounting/tests/test_models/test_booking_entries.py,sha256=z0BOIrUCUgBiq12HqGm6iYUu54_90HwZoc-Ls3D6NCw,6486
|
|
59
|
+
wbaccounting/tests/test_models/test_entry_accounting_information.py,sha256=CrOJNowjaH2ZQd8XbrpgOn1LIRDFjCaFEit-ZBzs2n8,4472
|
|
60
|
+
wbaccounting/tests/test_models/test_invoice_types.py,sha256=AvrkQFn5ffrYLJdPGlbV8YveeImTJh0mWjoyC0DdDi4,700
|
|
61
|
+
wbaccounting/tests/test_models/test_invoices.py,sha256=wufZdTv8m38SfcQWmJYox0EmKFjImgzxexpP2T7eKAs,3868
|
|
62
|
+
wbaccounting/tests/test_models/test_transactions.py,sha256=DWFePCqwznYKURzRxysaEN2MAQCG0rWrEIgod2Hk7sQ,1719
|
|
63
|
+
wbaccounting/tests/test_serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
64
|
+
wbaccounting/tests/test_serializers/test_booking_entries.py,sha256=fnyap47qoyj8-Mb1I0c2HL1xA3QHcv8g5OFC3klwJBI,2569
|
|
65
|
+
wbaccounting/tests/test_serializers/test_entry_accounting_information.py,sha256=aVINzrnUcWEDJKcBfv2OWGrzpvClx9X8XmoAPOOEvxc,2373
|
|
66
|
+
wbaccounting/tests/test_serializers/test_invoice_types.py,sha256=BN8obY9Z0BeNyyXxzW4aTEx5A90WVYqdonoqB4e4SDs,1214
|
|
67
|
+
wbaccounting/tests/test_serializers/test_transactions.py,sha256=ybp-1gAPb6veiSAwIQVIZ1nLxWt6WU-EkDbtrV2j-5M,3454
|
|
68
|
+
wbaccounting/viewsets/__init__.py,sha256=up2PNbfvbIwpcL8EuefLvldf6hqr2D86MtCKFNH1w04,608
|
|
69
|
+
wbaccounting/viewsets/booking_entry.py,sha256=4JN8zOO5Bazq6CMydQjyhmt3BUKs2HUCPpZhxw_z_lU,2219
|
|
70
|
+
wbaccounting/viewsets/cashflows.py,sha256=yrqxdN4PdTZGaa78eQA8-4sxxBnubyvnefQWDrEbE5w,4760
|
|
71
|
+
wbaccounting/viewsets/entry_accounting_information.py,sha256=NRW9qbYyCin-cm8h0aQ3WSp3CHKyoRKs6JQY8SU0aGM,6024
|
|
72
|
+
wbaccounting/viewsets/invoice.py,sha256=6xwoNmqAv7ScW4KrSFPi0Skm-lBNnZxVxlIF5fElW-w,11668
|
|
73
|
+
wbaccounting/viewsets/invoice_type.py,sha256=yfrZza-M3Nr08tHNITqWOmfwcvf9-8jpxxHou-ofrBI,999
|
|
74
|
+
wbaccounting/viewsets/transactions.py,sha256=YqG7pG6da63nlqYYzzUnpksfU3uuaOH1DH3EPldGeeY,1389
|
|
75
|
+
wbaccounting/viewsets/buttons/__init__.py,sha256=1DWfhlibtxzgNnvAQWjoV6x8WyYT6frg--zAS0j4rmc,207
|
|
76
|
+
wbaccounting/viewsets/buttons/booking_entry.py,sha256=MswXOp6O2PCDWHfoysnTlc3CoY9qa1X1i3rVNjfrnCU,534
|
|
77
|
+
wbaccounting/viewsets/buttons/entry_accounting_information.py,sha256=unXZUDd-hUG2Cx9onVwkC7AvEyoUfdtZOew25kW6zQA,4696
|
|
78
|
+
wbaccounting/viewsets/buttons/invoice.py,sha256=KvpJNLo0XGImxy_r9a8VNdDilJ2-qsgBuf20ABBsy-M,2492
|
|
79
|
+
wbaccounting/viewsets/display/__init__.py,sha256=yM13b6E_-JyECcIw0TvBWeFhoSbPd08fxOqrMLrgzX4,373
|
|
80
|
+
wbaccounting/viewsets/display/booking_entry.py,sha256=SpdGy21wXRd22YedrCrpj3EL_kk7aQL4CxBw1OyqjQI,2633
|
|
81
|
+
wbaccounting/viewsets/display/cashflows.py,sha256=mVPP4sejDMkRl03ZAaZnCW1fa552BY91ufwJyeebFjg,2398
|
|
82
|
+
wbaccounting/viewsets/display/entry_accounting_information.py,sha256=2JofsKjzQpoOSf1Afp-T6kICT7w9Xz8DUA8yj8WkWes,3781
|
|
83
|
+
wbaccounting/viewsets/display/invoice.py,sha256=hxDGFN2t_7bKSrUldEc5KZ2Q81aoxylyYMST9YyFalU,8904
|
|
84
|
+
wbaccounting/viewsets/display/invoice_type.py,sha256=tZVaBOLjNI-PbDBnsTh9GT0TwtX9hcoXR7jGusrcn0Q,642
|
|
85
|
+
wbaccounting/viewsets/display/transactions.py,sha256=di5DKaPfHZl0m8ns0WQ3HG1WCkDUOqS1Rpgd8_saBgQ,1512
|
|
86
|
+
wbaccounting/viewsets/endpoints/__init__.py,sha256=RM-bRpTt7XRE3Glhzj0oc_ZK6kAT83vTBffoljHEqIc,55
|
|
87
|
+
wbaccounting/viewsets/endpoints/invoice.py,sha256=-sIPWerCCrWtKsNX5zTjrKSWvZdP6p4qOGb5NMb7YS8,213
|
|
88
|
+
wbaccounting/viewsets/menu/__init__.py,sha256=t6JpxtH_PxqAK7iZueKJS75jpu4ZhUAEKOwftLqg0xk,300
|
|
89
|
+
wbaccounting/viewsets/menu/booking_entry.py,sha256=ZTn0ksW0EEtON8_0J1ZqW-M1PNnsToFrWpHHRb4nO70,552
|
|
90
|
+
wbaccounting/viewsets/menu/cashflows.py,sha256=WBYucafeYSAkyxD5KGLh2okE-UIYklSUqlMMs7XF2pc,359
|
|
91
|
+
wbaccounting/viewsets/menu/entry_accounting_information.py,sha256=WgiLRFSKHga0GrMeY5vVqRJuvwjQBCD4H7_kUUUjCus,419
|
|
92
|
+
wbaccounting/viewsets/menu/invoice.py,sha256=4AhVeVXSly3lF1_yaiSldy7UAP74uau-iOs-_yvUOi8,527
|
|
93
|
+
wbaccounting/viewsets/menu/invoice_type.py,sha256=fF1Pq-eFIpYs4ei8_Emls8Du32txTqJz9-kdlPgJrZE,557
|
|
94
|
+
wbaccounting/viewsets/menu/transactions.py,sha256=Pvhztgqd4cO0UyTRy917UDaaGLJj38acUO9e664Ut2I,555
|
|
95
|
+
wbaccounting/viewsets/titles/__init__.py,sha256=MiSeieoir_2wdRzVIF3BLO-49O5MLl52DSj7t_xj1io,252
|
|
96
|
+
wbaccounting/viewsets/titles/booking_entry.py,sha256=SNQJOYXf3QcjTtL3Co2uIYZC69dudts9xwKg4kR19Vw,297
|
|
97
|
+
wbaccounting/viewsets/titles/entry_accounting_information.py,sha256=76kXkK5ij-HV29tt8efUuvplQ9d1CrQklT8sSv6zHYE,344
|
|
98
|
+
wbaccounting/viewsets/titles/invoice.py,sha256=mr-iufJpM2SYuvexZ3XPLjBmQgPatgIMn1JC4eHLdnY,566
|
|
99
|
+
wbaccounting/viewsets/titles/invoice_type.py,sha256=szgA0iSYVILjLvhFhuLcq_WhMWv04_ESEVvogMYOkyk,301
|
|
100
|
+
wbaccounting-2.2.1.dist-info/METADATA,sha256=OHMrcNTHBzFj0mHZN_H_eXK-6vb4a-WUW4zVaoQKhnE,280
|
|
101
|
+
wbaccounting-2.2.1.dist-info/WHEEL,sha256=aO3RJuuiFXItVSnAUEmQ0yRBvv9e1sbJh68PtuQkyAE,105
|
|
102
|
+
wbaccounting-2.2.1.dist-info/RECORD,,
|