mirror of
https://github.com/inventree/InvenTree.git
synced 2025-08-23 03:45:54 +00:00
removes all lines consisting only of spaces
this really bothers me for some reason - nothing technical
This commit is contained in:
@@ -87,7 +87,7 @@ class StockItemResource(ModelResource):
|
||||
|
||||
# Date management
|
||||
updated = Field(attribute='updated', widget=widgets.DateWidget())
|
||||
|
||||
|
||||
stocktake_date = Field(attribute='stocktake_date', widget=widgets.DateWidget())
|
||||
|
||||
def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
|
||||
@@ -127,7 +127,7 @@ class StockItemAdmin(ImportExportModelAdmin):
|
||||
class StockAttachmentAdmin(admin.ModelAdmin):
|
||||
|
||||
list_display = ('stock_item', 'attachment', 'comment')
|
||||
|
||||
|
||||
|
||||
class StockTrackingAdmin(ImportExportModelAdmin):
|
||||
list_display = ('item', 'date', 'title')
|
||||
|
@@ -117,7 +117,7 @@ class StockAdjust(APIView):
|
||||
A generic class for handling stocktake actions.
|
||||
|
||||
Subclasses exist for:
|
||||
|
||||
|
||||
- StockCount: count stock items
|
||||
- StockAdd: add stock items
|
||||
- StockRemove: remove stock items
|
||||
@@ -184,7 +184,7 @@ class StockCount(StockAdjust):
|
||||
"""
|
||||
Endpoint for counting stock (performing a stocktake).
|
||||
"""
|
||||
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
self.get_items(request)
|
||||
@@ -225,7 +225,7 @@ class StockRemove(StockAdjust):
|
||||
def post(self, request, *args, **kwargs):
|
||||
|
||||
self.get_items(request)
|
||||
|
||||
|
||||
n = 0
|
||||
|
||||
for item in self.items:
|
||||
@@ -292,7 +292,7 @@ class StockLocationList(generics.ListCreateAPIView):
|
||||
params = self.request.query_params
|
||||
|
||||
loc_id = params.get('parent', None)
|
||||
|
||||
|
||||
cascade = str2bool(params.get('cascade', False))
|
||||
|
||||
# Do not filter by location
|
||||
@@ -304,7 +304,7 @@ class StockLocationList(generics.ListCreateAPIView):
|
||||
# If we allow "cascade" at the top-level, this essentially means *all* locations
|
||||
if not cascade:
|
||||
queryset = queryset.filter(parent=None)
|
||||
|
||||
|
||||
else:
|
||||
|
||||
try:
|
||||
@@ -321,7 +321,7 @@ class StockLocationList(generics.ListCreateAPIView):
|
||||
|
||||
except (ValueError, StockLocation.DoesNotExist):
|
||||
pass
|
||||
|
||||
|
||||
return queryset
|
||||
|
||||
filter_backends = [
|
||||
@@ -379,14 +379,14 @@ class StockList(generics.ListCreateAPIView):
|
||||
# A location was *not* specified - try to infer it
|
||||
if 'location' not in request.data:
|
||||
location = item.part.get_default_location()
|
||||
|
||||
|
||||
if location is not None:
|
||||
item.location = location
|
||||
item.save()
|
||||
|
||||
# An expiry date was *not* specified - try to infer it!
|
||||
if 'expiry_date' not in request.data:
|
||||
|
||||
|
||||
if item.part.default_expiry > 0:
|
||||
item.expiry_date = datetime.now().date() + timedelta(days=item.part.default_expiry)
|
||||
item.save()
|
||||
@@ -399,7 +399,7 @@ class StockList(generics.ListCreateAPIView):
|
||||
"""
|
||||
Override the 'list' method, as the StockLocation objects
|
||||
are very expensive to serialize.
|
||||
|
||||
|
||||
So, we fetch and serialize the required StockLocation objects only as required.
|
||||
"""
|
||||
|
||||
@@ -601,7 +601,7 @@ class StockList(generics.ListCreateAPIView):
|
||||
|
||||
if stale_days > 0:
|
||||
stale_date = datetime.now().date() + timedelta(days=stale_days)
|
||||
|
||||
|
||||
stale_filter = StockItem.IN_STOCK_FILTER & ~Q(expiry_date=None) & Q(expiry_date__lt=stale_date)
|
||||
|
||||
if stale:
|
||||
@@ -652,7 +652,7 @@ class StockList(generics.ListCreateAPIView):
|
||||
|
||||
if serial_number_gte is not None:
|
||||
queryset = queryset.filter(serial__gte=serial_number_gte)
|
||||
|
||||
|
||||
if serial_number_lte is not None:
|
||||
queryset = queryset.filter(serial__lte=serial_number_lte)
|
||||
|
||||
@@ -681,7 +681,7 @@ class StockList(generics.ListCreateAPIView):
|
||||
else:
|
||||
# Filter StockItem without build allocations or sales order allocations
|
||||
queryset = queryset.filter(Q(sales_order_allocations__isnull=True) & Q(allocations__isnull=True))
|
||||
|
||||
|
||||
# Do we wish to filter by "active parts"
|
||||
active = params.get('active', None)
|
||||
|
||||
@@ -766,7 +766,7 @@ class StockList(generics.ListCreateAPIView):
|
||||
queryset = queryset.filter(location__in=location.getUniqueChildren())
|
||||
else:
|
||||
queryset = queryset.filter(location=loc_id)
|
||||
|
||||
|
||||
except (ValueError, StockLocation.DoesNotExist):
|
||||
pass
|
||||
|
||||
@@ -994,14 +994,14 @@ class StockTrackingList(generics.ListCreateAPIView):
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
""" Create a new StockItemTracking object
|
||||
|
||||
|
||||
Here we override the default 'create' implementation,
|
||||
to save the user information associated with the request object.
|
||||
"""
|
||||
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
|
||||
# Record the user who created this Part object
|
||||
item = serializer.save()
|
||||
item.user = request.user
|
||||
|
@@ -118,7 +118,7 @@ class CreateStockItemForm(HelperForm):
|
||||
serial_numbers = forms.CharField(label=_('Serial Numbers'), required=False, help_text=_('Enter unique serial numbers (or leave blank)'))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
|
||||
self.field_prefix = {
|
||||
'serial_numbers': 'fa-hashtag',
|
||||
'link': 'fa-link',
|
||||
@@ -147,17 +147,17 @@ class CreateStockItemForm(HelperForm):
|
||||
# Custom clean to prevent complex StockItem.clean() logic from running (yet)
|
||||
def full_clean(self):
|
||||
self._errors = ErrorDict()
|
||||
|
||||
|
||||
if not self.is_bound: # Stop further processing.
|
||||
return
|
||||
|
||||
|
||||
self.cleaned_data = {}
|
||||
|
||||
# If the form is permitted to be empty, and none of the form data has
|
||||
# changed from the initial data, short circuit any validation.
|
||||
if self.empty_permitted and not self.has_changed():
|
||||
return
|
||||
|
||||
|
||||
# Don't run _post_clean() as this will run StockItem.clean()
|
||||
self._clean_fields()
|
||||
self._clean_form()
|
||||
@@ -167,9 +167,9 @@ class SerializeStockForm(HelperForm):
|
||||
""" Form for serializing a StockItem. """
|
||||
|
||||
destination = TreeNodeChoiceField(queryset=StockLocation.objects.all(), label=_('Destination'), required=True, help_text=_('Destination for serialized stock (by default, will remain in current location)'))
|
||||
|
||||
|
||||
serial_numbers = forms.CharField(label=_('Serial numbers'), required=True, help_text=_('Unique serial numbers (must match quantity)'))
|
||||
|
||||
|
||||
note = forms.CharField(label=_('Notes'), required=False, help_text=_('Add transaction note (optional)'))
|
||||
|
||||
quantity = RoundingDecimalFormField(max_digits=10, decimal_places=5, label=_('Quantity'))
|
||||
@@ -240,7 +240,7 @@ class TestReportFormatForm(HelperForm):
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
self.fields['template'].choices = self.get_template_choices()
|
||||
|
||||
|
||||
def get_template_choices(self):
|
||||
"""
|
||||
Generate a list of of TestReport options for the StockItem
|
||||
@@ -337,7 +337,7 @@ class InstallStockForm(HelperForm):
|
||||
raise ValidationError({'quantity_to_install': _('Must not exceed available quantity')})
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
class UninstallStockForm(forms.ModelForm):
|
||||
"""
|
||||
@@ -373,11 +373,11 @@ class AdjustStockForm(forms.ModelForm):
|
||||
"""
|
||||
|
||||
destination = TreeNodeChoiceField(queryset=StockLocation.objects.all(), label=_('Destination'), required=True, help_text=_('Destination stock location'))
|
||||
|
||||
|
||||
note = forms.CharField(label=_('Notes'), required=True, help_text=_('Add note (required)'))
|
||||
|
||||
|
||||
# transaction = forms.BooleanField(required=False, initial=False, label='Create Transaction', help_text='Create a stock transaction for these parts')
|
||||
|
||||
|
||||
confirm = forms.BooleanField(required=False, initial=False, label=_('Confirm stock adjustment'), help_text=_('Confirm movement of stock items'))
|
||||
|
||||
set_loc = forms.BooleanField(required=False, initial=False, label=_('Set Default Location'), help_text=_('Set the destination as the default location for selected parts'))
|
||||
@@ -396,7 +396,7 @@ class AdjustStockForm(forms.ModelForm):
|
||||
class EditStockItemForm(HelperForm):
|
||||
""" Form for editing a StockItem object.
|
||||
Note that not all fields can be edited here (even if they can be specified during creation.
|
||||
|
||||
|
||||
location - Must be updated in a 'move' transaction
|
||||
quantity - Must be updated in a 'stocktake' transaction
|
||||
part - Cannot be edited after creation
|
||||
|
@@ -131,7 +131,7 @@ def before_delete_stock_location(sender, instance, using, **kwargs):
|
||||
class StockItem(MPTTModel):
|
||||
"""
|
||||
A StockItem object represents a quantity of physical instances of a part.
|
||||
|
||||
|
||||
Attributes:
|
||||
parent: Link to another StockItem from which this StockItem was created
|
||||
uid: Field containing a unique-id which is mapped to a third-party identifier (e.g. a barcode)
|
||||
@@ -191,7 +191,7 @@ class StockItem(MPTTModel):
|
||||
add_note = False
|
||||
|
||||
user = kwargs.pop('user', None)
|
||||
|
||||
|
||||
add_note = add_note and kwargs.pop('note', True)
|
||||
|
||||
super(StockItem, self).save(*args, **kwargs)
|
||||
@@ -226,7 +226,7 @@ class StockItem(MPTTModel):
|
||||
"""
|
||||
|
||||
super(StockItem, self).validate_unique(exclude)
|
||||
|
||||
|
||||
# If the serial number is set, make sure it is not a duplicate
|
||||
if self.serial is not None:
|
||||
# Query to look for duplicate serial numbers
|
||||
@@ -421,7 +421,7 @@ class StockItem(MPTTModel):
|
||||
max_length=100, blank=True, null=True,
|
||||
help_text=_('Serial number for this item')
|
||||
)
|
||||
|
||||
|
||||
link = InvenTreeURLField(
|
||||
verbose_name=_('External Link'),
|
||||
max_length=125, blank=True,
|
||||
@@ -727,7 +727,7 @@ class StockItem(MPTTModel):
|
||||
items = StockItem.objects.filter(belongs_to=self)
|
||||
|
||||
for item in items:
|
||||
|
||||
|
||||
# Prevent duplication or recursion
|
||||
if item == self or item in installed:
|
||||
continue
|
||||
@@ -906,7 +906,7 @@ class StockItem(MPTTModel):
|
||||
|
||||
Brief automated note detailing a movement or quantity change.
|
||||
"""
|
||||
|
||||
|
||||
track = StockItemTracking.objects.create(
|
||||
item=self,
|
||||
title=title,
|
||||
@@ -970,7 +970,7 @@ class StockItem(MPTTModel):
|
||||
|
||||
# Create a new stock item for each unique serial number
|
||||
for serial in serials:
|
||||
|
||||
|
||||
# Create a copy of this StockItem
|
||||
new_item = StockItem.objects.get(pk=self.pk)
|
||||
new_item.quantity = 1
|
||||
@@ -1001,7 +1001,7 @@ class StockItem(MPTTModel):
|
||||
""" Copy stock history from another StockItem """
|
||||
|
||||
for item in other.tracking_info.all():
|
||||
|
||||
|
||||
item.item = self
|
||||
item.pk = None
|
||||
item.save()
|
||||
@@ -1151,7 +1151,7 @@ class StockItem(MPTTModel):
|
||||
@transaction.atomic
|
||||
def updateQuantity(self, quantity):
|
||||
""" Update stock quantity for this item.
|
||||
|
||||
|
||||
If the quantity has reached zero, this StockItem will be deleted.
|
||||
|
||||
Returns:
|
||||
@@ -1174,7 +1174,7 @@ class StockItem(MPTTModel):
|
||||
self.quantity = quantity
|
||||
|
||||
if quantity == 0 and self.delete_on_deplete and self.can_delete():
|
||||
|
||||
|
||||
# TODO - Do not actually "delete" stock at this point - instead give it a "DELETED" flag
|
||||
self.delete()
|
||||
return False
|
||||
@@ -1584,7 +1584,7 @@ class StockItemTestResult(models.Model):
|
||||
with automated testing setups.
|
||||
|
||||
Multiple results can be recorded against any given test, allowing tests to be run many times.
|
||||
|
||||
|
||||
Attributes:
|
||||
stock_item: Link to StockItem
|
||||
test: Test name (simple string matching)
|
||||
@@ -1613,7 +1613,7 @@ class StockItemTestResult(models.Model):
|
||||
|
||||
for template in templates:
|
||||
if key == template.key:
|
||||
|
||||
|
||||
if template.requires_value:
|
||||
if not self.value:
|
||||
raise ValidationError({
|
||||
|
@@ -140,7 +140,7 @@ class StockItemSerializer(InvenTreeModelSerializer):
|
||||
return queryset
|
||||
|
||||
status_text = serializers.CharField(source='get_status_display', read_only=True)
|
||||
|
||||
|
||||
supplier_part_detail = SupplierPartSerializer(source='supplier_part', many=False, read_only=True)
|
||||
|
||||
part_detail = PartBriefSerializer(source='part', many=False, read_only=True)
|
||||
@@ -150,7 +150,7 @@ class StockItemSerializer(InvenTreeModelSerializer):
|
||||
tracking_items = serializers.IntegerField(source='tracking_info_count', read_only=True, required=False)
|
||||
|
||||
quantity = serializers.FloatField()
|
||||
|
||||
|
||||
allocated = serializers.FloatField(source='allocation_count', required=False)
|
||||
|
||||
expired = serializers.BooleanField(required=False, read_only=True)
|
||||
|
@@ -38,7 +38,7 @@ class StockAPITestCase(InvenTreeAPITestCase):
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
|
||||
|
||||
super().setUp()
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ class StockItemListTest(StockAPITestCase):
|
||||
"""
|
||||
|
||||
response = self.get_stock(part=25)
|
||||
|
||||
|
||||
self.assertEqual(len(response), 8)
|
||||
|
||||
response = self.get_stock(part=10004)
|
||||
@@ -339,7 +339,7 @@ class StockItemTest(StockAPITestCase):
|
||||
)
|
||||
|
||||
self.assertContains(response, 'This field is required', status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
# POST with an invalid part reference
|
||||
|
||||
response = self.client.post(
|
||||
@@ -384,10 +384,10 @@ class StockItemTest(StockAPITestCase):
|
||||
- Otherwise, check if the referenced part has a default_expiry defined
|
||||
- If so, use that!
|
||||
- Otherwise, no expiry
|
||||
|
||||
|
||||
Notes:
|
||||
- Part <25> has a default_expiry of 10 days
|
||||
|
||||
|
||||
"""
|
||||
|
||||
# First test - create a new StockItem without an expiry date
|
||||
@@ -460,7 +460,7 @@ class StocktakeTest(StockAPITestCase):
|
||||
data['items'] = [{
|
||||
'pk': 10
|
||||
}]
|
||||
|
||||
|
||||
response = self.post(url, data)
|
||||
self.assertContains(response, 'must contain a valid pk', status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@@ -478,12 +478,12 @@ class StocktakeTest(StockAPITestCase):
|
||||
|
||||
response = self.post(url, data)
|
||||
self.assertContains(response, 'must contain a valid quantity', status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
data['items'] = [{
|
||||
'pk': 1234,
|
||||
'quantity': "-1.234"
|
||||
}]
|
||||
|
||||
|
||||
response = self.post(url, data)
|
||||
self.assertContains(response, 'must not be less than zero', status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
@@ -29,7 +29,7 @@ class StockViewTestCase(TestCase):
|
||||
|
||||
# Create a user
|
||||
user = get_user_model()
|
||||
|
||||
|
||||
self.user = user.objects.create_user(
|
||||
username='username',
|
||||
email='user@email.com',
|
||||
@@ -91,7 +91,7 @@ class StockLocationTest(StockViewTestCase):
|
||||
# Create with an invalid parent
|
||||
response = self.client.get(reverse('stock-location-create'), {'location': 999}, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
|
||||
class StockItemTest(StockViewTestCase):
|
||||
"""" Tests for StockItem views """
|
||||
@@ -211,7 +211,7 @@ class StockItemTest(StockViewTestCase):
|
||||
'serial_numbers': 'dd-23-adf',
|
||||
'destination': 'blorg'
|
||||
}
|
||||
|
||||
|
||||
# POST
|
||||
response = self.client.post(url, data_valid, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -247,7 +247,7 @@ class StockOwnershipTest(StockViewTestCase):
|
||||
|
||||
# Create a new user
|
||||
user = get_user_model()
|
||||
|
||||
|
||||
self.new_user = user.objects.create_user(
|
||||
username='john',
|
||||
email='john@email.com',
|
||||
@@ -314,7 +314,7 @@ class StockOwnershipTest(StockViewTestCase):
|
||||
response = self.client.post(reverse('stock-location-edit', args=(test_location_id,)),
|
||||
{'name': 'Office', 'owner': new_user_group_owner.pk},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
|
||||
|
||||
# Make sure the location's owner is unchanged
|
||||
location = StockLocation.objects.get(pk=test_location_id)
|
||||
self.assertEqual(location.owner, user_group_owner)
|
||||
@@ -366,7 +366,7 @@ class StockOwnershipTest(StockViewTestCase):
|
||||
response = self.client.post(reverse('stock-location-create'),
|
||||
new_location, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
self.assertContains(response, '"form_valid": true', status_code=200)
|
||||
|
||||
|
||||
# Retrieve created location
|
||||
location_created = StockLocation.objects.get(name=new_location['name'])
|
||||
|
||||
|
@@ -144,7 +144,7 @@ class StockTest(TestCase):
|
||||
self.drawer3.save()
|
||||
|
||||
self.assertNotEqual(self.drawer3.parent, self.office)
|
||||
|
||||
|
||||
self.assertEqual(self.drawer3.pathstring, 'Home/Drawer_3')
|
||||
|
||||
def test_children(self):
|
||||
@@ -486,7 +486,7 @@ class VariantTest(StockTest):
|
||||
# Attempt to create the same serial number but for a variant (should fail!)
|
||||
item.pk = None
|
||||
item.part = Part.objects.get(pk=10004)
|
||||
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
item.save()
|
||||
|
||||
@@ -542,7 +542,7 @@ class TestResultTest(StockTest):
|
||||
test='sew cushion',
|
||||
result=True
|
||||
)
|
||||
|
||||
|
||||
# Still should be failing at this point,
|
||||
# as the most recent "apply paint" test was False
|
||||
self.assertFalse(item.passedAllRequiredTests())
|
||||
|
@@ -14,7 +14,7 @@ location_urls = [
|
||||
url(r'^edit/?', views.StockLocationEdit.as_view(), name='stock-location-edit'),
|
||||
url(r'^delete/?', views.StockLocationDelete.as_view(), name='stock-location-delete'),
|
||||
url(r'^qr_code/?', views.StockLocationQRCode.as_view(), name='stock-location-qr'),
|
||||
|
||||
|
||||
url(r'sublocation/', views.StockLocationDetail.as_view(template_name='stock/sublocation.html'), name='stock-location-sublocation'),
|
||||
|
||||
# Anything else
|
||||
|
@@ -121,7 +121,7 @@ class StockLocationEdit(AjaxUpdateView):
|
||||
context_object_name = 'location'
|
||||
ajax_template_name = 'modal_form.html'
|
||||
ajax_form_title = _('Edit Stock Location')
|
||||
|
||||
|
||||
def get_form(self):
|
||||
""" Customize form data for StockLocation editing.
|
||||
|
||||
@@ -182,7 +182,7 @@ class StockLocationEdit(AjaxUpdateView):
|
||||
"""
|
||||
|
||||
self.object = form.save()
|
||||
|
||||
|
||||
# Is ownership control enabled?
|
||||
stock_ownership_control = InvenTreeSetting.get_setting('STOCK_OWNERSHIP_CONTROL')
|
||||
|
||||
@@ -267,7 +267,7 @@ class StockItemAttachmentCreate(AjaxCreateView):
|
||||
|
||||
def save(self, form, **kwargs):
|
||||
""" Record the user that uploaded the attachment """
|
||||
|
||||
|
||||
attachment = form.save(commit=False)
|
||||
attachment.user = self.request.user
|
||||
attachment.save()
|
||||
@@ -297,7 +297,7 @@ class StockItemAttachmentCreate(AjaxCreateView):
|
||||
|
||||
form = super().get_form()
|
||||
form.fields['stock_item'].widget = HiddenInput()
|
||||
|
||||
|
||||
return form
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ class StockItemAttachmentEdit(AjaxUpdateView):
|
||||
model = StockItemAttachment
|
||||
form_class = StockForms.EditStockItemAttachmentForm
|
||||
ajax_form_title = _("Edit Stock Item Attachment")
|
||||
|
||||
|
||||
def get_form(self):
|
||||
|
||||
form = super().get_form()
|
||||
@@ -327,7 +327,7 @@ class StockItemAttachmentDelete(AjaxDeleteView):
|
||||
ajax_form_title = _("Delete Stock Item Attachment")
|
||||
ajax_template_name = "attachment_delete.html"
|
||||
context_object_name = "attachment"
|
||||
|
||||
|
||||
def get_data(self):
|
||||
return {
|
||||
'danger': _("Deleted attachment"),
|
||||
@@ -376,7 +376,7 @@ class StockItemReturnToStock(AjaxUpdateView):
|
||||
ajax_form_title = _("Return to Stock")
|
||||
context_object_name = "item"
|
||||
form_class = StockForms.ReturnStockItemForm
|
||||
|
||||
|
||||
def validate(self, item, form, **kwargs):
|
||||
|
||||
location = form.cleaned_data.get('location', None)
|
||||
@@ -405,7 +405,7 @@ class StockItemDeleteTestData(AjaxUpdateView):
|
||||
model = StockItem
|
||||
form_class = ConfirmForm
|
||||
ajax_form_title = _("Delete All Test Data")
|
||||
|
||||
|
||||
role_required = ['stock.change', 'stock.delete']
|
||||
|
||||
def get_form(self):
|
||||
@@ -417,7 +417,7 @@ class StockItemDeleteTestData(AjaxUpdateView):
|
||||
|
||||
stock_item = StockItem.objects.get(pk=self.kwargs['pk'])
|
||||
form = self.get_form()
|
||||
|
||||
|
||||
confirm = str2bool(request.POST.get('confirm', False))
|
||||
|
||||
if confirm is not True:
|
||||
@@ -488,7 +488,7 @@ class StockItemTestResultEdit(AjaxUpdateView):
|
||||
form = super().get_form()
|
||||
|
||||
form.fields['stock_item'].widget = HiddenInput()
|
||||
|
||||
|
||||
return form
|
||||
|
||||
|
||||
@@ -545,11 +545,11 @@ class StockExport(AjaxView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
export_format = request.GET.get('format', 'csv').lower()
|
||||
|
||||
|
||||
# Check if a particular location was specified
|
||||
loc_id = request.GET.get('location', None)
|
||||
location = None
|
||||
|
||||
|
||||
if loc_id:
|
||||
try:
|
||||
location = StockLocation.objects.get(pk=loc_id)
|
||||
@@ -646,9 +646,9 @@ class StockItemInstall(AjaxUpdateView):
|
||||
|
||||
In contrast to the StockItemUninstall view,
|
||||
only a single stock item can be installed at once.
|
||||
|
||||
|
||||
The "part" to be installed must be provided in the GET query parameters.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
model = StockItem
|
||||
@@ -664,7 +664,7 @@ class StockItemInstall(AjaxUpdateView):
|
||||
|
||||
Requirements:
|
||||
- Items must be in stock
|
||||
|
||||
|
||||
Filters:
|
||||
- Items can be filtered by Part reference
|
||||
"""
|
||||
@@ -702,7 +702,7 @@ class StockItemInstall(AjaxUpdateView):
|
||||
|
||||
if self.part:
|
||||
initials['part'] = self.part
|
||||
|
||||
|
||||
return initials
|
||||
|
||||
def get_form(self):
|
||||
@@ -875,13 +875,13 @@ class StockItemUninstall(AjaxView, FormMixin):
|
||||
|
||||
class StockAdjust(AjaxView, FormMixin):
|
||||
""" View for enacting simple stock adjustments:
|
||||
|
||||
|
||||
- Take items from stock
|
||||
- Add items to stock
|
||||
- Count items
|
||||
- Move stock
|
||||
- Delete stock items
|
||||
|
||||
|
||||
"""
|
||||
|
||||
ajax_template_name = 'stock/stock_adjust.html'
|
||||
@@ -942,7 +942,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
|
||||
for item in self.request.POST:
|
||||
if item.startswith('stock-id-'):
|
||||
|
||||
|
||||
pk = item.replace('stock-id-', '')
|
||||
q = self.request.POST[item]
|
||||
|
||||
@@ -1022,9 +1022,9 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
form = self.get_form()
|
||||
|
||||
valid = form.is_valid()
|
||||
|
||||
|
||||
for item in self.stock_items:
|
||||
|
||||
|
||||
try:
|
||||
item.new_quantity = Decimal(item.new_quantity)
|
||||
except ValueError:
|
||||
@@ -1067,7 +1067,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
|
||||
# Was the entire stock taken?
|
||||
item = self.stock_items[0]
|
||||
|
||||
|
||||
if item.quantity == 0:
|
||||
# Instruct the form to redirect
|
||||
data['url'] = reverse('stock-index')
|
||||
@@ -1107,7 +1107,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
return _('No action performed')
|
||||
|
||||
def do_add(self):
|
||||
|
||||
|
||||
count = 0
|
||||
note = self.request.POST['note']
|
||||
|
||||
@@ -1137,12 +1137,12 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
return _('Removed stock from {n} items').format(n=count)
|
||||
|
||||
def do_count(self):
|
||||
|
||||
|
||||
count = 0
|
||||
note = self.request.POST['note']
|
||||
|
||||
for item in self.stock_items:
|
||||
|
||||
|
||||
item.stocktake(item.new_quantity, self.request.user, notes=note)
|
||||
|
||||
count += 1
|
||||
@@ -1165,7 +1165,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
if set_loc:
|
||||
item.part.default_location = destination
|
||||
item.part.save()
|
||||
|
||||
|
||||
# Do not move to the same location (unless the quantity is different)
|
||||
if destination == item.location and item.new_quantity == item.quantity:
|
||||
continue
|
||||
@@ -1188,7 +1188,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
|
||||
if count == 0:
|
||||
return _('No items were moved')
|
||||
|
||||
|
||||
else:
|
||||
return _('Moved {n} items to {dest}').format(
|
||||
n=count,
|
||||
@@ -1201,7 +1201,7 @@ class StockAdjust(AjaxView, FormMixin):
|
||||
# note = self.request.POST['note']
|
||||
|
||||
for item in self.stock_items:
|
||||
|
||||
|
||||
# TODO - In the future, StockItems should not be 'deleted'
|
||||
# TODO - Instead, they should be marked as "inactive"
|
||||
|
||||
@@ -1475,7 +1475,7 @@ class StockItemSerialize(AjaxUpdateView):
|
||||
return initials
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
||||
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
@@ -1503,13 +1503,13 @@ class StockItemSerialize(AjaxUpdateView):
|
||||
form.add_error('serial_numbers', e.messages)
|
||||
valid = False
|
||||
numbers = []
|
||||
|
||||
|
||||
if valid:
|
||||
try:
|
||||
item.serializeStock(quantity, numbers, user, notes=notes, location=destination)
|
||||
except ValidationError as e:
|
||||
messages = e.message_dict
|
||||
|
||||
|
||||
for k in messages.keys():
|
||||
if k in ['quantity', 'destination', 'serial_numbers']:
|
||||
form.add_error(k, messages[k])
|
||||
@@ -1595,7 +1595,7 @@ class StockItemCreate(AjaxCreateView):
|
||||
|
||||
if not part.purchaseable:
|
||||
form.fields.pop('purchase_price')
|
||||
|
||||
|
||||
# Hide the 'part' field (as a valid part is selected)
|
||||
# form.fields['part'].widget = HiddenInput()
|
||||
|
||||
@@ -1658,7 +1658,7 @@ class StockItemCreate(AjaxCreateView):
|
||||
if type(location_owner.owner) is Group:
|
||||
user_as_owner = Owner.get_owner(self.request.user)
|
||||
queryset = location_owner.get_related_owners()
|
||||
|
||||
|
||||
if user_as_owner in queryset:
|
||||
form.fields['owner'].initial = user_as_owner
|
||||
|
||||
@@ -1668,7 +1668,7 @@ class StockItemCreate(AjaxCreateView):
|
||||
# If location's owner is a user: automatically set owner field and disable it
|
||||
form.fields['owner'].disabled = True
|
||||
form.fields['owner'].initial = location_owner
|
||||
|
||||
|
||||
return form
|
||||
|
||||
def get_initial(self):
|
||||
@@ -1746,7 +1746,7 @@ class StockItemCreate(AjaxCreateView):
|
||||
data = form.cleaned_data
|
||||
|
||||
part = data.get('part', None)
|
||||
|
||||
|
||||
quantity = data.get('quantity', None)
|
||||
|
||||
owner = data.get('owner', None)
|
||||
@@ -1831,7 +1831,7 @@ class StockItemCreate(AjaxCreateView):
|
||||
)
|
||||
|
||||
item.save(user=self.request.user)
|
||||
|
||||
|
||||
# Create a single StockItem of the specified quantity
|
||||
else:
|
||||
form._post_clean()
|
||||
@@ -1841,12 +1841,12 @@ class StockItemCreate(AjaxCreateView):
|
||||
item.save(user=self.request.user)
|
||||
|
||||
return item
|
||||
|
||||
|
||||
# Non-trackable part
|
||||
else:
|
||||
|
||||
form._post_clean()
|
||||
|
||||
|
||||
item = form.save(commit=False)
|
||||
item.user = self.request.user
|
||||
item.save(user=self.request.user)
|
||||
|
Reference in New Issue
Block a user