Merge dev #9
1
run.sh
Normal file → Executable file
1
run.sh
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#! /usr/bin/env bash
|
||||
|
||||
source .env/bin/activate
|
||||
python manage.py runserver 0.0.0.0:9595
|
||||
|
@ -1,7 +1,15 @@
|
||||
from django import forms
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
from .models import Yeast, Propogation, Strain
|
||||
from .models import Yeast, Propogation, Strain, Storage
|
||||
from beer.models import Batch
|
||||
|
||||
|
||||
class MyModelChoiceField(forms.ModelChoiceField):
|
||||
def label_from_instance(self, obj):
|
||||
return obj.name
|
||||
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('django')
|
||||
@ -31,7 +39,7 @@ class BatchAddForm(forms.ModelForm):
|
||||
class Meta:
|
||||
# specify model to be used
|
||||
model = Propogation
|
||||
|
||||
|
||||
# specify fields to be used
|
||||
fields = [
|
||||
'production_date',
|
||||
@ -46,15 +54,70 @@ class BatchAddForm(forms.ModelForm):
|
||||
num_samples = forms.IntegerField()
|
||||
|
||||
class StrainAddForm(forms.ModelForm):
|
||||
|
||||
|
||||
# create meta class
|
||||
class Meta:
|
||||
# specify model to be used
|
||||
model = Strain
|
||||
|
||||
|
||||
# specify fields to be used
|
||||
fields = [
|
||||
'name',
|
||||
'long_name',
|
||||
'manufacturer',
|
||||
]
|
||||
|
||||
class PitchIntoBeerForm(forms.Form):
|
||||
batch = forms.ModelChoiceField(queryset=Batch.objects.all())
|
||||
starter = forms.BooleanField(required=False)
|
||||
sample = forms.ModelChoiceField(queryset=Yeast.available)
|
||||
|
||||
def pitch_sample(self):
|
||||
sample = self.cleaned_data['sample']
|
||||
sample.pitched = True
|
||||
sample.pitched_batch = self.cleaned_data['batch']
|
||||
sample.date_pitched = timezone.now()
|
||||
sample.save()
|
||||
|
||||
class PropogateSampleForm(forms.Form):
|
||||
num = forms.IntegerField(min_value=1)
|
||||
storage = forms.ModelChoiceField(queryset=Storage.objects.all())
|
||||
parent = forms.ModelChoiceField(queryset=Yeast.available)
|
||||
strain = forms.ModelChoiceField(queryset=Strain.objects.all())
|
||||
|
||||
def create_propogation(self):
|
||||
samples = self.cleaned_data['num']
|
||||
storage = self.cleaned_data['storage']
|
||||
parent = self.cleaned_data['parent']
|
||||
strain = self.cleaned_data['strain']
|
||||
|
||||
# send email using the self.cleaned_data dictionary
|
||||
prop_obj = Propogation(
|
||||
production_date=timezone.now(),
|
||||
strain = strain,
|
||||
source = 'PR',
|
||||
notes = 'Auto generated from form.'
|
||||
)
|
||||
|
||||
prop_obj.save()
|
||||
prop_obj.parent.add(parent)
|
||||
|
||||
for i in range(samples):
|
||||
if storage.name == 'Deep Freeze':
|
||||
cells = 40
|
||||
else:
|
||||
cells = 100
|
||||
|
||||
yeast = Yeast(
|
||||
propogation = prop_obj,
|
||||
generation_num = parent.generation_num + 1,
|
||||
storage = storage,
|
||||
pitched = False,
|
||||
cellcount = cells,
|
||||
notes = 'Auto generated from form.'
|
||||
)
|
||||
|
||||
yeast.save()
|
||||
|
||||
return prop_obj
|
||||
|
||||
|
17
yeast/migrations/0004_alter_propogation_options.py
Normal file
17
yeast/migrations/0004_alter_propogation_options.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.0.6 on 2024-06-07 15:29
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('yeast', '0003_rename_batch_propogation'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='propogation',
|
||||
options={},
|
||||
),
|
||||
]
|
@ -3,7 +3,7 @@
|
||||
{% block title %}Yeast Samples{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
.table td.fit,
|
||||
.table td.fit,
|
||||
.table th.fit {
|
||||
white-space: nowrap;
|
||||
width: 1%;
|
||||
@ -22,12 +22,12 @@
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th class="fit">Production Date</th><td>{{ sample.batch.production_date }}</td></tr>
|
||||
<tr><th class="fit">Production Date</th><td>{{ sample.propogation.production_date }}</td></tr>
|
||||
<tr><th class="fit">Storage</th>
|
||||
<td>
|
||||
{{ sample.storage }}
|
||||
{{ sample.storage }}
|
||||
{% if sample.pitched %}
|
||||
(Pitched <a href="{{ sample.pitched_batch.brewfather_url }}" target="_blank" rel="noopener noreferrer">#{{ sample.pitched_batch.brewfather_num }}: {{ sample.pitched_batch.brewfather_name }}</a>)
|
||||
(Pitched <a href="{{ sample.pitched_batch.brewfather_url }}" target="_blank" rel="noopener noreferrer">#{{ sample.pitched_batch.brewfather_num }}: {{ sample.pitched_batch.brewfather_name }}</a>)
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
@ -64,24 +64,20 @@
|
||||
<div id="propogate" class="container tab-pane active"><br>
|
||||
<!-- Sample Propogation Form -->
|
||||
<div class="container" style="border:1px solid #cecece;">
|
||||
<form >
|
||||
<form action="" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" value="{{ sample.id }}" name="parent">
|
||||
<input type="hidden" value="{{ sample.propogation.strain.id }}" name="strain">
|
||||
<legend>Propogate Yeast Sample</legend>
|
||||
<div class="mb-3">
|
||||
<label for="new-samples" class="form-label"># New Samples</label>
|
||||
<input type="number" class="form-control" id="new-samples" aria-describedby="numHelp">
|
||||
<div id="numHelp" class="form-text">New samples will be automatically created</div>
|
||||
{{ propogate_form.num }}
|
||||
<div id="id_num" class="form-text">New samples will be automatically created</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="parent" class="form-label">Default Storage Method</label>
|
||||
<select class="form-select" id="parent" name="parent" aria-describedby="storageHelp">
|
||||
<option selected>-- Choose an Option --</option>
|
||||
{% for method in storage %}
|
||||
<option value="{{ method.id }}">{{ method }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<div id="storageHelp" class="form-text">How will samples be stored?</div>
|
||||
{{ propogate_form.storage }}
|
||||
<div id="id_storage" class="form-text">How will samples be stored?</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<button name="propogate" type="submit" value="submit" class="btn btn-primary">Propogate Sample</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- End Sample Propogation Form -->
|
||||
@ -89,23 +85,20 @@
|
||||
<div id="pitch" class="container tab-pane fade"><br>
|
||||
<!-- Sample Pitch Form -->
|
||||
<div class="container" style="border:1px solid #cecece;">
|
||||
<form >
|
||||
<form action="" method="POST">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" value="{{ sample.id }}" name="sample">
|
||||
<legend>Pitch Yeast Sample</legend>
|
||||
<div class="mb-3">
|
||||
<label for="beer-batch" class="form-label">Beer Batch</label>
|
||||
<select class="form-select" id="beer-batch" name="beer-batch" aria-describedby="batchHelp">
|
||||
<option selected>Beer Batch</option>
|
||||
<option value="1">#16 So So Special</option>
|
||||
<option value="2">#17 Some other beer</option>
|
||||
<option value="3">#18 Another Thing</option>
|
||||
</select>
|
||||
<div id="batchHelp" class="form-text">Select batch of beer sample is pitched into.</div>
|
||||
<label for="id_batch" class="form-label">Beer Batch</label>
|
||||
{{ pitch_form.batch }}
|
||||
<div class="form-text">Select batch of beer sample is pitched into.</div>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="starterCheck">
|
||||
<label class="form-check-label" for="starterCheck">Pitched into starter?</label>
|
||||
{{ pitch_form.starter }}
|
||||
<label class="form-check-label" for="id_starter">Built up from starter?</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
<button name="pitch" type="submit" value="submit" class="btn btn-primary">Pitch Sample</button>
|
||||
</form>
|
||||
</div>
|
||||
<!-- End Sample Pitch Form -->
|
||||
|
@ -2,7 +2,7 @@ from django.urls import include, path
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import admin
|
||||
|
||||
from yeast.views import YeastListView, BatchListView, home, sample, batch, batch_labels, addBatch, addStrain, get_batch
|
||||
from yeast.views import YeastListView, BatchListView, home, sample, batch, batch_labels, addBatch, addStrain, get_batch, NewPropogation
|
||||
|
||||
# app_name = 'yeast'
|
||||
|
||||
@ -16,5 +16,6 @@ urlpatterns = [
|
||||
path('batches/', BatchListView.as_view(), name='batches'),
|
||||
path('batch_lookup/', get_batch, name='get_batch'),
|
||||
path('batch_labels/<int:batch_id>/', login_required(batch_labels), name='labels'),
|
||||
path('progation/add/', NewPropogation, name='propogate'),
|
||||
path('', home, name='home'),
|
||||
]
|
||||
|
@ -1,14 +1,15 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from django.views.generic import ListView
|
||||
from django.views.generic.edit import CreateView
|
||||
from django.http import HttpResponse, HttpRequest
|
||||
from django.views.generic.edit import CreateView, FormView
|
||||
from django.views import View
|
||||
from django.http import HttpResponse, HttpRequest, HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
from django.http import JsonResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from yeast.models import Yeast, Propogation, Strain
|
||||
from yeast.models import Yeast, Propogation, Strain, Storage
|
||||
from config.extras import AveryLabel
|
||||
from yeast.forms import BatchAddForm, StrainAddForm
|
||||
from yeast.forms import BatchAddForm, StrainAddForm, PropogateSampleForm, PitchIntoBeerForm
|
||||
|
||||
|
||||
import logging
|
||||
@ -21,23 +22,39 @@ class BatchListView(ListView):
|
||||
model = Propogation
|
||||
|
||||
def sample(request, yeast_id):
|
||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||
return render(request, 'yeast/sample.html', {
|
||||
'sample': sample,
|
||||
'batch': get_object_or_404(Propogation, pk=sample.batch_id),
|
||||
'storage': list(Storage.objects.all()),
|
||||
})
|
||||
if request.method == 'POST':
|
||||
if 'pitch' in request.POST:
|
||||
|
||||
# @login_required
|
||||
# def get_batches(request):
|
||||
# strains = {}
|
||||
# for strain in Strain.objects.all():
|
||||
# batches = [x.id for x in Batch.objects.filter(strain=strain)]
|
||||
# if batches:
|
||||
# strains[strain.id] = batches
|
||||
pitch_form = PitchIntoBeerForm(request.POST)
|
||||
|
||||
if pitch_form.is_valid():
|
||||
logger.critical(pitch_form.cleaned_data)
|
||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||
pitch_form.pitch_sample()
|
||||
return HttpResponseRedirect(reverse('yeast:yeast', kwargs={'yeast_id': sample.id}))
|
||||
|
||||
elif 'propogate' in request.POST:
|
||||
propogate_form = PropogateSampleForm(request.POST)
|
||||
if propogate_form.is_valid():
|
||||
new_prop = propogate_form.create_propogation()
|
||||
return HttpResponseRedirect(reverse('yeast:batches', kwargs={'propogation_id': new_prop.id}))
|
||||
else:
|
||||
|
||||
return redirect('yeast:samples', kwargs={'yeast_id':yeast_id})
|
||||
else:
|
||||
propogate_form = PropogateSampleForm(initial={'sample': get_object_or_404(Yeast, pk=yeast_id)})
|
||||
pitch_form = PitchIntoBeerForm()
|
||||
|
||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||
|
||||
return render(request, 'yeast/sample.html', {
|
||||
'sample': sample,
|
||||
'batch': get_object_or_404(Propogation, pk=sample.propogation_id),
|
||||
'storage': list(Storage.objects.all()),
|
||||
'propogate_form': propogate_form,
|
||||
'pitch_form': pitch_form,
|
||||
})
|
||||
|
||||
# return JsonResponse(
|
||||
# {'data': [strains]})
|
||||
|
||||
def get_batch(request):
|
||||
batch_id = int(request.POST.get('batch'))
|
||||
@ -57,9 +74,11 @@ def batch(request, batch_id):
|
||||
``Template``
|
||||
:template:`yeast/batch.html`
|
||||
"""
|
||||
|
||||
batch = get_object_or_404(Propogation, pk=batch_id)
|
||||
return render(request, 'yeast/batch.html', {'batch': batch})
|
||||
|
||||
|
||||
def batch_labels(request, batch_id):
|
||||
"""
|
||||
Create label PDF for samples in a batch.
|
||||
@ -111,4 +130,14 @@ class addStrain(CreateView):
|
||||
|
||||
def get_success_url(self):
|
||||
id = self.object.id #gets id from created object
|
||||
return reverse('yeast:batches')
|
||||
return reverse('yeast:batches')
|
||||
|
||||
@login_required
|
||||
class NewPropogation(FormView):
|
||||
# ~ template_name = "contact.html"
|
||||
form_class = PropogateSampleForm
|
||||
success_url = "/"
|
||||
|
||||
def form_valid(self, form):
|
||||
form.create_propogation()
|
||||
return super().form_valid(form)
|
||||
|
Loading…
Reference in New Issue
Block a user