Basic outline of yeast sample page.
None of the controls do anything yet.
This commit is contained in:
parent
e91a01f0bf
commit
c3634141a3
@ -1,6 +1,8 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from config.extras import BREWFATHER_APP_ROOT
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger('django')
|
logger = logging.getLogger('django')
|
||||||
|
|
||||||
@ -18,6 +20,10 @@ class Batch(CustomModel):
|
|||||||
brewfather_name = models.CharField(max_length=500, default='name')
|
brewfather_name = models.CharField(max_length=500, default='name')
|
||||||
recipe = models.ForeignKey('BatchRecipe', on_delete=models.CASCADE, default=1)
|
recipe = models.ForeignKey('BatchRecipe', on_delete=models.CASCADE, default=1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def brewfather_url(self):
|
||||||
|
return '{}/tabs/batches/batch/{}'.format(BREWFATHER_APP_ROOT, self.brewfather_id)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# Return a string that represents the instance
|
# Return a string that represents the instance
|
||||||
return 'BF #{num}: {name}'.format(name=self.brewfather_name, num=self.brewfather_num)
|
return 'BF #{num}: {name}'.format(name=self.brewfather_name, num=self.brewfather_num)
|
||||||
|
@ -8,12 +8,12 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
|
||||||
<!-- JS, Popper.js, and jQuery -->
|
<!-- JS, Popper.js, and jQuery -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js"
|
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.min.js" -->
|
||||||
integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy"
|
<!-- integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" -->
|
||||||
crossorigin="anonymous"></script>
|
<!-- crossorigin="anonymous"></script> -->
|
||||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
||||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
|
||||||
crossorigin="anonymous"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||||
{% block script %}{% endblock %}
|
{% block script %}{% endblock %}
|
||||||
<style>
|
<style>
|
||||||
{% block style %}{% endblock %}
|
{% block style %}{% endblock %}
|
||||||
@ -23,6 +23,15 @@
|
|||||||
label {
|
label {
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
.table-borderless > tbody > tr > td,
|
||||||
|
.table-borderless > tbody > tr > th,
|
||||||
|
.table-borderless > tfoot > tr > td,
|
||||||
|
.table-borderless > tfoot > tr > th,
|
||||||
|
.table-borderless > thead > tr > td,
|
||||||
|
.table-borderless > thead > tr > th {
|
||||||
|
border: none;
|
||||||
|
background-color: rgba(0,0,0, 0.0) !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -90,8 +99,6 @@
|
|||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
{% block endscript %}{% endblock %}
|
{% block endscript %}{% endblock %}
|
||||||
</html>
|
</html>
|
||||||
|
@ -2,33 +2,143 @@
|
|||||||
{% load mathfilters %}
|
{% load mathfilters %}
|
||||||
{% block title %}Yeast Samples{% endblock %}
|
{% block title %}Yeast Samples{% endblock %}
|
||||||
|
|
||||||
{% block jumbotron %}Yeast Sample:{% endblock %}
|
{% block style %}
|
||||||
{% block jumbotronsub %}<a href="{% url 'admin:yeast_yeast_change' sample.id %}">{{ sample.id }}</a>{% endblock %}
|
.table td.fit,
|
||||||
|
.table th.fit {
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 1%;
|
||||||
|
}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block jumbotron %}Yeast Sample{% endblock %}
|
||||||
|
{% block jumbotronsub %}
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tbody>
|
||||||
|
<tr><th class="fit">{{ batch.strain.manufacturer.name }} {{ batch.strain.name }}</th><td><a href="{% url 'admin:yeast_yeast_change' sample.id %}">{{ sample.id }}</a></td></tr>
|
||||||
|
<tr><th class="fit">Batch Source</th>
|
||||||
|
<td>{{ batch.get_source_display }}
|
||||||
|
{% if batch.source_batch %}
|
||||||
|
from <a href="{{ batch.beer_url }}" target="_blank" rel="noopener noreferrer">#{{ batch.beer_num }}: {{ batch.beer_name }}</a><br>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr><th class="fit">Production Date</th><td>{{ sample.batch.production_date }}</td></tr>
|
||||||
|
<tr><th class="fit">Storage</th>
|
||||||
|
<td>
|
||||||
|
{{ 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>)
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<!-- Information Header -->
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
<h3>{{ batch.strain.name }}</h3>
|
</div> <!-- /container -->
|
||||||
<b>Batch Source:</b> {{ batch.get_source_display }}
|
<!-- End Information Header -->
|
||||||
{% if batch.source_batch %}
|
|
||||||
from <a href="{{ batch.beer_url }}" target="_blank" rel="noopener noreferrer">#{{ batch.beer_num }}: {{ batch.beer_name }}</a>
|
<!-- Main Data Container -->
|
||||||
{% endif %}<br>
|
<div class="container mt-4 mb-4">
|
||||||
<b>Production Date:</b> {{ sample.batch.production_date }}<br>
|
<div class="row">
|
||||||
|
|
||||||
|
<!-- Tabbed Forms -->
|
||||||
|
<div class="col-lg-6" style="{% if sample.pitched %}display:none{% endif %}">
|
||||||
|
<!-- Nav tabs -->
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" data-bs-toggle="tab" href="#propogate">Propogate Sample</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" data-bs-toggle="tab" href="#pitch">Pitch Sample</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- Tab panes -->
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="propogate" class="container tab-pane active"><br>
|
||||||
|
<!-- Sample Propogation Form -->
|
||||||
|
<div class="container" style="border:1px solid #cecece;">
|
||||||
|
<form >
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- End Sample Propogation Form -->
|
||||||
|
</div>
|
||||||
|
<div id="pitch" class="container tab-pane fade"><br>
|
||||||
|
<!-- Sample Pitch Form -->
|
||||||
|
<div class="container" style="border:1px solid #cecece;">
|
||||||
|
<form >
|
||||||
|
<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>
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<!-- End Sample Pitch Form -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- End Tabbed Forms -->
|
||||||
|
|
||||||
|
<!-- Remain Sample List -->
|
||||||
|
<div class="col-lg-6">
|
||||||
|
{% if batch.remaining_samples %}<h4>Other Remaining Batch Samples</h4>
|
||||||
|
<ul>
|
||||||
|
{% for s in batch.remaining_samples|dictsort:"storage.name" %}
|
||||||
|
{% if s.id != sample.id %}
|
||||||
|
<li><a href="{% url 'yeast:yeast' s.id %}">{{ s.id }}</a> - {{ s.storage.name }} for {{ s.age }} days, {{ s.viability|mul:100|floatformat:1 }}%</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
{% if batch.used_samples %}<h4>Other Samples Used</h4>
|
||||||
|
<ul>
|
||||||
|
{% for s in batch.used_samples %}
|
||||||
|
{% if s.id != sample.id %}
|
||||||
|
<li><a href="{% url 'yeast:yeast' s.id %}">{{ s.id }}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<!-- End Remain Sample List -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Main Data Container -->
|
||||||
|
|
||||||
<p><p>
|
|
||||||
{% if batch.remaining_samples %}<h4>Batch Samples Remaining</h4>
|
|
||||||
<ul>
|
|
||||||
{% for sample in batch.remaining_samples %}
|
|
||||||
<li><a href="{% url 'yeast:yeast' sample.id %}">{{ sample.id }}</a> - Storage method: {{ sample.storage.name }} for {{ sample.age }} days, Viability: {{ sample.viability|mul:100|floatformat:1 }}%</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
{% if batch.used_samples %}<h4>Batch Samples Used</h4>
|
|
||||||
<ul>
|
|
||||||
{% for sample in batch.used_samples %}
|
|
||||||
<li><a href="{% url 'yeast:yeast' sample.id %}">{{ sample.id }}</a></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
</div> <!-- /container -->
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -6,7 +6,7 @@ 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, Batch, Strain
|
from yeast.models import Yeast, Batch, Strain, Storage
|
||||||
from config.extras import AveryLabel
|
from config.extras import AveryLabel
|
||||||
from yeast.forms import BatchAddForm, StrainAddForm
|
from yeast.forms import BatchAddForm, StrainAddForm
|
||||||
|
|
||||||
@ -21,10 +21,12 @@ class BatchListView(ListView):
|
|||||||
model = Batch
|
model = Batch
|
||||||
|
|
||||||
def sample(request, yeast_id):
|
def sample(request, yeast_id):
|
||||||
|
|
||||||
sample = get_object_or_404(Yeast, pk=yeast_id)
|
sample = get_object_or_404(Yeast, pk=yeast_id)
|
||||||
sample_batch = get_object_or_404(Batch, pk=sample.batch_id)
|
return render(request, 'yeast/sample.html', {
|
||||||
return render(request, 'yeast/sample.html', {'sample': sample, 'batch':sample_batch})
|
'sample': sample,
|
||||||
|
'batch': get_object_or_404(Batch, pk=sample.batch_id),
|
||||||
|
'storage': list(Storage.objects.all()),
|
||||||
|
})
|
||||||
|
|
||||||
# @login_required
|
# @login_required
|
||||||
# def get_batches(request):
|
# def get_batches(request):
|
||||||
|
Loading…
Reference in New Issue
Block a user