Add treatment and inspection history to a source
This commit is contained in:
parent
f599d831c8
commit
9e3d12ae2a
3 changed files with 92 additions and 98 deletions
75
html.go
75
html.go
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"github.com/Gleipnir-Technology/nidus-sync/models"
|
"github.com/Gleipnir-Technology/nidus-sync/models"
|
||||||
"github.com/aarondl/opt/null"
|
"github.com/aarondl/opt/null"
|
||||||
//"github.com/riverqueue/river/rivershared/util/slogutil"
|
//"github.com/riverqueue/river/rivershared/util/slogutil"
|
||||||
|
//"github.com/rs/zerolog/log"
|
||||||
"github.com/stephenafamo/bob/dialect/psql"
|
"github.com/stephenafamo/bob/dialect/psql"
|
||||||
"github.com/stephenafamo/bob/dialect/psql/sm"
|
"github.com/stephenafamo/bob/dialect/psql/sm"
|
||||||
"github.com/uber/h3-go/v4"
|
"github.com/uber/h3-go/v4"
|
||||||
|
|
@ -120,9 +121,11 @@ type ContentSignin struct {
|
||||||
}
|
}
|
||||||
type ContentSignup struct{}
|
type ContentSignup struct{}
|
||||||
type ContentSource struct {
|
type ContentSource struct {
|
||||||
MapData ComponentMap
|
Inspections []Inspection
|
||||||
Source *BreedingSourceDetail
|
MapData ComponentMap
|
||||||
User User
|
Source *BreedingSourceDetail
|
||||||
|
Treatments []Treatment
|
||||||
|
User User
|
||||||
}
|
}
|
||||||
type LatLng struct {
|
type LatLng struct {
|
||||||
Lat float64
|
Lat float64
|
||||||
|
|
@ -493,7 +496,18 @@ func htmlSource(w http.ResponseWriter, r *http.Request, user *models.User, id st
|
||||||
respondError(w, "Failed to get source", err, http.StatusInternalServerError)
|
respondError(w, "Failed to get source", err, http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
inspections, err := inspectionsBySource(r.Context(), org, id)
|
||||||
|
if err != nil {
|
||||||
|
respondError(w, "Failed to get inspections", err, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
treatments, err := treatmentsBySource(r.Context(), org, id)
|
||||||
|
if err != nil {
|
||||||
|
respondError(w, "Failed to get treatments", err, http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
data := ContentSource{
|
data := ContentSource{
|
||||||
|
Inspections: inspections,
|
||||||
MapData: ComponentMap{
|
MapData: ComponentMap{
|
||||||
Center: LatLng{
|
Center: LatLng{
|
||||||
Lat: s.GeometryY,
|
Lat: s.GeometryY,
|
||||||
|
|
@ -511,8 +525,9 @@ func htmlSource(w http.ResponseWriter, r *http.Request, user *models.User, id st
|
||||||
},
|
},
|
||||||
Zoom: 13,
|
Zoom: 13,
|
||||||
},
|
},
|
||||||
Source: s,
|
Source: s,
|
||||||
User: userContent,
|
Treatments: treatments,
|
||||||
|
User: userContent,
|
||||||
}
|
}
|
||||||
|
|
||||||
renderOrError(w, source, data)
|
renderOrError(w, source, data)
|
||||||
|
|
@ -666,6 +681,21 @@ func renderOrError(w http.ResponseWriter, template BuiltTemplate, context interf
|
||||||
buf.WriteTo(w)
|
buf.WriteTo(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func treatmentsBySource(ctx context.Context, org *models.Organization, sourceID string) ([]Treatment, error) {
|
||||||
|
var results []Treatment
|
||||||
|
rows, err := org.FSTreatments(
|
||||||
|
sm.Where(
|
||||||
|
models.FSTreatments.Columns.Pointlocid.EQ(psql.Arg(sourceID)),
|
||||||
|
),
|
||||||
|
sm.OrderBy("enddatetime"),
|
||||||
|
).All(ctx, PGInstance.BobDB)
|
||||||
|
if err != nil {
|
||||||
|
return results, fmt.Errorf("Failed to query rows: %w", err)
|
||||||
|
}
|
||||||
|
//log.Info().Int("row count", len(rows)).Msg("Getting treatments")
|
||||||
|
return toTemplateTreatment(rows)
|
||||||
|
}
|
||||||
|
|
||||||
func treatmentsByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]Treatment, error) {
|
func treatmentsByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]Treatment, error) {
|
||||||
var results []Treatment
|
var results []Treatment
|
||||||
boundary, err := c.Boundary()
|
boundary, err := c.Boundary()
|
||||||
|
|
@ -683,15 +713,7 @@ func treatmentsByCell(ctx context.Context, org *models.Organization, c h3.Cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, fmt.Errorf("Failed to query rows: %w", err)
|
return results, fmt.Errorf("Failed to query rows: %w", err)
|
||||||
}
|
}
|
||||||
for _, r := range rows {
|
return toTemplateTreatment(rows)
|
||||||
results = append(results, Treatment{
|
|
||||||
Date: *fsTimestampToTime(r.Enddatetime),
|
|
||||||
LocationID: r.Pointlocid.GetOr("none"),
|
|
||||||
Notes: r.Comments.GetOr("none"),
|
|
||||||
Product: r.Product.GetOr("none"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
}
|
||||||
func inspectionsByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]Inspection, error) {
|
func inspectionsByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]Inspection, error) {
|
||||||
var results []Inspection
|
var results []Inspection
|
||||||
|
|
@ -711,16 +733,21 @@ func inspectionsByCell(ctx context.Context, org *models.Organization, c h3.Cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, fmt.Errorf("Failed to query rows: %w", err)
|
return results, fmt.Errorf("Failed to query rows: %w", err)
|
||||||
}
|
}
|
||||||
for _, r := range rows {
|
return toTemplateInspection(rows)
|
||||||
results = append(results, Inspection{
|
}
|
||||||
Action: r.Actiontaken.GetOr("none"),
|
func inspectionsBySource(ctx context.Context, org *models.Organization, sourceID string) ([]Inspection, error) {
|
||||||
Date: *fsTimestampToTime(r.Enddatetime),
|
var results []Inspection
|
||||||
Notes: r.Comments.GetOr("none"),
|
|
||||||
Location: r.Locationname.GetOr("none"),
|
rows, err := org.FSMosquitoinspections(
|
||||||
LocationID: r.Pointlocid.GetOr(""),
|
sm.Where(
|
||||||
})
|
models.FSMosquitoinspections.Columns.Pointlocid.EQ(psql.Arg(sourceID)),
|
||||||
|
),
|
||||||
|
sm.OrderBy("enddatetime").Desc(),
|
||||||
|
).All(ctx, PGInstance.BobDB)
|
||||||
|
if err != nil {
|
||||||
|
return results, fmt.Errorf("Failed to query rows: %w", err)
|
||||||
}
|
}
|
||||||
return results, nil
|
return toTemplateInspection(rows)
|
||||||
}
|
}
|
||||||
func breedingSourcesByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]BreedingSourceSummary, error) {
|
func breedingSourcesByCell(ctx context.Context, org *models.Organization, c h3.Cell) ([]BreedingSourceSummary, error) {
|
||||||
var results []BreedingSourceSummary
|
var results []BreedingSourceSummary
|
||||||
|
|
@ -765,5 +792,5 @@ func sourceByGlobalId(ctx context.Context, org *models.Organization, id string)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to get point location: %w", err)
|
return nil, fmt.Errorf("Failed to get point location: %w", err)
|
||||||
}
|
}
|
||||||
return ConvertToDisplayModel(row), nil
|
return toTemplateBreedingSource(row), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,8 +72,35 @@ type BreedingSourceDetail struct {
|
||||||
Comments string `json:"comments"`
|
Comments string `json:"comments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertToDisplayModel transforms the DB model into the display model
|
func toTemplateTreatment(rows models.FSTreatmentSlice) ([]Treatment, error) {
|
||||||
func ConvertToDisplayModel(source *models.FSPointlocation) *BreedingSourceDetail {
|
var results []Treatment
|
||||||
|
for _, r := range rows {
|
||||||
|
results = append(results, Treatment{
|
||||||
|
Date: *fsTimestampToTime(r.Enddatetime),
|
||||||
|
LocationID: r.Pointlocid.GetOr("none"),
|
||||||
|
Notes: r.Comments.GetOr("none"),
|
||||||
|
Product: r.Product.GetOr("none"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func toTemplateInspection(rows models.FSMosquitoinspectionSlice) ([]Inspection, error) {
|
||||||
|
var results []Inspection
|
||||||
|
for _, r := range rows {
|
||||||
|
results = append(results, Inspection{
|
||||||
|
Action: r.Actiontaken.GetOr("none"),
|
||||||
|
Date: *fsTimestampToTime(r.Enddatetime),
|
||||||
|
Notes: r.Comments.GetOr("none"),
|
||||||
|
Location: r.Locationname.GetOr("none"),
|
||||||
|
LocationID: r.Pointlocid.GetOr(""),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toTemplateBreedingSource transforms the DB model into the display model
|
||||||
|
func toTemplateBreedingSource(source *models.FSPointlocation) *BreedingSourceDetail {
|
||||||
// Helper function to convert unix timestamp to time.Time
|
// Helper function to convert unix timestamp to time.Time
|
||||||
toTime := func(val null.Val[int64]) time.Time {
|
toTime := func(val null.Val[int64]) time.Time {
|
||||||
v, ok := val.Get()
|
v, ok := val.Get()
|
||||||
|
|
|
||||||
|
|
@ -244,53 +244,17 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{{ range .Treatments }}
|
||||||
<tr>
|
<tr>
|
||||||
<td>04/16/2023</td>
|
<td>{{.Date|timeSince}}</td>
|
||||||
<td>Bacillus thuringiensis israelensis (Bti)</td>
|
<td>{{.Product}}</td>
|
||||||
<td class="time-delta-neutral">On time</td>
|
<td class="time-delta-neutral">On time</td>
|
||||||
<td>Applied larvicide to standing water.</td>
|
<td>{{.Notes}}</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>04/02/2023</td>
|
|
||||||
<td>Methoprene</td>
|
|
||||||
<td class="time-delta-neutral">On time</td>
|
|
||||||
<td>Applied to ditch with extended release formula.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>03/18/2023</td>
|
|
||||||
<td>Bacillus sphaericus</td>
|
|
||||||
<td class="time-delta-negative">-1 day</td>
|
|
||||||
<td>Preemptive treatment before rain event.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>03/01/2023</td>
|
|
||||||
<td>Bacillus thuringiensis israelensis (Bti)</td>
|
|
||||||
<td class="time-delta-positive">+3 days</td>
|
|
||||||
<td>Delayed due to weather conditions.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>02/15/2023</td>
|
|
||||||
<td>Methoprene</td>
|
|
||||||
<td class="time-delta-neutral">On time</td>
|
|
||||||
<td>Regular treatment cycle.</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
{{ end }}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav aria-label="Treatments pagination">
|
|
||||||
<ul class="pagination justify-content-center">
|
|
||||||
<li class="page-item disabled">
|
|
||||||
<a class="page-link" href="#" tabindex="-1">Previous</a>
|
|
||||||
</li>
|
|
||||||
<li class="page-item active"><a class="page-link" href="#">1</a></li>
|
|
||||||
<li class="page-item"><a class="page-link" href="#">2</a></li>
|
|
||||||
<li class="page-item"><a class="page-link" href="#">3</a></li>
|
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link" href="#">Next</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -303,42 +267,18 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Inspection Date</th>
|
<th>Inspection Date</th>
|
||||||
<th>Inspector</th>
|
<th>Action</th>
|
||||||
<th>Larvae Present</th>
|
<th>Notes</th>
|
||||||
<th>Comments</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{{ range .Inspections }}
|
||||||
<tr>
|
<tr>
|
||||||
<td>04/15/2023</td>
|
<td>{{.Date|timeSince}}</td>
|
||||||
<td>J. Smith</td>
|
<td>{{.Action}}</td>
|
||||||
<td><span class="badge bg-danger">Yes</span></td>
|
<td>{{.Notes}}</td>
|
||||||
<td>Moderate larvae presence, treatment recommended.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>04/01/2023</td>
|
|
||||||
<td>M. Johnson</td>
|
|
||||||
<td><span class="badge bg-danger">Yes</span></td>
|
|
||||||
<td>High larvae count, immediate treatment needed.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>03/17/2023</td>
|
|
||||||
<td>J. Smith</td>
|
|
||||||
<td><span class="badge bg-success">No</span></td>
|
|
||||||
<td>No larvae observed, previous treatment effective.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>03/03/2023</td>
|
|
||||||
<td>R. Williams</td>
|
|
||||||
<td><span class="badge bg-danger">Yes</span></td>
|
|
||||||
<td>Low larvae count, monitoring recommended.</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>02/14/2023</td>
|
|
||||||
<td>M. Johnson</td>
|
|
||||||
<td><span class="badge bg-danger">Yes</span></td>
|
|
||||||
<td>Moderate larvae count, treatment scheduled.</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
{{ end }}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue