mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge branch 'master' of https://github.com/inventree/InvenTree into part-import
This commit is contained in:
commit
46723f42ca
@ -88,6 +88,11 @@ DEBUG = _is_true(get_setting(
|
|||||||
CONFIG.get('debug', True)
|
CONFIG.get('debug', True)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
DOCKER = _is_true(get_setting(
|
||||||
|
'INVENTREE_DOCKER',
|
||||||
|
False
|
||||||
|
))
|
||||||
|
|
||||||
# Configure logging settings
|
# Configure logging settings
|
||||||
log_level = get_setting(
|
log_level = get_setting(
|
||||||
'INVENTREE_LOG_LEVEL',
|
'INVENTREE_LOG_LEVEL',
|
||||||
|
@ -12,7 +12,7 @@ function attachClipboard(selector, containerselector, textElement) {
|
|||||||
return document.getElementById(textElement).textContent;
|
return document.getElementById(textElement).textContent;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
text = function() {
|
text = function(trigger) {
|
||||||
var content = trigger.parentElement.parentElement.textContent;return content.trim();
|
var content = trigger.parentElement.parentElement.textContent;return content.trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,7 +22,6 @@ function attachClipboard(selector, containerselector, textElement) {
|
|||||||
text: text,
|
text: text,
|
||||||
container: containerselector
|
container: containerselector
|
||||||
});
|
});
|
||||||
console.log(cis);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,7 +80,6 @@ function inventreeDocReady() {
|
|||||||
attachClipboard('.clip-btn');
|
attachClipboard('.clip-btn');
|
||||||
attachClipboard('.clip-btn', 'modal-about'); // modals
|
attachClipboard('.clip-btn', 'modal-about'); // modals
|
||||||
attachClipboard('.clip-btn-version', 'modal-about', 'about-copy-text'); // version-text
|
attachClipboard('.clip-btn-version', 'modal-about', 'about-copy-text'); // version-text
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isFileTransfer(transfer) {
|
function isFileTransfer(transfer) {
|
||||||
|
@ -459,8 +459,8 @@ class FileManagementFormView(MultiStepFormView):
|
|||||||
|
|
||||||
if guess:
|
if guess:
|
||||||
n = list(self.column_selections.values()).count(self.column_selections[col])
|
n = list(self.column_selections.values()).count(self.column_selections[col])
|
||||||
if n > 1:
|
if n > 1 and self.column_selections[col] not in duplicates:
|
||||||
duplicates.append(col)
|
duplicates.append(self.column_selections[col])
|
||||||
|
|
||||||
# Store extra context data
|
# Store extra context data
|
||||||
self.extra_context_data = {
|
self.extra_context_data = {
|
||||||
|
@ -13,6 +13,10 @@ from .models import SalesOrder, SalesOrderLineItem
|
|||||||
from .models import SalesOrderAllocation
|
from .models import SalesOrderAllocation
|
||||||
|
|
||||||
|
|
||||||
|
class PurchaseOrderLineItemInlineAdmin(admin.StackedInline):
|
||||||
|
model = PurchaseOrderLineItem
|
||||||
|
|
||||||
|
|
||||||
class PurchaseOrderAdmin(ImportExportModelAdmin):
|
class PurchaseOrderAdmin(ImportExportModelAdmin):
|
||||||
|
|
||||||
list_display = (
|
list_display = (
|
||||||
@ -29,6 +33,10 @@ class PurchaseOrderAdmin(ImportExportModelAdmin):
|
|||||||
'description',
|
'description',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
inlines = [
|
||||||
|
PurchaseOrderLineItemInlineAdmin
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class SalesOrderAdmin(ImportExportModelAdmin):
|
class SalesOrderAdmin(ImportExportModelAdmin):
|
||||||
|
|
||||||
|
@ -826,6 +826,9 @@ class SalesOrderAllocation(models.Model):
|
|||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def get_po(self):
|
||||||
|
return self.item.purchase_order
|
||||||
|
|
||||||
def complete_allocation(self, user):
|
def complete_allocation(self, user):
|
||||||
"""
|
"""
|
||||||
Complete this allocation (called when the parent SalesOrder is marked as "shipped"):
|
Complete this allocation (called when the parent SalesOrder is marked as "shipped"):
|
||||||
|
@ -235,6 +235,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer):
|
|||||||
location_path = serializers.CharField(source='get_location_path')
|
location_path = serializers.CharField(source='get_location_path')
|
||||||
location_id = serializers.IntegerField(source='get_location')
|
location_id = serializers.IntegerField(source='get_location')
|
||||||
serial = serializers.CharField(source='get_serial')
|
serial = serializers.CharField(source='get_serial')
|
||||||
|
po = serializers.CharField(source='get_po')
|
||||||
quantity = serializers.FloatField()
|
quantity = serializers.FloatField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -247,6 +248,7 @@ class SalesOrderAllocationSerializer(InvenTreeModelSerializer):
|
|||||||
'quantity',
|
'quantity',
|
||||||
'location_id',
|
'location_id',
|
||||||
'location_path',
|
'location_path',
|
||||||
|
'po',
|
||||||
'item',
|
'item',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ col }}
|
{{ col }}
|
||||||
{% for duplicate in duplicates %}
|
{% for duplicate in duplicates %}
|
||||||
{% if duplicate == col.name %}
|
{% if duplicate == col.value %}
|
||||||
<div class='alert alert-danger alert-block text-center' role='alert' style='padding:2px; margin-top:6px; margin-bottom:2px'>
|
<div class='alert alert-danger alert-block text-center' role='alert' style='padding:2px; margin-top:6px; margin-bottom:2px'>
|
||||||
<b>{% trans "Duplicate selection" %}</b>
|
<b>{% trans "Duplicate selection" %}</b>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,6 +87,9 @@ function showAllocationSubTable(index, row, element) {
|
|||||||
return renderLink(row.location_path, `/stock/location/${row.location_id}/`);
|
return renderLink(row.location_path, `/stock/location/${row.location_id}/`);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'po'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'buttons',
|
field: 'buttons',
|
||||||
title: '{% trans "Actions" %}',
|
title: '{% trans "Actions" %}',
|
||||||
@ -161,7 +164,10 @@ function showFulfilledSubTable(index, row, element) {
|
|||||||
|
|
||||||
return renderLink(text, `/stock/item/${row.pk}/`);
|
return renderLink(text, `/stock/item/${row.pk}/`);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
field: 'po'
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -271,6 +277,25 @@ $("#so-lines-table").inventreeTable({
|
|||||||
field: 'notes',
|
field: 'notes',
|
||||||
title: '{% trans "Notes" %}',
|
title: '{% trans "Notes" %}',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'po',
|
||||||
|
title: '{% trans "PO" %}',
|
||||||
|
formatter: function(value, row, index, field) {
|
||||||
|
var po_name = "";
|
||||||
|
if (row.allocated) {
|
||||||
|
row.allocations.forEach(function(allocation) {
|
||||||
|
if (allocation.po != po_name) {
|
||||||
|
if (po_name) {
|
||||||
|
po_name = "-";
|
||||||
|
} else {
|
||||||
|
po_name = allocation.po
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return `<div>` + po_name + `</div>`;
|
||||||
|
}
|
||||||
|
},
|
||||||
{% if order.status == SalesOrderStatus.PENDING %}
|
{% if order.status == SalesOrderStatus.PENDING %}
|
||||||
{
|
{
|
||||||
field: 'buttons',
|
field: 'buttons',
|
||||||
|
@ -90,7 +90,7 @@ class SalesOrderDetail(InvenTreeRoleMixin, DetailView):
|
|||||||
""" Detail view for a SalesOrder object """
|
""" Detail view for a SalesOrder object """
|
||||||
|
|
||||||
context_object_name = 'order'
|
context_object_name = 'order'
|
||||||
queryset = SalesOrder.objects.all().prefetch_related('lines')
|
queryset = SalesOrder.objects.all().prefetch_related('lines__allocations__item__purchase_order')
|
||||||
template_name = 'order/sales_order_detail.html'
|
template_name = 'order/sales_order_detail.html'
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
""" This module provides template tags for extra functionality
|
""" This module provides template tags for extra functionality
|
||||||
over and above the built-in Django tags.
|
over and above the built-in Django tags.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.conf import settings as djangosettings
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
@ -68,6 +74,33 @@ def part_allocation_count(build, part, *args, **kwargs):
|
|||||||
return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part))
|
return InvenTree.helpers.decimal2string(build.getAllocatedQuantity(part))
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag()
|
||||||
|
def inventree_in_debug_mode(*args, **kwargs):
|
||||||
|
""" Return True if the server is running in DEBUG mode """
|
||||||
|
|
||||||
|
return djangosettings.DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag()
|
||||||
|
def inventree_docker_mode(*args, **kwargs):
|
||||||
|
""" Return True if the server is running as a Docker image """
|
||||||
|
|
||||||
|
return djangosettings.DOCKER
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag()
|
||||||
|
def inventree_db_engine(*args, **kwargs):
|
||||||
|
""" Return the InvenTree database backend e.g. 'postgresql' """
|
||||||
|
|
||||||
|
db = djangosettings.DATABASES['default']
|
||||||
|
|
||||||
|
engine = db.get('ENGINE', _('Unknown database'))
|
||||||
|
|
||||||
|
engine = engine.replace('django.db.backends.', '')
|
||||||
|
|
||||||
|
return engine
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag()
|
@register.simple_tag()
|
||||||
def inventree_instance_name(*args, **kwargs):
|
def inventree_instance_name(*args, **kwargs):
|
||||||
""" Return the InstanceName associated with the current database """
|
""" Return the InstanceName associated with the current database """
|
||||||
|
@ -1370,6 +1370,12 @@ class StockItem(MPTTModel):
|
|||||||
if self.location:
|
if self.location:
|
||||||
s += ' @ {loc}'.format(loc=self.location.name)
|
s += ' @ {loc}'.format(loc=self.location.name)
|
||||||
|
|
||||||
|
if self.purchase_order:
|
||||||
|
s += " ({pre}{po})".format(
|
||||||
|
pre=helpers.getSetting("PURCHASEORDER_REFERENCE_PREFIX"),
|
||||||
|
po=self.purchase_order,
|
||||||
|
)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
|
@ -89,6 +89,15 @@ function setFieldOptions(fieldName, optionList, options={}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function clearFieldOptions(fieldName) {
|
||||||
|
/**
|
||||||
|
* Clear (emtpy) the options list for a particular field
|
||||||
|
*/
|
||||||
|
|
||||||
|
setFieldOptions(fieldName, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function reloadFieldOptions(fieldName, options) {
|
function reloadFieldOptions(fieldName, options) {
|
||||||
/* Reload the options for a given field,
|
/* Reload the options for a given field,
|
||||||
* using an AJAX request.
|
* using an AJAX request.
|
||||||
|
@ -1218,6 +1218,17 @@ function createNewStockItem(options) {
|
|||||||
field: 'part',
|
field: 'part',
|
||||||
action: function(value) {
|
action: function(value) {
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
// No part chosen
|
||||||
|
|
||||||
|
clearFieldOptions('supplier_part');
|
||||||
|
enableField('serial_numbers', false);
|
||||||
|
enableField('purchase_price_0', false);
|
||||||
|
enableField('purchase_price_1', false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Reload options for supplier part
|
// Reload options for supplier part
|
||||||
reloadFieldOptions(
|
reloadFieldOptions(
|
||||||
'supplier_part',
|
'supplier_part',
|
||||||
@ -1243,6 +1254,9 @@ function createNewStockItem(options) {
|
|||||||
enableField('serial_numbers', response.trackable);
|
enableField('serial_numbers', response.trackable);
|
||||||
clearField('serial_numbers');
|
clearField('serial_numbers');
|
||||||
|
|
||||||
|
enableField('purchase_price_0', response.purchaseable);
|
||||||
|
enableField('purchase_price_1', response.purchaseable);
|
||||||
|
|
||||||
// Populate the expiry date
|
// Populate the expiry date
|
||||||
if (response.default_expiry <= 0) {
|
if (response.default_expiry <= 0) {
|
||||||
// No expiry date
|
// No expiry date
|
||||||
|
@ -13,6 +13,27 @@
|
|||||||
<td>{% trans "Instance Name" %}</td>
|
<td>{% trans "Instance Name" %}</td>
|
||||||
<td>{% inventree_instance_name %}</td>
|
<td>{% inventree_instance_name %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><span class='fas fa-database'></span></td>
|
||||||
|
<td>{% trans "Database" %}</td>
|
||||||
|
<td>{% inventree_db_engine %}</td>
|
||||||
|
</tr>
|
||||||
|
{% inventree_in_debug_mode as debug_mode %}
|
||||||
|
{% if debug_mode %}
|
||||||
|
<tr>
|
||||||
|
<td><span class='fas fa-laptop-code'></span></td>
|
||||||
|
<td>{% trans "Debug Mode" %}</td>
|
||||||
|
<td>{% trans "Server is running in debug mode" %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
{% inventree_docker_mode as docker_mode %}
|
||||||
|
{% if docker_mode %}
|
||||||
|
<tr>
|
||||||
|
<td><span class='fab fa-docker'></span></td>
|
||||||
|
<td>{% trans "Docker Mode" %}</td>
|
||||||
|
<td>{% trans "Server is deployed using docker" %}</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span class='fas fa-server'></span></td>
|
<td><span class='fas fa-server'></span></td>
|
||||||
|
@ -3,3 +3,6 @@ InvenTree-Version: {% inventree_version %}
|
|||||||
Django Version: {% django_version %}
|
Django Version: {% django_version %}
|
||||||
{% inventree_commit_hash as hash %}{% if hash %}Commit Hash: {{ hash }}{% endif %}
|
{% inventree_commit_hash as hash %}{% if hash %}Commit Hash: {{ hash }}{% endif %}
|
||||||
{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %}
|
{% inventree_commit_date as commit_date %}{% if commit_date %}Commit Date: {{ commit_date }}{% endif %}
|
||||||
|
Database: {% inventree_db_engine %}
|
||||||
|
Debug-Mode: {% inventree_in_debug_mode %}
|
||||||
|
Deployed using Docker: {% inventree_docker_mode %}
|
@ -14,6 +14,7 @@ ENV INVENTREE_REPO="${repository}"
|
|||||||
ENV INVENTREE_BRANCH="${branch}"
|
ENV INVENTREE_BRANCH="${branch}"
|
||||||
|
|
||||||
ENV INVENTREE_LOG_LEVEL="INFO"
|
ENV INVENTREE_LOG_LEVEL="INFO"
|
||||||
|
ENV INVENTREE_DOCKER="true"
|
||||||
|
|
||||||
# InvenTree paths
|
# InvenTree paths
|
||||||
ENV INVENTREE_SRC_DIR="${INVENTREE_HOME}/src"
|
ENV INVENTREE_SRC_DIR="${INVENTREE_HOME}/src"
|
||||||
|
Loading…
Reference in New Issue
Block a user