├── requirements.txt ├── sales ├── tests.py ├── admin.py ├── apps.py ├── forms.py ├── templates │ └── sales │ │ ├── add_sale.html │ │ ├── add_product.html │ │ ├── add_customer.html │ │ ├── add_branch.html │ │ ├── add_accounting.html │ │ └── add_ledger.html ├── settings.py ├── models.py ├── urls.py └── views.py ├── structure.lua ├── manage.py └── LICENSE /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==3.2.9 2 | django-crispy-forms==1.12.0 3 | -------------------------------------------------------------------------------- /sales/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /sales/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /sales/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SalesConfig(AppConfig): 5 | default_auto_field = 'django.db.models.BigAutoField' 6 | name = 'sales' 7 | -------------------------------------------------------------------------------- /sales/forms.py: -------------------------------------------------------------------------------- 1 | # sales/forms.py 2 | 3 | from django import forms 4 | from .models import Sale 5 | 6 | class SaleForm(forms.ModelForm): 7 | class Meta: 8 | model = Sale 9 | fields = ['product', 'customer', 'quantity'] 10 | 11 | -------------------------------------------------------------------------------- /sales/templates/sales/add_sale.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% extends 'base.html' %} 4 | 5 | {% block content %} 6 |

Add Sale

7 |
8 | {% csrf_token %} 9 | {{ form.as_p }} 10 | 11 |
12 | {% endblock %} 13 | 14 | -------------------------------------------------------------------------------- /sales/templates/sales/add_product.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'base.html' %} 3 | 4 | {% block content %} 5 |

Add Product

6 |
7 | {% csrf_token %} 8 | {{ form.as_p }} 9 | 10 |
11 | {% endblock %} 12 | 13 | -------------------------------------------------------------------------------- /sales/templates/sales/add_customer.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'base.html' %} 3 | 4 | {% block content %} 5 |

Add Customer

6 |
7 | {% csrf_token %} 8 | {{ form.as_p }} 9 | 10 |
11 | {% endblock %} 12 | 13 | -------------------------------------------------------------------------------- /sales/templates/sales/add_branch.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'base.html' %} 3 | 4 | {% block content %} 5 |

Add Branch

6 |
7 | {% csrf_token %} 8 | 9 | 10 |
11 | {% endblock %} 12 | 13 | -------------------------------------------------------------------------------- /sales/templates/sales/add_accounting.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'base.html' %} 3 | 4 | {% block content %} 5 |

Add Accounting Record

