2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-04-28 11:36:44 +00:00

Add docstrings for Build app

This commit is contained in:
Oliver Walters 2019-04-27 20:35:14 +10:00
parent 6147ac3f06
commit d9169a0dd1
8 changed files with 103 additions and 41 deletions

View File

@ -1,3 +1,7 @@
"""
Provides a JSON API for the Build app
"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
@ -11,7 +15,14 @@ from .models import Build
from .serializers import BuildSerializer from .serializers import BuildSerializer
class BuildList(generics.ListAPIView): class BuildList(generics.ListCreateAPIView):
""" API endpoint for accessing a list of Build objects.
Provides two methods:
- GET: Return list of objects (with filters)
- POST: Create a new Build object
"""
queryset = Build.objects.all() queryset = Build.objects.all()
serializer_class = BuildSerializer serializer_class = BuildSerializer

View File

@ -1,3 +1,7 @@
"""
Django Forms for interacting with Build objects
"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
@ -7,6 +11,8 @@ from .models import Build
class EditBuildForm(HelperForm): class EditBuildForm(HelperForm):
""" Form for editing a Build object.
"""
class Meta: class Meta:
model = Build model = Build

View File

@ -1,3 +1,9 @@
"""
Build models
Defines the database models for part Builds
"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
@ -9,60 +15,61 @@ from django.core.validators import MinValueValidator
class Build(models.Model): class Build(models.Model):
""" A Build object organises the creation of new parts from the component parts """ A Build object organises the creation of new parts from the component parts.
It uses the part BOM to generate new parts.
Parts are then taken from stock
""" """
def get_absolute_url(self): def get_absolute_url(self):
return reverse('build-detail', kwargs={'pk': self.id}) return reverse('build-detail', kwargs={'pk': self.id})
part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
related_name='builds',
limit_choices_to={'buildable': True},
)
""" A reference to the part being built - only parts marked as 'buildable' may be selected """
#: Brief title describing the build
title = models.CharField(max_length=100, help_text='Brief description of the build')
#: Number of output parts to build
quantity = models.PositiveIntegerField(default=1,
validators=[MinValueValidator(1)],
help_text='Number of parts to build')
# Build status codes # Build status codes
PENDING = 10 # Build is pending / active PENDING = 10 # Build is pending / active
HOLDING = 20 # Build is currently being held HOLDING = 20 # Build is currently being held
CANCELLED = 30 # Build was cancelled CANCELLED = 30 # Build was cancelled
COMPLETE = 40 # Build is complete COMPLETE = 40 # Build is complete
#: Build status codes
BUILD_STATUS_CODES = {PENDING: _("Pending"), BUILD_STATUS_CODES = {PENDING: _("Pending"),
HOLDING: _("Holding"), HOLDING: _("Holding"),
CANCELLED: _("Cancelled"), CANCELLED: _("Cancelled"),
COMPLETE: _("Complete"), COMPLETE: _("Complete"),
} }
batch = models.CharField(max_length=100, blank=True, null=True, #: Status of the build (ref BUILD_STATUS_CODES)
help_text='Batch code for this build output')
# Status of the build
status = models.PositiveIntegerField(default=PENDING, status = models.PositiveIntegerField(default=PENDING,
choices=BUILD_STATUS_CODES.items(), choices=BUILD_STATUS_CODES.items(),
validators=[MinValueValidator(0)]) validators=[MinValueValidator(0)])
# Date the build model was 'created' #: Batch number for the build (optional)
batch = models.CharField(max_length=100, blank=True, null=True,
help_text='Batch code for this build output')
#: Date the build model was 'created'
creation_date = models.DateField(auto_now=True, editable=False) creation_date = models.DateField(auto_now=True, editable=False)
# Date the build was 'completed' #: Date the build was 'completed' (and parts removed from stock)
completion_date = models.DateField(null=True, blank=True) completion_date = models.DateField(null=True, blank=True)
# Brief build title #: Notes attached to each build output
title = models.CharField(max_length=100, help_text='Brief description of the build')
# A reference to the part being built
# Only 'buildable' parts can be selected
part = models.ForeignKey('part.Part', on_delete=models.CASCADE,
related_name='builds',
limit_choices_to={'buildable': True},
)
# How many parts to build?
quantity = models.PositiveIntegerField(default=1,
validators=[MinValueValidator(1)],
help_text='Number of parts to build')
# Notes can be attached to each build output
notes = models.TextField(blank=True) notes = models.TextField(blank=True)
@property @property
def required_parts(self): def required_parts(self):
""" Returns a dict of parts required to build this part (BOM) """
parts = [] parts = []
for item in self.part.bom_items.all(): for item in self.part.bom_items.all():
@ -77,8 +84,7 @@ class Build(models.Model):
@property @property
def can_build(self): def can_build(self):
""" Return true if there are enough parts to supply build """ Return true if there are enough parts to supply build """
"""
for item in self.required_parts: for item in self.required_parts:
if item['part'].total_stock < item['quantity']: if item['part'].total_stock < item['quantity']:
@ -88,10 +94,10 @@ class Build(models.Model):
@property @property
def is_active(self): def is_active(self):
""" Is this build active? """ Is this build active? An active build is either:
An active build is either:
- Pending - PENDING
- Holding - HOLDING
""" """
return self.status in [ return self.status in [
@ -101,4 +107,5 @@ class Build(models.Model):
@property @property
def is_complete(self): def is_complete(self):
""" Returns True if the build status is COMPLETE """
return self.status == self.COMPLETE return self.status == self.COMPLETE

View File

@ -1,3 +1,7 @@
"""
Provides JSON serializers for Build API
"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
@ -7,6 +11,7 @@ from .models import Build
class BuildSerializer(serializers.ModelSerializer): class BuildSerializer(serializers.ModelSerializer):
""" Serializes a Build object """
url = serializers.CharField(source='get_absolute_url', read_only=True) url = serializers.CharField(source='get_absolute_url', read_only=True)
status_text = serializers.CharField(source='get_status_display', read_only=True) status_text = serializers.CharField(source='get_status_display', read_only=True)

