fix many bugs

This commit is contained in:
Suherdy Yacob 2025-08-19 12:28:49 +07:00
parent a3ce1a8843
commit 80a514f1de
52 changed files with 50041 additions and 47183 deletions

View File

@ -8,6 +8,7 @@ A comprehensive Django-based manufacturing management application with modern UI
- **Simple Manufacturing Orders**: Input end product results without complex BOM requirements
- **Production Tracking**: Monitor daily, weekly, and monthly production metrics
- **Cost Management**: Track labor and overhead costs for manufacturing orders
- **Edit/Delete Orders**: Admin/superuser can edit or delete manufacturing orders
### 📦 Inventory Management
- **Product Management**: Complete product catalog with categories, pricing, and stock levels
@ -188,6 +189,12 @@ basic_manufacture_app/
3. Add labor and overhead costs
4. Save the order (automatically updates inventory)
### Editing a Manufacturing Order
1. Navigate to Manufacturing → Order List
2. Click on the order to view details
3. Click "Edit" button (admin/superuser only)
4. Modify order details and save
### Managing Inventory
1. Go to Inventory → Products
2. Add new products with categories and pricing

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -452,6 +452,18 @@
('core.apps',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\apps.py',
'PYMODULE'),
('core.management',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\management\\__init__.py',
'PYMODULE'),
('core.management.commands',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\management\\commands\\__init__.py',
'PYMODULE'),
('core.management.commands.check_database',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\management\\commands\\check_database.py',
'PYMODULE'),
('core.management.commands.populate_test_data',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\management\\commands\\populate_test_data.py',
'PYMODULE'),
('core.urls',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\core\\urls.py',
'PYMODULE'),
@ -6098,6 +6110,9 @@
('users.forms',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\users\\forms.py',
'PYMODULE'),
('users.management',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\users\\management\\__init__.py',
'PYMODULE'),
('users.migrations',
'D:\\Pythoncode\\Django_Basic_Manufacturing\\users\\migrations\\__init__.py',
'PYMODULE'),

Binary file not shown.

Binary file not shown.

View File

