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 = 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
|
||||
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
|
||||
- Adds 'priority' field to Build model and api endpoints
|
||||
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')
|
||||
|
||||
|
||||
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):
|
||||
"""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."""
|
||||
|
||||
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.
|
||||
|
||||
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(
|
||||
)
|
||||
|
||||
updated = models.DateTimeField(
|
||||
auto_now=True,
|
||||
null=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def check_recent(cls, key: str, uid: int, delta: timedelta):
|
||||
"""Test if a particular notification has been sent in the specified time period."""
|
||||
|
@ -364,6 +364,7 @@ class SupplierPartList(ListCreateDestroyAPIView):
|
||||
'packaging',
|
||||
'pack_size',
|
||||
'in_stock',
|
||||
'updated',
|
||||
]
|
||||
|
||||
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.
|
||||
|
||||
Attributes:
|
||||
@ -412,6 +412,7 @@ class SupplierPart(InvenTreeBarcodeMixin, models.Model):
|
||||
lead_time: Supplier lead time
|
||||
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)
|
||||
updated: Date that the SupplierPart was last updated
|
||||
"""
|
||||
|
||||
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'),)
|
||||
|
||||
updated = models.DateTimeField(auto_now=True, null=True, verbose_name=_('last updated'))
|
||||
|
||||
class Meta:
|
||||
"""Metaclass defines extra model options"""
|
||||
unique_together = ("part", "quantity")
|
||||
|
@ -282,6 +282,9 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
|
||||
|
||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||
|
||||
# Date fields
|
||||
updated = serializers.DateTimeField(allow_null=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
"""Metaclass options."""
|
||||
|
||||
@ -309,6 +312,7 @@ class SupplierPartSerializer(InvenTreeModelSerializer):
|
||||
'supplier',
|
||||
'supplier_detail',
|
||||
'url',
|
||||
'updated',
|
||||
]
|
||||
|
||||
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
|
||||
|
||||
|
||||
class PartPricing(models.Model):
|
||||
class PartPricing(common.models.MetaMixin):
|
||||
"""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".
|
||||
@ -2785,12 +2785,6 @@ class PartPricing(models.Model):
|
||||
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(
|
||||
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
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Attributes:
|
||||
@ -729,8 +729,6 @@ class StockItem(InvenTreeBarcodeMixin, MetadataMixin, MPTTModel):
|
||||
default=1
|
||||
)
|
||||
|
||||
updated = models.DateField(auto_now=True, null=True)
|
||||
|
||||
build = models.ForeignKey(
|
||||
'build.Build', on_delete=models.SET_NULL,
|
||||
verbose_name=_('Source Build'),
|
||||
|
@ -1043,6 +1043,11 @@ function loadSupplierPartTable(table, url, options) {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'updated',
|
||||
title: '{% trans "Last Updated" %}',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'actions',
|
||||
title: '',
|
||||
|
Loading…
Reference in New Issue
Block a user