6 |
7 | {% csrf_token %} 8 | 9 | 10 |
11 | {% endblock %} 12 | 13 | -------------------------------------------------------------------------------- /sales/settings.py: -------------------------------------------------------------------------------- 1 | # sales/settings.py 2 | 3 | # Database settings 4 | DATABASES = { 5 | 'default': { 6 | 'ENGINE': 'django.db.backends.mysql', 7 | 'NAME': 'your_database_name', 8 | 'USER': 'your_database_user', 9 | 'PASSWORD': 'your_database_password', 10 | 'HOST': 'localhost', 11 | 'PORT': '3306', 12 | } 13 | } 14 | 15 | # Add other settings as needed, such as static files, templates, etc. 16 | 17 | -------------------------------------------------------------------------------- /structure.lua: -------------------------------------------------------------------------------- 1 | mysite/ 2 | |-- manage.py 3 | |-- mysite/ 4 | | |-- __init__.py 5 | | |-- asgi.py 6 | | |-- settings.py 7 | | |-- urls.py 8 | | |-- wsgi.py 9 | |-- sales/ 10 | | |-- migrations/ 11 | | | |-- __init__.py 12 | | |-- templates/ 13 | | | |-- sales/ 14 | | | |-- add_cash_account_entry.html 15 | | | |-- cash_accounts_list.html 16 | | | |-- ... (other templates) 17 | | |-- __init__.py 18 | | |-- admin.py 19 | | |-- apps.py 20 | | |-- forms.py 21 | | |-- models.py 22 | | |-- tests.py 23 | | |-- urls.py 24 | | |-- views.py 25 | |-- venv/ (virtual environment - optional) 26 | |-- requirements.txt 27 | -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """Django's command-line utility for administrative tasks.""" 3 | import os 4 | import sys 5 | 6 | 7 | def main(): 8 | """Run administrative tasks.""" 9 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sales.settings') 10 | try: 11 | from django.core.management import execute_from_command_line 12 | except ImportError as exc: 13 | raise ImportError( 14 | "Couldn't import Django. Are you sure it's installed and " 15 | "available on your PYTHONPATH environment variable? Did you " 16 | "forget to activate a virtual environment?" 17 | ) from exc 18 | execute_from_command_line(sys.argv) 19 | 20 | 21 | if __name__ == '__main__': 22 | main() 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Victor Adly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sales/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | 4 | class Product(models.Model): 5 | name = models.CharField(max_length=255) 6 | price = models.DecimalField(max_digits=10, decimal_places=2) 7 | 8 | class Customer(models.Model): 9 | user = models.OneToOneField(User, on_delete=models.CASCADE) 10 | credit_limit = models.DecimalField(max_digits=10, decimal_places=2) 11 | 12 | class Sale(models.Model): 13 | product = models.ForeignKey(Product, on_delete=models.CASCADE) 14 | customer = models.ForeignKey(Customer, on_delete=models.CASCADE) 15 | quantity = models.IntegerField() 16 | total_price = models.DecimalField(max_digits=10, decimal_places=2) 17 | 18 | class Inventory(models.Model): 19 | product = models.OneToOneField(Product, on_delete=models.CASCADE) 20 | quantity = models.IntegerField() 21 | 22 | class Branch(models.Model): 23 | name = models.CharField(max_length=255) 24 | # Add other branch-related fields as needed 25 | 26 | class Accounting(models.Model): 27 | in_amount = models.DecimalField(max_digits=10, decimal_places=2) 28 | out_amount = models.DecimalField(max_digits=10, decimal_places=2) 29 | description = models.TextField() 30 | # Add other accounting-related fields as needed 31 | # Add more models as needed for branches, accounting, etc. 32 | 33 | -------------------------------------------------------------------------------- /sales/templates/sales/add_ledger.html: -------------------------------------------------------------------------------- 1 | 2 | {% extends 'base.html' %} 3 | 4 | {% block content %} 5 |

Add Ledger Entry

6 |
7 | {% csrf_token %} 8 | 9 | 10 |
11 | {% endblock %} 12 | 13 | 14 | {% extends 'base.html' %} 15 | 16 | {% block content %} 17 |

Ledgers List

18 | 23 | {% endblock %} 24 | 25 | 26 | {% extends 'base.html' %} 27 | 28 | {% block content %} 29 |

Add Trial Balance Entry

30 |
31 | {% csrf_token %} 32 | 33 | 34 |
35 | {% endblock %} 36 | 37 | 38 | {% extends 'base.html' %} 39 | 40 | {% block content %} 41 |

Trial Balances List

