Added global setting to enable manufacturer parts

Created SourceItem model
Updated templates
This commit is contained in:
eeintech 2021-03-29 13:22:15 -04:00
parent cbb887ae79
commit e6dfb7da52
8 changed files with 89 additions and 14 deletions

View File

@ -202,6 +202,13 @@ class InvenTreeSetting(models.Model):
'validator': bool, 'validator': bool,
}, },
'PART_ENABLE_MANUFACTURER_PARTS': {
'name': _('Enable Manufacturer Parts'),
'description': _('Enable the use of manufacturer parts for purchasing'),
'default': False,
'validator': bool,
},
'REPORT_DEBUG_MODE': { 'REPORT_DEBUG_MODE': {
'name': _('Debug Mode'), 'name': _('Debug Mode'),
'description': _('Generate reports in debug mode (HTML output)'), 'description': _('Generate reports in debug mode (HTML output)'),

View File

@ -130,7 +130,7 @@ class ManufacturerPartList(generics.ListCreateAPIView):
params = self.request.query_params params = self.request.query_params
# Filter by manufacturer # Filter by manufacturer
manufacturer = params.get('manufacturer', None) manufacturer = params.get('company', None)
if manufacturer is not None: if manufacturer is not None:
queryset = queryset.filter(manufacturer=manufacturer) queryset = queryset.filter(manufacturer=manufacturer)

View File

@ -0,0 +1,33 @@
# Generated by Django 3.0.7 on 2021-03-29 17:00
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('company', '0032_manufacturerpart'),
]
operations = [
migrations.CreateModel(
name='SourceItem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('part_id', models.PositiveIntegerField()),
('part_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
],
),
migrations.AddField(
model_name='manufacturerpart',
name='source_item',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='manufacturer_parts', to='company.SourceItem', verbose_name='Sourcing Item'),
),
migrations.AddField(
model_name='supplierpart',
name='source_item',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='supplier_parts', to='company.SourceItem', verbose_name='Sourcing Item'),
),
]

View File

