Merge remote-tracking branch 'inventree/master'
This commit is contained in:
commit
9837a7ae10
|
|
@ -157,3 +157,19 @@ class RoundingDecimalField(models.DecimalField):
|
|||
defaults.update(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)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import random
|
|||
import socket
|
||||
import string
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
import django.conf.locale
|
||||
from django.core.files.storage import default_storage
|
||||
|
|
@ -253,7 +252,6 @@ INSTALLED_APPS = [
|
|||
'import_export', # Import / export tables to file
|
||||
'django_cleanup.apps.CleanupConfig', # Automatically delete orphaned MEDIA files
|
||||
'mptt', # Modified Preorder Tree Traversal
|
||||
'markdownx', # Markdown editing
|
||||
'markdownify', # Markdown template rendering
|
||||
'django_admin_shell', # Python shell for the admin interface
|
||||
'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_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
|
||||
# Ref: https://django-markdownify.readthedocs.io/en/latest/settings.html
|
||||
|
||||
|
|
|
|||
|
|
@ -3539,15 +3539,6 @@ a.ui-button:active,
|
|||
.index-action-selected {
|
||||
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 {
|
||||
background-image: initial;
|
||||
background-color: rgb(32, 34, 36);
|
||||
|
|
|
|||
|
|
@ -63,30 +63,10 @@ main {
|
|||
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 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.markdownx-preview {
|
||||
border: 1px solid #cce;
|
||||
border-radius: 3px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* Progress bars */
|
||||
|
||||
.progress {
|
||||
|
|
|
|||
|
|
@ -126,9 +126,6 @@ backendpatterns = [
|
|||
|
||||
re_path(r'^api/', include(apipatterns)),
|
||||
re_path(r'^api-doc/', include_docs_urls(title='InvenTree API')),
|
||||
|
||||
# 3rd party endpoints
|
||||
re_path(r'^markdownx/', include('markdownx.urls')),
|
||||
]
|
||||
|
||||
frontendpatterns = [
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 2.2.9 on 2020-02-01 12:47
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='build',
|
||||
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
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
import mptt.fields
|
||||
|
||||
|
||||
|
|
@ -31,7 +30,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='build',
|
||||
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(
|
||||
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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -16,8 +16,6 @@ from django.dispatch.dispatcher import receiver
|
|||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from markdownx.models import MarkdownxField
|
||||
|
||||
from mptt.models import MPTTModel, TreeForeignKey
|
||||
from mptt.exceptions import InvalidMove
|
||||
|
||||
|
|
@ -320,9 +318,8 @@ class Build(MPTTModel, ReferenceIndexingMixin):
|
|||
blank=True, help_text=_('Link to external URL')
|
||||
)
|
||||
|
||||
notes = MarkdownxField(
|
||||
verbose_name=_('Notes'),
|
||||
blank=True, help_text=_('Extra build notes')
|
||||
notes = InvenTree.fields.InvenTreeNotesField(
|
||||
help_text=_('Extra build notes')
|
||||
)
|
||||
|
||||
def sub_builds(self, cascade=True):
|
||||
|
|
|
|||
|
|
@ -275,13 +275,8 @@
|
|||
</div>
|
||||
|
||||
{% if build.has_tracked_bom_items %}
|
||||
<button id='outputs-expand' class='btn btn-outline-secondary' type='button' title='{% trans "Expand all build output rows" %}'>
|
||||
<span class='fas fa-expand'></span>
|
||||
</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>
|
||||
{% include "expand_rows.html" with label="outputs" %}
|
||||
{% include "collapse_rows.html" with label="outputs" %}
|
||||
{% endif %}
|
||||
|
||||
{% include "filter_list.html" with id='incompletebuilditems' %}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 2.2.9 on 2020-02-01 12:31
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='company',
|
||||
name='notes',
|
||||
field=markdownx.models.MarkdownxField(blank=True),
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import company.models
|
|||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
import stdimage.models
|
||||
|
||||
|
||||
|
|
@ -44,7 +43,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='company',
|
||||
name='notes',
|
||||
field=markdownx.models.MarkdownxField(blank=True, verbose_name='Notes'),
|
||||
field=models.TextField(blank=True, verbose_name='Notes'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -11,12 +11,12 @@ from django.db.models import Q, Sum, UniqueConstraint
|
|||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from markdownx.models import MarkdownxField
|
||||
from moneyed import CURRENCIES
|
||||
from stdimage.models import StdImageField
|
||||
|
||||
import common.models
|
||||
import common.settings
|
||||
import InvenTree.fields
|
||||
import InvenTree.validators
|
||||
from common.settings import currency_code_default
|
||||
from InvenTree.fields import InvenTreeURLField
|
||||
|
|
@ -135,7 +135,7 @@ class Company(models.Model):
|
|||
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?'))
|
||||
|
||||
|
|
|
|||
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
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='purchaseorder',
|
||||
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
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
|
||||
|
||||
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')),
|
||||
('issue_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)),
|
||||
('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')),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ from django.conf import settings
|
|||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -43,7 +42,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='purchaseorder',
|
||||
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(
|
||||
model_name='purchaseorder',
|
||||
|
|
@ -148,7 +147,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='salesorder',
|
||||
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(
|
||||
model_name='salesorder',
|
||||
|
|
|
|||
|
|
@ -4,10 +4,6 @@ from django.conf import settings
|
|||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
import order.models
|
||||
|
||||
import markdownx.models
|
||||
|
||||
|
||||
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')),
|
||||
('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')),
|
||||
('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')),
|
||||
('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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -20,7 +20,6 @@ from django.utils.translation import gettext_lazy as _
|
|||
from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
from djmoney.contrib.exchange.models import convert_money
|
||||
from djmoney.money import Money
|
||||
from markdownx.models import MarkdownxField
|
||||
from mptt.models import TreeForeignKey
|
||||
|
||||
import InvenTree.helpers
|
||||
|
|
@ -28,7 +27,8 @@ import InvenTree.ready
|
|||
from common.settings import currency_code_default
|
||||
from company.models import Company, SupplierPart
|
||||
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,
|
||||
notify_responsible)
|
||||
from InvenTree.models import InvenTreeAttachment, ReferenceIndexingMixin
|
||||
|
|
@ -152,7 +152,7 @@ class Order(MetadataMixin, ReferenceIndexingMixin):
|
|||
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):
|
||||
"""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',
|
||||
)
|
||||
|
||||
notes = MarkdownxField(
|
||||
blank=True,
|
||||
verbose_name=_('Notes'),
|
||||
help_text=_('Shipment notes'),
|
||||
)
|
||||
notes = InvenTreeNotesField(help_text=_('Shipment notes'))
|
||||
|
||||
tracking_number = models.CharField(
|
||||
max_length=100,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
<div class='panel-content'>
|
||||
<div id='order-toolbar-buttons' class='btn-group' style='float: right;'>
|
||||
<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" %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -86,6 +88,8 @@
|
|||
{% if roles.sales_order.change %}
|
||||
<div id='pending-shipment-toolbar' class='btn-group' style='float: right;'>
|
||||
<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" %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -102,6 +106,8 @@
|
|||
<div class='panel-content'>
|
||||
<div id='completed-shipment-toolbar' class='btn-group' style='float: right;'>
|
||||
<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" %}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
# Generated by Django 2.2.9 on 2020-01-31 10:22
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='part',
|
||||
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
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='part',
|
||||
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.validators
|
||||
|
||||
import markdownx
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -38,7 +36,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='part',
|
||||
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(
|
||||
model_name='part',
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import InvenTree.fields
|
|||
import InvenTree.validators
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
import mptt.fields
|
||||
import part.settings
|
||||
|
||||
|
|
@ -65,7 +64,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='part',
|
||||
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(
|
||||
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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -25,7 +25,6 @@ from django_cleanup import cleanup
|
|||
from djmoney.contrib.exchange.exceptions import MissingRate
|
||||
from djmoney.contrib.exchange.models import convert_money
|
||||
from jinja2 import Template
|
||||
from markdownx.models import MarkdownxField
|
||||
from mptt.exceptions import InvalidMove
|
||||
from mptt.managers import TreeManager
|
||||
from mptt.models import MPTTModel, TreeForeignKey
|
||||
|
|
@ -41,7 +40,7 @@ from common.models import InvenTreeSetting
|
|||
from common.settings import currency_code_default
|
||||
from company.models import SupplierPart
|
||||
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.models import (DataImportMixin, InvenTreeAttachment,
|
||||
InvenTreeTree)
|
||||
|
|
@ -920,11 +919,7 @@ class Part(MetadataMixin, MPTTModel):
|
|||
verbose_name=_('Virtual'),
|
||||
help_text=_('Is this a virtual part, such as a software product or license?'))
|
||||
|
||||
notes = MarkdownxField(
|
||||
blank=True, null=True,
|
||||
verbose_name=_('Notes'),
|
||||
help_text=_('Part notes - supports Markdown formatting')
|
||||
)
|
||||
notes = InvenTreeNotesField(help_text=_('Part notes'))
|
||||
|
||||
bom_checksum = models.CharField(max_length=128, blank=True, verbose_name=_('BOM checksum'), help_text=_('Stored BOM checksum'))
|
||||
|
||||
|
|
|
|||
|
|
@ -1305,6 +1305,22 @@ class PartDetailTests(InvenTreeAPITestCase):
|
|||
self.assertFalse('hello' in part.metadata)
|
||||
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):
|
||||
"""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
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='stockitem',
|
||||
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
|
||||
|
||||
from django.db import migrations
|
||||
import markdownx.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
@ -14,6 +13,6 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='stockitem',
|
||||
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
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import markdownx.models
|
||||
import mptt.fields
|
||||
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ class Migration(migrations.Migration):
|
|||
migrations.AlterField(
|
||||
model_name='stockitem',
|
||||
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(
|
||||
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'),
|
||||
),
|
||||
]
|
||||
|
|
@ -18,7 +18,6 @@ from django.urls import reverse
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from jinja2 import Template
|
||||
from markdownx.models import MarkdownxField
|
||||
from mptt.managers import TreeManager
|
||||
from mptt.models import MPTTModel, TreeForeignKey
|
||||
|
||||
|
|
@ -29,7 +28,8 @@ import InvenTree.tasks
|
|||
import label.models
|
||||
import report.models
|
||||
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.serializers import extract_int
|
||||
from InvenTree.status_codes import StockHistoryCode, StockStatus
|
||||
|
|
@ -708,11 +708,7 @@ class StockItem(MetadataMixin, MPTTModel):
|
|||
choices=StockStatus.items(),
|
||||
validators=[MinValueValidator(0)])
|
||||
|
||||
notes = MarkdownxField(
|
||||
blank=True, null=True,
|
||||
verbose_name=_("Notes"),
|
||||
help_text=_('Stock Item Notes')
|
||||
)
|
||||
notes = InvenTreeNotesField(help_text=_('Stock Item Notes'))
|
||||
|
||||
purchase_price = InvenTreeModelMoneyField(
|
||||
max_digits=19,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -2540,6 +2540,17 @@ function loadSalesOrderShipmentTable(table, options={}) {
|
|||
|
||||
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) {
|
||||
// Construct "actions" for the given shipment row
|
||||
var pk = row.pk;
|
||||
|
|
@ -3416,6 +3427,15 @@ function loadSalesOrderLineItemTable(table, options={}) {
|
|||
// Show detail view if the PurchaseOrder is PENDING or 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
|
||||
var columns = [
|
||||
/*
|
||||
|
|
@ -3543,29 +3563,26 @@ function loadSalesOrderLineItemTable(table, options={}) {
|
|||
title: '{% trans "Available Stock" %}',
|
||||
formatter: function(value, row) {
|
||||
var available = row.available_stock;
|
||||
var total = row.part_detail.stock;
|
||||
var required = Math.max(row.quantity - row.allocated - row.shipped, 0);
|
||||
|
||||
var html = '';
|
||||
|
||||
if (total > 0) {
|
||||
if (available > 0) {
|
||||
var url = `/part/${row.part}/?display=part-stock`;
|
||||
|
||||
var text = available;
|
||||
|
||||
if (total != available) {
|
||||
text += ` / ${total}`;
|
||||
}
|
||||
|
||||
html = renderLink(text, url);
|
||||
} else {
|
||||
html += `<span class='badge rounded-pill bg-danger'>{% trans "No Stock Available" %}</span>`;
|
||||
}
|
||||
|
||||
if (available >= required) {
|
||||
html += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
|
||||
} else {
|
||||
html += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`;
|
||||
if (required > 0) {
|
||||
if (available >= required) {
|
||||
html += `<span class='fas fa-check-circle icon-green float-right' title='{% trans "Sufficient stock available" %}'></span>`;
|
||||
} else {
|
||||
html += `<span class='fas fa-times-circle icon-red float-right' title='{% trans "Insufficient stock available" %}'></span>`;
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ django-formtools==2.3 # Form wizard tools
|
|||
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-markdownify==0.8.0 # Markdown rendering
|
||||
django-markdownx==3.0.1 # Markdown form fields
|
||||
django-money==1.1 # Django app for currency management
|
||||
django-mptt==0.11.0 # Modified Preorder Tree Traversal
|
||||
django-redis>=5.0.0 # Redis integration
|
||||
|
|
|
|||
Loading…
Reference in New Issue