diff --git a/README.md b/README.md index 6284db8..66d27b0 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Setup with Virtualenv You can run the Ra demo locally #### Dependencies -* Python 3.4, 3.5 or 3.6 +* Python 3.4, 3.5 , 3.6 or 3.10 * [Virtualenv](https://virtualenv.pypa.io/en/stable/installation/) * [PostgresSql](https://www.postgresql.org/download/) * [VirtualenvWrapper](https://virtualenvwrapper.readthedocs.io/en/latest/install.html) (optional) diff --git a/myproject/myproject/environ.env b/myproject/myproject/environ.env new file mode 100644 index 0000000..fb9879d --- /dev/null +++ b/myproject/myproject/environ.env @@ -0,0 +1,3 @@ +DATABASE_NAME='test' +DATABASE_USER='admin' +DATABASE_PASSWORD='admin' \ No newline at end of file diff --git a/myproject/myproject/settings.py b/myproject/myproject/settings.py index a52a12a..b0ef69a 100644 --- a/myproject/myproject/settings.py +++ b/myproject/myproject/settings.py @@ -36,7 +36,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - + 'jazzmin', 'crequest', 'crispy_forms', 'reversion', @@ -134,9 +134,9 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': f'{env("DATABASE_NAME")}', - 'USER': f'{env("DATABASE_USER")}', - 'PASSWORD': f'{env("DATABASE_PASSWORD")}', + 'NAME': f'{env("test")}', + 'USER': f'{env("admin")}', + 'PASSWORD': f'{env("admin")}', 'HOST': '', 'PORT': '5432', } diff --git a/myproject/sales/admin.py b/myproject/sales/admin.py index d58b719..35f32e7 100644 --- a/myproject/sales/admin.py +++ b/myproject/sales/admin.py @@ -1,29 +1,31 @@ -from django import forms -from ra.admin.admin import ra_admin_site, RaAdmin, RaMovementAdmin -from .models import Client, Product, SimpleSales +from .models import Client, Product, Expense, ExpenseTransaction, SalesLineTransaction, SalesTransaction +from ra.admin.admin import ra_admin_site, EntityAdmin, TransactionAdmin, TransactionItemAdmin -class ClientAdmin(RaAdmin): - fields = ('slug', 'title', 'notes', 'address', 'email', 'telephone') - view_template = 'sales/admin/client_view.html' +class ExpenseAdmin(EntityAdmin): + pass + +class ProductAdmin(EntityAdmin): + pass -class ProductAdmin(RaAdmin): +class ClientAdmin(EntityAdmin): pass -class SalesOrderAdmin(RaMovementAdmin): - fields = ['slug', 'doc_date', 'client', ('product', 'price', 'quantity', 'value')] - add_form_template = change_form_template = 'sales/admin/salesorder_changeform.html' +class SalesLineAdmin(TransactionItemAdmin): + fields = ('product', 'price', 'quantity', 'value') + model = SalesLineTransaction + - def formfield_for_dbfield(self, db_field, request, **kwargs): - formfield = super().formfield_for_dbfield(db_field, request, **kwargs) - if db_field.name == 'value': - formfield.widget = forms.TextInput(attrs={'readonly': 'readonly'}) - return formfield +class SalesOrderAdmin(TransactionAdmin): + inlines = [SalesLineAdmin] + fields = ['slug', 'doc_date', 'client', ] + copy_to_formset = ['client'] ra_admin_site.register(Client, ClientAdmin) ra_admin_site.register(Product, ProductAdmin) -ra_admin_site.register(SimpleSales, SalesOrderAdmin) +ra_admin_site.register(Expense, ExpenseAdmin) +ra_admin_site.register(SalesTransaction, SalesOrderAdmin) \ No newline at end of file diff --git a/myproject/sales/apps.py b/myproject/sales/apps.py index 181473f..b63497c 100644 --- a/myproject/sales/apps.py +++ b/myproject/sales/apps.py @@ -2,6 +2,7 @@ class SalesConfig(AppConfig): + name = 'sales' def ready(self): diff --git a/myproject/sales/models.py b/myproject/sales/models.py index d73f475..32ef2a6 100644 --- a/myproject/sales/models.py +++ b/myproject/sales/models.py @@ -1,35 +1,47 @@ from django.db import models - -from django.db import models -from ra.base.models import BaseInfo, BasePersonInfo, BaseMovementInfo, QuanValueMovementItem +from ra.base.models import EntityModel, TransactionModel, TransactionItemModel, QuantitativeTransactionItemModel from ra.base.registry import register_doc_type -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ -class Product(BaseInfo): +class Product(EntityModel): class Meta: verbose_name = _('Product') verbose_name_plural = _('Products') - -class Client(BasePersonInfo): +class Client(EntityModel): class Meta: verbose_name = _('Client') verbose_name_plural = _('Clients') -class SimpleSales(QuanValueMovementItem): - client = models.ForeignKey(Client, on_delete=models.CASCADE) - product = models.ForeignKey(Product, on_delete=models.CASCADE) +class Expense(EntityModel): + class Meta: + verbose_name = _('Expense') + verbose_name_plural = _('Expenses') + + +class ExpenseTransaction(TransactionItemModel): + expense = models.ForeignKey(Expense, on_delete=models.CASCADE) - @classmethod - def get_doc_type(cls): - return 'sales' + class Meta: + verbose_name = _('Expense Transaction') + verbose_name_plural = _('Expense Transactions') + + +class SalesTransaction(TransactionModel): + client = models.ForeignKey(Client, on_delete=models.CASCADE) class Meta: verbose_name = _('Sale') verbose_name_plural = _('Sales') -sales = {'name': 'sales', 'plus_list': ['Client'], 'minus_list': ['Product'], } -register_doc_type(sales) +class SalesLineTransaction(QuantitativeTransactionItemModel): + sales_transaction = models.ForeignKey(SalesTransaction, on_delete=models.CASCADE) + product = models.ForeignKey(Product, on_delete=models.CASCADE) + client = models.ForeignKey(Client, on_delete=models.CASCADE) + + class Meta: + verbose_name = _('Sale Transaction Line') + verbose_name_plural = _('Sale Transaction Lines') \ No newline at end of file diff --git a/myproject/sales/reports.py b/myproject/sales/reports.py index 6bc3f0b..ddb7dd7 100644 --- a/myproject/sales/reports.py +++ b/myproject/sales/reports.py @@ -1,7 +1,7 @@ -from django.utils.translation import ugettext_lazy as _ -from ra.reporting.decorators import register_report_view +from django.utils.translation import gettext_lazy as _ +from ra.reporting.registry import register_report_view from ra.reporting.views import ReportView -from .models import Client, SimpleSales, Product +from .models import Client, SalesLineTransaction, Product @register_report_view @@ -9,7 +9,7 @@ class ClientTotalBalance(ReportView): report_title = _('Clients Balances') base_model = Client - report_model = SimpleSales + report_model = SalesLineTransaction form_settings = {'group_by': 'client', 'group_columns': ['slug', 'title', '__balance__']} @@ -40,10 +40,10 @@ class ProductTotalSales(ReportView): base_model = Product # What model hold the data that we want to compute. - report_model = SimpleSales + report_model = SalesLineTransaction # The meat and potato of the report. - # We group the records in SimpleSales by Client , + # We group the records in SalesLineTransaction by Client , # And we display the columns `slug` and `title` (relative to the `base_model` defined above) # the magic field `__balance__` computes the balance (of the base model) form_settings = {'group_by': 'product', @@ -54,7 +54,7 @@ class ClientList(ReportView): report_title = _('Our Clients') base_model = Client - report_model = SimpleSales + report_model = SalesLineTransaction # will not appear on the reports menu hidden = True @@ -73,7 +73,7 @@ class ProductClientSales(ReportView): report_title = _('Client Sales for each product') base_model = Client - report_model = SimpleSales + report_model = SalesLineTransaction must_exist_filter = 'client_id' header_report = ClientList @@ -88,7 +88,7 @@ class ProductClientSales(ReportView): class ClientDetailedStatement(ReportView): report_title = _('client Statement') base_model = Client - report_model = SimpleSales + report_model = SalesLineTransaction must_exist_filter = 'client_id' header_report = ClientList @@ -103,7 +103,7 @@ class ProductSalesMonthly(ReportView): report_title = _('Product Sales Monthly') base_model = Product - report_model = SimpleSales + report_model = SalesLineTransaction form_settings = { 'group_by': 'product', @@ -172,7 +172,7 @@ class ClientSalesMonthlySeries(ReportView): report_title = _('Client Sales Monthly') base_model = Client - report_model = SimpleSales + report_model = SalesLineTransaction form_settings = { 'group_by': 'client', @@ -186,7 +186,7 @@ class ClientSalesMonthlySeries(ReportView): @register_report_view class ProductClientSalesMatrix(ReportView): base_model = Product - report_model = SimpleSales + report_model = SalesLineTransaction report_title = _('Product Client sales Cross-tab') form_settings = { diff --git a/myproject/sales/templates/sales/admin/salesorder_changeform.html b/myproject/sales/templates/sales/admin/salesorder_changeform.html index c4801ac..8d9902b 100644 --- a/myproject/sales/templates/sales/admin/salesorder_changeform.html +++ b/myproject/sales/templates/sales/admin/salesorder_changeform.html @@ -1,19 +1,30 @@ -{% extends RA_THEME|add:'/change_form.html' %} +{% extends 'ra/change_form.html' %} -{% block admin_change_form_document_ready %} - -{% endblock %} + allQuantity.on('change', calculateTotal); + allPrice.on('change', calculateTotal); + + // The newly created rows + // ref: https://docs.djangoproject.com/en/2.2/ref/contrib/admin/javascript/ + django.jQuery(document).on('formset:added', function (event, $row, formsetName) { + $row.find('[name*=quantity]').on('change', calculateTotal) + $row.find('[name*=price]').on('change', calculateTotal) + }); + }) + +{% endblock %} \ No newline at end of file diff --git a/myproject/sales/templates/sales/index.html b/myproject/sales/templates/sales/index.html index 37bb17a..2755daf 100644 --- a/myproject/sales/templates/sales/index.html +++ b/myproject/sales/templates/sales/index.html @@ -1,19 +1,9 @@ -{% extends 'ra/admin/base_site.html' %} -{% load ra_admin_tags %} +{% extends 'ra/base_site.html' %} +{% load ra_admin_tags ra_tags %} {% block content %} -{% get_report base_model='client' report_slug='clienttotalbalance' as client_balances %} -
- -
-
- -
- - -
-
- -{% endblock %} +
+ {% get_report base_model='product' report_slug='ProductSalesMonthly' as ProductSalesMonthly %} + {% get_html_panel ProductSalesMonthly %} +
+{% endblock %} \ No newline at end of file