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:
@ -44,6 +44,10 @@ class EditStockItemForm(forms.ModelForm):
|
||||
'part',
|
||||
'supplier_part',
|
||||
'location',
|
||||
'belongs_to',
|
||||
'serial',
|
||||
'batch',
|
||||
'quantity',
|
||||
'status'
|
||||
'status',
|
||||
'customer'
|
||||
]
|
||||
|
81
InvenTree/stock/migrations/0007_auto_20180416_0853.py
Normal file
81
InvenTree/stock/migrations/0007_auto_20180416_0853.py
Normal 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),
|
||||
),
|
||||
]
|
@ -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()
|
||||
|
@ -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>
|
||||
|
Reference in New Issue
Block a user