mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-30 04:26:44 +00:00
Merge remote-tracking branch 'inventree/master' into variant-available
# Conflicts: # InvenTree/InvenTree/version.py
This commit is contained in:
commit
3b4d0c2f9c
149
InvenTree/InvenTree/api_version.py
Normal file
149
InvenTree/InvenTree/api_version.py
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
"""
|
||||||
|
InvenTree API version information
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# InvenTree API version
|
||||||
|
INVENTREE_API_VERSION = 40
|
||||||
|
|
||||||
|
"""
|
||||||
|
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
||||||
|
|
||||||
|
v40 -> 2022-04-19
|
||||||
|
- Adds ability to filter StockItem list by "tracked" parameter
|
||||||
|
- This checks the serial number or batch code fields
|
||||||
|
|
||||||
|
v39 -> 2022-04-18
|
||||||
|
- Adds ability to filter StockItem list by "has_batch" parameter
|
||||||
|
|
||||||
|
v38 -> 2022-04-14 : https://github.com/inventree/InvenTree/pull/2828
|
||||||
|
- Adds the ability to include stock test results for "installed items"
|
||||||
|
|
||||||
|
v37 -> 2022-04-07 : https://github.com/inventree/InvenTree/pull/2806
|
||||||
|
- Adds extra stock availability information to the BomItem serializer
|
||||||
|
|
||||||
|
v36 -> 2022-04-03
|
||||||
|
- Adds ability to filter part list endpoint by unallocated_stock argument
|
||||||
|
|
||||||
|
v35 -> 2022-04-01 : https://github.com/inventree/InvenTree/pull/2797
|
||||||
|
- Adds stock allocation information to the Part API
|
||||||
|
- Adds calculated field for "unallocated_quantity"
|
||||||
|
|
||||||
|
v34 -> 2022-03-25
|
||||||
|
- Change permissions for "plugin list" API endpoint (now allows any authenticated user)
|
||||||
|
|
||||||
|
v33 -> 2022-03-24
|
||||||
|
- Adds "plugins_enabled" information to root API endpoint
|
||||||
|
|
||||||
|
v32 -> 2022-03-19
|
||||||
|
- Adds "parameters" detail to Part API endpoint (use ¶meters=true)
|
||||||
|
- Adds ability to filter PartParameterTemplate API by Part instance
|
||||||
|
- Adds ability to filter PartParameterTemplate API by PartCategory instance
|
||||||
|
|
||||||
|
v31 -> 2022-03-14
|
||||||
|
- Adds "updated" field to SupplierPriceBreakList and SupplierPriceBreakDetail API endpoints
|
||||||
|
|
||||||
|
v30 -> 2022-03-09
|
||||||
|
- Adds "exclude_location" field to BuildAutoAllocation API endpoint
|
||||||
|
- Allows BuildItem API endpoint to be filtered by BomItem relation
|
||||||
|
|
||||||
|
v29 -> 2022-03-08
|
||||||
|
- Adds "scheduling" endpoint for predicted stock scheduling information
|
||||||
|
|
||||||
|
v28 -> 2022-03-04
|
||||||
|
- Adds an API endpoint for auto allocation of stock items against a build order
|
||||||
|
- Ref: https://github.com/inventree/InvenTree/pull/2713
|
||||||
|
|
||||||
|
v27 -> 2022-02-28
|
||||||
|
- Adds target_date field to individual line items for purchase orders and sales orders
|
||||||
|
|
||||||
|
v26 -> 2022-02-17
|
||||||
|
- Adds API endpoint for uploading a BOM file and extracting data
|
||||||
|
|
||||||
|
v25 -> 2022-02-17
|
||||||
|
- Adds ability to filter "part" list endpoint by "in_bom_for" argument
|
||||||
|
|
||||||
|
v24 -> 2022-02-10
|
||||||
|
- Adds API endpoint for deleting (cancelling) build order outputs
|
||||||
|
|
||||||
|
v23 -> 2022-02-02
|
||||||
|
- Adds API endpoints for managing plugin classes
|
||||||
|
- Adds API endpoints for managing plugin settings
|
||||||
|
|
||||||
|
v22 -> 2021-12-20
|
||||||
|
- Adds API endpoint to "merge" multiple stock items
|
||||||
|
|
||||||
|
v21 -> 2021-12-04
|
||||||
|
- Adds support for multiple "Shipments" against a SalesOrder
|
||||||
|
- Refactors process for stock allocation against a SalesOrder
|
||||||
|
|
||||||
|
v20 -> 2021-12-03
|
||||||
|
- Adds ability to filter POLineItem endpoint by "base_part"
|
||||||
|
- Adds optional "order_detail" to POLineItem list endpoint
|
||||||
|
|
||||||
|
v19 -> 2021-12-02
|
||||||
|
- Adds the ability to filter the StockItem API by "part_tree"
|
||||||
|
- Returns only stock items which match a particular part.tree_id field
|
||||||
|
|
||||||
|
v18 -> 2021-11-15
|
||||||
|
- Adds the ability to filter BomItem API by "uses" field
|
||||||
|
- This returns a list of all BomItems which "use" the specified part
|
||||||
|
- Includes inherited BomItem objects
|
||||||
|
|
||||||
|
v17 -> 2021-11-09
|
||||||
|
- Adds API endpoints for GLOBAL and USER settings objects
|
||||||
|
- Ref: https://github.com/inventree/InvenTree/pull/2275
|
||||||
|
|
||||||
|
v16 -> 2021-10-17
|
||||||
|
- Adds API endpoint for completing build order outputs
|
||||||
|
|
||||||
|
v15 -> 2021-10-06
|
||||||
|
- Adds detail endpoint for SalesOrderAllocation model
|
||||||
|
- Allows use of the API forms interface for adjusting SalesOrderAllocation objects
|
||||||
|
|
||||||
|
v14 -> 2021-10-05
|
||||||
|
- Stock adjustment actions API is improved, using native DRF serializer support
|
||||||
|
- However adjustment actions now only support 'pk' as a lookup field
|
||||||
|
|
||||||
|
v13 -> 2021-10-05
|
||||||
|
- Adds API endpoint to allocate stock items against a BuildOrder
|
||||||
|
- Updates StockItem API with improved filtering against BomItem data
|
||||||
|
|
||||||
|
v12 -> 2021-09-07
|
||||||
|
- Adds API endpoint to receive stock items against a PurchaseOrder
|
||||||
|
|
||||||
|
v11 -> 2021-08-26
|
||||||
|
- Adds "units" field to PartBriefSerializer
|
||||||
|
- This allows units to be introspected from the "part_detail" field in the StockItem serializer
|
||||||
|
|
||||||
|
v10 -> 2021-08-23
|
||||||
|
- Adds "purchase_price_currency" to StockItem serializer
|
||||||
|
- Adds "purchase_price_string" to StockItem serializer
|
||||||
|
- Purchase price is now writable for StockItem serializer
|
||||||
|
|
||||||
|
v9 -> 2021-08-09
|
||||||
|
- Adds "price_string" to part pricing serializers
|
||||||
|
|
||||||
|
v8 -> 2021-07-19
|
||||||
|
- Refactors the API interface for SupplierPart and ManufacturerPart models
|
||||||
|
- ManufacturerPart objects can no longer be created via the SupplierPart API endpoint
|
||||||
|
|
||||||
|
v7 -> 2021-07-03
|
||||||
|
- Introduced the concept of "API forms" in https://github.com/inventree/InvenTree/pull/1716
|
||||||
|
- API OPTIONS endpoints provide comprehensive field metedata
|
||||||
|
- Multiple new API endpoints added for database models
|
||||||
|
|
||||||
|
v6 -> 2021-06-23
|
||||||
|
- Part and Company images can now be directly uploaded via the REST API
|
||||||
|
|
||||||
|
v5 -> 2021-06-21
|
||||||
|
- Adds API interface for manufacturer part parameters
|
||||||
|
|
||||||
|
v4 -> 2021-06-01
|
||||||
|
- BOM items can now accept "variant stock" to be assigned against them
|
||||||
|
- Many slight API tweaks were needed to get this to work properly!
|
||||||
|
|
||||||
|
v3 -> 2021-05-22:
|
||||||
|
- The updated StockItem "history tracking" now uses a different interface
|
||||||
|
|
||||||
|
"""
|
@ -282,6 +282,7 @@ INSTALLED_APPS = [
|
|||||||
|
|
||||||
MIDDLEWARE = CONFIG.get('middleware', [
|
MIDDLEWARE = CONFIG.get('middleware', [
|
||||||
'django.middleware.security.SecurityMiddleware',
|
'django.middleware.security.SecurityMiddleware',
|
||||||
|
'x_forwarded_for.middleware.XForwardedForMiddleware',
|
||||||
'user_sessions.middleware.SessionMiddleware', # db user sessions
|
'user_sessions.middleware.SessionMiddleware', # db user sessions
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
'django.middleware.common.CommonMiddleware',
|
'django.middleware.common.CommonMiddleware',
|
||||||
@ -662,11 +663,13 @@ LANGUAGE_CODE = CONFIG.get('language', 'en-us')
|
|||||||
|
|
||||||
# If a new language translation is supported, it must be added here
|
# If a new language translation is supported, it must be added here
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
|
('cs', _('Czech')),
|
||||||
('de', _('German')),
|
('de', _('German')),
|
||||||
('el', _('Greek')),
|
('el', _('Greek')),
|
||||||
('en', _('English')),
|
('en', _('English')),
|
||||||
('es', _('Spanish')),
|
('es', _('Spanish')),
|
||||||
('es-mx', _('Spanish (Mexican)')),
|
('es-mx', _('Spanish (Mexican)')),
|
||||||
|
('fa', _('Farsi / Persian')),
|
||||||
('fr', _('French')),
|
('fr', _('French')),
|
||||||
('he', _('Hebrew')),
|
('he', _('Hebrew')),
|
||||||
('hu', _('Hungarian')),
|
('hu', _('Hungarian')),
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/*! jQuery UI - v1.12.1 - 2021-07-18
|
/*! jQuery UI - v1.13.0 - 2021-10-07
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
* Includes: widget.js, position.js, disable-selection.js, keycode.js, unique-id.js, widgets/resizable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js
|
* Includes: widget.js, position.js, disable-selection.js, keycode.js, unique-id.js, widgets/resizable.js, widgets/autocomplete.js, widgets/menu.js, widgets/mouse.js
|
||||||
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
* Copyright jQuery Foundation and other contributors; Licensed MIT */
|
||||||
@ -17,11 +17,11 @@
|
|||||||
|
|
||||||
$.ui = $.ui || {};
|
$.ui = $.ui || {};
|
||||||
|
|
||||||
var version = $.ui.version = "1.12.1";
|
var version = $.ui.version = "1.13.1";
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Widget 1.12.1
|
* jQuery UI Widget 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -744,7 +744,7 @@ var widget = $.widget;
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Position 1.12.1
|
* jQuery UI Position 1.13.1
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1232,7 +1232,7 @@ var position = $.ui.position;
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Disable Selection 1.12.1
|
* jQuery UI Disable Selection 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1268,7 +1268,7 @@ var disableSelection = $.fn.extend( {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Keycode 1.12.1
|
* jQuery UI Keycode 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1303,7 +1303,7 @@ var keycode = $.ui.keyCode = {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Unique ID 1.12.1
|
* jQuery UI Unique ID 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1347,7 +1347,7 @@ var uniqueId = $.fn.extend( {
|
|||||||
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Mouse 1.12.1
|
* jQuery UI Mouse 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1368,7 +1368,7 @@ $( document ).on( "mouseup", function() {
|
|||||||
} );
|
} );
|
||||||
|
|
||||||
var widgetsMouse = $.widget( "ui.mouse", {
|
var widgetsMouse = $.widget( "ui.mouse", {
|
||||||
version: "1.12.1",
|
version: "1.13.0",
|
||||||
options: {
|
options: {
|
||||||
cancel: "input, textarea, button, select, option",
|
cancel: "input, textarea, button, select, option",
|
||||||
distance: 1,
|
distance: 1,
|
||||||
@ -1592,7 +1592,7 @@ var plugin = $.ui.plugin = {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Resizable 1.12.1
|
* jQuery UI Resizable 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -1612,7 +1612,7 @@ var plugin = $.ui.plugin = {
|
|||||||
|
|
||||||
|
|
||||||
$.widget( "ui.resizable", $.ui.mouse, {
|
$.widget( "ui.resizable", $.ui.mouse, {
|
||||||
version: "1.12.1",
|
version: "1.13.0",
|
||||||
widgetEventPrefix: "resize",
|
widgetEventPrefix: "resize",
|
||||||
options: {
|
options: {
|
||||||
alsoResize: false,
|
alsoResize: false,
|
||||||
@ -2806,7 +2806,7 @@ var safeActiveElement = $.ui.safeActiveElement = function( document ) {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Menu 1.12.1
|
* jQuery UI Menu 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -2826,7 +2826,7 @@ var safeActiveElement = $.ui.safeActiveElement = function( document ) {
|
|||||||
|
|
||||||
|
|
||||||
var widgetsMenu = $.widget( "ui.menu", {
|
var widgetsMenu = $.widget( "ui.menu", {
|
||||||
version: "1.12.1",
|
version: "1.13.0",
|
||||||
defaultElement: "<ul>",
|
defaultElement: "<ul>",
|
||||||
delay: 300,
|
delay: 300,
|
||||||
options: {
|
options: {
|
||||||
@ -3461,7 +3461,7 @@ var widgetsMenu = $.widget( "ui.menu", {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* jQuery UI Autocomplete 1.12.1
|
* jQuery UI Autocomplete 1.13.0
|
||||||
* http://jqueryui.com
|
* http://jqueryui.com
|
||||||
*
|
*
|
||||||
* Copyright jQuery Foundation and other contributors
|
* Copyright jQuery Foundation and other contributors
|
||||||
@ -3481,7 +3481,7 @@ var widgetsMenu = $.widget( "ui.menu", {
|
|||||||
|
|
||||||
|
|
||||||
$.widget( "ui.autocomplete", {
|
$.widget( "ui.autocomplete", {
|
||||||
version: "1.12.1",
|
version: "1.13.0",
|
||||||
defaultElement: "<input>",
|
defaultElement: "<input>",
|
||||||
options: {
|
options: {
|
||||||
appendTo: null,
|
appendTo: null,
|
||||||
|
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
|||||||
"name": "jquery-ui",
|
"name": "jquery-ui",
|
||||||
"title": "jQuery UI",
|
"title": "jQuery UI",
|
||||||
"description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
|
"description": "A curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library.",
|
||||||
"version": "1.12.1",
|
"version": "1.13.0",
|
||||||
"homepage": "http://jqueryui.com",
|
"homepage": "http://jqueryui.com",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "jQuery Foundation and other contributors",
|
"name": "jQuery Foundation and other contributors",
|
||||||
|
@ -255,6 +255,9 @@ class StockHistoryCode(StatusCode):
|
|||||||
# Stock merging operations
|
# Stock merging operations
|
||||||
MERGED_STOCK_ITEMS = 45
|
MERGED_STOCK_ITEMS = 45
|
||||||
|
|
||||||
|
# Convert stock item to variant
|
||||||
|
CONVERTED_TO_VARIANT = 48
|
||||||
|
|
||||||
# Build order codes
|
# Build order codes
|
||||||
BUILD_OUTPUT_CREATED = 50
|
BUILD_OUTPUT_CREATED = 50
|
||||||
BUILD_OUTPUT_COMPLETED = 55
|
BUILD_OUTPUT_COMPLETED = 55
|
||||||
@ -294,6 +297,8 @@ class StockHistoryCode(StatusCode):
|
|||||||
|
|
||||||
MERGED_STOCK_ITEMS: _('Merged stock items'),
|
MERGED_STOCK_ITEMS: _('Merged stock items'),
|
||||||
|
|
||||||
|
CONVERTED_TO_VARIANT: _('Converted to variant'),
|
||||||
|
|
||||||
SENT_TO_CUSTOMER: _('Sent to customer'),
|
SENT_TO_CUSTOMER: _('Sent to customer'),
|
||||||
RETURNED_FROM_CUSTOMER: _('Returned from customer'),
|
RETURNED_FROM_CUSTOMER: _('Returned from customer'),
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
""" Version information for InvenTree.
|
"""
|
||||||
|
Version information for InvenTree.
|
||||||
Provides information on the current InvenTree version
|
Provides information on the current InvenTree version
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -8,150 +9,11 @@ import re
|
|||||||
|
|
||||||
import common.models
|
import common.models
|
||||||
|
|
||||||
|
from InvenTree.api_version import INVENTREE_API_VERSION
|
||||||
|
|
||||||
# InvenTree software version
|
# InvenTree software version
|
||||||
INVENTREE_SW_VERSION = "0.7.0 dev"
|
INVENTREE_SW_VERSION = "0.7.0 dev"
|
||||||
|
|
||||||
# InvenTree API version
|
|
||||||
INVENTREE_API_VERSION = 39
|
|
||||||
|
|
||||||
"""
|
|
||||||
Increment this API version number whenever there is a significant change to the API that any clients need to know about
|
|
||||||
|
|
||||||
v39 -> 2022-04-15 : https://github.com/inventree/InvenTree/pull/2833
|
|
||||||
- Adds 'available_variant_stock' information to the BomItem API
|
|
||||||
|
|
||||||
v38 -> 2022-04-14 : https://github.com/inventree/InvenTree/pull/2828
|
|
||||||
- Adds the ability to include stock test results for "installed items"
|
|
||||||
|
|
||||||
v37 -> 2022-04-07 : https://github.com/inventree/InvenTree/pull/2806
|
|
||||||
- Adds extra stock availability information to the BomItem serializer
|
|
||||||
|
|
||||||
v36 -> 2022-04-03
|
|
||||||
- Adds ability to filter part list endpoint by unallocated_stock argument
|
|
||||||
|
|
||||||
v35 -> 2022-04-01 : https://github.com/inventree/InvenTree/pull/2797
|
|
||||||
- Adds stock allocation information to the Part API
|
|
||||||
- Adds calculated field for "unallocated_quantity"
|
|
||||||
|
|
||||||
v34 -> 2022-03-25
|
|
||||||
- Change permissions for "plugin list" API endpoint (now allows any authenticated user)
|
|
||||||
|
|
||||||
v33 -> 2022-03-24
|
|
||||||
- Adds "plugins_enabled" information to root API endpoint
|
|
||||||
|
|
||||||
v32 -> 2022-03-19
|
|
||||||
- Adds "parameters" detail to Part API endpoint (use ¶meters=true)
|
|
||||||
- Adds ability to filter PartParameterTemplate API by Part instance
|
|
||||||
- Adds ability to filter PartParameterTemplate API by PartCategory instance
|
|
||||||
|
|
||||||
v31 -> 2022-03-14
|
|
||||||
- Adds "updated" field to SupplierPriceBreakList and SupplierPriceBreakDetail API endpoints
|
|
||||||
|
|
||||||
v30 -> 2022-03-09
|
|
||||||
- Adds "exclude_location" field to BuildAutoAllocation API endpoint
|
|
||||||
- Allows BuildItem API endpoint to be filtered by BomItem relation
|
|
||||||
|
|
||||||
v29 -> 2022-03-08
|
|
||||||
- Adds "scheduling" endpoint for predicted stock scheduling information
|
|
||||||
|
|
||||||
v28 -> 2022-03-04
|
|
||||||
- Adds an API endpoint for auto allocation of stock items against a build order
|
|
||||||
- Ref: https://github.com/inventree/InvenTree/pull/2713
|
|
||||||
|
|
||||||
v27 -> 2022-02-28
|
|
||||||
- Adds target_date field to individual line items for purchase orders and sales orders
|
|
||||||
|
|
||||||
v26 -> 2022-02-17
|
|
||||||
- Adds API endpoint for uploading a BOM file and extracting data
|
|
||||||
|
|
||||||
v25 -> 2022-02-17
|
|
||||||
- Adds ability to filter "part" list endpoint by "in_bom_for" argument
|
|
||||||
|
|
||||||
v24 -> 2022-02-10
|
|
||||||
- Adds API endpoint for deleting (cancelling) build order outputs
|
|
||||||
|
|
||||||
v23 -> 2022-02-02
|
|
||||||
- Adds API endpoints for managing plugin classes
|
|
||||||
- Adds API endpoints for managing plugin settings
|
|
||||||
|
|
||||||
v22 -> 2021-12-20
|
|
||||||
- Adds API endpoint to "merge" multiple stock items
|
|
||||||
|
|
||||||
v21 -> 2021-12-04
|
|
||||||
- Adds support for multiple "Shipments" against a SalesOrder
|
|
||||||
- Refactors process for stock allocation against a SalesOrder
|
|
||||||
|
|
||||||
v20 -> 2021-12-03
|
|
||||||
- Adds ability to filter POLineItem endpoint by "base_part"
|
|
||||||
- Adds optional "order_detail" to POLineItem list endpoint
|
|
||||||
|
|
||||||
v19 -> 2021-12-02
|
|
||||||
- Adds the ability to filter the StockItem API by "part_tree"
|
|
||||||
- Returns only stock items which match a particular part.tree_id field
|
|
||||||
|
|
||||||
v18 -> 2021-11-15
|
|
||||||
- Adds the ability to filter BomItem API by "uses" field
|
|
||||||
- This returns a list of all BomItems which "use" the specified part
|
|
||||||
- Includes inherited BomItem objects
|
|
||||||
|
|
||||||
v17 -> 2021-11-09
|
|
||||||
- Adds API endpoints for GLOBAL and USER settings objects
|
|
||||||
- Ref: https://github.com/inventree/InvenTree/pull/2275
|
|
||||||
|
|
||||||
v16 -> 2021-10-17
|
|
||||||
- Adds API endpoint for completing build order outputs
|
|
||||||
|
|
||||||
v15 -> 2021-10-06
|
|
||||||
- Adds detail endpoint for SalesOrderAllocation model
|
|
||||||
- Allows use of the API forms interface for adjusting SalesOrderAllocation objects
|
|
||||||
|
|
||||||
v14 -> 2021-10-05
|
|
||||||
- Stock adjustment actions API is improved, using native DRF serializer support
|
|
||||||
- However adjustment actions now only support 'pk' as a lookup field
|
|
||||||
|
|
||||||
v13 -> 2021-10-05
|
|
||||||
- Adds API endpoint to allocate stock items against a BuildOrder
|
|
||||||
- Updates StockItem API with improved filtering against BomItem data
|
|
||||||
|
|
||||||
v12 -> 2021-09-07
|
|
||||||
- Adds API endpoint to receive stock items against a PurchaseOrder
|
|
||||||
|
|
||||||
v11 -> 2021-08-26
|
|
||||||
- Adds "units" field to PartBriefSerializer
|
|
||||||
- This allows units to be introspected from the "part_detail" field in the StockItem serializer
|
|
||||||
|
|
||||||
v10 -> 2021-08-23
|
|
||||||
- Adds "purchase_price_currency" to StockItem serializer
|
|
||||||
- Adds "purchase_price_string" to StockItem serializer
|
|
||||||
- Purchase price is now writable for StockItem serializer
|
|
||||||
|
|
||||||
v9 -> 2021-08-09
|
|
||||||
- Adds "price_string" to part pricing serializers
|
|
||||||
|
|
||||||
v8 -> 2021-07-19
|
|
||||||
- Refactors the API interface for SupplierPart and ManufacturerPart models
|
|
||||||
- ManufacturerPart objects can no longer be created via the SupplierPart API endpoint
|
|
||||||
|
|
||||||
v7 -> 2021-07-03
|
|
||||||
- Introduced the concept of "API forms" in https://github.com/inventree/InvenTree/pull/1716
|
|
||||||
- API OPTIONS endpoints provide comprehensive field metedata
|
|
||||||
- Multiple new API endpoints added for database models
|
|
||||||
|
|
||||||
v6 -> 2021-06-23
|
|
||||||
- Part and Company images can now be directly uploaded via the REST API
|
|
||||||
|
|
||||||
v5 -> 2021-06-21
|
|
||||||
- Adds API interface for manufacturer part parameters
|
|
||||||
|
|
||||||
v4 -> 2021-06-01
|
|
||||||
- BOM items can now accept "variant stock" to be assigned against them
|
|
||||||
- Many slight API tweaks were needed to get this to work properly!
|
|
||||||
|
|
||||||
v3 -> 2021-05-22:
|
|
||||||
- The updated StockItem "history tracking" now uses a different interface
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def inventreeInstanceName():
|
def inventreeInstanceName():
|
||||||
""" Returns the InstanceName settings for the current database """
|
""" Returns the InstanceName settings for the current database """
|
||||||
|
@ -238,7 +238,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
{% if company.is_customer %}
|
{% if company.is_customer %}
|
||||||
onPanelLoad('panel-sales-orders', function() {
|
onPanelLoad('sales-orders', function() {
|
||||||
loadSalesOrderTable("#sales-order-table", {
|
loadSalesOrderTable("#sales-order-table", {
|
||||||
url: "{% url 'api-so-list' %}",
|
url: "{% url 'api-so-list' %}",
|
||||||
params: {
|
params: {
|
||||||
|
BIN
InvenTree/locale/cs/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/cs/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
10114
InvenTree/locale/cs/LC_MESSAGES/django.po
Normal file
10114
InvenTree/locale/cs/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
InvenTree/locale/fa/LC_MESSAGES/django.mo
Normal file
BIN
InvenTree/locale/fa/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
7845
InvenTree/locale/fa/LC_MESSAGES/django.po
Normal file
7845
InvenTree/locale/fa/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
|||||||
{% load i18n %}
|
|
||||||
|
|
||||||
<div class="markdownx row">
|
|
||||||
<div class="markdown col-md-6">
|
|
||||||
{% include 'django/forms/widgets/textarea.html' %}
|
|
||||||
</div>
|
|
||||||
<div class="markdown col-md-6">
|
|
||||||
<div class="markdownx-preview"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -187,6 +187,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='panel panel-hidden' id='panel-stock'>
|
||||||
|
<div class='panel-heading'>
|
||||||
|
<h4>{% trans "Stock Items" %}</h4>
|
||||||
|
</div>
|
||||||
|
<div class='panel-content'>
|
||||||
|
{% include "stock_table.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class='panel panel-hidden' id='panel-parameters'>
|
<div class='panel panel-hidden' id='panel-parameters'>
|
||||||
<div class='panel-heading'>
|
<div class='panel-heading'>
|
||||||
<h4>{% trans "Part Parameters" %}</h4>
|
<h4>{% trans "Part Parameters" %}</h4>
|
||||||
@ -223,6 +232,21 @@
|
|||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
{% if category %}
|
{% if category %}
|
||||||
|
|
||||||
|
onPanelLoad('stock', function() {
|
||||||
|
loadStockTable(
|
||||||
|
$('#stock-table'),
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
category: {{ category.pk }},
|
||||||
|
part_detail: true,
|
||||||
|
location_detail: true,
|
||||||
|
supplier_part_detail: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
onPanelLoad('parameters', function() {
|
onPanelLoad('parameters', function() {
|
||||||
loadParametricPartTable(
|
loadParametricPartTable(
|
||||||
"#parametric-part-table",
|
"#parametric-part-table",
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
{% include "sidebar_link.html" with url=url text=text icon="fa-file-upload" %}
|
{% include "sidebar_link.html" with url=url text=text icon="fa-file-upload" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if category %}
|
{% if category %}
|
||||||
|
{% trans "Stock Items" as text %}
|
||||||
|
{% include "sidebar_item.html" with label='stock' text=text icon='fa-boxes' %}
|
||||||
{% trans "Parameters" as text %}
|
{% trans "Parameters" as text %}
|
||||||
{% include "sidebar_item.html" with label="parameters" text=text icon="fa-tasks" %}
|
{% include "sidebar_item.html" with label="parameters" text=text icon="fa-tasks" %}
|
||||||
{% endif %}
|
{% endif %}
|
@ -94,6 +94,14 @@ class IntegrationPluginBase(MixinBase, plugin_base.InvenTreePluginBase):
|
|||||||
"""
|
"""
|
||||||
return getattr(self, 'is_package', False)
|
return getattr(self, 'is_package', False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_sample(self):
|
||||||
|
"""
|
||||||
|
Is this plugin part of the samples?
|
||||||
|
"""
|
||||||
|
path = str(self.package_path)
|
||||||
|
return path.startswith('plugin/samples/')
|
||||||
|
|
||||||
# region properties
|
# region properties
|
||||||
@property
|
@property
|
||||||
def slug(self):
|
def slug(self):
|
||||||
|
@ -402,11 +402,51 @@ class StockFilter(rest_filters.FilterSet):
|
|||||||
serialized = rest_filters.BooleanFilter(label='Has serial number', method='filter_serialized')
|
serialized = rest_filters.BooleanFilter(label='Has serial number', method='filter_serialized')
|
||||||
|
|
||||||
def filter_serialized(self, queryset, name, value):
|
def filter_serialized(self, queryset, name, value):
|
||||||
|
"""
|
||||||
|
Filter by whether the StockItem has a serial number (or not)
|
||||||
|
"""
|
||||||
|
|
||||||
|
q = Q(serial=None) | Q(serial='')
|
||||||
|
|
||||||
if str2bool(value):
|
if str2bool(value):
|
||||||
queryset = queryset.exclude(serial=None)
|
queryset = queryset.exclude(q)
|
||||||
else:
|
else:
|
||||||
queryset = queryset.filter(serial=None)
|
queryset = queryset.filter(q)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
has_batch = rest_filters.BooleanFilter(label='Has batch code', method='filter_has_batch')
|
||||||
|
|
||||||
|
def filter_has_batch(self, queryset, name, value):
|
||||||
|
"""
|
||||||
|
Filter by whether the StockItem has a batch code (or not)
|
||||||
|
"""
|
||||||
|
|
||||||
|
q = Q(batch=None) | Q(batch='')
|
||||||
|
|
||||||
|
if str2bool(value):
|
||||||
|
queryset = queryset.exclude(q)
|
||||||
|
else:
|
||||||
|
queryset = queryset.filter(q)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
tracked = rest_filters.BooleanFilter(label='Tracked', method='filter_tracked')
|
||||||
|
|
||||||
|
def filter_tracked(self, queryset, name, value):
|
||||||
|
"""
|
||||||
|
Filter by whether this stock item is *tracked*, meaning either:
|
||||||
|
- It has a serial number
|
||||||
|
- It has a batch code
|
||||||
|
"""
|
||||||
|
|
||||||
|
q_batch = Q(batch=None) | Q(batch='')
|
||||||
|
q_serial = Q(serial=None) | Q(serial='')
|
||||||
|
|
||||||
|
if str2bool(value):
|
||||||
|
queryset = queryset.exclude(q_batch & q_serial)
|
||||||
|
else:
|
||||||
|
queryset = queryset.filter(q_batch & q_serial)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@ -1220,6 +1260,15 @@ class StockTrackingList(generics.ListAPIView):
|
|||||||
if not deltas:
|
if not deltas:
|
||||||
deltas = {}
|
deltas = {}
|
||||||
|
|
||||||
|
# Add part detail
|
||||||
|
if 'part' in deltas:
|
||||||
|
try:
|
||||||
|
part = Part.objects.get(pk=deltas['part'])
|
||||||
|
serializer = PartBriefSerializer(part)
|
||||||
|
deltas['part_detail'] = serializer.data
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
# Add location detail
|
# Add location detail
|
||||||
if 'location' in deltas:
|
if 'location' in deltas:
|
||||||
try:
|
try:
|
||||||
|
@ -453,6 +453,12 @@ class StockItem(MPTTModel):
|
|||||||
|
|
||||||
super().clean()
|
super().clean()
|
||||||
|
|
||||||
|
if self.serial is not None and type(self.serial) is str:
|
||||||
|
self.serial = self.serial.strip()
|
||||||
|
|
||||||
|
if self.batch is not None and type(self.batch) is str:
|
||||||
|
self.batch = self.batch.strip()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.part.trackable:
|
if self.part.trackable:
|
||||||
# Trackable parts must have integer values for quantity field!
|
# Trackable parts must have integer values for quantity field!
|
||||||
@ -718,6 +724,33 @@ class StockItem(MPTTModel):
|
|||||||
help_text=_('Select Owner'),
|
help_text=_('Select Owner'),
|
||||||
related_name='stock_items')
|
related_name='stock_items')
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def convert_to_variant(self, variant, user, notes=None):
|
||||||
|
"""
|
||||||
|
Convert this StockItem instance to a "variant",
|
||||||
|
i.e. change the "part" reference field
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not variant:
|
||||||
|
# Ignore null values
|
||||||
|
return
|
||||||
|
|
||||||
|
if variant == self.part:
|
||||||
|
# Variant is the same as the current part
|
||||||
|
return
|
||||||
|
|
||||||
|
self.part = variant
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
self.add_tracking_entry(
|
||||||
|
StockHistoryCode.CONVERTED_TO_VARIANT,
|
||||||
|
user,
|
||||||
|
deltas={
|
||||||
|
'part': variant.pk,
|
||||||
|
},
|
||||||
|
notes=_('Converted to part') + ': ' + variant.full_name,
|
||||||
|
)
|
||||||
|
|
||||||
def get_item_owner(self):
|
def get_item_owner(self):
|
||||||
"""
|
"""
|
||||||
Return the closest "owner" for this StockItem.
|
Return the closest "owner" for this StockItem.
|
||||||
|
@ -26,11 +26,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class='panel-content'>
|
<div class='panel-content'>
|
||||||
<div id='table-toolbar'>
|
<div id='tracking-table-toolbar'>
|
||||||
<div class='btn-group'>
|
<div class='btn-group'>
|
||||||
|
{% include "filter_list.html" with id="stocktracking" %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#table-toolbar'>
|
<table class='table table-condensed table-striped' id='track-table' data-toolbar='#tracking-table-toolbar'>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -342,7 +343,6 @@
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
loadStockTrackingTable($("#track-table"), {
|
loadStockTrackingTable($("#track-table"), {
|
||||||
params: {
|
params: {
|
||||||
ordering: '-date',
|
ordering: '-date',
|
||||||
|
@ -210,6 +210,46 @@ class StockItemListTest(StockAPITestCase):
|
|||||||
for item in response:
|
for item in response:
|
||||||
self.assertIsNone(item['serial'])
|
self.assertIsNone(item['serial'])
|
||||||
|
|
||||||
|
def test_filter_by_has_batch(self):
|
||||||
|
"""
|
||||||
|
Test the 'has_batch' filter, which tests if the stock item has been assigned a batch code
|
||||||
|
"""
|
||||||
|
|
||||||
|
with_batch = self.get_stock(has_batch=1)
|
||||||
|
without_batch = self.get_stock(has_batch=0)
|
||||||
|
|
||||||
|
n_stock_items = StockItem.objects.all().count()
|
||||||
|
|
||||||
|
# Total sum should equal the total count of stock items
|
||||||
|
self.assertEqual(n_stock_items, len(with_batch) + len(without_batch))
|
||||||
|
|
||||||
|
for item in with_batch:
|
||||||
|
self.assertFalse(item['batch'] in [None, ''])
|
||||||
|
|
||||||
|
for item in without_batch:
|
||||||
|
self.assertTrue(item['batch'] in [None, ''])
|
||||||
|
|
||||||
|
def test_filter_by_tracked(self):
|
||||||
|
"""
|
||||||
|
Test the 'tracked' filter.
|
||||||
|
This checks if the stock item has either a batch code *or* a serial number
|
||||||
|
"""
|
||||||
|
|
||||||
|
tracked = self.get_stock(tracked=True)
|
||||||
|
untracked = self.get_stock(tracked=False)
|
||||||
|
|
||||||
|
n_stock_items = StockItem.objects.all().count()
|
||||||
|
|
||||||
|
self.assertEqual(n_stock_items, len(tracked) + len(untracked))
|
||||||
|
|
||||||
|
blank = [None, '']
|
||||||
|
|
||||||
|
for item in tracked:
|
||||||
|
self.assertTrue(item['batch'] not in blank or item['serial'] not in blank)
|
||||||
|
|
||||||
|
for item in untracked:
|
||||||
|
self.assertTrue(item['batch'] in blank and item['serial'] in blank)
|
||||||
|
|
||||||
def test_filter_by_expired(self):
|
def test_filter_by_expired(self):
|
||||||
"""
|
"""
|
||||||
Filter StockItem by expiry status
|
Filter StockItem by expiry status
|
||||||
|
@ -644,6 +644,16 @@ class StockItemConvert(AjaxUpdateView):
|
|||||||
|
|
||||||
return form
|
return form
|
||||||
|
|
||||||
|
def save(self, obj, form):
|
||||||
|
|
||||||
|
stock_item = self.get_object()
|
||||||
|
|
||||||
|
variant = form.cleaned_data.get('part', None)
|
||||||
|
|
||||||
|
stock_item.convert_to_variant(variant, user=self.request.user)
|
||||||
|
|
||||||
|
return stock_item
|
||||||
|
|
||||||
|
|
||||||
class StockLocationCreate(AjaxCreateView):
|
class StockLocationCreate(AjaxCreateView):
|
||||||
"""
|
"""
|
||||||
|
@ -77,6 +77,12 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if plugin.is_sample %}
|
||||||
|
<a class='sidebar-selector' id='select-plugin-{{plugin_key}}' data-bs-parent="#sidebar">
|
||||||
|
<span class='badge bg-info rounded-pill'>{% trans "code sample" %}</span>
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if plugin.website %}
|
{% if plugin.website %}
|
||||||
<a href="{{ plugin.website }}"><span class="fas fa-globe"></span></a>
|
<a href="{{ plugin.website }}"><span class="fas fa-globe"></span></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -99,14 +99,22 @@ function renderStockItem(name, data, parameters={}, options={}) {
|
|||||||
|
|
||||||
var stock_detail = '';
|
var stock_detail = '';
|
||||||
|
|
||||||
if (data.serial && data.quantity == 1) {
|
if (data.quantity == 0) {
|
||||||
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`;
|
|
||||||
} else if (data.quantity == 0) {
|
|
||||||
stock_detail = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock"% }</span>`;
|
stock_detail = `<span class='badge rounded-pill bg-danger'>{% trans "No Stock"% }</span>`;
|
||||||
} else {
|
} else {
|
||||||
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
|
if (data.serial && data.quantity == 1) {
|
||||||
|
stock_detail = `{% trans "Serial Number" %}: ${data.serial}`;
|
||||||
|
} else {
|
||||||
|
stock_detail = `{% trans "Quantity" %}: ${data.quantity}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.batch) {
|
||||||
|
stock_detail += ` - <small>{% trans "Batch" %}: ${data.batch}</small>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var html = `
|
var html = `
|
||||||
<span>
|
<span>
|
||||||
${part_detail}
|
${part_detail}
|
||||||
|
@ -171,6 +171,9 @@ function notificationCheck(force = false) {
|
|||||||
{
|
{
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
updateNotificationIndicator(response.length);
|
updateNotificationIndicator(response.length);
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
console.warn('Could not access server: /api/notifications');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -293,6 +293,7 @@ function categoryFields() {
|
|||||||
return {
|
return {
|
||||||
parent: {
|
parent: {
|
||||||
help_text: '{% trans "Parent part category" %}',
|
help_text: '{% trans "Parent part category" %}',
|
||||||
|
required: false,
|
||||||
},
|
},
|
||||||
name: {},
|
name: {},
|
||||||
description: {},
|
description: {},
|
||||||
|
@ -107,6 +107,7 @@ function stockLocationFields(options={}) {
|
|||||||
var fields = {
|
var fields = {
|
||||||
parent: {
|
parent: {
|
||||||
help_text: '{% trans "Parent stock location" %}',
|
help_text: '{% trans "Parent stock location" %}',
|
||||||
|
required: false,
|
||||||
},
|
},
|
||||||
name: {},
|
name: {},
|
||||||
description: {},
|
description: {},
|
||||||
@ -240,9 +241,11 @@ function stockItemFields(options={}) {
|
|||||||
serial: {
|
serial: {
|
||||||
icon: 'fa-hashtag',
|
icon: 'fa-hashtag',
|
||||||
},
|
},
|
||||||
|
batch: {
|
||||||
|
icon: 'fa-layer-group',
|
||||||
|
},
|
||||||
status: {},
|
status: {},
|
||||||
expiry_date: {},
|
expiry_date: {},
|
||||||
batch: {},
|
|
||||||
purchase_price: {
|
purchase_price: {
|
||||||
icon: 'fa-dollar-sign',
|
icon: 'fa-dollar-sign',
|
||||||
},
|
},
|
||||||
@ -963,6 +966,10 @@ function adjustStock(action, items, options={}) {
|
|||||||
quantity = `#${item.serial}`;
|
quantity = `#${item.serial}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (item.batch) {
|
||||||
|
quantity += ` - <small>{% trans "Batch" %}: ${item.batch}</small>`;
|
||||||
|
}
|
||||||
|
|
||||||
var actionInput = '';
|
var actionInput = '';
|
||||||
|
|
||||||
if (actionTitle != null) {
|
if (actionTitle != null) {
|
||||||
@ -2314,6 +2321,23 @@ function loadStockTrackingTable(table, options) {
|
|||||||
|
|
||||||
var cols = [];
|
var cols = [];
|
||||||
|
|
||||||
|
var filterTarget = '#filter-list-stocktracking';
|
||||||
|
|
||||||
|
var filterKey = 'stocktracking';
|
||||||
|
|
||||||
|
var filters = loadTableFilters(filterKey);
|
||||||
|
|
||||||
|
var params = options.params;
|
||||||
|
|
||||||
|
var original = {};
|
||||||
|
|
||||||
|
for (var k in params) {
|
||||||
|
original[k] = params[k];
|
||||||
|
filters[k] = params[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
setupFilterList(filterKey, table, filterTarget);
|
||||||
|
|
||||||
// Date
|
// Date
|
||||||
cols.push({
|
cols.push({
|
||||||
field: 'date',
|
field: 'date',
|
||||||
@ -2351,6 +2375,19 @@ function loadStockTrackingTable(table, options) {
|
|||||||
return html;
|
return html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Part information
|
||||||
|
if (details.part) {
|
||||||
|
html += `<tr><th>{% trans "Part" %}</th><td>`;
|
||||||
|
|
||||||
|
if (details.part_detail) {
|
||||||
|
html += renderLink(details.part_detail.full_name, `/part/${details.part}/`);
|
||||||
|
} else {
|
||||||
|
html += `{% trans "Part information unavailable" %}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `</td></tr>`;
|
||||||
|
}
|
||||||
|
|
||||||
// Location information
|
// Location information
|
||||||
if (details.location) {
|
if (details.location) {
|
||||||
|
|
||||||
@ -2488,27 +2525,10 @@ function loadStockTrackingTable(table, options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
// 2021-05-11 - Ability to edit or delete StockItemTracking entries is now removed
|
|
||||||
cols.push({
|
|
||||||
sortable: false,
|
|
||||||
formatter: function(value, row, index, field) {
|
|
||||||
// Manually created entries can be edited or deleted
|
|
||||||
if (false && !row.system) {
|
|
||||||
var bEdit = "<button title='{% trans 'Edit tracking entry' %}' class='btn btn-entry-edit btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/edit/'><span class='fas fa-edit'/></button>";
|
|
||||||
var bDel = "<button title='{% trans 'Delete tracking entry' %}' class='btn btn-entry-delete btn-outline-secondary' type='button' url='/stock/track/" + row.pk + "/delete/'><span class='fas fa-trash-alt icon-red'/></button>";
|
|
||||||
|
|
||||||
return "<div class='btn-group' role='group'>" + bEdit + bDel + "</div>";
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
table.inventreeTable({
|
table.inventreeTable({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
queryParams: options.params,
|
queryParams: filters,
|
||||||
|
original: original,
|
||||||
columns: cols,
|
columns: cols,
|
||||||
url: options.url,
|
url: options.url,
|
||||||
});
|
});
|
||||||
@ -2639,7 +2659,8 @@ function installStockItem(stock_item_id, part_id, options={}) {
|
|||||||
<ul>
|
<ul>
|
||||||
<li>{% trans "The Stock Item links to a Part which is the BOM for this Stock Item" %}</li>
|
<li>{% trans "The Stock Item links to a Part which is the BOM for this Stock Item" %}</li>
|
||||||
<li>{% trans "The Stock Item is currently available in stock" %}</li>
|
<li>{% trans "The Stock Item is currently available in stock" %}</li>
|
||||||
<li>{% trans "The Stock Item is serialized and does not belong to another item" %}</li>
|
<li>{% trans "The Stock Item is not already installed in another item" %}</li>
|
||||||
|
<li>{% trans "The Stock Item is tracked by either a batch code or serial number" %}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
@ -2665,7 +2686,7 @@ function installStockItem(stock_item_id, part_id, options={}) {
|
|||||||
filters: {
|
filters: {
|
||||||
part_detail: true,
|
part_detail: true,
|
||||||
in_stock: true,
|
in_stock: true,
|
||||||
serialized: true,
|
tracked: true,
|
||||||
},
|
},
|
||||||
adjustFilters: function(filters, opts) {
|
adjustFilters: function(filters, opts) {
|
||||||
var part = getFormFieldValue('part', {}, opts);
|
var part = getFormFieldValue('part', {}, opts);
|
||||||
|
@ -234,10 +234,19 @@ function getAvailableTableFilters(tableKey) {
|
|||||||
title: '{% trans "Stock status" %}',
|
title: '{% trans "Stock status" %}',
|
||||||
description: '{% trans "Stock status" %}',
|
description: '{% trans "Stock status" %}',
|
||||||
},
|
},
|
||||||
|
has_batch: {
|
||||||
|
title: '{% trans "Has batch code" %}',
|
||||||
|
type: 'bool',
|
||||||
|
},
|
||||||
batch: {
|
batch: {
|
||||||
title: '{% trans "Batch" %}',
|
title: '{% trans "Batch" %}',
|
||||||
description: '{% trans "Batch code" %}',
|
description: '{% trans "Batch code" %}',
|
||||||
},
|
},
|
||||||
|
tracked: {
|
||||||
|
title: '{% trans "Tracked" %}',
|
||||||
|
description: '{% trans "Stock item is tracked by either batch code or serial number" %}',
|
||||||
|
type: 'bool',
|
||||||
|
},
|
||||||
has_purchase_price: {
|
has_purchase_price: {
|
||||||
type: 'bool',
|
type: 'bool',
|
||||||
title: '{% trans "Has purchase price" %}',
|
title: '{% trans "Has purchase price" %}',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# InvenTree environment variables for a development setup
|
# InvenTree environment variables for a development setup
|
||||||
|
|
||||||
# Set DEBUG to False for a production environment!
|
# Set DEBUG to True for a development setup
|
||||||
INVENTREE_DEBUG=True
|
INVENTREE_DEBUG=True
|
||||||
INVENTREE_DEBUG_LEVEL=INFO
|
INVENTREE_DEBUG_LEVEL=INFO
|
||||||
|
|
||||||
@ -15,3 +15,5 @@ INVENTREE_DB_PASSWORD=pgpassword
|
|||||||
|
|
||||||
# Enable plugins?
|
# Enable plugins?
|
||||||
INVENTREE_PLUGINS_ENABLED=True
|
INVENTREE_PLUGINS_ENABLED=True
|
||||||
|
|
||||||
|
COMPOSE_PROJECT_NAME=inventree-development
|
@ -110,7 +110,8 @@ RUN pip3 install --user --no-cache-dir --disable-pip-version-check -r ${INVENTRE
|
|||||||
WORKDIR ${INVENTREE_MNG_DIR}
|
WORKDIR ${INVENTREE_MNG_DIR}
|
||||||
|
|
||||||
# Server init entrypoint
|
# Server init entrypoint
|
||||||
ENTRYPOINT ["/bin/bash", "../docker/init.sh"]
|
COPY init.sh ${INVENTREE_HOME}/init.sh
|
||||||
|
ENTRYPOINT ["/bin/bash", "${INVENTREE_HOME}/init.sh"]
|
||||||
|
|
||||||
# Launch the production server
|
# Launch the production server
|
||||||
# TODO: Work out why environment variables cannot be interpolated in this command
|
# TODO: Work out why environment variables cannot be interpolated in this command
|
||||||
@ -137,7 +138,6 @@ ENV INVENTREE_CONFIG_FILE="${INVENTREE_DEV_DIR}/config.yaml"
|
|||||||
ENV INVENTREE_SECRET_KEY_FILE="${INVENTREE_DEV_DIR}/secret_key.txt"
|
ENV INVENTREE_SECRET_KEY_FILE="${INVENTREE_DEV_DIR}/secret_key.txt"
|
||||||
ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DEV_DIR}/plugins.txt"
|
ENV INVENTREE_PLUGIN_FILE="${INVENTREE_DEV_DIR}/plugins.txt"
|
||||||
|
|
||||||
|
|
||||||
WORKDIR ${INVENTREE_HOME}
|
WORKDIR ${INVENTREE_HOME}
|
||||||
|
|
||||||
# Entrypoint ensures that we are running in the python virtual environment
|
# Entrypoint ensures that we are running in the python virtual environment
|
||||||
|
@ -1,106 +0,0 @@
|
|||||||
version: "3.8"
|
|
||||||
|
|
||||||
# Docker compose recipe for InvenTree development server
|
|
||||||
# - Runs PostgreSQL as the database backend
|
|
||||||
# - Uses built-in django webserver
|
|
||||||
# - Runs the InvenTree background worker process
|
|
||||||
# - Serves media and static content directly from Django webserver
|
|
||||||
|
|
||||||
# IMPORANT NOTE:
|
|
||||||
# The InvenTree docker image does not clone source code from git.
|
|
||||||
# Instead, you must specify *where* the source code is located,
|
|
||||||
# (on your local machine).
|
|
||||||
# The django server will auto-detect any code changes and reload the server.
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
# Database service
|
|
||||||
# Use PostgreSQL as the database backend
|
|
||||||
# Note: This can be changed to a different backend if required
|
|
||||||
inventree-dev-db:
|
|
||||||
container_name: inventree-dev-db
|
|
||||||
image: postgres:13
|
|
||||||
ports:
|
|
||||||
- 5432/tcp
|
|
||||||
environment:
|
|
||||||
- PGDATA=/var/lib/postgresql/data/dev/pgdb
|
|
||||||
# The pguser and pgpassword values must be the same in the other containers
|
|
||||||
# Ensure that these are correctly configured in your dev-config.env file
|
|
||||||
- POSTGRES_USER=pguser
|
|
||||||
- POSTGRES_PASSWORD=pgpassword
|
|
||||||
volumes:
|
|
||||||
# Map 'data' volume such that postgres database is stored externally
|
|
||||||
- src:/var/lib/postgresql/data
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
# InvenTree web server services
|
|
||||||
# Uses gunicorn as the web server
|
|
||||||
inventree-dev-server:
|
|
||||||
container_name: inventree-dev-server
|
|
||||||
depends_on:
|
|
||||||
- inventree-dev-db
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
target: dev
|
|
||||||
ports:
|
|
||||||
# Expose web server on port 8000
|
|
||||||
- 8000:8000
|
|
||||||
# Note: If using the inventree-dev-proxy container (see below),
|
|
||||||
# comment out the "ports" directive (above) and uncomment the "expose" directive
|
|
||||||
#expose:
|
|
||||||
# - 8000
|
|
||||||
volumes:
|
|
||||||
# Ensure you specify the location of the 'src' directory at the end of this file
|
|
||||||
- src:/home/inventree
|
|
||||||
env_file:
|
|
||||||
# Environment variables required for the dev server are configured in dev-config.env
|
|
||||||
- dev-config.env
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
# Background worker process handles long-running or periodic tasks
|
|
||||||
inventree-dev-worker:
|
|
||||||
container_name: inventree-dev-worker
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
target: dev
|
|
||||||
command: invoke worker
|
|
||||||
depends_on:
|
|
||||||
- inventree-dev-server
|
|
||||||
volumes:
|
|
||||||
# Ensure you specify the location of the 'src' directory at the end of this file
|
|
||||||
- src:/home/inventree
|
|
||||||
env_file:
|
|
||||||
# Environment variables required for the dev server are configured in dev-config.env
|
|
||||||
- dev-config.env
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
### Optional: Serve static and media files using nginx
|
|
||||||
### Uncomment the following lines to enable nginx proxy for testing
|
|
||||||
### Note: If enabling the proxy, change "ports" to "expose" for the inventree-dev-server container (above)
|
|
||||||
#inventree-dev-proxy:
|
|
||||||
# container_name: inventree-dev-proxy
|
|
||||||
# image: nginx:stable
|
|
||||||
# depends_on:
|
|
||||||
# - inventree-dev-server
|
|
||||||
# ports:
|
|
||||||
# # Change "8000" to the port that you want InvenTree web server to be available on
|
|
||||||
# - 8000:80
|
|
||||||
# volumes:
|
|
||||||
# # Provide ./nginx.conf file to the container
|
|
||||||
# # Refer to the provided example file as a starting point
|
|
||||||
# - ./nginx.dev.conf:/etc/nginx/conf.d/default.conf:ro
|
|
||||||
# # nginx proxy needs access to static and media files
|
|
||||||
# - src:/var/www
|
|
||||||
# restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
# NOTE: Change "../" to a directory on your local machine, where the InvenTree source code is located
|
|
||||||
# Persistent data, stored external to the container(s)
|
|
||||||
src:
|
|
||||||
driver: local
|
|
||||||
driver_opts:
|
|
||||||
type: none
|
|
||||||
o: bind
|
|
||||||
# This directory specified where InvenTree source code is stored "outside" the docker containers
|
|
||||||
# By default, this directory is one level above the "docker" directory
|
|
||||||
device: ../
|
|
@ -21,32 +21,34 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
target: dev
|
target: dev
|
||||||
|
# Cache the built image to be used by the inventree-dev-worker process
|
||||||
|
image: inventree-dev-image
|
||||||
ports:
|
ports:
|
||||||
# Expose web server on port 8000
|
# Expose web server on port 8000
|
||||||
- 8000:8000
|
- 8000:8000
|
||||||
volumes:
|
volumes:
|
||||||
# Ensure you specify the location of the 'src' directory at the end of this file
|
# Ensure you specify the location of the 'src' directory at the end of this file
|
||||||
- src:/home/inventree
|
- src:/home/inventree
|
||||||
env_file:
|
environment:
|
||||||
# Environment variables required for the dev server are configured in dev-config.env
|
- INVENTREE_DEBUG=True
|
||||||
- sqlite-config.env
|
- INVENTREE_DB_ENGINE=sqlite
|
||||||
|
- INVENTREE_DB_NAME=/home/inventree/db.sqlite3
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# Background worker process handles long-running or periodic tasks
|
# Background worker process handles long-running or periodic tasks
|
||||||
inventree-dev-worker:
|
inventree-dev-worker:
|
||||||
container_name: inventree-dev-worker
|
container_name: inventree-dev-worker
|
||||||
build:
|
image: inventree-dev-image
|
||||||
context: .
|
|
||||||
target: dev
|
|
||||||
command: invoke worker
|
command: invoke worker
|
||||||
depends_on:
|
depends_on:
|
||||||
- inventree-dev-server
|
- inventree-dev-server
|
||||||
volumes:
|
volumes:
|
||||||
# Ensure you specify the location of the 'src' directory at the end of this file
|
# Ensure you specify the location of the 'src' directory at the end of this file
|
||||||
- src:/home/inventree
|
- src:/home/inventree
|
||||||
env_file:
|
environment:
|
||||||
# Environment variables required for the dev server are configured in dev-config.env
|
- INVENTREE_DEBUG=True
|
||||||
- sqlite-config.env
|
- INVENTREE_DB_ENGINE=sqlite
|
||||||
|
- INVENTREE_DB_NAME=/home/inventree/db.sqlite3
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
@ -59,4 +61,4 @@ volumes:
|
|||||||
o: bind
|
o: bind
|
||||||
# This directory specified where InvenTree source code is stored "outside" the docker containers
|
# This directory specified where InvenTree source code is stored "outside" the docker containers
|
||||||
# By default, this directory is one level above the "docker" directory
|
# By default, this directory is one level above the "docker" directory
|
||||||
device: ../
|
device: ${INVENTREE_EXT_VOLUME:-../}
|
||||||
|
@ -1,119 +1,104 @@
|
|||||||
version: "3.8"
|
version: "3.8"
|
||||||
|
|
||||||
# Docker compose recipe for InvenTree
|
# Docker compose recipe for InvenTree development server
|
||||||
# - Runs PostgreSQL as the database backend
|
# - Runs PostgreSQL as the database backend
|
||||||
# - Runs Gunicorn as the InvenTree web server
|
# - Uses built-in django webserver
|
||||||
# - Runs the InvenTree background worker process
|
# - Runs the InvenTree background worker process
|
||||||
# - Runs nginx as a reverse proxy
|
# - Serves media and static content directly from Django webserver
|
||||||
|
|
||||||
# ---------------------------------
|
# IMPORANT NOTE:
|
||||||
# IMPORTANT - READ BEFORE STARTING!
|
# The InvenTree development image does not clone source code from git.
|
||||||
# ---------------------------------
|
# Instead, it runs from source code on your local machine.
|
||||||
# Before running, ensure that you change the "/path/to/data" directory,
|
# The django server will auto-detect any code changes and reload the server.
|
||||||
# specified in the "volumes" section at the end of this file.
|
|
||||||
# This path determines where the InvenTree data will be stored!
|
# If you have cloned the InvenTree git repo, and not made any changes to this file,
|
||||||
#
|
# then the default setup in this file should work straight out of the box, without modification
|
||||||
#
|
|
||||||
# InvenTree Image Versions
|
|
||||||
# ------------------------
|
|
||||||
# By default, this docker-compose script targets the STABLE version of InvenTree,
|
|
||||||
# image: inventree/inventree:stable
|
|
||||||
#
|
|
||||||
# To run the LATEST (development) version of InvenTree, change the target image to:
|
|
||||||
# image: inventree/inventree:latest
|
|
||||||
#
|
|
||||||
# Alternatively, you could target a specific tagged release version with (for example):
|
|
||||||
# image: inventree/inventree:0.5.3
|
|
||||||
#
|
|
||||||
# NOTE: If you change the target image, ensure it is the same for the following containers:
|
|
||||||
# - inventree-server
|
|
||||||
# - inventree-worker
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
# Database service
|
# Database service
|
||||||
# Use PostgreSQL as the database backend
|
# Use PostgreSQL as the database backend
|
||||||
# Note: this can be changed to a different backend,
|
# Note: This can be changed to a different backend if required
|
||||||
# just make sure that you change the INVENTREE_DB_xxx vars below
|
inventree-dev-db:
|
||||||
inventree-db:
|
container_name: inventree-dev-db
|
||||||
container_name: inventree-db
|
|
||||||
image: postgres:13
|
image: postgres:13
|
||||||
ports:
|
ports:
|
||||||
- 5432/tcp
|
- ${INVENTREE_DB_PORT:-5432}/tcp
|
||||||
environment:
|
environment:
|
||||||
- PGDATA=/var/lib/postgresql/data/pgdb
|
- PGDATA=/var/lib/postgresql/data/dev/pgdb
|
||||||
# The pguser and pgpassword values must be the same in the other containers
|
- POSTGRES_USER=${INVENTREE_DB_USER:?You must provide the 'INVENTREE_DB_USER' variable in the .env file}
|
||||||
# Ensure that these are correctly configured in your prod-config.env file
|
- POSTGRES_PASSWORD=${INVENTREE_DB_PASSWORD:?You must provide the 'INVENTREE_DB_PASSWORD' variable in the .env file}
|
||||||
- POSTGRES_USER=pguser
|
- POSTGRES_DB=${INVENTREE_DB_NAME:?You must provide the 'INVENTREE_DB_NAME' variable in the .env file}
|
||||||
- POSTGRES_PASSWORD=pgpassword
|
|
||||||
volumes:
|
volumes:
|
||||||
# Map 'data' volume such that postgres database is stored externally
|
# Map 'data' volume such that postgres database is stored externally
|
||||||
- data:/var/lib/postgresql/data/
|
- inventree_src:/var/lib/postgresql/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# InvenTree web server services
|
# InvenTree web server services
|
||||||
# Uses gunicorn as the web server
|
# Uses gunicorn as the web server
|
||||||
inventree-server:
|
inventree-dev-server:
|
||||||
container_name: inventree-server
|
container_name: inventree-dev-server
|
||||||
# If you wish to specify a particular InvenTree version, do so here
|
|
||||||
image: inventree/inventree:stable
|
|
||||||
expose:
|
|
||||||
- 8000
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- inventree-db
|
- inventree-dev-db
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
target: dev
|
||||||
|
# Cache the built image to be used by the inventree-dev-worker process
|
||||||
|
image: inventree-dev-image
|
||||||
|
ports:
|
||||||
|
# Expose web server on port 8000
|
||||||
|
- 8000:8000
|
||||||
|
# Note: If using the inventree-dev-proxy container (see below),
|
||||||
|
# comment out the "ports" directive (above) and uncomment the "expose" directive
|
||||||
|
#expose:
|
||||||
|
# - 8000
|
||||||
volumes:
|
volumes:
|
||||||
# Data volume must map to /home/inventree/data
|
# Ensure you specify the location of the 'src' directory at the end of this file
|
||||||
- data:/home/inventree/data
|
- inventree_src:/home/inventree
|
||||||
env_file:
|
env_file:
|
||||||
# Environment variables required for the production server are configured in prod-config.env
|
- .env
|
||||||
- prod-config.env
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# Background worker process handles long-running or periodic tasks
|
# Background worker process handles long-running or periodic tasks
|
||||||
inventree-worker:
|
inventree-dev-worker:
|
||||||
container_name: inventree-worker
|
container_name: inventree-dev-worker
|
||||||
# If you wish to specify a particular InvenTree version, do so here
|
image: inventree-dev-image
|
||||||
image: inventree/inventree:stable
|
|
||||||
command: invoke worker
|
command: invoke worker
|
||||||
depends_on:
|
depends_on:
|
||||||
- inventree-db
|
- inventree-dev-server
|
||||||
- inventree-server
|
|
||||||
volumes:
|
volumes:
|
||||||
# Data volume must map to /home/inventree/data
|
# Ensure you specify the location of the 'src' directory at the end of this file
|
||||||
- data:/home/inventree/data
|
- inventree_src:/home/inventree
|
||||||
env_file:
|
env_file:
|
||||||
# Environment variables required for the production server are configured in prod-config.env
|
- .env
|
||||||
- prod-config.env
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
# nginx acts as a reverse proxy
|
### Optional: Serve static and media files using nginx
|
||||||
# static files are served directly by nginx
|
### Uncomment the following lines to enable nginx proxy for testing
|
||||||
# media files are served by nginx, although authentication is redirected to inventree-server
|
### Note: If enabling the proxy, change "ports" to "expose" for the inventree-dev-server container (above)
|
||||||
# web requests are redirected to gunicorn
|
#inventree-dev-proxy:
|
||||||
# NOTE: You will need to provide a working nginx.conf file!
|
# container_name: inventree-dev-proxy
|
||||||
inventree-proxy:
|
# image: nginx:stable
|
||||||
container_name: inventree-proxy
|
# depends_on:
|
||||||
image: nginx:stable
|
# - inventree-dev-server
|
||||||
depends_on:
|
# ports:
|
||||||
- inventree-server
|
# # Change "8000" to the port that you want InvenTree web server to be available on
|
||||||
ports:
|
# - 8000:80
|
||||||
# Change "1337" to the port that you want InvenTree web server to be available on
|
# volumes:
|
||||||
- 1337:80
|
# # Provide ./nginx.dev.conf file to the container
|
||||||
volumes:
|
# # Refer to the provided example file as a starting point
|
||||||
# Provide ./nginx.conf file to the container
|
# - ./nginx.dev.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
# Refer to the provided example file as a starting point
|
# # nginx proxy needs access to static and media files
|
||||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
# - inventree_src:/var/www
|
||||||
# nginx proxy needs access to static and media files
|
# restart: unless-stopped
|
||||||
- data:/var/www
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# NOTE: Change /path/to/data to a directory on your local machine
|
|
||||||
# Persistent data, stored external to the container(s)
|
# Persistent data, stored external to the container(s)
|
||||||
data:
|
inventree_src:
|
||||||
driver: local
|
driver: local
|
||||||
driver_opts:
|
driver_opts:
|
||||||
type: none
|
type: none
|
||||||
o: bind
|
o: bind
|
||||||
# This directory specified where InvenTree data are stored "outside" the docker containers
|
# This directory specified where InvenTree source code is stored "outside" the docker containers
|
||||||
# Change this path to a local system path where you want InvenTree data stored
|
# By default, this directory is one level above the "docker" directory
|
||||||
device: /path/to/data
|
device: ${INVENTREE_EXT_VOLUME:-../}
|
||||||
|
@ -33,7 +33,7 @@ if [[ -n "$INVENTREE_PY_ENV" ]]; then
|
|||||||
source ${INVENTREE_PY_ENV}/bin/activate
|
source ${INVENTREE_PY_ENV}/bin/activate
|
||||||
|
|
||||||
# Note: Python packages will have to be installed on first run
|
# Note: Python packages will have to be installed on first run
|
||||||
# e.g docker-compose -f docker-compose.dev.yml run inventree-dev-server invoke install
|
# e.g docker-compose run inventree-dev-server invoke update
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd ${INVENTREE_HOME}
|
cd ${INVENTREE_HOME}
|
||||||
|
@ -4,24 +4,30 @@ server {
|
|||||||
# Listen for connection on (internal) port 80
|
# Listen for connection on (internal) port 80
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
location / {
|
real_ip_header proxy_protocol;
|
||||||
# Change 'inventree-dev-server' to the name of the inventree server container,
|
|
||||||
# and '8000' to the INVENTREE_WEB_PORT (if not default)
|
|
||||||
proxy_pass http://inventree-dev-server:8000;
|
|
||||||
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
location / {
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header CLIENT_IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass_request_headers on;
|
||||||
|
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
||||||
client_max_body_size 100M;
|
client_max_body_size 100M;
|
||||||
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_request_buffering off;
|
proxy_request_buffering off;
|
||||||
|
|
||||||
|
# Change 'inventree-dev-server' to the name of the inventree server container,
|
||||||
|
# and '8000' to the INVENTREE_WEB_PORT (if not default)
|
||||||
|
proxy_pass http://inventree-dev-server:8000;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Redirect any requests for static files
|
# Redirect any requests for static files
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
# InvenTree environment variables for a production setup
|
|
||||||
|
|
||||||
# Note: If your production setup varies from the example, you may want to change these values
|
|
||||||
|
|
||||||
# Ensure debug is false for a production setup
|
|
||||||
INVENTREE_DEBUG=False
|
|
||||||
INVENTREE_LOG_LEVEL=WARNING
|
|
||||||
|
|
||||||
# Database configuration options
|
|
||||||
# Note: The example setup is for a PostgreSQL database (change as required)
|
|
||||||
INVENTREE_DB_ENGINE=postgresql
|
|
||||||
INVENTREE_DB_NAME=inventree
|
|
||||||
INVENTREE_DB_HOST=inventree-db
|
|
||||||
INVENTREE_DB_PORT=5432
|
|
||||||
INVENTREE_DB_USER=pguser
|
|
||||||
INVENTREE_DB_PASSWORD=pgpassword
|
|
||||||
|
|
||||||
# Enable plugins?
|
|
||||||
INVENTREE_PLUGINS_ENABLED=False
|
|
34
docker/production/.env
Normal file
34
docker/production/.env
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# InvenTree environment variables for a postgresql production setup
|
||||||
|
|
||||||
|
# Location of persistent database data (stored external to the docker containers)
|
||||||
|
# Note: You *must* un-comment this line, and point it to a path on your local machine
|
||||||
|
|
||||||
|
# e.g. Linux
|
||||||
|
#INVENTREE_EXT_VOLUME=/home/me/inventree-data
|
||||||
|
|
||||||
|
# e.g. Windows (docker desktop)
|
||||||
|
#INVENTREE_EXT_VOLUME=c:/Users/me/inventree-data
|
||||||
|
|
||||||
|
# Default web port for the InvenTree server
|
||||||
|
INVENTREE_WEB_PORT=1337
|
||||||
|
|
||||||
|
# Ensure debug is false for a production setup
|
||||||
|
INVENTREE_DEBUG=False
|
||||||
|
INVENTREE_LOG_LEVEL=WARNING
|
||||||
|
|
||||||
|
# Database configuration options
|
||||||
|
# Note: The example setup is for a PostgreSQL database
|
||||||
|
INVENTREE_DB_ENGINE=postgresql
|
||||||
|
INVENTREE_DB_NAME=inventree
|
||||||
|
INVENTREE_DB_HOST=inventree-db
|
||||||
|
INVENTREE_DB_PORT=5432
|
||||||
|
|
||||||
|
# Database credentials - These must be configured before running
|
||||||
|
# Uncomment the lines below, and change from the default values!
|
||||||
|
#INVENTREE_DB_USER=pguser
|
||||||
|
#INVENTREE_DB_PASSWORD=pgpassword
|
||||||
|
|
||||||
|
# Enable plugins?
|
||||||
|
INVENTREE_PLUGINS_ENABLED=False
|
||||||
|
|
||||||
|
COMPOSE_PROJECT_NAME=inventree-production
|
124
docker/production/docker-compose.yml
Normal file
124
docker/production/docker-compose.yml
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
# Docker compose recipe for InvenTree production server
|
||||||
|
# - PostgreSQL as the database backend
|
||||||
|
# - gunicorn as the InvenTree web server
|
||||||
|
# - django-q as the InvenTree background worker process
|
||||||
|
# - nginx as a reverse proxy
|
||||||
|
|
||||||
|
# ---------------------
|
||||||
|
# READ BEFORE STARTING!
|
||||||
|
# ---------------------
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Setting environment variables
|
||||||
|
# -----------------------------
|
||||||
|
# Shared environment variables should be stored in the .env file
|
||||||
|
# Changes made to this file are reflected across all containers!
|
||||||
|
#
|
||||||
|
# IMPORTANT NOTE:
|
||||||
|
# You should not have to change *anything* within the docker-compose.yml file!
|
||||||
|
# Instead, make any changes in the .env file!
|
||||||
|
# The only *mandatory* change is to set the INVENTREE_EXT_VOLUME variable,
|
||||||
|
# which defines the directory (on your local machine) where persistent data are stored.
|
||||||
|
|
||||||
|
# ------------------------
|
||||||
|
# InvenTree Image Versions
|
||||||
|
# ------------------------
|
||||||
|
# By default, this docker-compose script targets the STABLE version of InvenTree,
|
||||||
|
# image: inventree/inventree:stable
|
||||||
|
#
|
||||||
|
# To run the LATEST (development) version of InvenTree, change the target image to:
|
||||||
|
# image: inventree/inventree:latest
|
||||||
|
#
|
||||||
|
# Alternatively, you could target a specific tagged release version with (for example):
|
||||||
|
# image: inventree/inventree:0.5.3
|
||||||
|
#
|
||||||
|
# NOTE: If you change the target image, ensure it is the same for the following containers:
|
||||||
|
# - inventree-server
|
||||||
|
# - inventree-worker
|
||||||
|
|
||||||
|
services:
|
||||||
|
# Database service
|
||||||
|
# Use PostgreSQL as the database backend
|
||||||
|
inventree-db:
|
||||||
|
container_name: inventree-db
|
||||||
|
image: postgres:13
|
||||||
|
ports:
|
||||||
|
- ${INVENTREE_DB_PORT:-5432}/tcp
|
||||||
|
environment:
|
||||||
|
- PGDATA=/var/lib/postgresql/data/pgdb
|
||||||
|
- POSTGRES_USER=${INVENTREE_DB_USER:?You must provide the 'INVENTREE_DB_USER' variable in the .env file}
|
||||||
|
- POSTGRES_PASSWORD=${INVENTREE_DB_PASSWORD:?You must provide the 'INVENTREE_DB_PASSWORD' variable in the .env file}
|
||||||
|
- POSTGRES_DB=${INVENTREE_DB_NAME:?You must provide the 'INVENTREE_DB_NAME' variable in the .env file}
|
||||||
|
volumes:
|
||||||
|
# Map 'data' volume such that postgres database is stored externally
|
||||||
|
- inventree_data:/var/lib/postgresql/data/
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# InvenTree web server services
|
||||||
|
# Uses gunicorn as the web server
|
||||||
|
inventree-server:
|
||||||
|
container_name: inventree-server
|
||||||
|
# If you wish to specify a particular InvenTree version, do so here
|
||||||
|
image: inventree/inventree:stable
|
||||||
|
expose:
|
||||||
|
- 8000
|
||||||
|
depends_on:
|
||||||
|
- inventree-db
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
# Data volume must map to /home/inventree/data
|
||||||
|
- inventree_data:/home/inventree/data
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# Background worker process handles long-running or periodic tasks
|
||||||
|
inventree-worker:
|
||||||
|
container_name: inventree-worker
|
||||||
|
# If you wish to specify a particular InvenTree version, do so here
|
||||||
|
image: inventree/inventree:stable
|
||||||
|
command: invoke worker
|
||||||
|
depends_on:
|
||||||
|
- inventree-db
|
||||||
|
- inventree-server
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
volumes:
|
||||||
|
# Data volume must map to /home/inventree/data
|
||||||
|
- inventree_data:/home/inventree/data
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# nginx acts as a reverse proxy
|
||||||
|
# static files are served directly by nginx
|
||||||
|
# media files are served by nginx, although authentication is redirected to inventree-server
|
||||||
|
# web requests are redirected to gunicorn
|
||||||
|
# NOTE: You will need to provide a working nginx.conf file!
|
||||||
|
inventree-proxy:
|
||||||
|
container_name: inventree-proxy
|
||||||
|
image: nginx:stable
|
||||||
|
depends_on:
|
||||||
|
- inventree-server
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
# Default web port is 1337 (can be changed in the .env file)
|
||||||
|
- ${INVENTREE_WEB_PORT:-1337}:80
|
||||||
|
volumes:
|
||||||
|
# Provide nginx configuration file to the container
|
||||||
|
# Refer to the provided example file as a starting point
|
||||||
|
- ./nginx.prod.conf:/etc/nginx/conf.d/default.conf:ro
|
||||||
|
# nginx proxy needs access to static and media files
|
||||||
|
- inventree_data:/var/www
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
# NOTE: Change /path/to/data to a directory on your local machine
|
||||||
|
# Persistent data, stored external to the container(s)
|
||||||
|
inventree_data:
|
||||||
|
driver: local
|
||||||
|
driver_opts:
|
||||||
|
type: none
|
||||||
|
o: bind
|
||||||
|
# This directory specified where InvenTree data are stored "outside" the docker containers
|
||||||
|
device: ${INVENTREE_EXT_VOLUME:?You must specify the 'INVENTREE_EXT_VOLUME' variable in the .env file!}
|
@ -4,24 +4,29 @@ server {
|
|||||||
# Listen for connection on (internal) port 80
|
# Listen for connection on (internal) port 80
|
||||||
listen 80;
|
listen 80;
|
||||||
|
|
||||||
location / {
|
real_ip_header proxy_protocol;
|
||||||
# Change 'inventree-server' to the name of the inventree server container,
|
|
||||||
# and '8000' to the INVENTREE_WEB_PORT (if not default)
|
|
||||||
proxy_pass http://inventree-server:8000;
|
|
||||||
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
location / {
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Forwarded-By $server_addr:$server_port;
|
||||||
|
proxy_set_header X-Forwarded-For $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header CLIENT_IP $remote_addr;
|
||||||
|
|
||||||
|
proxy_pass_request_headers on;
|
||||||
|
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
|
|
||||||
client_max_body_size 100M;
|
client_max_body_size 100M;
|
||||||
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
proxy_request_buffering off;
|
proxy_request_buffering off;
|
||||||
|
|
||||||
|
# Change 'inventree-server' to the name of the inventree server container,
|
||||||
|
# and '8000' to the INVENTREE_WEB_PORT (if not default)
|
||||||
|
proxy_pass http://inventree-server:8000;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Redirect any requests for static files
|
# Redirect any requests for static files
|
@ -1,10 +0,0 @@
|
|||||||
# InvenTree environment variables for a development setup
|
|
||||||
|
|
||||||
# Set DEBUG to False for a production environment!
|
|
||||||
INVENTREE_DEBUG=True
|
|
||||||
INVENTREE_DEBUG_LEVEL=INFO
|
|
||||||
|
|
||||||
# Database configuration options
|
|
||||||
# Note: The example setup is for a PostgreSQL database (change as required)
|
|
||||||
INVENTREE_DB_ENGINE=sqlite
|
|
||||||
INVENTREE_DB_NAME=/home/inventree/dev/inventree_db.sqlite3
|
|
@ -1,46 +1,47 @@
|
|||||||
# Please keep this list sorted
|
# Please keep this list sorted
|
||||||
Django==3.2.12 # Django package
|
Django==3.2.13 # Django package
|
||||||
bleach==4.1.0 # HTML santization
|
bleach==4.1.0 # HTML santization
|
||||||
certifi # Certifi is (most likely) installed through one of the requirements above
|
certifi # Certifi is (most likely) installed through one of the requirements above
|
||||||
coreapi==2.3.0 # API documentation
|
coreapi==2.3.0 # API documentation
|
||||||
coverage==5.3 # Unit test coverage
|
coverage==5.3 # Unit test coverage
|
||||||
coveralls==2.1.2 # Coveralls linking (for Travis)
|
coveralls==2.1.2 # Coveralls linking (for Travis)
|
||||||
cryptography==3.4.8 # Cryptography support
|
cryptography==3.4.8 # Cryptography support
|
||||||
django-admin-shell==0.1.2 # Python shell for the admin interface
|
django-admin-shell==0.1.2 # Python shell for the admin interface
|
||||||
django-allauth==0.45.0 # SSO for external providers via OpenID
|
django-allauth==0.45.0 # SSO for external providers via OpenID
|
||||||
django-allauth-2fa==0.8 # MFA / 2FA
|
django-allauth-2fa==0.8 # MFA / 2FA
|
||||||
django-cleanup==5.1.0 # Manage deletion of old / unused uploaded files
|
django-cleanup==5.1.0 # Manage deletion of old / unused uploaded files
|
||||||
django-cors-headers==3.2.0 # CORS headers extension for DRF
|
django-cors-headers==3.2.0 # CORS headers extension for DRF
|
||||||
django-crispy-forms==1.11.2 # Form helpers
|
django-crispy-forms==1.11.2 # Form helpers
|
||||||
django-debug-toolbar==2.2 # Debug / profiling toolbar
|
django-debug-toolbar==3.2.4 # Debug / profiling toolbar
|
||||||
django-error-report==0.2.0 # Error report viewer for the admin interface
|
django-error-report==0.2.0 # Error report viewer for the admin interface
|
||||||
django-filter==2.4.0 # Extended filtering options
|
django-filter==2.4.0 # Extended filtering options
|
||||||
django-formtools==2.3 # Form wizard tools
|
django-formtools==2.3 # Form wizard tools
|
||||||
django-import-export==2.5.0 # Data import / export for admin interface
|
django-import-export==2.5.0 # Data import / export for admin interface
|
||||||
django-maintenance-mode==0.16.1 # Shut down application while reloading etc.
|
django-maintenance-mode==0.16.1 # Shut down application while reloading etc.
|
||||||
django-markdownify==0.8.0 # Markdown rendering
|
django-markdownify==0.8.0 # Markdown rendering
|
||||||
django-markdownx==3.0.1 # Markdown form fields
|
django-markdownx==3.0.1 # Markdown form fields
|
||||||
django-money==1.1 # Django app for currency management
|
django-money==1.1 # Django app for currency management
|
||||||
django-mptt==0.11.0 # Modified Preorder Tree Traversal
|
django-mptt==0.11.0 # Modified Preorder Tree Traversal
|
||||||
django-redis>=5.0.0
|
django-redis>=5.0.0 # Redis integration
|
||||||
django-q==1.3.4 # Background task scheduling
|
django-q==1.3.4 # Background task scheduling
|
||||||
django-sql-utils==0.5.0 # Advanced query annotation / aggregation
|
django-sql-utils==0.5.0 # Advanced query annotation / aggregation
|
||||||
django-stdimage==5.1.1 # Advanced ImageField management
|
django-stdimage==5.1.1 # Advanced ImageField management
|
||||||
django-test-migrations==1.1.0 # Unit testing for database migrations
|
django-test-migrations==1.1.0 # Unit testing for database migrations
|
||||||
django-user-sessions==1.7.1 # user sessions in DB
|
django-user-sessions==1.7.1 # user sessions in DB
|
||||||
django-weasyprint==1.0.1 # django weasyprint integration
|
django-weasyprint==1.0.1 # django weasyprint integration
|
||||||
djangorestframework==3.12.4 # DRF framework
|
djangorestframework==3.12.4 # DRF framework
|
||||||
flake8==3.8.3 # PEP checking
|
django-xforwardedfor-middleware==2.0 # IP forwarding metadata
|
||||||
gunicorn>=20.1.0 # Gunicorn web server
|
flake8==3.8.3 # PEP checking
|
||||||
importlib_metadata # Backport for importlib.metadata
|
gunicorn>=20.1.0 # Gunicorn web server
|
||||||
inventree # Install the latest version of the InvenTree API python library
|
importlib_metadata # Backport for importlib.metadata
|
||||||
markdown==3.3.4 # Force particular version of markdown
|
inventree # Install the latest version of the InvenTree API python library
|
||||||
pep8-naming==0.11.1 # PEP naming convention extension
|
markdown==3.3.4 # Force particular version of markdown
|
||||||
pillow==9.0.1 # Image manipulation
|
pep8-naming==0.11.1 # PEP naming convention extension
|
||||||
py-moneyed==0.8.0 # Specific version requirement for py-moneyed
|
pillow==9.0.1 # Image manipulation
|
||||||
pygments==2.7.4 # Syntax highlighting
|
py-moneyed==0.8.0 # Specific version requirement for py-moneyed
|
||||||
python-barcode[images]==0.13.1 # Barcode generator
|
pygments==2.7.4 # Syntax highlighting
|
||||||
qrcode[pil]==6.1 # QR code generator
|
python-barcode[images]==0.13.1 # Barcode generator
|
||||||
rapidfuzz==0.7.6 # Fuzzy string matching
|
qrcode[pil]==6.1 # QR code generator
|
||||||
tablib[xls,xlsx,yaml] # Support for XLS and XLSX formats
|
rapidfuzz==0.7.6 # Fuzzy string matching
|
||||||
weasyprint==52.5 # PDF generation library (Note: in the future need to update to 53)
|
tablib[xls,xlsx,yaml] # Support for XLS and XLSX formats
|
||||||
|
weasyprint==52.5 # PDF generation library (Note: in the future need to update to 53)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user