mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/inventree/InvenTree into plugin-2037
This commit is contained in:
		
							
								
								
									
										7
									
								
								.github/workflows/postgresql.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/postgresql.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,7 @@ jobs: | ||||
|       INVENTREE_DEBUG: info | ||||
|       INVENTREE_MEDIA_ROOT: ./media | ||||
|       INVENTREE_STATIC_ROOT: ./static | ||||
|       INVENTREE_CACHE_HOST: localhost | ||||
|  | ||||
|     services: | ||||
|       postgres: | ||||
| @@ -37,6 +38,11 @@ jobs: | ||||
|         ports: | ||||
|           - 5432:5432 | ||||
|  | ||||
|       redis: | ||||
|         image: redis | ||||
|         ports: | ||||
|           - 6379:6379 | ||||
|  | ||||
|     steps: | ||||
|       - name: Checkout Code | ||||
|         uses: actions/checkout@v2 | ||||
| @@ -49,6 +55,7 @@ jobs: | ||||
|           sudo apt-get install libpq-dev | ||||
|           pip3 install invoke | ||||
|           pip3 install psycopg2 | ||||
|           pip3 install django-redis>=5.0.0 | ||||
|           invoke install | ||||
|       - name: Run Tests | ||||
|         run: invoke test | ||||
|   | ||||
| @@ -15,6 +15,7 @@ import logging | ||||
|  | ||||
| import os | ||||
| import random | ||||
| import socket | ||||
| import string | ||||
| import shutil | ||||
| import sys | ||||
| @@ -378,30 +379,6 @@ REST_FRAMEWORK = { | ||||
|  | ||||
| WSGI_APPLICATION = 'InvenTree.wsgi.application' | ||||
|  | ||||
| background_workers = os.environ.get('INVENTREE_BACKGROUND_WORKERS', None) | ||||
|  | ||||
| if background_workers is not None: | ||||
|     try: | ||||
|         background_workers = int(background_workers) | ||||
|     except ValueError: | ||||
|         background_workers = None | ||||
|  | ||||
| if background_workers is None: | ||||
|     # Sensible default? | ||||
|     background_workers = 4 | ||||
|  | ||||
| # django-q configuration | ||||
| Q_CLUSTER = { | ||||
|     'name': 'InvenTree', | ||||
|     'workers': background_workers, | ||||
|     'timeout': 90, | ||||
|     'retry': 120, | ||||
|     'queue_limit': 50, | ||||
|     'bulk': 10, | ||||
|     'orm': 'default', | ||||
|     'sync': False, | ||||
| } | ||||
|  | ||||
| """ | ||||
| Configure the database backend based on the user-specified values. | ||||
|  | ||||
| @@ -579,12 +556,84 @@ DATABASES = { | ||||
| } | ||||
|  | ||||
|  | ||||
| CACHES = { | ||||
|     'default': { | ||||
|         'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', | ||||
|     }, | ||||
| _cache_config = CONFIG.get("cache", {}) | ||||
| _cache_host = _cache_config.get("host", os.getenv("INVENTREE_CACHE_HOST")) | ||||
| _cache_port = _cache_config.get( | ||||
|     "port", os.getenv("INVENTREE_CACHE_PORT", "6379") | ||||
| ) | ||||
|  | ||||
| if _cache_host: | ||||
|     # We are going to rely upon a possibly non-localhost for our cache, | ||||
|     # so don't wait too long for the cache as nothing in the cache should be | ||||
|     # irreplacable.  Django Q Cluster will just try again later. | ||||
|     _cache_options = { | ||||
|         "CLIENT_CLASS": "django_redis.client.DefaultClient", | ||||
|         "SOCKET_CONNECT_TIMEOUT": int(os.getenv("CACHE_CONNECT_TIMEOUT", "2")), | ||||
|         "SOCKET_TIMEOUT": int(os.getenv("CACHE_SOCKET_TIMEOUT", "2")), | ||||
|         "CONNECTION_POOL_KWARGS": { | ||||
|             "socket_keepalive": _is_true( | ||||
|                 os.getenv("CACHE_TCP_KEEPALIVE", "1") | ||||
|             ), | ||||
|             "socket_keepalive_options": { | ||||
|                 socket.TCP_KEEPCNT: int( | ||||
|                     os.getenv("CACHE_KEEPALIVES_COUNT", "5") | ||||
|                 ), | ||||
|                 socket.TCP_KEEPIDLE: int( | ||||
|                     os.getenv("CACHE_KEEPALIVES_IDLE", "1") | ||||
|                 ), | ||||
|                 socket.TCP_KEEPINTVL: int( | ||||
|                     os.getenv("CACHE_KEEPALIVES_INTERVAL", "1") | ||||
|                 ), | ||||
|                 socket.TCP_USER_TIMEOUT: int( | ||||
|                     os.getenv("CACHE_TCP_USER_TIMEOUT", "1000") | ||||
|                 ), | ||||
|             }, | ||||
|         }, | ||||
|     } | ||||
|     CACHES = { | ||||
|         # Connection configuration for Django Q Cluster | ||||
|         "worker": { | ||||
|             "BACKEND": "django_redis.cache.RedisCache", | ||||
|             "LOCATION": f"redis://{_cache_host}:{_cache_port}/0", | ||||
|             "OPTIONS": _cache_options, | ||||
|         }, | ||||
|         "default": { | ||||
|             "BACKEND": "django_redis.cache.RedisCache", | ||||
|             "LOCATION": f"redis://{_cache_host}:{_cache_port}/1", | ||||
|             "OPTIONS": _cache_options, | ||||
|         }, | ||||
|     } | ||||
| else: | ||||
|     CACHES = { | ||||
|         "default": { | ||||
|             "BACKEND": "django.core.cache.backends.locmem.LocMemCache", | ||||
|         }, | ||||
|     } | ||||
|  | ||||
| try: | ||||
|     # 4 background workers seems like a sensible default | ||||
|     background_workers = int(os.environ.get('INVENTREE_BACKGROUND_WORKERS', 4)) | ||||
| except ValueError: | ||||
|     background_workers = 4 | ||||
|  | ||||
| # django-q configuration | ||||
| Q_CLUSTER = { | ||||
|     'name': 'InvenTree', | ||||
|     'workers': background_workers, | ||||
|     'timeout': 90, | ||||
|     'retry': 120, | ||||
|     'queue_limit': 50, | ||||
|     'bulk': 10, | ||||
|     'orm': 'default', | ||||
|     'sync': False, | ||||
| } | ||||
|  | ||||
| if _cache_host: | ||||
|     # If using external redis cache, make the cache the broker for Django Q | ||||
|     # as well | ||||
|     Q_CLUSTER["django_redis"] = "worker" | ||||
|  | ||||
|  | ||||
| # Password validation | ||||
| # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators | ||||
|  | ||||
|   | ||||
| @@ -34,6 +34,7 @@ src="{% static 'img/blank_image.png' %}" | ||||
| {% include "admin_button.html" with url=url %} | ||||
| {% endif %} | ||||
| <!-- Printing options --> | ||||
| {% if report_enabled %} | ||||
| <div class='btn-group'> | ||||
|     <button id='print-options' title='{% trans "Print actions" %}' class='btn btn-outline-secondary dropdown-toggle' type='button' data-bs-toggle='dropdown'> | ||||
|         <span class='fas fa-print'></span> <span class='caret'></span> | ||||
| @@ -42,6 +43,7 @@ src="{% static 'img/blank_image.png' %}" | ||||
|         <li><a class='dropdown-item' href='#' id='print-build-report'><span class='fas fa-file-pdf'></span> {% trans "Print build order report" %}</a></li> | ||||
|     </ul> | ||||
| </div> | ||||
| {% endif %} | ||||
| <!-- Build actions --> | ||||
| {% if roles.build.change %} | ||||
| <div class='btn-group'> | ||||
| @@ -224,9 +226,11 @@ src="{% static 'img/blank_image.png' %}" | ||||
|         {% endif %} | ||||
|     }); | ||||
|  | ||||
|     {% if report_enabled %} | ||||
|     $('#print-build-report').click(function() { | ||||
|         printBuildReports([{{ build.pk }}]); | ||||
|     }); | ||||
|     {% endif %} | ||||
|  | ||||
|     $("#build-delete").on('click', function() { | ||||
|         launchModalForm( | ||||
|   | ||||
| @@ -27,6 +27,7 @@ | ||||
|         <div class='button-toolbar container-fluid' style='float: right;'> | ||||
|             <div class='btn-group' role='group'> | ||||
|                  | ||||
|                 {% if report_enabled %} | ||||
|                 <div class='btn-group' role='group'> | ||||
|                     <!-- Print actions --> | ||||
|                     <button id='build-print-options' class='btn btn-primary dropdown-toggle' data-bs-toggle='dropdown'> | ||||
| @@ -38,6 +39,7 @@ | ||||
|                         </a></li> | ||||
|                     </ul> | ||||
|                 </div> | ||||
|                 {% endif %} | ||||
|                 <!-- Buttons to switch between list and calendar views --> | ||||
|                 <button class='btn btn-outline-secondary' type='button' id='view-calendar' title='{% trans "Display calendar view" %}'> | ||||
|                     <span class='fas fa-calendar-alt'></span> | ||||
| @@ -181,6 +183,7 @@ loadBuildTable($("#build-table"), { | ||||
|     url: "{% url 'api-build-list' %}", | ||||
| }); | ||||
|  | ||||
| {% if report_enabled %} | ||||
| $('#multi-build-print').click(function() { | ||||
|     var rows = $("#build-table").bootstrapTable('getSelections'); | ||||
|  | ||||
| @@ -192,5 +195,6 @@ $('#multi-build-print').click(function() { | ||||
|  | ||||
|     printBuildReports(build_ids); | ||||
| }); | ||||
| {% endif %} | ||||
|  | ||||
| {% endblock %} | ||||
| @@ -791,6 +791,13 @@ class InvenTreeSetting(BaseInvenTreeSetting): | ||||
|             'validator': InvenTree.validators.validate_part_name_format | ||||
|         }, | ||||
|  | ||||
|         'REPORT_ENABLE': { | ||||
|             'name': _('Enable Reports'), | ||||
|             'description': _('Enable generation of reports'), | ||||
|             'default': False, | ||||
|             'validator': bool, | ||||
|         }, | ||||
|  | ||||
|         'REPORT_DEBUG_MODE': { | ||||
|             'name': _('Debug Mode'), | ||||
|             'description': _('Generate reports in debug mode (HTML output)'), | ||||
|   | ||||
| @@ -29,7 +29,9 @@ | ||||
|         <span class='fas fa-print'></span> <span class='caret'></span> | ||||
|     </button> | ||||
|     <ul class='dropdown-menu' role='menu'> | ||||
|         {% if report_enabled %} | ||||
|         <li><a class='dropdown-item' href='#' id='print-order-report'><span class='fas fa-file-pdf'></span> {% trans "Print purchase order report" %}</a></li> | ||||
|         {% endif %} | ||||
|         <li><a class='dropdown-item' href='#' id='export-order'><span class='fas fa-file-download'></span> {% trans "Export order to file" %}</a></li> | ||||
|     </ul> | ||||
| </div> | ||||
| @@ -169,9 +171,11 @@ $("#place-order").click(function() { | ||||
| }); | ||||
| {% endif %} | ||||
|  | ||||
| {% if report_enabled %} | ||||
| $('#print-order-report').click(function() { | ||||
|     printPurchaseOrderReports([{{ order.pk }}]); | ||||
| }); | ||||
| {% endif %} | ||||
|  | ||||
| $("#edit-order").click(function() { | ||||
|  | ||||
|   | ||||
| @@ -26,10 +26,11 @@ | ||||
|     <div id='table-buttons'> | ||||
|         <div class='button-toolbar container-fluid' style='float: right;'> | ||||
|             <div class='btn-group' role='group'> | ||||
|                  | ||||
|                 {% if report_enabled %} | ||||
|                 <button id='order-print' class='btn btn-outline-secondary' title='{% trans "Print Order Reports" %}'> | ||||
|                     <span class='fas fa-print'></span> | ||||
|                 </button> | ||||
|                 {% endif %} | ||||
|                 <button class='btn btn-outline-secondary' type='button' id='view-calendar' title='{% trans "Display calendar view" %}'> | ||||
|                     <span class='fas fa-calendar-alt'></span> | ||||
|                 </button> | ||||
| @@ -169,6 +170,7 @@ $("#view-list").click(function() { | ||||
|     $("#view-calendar").show(); | ||||
| }); | ||||
|  | ||||
| {% if report_enabled %} | ||||
| $("#order-print").click(function() { | ||||
|     var rows = $("#purchase-order-table").bootstrapTable('getSelections'); | ||||
|  | ||||
| @@ -180,6 +182,7 @@ $("#order-print").click(function() { | ||||
|  | ||||
|     printPurchaseOrderReports(orders); | ||||
| }) | ||||
| {% endif %} | ||||
|  | ||||
| $("#po-create").click(function() { | ||||
|     createPurchaseOrder(); | ||||
|   | ||||
| @@ -39,7 +39,9 @@ src="{% static 'img/blank_image.png' %}" | ||||
|         <span class='fas fa-print'></span> <span class='caret'></span> | ||||
|     </button> | ||||
|     <ul class='dropdown-menu' role='menu'> | ||||
|         {% if report_enabled %} | ||||
|         <li><a class='dropdown-item' href='#' id='print-order-report'><span class='fas fa-file-pdf'></span> {% trans "Print sales order report" %}</a></li> | ||||
|         {% endif %} | ||||
|         <li><a class='dropdown-item' href='#' id='export-order'><span class='fas fa-file-download'></span> {% trans "Export order to file" %}</a></li> | ||||
|         <!-- | ||||
|         <li><a class='dropdown-item' href='#' id='print-packing-list'><span class='fas fa-clipboard-list'></span>{% trans "Print packing list" %}</a></li> | ||||
| @@ -206,9 +208,11 @@ $("#ship-order").click(function() { | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| {% if report_enabled %} | ||||
| $('#print-order-report').click(function() { | ||||
|     printSalesOrderReports([{{ order.pk }}]); | ||||
| }); | ||||
| {% endif %} | ||||
|  | ||||
| $('#export-order').click(function() { | ||||
|     exportOrder('{% url "so-export" order.id %}'); | ||||
|   | ||||
| @@ -29,10 +29,11 @@ | ||||
|     <div id='table-buttons'> | ||||
|         <div class='button-toolbar container-fluid' style='float: right;'> | ||||
|             <div class='btn-group'> | ||||
|                  | ||||
|                 {% if report_enabled %} | ||||
|                 <button id='order-print' class='btn btn-outline-secondary' title='{% trans "Print Order Reports" %}'> | ||||
|                     <span class='fas fa-print'></span> | ||||
|                 </button> | ||||
|                 {% endif %} | ||||
|                 <button class='btn btn-outline-secondary' type='button' id='view-calendar' title='{% trans "Display calendar view" %}'> | ||||
|                     <span class='fas fa-calendar-alt'></span> | ||||
|                 </button> | ||||
| @@ -173,6 +174,7 @@ loadSalesOrderTable("#sales-order-table", { | ||||
|     url: "{% url 'api-so-list' %}", | ||||
| }); | ||||
|  | ||||
| {% if report_enabled %} | ||||
| $("#order-print").click(function() { | ||||
|     var rows = $("#sales-order-table").bootstrapTable('getSelections'); | ||||
|  | ||||
| @@ -184,6 +186,7 @@ $("#order-print").click(function() { | ||||
|  | ||||
|     printSalesOrderReports(orders); | ||||
| }) | ||||
| {% endif %} | ||||
|  | ||||
| $("#so-create").click(function() { | ||||
|     createSalesOrder(); | ||||
|   | ||||
| @@ -164,7 +164,9 @@ | ||||
|                     <li><a class='dropdown-item' href='#' id='multi-part-category' title='{% trans "Set category" %}'>{% trans "Set Category" %}</a></li> | ||||
|                     {% endif %} | ||||
|                     <li><a class='dropdown-item' href='#' id='multi-part-order' title='{% trans "Order parts" %}'>{% trans "Order Parts" %}</a></li> | ||||
|                     {% if report_enabled %} | ||||
|                     <li><a class='dropdown-item' href='#' id='multi-part-print-label' title='{% trans "Print Labels" %}'>{% trans "Print Labels" %}</a></li> | ||||
|                     {% endif %} | ||||
|                     <li><a class='dropdown-item' href='#' id='multi-part-export' title='{% trans "Export" %}'>{% trans "Export Data" %}</a></li> | ||||
|                 </ul> | ||||
|             </div> | ||||
|   | ||||
| @@ -373,7 +373,9 @@ | ||||
|                     </button> | ||||
|                     <ul class='dropdown-menu' role='menu'> | ||||
|                         <li><a class='dropdown-item' href='#' id='download-bom'><span class='fas fa-file-download'></span> {% trans "Export BOM" %}</a></li> | ||||
|                         {% if report_enabled %} | ||||
|                         <li><a class='dropdown-item' href='#' id='print-bom-report'><span class='fas fa-file-pdf'></span> {% trans "Print BOM Report" %}</a></li> | ||||
|                         {% endif %} | ||||
|                     </ul> | ||||
|                 </div> | ||||
|                 <!-- Actions menu --> | ||||
| @@ -766,9 +768,11 @@ | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         {% if report_enabled %} | ||||
|         $("#print-bom-report").click(function() { | ||||
|             printBomReports([{{ part.pk }}]); | ||||
|         }); | ||||
|         {% endif %} | ||||
|     }); | ||||
|  | ||||
|     // Load the "related parts" tab | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|  | ||||
| <table class='table table-striped table-condensed'> | ||||
|     <tbody> | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_DEFAULT_PAGE_SIZE" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_DEBUG_MODE" %} | ||||
|         {% include "InvenTree/settings/setting.html" with key="REPORT_ENABLE_TEST_REPORT" %} | ||||
|   | ||||
| @@ -5,6 +5,9 @@ | ||||
| {% load inventree_extras %} | ||||
| {% load plugin_extras %} | ||||
|  | ||||
| {% block breadcrumb_list %} | ||||
| {% endblock %} | ||||
|  | ||||
| {% block page_title %} | ||||
| {% inventree_title %} | {% trans "Settings" %} | ||||
| {% endblock %} | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| {% settings_value 'BARCODE_ENABLE' as barcodes %} | ||||
| {% settings_value 'REPORT_ENABLE_TEST_REPORT' as test_report_enabled %} | ||||
| {% settings_value "REPORT_ENABLE" as report_enabled %} | ||||
|  | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|   | ||||
| @@ -11,3 +11,6 @@ psycopg2>=2.9.1 | ||||
| mysqlclient>=2.0.3 | ||||
| pgcli>=3.1.0 | ||||
| mariadb>=1.0.7 | ||||
|  | ||||
| # Cache | ||||
| django-redis>=5.0.0 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user