2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-04 14:28:48 +00:00

Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2019-08-15 13:41:50 +10:00
commit c3fe101571
14 changed files with 37 additions and 53 deletions

View File

@ -4,7 +4,7 @@ Provides information on the current InvenTree version
import subprocess import subprocess
INVENTREE_SW_VERSION = "0.0.2" INVENTREE_SW_VERSION = "0.0.3"
def inventreeVersion(): def inventreeVersion():

View File

@ -41,7 +41,7 @@ cors:
# MEDIA_ROOT is the local filesystem location for storing uploaded files # MEDIA_ROOT is the local filesystem location for storing uploaded files
# By default, it is stored in a directory named 'media' local to the InvenTree directory # By default, it is stored in a directory named 'media' local to the InvenTree directory
# This should be changed for a production installation # This should be changed for a production installation
media_root: 'media' media_root: './media'
# STATIC_ROOT is the local filesystem location for storing static files # STATIC_ROOT is the local filesystem location for storing static files
# By default it is stored in a directory named 'static' local to the InvenTree directory # By default it is stored in a directory named 'static' local to the InvenTree directory
@ -52,4 +52,4 @@ log_queries: False
# Backup options # Backup options
# Set the backup_dir parameter to store backup files in a specific location # Set the backup_dir parameter to store backup files in a specific location
backup_dir: '/mnt/c/Users/Oliver/inventree-backup/' #backup_dir: '/home/inventree/backup/'

View File

@ -36,8 +36,8 @@
{{ part.full_name }} <small><i>{{ part.description }}</i></small> {{ part.full_name }} <small><i>{{ part.description }}</i></small>
</td> </td>
<td> <td>
<button class='btn btn-default btn-create' id='new_supplier_part_{{ part.id }}' title='Create new supplier part for {{ part }}' type='button'> <button class='btn btn-default btn-create' onClick='newSupplierPartFromOrderWizard()' id='new_supplier_part_{{ part.id }}' title='Create new supplier part for {{ part }}' type='button'>
<span part-id='{{ part.id }}' onClick='newSupplierPartFromOrderWizard()' class='glyphicon glyphicon-small glyphicon-plus'></span> <span part-id='{{ part.id }}' class='glyphicon glyphicon-small glyphicon-plus'></span>
</button> </button>
</td> </td>
<td> <td>
@ -63,8 +63,8 @@
</div> </div>
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' id='del_item_{{ part.id }}' title='Remove part' type='button'> <button class='btn btn-default btn-remove' onclick='removeOrderRowFromOrderWizard()' id='del_item_{{ part.id }}' title='Remove part' type='button'>
<span row='part_row_{{ part.id }}' onclick='removeOrderRowFromOrderWizard()' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='part_row_{{ part.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -41,8 +41,9 @@
class='btn btn-default btn-create' class='btn btn-default btn-create'
id='new_po_{{ supplier.id }}' id='new_po_{{ supplier.id }}'
title='Create new purchase order for {{ supplier.name }}' title='Create new purchase order for {{ supplier.name }}'
type='button'> type='button'
<span supplier-id='{{ supplier.id }}' onclick='newPurchaseOrderFromOrderWizard()' class='glyphicon glyphicon-small glyphicon-plus'></span> onclick='newPurchaseOrderFromOrderWizard()'>
<span supplier-id='{{ supplier.id }}' class='glyphicon glyphicon-small glyphicon-plus'></span>
</button> </button>
</td> </td>
<td> <td>

View File

@ -57,8 +57,8 @@ Receive outstanding parts for <b>{{ order }}</b> - <i>{{ order.description }}</i
</div> </div>
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' id='del_item_{{ line.id }}' title='Remove line' type='button'> <button class='btn btn-default btn-remove' onClick="removeOrderRowFromOrderWizard()" id='del_item_{{ line.id }}' title='Remove line' type='button'>
<span row='line_row_{{ line.id }}' onClick="removeOrderRowFromOrderWizard()" class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='line_row_{{ line.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -149,9 +149,7 @@ class BomUploadManager:
return len(self.data.headers) return len(self.data.headers)
def row_count(self): def row_count(self):
""" Return the number of rows in the file. """ Return the number of rows in the file. """
Ignored the top rows as indicated by 'starting row'
"""
if self.data is None: if self.data is None:
return 0 return 0

View File

