Refactor "uninstall stock item" form to use the API

This commit is contained in:
Oliver Walters 2022-05-04 17:25:24 +10:00
parent 5cf30a850d
commit adbcd68fe8
11 changed files with 111 additions and 107 deletions

View File

@ -92,13 +92,8 @@ class StockDetail(generics.RetrieveUpdateDestroyAPIView):
return self.serializer_class(*args, **kwargs)
class StockItemSerialize(generics.CreateAPIView):
"""
API endpoint for serializing a stock item
"""
queryset = StockItem.objects.none()
serializer_class = StockSerializers.SerializeStockItemSerializer
class StockItemContextMixin:
""" Mixin class for adding StockItem object to serializer context """
def get_serializer_context(self):
@ -112,8 +107,16 @@ class StockItemSerialize(generics.CreateAPIView):
return context
class StockItemSerialize(StockItemContextMixin, generics.CreateAPIView):
"""
API endpoint for serializing a stock item
"""
class StockItemInstall(generics.CreateAPIView):
queryset = StockItem.objects.none()
serializer_class = StockSerializers.SerializeStockItemSerializer
class StockItemInstall(StockItemContextMixin, generics.CreateAPIView):
"""
API endpoint for installing a particular stock item into this stock item.
@ -125,17 +128,14 @@ class StockItemInstall(generics.CreateAPIView):
queryset = StockItem.objects.none()
serializer_class = StockSerializers.InstallStockItemSerializer
def get_serializer_context(self):
context = super().get_serializer_context()
context['request'] = self.request
class StockItemUninstall(StockItemContextMixin, generics.CreateAPIView):
"""
API endpoint for removing (uninstalling) items from this item
"""
try:
context['item'] = StockItem.objects.get(pk=self.kwargs.get('pk', None))
except:
pass
return context
queryset = StockItem.objects.none()
serializer_class = StockSerializers.UninstallStockItemSerializer
class StockAdjustView(generics.CreateAPIView):
@ -1421,6 +1421,7 @@ stock_api_urls = [
re_path(r'^(?P<pk>\d+)/', include([
re_path(r'^serialize/', StockItemSerialize.as_view(), name='api-stock-item-serialize'),
re_path(r'^install/', StockItemInstall.as_view(), name='api-stock-item-install'),
re_path(r'^uninstall/', StockItemUninstall.as_view(), name='api-stock-item-uninstall'),
re_path(r'^.*$', StockDetail.as_view(), name='api-stock-detail'),
])),

View File

@ -1142,7 +1142,7 @@ class StockItem(MPTTModel):
)
@transaction.atomic
def uninstallIntoLocation(self, location, user, notes):
def uninstall_into_location(self, location, user, notes):
"""
Uninstall this stock item from another item, into a location.

View File

