From 4bedf0ed4c0158e29867bf0c6f96ba86467dfa65 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 22 Apr 2018 21:54:12 +1000 Subject: [PATCH] Finally got migrations working together --- InvenTree/InvenTree/urls.py | 2 + InvenTree/build/migrations/0001_initial.py | 23 +-- .../migrations/0002_auto_20180416_1423.py | 36 ---- InvenTree/build/migrations/0003_build_part.py | 23 --- .../migrations/0004_auto_20180417_0657.py | 48 ----- .../migrations/0004_auto_20180417_2127.py | 20 --- .../migrations/0005_buildoutput_batch.py | 20 --- .../migrations/0006_auto_20180417_0933.py | 66 ------- .../migrations/0007_auto_20180417_1025.py | 21 --- .../migrations/0008_merge_20180417_2307.py | 16 -- .../migrations/0009_auto_20180417_1316.py | 21 --- .../migrations/0010_auto_20180418_0028.py | 21 --- .../migrations/0011_auto_20180417_1514.py | 21 --- .../migrations/0012_auto_20180417_1516.py | 20 --- InvenTree/build/models.py | 4 +- InvenTree/company/admin.py | 15 +- InvenTree/company/forms.py | 31 +--- InvenTree/company/migrations/0001_initial.py | 89 +-------- .../migrations/0002_auto_20180412_0622.py | 21 --- .../migrations/0003_auto_20180414_0540.py | 30 ---- .../migrations/0004_auto_20180414_0624.py | 21 --- .../migrations/0005_auto_20180415_0255.py | 30 ---- .../migrations/0006_auto_20180415_1011.py | 26 --- .../migrations/0007_auto_20180416_1253.py | 36 ---- .../migrations/0008_delete_customer.py | 18 -- .../migrations/0009_auto_20180417_1411.py | 42 ----- .../migrations/0009_auto_20180417_1516.py | 25 --- .../migrations/0010_auto_20180417_1420.py | 20 --- .../migrations/0011_auto_20180417_1436.py | 61 ------- .../migrations/0012_auto_20180417_1447.py | 25 --- .../migrations/0013_merge_20180417_1517.py | 16 -- .../migrations/0014_auto_20180417_1520.py | 31 ---- .../0015_supplierorderlineitem_received.py | 20 --- InvenTree/company/models.py | 169 +++--------------- .../company/templates/company/index.html | 18 +- InvenTree/company/urls.py | 78 +------- InvenTree/company/views.py | 61 +------ InvenTree/part/admin.py | 14 +- InvenTree/part/forms.py | 25 +++ InvenTree/part/migrations/0001_initial.py | 117 ++++++------ .../migrations/0002_auto_20180412_0600.py | 48 ----- ...ation.py => 0002_part_default_location.py} | 8 +- .../migrations/0003_auto_20180412_0644.py | 19 -- .../migrations/0004_auto_20180413_0834.py | 21 --- .../migrations/0005_auto_20180413_1230.py | 20 --- .../migrations/0006_auto_20180414_0403.py | 21 --- .../migrations/0007_auto_20180414_0416.py | 33 ---- InvenTree/part/migrations/0008_part_url.py | 20 --- InvenTree/part/migrations/0009_part_image.py | 20 --- .../migrations/0010_auto_20180414_0725.py | 21 --- .../part/migrations/0011_partattachment.py | 25 --- .../migrations/0012_auto_20180414_1032.py | 21 --- .../migrations/0013_auto_20180414_2238.py | 24 --- .../migrations/0014_auto_20180415_0107.py | 21 --- .../migrations/0015_auto_20180415_0302.py | 20 --- .../migrations/0016_auto_20180415_0316.py | 20 --- .../part/migrations/0017_part_purchaseable.py | 20 --- .../part/migrations/0018_part_buildable.py | 20 --- .../migrations/0019_auto_20180416_1249.py | 62 ------- .../part/migrations/0020_part_salable.py | 20 --- .../migrations/0022_auto_20180417_0819.py | 27 --- InvenTree/part/migrations/0023_part_notes.py | 20 --- InvenTree/part/models.py | 79 +++++++- InvenTree/part/urls.py | 13 ++ InvenTree/part/views.py | 58 +++++- InvenTree/stock/migrations/0001_initial.py | 83 ++++----- .../migrations/0002_auto_20180412_0622.py | 34 ---- .../migrations/0003_auto_20180413_1230.py | 20 --- .../migrations/0004_auto_20180414_1032.py | 21 --- .../migrations/0005_auto_20180415_0107.py | 21 --- .../migrations/0006_auto_20180415_0302.py | 20 --- .../migrations/0007_auto_20180416_0853.py | 81 --------- .../stock/migrations/0008_stockitem_url.py | 20 --- .../migrations/0009_auto_20180416_1253.py | 46 ----- .../stock/migrations/0010_stockitem_build.py | 22 --- .../migrations/0011_auto_20180417_2127.py | 21 --- .../migrations/0012_auto_20180417_1316.py | 21 --- .../migrations/0013_auto_20180417_1337.py | 21 --- .../migrations/0014_auto_20180418_0028.py | 21 --- .../migrations/0015_auto_20180417_1514.py | 21 --- .../migrations/0016_auto_20180417_1516.py | 20 --- .../migrations/0017_auto_20180417_1536.py | 24 --- .../0018_stockitemtracking_system.py | 20 --- InvenTree/stock/models.py | 13 +- InvenTree/templates/navbar.html | 1 - Makefile | 2 +- 86 files changed, 356 insertions(+), 2279 deletions(-) delete mode 100644 InvenTree/build/migrations/0002_auto_20180416_1423.py delete mode 100644 InvenTree/build/migrations/0003_build_part.py delete mode 100644 InvenTree/build/migrations/0004_auto_20180417_0657.py delete mode 100644 InvenTree/build/migrations/0004_auto_20180417_2127.py delete mode 100644 InvenTree/build/migrations/0005_buildoutput_batch.py delete mode 100644 InvenTree/build/migrations/0006_auto_20180417_0933.py delete mode 100644 InvenTree/build/migrations/0007_auto_20180417_1025.py delete mode 100644 InvenTree/build/migrations/0008_merge_20180417_2307.py delete mode 100644 InvenTree/build/migrations/0009_auto_20180417_1316.py delete mode 100644 InvenTree/build/migrations/0010_auto_20180418_0028.py delete mode 100644 InvenTree/build/migrations/0011_auto_20180417_1514.py delete mode 100644 InvenTree/build/migrations/0012_auto_20180417_1516.py delete mode 100644 InvenTree/company/migrations/0002_auto_20180412_0622.py delete mode 100644 InvenTree/company/migrations/0003_auto_20180414_0540.py delete mode 100644 InvenTree/company/migrations/0004_auto_20180414_0624.py delete mode 100644 InvenTree/company/migrations/0005_auto_20180415_0255.py delete mode 100644 InvenTree/company/migrations/0006_auto_20180415_1011.py delete mode 100644 InvenTree/company/migrations/0007_auto_20180416_1253.py delete mode 100644 InvenTree/company/migrations/0008_delete_customer.py delete mode 100644 InvenTree/company/migrations/0009_auto_20180417_1411.py delete mode 100644 InvenTree/company/migrations/0009_auto_20180417_1516.py delete mode 100644 InvenTree/company/migrations/0010_auto_20180417_1420.py delete mode 100644 InvenTree/company/migrations/0011_auto_20180417_1436.py delete mode 100644 InvenTree/company/migrations/0012_auto_20180417_1447.py delete mode 100644 InvenTree/company/migrations/0013_merge_20180417_1517.py delete mode 100644 InvenTree/company/migrations/0014_auto_20180417_1520.py delete mode 100644 InvenTree/company/migrations/0015_supplierorderlineitem_received.py delete mode 100644 InvenTree/part/migrations/0002_auto_20180412_0600.py rename InvenTree/part/migrations/{0021_part_default_location.py => 0002_part_default_location.py} (69%) delete mode 100644 InvenTree/part/migrations/0003_auto_20180412_0644.py delete mode 100644 InvenTree/part/migrations/0004_auto_20180413_0834.py delete mode 100644 InvenTree/part/migrations/0005_auto_20180413_1230.py delete mode 100644 InvenTree/part/migrations/0006_auto_20180414_0403.py delete mode 100644 InvenTree/part/migrations/0007_auto_20180414_0416.py delete mode 100644 InvenTree/part/migrations/0008_part_url.py delete mode 100644 InvenTree/part/migrations/0009_part_image.py delete mode 100644 InvenTree/part/migrations/0010_auto_20180414_0725.py delete mode 100644 InvenTree/part/migrations/0011_partattachment.py delete mode 100644 InvenTree/part/migrations/0012_auto_20180414_1032.py delete mode 100644 InvenTree/part/migrations/0013_auto_20180414_2238.py delete mode 100644 InvenTree/part/migrations/0014_auto_20180415_0107.py delete mode 100644 InvenTree/part/migrations/0015_auto_20180415_0302.py delete mode 100644 InvenTree/part/migrations/0016_auto_20180415_0316.py delete mode 100644 InvenTree/part/migrations/0017_part_purchaseable.py delete mode 100644 InvenTree/part/migrations/0018_part_buildable.py delete mode 100644 InvenTree/part/migrations/0019_auto_20180416_1249.py delete mode 100644 InvenTree/part/migrations/0020_part_salable.py delete mode 100644 InvenTree/part/migrations/0022_auto_20180417_0819.py delete mode 100644 InvenTree/part/migrations/0023_part_notes.py delete mode 100644 InvenTree/stock/migrations/0002_auto_20180412_0622.py delete mode 100644 InvenTree/stock/migrations/0003_auto_20180413_1230.py delete mode 100644 InvenTree/stock/migrations/0004_auto_20180414_1032.py delete mode 100644 InvenTree/stock/migrations/0005_auto_20180415_0107.py delete mode 100644 InvenTree/stock/migrations/0006_auto_20180415_0302.py delete mode 100644 InvenTree/stock/migrations/0007_auto_20180416_0853.py delete mode 100644 InvenTree/stock/migrations/0008_stockitem_url.py delete mode 100644 InvenTree/stock/migrations/0009_auto_20180416_1253.py delete mode 100644 InvenTree/stock/migrations/0010_stockitem_build.py delete mode 100644 InvenTree/stock/migrations/0011_auto_20180417_2127.py delete mode 100644 InvenTree/stock/migrations/0012_auto_20180417_1316.py delete mode 100644 InvenTree/stock/migrations/0013_auto_20180417_1337.py delete mode 100644 InvenTree/stock/migrations/0014_auto_20180418_0028.py delete mode 100644 InvenTree/stock/migrations/0015_auto_20180417_1514.py delete mode 100644 InvenTree/stock/migrations/0016_auto_20180417_1516.py delete mode 100644 InvenTree/stock/migrations/0017_auto_20180417_1536.py delete mode 100644 InvenTree/stock/migrations/0018_stockitemtracking_system.py diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 3e70aa560a..7ef9e6163c 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -4,6 +4,7 @@ from django.contrib import admin from part.urls import part_api_urls, part_cat_api_urls from part.urls import bom_api_urls from part.urls import part_urls +from part.urls import supplier_part_urls from stock.urls import stock_api_urls, stock_api_loc_urls from stock.urls import stock_urls @@ -69,6 +70,7 @@ urlpatterns = [ url(r'^part/', include(part_urls)), url(r'^stock/', include(stock_urls)), url(r'^company/', include(company_urls)), + url(r'^supplier-part/', include(supplier_part_urls)), url(r'^build/', include(build_urls)), url(r'^admin/', admin.site.urls), diff --git a/InvenTree/build/migrations/0001_initial.py b/InvenTree/build/migrations/0001_initial.py index 2827070df8..26e835b978 100644 --- a/InvenTree/build/migrations/0001_initial.py +++ b/InvenTree/build/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 14:03 +# Generated by Django 1.11.12 on 2018-04-22 11:53 from __future__ import unicode_literals import django.core.validators @@ -12,7 +12,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('part', '0019_auto_20180416_1249'), + ('part', '0001_initial'), ] operations = [ @@ -20,21 +20,14 @@ class Migration(migrations.Migration): name='Build', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('status', models.PositiveIntegerField(choices=[(b'20', b'Allocated'), (b'30', b'Cancelled'), (b'40', b'Complete'), (b'10', b'Pending')], default=10)), - ], - ), - migrations.CreateModel( - name='BuildOutput', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('part_name', models.CharField(max_length=255)), + ('batch', models.CharField(blank=True, help_text='Batch code for this build output', max_length=100, null=True)), + ('status', models.PositiveIntegerField(choices=[(40, 'Complete'), (10, 'Pending'), (20, 'Holding'), (30, 'Cancelled')], default=10, validators=[django.core.validators.MinValueValidator(0)])), + ('creation_date', models.DateField(auto_now=True)), + ('completion_date', models.DateField(blank=True, null=True)), + ('title', models.CharField(help_text='Brief description of the build', max_length=100)), ('quantity', models.PositiveIntegerField(default=1, help_text='Number of parts to build', validators=[django.core.validators.MinValueValidator(1)])), - ('build', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='outputs', to='build.Build')), + ('notes', models.TextField(blank=True)), ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='builds', to='part.Part')), ], ), - migrations.AlterUniqueTogether( - name='buildoutput', - unique_together=set([('part', 'build')]), - ), ] diff --git a/InvenTree/build/migrations/0002_auto_20180416_1423.py b/InvenTree/build/migrations/0002_auto_20180416_1423.py deleted file mode 100644 index 59e747efbc..0000000000 --- a/InvenTree/build/migrations/0002_auto_20180416_1423.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 14:23 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0001_initial'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='buildoutput', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='buildoutput', - name='build', - ), - migrations.RemoveField( - model_name='buildoutput', - name='part', - ), - migrations.AddField( - model_name='build', - name='quantity', - field=models.PositiveIntegerField(default=1, help_text='Number of parts to build', validators=[django.core.validators.MinValueValidator(1)]), - ), - migrations.DeleteModel( - name='BuildOutput', - ), - ] diff --git a/InvenTree/build/migrations/0003_build_part.py b/InvenTree/build/migrations/0003_build_part.py deleted file mode 100644 index a832f1da73..0000000000 --- a/InvenTree/build/migrations/0003_build_part.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 14:28 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0019_auto_20180416_1249'), - ('build', '0002_auto_20180416_1423'), - ] - - operations = [ - migrations.AddField( - model_name='build', - name='part', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='builds', to='part.Part'), - preserve_default=False, - ), - ] diff --git a/InvenTree/build/migrations/0004_auto_20180417_0657.py b/InvenTree/build/migrations/0004_auto_20180417_0657.py deleted file mode 100644 index 23211a8d7c..0000000000 --- a/InvenTree/build/migrations/0004_auto_20180417_0657.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 06:57 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0019_auto_20180416_1249'), - ('build', '0003_build_part'), - ] - - operations = [ - migrations.CreateModel( - name='BuildOutput', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.PositiveIntegerField(default=1, help_text='Number of parts to build', validators=[django.core.validators.MinValueValidator(1)])), - ], - ), - migrations.RemoveField( - model_name='build', - name='part', - ), - migrations.RemoveField( - model_name='build', - name='quantity', - ), - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[(40, 'Cancelled'), (10, 'Pending'), (20, 'Allocated'), (50, 'Complete'), (30, 'Holding')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - migrations.AddField( - model_name='buildoutput', - name='build', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='outputs', to='build.Build'), - ), - migrations.AddField( - model_name='buildoutput', - name='part', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='builds', to='part.Part'), - ), - ] diff --git a/InvenTree/build/migrations/0004_auto_20180417_2127.py b/InvenTree/build/migrations/0004_auto_20180417_2127.py deleted file mode 100644 index 3898af57ea..0000000000 --- a/InvenTree/build/migrations/0004_auto_20180417_2127.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-17 11:27 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0003_build_part'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[('20', 'Allocated'), ('30', 'Cancelled'), ('40', 'Complete'), ('10', 'Pending')], default=10), - ), - ] diff --git a/InvenTree/build/migrations/0005_buildoutput_batch.py b/InvenTree/build/migrations/0005_buildoutput_batch.py deleted file mode 100644 index b53c83270e..0000000000 --- a/InvenTree/build/migrations/0005_buildoutput_batch.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 08:29 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0004_auto_20180417_0657'), - ] - - operations = [ - migrations.AddField( - model_name='buildoutput', - name='batch', - field=models.CharField(blank=True, help_text='Batch code for this build output', max_length=100), - ), - ] diff --git a/InvenTree/build/migrations/0006_auto_20180417_0933.py b/InvenTree/build/migrations/0006_auto_20180417_0933.py deleted file mode 100644 index 3ed5efb74e..0000000000 --- a/InvenTree/build/migrations/0006_auto_20180417_0933.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 09:33 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0022_auto_20180417_0819'), - ('build', '0005_buildoutput_batch'), - ] - - operations = [ - migrations.RemoveField( - model_name='buildoutput', - name='build', - ), - migrations.RemoveField( - model_name='buildoutput', - name='part', - ), - migrations.AddField( - model_name='build', - name='batch', - field=models.CharField(blank=True, help_text='Batch code for this build output', max_length=100, null=True), - ), - migrations.AddField( - model_name='build', - name='completion_date', - field=models.DateField(blank=True, null=True), - ), - migrations.AddField( - model_name='build', - name='creation_date', - field=models.DateField(auto_now=True), - ), - migrations.AddField( - model_name='build', - name='notes', - field=models.CharField(blank=True, max_length=500), - ), - migrations.AddField( - model_name='build', - name='part', - field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='builds', to='part.Part'), - preserve_default=False, - ), - migrations.AddField( - model_name='build', - name='quantity', - field=models.PositiveIntegerField(default=1, help_text='Number of parts to build', validators=[django.core.validators.MinValueValidator(1)]), - ), - migrations.AddField( - model_name='build', - name='title', - field=models.CharField(default='Build title', help_text='Brief description of the build', max_length=100), - preserve_default=False, - ), - migrations.DeleteModel( - name='BuildOutput', - ), - ] diff --git a/InvenTree/build/migrations/0007_auto_20180417_1025.py b/InvenTree/build/migrations/0007_auto_20180417_1025.py deleted file mode 100644 index d50af03384..0000000000 --- a/InvenTree/build/migrations/0007_auto_20180417_1025.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 10:25 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0006_auto_20180417_0933'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[(40, 'Complete'), (10, 'Pending'), (20, 'Holding'), (30, 'Cancelled')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/build/migrations/0008_merge_20180417_2307.py b/InvenTree/build/migrations/0008_merge_20180417_2307.py deleted file mode 100644 index 70b385da04..0000000000 --- a/InvenTree/build/migrations/0008_merge_20180417_2307.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-17 13:07 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0004_auto_20180417_2127'), - ('build', '0007_auto_20180417_1025'), - ] - - operations = [ - ] diff --git a/InvenTree/build/migrations/0009_auto_20180417_1316.py b/InvenTree/build/migrations/0009_auto_20180417_1316.py deleted file mode 100644 index 55af1de801..0000000000 --- a/InvenTree/build/migrations/0009_auto_20180417_1316.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 13:16 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0008_merge_20180417_2307'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[(40, 'Complete'), (10, 'Pending'), (20, 'Holding'), (30, 'Cancelled')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/build/migrations/0010_auto_20180418_0028.py b/InvenTree/build/migrations/0010_auto_20180418_0028.py deleted file mode 100644 index a75488c11b..0000000000 --- a/InvenTree/build/migrations/0010_auto_20180418_0028.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-17 14:28 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0009_auto_20180417_1316'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'Pending'), (20, 'Holding'), (30, 'Cancelled'), (40, 'Complete')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/build/migrations/0011_auto_20180417_1514.py b/InvenTree/build/migrations/0011_auto_20180417_1514.py deleted file mode 100644 index 4ecfce80d5..0000000000 --- a/InvenTree/build/migrations/0011_auto_20180417_1514.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:14 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0010_auto_20180418_0028'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='status', - field=models.PositiveIntegerField(choices=[(40, 'Complete'), (10, 'Pending'), (20, 'Holding'), (30, 'Cancelled')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/build/migrations/0012_auto_20180417_1516.py b/InvenTree/build/migrations/0012_auto_20180417_1516.py deleted file mode 100644 index e3e75c3f47..0000000000 --- a/InvenTree/build/migrations/0012_auto_20180417_1516.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:16 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0011_auto_20180417_1514'), - ] - - operations = [ - migrations.AlterField( - model_name='build', - name='notes', - field=models.TextField(blank=True), - ), - ] diff --git a/InvenTree/build/models.py b/InvenTree/build/models.py index 32bd2e8464..385ce01658 100644 --- a/InvenTree/build/models.py +++ b/InvenTree/build/models.py @@ -6,7 +6,7 @@ from django.utils.translation import ugettext as _ from django.db import models from django.core.validators import MinValueValidator -from part.models import Part +#from part.models import Part class Build(models.Model): @@ -49,7 +49,7 @@ class Build(models.Model): # A reference to the part being built # Only 'buildable' parts can be selected - part = models.ForeignKey(Part, on_delete=models.CASCADE, + part = models.ForeignKey('part.Part', on_delete=models.CASCADE, related_name='builds', limit_choices_to={'buildable': True}, ) diff --git a/InvenTree/company/admin.py b/InvenTree/company/admin.py index 2edc1a5d24..97ee0cf8e8 100644 --- a/InvenTree/company/admin.py +++ b/InvenTree/company/admin.py @@ -1,21 +1,16 @@ from django.contrib import admin from import_export.admin import ImportExportModelAdmin -from .models import Company, SupplierPart -from .models import SupplierOrder +from .models import Company +#from .models import SupplierOrder class CompanyAdmin(ImportExportModelAdmin): list_display = ('name', 'website', 'contact') -class SupplierPartAdmin(ImportExportModelAdmin): - list_display = ('part', 'supplier', 'SKU') - - -class SupplierOrderAdmin(admin.ModelAdmin): - list_display = ('internal_ref', 'supplier', 'issued_date', 'delivery_date', 'status') +#class SupplierOrderAdmin(admin.ModelAdmin): +# list_display = ('internal_ref', 'supplier', 'issued_date', 'delivery_date', 'status') admin.site.register(Company, CompanyAdmin) -admin.site.register(SupplierPart, SupplierPartAdmin) -admin.site.register(SupplierOrder, SupplierOrderAdmin) +#admin.site.register(SupplierOrder, SupplierOrderAdmin) diff --git a/InvenTree/company/forms.py b/InvenTree/company/forms.py index 90f49fca8e..b9766e3f36 100644 --- a/InvenTree/company/forms.py +++ b/InvenTree/company/forms.py @@ -2,10 +2,10 @@ from django import forms from crispy_forms.helper import FormHelper from crispy_forms.layout import Submit -from .models import Company, SupplierPart -from .models import SupplierOrder +from .models import Company +""" class EditSupplierOrderForm(forms.ModelForm): def __init__(self, *args, **kwargs): @@ -26,7 +26,7 @@ class EditSupplierOrderForm(forms.ModelForm): 'notes', 'issued_date', ] - +""" class EditCompanyForm(forms.ModelForm): @@ -50,29 +50,6 @@ class EditCompanyForm(forms.ModelForm): 'phone', 'email', 'contact', + 'image', 'notes' ] - - -class EditSupplierPartForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - super(EditSupplierPartForm, self).__init__(*args, **kwargs) - self.helper = FormHelper() - - self.helper.form_id = 'id-edit-part-form' - self.helper.form_class = 'blueForms' - self.helper.form_method = 'post' - - self.helper.add_input(Submit('submit', 'Submit')) - - class Meta: - model = SupplierPart - fields = [ - 'supplier', - 'SKU', - 'part', - 'description', - 'URL', - 'manufacturer', - 'MPN', - ] diff --git a/InvenTree/company/migrations/0001_initial.py b/InvenTree/company/migrations/0001_initial.py index eb2d181f2c..791011304c 100644 --- a/InvenTree/company/migrations/0001_initial.py +++ b/InvenTree/company/migrations/0001_initial.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 05:02 +# Generated by Django 1.11.12 on 2018-04-22 11:53 from __future__ import unicode_literals -import django.core.validators +import company.models from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): @@ -12,92 +11,22 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('part', '0001_initial'), ] operations = [ migrations.CreateModel( - name='Customer', + name='Company', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, unique=True)), - ('website', models.URLField(blank=True)), - ('address', models.CharField(blank=True, max_length=200)), + ('name', models.CharField(help_text='Company naem', max_length=100, unique=True)), + ('description', models.CharField(max_length=500)), + ('website', models.URLField(blank=True, help_text='Company website URL')), + ('address', models.CharField(blank=True, help_text='Company address', max_length=200)), ('phone', models.CharField(blank=True, max_length=50)), ('email', models.EmailField(blank=True, max_length=254)), ('contact', models.CharField(blank=True, max_length=100)), - ('notes', models.CharField(blank=True, max_length=500)), + ('image', models.ImageField(blank=True, max_length=255, null=True, upload_to=company.models.rename_company_image)), + ('notes', models.TextField(blank=True)), ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='Manufacturer', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, unique=True)), - ('website', models.URLField(blank=True)), - ('address', models.CharField(blank=True, max_length=200)), - ('phone', models.CharField(blank=True, max_length=50)), - ('email', models.EmailField(blank=True, max_length=254)), - ('contact', models.CharField(blank=True, max_length=100)), - ('notes', models.CharField(blank=True, max_length=500)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='Supplier', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, unique=True)), - ('website', models.URLField(blank=True)), - ('address', models.CharField(blank=True, max_length=200)), - ('phone', models.CharField(blank=True, max_length=50)), - ('email', models.EmailField(blank=True, max_length=254)), - ('contact', models.CharField(blank=True, max_length=100)), - ('notes', models.CharField(blank=True, max_length=500)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='SupplierPart', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('SKU', models.CharField(max_length=100)), - ('MPN', models.CharField(blank=True, max_length=100)), - ('URL', models.URLField(blank=True)), - ('description', models.CharField(blank=True, max_length=250)), - ('single_price', models.DecimalField(decimal_places=3, default=0, max_digits=10)), - ('base_cost', models.DecimalField(decimal_places=3, default=0, max_digits=10)), - ('packaging', models.CharField(blank=True, max_length=50)), - ('multiple', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), - ('minimum', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), - ('lead_time', models.DurationField(blank=True, null=True)), - ('manufacturer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='supplier.Manufacturer')), - ('part', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='part.Part')), - ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='supplier.Supplier')), - ], - ), - migrations.CreateModel( - name='SupplierPriceBreak', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(0)])), - ('cost', models.DecimalField(decimal_places=3, max_digits=10)), - ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='price_breaks', to='supplier.SupplierPart')), - ], - ), - migrations.AlterUniqueTogether( - name='supplierpricebreak', - unique_together=set([('part', 'quantity')]), - ), - migrations.AlterUniqueTogether( - name='supplierpart', - unique_together=set([('part', 'supplier', 'SKU')]), ), ] diff --git a/InvenTree/company/migrations/0002_auto_20180412_0622.py b/InvenTree/company/migrations/0002_auto_20180412_0622.py deleted file mode 100644 index cbd415caa2..0000000000 --- a/InvenTree/company/migrations/0002_auto_20180412_0622.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 06:22 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='supplierpart', - name='part', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='supplier_parts', to='part.Part'), - ), - ] diff --git a/InvenTree/company/migrations/0003_auto_20180414_0540.py b/InvenTree/company/migrations/0003_auto_20180414_0540.py deleted file mode 100644 index 3c8c391cee..0000000000 --- a/InvenTree/company/migrations/0003_auto_20180414_0540.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 05:40 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0002_auto_20180412_0622'), - ] - - operations = [ - migrations.AddField( - model_name='customer', - name='description', - field=models.CharField(blank=True, max_length=500), - ), - migrations.AddField( - model_name='manufacturer', - name='description', - field=models.CharField(blank=True, max_length=500), - ), - migrations.AddField( - model_name='supplier', - name='description', - field=models.CharField(blank=True, max_length=500), - ), - ] diff --git a/InvenTree/company/migrations/0004_auto_20180414_0624.py b/InvenTree/company/migrations/0004_auto_20180414_0624.py deleted file mode 100644 index c9701ecf61..0000000000 --- a/InvenTree/company/migrations/0004_auto_20180414_0624.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 06:24 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0003_auto_20180414_0540'), - ] - - operations = [ - migrations.AlterField( - model_name='supplierpart', - name='supplier', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parts', to='supplier.Supplier'), - ), - ] diff --git a/InvenTree/company/migrations/0005_auto_20180415_0255.py b/InvenTree/company/migrations/0005_auto_20180415_0255.py deleted file mode 100644 index 5561db90d5..0000000000 --- a/InvenTree/company/migrations/0005_auto_20180415_0255.py +++ /dev/null @@ -1,30 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 02:55 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0004_auto_20180414_0624'), - ] - - operations = [ - migrations.AlterField( - model_name='customer', - name='description', - field=models.CharField(max_length=500), - ), - migrations.AlterField( - model_name='manufacturer', - name='description', - field=models.CharField(max_length=500), - ), - migrations.AlterField( - model_name='supplier', - name='description', - field=models.CharField(max_length=500), - ), - ] diff --git a/InvenTree/company/migrations/0006_auto_20180415_1011.py b/InvenTree/company/migrations/0006_auto_20180415_1011.py deleted file mode 100644 index e55a81e7d3..0000000000 --- a/InvenTree/company/migrations/0006_auto_20180415_1011.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 10:11 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0005_auto_20180415_0255'), - ] - - operations = [ - migrations.AlterField( - model_name='supplierpart', - name='manufacturer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='supplier.Manufacturer'), - ), - migrations.AlterField( - model_name='supplierpart', - name='part', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='supplier_parts', to='part.Part'), - ), - ] diff --git a/InvenTree/company/migrations/0007_auto_20180416_1253.py b/InvenTree/company/migrations/0007_auto_20180416_1253.py deleted file mode 100644 index bf75d0fba9..0000000000 --- a/InvenTree/company/migrations/0007_auto_20180416_1253.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 12:53 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0006_auto_20180415_1011'), - ] - - operations = [ - migrations.AlterField( - model_name='supplierpart', - name='MPN', - field=models.CharField(blank=True, help_text='Manufacturer part number', max_length=100), - ), - migrations.AlterField( - model_name='supplierpart', - name='SKU', - field=models.CharField(help_text='Supplier stock keeping unit', max_length=100), - ), - migrations.AlterField( - model_name='supplierpart', - name='manufacturer', - field=models.ForeignKey(blank=True, help_text='Manufacturer', null=True, on_delete=django.db.models.deletion.SET_NULL, to='supplier.Manufacturer'), - ), - migrations.AlterField( - model_name='supplierpart', - name='part', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supplier_parts', to='part.Part'), - ), - ] diff --git a/InvenTree/company/migrations/0008_delete_customer.py b/InvenTree/company/migrations/0008_delete_customer.py deleted file mode 100644 index 09d7234f35..0000000000 --- a/InvenTree/company/migrations/0008_delete_customer.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 13:37 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0007_auto_20180416_1253'), - ] - - operations = [ - migrations.DeleteModel( - name='Customer', - ), - ] diff --git a/InvenTree/company/migrations/0009_auto_20180417_1411.py b/InvenTree/company/migrations/0009_auto_20180417_1411.py deleted file mode 100644 index b89f2adcf6..0000000000 --- a/InvenTree/company/migrations/0009_auto_20180417_1411.py +++ /dev/null @@ -1,42 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 14:11 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0008_delete_customer'), - ] - - operations = [ - migrations.CreateModel( - name='SupplierOrder', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('internal_ref', models.CharField(max_length=25, unique=True)), - ('created_date', models.DateField(auto_now_add=True)), - ('issued_date', models.DateField(blank=True, help_text='Date the purchase order was issued')), - ('notes', models.TextField(blank=True, help_text='Order notes')), - ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='supplier.Supplier')), - ], - ), - migrations.CreateModel( - name='SupplierOrderLineItem', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('line_number', models.PositiveIntegerField(default=1)), - ('quantity', models.PositiveIntegerField(default=1)), - ('notes', models.TextField(blank=True)), - ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='supplier.SupplierOrder')), - ('part', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='supplier.SupplierPart')), - ], - ), - migrations.AlterUniqueTogether( - name='supplierorderlineitem', - unique_together=set([('order', 'line_number'), ('order', 'part')]), - ), - ] diff --git a/InvenTree/company/migrations/0009_auto_20180417_1516.py b/InvenTree/company/migrations/0009_auto_20180417_1516.py deleted file mode 100644 index 2a503ef682..0000000000 --- a/InvenTree/company/migrations/0009_auto_20180417_1516.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:16 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0008_delete_customer'), - ] - - operations = [ - migrations.AlterField( - model_name='manufacturer', - name='notes', - field=models.TextField(blank=True), - ), - migrations.AlterField( - model_name='supplier', - name='notes', - field=models.TextField(blank=True), - ), - ] diff --git a/InvenTree/company/migrations/0010_auto_20180417_1420.py b/InvenTree/company/migrations/0010_auto_20180417_1420.py deleted file mode 100644 index a8e8a8436c..0000000000 --- a/InvenTree/company/migrations/0010_auto_20180417_1420.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 14:20 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0009_auto_20180417_1411'), - ] - - operations = [ - migrations.AlterField( - model_name='supplierorder', - name='issued_date', - field=models.DateField(blank=True, help_text='Date the purchase order was issued', null=True), - ), - ] diff --git a/InvenTree/company/migrations/0011_auto_20180417_1436.py b/InvenTree/company/migrations/0011_auto_20180417_1436.py deleted file mode 100644 index b050871bbd..0000000000 --- a/InvenTree/company/migrations/0011_auto_20180417_1436.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 14:36 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0010_auto_20180417_1420'), - ] - - operations = [ - migrations.AlterField( - model_name='manufacturer', - name='address', - field=models.CharField(blank=True, help_text='Company address', max_length=200), - ), - migrations.AlterField( - model_name='manufacturer', - name='name', - field=models.CharField(help_text='Company naem', max_length=100, unique=True), - ), - migrations.AlterField( - model_name='manufacturer', - name='notes', - field=models.TextField(blank=True), - ), - migrations.AlterField( - model_name='manufacturer', - name='website', - field=models.URLField(blank=True, help_text='Company website URL'), - ), - migrations.AlterField( - model_name='supplier', - name='address', - field=models.CharField(blank=True, help_text='Company address', max_length=200), - ), - migrations.AlterField( - model_name='supplier', - name='name', - field=models.CharField(help_text='Company naem', max_length=100, unique=True), - ), - migrations.AlterField( - model_name='supplier', - name='notes', - field=models.TextField(blank=True), - ), - migrations.AlterField( - model_name='supplier', - name='website', - field=models.URLField(blank=True, help_text='Company website URL'), - ), - migrations.AlterField( - model_name='supplierorder', - name='supplier', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='orders', to='supplier.Supplier'), - ), - ] diff --git a/InvenTree/company/migrations/0012_auto_20180417_1447.py b/InvenTree/company/migrations/0012_auto_20180417_1447.py deleted file mode 100644 index 2423b723ae..0000000000 --- a/InvenTree/company/migrations/0012_auto_20180417_1447.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 14:47 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0011_auto_20180417_1436'), - ] - - operations = [ - migrations.AddField( - model_name='supplierorder', - name='delivery_date', - field=models.DateField(blank=True, null=True), - ), - migrations.AddField( - model_name='supplierorder', - name='status', - field=models.PositiveIntegerField(choices=[(40, 'Cancelled'), (10, 'Pending'), (20, 'Placed'), (50, 'Lost'), (30, 'Received')], default=10), - ), - ] diff --git a/InvenTree/company/migrations/0013_merge_20180417_1517.py b/InvenTree/company/migrations/0013_merge_20180417_1517.py deleted file mode 100644 index 021c3fcf0f..0000000000 --- a/InvenTree/company/migrations/0013_merge_20180417_1517.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:17 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0009_auto_20180417_1516'), - ('supplier', '0012_auto_20180417_1447'), - ] - - operations = [ - ] diff --git a/InvenTree/company/migrations/0014_auto_20180417_1520.py b/InvenTree/company/migrations/0014_auto_20180417_1520.py deleted file mode 100644 index aceb80a5e5..0000000000 --- a/InvenTree/company/migrations/0014_auto_20180417_1520.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:20 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0022_auto_20180417_0819'), - ('supplier', '0013_merge_20180417_1517'), - ] - - operations = [ - migrations.RenameField( - model_name='supplierorderlineitem', - old_name='part', - new_name='supplier_part', - ), - migrations.AddField( - model_name='supplierorderlineitem', - name='internal_part', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='part.Part'), - ), - migrations.AlterUniqueTogether( - name='supplierorderlineitem', - unique_together=set([('order', 'line_number'), ('order', 'internal_part'), ('order', 'supplier_part')]), - ), - ] diff --git a/InvenTree/company/migrations/0015_supplierorderlineitem_received.py b/InvenTree/company/migrations/0015_supplierorderlineitem_received.py deleted file mode 100644 index 4d75051884..0000000000 --- a/InvenTree/company/migrations/0015_supplierorderlineitem_received.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:22 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0014_auto_20180417_1520'), - ] - - operations = [ - migrations.AddField( - model_name='supplierorderlineitem', - name='received', - field=models.BooleanField(default=False), - ), - ] diff --git a/InvenTree/company/models.py b/InvenTree/company/models.py index 4438f3ed3f..38da4cb7f3 100644 --- a/InvenTree/company/models.py +++ b/InvenTree/company/models.py @@ -1,16 +1,31 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +import os + from django.utils.translation import ugettext as _ from django.db import models from django.core.validators import MinValueValidator -from part.models import Part + +def rename_company_image(instance, filename): + base = 'company_images' + + if filename.count('.') > 0: + ext = filename.split('.')[-1] + else: + ext = '' + + fn = 'company_{pk}_img'.format(pk=instance.pk) + + if ext: + fn += '.' + ext + + return os.path.join(base,fn) + class Company(models.Model): - """ Abstract model representing an external company - """ name = models.CharField(max_length=100, unique=True, help_text='Company naem') @@ -30,6 +45,8 @@ class Company(models.Model): contact = models.CharField(max_length=100, blank=True) + image = models.ImageField(upload_to=rename_company_image, max_length=255, null=True, blank=True) + notes = models.TextField(blank=True) def __str__(self): @@ -54,149 +71,3 @@ class Company(models.Model): def has_orders(self): return self.order_count > 0 - -class SupplierPart(models.Model): - """ Represents a unique part as provided by a Supplier - Each SupplierPart is identified by a MPN (Manufacturer Part Number) - Each SupplierPart is also linked to a Part object - - A Part may be available from multiple suppliers - """ - - def get_absolute_url(self): - return "/supplier/part/{id}/".format(id=self.id) - - class Meta: - unique_together = ('part', 'supplier', 'SKU') - - # Link to an actual part -# The part will have a field 'supplier_parts' which links to the supplier part options - part = models.ForeignKey(Part, on_delete=models.CASCADE, - related_name='supplier_parts') - - supplier = models.ForeignKey(Company, on_delete=models.CASCADE, - related_name='parts') - - SKU = models.CharField(max_length=100, help_text='Supplier stock keeping unit') - - manufacturer = models.CharField(max_length=100, blank=True, help_text='Manufacturer') - - MPN = models.CharField(max_length=100, blank=True, help_text='Manufacturer part number') - - URL = models.URLField(blank=True) - - description = models.CharField(max_length=250, blank=True) - - # Default price for a single unit - single_price = models.DecimalField(max_digits=10, decimal_places=3, default=0) - - # Base charge added to order independent of quantity e.g. "Reeling Fee" - base_cost = models.DecimalField(max_digits=10, decimal_places=3, default=0) - - # packaging that the part is supplied in, e.g. "Reel" - packaging = models.CharField(max_length=50, blank=True) - - # multiple that the part is provided in - multiple = models.PositiveIntegerField(default=1, validators=[MinValueValidator(0)]) - - # Mimumum number required to order - minimum = models.PositiveIntegerField(default=1, validators=[MinValueValidator(0)]) - - # lead time for parts that cannot be delivered immediately - lead_time = models.DurationField(blank=True, null=True) - - def __str__(self): - return "{sku} - {supplier}".format( - sku=self.SKU, - supplier=self.supplier.name) - - -class SupplierPriceBreak(models.Model): - """ Represents a quantity price break for a SupplierPart - - Suppliers can offer discounts at larger quantities - - SupplierPart(s) may have zero-or-more associated SupplierPriceBreak(s) - """ - - part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='price_breaks') - quantity = models.PositiveIntegerField(validators=[MinValueValidator(0)]) - cost = models.DecimalField(max_digits=10, decimal_places=3) - - class Meta: - unique_together = ("part", "quantity") - - def __str__(self): - return "{mpn} - {cost}{currency} @ {quan}".format( - mpn=self.part.MPN, - cost=self.cost, - currency=self.currency if self.currency else '', - quan=self.quantity) - - -class SupplierOrder(models.Model): - """ - An order of parts from a supplier, made up of multiple line items - """ - - def get_absolute_url(self): - return "/supplier/order/{id}/".format(id=self.id) - - # Interal reference for this order - internal_ref = models.CharField(max_length=25, unique=True) - - supplier = models.ForeignKey(Company, on_delete=models.CASCADE, - related_name='orders') - - created_date = models.DateField(auto_now_add=True, editable=False) - - issued_date = models.DateField(blank=True, null=True, help_text="Date the purchase order was issued") - - notes = models.TextField(blank=True, help_text="Order notes") - - def __str__(self): - return "PO {ref} ({status})".format(ref=self.internal_ref, - status=self.get_status_display) - - PENDING = 10 # Order is pending (not yet placed) - PLACED = 20 # Order has been placed - RECEIVED = 30 # Order has been received - CANCELLED = 40 # Order was cancelled - LOST = 50 # Order was lost - - ORDER_STATUS_CODES = {PENDING: _("Pending"), - PLACED: _("Placed"), - CANCELLED: _("Cancelled"), - RECEIVED: _("Received"), - LOST: _("Lost") - } - - status = models.PositiveIntegerField(default=PENDING, - choices=ORDER_STATUS_CODES.items()) - - delivery_date = models.DateField(blank=True, null=True) - - - -class SupplierOrderLineItem(models.Model): - """ - A line item in a supplier order, corresponding to some quantity of part - """ - - class Meta: - unique_together = [ - ('order', 'line_number'), - ('order', 'supplier_part'), - ('order', 'internal_part'), - ] - - order = models.ForeignKey(SupplierOrder, on_delete=models.CASCADE) - - line_number = models.PositiveIntegerField(default=1) - - internal_part = models.ForeignKey(Part, null=True, blank=True, on_delete=models.SET_NULL) - - supplier_part = models.ForeignKey(SupplierPart, null=True, blank=True, on_delete=models.SET_NULL) - - quantity = models.PositiveIntegerField(default=1) - - notes = models.TextField(blank=True) - - received = models.BooleanField(default=False) diff --git a/InvenTree/company/templates/company/index.html b/InvenTree/company/templates/company/index.html index bce8b9d96e..90a8d0e9a5 100644 --- a/InvenTree/company/templates/company/index.html +++ b/InvenTree/company/templates/company/index.html @@ -2,26 +2,26 @@ {% block content %} -

Suppliers

+

Companies

- - + +
diff --git a/InvenTree/company/urls.py b/InvenTree/company/urls.py index 6109de5a6d..e83b587c70 100644 --- a/InvenTree/company/urls.py +++ b/InvenTree/company/urls.py @@ -3,94 +3,20 @@ from django.views.generic.base import RedirectView from . import views -""" -cust_urls = [ - # Customer detail - url(r'^(?P[0-9]+)/?$', api.CustomerDetail.as_view(), name='customer-detail'), - - # List customers - url(r'^\?.*/?$', api.CustomerList.as_view()), - url(r'^$', api.CustomerList.as_view()) -] - -manu_urls = [ - # Manufacturer detail - url(r'^(?P[0-9]+)/?$', api.ManufacturerDetail.as_view(), name='manufacturer-detail'), - - # List manufacturers - url(r'^\?.*/?$', api.ManufacturerList.as_view()), - url(r'^$', api.ManufacturerList.as_view()) -] - -supplier_api_part_urls = [ - url(r'^(?P[0-9]+)/?$', api.SupplierPartDetail.as_view(), name='supplierpart-detail'), - - url(r'^\?.*/?$', api.SupplierPartList.as_view()), - url(r'^$', api.SupplierPartList.as_view()) -] - -price_break_urls = [ - url(r'^(?P[0-9]+)/?$', api.SupplierPriceBreakDetail.as_view(), name='supplierpricebreak-detail'), - - url(r'^\?.*/?$', api.SupplierPriceBreakList.as_view()), - url(r'^$', api.SupplierPriceBreakList.as_view()) -] - -supplier_api_urls = [ - - # Display details of a supplier - url(r'^(?P[0-9]+)/$', api.SupplierDetail.as_view(), name='supplier-detail'), - - # List suppliers - url(r'^\?.*/?$', api.SupplierList.as_view()), - url(r'^$', api.SupplierList.as_view()) -] -""" company_detail_urls = [ url(r'edit/?', views.CompanyEdit.as_view(), name='company-edit'), url(r'delete/?', views.CompanyDelete.as_view(), name='company-delete'), - url(r'orders/?', views.CompanyDetail.as_view(template_name='supplier/orders.html'), name='company-detail-orders'), + # url(r'orders/?', views.CompanyDetail.as_view(template_name='company/orders.html'), name='company-detail-orders'), url(r'^.*$', views.CompanyDetail.as_view(), name='company-detail'), ] -supplier_part_detail_urls = [ - url(r'edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'), - url(r'delete/?', views.SupplierPartDelete.as_view(), name='supplier-part-delete'), - - url('^.*$', views.SupplierPartDetail.as_view(), name='supplier-part-detail'), -] - -supplier_part_urls = [ - url(r'^new/?', views.SupplierPartCreate.as_view(), name='supplier-part-create'), - - url(r'^(?P\d+)/', include(supplier_part_detail_urls)), -] - -""" -supplier_order_detail_urls = [ - - - url('^.*$', views.SupplierOrderDetail.as_view(), name='supplier-order-detail'), -] - -supplier_order_urls = [ - url(r'^new/?', views.SupplierOrderCreate.as_view(), name='supplier-order-create'), - - url(r'^(?P\d+)/', include(supplier_order_detail_urls)), -] -""" company_urls = [ - - url(r'supplier_part/', include(supplier_part_urls)), - - #url(r'order/', include(supplier_order_urls)), - - #url(r'new/?', views.SupplierCreate.as_view(), name='supplier-create'), + url(r'new/?', views.CompanyCreate.as_view(), name='company-create'), url(r'^(?P\d+)/', include(company_detail_urls)), diff --git a/InvenTree/company/views.py b/InvenTree/company/views.py index be46e1ecb0..e2536678c5 100644 --- a/InvenTree/company/views.py +++ b/InvenTree/company/views.py @@ -6,13 +6,12 @@ from django.views.generic.edit import UpdateView, DeleteView, CreateView from part.models import Part from .models import Company -from .models import SupplierPart -from .models import SupplierOrder +#from .models import SupplierOrder from .forms import EditCompanyForm -from .forms import EditSupplierPartForm -from .forms import EditSupplierOrderForm +#from .forms import EditSupplierOrderForm +""" class SupplierOrderDetail(DetailView): context_object_name = 'order' model = SupplierOrder @@ -35,6 +34,7 @@ class SupplierOrderCreate(CreateView): initials['supplier'] = get_object_or_404(Supplier, pk=s_id) return initials +""" class CompanyIndex(ListView): @@ -44,7 +44,7 @@ class CompanyIndex(ListView): paginate_by = 50 def get_queryset(self): - return Supplier.objects.order_by('name') + return Company.objects.order_by('name') class CompanyDetail(DetailView): @@ -58,11 +58,12 @@ class CompanyEdit(UpdateView): model = Company form_class = EditCompanyForm template_name = 'company/edit.html' - context_object_name = 'supplier' + context_object_name = 'company' class CompanyCreate(CreateView): model = Company + context_object_name = 'company' form_class = EditCompanyForm template_name = "company/create.html" @@ -79,51 +80,3 @@ class CompanyDelete(DeleteView): return HttpResponseRedirect(self.get_object().get_absolute_url()) -class SupplierPartDetail(DetailView): - model = SupplierPart - template_name = 'company/partdetail.html' - context_object_name = 'part' - queryset = SupplierPart.objects.all() - - -class SupplierPartEdit(UpdateView): - model = SupplierPart - template_name = 'company/partedit.html' - context_object_name = 'part' - form_class = EditSupplierPartForm - - -class SupplierPartCreate(CreateView): - model = SupplierPart - form_class = EditSupplierPartForm - template_name = 'company/partcreate.html' - context_object_name = 'part' - - def get_initial(self): - initials = super(SupplierPartCreate, self).get_initial().copy() - - supplier_id = self.request.GET.get('supplier', None) - part_id = self.request.GET.get('part', None) - - if supplier_id: - initials['supplier'] = get_object_or_404(Supplier, pk=supplier_id) - # TODO - # self.fields['supplier'].disabled = True - if part_id: - initials['part'] = get_object_or_404(Part, pk=part_id) - # TODO - # self.fields['part'].disabled = True - - return initials - - -class SupplierPartDelete(DeleteView): - model = SupplierPart - success_url = '/supplier/' - template_name = 'company/partdelete.html' - - def post(self, request, *args, **kwargs): - if 'confirm' in request.POST: - return super(SupplierPartDelete, self).post(request, *args, **kwargs) - else: - return HttpResponseRedirect(self.get_object().get_absolute_url()) diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index d1c025c6fb..7fe4e65dc3 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -2,6 +2,7 @@ from django.contrib import admin from import_export.admin import ImportExportModelAdmin from .models import PartCategory, Part +from .models import SupplierPart from .models import BomItem from .models import PartAttachment @@ -20,8 +21,11 @@ class BomItemAdmin(ImportExportModelAdmin): list_display = ('part', 'sub_part', 'quantity') -class PartAttachmentAdmin(admin.ModelAdmin): - list_display = ('part', 'attachment') +#class PartAttachmentAdmin(admin.ModelAdmin): +# list_display = ('part', 'attachment') + +class SupplierPartAdmin(ImportExportModelAdmin): + list_display = ('part', 'supplier', 'SKU') """ @@ -36,8 +40,4 @@ class ParameterAdmin(admin.ModelAdmin): admin.site.register(Part, PartAdmin) admin.site.register(PartCategory, PartCategoryAdmin) admin.site.register(BomItem, BomItemAdmin) -admin.site.register(PartAttachment, PartAttachmentAdmin) - -# admin.site.register(PartParameter, ParameterAdmin) -# admin.site.register(PartParameterTemplate, ParameterTemplateAdmin) -# admin.site.register(CategoryParameterLink) +admin.site.register(SupplierPart, SupplierPartAdmin) diff --git a/InvenTree/part/forms.py b/InvenTree/part/forms.py index cc9355e4cc..109b1961b6 100644 --- a/InvenTree/part/forms.py +++ b/InvenTree/part/forms.py @@ -3,6 +3,7 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Submit from .models import Part, PartCategory, BomItem +from .models import SupplierPart class EditPartForm(forms.ModelForm): @@ -73,3 +74,27 @@ class EditBomItemForm(forms.ModelForm): 'sub_part', 'quantity' ] + + +class EditSupplierPartForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + super(EditSupplierPartForm, self).__init__(*args, **kwargs) + self.helper = FormHelper() + + self.helper.form_id = 'id-edit-part-form' + self.helper.form_class = 'blueForms' + self.helper.form_method = 'post' + + self.helper.add_input(Submit('submit', 'Submit')) + + class Meta: + model = SupplierPart + fields = [ + 'supplier', + 'SKU', + 'part', + 'description', + 'URL', + 'manufacturer', + 'MPN', + ] diff --git a/InvenTree/part/migrations/0001_initial.py b/InvenTree/part/migrations/0001_initial.py index 3596095a77..361436047e 100644 --- a/InvenTree/part/migrations/0001_initial.py +++ b/InvenTree/part/migrations/0001_initial.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 05:02 +# Generated by Django 1.11.12 on 2018-04-22 11:53 from __future__ import unicode_literals import django.core.validators from django.db import migrations, models import django.db.models.deletion +import part.models class Migration(migrations.Migration): @@ -12,42 +13,57 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('company', '0001_initial'), ] operations = [ migrations.CreateModel( - name='CategoryParameterLink', + name='BomItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('quantity', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), ], options={ - 'verbose_name': 'Category Parameter', - 'verbose_name_plural': 'Category Parameters', + 'verbose_name': 'BOM Item', }, ), migrations.CreateModel( name='Part', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ('description', models.CharField(blank=True, max_length=250)), - ('IPN', models.CharField(blank=True, max_length=100)), - ('minimum_stock', models.PositiveIntegerField(default=0, validators=[django.core.validators.MinValueValidator(0)])), + ('name', models.CharField(help_text='Part name (must be unique)', max_length=100, unique=True)), + ('description', models.CharField(help_text='Part description', max_length=250)), + ('IPN', models.CharField(blank=True, help_text='Internal Part Number', max_length=100)), + ('URL', models.URLField(blank=True, help_text='Link to extenal URL')), + ('image', models.ImageField(blank=True, max_length=255, null=True, upload_to=part.models.rename_part_image)), + ('minimum_stock', models.PositiveIntegerField(default=0, help_text='Minimum allowed stock level', validators=[django.core.validators.MinValueValidator(0)])), ('units', models.CharField(blank=True, default='pcs', max_length=20)), - ('trackable', models.BooleanField(default=False)), + ('buildable', models.BooleanField(default=False, help_text='Can this part be built from other parts?')), + ('trackable', models.BooleanField(default=False, help_text='Does this part have tracking for unique items?')), + ('purchaseable', models.BooleanField(default=True, help_text='Can this part be purchased from external suppliers?')), + ('salable', models.BooleanField(default=False, help_text='Can this part be sold to customers?')), + ('notes', models.TextField(blank=True)), ], options={ 'verbose_name': 'Part', 'verbose_name_plural': 'Parts', }, ), + migrations.CreateModel( + name='PartAttachment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('attachment', models.FileField(blank=True, null=True, upload_to=part.models.attach_file)), + ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='part.Part')), + ], + ), migrations.CreateModel( name='PartCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ('description', models.CharField(blank=True, max_length=250)), - ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='part.PartCategory')), + ('name', models.CharField(max_length=100, unique=True)), + ('description', models.CharField(max_length=250)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='part.PartCategory')), ], options={ 'verbose_name': 'Part Category', @@ -55,62 +71,63 @@ class Migration(migrations.Migration): }, ), migrations.CreateModel( - name='PartParameter', + name='SupplierPart', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('value', models.CharField(blank=True, max_length=50)), - ('min_value', models.CharField(blank=True, max_length=50)), - ('max_value', models.CharField(blank=True, max_length=50)), - ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parameters', to='part.Part')), + ('SKU', models.CharField(help_text='Supplier stock keeping unit', max_length=100)), + ('manufacturer', models.CharField(blank=True, help_text='Manufacturer', max_length=100)), + ('MPN', models.CharField(blank=True, help_text='Manufacturer part number', max_length=100)), + ('URL', models.URLField(blank=True)), + ('description', models.CharField(blank=True, max_length=250)), + ('single_price', models.DecimalField(decimal_places=3, default=0, max_digits=10)), + ('base_cost', models.DecimalField(decimal_places=3, default=0, max_digits=10)), + ('packaging', models.CharField(blank=True, max_length=50)), + ('multiple', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), + ('minimum', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), + ('lead_time', models.DurationField(blank=True, null=True)), + ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='supplier_parts', to='part.Part')), + ('supplier', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parts', to='company.Company')), ], - options={ - 'verbose_name': 'Part Parameter', - 'verbose_name_plural': 'Part Parameters', - }, ), migrations.CreateModel( - name='PartParameterTemplate', + name='SupplierPriceBreak', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=20, unique=True)), - ('units', models.CharField(blank=True, max_length=10)), - ('format', models.PositiveIntegerField(choices=[(10, 'Numeric'), (20, 'Text'), (30, 'Bool')], default=10, validators=[django.core.validators.MinValueValidator(0)])), + ('quantity', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(0)])), + ('cost', models.DecimalField(decimal_places=3, max_digits=10)), + ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='price_breaks', to='part.SupplierPart')), ], - options={ - 'verbose_name': 'Parameter Template', - 'verbose_name_plural': 'Parameter Templates', - }, - ), - migrations.AddField( - model_name='partparameter', - name='template', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='part.PartParameterTemplate'), ), migrations.AddField( model_name='part', name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='part.PartCategory'), + field=models.ForeignKey(blank=True, help_text='Part category', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory'), ), migrations.AddField( - model_name='categoryparameterlink', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='part.PartCategory'), + model_name='part', + name='default_supplier', + field=models.ForeignKey(blank=True, help_text='Default supplier part', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='part.SupplierPart'), ), migrations.AddField( - model_name='categoryparameterlink', - name='template', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='part.PartParameterTemplate'), - ), - migrations.AlterUniqueTogether( - name='partparameter', - unique_together=set([('part', 'template')]), - ), - migrations.AlterUniqueTogether( + model_name='bomitem', name='part', - unique_together=set([('name', 'category'), ('IPN', 'category')]), + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bom_items', to='part.Part'), + ), + migrations.AddField( + model_name='bomitem', + name='sub_part', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='used_in', to='part.Part'), ), migrations.AlterUniqueTogether( - name='categoryparameterlink', - unique_together=set([('category', 'template')]), + name='supplierpricebreak', + unique_together=set([('part', 'quantity')]), + ), + migrations.AlterUniqueTogether( + name='supplierpart', + unique_together=set([('part', 'supplier', 'SKU')]), + ), + migrations.AlterUniqueTogether( + name='bomitem', + unique_together=set([('part', 'sub_part')]), ), ] diff --git a/InvenTree/part/migrations/0002_auto_20180412_0600.py b/InvenTree/part/migrations/0002_auto_20180412_0600.py deleted file mode 100644 index 7e577c33f1..0000000000 --- a/InvenTree/part/migrations/0002_auto_20180412_0600.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 06:00 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0001_initial'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='categoryparameterlink', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='categoryparameterlink', - name='category', - ), - migrations.RemoveField( - model_name='categoryparameterlink', - name='template', - ), - migrations.AlterUniqueTogether( - name='partparameter', - unique_together=set([]), - ), - migrations.RemoveField( - model_name='partparameter', - name='part', - ), - migrations.RemoveField( - model_name='partparameter', - name='template', - ), - migrations.DeleteModel( - name='CategoryParameterLink', - ), - migrations.DeleteModel( - name='PartParameter', - ), - migrations.DeleteModel( - name='PartParameterTemplate', - ), - ] diff --git a/InvenTree/part/migrations/0021_part_default_location.py b/InvenTree/part/migrations/0002_part_default_location.py similarity index 69% rename from InvenTree/part/migrations/0021_part_default_location.py rename to InvenTree/part/migrations/0002_part_default_location.py index 0690abb280..c5a65d284d 100644 --- a/InvenTree/part/migrations/0021_part_default_location.py +++ b/InvenTree/part/migrations/0002_part_default_location.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 08:12 +# Generated by Django 1.11.12 on 2018-04-22 11:53 from __future__ import unicode_literals from django.db import migrations, models @@ -9,14 +9,14 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('stock', '0010_stockitem_build'), - ('part', '0020_part_salable'), + ('stock', '0001_initial'), + ('part', '0001_initial'), ] operations = [ migrations.AddField( model_name='part', name='default_location', - field=models.ForeignKey(blank=True, help_text='Where is this item normally stored?', null=True, on_delete=django.db.models.deletion.SET_NULL, to='stock.StockLocation'), + field=models.ForeignKey(blank=True, help_text='Where is this item normally stored?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='stock.StockLocation'), ), ] diff --git a/InvenTree/part/migrations/0003_auto_20180412_0644.py b/InvenTree/part/migrations/0003_auto_20180412_0644.py deleted file mode 100644 index 4e94431685..0000000000 --- a/InvenTree/part/migrations/0003_auto_20180412_0644.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 06:44 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0002_auto_20180412_0600'), - ] - - operations = [ - migrations.AlterUniqueTogether( - name='part', - unique_together=set([('name', 'category')]), - ), - ] diff --git a/InvenTree/part/migrations/0004_auto_20180413_0834.py b/InvenTree/part/migrations/0004_auto_20180413_0834.py deleted file mode 100644 index b34d5cdbe1..0000000000 --- a/InvenTree/part/migrations/0004_auto_20180413_0834.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-13 08:34 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0003_auto_20180412_0644'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='parts', to='part.PartCategory'), - ), - ] diff --git a/InvenTree/part/migrations/0005_auto_20180413_1230.py b/InvenTree/part/migrations/0005_auto_20180413_1230.py deleted file mode 100644 index 76b3e82868..0000000000 --- a/InvenTree/part/migrations/0005_auto_20180413_1230.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-13 12:30 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0004_auto_20180413_0834'), - ] - - operations = [ - migrations.AlterField( - model_name='partcategory', - name='name', - field=models.CharField(max_length=100, unique=True), - ), - ] diff --git a/InvenTree/part/migrations/0006_auto_20180414_0403.py b/InvenTree/part/migrations/0006_auto_20180414_0403.py deleted file mode 100644 index 0d7f5c7060..0000000000 --- a/InvenTree/part/migrations/0006_auto_20180414_0403.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 04:03 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0005_auto_20180413_1230'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='category', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='parts', to='part.PartCategory'), - ), - ] diff --git a/InvenTree/part/migrations/0007_auto_20180414_0416.py b/InvenTree/part/migrations/0007_auto_20180414_0416.py deleted file mode 100644 index 1ae2e5685e..0000000000 --- a/InvenTree/part/migrations/0007_auto_20180414_0416.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 04:16 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0006_auto_20180414_0403'), - ] - - operations = [ - migrations.CreateModel( - name='BomItem', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.PositiveIntegerField(default=1, validators=[django.core.validators.MinValueValidator(0)])), - ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bom_items', to='part.Part')), - ('sub_part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='used_in', to='part.Part')), - ], - options={ - 'verbose_name': 'BOM Item', - }, - ), - migrations.AlterUniqueTogether( - name='bomitem', - unique_together=set([('part', 'sub_part')]), - ), - ] diff --git a/InvenTree/part/migrations/0008_part_url.py b/InvenTree/part/migrations/0008_part_url.py deleted file mode 100644 index 1cc9dee52e..0000000000 --- a/InvenTree/part/migrations/0008_part_url.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 06:31 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0007_auto_20180414_0416'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='URL', - field=models.URLField(blank=True), - ), - ] diff --git a/InvenTree/part/migrations/0009_part_image.py b/InvenTree/part/migrations/0009_part_image.py deleted file mode 100644 index 9dc9c28c70..0000000000 --- a/InvenTree/part/migrations/0009_part_image.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 06:53 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0008_part_url'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='image', - field=models.ImageField(blank=True, upload_to='part_images'), - ), - ] diff --git a/InvenTree/part/migrations/0010_auto_20180414_0725.py b/InvenTree/part/migrations/0010_auto_20180414_0725.py deleted file mode 100644 index 24266bff6c..0000000000 --- a/InvenTree/part/migrations/0010_auto_20180414_0725.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 07:25 -from __future__ import unicode_literals - -from django.db import migrations, models -import part.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0009_part_image'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='image', - field=models.ImageField(blank=True, max_length=255, null=True, upload_to=part.models.rename_part_image), - ), - ] diff --git a/InvenTree/part/migrations/0011_partattachment.py b/InvenTree/part/migrations/0011_partattachment.py deleted file mode 100644 index 9d3ce4b166..0000000000 --- a/InvenTree/part/migrations/0011_partattachment.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 08:21 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion -import part.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0010_auto_20180414_0725'), - ] - - operations = [ - migrations.CreateModel( - name='PartAttachment', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('attachment', models.FileField(blank=True, null=True, upload_to=part.models.attach_file)), - ('part', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='part.Part')), - ], - ), - ] diff --git a/InvenTree/part/migrations/0012_auto_20180414_1032.py b/InvenTree/part/migrations/0012_auto_20180414_1032.py deleted file mode 100644 index a23e7d502d..0000000000 --- a/InvenTree/part/migrations/0012_auto_20180414_1032.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 10:32 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0011_partattachment'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='category', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory'), - ), - ] diff --git a/InvenTree/part/migrations/0013_auto_20180414_2238.py b/InvenTree/part/migrations/0013_auto_20180414_2238.py deleted file mode 100644 index 1184324c50..0000000000 --- a/InvenTree/part/migrations/0013_auto_20180414_2238.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 22:38 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0012_auto_20180414_1032'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='name', - field=models.CharField(max_length=100, unique=True), - ), - migrations.AlterUniqueTogether( - name='part', - unique_together=set([]), - ), - ] diff --git a/InvenTree/part/migrations/0014_auto_20180415_0107.py b/InvenTree/part/migrations/0014_auto_20180415_0107.py deleted file mode 100644 index e1f62a4d28..0000000000 --- a/InvenTree/part/migrations/0014_auto_20180415_0107.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 01:07 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0013_auto_20180414_2238'), - ] - - operations = [ - migrations.AlterField( - model_name='partcategory', - name='parent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='part.PartCategory'), - ), - ] diff --git a/InvenTree/part/migrations/0015_auto_20180415_0302.py b/InvenTree/part/migrations/0015_auto_20180415_0302.py deleted file mode 100644 index 50365550a7..0000000000 --- a/InvenTree/part/migrations/0015_auto_20180415_0302.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 03:02 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0014_auto_20180415_0107'), - ] - - operations = [ - migrations.AlterField( - model_name='partcategory', - name='description', - field=models.CharField(max_length=250), - ), - ] diff --git a/InvenTree/part/migrations/0016_auto_20180415_0316.py b/InvenTree/part/migrations/0016_auto_20180415_0316.py deleted file mode 100644 index c0a22fff24..0000000000 --- a/InvenTree/part/migrations/0016_auto_20180415_0316.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 03:16 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0015_auto_20180415_0302'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='description', - field=models.CharField(max_length=250), - ), - ] diff --git a/InvenTree/part/migrations/0017_part_purchaseable.py b/InvenTree/part/migrations/0017_part_purchaseable.py deleted file mode 100644 index b3f6860a38..0000000000 --- a/InvenTree/part/migrations/0017_part_purchaseable.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 14:21 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0016_auto_20180415_0316'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='purchaseable', - field=models.BooleanField(default=True), - ), - ] diff --git a/InvenTree/part/migrations/0018_part_buildable.py b/InvenTree/part/migrations/0018_part_buildable.py deleted file mode 100644 index 8c4ca8d631..0000000000 --- a/InvenTree/part/migrations/0018_part_buildable.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 12:08 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0017_part_purchaseable'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='buildable', - field=models.BooleanField(default=False), - ), - ] diff --git a/InvenTree/part/migrations/0019_auto_20180416_1249.py b/InvenTree/part/migrations/0019_auto_20180416_1249.py deleted file mode 100644 index fb2717a7b6..0000000000 --- a/InvenTree/part/migrations/0019_auto_20180416_1249.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 12:49 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0018_part_buildable'), - ] - - operations = [ - migrations.AlterField( - model_name='part', - name='IPN', - field=models.CharField(blank=True, help_text='Internal Part Number', max_length=100), - ), - migrations.AlterField( - model_name='part', - name='URL', - field=models.URLField(blank=True, help_text='Link to extenal URL'), - ), - migrations.AlterField( - model_name='part', - name='buildable', - field=models.BooleanField(default=False, help_text='Can this part be built from other parts?'), - ), - migrations.AlterField( - model_name='part', - name='category', - field=models.ForeignKey(blank=True, help_text='Part category', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory'), - ), - migrations.AlterField( - model_name='part', - name='description', - field=models.CharField(help_text='Part description', max_length=250), - ), - migrations.AlterField( - model_name='part', - name='minimum_stock', - field=models.PositiveIntegerField(default=0, help_text='Minimum allowed stock level', validators=[django.core.validators.MinValueValidator(0)]), - ), - migrations.AlterField( - model_name='part', - name='name', - field=models.CharField(help_text='Part name (must be unique)', max_length=100, unique=True), - ), - migrations.AlterField( - model_name='part', - name='purchaseable', - field=models.BooleanField(default=True, help_text='Can this part be purchased from external suppliers?'), - ), - migrations.AlterField( - model_name='part', - name='trackable', - field=models.BooleanField(default=False, help_text='Does this part have tracking for unique items?'), - ), - ] diff --git a/InvenTree/part/migrations/0020_part_salable.py b/InvenTree/part/migrations/0020_part_salable.py deleted file mode 100644 index 9d24532273..0000000000 --- a/InvenTree/part/migrations/0020_part_salable.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 08:06 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0019_auto_20180416_1249'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='salable', - field=models.BooleanField(default=False, help_text='Can this part be sold to customers?'), - ), - ] diff --git a/InvenTree/part/migrations/0022_auto_20180417_0819.py b/InvenTree/part/migrations/0022_auto_20180417_0819.py deleted file mode 100644 index 3c21afeed1..0000000000 --- a/InvenTree/part/migrations/0022_auto_20180417_0819.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 08:19 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('company', '0007_auto_20180416_1253'), - ('part', '0021_part_default_location'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='default_supplier', - field=models.ForeignKey(blank=True, help_text='Default supplier part', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='company.SupplierPart'), - ), - migrations.AlterField( - model_name='part', - name='default_location', - field=models.ForeignKey(blank=True, help_text='Where is this item normally stored?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='stock.StockLocation'), - ), - ] diff --git a/InvenTree/part/migrations/0023_part_notes.py b/InvenTree/part/migrations/0023_part_notes.py deleted file mode 100644 index 62eb70fb5e..0000000000 --- a/InvenTree/part/migrations/0023_part_notes.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:34 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0022_auto_20180417_0819'), - ] - - operations = [ - migrations.AddField( - model_name='part', - name='notes', - field=models.TextField(blank=True), - ), - ] diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 26a7597f33..6a7ddfcd4e 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -11,7 +11,7 @@ from django.db.models.signals import pre_delete from django.dispatch import receiver from InvenTree.models import InvenTreeTree - +from company.models import Company class PartCategory(InvenTreeTree): """ PartCategory provides hierarchical organization of Part objects. @@ -111,7 +111,7 @@ class Part(models.Model): related_name='default_parts') # Default supplier part - default_supplier = models.ForeignKey('company.SupplierPart', + default_supplier = models.ForeignKey('part.SupplierPart', on_delete=models.SET_NULL, blank=True, null=True, help_text='Default supplier part', @@ -352,3 +352,78 @@ class BomItem(models.Model): par=self.part.name, child=self.sub_part.name, n=self.quantity) + +class SupplierPart(models.Model): + """ Represents a unique part as provided by a Supplier + Each SupplierPart is identified by a MPN (Manufacturer Part Number) + Each SupplierPart is also linked to a Part object + - A Part may be available from multiple suppliers + """ + + def get_absolute_url(self): + return "/supplier-part/{id}/".format(id=self.id) + + class Meta: + unique_together = ('part', 'supplier', 'SKU') + + # Link to an actual part +# The part will have a field 'supplier_parts' which links to the supplier part options + part = models.ForeignKey(Part, on_delete=models.CASCADE, + related_name='supplier_parts') + + supplier = models.ForeignKey(Company, on_delete=models.CASCADE, + related_name='parts') + + SKU = models.CharField(max_length=100, help_text='Supplier stock keeping unit') + + manufacturer = models.CharField(max_length=100, blank=True, help_text='Manufacturer') + + MPN = models.CharField(max_length=100, blank=True, help_text='Manufacturer part number') + + URL = models.URLField(blank=True) + + description = models.CharField(max_length=250, blank=True) + + # Default price for a single unit + single_price = models.DecimalField(max_digits=10, decimal_places=3, default=0) + + # Base charge added to order independent of quantity e.g. "Reeling Fee" + base_cost = models.DecimalField(max_digits=10, decimal_places=3, default=0) + + # packaging that the part is supplied in, e.g. "Reel" + packaging = models.CharField(max_length=50, blank=True) + + # multiple that the part is provided in + multiple = models.PositiveIntegerField(default=1, validators=[MinValueValidator(0)]) + + # Mimumum number required to order + minimum = models.PositiveIntegerField(default=1, validators=[MinValueValidator(0)]) + + # lead time for parts that cannot be delivered immediately + lead_time = models.DurationField(blank=True, null=True) + + def __str__(self): + return "{sku} - {supplier}".format( + sku=self.SKU, + supplier=self.supplier.name) + + +class SupplierPriceBreak(models.Model): + """ Represents a quantity price break for a SupplierPart + - Suppliers can offer discounts at larger quantities + - SupplierPart(s) may have zero-or-more associated SupplierPriceBreak(s) + """ + + part = models.ForeignKey(SupplierPart, on_delete=models.CASCADE, related_name='price_breaks') + quantity = models.PositiveIntegerField(validators=[MinValueValidator(0)]) + cost = models.DecimalField(max_digits=10, decimal_places=3) + + class Meta: + unique_together = ("part", "quantity") + + def __str__(self): + return "{mpn} - {cost}{currency} @ {quan}".format( + mpn=self.part.MPN, + cost=self.cost, + currency=self.currency if self.currency else '', + quan=self.quantity) diff --git a/InvenTree/part/urls.py b/InvenTree/part/urls.py index 97888dc20b..ace3387054 100644 --- a/InvenTree/part/urls.py +++ b/InvenTree/part/urls.py @@ -4,6 +4,19 @@ from django.views.generic.base import RedirectView from . import views from . import api +supplier_part_detail_urls = [ + url(r'edit/?', views.SupplierPartEdit.as_view(), name='supplier-part-edit'), + url(r'delete/?', views.SupplierPartDelete.as_view(), name='supplier-part-delete'), + + url('^.*$', views.SupplierPartDetail.as_view(), name='supplier-part-detail'), +] + +supplier_part_urls = [ + url(r'^new/?', views.SupplierPartCreate.as_view(), name='supplier-part-create'), + + url(r'^(?P\d+)/', include(supplier_part_detail_urls)), +] + # URL list for part category API part_cat_api_urls = [ diff --git a/InvenTree/part/views.py b/InvenTree/part/views.py index 0fe775a6b9..9093ca326b 100644 --- a/InvenTree/part/views.py +++ b/InvenTree/part/views.py @@ -7,8 +7,14 @@ from django.http import HttpResponseRedirect from django.views.generic import DetailView, ListView from django.views.generic.edit import UpdateView, DeleteView, CreateView -from .forms import EditPartForm, EditCategoryForm, EditBomItemForm from .models import PartCategory, Part, BomItem +from .models import SupplierPart + +from .forms import EditPartForm +from .forms import EditCategoryForm +from .forms import EditBomItemForm + +from .forms import EditSupplierPartForm class PartIndex(ListView): @@ -191,3 +197,53 @@ class BomItemDelete(DeleteView): return super(BomItemDelete, self).post(request, *args, **kwargs) else: return HttpResponseRedirect(self.get_object().get_absolute_url()) + + +class SupplierPartDetail(DetailView): + model = SupplierPart + template_name = 'company/partdetail.html' + context_object_name = 'part' + queryset = SupplierPart.objects.all() + + +class SupplierPartEdit(UpdateView): + model = SupplierPart + template_name = 'company/partedit.html' + context_object_name = 'part' + form_class = EditSupplierPartForm + + +class SupplierPartCreate(CreateView): + model = SupplierPart + form_class = EditSupplierPartForm + template_name = 'company/partcreate.html' + context_object_name = 'part' + + def get_initial(self): + initials = super(SupplierPartCreate, self).get_initial().copy() + + supplier_id = self.request.GET.get('supplier', None) + part_id = self.request.GET.get('part', None) + + if supplier_id: + initials['supplier'] = get_object_or_404(Supplier, pk=supplier_id) + # TODO + # self.fields['supplier'].disabled = True + if part_id: + initials['part'] = get_object_or_404(Part, pk=part_id) + # TODO + # self.fields['part'].disabled = True + + return initials + + +class SupplierPartDelete(DeleteView): + model = SupplierPart + success_url = '/supplier/' + template_name = 'company/partdelete.html' + + def post(self, request, *args, **kwargs): + if 'confirm' in request.POST: + return super(SupplierPartDelete, self).post(request, *args, **kwargs) + else: + return HttpResponseRedirect(self.get_object().get_absolute_url()) diff --git a/InvenTree/stock/migrations/0001_initial.py b/InvenTree/stock/migrations/0001_initial.py index a1c421bb2a..b4d15a7f64 100644 --- a/InvenTree/stock/migrations/0001_initial.py +++ b/InvenTree/stock/migrations/0001_initial.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 05:02 +# Generated by Django 1.11.12 on 2018-04-22 11:53 from __future__ import unicode_literals from django.conf import settings @@ -15,54 +15,47 @@ class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('part', '0001_initial'), - ('supplier', '__first__'), + ('company', '0001_initial'), ] operations = [ - migrations.CreateModel( - name='HistoricalStockItem', - fields=[ - ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), - ('quantity', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(0)])), - ('updated', models.DateField(blank=True, editable=False)), - ('stocktake_date', models.DateField(blank=True, null=True)), - ('review_needed', models.BooleanField(default=False)), - ('status', models.PositiveIntegerField(choices=[(10, 'In stock'), (15, 'Incoming'), (50, 'Attention needed'), (20, 'In progress'), (55, 'Damaged'), (25, 'Complete'), (60, 'Destroyed')], default=10, validators=[django.core.validators.MinValueValidator(0)])), - ('notes', models.CharField(blank=True, max_length=100)), - ('expected_arrival', models.DateField(blank=True, null=True)), - ('infinite', models.BooleanField(default=False)), - ('history_id', models.AutoField(primary_key=True, serialize=False)), - ('history_date', models.DateTimeField()), - ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), - ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), - ], - options={ - 'ordering': ('-history_date', '-history_id'), - 'get_latest_by': 'history_date', - 'verbose_name': 'historical stock item', - }, - ), migrations.CreateModel( name='StockItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('serial', models.PositiveIntegerField(blank=True, help_text='Serial number for this item', null=True)), + ('URL', models.URLField(blank=True, max_length=125)), + ('batch', models.CharField(blank=True, help_text='Batch code for this stock item', max_length=100)), ('quantity', models.PositiveIntegerField(validators=[django.core.validators.MinValueValidator(0)])), ('updated', models.DateField(auto_now=True)), ('stocktake_date', models.DateField(blank=True, null=True)), ('review_needed', models.BooleanField(default=False)), - ('status', models.PositiveIntegerField(choices=[(10, 'In stock'), (15, 'Incoming'), (50, 'Attention needed'), (20, 'In progress'), (55, 'Damaged'), (25, 'Complete'), (60, 'Destroyed')], default=10, validators=[django.core.validators.MinValueValidator(0)])), - ('notes', models.CharField(blank=True, max_length=100)), - ('expected_arrival', models.DateField(blank=True, null=True)), + ('status', models.PositiveIntegerField(choices=[(10, 'OK'), (60, 'Destroyed'), (50, 'Attention needed'), (55, 'Damaged')], default=10, validators=[django.core.validators.MinValueValidator(0)])), + ('notes', models.TextField(blank=True)), ('infinite', models.BooleanField(default=False)), + ('belongs_to', models.ForeignKey(blank=True, help_text='Is this item installed in another item?', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='owned_parts', to='stock.StockItem')), + ('customer', models.ForeignKey(blank=True, help_text='Item assigned to customer?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stockitems', to='company.Company')), + ], + ), + migrations.CreateModel( + name='StockItemTracking', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField(auto_now_add=True)), + ('title', models.CharField(max_length=250)), + ('notes', models.TextField(blank=True)), + ('system', models.BooleanField(default=False)), + ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tracking_info', to='stock.StockItem')), + ('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='StockLocation', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100)), - ('description', models.CharField(blank=True, max_length=250)), - ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='stock.StockLocation')), + ('name', models.CharField(max_length=100, unique=True)), + ('description', models.CharField(max_length=250)), + ('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='stock.StockLocation')), ], options={ 'abstract': False, @@ -71,7 +64,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='stockitem', name='location', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stock.StockLocation'), + field=models.ForeignKey(blank=True, help_text='Where is this stock item located?', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='items', to='stock.StockLocation'), ), migrations.AddField( model_name='stockitem', @@ -86,30 +79,14 @@ class Migration(migrations.Migration): migrations.AddField( model_name='stockitem', name='supplier_part', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='supplier.SupplierPart'), - ), - migrations.AddField( - model_name='historicalstockitem', - name='location', - field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='stock.StockLocation'), - ), - migrations.AddField( - model_name='historicalstockitem', - name='part', - field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='part.Part'), - ), - migrations.AddField( - model_name='historicalstockitem', - name='stocktake_user', - field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL), - ), - migrations.AddField( - model_name='historicalstockitem', - name='supplier_part', - field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='supplier.SupplierPart'), + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='part.SupplierPart'), ), migrations.AlterUniqueTogether( name='stocklocation', unique_together=set([('name', 'parent')]), ), + migrations.AlterUniqueTogether( + name='stockitem', + unique_together=set([('part', 'serial')]), + ), ] diff --git a/InvenTree/stock/migrations/0002_auto_20180412_0622.py b/InvenTree/stock/migrations/0002_auto_20180412_0622.py deleted file mode 100644 index f724dd7d07..0000000000 --- a/InvenTree/stock/migrations/0002_auto_20180412_0622.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-12 06:22 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='historicalstockitem', - name='expected_arrival', - ), - migrations.RemoveField( - model_name='stockitem', - name='expected_arrival', - ), - migrations.AlterField( - model_name='historicalstockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (60, 'Destroyed'), (50, 'Attention needed'), (55, 'Damaged')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - migrations.AlterField( - model_name='stockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (60, 'Destroyed'), (50, 'Attention needed'), (55, 'Damaged')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/stock/migrations/0003_auto_20180413_1230.py b/InvenTree/stock/migrations/0003_auto_20180413_1230.py deleted file mode 100644 index 062c9490e7..0000000000 --- a/InvenTree/stock/migrations/0003_auto_20180413_1230.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-13 12:30 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0002_auto_20180412_0622'), - ] - - operations = [ - migrations.AlterField( - model_name='stocklocation', - name='name', - field=models.CharField(max_length=100, unique=True), - ), - ] diff --git a/InvenTree/stock/migrations/0004_auto_20180414_1032.py b/InvenTree/stock/migrations/0004_auto_20180414_1032.py deleted file mode 100644 index 2fd841dea8..0000000000 --- a/InvenTree/stock/migrations/0004_auto_20180414_1032.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-14 10:32 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0003_auto_20180413_1230'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='location', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='items', to='stock.StockLocation'), - ), - ] diff --git a/InvenTree/stock/migrations/0005_auto_20180415_0107.py b/InvenTree/stock/migrations/0005_auto_20180415_0107.py deleted file mode 100644 index 1ff0d4eaa2..0000000000 --- a/InvenTree/stock/migrations/0005_auto_20180415_0107.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 01:07 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0004_auto_20180414_1032'), - ] - - operations = [ - migrations.AlterField( - model_name='stocklocation', - name='parent', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='children', to='stock.StockLocation'), - ), - ] diff --git a/InvenTree/stock/migrations/0006_auto_20180415_0302.py b/InvenTree/stock/migrations/0006_auto_20180415_0302.py deleted file mode 100644 index 14e02a167a..0000000000 --- a/InvenTree/stock/migrations/0006_auto_20180415_0302.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-15 03:02 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0005_auto_20180415_0107'), - ] - - operations = [ - migrations.AlterField( - model_name='stocklocation', - name='description', - field=models.CharField(max_length=250), - ), - ] diff --git a/InvenTree/stock/migrations/0007_auto_20180416_0853.py b/InvenTree/stock/migrations/0007_auto_20180416_0853.py deleted file mode 100644 index 0aa701198a..0000000000 --- a/InvenTree/stock/migrations/0007_auto_20180416_0853.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 08:53 -from __future__ import unicode_literals - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('supplier', '0006_auto_20180415_1011'), - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('stock', '0006_auto_20180415_0302'), - ] - - operations = [ - migrations.CreateModel( - name='StockItemTracking', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateField(auto_now_add=True)), - ('title', models.CharField(max_length=250)), - ('description', models.CharField(blank=True, max_length=1024)), - ], - ), - migrations.RemoveField( - model_name='historicalstockitem', - name='history_user', - ), - migrations.RemoveField( - model_name='historicalstockitem', - name='location', - ), - migrations.RemoveField( - model_name='historicalstockitem', - name='part', - ), - migrations.RemoveField( - model_name='historicalstockitem', - name='stocktake_user', - ), - migrations.RemoveField( - model_name='historicalstockitem', - name='supplier_part', - ), - migrations.AddField( - model_name='stockitem', - name='batch', - field=models.CharField(blank=True, max_length=100), - ), - migrations.AddField( - model_name='stockitem', - name='belongs_to', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='owned_parts', to='stock.StockItem'), - ), - migrations.AddField( - model_name='stockitem', - name='customer', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stockitems', to='supplier.Customer'), - ), - migrations.AddField( - model_name='stockitem', - name='serial', - field=models.PositiveIntegerField(blank=True, null=True), - ), - migrations.DeleteModel( - name='HistoricalStockItem', - ), - migrations.AddField( - model_name='stockitemtracking', - name='item', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tracking_info', to='stock.StockItem'), - ), - migrations.AddField( - model_name='stockitemtracking', - name='user', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/InvenTree/stock/migrations/0008_stockitem_url.py b/InvenTree/stock/migrations/0008_stockitem_url.py deleted file mode 100644 index 93e79fb4e9..0000000000 --- a/InvenTree/stock/migrations/0008_stockitem_url.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 11:05 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0007_auto_20180416_0853'), - ] - - operations = [ - migrations.AddField( - model_name='stockitem', - name='URL', - field=models.URLField(blank=True, max_length=125), - ), - ] diff --git a/InvenTree/stock/migrations/0009_auto_20180416_1253.py b/InvenTree/stock/migrations/0009_auto_20180416_1253.py deleted file mode 100644 index c1c8bab1c4..0000000000 --- a/InvenTree/stock/migrations/0009_auto_20180416_1253.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 12:53 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('part', '0019_auto_20180416_1249'), - ('stock', '0008_stockitem_url'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='batch', - field=models.CharField(blank=True, help_text='Batch code for this stock item', max_length=100), - ), - migrations.AlterField( - model_name='stockitem', - name='belongs_to', - field=models.ForeignKey(blank=True, help_text='Is this item installed in another item?', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='owned_parts', to='stock.StockItem'), - ), - migrations.AlterField( - model_name='stockitem', - name='customer', - field=models.ForeignKey(blank=True, help_text='Item assigned to customer?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stockitems', to='supplier.Customer'), - ), - migrations.AlterField( - model_name='stockitem', - name='location', - field=models.ForeignKey(blank=True, help_text='Where is this stock item located?', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='items', to='stock.StockLocation'), - ), - migrations.AlterField( - model_name='stockitem', - name='serial', - field=models.PositiveIntegerField(blank=True, help_text='Serial number for this item', null=True), - ), - migrations.AlterUniqueTogether( - name='stockitem', - unique_together=set([('part', 'serial')]), - ), - ] diff --git a/InvenTree/stock/migrations/0010_stockitem_build.py b/InvenTree/stock/migrations/0010_stockitem_build.py deleted file mode 100644 index 831fc72e25..0000000000 --- a/InvenTree/stock/migrations/0010_stockitem_build.py +++ /dev/null @@ -1,22 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-16 14:03 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('build', '0001_initial'), - ('stock', '0009_auto_20180416_1253'), - ] - - operations = [ - migrations.AddField( - model_name='stockitem', - name='build', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='build.Build'), - ), - ] diff --git a/InvenTree/stock/migrations/0011_auto_20180417_2127.py b/InvenTree/stock/migrations/0011_auto_20180417_2127.py deleted file mode 100644 index d9f8c2364d..0000000000 --- a/InvenTree/stock/migrations/0011_auto_20180417_2127.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-17 11:27 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0010_stockitem_build'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (50, 'Attention needed'), (55, 'Damaged'), (60, 'Destroyed')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/stock/migrations/0012_auto_20180417_1316.py b/InvenTree/stock/migrations/0012_auto_20180417_1316.py deleted file mode 100644 index 9ea7a1eed3..0000000000 --- a/InvenTree/stock/migrations/0012_auto_20180417_1316.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 13:16 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0011_auto_20180417_2127'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (60, 'Destroyed'), (50, 'Attention needed'), (55, 'Damaged')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/stock/migrations/0013_auto_20180417_1337.py b/InvenTree/stock/migrations/0013_auto_20180417_1337.py deleted file mode 100644 index 6ad54b4eb0..0000000000 --- a/InvenTree/stock/migrations/0013_auto_20180417_1337.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 13:37 -from __future__ import unicode_literals - -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0012_auto_20180417_1316'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='customer', - field=models.ForeignKey(blank=True, help_text='Item assigned to customer?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='stockitems', to='supplier.Supplier'), - ), - ] diff --git a/InvenTree/stock/migrations/0014_auto_20180418_0028.py b/InvenTree/stock/migrations/0014_auto_20180418_0028.py deleted file mode 100644 index c2056b0d7e..0000000000 --- a/InvenTree/stock/migrations/0014_auto_20180418_0028.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11 on 2018-04-17 14:28 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0013_auto_20180417_1337'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (50, 'Attention needed'), (55, 'Damaged'), (60, 'Destroyed')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/stock/migrations/0015_auto_20180417_1514.py b/InvenTree/stock/migrations/0015_auto_20180417_1514.py deleted file mode 100644 index b55cc6aa28..0000000000 --- a/InvenTree/stock/migrations/0015_auto_20180417_1514.py +++ /dev/null @@ -1,21 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:14 -from __future__ import unicode_literals - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0014_auto_20180418_0028'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='status', - field=models.PositiveIntegerField(choices=[(10, 'OK'), (60, 'Destroyed'), (50, 'Attention needed'), (55, 'Damaged')], default=10, validators=[django.core.validators.MinValueValidator(0)]), - ), - ] diff --git a/InvenTree/stock/migrations/0016_auto_20180417_1516.py b/InvenTree/stock/migrations/0016_auto_20180417_1516.py deleted file mode 100644 index c128ee54d0..0000000000 --- a/InvenTree/stock/migrations/0016_auto_20180417_1516.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:16 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0015_auto_20180417_1514'), - ] - - operations = [ - migrations.AlterField( - model_name='stockitem', - name='notes', - field=models.TextField(blank=True), - ), - ] diff --git a/InvenTree/stock/migrations/0017_auto_20180417_1536.py b/InvenTree/stock/migrations/0017_auto_20180417_1536.py deleted file mode 100644 index 0dc9676068..0000000000 --- a/InvenTree/stock/migrations/0017_auto_20180417_1536.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 15:36 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0016_auto_20180417_1516'), - ] - - operations = [ - migrations.RemoveField( - model_name='stockitemtracking', - name='description', - ), - migrations.AddField( - model_name='stockitemtracking', - name='notes', - field=models.TextField(blank=True), - ), - ] diff --git a/InvenTree/stock/migrations/0018_stockitemtracking_system.py b/InvenTree/stock/migrations/0018_stockitemtracking_system.py deleted file mode 100644 index 24072b22b8..0000000000 --- a/InvenTree/stock/migrations/0018_stockitemtracking_system.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.11.12 on 2018-04-17 22:43 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('stock', '0017_auto_20180417_1536'), - ] - - operations = [ - migrations.AddField( - model_name='stockitemtracking', - name='system', - field=models.BooleanField(default=False), - ), - ] diff --git a/InvenTree/stock/models.py b/InvenTree/stock/models.py index 2251e856bd..14c4d821ff 100644 --- a/InvenTree/stock/models.py +++ b/InvenTree/stock/models.py @@ -11,10 +11,11 @@ from django.dispatch import receiver from datetime import datetime -from company.models import SupplierPart -from part.models import Part +#from company.models import Company +#from part.models import Part +#from part.models import SupplierPart from InvenTree.models import InvenTreeTree -from build.models import Build +#from build.models import Build class StockLocation(InvenTreeTree): @@ -66,10 +67,10 @@ class StockItem(models.Model): ] # The 'master' copy of the part of which this stock item is an instance - part = models.ForeignKey(Part, on_delete=models.CASCADE, related_name='locations') + part = models.ForeignKey('part.Part', on_delete=models.CASCADE, related_name='locations') # The 'supplier part' used in this instance. May be null if no supplier parts are defined the master part - supplier_part = models.ForeignKey(SupplierPart, blank=True, null=True, on_delete=models.SET_NULL) + supplier_part = models.ForeignKey('part.SupplierPart', blank=True, null=True, on_delete=models.SET_NULL) # Where the part is stored. If the part has been used to build another stock item, the location may not make sense location = models.ForeignKey(StockLocation, on_delete=models.DO_NOTHING, @@ -98,7 +99,7 @@ class StockItem(models.Model): help_text='Batch code for this stock item') # If this part was produced by a build, point to that build here - build = models.ForeignKey(Build, on_delete=models.SET_NULL, blank=True, null=True) + # build = models.ForeignKey('build.Build', on_delete=models.SET_NULL, blank=True, null=True) # Quantity of this stock item. Value may be overridden by other settings quantity = models.PositiveIntegerField(validators=[MinValueValidator(0)]) diff --git a/InvenTree/templates/navbar.html b/InvenTree/templates/navbar.html index 70863e0291..c7aaa2dfd4 100644 --- a/InvenTree/templates/navbar.html +++ b/InvenTree/templates/navbar.html @@ -9,7 +9,6 @@
  • Parts
  • Stock
  • Build
  • -
  • Suppliers
  • \ No newline at end of file diff --git a/Makefile b/Makefile index e640daa561..2c6845dc59 100644 --- a/Makefile +++ b/Makefile @@ -15,9 +15,9 @@ test: python InvenTree/manage.py test --noinput migrate: + python InvenTree/manage.py makemigrations company python InvenTree/manage.py makemigrations part python InvenTree/manage.py makemigrations stock - python InvenTree/manage.py makemigrations company python InvenTree/manage.py makemigrations build python InvenTree/manage.py migrate --run-syncdb python InvenTree/manage.py check