fix many bugs
This commit is contained in:
parent
a3ce1a8843
commit
80a514f1de
@ -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.
@ -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.
@ -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)
|
||||
|
||||
@ -156,6 +156,8 @@ imports:
|
||||
• <a href="#core">core</a>
|
||||
• <a href="#crispy_bootstrap5">crispy_bootstrap5</a>
|
||||
• <a href="#crispy_forms">crispy_forms</a>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#django.conf">django.conf</a>
|
||||
• <a href="#django.contrib.admin">django.contrib.admin</a>
|
||||
• <a href="#django.contrib.admin.apps">django.contrib.admin.apps</a>
|
||||
• <a href="#django.contrib.auth">django.contrib.auth</a>
|
||||
@ -169,6 +171,17 @@ imports:
|
||||
• <a href="#django.contrib.staticfiles">django.contrib.staticfiles</a>
|
||||
• <a href="#django.contrib.staticfiles.apps">django.contrib.staticfiles.apps</a>
|
||||
• <a href="#django.core.management">django.core.management</a>
|
||||
• <a href="#django.db">django.db</a>
|
||||
• <a href="#django.db.models">django.db.models</a>
|
||||
• <a href="#django.db.models.fields">django.db.models.fields</a>
|
||||
• <a href="#django.db.models.fields.related">django.db.models.fields.related</a>
|
||||
• <a href="#django.db.models.fields.reverse_related">django.db.models.fields.reverse_related</a>
|
||||
• <a href="#django.db.utils">django.db.utils</a>
|
||||
• <a href="#django.forms">django.forms</a>
|
||||
• <a href="#django.forms.boundfield">django.forms.boundfield</a>
|
||||
• <a href="#django.forms.fields">django.forms.fields</a>
|
||||
• <a href="#django.forms.models">django.forms.models</a>
|
||||
• <a href="#django.forms.widgets">django.forms.widgets</a>
|
||||
• <a href="#django_extensions">django_extensions</a>
|
||||
• <a href="#encodings">encodings</a>
|
||||
• <a href="#encodings.aliases">encodings.aliases</a>
|
||||
@ -306,6 +319,7 @@ imports:
|
||||
• <a href="#ntpath">ntpath</a>
|
||||
• <a href="#operator">operator</a>
|
||||
• <a href="#os">os</a>
|
||||
• <a href="#pathlib">pathlib</a>
|
||||
• <a href="#posixpath">posixpath</a>
|
||||
• <a href="#purchase">purchase</a>
|
||||
• <a href="#pyi_rth__tkinter.py">pyi_rth__tkinter.py</a>
|
||||
@ -326,6 +340,7 @@ imports:
|
||||
• <a href="#sre_constants">sre_constants</a>
|
||||
• <a href="#sre_parse">sre_parse</a>
|
||||
• <a href="#stat">stat</a>
|
||||
• <a href="#sys">sys</a>
|
||||
• <a href="#traceback">traceback</a>
|
||||
• <a href="#types">types</a>
|
||||
• <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>
|
||||
• <a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
|
||||
• <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>
|
||||
• <a href="#core.apps">core.apps</a>
|
||||
• <a href="#core.management">core.management</a>
|
||||
• <a href="#core.urls">core.urls</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <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>
|
||||
• <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>
|
||||
• <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
|
||||
• <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>
|
||||
• <a href="#django.conf">django.conf</a>
|
||||
• <a href="#django.core.management.base">django.core.management.base</a>
|
||||
• <a href="#os">os</a>
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <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>
|
||||
• <a href="#django.core.management.base">django.core.management.base</a>
|
||||
• <a href="#django.db">django.db</a>
|
||||
• <a href="#django.db.transaction">django.db.transaction</a>
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <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:
|
||||
• <a href="#inventory.models">inventory.models</a>
|
||||
• <a href="#manufacture.models">manufacture.models</a>
|
||||
• <a href="#os">os</a>
|
||||
• <a href="#pathlib">pathlib</a>
|
||||
• <a href="#purchase.forms">purchase.forms</a>
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <a href="#sales.forms">sales.forms</a>
|
||||
• <a href="#sales.models">sales.models</a>
|
||||
• <a href="#shutil">shutil</a>
|
||||
• <a href="#sqlite3">sqlite3</a>
|
||||
• <a href="#sys">sys</a>
|
||||
|
||||
</div>
|
||||
<div class="import">
|
||||
@ -9114,6 +9212,10 @@ imported by:
|
||||
imports:
|
||||
<a href="#core">core</a>
|
||||
• <a href="#core.apps">core.apps</a>
|
||||
• <a href="#core.management">core.management</a>
|
||||
• <a href="#core.management.commands">core.management.commands</a>
|
||||
• <a href="#core.management.commands.check_database">core.management.commands.check_database</a>
|
||||
• <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
|
||||
• <a href="#core.urls">core.urls</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#crispy_bootstrap5">crispy_bootstrap5</a>
|
||||
@ -10073,6 +10175,7 @@ imports:
|
||||
• <a href="#users.admin">users.admin</a>
|
||||
• <a href="#users.apps">users.apps</a>
|
||||
• <a href="#users.forms">users.forms</a>
|
||||
• <a href="#users.management">users.management</a>
|
||||
• <a href="#users.migrations">users.migrations</a>
|
||||
• <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
|
||||
• <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:
|
||||
• <a href="#manufacture.forms">manufacture.forms</a>
|
||||
• <a href="#purchase.forms">purchase.forms</a>
|
||||
• <a href="#sales.forms">sales.forms</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <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>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#crispy_forms.templatetags.crispy_forms_field">crispy_forms.templatetags.crispy_forms_field</a>
|
||||
• <a href="#crispy_forms.templatetags.crispy_forms_filters">crispy_forms.templatetags.crispy_forms_filters</a>
|
||||
• <a href="#crispy_forms.templatetags.crispy_forms_tags">crispy_forms.templatetags.crispy_forms_tags</a>
|
||||
@ -10590,6 +10695,7 @@ imported by:
|
||||
• <a href="#manufacture_app.urls">manufacture_app.urls</a>
|
||||
• <a href="#purchase.migrations.0001_initial">purchase.migrations.0001_initial</a>
|
||||
• <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <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>
|
||||
• <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#django.contrib.auth.management.commands.changepassword">django.contrib.auth.management.commands.changepassword</a>
|
||||
• <a href="#django.contrib.auth.management.commands.createsuperuser">django.contrib.auth.management.commands.createsuperuser</a>
|
||||
• <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>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#django.contrib.admin.checks">django.contrib.admin.checks</a>
|
||||
• <a href="#django.contrib.admin.filters">django.contrib.admin.filters</a>
|
||||
@ -24625,6 +24734,7 @@ imported by:
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
|
||||
• <a href="#sales.models">sales.models</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
|
||||
• <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>
|
||||
• <a href="#users.models">users.models</a>
|
||||
@ -26835,6 +26945,7 @@ imported by:
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <a href="#sales.migrations.0001_initial">sales.migrations.0001_initial</a>
|
||||
• <a href="#sales.models">sales.models</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <a href="#users.migrations.0001_initial">users.migrations.0001_initial</a>
|
||||
• <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>
|
||||
• <a href="#users.models">users.models</a>
|
||||
@ -27325,6 +27436,7 @@ imported by:
|
||||
• <a href="#django.db.models.lookups">django.db.models.lookups</a>
|
||||
• <a href="#django.db.models.sql.query">django.db.models.sql.query</a>
|
||||
• <a href="#django_extensions.management.commands.sqldiff">django_extensions.management.commands.sqldiff</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -27482,6 +27594,7 @@ imported by:
|
||||
• <a href="#django.db.models">django.db.models</a>
|
||||
• <a href="#django.db.models.base">django.db.models.base</a>
|
||||
• <a href="#django_extensions.management.modelviz">django_extensions.management.modelviz</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -27557,6 +27670,7 @@ imported by:
|
||||
<a href="#django">django</a>
|
||||
• <a href="#django.db.models.fields.related">django.db.models.fields.related</a>
|
||||
• <a href="#django_extensions.management.modelviz">django_extensions.management.modelviz</a>
|
||||
• <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>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#django.contrib.admin.options">django.contrib.admin.options</a>
|
||||
• <a href="#django.contrib.auth.admin">django.contrib.auth.admin</a>
|
||||
• <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:
|
||||
• <a href="#django.db.backends.sqlite3.features">django.db.backends.sqlite3.features</a>
|
||||
• <a href="#django.db.models.constraints">django.db.models.constraints</a>
|
||||
• <a href="#django.test.signals">django.test.signals</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -28407,6 +28523,7 @@ imported by:
|
||||
• <a href="#manufacture.forms">manufacture.forms</a>
|
||||
• <a href="#purchase.forms">purchase.forms</a>
|
||||
• <a href="#sales.forms">sales.forms</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <a href="#users.forms">users.forms</a>
|
||||
|
||||
</div>
|
||||
@ -28434,6 +28551,7 @@ imported by:
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#django.forms">django.forms</a>
|
||||
• <a href="#django.forms.fields">django.forms.fields</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -28481,6 +28599,7 @@ imported by:
|
||||
• <a href="#django.forms.formsets">django.forms.formsets</a>
|
||||
• <a href="#django.forms.models">django.forms.models</a>
|
||||
• <a href="#django.test.testcases">django.test.testcases</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -28578,6 +28697,7 @@ imported by:
|
||||
• <a href="#django.contrib.contenttypes.forms">django.contrib.contenttypes.forms</a>
|
||||
• <a href="#django.forms">django.forms</a>
|
||||
• <a href="#django.views.generic.edit">django.views.generic.edit</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -28687,6 +28807,7 @@ imported by:
|
||||
• <a href="#django.forms.forms">django.forms.forms</a>
|
||||
• <a href="#django.forms.formsets">django.forms.formsets</a>
|
||||
• <a href="#django.forms.models">django.forms.models</a>
|
||||
• <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>
|
||||
• <a href="#'pygments.lexers'">'pygments.lexers'</a>
|
||||
• <a href="#contextlib">contextlib</a>
|
||||
• <a href="#django.conf">django.conf</a>
|
||||
• <a href="#django.core.exceptions">django.core.exceptions</a>
|
||||
@ -34755,7 +34877,6 @@ imports:
|
||||
• <a href="#django.db.backends.utils">django.db.backends.utils</a>
|
||||
• <a href="#django_extensions.management">django_extensions.management</a>
|
||||
• <a href="#django_extensions.settings">django_extensions.settings</a>
|
||||
• <a href="#pygments">pygments</a>
|
||||
• <a href="#sqlparse">sqlparse</a>
|
||||
• <a href="#time">time</a>
|
||||
• <a href="#traceback">traceback</a>
|
||||
@ -41522,7 +41643,6 @@ imports:
|
||||
• <a href="#importlib">importlib</a>
|
||||
• <a href="#importlib._bootstrap">importlib._bootstrap</a>
|
||||
• <a href="#importlib._bootstrap_external">importlib._bootstrap_external</a>
|
||||
• <a href="#importlib.machinery">importlib.machinery</a>
|
||||
• <a href="#sys">sys</a>
|
||||
• <a href="#warnings">warnings</a>
|
||||
|
||||
@ -41719,7 +41839,6 @@ imported by:
|
||||
<a href="#ctypes.util">ctypes.util</a>
|
||||
• <a href="#idlelib.pathbrowser">idlelib.pathbrowser</a>
|
||||
• <a href="#imp">imp</a>
|
||||
• <a href="#importlib">importlib</a>
|
||||
• <a href="#importlib.abc">importlib.abc</a>
|
||||
• <a href="#inspect">inspect</a>
|
||||
• <a href="#packaging.tags">packaging.tags</a>
|
||||
@ -42417,6 +42536,8 @@ imported by:
|
||||
• <a href="#inventory.views">inventory.views</a>
|
||||
• <a href="#manufacture.forms">manufacture.forms</a>
|
||||
• <a href="#purchase.forms">purchase.forms</a>
|
||||
• <a href="#purchase.models">purchase.models</a>
|
||||
• <a href="#sales.admin">sales.admin</a>
|
||||
• <a href="#sales.forms">sales.forms</a>
|
||||
• <a href="#sales.models">sales.models</a>
|
||||
|
||||
@ -43589,6 +43710,7 @@ imports:
|
||||
• <a href="#manufacture_app">manufacture_app</a>
|
||||
• <a href="#os">os</a>
|
||||
• <a href="#pathlib">pathlib</a>
|
||||
• <a href="#sys">sys</a>
|
||||
|
||||
</div>
|
||||
<div class="import">
|
||||
@ -44903,6 +45025,7 @@ imported by:
|
||||
• <a href="#concurrent.futures.thread">concurrent.futures.thread</a>
|
||||
• <a href="#configparser">configparser</a>
|
||||
• <a href="#contextlib">contextlib</a>
|
||||
• <a href="#core.management.commands.check_database">core.management.commands.check_database</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#ctypes">ctypes</a>
|
||||
• <a href="#ctypes._aix">ctypes._aix</a>
|
||||
@ -45782,6 +45905,7 @@ imported by:
|
||||
<a href="#PIL.Image">PIL.Image</a>
|
||||
• <a href="#PIL._util">PIL._util</a>
|
||||
• <a href="#compileall">compileall</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#django.conf">django.conf</a>
|
||||
• <a href="#django.contrib.admindocs.views">django.contrib.admindocs.views</a>
|
||||
• <a href="#django.contrib.auth.password_validation">django.contrib.auth.password_validation</a>
|
||||
@ -45856,6 +45980,7 @@ imported by:
|
||||
• <a href="#setuptools.config.expand">setuptools.config.expand</a>
|
||||
• <a href="#setuptools.discovery">setuptools.discovery</a>
|
||||
• <a href="#setuptools.dist">setuptools.dist</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <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>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#purchase.views">purchase.views</a>
|
||||
|
||||
</div>
|
||||
@ -56018,12 +56144,15 @@ imports:
|
||||
• <a href="#django.utils">django.utils</a>
|
||||
• <a href="#django.utils.timezone">django.utils.timezone</a>
|
||||
• <a href="#django.utils.translation">django.utils.translation</a>
|
||||
• <a href="#inventory.models">inventory.models</a>
|
||||
• <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>
|
||||
• <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#inventory.views">inventory.views</a>
|
||||
• <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>
|
||||
• <a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
|
||||
<a href="#django_extensions.templatetags.highlighting">django_extensions.templatetags.highlighting</a>
|
||||
• <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>
|
||||
• <a href="#django.contrib.admin">django.contrib.admin</a>
|
||||
• <a href="#inventory.models">inventory.models</a>
|
||||
• <a href="#sales">sales</a>
|
||||
• <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>
|
||||
• <a href="#django">django</a>
|
||||
• <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>
|
||||
• <a href="#core.management.commands.populate_test_data">core.management.commands.populate_test_data</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#django">django</a>
|
||||
• <a href="#inventory.views">inventory.views</a>
|
||||
• <a href="#sales.admin">sales.admin</a>
|
||||
@ -62655,6 +62787,7 @@ imported by:
|
||||
• <a href="#concurrent.futures.process">concurrent.futures.process</a>
|
||||
• <a href="#configparser">configparser</a>
|
||||
• <a href="#contextlib">contextlib</a>
|
||||
• <a href="#core.views">core.views</a>
|
||||
• <a href="#crispy_forms.utils">crispy_forms.utils</a>
|
||||
• <a href="#ctypes">ctypes</a>
|
||||
• <a href="#ctypes._aix">ctypes._aix</a>
|
||||
@ -62798,6 +62931,7 @@ imported by:
|
||||
• <a href="#linecache">linecache</a>
|
||||
• <a href="#locale">locale</a>
|
||||
• <a href="#logging">logging</a>
|
||||
• <a href="#manufacture_app.settings">manufacture_app.settings</a>
|
||||
• <a href="#mimetypes">mimetypes</a>
|
||||
• <a href="#multiprocessing">multiprocessing</a>
|
||||
• <a href="#multiprocessing.connection">multiprocessing.connection</a>
|
||||
@ -63005,6 +63139,7 @@ imported by:
|
||||
• <a href="#socketserver">socketserver</a>
|
||||
• <a href="#sqlparse.cli">sqlparse.cli</a>
|
||||
• <a href="#ssl">ssl</a>
|
||||
• <a href="#start_server.py">start_server.py</a>
|
||||
• <a href="#statistics">statistics</a>
|
||||
• <a href="#subprocess">subprocess</a>
|
||||
• <a href="#sysconfig">sysconfig</a>
|
||||
@ -65851,6 +65986,7 @@ imported by:
|
||||
• <a href="#users.admin">users.admin</a>
|
||||
• <a href="#users.apps">users.apps</a>
|
||||
• <a href="#users.forms">users.forms</a>
|
||||
• <a href="#users.management">users.management</a>
|
||||
• <a href="#users.migrations">users.migrations</a>
|
||||
• <a href="#users.models">users.models</a>
|
||||
• <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>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
0
core/management/__init__.py
Normal file
0
core/management/__init__.py
Normal file
0
core/management/commands/__init__.py
Normal file
0
core/management/commands/__init__.py
Normal file
43
core/management/commands/check_database.py
Normal file
43
core/management/commands/check_database.py
Normal 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')
|
||||
48
core/management/commands/populate_test_data.py
Normal file
48
core/management/commands/populate_test_data.py
Normal 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'
|
||||
)
|
||||
)
|
||||
@ -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'),
|
||||
]
|
||||
|
||||
170
core/views.py
170
core/views.py
@ -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
|
||||
|
||||
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
BIN
dist/start_server.exe
vendored
BIN
dist/start_server.exe
vendored
Binary file not shown.
Binary file not shown.
@ -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}),
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@ -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'),
|
||||
]
|
||||
|
||||
@ -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"""
|
||||
|
||||
Binary file not shown.
@ -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',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
||||
@ -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"""
|
||||
|
||||
@ -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')
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
||||
@ -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"""
|
||||
|
||||
@ -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')
|
||||
|
||||
144
start_server.py
144
start_server.py
@ -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'])
|
||||
@ -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(
|
||||
|
||||
@ -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>
|
||||
|
||||
49
templates/core/simple_test.html
Normal file
49
templates/core/simple_test.html
Normal 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 %}
|
||||
109
templates/core/test_form.html
Normal file
109
templates/core/test_form.html
Normal 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 %}
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 %}">
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
0
users/management/__init__.py
Normal file
0
users/management/__init__.py
Normal file
57
users/management/commands/change_password.py
Normal file
57
users/management/commands/change_password.py
Normal 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}"')
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user