Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions deployment_options/docker-compose/Caddyfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
:8080

reverse_proxy mventory:9000
file_server /static/* {
root assets
handle_path /static/* {
root * /opt/app/assets
file_server
}

handle {
reverse_proxy mventory:9000
}
log {
format json
format json
}

1 change: 1 addition & 0 deletions deployment_options/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ services:
- mventory
volumes:
- $PWD/deployment_options/docker-compose/Caddyfile:/etc/caddy/Caddyfile
- $PWD/:/opt/app
ports:
- "8180:8080"

Expand Down
6 changes: 5 additions & 1 deletion inventory/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
Room,
StorageUnit,
StorageBin,
Component)
Component,
Supplier,
ComponentSupplier)

admin.site.register(ComponentMeasurementUnit)
admin.site.register(Building)
admin.site.register(Room)
admin.site.register(StorageUnit)
admin.site.register(StorageBin)
admin.site.register(Component)
admin.site.register(Supplier)
admin.site.register(ComponentSupplier)
45 changes: 45 additions & 0 deletions inventory/migrations/0006_auto_20220305_1803.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 3.2.5 on 2022-03-05 18:03

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('inventory', '0005_auto_20210623_0537'),
]

operations = [
migrations.CreateModel(
name='ComponentSupplier',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cost', models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)),
('markup_percentage', models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)),
('price', models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)),
('component', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='components', to='inventory.component')),
],
),
migrations.CreateModel(
name='Supplier',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('description', models.CharField(blank=True, max_length=200, null=True)),
('website', models.URLField(blank=True, null=True)),
('contact_email', models.EmailField(blank=True, max_length=254, null=True)),
('components_available', models.ManyToManyField(through='inventory.ComponentSupplier', to='inventory.Component')),
],
),
migrations.AddField(
model_name='componentsupplier',
name='supplier',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='suppliers', to='inventory.supplier'),
),
migrations.AddField(
model_name='component',
name='supplier_options',
field=models.ManyToManyField(through='inventory.ComponentSupplier', to='inventory.Supplier'),
),
]
18 changes: 18 additions & 0 deletions inventory/migrations/0007_componentsupplier_currency.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.2.5 on 2022-03-05 19:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('inventory', '0006_auto_20220305_1803'),
]

operations = [
migrations.AddField(
model_name='componentsupplier',
name='currency',
field=models.CharField(choices=[('GBP', 'British Pound'), ('EUR', 'Euro'), ('CHF', 'Swiss Franc'), ('USD', 'US Dollar')], default='GBP', max_length=3),
),
]
33 changes: 33 additions & 0 deletions inventory/migrations/0008_auto_20220305_2316.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Generated by Django 3.2.5 on 2022-03-05 23:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('inventory', '0007_componentsupplier_currency'),
]

operations = [
migrations.RenameField(
model_name='componentsupplier',
old_name='cost',
new_name='bought_at',
),
migrations.RenameField(
model_name='componentsupplier',
old_name='price',
new_name='members_price',
),
migrations.AddField(
model_name='componentsupplier',
name='buying_discount_from_rrp',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True),
),
migrations.AddField(
model_name='componentsupplier',
name='rrp',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True),
),
]
41 changes: 41 additions & 0 deletions inventory/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ class ComponentMeasurementUnit(ExportModelOperationsMixin('ComponentMeasurementU
def __str__(self):
return self.unit_name

class Supplier(ExportModelOperationsMixin('Supplier'),models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=200,null=True, blank=True)
website = models.URLField(null=True,blank=True)
contact_email = models.EmailField(null=True,blank=True)
components_available = models.ManyToManyField('Component', through='ComponentSupplier')

def __str__(self):
return self.name


class Building(ExportModelOperationsMixin('Building'), models.Model):
name = models.CharField(max_length=200)
Expand Down Expand Up @@ -57,6 +67,37 @@ class Component(ExportModelOperationsMixin('Component'), models.Model):
storage_bin = models.ManyToManyField(StorageBin)
measurement_unit = models.ForeignKey(ComponentMeasurementUnit, on_delete=models.CASCADE)
qty = models.IntegerField(default=0, validators=[MinValueValidator(0)])
supplier_options = models.ManyToManyField('Supplier', through='ComponentSupplier')


def __str__(self):
return self.name


class ComponentSupplier(ExportModelOperationsMixin('ComponentSupplier'),models.Model):
BRITISH_POUND = 'GBP'
EURO = 'EUR'
SWISS_FRANC = 'CHF'
US_DOLLAR = 'USD'

CURRENCIES = [
(BRITISH_POUND, 'British Pound'),
(EURO, 'Euro'),
(SWISS_FRANC, 'Swiss Franc'),
(US_DOLLAR, 'US Dollar')
]

component = models.ForeignKey('Component',models.SET_NULL,related_name='components',null=True,blank=True)
supplier = models.ForeignKey('Supplier',models.SET_NULL,related_name='suppliers',null=True,blank=True)
bought_at = models.DecimalField(decimal_places=2,max_digits=7,null=True,blank=True)
rrp = models.DecimalField(decimal_places=2,max_digits=7,null=True,blank=True)
buying_discount_from_rrp = models.DecimalField(decimal_places=2,max_digits=7,null=True,blank=True)
markup_percentage = models.DecimalField(decimal_places=2,max_digits=7,null=True,blank=True)
members_price = models.DecimalField(decimal_places=2,max_digits=7,null=True,blank=True)
currency = models.CharField(max_length = 3,
choices = CURRENCIES,
default = BRITISH_POUND)


def __str__(self):
return f"{self.component} from {self.supplier}: {self.price}{self.currency}"
29 changes: 27 additions & 2 deletions inventory/serializers.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os
from .utils import OctopartClient
from .models import Building, Room, StorageUnit, StorageBin, Component, ComponentMeasurementUnit
from .models import Building, Room, StorageUnit, StorageBin, Component, ComponentMeasurementUnit, ComponentSupplier, Supplier
from rest_framework import serializers


Expand All @@ -25,8 +25,14 @@ class Meta:
model = StorageBin
fields = ['url', 'name', 'short_code', 'unit_row','unit_column', 'storage_unit']

class SupplierSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Supplier
fields = ['url', 'name', 'description']

class ComponentSerializer(serializers.HyperlinkedModelSerializer):
octopart_data = serializers.SerializerMethodField()
component_prices = serializers.SerializerMethodField()

def get_octopart_data(self, obj):
op_data = {}
Expand All @@ -44,9 +50,28 @@ def get_octopart_data(self, obj):
op_data["datasheet_url"] = None
return op_data

def get_component_prices(self, obj):
prices = []

for supplier in obj.supplier_options.all():
suppliers = serializers.HyperlinkedRelatedField(
view_name='suppliers',
lookup_field='supplier',
read_only=True
)
details = {}
details['supplier'] = supplier.name
cs_details = ComponentSupplier.objects.get(supplier=supplier, component=obj)
details['price'] = cs_details.members_price
details['currency'] = cs_details.currency
details['included_donation_amount'] = cs_details.members_price - cs_details.bought_at
prices.append(details)

return prices

class Meta:
model = Component
fields = ['url', 'name', 'sku', 'mpn', 'upc', 'octopart_data', 'storage_bin','measurement_unit', 'qty']
fields = ['url', 'name', 'sku', 'mpn', 'upc', 'octopart_data', 'storage_bin','measurement_unit', 'qty', 'component_prices']
depth = 4

class ComponentMeasurementUnitSerializer(serializers.HyperlinkedModelSerializer):
Expand Down
13 changes: 11 additions & 2 deletions inventory/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
from django.shortcuts import render

# Create your views here.
from .models import Building, Room, StorageUnit, StorageBin, Component, ComponentMeasurementUnit
from .models import Building, Room, StorageUnit, StorageBin, Component, ComponentMeasurementUnit, Supplier
from rest_framework import viewsets, permissions, filters
from inventory.serializers import (
BuildingSerializer,
RoomSerializer,
StorageUnitSerializer,
StorageBinSerializer,
ComponentSerializer,
ComponentMeasurementUnitSerializer
ComponentMeasurementUnitSerializer,
SupplierSerializer
)


Expand Down Expand Up @@ -80,3 +81,11 @@ class ComponentMeasurementUnitViewSet(viewsets.ModelViewSet):
queryset = ComponentMeasurementUnit.objects.all()
serializer_class = ComponentMeasurementUnitSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

class SupplierViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows suppliers to be viewed or edited.
"""
queryset = Supplier.objects.all()
serializer_class = SupplierSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
1 change: 1 addition & 0 deletions mventory/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
router.register(r'storage_bins', views.StorageBinViewSet)
router.register(r'components', views.ComponentViewSet)
router.register(r'component_measurements', views.ComponentMeasurementUnitViewSet)
router.register(r'suppliers', views.SupplierViewSet)

urlpatterns = [
path('', views.index),
Expand Down
2 changes: 0 additions & 2 deletions scripts/prod_deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,4 @@ python manage.py wait_for_db
python manage.py collectstatic --noinput
python manage.py migrate

#unset MVENTORY_DEBUG

uwsgi --ini uwsgi.ini