added location admin, updated readme with features and todos

This commit is contained in:
Jens Timmerman 2018-10-07 13:09:07 +02:00
parent c61e36acfc
commit e55a312771
6 changed files with 86 additions and 13 deletions

View File

@ -4,6 +4,17 @@ Pantry inventory management
# Inventory management system written in django - python
The object of this django app is to keep track of which goods you own, when they will expire, when you should consume them and when you shoud buy more.
## features
- Enter items in your pantry (or other locations, with their location) with their expiry date
- Items can have a minimum quantity you always want to keep in the pantry
- a shopping list is automatically populated with items whose quantity is below this minimum quantity
- You get an overview of items per expiry date so you know what to consume first (or throw away)
- Extensive search and filtering and grouping on locations, categories, units, expiry date using the auto generated django admin
interface
- Locations are recursive so things can be in the kitchen pantry closet on the 3rd shelf on the right and still be in
the kitchen
# Getting started
`pip3 install django`
@ -29,18 +40,39 @@ The object of this django app is to keep track of which goods you own, when they
# feature requests
## High
- make expirations a calendar view, generate ics file to import
- add locations to items
- public wishlist
- one off shoping list
- easy clearing of shopping list
- add easy consume view
- save date consumed in history
# medium high
- mobile app
- (requires rest api?)
# medium
- make work offline
- add users
- federated? use sqrl instead of passwords?
# medium low
- allow for lending stuff out
- auto mailings when things should be returned?
- double bookkeeping of where things are if both parties have this set up
- ipfs (+ blockchain?)
- will be done in a seperate app, oos for inventory
- make it look something like this https://getbootstrap.com/docs/4.0/examples/dashboard/
- easy clearing of shopping list
- figure out average usage of items over time and predict how much to buy in shopping list based on average expiry
dates
- figure out how long a certain item can last given current stock and average usage
- easily deploy somewhere (docker? on synology?)
## low
- add recepies
- shopping list created based on recepy ingredients
- auto proposal of recepy based on next expiry dates
- offer to buy things that have been on shopping list for a while online (in bulk/aggregated)

View File

@ -8,6 +8,11 @@ class PantryItemInLine(admin.TabularInline):
extra = 1
class LocationInLine(admin.TabularInline):
model = Location
extra = 1
def upper_case_name(obj):
return obj.name.upper()
upper_case_name.short_description = 'Name'
@ -18,7 +23,7 @@ def capitalize_name(obj):
upper_case_name.short_description = 'Name'
class PantryItemInLineAdmin(admin.ModelAdmin):
class PantryItemLineAdmin(admin.ModelAdmin):
list_filter = ['expiry_date', 'pantry_item__unit', 'pantry_item', 'pantry_item__min_quantity']
search_fields = ['info', 'pantry_item__name', 'pantry_item__info']
autocomplete_fields = ['pantry_item']
@ -47,6 +52,10 @@ class AutocompleteAdmin(admin.ModelAdmin):
search_fields = ["name"]
class LocationAdmin(AutocompleteAdmin):
inlines = [LocationInLine]
class PantryItemAdmin(admin.ModelAdmin):
list_filter = ['category', 'unit', 'min_quantity', 'location']
search_fields = ['info', 'name', 'category__name', 'unit__name']
@ -73,7 +82,7 @@ class PantryItemAdmin(admin.ModelAdmin):
)
admin.site.register(PantryItem, PantryItemAdmin)
admin.site.register(PantryItemLine, PantryItemInLineAdmin)
admin.site.register(PantryItemLine, PantryItemLineAdmin)
admin.site.register(Unit, AutocompleteAdmin)
admin.site.register(Category, AutocompleteAdmin)
admin.site.register(Location, AutocompleteAdmin)
admin.site.register(Location, LocationAdmin)

View File

@ -0,0 +1,26 @@
# Generated by Django 2.1.2 on 2018-10-07 11:08
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('inventory', '0016_auto_20180930_1409'),
]
operations = [
migrations.CreateModel(
name='ShoppingListItem',
fields=[
('pantryitem_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='inventory.PantryItem')),
],
bases=('inventory.pantryitem',),
),
migrations.AlterField(
model_name='pantryitem',
name='location',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='inventory.Location'),
),
]

View File

@ -46,26 +46,32 @@ class Location(models.Model):
return self.name + ' ' + str(self.in_location)
return self.name
class PantryItem(models.Model):
"""A think you keep in your pantry """
name = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
min_quantity = models.IntegerField(default=1) #, decimal_places=3, max_digits=32)
unit = models.ForeignKey(Unit, on_delete=models.PROTECT, null=True)
info = models.CharField(max_length=200, null=True, blank=True)
# some things don't have a fixed expiry date, like legumes or garlic, we can specify a default expiration for
# this.
# if expiry duration is set the expiration date for a pantryitemline will be set to now + duration on save
# represents days
expiry_duration = models.IntegerField(null=True, blank=True)
# location is saved on a per pantryitem base, not pantryitemline
name = models.CharField(max_length=200)
unit = models.ForeignKey(Unit, on_delete=models.PROTECT, null=True)
info = models.CharField(max_length=200, null=True, blank=True)
# location is saved on a per item base, not itemline
# you can have multiple pantries with subpantries
# if a pantryitem moves to the kitchen or fridge it is no longer a pantry item
location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True)
location = models.ForeignKey(Location, on_delete=models.PROTECT, null=True, blank=True)
def __str__(self):
return self.name
class ShoppingListItem(PantryItem):
"""Items to buy now that aren't meant for the pantry but for imidiate usage"""
pass
class PantryItemLine(models.Model):
# user?
pantry_item = models.ForeignKey(PantryItem, on_delete=models.PROTECT)

View File

@ -21,7 +21,7 @@
<a class="nav-link" href="{% url 'im:consume' %} ">Consume</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'admin:inventory_pantryitemline_add' %} ">Add</a>
<a class="nav-link" href="{% url 'admin:inventory_pantryitem_changelist' %} ">Add</a>
</li>
<li class="nav-item">

View File

@ -7,7 +7,7 @@
<li>
{{ pi|title }} (We have
{{ pi.total_quantity }} {{pi.unit}} but we want at least
{{ pi.min_quantity }} {{pi.unit }})
{{ pi.min_quantity }} {{pi.unit }} in {{ pi.location}})
</li>
{% endfor %}
</ul>