2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 11:35:41 +00:00

Moved tracking information to StockItem

This commit is contained in:
Oliver
2018-04-16 20:08:04 +10:00
parent f7eff8ae98
commit 76ee150ca4
31 changed files with 167 additions and 640 deletions

View File

@ -44,6 +44,10 @@ class EditStockItemForm(forms.ModelForm):
'part',
'supplier_part',
'location',
'belongs_to',
'serial',
'batch',
'quantity',
'status'
'status',
'customer'
]

View File

@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11 on 2018-04-16 08:53
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('supplier', '0006_auto_20180415_1011'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('stock', '0006_auto_20180415_0302'),
]
operations = [
migrations.CreateModel(
name='StockItemTracking',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('date', models.DateField(auto_now_add=True)),
('title', models.CharField(max_length=250)),
('description', models.CharField(blank=True, max_length=1024)),
],
),
migrations.RemoveField(
model_name='historicalstockitem',
name='history_user',
),
migrations.RemoveField(
model_name='historicalstockitem',
name='location',
),
migrations.RemoveField(
model_name='historicalstockitem',
name='part',
),
migrations.RemoveField(
model_name='historicalstockitem',
name='stocktake_user',
),
migrations.RemoveField(
model_name='historicalstockitem',
name='supplier_part',
),
migrations.AddField(
model_name='stockitem',
name='batch',
field=models.CharField(blank=True, max_length=100),
),
migrations.AddField(
model_name='stockitem',
name='belongs_to',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='owned_parts', to='stock.StockItem'),
),
migrations.AddField(
model_name='stockitem',
name='customer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stockitems', to='supplier.Customer'),
),
migrations.AddField(
model_name='stockitem',
name='serial',
field=models.PositiveIntegerField(blank=True, null=True),
),
migrations.DeleteModel(
name='HistoricalStockItem',
),
migrations.AddField(
model_name='stockitemtracking',
name='item',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tracking_info', to='stock.StockItem'),
),
migrations.AddField(
model_name='stockitemtracking',
name='user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -3,9 +3,9 @@ from django.utils.translation import ugettext as _
from django.db import models, transaction
from django.core.validators import MinValueValidator
from django.contrib.auth.models import User
from simple_history.models import HistoricalRecords
from supplier.models import SupplierPart
from supplier.models import Customer
from part.models import Part
from InvenTree.models import InvenTreeTree
@ -50,19 +50,43 @@ def before_delete_stock_location(sender, instance, using, **kwargs):
class StockItem(models.Model):
"""
A 'StockItem' instance represents a quantity of physical instances of a part.
It may exist in a StockLocation, or as part of a sub-assembly installed into another StockItem
StockItems may be tracked using batch or serial numbers.
If a serial number is assigned, then StockItem cannot have a quantity other than 1
"""
def get_absolute_url(self):
return '/stock/item/{id}/'.format(id=self.id)
# The 'master' copy of the part of which this stock item is an instance
part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations')
# The 'supplier part' used in this instance. May be null if no supplier parts are defined the master part
supplier_part = models.ForeignKey(SupplierPart, blank=True, null=True, on_delete=models.SET_NULL)
# Where the part is stored. If the part has been used to build another stock item, the location may not make sense
location = models.ForeignKey(StockLocation, on_delete=models.DO_NOTHING,
related_name='items', blank=True, null=True)
# If this StockItem belongs to another StockItem (e.g. as part of a sub-assembly)
belongs_to = models.ForeignKey('self', on_delete=models.DO_NOTHING,
related_name='owned_parts', blank=True, null=True)
# The StockItem may be assigned to a particular customer
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, related_name='stockitems', blank=True, null=True)
# Optional serial number
serial = models.PositiveIntegerField(blank=True, null=True)
# Optional batch information
batch = models.CharField(max_length=100, blank=True)
# Quantity of this stock item. Value may be overridden by other settings
quantity = models.PositiveIntegerField(validators=[MinValueValidator(0)])
# Last time this item was updated (set automagically)
updated = models.DateField(auto_now=True)
# last time the stock was checked / counted
@ -97,9 +121,6 @@ class StockItem(models.Model):
infinite = models.BooleanField(default=False)
# History of this item
history = HistoricalRecords()
@transaction.atomic
def stocktake(self, count, user):
""" Perform item stocktake.
@ -147,3 +168,30 @@ class StockItem(models.Model):
n=self.quantity,
part=self.part.name,
loc=self.location.name)
class StockItemTracking(models.Model):
""" Stock tracking entry
"""
# Stock item
item = models.ForeignKey(StockItem, on_delete=models.CASCADE,
related_name='tracking_info')
# Date this entry was created (cannot be edited)
date = models.DateField(auto_now_add=True, editable=False)
# Short-form title for this tracking entry
title = models.CharField(max_length=250)
# Optional longer description
description = models.CharField(max_length=1024, blank=True)
# Which user created this tracking entry?
user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True)
# TODO
# image = models.ImageField(upload_to=func, max_length=255, null=True, blank=True)
# TODO
# file = models.FileField()

View File

@ -11,10 +11,35 @@
<td>Part</td>
<td><a href="{% url 'part-stock' item.part.id %}">{{ item.part.name }}</td>
</tr>
{% if item.belongs_to %}
<tr>
<td>Belongs To</td>
<td><a href="{% url 'stock-item-detail' item.belongs_to.id %}">{{ item.belongs_to }}</a></td>
</tr>
{% elif item.location %}
<tr>
<td>Location</td>
<td><a href="{% url 'stock-location-detail' item.location.id %}">{{ item.location.name }}</a></td>
</tr>
{% endif %}
{% if item.serial %}
<tr>
<td>Serial</td>
<td>{{ item.serial }}</td>
</tr>
{% endif %}
{% if item.batch %}
<tr>
<td>Batch</td>
<td>{{ item.batch }}</td>
</tr>
{% endif %}
{% if item.customer %}
<tr>
<td>Customer</td>
<td>{{ item.customer.name }}</td>
</tr>
{% endif %}
<tr>
<td>Quantity</td>
<td>{{ item.quantity }}</td>