mirror of
https://github.com/grassrootseconomics/farmstar-survey-backend.git
synced 2024-12-21 15:07:32 +01:00
244 lines
9.6 KiB
Go
244 lines
9.6 KiB
Go
package router
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/labstack/echo/v5"
|
|
"github.com/pocketbase/pocketbase/apis"
|
|
"github.com/pocketbase/pocketbase/core"
|
|
"github.com/pocketbase/pocketbase/daos"
|
|
"github.com/pocketbase/pocketbase/forms"
|
|
"github.com/pocketbase/pocketbase/models"
|
|
)
|
|
|
|
func (r *RouterContainer) bootstrapFarmerSurveyRoute() {
|
|
r.PB.OnBeforeServe().Add(func(e *core.ServeEvent) error {
|
|
e.Router.POST("/farmer", func(c echo.Context) error {
|
|
requestData := struct {
|
|
Phone string `json:"phone"`
|
|
County string `json:"county" `
|
|
SubCounty string `json:"sub_county"`
|
|
FarmingAreaAcres string `json:"farming_area_acres"`
|
|
PlannedCrops []string `json:"planned_crops"`
|
|
PastHarvestDetails []struct {
|
|
CropType string `json:"crop_type"`
|
|
AverageHarvest string `json:"average_harvest"`
|
|
AverageEarning string `json:"average_earning"`
|
|
} `json:"past_harvest_details"`
|
|
TotalExpenditure string `json:"total_expenditure"`
|
|
SeedsExpenditurePercentage string `json:"seeds_expenditure_percentage"`
|
|
FertilizerExpenditurePercentage string `json:"fertilizer_expenditure_percentage"`
|
|
CropsProtectionExpenditurePercentage string `json:"crops_protection_expenditure_percentage"`
|
|
SyntheticFertilizersExpenditurePercentage string `json:"synthetic_fertilizers_expenditure_percentage"`
|
|
NaturalFertilizersExpenditure string `json:"natural_fertilizers_expenditure_percentage"`
|
|
IncreasedExpenses []struct {
|
|
ExpenseType string `json:"expense_type"`
|
|
IncreasedExpenseActions []string `json:"increased_expense_actions"`
|
|
ExpenseActionOverallEffect string `json:"expense_action_overall_effect"`
|
|
} `json:"increased_expenses"`
|
|
EvergrowPast string `json:"evergrow_past"`
|
|
EvergrowFirst string `json:"evergrow_first"`
|
|
EvergrowApplication string `json:"evergrow_application"`
|
|
EvergrowCrops []string `json:"evergrow_crops"`
|
|
EvergrowYield string `json:"evergrow_yield"`
|
|
OtherFertilizers string `json:"other_fertilizers"`
|
|
PurchaseChannels []string `json:"purchase_channels"`
|
|
OtherFertilizersDetails []struct {
|
|
OtherFertilizerType string `json:"other_fertilizer_type"`
|
|
OtherFertilizerApplication string `json:"other_fertilizer_application"`
|
|
OtherFertilizerCrops []string `json:"other_fertilizer_crops"`
|
|
} `json:"other_fertilizers_details"`
|
|
}{}
|
|
if err := c.Bind(&requestData); err != nil {
|
|
return apis.NewBadRequestError("Failed to read request data", err)
|
|
}
|
|
|
|
budgetSplit, err := validatePercentage(requestData.CropsProtectionExpenditurePercentage, requestData.FertilizerExpenditurePercentage, requestData.SeedsExpenditurePercentage)
|
|
if err != nil {
|
|
return apis.NewBadRequestError("Could not validate budget split percentage", err)
|
|
}
|
|
if !budgetSplit {
|
|
return apis.NewNotFoundError("Budget split percentage should add up to 100% ", err)
|
|
}
|
|
|
|
fertilizerSplit, err := validatePercentage(requestData.SyntheticFertilizersExpenditurePercentage, requestData.NaturalFertilizersExpenditure)
|
|
if err != nil {
|
|
return apis.NewBadRequestError("Could not validate fertilizer split percentage", err)
|
|
}
|
|
if !fertilizerSplit {
|
|
return apis.NewNotFoundError("Fertilizer split percentage should add up to 100% ", err)
|
|
}
|
|
|
|
if err := r.PB.Dao().RunInTransaction(func(txDao *daos.Dao) error {
|
|
userRecord, err := r.PB.Dao().FindFirstRecordByData("users", "phone", requestData.Phone)
|
|
if err != nil {
|
|
return apis.NewNotFoundError("Phone number not found", err)
|
|
}
|
|
|
|
if userRecord.GetString("participant_type") != "farmer" {
|
|
return apis.NewNotFoundError("User is not registered as a farmer", err)
|
|
}
|
|
|
|
farmerFarmCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_farm")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
farmerFarmRecord := models.NewRecord(farmerFarmCollection)
|
|
farmerFarmForm := forms.NewRecordUpsert(r.PB, farmerFarmRecord)
|
|
farmerFarmForm.SetDao(txDao)
|
|
|
|
farmerFarmForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"county": requestData.County,
|
|
"sub_county": requestData.SubCounty,
|
|
"farming_area_acres": requestData.FarmingAreaAcres,
|
|
"planned_crops": requestData.PlannedCrops,
|
|
})
|
|
|
|
if err := farmerFarmForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit farm details", err)
|
|
}
|
|
|
|
farmerPastHarvestCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_past_harvest")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, v := range requestData.PastHarvestDetails {
|
|
farmerPastHarvestRecord := models.NewRecord(farmerPastHarvestCollection)
|
|
farmerPastHarvestForm := forms.NewRecordUpsert(r.PB, farmerPastHarvestRecord)
|
|
farmerPastHarvestForm.SetDao(txDao)
|
|
|
|
farmerPastHarvestForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"crop": v.CropType,
|
|
"average_harvest": v.AverageHarvest,
|
|
"average_earning": v.AverageEarning,
|
|
})
|
|
|
|
if err := farmerPastHarvestForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit harvest details", err)
|
|
}
|
|
}
|
|
|
|
farmerExpenditureBaseCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_expenditure_base")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
farmerExpenditureBaseRecord := models.NewRecord(farmerExpenditureBaseCollection)
|
|
farmerExpenditureBaseFarmForm := forms.NewRecordUpsert(r.PB, farmerExpenditureBaseRecord)
|
|
farmerExpenditureBaseFarmForm.SetDao(txDao)
|
|
|
|
farmerExpenditureBaseFarmForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"total_expenditure": requestData.TotalExpenditure,
|
|
"seeds_expenditure_percentage": requestData.SeedsExpenditurePercentage,
|
|
"fertilizer_expenditure_percentage": requestData.FertilizerExpenditurePercentage,
|
|
"crops_protection_expenditure_percentage": requestData.CropsProtectionExpenditurePercentage,
|
|
"synthetic_fertilizers_expenditure_percentage": requestData.SyntheticFertilizersExpenditurePercentage,
|
|
"natural_fertilizers_expenditure_percentage": requestData.NaturalFertilizersExpenditure,
|
|
})
|
|
|
|
if err := farmerExpenditureBaseFarmForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit expenditure base details", err)
|
|
}
|
|
|
|
farmerExpenditureIncreasedCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_expenditure_increased")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, v := range requestData.IncreasedExpenses {
|
|
farmerExpenditureIncreasedRecord := models.NewRecord(farmerExpenditureIncreasedCollection)
|
|
farmerExpenditureIncreasedForm := forms.NewRecordUpsert(r.PB, farmerExpenditureIncreasedRecord)
|
|
farmerExpenditureIncreasedForm.SetDao(txDao)
|
|
|
|
farmerExpenditureIncreasedForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"expense": v.ExpenseType,
|
|
"actions": v.IncreasedExpenseActions,
|
|
"overall_effect": v.ExpenseActionOverallEffect,
|
|
})
|
|
|
|
if err := farmerExpenditureIncreasedForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit farmer expenditure increased details", err)
|
|
}
|
|
}
|
|
|
|
farmerEvergrowCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_evergrow")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
farmerEvergrowRecord := models.NewRecord(farmerEvergrowCollection)
|
|
farmerEvergrowForm := forms.NewRecordUpsert(r.PB, farmerEvergrowRecord)
|
|
farmerEvergrowForm.SetDao(txDao)
|
|
|
|
farmerEvergrowForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"evergrow_past": requestData.EvergrowPast,
|
|
"evergrow_first": requestData.EvergrowFirst,
|
|
"evergrow_application": requestData.EvergrowApplication,
|
|
"evergrow_crops": requestData.EvergrowCrops,
|
|
"evergrow_yield": requestData.EvergrowYield,
|
|
"other_fertilizers": requestData.OtherFertilizers,
|
|
"purchase_channels": requestData.PurchaseChannels,
|
|
})
|
|
|
|
if err := farmerEvergrowForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit evergrow details", err)
|
|
}
|
|
|
|
farmerOtherFertilizersCollection, err := r.PB.Dao().FindCollectionByNameOrId("farmer_other_fertilizers")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, v := range requestData.OtherFertilizersDetails {
|
|
farmerOtherFertilizersRecord := models.NewRecord(farmerOtherFertilizersCollection)
|
|
farmerOtherFertilizersForm := forms.NewRecordUpsert(r.PB, farmerOtherFertilizersRecord)
|
|
farmerOtherFertilizersForm.SetDao(txDao)
|
|
|
|
farmerOtherFertilizersForm.LoadData(map[string]any{
|
|
"user": userRecord.Id,
|
|
"fertilizer_type": v.OtherFertilizerType,
|
|
"fertilizer_application": v.OtherFertilizerApplication,
|
|
"crops": v.OtherFertilizerCrops,
|
|
})
|
|
|
|
if err := farmerOtherFertilizersForm.Submit(); err != nil {
|
|
return apis.NewBadRequestError("Failed to submit other fertilizers details", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
|
|
}); err != nil {
|
|
c.JSON(400, map[string]any{"ok": "false", "error": err.Error()})
|
|
|
|
return nil
|
|
}
|
|
|
|
c.JSON(200, map[string]any{"ok": "true"})
|
|
|
|
return nil
|
|
})
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func validatePercentage(inputs ...string) (bool, error) {
|
|
sum := 0
|
|
for _, numStr := range inputs {
|
|
num, err := strconv.Atoi(numStr)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
sum += num
|
|
}
|
|
return sum == 100, nil
|
|
}
|