2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00
- Ref: https://github.com/inventree/InvenTree/pull/6335
- Fixes bug with regard to splitting stock items
This commit is contained in:
Oliver 2024-01-25 08:33:23 +11:00 committed by GitHub
parent 3daf85c3d0
commit c12e6dbf42
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 221 additions and 195 deletions

View File

@ -57,7 +57,6 @@ class AddFieldOrSkip(migrations.AddField):
try:
super().database_forwards(app_label, schema_editor, from_state, to_state)
print(f'Added field {self.name} to model {self.model_name}')
except Exception as exc:
pass

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import logging
import os
from datetime import datetime, timedelta
from decimal import Decimal, InvalidOperation
@ -40,6 +41,8 @@ from part import models as PartModels
from plugin.events import trigger_event
from users.models import Owner
logger = logging.getLogger('inventree')
class StockLocationType(MetadataMixin, models.Model):
"""A type of stock location like Warehouse, room, shelf, drawer.
@ -1660,9 +1663,12 @@ class StockItem(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, commo
# Nullify the PK so a new record is created
new_stock = StockItem.objects.get(pk=self.pk)
new_stock.pk = None
new_stock.parent = self
new_stock.quantity = quantity
# Update the new stock item to ensure the tree structure is observed
new_stock.parent = self
new_stock.level = self.level + 1
# Move to the new location if specified, otherwise use current location
if location:
new_stock.location = location
@ -1704,6 +1710,19 @@ class StockItem(InvenTreeBarcodeMixin, InvenTreeNotesMixin, MetadataMixin, commo
stockitem=new_stock,
)
# Rebuild the tree for this parent item
try:
StockItem.objects.partial_rebuild(tree_id=self.tree_id)
except Exception:
logger.warning('Rebuilding entire StockItem tree')
StockItem.objects.rebuild()
# Attempt to reload the new item from the database
try:
new_stock.refresh_from_db()
except Exception:
pass
# Return a copy of the "new" stock item
return new_stock

View File

@ -19,7 +19,7 @@ from .models import (StockItem, StockItemTestResult, StockItemTracking,
class StockTestBase(InvenTreeTestCase):
"""Base class for running Stock tests"""
"""Base class for running Stock tests."""
fixtures = [
'category',
@ -54,11 +54,11 @@ class StockTest(StockTestBase):
"""Tests to ensure that the stock location tree functions correctly."""
def test_pathstring(self):
"""Check that pathstring updates occur as expected"""
a = StockLocation.objects.create(name="A")
b = StockLocation.objects.create(name="B", parent=a)
c = StockLocation.objects.create(name="C", parent=b)
d = StockLocation.objects.create(name="D", parent=c)
"""Check that pathstring updates occur as expected."""
a = StockLocation.objects.create(name='A')
b = StockLocation.objects.create(name='B', parent=a)
c = StockLocation.objects.create(name='C', parent=b)
d = StockLocation.objects.create(name='D', parent=c)
def refresh():
a.refresh_from_db()
@ -67,56 +67,56 @@ class StockTest(StockTestBase):
d.refresh_from_db()
# Initial checks
self.assertEqual(a.pathstring, "A")
self.assertEqual(b.pathstring, "A/B")
self.assertEqual(c.pathstring, "A/B/C")
self.assertEqual(d.pathstring, "A/B/C/D")
self.assertEqual(a.pathstring, 'A')
self.assertEqual(b.pathstring, 'A/B')
self.assertEqual(c.pathstring, 'A/B/C')
self.assertEqual(d.pathstring, 'A/B/C/D')
c.name = "Cc"
c.name = 'Cc'
c.save()
refresh()
self.assertEqual(a.pathstring, "A")
self.assertEqual(b.pathstring, "A/B")
self.assertEqual(c.pathstring, "A/B/Cc")
self.assertEqual(d.pathstring, "A/B/Cc/D")
self.assertEqual(a.pathstring, 'A')
self.assertEqual(b.pathstring, 'A/B')
self.assertEqual(c.pathstring, 'A/B/Cc')
self.assertEqual(d.pathstring, 'A/B/Cc/D')
b.name = "Bb"
b.name = 'Bb'
b.save()
refresh()
self.assertEqual(a.pathstring, "A")
self.assertEqual(b.pathstring, "A/Bb")
self.assertEqual(c.pathstring, "A/Bb/Cc")
self.assertEqual(d.pathstring, "A/Bb/Cc/D")
self.assertEqual(a.pathstring, 'A')
self.assertEqual(b.pathstring, 'A/Bb')
self.assertEqual(c.pathstring, 'A/Bb/Cc')
self.assertEqual(d.pathstring, 'A/Bb/Cc/D')
a.name = "Aa"
a.name = 'Aa'
a.save()
refresh()
self.assertEqual(a.pathstring, "Aa")
self.assertEqual(b.pathstring, "Aa/Bb")
self.assertEqual(c.pathstring, "Aa/Bb/Cc")
self.assertEqual(d.pathstring, "Aa/Bb/Cc/D")
self.assertEqual(a.pathstring, 'Aa')
self.assertEqual(b.pathstring, 'Aa/Bb')
self.assertEqual(c.pathstring, 'Aa/Bb/Cc')
self.assertEqual(d.pathstring, 'Aa/Bb/Cc/D')
d.name = "Dd"
d.name = 'Dd'
d.save()
refresh()
self.assertEqual(a.pathstring, "Aa")
self.assertEqual(b.pathstring, "Aa/Bb")
self.assertEqual(c.pathstring, "Aa/Bb/Cc")
self.assertEqual(d.pathstring, "Aa/Bb/Cc/Dd")
self.assertEqual(a.pathstring, 'Aa')
self.assertEqual(b.pathstring, 'Aa/Bb')
self.assertEqual(c.pathstring, 'Aa/Bb/Cc')
self.assertEqual(d.pathstring, 'Aa/Bb/Cc/Dd')
# Test a really long name
# (it will be clipped to < 250 characters)
a.name = "A" * 100
a.name = 'A' * 100
a.save()
b.name = "B" * 100
b.name = 'B' * 100
b.save()
c.name = "C" * 100
c.name = 'C' * 100
c.save()
d.name = "D" * 100
d.name = 'D' * 100
d.save()
refresh()
@ -125,19 +125,15 @@ class StockTest(StockTestBase):
self.assertEqual(len(c.pathstring), 249)
self.assertEqual(len(d.pathstring), 249)
self.assertTrue(d.pathstring.startswith("AAAAAAAA"))
self.assertTrue(d.pathstring.endswith("DDDDDDDD"))
self.assertTrue(d.pathstring.startswith('AAAAAAAA'))
self.assertTrue(d.pathstring.endswith('DDDDDDDD'))
def test_link(self):
"""Test the link URL field validation"""
"""Test the link URL field validation."""
item = StockItem.objects.get(pk=1)
# Check that invalid URLs fail
for bad_url in [
'test.com',
'httpx://abc.xyz',
'https:google.com',
]:
for bad_url in ['test.com', 'httpx://abc.xyz', 'https:google.com']:
with self.assertRaises(ValidationError):
item.link = bad_url
item.save()
@ -168,52 +164,42 @@ class StockTest(StockTestBase):
@override_settings(EXTRA_URL_SCHEMES=['ssh'])
def test_exteneded_schema(self):
"""Test that extended URL schemes are allowed"""
"""Test that extended URL schemes are allowed."""
item = StockItem.objects.get(pk=1)
item.link = 'ssh://user:pwd@deb.org:223'
item.save()
item.full_clean()
def test_serial_numbers(self):
"""Test serial number uniqueness"""
"""Test serial number uniqueness."""
# Ensure that 'global uniqueness' setting is enabled
InvenTreeSetting.set_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', True, self.user)
part_a = Part.objects.create(name='A', description='A part with a description', trackable=True)
part_b = Part.objects.create(name='B', description='B part with a description', trackable=True)
part_a = Part.objects.create(
name='A', description='A part with a description', trackable=True
)
part_b = Part.objects.create(
name='B', description='B part with a description', trackable=True
)
# Create a StockItem for part_a
StockItem.objects.create(
part=part_a,
quantity=1,
serial='ABCDE',
)
StockItem.objects.create(part=part_a, quantity=1, serial='ABCDE')
# Create a StockItem for part_a (but, will error due to identical serial)
with self.assertRaises(ValidationError):
StockItem.objects.create(
part=part_b,
quantity=1,
serial='ABCDE',
)
StockItem.objects.create(part=part_b, quantity=1, serial='ABCDE')
# Now, allow serial numbers to be duplicated between different parts
InvenTreeSetting.set_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', False, self.user)
StockItem.objects.create(
part=part_b,
quantity=1,
serial='ABCDE',
)
StockItem.objects.create(part=part_b, quantity=1, serial='ABCDE')
def test_expiry(self):
"""Test expiry date functionality for StockItem model."""
today = datetime.datetime.now().date()
item = StockItem.objects.create(
location=self.office,
part=Part.objects.get(pk=1),
quantity=10,
location=self.office, part=Part.objects.get(pk=1), quantity=10
)
# Without an expiry_date set, item should not be "expired"
@ -249,13 +235,14 @@ class StockTest(StockTestBase):
# And there should be *no* items being build
self.assertEqual(part.quantity_being_built, 0)
build = Build.objects.create(reference='BO-4444', part=part, title='A test build', quantity=1)
build = Build.objects.create(
reference='BO-4444', part=part, title='A test build', quantity=1
)
# Add some stock items which are "building"
for _ in range(10):
StockItem.objects.create(
part=part, build=build,
quantity=10, is_building=True
part=part, build=build, quantity=10, is_building=True
)
# The "is_building" quantity should not be counted here
@ -330,7 +317,10 @@ class StockTest(StockTestBase):
# There should be 16 widgets "in stock"
self.assertEqual(
StockItem.objects.filter(part=25).aggregate(Sum('quantity'))['quantity__sum'], 16
StockItem.objects.filter(part=25).aggregate(Sum('quantity'))[
'quantity__sum'
],
16,
)
def test_delete_location(self):
@ -339,7 +329,9 @@ class StockTest(StockTestBase):
n_stock = StockItem.objects.count()
# What parts are in drawer 3?
stock_ids = [part.id for part in StockItem.objects.filter(location=self.drawer3.id)]
stock_ids = [
part.id for part in StockItem.objects.filter(location=self.drawer3.id)
]
# Delete location - parts should move to parent location
self.drawer3.delete()
@ -361,7 +353,9 @@ class StockTest(StockTestBase):
self.assertEqual(it.location, self.bathroom)
# There now should be 2 lots of screws in the bathroom
self.assertEqual(StockItem.objects.filter(part=1, location=self.bathroom).count(), 2)
self.assertEqual(
StockItem.objects.filter(part=1, location=self.bathroom).count(), 2
)
# Check that a tracking item was added
track = StockItemTracking.objects.filter(item=it).latest('id')
@ -463,13 +457,15 @@ class StockTest(StockTestBase):
self.assertFalse(it.add_stock(-10, None))
def test_allocate_to_customer(self):
"""Test allocating stock to a customer"""
"""Test allocating stock to a customer."""
it = StockItem.objects.get(pk=2)
n = it.quantity
an = n - 10
customer = Company.objects.create(name="MyTestCompany")
order = SalesOrder.objects.create(description="Test order")
ait = it.allocateToCustomer(customer, quantity=an, order=order, user=None, notes='Allocated some stock')
customer = Company.objects.create(name='MyTestCompany')
order = SalesOrder.objects.create(description='Test order')
ait = it.allocateToCustomer(
customer, quantity=an, order=order, user=None, notes='Allocated some stock'
)
# Check if new stockitem is created
self.assertTrue(ait)
@ -485,29 +481,48 @@ class StockTest(StockTestBase):
# Check that a tracking item was added
track = StockItemTracking.objects.filter(item=ait).latest('id')
self.assertEqual(track.tracking_type, StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER)
self.assertEqual(
track.tracking_type, StockHistoryCode.SHIPPED_AGAINST_SALES_ORDER
)
self.assertIn('Allocated some stock', track.notes)
def test_return_from_customer(self):
"""Test removing previous allocated stock from customer"""
"""Test removing previous allocated stock from customer."""
it = StockItem.objects.get(pk=2)
# First establish total stock for this part
allstock_before = StockItem.objects.filter(part=it.part).aggregate(Sum("quantity"))["quantity__sum"]
allstock_before = StockItem.objects.filter(part=it.part).aggregate(
Sum('quantity')
)['quantity__sum']
n = it.quantity
an = n - 10
customer = Company.objects.create(name="MyTestCompany")
order = SalesOrder.objects.create(description="Test order")
customer = Company.objects.create(name='MyTestCompany')
order = SalesOrder.objects.create(description='Test order')
ait = it.allocateToCustomer(customer, quantity=an, order=order, user=None, notes='Allocated some stock')
ait.return_from_customer(it.location, None, notes="Stock removed from customer")
ait = it.allocateToCustomer(
customer, quantity=an, order=order, user=None, notes='Allocated some stock'
)
self.assertEqual(ait.quantity, an)
self.assertTrue(ait.parent, it)
# There should be only quantity 10x remaining
it.refresh_from_db()
self.assertEqual(it.quantity, 10)
ait.return_from_customer(it.location, None, notes='Stock removed from customer')
# When returned stock is returned to its original (parent) location, check that the parent has correct quantity
it.refresh_from_db()
self.assertEqual(it.quantity, n)
ait = it.allocateToCustomer(customer, quantity=an, order=order, user=None, notes='Allocated some stock')
ait.return_from_customer(self.drawer3, None, notes="Stock removed from customer")
ait = it.allocateToCustomer(
customer, quantity=an, order=order, user=None, notes='Allocated some stock'
)
ait.return_from_customer(
self.drawer3, None, notes='Stock removed from customer'
)
# Check correct assignment of the new location
self.assertEqual(ait.location, self.drawer3)
@ -527,7 +542,9 @@ class StockTest(StockTestBase):
self.assertIn('Stock removed from customer', track.notes)
# Establish total stock for the part after remove from customer to check that we still have the correct quantity in stock
allstock_after = StockItem.objects.filter(part=it.part).aggregate(Sum("quantity"))["quantity__sum"]
allstock_after = StockItem.objects.filter(part=it.part).aggregate(
Sum('quantity')
)['quantity__sum']
self.assertEqual(allstock_before, allstock_after)
def test_take_stock(self):
@ -578,10 +595,7 @@ class StockTest(StockTestBase):
# Ensure we do not have unique serials enabled
InvenTreeSetting.set_setting('SERIAL_NUMBER_GLOBALLY_UNIQUE', False, None)
item = StockItem.objects.create(
part=p,
quantity=1,
)
item = StockItem.objects.create(part=p, quantity=1)
self.assertFalse(item.serialized)
@ -609,10 +623,7 @@ class StockTest(StockTestBase):
trackable=True,
)
item = StockItem.objects.create(
part=p,
quantity=1,
)
item = StockItem.objects.create(part=p, quantity=1)
for sn in [12345, '12345', ' 12345 ']:
item.serial = sn
@ -620,7 +631,7 @@ class StockTest(StockTestBase):
self.assertEqual(item.serial_int, 12345)
item.serial = "-123"
item.serial = '-123'
item.save()
# Negative number should map to positive value
@ -631,7 +642,7 @@ class StockTest(StockTestBase):
item.save()
# The 'integer' portion has been clipped to a maximum value
self.assertEqual(item.serial_int, 0x7fffffff)
self.assertEqual(item.serial_int, 0x7FFFFFFF)
# Non-numeric values should encode to zero
for sn in ['apple', 'banana', 'carrot']:
@ -644,30 +655,18 @@ class StockTest(StockTestBase):
item.serial = 100
item.save()
item_next = StockItem.objects.create(
part=p,
serial=150,
quantity=1
)
item_next = StockItem.objects.create(part=p, serial=150, quantity=1)
self.assertEqual(item.get_next_serialized_item(), item_next)
item_prev = StockItem.objects.create(
part=p,
serial=' 57',
quantity=1,
)
item_prev = StockItem.objects.create(part=p, serial=' 57', quantity=1)
self.assertEqual(item.get_next_serialized_item(reverse=True), item_prev)
# Create a number of serialized stock items around the current item
for i in range(75, 125):
try:
StockItem.objects.create(
part=p,
serial=i,
quantity=1,
)
StockItem.objects.create(part=p, serial=i, quantity=1)
except Exception:
pass
@ -696,14 +695,14 @@ class StockTest(StockTestBase):
# Try an invalid quantity
with self.assertRaises(ValidationError):
item.serializeStock("k", [], self.user)
item.serializeStock('k', [], self.user)
with self.assertRaises(ValidationError):
item.serializeStock(-1, [], self.user)
# Not enough serial numbers for all stock items.
with self.assertRaises(ValidationError):
item.serializeStock(3, "hello", self.user)
item.serializeStock(3, 'hello', self.user)
def test_serialize_stock_valid(self):
"""Perform valid stock serializations."""
@ -755,55 +754,25 @@ class StockTest(StockTestBase):
"""
# First, we will create a stock location structure
A = StockLocation.objects.create(
name='A',
description='Top level location'
)
A = StockLocation.objects.create(name='A', description='Top level location')
B1 = StockLocation.objects.create(
name='B1',
parent=A
)
B1 = StockLocation.objects.create(name='B1', parent=A)
B2 = StockLocation.objects.create(
name='B2',
parent=A
)
B2 = StockLocation.objects.create(name='B2', parent=A)
B3 = StockLocation.objects.create(
name='B3',
parent=A
)
B3 = StockLocation.objects.create(name='B3', parent=A)
C11 = StockLocation.objects.create(
name='C11',
parent=B1,
)
C11 = StockLocation.objects.create(name='C11', parent=B1)
C12 = StockLocation.objects.create(
name='C12',
parent=B1,
)
C12 = StockLocation.objects.create(name='C12', parent=B1)
C21 = StockLocation.objects.create(
name='C21',
parent=B2,
)
C21 = StockLocation.objects.create(name='C21', parent=B2)
C22 = StockLocation.objects.create(
name='C22',
parent=B2,
)
C22 = StockLocation.objects.create(name='C22', parent=B2)
C31 = StockLocation.objects.create(
name='C31',
parent=B3,
)
C31 = StockLocation.objects.create(name='C31', parent=B3)
C32 = StockLocation.objects.create(
name='C32',
parent=B3
)
C32 = StockLocation.objects.create(name='C32', parent=B3)
# Check that the tree_id is correct for each sublocation
for loc in [B1, B2, B3, C11, C12, C21, C22, C31, C32]:
@ -850,9 +819,7 @@ class StockTest(StockTestBase):
# Add some stock items to B3
for _ in range(10):
StockItem.objects.create(
part=Part.objects.get(pk=1),
quantity=10,
location=B3
part=Part.objects.get(pk=1), quantity=10, location=B3
)
self.assertEqual(StockItem.objects.filter(location=B3).count(), 10)
@ -930,10 +897,10 @@ class StockTest(StockTestBase):
class StockBarcodeTest(StockTestBase):
"""Run barcode tests for the stock app"""
"""Run barcode tests for the stock app."""
def test_stock_item_barcode_basics(self):
"""Simple tests for the StockItem barcode integration"""
"""Simple tests for the StockItem barcode integration."""
item = StockItem.objects.get(pk=1)
self.assertEqual(StockItem.barcode_model_type(), 'stockitem')
@ -949,7 +916,7 @@ class StockBarcodeTest(StockTestBase):
self.assertEqual(barcode, '{"stockitem": 1}')
def test_location_barcode_basics(self):
"""Simple tests for the StockLocation barcode integration"""
"""Simple tests for the StockLocation barcode integration."""
self.assertEqual(StockLocation.barcode_model_type(), 'stocklocation')
loc = StockLocation.objects.get(pk=1)
@ -982,7 +949,10 @@ class VariantTest(StockTestBase):
chair = Part.objects.get(pk=10000)
# Operations on the top-level object
[self.assertFalse(chair.validate_serial_number(i)) for i in [1, 2, 3, 4, 5, 20, 21, 22]]
[
self.assertFalse(chair.validate_serial_number(i))
for i in [1, 2, 3, 4, 5, 20, 21, 22]
]
self.assertFalse(chair.validate_serial_number(20))
self.assertFalse(chair.validate_serial_number(21))
@ -1006,11 +976,7 @@ class VariantTest(StockTestBase):
# Create a new serial number
n = variant.get_latest_serial_number()
item = StockItem(
part=variant,
quantity=1,
serial=n
)
item = StockItem(part=variant, quantity=1, serial=n)
# This should fail
with self.assertRaises(ValidationError):
@ -1031,6 +997,63 @@ class VariantTest(StockTestBase):
item.save()
class StockTreeTest(StockTestBase):
"""Unit test for StockItem tree structure."""
def test_stock_split(self):
"""Test that stock splitting works correctly."""
StockItem.objects.rebuild()
part = Part.objects.create(name='My part', description='My part description')
location = StockLocation.objects.create(name='Test Location')
# Create an initial stock item
item = StockItem.objects.create(part=part, quantity=1000, location=location)
# Test that the initial MPTT values are correct
self.assertEqual(item.level, 0)
self.assertEqual(item.lft, 1)
self.assertEqual(item.rght, 2)
children = []
self.assertEqual(item.get_descendants(include_self=False).count(), 0)
self.assertEqual(item.get_descendants(include_self=True).count(), 1)
# Create child items by splitting stock
for idx in range(10):
child = item.splitStock(50, None, None)
children.append(child)
# Check that the child item has been correctly created
self.assertEqual(child.parent.pk, item.pk)
self.assertEqual(child.tree_id, item.tree_id)
self.assertEqual(child.level, 1)
item.refresh_from_db()
self.assertEqual(item.get_children().count(), idx + 1)
self.assertEqual(item.get_descendants(include_self=True).count(), idx + 2)
item.refresh_from_db()
n = item.get_descendants(include_self=True).count()
for child in children:
# Create multiple sub-childs
for _idx in range(3):
sub_child = child.splitStock(10, None, None)
self.assertEqual(sub_child.parent.pk, child.pk)
self.assertEqual(sub_child.tree_id, child.tree_id)
self.assertEqual(sub_child.level, 2)
self.assertEqual(sub_child.get_ancestors(include_self=True).count(), 3)
child.refresh_from_db()
self.assertEqual(child.get_descendants(include_self=True).count(), 4)
item.refresh_from_db()
self.assertEqual(item.get_descendants(include_self=True).count(), n + 30)
class TestResultTest(StockTestBase):
"""Tests for the StockItemTestResult model."""
@ -1040,7 +1063,7 @@ class TestResultTest(StockTestBase):
tests = item.test_results
self.assertEqual(tests.count(), 4)
results = item.getTestResults(test="Temperature Test")
results = item.getTestResults(test='Temperature Test')
self.assertEqual(results.count(), 2)
# Passing tests
@ -1074,9 +1097,7 @@ class TestResultTest(StockTestBase):
test.save()
StockItemTestResult.objects.create(
stock_item=item,
test='sew cushion',
result=True
stock_item=item, test='sew cushion', result=True
)
# Still should be failing at this point,
@ -1088,7 +1109,7 @@ class TestResultTest(StockTestBase):
stock_item=item,
test='apply paint',
date=datetime.datetime(2022, 12, 12),
result=True
result=True,
)
self.assertTrue(item.passedAllRequiredTests())
@ -1096,6 +1117,9 @@ class TestResultTest(StockTestBase):
def test_duplicate_item_tests(self):
"""Test duplicate item behaviour."""
# Create an example stock item by copying one from the database (because we are lazy)
StockItem.objects.rebuild()
item = StockItem.objects.get(pk=522)
item.pk = None
@ -1103,32 +1127,25 @@ class TestResultTest(StockTestBase):
item.quantity = 50
# Try with an invalid batch code (according to sample validatoin plugin)
item.batch = "X234"
item.batch = 'X234'
with self.assertRaises(ValidationError):
item.save()
item.batch = "B123"
item.batch = 'B123'
item.save()
# Do some tests!
StockItemTestResult.objects.create(
stock_item=item,
test="Firmware",
result=True
stock_item=item, test='Firmware', result=True
)
StockItemTestResult.objects.create(
stock_item=item,
test="Paint Color",
result=True,
value="Red"
stock_item=item, test='Paint Color', result=True, value='Red'
)
StockItemTestResult.objects.create(
stock_item=item,
test="Applied Sticker",
result=False
stock_item=item, test='Applied Sticker', result=False
)
self.assertEqual(item.test_results.count(), 3)
@ -1142,10 +1159,7 @@ class TestResultTest(StockTestBase):
self.assertEqual(item.test_results.count(), 3)
self.assertEqual(item2.test_results.count(), 3)
StockItemTestResult.objects.create(
stock_item=item2,
test='A new test'
)
StockItemTestResult.objects.create(stock_item=item2, test='A new test')
self.assertEqual(item.test_results.count(), 3)
self.assertEqual(item2.test_results.count(), 4)
@ -1154,10 +1168,7 @@ class TestResultTest(StockTestBase):
item2.serializeStock(1, [100], self.user)
# Add a test result to the parent *after* serialization
StockItemTestResult.objects.create(
stock_item=item2,
test='abcde'
)
StockItemTestResult.objects.create(stock_item=item2, test='abcde')
self.assertEqual(item2.test_results.count(), 5)
@ -1182,10 +1193,7 @@ class TestResultTest(StockTestBase):
# Create a stock item which is installed *inside* the master item
sub_item = StockItem.objects.create(
part=item.part,
quantity=1,
belongs_to=item,
location=None
part=item.part, quantity=1, belongs_to=item, location=None
)
# Now, create some test results against the sub item
@ -1195,7 +1203,7 @@ class TestResultTest(StockTestBase):
stock_item=sub_item,
test='firmware version',
date=datetime.datetime.now().date(),
result=True
result=True,
)
# Should return the same number of tests as before