diff --git a/InvenTree/part/migrations/0065_auto_20210505_2144.py b/InvenTree/part/migrations/0065_auto_20210505_2144.py
new file mode 100644
index 0000000000..328ce1f588
--- /dev/null
+++ b/InvenTree/part/migrations/0065_auto_20210505_2144.py
@@ -0,0 +1,24 @@
+# Generated by Django 3.2 on 2021-05-05 21:44
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('part', '0064_auto_20210404_2016'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='part',
+            name='base_cost',
+            field=models.DecimalField(decimal_places=3, default=0, help_text='Minimum charge (e.g. stocking fee)', max_digits=10, validators=[django.core.validators.MinValueValidator(0)], verbose_name='base cost'),
+        ),
+        migrations.AddField(
+            model_name='part',
+            name='multiple',
+            field=models.PositiveIntegerField(default=1, help_text='Sell multiple', validators=[django.core.validators.MinValueValidator(1)], verbose_name='multiple'),
+        ),
+    ]
diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py
index 137781ba2b..4c7086f51d 100644
--- a/InvenTree/part/models.py
+++ b/InvenTree/part/models.py
@@ -1611,6 +1611,44 @@ class Part(MPTTModel):
                 max(buy_price_range[1], bom_price_range[1])
             )
 
+    base_cost = models.DecimalField(max_digits=10, decimal_places=3, default=0, validators=[MinValueValidator(0)], verbose_name=_('base cost'), help_text=_('Minimum charge (e.g. stocking fee)'))
+
+    multiple = models.PositiveIntegerField(default=1, validators=[MinValueValidator(1)], verbose_name=_('multiple'), help_text=_('Sell multiple'))
+
+    get_price = common.models.get_price
+
+    @property
+    def has_price_breaks(self):
+        return self.price_breaks.count() > 0
+
+    @property
+    def price_breaks(self):
+        """ Return the associated price breaks in the correct order """
+        return self.salepricebreaks.order_by('quantity').all()
+
+    @property
+    def unit_pricing(self):
+        return self.get_price(1)
+
+    def add_price_break(self, quantity, price):
+        """
+        Create a new price break for this part
+
+        args:
+            quantity - Numerical quantity
+            price - Must be a Money object
+        """
+
+        # Check if a price break at that quantity already exists...
+        if self.price_breaks.filter(quantity=quantity, part=self.pk).exists():
+            return
+
+        PartSellPriceBreak.objects.create(
+            part=self,
+            quantity=quantity,
+            price=price
+        )
+
     @transaction.atomic
     def copy_bom_from(self, other, clear=True, **kwargs):
         """