42 | 47 | {% endblock %} 48 | 49 | -------------------------------------------------------------------------------- /sales/urls.py: -------------------------------------------------------------------------------- 1 | """ 2 | URL configuration for sales_app project. 3 | 4 | The `urlpatterns` list routes URLs to views. For more information please see: 5 | https://docs.djangoproject.com/en/5.0/topics/http/urls/ 6 | Examples: 7 | Function views 8 | 1. Add an import: from my_app import views 9 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 10 | Class-based views 11 | 1. Add an import: from other_app.views import Home 12 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 13 | Including another URLconf 14 | 1. Import the include() function: from django.urls import include, path 15 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 16 | """ 17 | from django.contrib import admin 18 | from django.urls import path 19 | from .views import add_sale, add_product, add_customer, add_branch, add_accounting, add_expense, expenses_list 20 | from .views import add_general_journal, general_journals_list, add_ledger, ledgers_list, add_trial_balance, trial_balances_list 21 | from .views import add_income_summary, income_summaries_list 22 | 23 | urlpatterns = [ 24 | path('admin/', admin.site.urls), 25 | path('add-sale/', add_sale, name='add_sale'), 26 | path('add-product/', add_product, name='add_product'), 27 | path('add-customer/', add_customer, name='add_customer'), 28 | path('add-branch/', add_branch, name='add_branch'), 29 | path('add-accounting/', add_accounting, name='add_accounting'), 30 | path('add-expense/', add_expense, name='add_expense'), 31 | path('expenses-list/', expenses_list, name='expenses_list'), 32 | path('add-general-journal/', add_general_journal, name='add_general_journal'), 33 | path('general-journals-list/', general_journals_list, name='general_journals_list'), 34 | path('add-ledger/', add_ledger, name='add_ledger'), 35 | path('ledgers-list/', ledgers_list, name='ledgers_list'), 36 | path('add-trial-balance/', add_trial_balance, name='add_trial_balance'), 37 | path('trial-balances-list/', trial_balances_list, name='trial_balances_list'), 38 | path('add-income-summary/', add_income_summary, name='add_income_summary'), 39 | path('income-summaries-list/', income_summaries_list, name='income_summaries_list'), 40 | ] 41 | -------------------------------------------------------------------------------- /sales/views.py: -------------------------------------------------------------------------------- 1 | # sales/views.py 2 | 3 | from django.shortcuts import render, redirect 4 | from .models import Product, Customer, Sale, Inventory, Branch, Accounting, Expense, GeneralJournal, JournalEntry 5 | from .models import Ledger, TrialBalance, IncomeSummary, Deposit, Withdraw, CashDiscount, SalesReturnsAllowances 6 | from .models import Purchases, PurchasesReturnsAllowances, NotesReceivable, AccountsReceivable, InventoryAdjustingEntry, AdjustingEntry 7 | from .forms import SaleForm, ProductForm, CustomerForm, ExpenseForm, GeneralJournalForm, JournalEntryForm 8 | from .forms import LedgerForm, TrialBalanceForm, IncomeSummaryForm, DepositForm, WithdrawForm, CashDiscountForm, SalesReturnsAllowancesForm 9 | from .forms import PurchasesForm, PurchasesReturnsAllowancesForm, NotesReceivableForm, AccountsReceivableForm, InventoryAdjustingEntryForm, AdjustingEntryForm 10 | 11 | def add_sale(request): 12 | if request.method == 'POST': 13 | # Handle form submission and add sale to the database 14 | # Remember to validate the form data and handle errors 15 | # ... 16 | 17 | products = Product.objects.all() 18 | customers = Customer.objects.all() 19 | return render(request, 'sales/add_sale.html', {'products': products, 'customers': customers}) 20 | 21 | def add_income_summary(request): 22 | if request.method == 'POST': 23 | form = IncomeSummaryForm(request.POST) 24 | if form.is_valid(): 25 | form.save() 26 | return redirect('income_summaries_list') 27 | else: 28 | form = IncomeSummaryForm() 29 | 30 | return render(request, 'sales/add_income_summary.html', {'form': form}) 31 | 32 | def income_summaries_list(request): 33 | summaries = IncomeSummary.objects.all() 34 | return render(request, 'sales/income_summaries_list.html', {'summaries': summaries}) 35 | 36 | def add_branch(request): 37 | if request.method == 'POST': 38 | # Handle form submission and add branch to the database 39 | # Remember to validate the form data and handle errors 40 | # ... 41 | 42 | return render(request, 'sales/add_branch.html') 43 | 44 | def add_accounting(request): 45 | if request.method == 'POST': 46 | # Handle form submission and add accounting record to the database 47 | # Remember to validate the form data and handle errors 48 | # ... 49 | 50 | return render(request, 'sales/add_accounting.html') 51 | 52 | # Implement views for other modules similarly 53 | def add_ledger(request): 54 | if request.method == 'POST': 55 | form = LedgerForm(request.POST) 56 | if form.is_valid(): 57 | form.save() 58 | return redirect('ledgers_list') 59 | else: 60 | form = LedgerForm() 61 | 62 | return render(request, 'sales/add_ledger.html', {'form': form}) 63 | 64 | def ledgers_list(request): 65 | ledgers = Ledger.objects.all() 66 | return render(request, 'sales/ledgers_list.html', {'ledgers': ledgers}) 67 | 68 | def add_trial_balance(request): 69 | if request.method == 'POST': 70 | form = TrialBalanceForm(request.POST) 71 | if form.is_valid(): 72 | form.save() 73 | return redirect('trial_balances_list') 74 | else: 75 | form = TrialBalanceForm() 76 | 77 | return render(request, 'sales/add_trial_balance.html', {'form': form}) 78 | 79 | def trial_balances_list(request): 80 | trial_balances = TrialBalance.objects.all() 81 | return render(request, 'sales/trial_balances_list.html', {'trial_balances': trial_balances}) 82 | 83 | # Implement views for other financial statements similarly 84 | --------------------------------------------------------------------------------