View File

@ -1,3 +1,7 @@
"""
URL lookup for Build app
"""
from django.conf.urls import url, include from django.conf.urls import url, include
from . import views from . import views

View File

@ -1,3 +1,7 @@
"""
Provides Django views for interacting with Build objects
"""
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import unicode_literals from __future__ import unicode_literals
@ -13,11 +17,14 @@ from InvenTree.views import AjaxView, AjaxUpdateView, AjaxCreateView
class BuildIndex(ListView): class BuildIndex(ListView):
""" View for displaying list of Builds
"""
model = Build model = Build
template_name = 'build/index.html' template_name = 'build/index.html'
context_object_name = 'builds' context_object_name = 'builds'
def get_queryset(self): def get_queryset(self):
""" Return all Build objects (order by date, newest first) """
return Build.objects.order_by('status', '-completion_date') return Build.objects.order_by('status', '-completion_date')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -35,6 +42,9 @@ class BuildIndex(ListView):
class BuildCancel(AjaxView): class BuildCancel(AjaxView):
""" View to cancel a Build.
Provides a cancellation information dialog
"""
model = Build model = Build
template_name = 'build/cancel.html' template_name = 'build/cancel.html'
ajax_form_title = 'Cancel Build' ajax_form_title = 'Cancel Build'
@ -42,6 +52,7 @@ class BuildCancel(AjaxView):
fields = [] fields = []
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
""" Handle POST request. Mark the build status as CANCELLED """
build = get_object_or_404(Build, pk=self.kwargs['pk']) build = get_object_or_404(Build, pk=self.kwargs['pk'])
@ -51,24 +62,28 @@ class BuildCancel(AjaxView):
return self.renderJsonResponse(request, None) return self.renderJsonResponse(request, None)
def get_data(self): def get_data(self):
""" Provide JSON context data. """
return { return {
'info': 'Build was cancelled' 'info': 'Build was cancelled'
} }
class BuildDetail(DetailView): class BuildDetail(DetailView):
""" Detail view of a single Build object. """
model = Build model = Build
template_name = 'build/detail.html' template_name = 'build/detail.html'
context_object_name = 'build' context_object_name = 'build'
class BuildAllocate(DetailView): class BuildAllocate(DetailView):
""" View for allocating parts to a Build """
model = Build model = Build
context_object_name = 'build' context_object_name = 'build'
template_name = 'build/allocate.html' template_name = 'build/allocate.html'
class BuildCreate(AjaxCreateView): class BuildCreate(AjaxCreateView):
""" View to create a new Build object """
model = Build model = Build
context_object_name = 'build' context_object_name = 'build'
form_class = EditBuildForm form_class = EditBuildForm
@ -76,6 +91,11 @@ class BuildCreate(AjaxCreateView):
ajax_template_name = 'modal_form.html' ajax_template_name = 'modal_form.html'
def get_initial(self): def get_initial(self):
""" Get initial parameters for Build creation.
If 'part' is specified in the GET query, initialize the Build with the specified Part
"""
initials = super(BuildCreate, self).get_initial().copy() initials = super(BuildCreate, self).get_initial().copy()
part_id = self.request.GET.get('part', None) part_id = self.request.GET.get('part', None)
@ -92,6 +112,8 @@ class BuildCreate(AjaxCreateView):
class BuildUpdate(AjaxUpdateView): class BuildUpdate(AjaxUpdateView):
""" View for editing a Build object """
model = Build model = Build
form_class = EditBuildForm form_class = EditBuildForm
context_object_name = 'build' context_object_name = 'build'

View File

@ -1,7 +1,5 @@
""" """
Module keygen Generates a Django SECRET_KEY file to be used by manage.py
=============
This module generates a Django SECRET_KEY file to be used by manage.py
""" """
import random import random
@ -15,11 +13,13 @@ KEY_DIR = os.path.dirname(os.path.realpath(__file__))
def generate_key(length=50): def generate_key(length=50):
""" """ Generate a random string
Generate a random string
:param length: Number of characters in returned string (default=50) Args:
:returns: Randomized secret key string length: Number of characters in returned string (default = 50)
Returns:
Randomized secret key string
""" """
options = string.digits + string.ascii_letters + string.punctuation options = string.digits + string.ascii_letters + string.punctuation

View File

@ -28,9 +28,13 @@ copyright = '2019, InvenTree'
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [ extensions = [
'autoapi.extension' 'sphinx.ext.napoleon',
'autoapi.extension',
] ]
napoleon_google_docstring = True
napoleon_numpy_docstring = False
autoapi_dirs = [ autoapi_dirs = [
'../InvenTree', '../InvenTree',
] ]
@ -44,7 +48,10 @@ autoapi_type = 'python'
autoapi_ignore = [ autoapi_ignore = [
'*migrations*', '*migrations*',
'**/test*.py', '**/test*.py',
'**/manage.py' '**/manage.py',
'**/apps.py',
'**/admin.py',
'**/templates/',
] ]
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.