2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-19 05:25:42 +00:00

UI improvements

This commit is contained in:
Oliver
2018-04-16 23:09:45 +10:00
parent b6b4189c49
commit a67d5b58db
16 changed files with 213 additions and 23 deletions

View File

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-16 12:49
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('part', '0018_part_buildable'),
]
operations = [
migrations.AlterField(
model_name='part',
name='IPN',
field=models.CharField(blank=True, help_text='Internal Part Number', max_length=100),
),
migrations.AlterField(
model_name='part',
name='URL',
field=models.URLField(blank=True, help_text='Link to extenal URL'),
),
migrations.AlterField(
model_name='part',
name='buildable',
field=models.BooleanField(default=False, help_text='Can this part be built from other parts?'),
),
migrations.AlterField(
model_name='part',
name='category',
field=models.ForeignKey(blank=True, help_text='Part category', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory'),
),
migrations.AlterField(
model_name='part',
name='description',
field=models.CharField(help_text='Part description', max_length=250),
),
migrations.AlterField(
model_name='part',
name='minimum_stock',
field=models.PositiveIntegerField(default=0, help_text='Minimum allowed stock level', validators=[django.core.validators.MinValueValidator(0)]),
),
migrations.AlterField(
model_name='part',
name='name',
field=models.CharField(help_text='Part name (must be unique)', max_length=100, unique=True),
),
migrations.AlterField(
model_name='part',
name='purchaseable',
field=models.BooleanField(default=True, help_text='Can this part be purchased from external suppliers?'),
),
migrations.AlterField(
model_name='part',
name='trackable',
field=models.BooleanField(default=False, help_text='Does this part have tracking for unique items?'),
),
]

View File

@ -84,43 +84,44 @@ class Part(models.Model):
return '/part/{id}/'.format(id=self.id)
# Short name of the part
name = models.CharField(max_length=100, unique=True)
name = models.CharField(max_length=100, unique=True, help_text='Part name (must be unique)')
# Longer description of the part (optional)
description = models.CharField(max_length=250)
description = models.CharField(max_length=250, help_text='Part description')
# Internal Part Number (optional)
# Potentially multiple parts map to the same internal IPN (variants?)
# So this does not have to be unique
IPN = models.CharField(max_length=100, blank=True)
IPN = models.CharField(max_length=100, blank=True, help_text='Internal Part Number')
# Provide a URL for an external link
URL = models.URLField(blank=True)
URL = models.URLField(blank=True, help_text='Link to extenal URL')
# Part category - all parts must be assigned to a category
category = models.ForeignKey(PartCategory, related_name='parts',
null=True, blank=True,
on_delete=models.DO_NOTHING)
on_delete=models.DO_NOTHING,
help_text='Part category')
image = models.ImageField(upload_to=rename_part_image, max_length=255, null=True, blank=True)
# Minimum "allowed" stock level
minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)])
minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)], help_text='Minimum allowed stock level')
# Units of quantity for this part. Default is "pcs"
units = models.CharField(max_length=20, default="pcs", blank=True)
# Can this part be built?
buildable = models.BooleanField(default=False)
buildable = models.BooleanField(default=False, help_text='Can this part be built from other parts?')
# Is this part "trackable"?
# Trackable parts can have unique instances
# which are assigned serial numbers (or batch numbers)
# and can have their movements tracked
trackable = models.BooleanField(default=False)
trackable = models.BooleanField(default=False, help_text='Does this part have tracking for unique items?')
# Is this part "purchaseable"?
purchaseable = models.BooleanField(default=True)
purchaseable = models.BooleanField(default=True, help_text='Can this part be purchased from external suppliers?')
def __str__(self):
if self.IPN:

View File

@ -12,7 +12,6 @@ Deletion title goes here
<p><b>This is a permanent action and cannot be undone.</b></p>
{% block del_body %}
Deletion body goes here
{% endblock %}
<form action="" method="post">{% csrf_token %}

View File

