mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Merge pull request #181 from SchrodingersGat/supplier-parts
Supplier parts
This commit is contained in:
commit
e5e6480099
@ -69,6 +69,22 @@ class AjaxMixin(object):
|
|||||||
ajax_form_action = ''
|
ajax_form_action = ''
|
||||||
ajax_form_title = ''
|
ajax_form_title = ''
|
||||||
|
|
||||||
|
def get_param(self, name, method='GET'):
|
||||||
|
""" Get a request query parameter value from URL e.g. ?part=3
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name: Variable name e.g. 'part'
|
||||||
|
method: Request type ('GET' or 'POST')
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Value of the supplier parameter or None if parameter is not available
|
||||||
|
"""
|
||||||
|
|
||||||
|
if method == 'POST':
|
||||||
|
return self.request.POST.get(name, None)
|
||||||
|
else:
|
||||||
|
return self.request.GET.get(name, None)
|
||||||
|
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
""" Get extra context data (default implementation is empty dict)
|
""" Get extra context data (default implementation is empty dict)
|
||||||
|
|
||||||
@ -134,79 +150,82 @@ class AjaxCreateView(AjaxMixin, CreateView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
""" Creates form with initial data, and renders JSON response """
|
||||||
|
|
||||||
response = super(CreateView, self).get(request, *args, **kwargs)
|
super(CreateView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
if request.is_ajax():
|
form = self.get_form()
|
||||||
# Initialize a a new form
|
return self.renderJsonResponse(request, form)
|
||||||
form = self.form_class(initial=self.get_initial())
|
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form)
|
|
||||||
|
|
||||||
else:
|
|
||||||
return response
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
form = self.form_class(data=request.POST, files=request.FILES)
|
""" Responds to form POST. Validates POST data and returns status info.
|
||||||
|
|
||||||
if request.is_ajax():
|
- Validate POST form data
|
||||||
|
- If valid, save form
|
||||||
|
- Return status info (success / failure)
|
||||||
|
"""
|
||||||
|
form = self.get_form()
|
||||||
|
|
||||||
data = {
|
# Extra JSON data sent alongside form
|
||||||
'form_valid': form.is_valid(),
|
data = {
|
||||||
}
|
'form_valid': form.is_valid(),
|
||||||
|
}
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
obj = form.save()
|
obj = form.save()
|
||||||
|
|
||||||
# Return the PK of the newly-created object
|
# Return the PK of the newly-created object
|
||||||
data['pk'] = obj.pk
|
data['pk'] = obj.pk
|
||||||
|
|
||||||
data['url'] = obj.get_absolute_url()
|
data['url'] = obj.get_absolute_url()
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form, data)
|
return self.renderJsonResponse(request, form, data)
|
||||||
|
|
||||||
else:
|
|
||||||
return super(CreateView, self).post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class AjaxUpdateView(AjaxMixin, UpdateView):
|
class AjaxUpdateView(AjaxMixin, UpdateView):
|
||||||
|
|
||||||
""" An 'AJAXified' UpdateView for updating an object in the db
|
""" An 'AJAXified' UpdateView for updating an object in the db
|
||||||
- Returns form in JSON format (for delivery to a modal window)
|
- Returns form in JSON format (for delivery to a modal window)
|
||||||
- Handles repeated form validation (via AJAX) until the form is valid
|
- Handles repeated form validation (via AJAX) until the form is valid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
""" Respond to GET request.
|
||||||
|
|
||||||
html_response = super(UpdateView, self).get(request, *args, **kwargs)
|
- Populates form with object data
|
||||||
|
- Renders form to JSON and returns to client
|
||||||
|
"""
|
||||||
|
|
||||||
if request.is_ajax():
|
super(UpdateView, self).get(request, *args, **kwargs)
|
||||||
form = self.form_class(instance=self.get_object())
|
|
||||||
|
|
||||||
return self.renderJsonResponse(request, form)
|
form = self.get_form()
|
||||||
|
|
||||||
else:
|
return self.renderJsonResponse(request, form)
|
||||||
return html_response
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
""" Respond to POST request.
|
||||||
|
|
||||||
form = self.form_class(instance=self.get_object(), data=request.POST, files=request.FILES)
|
- Updates model with POST field data
|
||||||
|
- Performs form and object validation
|
||||||
|
- If errors exist, re-render the form
|
||||||
|
- Otherwise, return sucess status
|
||||||
|
"""
|
||||||
|
|
||||||
if request.is_ajax():
|
super(UpdateView, self).post(request, *args, **kwargs)
|
||||||
|
|
||||||
data = {'form_valid': form.is_valid()}
|
form = self.get_form()
|
||||||
|
|
||||||
if form.is_valid():
|
data = {
|
||||||
obj = form.save()
|
'form_valid': form.is_valid()
|
||||||
|
}
|
||||||
|
|
||||||
data['pk'] = obj.id
|
if form.is_valid():
|
||||||
data['url'] = obj.get_absolute_url()
|
obj = form.save()
|
||||||
|
|
||||||
|
# Include context data about the updated object
|
||||||
|
data['pk'] = obj.id
|
||||||
|
data['url'] = obj.get_absolute_url()
|
||||||
|
|
||||||
response = self.renderJsonResponse(request, form, data)
|
return self.renderJsonResponse(request, form, data)
|
||||||
return response
|
|
||||||
|
|
||||||
else:
|
|
||||||
return super(UpdateView, self).post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class AjaxDeleteView(AjaxMixin, DeleteView):
|
class AjaxDeleteView(AjaxMixin, DeleteView):
|
||||||
@ -217,39 +236,43 @@ class AjaxDeleteView(AjaxMixin, DeleteView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
""" Respond to GET request
|
||||||
|
|
||||||
html_response = super(DeleteView, self).get(request, *args, **kwargs)
|
- Render a DELETE confirmation form to JSON
|
||||||
|
- Return rendered form to client
|
||||||
|
"""
|
||||||
|
|
||||||
if request.is_ajax():
|
super(DeleteView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
data = {'id': self.get_object().id,
|
data = {
|
||||||
'delete': False,
|
'id': self.get_object().id,
|
||||||
'title': self.ajax_form_title,
|
'delete': False,
|
||||||
'html_data': render_to_string(self.ajax_template_name,
|
'title': self.ajax_form_title,
|
||||||
self.get_context_data(),
|
'html_data': render_to_string(
|
||||||
request=request)
|
self.ajax_template_name,
|
||||||
}
|
self.get_context_data(),
|
||||||
|
request=request)
|
||||||
|
}
|
||||||
|
|
||||||
return JsonResponse(data)
|
return JsonResponse(data)
|
||||||
|
|
||||||
else:
|
|
||||||
return html_response
|
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
""" Respond to POST request
|
||||||
|
|
||||||
if request.is_ajax():
|
- DELETE the object
|
||||||
|
- Render success message to JSON and return to client
|
||||||
|
"""
|
||||||
|
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
pk = obj.id
|
pk = obj.id
|
||||||
obj.delete()
|
obj.delete()
|
||||||
|
|
||||||
data = {'id': pk,
|
data = {
|
||||||
'delete': True}
|
'id': pk,
|
||||||
|
'delete': True
|
||||||
|
}
|
||||||
|
|
||||||
return self.renderJsonResponse(request, data=data)
|
return self.renderJsonResponse(request, data=data)
|
||||||
|
|
||||||
else:
|
|
||||||
return super(DeleteView, self).post(request, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class IndexView(TemplateView):
|
class IndexView(TemplateView):
|
||||||
|
@ -101,7 +101,10 @@ class BuildCreate(AjaxCreateView):
|
|||||||
part_id = self.request.GET.get('part', None)
|
part_id = self.request.GET.get('part', None)
|
||||||
|
|
||||||
if part_id:
|
if part_id:
|
||||||
initials['part'] = get_object_or_404(Part, pk=part_id)
|
try:
|
||||||
|
initials['part'] = Part.objects.get(pk=part_id)
|
||||||
|
except Part.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ from rest_framework import generics, permissions
|
|||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
from .models import Part, PartCategory, BomItem
|
from .models import Part, PartCategory, BomItem
|
||||||
from .models import SupplierPart, SupplierPriceBreak
|
from .models import SupplierPart, SupplierPriceBreak
|
||||||
@ -99,20 +98,24 @@ class PartList(generics.ListCreateAPIView):
|
|||||||
parts_list = Part.objects.all()
|
parts_list = Part.objects.all()
|
||||||
|
|
||||||
if cat_id:
|
if cat_id:
|
||||||
category = get_object_or_404(PartCategory, pk=cat_id)
|
try:
|
||||||
|
category = PartCategory.objects.get(pk=cat_id)
|
||||||
|
|
||||||
|
# Filter by the supplied category
|
||||||
|
flt = Q(category=cat_id)
|
||||||
|
|
||||||
# Filter by the supplied category
|
if self.request.query_params.get('include_child_categories', None):
|
||||||
flt = Q(category=cat_id)
|
childs = category.getUniqueChildren()
|
||||||
|
for child in childs:
|
||||||
|
# Ignore the top-level category (already filtered)
|
||||||
|
if str(child) == str(cat_id):
|
||||||
|
continue
|
||||||
|
flt |= Q(category=child)
|
||||||
|
|
||||||
if self.request.query_params.get('include_child_categories', None):
|
parts_list = parts_list.filter(flt)
|
||||||
childs = category.getUniqueChildren()
|
|
||||||
for child in childs:
|
|
||||||
# Ignore the top-level category (already filtered)
|
|
||||||
if str(child) == str(cat_id):
|
|
||||||
continue
|
|
||||||
flt |= Q(category=child)
|
|
||||||
|
|
||||||
parts_list = parts_list.filter(flt)
|
except PartCategory.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return parts_list
|
return parts_list
|
||||||
|
|
||||||
|
@ -92,6 +92,8 @@ class EditBomItemForm(HelperForm):
|
|||||||
'quantity',
|
'quantity',
|
||||||
'note'
|
'note'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Prevent editing of the part associated with this BomItem
|
||||||
widgets = {'part': forms.HiddenInput()}
|
widgets = {'part': forms.HiddenInput()}
|
||||||
|
|
||||||
|
|
||||||
@ -101,13 +103,13 @@ class EditSupplierPartForm(HelperForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
fields = [
|
fields = [
|
||||||
|
'part',
|
||||||
'supplier',
|
'supplier',
|
||||||
'SKU',
|
'SKU',
|
||||||
'part',
|
|
||||||
'description',
|
'description',
|
||||||
'URL',
|
|
||||||
'manufacturer',
|
'manufacturer',
|
||||||
'MPN',
|
'MPN',
|
||||||
|
'URL',
|
||||||
'note',
|
'note',
|
||||||
'single_price',
|
'single_price',
|
||||||
'base_cost',
|
'base_cost',
|
||||||
|
@ -84,7 +84,10 @@ class PartCreate(AjaxCreateView):
|
|||||||
cat_id = self.get_category_id()
|
cat_id = self.get_category_id()
|
||||||
|
|
||||||
if cat_id:
|
if cat_id:
|
||||||
context['category'] = get_object_or_404(PartCategory, pk=cat_id)
|
try:
|
||||||
|
context['category'] = PartCategory.objects.get(pk=cat_id)
|
||||||
|
except PartCategory.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@ -111,7 +114,10 @@ class PartCreate(AjaxCreateView):
|
|||||||
initials = super(PartCreate, self).get_initial()
|
initials = super(PartCreate, self).get_initial()
|
||||||
|
|
||||||
if self.get_category_id():
|
if self.get_category_id():
|
||||||
initials['category'] = get_object_or_404(PartCategory, pk=self.get_category_id())
|
try:
|
||||||
|
initials['category'] = PartCategory.objects.get(pk=self.get_category_id())
|
||||||
|
except PartCategory.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
@ -158,7 +164,6 @@ class PartEdit(AjaxUpdateView):
|
|||||||
""" View for editing Part object """
|
""" View for editing Part object """
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
template_name = 'part/edit.html'
|
|
||||||
form_class = EditPartForm
|
form_class = EditPartForm
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Edit Part Properties'
|
ajax_form_title = 'Edit Part Properties'
|
||||||
@ -246,7 +251,6 @@ class PartDelete(AjaxDeleteView):
|
|||||||
""" View to delete a Part object """
|
""" View to delete a Part object """
|
||||||
|
|
||||||
model = Part
|
model = Part
|
||||||
template_name = 'part/delete.html'
|
|
||||||
ajax_template_name = 'part/partial_delete.html'
|
ajax_template_name = 'part/partial_delete.html'
|
||||||
ajax_form_title = 'Confirm Part Deletion'
|
ajax_form_title = 'Confirm Part Deletion'
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
@ -270,7 +274,6 @@ class CategoryDetail(DetailView):
|
|||||||
class CategoryEdit(AjaxUpdateView):
|
class CategoryEdit(AjaxUpdateView):
|
||||||
""" Update view to edit a PartCategory """
|
""" Update view to edit a PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
template_name = 'part/category_edit.html'
|
|
||||||
form_class = EditCategoryForm
|
form_class = EditCategoryForm
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Edit Part Category'
|
ajax_form_title = 'Edit Part Category'
|
||||||
@ -278,7 +281,10 @@ class CategoryEdit(AjaxUpdateView):
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(CategoryEdit, self).get_context_data(**kwargs).copy()
|
context = super(CategoryEdit, self).get_context_data(**kwargs).copy()
|
||||||
|
|
||||||
context['category'] = get_object_or_404(PartCategory, pk=self.kwargs['pk'])
|
try:
|
||||||
|
context['category'] = PartCategory.objects.get(pk=self.kwargs['pk'])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@ -286,7 +292,7 @@ class CategoryEdit(AjaxUpdateView):
|
|||||||
class CategoryDelete(AjaxDeleteView):
|
class CategoryDelete(AjaxDeleteView):
|
||||||
""" Delete view to delete a PartCategory """
|
""" Delete view to delete a PartCategory """
|
||||||
model = PartCategory
|
model = PartCategory
|
||||||
template_name = 'part/category_delete.html'
|
ajax_template_name = 'part/category_delete.html'
|
||||||
context_object_name = 'category'
|
context_object_name = 'category'
|
||||||
success_url = '/part/'
|
success_url = '/part/'
|
||||||
|
|
||||||
@ -302,7 +308,6 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
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'
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
template_name = 'part/category_new.html'
|
|
||||||
form_class = EditCategoryForm
|
form_class = EditCategoryForm
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
@ -315,7 +320,10 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
parent_id = self.request.GET.get('category', None)
|
parent_id = self.request.GET.get('category', None)
|
||||||
|
|
||||||
if parent_id:
|
if parent_id:
|
||||||
context['category'] = get_object_or_404(PartCategory, pk=parent_id)
|
try:
|
||||||
|
context['category'] = PartCategory.objects.get(pk=parent_id)
|
||||||
|
except PartCategory.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@ -329,7 +337,10 @@ class CategoryCreate(AjaxCreateView):
|
|||||||
parent_id = self.request.GET.get('category', None)
|
parent_id = self.request.GET.get('category', None)
|
||||||
|
|
||||||
if parent_id:
|
if parent_id:
|
||||||
initials['parent'] = get_object_or_404(PartCategory, pk=parent_id)
|
try:
|
||||||
|
initials['parent'] = PartCategory.objects.get(pk=parent_id)
|
||||||
|
except PartCategory.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
@ -345,7 +356,6 @@ class BomItemCreate(AjaxCreateView):
|
|||||||
""" Create view for making a new BomItem object """
|
""" Create view for making a new BomItem object """
|
||||||
model = BomItem
|
model = BomItem
|
||||||
form_class = EditBomItemForm
|
form_class = EditBomItemForm
|
||||||
template_name = 'part/bom-create.html'
|
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Create BOM item'
|
ajax_form_title = 'Create BOM item'
|
||||||
|
|
||||||
@ -362,7 +372,10 @@ class BomItemCreate(AjaxCreateView):
|
|||||||
parent_id = self.request.GET.get('parent', None)
|
parent_id = self.request.GET.get('parent', None)
|
||||||
|
|
||||||
if parent_id:
|
if parent_id:
|
||||||
initials['part'] = get_object_or_404(Part, pk=parent_id)
|
try:
|
||||||
|
initials['part'] = Part.objects.get(pk=parent_id)
|
||||||
|
except Part.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
@ -372,7 +385,6 @@ class BomItemEdit(AjaxUpdateView):
|
|||||||
|
|
||||||
model = BomItem
|
model = BomItem
|
||||||
form_class = EditBomItemForm
|
form_class = EditBomItemForm
|
||||||
template_name = 'part/bom-edit.html'
|
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Edit BOM item'
|
ajax_form_title = 'Edit BOM item'
|
||||||
|
|
||||||
@ -380,7 +392,7 @@ class BomItemEdit(AjaxUpdateView):
|
|||||||
class BomItemDelete(AjaxDeleteView):
|
class BomItemDelete(AjaxDeleteView):
|
||||||
""" Delete view for removing BomItem """
|
""" Delete view for removing BomItem """
|
||||||
model = BomItem
|
model = BomItem
|
||||||
template_name = 'part/bom-delete.html'
|
ajax_template_name = 'part/bom-delete.html'
|
||||||
context_object_name = 'item'
|
context_object_name = 'item'
|
||||||
ajax_form_title = 'Confim BOM item deletion'
|
ajax_form_title = 'Confim BOM item deletion'
|
||||||
|
|
||||||
@ -397,7 +409,6 @@ class SupplierPartEdit(AjaxUpdateView):
|
|||||||
""" Update view for editing SupplierPart """
|
""" Update view for editing SupplierPart """
|
||||||
|
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
template_name = 'company/partedit.html'
|
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
form_class = EditSupplierPartForm
|
form_class = EditSupplierPartForm
|
||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
@ -413,6 +424,19 @@ class SupplierPartCreate(AjaxCreateView):
|
|||||||
ajax_form_title = 'Create new Supplier Part'
|
ajax_form_title = 'Create new Supplier Part'
|
||||||
context_object_name = 'part'
|
context_object_name = 'part'
|
||||||
|
|
||||||
|
def get_form(self):
|
||||||
|
form = super(AjaxCreateView, self).get_form()
|
||||||
|
|
||||||
|
if form.initial.get('supplier', None):
|
||||||
|
# Hide the supplier field
|
||||||
|
form.fields['supplier'].widget.attrs['disabled'] = True
|
||||||
|
|
||||||
|
if form.initial.get('part', None):
|
||||||
|
# Hide the part field
|
||||||
|
form.fields['part'].widget.attrs['disabled'] = True
|
||||||
|
|
||||||
|
return form
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
""" Provide initial data for new SupplierPart:
|
""" Provide initial data for new SupplierPart:
|
||||||
|
|
||||||
@ -421,18 +445,21 @@ class SupplierPartCreate(AjaxCreateView):
|
|||||||
"""
|
"""
|
||||||
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.get_param('supplier')
|
||||||
part_id = self.request.GET.get('part', None)
|
part_id = self.get_param('part')
|
||||||
|
|
||||||
if supplier_id:
|
if supplier_id:
|
||||||
initials['supplier'] = get_object_or_404(Company, pk=supplier_id)
|
try:
|
||||||
# TODO
|
initials['supplier'] = Company.objects.get(pk=supplier_id)
|
||||||
# self.fields['supplier'].disabled = True
|
except Company.DoesNotExist:
|
||||||
|
initials['supplier'] = None
|
||||||
|
|
||||||
if part_id:
|
if part_id:
|
||||||
initials['part'] = get_object_or_404(Part, pk=part_id)
|
try:
|
||||||
# TODO
|
initials['part'] = Part.objects.get(pk=part_id)
|
||||||
# self.fields['part'].disabled = True
|
except Part.DoesNotExist:
|
||||||
|
initials['part'] = None
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
|
|
||||||
@ -440,4 +467,4 @@ class SupplierPartDelete(AjaxDeleteView):
|
|||||||
""" Delete view for removing a SupplierPart """
|
""" Delete view for removing a SupplierPart """
|
||||||
model = SupplierPart
|
model = SupplierPart
|
||||||
success_url = '/supplier/'
|
success_url = '/supplier/'
|
||||||
template_name = 'company/partdelete.html'
|
ajax_template_name = 'company/partdelete.html'
|
||||||
|
@ -7,7 +7,6 @@ from django_filters import NumberFilter
|
|||||||
|
|
||||||
from django.conf.urls import url, include
|
from django.conf.urls import url, include
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
from .models import StockLocation, StockItem
|
from .models import StockLocation, StockItem
|
||||||
from .models import StockItemTracking
|
from .models import StockItemTracking
|
||||||
@ -238,20 +237,24 @@ class StockList(generics.ListCreateAPIView):
|
|||||||
stock_list = StockItem.objects.all()
|
stock_list = StockItem.objects.all()
|
||||||
|
|
||||||
if loc_id:
|
if loc_id:
|
||||||
location = get_object_or_404(StockLocation, pk=loc_id)
|
try:
|
||||||
|
location = StockLocation.objects.get(pk=loc_id)
|
||||||
|
|
||||||
# Filter by the supplied category
|
# Filter by the supplied category
|
||||||
flt = Q(location=loc_id)
|
flt = Q(location=loc_id)
|
||||||
|
|
||||||
if self.request.query_params.get('include_child_locations', None):
|
if self.request.query_params.get('include_child_locations', None):
|
||||||
childs = location.getUniqueChildren()
|
childs = location.getUniqueChildren()
|
||||||
for child in childs:
|
for child in childs:
|
||||||
# Ignore the top-level category (already filtered!)
|
# Ignore the top-level category (already filtered!)
|
||||||
if str(child) == str(loc_id):
|
if str(child) == str(loc_id):
|
||||||
continue
|
continue
|
||||||
flt |= Q(location=child)
|
flt |= Q(location=child)
|
||||||
|
|
||||||
stock_list = stock_list.filter(flt)
|
stock_list = stock_list.filter(flt)
|
||||||
|
|
||||||
|
except StockLocation.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return stock_list
|
return stock_list
|
||||||
|
|
||||||
|
@ -5,8 +5,6 @@ Django views for interacting with Stock app
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
|
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from django.forms.models import model_to_dict
|
from django.forms.models import model_to_dict
|
||||||
|
|
||||||
@ -106,7 +104,10 @@ class StockLocationCreate(AjaxCreateView):
|
|||||||
loc_id = self.request.GET.get('location', None)
|
loc_id = self.request.GET.get('location', None)
|
||||||
|
|
||||||
if loc_id:
|
if loc_id:
|
||||||
initials['parent'] = get_object_or_404(StockLocation, pk=loc_id)
|
try:
|
||||||
|
initials['parent'] = StockLocation.objects.get(pk=loc_id)
|
||||||
|
except StockLocation.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
@ -125,7 +126,30 @@ class StockItemCreate(AjaxCreateView):
|
|||||||
ajax_template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
ajax_form_title = 'Create new Stock Item'
|
ajax_form_title = 'Create new Stock Item'
|
||||||
|
|
||||||
|
def get_form(self):
|
||||||
|
""" Get form for StockItem creation.
|
||||||
|
Overrides the default get_form() method to intelligently limit
|
||||||
|
ForeignKey choices based on other selections
|
||||||
|
"""
|
||||||
|
|
||||||
|
form = super(AjaxCreateView, self).get_form()
|
||||||
|
|
||||||
|
# If the user has selected a Part, limit choices for SupplierPart
|
||||||
|
if form['part'].value() is not None:
|
||||||
|
part = form['part'].value()
|
||||||
|
parts = form.fields['supplier_part'].queryset
|
||||||
|
parts = parts.filter(part=part)
|
||||||
|
form.fields['supplier_part'].queryset = parts
|
||||||
|
|
||||||
|
# Otherwise if the user has selected a SupplierPart, we know what Part they meant!
|
||||||
|
elif form['supplier_part'].value() is not None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return form
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
|
""" Provide initial data to create a new StockItem object
|
||||||
|
"""
|
||||||
|
|
||||||
# Is the client attempting to copy an existing stock item?
|
# Is the client attempting to copy an existing stock item?
|
||||||
item_to_copy = self.request.GET.get('copy', None)
|
item_to_copy = self.request.GET.get('copy', None)
|
||||||
@ -144,15 +168,22 @@ class StockItemCreate(AjaxCreateView):
|
|||||||
part_id = self.request.GET.get('part', None)
|
part_id = self.request.GET.get('part', None)
|
||||||
loc_id = self.request.GET.get('location', None)
|
loc_id = self.request.GET.get('location', None)
|
||||||
|
|
||||||
|
# Part field has been specified
|
||||||
if part_id:
|
if part_id:
|
||||||
part = get_object_or_404(Part, pk=part_id)
|
try:
|
||||||
if part:
|
part = Part.objects.get(pk=part_id)
|
||||||
initials['part'] = get_object_or_404(Part, pk=part_id)
|
initials['part'] = part
|
||||||
initials['location'] = part.default_location
|
initials['location'] = part.default_location
|
||||||
initials['supplier_part'] = part.default_supplier
|
initials['supplier_part'] = part.default_supplier
|
||||||
|
except Part.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Location has been specified
|
||||||
if loc_id:
|
if loc_id:
|
||||||
initials['location'] = get_object_or_404(StockLocation, pk=loc_id)
|
try:
|
||||||
|
initials['location'] = StockLocation.objects.get(pk=loc_id)
|
||||||
|
except StockLocation.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
return initials
|
return initials
|
||||||
|
|
||||||
@ -178,7 +209,7 @@ class StockItemDelete(AjaxDeleteView):
|
|||||||
|
|
||||||
model = StockItem
|
model = StockItem
|
||||||
success_url = '/stock/'
|
success_url = '/stock/'
|
||||||
template_name = 'stock/item_delete.html'
|
ajax_template_name = 'stock/item_delete.html'
|
||||||
context_object_name = 'item'
|
context_object_name = 'item'
|
||||||
ajax_form_title = 'Delete Stock Item'
|
ajax_form_title = 'Delete Stock Item'
|
||||||
|
|
||||||
@ -190,7 +221,7 @@ class StockItemMove(AjaxUpdateView):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
model = StockItem
|
model = StockItem
|
||||||
template_name = 'modal_form.html'
|
ajax_template_name = 'modal_form.html'
|
||||||
context_object_name = 'item'
|
context_object_name = 'item'
|
||||||
ajax_form_title = 'Move Stock Item'
|
ajax_form_title = 'Move Stock Item'
|
||||||
form_class = MoveStockItemForm
|
form_class = MoveStockItemForm
|
||||||
|
Loading…
Reference in New Issue
Block a user