mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
[FR] Add last updated column for supplier parts (#4214)
* Move to updated Meta mixin * [FR] Add last updated column for supplier parts Fixes #3327 * add updated to table * bump API version * add missing migration * incremetn api ;-)
This commit is contained in:
parent
af0bc90e48
commit
0e0d961205
@ -2,10 +2,13 @@
|
|||||||
|
|
||||||
|
|
||||||
# InvenTree API version
|
# InvenTree API version
|
||||||
INVENTREE_API_VERSION = 88
|
INVENTREE_API_VERSION = 89
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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
|
||||||
|
v89 -> 2023-01-25 : https://github.com/inventree/InvenTree/pull/4214
|
||||||
|
- Adds updated field to SupplierPart API
|
||||||
|
- Adds API date orddering for supplier part list
|
||||||
v88 -> 2023-01-17: https://github.com/inventree/InvenTree/pull/4225
|
v88 -> 2023-01-17: https://github.com/inventree/InvenTree/pull/4225
|
||||||
- Adds 'priority' field to Build model and api endpoints
|
- Adds 'priority' field to Build model and api endpoints
|
||||||
v87 -> 2023-01-04 : https://github.com/inventree/InvenTree/pull/4067
|
v87 -> 2023-01-04 : https://github.com/inventree/InvenTree/pull/4067
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.16 on 2023-01-15 14:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('common', '0015_newsfeedentry'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='notificationentry',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
]
|
@ -49,6 +49,25 @@ import order.validators
|
|||||||
logger = logging.getLogger('inventree')
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
|
class MetaMixin(models.Model):
|
||||||
|
"""A base class for InvenTree models to include shared meta fields.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
- updated: The last time this object was updated
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta options for MetaMixin."""
|
||||||
|
abstract = True
|
||||||
|
|
||||||
|
updated = models.DateTimeField(
|
||||||
|
verbose_name=_('Updated'),
|
||||||
|
help_text=_('Timestamp of last update'),
|
||||||
|
auto_now=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EmptyURLValidator(URLValidator):
|
class EmptyURLValidator(URLValidator):
|
||||||
"""Validator for filed with url - that can be empty."""
|
"""Validator for filed with url - that can be empty."""
|
||||||
|
|
||||||
@ -1875,7 +1894,7 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PriceBreak(models.Model):
|
class PriceBreak(MetaMixin):
|
||||||
"""Represents a PriceBreak model."""
|
"""Represents a PriceBreak model."""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -2246,7 +2265,7 @@ class WebhookMessage(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class NotificationEntry(models.Model):
|
class NotificationEntry(MetaMixin):
|
||||||
"""A NotificationEntry records the last time a particular notifaction was sent out.
|
"""A NotificationEntry records the last time a particular notifaction was sent out.
|
||||||
|
|
||||||
It is recorded to ensure that notifications are not sent out "too often" to users.
|
It is recorded to ensure that notifications are not sent out "too often" to users.
|
||||||
@ -2272,11 +2291,6 @@ class NotificationEntry(models.Model):
|
|||||||
uid = models.IntegerField(
|
uid = models.IntegerField(
|
||||||
)
|
)
|
||||||
|
|
||||||
updated = models.DateTimeField(
|
|
||||||
auto_now=True,
|
|
||||||
null=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def check_recent(cls, key: str, uid: int, delta: timedelta):
|
def check_recent(cls, key: str, uid: int, delta: timedelta):
|
||||||
"""Test if a particular notification has been sent in the specified time period."""
|
"""Test if a particular notification has been sent in the specified time period."""
|
||||||
|
@ -364,6 +364,7 @@ class SupplierPartList(ListCreateDestroyAPIView):
|
|||||||
'packaging',
|
'packaging',
|
||||||
'pack_size',
|
'pack_size',
|
||||||
'in_stock',
|
'in_stock',
|
||||||
|
'updated',
|
||||||
]
|
]
|
||||||
|
|
||||||
ordering_field_aliases = {
|
ordering_field_aliases = {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.16 on 2023-01-15 14:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('company', '0051_alter_supplierpricebreak_price'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='supplierpricebreak',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
]
|
18
InvenTree/company/migrations/0053_supplierpart_updated.py
Normal file
18
InvenTree/company/migrations/0053_supplierpart_updated.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.16 on 2023-01-17 20:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('company', '0052_alter_supplierpricebreak_updated'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='supplierpart',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
]
|
@ -396,7 +396,7 @@ class SupplierPartManager(models.Manager):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SupplierPart(InvenTreeBarcodeMixin, models.Model):
|
class SupplierPart(InvenTreeBarcodeMixin, common.models.MetaMixin):
|
||||||
"""Represents a unique part as provided by a Supplier Each SupplierPart is identified by a SKU (Supplier Part Number) Each SupplierPart is also linked to a Part or ManufacturerPart object. A Part may be available from multiple suppliers.
|
"""Represents a unique part as provided by a Supplier Each SupplierPart is identified by a SKU (Supplier Part Number) Each SupplierPart is also linked to a Part or ManufacturerPart object. A Part may be available from multiple suppliers.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
@ -412,6 +412,7 @@ class SupplierPart(InvenTreeBarcodeMixin, models.Model):
|
|||||||
lead_time: Supplier lead time
|
lead_time: Supplier lead time
|
||||||
packaging: packaging that the part is supplied in, e.g. "Reel"
|
packaging: packaging that the part is supplied in, e.g. "Reel"
|
||||||
pack_size: Quantity of item supplied in a single pack (e.g. 30ml in a single tube)
|
pack_size: Quantity of item supplied in a single pack (e.g. 30ml in a single tube)
|
||||||
|
updated: Date that the SupplierPart was last updated
|
||||||
"""
|
"""
|
||||||
|
|
||||||
objects = SupplierPartManager()
|
objects = SupplierPartManager()
|
||||||
@ -683,8 +684,6 @@ class SupplierPriceBreak(common.models.PriceBreak):
|
|||||||
|
|
||||||
part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks', verbose_name=_('Part'),)
|
part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='pricebreaks', verbose_name=_('Part'),)
|
||||||
|
|
||||||
updated = models.DateTimeField(auto_now=True, null=True, verbose_name=_('last updated'))
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Metaclass defines extra model options"""
|
"""Metaclass defines extra model options"""
|
||||||
unique_together = ("part", "quantity")
|
unique_together = ("part", "quantity")
|
||||||
|
@ -282,6 +282,9 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
|
|||||||
|
|
||||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||||
|
|
||||||
|
# Date fields
|
||||||
|
updated = serializers.DateTimeField(allow_null=True, read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Metaclass options."""
|
"""Metaclass options."""
|
||||||
|
|
||||||
@ -309,6 +312,7 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
|
|||||||
'supplier',
|
'supplier',
|
||||||
'supplier_detail',
|
'supplier_detail',
|
||||||
'url',
|
'url',
|
||||||
|
'updated',
|
||||||
]
|
]
|
||||||
|
|
||||||
read_only_fields = [
|
read_only_fields = [
|
||||||
|
28
InvenTree/part/migrations/0093_auto_20230115_1404.py
Normal file
28
InvenTree/part/migrations/0093_auto_20230115_1404.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Generated by Django 3.2.16 on 2023-01-15 14:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('part', '0092_part_last_stocktake'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='partinternalpricebreak',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='partsellpricebreak',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='partpricing',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
]
|
@ -2275,7 +2275,7 @@ def after_save_part(sender, instance: Part, created, **kwargs):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PartPricing(models.Model):
|
class PartPricing(common.models.MetaMixin):
|
||||||
"""Model for caching min/max pricing information for a particular Part
|
"""Model for caching min/max pricing information for a particular Part
|
||||||
|
|
||||||
It is prohibitively expensive to calculate min/max pricing for a part "on the fly".
|
It is prohibitively expensive to calculate min/max pricing for a part "on the fly".
|
||||||
@ -2785,12 +2785,6 @@ class PartPricing(models.Model):
|
|||||||
choices=common.settings.currency_code_mappings(),
|
choices=common.settings.currency_code_mappings(),
|
||||||
)
|
)
|
||||||
|
|
||||||
updated = models.DateTimeField(
|
|
||||||
verbose_name=_('Updated'),
|
|
||||||
help_text=_('Timestamp of last pricing update'),
|
|
||||||
auto_now=True
|
|
||||||
)
|
|
||||||
|
|
||||||
scheduled_for_update = models.BooleanField(
|
scheduled_for_update = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
18
InvenTree/stock/migrations/0092_alter_stockitem_updated.py
Normal file
18
InvenTree/stock/migrations/0092_alter_stockitem_updated.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.2.16 on 2023-01-15 14:04
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('stock', '0091_alter_stockitem_delete_on_deplete'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='stockitem',
|
||||||
|
name='updated',
|
||||||
|
field=models.DateTimeField(auto_now=True, help_text='Timestamp of last update', null=True, verbose_name='Updated'),
|
||||||
|
),
|
||||||
|
]
|
@ -266,7 +266,7 @@ def default_delete_on_deplete():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
class StockItem(InvenTreeBarcodeMixin, MetadataMixin, MPTTModel):
|
class StockItem(InvenTreeBarcodeMixin, MetadataMixin, common.models.MetaMixin, MPTTModel):
|
||||||
"""A StockItem object represents a quantity of physical instances of a part.
|
"""A StockItem object represents a quantity of physical instances of a part.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
@ -729,8 +729,6 @@ class StockItem(InvenTreeBarcodeMixin, MetadataMixin, MPTTModel):
|
|||||||
default=1
|
default=1
|
||||||
)
|
)
|
||||||
|
|
||||||
updated = models.DateField(auto_now=True, null=True)
|
|
||||||
|
|
||||||
build = models.ForeignKey(
|
build = models.ForeignKey(
|
||||||
'build.Build', on_delete=models.SET_NULL,
|
'build.Build', on_delete=models.SET_NULL,
|
||||||
verbose_name=_('Source Build'),
|
verbose_name=_('Source Build'),
|
||||||
|
@ -1043,6 +1043,11 @@ function loadSupplierPartTable(table, url, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
field: 'updated',
|
||||||
|
title: '{% trans "Last Updated" %}',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
field: 'actions',
|
field: 'actions',
|
||||||
title: '',
|
title: '',
|
||||||
|
Loading…
Reference in New Issue
Block a user