@ -14,9 +14,12 @@ Types if import:
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named pyimod02_importers - imported by D:\Pythoncode\Django_Basic_Manufacturing\.venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed), D:\Pythoncode\Django_Basic_Manufacturing\.venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgres.py (delayed)
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), getpass (delayed), http.server (delayed, optional), webbrowser (delayed), netrc (delayed, conditional), smtpd (conditional, optional), distutils.util (delayed, conditional, optional), distutils.archive_util (optional), setuptools._distutils.archive_util (optional), setuptools._distutils.util (delayed, conditional, optional)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), distutils.archive_util (optional), setuptools._distutils.archive_util (optional)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional), django.core.files.locks (conditional, optional), pty (delayed, optional)
missing module named 'org.python' - imported by copy (optional), xml.sax (delayed, conditional)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level), pip._vendor.distlib.resources (optional)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level), pip._vendor.distlib.resources (optional)
missing module named org - imported by pickle (optional)
missing module named urllib.splittype - imported by urllib (conditional), pip._vendor.distlib.compat (conditional)
missing module named urllib.ContentTooShortError - imported by urllib (conditional), pip._vendor.distlib.compat (conditional)
@ -25,18 +28,15 @@ missing module named urllib.url2pathname - imported by urllib (conditional), pip
missing module named urllib.unquote - imported by urllib (conditional), pip._vendor.distlib.compat (conditional)
missing module named urllib.quote - imported by urllib (conditional), pip._vendor.distlib.compat (conditional)
missing module named urllib.urlretrieve - imported by urllib (conditional), pip._vendor.distlib.compat (conditional)
missing module named posix - imported by os (conditional, optional), posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional)
missing module named posix - imported by posixpath (optional), shutil (conditional), importlib._bootstrap_external (conditional), os (conditional, optional)
missing module named resource - imported by posix (top-level), test.support (delayed, conditional, optional)
missing module named grp - imported by shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), distutils.archive_util (optional), setuptools._distutils.archive_util (optional)
missing module named pwd - imported by posixpath (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), subprocess (delayed, conditional, optional), getpass (delayed), http.server (delayed, optional), webbrowser (delayed), netrc (delayed, conditional), smtpd (conditional, optional), distutils.util (delayed, conditional, optional), distutils.archive_util (optional), setuptools._distutils.archive_util (optional), setuptools._distutils.util (delayed, conditional, optional)
missing module named pyimod02_importers - imported by D:\Pythoncode\Django_Basic_Manufacturing\.venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgutil.py (delayed), D:\Pythoncode\Django_Basic_Manufacturing\.venv\Lib\site-packages\PyInstaller\hooks\rthooks\pyi_rth_pkgres.py (delayed)
missing module named _posixsubprocess - imported by subprocess (conditional), multiprocessing.util (delayed)
missing module named fcntl - imported by subprocess (optional), django.core.files.locks (conditional, optional), pty (delayed, optional)
missing module named _manylinux - imported by pip._vendor.packaging._manylinux (delayed, optional), packaging._manylinux (delayed, optional), setuptools._vendor.packaging._manylinux (delayed, optional), pkg_resources._vendor.packaging._manylinux (delayed, optional)
missing module named jinja2 - imported by django.template.backends.jinja2 (top-level), django.test.utils (optional), pkg_resources._vendor.pyparsing.diagram (top-level), setuptools._vendor.pyparsing.diagram (top-level)
missing module named pyparsing - imported by pkg_resources._vendor.pyparsing.diagram (top-level), setuptools._vendor.pyparsing.diagram (top-level)
missing module named railroad - imported by pkg_resources._vendor.pyparsing.diagram (top-level), setuptools._vendor.pyparsing.diagram (top-level)
missing module named termios - imported by django.utils.autoreload (optional), getpass (optional), tty (top-level)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional), zipimport (top-level), pip._vendor.distlib.resources (optional)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional), zipimport (top-level), pip._vendor.distlib.resources (optional)
missing module named readline - imported by code (delayed, conditional, optional), django.core.management.commands.shell (delayed, optional), rlcompleter (optional), cmd (delayed, conditional, optional), pdb (delayed, optional), site (delayed, optional), pstats (conditional, optional), django_extensions.management.commands.shell_plus (delayed, optional)
missing module named 'pkg_resources.extern.pyparsing' - imported by pkg_resources._vendor.packaging.markers (top-level), pkg_resources._vendor.packaging.requirements (top-level)
missing module named 'pkg_resources.extern.importlib_resources' - imported by pkg_resources._vendor.jaraco.text (optional)
@ -90,6 +90,16 @@ missing module named defusedxml - imported by PIL.Image (optional)
missing module named pytz - imported by django.utils.timezone (delayed, conditional), django.db.backends.base.base (delayed, conditional), django.templatetags.tz (delayed, conditional)
missing module named _typeshed - imported by asgiref.sync (conditional), pip._vendor.pkg_resources (conditional)
missing module named backports - imported by django.utils.timezone (optional), django.db.backends.base.base (optional), django.templatetags.tz (optional)
missing module named colorama - imported by django.core.management.color (optional)
missing module named win32evtlog - imported by logging.handlers (delayed, optional)
missing module named win32evtlogutil - imported by logging.handlers (delayed, optional)
missing module named redis - imported by django.core.cache.backends.redis (delayed), pip._vendor.cachecontrol.caches.redis_cache (conditional)
missing module named pymemcache - imported by django.core.cache.backends.memcached (delayed)
missing module named pylibmc - imported by django.core.cache.backends.memcached (delayed)
missing module named django.db.models.BooleanField - imported by django.db.models (delayed), django.db.models.query_utils (delayed), django.db.models.sql.where (delayed), django.contrib.gis.db.models.functions (top-level), django.contrib.postgres.aggregates.general (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.DurationField - imported by django.db.models (top-level), django.db.backends.oracle.functions (top-level)
missing module named django.db.models.DecimalField - imported by django.db.models (top-level), django.db.backends.oracle.functions (top-level)
missing module named django.db.models.NOT_PROVIDED - imported by django.db.models (top-level), django.db.models.base (top-level), django.db.migrations.operations.fields (top-level), django.db.migrations.state (top-level), django.db.migrations.questioner (top-level), django.db.backends.mysql.schema (top-level)
missing module named 'psycopg.types' - imported by django.db.backends.postgresql.psycopg_any (optional), django.db.backends.postgresql.operations (conditional), django.contrib.gis.db.backends.postgis.base (conditional), django.contrib.postgres.signals (conditional)
missing module named 'psycopg.pq' - imported by django.db.backends.postgresql.base (conditional), django.contrib.gis.db.backends.postgis.base (conditional)
missing module named 'psycopg.postgres' - imported by django.db.backends.postgresql.psycopg_any (optional)
@ -98,34 +108,27 @@ missing module named cx_Oracle - imported by django.db.backends.oracle.base (opt
missing module named 'MySQLdb.converters' - imported by django.db.backends.mysql.base (top-level)
missing module named 'MySQLdb.constants' - imported by django.db.backends.mysql.base (top-level), django.db.backends.mysql.introspection (top-level), django.contrib.gis.db.backends.mysql.introspection (top-level)
missing module named MySQLdb - imported by django.db.backends.mysql.base (optional), django_extensions.management.commands.drop_test_database (delayed, conditional), django_extensions.management.commands.reset_db (delayed, conditional)
missing module named colorama - imported by django.core.management.color (optional)
missing module named win32evtlog - imported by logging.handlers (delayed, optional)
missing module named win32evtlogutil - imported by logging.handlers (delayed, optional)
missing module named redis - imported by django.core.cache.backends.redis (delayed), pip._vendor.cachecontrol.caches.redis_cache (conditional)
missing module named pymemcache - imported by django.core.cache.backends.memcached (delayed)
missing module named pylibmc - imported by django.core.cache.backends.memcached (delayed)
missing module named django.db.models.Max - imported by django.db.models (top-level), django.db.models.base (top-level)
missing module named django.db.models.IntegerField - imported by django.db.models (top-level), django.db.models.base (top-level), django.contrib.gis.db.models.functions (top-level), django.contrib.postgres.fields.array (top-level), django.contrib.postgres.aggregates.statistics (top-level)
missing module named django.db.models.NOT_PROVIDED - imported by django.db.models (top-level), django.db.models.base (top-level), django.db.migrations.operations.fields (top-level), django.db.migrations.state (top-level), django.db.migrations.questioner (top-level), django.db.backends.mysql.schema (top-level)
missing module named django.db.models.Field - imported by django.db.models (top-level), django.db.models.query (top-level), django.forms.models (delayed), django.contrib.admin.views.main (top-level), django.contrib.gis.db.models.fields (top-level), django.contrib.postgres.search (top-level), django.contrib.postgres.fields.array (top-level), django.contrib.postgres.fields.hstore (top-level)
missing module named django.db.models.DateTimeField - imported by django.db.models (top-level), django.db.models.query (top-level), django.contrib.postgres.functions (top-level), django_extensions.db.fields (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.DateField - imported by django.db.models (top-level), django.db.models.query (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.DurationField - imported by django.db.models (top-level), django.db.backends.oracle.functions (top-level)
missing module named django.db.models.DecimalField - imported by django.db.models (top-level), django.db.backends.oracle.functions (top-level)
missing module named django.db.models.BooleanField - imported by django.db.models (delayed), django.db.models.query_utils (delayed), django.db.models.sql.where (delayed), django.contrib.gis.db.models.functions (top-level), django.contrib.postgres.aggregates.general (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.UniqueConstraint - imported by django.db.models (top-level), django.db.models.options (top-level), django.db.backends.mysql.schema (top-level), django.db.backends.sqlite3.schema (top-level), django_extensions.db.fields (top-level), django_extensions.management.commands.sqldiff (top-level)
missing module named django.db.models.AutoField - imported by django.db.models (top-level), django.db.models.options (top-level), django.db.models.query (top-level), django.forms.models (delayed), django.db.backends.oracle.operations (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named pywatchman - imported by django.utils.autoreload (optional)
missing module named django.db.models.Field - imported by django.db.models (top-level), django.db.models.query (top-level), django.forms.models (delayed), django.contrib.admin.views.main (top-level), django.contrib.gis.db.models.fields (top-level), django.contrib.postgres.search (top-level), django.contrib.postgres.fields.array (top-level), django.contrib.postgres.fields.hstore (top-level)
missing module named django.db.models.DateTimeField - imported by django.db.models (top-level), django.db.models.query (top-level), django.contrib.postgres.functions (top-level), django_extensions.db.fields (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.DateField - imported by django.db.models (top-level), django.db.models.query (top-level), django_extensions.management.commands.dumpscript (top-level)
missing module named django.db.models.Max - imported by django.db.models (top-level), django.db.models.base (top-level)
missing module named django.db.models.IntegerField - imported by django.db.models (top-level), django.db.models.base (top-level), django.contrib.gis.db.models.functions (top-level), django.contrib.postgres.fields.array (top-level), django.contrib.postgres.aggregates.statistics (top-level)
missing module named collections.MutableMapping - imported by collections (optional), pip._vendor.urllib3._collections (optional), pip._vendor.distlib.compat (optional)
missing module named collections.Mapping - imported by collections (optional), pip._vendor.urllib3._collections (optional)
missing module named tblib - imported by django.test.runner (optional)
missing module named ipdb - imported by django.test.runner (optional), django_extensions.management.utils (delayed, optional), django_extensions.management.commands.runserver_plus (delayed, conditional, optional)
missing module named bpython - imported by django.core.management.commands.shell (delayed), django_extensions.management.commands.shell_plus (delayed, optional)
missing module named ConfigParser - imported by pip._vendor.distlib.compat (conditional), decouple (conditional)
missing module named 'pygments.lexers' - imported by django_extensions.templatetags.highlighting (optional), django_extensions.templatetags.syntax_color (optional)
missing module named 'pygments.formatters' - imported by django_extensions.management.debug_cursor (delayed, conditional, optional), django_extensions.templatetags.highlighting (optional), django_extensions.templatetags.syntax_color (optional)
missing module named pygments - imported by django_extensions.management.debug_cursor (delayed, conditional, optional), django_extensions.templatetags.highlighting (optional), django_extensions.templatetags.syntax_color (optional)
missing module named 'mongoengine.queryset' - imported by django_extensions.mongodb.models (top-level)
missing module named 'mongoengine.fields' - imported by django_extensions.mongodb.models (top-level), django_extensions.mongodb.fields (top-level)
missing module named 'mongoengine.document' - imported by django_extensions.mongodb.models (top-level)
missing module named IPython - imported by django_extensions.management.utils (delayed, optional), django_extensions.management.commands.shell_plus (delayed, optional)
missing module named ipdb - imported by django.test.runner (optional), django_extensions.management.utils (delayed, optional), django_extensions.management.commands.runserver_plus (delayed, conditional, optional)
missing module named mongoengine - imported by django_extensions.management.shells (delayed, optional)
missing module named 'pygments.formatters' - imported by django_extensions.templatetags.syntax_color (optional), django_extensions.templatetags.highlighting (optional), django_extensions.management.debug_cursor (delayed, conditional, optional)
missing module named 'pygments.lexers' - imported by django_extensions.templatetags.syntax_color (optional), django_extensions.templatetags.highlighting (optional), django_extensions.management.debug_cursor (delayed, conditional, optional)
missing module named boto - imported by django_extensions.management.commands.sync_s3 (optional)
missing module named 'prompt_toolkit.contrib' - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named 'ptpython.ipython' - imported by django_extensions.management.commands.shell_plus (delayed, optional)
@ -133,7 +136,6 @@ missing module named 'ptpython.repl' - imported by django_extensions.management.
missing module named prompt_toolkit - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named ptpython - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named 'IPython.Shell' - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named bpython - imported by django.core.management.commands.shell (delayed), django_extensions.management.commands.shell_plus (delayed, optional)
missing module named 'notebook.notebookapp' - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named jupyterlab - imported by django_extensions.management.commands.shell_plus (delayed, optional)
missing module named 'IPython.frontend' - imported by django_extensions.management.commands.shell_plus (delayed, optional)
@ -161,7 +163,6 @@ missing module named 'pip._vendor.rich.markdown' - imported by pip._vendor.rich.
missing module named _abcoll - imported by pip._vendor.distlib.compat (optional)
missing module named dummy_thread - imported by pip._vendor.distlib.compat (optional)
missing module named thread - imported by pip._vendor.distlib.compat (optional)
missing module named collections.MutableMapping - imported by collections (optional), pip._vendor.urllib3._collections (optional), pip._vendor.distlib.compat (optional)
missing module named htmlentitydefs - imported by pip._vendor.distlib.compat (conditional)
missing module named HTMLParser - imported by pip._vendor.distlib.compat (conditional)
missing module named Queue - imported by pip._vendor.urllib3.util.queue (conditional), pip._vendor.distlib.compat (conditional)
@ -179,7 +180,6 @@ missing module named 'cryptography.x509' - imported by pip._vendor.urllib3.contr
missing module named 'cryptography.hazmat' - imported by pip._vendor.urllib3.contrib.pyopenssl (top-level)
missing module named cryptography - imported by pip._vendor.urllib3.contrib.pyopenssl (top-level), pip._vendor.requests (conditional, optional)
missing module named 'OpenSSL.SSL' - imported by pip._vendor.urllib3.contrib.pyopenssl (top-level)
missing module named collections.Mapping - imported by collections (optional), pip._vendor.urllib3._collections (optional)
missing module named socks - imported by pip._vendor.urllib3.contrib.socks (optional)
missing module named pip.__file__ - imported by pip (top-level), pip._internal.build_env (top-level)
missing module named filelock - imported by pip._vendor.cachecontrol.caches.file_cache (delayed, conditional, optional)
@ -195,8 +195,8 @@ missing module named pydotplus - imported by django_extensions.management.comman
missing module named pygraphviz - imported by django_extensions.management.commands.graph_models (optional)
missing module named vobject - imported by django_extensions.management.commands.export_emails (delayed, optional)
missing module named shortuuid - imported by django_extensions.db.fields (optional)
missing module named pygments - imported by django_extensions.templatetags.syntax_color (optional), django_extensions.templatetags.highlighting (optional)
missing module named selenium - imported by django.test.selenium (delayed, conditional)
missing module named tblib - imported by django.test.runner (optional)
missing module named django.contrib.postgres.fields.ArrayField - imported by django.contrib.postgres.fields (top-level), django.contrib.postgres.expressions (top-level), django.contrib.postgres.aggregates.general (top-level)
missing module named 'geoip2.database' - imported by django.contrib.gis.geoip2.base (top-level)
missing module named geoip2 - imported by django.contrib.gis.geoip2 (optional)

View File

@ -156,6 +156,8 @@ imports:
&#8226; <a href="#core">core</a>
&#8226; <a href="#crispy_bootstrap5">crispy_bootstrap5</a>
&#8226; <a href="#crispy_forms">crispy_forms</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#django.conf">django.conf</a>
&#8226; <a href="#django.contrib.admin">django.contrib.admin</a>
&#8226; <a href="#django.contrib.admin.apps">django.contrib.admin.apps</a>
&#8226; <a href="#django.contrib.auth">django.contrib.auth</a>
@ -169,6 +171,17 @@ imports:
&#8226; <a href="#django.contrib.staticfiles">django.contrib.staticfiles</a>
&#8226; <a href="#django.contrib.staticfiles.apps">django.contrib.staticfiles.apps</a>
&#8226; <a href="#django.core.management">django.core.management</a>
&#8226; <a href="#django.db">django.db</a>
&#8226; <a href="#django.db.models">django.db.models</a>
&#8226; <a href="#django.db.models.fields">django.db.models.fields</a>
&#8226; <a href="#django.db.models.fields.related">django.db.models.fields.related</a>
&#8226; <a href="#django.db.models.fields.reverse_related">django.db.models.fields.reverse_related</a>
&#8226; <a href="#django.db.utils">django.db.utils</a>
&#8226; <a href="#django.forms">django.forms</a>
&#8226; <a href="#django.forms.boundfield">django.forms.boundfield</a>
&#8226; <a href="#django.forms.fields">django.forms.fields</a>
&#8226; <a href="#django.forms.models">django.forms.models</a>
&#8226; <a href="#django.forms.widgets">django.forms.widgets</a>
&#8226; <a href="#django_extensions">django_extensions</a>
&#8226; <a href="#encodings">encodings</a>
&#8226; <a href="#encodings.aliases">encodings.aliases</a>
@ -306,6 +319,7 @@ imports:
&#8226; <a href="#ntpath">ntpath</a>
&#8226; <a href="#operator">operator</a>
&#8226; <a href="#os">os</a>
&#8226; <a href="#pathlib">pathlib</a>
&#8226; <a href="#posixpath">posixpath</a>
&#8226; <a href="#purchase">purchase</a>
&#8226; <a href="#pyi_rth__tkinter.py">pyi_rth__tkinter.py</a>
@ -326,6 +340,7 @@ imports:
&#8226; <a href="#sre_constants">sre_constants</a>
&#8226; <a href="#sre_parse">sre_parse</a>
&#8226; <a href="#stat">stat</a>
&#8226; <a href="#sys">sys</a>
&#8226; <a href="#traceback">traceback</a>
&#8226; <a href="#types">types</a>
&#8226; <a href="#users">users</a>
@ -801,7 +816,8 @@ imported by:
<a target="code" href="" type="text/plain"><tt>'pygments.lexers'</tt></a>
<span class="moduletype">MissingModule</span> <div class="import">
imported by:
<a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
<a href="#django_extensions.management.debug_cursor">django_extensions.management.debug_cursor</a>
&#8226; <a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
&#8226; <a href="#django_extensions.templatetags.syntax_color">django_extensions.templatetags.syntax_color</a>
</div>
@ -6969,6 +6985,7 @@ imports:
imported by:
<a href="#core">core</a>
&#8226; <a href="#core.apps">core.apps</a>
&#8226; <a href="#core.management">core.management</a>
&#8226; <a href="#core.urls">core.urls</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
@ -6995,6 +7012,83 @@ imported by:
</div>
<div class="node">
<a name="core.management"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/core/management/__init__.py" type="text/plain"><tt>core.management</tt></a>
<span class="moduletype">Package</span> <div class="import">
imports:
<a href="#core">core</a>
</div>
<div class="import">
imported by:
<a href="#core.management.commands">core.management.commands</a>
&#8226; <a href="#django">django</a>
</div>
</div>
<div class="node">
<a name="core.management.commands"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/core/management/commands/__init__.py" type="text/plain"><tt>core.management.commands</tt></a>
<span class="moduletype">Package</span> <div class="import">
imports:
<a href="#core.management">core.management</a>
</div>
<div class="import">
imported by:
<a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#django">django</a>
</div>
</div>
<div class="node">
<a name="core.management.commands.check_database"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/core/management/commands/check_database.py" type="text/plain"><tt>core.management.commands.check_database</tt></a>
<span class="moduletype">SourceModule</span> <div class="import">
imports:
<a href="#core.management.commands">core.management.commands</a>
&#8226; <a href="#django.conf">django.conf</a>
&#8226; <a href="#django.core.management.base">django.core.management.base</a>
&#8226; <a href="#os">os</a>
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.models">sales.models</a>
</div>
<div class="import">
imported by:
<a href="#django">django</a>
</div>
</div>
<div class="node">
<a name="core.management.commands.populate_test_data"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/core/management/commands/populate_test_data.py" type="text/plain"><tt>core.management.commands.populate_test_data</tt></a>
<span class="moduletype">SourceModule</span> <div class="import">
imports:
<a href="#core.management.commands">core.management.commands</a>
&#8226; <a href="#django.core.management.base">django.core.management.base</a>
&#8226; <a href="#django.db">django.db</a>
&#8226; <a href="#django.db.transaction">django.db.transaction</a>
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.models">sales.models</a>
</div>
<div class="import">
imported by:
<a href="#django">django</a>
</div>
</div>
<div class="node">
<a name="core.urls"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/core/urls.py" type="text/plain"><tt>core.urls</tt></a>
@ -7037,10 +7131,14 @@ imports:
&#8226; <a href="#inventory.models">inventory.models</a>
&#8226; <a href="#manufacture.models">manufacture.models</a>
&#8226; <a href="#os">os</a>
&#8226; <a href="#pathlib">pathlib</a>
&#8226; <a href="#purchase.forms">purchase.forms</a>
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.forms">sales.forms</a>
&#8226; <a href="#sales.models">sales.models</a>
&#8226; <a href="#shutil">shutil</a>
&#8226; <a href="#sqlite3">sqlite3</a>
&#8226; <a href="#sys">sys</a>
</div>
<div class="import">
@ -9114,6 +9212,10 @@ imported by:
imports:
<a href="#core">core</a>
&#8226; <a href="#core.apps">core.apps</a>
&#8226; <a href="#core.management">core.management</a>
&#8226; <a href="#core.management.commands">core.management.commands</a>
&#8226; <a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#core.urls">core.urls</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#crispy_bootstrap5">crispy_bootstrap5</a>
@ -10073,6 +10175,7 @@ imports:
&#8226; <a href="#users.admin">users.admin</a>
&#8226; <a href="#users.apps">users.apps</a>
&#8226; <a href="#users.forms">users.forms</a>
&#8226; <a href="#users.management">users.management</a>
&#8226; <a href="#users.migrations">users.migrations</a>
&#8226; <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
&#8226; <a href="#users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more">users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more</a>
@ -10151,6 +10254,7 @@ imported by:
&#8226; <a href="#manufacture.forms">manufacture.forms</a>
&#8226; <a href="#purchase.forms">purchase.forms</a>
&#8226; <a href="#sales.forms">sales.forms</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#users.forms">users.forms</a>
</div>
@ -10373,7 +10477,8 @@ imports:
</div>
<div class="import">
imported by:
<a href="#core.views">core.views</a>
<a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#crispy_forms.templatetags.crispy_forms_field">crispy_forms.templatetags.crispy_forms_field</a>
&#8226; <a href="#crispy_forms.templatetags.crispy_forms_filters">crispy_forms.templatetags.crispy_forms_filters</a>
&#8226; <a href="#crispy_forms.templatetags.crispy_forms_tags">crispy_forms.templatetags.crispy_forms_tags</a>
@ -10590,6 +10695,7 @@ imported by:
&#8226; <a href="#manufacture_app.urls">manufacture_app.urls</a>
&#8226; <a href="#purchase.migrations.0001_initial">purchase.migrations.0001_initial</a>
&#8226; <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
</div>
@ -23134,7 +23240,9 @@ imports:
</div>
<div class="import">
imported by:
<a href="#django">django</a>
<a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#django.contrib.auth.management.commands.changepassword">django.contrib.auth.management.commands.changepassword</a>
&#8226; <a href="#django.contrib.auth.management.commands.createsuperuser">django.contrib.auth.management.commands.createsuperuser</a>
&#8226; <a href="#django.contrib.gis.management.commands.ogrinspect">django.contrib.gis.management.commands.ogrinspect</a>
@ -24443,7 +24551,8 @@ imports:
</div>
<div class="import">
imported by:
<a href="#core.views">core.views</a>
<a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#django.contrib.admin.checks">django.contrib.admin.checks</a>
&#8226; <a href="#django.contrib.admin.filters">django.contrib.admin.filters</a>
@ -24625,6 +24734,7 @@ imported by:
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
&#8226; <a href="#sales.models">sales.models</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
&#8226; <a href="#users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more">users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more</a>
&#8226; <a href="#users.models">users.models</a>
@ -26835,6 +26945,7 @@ imported by:
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
&#8226; <a href="#sales.models">sales.models</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
&#8226; <a href="#users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more">users.migrations.0002_remove_customuser_user_type_remove_usergroup_users_and_more</a>
&#8226; <a href="#users.models">users.models</a>
@ -27325,6 +27436,7 @@ imported by:
&#8226; <a href="#django.db.models.lookups">django.db.models.lookups</a>
&#8226; <a href="#django.db.models.sql.query">django.db.models.sql.query</a>
&#8226; <a href="#django_extensions.management.commands.sqldiff">django_extensions.management.commands.sqldiff</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -27482,6 +27594,7 @@ imported by:
&#8226; <a href="#django.db.models">django.db.models</a>
&#8226; <a href="#django.db.models.base">django.db.models.base</a>
&#8226; <a href="#django_extensions.management.modelviz">django_extensions.management.modelviz</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -27557,6 +27670,7 @@ imported by:
<a href="#django">django</a>
&#8226; <a href="#django.db.models.fields.related">django.db.models.fields.related</a>
&#8226; <a href="#django_extensions.management.modelviz">django_extensions.management.modelviz</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -28242,7 +28356,8 @@ imports:
</div>
<div class="import">
imported by:
<a href="#django">django</a>
<a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#django.contrib.admin.options">django.contrib.admin.options</a>
&#8226; <a href="#django.contrib.auth.admin">django.contrib.auth.admin</a>
&#8226; <a href="#django.contrib.auth.migrations.0011_update_proxy_permissions">django.contrib.auth.migrations.0011_update_proxy_permissions</a>
@ -28300,6 +28415,7 @@ imported by:
&#8226; <a href="#django.db.backends.sqlite3.features">django.db.backends.sqlite3.features</a>
&#8226; <a href="#django.db.models.constraints">django.db.models.constraints</a>
&#8226; <a href="#django.test.signals">django.test.signals</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -28407,6 +28523,7 @@ imported by:
&#8226; <a href="#manufacture.forms">manufacture.forms</a>
&#8226; <a href="#purchase.forms">purchase.forms</a>
&#8226; <a href="#sales.forms">sales.forms</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#users.forms">users.forms</a>
</div>
@ -28434,6 +28551,7 @@ imported by:
&#8226; <a href="#django">django</a>
&#8226; <a href="#django.forms">django.forms</a>
&#8226; <a href="#django.forms.fields">django.forms.fields</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -28481,6 +28599,7 @@ imported by:
&#8226; <a href="#django.forms.formsets">django.forms.formsets</a>
&#8226; <a href="#django.forms.models">django.forms.models</a>
&#8226; <a href="#django.test.testcases">django.test.testcases</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -28578,6 +28697,7 @@ imported by:
&#8226; <a href="#django.contrib.contenttypes.forms">django.contrib.contenttypes.forms</a>
&#8226; <a href="#django.forms">django.forms</a>
&#8226; <a href="#django.views.generic.edit">django.views.generic.edit</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -28687,6 +28807,7 @@ imported by:
&#8226; <a href="#django.forms.forms">django.forms.forms</a>
&#8226; <a href="#django.forms.formsets">django.forms.formsets</a>
&#8226; <a href="#django.forms.models">django.forms.models</a>
&#8226; <a href="#start_server.py">start_server.py</a>
</div>
@ -34745,6 +34866,7 @@ imported by:
<span class="moduletype">SourceModule</span> <div class="import">
imports:
<a href="#'pygments.formatters'">'pygments.formatters'</a>
&#8226; <a href="#'pygments.lexers'">'pygments.lexers'</a>
&#8226; <a href="#contextlib">contextlib</a>
&#8226; <a href="#django.conf">django.conf</a>
&#8226; <a href="#django.core.exceptions">django.core.exceptions</a>
@ -34755,7 +34877,6 @@ imports:
&#8226; <a href="#django.db.backends.utils">django.db.backends.utils</a>
&#8226; <a href="#django_extensions.management">django_extensions.management</a>
&#8226; <a href="#django_extensions.settings">django_extensions.settings</a>
&#8226; <a href="#pygments">pygments</a>
&#8226; <a href="#sqlparse">sqlparse</a>
&#8226; <a href="#time">time</a>
&#8226; <a href="#traceback">traceback</a>
@ -41522,7 +41643,6 @@ imports:
&#8226; <a href="#importlib">importlib</a>
&#8226; <a href="#importlib._bootstrap">importlib._bootstrap</a>
&#8226; <a href="#importlib._bootstrap_external">importlib._bootstrap_external</a>
&#8226; <a href="#importlib.machinery">importlib.machinery</a>
&#8226; <a href="#sys">sys</a>
&#8226; <a href="#warnings">warnings</a>
@ -41719,7 +41839,6 @@ imported by:
<a href="#ctypes.util">ctypes.util</a>
&#8226; <a href="#idlelib.pathbrowser">idlelib.pathbrowser</a>
&#8226; <a href="#imp">imp</a>
&#8226; <a href="#importlib">importlib</a>
&#8226; <a href="#importlib.abc">importlib.abc</a>
&#8226; <a href="#inspect">inspect</a>
&#8226; <a href="#packaging.tags">packaging.tags</a>
@ -42417,6 +42536,8 @@ imported by:
&#8226; <a href="#inventory.views">inventory.views</a>
&#8226; <a href="#manufacture.forms">manufacture.forms</a>
&#8226; <a href="#purchase.forms">purchase.forms</a>
&#8226; <a href="#purchase.models">purchase.models</a>
&#8226; <a href="#sales.admin">sales.admin</a>
&#8226; <a href="#sales.forms">sales.forms</a>
&#8226; <a href="#sales.models">sales.models</a>
@ -43589,6 +43710,7 @@ imports:
&#8226; <a href="#manufacture_app">manufacture_app</a>
&#8226; <a href="#os">os</a>
&#8226; <a href="#pathlib">pathlib</a>
&#8226; <a href="#sys">sys</a>
</div>
<div class="import">
@ -44903,6 +45025,7 @@ imported by:
&#8226; <a href="#concurrent.futures.thread">concurrent.futures.thread</a>
&#8226; <a href="#configparser">configparser</a>
&#8226; <a href="#contextlib">contextlib</a>
&#8226; <a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#ctypes">ctypes</a>
&#8226; <a href="#ctypes._aix">ctypes._aix</a>
@ -45782,6 +45905,7 @@ imported by:
<a href="#PIL.Image">PIL.Image</a>
&#8226; <a href="#PIL._util">PIL._util</a>
&#8226; <a href="#compileall">compileall</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#django.conf">django.conf</a>
&#8226; <a href="#django.contrib.admindocs.views">django.contrib.admindocs.views</a>
&#8226; <a href="#django.contrib.auth.password_validation">django.contrib.auth.password_validation</a>
@ -45856,6 +45980,7 @@ imported by:
&#8226; <a href="#setuptools.config.expand">setuptools.config.expand</a>
&#8226; <a href="#setuptools.discovery">setuptools.discovery</a>
&#8226; <a href="#setuptools.dist">setuptools.dist</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#zipfile">zipfile</a>
</div>
@ -55959,7 +56084,8 @@ imports:
</div>
<div class="import">
imported by:
<a href="#django">django</a>
<a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#purchase.views">purchase.views</a>
</div>
@ -56018,12 +56144,15 @@ imports:
&#8226; <a href="#django.utils">django.utils</a>
&#8226; <a href="#django.utils.timezone">django.utils.timezone</a>
&#8226; <a href="#django.utils.translation">django.utils.translation</a>
&#8226; <a href="#inventory.models">inventory.models</a>
&#8226; <a href="#purchase">purchase</a>
</div>
<div class="import">
imported by:
<a href="#core.views">core.views</a>
<a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#inventory.views">inventory.views</a>
&#8226; <a href="#purchase.admin">purchase.admin</a>
@ -56267,8 +56396,7 @@ imported by:
<a target="code" href="" type="text/plain"><tt>pygments</tt></a>
<span class="moduletype">MissingModule</span> <div class="import">
imported by:
<a href="#django_extensions.management.debug_cursor">django_extensions.management.debug_cursor</a>
&#8226; <a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
<a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
&#8226; <a href="#django_extensions.templatetags.syntax_color">django_extensions.templatetags.syntax_color</a>
</div>
@ -57053,6 +57181,7 @@ imported by:
imports:
<a href="#django.contrib">django.contrib</a>
&#8226; <a href="#django.contrib.admin">django.contrib.admin</a>
&#8226; <a href="#inventory.models">inventory.models</a>
&#8226; <a href="#sales">sales</a>
&#8226; <a href="#sales.models">sales.models</a>
@ -57096,7 +57225,8 @@ imports:
</div>
<div class="import">
imported by:
<a href="#django">django</a>
<a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#sales.views">sales.views</a>
</div>
@ -57161,7 +57291,9 @@ imports:
</div>
<div class="import">
imported by:
<a href="#core.views">core.views</a>
<a href="#core.management.commands.check_database">core.management.commands.check_database</a>
&#8226; <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#django">django</a>
&#8226; <a href="#inventory.views">inventory.views</a>
&#8226; <a href="#sales.admin">sales.admin</a>
@ -62655,6 +62787,7 @@ imported by:
&#8226; <a href="#concurrent.futures.process">concurrent.futures.process</a>
&#8226; <a href="#configparser">configparser</a>
&#8226; <a href="#contextlib">contextlib</a>
&#8226; <a href="#core.views">core.views</a>
&#8226; <a href="#crispy_forms.utils">crispy_forms.utils</a>
&#8226; <a href="#ctypes">ctypes</a>
&#8226; <a href="#ctypes._aix">ctypes._aix</a>
@ -62798,6 +62931,7 @@ imported by:
&#8226; <a href="#linecache">linecache</a>
&#8226; <a href="#locale">locale</a>
&#8226; <a href="#logging">logging</a>
&#8226; <a href="#manufacture_app.settings">manufacture_app.settings</a>
&#8226; <a href="#mimetypes">mimetypes</a>
&#8226; <a href="#multiprocessing">multiprocessing</a>
&#8226; <a href="#multiprocessing.connection">multiprocessing.connection</a>
@ -63005,6 +63139,7 @@ imported by:
&#8226; <a href="#socketserver">socketserver</a>
&#8226; <a href="#sqlparse.cli">sqlparse.cli</a>
&#8226; <a href="#ssl">ssl</a>
&#8226; <a href="#start_server.py">start_server.py</a>
&#8226; <a href="#statistics">statistics</a>
&#8226; <a href="#subprocess">subprocess</a>
&#8226; <a href="#sysconfig">sysconfig</a>
@ -65851,6 +65986,7 @@ imported by:
&#8226; <a href="#users.admin">users.admin</a>
&#8226; <a href="#users.apps">users.apps</a>
&#8226; <a href="#users.forms">users.forms</a>
&#8226; <a href="#users.management">users.management</a>
&#8226; <a href="#users.migrations">users.migrations</a>
&#8226; <a href="#users.models">users.models</a>
&#8226; <a href="#users.urls">users.urls</a>
@ -65920,6 +66056,22 @@ imported by:
</div>
<div class="node">
<a name="users.management"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/users/management/__init__.py" type="text/plain"><tt>users.management</tt></a>
<span class="moduletype">Package</span> <div class="import">
imports:
<a href="#users">users</a>
</div>
<div class="import">
imported by:
<a href="#django">django</a>
</div>
</div>
<div class="node">
<a name="users.migrations"></a>
<a target="code" href="///D:/Pythoncode/Django_Basic_Manufacturing/users/migrations/__init__.py" type="text/plain"><tt>users.migrations</tt></a>

View File

View File

View File

@ -0,0 +1,43 @@
from django.core.management.base import BaseCommand
from django.conf import settings
import os
class Command(BaseCommand):
help = 'Check database path and contents'
def handle(self, *args, **options):
# Show database path
db_path = settings.DATABASES['default']['NAME']
self.stdout.write(f'Database path: {db_path}')
self.stdout.write(f'Database exists: {os.path.exists(db_path)}')
if os.path.exists(db_path):
# Check file size
file_size = os.path.getsize(db_path)
self.stdout.write(f'Database size: {file_size} bytes ({file_size / 1024:.2f} KB)')
# Try to access some data
try:
from purchase.models import Supplier
from sales.models import Customer
supplier_count = Supplier.objects.count()
customer_count = Customer.objects.count()
self.stdout.write(f'Suppliers in database: {supplier_count}')
self.stdout.write(f'Customers in database: {customer_count}')
if supplier_count > 0:
self.stdout.write('First 3 suppliers:')
for supplier in Supplier.objects.all()[:3]:
self.stdout.write(f' - {supplier.name} ({supplier.code})')
if customer_count > 0:
self.stdout.write('First 3 customers:')
for customer in Customer.objects.all()[:3]:
self.stdout.write(f' - {customer.name} ({customer.code})')
except Exception as e:
self.stdout.write(f'Error accessing database contents: {e}')
else:
self.stdout.write('Database file not found')

View File

@ -0,0 +1,48 @@
from django.core.management.base import BaseCommand
from django.db import transaction
from purchase.models import Supplier
from sales.models import Customer
class Command(BaseCommand):
help = 'Populate test suppliers and customers'
def handle(self, *args, **options):
# Create test suppliers
suppliers_data = [
{'name': 'ABC Supplier', 'code': 'SUP001', 'contact_person': 'John Doe', 'email': 'john@abcsupplier.com'},
{'name': 'XYZ Supplier', 'code': 'SUP002', 'contact_person': 'Jane Smith', 'email': 'jane@xyzsupplier.com'},
{'name': 'Global Parts', 'code': 'SUP003', 'contact_person': 'Bob Johnson', 'email': 'bob@globalparts.com'},
]
created_suppliers = 0
for supplier_data in suppliers_data:
supplier, created = Supplier.objects.get_or_create(
code=supplier_data['code'],
defaults=supplier_data
)
if created:
created_suppliers += 1
self.stdout.write(f'Created supplier: {supplier.name}')
# Create test customers
customers_data = [
{'name': 'Tech Solutions Inc.', 'code': 'CUST01', 'contact_person': 'Alice Brown', 'email': 'alice@techsolutions.com'},
{'name': 'Global Enterprises', 'code': 'CUST002', 'contact_person': 'Charlie Wilson', 'email': 'charlie@globalenterprises.com'},
{'name': 'Local Business', 'code': 'CUST03', 'contact_person': 'Diana Prince', 'email': 'diana@localbusiness.com'},
]
created_customers = 0
for customer_data in customers_data:
customer, created = Customer.objects.get_or_create(
code=customer_data['code'],
defaults=customer_data
)
if created:
created_customers += 1
self.stdout.write(f'Created customer: {customer.name}')
self.stdout.write(
self.style.SUCCESS(
f'Successfully populated test data: {created_suppliers} suppliers, {created_customers} customers'
)
)

View File

@ -10,4 +10,7 @@ urlpatterns = [
path('database/', login_required(views.DatabaseManagementView.as_view()), name='database_management'),
path('database/backup/', login_required(views.backup_database), name='backup_database'),
path('database/restore/', login_required(views.restore_database), name='restore_database'),
path('database/change-password/', login_required(views.change_password), name='change_password'),
path('test-form/', login_required(views.test_form), name='test_form'),
path('simple-test/', login_required(views.simple_test), name='simple_test'),
]

View File

@ -8,10 +8,12 @@ from django.conf import settings
import sqlite3
import os
import shutil
import sys
from datetime import datetime, timedelta
from django.utils import timezone
from django.db.models import Sum, Count, Avg
from decimal import Decimal
from pathlib import Path
from inventory.models import Product, StockMovement
from purchase.models import PurchaseOrder, PurchaseOrderItem
@ -152,19 +154,33 @@ class DatabaseManagementView(TemplateView):
context = super().get_context_data(**kwargs)
# Database file information
db_path = os.path.join(settings.BASE_DIR, 'db.sqlite3')
# Use the same path logic as in settings.py
if getattr(sys, 'frozen', False):
# Running as compiled executable
base_db_dir = Path(os.path.dirname(sys.executable))
else:
# Running as script
base_db_dir = settings.BASE_DIR
db_path = base_db_dir / 'db.sqlite3'
if os.path.exists(db_path):
stat = os.stat(db_path)
context['db_size'] = f"{stat.st_size / (1024*1024):.2f} MB"
context['db_modified'] = datetime.fromtimestamp(stat.st_mtime).strftime('%Y-%m-%d %H:%M:%S')
# Available backups
backup_dir = os.path.join(settings.BASE_DIR, 'backups')
# Use the same path logic as in settings.py
if getattr(sys, 'frozen', False):
# Running as compiled executable
base_db_dir = Path(os.path.dirname(sys.executable))
else:
# Running as script
base_db_dir = settings.BASE_DIR
backup_dir = base_db_dir / 'backups'
if os.path.exists(backup_dir):
backups = []
for file in os.listdir(backup_dir):
if file.endswith('.sqlite3'):
file_path = os.path.join(backup_dir, file)
file_path = backup_dir / file
stat = os.stat(file_path)
backups.append({
'name': file,
@ -200,17 +216,25 @@ class DatabaseManagementView(TemplateView):
def backup_database(request):
if request.method == 'POST':
try:
# Use the same path logic as in settings.py
if getattr(sys, 'frozen', False):
# Running as compiled executable
base_db_dir = Path(os.path.dirname(sys.executable))
else:
# Running as script
base_db_dir = settings.BASE_DIR
# Create backup directory if it doesn't exist
backup_dir = os.path.join(settings.BASE_DIR, 'backups')
backup_dir = base_db_dir / 'backups'
os.makedirs(backup_dir, exist_ok=True)
# Generate backup filename with timestamp
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
backup_filename = f'manufacture_app_backup_{timestamp}.sqlite3'
backup_path = os.path.join(backup_dir, backup_filename)
backup_path = backup_dir / backup_filename
# Copy the database file
db_path = os.path.join(settings.BASE_DIR, 'db.sqlite3')
db_path = base_db_dir / 'db.sqlite3'
shutil.copy2(db_path, backup_path)
messages.success(request, f'Database backed up successfully to {backup_filename}')
@ -219,17 +243,147 @@ def backup_database(request):
return redirect('core:database_management')
def test_form(request):
"""Test view to isolate form rendering issue"""
# Check database connectivity
db_connected = False
db_error = None
try:
from django.db import connection
connection.ensure_connection()
db_connected = True
except Exception as e:
db_error = str(e)
from purchase.forms import PurchaseOrderForm
from sales.forms import SaleOrderForm
purchase_form = PurchaseOrderForm()
sales_form = SaleOrderForm()
# Check if suppliers/customers are available
suppliers = []
customers = []
supplier_count = 0
customer_count = 0
model_error = None
try:
from purchase.models import Supplier
from sales.models import Customer
suppliers = Supplier.objects.all()
customers = Customer.objects.all()
supplier_count = suppliers.count()
customer_count = customers.count()
except Exception as e:
model_error = str(e)
# Debug information
purchase_form_debug = {
'field_type': type(purchase_form.fields['supplier']).__name__,
'choices_count': len(purchase_form.fields['supplier'].choices) if hasattr(purchase_form.fields['supplier'], 'choices') else 'N/A',
'choices': list(purchase_form.fields['supplier'].choices) if hasattr(purchase_form.fields['supplier'], 'choices') else [],
}
sales_form_debug = {
'field_type': type(sales_form.fields['customer']).__name__,
'choices_count': len(sales_form.fields['customer'].choices) if hasattr(sales_form.fields['customer'], 'choices') else 'N/A',
'choices': list(sales_form.fields['customer'].choices) if hasattr(sales_form.fields['customer'], 'choices') else [],
}
context = {
'purchase_form': purchase_form,
'sales_form': sales_form,
'suppliers': suppliers,
'customers': customers,
'supplier_count': supplier_count,
'customer_count': customer_count,
'db_connected': db_connected,
'db_error': db_error,
'model_error': model_error,
'purchase_form_debug': purchase_form_debug,
'sales_form_debug': sales_form_debug,
}
return render(request, 'core/test_form.html', context)
@login_required
@user_passes_test(is_admin)
def change_password(request):
if request.method == 'POST':
try:
username = request.POST.get('username')
new_password = request.POST.get('new_password')
confirm_password = request.POST.get('confirm_password')
if not username:
messages.error(request, 'Username is required.')
return redirect('core:database_management')
if not new_password:
messages.error(request, 'New password is required.')
return redirect('core:database_management')
if new_password != confirm_password:
messages.error(request, 'Passwords do not match.')
return redirect('core:database_management')
# Validate password length
if len(new_password) < 8:
messages.error(request, 'Password must be at least 8 characters long.')
return redirect('core:database_management')
# Get user and change password
from django.contrib.auth import get_user_model
User = get_user_model()
try:
user = User.objects.get(username=username)
user.set_password(new_password)
user.save()
messages.success(request, f'Successfully changed password for user "{username}"')
except User.DoesNotExist:
messages.error(request, f'User "{username}" does not exist.')
except Exception as e:
messages.error(request, f'Failed to change password: {str(e)}')
return redirect('core:database_management')
@login_required
def simple_test(request):
"""Simple test view to isolate form rendering issue"""
from purchase.forms import PurchaseOrderForm
from sales.forms import SaleOrderForm
purchase_form = PurchaseOrderForm()
sales_form = SaleOrderForm()
context = {
'purchase_form': purchase_form,
'sales_form': sales_form,
}
return render(request, 'core/simple_test.html', context)
@login_required
@user_passes_test(is_admin)
def restore_database(request):
if request.method == 'POST':
try:
# Use the same path logic as in settings.py
if getattr(sys, 'frozen', False):
# Running as compiled executable
base_db_dir = Path(os.path.dirname(sys.executable))
else:
# Running as script
base_db_dir = settings.BASE_DIR
backup_file = request.FILES.get('backup_file')
if backup_file:
# Create backup of current database first
current_db = os.path.join(settings.BASE_DIR, 'db.sqlite3')
current_db = base_db_dir / 'db.sqlite3'
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
safety_backup = os.path.join(settings.BASE_DIR, f'safety_backup_{timestamp}.sqlite3')
safety_backup = base_db_dir / f'safety_backup_{timestamp}.sqlite3'
shutil.copy2(current_db, safety_backup)
# Restore from uploaded backup

Binary file not shown.

BIN
dist/start_server.exe vendored

Binary file not shown.

View File

@ -27,7 +27,7 @@ class SupplierForm(forms.ModelForm):
class Meta:
model = Supplier
fields = ['code', 'name', 'contact_person', 'email', 'phone', 'address', 'rating', 'credit_limit', 'is_active']
fields = ['code', 'name', 'contact_person', 'email', 'phone', 'address', 'credit_limit', 'is_active']
widgets = {
'address': forms.Textarea(attrs={'rows': 3}),
}

View File

@ -234,10 +234,6 @@ class Supplier(models.Model):
email = models.EmailField(blank=True)
phone = models.CharField(max_length=20, blank=True)
address = models.TextField(blank=True)
rating = models.PositiveSmallIntegerField(
validators=[MinValueValidator(1), MaxValueValidator(5)],
default=3
)
credit_limit = models.DecimalField(max_digits=12, decimal_places=2, default=0)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)

View File

@ -8,5 +8,6 @@ urlpatterns = [
path('', views.ManufactureListView.as_view(), name='manufacture_list'),
path('create/', views.manufacture_create, name='manufacture_create'),
path('<int:pk>/', views.ManufactureDetailView.as_view(), name='manufacture_detail'),
path('<int:pk>/edit/', views.manufacture_edit, name='manufacture_edit'),
path('<int:pk>/delete/', views.manufacture_delete, name='manufacture_delete'),
]

View File

@ -1,4 +1,4 @@
from django.shortcuts import render, redirect
from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import ListView, DetailView
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
@ -46,6 +46,31 @@ def manufacture_create(request):
return render(request, 'manufacture/manufacture_form.html', {'form': form, 'title': 'Create Manufacturing Order'})
@login_required
def manufacture_edit(request, pk):
"""Edit an existing manufacturing order"""
from users.views import is_administrator
if not is_administrator(request.user):
messages.error(request, 'You do not have permission to edit manufacturing orders.')
return redirect('manufacture:manufacture_detail', pk=pk)
manufacturing_order = get_object_or_404(ManufacturingOrder, pk=pk)
if request.method == 'POST':
form = ManufacturingOrderForm(request.POST, instance=manufacturing_order)
if form.is_valid():
form.save()
messages.success(request, f'Manufacturing order "{manufacturing_order.order_number}" updated successfully!')
return redirect('manufacture:manufacture_detail', pk=manufacturing_order.pk)
else:
form = ManufacturingOrderForm(instance=manufacturing_order)
return render(request, 'manufacture/manufacture_form.html', {
'form': form,
'title': 'Edit Manufacturing Order',
'manufacturing_order': manufacturing_order
})
@login_required
def manufacture_delete(request, pk):
"""Delete a manufacturing order"""

View File

@ -69,10 +69,22 @@ TEMPLATES = [
WSGI_APPLICATION = 'manufacture_app.wsgi.application'
# Database
# When running as executable, database should be in the same directory as the executable
import sys
import os
# Check if we're running as a PyInstaller executable
if getattr(sys, 'frozen', False):
# Running as compiled executable
BASE_DB_DIR = Path(os.path.dirname(sys.executable))
else:
# Running as script
BASE_DB_DIR = BASE_DIR
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'NAME': BASE_DB_DIR / 'db.sqlite3',
}
}

View File

@ -8,9 +8,9 @@ class PurchaseOrderItemInline(admin.TabularInline):
@admin.register(Supplier)
class SupplierAdmin(admin.ModelAdmin):
list_display = ('name', 'code', 'contact_person', 'email', 'phone',
'rating', 'is_active', 'created_at')
list_filter = ('is_active', 'rating', 'created_at')
list_display = ('name', 'code', 'contact_person', 'email', 'phone',
'is_active', 'created_at')
list_filter = ('is_active', 'created_at')
search_fields = ('name', 'code', 'contact_person', 'email', 'phone')
ordering = ('name',)
@ -18,7 +18,7 @@ class SupplierAdmin(admin.ModelAdmin):
('Basic Information', {'fields': ('name', 'code', 'contact_person', 'email', 'phone')}),
('Address', {'fields': ('address',)}),
('Business Information', {'fields': ('tax_id', 'payment_terms', 'credit_limit')}),
('Status', {'fields': ('is_active', 'rating')}),
('Status', {'fields': ('is_active',)}),
)
@admin.register(PurchaseOrder)

View File

@ -1,6 +1,6 @@
from django import forms
from .models import PurchaseOrder, PurchaseOrderItem, Supplier
from inventory.models import Product
from .models import PurchaseOrder, PurchaseOrderItem
from inventory.models import Product, Supplier
class PurchaseOrderForm(forms.ModelForm):
"""Form for creating and editing purchase orders"""
@ -17,7 +17,12 @@ class PurchaseOrderForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Add Bootstrap classes
# Update the supplier field queryset to only show active suppliers
from inventory.models import Supplier
self.fields['supplier'].queryset = Supplier.objects.filter(is_active=True).order_by('name')
self.fields['supplier'].widget.attrs.update({'class': 'form-control'})
# Add Bootstrap classes to other fields
for field in self.fields.values():
if isinstance(field.widget, (forms.CheckboxInput, forms.RadioSelect)):
field.widget.attrs.update({'class': 'form-check-input'})
@ -25,8 +30,10 @@ class PurchaseOrderForm(forms.ModelForm):
field.widget.attrs.update({'class': 'form-control'})
elif isinstance(field.widget, forms.DateInput):
field.widget.attrs.update({'class': 'form-control'})
else:
elif not isinstance(field.widget, forms.Select): # Skip Select widgets as we already handled them
field.widget.attrs.update({'class': 'form-control'})
# Removed _get_supplier_choices method as it's no longer needed
class PurchaseOrderItemForm(forms.ModelForm):
"""Form for purchase order items"""

View File

@ -2,52 +2,9 @@ from django.db import models
from django.core.validators import MinValueValidator
from django.utils.translation import gettext_lazy as _
from decimal import Decimal
from inventory.models import Supplier
class Supplier(models.Model):
"""Supplier information"""
name = models.CharField(max_length=200)
code = models.CharField(max_length=50, unique=True, help_text='Unique supplier code')
contact_person = models.CharField(max_length=100, blank=True)
email = models.EmailField(blank=True)
phone = models.CharField(max_length=20, blank=True)
address = models.TextField(blank=True)
# Business information
tax_id = models.CharField(max_length=50, blank=True)
payment_terms = models.CharField(max_length=100, blank=True, help_text='e.g., Net 30, Net 60')
credit_limit = models.DecimalField(
max_digits=12,
decimal_places=2,
default=0,
validators=[MinValueValidator(Decimal('0'))]
)
# Status
is_active = models.BooleanField(default=True)
rating = models.IntegerField(
choices=[(i, i) for i in range(1, 6)],
default=3,
help_text='Supplier rating from 1-5'
)
# Timestamps
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['name']
verbose_name = _('Supplier')
verbose_name_plural = _('Suppliers')
def __str__(self):
return f"{self.name} ({self.code})"
def get_total_purchases(self):
"""Get total purchases from this supplier"""
return self.purchase_orders.aggregate(
total=models.Sum('total_amount')
)['total'] or Decimal('0')
# Supplier model removed - using inventory.models.Supplier instead
class PurchaseOrder(models.Model):
"""Purchase order model"""
@ -61,7 +18,7 @@ class PurchaseOrder(models.Model):
]
order_number = models.CharField(max_length=50, unique=True, help_text='Unique purchase order number')
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, related_name='purchase_orders')
supplier = models.ForeignKey('inventory.Supplier', on_delete=models.CASCADE, related_name='purchase_orders')
date = models.DateField()
expected_delivery_date = models.DateField(blank=True, null=True)
status = models.CharField(max_length=20, choices=ORDER_STATUS, default='draft')

View File

@ -1,5 +1,6 @@
from django.contrib import admin
from .models import Customer, SaleOrder, SaleOrderItem, DeliveryNote
from .models import SaleOrder, SaleOrderItem, DeliveryNote
from inventory.models import Customer
class SaleOrderItemInline(admin.TabularInline):
model = SaleOrderItem
@ -8,9 +9,9 @@ class SaleOrderItemInline(admin.TabularInline):
@admin.register(Customer)
class CustomerAdmin(admin.ModelAdmin):
list_display = ('name', 'code', 'customer_type', 'contact_person', 'email', 'phone',
'rating', 'is_active', 'created_at')
list_filter = ('customer_type', 'is_active', 'rating', 'created_at')
list_display = ('name', 'code', 'customer_type', 'contact_person', 'email', 'phone',
'is_active', 'created_at')
list_filter = ('customer_type', 'is_active', 'created_at')
search_fields = ('name', 'code', 'contact_person', 'email', 'phone')
ordering = ('name',)
@ -18,7 +19,7 @@ class CustomerAdmin(admin.ModelAdmin):
('Basic Information', {'fields': ('name', 'code', 'customer_type', 'contact_person', 'email', 'phone')}),
('Address', {'fields': ('address',)}),
('Business Information', {'fields': ('tax_id', 'payment_terms', 'credit_limit')}),
('Status', {'fields': ('is_active', 'rating')}),
('Status', {'fields': ('is_active',)}),
)
@admin.register(SaleOrder)

View File

@ -1,6 +1,6 @@
from django import forms
from .models import SaleOrder, SaleOrderItem, Customer
from inventory.models import Product
from .models import SaleOrder, SaleOrderItem
from inventory.models import Product, Customer
class SaleOrderForm(forms.ModelForm):
"""Form for creating and editing sales orders"""
@ -17,7 +17,12 @@ class SaleOrderForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Add Bootstrap classes
# Update the customer field queryset to only show active customers
from inventory.models import Customer
self.fields['customer'].queryset = Customer.objects.filter(is_active=True).order_by('name')
self.fields['customer'].widget.attrs.update({'class': 'form-control'})
# Add Bootstrap classes to other fields
for field in self.fields.values():
if isinstance(field.widget, (forms.CheckboxInput, forms.RadioSelect)):
field.widget.attrs.update({'class': 'form-check-input'})
@ -25,8 +30,10 @@ class SaleOrderForm(forms.ModelForm):
field.widget.attrs.update({'class': 'form-control'})
elif isinstance(field.widget, forms.DateInput):
field.widget.attrs.update({'class': 'form-control'})
else:
elif not isinstance(field.widget, forms.Select): # Skip Select widgets as we already handled them
field.widget.attrs.update({'class': 'form-control'})
# Removed _get_customer_choices method as it's no longer needed
class SaleOrderItemForm(forms.ModelForm):
"""Form for sales order items"""

View File

@ -2,62 +2,9 @@ from django.db import models
from django.core.validators import MinValueValidator
from django.utils.translation import gettext_lazy as _
from decimal import Decimal
from inventory.models import Customer
class Customer(models.Model):
"""Customer information"""
CUSTOMER_TYPE_CHOICES = [
('retail', 'Retail'),
('wholesale', 'Wholesale'),
('distributor', 'Distributor'),
('corporate', 'Corporate'),
]
name = models.CharField(max_length=200)
code = models.CharField(max_length=50, unique=True, help_text='Unique customer code')
customer_type = models.CharField(max_length=20, choices=CUSTOMER_TYPE_CHOICES, default='retail')
# Contact information
contact_person = models.CharField(max_length=100, blank=True)
email = models.EmailField(blank=True)
phone = models.CharField(max_length=20, blank=True)
address = models.TextField(blank=True)
# Business information
tax_id = models.CharField(max_length=50, blank=True)
payment_terms = models.CharField(max_length=100, blank=True, help_text='e.g., Net 30, Net 60')
credit_limit = models.DecimalField(
max_digits=12,
decimal_places=2,
default=0,
validators=[MinValueValidator(Decimal('0'))]
)
# Status
is_active = models.BooleanField(default=True)
rating = models.IntegerField(
choices=[(i, i) for i in range(1, 6)],
default=3,
help_text='Customer rating from 1-5'
)
# Timestamps
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['name']
verbose_name = _('Customer')
verbose_name_plural = _('Customers')
def __str__(self):
return f"{self.name} ({self.code})"
def get_total_sales(self):
"""Get total sales to this customer"""
return self.sale_orders.aggregate(
total=models.Sum('total_amount')
)['total'] or Decimal('0')
# Customer model removed - using inventory.models.Customer instead
class SaleOrder(models.Model):
"""Sales order model"""
@ -71,7 +18,7 @@ class SaleOrder(models.Model):
]
order_number = models.CharField(max_length=50, unique=True, help_text='Unique sales order number')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='sale_orders')
customer = models.ForeignKey('inventory.Customer', on_delete=models.CASCADE, related_name='sale_orders')
date = models.DateField()
expected_delivery_date = models.DateField(blank=True, null=True)
status = models.CharField(max_length=20, choices=ORDER_STATUS, default='draft')

View File

@ -1,6 +1,146 @@
import os
from django.core.management import execute_from_command_line
import sys
from pathlib import Path
def setup_django():
"""Set up Django environment"""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'manufacture_app.settings')
import django
django.setup()
def get_db_path():
"""Get the database path based on execution mode"""
# Check if we're running as a PyInstaller executable
if getattr(sys, 'frozen', False):
# Running as compiled executable
base_db_dir = Path(os.path.dirname(sys.executable))
print(f"Running as compiled executable. Database directory: {base_db_dir}")
else:
# Running as script
# Use the same logic as Django settings to determine the base directory
# BASE_DIR is the parent of the settings module directory
base_db_dir = Path(os.path.dirname(os.path.abspath(__file__))).parent
print(f"Running as script. Database directory: {base_db_dir}")
db_path = base_db_dir / 'db.sqlite3'
print(f"Database path: {db_path}")
# If running as script and the database doesn't exist in the project root,
# check if there's one in the current working directory
if not getattr(sys, 'frozen', False) and not db_path.exists():
cwd_db_path = Path.cwd() / 'db.sqlite3'
if cwd_db_path.exists():
print(f"Using database from current working directory: {cwd_db_path}")
return cwd_db_path
return db_path
def db_initialized():
"""Check if the database is initialized by checking if tables exist"""
setup_django()
try:
from django.db import connection
from django.db.utils import OperationalError
# Try to connect to the database
connection.ensure_connection()
print("Database connection established")
# Check if any tables exist
with connection.cursor() as cursor:
# For SQLite, we can check the sqlite_master table
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='django_migrations'")
result = cursor.fetchone()
print(f"django_migrations table exists: {result is not None}")
return result is not None
except OperationalError as e:
print(f"Database connection error: {e}")
return False
except Exception as e:
print(f"Unexpected error checking database: {e}")
import traceback
traceback.print_exc()
return False
def create_default_superuser():
"""Create a default superuser account"""
setup_django()
try:
from django.contrib.auth import get_user_model
User = get_user_model()
# Check if superuser already exists
if User.objects.filter(is_superuser=True).exists():
print("Superuser already exists. Skipping creation.")
return True
# Create default superuser
superuser = User.objects.create_superuser(
username='admin',
email='admin@example.com',
password='admin123'
)
print("Default superuser created:")
print(" Username: admin")
print(" Password: admin123")
print(" Email: admin@example.com")
print("Please change the password after first login!")
return True
except Exception as e:
print(f"Failed to create default superuser: {e}")
import traceback
traceback.print_exc()
return False
def initialize_database():
"""Initialize the database with migrations and initial data"""
print("Initializing database...")
setup_django()
# Check database path from Django settings
from django.conf import settings
print(f"Django database path: {settings.DATABASES['default']['NAME']}")
try:
from django.core.management import call_command
# Run migrations
print("Applying database migrations...")
call_command('migrate', verbosity=1)
# Create default groups
print("Creating default user groups...")
call_command('create_default_groups', verbosity=1)
# Create default superuser
print("Creating default superuser...")
create_default_superuser()
print("Database initialization completed successfully.")
return True
except Exception as e:
print(f"Database initialization failed: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == '__main__':
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'manufacture_app.settings')
# Check if database exists and is initialized
db_path = get_db_path()
print(f"Database file exists: {db_path.exists()}")
if not db_path.exists() or not db_initialized():
print("Database not found or not initialized. Initializing now...")
if not initialize_database():
print("Failed to initialize database. Exiting.")
sys.exit(1)
print("Database ready.")
# Setup Django for running the server
setup_django()
# Start the server
from django.core.management import execute_from_command_line
execute_from_command_line(['manage.py', 'runserver', '--noreload'])

