mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Add notes to mp and sp (#7667)
* add notes to mp and sp * bump api version
This commit is contained in:
parent
b783f521de
commit
453254c278
@ -1,12 +1,15 @@
|
|||||||
"""InvenTree API version information."""
|
"""InvenTree API version information."""
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 223
|
INVENTREE_API_VERSION = 224
|
||||||
|
|
||||||
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
"""Increment this API version number whenever there is a significant change to the API that any clients need to know about."""
|
||||||
|
|
||||||
|
|
||||||
INVENTREE_API_TEXT = """
|
INVENTREE_API_TEXT = """
|
||||||
|
v224 - 2024-07-14 : https://github.com/inventree/InvenTree/pull/7667
|
||||||
|
- Add notes field to ManufacturerPart and SupplierPart API endpoints
|
||||||
|
|
||||||
v223 - 2024-07-14 : https://github.com/inventree/InvenTree/pull/7649
|
v223 - 2024-07-14 : https://github.com/inventree/InvenTree/pull/7649
|
||||||
- Allow adjustment of "packaging" field when receiving items against a purchase order
|
- Allow adjustment of "packaging" field when receiving items against a purchase order
|
||||||
|
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 4.2.11 on 2024-07-16 12:58
|
||||||
|
|
||||||
|
import InvenTree.fields
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('company', '0070_remove_manufacturerpartattachment_manufacturer_part_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='manufacturerpart',
|
||||||
|
name='notes',
|
||||||
|
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Markdown notes (optional)', max_length=50000, null=True, verbose_name='Notes'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='supplierpart',
|
||||||
|
name='notes',
|
||||||
|
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Markdown notes (optional)', max_length=50000, null=True, verbose_name='Notes'),
|
||||||
|
),
|
||||||
|
]
|
@ -451,6 +451,7 @@ class Address(InvenTree.models.InvenTreeModel):
|
|||||||
class ManufacturerPart(
|
class ManufacturerPart(
|
||||||
InvenTree.models.InvenTreeAttachmentMixin,
|
InvenTree.models.InvenTreeAttachmentMixin,
|
||||||
InvenTree.models.InvenTreeBarcodeMixin,
|
InvenTree.models.InvenTreeBarcodeMixin,
|
||||||
|
InvenTree.models.InvenTreeNotesMixin,
|
||||||
InvenTree.models.InvenTreeMetadataModel,
|
InvenTree.models.InvenTreeMetadataModel,
|
||||||
):
|
):
|
||||||
"""Represents a unique part as provided by a Manufacturer Each ManufacturerPart is identified by a MPN (Manufacturer Part Number) Each ManufacturerPart is also linked to a Part object. A Part may be available from multiple manufacturers.
|
"""Represents a unique part as provided by a Manufacturer Each ManufacturerPart is identified by a MPN (Manufacturer Part Number) Each ManufacturerPart is also linked to a Part object. A Part may be available from multiple manufacturers.
|
||||||
@ -624,6 +625,7 @@ class SupplierPartManager(models.Manager):
|
|||||||
class SupplierPart(
|
class SupplierPart(
|
||||||
InvenTree.models.MetadataMixin,
|
InvenTree.models.MetadataMixin,
|
||||||
InvenTree.models.InvenTreeBarcodeMixin,
|
InvenTree.models.InvenTreeBarcodeMixin,
|
||||||
|
InvenTree.models.InvenTreeNotesMixin,
|
||||||
common.models.MetaMixin,
|
common.models.MetaMixin,
|
||||||
InvenTree.models.InvenTreeModel,
|
InvenTree.models.InvenTreeModel,
|
||||||
):
|
):
|
||||||
|
@ -213,7 +213,7 @@ class ContactSerializer(DataImportExportSerializerMixin, InvenTreeModelSerialize
|
|||||||
|
|
||||||
@register_importer()
|
@register_importer()
|
||||||
class ManufacturerPartSerializer(
|
class ManufacturerPartSerializer(
|
||||||
DataImportExportSerializerMixin, InvenTreeTagModelSerializer
|
DataImportExportSerializerMixin, InvenTreeTagModelSerializer, NotesFieldMixin
|
||||||
):
|
):
|
||||||
"""Serializer for ManufacturerPart object."""
|
"""Serializer for ManufacturerPart object."""
|
||||||
|
|
||||||
@ -232,6 +232,7 @@ class ManufacturerPartSerializer(
|
|||||||
'MPN',
|
'MPN',
|
||||||
'link',
|
'link',
|
||||||
'barcode_hash',
|
'barcode_hash',
|
||||||
|
'notes',
|
||||||
'tags',
|
'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -305,7 +306,7 @@ class ManufacturerPartParameterSerializer(
|
|||||||
|
|
||||||
@register_importer()
|
@register_importer()
|
||||||
class SupplierPartSerializer(
|
class SupplierPartSerializer(
|
||||||
DataImportExportSerializerMixin, InvenTreeTagModelSerializer
|
DataImportExportSerializerMixin, InvenTreeTagModelSerializer, NotesFieldMixin
|
||||||
):
|
):
|
||||||
"""Serializer for SupplierPart object."""
|
"""Serializer for SupplierPart object."""
|
||||||
|
|
||||||
@ -340,6 +341,7 @@ class SupplierPartSerializer(
|
|||||||
'supplier_detail',
|
'supplier_detail',
|
||||||
'url',
|
'url',
|
||||||
'updated',
|
'updated',
|
||||||
|
'notes',
|
||||||
'tags',
|
'tags',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -171,11 +171,40 @@ src="{% static 'img/blank_image.png' %}"
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='panel panel-hidden' id='panel-manufacturer-part-notes'>
|
||||||
|
<div class='panel-heading'>
|
||||||
|
<div class='d-flex flex-wrap'>
|
||||||
|
<h4>{% trans "Manufacturer Part Notes" %}</h4>
|
||||||
|
{% include "spacer.html" %}
|
||||||
|
<div class='btn-group' role='group'>
|
||||||
|
{% include "notes_buttons.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='panel-content'>
|
||||||
|
<textarea id='manufacturer-part-notes'></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
||||||
|
|
||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
|
// Load the "notes" tab
|
||||||
|
onPanelLoad('manufacturer-part-notes', function() {
|
||||||
|
|
||||||
|
setupNotesField(
|
||||||
|
'manufacturer-part-notes',
|
||||||
|
'{% url "api-manufacturer-part-detail" part.pk %}',
|
||||||
|
{
|
||||||
|
model_type: "manufacturerpart",
|
||||||
|
model_id: {{ part.pk }},
|
||||||
|
editable: {% js_bool roles.purchase_order.change %},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
onPanelLoad("attachments", function() {
|
onPanelLoad("attachments", function() {
|
||||||
loadAttachmentTable('manufacturerpart', {{ part.pk }});
|
loadAttachmentTable('manufacturerpart', {{ part.pk }});
|
||||||
});
|
});
|
||||||
|
@ -8,3 +8,5 @@
|
|||||||
{% include "sidebar_item.html" with label='supplier-parts' text=text icon="fa-building" %}
|
{% include "sidebar_item.html" with label='supplier-parts' text=text icon="fa-building" %}
|
||||||
{% trans "Attachments" as text %}
|
{% trans "Attachments" as text %}
|
||||||
{% include "sidebar_item.html" with label='attachments' text=text icon="fa-paperclip" %}
|
{% include "sidebar_item.html" with label='attachments' text=text icon="fa-paperclip" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="manufacturer-part-notes" text=text icon="fa-clipboard" %}
|
||||||
|
@ -264,11 +264,40 @@ src="{% static 'img/blank_image.png' %}"
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class='panel panel-hidden' id='panel-supplier-part-notes'>
|
||||||
|
<div class='panel-heading'>
|
||||||
|
<div class='d-flex flex-wrap'>
|
||||||
|
<h4>{% trans "Supplier Part Notes" %}</h4>
|
||||||
|
{% include "spacer.html" %}
|
||||||
|
<div class='btn-group' role='group'>
|
||||||
|
{% include "notes_buttons.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class='panel-content'>
|
||||||
|
<textarea id='supplier-part-notes'></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock page_content %}
|
{% endblock page_content %}
|
||||||
|
|
||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
|
// Load the "notes" tab
|
||||||
|
onPanelLoad('supplier-part-notes', function() {
|
||||||
|
|
||||||
|
setupNotesField(
|
||||||
|
'supplier-part-notes',
|
||||||
|
'{% url "api-supplier-part-detail" part.pk %}',
|
||||||
|
{
|
||||||
|
model_type: "supplierpart",
|
||||||
|
model_id: {{ part.pk }},
|
||||||
|
editable: {% js_bool roles.purchase_order.change %},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
{% if barcodes %}
|
{% if barcodes %}
|
||||||
|
|
||||||
$("#show-qr-code").click(function() {
|
$("#show-qr-code").click(function() {
|
||||||
|
@ -8,3 +8,5 @@
|
|||||||
{% include "sidebar_item.html" with label='purchase-orders' text=text icon="fa-shopping-cart" %}
|
{% include "sidebar_item.html" with label='purchase-orders' text=text icon="fa-shopping-cart" %}
|
||||||
{% trans "Supplier Part Pricing" as text %}
|
{% trans "Supplier Part Pricing" as text %}
|
||||||
{% include "sidebar_item.html" with label='pricing' text=text icon="fa-dollar-sign" %}
|
{% include "sidebar_item.html" with label='pricing' text=text icon="fa-dollar-sign" %}
|
||||||
|
{% trans "Notes" as text %}
|
||||||
|
{% include "sidebar_item.html" with label="supplier-part-notes" text=text icon="fa-clipboard" %}
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
IconDots,
|
IconDots,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
IconList,
|
IconList,
|
||||||
|
IconNotes,
|
||||||
IconPaperclip
|
IconPaperclip
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
@ -14,6 +15,7 @@ import AdminButton from '../../components/buttons/AdminButton';
|
|||||||
import { DetailsField, DetailsTable } from '../../components/details/Details';
|
import { DetailsField, DetailsTable } from '../../components/details/Details';
|
||||||
import { DetailsImage } from '../../components/details/DetailsImage';
|
import { DetailsImage } from '../../components/details/DetailsImage';
|
||||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||||
|
import NotesEditor from '../../components/editors/NotesEditor';
|
||||||
import {
|
import {
|
||||||
ActionDropdown,
|
ActionDropdown,
|
||||||
DeleteItemAction,
|
DeleteItemAction,
|
||||||
@ -179,6 +181,18 @@ export default function ManufacturerPartDetail() {
|
|||||||
model_id={manufacturerPart?.pk}
|
model_id={manufacturerPart?.pk}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'notes',
|
||||||
|
label: t`Notes`,
|
||||||
|
icon: <IconNotes />,
|
||||||
|
content: (
|
||||||
|
<NotesEditor
|
||||||
|
modelType={ModelType.manufacturerpart}
|
||||||
|
modelId={manufacturerPart.pk}
|
||||||
|
editable={user.hasChangeRole(UserRoles.purchase_order)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}, [manufacturerPart]);
|
}, [manufacturerPart]);
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
IconCurrencyDollar,
|
IconCurrencyDollar,
|
||||||
IconDots,
|
IconDots,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
|
IconNotes,
|
||||||
IconPackages,
|
IconPackages,
|
||||||
IconShoppingCart
|
IconShoppingCart
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
@ -15,6 +16,7 @@ import { DetailsField, DetailsTable } from '../../components/details/Details';
|
|||||||
import DetailsBadge from '../../components/details/DetailsBadge';
|
import DetailsBadge from '../../components/details/DetailsBadge';
|
||||||
import { DetailsImage } from '../../components/details/DetailsImage';
|
import { DetailsImage } from '../../components/details/DetailsImage';
|
||||||
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
import { ItemDetailsGrid } from '../../components/details/ItemDetails';
|
||||||
|
import NotesEditor from '../../components/editors/NotesEditor';
|
||||||
import {
|
import {
|
||||||
ActionDropdown,
|
ActionDropdown,
|
||||||
DeleteItemAction,
|
DeleteItemAction,
|
||||||
@ -240,6 +242,18 @@ export default function SupplierPartDetail() {
|
|||||||
) : (
|
) : (
|
||||||
<Skeleton />
|
<Skeleton />
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'notes',
|
||||||
|
label: t`Notes`,
|
||||||
|
icon: <IconNotes />,
|
||||||
|
content: (
|
||||||
|
<NotesEditor
|
||||||
|
modelType={ModelType.supplierpart}
|
||||||
|
modelId={supplierPart.pk}
|
||||||
|
editable={user.hasChangeRole(UserRoles.purchase_order)}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}, [supplierPart]);
|
}, [supplierPart]);
|
||||||
|
Loading…
Reference in New Issue
Block a user