django-ledger 0.6.3__py3-none-any.whl → 0.7.0__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.
Potentially problematic release.
This version of django-ledger might be problematic. Click here for more details.
- django_ledger/__init__.py +1 -4
- django_ledger/admin/coa.py +1 -2
- django_ledger/contrib/django_ledger_graphene/accounts/schema.py +1 -1
- django_ledger/forms/account.py +60 -44
- django_ledger/forms/bank_account.py +3 -2
- django_ledger/forms/bill.py +24 -36
- django_ledger/forms/customer.py +1 -1
- django_ledger/forms/data_import.py +3 -3
- django_ledger/forms/estimate.py +1 -1
- django_ledger/forms/invoice.py +5 -7
- django_ledger/forms/item.py +24 -15
- django_ledger/forms/transactions.py +3 -3
- django_ledger/io/io_core.py +4 -2
- django_ledger/io/io_middleware.py +5 -0
- django_ledger/io/roles.py +6 -0
- django_ledger/migrations/0017_alter_accountmodel_unique_together_and_more.py +31 -0
- django_ledger/models/accounts.py +629 -342
- django_ledger/models/bank_account.py +0 -4
- django_ledger/models/bill.py +0 -3
- django_ledger/models/closing_entry.py +0 -3
- django_ledger/models/coa.py +59 -48
- django_ledger/models/coa_default.py +9 -8
- django_ledger/models/customer.py +0 -4
- django_ledger/models/data_import.py +0 -3
- django_ledger/models/entity.py +80 -40
- django_ledger/models/estimate.py +0 -9
- django_ledger/models/invoice.py +0 -3
- django_ledger/models/items.py +4 -6
- django_ledger/models/journal_entry.py +2 -5
- django_ledger/models/ledger.py +0 -3
- django_ledger/models/mixins.py +0 -3
- django_ledger/models/purchase_order.py +0 -4
- django_ledger/models/signals.py +0 -3
- django_ledger/models/transactions.py +2 -5
- django_ledger/models/unit.py +0 -3
- django_ledger/models/utils.py +0 -3
- django_ledger/models/vendor.py +0 -3
- django_ledger/report/cash_flow_statement.py +1 -1
- django_ledger/static/.DS_Store +0 -0
- django_ledger/static/django_ledger/.DS_Store +0 -0
- django_ledger/static/django_ledger/logo_2/.DS_Store +0 -0
- django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark.png +0 -0
- django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/django_ledger_logo_dark@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-full-vert.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-full-vert@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-full-vert@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-full-vert@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-horiz@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-vert.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo-full-vert@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-logo@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-horiz@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-vert.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-full-vert@3x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-horiz.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-horiz@0.5x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-horiz@2x.png +0 -0
- django_ledger/static/django_ledger/logo_2/djl-txt-horiz@3x.png +0 -0
- django_ledger/templates/django_ledger/account/account_create.html +2 -2
- django_ledger/templates/django_ledger/account/account_update.html +1 -1
- django_ledger/templates/django_ledger/account/tags/account_txs_table.html +1 -0
- django_ledger/templates/django_ledger/account/tags/accounts_table.html +27 -18
- django_ledger/templates/django_ledger/bills/bill_detail.html +3 -3
- django_ledger/templates/django_ledger/expense/tags/expense_item_table.html +7 -0
- django_ledger/templates/django_ledger/invoice/invoice_detail.html +3 -3
- django_ledger/templatetags/django_ledger.py +7 -1
- django_ledger/tests/base.py +23 -7
- django_ledger/tests/test_accounts.py +145 -9
- django_ledger/urls/account.py +17 -24
- django_ledger/utils.py +8 -0
- django_ledger/views/__init__.py +1 -1
- django_ledger/views/account.py +80 -118
- django_ledger/views/auth.py +1 -1
- django_ledger/views/bank_account.py +9 -11
- django_ledger/views/bill.py +91 -80
- django_ledger/views/closing_entry.py +8 -0
- django_ledger/views/coa.py +2 -1
- django_ledger/views/customer.py +1 -1
- django_ledger/views/data_import.py +1 -1
- django_ledger/views/entity.py +1 -1
- django_ledger/views/estimate.py +13 -8
- django_ledger/views/feedback.py +1 -1
- django_ledger/views/financial_statement.py +1 -1
- django_ledger/views/home.py +1 -1
- django_ledger/views/inventory.py +9 -0
- django_ledger/views/invoice.py +5 -2
- django_ledger/views/item.py +58 -68
- django_ledger/views/journal_entry.py +1 -1
- django_ledger/views/ledger.py +3 -1
- django_ledger/views/mixins.py +9 -8
- django_ledger/views/purchase_order.py +1 -1
- django_ledger/views/transactions.py +1 -1
- django_ledger/views/unit.py +9 -0
- django_ledger/views/vendor.py +1 -1
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/AUTHORS.md +8 -2
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/METADATA +34 -43
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/RECORD +115 -79
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/WHEEL +1 -1
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/top_level.txt +0 -1
- {django_ledger-0.6.3.dist-info → django_ledger-0.7.0.dist-info}/LICENSE +0 -0
django_ledger/views/item.py
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
3
|
+
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
|
+
|
|
5
|
+
Contributions to this module:
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
1
9
|
from django.contrib.messages import add_message, ERROR
|
|
2
10
|
from django.core.exceptions import ObjectDoesNotExist
|
|
3
11
|
from django.db import IntegrityError
|
|
@@ -20,19 +28,17 @@ from django_ledger.views.mixins import DjangoLedgerSecurityMixIn
|
|
|
20
28
|
# todo: Create delete views...
|
|
21
29
|
|
|
22
30
|
# UNIT OF MEASURE VIEWS....
|
|
23
|
-
class
|
|
31
|
+
class UnitOfMeasureModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
24
32
|
queryset = None
|
|
25
33
|
|
|
26
34
|
def get_queryset(self):
|
|
27
35
|
if self.queryset is None:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
user_model=self.request.user
|
|
31
|
-
)
|
|
36
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
37
|
+
self.queryset = entity_model.unitofmeasuremodel_set.all()
|
|
32
38
|
return super().get_queryset()
|
|
33
39
|
|
|
34
40
|
|
|
35
|
-
class UnitOfMeasureModelListView(
|
|
41
|
+
class UnitOfMeasureModelListView(UnitOfMeasureModelModelBaseView, ListView):
|
|
36
42
|
template_name = 'django_ledger/uom/uom_list.html'
|
|
37
43
|
PAGE_TITLE = _('Unit of Measures')
|
|
38
44
|
context_object_name = 'uom_list'
|
|
@@ -43,7 +49,7 @@ class UnitOfMeasureModelListView(DjangoLedgerSecurityMixIn, UnitOfMeasureModelMo
|
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
|
|
46
|
-
class UnitOfMeasureModelCreateView(
|
|
52
|
+
class UnitOfMeasureModelCreateView(UnitOfMeasureModelModelBaseView, CreateView):
|
|
47
53
|
template_name = 'django_ledger/uom/uom_create.html'
|
|
48
54
|
PAGE_TITLE = _('Create Unit of Measure')
|
|
49
55
|
extra_context = {
|
|
@@ -92,7 +98,7 @@ class UnitOfMeasureModelCreateView(DjangoLedgerSecurityMixIn, UnitOfMeasureModel
|
|
|
92
98
|
return super().form_valid(form)
|
|
93
99
|
|
|
94
100
|
|
|
95
|
-
class UnitOfMeasureModelUpdateView(
|
|
101
|
+
class UnitOfMeasureModelUpdateView(UnitOfMeasureModelModelBaseView, UpdateView):
|
|
96
102
|
template_name = 'django_ledger/uom/uom_update.html'
|
|
97
103
|
PAGE_TITLE = _('Update Unit of Measure')
|
|
98
104
|
context_object_name = 'uom'
|
|
@@ -118,7 +124,7 @@ class UnitOfMeasureModelUpdateView(DjangoLedgerSecurityMixIn, UnitOfMeasureModel
|
|
|
118
124
|
)
|
|
119
125
|
|
|
120
126
|
|
|
121
|
-
class UnitOfMeasureModelDeleteView(
|
|
127
|
+
class UnitOfMeasureModelDeleteView(UnitOfMeasureModelModelBaseView, DeleteView):
|
|
122
128
|
pk_url_kwarg = 'uom_pk'
|
|
123
129
|
template_name = 'django_ledger/uom/uom_delete.html'
|
|
124
130
|
context_object_name = 'uom_model'
|
|
@@ -150,23 +156,21 @@ class UnitOfMeasureModelDeleteView(DjangoLedgerSecurityMixIn, UnitOfMeasureModel
|
|
|
150
156
|
|
|
151
157
|
|
|
152
158
|
# PRODUCTS VIEWS...
|
|
153
|
-
class
|
|
159
|
+
class ProductItemModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
154
160
|
queryset = None
|
|
155
161
|
|
|
156
162
|
def get_queryset(self):
|
|
157
163
|
if not self.queryset:
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
'
|
|
163
|
-
'
|
|
164
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
165
|
+
self.queryset = entity_model.itemmodel_set.products().select_related(
|
|
166
|
+
'earnings_account',
|
|
167
|
+
'cogs_account',
|
|
168
|
+
'inventory_account',
|
|
169
|
+
'uom').order_by('-updated')
|
|
164
170
|
return super().get_queryset()
|
|
165
171
|
|
|
166
172
|
|
|
167
|
-
class ProductListView(
|
|
168
|
-
ProductItemModelModelViewQuerySetMixIn,
|
|
169
|
-
ListView):
|
|
173
|
+
class ProductListView(ProductItemModelModelBaseView, ListView):
|
|
170
174
|
template_name = 'django_ledger/product/product_list.html'
|
|
171
175
|
PAGE_TITLE = _('Products')
|
|
172
176
|
context_object_name = 'product_list'
|
|
@@ -177,9 +181,7 @@ class ProductListView(DjangoLedgerSecurityMixIn,
|
|
|
177
181
|
}
|
|
178
182
|
|
|
179
183
|
|
|
180
|
-
class ProductCreateView(
|
|
181
|
-
ProductItemModelModelViewQuerySetMixIn,
|
|
182
|
-
CreateView):
|
|
184
|
+
class ProductCreateView(ProductItemModelModelBaseView, CreateView):
|
|
183
185
|
template_name = 'django_ledger/product/product_create.html'
|
|
184
186
|
model = ItemModel
|
|
185
187
|
PAGE_TITLE = _('Create New Product')
|
|
@@ -212,9 +214,7 @@ class ProductCreateView(DjangoLedgerSecurityMixIn,
|
|
|
212
214
|
return super().form_valid(form=form)
|
|
213
215
|
|
|
214
216
|
|
|
215
|
-
class ProductUpdateView(
|
|
216
|
-
ProductItemModelModelViewQuerySetMixIn,
|
|
217
|
-
UpdateView):
|
|
217
|
+
class ProductUpdateView(ProductItemModelModelBaseView, UpdateView):
|
|
218
218
|
template_name = 'django_ledger/product/product_update.html'
|
|
219
219
|
PAGE_TITLE = _('Update Product')
|
|
220
220
|
context_object_name = 'item'
|
|
@@ -226,10 +226,10 @@ class ProductUpdateView(DjangoLedgerSecurityMixIn,
|
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
def get_queryset(self):
|
|
229
|
-
return ItemModel.objects.
|
|
230
|
-
entity_slug=self.
|
|
229
|
+
return ItemModel.objects.for_entity(
|
|
230
|
+
entity_slug=self.AUTHORIZED_ENTITY_MODEL,
|
|
231
231
|
user_model=self.request.user
|
|
232
|
-
)
|
|
232
|
+
).products()
|
|
233
233
|
|
|
234
234
|
def get_form(self, form_class=None):
|
|
235
235
|
return ProductUpdateForm(
|
|
@@ -245,9 +245,7 @@ class ProductUpdateView(DjangoLedgerSecurityMixIn,
|
|
|
245
245
|
})
|
|
246
246
|
|
|
247
247
|
|
|
248
|
-
class ProductDeleteView(
|
|
249
|
-
ProductItemModelModelViewQuerySetMixIn,
|
|
250
|
-
DeleteView):
|
|
248
|
+
class ProductDeleteView(ProductItemModelModelBaseView, DeleteView):
|
|
251
249
|
template_name = 'django_ledger/product/product_delete.html'
|
|
252
250
|
pk_url_kwarg = 'item_pk'
|
|
253
251
|
context_object_name = 'item_model'
|
|
@@ -280,23 +278,21 @@ class ProductDeleteView(DjangoLedgerSecurityMixIn,
|
|
|
280
278
|
|
|
281
279
|
|
|
282
280
|
# SERVICES VIEWS...
|
|
283
|
-
class
|
|
281
|
+
class ServiceItemModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
284
282
|
queryset = None
|
|
285
283
|
|
|
286
284
|
def get_queryset(self):
|
|
287
285
|
if not self.queryset:
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
'
|
|
293
|
-
'
|
|
286
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
287
|
+
self.queryset = entity_model.itemmodel_set.services().select_related(
|
|
288
|
+
'earnings_account',
|
|
289
|
+
'cogs_account',
|
|
290
|
+
'inventory_account',
|
|
291
|
+
'uom').order_by('-updated')
|
|
294
292
|
return super().get_queryset()
|
|
295
293
|
|
|
296
294
|
|
|
297
|
-
class ServiceListView(
|
|
298
|
-
ServiceItemModelModelViewQuerySetMixIn,
|
|
299
|
-
ListView):
|
|
295
|
+
class ServiceListView(ServiceItemModelModelBaseView, ListView):
|
|
300
296
|
template_name = 'django_ledger/service/service_list.html'
|
|
301
297
|
PAGE_TITLE = _('Services')
|
|
302
298
|
context_object_name = 'service_list'
|
|
@@ -307,9 +303,7 @@ class ServiceListView(DjangoLedgerSecurityMixIn,
|
|
|
307
303
|
}
|
|
308
304
|
|
|
309
305
|
|
|
310
|
-
class ServiceCreateView(
|
|
311
|
-
ServiceItemModelModelViewQuerySetMixIn,
|
|
312
|
-
CreateView):
|
|
306
|
+
class ServiceCreateView(ServiceItemModelModelBaseView, CreateView):
|
|
313
307
|
template_name = 'django_ledger/service/service_create.html'
|
|
314
308
|
model = ItemModel
|
|
315
309
|
PAGE_TITLE = _('Create New Service')
|
|
@@ -341,9 +335,7 @@ class ServiceCreateView(DjangoLedgerSecurityMixIn,
|
|
|
341
335
|
return super().form_valid(form=form)
|
|
342
336
|
|
|
343
337
|
|
|
344
|
-
class ServiceUpdateView(
|
|
345
|
-
ServiceItemModelModelViewQuerySetMixIn,
|
|
346
|
-
UpdateView):
|
|
338
|
+
class ServiceUpdateView(ServiceItemModelModelBaseView, UpdateView):
|
|
347
339
|
template_name = 'django_ledger/service/service_update.html'
|
|
348
340
|
PAGE_TITLE = _('Update Service')
|
|
349
341
|
context_object_name = 'item'
|
|
@@ -374,9 +366,7 @@ class ServiceUpdateView(DjangoLedgerSecurityMixIn,
|
|
|
374
366
|
})
|
|
375
367
|
|
|
376
368
|
|
|
377
|
-
class ServiceDeleteView(
|
|
378
|
-
ServiceItemModelModelViewQuerySetMixIn,
|
|
379
|
-
DeleteView):
|
|
369
|
+
class ServiceDeleteView(ServiceItemModelModelBaseView, DeleteView):
|
|
380
370
|
template_name = 'django_ledger/service/service_delete.html'
|
|
381
371
|
pk_url_kwarg = 'item_pk'
|
|
382
372
|
context_object_name = 'item_model'
|
|
@@ -409,20 +399,19 @@ class ServiceDeleteView(DjangoLedgerSecurityMixIn,
|
|
|
409
399
|
|
|
410
400
|
|
|
411
401
|
# EXPENSE ITEMS VIEW...
|
|
412
|
-
|
|
413
|
-
class ExpenseItemItemModelModelViewQuerySetMixIn:
|
|
402
|
+
class ExpenseItemItemModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
414
403
|
queryset = None
|
|
415
404
|
|
|
416
405
|
def get_queryset(self):
|
|
417
406
|
if not self.queryset:
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
407
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
408
|
+
self.queryset = entity_model.itemmodel_set.expenses().select_related(
|
|
409
|
+
'expense_account',
|
|
410
|
+
'uom').order_by('-updated')
|
|
422
411
|
return super().get_queryset()
|
|
423
412
|
|
|
424
413
|
|
|
425
|
-
class ExpenseItemModelListView(
|
|
414
|
+
class ExpenseItemModelListView(ExpenseItemItemModelModelBaseView, ListView):
|
|
426
415
|
template_name = 'django_ledger/expense/expense_list.html'
|
|
427
416
|
PAGE_TITLE = _('Expense Items')
|
|
428
417
|
context_object_name = 'expense_list'
|
|
@@ -433,7 +422,7 @@ class ExpenseItemModelListView(DjangoLedgerSecurityMixIn, ExpenseItemItemModelMo
|
|
|
433
422
|
}
|
|
434
423
|
|
|
435
424
|
|
|
436
|
-
class ExpenseItemCreateView(
|
|
425
|
+
class ExpenseItemCreateView(ExpenseItemItemModelModelBaseView, CreateView):
|
|
437
426
|
template_name = 'django_ledger/expense/expense_create.html'
|
|
438
427
|
model = ItemModel
|
|
439
428
|
PAGE_TITLE = _('Create New Expense Item')
|
|
@@ -466,7 +455,7 @@ class ExpenseItemCreateView(DjangoLedgerSecurityMixIn, ExpenseItemItemModelModel
|
|
|
466
455
|
return super().form_valid(form=form)
|
|
467
456
|
|
|
468
457
|
|
|
469
|
-
class ExpenseItemUpdateView(
|
|
458
|
+
class ExpenseItemUpdateView(ExpenseItemItemModelModelBaseView, UpdateView):
|
|
470
459
|
template_name = 'django_ledger/expense/expense_update.html'
|
|
471
460
|
PAGE_TITLE = _('Update Expense Item')
|
|
472
461
|
context_object_name = 'item'
|
|
@@ -493,20 +482,21 @@ class ExpenseItemUpdateView(DjangoLedgerSecurityMixIn, ExpenseItemItemModelModel
|
|
|
493
482
|
|
|
494
483
|
|
|
495
484
|
# INVENTORY VIEWS...
|
|
496
|
-
|
|
497
|
-
class InventoryItemItemModelModelViewQuerySetMixIn:
|
|
485
|
+
class InventoryItemItemModelModelBaseView(DjangoLedgerSecurityMixIn):
|
|
498
486
|
queryset = None
|
|
499
487
|
|
|
500
488
|
def get_queryset(self):
|
|
501
489
|
if not self.queryset:
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
490
|
+
entity_model: EntityModel = self.get_authorized_entity_instance()
|
|
491
|
+
self.queryset = entity_model.itemmodel_set.inventory_wip().select_related(
|
|
492
|
+
'inventory_account',
|
|
493
|
+
'cogs_account',
|
|
494
|
+
'uom'
|
|
495
|
+
).order_by('-updated')
|
|
506
496
|
return super().get_queryset()
|
|
507
497
|
|
|
508
498
|
|
|
509
|
-
class InventoryItemModelListView(
|
|
499
|
+
class InventoryItemModelListView(InventoryItemItemModelModelBaseView, ListView):
|
|
510
500
|
template_name = 'django_ledger/inventory/inventory_item_list.html'
|
|
511
501
|
PAGE_TITLE = _('Inventory Items')
|
|
512
502
|
context_object_name = 'inventory_item_list'
|
|
@@ -517,7 +507,7 @@ class InventoryItemModelListView(DjangoLedgerSecurityMixIn, InventoryItemItemMod
|
|
|
517
507
|
}
|
|
518
508
|
|
|
519
509
|
|
|
520
|
-
class InventoryItemCreateView(
|
|
510
|
+
class InventoryItemCreateView(InventoryItemItemModelModelBaseView, CreateView):
|
|
521
511
|
template_name = 'django_ledger/inventory/inventory_item_create.html'
|
|
522
512
|
model = ItemModel
|
|
523
513
|
PAGE_TITLE = _('Create New Inventory Item')
|
|
@@ -554,7 +544,7 @@ class InventoryItemCreateView(DjangoLedgerSecurityMixIn, InventoryItemItemModelM
|
|
|
554
544
|
return super().form_valid(form=form)
|
|
555
545
|
|
|
556
546
|
|
|
557
|
-
class InventoryItemUpdateView(
|
|
547
|
+
class InventoryItemUpdateView(InventoryItemItemModelModelBaseView, UpdateView):
|
|
558
548
|
template_name = 'django_ledger/inventory/inventory_item_update.html'
|
|
559
549
|
PAGE_TITLE = _('Update Inventory Item')
|
|
560
550
|
context_object_name = 'item'
|
|
@@ -3,7 +3,7 @@ Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
4
|
|
|
5
5
|
Contributions to this module:
|
|
6
|
-
Miguel Sanda <msanda@arrobalytics.com>
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
from django.contrib import messages
|
|
9
9
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
django_ledger/views/ledger.py
CHANGED
|
@@ -3,7 +3,7 @@ Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
4
|
|
|
5
5
|
Contributions to this module:
|
|
6
|
-
Miguel Sanda <msanda@arrobalytics.com>
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
from django.contrib import messages
|
|
9
9
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|
@@ -38,6 +38,7 @@ class LedgerModelModelViewQuerySetMixIn:
|
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
class LedgerModelListView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuerySetMixIn, ArchiveIndexView):
|
|
41
|
+
allow_empty = True
|
|
41
42
|
context_object_name = 'ledger_list'
|
|
42
43
|
template_name = 'django_ledger/ledger/ledger_list.html'
|
|
43
44
|
PAGE_TITLE = _('Entity Ledgers')
|
|
@@ -49,6 +50,7 @@ class LedgerModelListView(DjangoLedgerSecurityMixIn, LedgerModelModelViewQuerySe
|
|
|
49
50
|
date_field = 'created'
|
|
50
51
|
ordering = '-created'
|
|
51
52
|
|
|
53
|
+
|
|
52
54
|
show_all = False
|
|
53
55
|
show_current = False
|
|
54
56
|
show_visible = False
|
django_ledger/views/mixins.py
CHANGED
|
@@ -3,7 +3,7 @@ Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
4
|
|
|
5
5
|
Contributions to this module:
|
|
6
|
-
Miguel Sanda <msanda@arrobalytics.com>
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from calendar import monthrange
|
|
@@ -389,7 +389,6 @@ class EntityUnitMixIn:
|
|
|
389
389
|
|
|
390
390
|
|
|
391
391
|
class DigestContextMixIn:
|
|
392
|
-
|
|
393
392
|
IO_DIGEST_UNBOUNDED = False
|
|
394
393
|
IO_DIGEST_BOUNDED = False
|
|
395
394
|
|
|
@@ -522,7 +521,8 @@ class BaseDateNavigationUrlMixIn:
|
|
|
522
521
|
'entity_slug',
|
|
523
522
|
'unit_slug',
|
|
524
523
|
'ledger_pk',
|
|
525
|
-
'account_pk'
|
|
524
|
+
'account_pk',
|
|
525
|
+
'coa_slug'
|
|
526
526
|
)
|
|
527
527
|
|
|
528
528
|
def get_context_data(self, **kwargs):
|
|
@@ -533,11 +533,12 @@ class BaseDateNavigationUrlMixIn:
|
|
|
533
533
|
def get_base_date_nav_url(self, context, **kwargs):
|
|
534
534
|
view_name = context['view'].request.resolver_match.url_name
|
|
535
535
|
view_name_base = '-'.join(view_name.split('-')[:2])
|
|
536
|
-
context['date_navigation_url'] = reverse(
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
536
|
+
context['date_navigation_url'] = reverse(
|
|
537
|
+
f'django_ledger:{view_name_base}',
|
|
538
|
+
kwargs={
|
|
539
|
+
k: v for k, v in self.kwargs.items() if
|
|
540
|
+
k in self.BASE_DATE_URL_KWARGS
|
|
541
|
+
})
|
|
541
542
|
|
|
542
543
|
|
|
543
544
|
class PDFReportMixIn:
|
|
@@ -3,7 +3,7 @@ Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
4
|
|
|
5
5
|
Contributions to this module:
|
|
6
|
-
Miguel Sanda <msanda@arrobalytics.com>
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
from django.contrib import messages
|
|
9
9
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
django_ledger/views/unit.py
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
3
|
+
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
|
+
|
|
5
|
+
Contributions to this module:
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
|
|
1
10
|
from django.http import HttpResponseRedirect
|
|
2
11
|
from django.shortcuts import get_object_or_404
|
|
3
12
|
from django.urls import reverse
|
django_ledger/views/vendor.py
CHANGED
|
@@ -3,7 +3,7 @@ Django Ledger created by Miguel Sanda <msanda@arrobalytics.com>.
|
|
|
3
3
|
Copyright© EDMA Group Inc licensed under the GPLv3 Agreement.
|
|
4
4
|
|
|
5
5
|
Contributions to this module:
|
|
6
|
-
Miguel Sanda <msanda@arrobalytics.com>
|
|
6
|
+
* Miguel Sanda <msanda@arrobalytics.com>
|
|
7
7
|
"""
|
|
8
8
|
from django.shortcuts import get_object_or_404
|
|
9
9
|
from django.urls import reverse
|
|
@@ -7,12 +7,18 @@ Django Ledger was created by [Miguel Sanda](https://github.com/elarroba).
|
|
|
7
7
|
### Project Maintainers
|
|
8
8
|
* Miguel Sanda [@elarroba](https://github.com/elarroba)
|
|
9
9
|
|
|
10
|
-
### Developers
|
|
10
|
+
### Developers
|
|
11
11
|
* Miguel Sanda [@elarroba](https://github.com/elarroba)
|
|
12
|
+
|
|
13
|
+
### Contributors
|
|
12
14
|
* Michael Noel [@mnooel](https://github.com/mnooel)
|
|
13
15
|
* Eric Owuor [@Ericpaul](https://github.com/25-do)
|
|
16
|
+
* Pranav P Tulshyan
|
|
14
17
|
|
|
15
18
|
### Accountants, CPAs & Bookkeepers
|
|
16
19
|
* Miguel Sanda [@elarroba](https://github.com/elarroba)
|
|
17
20
|
* Albert Salazar [@Beachwood619](https://github.com/Beachwood619)
|
|
18
|
-
* Michael Noel, CPA [@mnooel](https://github.com/mnooel)
|
|
21
|
+
* Michael Noel, CPA [@mnooel](https://github.com/mnooel)
|
|
22
|
+
|
|
23
|
+
### Documentation Contributors
|
|
24
|
+
* Miguel Sanda [@elarroba](https://github.com/elarroba)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: django-ledger
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Double entry accounting system built on the Django Web Framework.
|
|
5
5
|
Author-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
6
6
|
Maintainer-email: Miguel Sanda <msanda@arrobalytics.com>
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
14
14
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
15
15
|
Classifier: Topic :: Office/Business :: Financial :: Accounting
|
|
16
16
|
Classifier: Framework :: Django :: 4.0
|
|
17
|
+
Classifier: Framework :: Django :: 5.0
|
|
17
18
|
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
18
19
|
Classifier: Intended Audience :: End Users/Desktop
|
|
19
20
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
@@ -40,59 +41,49 @@ Requires-Dist: furo ; extra == 'dev'
|
|
|
40
41
|
|
|
41
42
|

|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
Here's a more concise and readable version of the Django Ledger README:
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
using the [Django Web Framework](https://www.djangoproject.com). Developed by lead developer Miguel Sanda, this system
|
|
47
|
-
offers a simplified, high-level API, making it easier for users to navigate the complexities of accounting.
|
|
46
|
+
# Django Ledger
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
in contributing, consider joining our new discord channel for further collaboration and discussions.
|
|
48
|
+
## A Double Entry Accounting Engine for Django
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
Django Ledger is a powerful financial management system built on the Django Web Framework. It offers a simplified API for handling complex accounting tasks in financially driven applications.
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
[Join our Discord](https://discord.gg/c7PZcbYgrc) | [Documentation](https://django-ledger.readthedocs.io/en/latest/) | [QuickStart Notebook](https://github.com/arrobalytics/django-ledger/blob/develop/notebooks/QuickStart%20Notebook.ipynb)
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
Also, you may download the QuickStart Jupyter Notebook
|
|
58
|
-
[here](https://github.com/arrobalytics/django-ledger/blob/develop/notebooks/QuickStart%20Notebook.ipynb).
|
|
54
|
+
## Key Features
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
- High-level API
|
|
57
|
+
- Double entry accounting
|
|
58
|
+
- Hierarchical Chart of Accounts
|
|
59
|
+
- Financial statements (Income Statement, Balance Sheet, Cash Flow)
|
|
60
|
+
- Purchase Orders, Sales Orders, Bills, and Invoices
|
|
61
|
+
- Financial ratio calculations
|
|
62
|
+
- Multi-tenancy support
|
|
63
|
+
- Ledgers, Journal Entries & Transactions
|
|
64
|
+
- OFX & QFX file import
|
|
65
|
+
- Closing Entries
|
|
66
|
+
- Inventory management
|
|
67
|
+
- Unit of Measures
|
|
68
|
+
- Bank account information
|
|
69
|
+
- Django Admin integration
|
|
70
|
+
- Built-in Entity Management UI
|
|
61
71
|
|
|
62
|
-
|
|
63
|
-
- Double entry accounting system.
|
|
64
|
-
- Multiple Hierarchical Chart of Accounts.
|
|
65
|
-
- Financial Statements (Income Statement, Balance Sheet & Cash Flow Statement).
|
|
66
|
-
- Purchase Orders, Sales Orders (Estimates), Bills and Invoices.
|
|
67
|
-
- Automatic financial ratio & insight calculations.
|
|
68
|
-
- Multi tenancy (multiple companies/users/clients).
|
|
69
|
-
- Self-contained Ledgers, Journal Entries & Transactions.
|
|
70
|
-
- Basic OFX & QFX file import.
|
|
71
|
-
- Closing Entries.
|
|
72
|
-
- Items, lists & inventory management.
|
|
73
|
-
- Unit of Measures.
|
|
74
|
-
- Bank Accounts Information.
|
|
75
|
-
- Django Admin Classes.
|
|
76
|
-
- Built In Entity Management UI.
|
|
72
|
+
## Getting Involved
|
|
77
73
|
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
- **Feature Requests/Bug Reports**: Open an issue in the repository
|
|
75
|
+
- **For software customization, advanced features and consulting services**:
|
|
76
|
+
[Contact us](https://www.miguelsanda.com/work-with-me/) or email msanda@arrobalytics.com
|
|
77
|
+
- **Contribute**: See our [contribution guidelines](https://github.com/arrobalytics/django-ledger/blob/master/Contribute.md)
|
|
80
78
|
|
|
81
|
-
|
|
79
|
+
## Who Should Contribute?
|
|
82
80
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
We're looking for contributors with:
|
|
82
|
+
- Python and Django programming skills
|
|
83
|
+
- Finance and accounting expertise
|
|
84
|
+
- Interest in developing a robust accounting engine API
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
is a big plus for potential contributors. If you have the relevant experience and want to contribute, feel free to
|
|
90
|
-
reach out to me or submit your pull request.
|
|
91
|
-
|
|
92
|
-
You can find the contribution guidelines at the specified link.
|
|
93
|
-
The project welcomes anyone interested in making a contribution.
|
|
94
|
-
|
|
95
|
-
See __[contribution guidelines](https://github.com/arrobalytics/django-ledger/blob/develop/Contribute.md)__.
|
|
86
|
+
If you have relevant experience, especially in accounting, we welcome your pull requests or direct contact.
|
|
96
87
|
|
|
97
88
|
# Installation
|
|
98
89
|
|