Merge 3-sample_controls #8
1
run.sh
Normal file → Executable file
1
run.sh
Normal file → Executable file
@ -1,3 +1,4 @@
|
|||||||
#! /usr/bin/env bash
|
#! /usr/bin/env bash
|
||||||
|
|
||||||
|
source .env/bin/activate
|
||||||
python manage.py runserver 0.0.0.0:9595
|
python manage.py runserver 0.0.0.0:9595
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.utils import timezone
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
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
|
import logging
|
||||||
logger = logging.getLogger('django')
|
logger = logging.getLogger('django')
|
||||||
@ -31,7 +39,7 @@ class BatchAddForm(forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
# specify model to be used
|
# specify model to be used
|
||||||
model = Propogation
|
model = Propogation
|
||||||
|
|
||||||
# specify fields to be used
|
# specify fields to be used
|
||||||
fields = [
|
fields = [
|
||||||
'production_date',
|
'production_date',
|
||||||
@ -46,15 +54,70 @@ class BatchAddForm(forms.ModelForm):
|
|||||||
num_samples = forms.IntegerField()
|
num_samples = forms.IntegerField()
|
||||||
|
|
||||||
class StrainAddForm(forms.ModelForm):
|
class StrainAddForm(forms.ModelForm):
|
||||||
|
|
||||||
# create meta class
|
# create meta class
|
||||||
class Meta:
|
class Meta:
|
||||||
# specify model to be used
|
# specify model to be used
|
||||||
model = Strain
|
model = Strain
|
||||||
|
|
||||||
# specify fields to be used
|
# specify fields to be used
|
||||||
fields = [
|
fields = [
|
||||||
'name',
|
'name',
|
||||||
'long_name',
|
'long_name',
|
||||||
'manufacturer',
|
'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
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
{% block title %}Yeast Samples{% endblock %}
|
{% block title %}Yeast Samples{% endblock %}
|
||||||
|
|
||||||
{% block style %}
|
{% block style %}
|
||||||
.table td.fit,
|
.table td.fit,
|
||||||
.table th.fit {
|
.table th.fit {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: 1%;
|
width: 1%;
|
||||||
@ -22,12 +22,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
<tr><th class="fit">Storage</th>
|
||||||
<td>
|
<td>
|
||||||
{{ sample.storage }}
|
{{ sample.storage }}
|
||||||
{% if sample.pitched %}
|
{% 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 %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -64,24 +64,20 @@
|
|||||||
<div id="propogate" class="container tab-pane active"><br>
|
<div id="propogate" class="container tab-pane active"><br>
|
||||||
<!-- Sample Propogation Form -->
|
<!-- Sample Propogation Form -->
|
||||||
<div class="container" style="border:1px solid #cecece;">
|
<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>
|
<legend>Propogate Yeast Sample</legend>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="new-samples" class="form-label"># New Samples</label>
|
{{ propogate_form.num }}
|
||||||
<input type="number" class="form-control" id="new-samples" aria-describedby="numHelp">
|
<div id="id_num" class="form-text">New samples will be automatically created</div>
|
||||||
<div id="numHelp" class="form-text">New samples will be automatically created</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="parent" class="form-label">Default Storage Method</label>
|
{{ propogate_form.storage }}
|
||||||
<select class="form-select" id="parent" name="parent" aria-describedby="storageHelp">
|
<div id="id_storage" class="form-text">How will samples be stored?</div>
|
||||||
<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>
|
|
||||||
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- End Sample Propogation Form -->
|
<!-- End Sample Propogation Form -->
|
||||||
@ -89,23 +85,20 @@
|
|||||||
<div id="pitch" class="container tab-pane fade"><br>
|
<div id="pitch" class="container tab-pane fade"><br>
|
||||||
<!-- Sample Pitch Form -->
|
<!-- Sample Pitch Form -->
|
||||||
<div class="container" style="border:1px solid #cecece;">
|
<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>
|
<legend>Pitch Yeast Sample</legend>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="beer-batch" class="form-label">Beer Batch</label>
|
<label for="id_batch" class="form-label">Beer Batch</label>
|
||||||
<select class="form-select" id="beer-batch" name="beer-batch" aria-describedby="batchHelp">
|
{{ pitch_form.batch }}
|
||||||
<option selected>Beer Batch</option>
|
<div class="form-text">Select batch of beer sample is pitched into.</div>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3 form-check">
|
<div class="mb-3 form-check">
|
||||||
<input type="checkbox" class="form-check-input" id="starterCheck">
|
{{ pitch_form.starter }}
|
||||||
<label class="form-check-label" for="starterCheck">Pitched into starter?</label>
|
<label class="form-check-label" for="id_starter">Built up from starter?</label>
|
||||||
</div>
|
</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>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- End Sample Pitch Form -->
|
<!-- 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.auth.decorators import login_required
|
||||||
from django.contrib import admin
|
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'
|
# app_name = 'yeast'
|
||||||
|
|
||||||
@ -16,5 +16,6 @@ urlpatterns = [
|
|||||||
path('batches/', BatchListView.as_view(), name='batches'),
|
path('batches/', BatchListView.as_view(), name='batches'),
|
||||||
path('batch_lookup/', get_batch, name='get_batch'),
|
path('batch_lookup/', get_batch, name='get_batch'),
|
||||||
path('batch_labels/<int:batch_id>/', login_required(batch_labels), name='labels'),
|
path('batch_labels/<int:batch_id>/', login_required(batch_labels), name='labels'),
|
||||||
|
path('progation/add/', NewPropogation, name='propogate'),
|
||||||
path('', home, name='home'),
|
path('', home, name='home'),
|
||||||
]
|
]
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
from django.shortcuts import render, get_object_or_404, redirect
|
from django.shortcuts import render, get_object_or_404, redirect
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView
|
||||||
from django.views.generic.edit import CreateView
|
from django.views.generic.edit import CreateView, FormView
|
||||||
from django.http import HttpResponse, HttpRequest
|
from django.views import View
|
||||||
|
from django.http import HttpResponse, HttpRequest, HttpResponseRedirect
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
from django.contrib.auth.decorators import login_required
|
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 config.extras import AveryLabel
|
||||||
from yeast.forms import BatchAddForm, StrainAddForm
|
from yeast.forms import BatchAddForm, StrainAddForm, PropogateSampleForm, PitchIntoBeerForm
|
||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@ -21,23 +22,39 @@ class BatchListView(ListView):
|
|||||||
model = Propogation
|
model = Propogation
|
||||||
|
|
||||||
def sample(request, yeast_id):
|
def sample(request, yeast_id):
|
||||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
if request.method == 'POST':
|
||||||
return render(request, 'yeast/sample.html', {
|
if 'pitch' in request.POST:
|
||||||
'sample': sample,
|
|
||||||
'batch': get_object_or_404(Propogation, pk=sample.batch_id),
|
|
||||||
'storage': list(Storage.objects.all()),
|
|
||||||
})
|
|
||||||
|
|
||||||
# @login_required
|
pitch_form = PitchIntoBeerForm(request.POST)
|
||||||
# def get_batches(request):
|
|
||||||
# strains = {}
|
if pitch_form.is_valid():
|
||||||
# for strain in Strain.objects.all():
|
logger.critical(pitch_form.cleaned_data)
|
||||||
# batches = [x.id for x in Batch.objects.filter(strain=strain)]
|
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||||
# if batches:
|
pitch_form.pitch_sample()
|
||||||
# strains[strain.id] = batches
|
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):
|
def get_batch(request):
|
||||||
batch_id = int(request.POST.get('batch'))
|
batch_id = int(request.POST.get('batch'))
|
||||||
@ -57,9 +74,11 @@ def batch(request, batch_id):
|
|||||||
``Template``
|
``Template``
|
||||||
:template:`yeast/batch.html`
|
:template:`yeast/batch.html`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
batch = get_object_or_404(Propogation, pk=batch_id)
|
batch = get_object_or_404(Propogation, pk=batch_id)
|
||||||
return render(request, 'yeast/batch.html', {'batch': batch})
|
return render(request, 'yeast/batch.html', {'batch': batch})
|
||||||
|
|
||||||
|
|
||||||
def batch_labels(request, batch_id):
|
def batch_labels(request, batch_id):
|
||||||
"""
|
"""
|
||||||
Create label PDF for samples in a batch.
|
Create label PDF for samples in a batch.
|
||||||
@ -111,4 +130,14 @@ class addStrain(CreateView):
|
|||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
id = self.object.id #gets id from created object
|
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