diff --git a/arduino/dcc-ex.github.io b/arduino/dcc-ex.github.io index 9acc446..e661bb0 160000 --- a/arduino/dcc-ex.github.io +++ b/arduino/dcc-ex.github.io @@ -1 +1 @@ -Subproject commit 9acc446358e24a62d1ec1616bc32e0de9d5b4f3a +Subproject commit e661bb0fab8dbe6a43c899ee2929bd2faa81a9f8 diff --git a/arduino/vim-arduino b/arduino/vim-arduino index 111db61..2ded67c 160000 --- a/arduino/vim-arduino +++ b/arduino/vim-arduino @@ -1 +1 @@ -Subproject commit 111db616db21d4f925691f1517792953f7671647 +Subproject commit 2ded67cdf09bb07c4805d9e93d478095ed3d8606 diff --git a/ram/bookshelf/migrations/0023_delete_basebookdocument.py b/ram/bookshelf/migrations/0023_delete_basebookdocument.py new file mode 100644 index 0000000..bd7cdc3 --- /dev/null +++ b/ram/bookshelf/migrations/0023_delete_basebookdocument.py @@ -0,0 +1,16 @@ +# Generated by Django 5.1.4 on 2025-02-09 13:47 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookshelf", "0022_basebook_shop"), + ] + + operations = [ + migrations.DeleteModel( + name="BaseBookDocument", + ), + ] diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index b059b4e..fba7aa5 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -6,7 +6,7 @@ from django.urls import reverse from django_countries.fields import CountryField from ram.utils import DeduplicatedStorage -from ram.models import BaseModel, Image, Document, PropertyInstance +from ram.models import BaseModel, Image, PropertyInstance from metadata.models import Scale, Manufacturer, Shop, Tag @@ -89,21 +89,6 @@ class BaseBookImage(Image): ) -class BaseBookDocument(Document): - book = models.ForeignKey( - BaseBook, on_delete=models.CASCADE, related_name="document" - ) - - class Meta: - verbose_name_plural = "Documents" - constraints = [ - models.UniqueConstraint( - fields=["book", "file"], - name="unique_book_file" - ) - ] - - class BaseBookProperty(PropertyInstance): book = models.ForeignKey( BaseBook, diff --git a/ram/metadata/admin.py b/ram/metadata/admin.py index cfed7b3..c017394 100644 --- a/ram/metadata/admin.py +++ b/ram/metadata/admin.py @@ -2,10 +2,10 @@ from django.contrib import admin from django.utils.html import format_html from adminsortable2.admin import SortableAdminMixin +from repository.models import DecoderDocument from metadata.models import ( Property, Decoder, - DecoderDocument, Scale, Shop, Manufacturer, diff --git a/ram/metadata/migrations/0024_remove_genericdocument_tags_delete_decoderdocument_and_more.py b/ram/metadata/migrations/0024_remove_genericdocument_tags_delete_decoderdocument_and_more.py new file mode 100644 index 0000000..39a21f0 --- /dev/null +++ b/ram/metadata/migrations/0024_remove_genericdocument_tags_delete_decoderdocument_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 5.1.4 on 2025-02-09 13:47 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("metadata", "0023_shop"), + ] + + operations = [ + migrations.RemoveField( + model_name="genericdocument", + name="tags", + ), + migrations.DeleteModel( + name="DecoderDocument", + ), + migrations.DeleteModel( + name="GenericDocument", + ), + ] diff --git a/ram/metadata/models.py b/ram/metadata/models.py index be193f1..29a3ae8 100644 --- a/ram/metadata/models.py +++ b/ram/metadata/models.py @@ -6,9 +6,6 @@ from django.dispatch.dispatcher import receiver from django.core.exceptions import ValidationError from django_countries.fields import CountryField -from tinymce import models as tinymce - -from ram.models import Document from ram.utils import DeduplicatedStorage, get_image_preview, slugify from ram.managers import PublicManager @@ -132,20 +129,6 @@ class Decoder(models.Model): image_thumbnail.short_description = "Preview" -class DecoderDocument(Document): - decoder = models.ForeignKey( - Decoder, on_delete=models.CASCADE, related_name="document" - ) - - class Meta: - constraints = [ - models.UniqueConstraint( - fields=["decoder", "file"], - name="unique_decoder_file" - ) - ] - - def calculate_ratio(ratio): try: num, den = ratio.split(":") @@ -239,14 +222,6 @@ class Tag(models.Model): ) -class GenericDocument(Document): - notes = tinymce.HTMLField(blank=True) - tags = models.ManyToManyField(Tag, blank=True) - - class Meta: - verbose_name_plural = "Generic Documents" - - class Shop(models.Model): name = models.CharField(max_length=128, unique=True) country = CountryField(blank=True) diff --git a/ram/repository/admin.py b/ram/repository/admin.py index 8f61627..e8284a3 100644 --- a/ram/repository/admin.py +++ b/ram/repository/admin.py @@ -1,7 +1,12 @@ from django.contrib import admin from ram.admin import publish, unpublish -from repository.models import GenericDocument, RollingStockDocument +from repository.models import ( + GenericDocument, + BaseBookDocument, + DecoderDocument, + RollingStockDocument +) @admin.register(GenericDocument) @@ -49,6 +54,76 @@ class GenericDocumentAdmin(admin.ModelAdmin): actions = [publish, unpublish] +# @admin.register(BaseBookDocument) +# class BookDocumentAdmin(admin.ModelAdmin): +# readonly_fields = ("size",) +# list_display = ( +# "__str__", +# # FIXME +# "book__book", +# "book__catalog", +# "description", +# "private", +# "size", +# "download", +# ) +# search_fields = ( +# "book__title", +# "description", +# "file", +# ) +# fieldsets = ( +# ( +# None, +# { +# "fields": ( +# "private", +# # FIXME +# "description", +# "file", +# "size", +# ) +# }, +# ), +# ) +# actions = [publish, unpublish] + + +@admin.register(DecoderDocument) +class DecoderDocumentAdmin(admin.ModelAdmin): + readonly_fields = ("size",) + list_display = ( + "__str__", + "decoder", + "description", + "private", + "size", + "download", + ) + search_fields = ( + "decoder__name", + "decoder__manufacturer__name", + "description", + "file", + ) + autocomplete_fields = ("decoder",) + fieldsets = ( + ( + None, + { + "fields": ( + "private", + "decoder", + "description", + "file", + "size", + ) + }, + ), + ) + actions = [publish, unpublish] + + @admin.register(RollingStockDocument) class RollingStockDocumentAdmin(admin.ModelAdmin): readonly_fields = ("size",) @@ -81,3 +156,4 @@ class RollingStockDocumentAdmin(admin.ModelAdmin): }, ), ) + actions = [publish, unpublish] diff --git a/ram/repository/migrations/0002_alter_decoderdocument_options_and_more.py b/ram/repository/migrations/0002_alter_decoderdocument_options_and_more.py new file mode 100644 index 0000000..4b65285 --- /dev/null +++ b/ram/repository/migrations/0002_alter_decoderdocument_options_and_more.py @@ -0,0 +1,80 @@ +# Generated by Django 5.1.4 on 2025-02-09 13:48 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookshelf", "0023_delete_basebookdocument"), + ( + "metadata", + "0024_remove_genericdocument_tags_delete_decoderdocument_and_more", + ), + ("repository", "0001_initial"), + ("roster", "0036_delete_rollingstockdocument"), + ] + + operations = [ + migrations.AlterModelOptions( + name="decoderdocument", + options={}, + ), + migrations.AlterModelOptions( + name="rollingstockdocument", + options={}, + ), + migrations.AlterField( + model_name="basebookdocument", + name="book", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="document", + to="bookshelf.basebook", + ), + ), + migrations.AlterField( + model_name="decoderdocument", + name="decoder", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="document", + to="metadata.decoder", + ), + ), + migrations.AlterField( + model_name="genericdocument", + name="tags", + field=models.ManyToManyField( + blank=True, related_name="document", to="metadata.tag" + ), + ), + migrations.AlterField( + model_name="rollingstockdocument", + name="rolling_stock", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="document", + to="roster.rollingstock", + ), + ), + migrations.AddConstraint( + model_name="basebookdocument", + constraint=models.UniqueConstraint( + fields=("book", "file"), name="unique_book_file" + ), + ), + migrations.AddConstraint( + model_name="decoderdocument", + constraint=models.UniqueConstraint( + fields=("decoder", "file"), name="unique_decoder_file" + ), + ), + migrations.AddConstraint( + model_name="rollingstockdocument", + constraint=models.UniqueConstraint( + fields=("rolling_stock", "file"), name="unique_stock_file" + ), + ), + ] diff --git a/ram/repository/models.py b/ram/repository/models.py index 9a33207..0c31e7e 100644 --- a/ram/repository/models.py +++ b/ram/repository/models.py @@ -1,4 +1,6 @@ from django.db import models +from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes import fields from tinymce import models as tinymce @@ -10,50 +12,56 @@ from bookshelf.models import BaseBook class GenericDocument(Document): notes = tinymce.HTMLField(blank=True) - tags = models.ManyToManyField(Tag, blank=True, related_name="new_document") + tags = models.ManyToManyField(Tag, blank=True, related_name="document") class Meta: verbose_name_plural = "Generic Documents" +class InvoiceDocument(Document): + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() + content_object = fields.GenericForeignKey("content_type", "object_id") + + class DecoderDocument(Document): decoder = models.ForeignKey( - Decoder, on_delete=models.CASCADE, related_name="new_document" + Decoder, on_delete=models.CASCADE, related_name="document" ) - # class Meta: - # constraints = [ - # models.UniqueConstraint( - # fields=["decoder", "file"], - # name="unique_decoder_file" - # ) - # ] + class Meta: + constraints = [ + models.UniqueConstraint( + fields=["decoder", "file"], + name="unique_decoder_file" + ) + ] class BaseBookDocument(Document): book = models.ForeignKey( - BaseBook, on_delete=models.CASCADE, related_name="new_document" + BaseBook, on_delete=models.CASCADE, related_name="document" ) - # class Meta: - # verbose_name_plural = "Documents" - # constraints = [ - # models.UniqueConstraint( - # fields=["book", "file"], - # name="unique_book_file" - # ) - # ] + class Meta: + verbose_name_plural = "Documents" + constraints = [ + models.UniqueConstraint( + fields=["book", "file"], + name="unique_book_file" + ) + ] class RollingStockDocument(Document): rolling_stock = models.ForeignKey( - RollingStock, on_delete=models.CASCADE, related_name="new_document" + RollingStock, on_delete=models.CASCADE, related_name="document" ) - # class Meta: - # constraints = [ - # models.UniqueConstraint( - # fields=["rolling_stock", "file"], - # name="unique_stock_file" - # ) - # ] + class Meta: + constraints = [ + models.UniqueConstraint( + fields=["rolling_stock", "file"], + name="unique_stock_file" + ) + ] diff --git a/ram/roster/migrations/0036_delete_rollingstockdocument.py b/ram/roster/migrations/0036_delete_rollingstockdocument.py new file mode 100644 index 0000000..01fa429 --- /dev/null +++ b/ram/roster/migrations/0036_delete_rollingstockdocument.py @@ -0,0 +1,16 @@ +# Generated by Django 5.1.4 on 2025-02-09 13:47 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("roster", "0035_alter_rollingstock_shop"), + ] + + operations = [ + migrations.DeleteModel( + name="RollingStockDocument", + ), + ] diff --git a/ram/roster/models.py b/ram/roster/models.py index 999819b..99ce68d 100644 --- a/ram/roster/models.py +++ b/ram/roster/models.py @@ -5,12 +5,14 @@ from django.db import models from django.urls import reverse from django.conf import settings from django.dispatch import receiver +from django.contrib.contenttypes import fields from tinymce import models as tinymce -from ram.models import BaseModel, Document, Image, PropertyInstance +from ram.models import BaseModel, Image, PropertyInstance from ram.utils import DeduplicatedStorage, slugify from ram.managers import PublicManager +from repository.models import InvoiceDocument from metadata.models import ( Scale, Manufacturer, @@ -113,6 +115,9 @@ class RollingStock(BaseModel): null=True, blank=True, ) + invoice = fields.GenericRelation( + app.get_model("repository", "InvoiceDocument"), + InvoiceDocument) tags = models.ManyToManyField( Tag, related_name="rolling_stock", blank=True ) @@ -169,20 +174,6 @@ def pre_save_internal_fields(sender, instance, *args, **kwargs): instance.item_number_slug = slugify(instance.item_number) -class RollingStockDocument(Document): - rolling_stock = models.ForeignKey( - RollingStock, on_delete=models.CASCADE, related_name="document" - ) - - class Meta: - constraints = [ - models.UniqueConstraint( - fields=["rolling_stock", "file"], - name="unique_stock_file" - ) - ] - - def rolling_stock_image_upload(instance, filename): return os.path.join( "images",