View File

@ -59,9 +59,70 @@ for app in django_apps:
datas.append((str(file_path), str(relative_path.parent)))
# Add the database
db_file = base_dir / 'db.sqlite3'
if db_file.exists():
datas.append((str(db_file), '.'))
# Database is now kept external to the executable
# db_file = base_dir / 'db.sqlite3'
# if db_file.exists():
# datas.append((str(db_file), '.'))
# Add crispy forms templates
try:
import crispy_forms
crispy_forms_path = Path(crispy_forms.__file__).parent
crispy_templates_dir = crispy_forms_path / 'templates'
if crispy_templates_dir.exists():
for root, dirs, files in os.walk(crispy_templates_dir):
for file in files:
file_path = Path(root) / file
relative_path = file_path.relative_to(crispy_forms_path)
datas.append((str(file_path), str(relative_path.parent)))
except ImportError:
pass
# Add crispy bootstrap5 templates
try:
import crispy_bootstrap5
crispy_bootstrap5_path = Path(crispy_bootstrap5.__file__).parent
crispy_bootstrap5_templates_dir = crispy_bootstrap5_path / 'templates'
if crispy_bootstrap5_templates_dir.exists():
for root, dirs, files in os.walk(crispy_bootstrap5_templates_dir):
for file in files:
file_path = Path(root) / file
relative_path = file_path.relative_to(crispy_bootstrap5_path)
datas.append((str(file_path), str(relative_path.parent)))
except ImportError:
pass
# Add Django templates
try:
import django
django_path = Path(django.__file__).parent
django_templates_dir = django_path / 'forms' / 'templates'
if django_templates_dir.exists():
for root, dirs, files in os.walk(django_templates_dir):
for file in files:
file_path = Path(root) / file
relative_path = file_path.relative_to(django_path)
datas.append((str(file_path), str(relative_path.parent)))
except ImportError:
pass
# Add more Django templates
try:
import django
django_path = Path(django.__file__).parent
django_contrib_dir = django_path / 'contrib'
if django_contrib_dir.exists():
for root, dirs, files in os.walk(django_contrib_dir):
# Look for templates directories
if 'templates' in dirs:
templates_dir = Path(root) / 'templates'
for t_root, t_dirs, t_files in os.walk(templates_dir):
for file in t_files:
file_path = Path(t_root) / file
relative_path = file_path.relative_to(django_path)
datas.append((str(file_path), str(relative_path.parent)))
except ImportError:
pass
# Hidden imports for Django
hiddenimports = [
@ -87,6 +148,17 @@ hiddenimports = [
'django.contrib.sessions.apps',
'django.contrib.messages.apps',
'django.contrib.staticfiles.apps',
# Additional imports for form rendering
'django.forms',
'django.forms.widgets',
'django.forms.models',
'django.forms.fields',
'django.forms.boundfield',
# Additional imports for model relationships
'django.db.models',
'django.db.models.fields',
'django.db.models.fields.related',
'django.db.models.fields.reverse_related',
]
a = Analysis(

View File

@ -76,46 +76,45 @@
</div>
<!-- Restore Database -->
<div class="row">
<!-- Change Password -->
<div class="row mt-4">
<div class="col-lg-8">
<div class="card">
<div class="card-header">
<h6 class="m-0 font-weight-bold text-warning">
<i class="bi bi-upload me-2"></i>
Restore Database
<h6 class="m-0 font-weight-bold text-info">
<i class="bi bi-key me-2"></i>
Change Password
</h6>
</div>
<div class="card-body">
<div class="alert alert-warning">
<i class="bi bi-exclamation-triangle me-2"></i>
<strong>Warning:</strong> Restoring a database will overwrite the current database.
A safety backup of the current database will be created automatically before restoration.
<div class="alert alert-info">
<i class="bi bi-info-circle me-2"></i>
<strong>Info:</strong> Change the password for any user account in the system.
</div>
<form method="post" action="{% url 'core:restore_database' %}" enctype="multipart/form-data">
<form method="post" action="{% url 'core:change_password' %}">
{% csrf_token %}
<div class="mb-3">
<label for="backup_file" class="form-label">Select Backup File</label>
<input type="file" class="form-control" id="backup_file" name="backup_file"
accept=".sqlite3,.db" required>
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="new_password" class="form-label">New Password</label>
<input type="password" class="form-control" id="new_password" name="new_password" required>
<div class="form-text">
Only SQLite database files (.sqlite3, .db) are supported.
Password must be at least 8 characters long.
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="confirm_restore" required>
<label class="form-check-label" for="confirm_restore">
I understand that this will overwrite the current database
</label>
</div>
<label for="confirm_password" class="form-label">Confirm New Password</label>
<input type="password" class="form-control" id="confirm_password" name="confirm_password" required>
</div>
<button type="submit" class="btn btn-warning" id="restore_btn" disabled>
<i class="bi bi-upload me-2"></i>
Restore Database
<button type="submit" class="btn btn-info">
<i class="bi bi-key me-2"></i>
Change Password
</button>
</form>
</div>

View File

@ -0,0 +1,49 @@
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Simple Test{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="bi bi-bug me-2"></i>
Simple Test
</h1>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Purchase Order Form</h5>
</div>
<div class="card-body">
<form>
<div class="mb-3">
<label class="form-label">Supplier:</label>
{{ purchase_form.supplier }}
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Sales Order Form</h5>
</div>
<div class="card-body">
<form>
<div class="mb-3">
<label class="form-label">Customer:</label>
{{ sales_form.customer }}
</div>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,109 @@
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Test Form{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">
<i class="bi bi-bug me-2"></i>
Test Form
</h1>
</div>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Purchase Order Form</h5>
</div>
<div class="card-body">
<form>
<div class="mb-3">
<label class="form-label">Supplier Field:</label>
{{ purchase_form.supplier|as_crispy_field }}
</div>
<div class="mb-3">
<label class="form-label">Date Field:</label>
{{ purchase_form.date|as_crispy_field }}
</div>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Sales Order Form</h5>
</div>
<div class="card-body">
<form>
<div class="mb-3">
<label class="form-label">Customer Field:</label>
{{ sales_form.customer|as_crispy_field }}
</div>
<div class="mb-3">
<label class="form-label">Date Field:</label>
{{ sales_form.date|as_crispy_field }}
</div>
</form>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Debug Information</h5>
</div>
<div class="card-body">
<h6>Suppliers in Database:</h6>
<ul>
{% for supplier in suppliers %}
<li>{{ supplier.name }} ({{ supplier.code }})</li>
{% empty %}
<li>No suppliers found</li>
{% endfor %}
</ul>
<h6>Customers in Database:</h6>
<ul>
{% for customer in customers %}
<li>{{ customer.name }} ({{ customer.code }})</li>
{% empty %}
<li>No customers found</li>
{% endfor %}
</ul>
<h6>Database Connectivity:</h6>
<p>Connected: {{ db_connected|yesno:"Yes,No" }}</p>
{% if db_error %}
<p>Error: {{ db_error }}</p>
{% endif %}
<h6>Database Information:</h6>
<p>Suppliers in database: {{ supplier_count }}</p>
<p>Customers in database: {{ customer_count }}</p>
{% if model_error %}
<p>Model error: {{ model_error }}</p>
{% endif %}
<h6>Purchase Form Debug Info:</h6>
<p>Field type: {{ purchase_form_debug.field_type }}</p>
<p>Choices count: {{ purchase_form_debug.choices_count }}</p>
<p>Choices: {{ purchase_form_debug.choices }}</p>
<h6>Sales Form Debug Info:</h6>
<p>Field type: {{ sales_form_debug.field_type }}</p>
<p>Choices count: {{ sales_form_debug.choices_count }}</p>
<p>Choices: {{ sales_form_debug.choices }}</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -31,12 +31,7 @@
<div class="col-md-6">
<p><strong>Supplier Code:</strong> {{ supplier.code }}</p>
<p><strong>Name:</strong> {{ supplier.name }}</p>
<p><strong>Rating:</strong>
<span class="badge bg-{% if supplier.rating >= 4 %}success{% elif supplier.rating >= 3 %}warning{% else %}danger{% endif %}">
{{ supplier.rating }}/5
</span>
</p>
<p><strong>Status:</strong>
<p><strong>Status:</strong>
<span class="badge bg-{% if supplier.is_active %}success{% else %}secondary{% endif %}">
{{ supplier.is_active|yesno:"Active,Inactive" }}
</span>

View File

@ -44,9 +44,6 @@
<div class="col-md-6">
{{ form.phone|as_crispy_field }}
</div>
<div class="col-md-6">
{{ form.rating|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-12">
@ -87,10 +84,6 @@
<i class="bi bi-info-circle text-primary me-2"></i>
Supplier code should be unique
</li>
<li class="mb-2">
<i class="bi bi-star text-warning me-2"></i>
Rate suppliers based on performance
</li>
<li class="mb-2">
<i class="bi bi-telephone text-info me-2"></i>
Keep contact information up to date

View File

@ -26,7 +26,6 @@
<th>Contact Person</th>
<th>Email</th>
<th>Phone</th>
<th>Rating</th>
<th>Credit Limit</th>
<th>Status</th>
<th>Actions</th>
@ -42,11 +41,6 @@
<td>{{ supplier.contact_person|default:"N/A" }}</td>
<td>{{ supplier.email|default:"N/A" }}</td>
<td>{{ supplier.phone|default:"N/A" }}</td>
<td>
<span class="badge bg-{% if supplier.rating >= 4 %}success{% elif supplier.rating >= 3 %}warning{% else %}danger{% endif %}">
{{ supplier.rating }}/5
</span>
</td>
<td>Rp {{ supplier.credit_limit|floatformat:0 }}</td>
<td>
<span class="badge bg-{% if supplier.is_active %}success{% else %}secondary{% endif %}">

View File

@ -13,10 +13,12 @@
<i class="bi bi-arrow-left me-2"></i>
Back to List
</a>
<a href="#" class="btn btn-primary">
{% if user.is_superuser or user.is_staff %}
<a href="{% url 'manufacture:manufacture_edit' manufacturing_order.pk %}" class="btn btn-primary">
<i class="bi bi-pencil me-2"></i>
Edit
</a>
{% endif %}
</div>
</div>

View File

View File

@ -0,0 +1,57 @@
from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from django.core.exceptions import ValidationError
import getpass
User = get_user_model()
class Command(BaseCommand):
help = 'Change password for a user'
def add_arguments(self, parser):
parser.add_argument('username', nargs='?', type=str, help='Username to change password for')
def handle(self, *args, **options):
username = options['username']
if not username:
username = input("Enter username: ")
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
self.stdout.write(
self.style.ERROR(f'User "{username}" does not exist')
)
return
# Get new password
while True:
new_password = getpass.getpass("Enter new password: ")
confirm_password = getpass.getpass("Confirm new password: ")
if new_password != confirm_password:
self.stdout.write(
self.style.ERROR("Passwords do not match. Please try again.")
)
continue
# Validate password
try:
validate_password(new_password, user)
except ValidationError as e:
self.stdout.write(
self.style.ERROR(f"Password validation failed: {', '.join(e.messages)}")
)
continue
break
# Set new password
user.set_password(new_password)
user.save()
self.stdout.write(
self.style.SUCCESS(f'Successfully changed password for user "{username}"')
)