2
0
mirror of https://github.com/inventree/InvenTree.git synced 2026-05-23 09:35:30 +00:00

Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters
2022-06-21 16:57:10 +10:00
62 changed files with 26392 additions and 26117 deletions
+16
View File
@@ -157,3 +157,19 @@ class RoundingDecimalField(models.DecimalField):
defaults.update(kwargs) defaults.update(kwargs)
return super().formfield(**kwargs) return super().formfield(**kwargs)
class InvenTreeNotesField(models.TextField):
"""Custom implementation of a 'notes' field"""
# Maximum character limit for the various 'notes' fields
NOTES_MAX_LENGTH = 50000
def __init__(self, **kwargs):
"""Configure default initial values for this field"""
kwargs['max_length'] = self.NOTES_MAX_LENGTH
kwargs['verbose_name'] = _('Notes')
kwargs['blank'] = True
kwargs['null'] = True
super().__init__(**kwargs)
-6
View File
@@ -15,7 +15,6 @@ import random
import socket import socket
import string import string
import sys import sys
from datetime import datetime
import django.conf.locale import django.conf.locale
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
@@ -253,7 +252,6 @@ INSTALLED_APPS = [
'import_export', # Import / export tables to file 'import_export', # Import / export tables to file
'django_cleanup.apps.CleanupConfig', # Automatically delete orphaned MEDIA files 'django_cleanup.apps.CleanupConfig', # Automatically delete orphaned MEDIA files
'mptt', # Modified Preorder Tree Traversal 'mptt', # Modified Preorder Tree Traversal
'markdownx', # Markdown editing
'markdownify', # Markdown template rendering 'markdownify', # Markdown template rendering
'django_admin_shell', # Python shell for the admin interface 'django_admin_shell', # Python shell for the admin interface
'djmoney', # django-money integration 'djmoney', # django-money integration
@@ -875,10 +873,6 @@ ACCOUNT_ADAPTER = 'InvenTree.forms.CustomAccountAdapter'
REMOTE_LOGIN = get_setting('INVENTREE_REMOTE_LOGIN', CONFIG.get('remote_login', False)) REMOTE_LOGIN = get_setting('INVENTREE_REMOTE_LOGIN', CONFIG.get('remote_login', False))
REMOTE_LOGIN_HEADER = get_setting('INVENTREE_REMOTE_LOGIN_HEADER', CONFIG.get('remote_login_header', 'REMOTE_USER')) REMOTE_LOGIN_HEADER = get_setting('INVENTREE_REMOTE_LOGIN_HEADER', CONFIG.get('remote_login_header', 'REMOTE_USER'))
# Markdownx configuration
# Ref: https://neutronx.github.io/django-markdownx/customization/
MARKDOWNX_MEDIA_PATH = datetime.now().strftime('markdownx/%Y/%m/%d')
# Markdownify configuration # Markdownify configuration
# Ref: https://django-markdownify.readthedocs.io/en/latest/settings.html # Ref: https://django-markdownify.readthedocs.io/en/latest/settings.html
@@ -3539,15 +3539,6 @@ a.ui-button:active,
.index-action-selected { .index-action-selected {
background-color: rgb(32, 34, 36); background-color: rgb(32, 34, 36);
} }
.markdownx .row {
border-color: rgb(31, 31, 92);
}
.markdownx-editor {
border-color: rgb(31, 31, 92);
}
.markdownx-preview {
border-color: rgb(31, 31, 92);
}
.progress { .progress {
background-image: initial; background-image: initial;
background-color: rgb(32, 34, 36); background-color: rgb(32, 34, 36);
@@ -63,30 +63,10 @@ main {
background-color: #EEEEF5; background-color: #EEEEF5;
} }
.markdownx .row {
margin: 5px;
padding: 5px;
border: 1px solid #cce;
border-radius: 4px;
}
.markdownx-editor {
width: 100%;
border: 1px solid #cce;
border-radius: 3px;
padding: 10px;
}
.panel-content { .panel-content {
padding: 10px; padding: 10px;
} }
.markdownx-preview {
border: 1px solid #cce;
border-radius: 3px;
padding: 10px;
}
/* Progress bars */ /* Progress bars */
.progress { .progress {
-3
View File
@@ -126,9 +126,6 @@ backendpatterns = [
re_path(r'^api/', include(apipatterns)), re_path(r'^api/', include(apipatterns)),
re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')), re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')),
# 3rd party endpoints
re_path(r'^markdownx/', include('markdownx.urls')),
] ]
frontendpatterns = [ frontendpatterns = [
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-01 12:47 # Generated by Django 2.2.9 on 2020-02-01 12:47
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='build', model_name='build',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes'), field=models.TextField(blank=True, help_text='Extra build notes'),
), ),
] ]
@@ -4,7 +4,6 @@ import InvenTree.fields
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
import mptt.fields import mptt.fields
@@ -31,7 +30,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='build', model_name='build',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Extra build notes', verbose_name='Notes'), field=models.TextField(blank=True, help_text='Extra build notes', verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='build', model_name='build',
@@ -0,0 +1,19 @@
# Generated by Django 3.2.13 on 2022-06-20 07:28
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('build', '0034_alter_build_reference_int'),
]
operations = [
migrations.AlterField(
model_name='build',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Extra build notes', max_length=50000, null=True, verbose_name='Notes'),
),
]
+2 -5
View File
@@ -16,8 +16,6 @@ from django.dispatch.dispatcher import receiver
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from markdownx.models import MarkdownxField
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
from mptt.exceptions import InvalidMove from mptt.exceptions import InvalidMove
@@ -320,9 +318,8 @@ class Build(MPTTModel, ReferenceIndexingMixin):
blank=True, help_text=_('Link to external URL') blank=True, help_text=_('Link to external URL')
) )
notes = MarkdownxField( notes = InvenTree.fields.InvenTreeNotesField(
verbose_name=_('Notes'), help_text=_('Extra build notes')
blank=True, help_text=_('Extra build notes')
) )
def sub_builds(self, cascade=True): def sub_builds(self, cascade=True):
+2 -7
View File
@@ -275,13 +275,8 @@
</div> </div>
{% if build.has_tracked_bom_items %} {% if build.has_tracked_bom_items %}
<button id='outputs-expand' class='btn btn-outline-secondary' type='button' title='{% trans "Expand all build output rows" %}'> {% include "expand_rows.html" with label="outputs" %}
<span class='fas fa-expand'></span> {% include "collapse_rows.html" with label="outputs" %}
</button>
<button id='outputs-collapse' class='btn btn-outline-secondary' type='button' title='{% trans "Collapse all build output rows" %}'>
<span class='fas fa-compress'></span>
</button>
{% endif %} {% endif %}
{% include "filter_list.html" with id='incompletebuilditems' %} {% include "filter_list.html" with id='incompletebuilditems' %}
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-01 12:31 # Generated by Django 2.2.9 on 2020-02-01 12:31
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='company', model_name='company',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True), field=models.TextField(blank=True),
), ),
] ]
@@ -5,7 +5,6 @@ import company.models
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
import stdimage.models import stdimage.models
@@ -44,7 +43,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='company', model_name='company',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, verbose_name='Notes'), field=models.TextField(blank=True, verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='supplierpart', model_name='supplierpart',
@@ -0,0 +1,19 @@
# Generated by Django 3.2.13 on 2022-06-20 11:23
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('company', '0044_auto_20220607_2204'),
]
operations = [
migrations.AlterField(
model_name='company',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Company Notes', max_length=50000, null=True, verbose_name='Notes'),
),
]
+2 -2
View File
@@ -11,12 +11,12 @@ from django.db.models import Q, Sum, UniqueConstraint
from django.urls import reverse from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from markdownx.models import MarkdownxField
from moneyed import CURRENCIES from moneyed import CURRENCIES
from stdimage.models import StdImageField from stdimage.models import StdImageField
import common.models import common.models
import common.settings import common.settings
import InvenTree.fields
import InvenTree.validators import InvenTree.validators
from common.settings import currency_code_default from common.settings import currency_code_default
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeURLField
@@ -135,7 +135,7 @@ class Company(models.Model):
verbose_name=_('Image'), verbose_name=_('Image'),
) )
notes = MarkdownxField(blank=True, verbose_name=_('Notes')) notes = InvenTree.fields.InvenTreeNotesField(help_text=_("Company Notes"))
is_customer = models.BooleanField(default=False, verbose_name=_('is customer'), help_text=_('Do you sell items to this company?')) is_customer = models.BooleanField(default=False, verbose_name=_('is customer'), help_text=_('Do you sell items to this company?'))
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-01 23:46 # Generated by Django 2.2.9 on 2020-02-01 23:46
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='purchaseorder', model_name='purchaseorder',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes'), field=models.TextField(blank=True, help_text='Order notes'),
), ),
] ]
@@ -6,7 +6,6 @@ from django.conf import settings
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -29,7 +28,7 @@ class Migration(migrations.Migration):
('status', models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Placed'), (30, 'Complete'), (40, 'Cancelled'), (50, 'Lost'), (60, 'Returned')], default=10, help_text='Order status')), ('status', models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Placed'), (30, 'Complete'), (40, 'Cancelled'), (50, 'Lost'), (60, 'Returned')], default=10, help_text='Order status')),
('issue_date', models.DateField(blank=True, null=True)), ('issue_date', models.DateField(blank=True, null=True)),
('complete_date', models.DateField(blank=True, null=True)), ('complete_date', models.DateField(blank=True, null=True)),
('notes', markdownx.models.MarkdownxField(blank=True, help_text='Order notes')), ('notes', models.TextField(blank=True, help_text='Order notes')),
('customer_reference', models.CharField(blank=True, help_text='Customer order reference code', max_length=64)), ('customer_reference', models.CharField(blank=True, help_text='Customer order reference code', max_length=64)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('customer', models.ForeignKey(help_text='Customer', limit_choices_to={True, 'is_supplier'}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sales_orders', to='company.Company')), ('customer', models.ForeignKey(help_text='Customer', limit_choices_to={True, 'is_supplier'}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sales_orders', to='company.Company')),
@@ -6,7 +6,6 @@ from django.conf import settings
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -43,7 +42,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='purchaseorder', model_name='purchaseorder',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'), field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='purchaseorder', model_name='purchaseorder',
@@ -148,7 +147,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='salesorder', model_name='salesorder',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Order notes', verbose_name='Notes'), field=models.TextField(blank=True, help_text='Order notes', verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='salesorder', model_name='salesorder',
@@ -4,10 +4,6 @@ from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import order.models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -23,7 +19,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('shipment_date', models.DateField(blank=True, help_text='Date of shipment', null=True, verbose_name='Shipment Date')), ('shipment_date', models.DateField(blank=True, help_text='Date of shipment', null=True, verbose_name='Shipment Date')),
('reference', models.CharField(default='1', help_text='Shipment reference', max_length=100, verbose_name='Reference')), ('reference', models.CharField(default='1', help_text='Shipment reference', max_length=100, verbose_name='Reference')),
('notes', markdownx.models.MarkdownxField(blank=True, help_text='Shipment notes', verbose_name='Notes')), ('notes', models.TextField(blank=True, help_text='Shipment notes', verbose_name='Notes')),
('checked_by', models.ForeignKey(blank=True, help_text='User who checked this shipment', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Checked By')), ('checked_by', models.ForeignKey(blank=True, help_text='User who checked this shipment', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL, verbose_name='Checked By')),
('order', models.ForeignKey(help_text='Sales Order', on_delete=django.db.models.deletion.CASCADE, related_name='shipments', to='order.salesorder', verbose_name='Order')), ('order', models.ForeignKey(help_text='Sales Order', on_delete=django.db.models.deletion.CASCADE, related_name='shipments', to='order.salesorder', verbose_name='Order')),
], ],
@@ -0,0 +1,29 @@
# Generated by Django 3.2.13 on 2022-06-20 07:28
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('order', '0069_auto_20220524_0508'),
]
operations = [
migrations.AlterField(
model_name='purchaseorder',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
),
migrations.AlterField(
model_name='salesorder',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Order notes', max_length=50000, null=True, verbose_name='Notes'),
),
migrations.AlterField(
model_name='salesordershipment',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Shipment notes', max_length=50000, null=True, verbose_name='Notes'),
),
]
+4 -8
View File
@@ -20,7 +20,6 @@ from django.utils.translation import gettext_lazy as _
from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.exceptions import MissingRate
from djmoney.contrib.exchange.models import convert_money from djmoney.contrib.exchange.models import convert_money
from djmoney.money import Money from djmoney.money import Money
from markdownx.models import MarkdownxField
from mptt.models import TreeForeignKey from mptt.models import TreeForeignKey
import InvenTree.helpers import InvenTree.helpers
@@ -28,7 +27,8 @@ import InvenTree.ready
from common.settings import currency_code_default from common.settings import currency_code_default
from company.models import Company, SupplierPart from company.models import Company, SupplierPart
from InvenTree.exceptions import log_error from InvenTree.exceptions import log_error
from InvenTree.fields import InvenTreeModelMoneyField, RoundingDecimalField from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
RoundingDecimalField)
from InvenTree.helpers import (decimal2string, getSetting, increment, from InvenTree.helpers import (decimal2string, getSetting, increment,
notify_responsible) notify_responsible)
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
@@ -152,7 +152,7 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
related_name='+', related_name='+',
) )
notes = MarkdownxField(blank=True, verbose_name=_('Notes'), help_text=_('Order notes')) notes = InvenTreeNotesField(help_text=_('Order notes'))
def get_total_price(self, target_currency=None): def get_total_price(self, target_currency=None):
"""Calculates the total price of all order lines, and converts to the specified target currency. """Calculates the total price of all order lines, and converts to the specified target currency.
@@ -1210,11 +1210,7 @@ class SalesOrderShipment(models.Model):
default='1', default='1',
) )
notes = MarkdownxField( notes = InvenTreeNotesField(help_text=_('Shipment notes'))
blank=True,
verbose_name=_('Notes'),
help_text=_('Shipment notes'),
)
tracking_number = models.CharField( tracking_number = models.CharField(
max_length=100, max_length=100,
@@ -28,6 +28,8 @@
<div class='panel-content'> <div class='panel-content'>
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'> <div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
<div class='btn-group'> <div class='btn-group'>
{% include "expand_rows.html" with label="sales-lines" %}
{% include "collapse_rows.html" with label="sales-lines" %}
{% include "filter_list.html" with id="sales-order-lines" %} {% include "filter_list.html" with id="sales-order-lines" %}
</div> </div>
</div> </div>
@@ -86,6 +88,8 @@
{% if roles.sales_order.change %} {% if roles.sales_order.change %}
<div id='pending-shipment-toolbar' class='btn-group' style='float: right;'> <div id='pending-shipment-toolbar' class='btn-group' style='float: right;'>
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
{% include "expand_rows.html" with label="pending-shipments" %}
{% include "collapse_rows.html" with label="pending-shipments" %}
{% include "filter_list.html" with id="pending-shipments" %} {% include "filter_list.html" with id="pending-shipments" %}
</div> </div>
</div> </div>
@@ -102,6 +106,8 @@
<div class='panel-content'> <div class='panel-content'>
<div id='completed-shipment-toolbar' class='btn-group' style='float: right;'> <div id='completed-shipment-toolbar' class='btn-group' style='float: right;'>
<div class='btn-group' role='group'> <div class='btn-group' role='group'>
{% include "expand_rows.html" with label="completed-shipments" %}
{% include "collapse_rows.html" with label="completed-shipments" %}
{% include "filter_list.html" with id="completed-shipments" %} {% include "filter_list.html" with id="completed-shipments" %}
</div> </div>
</div> </div>
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-01-31 10:22 # Generated by Django 2.2.9 on 2020-01-31 10:22
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(help_text='Part notes - supports Markdown formatting'), field=models.TextField(help_text='Part notes - supports Markdown formatting'),
), ),
] ]
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-23 09:01 # Generated by Django 2.2.9 on 2020-02-23 09:01
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting'), field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting'),
), ),
] ]
@@ -3,8 +3,6 @@
import InvenTree.fields import InvenTree.fields
import InvenTree.validators import InvenTree.validators
import markdownx
from django.db import migrations, models from django.db import migrations, models
@@ -38,7 +36,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True), field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True),
), ),
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
@@ -4,7 +4,6 @@ import InvenTree.fields
import InvenTree.validators import InvenTree.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
import mptt.fields import mptt.fields
import part.settings import part.settings
@@ -65,7 +64,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'), field=models.TextField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='part', model_name='part',
@@ -0,0 +1,19 @@
# Generated by Django 3.2.13 on 2022-06-20 07:28
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('part', '0078_auto_20220606_0024'),
]
operations = [
migrations.AlterField(
model_name='part',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Part notes', max_length=50000, null=True, verbose_name='Notes'),
),
]
+2 -7
View File
@@ -25,7 +25,6 @@ from django_cleanup import cleanup
from djmoney.contrib.exchange.exceptions import MissingRate from djmoney.contrib.exchange.exceptions import MissingRate
from djmoney.contrib.exchange.models import convert_money from djmoney.contrib.exchange.models import convert_money
from jinja2 import Template from jinja2 import Template
from markdownx.models import MarkdownxField
from mptt.exceptions import InvalidMove from mptt.exceptions import InvalidMove
from mptt.managers import TreeManager from mptt.managers import TreeManager
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
@@ -41,7 +40,7 @@ from common.models import InvenTreeSetting
from common.settings import currency_code_default from common.settings import currency_code_default
from company.models import SupplierPart from company.models import SupplierPart
from InvenTree import helpers, validators from InvenTree import helpers, validators
from InvenTree.fields import InvenTreeURLField from InvenTree.fields import InvenTreeNotesField, InvenTreeURLField
from InvenTree.helpers import decimal2money, decimal2string, normalize from InvenTree.helpers import decimal2money, decimal2string, normalize
from InvenTree.models import (DataImportMixin, InvenTreeAttachment, from InvenTree.models import (DataImportMixin, InvenTreeAttachment,
InvenTreeTree) InvenTreeTree)
@@ -920,11 +919,7 @@ class Part(MetadataMixin, MPTTModel):
verbose_name=_('Virtual'), verbose_name=_('Virtual'),
help_text=_('Is this a virtual part, such as a software product or license?')) help_text=_('Is this a virtual part, such as a software product or license?'))
notes = MarkdownxField( notes = InvenTreeNotesField(help_text=_('Part notes'))
blank=True, null=True,
verbose_name=_('Notes'),
help_text=_('Part notes - supports Markdown formatting')
)
bom_checksum = models.CharField(max_length=128, blank=True, verbose_name=_('BOM checksum'), help_text=_('Stored BOM checksum')) bom_checksum = models.CharField(max_length=128, blank=True, verbose_name=_('BOM checksum'), help_text=_('Stored BOM checksum'))
+16
View File
@@ -1305,6 +1305,22 @@ class PartDetailTests(InvenTreeAPITestCase):
self.assertFalse('hello' in part.metadata) self.assertFalse('hello' in part.metadata)
self.assertEqual(part.metadata['x'], 'y') self.assertEqual(part.metadata['x'], 'y')
def test_part_notes(self):
"""Unit tests for the part 'notes' field"""
# Ensure that we cannot upload a very long piece of text
url = reverse('api-part-detail', kwargs={'pk': 1})
response = self.patch(
url,
{
'notes': 'abcde' * 10001
},
expected_code=400
)
self.assertIn('Ensure this field has no more than 50000 characters', str(response.data['notes']))
class PartAPIAggregationTest(InvenTreeAPITestCase): class PartAPIAggregationTest(InvenTreeAPITestCase):
"""Tests to ensure that the various aggregation annotations are working correctly...""" """Tests to ensure that the various aggregation annotations are working correctly..."""
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-02 01:03 # Generated by Django 2.2.9 on 2020-02-02 01:03
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='stockitem', model_name='stockitem',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes'), field=models.TextField(blank=True, help_text='Stock Item Notes'),
), ),
] ]
@@ -1,7 +1,6 @@
# Generated by Django 2.2.9 on 2020-02-06 12:13 # Generated by Django 2.2.9 on 2020-02-06 12:13
from django.db import migrations from django.db import migrations, models
import markdownx.models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@@ -14,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='stockitem', model_name='stockitem',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True), field=models.TextField(blank=True, help_text='Stock Item Notes', null=True),
), ),
] ]
@@ -4,7 +4,6 @@ import InvenTree.fields
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import markdownx.models
import mptt.fields import mptt.fields
@@ -56,7 +55,7 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='stockitem', model_name='stockitem',
name='notes', name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'), field=models.TextField(blank=True, help_text='Stock Item Notes', null=True, verbose_name='Notes'),
), ),
migrations.AlterField( migrations.AlterField(
model_name='stockitem', model_name='stockitem',
@@ -0,0 +1,19 @@
# Generated by Django 3.2.13 on 2022-06-20 07:28
import InvenTree.fields
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('stock', '0076_alter_stockitem_status'),
]
operations = [
migrations.AlterField(
model_name='stockitem',
name='notes',
field=InvenTree.fields.InvenTreeNotesField(blank=True, help_text='Stock Item Notes', max_length=50000, null=True, verbose_name='Notes'),
),
]
+3 -7
View File
@@ -18,7 +18,6 @@ from django.urls import reverse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from jinja2 import Template from jinja2 import Template
from markdownx.models import MarkdownxField
from mptt.managers import TreeManager from mptt.managers import TreeManager
from mptt.models import MPTTModel, TreeForeignKey from mptt.models import MPTTModel, TreeForeignKey
@@ -29,7 +28,8 @@ import InvenTree.tasks
import label.models import label.models
import report.models import report.models
from company import models as CompanyModels from company import models as CompanyModels
from InvenTree.fields import InvenTreeModelMoneyField, InvenTreeURLField from InvenTree.fields import (InvenTreeModelMoneyField, InvenTreeNotesField,
InvenTreeURLField)
from InvenTree.models import InvenTreeAttachment, InvenTreeTree from InvenTree.models import InvenTreeAttachment, InvenTreeTree
from InvenTree.serializers import extract_int from InvenTree.serializers import extract_int
from InvenTree.status_codes import StockHistoryCode, StockStatus from InvenTree.status_codes import StockHistoryCode, StockStatus
@@ -708,11 +708,7 @@ class StockItem(MetadataMixin, MPTTModel):
choices=StockStatus.items(), choices=StockStatus.items(),
validators=[MinValueValidator(0)]) validators=[MinValueValidator(0)])
notes = MarkdownxField( notes = InvenTreeNotesField(help_text=_('Stock Item Notes'))
blank=True, null=True,
verbose_name=_("Notes"),
help_text=_('Stock Item Notes')
)
purchase_price = InvenTreeModelMoneyField( purchase_price = InvenTreeModelMoneyField(
max_digits=19, max_digits=19,
+5
View File
@@ -0,0 +1,5 @@
{% load i18n %}
<button id='{{ label }}-collapse' class='btn btn-outline-secondary' type='button' title='{% trans "Collapse all rows" %}'>
<span class='fas fa-compress'></span>
</button>
+5
View File
@@ -0,0 +1,5 @@
{% load i18n %}
<button id='{{ label }}-expand' class='btn btn-outline-secondary' type='button' title='{% trans "Expand all rows" %}'>
<span class='fas fa-expand'></span>
</button>
+27 -10
View File
@@ -2540,6 +2540,17 @@ function loadSalesOrderShipmentTable(table, options={}) {
setupFilterList('salesordershipment', $(table), options.filter_target); setupFilterList('salesordershipment', $(table), options.filter_target);
// Add callbacks for expand / collapse buttons
var prefix = options.shipped ? 'completed' : 'pending';
$(`#${prefix}-shipments-expand`).click(function() {
$(table).bootstrapTable('expandAllRows');
});
$(`#${prefix}-shipments-collapse`).click(function() {
$(table).bootstrapTable('collapseAllRows');
});
function makeShipmentActions(row) { function makeShipmentActions(row) {
// Construct "actions" for the given shipment row // Construct "actions" for the given shipment row
var pk = row.pk; var pk = row.pk;
@@ -3416,6 +3427,15 @@ function loadSalesOrderLineItemTable(table, options={}) {
// Show detail view if the PurchaseOrder is PENDING or SHIPPED // Show detail view if the PurchaseOrder is PENDING or SHIPPED
var show_detail = pending || shipped; var show_detail = pending || shipped;
// Add callbacks for expand / collapse buttons
$('#sales-lines-expand').click(function() {
$(table).bootstrapTable('expandAllRows');
});
$('#sales-lines-collapse').click(function() {
$(table).bootstrapTable('collapseAllRows');
});
// Table columns to display // Table columns to display
var columns = [ var columns = [
/* /*
@@ -3543,29 +3563,26 @@ function loadSalesOrderLineItemTable(table, options={}) {
title: '{% trans "Available Stock" %}', title: '{% trans "Available Stock" %}',
formatter: function(value, row) { formatter: function(value, row) {
var available = row.available_stock; var available = row.available_stock;
var total = row.part_detail.stock;
var required = Math.max(row.quantity - row.allocated - row.shipped, 0); var required = Math.max(row.quantity - row.allocated - row.shipped, 0);
var html = ''; var html = '';
if (total > 0) { if (available > 0) {
var url = `/part/${row.part}/?display=part-stock`; var url = `/part/${row.part}/?display=part-stock`;
var text = available; var text = available;
if (total != available) {
text += ` / ${total}`;
}
html = renderLink(text, url); html = renderLink(text, url);
} else { } else {
html += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`; html += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
} }
if (available >= required) { if (required > 0) {
html += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`; if (available >= required) {
} else { html += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
html += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`; } else {
html += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`;
}
} }
return html; return html;
-1
View File
@@ -19,7 +19,6 @@ django-formtools==2.3 # Form wizard tools
django-import-export==2.5.0 # Data import / export for admin interface django-import-export==2.5.0 # Data import / export for admin interface
django-maintenance-mode==0.16.1 # Shut down application while reloading etc. django-maintenance-mode==0.16.1 # Shut down application while reloading etc.
django-markdownify==0.8.0 # Markdown rendering django-markdownify==0.8.0 # Markdown rendering
django-markdownx==3.0.1 # Markdown form fields
django-money==1.1 # Django app for currency management django-money==1.1 # Django app for currency management
django-mptt==0.11.0 # Modified Preorder Tree Traversal django-mptt==0.11.0 # Modified Preorder Tree Traversal
django-redis>=5.0.0 # Redis integration django-redis>=5.0.0 # Redis integration