@ -13,6 +13,8 @@ from django.utils.translation import gettext_lazy as _
from django.core.validators import MinValueValidator from django.core.validators import MinValueValidator
from django.db import models from django.db import models
from django.db.models import Sum, Q, UniqueConstraint from django.db.models import Sum, Q, UniqueConstraint
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.apps import apps from django.apps import apps
from django.urls import reverse from django.urls import reverse
@ -278,6 +280,20 @@ class Contact(models.Model):
on_delete=models.CASCADE) on_delete=models.CASCADE)
class SourceItem(models.Model):
""" This model allows flexibility for sourcing of InvenTree parts.
Each SourceItem instance represents a single ManufacturerPart or
SupplierPart instance.
SourceItem can be linked to either Part or ManufacturerPart instances.
"""
part_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
part_id = models.PositiveIntegerField()
part = GenericForeignKey('part_type', 'part_id')
class ManufacturerPart(models.Model): class ManufacturerPart(models.Model):
""" Represents a unique part as provided by a Manufacturer """ Represents a unique part as provided by a Manufacturer
Each ManufacturerPart is identified by a MPN (Manufacturer Part Number) Each ManufacturerPart is identified by a MPN (Manufacturer Part Number)
@ -286,6 +302,7 @@ class ManufacturerPart(models.Model):
Attributes: Attributes:
part: Link to the master Part part: Link to the master Part
source_item: The sourcing item linked to this ManufacturerPart instance
manufacturer: Company that manufactures the ManufacturerPart manufacturer: Company that manufactures the ManufacturerPart
MPN: Manufacture part number MPN: Manufacture part number
link: Link to external website for this manufacturer part link: Link to external website for this manufacturer part
@ -304,6 +321,12 @@ class ManufacturerPart(models.Model):
help_text=_('Select part'), help_text=_('Select part'),
) )
source_item = models.ForeignKey(SourceItem, on_delete=models.CASCADE,
blank=True, null=True,
related_name='manufacturer_parts',
verbose_name=_('Sourcing Item'),
)
manufacturer = models.ForeignKey( manufacturer = models.ForeignKey(
Company, Company,
on_delete=models.CASCADE, on_delete=models.CASCADE,
@ -341,8 +364,8 @@ class SupplierPart(models.Model):
A Part may be available from multiple suppliers A Part may be available from multiple suppliers
Attributes: Attributes:
part_type: Part or ManufacturerPart part: Link to the master Part
part_id: Part or ManufacturerPart ID source_item: The sourcing item linked to this SupplierPart instance
supplier: Company that supplies this SupplierPart object supplier: Company that supplies this SupplierPart object
SKU: Stock keeping unit (supplier part number) SKU: Stock keeping unit (supplier part number)
link: Link to external website for this supplier part link: Link to external website for this supplier part
@ -372,6 +395,12 @@ class SupplierPart(models.Model):
help_text=_('Select part'), help_text=_('Select part'),
) )
source_item = models.ForeignKey(SourceItem, on_delete=models.CASCADE,
blank=True, null=True,
related_name='supplier_parts',
verbose_name=_('Sourcing Item'),
)
supplier = models.ForeignKey(Company, on_delete=models.CASCADE, supplier = models.ForeignKey(Company, on_delete=models.CASCADE,
related_name='supplied_parts', related_name='supplied_parts',
limit_choices_to={'is_supplier': True}, limit_choices_to={'is_supplier': True},

View File

@ -1,6 +1,7 @@
{% extends "company/company_base.html" %} {% extends "company/company_base.html" %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% load inventree_extras %}
{% block menubar %} {% block menubar %}
{% include 'company/navbar.html' with tab='parts' %} {% include 'company/navbar.html' with tab='parts' %}
@ -12,17 +13,18 @@
{% block details %} {% block details %}
{% setting_object 'PART_ENABLE_MANUFACTURER_PARTS' as manufacturer_parts %}
{% if roles.purchase_order.change %} {% if roles.purchase_order.change %}
<div id='button-toolbar'> <div id='button-toolbar'>
<div class='button-toolbar container-fluid'> <div class='button-toolbar container-fluid'>
<div class='btn-group role='group'> <div class='btn-group role='group'>
{% if roles.purchase_order.add %} {% if roles.purchase_order.add %}
{% if company.is_manufacturer %} {% if manufacturer_parts.value == "True" and company.is_manufacturer %}
<button class="btn btn-success" id='manufacturer-part-create' title='{% trans "Create new manufacturer part" %}'> <button class="btn btn-success" id='manufacturer-part-create' title='{% trans "Create new manufacturer part" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Manufacturer Part" %} <span class='fas fa-plus-circle'></span> {% trans "New Manufacturer Part" %}
</button> </button>
{% endif %} {% else %}
{% if company.is_supplier %}
<button class="btn btn-success" id='supplier-part-create' title='{% trans "Create new supplier part" %}'> <button class="btn btn-success" id='supplier-part-create' title='{% trans "Create new supplier part" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %} <span class='fas fa-plus-circle'></span> {% trans "New Supplier Part" %}
</button> </button>
@ -57,6 +59,7 @@
{% endblock %} {% endblock %}
{% block js_ready %} {% block js_ready %}
{{ block.super }} {{ block.super }}
{% setting_object 'PART_ENABLE_MANUFACTURER_PARTS' as manufacturer_parts %}
$("#manufacturer-part-create").click(function () { $("#manufacturer-part-create").click(function () {
launchModalForm( launchModalForm(
@ -108,7 +111,7 @@
}); });
}); });
{% if company.is_manufacturer %} {% if manufacturer_parts.value == "True" and company.is_manufacturer %}
loadManufacturerPartTable( loadManufacturerPartTable(
"#part-table", "#part-table",
"{% url 'api-manufacturer-part-list' %}", "{% url 'api-manufacturer-part-list' %}",
@ -120,9 +123,7 @@
}, },
} }
); );
{% endif %} {% else %}
{% if company.is_supplier %}
loadSupplierPartTable( loadSupplierPartTable(
"#part-table", "#part-table",
"{% url 'api-supplier-part-list' %}", "{% url 'api-supplier-part-list' %}",

View File

@ -2,6 +2,8 @@
{% load static %} {% load static %}
{% load inventree_extras %} {% load inventree_extras %}
{% setting_object 'PART_ENABLE_MANUFACTURER_PARTS' as manufacturer_parts %}
<ul class='list-group'> <ul class='list-group'>
<li class='list-group-item'> <li class='list-group-item'>
<a href='#' id='company-menu-toggle'> <a href='#' id='company-menu-toggle'>
@ -16,16 +18,14 @@
</a> </a>
</li> </li>
{% if company.is_manufacturer %} {% if manufacturer_parts.value == "True" and company.is_manufacturer %}
<li class='list-group-item {% if tab == "parts" %}active{% endif %}' title='{% trans "Manufactured Parts" %}'> <li class='list-group-item {% if tab == "parts" %}active{% endif %}' title='{% trans "Manufactured Parts" %}'>
<a href='{% url "company-detail-parts" company.id %}'> <a href='{% url "company-detail-parts" company.id %}'>
<span class='fas fa-shapes'></span> <span class='fas fa-shapes'></span>
{% trans "Parts" %} {% trans "Parts" %}
</a> </a>
</li> </li>
{% endif %} {% else %}
{% if company.is_supplier %}
<li class='list-group-item {% if tab == "parts" %}active{% endif %}' title='{% trans "Supplied Parts" %}'> <li class='list-group-item {% if tab == "parts" %}active{% endif %}' title='{% trans "Supplied Parts" %}'>
<a href='{% url "company-detail-parts" company.id %}'> <a href='{% url "company-detail-parts" company.id %}'>
<span class='fas fa-shapes'></span> <span class='fas fa-shapes'></span>

View File

@ -68,13 +68,16 @@
</a> </a>
</li> </li>
{% endif %} {% endif %}
{% setting_object 'PART_ENABLE_MANUFACTURER_PARTS' as manufacturer_parts %}
{% if part.purchaseable and roles.purchase_order.view %} {% if part.purchaseable and roles.purchase_order.view %}
{% if manufacturer_parts.value == "True" %}
<li class='list-group-item {% if tab == "manufacturers" %}active{% endif %}' title='{% trans "Manufacturers" %}'> <li class='list-group-item {% if tab == "manufacturers" %}active{% endif %}' title='{% trans "Manufacturers" %}'>
<a href='{% url "part-manufacturers" part.id %}'> <a href='{% url "part-manufacturers" part.id %}'>
<span class='menu-tab-icon fas fa-building'></span> <span class='menu-tab-icon fas fa-building'></span>
{% trans "Manufacturers" %} {% trans "Manufacturers" %}
</a> </a>
</li> </li>
{% endif %}
<li class='list-group-item {% if tab == "suppliers" %}active{% endif %}' title='{% trans "Suppliers" %}'> <li class='list-group-item {% if tab == "suppliers" %}active{% endif %}' title='{% trans "Suppliers" %}'>
<a href='{% url "part-suppliers" part.id %}'> <a href='{% url "part-suppliers" part.id %}'>
<span class='menu-tab-icon fas fa-warehouse'></span> <span class='menu-tab-icon fas fa-warehouse'></span>

View File

@ -34,6 +34,8 @@
{% include "InvenTree/settings/setting.html" with key="PART_COPY_PARAMETERS" %} {% include "InvenTree/settings/setting.html" with key="PART_COPY_PARAMETERS" %}
{% include "InvenTree/settings/setting.html" with key="PART_COPY_TESTS" %} {% include "InvenTree/settings/setting.html" with key="PART_COPY_TESTS" %}
{% include "InvenTree/settings/setting.html" with key="PART_CATEGORY_PARAMETERS" %} {% include "InvenTree/settings/setting.html" with key="PART_CATEGORY_PARAMETERS" %}
<tr><td colspan='5'></td></tr>
{% include "InvenTree/settings/setting.html" with key="PART_ENABLE_MANUFACTURER_PARTS" %}
</tbody> </tbody>
</table> </table>