@ -448,6 +448,48 @@ class InstallStockItemSerializer(serializers.Serializer):
)
class UninstallStockItemSerializer(serializers.Serializer):
"""
API serializers for uninstalling an installed item from a stock item
"""
class Meta:
fields = [
'location',
'note',
]
location = serializers.PrimaryKeyRelatedField(
queryset=StockLocation.objects.all(),
many=False, required=True, allow_null=False,
label=_('Location'),
help_text=_('Destination location for uninstalled item')
)
note = serializers.CharField(
label=_('Notes'),
help_text=_('Add transaction note (optional)'),
required=False, allow_blank=True,
)
def save(self):
item = self.context['item']
data = self.validated_data
request = self.context['request']
location = data['location']
note = data.get('note', '')
item.uninstall_into_location(
location,
request.user,
note
)
class LocationTreeSerializer(InvenTree.serializers.InvenTreeModelSerializer):
"""
Serializer for a simple tree view

View File

@ -1,7 +0,0 @@
{% extends "modal_delete_form.html" %}
{% load i18n %}
{% block pre_form_content %}
{% trans "Are you sure you want to delete this attachment?" %}
<br>
{% endblock %}

View File

@ -159,9 +159,12 @@
</div>
</div>
<div class='panel-content'>
<div class='btn-group'>
<div id='installed-table-toolbar'>
<div class='btn-group' role='group'>
{% include "filter_list.html" with id='installed-items' %}
</div>
</div>
<table class='table table-striped table-condensed' id='installed-table'></table>
<table class='table table-striped table-condensed' id='installed-table' data-toolbar='#installed-table-toolbar'></table>
</div>
</div>
@ -207,28 +210,6 @@
quantity: {{ item.quantity|unlocalize }},
}
);
$('#multi-item-uninstall').click(function() {
var selections = $('#installed-table').bootstrapTable('getSelections');
var items = [];
selections.forEach(function(item) {
items.push(item.pk);
});
launchModalForm(
"{% url 'stock-item-uninstall' %}",
{
data: {
'items[]': items,
},
reload: true,
}
);
});
onPanelLoad('notes', function() {
setupNotesField(

View File

@ -445,12 +445,9 @@ $('#stock-install-in').click(function() {
$('#stock-uninstall').click(function() {
launchModalForm(
"{% url 'stock-item-uninstall' %}",
uninstallStockItem(
{{ item.pk }},
{
data: {
'items[]': [{{ item.pk }}],
},
reload: true,
}
);

View File

@ -1,28 +0,0 @@
{% extends "modal_form.html" %}
{% load i18n %}
{% load inventree_extras %}
{% block pre_form_content %}
<div class='alert alert-block alert-success'>
{% trans "The following stock items will be uninstalled" %}
</div>
<ul class='list-group'>
{% for item in stock_items %}
<li class='list-group-item'>
{% include "hover_image.html" with image=item.part.image hover=False %}
{{ item }}
</li>
{% endfor %}
</ul>
{% endblock %}
{% block form_data %}
{% for item in stock_items %}
<input type='hidden' name='stock-item-{{ item.pk }}' value='{{ item.pk }}'/>
{% endfor %}
{% endblock %}

View File

@ -43,8 +43,6 @@ stock_urls = [
# Stock location
re_path(r'^location/', include(location_urls)),
re_path(r'^item/uninstall/', views.StockItemUninstall.as_view(), name='stock-item-uninstall'),
re_path(r'^track/', include(stock_tracking_urls)),
# Individual stock items

View File

@ -5,38 +5,23 @@ Django views for interacting with Stock app
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.core.exceptions import ValidationError
from django.views.generic.edit import FormMixin
from django.views.generic import DetailView, ListView
from django.forms.models import model_to_dict
from django.forms import HiddenInput
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.utils.translation import gettext_lazy as _
from moneyed import CURRENCIES
from InvenTree.views import AjaxUpdateView, AjaxDeleteView, AjaxCreateView
from InvenTree.views import QRCodeView
from InvenTree.views import InvenTreeRoleMixin
from InvenTree.forms import ConfirmForm
from InvenTree.helpers import str2bool
from InvenTree.helpers import extract_serial_numbers
from decimal import Decimal, InvalidOperation
from datetime import datetime, timedelta
from company.models import SupplierPart
from part.models import Part
from .models import StockItem, StockLocation, StockItemTracking
import common.settings
from common.models import InvenTreeSetting
from users.models import Owner
from . import forms as StockForms

View File

@ -81,7 +81,7 @@ function renderStockItem(name, data, parameters={}, options={}) {
var part_detail = '';
if (render_part_detail) {
if (render_part_detail && data.part_detail) {
part_detail = `<img src='${image}' class='select2-thumbnail'><span>${data.part_detail.full_name}</span> - `;
}

View File

@ -57,6 +57,7 @@
stockItemFields,
stockLocationFields,
stockStatusCodes,
uninstallStockItem,
*/
@ -2630,13 +2631,10 @@ function loadInstalledInTable(table, options) {
table.find('.button-uninstall').click(function() {
var pk = $(this).attr('pk');
launchModalForm(
'{% url "stock-item-uninstall" %}',
uninstallStockItem(
pk,
{
data: {
'items[]': pk,
},
success: function() {
onSuccess: function(response) {
table.bootstrapTable('refresh');
}
}
@ -2647,6 +2645,43 @@ function loadInstalledInTable(table, options) {
}
/*
* Launch a dialog to uninstall a stock item from another stock item
*/
function uninstallStockItem(installed_item_id, options={}) {
constructForm(
`/api/stock/${installed_item_id}/uninstall/`,
{
confirm: true,
method: 'POST',
title: '{% trans "Uninstall Stock Item" %}',
fields: {
location: {
icon: 'fa-sitemap',
},
note: {},
},
preFormContent: function(opts) {
var html = '';
if (installed_item_id == null) {
html += `
<div class='alert alert-block alert-info'>
{% trans "Select stock item to uninstall" %}
</div>`;
}
return html;
},
onSuccess: function(response) {
handleFormSuccess(response, options);
}
}
);
}
/*
* Launch a dialog to install a stock item into another stock item
*/