diff --git a/scipost_django/finances/admin.py b/scipost_django/finances/admin.py
index 7aceacfcb9afeeffdbcc8146d91c1756f058181b..36cf1bf8d8720665412dc417ba37759a75620bcf 100644
--- a/scipost_django/finances/admin.py
+++ b/scipost_django/finances/admin.py
@@ -69,6 +69,7 @@ class PubFracAdmin(admin.ModelAdmin):
         "organization",
         "doi_label_display",
         "fraction",
+        "cf_value",
     ]
     autocomplete_fields = [
         "organization",
diff --git a/scipost_django/finances/migrations/0035_pubfrac_cf_value.py b/scipost_django/finances/migrations/0035_pubfrac_cf_value.py
new file mode 100644
index 0000000000000000000000000000000000000000..364c59f38c2f1e1dd346cdf23c314e730fd1d03e
--- /dev/null
+++ b/scipost_django/finances/migrations/0035_pubfrac_cf_value.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.2.10 on 2024-03-15 04:11
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("finances", "0034_alter_worklog_content_type_alter_worklog_user"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="pubfrac",
+            name="cf_value",
+            field=models.PositiveIntegerField(blank=True, null=True),
+        ),
+    ]
diff --git a/scipost_django/finances/migrations/0036_populate_pubfrac_cf_value.py b/scipost_django/finances/migrations/0036_populate_pubfrac_cf_value.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffbe52be7f3da613b9ce2fe28f870831702b3536
--- /dev/null
+++ b/scipost_django/finances/migrations/0036_populate_pubfrac_cf_value.py
@@ -0,0 +1,36 @@
+# Generated by Django 4.2.10 on 2024-03-15 04:11
+
+from django.db import migrations
+
+
+def populate_pubfrac_cf_value(apps, schema_editor):
+    PubFrac = apps.get_model("finances.PubFrac")
+    Journal = apps.get_model("journals.Journal")
+
+    # Some contortions required since model methods not available in migrations
+    for pf in PubFrac.objects.all():
+        if pf.publication.in_journal:
+            journal = Journal.objects.get(pk=pf.publication.in_journal.id)
+        elif pf.publication.in_issue.in_journal:
+            journal = Journal.objects.get(pk=pf.publication.in_issue.in_journal.id)
+        else:
+            journal = Journal.objects.get(pk=pf.publication.in_issue.in_volume.in_journal.id)
+        cost_per_publication = journal.cost_info[pf.publication.publication_date.year] \
+            if pf.publication.publication_date.year in journal.cost_info else \
+               journal.cost_info["default"]
+        pf.cf_value = int(pf.fraction * cost_per_publication)
+        pf.save()
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("finances", "0035_pubfrac_cf_value"),
+    ]
+
+    operations = [
+        migrations.RunPython(
+            populate_pubfrac_cf_value,
+            reverse_code=migrations.RunPython.noop,
+        )
+    ]
diff --git a/scipost_django/finances/models/pubfrac.py b/scipost_django/finances/models/pubfrac.py
index 836c8fa26b02060b2eb2fed48ac20e35ae4dba41..6207be70e3efb86c133fe25fe5cd676886c03603 100644
--- a/scipost_django/finances/models/pubfrac.py
+++ b/scipost_django/finances/models/pubfrac.py
@@ -5,6 +5,8 @@ __license__ = "AGPL v3"
 from decimal import Decimal
 
 from django.db import models
+from django.db.models.signals import pre_save
+from django.dispatch import receiver
 
 
 class PubFrac(models.Model):
@@ -31,11 +33,19 @@ class PubFrac(models.Model):
         max_digits=4, decimal_places=3, default=Decimal("0.000")
     )
 
+    # Calculated field
+    cf_value = models.PositiveIntegerField(blank=True, null=True)
+
     class Meta:
         unique_together = (("organization", "publication"),)
 
-    @property
-    def value(self):
-        return int(self.fraction * self.publication.get_journal().cost_per_publication(
-            self.publication.publication_date.year
-        ))
+
+@receiver(pre_save, sender=PubFrac)
+def calculate_cf_value(sender, instance: PubFrac, **kwargs):
+    """Calculate the cf_value field before saving."""
+    instance.cf_value = int(
+        instance.fraction * instance.publication.get_journal(
+        ).cost_per_publication(
+            instance.publication.publication_date.year
+        )
+    )