@ -8,7 +8,6 @@ from __future__ import unicode_literals
from InvenTree.forms import HelperForm from InvenTree.forms import HelperForm
from django import forms from django import forms
from django.core.validators import MinValueValidator
from .models import Part, PartCategory, PartAttachment from .models import Part, PartCategory, PartAttachment
from .models import BomItem from .models import BomItem
@ -51,18 +50,6 @@ class BomUploadSelectFile(HelperForm):
] ]
class BomUploadSelectFields(HelperForm):
""" Form for selecting BOM fields """
starting_row = forms.IntegerField(required=True, initial=2, help_text='Index of starting row', validators=[MinValueValidator(1)])
class Meta:
model = Part
fields = [
'starting_row',
]
class EditPartAttachmentForm(HelperForm): class EditPartAttachmentForm(HelperForm):
""" Form for editing a PartAttachment object """ """ Form for editing a PartAttachment object """

View File

@ -24,9 +24,6 @@
<form method="post" action='' class='js-modal-form' enctype="multipart/form-data"> <form method="post" action='' class='js-modal-form' enctype="multipart/form-data">
<button type="submit" class="save btn btn-default">Submit Selections</button> <button type="submit" class="save btn btn-default">Submit Selections</button>
{% csrf_token %} {% csrf_token %}
{% load crispy_forms_tags %}
{% crispy form %}
<input type='hidden' name='form_step' value='select_fields'/> <input type='hidden' name='form_step' value='select_fields'/>
@ -40,8 +37,8 @@
<div> <div>
<input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/> <input type='hidden' name='col_name_{{ forloop.counter0 }}' value='{{ col.name }}'/>
{{ col.name }} {{ col.name }}
<button class='btn btn-default btn-remove' id='del_col_{{ forloop.counter0 }}' style='display: inline; float: right;' title='Remove column'> <button class='btn btn-default btn-remove' onClick='removeColFromBomWizard()' id='del_col_{{ forloop.counter0 }}' style='display: inline; float: right;' title='Remove column'>
<span col_id='{{ forloop.counter0 }}' onClick='removeColFromBomWizard()' class='glyphicon glyphicon-small glyphicon-remove'></span> <span col_id='{{ forloop.counter0 }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</div> </div>
</th> </th>
@ -69,8 +66,8 @@
{% for row in bom_rows %} {% for row in bom_rows %}
<tr> <tr>
<td> <td>
<button class='btn btn-default btn-remove' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'> <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'>
<span row_id='{{ forloop.counter }}' onClick='removeRowFromBomWizard()' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row_id='{{ forloop.counter }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</td> </td>
<td>{{ forloop.counter }}</td> <td>{{ forloop.counter }}</td>

View File

@ -47,8 +47,8 @@
{% for row in bom_rows %} {% for row in bom_rows %}
<tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'> <tr {% if row.errors %} style='background: #ffeaea;'{% endif %} part-name='{{ row.part_name }}' part-description='{{ row.description }}' part-select='#select_part_{{ row.index }}'>
<td> <td>
<button class='btn btn-default btn-remove' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'> <button class='btn btn-default btn-remove' onClick='removeRowFromBomWizard()' id='del_row_{{ forloop.counter }}' style='display: inline; float: right;' title='Remove row'>
<span row_id='{{ forloop.counter }}' onClick='removeRowFromBomWizard()' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row_id='{{ forloop.counter }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</td> </td>
<td> <td>
@ -57,8 +57,8 @@
{% for item in row.data %} {% for item in row.data %}
<td> <td>
{% if item.column.guess == 'Part' %} {% if item.column.guess == 'Part' %}
<button class='btn btn-default btn-create' id='new_part_row_{{ row.index }}' title='Create new part' type='button'> <button class='btn btn-default btn-create' onClick='newPartFromBomWizard()' id='new_part_row_{{ row.index }}' title='Create new part' type='button'>
<span row_id='{{ row.index }}' class='glyphicon glyphicon-small glyphicon-plus' onClick='newPartFromBomWizard()'/> <span row_id='{{ row.index }}' class='glyphicon glyphicon-small glyphicon-plus'/>
</button> </button>
<select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'> <select class='select bomselect' id='select_part_{{ row.index }}' name='part_{{ row.index }}'>

View File

