diff --git a/InvenTree/order/models.py b/InvenTree/order/models.py
index 99c71d1c3e..248ecb277d 100644
--- a/InvenTree/order/models.py
+++ b/InvenTree/order/models.py
@@ -747,8 +747,15 @@ class PurchaseOrderLineItem(OrderLineItem):
)
def get_base_part(self):
- """ Return the base-part for the line item """
- return self.part.part
+ """
+ Return the base part.Part object for the line item
+
+ Note: Returns None if the SupplierPart is not set!
+ """
+ if self.part is None:
+ return None
+ else:
+ return self.part.part
# TODO - Function callback for when the SupplierPart is deleted?
diff --git a/InvenTree/order/templates/order/purchase_order_detail.html b/InvenTree/order/templates/order/purchase_order_detail.html
index 9746103c89..2e1ec0c39c 100644
--- a/InvenTree/order/templates/order/purchase_order_detail.html
+++ b/InvenTree/order/templates/order/purchase_order_detail.html
@@ -179,7 +179,11 @@ $("#po-table").inventreeTable({
field: 'supplier_part_detail.SKU',
title: '{% trans "SKU" %}',
formatter: function(value, row, index, field) {
- return renderLink(value, `/supplier-part/${row.part}/`);
+ if (value) {
+ return renderLink(value, `/supplier-part/${row.part}/`);
+ } else {
+ return '-';
+ }
},
},
{
@@ -188,7 +192,7 @@ $("#po-table").inventreeTable({
field: 'supplier_part_detail.MPN',
title: '{% trans "MPN" %}',
formatter: function(value, row, index, field) {
- if (row.supplier_part_detail.manufacturer_part) {
+ if (row.supplier_part_detail && row.supplier_part_detail.manufacturer_part) {
return renderLink(value, `/manufacturer-part/${row.supplier_part_detail.manufacturer_part.pk}/`);
} else {
return "";
diff --git a/InvenTree/templates/js/model_renderers.js b/InvenTree/templates/js/model_renderers.js
index 9e98199bfa..caa209dc90 100644
--- a/InvenTree/templates/js/model_renderers.js
+++ b/InvenTree/templates/js/model_renderers.js
@@ -1,5 +1,20 @@
{% load i18n %}
+
+function blankImage() {
+ return `/static/img/blank_image.png`;
+}
+
+// Render a select2 thumbnail image
+function select2Thumbnail(image) {
+ if (!image) {
+ image = blankImage();
+ }
+
+ return ``;
+}
+
+
/*
* This file contains functions for rendering various InvenTree database models,
* in particular for displaying them in modal forms in a 'select2' context.
@@ -15,8 +30,10 @@
// Renderer for "Company" model
function renderCompany(name, data, parameters, options) {
+
+ var html = select2Thumbnail(data.image);
- var html = `${data.name} - ${data.description}`;
+ html += `${data.name} - ${data.description}`;
html += `{% trans "Company ID" %}: ${data.pk}`;
@@ -27,11 +44,7 @@ function renderCompany(name, data, parameters, options) {
// Renderer for "StockItem" model
function renderStockItem(name, data, parameters, options) {
- var image = data.part_detail.thumbnail || data.part_detail.image;
-
- if (!image) {
- image = `/static/img/blank_image.png`;
- }
+ var image = data.part_detail.thumbnail || data.part_detail.image || blankImage();
var html = ``;
@@ -72,15 +85,13 @@ function renderStockLocation(name, data, parameters, options) {
function renderBuild(name, data, parameters, options) {
- var image = '';
+ var image = null;
if (data.part_detail && data.part_detail.thumbnail) {
image = data.part_detail.thumbnail;
- } else {
- image = `/static/img/blank_image.png`;
- }
+ }
- var html = ``;
+ var html = select2Thumbnail(image);
html += `${data.reference} - ${data.quantity} x ${data.part_detail.full_name}`;
html += `{% trans "Build ID" %}: ${data.pk}`;
@@ -94,13 +105,7 @@ function renderBuild(name, data, parameters, options) {
// Renderer for "Part" model
function renderPart(name, data, parameters, options) {
- var image = data.image;
-
- if (!image) {
- image = `/static/img/blank_image.png`;
- }
-
- var html = ``;
+ var html = select2Thumbnail(data.image);
html += ` ${data.full_name || data.name}`;
@@ -131,7 +136,6 @@ function renderOwner(name, data, parameters, options) {
var html = `${data.name}`;
-
switch (data.label) {
case 'user':
html += ``;
@@ -177,13 +181,21 @@ function renderPartParameterTemplate(name, data, parameters, options) {
// Rendered for "SupplierPart" model
function renderSupplierPart(name, data, parameters, options) {
- var image = data.supplier_detail.image;
-
- if (!image) {
- image = `/static/img/blank_image.png`;
+ var supplier_image = null;
+ var part_image = null;
+
+ if (data.supplier_detail) {
+ supplier_image = data.supplier_detail.image;
}
- var html = ``;
+ if (data.part_detail) {
+ part_image = data.part_detail.thumbnail || data.part_detail.image;
+ }
+
+ var html = '';
+
+ html += select2Thumbnail(supplier_image);
+ html += select2Thumbnail(part_image);
html += ` ${data.supplier_detail.name} - ${data.SKU}`;
html += ` - ${data.part_detail.full_name}`;
@@ -193,4 +205,4 @@ function renderSupplierPart(name, data, parameters, options) {
return html;
-}
\ No newline at end of file
+}
diff --git a/InvenTree/templates/js/stock.js b/InvenTree/templates/js/stock.js
index 948c0ff768..524b116743 100644
--- a/InvenTree/templates/js/stock.js
+++ b/InvenTree/templates/js/stock.js
@@ -696,7 +696,14 @@ function loadStockTable(table, options) {
}
var link = `/supplier-part/${row.supplier_part}/stock/`;
- var text = `${row.supplier_part_detail.SKU}`;
+
+ var text = '';
+
+ if (row.supplier_part_detail) {
+ text = `${row.supplier_part_detail.SKU}`;
+ } else {
+ text = `{% trans "Supplier part not specified" %}`;
+ }
return renderLink(text, link);
}