@ -4,18 +4,22 @@
{% include 'part/tabs.html' with tab='bom' %}
<h3>Bill of Materials</h3>
<table class="table table-striped">
<tr>
<th>Part</th>
<th>Description</th>
<th>Quantity</th>
<th>Edit</th>
</tr>
{% for bom_item in part.bom_items.all %}
{% with sub_part=bom_item.sub_part %}
<tr>
<td><a href="{% url 'part-detail' sub_part.id %}">{{ sub_part.name }}</a></td>
<td>{{ sub_part.description }}</td>
<td>{{ bom_item.quantity }}<span class='badge'>{{ bom_item.sub_part.available_stock }}</span></td>
<td>{{ bom_item.quantity }}</span></td>
<td><a href="{% url 'bom-item-detail' bom_item.id %}">Edit</a></td>
</tr>
{% endwith %}
{% endfor %}

View File

@ -0,0 +1,13 @@
{% extends "part/part_base.html" %}
{% block details %}
{% include 'part/tabs.html' with tab='build' %}
<h3>Build Part</h3>
TODO
<br><br>
You can build {{ part.can_build }} of this part with current stock.
{% endblock %}

View File

@ -4,9 +4,11 @@
{% include 'part/tabs.html' with tab='detail' %}
<h3>Part Details</h3>
<table class='table table-striped'>
<tr>
<td>Name</td>
<td>Part name</td>
<td>{{ part.name }}</td>
</tr>
<tr>
@ -37,6 +39,12 @@
<td>Purchaseable</td>
<td>{{ part.purchaseable }}</td>
</tr>
{% if part.minimum_stock > 0 %}
<tr>
<td>Minimum Stock</td>
<td>{{ part.minimum_stock }}</td>
</tr>
{% endif %}
</table>
<div class='container-fluid'>

View File

@ -4,6 +4,8 @@
{% include 'part/tabs.html' with tab='stock' %}
<h3>Part Stock</h3>
<table class="table table-striped">
<tr>
<th>Link</th>

View File

@ -4,6 +4,8 @@
{% include 'part/tabs.html' with tab='suppliers' %}
<h3>Part Suppliers</h3>
<table class="table table-striped">
<tr>
<th>SKU</th>

View File

@ -2,7 +2,7 @@
<li{% ifequal tab 'detail' %} class="active"{% endifequal %}><a href="{% url 'part-detail' part.id %}">Details</a></li>
{% if part.buildable %}
<li{% ifequal tab 'bom' %} class="active"{% endifequal %}><a href="{% url 'part-bom' part.id %}">BOM<span class="badge">{{ part.bom_count }}</span></a></li>
<li{% ifequal tab 'build' %} class "active"{% endifequal %}><a href="#">Build<span class='badge'>{{ part.can_build }}</span></a></li>
<li{% ifequal tab 'build' %} class="active"{% endifequal %}><a href="{% url 'part-build' part.id %}">Build<span class='badge'>{{ part.can_build }}</span></a></li>
{% endif %}
{% if part.used_in_count > 0 %}
<li{% ifequal tab 'used' %} class="active"{% endifequal %}><a href="{% url 'part-used-in' part.id %}">Used In{% if part.used_in_count > 0 %}<span class="badge">{{ part.used_in_count }}</span>{% endif %}</a></li>

View File

@ -4,6 +4,8 @@
{% include 'part/tabs.html' with tab='used' %}
<h3>Used In</h3>
<table class="table table-striped">
<tr>
<th>Part</th>

View File

@ -41,6 +41,7 @@ part_detail_urls = [
url(r'^delete/?', views.PartDelete.as_view(), name='part-delete'),
url(r'^track/?', views.PartDetail.as_view(template_name='part/track.html'), name='part-track'),
url(r'^bom/?', views.PartDetail.as_view(template_name='part/bom.html'), name='part-bom'),
url(r'^build/?', views.PartDetail.as_view(template_name='part/build.html'), name='part-build'),
url(r'^stock/?', views.PartDetail.as_view(template_name='part/stock.html'), name='part-stock'),
url(r'^used/?', views.PartDetail.as_view(template_name='part/used_in.html'), name='part-used-in'),
url(r'^suppliers/?', views.PartDetail.as_view(template_name='part/supplier.html'), name='part-suppliers'),