@ -46,8 +46,8 @@
{{ part.category.pathstring }} {{ part.category.pathstring }}
</td> </td>
<td> <td>
<button class='btn btn-default btn-remove' title='Remove part' type='button'> <button class='btn btn-default btn-remove' onClick='removeRowFromModalForm()' title='Remove part' type='button'>
<span row='part_row_{{ part.id }}' onClick='removeRowFromModalForm()' class='glyphicon glyphicon-small glyphicon-remove'></span> <span row='part_row_{{ part.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span>
</button> </button>
</td> </td>
</tr> </tr>

View File

@ -671,13 +671,8 @@ class BomUpload(FormView):
def get_form_class(self): def get_form_class(self):
form_step = self.request.POST.get('form_step', None) # Default form is the starting point
return part_forms.BomUploadSelectFile
if form_step == 'select_fields':
return part_forms.BomUploadSelectFields
else:
# Default form is the starting point
return part_forms.BomUploadSelectFile
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
@ -776,7 +771,7 @@ class BomUpload(FormView):
if bom_file_valid: if bom_file_valid:
# BOM file is valid? Proceed to the next step! # BOM file is valid? Proceed to the next step!
form = part_forms.BomUploadSelectFields form = None
self.template_name = 'part/bom_upload/select_fields.html' self.template_name = 'part/bom_upload/select_fields.html'
self.extractDataFromFile(manager) self.extractDataFromFile(manager)
@ -983,18 +978,15 @@ class BomUpload(FormView):
self.getTableDataFromPost() self.getTableDataFromPost()
valid = len(self.missing_columns) == 0 and not self.duplicates valid = len(self.missing_columns) == 0 and not self.duplicates
form = part_forms.BomUploadSelectFields
if valid: if valid:
# Try to extract meaningful data # Try to extract meaningful data
self.preFillSelections() self.preFillSelections()
form = None
self.template_name = 'part/bom_upload/select_parts.html' self.template_name = 'part/bom_upload/select_parts.html'
else: else:
self.template_name = 'part/bom_upload/select_fields.html' self.template_name = 'part/bom_upload/select_fields.html'
return self.render_to_response(self.get_context_data(form=form)) return self.render_to_response(self.get_context_data(form=None))
def handlePartSelection(self): def handlePartSelection(self):

View File

@ -131,6 +131,12 @@
title: 'Create New Part', title: 'Create New Part',
url: "{% url 'part-create' %}", url: "{% url 'part-create' %}",
}, },
{
field: 'supplier_part',
label: 'New Supplier Part',
title: 'Create new Supplier Part',
url: "{% url 'supplier-part-create' %}"
},
{ {
field: 'location', field: 'location',
label: 'New Location', label: 'New Location',

View File

@ -29,7 +29,7 @@
<br><span class='help-inline'>{{ item.error }}</span> <br><span class='help-inline'>{{ item.error }}</span>
{% endif %} {% endif %}
</td> </td>
<td><button class='btn btn-default btn-remove' id='del-{{ item.id }}' title='Remove item' type='button'><span row='stock-row-{{ item.id }}' onclick='removeStockRow()' class='glyphicon glyphicon-small glyphicon-remove'></span></button></td> <td><button class='btn btn-default btn-remove' onclick='removeStockRow()' id='del-{{ item.id }}' title='Remove item' type='button'><span row='stock-row-{{ item.id }}' class='glyphicon glyphicon-small glyphicon-remove'></span></button></td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -40,6 +40,9 @@ These requirements can be installed from the base directory with the command ``m
It is up to the database adminstrator to create a new database to store inventree data, in addition to a username/password to access the data. It is up to the database adminstrator to create a new database to store inventree data, in addition to a username/password to access the data.
.. important:: MySQL Collation:
When creating the database, the adminstrator must ensure that the collation option is set to *utf8_unicode_520_ci* to ensure that InvenTree features function correctly.
The database options then need to be adjusted to communicate the MySQL backend. Refer to the `Django docs <https://docs.djangoproject.com/en/dev/ref/databases/>`_ for further information. The database options then need to be adjusted to communicate the MySQL backend. Refer to the `Django docs <https://docs.djangoproject.com/en/dev/ref/databases/>`_ for further information.
**POSTGRESQL:** PostgreSQL database backend is supported with the native Django implementation. Note that to use this backend, the ``psycopg2`` Python library must first be installed. **POSTGRESQL:** PostgreSQL database backend is supported with the native Django implementation. Note that to use this backend, the ``psycopg2`` Python library must first be installed.