mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Documentation for Part app
This commit is contained in:
parent
5e6d49102d
commit
ed3ae30248
@ -18,8 +18,6 @@ from .serializers import BuildSerializer
|
|||||||
class BuildList(generics.ListCreateAPIView):
|
class BuildList(generics.ListCreateAPIView):
|
||||||
""" API endpoint for accessing a list of Build objects.
|
""" API endpoint for accessing a list of Build objects.
|
||||||
|
|
||||||
Provides two methods:
|
|
||||||
|
|
||||||
- GET: Return list of objects (with filters)
|
- GET: Return list of objects (with filters)
|
||||||
- POST: Create a new Build object
|
- POST: Create a new Build object
|
||||||
"""
|
"""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Provides JSON serializers for Build API
|
JSON serializers for Build API
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Provides Django views for interacting with Build objects
|
Django views for interacting with Build objects
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
|
"""
|
||||||
|
JSON serializers for Company app
|
||||||
|
"""
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .models import Company
|
from .models import Company
|
||||||
|
|
||||||
|
|
||||||
class CompanyBriefSerializer(serializers.ModelSerializer):
|
class CompanyBriefSerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for Company object (limited detail) """
|
||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
@ -17,6 +22,7 @@ class CompanyBriefSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class CompanySerializer(serializers.ModelSerializer):
|
class CompanySerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for Company object (full detail) """
|
||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
"""
|
||||||
|
Django views for interacting with Company app
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -12,12 +17,20 @@ from .forms import CompanyImageForm
|
|||||||
|
|
||||||
|
|
||||||
class CompanyIndex(ListView):
|
class CompanyIndex(ListView):
|
||||||
|
""" View for displaying list of companies
|
||||||
|
"""
|
||||||
|
|
||||||
model = Company
|
model = Company
|
||||||
template_name = 'company/index.html'
|
template_name = 'company/index.html'
|
||||||
context_object_name = 'companies'
|
context_object_name = 'companies'
|
||||||
paginate_by = 50
|
paginate_by = 50
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
""" Retrieve the Company queryset based on HTTP request parameters.
|
||||||
|
|
||||||
|
- supplier: Filter by supplier
|
||||||
|
- customer: Filter by customer
|
||||||
|
"""
|
||||||
queryset = Company.objects.all().order_by('name')
|
queryset = Company.objects.all().order_by('name')
|
||||||
|
|
||||||
if self.request.GET.get('supplier', None):
|
if self.request.GET.get('supplier', None):
|
||||||
@ -30,6 +43,7 @@ class CompanyIndex(ListView):
|
|||||||
|
|
||||||
|
|
||||||
class CompanyDetail(DetailView):
|
class CompanyDetail(DetailView):
|
||||||
|
""" Detail view for Company object """
|
||||||
context_obect_name = 'company'
|
context_obect_name = 'company'
|
||||||
template_name = 'company/detail.html'
|
template_name = 'company/detail.html'
|
||||||
queryset = Company.objects.all()
|
queryset = Company.objects.all()
|
||||||
@ -37,6 +51,7 @@ class CompanyDetail(DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class CompanyImage(AjaxUpdateView):
|
class CompanyImage(AjaxUpdateView):
|
||||||
|
""" View for uploading an image for the Company """
|
||||||
model = Company
|
model = Company
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Update Company Image'
|
ajax_form_title = 'Update Company Image'
|
||||||
@ -49,6 +64,7 @@ class CompanyImage(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class CompanyEdit(AjaxUpdateView):
|
class CompanyEdit(AjaxUpdateView):
|
||||||
|
""" View for editing a Company object """
|
||||||
model = Company
|
model = Company
|
||||||
form_class = EditCompanyForm
|
form_class = EditCompanyForm
|
||||||
context_object_name = 'company'
|
context_object_name = 'company'
|
||||||
@ -62,6 +78,7 @@ class CompanyEdit(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class CompanyCreate(AjaxCreateView):
|
class CompanyCreate(AjaxCreateView):
|
||||||
|
""" View for creating a new Company object """
|
||||||
model = Company
|
model = Company
|
||||||
context_object_name = 'company'
|
context_object_name = 'company'
|
||||||
form_class = EditCompanyForm
|
form_class = EditCompanyForm
|
||||||
@ -75,6 +92,7 @@ class CompanyCreate(AjaxCreateView):
|
|||||||
|
|
||||||
|
|
||||||
class CompanyDelete(AjaxDeleteView):
|
class CompanyDelete(AjaxDeleteView):
|
||||||
|
""" View for deleting a Company object """
|
||||||
model = Company
|
model = Company
|
||||||
success_url = '/company/'
|
success_url = '/company/'
|
||||||
ajax_template_name = 'company/delete.html'
|
ajax_template_name = 'company/delete.html'
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Provides a JSON API for the Part app
|
||||||
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -26,6 +30,12 @@ class PartCategoryTree(TreeSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryList(generics.ListCreateAPIView):
|
class CategoryList(generics.ListCreateAPIView):
|
||||||
|
""" API endpoint for accessing a list of PartCategory objects.
|
||||||
|
|
||||||
|
- GET: Return a list of PartCategory objects
|
||||||
|
- POST: Create a new PartCategory object
|
||||||
|
"""
|
||||||
|
|
||||||
queryset = PartCategory.objects.all()
|
queryset = PartCategory.objects.all()
|
||||||
serializer_class = CategorySerializer
|
serializer_class = CategorySerializer
|
||||||
|
|
||||||
@ -56,11 +66,13 @@ class CategoryList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
class CategoryDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
""" API endpoint for detail view of a single PartCategory object """
|
||||||
serializer_class = CategorySerializer
|
serializer_class = CategorySerializer
|
||||||
queryset = PartCategory.objects.all()
|
queryset = PartCategory.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class PartDetail(generics.RetrieveUpdateDestroyAPIView):
|
class PartDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
""" API endpoint for detail view of a single Part object """
|
||||||
queryset = Part.objects.all()
|
queryset = Part.objects.all()
|
||||||
serializer_class = PartSerializer
|
serializer_class = PartSerializer
|
||||||
|
|
||||||
@ -70,6 +82,11 @@ class PartDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class PartList(generics.ListCreateAPIView):
|
class PartList(generics.ListCreateAPIView):
|
||||||
|
""" API endpoint for accessing a list of Part objects
|
||||||
|
|
||||||
|
- GET: Return list of objects
|
||||||
|
- POST: Create a new Part object
|
||||||
|
"""
|
||||||
|
|
||||||
serializer_class = PartSerializer
|
serializer_class = PartSerializer
|
||||||
|
|
||||||
@ -130,6 +147,11 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class BomList(generics.ListCreateAPIView):
|
class BomList(generics.ListCreateAPIView):
|
||||||
|
""" API endpoing for accessing a list of BomItem objects
|
||||||
|
|
||||||
|
- GET: Return list of BomItem objects
|
||||||
|
- POST: Create a new BomItem object
|
||||||
|
"""
|
||||||
|
|
||||||
queryset = BomItem.objects.all()
|
queryset = BomItem.objects.all()
|
||||||
serializer_class = BomItemSerializer
|
serializer_class = BomItemSerializer
|
||||||
@ -151,6 +173,7 @@ class BomList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class BomDetail(generics.RetrieveUpdateDestroyAPIView):
|
class BomDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
""" API endpoint for detail view of a single BomItem object """
|
||||||
|
|
||||||
queryset = BomItem.objects.all()
|
queryset = BomItem.objects.all()
|
||||||
serializer_class = BomItemSerializer
|
serializer_class = BomItemSerializer
|
||||||
@ -161,6 +184,11 @@ class BomDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartList(generics.ListCreateAPIView):
|
class SupplierPartList(generics.ListCreateAPIView):
|
||||||
|
""" API endpoint for list view of SupplierPart object
|
||||||
|
|
||||||
|
- GET: Return list of SupplierPart objects
|
||||||
|
- POST: Create a new SupplierPart object
|
||||||
|
"""
|
||||||
|
|
||||||
queryset = SupplierPart.objects.all()
|
queryset = SupplierPart.objects.all()
|
||||||
serializer_class = SupplierPartSerializer
|
serializer_class = SupplierPartSerializer
|
||||||
@ -182,6 +210,12 @@ class SupplierPartList(generics.ListCreateAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartDetail(generics.RetrieveUpdateDestroyAPIView):
|
class SupplierPartDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
""" API endpoint for detail view of SupplierPart object
|
||||||
|
|
||||||
|
- GET: Retrieve detail view
|
||||||
|
- PATCH: Update object
|
||||||
|
- DELETE: Delete objec
|
||||||
|
"""
|
||||||
|
|
||||||
queryset = SupplierPart.objects.all()
|
queryset = SupplierPart.objects.all()
|
||||||
serializer_class = SupplierPartSerializer
|
serializer_class = SupplierPartSerializer
|
||||||
@ -192,6 +226,11 @@ class SupplierPartDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPriceBreakList(generics.ListCreateAPIView):
|
class SupplierPriceBreakList(generics.ListCreateAPIView):
|
||||||
|
""" API endpoint for list view of SupplierPriceBreak object
|
||||||
|
|
||||||
|
- GET: Retrieve list of SupplierPriceBreak objects
|
||||||
|
- POST: Create a new SupplierPriceBreak object
|
||||||
|
"""
|
||||||
|
|
||||||
queryset = SupplierPriceBreak.objects.all()
|
queryset = SupplierPriceBreak.objects.all()
|
||||||
serializer_class = SupplierPriceBreakSerializer
|
serializer_class = SupplierPriceBreakSerializer
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Django Forms for interacting with Part objects
|
||||||
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -10,6 +14,7 @@ from .models import SupplierPart
|
|||||||
|
|
||||||
|
|
||||||
class PartImageForm(HelperForm):
|
class PartImageForm(HelperForm):
|
||||||
|
""" Form for uploading a Part image """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Part
|
model = Part
|
||||||
@ -40,6 +45,7 @@ class BomExportForm(HelperForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditPartForm(HelperForm):
|
class EditPartForm(HelperForm):
|
||||||
|
""" Form for editing a Part object """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Part
|
model = Part
|
||||||
@ -64,6 +70,7 @@ class EditPartForm(HelperForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditCategoryForm(HelperForm):
|
class EditCategoryForm(HelperForm):
|
||||||
|
""" Form for editing a PartCategory object """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
@ -75,6 +82,7 @@ class EditCategoryForm(HelperForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditBomItemForm(HelperForm):
|
class EditBomItemForm(HelperForm):
|
||||||
|
""" Form for editing a BomItem object """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = BomItem
|
model = BomItem
|
||||||
@ -88,6 +96,7 @@ class EditBomItemForm(HelperForm):
|
|||||||
|
|
||||||
|
|
||||||
class EditSupplierPartForm(HelperForm):
|
class EditSupplierPartForm(HelperForm):
|
||||||
|
""" Form for editing a SupplierPart object """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Part database model definitions
|
||||||
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -47,11 +51,19 @@ class PartCategory(InvenTreeTree):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def has_parts(self):
|
def has_parts(self):
|
||||||
|
""" True if there are any parts in this category """
|
||||||
return self.parts.count() > 0
|
return self.parts.count() > 0
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_delete, sender=PartCategory, dispatch_uid='partcategory_delete_log')
|
@receiver(pre_delete, sender=PartCategory, dispatch_uid='partcategory_delete_log')
|
||||||
def before_delete_part_category(sender, instance, using, **kwargs):
|
def before_delete_part_category(sender, instance, using, **kwargs):
|
||||||
|
""" Receives before_delete signal for PartCategory object
|
||||||
|
|
||||||
|
Before deleting, update child Part and PartCategory objects:
|
||||||
|
|
||||||
|
- For each child category, set the parent to the parent of *this* category
|
||||||
|
- For each part, set the 'category' to the parent of *this* category
|
||||||
|
"""
|
||||||
|
|
||||||
# Update each part in this category to point to the parent category
|
# Update each part in this category to point to the parent category
|
||||||
for part in instance.parts.all():
|
for part in instance.parts.all():
|
||||||
@ -67,6 +79,16 @@ def before_delete_part_category(sender, instance, using, **kwargs):
|
|||||||
# Function to automatically rename a part image on upload
|
# Function to automatically rename a part image on upload
|
||||||
# Format: part_pk.<img>
|
# Format: part_pk.<img>
|
||||||
def rename_part_image(instance, filename):
|
def rename_part_image(instance, filename):
|
||||||
|
""" Function for renaming a part image file
|
||||||
|
|
||||||
|
Args:
|
||||||
|
instance: Instance of a Part object
|
||||||
|
filename: Name of original uploaded file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Cleaned filename in format part_<n>_img
|
||||||
|
"""
|
||||||
|
|
||||||
base = 'part_images'
|
base = 'part_images'
|
||||||
|
|
||||||
if filename.count('.') > 0:
|
if filename.count('.') > 0:
|
||||||
@ -248,7 +270,8 @@ class Part(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def allocation_count(self):
|
def allocation_count(self):
|
||||||
""" Return true if any of this part is allocated
|
""" Return true if any of this part is allocated:
|
||||||
|
|
||||||
- To another build
|
- To another build
|
||||||
- To a customer order
|
- To a customer order
|
||||||
"""
|
"""
|
||||||
@ -311,6 +334,15 @@ class Part(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
def attach_file(instance, filename):
|
def attach_file(instance, filename):
|
||||||
|
""" Function for storing a file for a PartAttachment
|
||||||
|
|
||||||
|
Args:
|
||||||
|
instance: Instance of a PartAttachment object
|
||||||
|
filename: name of uploaded file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
path to store file, format: 'part_file_<pk>_filename'
|
||||||
|
"""
|
||||||
# Construct a path to store a file attachment
|
# Construct a path to store a file attachment
|
||||||
return os.path.join('part_files', str(instance.part.id), filename)
|
return os.path.join('part_files', str(instance.part.id), filename)
|
||||||
|
|
||||||
@ -356,6 +388,13 @@ class BomItem(models.Model):
|
|||||||
note = models.CharField(max_length=100, blank=True, help_text='Item notes')
|
note = models.CharField(max_length=100, blank=True, help_text='Item notes')
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
""" Check validity of the BomItem model.
|
||||||
|
|
||||||
|
Performs model checks beyond simple field validation.
|
||||||
|
|
||||||
|
- A part cannot refer to itself in its BOM
|
||||||
|
- A part cannot refer to a part which refers to it
|
||||||
|
"""
|
||||||
|
|
||||||
# A part cannot refer to itself in its BOM
|
# A part cannot refer to itself in its BOM
|
||||||
if self.part == self.sub_part:
|
if self.part == self.sub_part:
|
||||||
@ -382,8 +421,9 @@ class BomItem(models.Model):
|
|||||||
class SupplierPart(models.Model):
|
class SupplierPart(models.Model):
|
||||||
""" Represents a unique part as provided by a Supplier
|
""" Represents a unique part as provided by a Supplier
|
||||||
Each SupplierPart is identified by a MPN (Manufacturer Part Number)
|
Each SupplierPart is identified by a MPN (Manufacturer Part Number)
|
||||||
Each SupplierPart is also linked to a Part object
|
Each SupplierPart is also linked to a Part object.
|
||||||
- A Part may be available from multiple suppliers
|
|
||||||
|
A Part may be available from multiple suppliers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
@ -453,6 +493,7 @@ class SupplierPart(models.Model):
|
|||||||
|
|
||||||
def get_price(self, quantity, moq=True, multiples=True):
|
def get_price(self, quantity, moq=True, multiples=True):
|
||||||
""" Calculate the supplier price based on quantity price breaks.
|
""" Calculate the supplier price based on quantity price breaks.
|
||||||
|
|
||||||
- If no price breaks available, use the single_price field
|
- If no price breaks available, use the single_price field
|
||||||
- Don't forget to add in flat-fee cost (base_cost field)
|
- Don't forget to add in flat-fee cost (base_cost field)
|
||||||
- If MOQ (minimum order quantity) is required, bump quantity
|
- If MOQ (minimum order quantity) is required, bump quantity
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
JSON serializers for Part app
|
||||||
|
"""
|
||||||
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from .models import Part, PartCategory, BomItem
|
from .models import Part, PartCategory, BomItem
|
||||||
@ -7,6 +11,7 @@ from InvenTree.serializers import InvenTreeModelSerializer
|
|||||||
|
|
||||||
|
|
||||||
class CategorySerializer(serializers.ModelSerializer):
|
class CategorySerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for PartCategory """
|
||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
@ -23,6 +28,7 @@ class CategorySerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class PartBriefSerializer(serializers.ModelSerializer):
|
class PartBriefSerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for Part (brief detail) """
|
||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
@ -68,6 +74,7 @@ class PartSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class BomItemSerializer(InvenTreeModelSerializer):
|
class BomItemSerializer(InvenTreeModelSerializer):
|
||||||
|
""" Serializer for BomItem object """
|
||||||
|
|
||||||
# url = serializers.CharField(source='get_absolute_url', read_only=True)
|
# url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
@ -89,6 +96,7 @@ class BomItemSerializer(InvenTreeModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartSerializer(serializers.ModelSerializer):
|
class SupplierPartSerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for SupplierPart object """
|
||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
@ -112,6 +120,7 @@ class SupplierPartSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPriceBreakSerializer(serializers.ModelSerializer):
|
class SupplierPriceBreakSerializer(serializers.ModelSerializer):
|
||||||
|
""" Serializer for SupplierPriceBreak object """
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SupplierPriceBreak
|
model = SupplierPriceBreak
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
URL lookup for Part app
|
||||||
|
"""
|
||||||
|
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Django views for interacting with Part app
|
||||||
|
"""
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
@ -21,10 +25,12 @@ from .forms import EditSupplierPartForm
|
|||||||
|
|
||||||
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
|
||||||
|
|
||||||
from InvenTree.helpers import DownloadFile
|
from InvenTree.helpers import DownloadFile, str2bool
|
||||||
|
|
||||||
|
|
||||||
class PartIndex(ListView):
|
class PartIndex(ListView):
|
||||||
|
""" View for displaying list of Part objects
|
||||||
|
"""
|
||||||
model = Part
|
model = Part
|
||||||
template_name = 'part/category.html'
|
template_name = 'part/category.html'
|
||||||
context_object_name = 'parts'
|
context_object_name = 'parts'
|
||||||
@ -45,8 +51,12 @@ class PartIndex(ListView):
|
|||||||
|
|
||||||
|
|
||||||
class PartCreate(AjaxCreateView):
|
class PartCreate(AjaxCreateView):
|
||||||
""" Create a new part
|
""" View for creating a new Part object.
|
||||||
- Optionally provide a category object as initial data
|
|
||||||
|
Options for providing initial conditions:
|
||||||
|
|
||||||
|
- Provide a category object as initial data
|
||||||
|
- Copy an existing Part
|
||||||
"""
|
"""
|
||||||
model = Part
|
model = Part
|
||||||
form_class = EditPartForm
|
form_class = EditPartForm
|
||||||
@ -64,6 +74,10 @@ class PartCreate(AjaxCreateView):
|
|||||||
|
|
||||||
# If a category is provided in the URL, pass that to the page context
|
# If a category is provided in the URL, pass that to the page context
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
""" Provide extra context information for the form to display:
|
||||||
|
|
||||||
|
- Add category information (if provided)
|
||||||
|
"""
|
||||||
context = super(PartCreate, self).get_context_data(**kwargs)
|
context = super(PartCreate, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
# Add category information to the page
|
# Add category information to the page
|
||||||
@ -76,6 +90,11 @@ class PartCreate(AjaxCreateView):
|
|||||||
|
|
||||||
# Pre-fill the category field if a valid category is provided
|
# Pre-fill the category field if a valid category is provided
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
""" Get initial data for the new Part object:
|
||||||
|
|
||||||
|
- If a category is provided, pre-fill the Category field
|
||||||
|
- If 'copy' parameter is provided, copy from referenced Part
|
||||||
|
"""
|
||||||
|
|
||||||
# Is the client attempting to copy an existing part?
|
# Is the client attempting to copy an existing part?
|
||||||
part_to_copy = self.request.GET.get('copy', None)
|
part_to_copy = self.request.GET.get('copy', None)
|
||||||
@ -98,15 +117,22 @@ class PartCreate(AjaxCreateView):
|
|||||||
|
|
||||||
|
|
||||||
class PartDetail(DetailView):
|
class PartDetail(DetailView):
|
||||||
|
""" Detail view for Part object
|
||||||
|
"""
|
||||||
|
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
queryset = Part.objects.all()
|
queryset = Part.objects.all()
|
||||||
template_name = 'part/detail.html'
|
template_name = 'part/detail.html'
|
||||||
|
|
||||||
# Add in some extra context information based on query params
|
# Add in some extra context information based on query params
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
""" Provide extra context data to template
|
||||||
|
|
||||||
|
- If '?editing=True', set 'editing_enabled' context variable
|
||||||
|
"""
|
||||||
context = super(PartDetail, self).get_context_data(**kwargs)
|
context = super(PartDetail, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
if self.request.GET.get('edit', '').lower() in ['true', 'yes', '1']:
|
if str2bool(self.request.GET.get('edit', '')):
|
||||||
context['editing_enabled'] = 1
|
context['editing_enabled'] = 1
|
||||||
else:
|
else:
|
||||||
context['editing_enabled'] = 0
|
context['editing_enabled'] = 0
|
||||||
@ -115,6 +141,7 @@ class PartDetail(DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class PartImage(AjaxUpdateView):
|
class PartImage(AjaxUpdateView):
|
||||||
|
""" View for uploading Part image """
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
@ -128,6 +155,8 @@ class PartImage(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class PartEdit(AjaxUpdateView):
|
class PartEdit(AjaxUpdateView):
|
||||||
|
""" View for editing Part object """
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
template_name = 'part/edit.html'
|
template_name = 'part/edit.html'
|
||||||
form_class = EditPartForm
|
form_class = EditPartForm
|
||||||
@ -214,6 +243,8 @@ class BomDownload(AjaxView):
|
|||||||
|
|
||||||
|
|
||||||
class PartDelete(AjaxDeleteView):
|
class PartDelete(AjaxDeleteView):
|
||||||
|
""" View to delete a Part object """
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
template_name = 'part/delete.html'
|
template_name = 'part/delete.html'
|
||||||
ajax_template_name = 'part/partial_delete.html'
|
ajax_template_name = 'part/partial_delete.html'
|
||||||
@ -229,6 +260,7 @@ class PartDelete(AjaxDeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryDetail(DetailView):
|
class CategoryDetail(DetailView):
|
||||||
|
""" Detail view for PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
context_object_name = 'category'
|
context_object_name = 'category'
|
||||||
queryset = PartCategory.objects.all()
|
queryset = PartCategory.objects.all()
|
||||||
@ -236,6 +268,7 @@ class CategoryDetail(DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryEdit(AjaxUpdateView):
|
class CategoryEdit(AjaxUpdateView):
|
||||||
|
""" Update view to edit a PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
template_name = 'part/category_edit.html'
|
template_name = 'part/category_edit.html'
|
||||||
form_class = EditCategoryForm
|
form_class = EditCategoryForm
|
||||||
@ -251,6 +284,7 @@ class CategoryEdit(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryDelete(AjaxDeleteView):
|
class CategoryDelete(AjaxDeleteView):
|
||||||
|
""" Delete view to delete a PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
template_name = 'part/category_delete.html'
|
template_name = 'part/category_delete.html'
|
||||||
context_object_name = 'category'
|
context_object_name = 'category'
|
||||||
@ -263,6 +297,7 @@ class CategoryDelete(AjaxDeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class CategoryCreate(AjaxCreateView):
|
class CategoryCreate(AjaxCreateView):
|
||||||
|
""" Create view to make a new PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
ajax_form_action = reverse_lazy('category-create')
|
ajax_form_action = reverse_lazy('category-create')
|
||||||
ajax_form_title = 'Create new part category'
|
ajax_form_title = 'Create new part category'
|
||||||
@ -271,6 +306,10 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
form_class = EditCategoryForm
|
form_class = EditCategoryForm
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
|
""" Add extra context data to template.
|
||||||
|
|
||||||
|
- If parent category provided, pass the category details to the template
|
||||||
|
"""
|
||||||
context = super(CategoryCreate, self).get_context_data(**kwargs).copy()
|
context = super(CategoryCreate, self).get_context_data(**kwargs).copy()
|
||||||
|
|
||||||
parent_id = self.request.GET.get('category', None)
|
parent_id = self.request.GET.get('category', None)
|
||||||
@ -281,6 +320,10 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
""" Get initial data for new PartCategory
|
||||||
|
|
||||||
|
- If parent provided, pre-fill the parent category
|
||||||
|
"""
|
||||||
initials = super(CategoryCreate, self).get_initial().copy()
|
initials = super(CategoryCreate, self).get_initial().copy()
|
||||||
|
|
||||||
parent_id = self.request.GET.get('category', None)
|
parent_id = self.request.GET.get('category', None)
|
||||||
@ -292,12 +335,14 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
|
|
||||||
|
|
||||||
class BomItemDetail(DetailView):
|
class BomItemDetail(DetailView):
|
||||||
|
""" Detail view for BomItem """
|
||||||
context_object_name = 'item'
|
context_object_name = 'item'
|
||||||
queryset = BomItem.objects.all()
|
queryset = BomItem.objects.all()
|
||||||
template_name = 'part/bom-detail.html'
|
template_name = 'part/bom-detail.html'
|
||||||
|
|
||||||
|
|
||||||
class BomItemCreate(AjaxCreateView):
|
class BomItemCreate(AjaxCreateView):
|
||||||
|
""" Create view for making a new BomItem object """
|
||||||
model = BomItem
|
model = BomItem
|
||||||
form_class = EditBomItemForm
|
form_class = EditBomItemForm
|
||||||
template_name = 'part/bom-create.html'
|
template_name = 'part/bom-create.html'
|
||||||
@ -305,6 +350,11 @@ class BomItemCreate(AjaxCreateView):
|
|||||||
ajax_form_title = 'Create BOM item'
|
ajax_form_title = 'Create BOM item'
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
""" Provide initial data for the BomItem:
|
||||||
|
|
||||||
|
- If 'parent' provided, set the parent part field
|
||||||
|
"""
|
||||||
|
|
||||||
# Look for initial values
|
# Look for initial values
|
||||||
initials = super(BomItemCreate, self).get_initial().copy()
|
initials = super(BomItemCreate, self).get_initial().copy()
|
||||||
|
|
||||||
@ -318,6 +368,8 @@ class BomItemCreate(AjaxCreateView):
|
|||||||
|
|
||||||
|
|
||||||
class BomItemEdit(AjaxUpdateView):
|
class BomItemEdit(AjaxUpdateView):
|
||||||
|
""" Update view for editing BomItem """
|
||||||
|
|
||||||
model = BomItem
|
model = BomItem
|
||||||
form_class = EditBomItemForm
|
form_class = EditBomItemForm
|
||||||
template_name = 'part/bom-edit.html'
|
template_name = 'part/bom-edit.html'
|
||||||
@ -326,6 +378,7 @@ class BomItemEdit(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class BomItemDelete(AjaxDeleteView):
|
class BomItemDelete(AjaxDeleteView):
|
||||||
|
""" Delete view for removing BomItem """
|
||||||
model = BomItem
|
model = BomItem
|
||||||
template_name = 'part/bom-delete.html'
|
template_name = 'part/bom-delete.html'
|
||||||
context_object_name = 'item'
|
context_object_name = 'item'
|
||||||
@ -333,6 +386,7 @@ class BomItemDelete(AjaxDeleteView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartDetail(DetailView):
|
class SupplierPartDetail(DetailView):
|
||||||
|
""" Detail view for SupplierPart """
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
template_name = 'company/partdetail.html'
|
template_name = 'company/partdetail.html'
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
@ -340,6 +394,8 @@ class SupplierPartDetail(DetailView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartEdit(AjaxUpdateView):
|
class SupplierPartEdit(AjaxUpdateView):
|
||||||
|
""" Update view for editing SupplierPart """
|
||||||
|
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
template_name = 'company/partedit.html'
|
template_name = 'company/partedit.html'
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
@ -349,6 +405,8 @@ class SupplierPartEdit(AjaxUpdateView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartCreate(AjaxCreateView):
|
class SupplierPartCreate(AjaxCreateView):
|
||||||
|
""" Create view for making new SupplierPart """
|
||||||
|
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
form_class = EditSupplierPartForm
|
form_class = EditSupplierPartForm
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
@ -356,6 +414,11 @@ class SupplierPartCreate(AjaxCreateView):
|
|||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
""" Provide initial data for new SupplierPart:
|
||||||
|
|
||||||
|
- If 'supplier_id' provided, pre-fill supplier field
|
||||||
|
- If 'part_id' provided, pre-fill part field
|
||||||
|
"""
|
||||||
initials = super(SupplierPartCreate, self).get_initial().copy()
|
initials = super(SupplierPartCreate, self).get_initial().copy()
|
||||||
|
|
||||||
supplier_id = self.request.GET.get('supplier', None)
|
supplier_id = self.request.GET.get('supplier', None)
|
||||||
@ -374,6 +437,7 @@ class SupplierPartCreate(AjaxCreateView):
|
|||||||
|
|
||||||
|
|
||||||
class SupplierPartDelete(AjaxDeleteView):
|
class SupplierPartDelete(AjaxDeleteView):
|
||||||
|
""" Delete view for removing a SupplierPart """
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
success_url = '/supplier/'
|
success_url = '/supplier/'
|
||||||
template_name = 'company/partdelete.html'
|
template_name = 'company/partdelete.html'
|
||||||
|
Loading…
Reference in New Issue
Block a user