From 284a40fac219db7854e35e1b8072d10f0af1958a Mon Sep 17 00:00:00 2001 From: matze Date: Tue, 15 Apr 2025 22:36:22 +0200 Subject: [PATCH] final project structure --- wagfarm-api/{models => }/Schlagkartei52.xlsm | Bin wagfarm-api/asset/asset.go | 28 ++++ wagfarm-api/asset/base/model.go | 30 ++++ wagfarm-api/asset/fertilizer/model.go | 20 +++ wagfarm-api/asset/fertilizer/route.go | 11 ++ wagfarm-api/asset/land/model.go | 11 ++ wagfarm-api/asset/land/route.go | 11 ++ wagfarm-api/asset/machine/model.go | 9 ++ wagfarm-api/asset/machine/route.go | 11 ++ wagfarm-api/asset/pesticide/model.go | 9 ++ wagfarm-api/asset/pesticide/route.go | 11 ++ wagfarm-api/asset/plant/model.go | 18 +++ wagfarm-api/asset/plant/route.go | 11 ++ wagfarm-api/asset/product/model.go | 9 ++ wagfarm-api/asset/product/route.go | 11 ++ wagfarm-api/asset/seed/model.go | 11 ++ wagfarm-api/asset/seed/route.go | 11 ++ wagfarm-api/controllers/logs/logs.go | 142 ------------------ wagfarm-api/database/db.go | 7 +- .../seedinglog.go => generic/controller.go} | 104 +++++++------ wagfarm-api/generic/model.go | 5 + wagfarm-api/generic/route.go | 16 ++ wagfarm-api/log/base/model.go | 31 ++++ wagfarm-api/log/base/route.go | 11 ++ wagfarm-api/log/cropprotection/model.go | 12 ++ wagfarm-api/log/cropprotection/route.go | 11 ++ wagfarm-api/log/fertilizing/model.go | 12 ++ wagfarm-api/log/fertilizing/route.go | 11 ++ wagfarm-api/log/harvest/model.go | 9 ++ wagfarm-api/log/harvest/route.go | 11 ++ wagfarm-api/log/seeding/model.go | 14 ++ wagfarm-api/log/seeding/route.go | 11 ++ wagfarm-api/main.go | 7 +- wagfarm-api/models/assets.go | 98 ------------ wagfarm-api/models/logs.go | 67 --------- wagfarm-api/models/taxonomy.go | 44 ------ wagfarm-api/routes/logs.go | 27 ---- wagfarm-api/routes/routes.go | 13 -- wagfarm-api/taxonomy/base/model.go | 8 + wagfarm-api/taxonomy/crop/model.go | 5 + wagfarm-api/taxonomy/crop/route.go | 11 ++ wagfarm-api/taxonomy/customer/model.go | 5 + wagfarm-api/taxonomy/customer/route.go | 11 ++ wagfarm-api/taxonomy/fertilizertype/model.go | 5 + wagfarm-api/taxonomy/fertilizertype/route.go | 11 ++ wagfarm-api/taxonomy/ingredient/model.go | 12 ++ wagfarm-api/taxonomy/ingredient/route.go | 11 ++ wagfarm-api/taxonomy/pesticidetype/model.go | 5 + wagfarm-api/taxonomy/pesticidetype/route.go | 11 ++ wagfarm-api/taxonomy/producttype/model.go | 5 + wagfarm-api/taxonomy/producttype/route.go | 11 ++ .../taxonomy/seedingcondition/model.go | 5 + .../taxonomy/seedingcondition/route.go | 11 ++ .../taxonomy/seedingtechnique/model.go | 5 + .../taxonomy/seedingtechnique/route.go | 11 ++ wagfarm-api/taxonomy/seedtype/model.go | 12 ++ wagfarm-api/taxonomy/seedtype/route.go | 11 ++ wagfarm-api/taxonomy/seller/model.go | 5 + wagfarm-api/taxonomy/seller/route.go | 11 ++ wagfarm-api/taxonomy/unit/model.go | 5 + wagfarm-api/taxonomy/unit/route.go | 11 ++ wagfarm-api/taxonomy/visibility/model.go | 5 + wagfarm-api/taxonomy/visibility/route.go | 11 ++ wagfarm-api/taxonomy/worker/model.go | 5 + wagfarm-api/taxonomy/worker/route.go | 11 ++ 65 files changed, 668 insertions(+), 447 deletions(-) rename wagfarm-api/{models => }/Schlagkartei52.xlsm (100%) create mode 100644 wagfarm-api/asset/asset.go create mode 100644 wagfarm-api/asset/base/model.go create mode 100644 wagfarm-api/asset/fertilizer/model.go create mode 100644 wagfarm-api/asset/fertilizer/route.go create mode 100644 wagfarm-api/asset/land/model.go create mode 100644 wagfarm-api/asset/land/route.go create mode 100644 wagfarm-api/asset/machine/model.go create mode 100644 wagfarm-api/asset/machine/route.go create mode 100644 wagfarm-api/asset/pesticide/model.go create mode 100644 wagfarm-api/asset/pesticide/route.go create mode 100644 wagfarm-api/asset/plant/model.go create mode 100644 wagfarm-api/asset/plant/route.go create mode 100644 wagfarm-api/asset/product/model.go create mode 100644 wagfarm-api/asset/product/route.go create mode 100644 wagfarm-api/asset/seed/model.go create mode 100644 wagfarm-api/asset/seed/route.go delete mode 100644 wagfarm-api/controllers/logs/logs.go rename wagfarm-api/{controllers/logs/seedinglog.go => generic/controller.go} (51%) create mode 100644 wagfarm-api/generic/model.go create mode 100644 wagfarm-api/generic/route.go create mode 100644 wagfarm-api/log/base/model.go create mode 100644 wagfarm-api/log/base/route.go create mode 100644 wagfarm-api/log/cropprotection/model.go create mode 100644 wagfarm-api/log/cropprotection/route.go create mode 100644 wagfarm-api/log/fertilizing/model.go create mode 100644 wagfarm-api/log/fertilizing/route.go create mode 100644 wagfarm-api/log/harvest/model.go create mode 100644 wagfarm-api/log/harvest/route.go create mode 100644 wagfarm-api/log/seeding/model.go create mode 100644 wagfarm-api/log/seeding/route.go delete mode 100644 wagfarm-api/models/assets.go delete mode 100644 wagfarm-api/models/logs.go delete mode 100644 wagfarm-api/models/taxonomy.go delete mode 100644 wagfarm-api/routes/logs.go delete mode 100644 wagfarm-api/routes/routes.go create mode 100644 wagfarm-api/taxonomy/base/model.go create mode 100644 wagfarm-api/taxonomy/crop/model.go create mode 100644 wagfarm-api/taxonomy/crop/route.go create mode 100644 wagfarm-api/taxonomy/customer/model.go create mode 100644 wagfarm-api/taxonomy/customer/route.go create mode 100644 wagfarm-api/taxonomy/fertilizertype/model.go create mode 100644 wagfarm-api/taxonomy/fertilizertype/route.go create mode 100644 wagfarm-api/taxonomy/ingredient/model.go create mode 100644 wagfarm-api/taxonomy/ingredient/route.go create mode 100644 wagfarm-api/taxonomy/pesticidetype/model.go create mode 100644 wagfarm-api/taxonomy/pesticidetype/route.go create mode 100644 wagfarm-api/taxonomy/producttype/model.go create mode 100644 wagfarm-api/taxonomy/producttype/route.go create mode 100644 wagfarm-api/taxonomy/seedingcondition/model.go create mode 100644 wagfarm-api/taxonomy/seedingcondition/route.go create mode 100644 wagfarm-api/taxonomy/seedingtechnique/model.go create mode 100644 wagfarm-api/taxonomy/seedingtechnique/route.go create mode 100644 wagfarm-api/taxonomy/seedtype/model.go create mode 100644 wagfarm-api/taxonomy/seedtype/route.go create mode 100644 wagfarm-api/taxonomy/seller/model.go create mode 100644 wagfarm-api/taxonomy/seller/route.go create mode 100644 wagfarm-api/taxonomy/unit/model.go create mode 100644 wagfarm-api/taxonomy/unit/route.go create mode 100644 wagfarm-api/taxonomy/visibility/model.go create mode 100644 wagfarm-api/taxonomy/visibility/route.go create mode 100644 wagfarm-api/taxonomy/worker/model.go create mode 100644 wagfarm-api/taxonomy/worker/route.go diff --git a/wagfarm-api/models/Schlagkartei52.xlsm b/wagfarm-api/Schlagkartei52.xlsm similarity index 100% rename from wagfarm-api/models/Schlagkartei52.xlsm rename to wagfarm-api/Schlagkartei52.xlsm diff --git a/wagfarm-api/asset/asset.go b/wagfarm-api/asset/asset.go new file mode 100644 index 0000000..8213a4b --- /dev/null +++ b/wagfarm-api/asset/asset.go @@ -0,0 +1,28 @@ +package asset + +import ( + "wagfarm-api/asset/fertilizer" + "wagfarm-api/asset/land" + "wagfarm-api/asset/machine" + "wagfarm-api/asset/pesticide" + "wagfarm-api/asset/plant" + "wagfarm-api/asset/product" + "wagfarm-api/asset/seed" + + "github.com/gin-gonic/gin" +) + +const Models []interface{} { + +} + +func RegisterRoutes(rg *gin.RouterGroup) { + group := rg.Group("/asset") + fertilizer.RegisterRoutes(group) + land.RegisterRoutes(group) + machine.RegisterRoutes(group) + pesticide.RegisterRoutes(group) + plant.RegisterRoutes(group) + product.RegisterRoutes(group) + seed.RegisterRoutes(group) +} diff --git a/wagfarm-api/asset/base/model.go b/wagfarm-api/asset/base/model.go new file mode 100644 index 0000000..f32bd6c --- /dev/null +++ b/wagfarm-api/asset/base/model.go @@ -0,0 +1,30 @@ +package base + +type Asset struct { + ID uint `gorm:"primaryKey` + Name string `gorm:"not null"` + Notes string +} + +func (a Asset) GetID() uint { return a.ID } + +type Resource struct { + Asset + UnitID uint `gorm:"not null"` + Unit unit.Unit `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + Cost decimal.Decimal `gorm:"not null; type:decimal(10,2);"` // in euro/unit +} + +type BoughtResource struct { + Resource + BuyDate Datetime.Time `gorm:"type:date;default:CURRENT_DATE"` + BoughtFromID uint `gorm:"not null"` + BoughtFrom Seller `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} + +type SoldResource struct { + Resource + SaleDate Datetime.Time `gorm:"type:date;default:CURRENT_DATE"` + SoldToID uint `gorm:"not null"` + SoldTo Customer `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} diff --git a/wagfarm-api/asset/fertilizer/model.go b/wagfarm-api/asset/fertilizer/model.go new file mode 100644 index 0000000..d607f42 --- /dev/null +++ b/wagfarm-api/asset/fertilizer/model.go @@ -0,0 +1,20 @@ +package fertilizer + +import "wagfarm-api/asset/base" + +type Fertilizer struct { + base.BoughtResource + FertilizerTypeID uint `gorm:"not null"` + FertilizerType FertilizerType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + // Association to the ingredients. This represents the composition. + Ingredients []FertilizerIngredient `gorm:"not null; many2many:fertilizer_ingredient"` +} + +type FertilizerIngredient struct { + FertilizerAssetID uint `gorm:"primaryKey"` // foreign key to the fertilizer asset + IngredientID uint `gorm:"primaryKey"` // foreign key to the ingredient + Amount float64 `gorm:"not null"` // amount of the ingredient + + // Preload the ingredient details if needed. + Ingredient Ingredient `gorm:"not null"` +} diff --git a/wagfarm-api/asset/fertilizer/route.go b/wagfarm-api/asset/fertilizer/route.go new file mode 100644 index 0000000..3233ec7 --- /dev/null +++ b/wagfarm-api/asset/fertilizer/route.go @@ -0,0 +1,11 @@ +package fertilizer + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/fertilizer"), generic.DefaultCRUDController[Fertilizer]()) +} diff --git a/wagfarm-api/asset/land/model.go b/wagfarm-api/asset/land/model.go new file mode 100644 index 0000000..9d73b2f --- /dev/null +++ b/wagfarm-api/asset/land/model.go @@ -0,0 +1,11 @@ +package land + +import "wagfarm-api/asset/base" + +type Land struct { + base.Asset + FID string `gorm:"not null"` + IsWaterProtectionArea bool `gorm:"not null"` + IsRedArea bool `gorm:"not null"` + Area float64 `gorm:"not null"` +} diff --git a/wagfarm-api/asset/land/route.go b/wagfarm-api/asset/land/route.go new file mode 100644 index 0000000..febc1f3 --- /dev/null +++ b/wagfarm-api/asset/land/route.go @@ -0,0 +1,11 @@ +package land + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/land"), generic.DefaultCRUDController[Land]()) +} diff --git a/wagfarm-api/asset/machine/model.go b/wagfarm-api/asset/machine/model.go new file mode 100644 index 0000000..7f23b33 --- /dev/null +++ b/wagfarm-api/asset/machine/model.go @@ -0,0 +1,9 @@ +package machine + +import ( + "wagfarm-api/asset/base" +) + +type Machine struct { + base.Resource +} diff --git a/wagfarm-api/asset/machine/route.go b/wagfarm-api/asset/machine/route.go new file mode 100644 index 0000000..96aae42 --- /dev/null +++ b/wagfarm-api/asset/machine/route.go @@ -0,0 +1,11 @@ +package machine + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/machine"), generic.DefaultCRUDController[Machine]()) +} diff --git a/wagfarm-api/asset/pesticide/model.go b/wagfarm-api/asset/pesticide/model.go new file mode 100644 index 0000000..85be35a --- /dev/null +++ b/wagfarm-api/asset/pesticide/model.go @@ -0,0 +1,9 @@ +package pesticide + +import "wagfarm-api/asset/base" + +type Pesticide struct { + base.BoughtResource + PesticideTypeID uint `gorm:"not null"` + PesticideType PesticideType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} diff --git a/wagfarm-api/asset/pesticide/route.go b/wagfarm-api/asset/pesticide/route.go new file mode 100644 index 0000000..dd7d2ff --- /dev/null +++ b/wagfarm-api/asset/pesticide/route.go @@ -0,0 +1,11 @@ +package pesticide + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/pesticide"), generic.DefaultCRUDController[Pesticide]()) +} diff --git a/wagfarm-api/asset/plant/model.go b/wagfarm-api/asset/plant/model.go new file mode 100644 index 0000000..b4f1b49 --- /dev/null +++ b/wagfarm-api/asset/plant/model.go @@ -0,0 +1,18 @@ +package plant + +import ( + "wagfarm-api/asset/base" + "wagfarm-api/asset/land" +) + +type Plant struct { + base.Asset + LandId uint `gorm:"not null"` + Land land.Land `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + CropID uint `gorm:"not null"` + Crop crop.Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + CoverCropID uint `gorm:"not null"` + CoverCrop crop.Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` + Year uint `gorm:"not null"` + AreaPercentage float64 `gorm:"not null"` +} diff --git a/wagfarm-api/asset/plant/route.go b/wagfarm-api/asset/plant/route.go new file mode 100644 index 0000000..0b45f0c --- /dev/null +++ b/wagfarm-api/asset/plant/route.go @@ -0,0 +1,11 @@ +package plant + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/plant"), generic.DefaultCRUDController[Plant]()) +} diff --git a/wagfarm-api/asset/product/model.go b/wagfarm-api/asset/product/model.go new file mode 100644 index 0000000..dd71d30 --- /dev/null +++ b/wagfarm-api/asset/product/model.go @@ -0,0 +1,9 @@ +package product + +import "wagfarm-api/asset/base" + +type Product struct { + base.SoldResource + ProductTypeID uint `gorm:"not null"` + ProductType ProductType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} diff --git a/wagfarm-api/asset/product/route.go b/wagfarm-api/asset/product/route.go new file mode 100644 index 0000000..6ebb709 --- /dev/null +++ b/wagfarm-api/asset/product/route.go @@ -0,0 +1,11 @@ +package product + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/product"), generic.DefaultCRUDController[Product]()) +} diff --git a/wagfarm-api/asset/seed/model.go b/wagfarm-api/asset/seed/model.go new file mode 100644 index 0000000..b5dc3ea --- /dev/null +++ b/wagfarm-api/asset/seed/model.go @@ -0,0 +1,11 @@ +package seed + +import ( + "wagfarm-api/asset/base" +) + +type Seed struct { + base.BoughtResource + SeedTypeID uint `gorm:"not null"` + SeedType SeedType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} diff --git a/wagfarm-api/asset/seed/route.go b/wagfarm-api/asset/seed/route.go new file mode 100644 index 0000000..bb53700 --- /dev/null +++ b/wagfarm-api/asset/seed/route.go @@ -0,0 +1,11 @@ +package seed + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seed"), generic.DefaultCRUDController[Seed]()) +} diff --git a/wagfarm-api/controllers/logs/logs.go b/wagfarm-api/controllers/logs/logs.go deleted file mode 100644 index 5bc4817..0000000 --- a/wagfarm-api/controllers/logs/logs.go +++ /dev/null @@ -1,142 +0,0 @@ -package logs - -import ( - "net/http" - "strconv" - "time" - "wagfarm-api/database" - "wagfarm-api/models" - - "github.com/gin-gonic/gin" -) - -type LogController interface { - GetAll(c *gin.Context) - GetOne(c *gin.Context) - Create(c *gin.Context) - Update(c *gin.Context) - Delete(c *gin.Context) -} - -type GenericLogController struct{} - -// GetLogs handles GET /logs and returns all log records. -func (l *GenericLogController) GetAll(c *gin.Context) { - var logs []models.Log - // Preload the Visibility association - if err := database.DB.Preload("Visibility").Find(&logs).Error; err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Error fetching logs: " + err.Error()}) - return - } - c.JSON(http.StatusOK, logs) -} - -// GetLog handles GET /logs/:id and returns a single log record. -func (l *GenericLogController) GetOne(c *gin.Context) { - idParam := c.Param("id") - id, err := strconv.Atoi(idParam) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid log ID"}) - return - } - - var logEntry models.Log - if err := database.DB.Preload("Visibility").First(&logEntry, id).Error; err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) - return - } - c.JSON(http.StatusOK, logEntry) -} - -// CreateLog handles POST /logs and creates a new log record. -func (l *GenericLogController) Create(c *gin.Context) { - var input models.Log - if err := c.ShouldBindJSON(&input); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - // For safety, you might want to assign defaults (for example, date) if not provided. - if input.Date.IsZero() { - input.Date = time.Now() - } - - newLog := models.Log{ - Name: input.Name, - Notes: input.Notes, - LogType: input.LogType, - Date: input.Date, - Duration: input.Duration, - VisibiltyID: input.VisibiltyID, - } - - if err := database.DB.Create(&newLog).Error; err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create log: " + err.Error()}) - return - } - - // Optionally preload visibility before returning. - database.DB.Preload("Visibility").First(&newLog, newLog.ID) - c.JSON(http.StatusCreated, newLog) -} - -// UpdateLog handles PUT /logs/:id and updates an existing log record. -func (l *GenericLogController) Update(c *gin.Context) { - idParam := c.Param("id") - id, err := strconv.Atoi(idParam) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid log ID"}) - return - } - - var existing models.Log - if err := database.DB.First(&existing, id).Error; err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) - return - } - - var input models.Log - if err := c.ShouldBindJSON(&input); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) - return - } - - updated := models.Log{ - Name: input.Name, - Notes: input.Notes, - LogType: input.LogType, - Date: input.Date, - Duration: input.Duration, - VisibiltyID: input.VisibiltyID, - } - - if err := database.DB.Model(&existing).Updates(updated).Error; err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update log: " + err.Error()}) - return - } - - database.DB.Preload("Visibility").First(&existing, id) - c.JSON(http.StatusOK, existing) -} - -// DeleteLog handles DELETE /logs/:id and deletes a log record. -func (l *GenericLogController) Delete(c *gin.Context) { - idParam := c.Param("id") - id, err := strconv.Atoi(idParam) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid log ID"}) - return - } - - var logEntry models.Log - if err := database.DB.First(&logEntry, id).Error; err != nil { - c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) - return - } - - if err := database.DB.Delete(&logEntry).Error; err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete log: " + err.Error()}) - return - } - c.JSON(http.StatusOK, gin.H{"message": "Log deleted successfully"}) -} diff --git a/wagfarm-api/database/db.go b/wagfarm-api/database/db.go index dc47c61..df7fdb2 100644 --- a/wagfarm-api/database/db.go +++ b/wagfarm-api/database/db.go @@ -8,6 +8,7 @@ import ( "gorm.io/driver/mysql" "gorm.io/gorm" + "gorm.io/gorm/clause" ) var DB *gorm.DB @@ -37,7 +38,7 @@ func Connect() error { func Migrate() error { var err error err = DB.AutoMigrate(slices.Concat( - models.LogModels, models.AssetModels, models.TaxonomyModels)) + log.Models, asset.Models, taxonomy.Models)) if err != nil { return fmt.Errorf("auto migration failed: %w", err) } @@ -49,3 +50,7 @@ func Migrate() error { return nil } + +func Preload() *gorm.DB { + return DB.Preload(clause.Associations) +} diff --git a/wagfarm-api/controllers/logs/seedinglog.go b/wagfarm-api/generic/controller.go similarity index 51% rename from wagfarm-api/controllers/logs/seedinglog.go rename to wagfarm-api/generic/controller.go index d1574e3..be999bd 100644 --- a/wagfarm-api/controllers/logs/seedinglog.go +++ b/wagfarm-api/generic/controller.go @@ -1,24 +1,46 @@ -package logs +package generic import ( "net/http" "strconv" - "time" "wagfarm-api/database" - "wagfarm-api/models" "github.com/gin-gonic/gin" ) -type SeedingLogController struct { - GenericLogController +type RController struct { + GetAll func(*gin.Context) + GetOne func(*gin.Context) +} + +func DefaultRController[T Model]() RController { + return RController{ + GetAll: GetAll[T], + GetOne: GetOne[T], + } +} + +type CRUDController struct { + RController + Create func(*gin.Context) + Update func(*gin.Context) + Delete func(*gin.Context) +} + +func DefaultCRUDController[T Model]() CRUDController { + return CRUDController{ + RController: DefaultRController[T](), + Create: Create[T], + Update: Update[T], + Delete: Delete[T], + } } // GetLogs handles GET /logs and returns all log records. -func (l *SeedingLogController) GetAll(c *gin.Context) { - var logs []models.SeedingLog - // Preload the Visibility association - if err := database.DB.Preload("Log").Find(&logs).Error; err != nil { +func GetAll[T Model](c *gin.Context) { + var logs []T + + if err := database.Preload().Find(&logs).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Error fetching logs: " + err.Error()}) return } @@ -26,7 +48,7 @@ func (l *SeedingLogController) GetAll(c *gin.Context) { } // GetLog handles GET /logs/:id and returns a single log record. -func (l *SeedingLogController) GetOne(c *gin.Context) { +func GetOne[T Model](c *gin.Context) { idParam := c.Param("id") id, err := strconv.Atoi(idParam) if err != nil { @@ -34,48 +56,33 @@ func (l *SeedingLogController) GetOne(c *gin.Context) { return } - var logEntry models.Log - if err := database.DB.Preload("Visibility").First(&logEntry, id).Error; err != nil { + var log T + if err := database.Preload().First(&log, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) return } - c.JSON(http.StatusOK, logEntry) + c.JSON(http.StatusOK, log) } // CreateLog handles POST /logs and creates a new log record. -func (l *SeedingLogController) Create(c *gin.Context) { - var input models.Log - if err := c.ShouldBindJSON(&input); err != nil { +func Create[T Model](c *gin.Context) { + var log T + if err := c.ShouldBindJSON(&log); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - - // For safety, you might want to assign defaults (for example, date) if not provided. - if input.Date.IsZero() { - input.Date = time.Now() - } - - newLog := models.Log{ - Name: input.Name, - Notes: input.Notes, - LogType: input.LogType, - Date: input.Date, - Duration: input.Duration, - VisibiltyID: input.VisibiltyID, - } - - if err := database.DB.Create(&newLog).Error; err != nil { + if err := database.DB.Create(&log).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create log: " + err.Error()}) return } // Optionally preload visibility before returning. - database.DB.Preload("Visibility").First(&newLog, newLog.ID) - c.JSON(http.StatusCreated, newLog) + database.Preload().First(&log, log.GetID()) + c.JSON(http.StatusCreated, log) } // UpdateLog handles PUT /logs/:id and updates an existing log record. -func (l *SeedingLogController) Update(c *gin.Context) { +func Update[T Model](c *gin.Context) { idParam := c.Param("id") id, err := strconv.Atoi(idParam) if err != nil { @@ -83,38 +90,29 @@ func (l *SeedingLogController) Update(c *gin.Context) { return } - var existing models.Log + var existing T if err := database.DB.First(&existing, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) return } - var input models.Log - if err := c.ShouldBindJSON(&input); err != nil { + var log T + if err := c.ShouldBindJSON(&log); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - updated := models.Log{ - Name: input.Name, - Notes: input.Notes, - LogType: input.LogType, - Date: input.Date, - Duration: input.Duration, - VisibiltyID: input.VisibiltyID, - } - - if err := database.DB.Model(&existing).Updates(updated).Error; err != nil { + if err := database.DB.Model(&existing).Updates(log).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update log: " + err.Error()}) return } - database.DB.Preload("Visibility").First(&existing, id) + database.Preload().First(&existing, log.GetID()) c.JSON(http.StatusOK, existing) } // DeleteLog handles DELETE /logs/:id and deletes a log record. -func (l *SeedingLogController) Delete(c *gin.Context) { +func Delete[T Model](c *gin.Context) { idParam := c.Param("id") id, err := strconv.Atoi(idParam) if err != nil { @@ -122,13 +120,13 @@ func (l *SeedingLogController) Delete(c *gin.Context) { return } - var logEntry models.Log - if err := database.DB.First(&logEntry, id).Error; err != nil { + var log T + if err := database.DB.First(&log, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Log not found"}) return } - if err := database.DB.Delete(&logEntry).Error; err != nil { + if err := database.DB.Delete(&log).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete log: " + err.Error()}) return } diff --git a/wagfarm-api/generic/model.go b/wagfarm-api/generic/model.go new file mode 100644 index 0000000..3d2f12b --- /dev/null +++ b/wagfarm-api/generic/model.go @@ -0,0 +1,5 @@ +package generic + +type Model interface { + GetID() uint +} diff --git a/wagfarm-api/generic/route.go b/wagfarm-api/generic/route.go new file mode 100644 index 0000000..e4af96d --- /dev/null +++ b/wagfarm-api/generic/route.go @@ -0,0 +1,16 @@ +package generic + +import "github.com/gin-gonic/gin" + +func RegisterCRUDRoutes(rg *gin.RouterGroup, l CRUDController) { + rg.GET("/", l.GetAll) + rg.GET("/:id", l.GetOne) + rg.POST("/", l.Create) + rg.PUT("/:id", l.Update) + rg.DELETE("/:id", l.Delete) +} + +func RegisterRRoutes(rg *gin.RouterGroup, l RController) { + rg.GET("/", l.GetAll) + rg.GET("/:id", l.GetOne) +} diff --git a/wagfarm-api/log/base/model.go b/wagfarm-api/log/base/model.go new file mode 100644 index 0000000..d055585 --- /dev/null +++ b/wagfarm-api/log/base/model.go @@ -0,0 +1,31 @@ +package base + +import "time" + +type BaseLog struct { + ID uint `gorm:"primaryKey"` + Name string `gorm:"not null"` + Notes string `gorm:"not null"` + LogType string `gorm:"not null"` + Date time.Time `gorm:"default:CURRENT_TIME"` + Duration float64 `gorm:"not null"` // in hours + VisibiltyID uint `gorm:"not null"` + Visibility taxonomy.Visibility `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` +} + +func (l BaseLog) GetID() uint { return l.ID } + +type ExtendedLog struct { + ID uint `gorm:"primaryKey"` + LogID uint `gorm:"not null"` + BaseLog BaseLog `gorm:"foreignKey:LogID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` +} + +func (l ExtendedLog) GetID() uint { return l.ID } + +type FieldWorkLog struct { + ExtendedLog + WorkedAreaPercentage float64 `gorm:"not null"` + MachineID uint `gorm:"not null"` + Machine asset.Machine `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` +} diff --git a/wagfarm-api/log/base/route.go b/wagfarm-api/log/base/route.go new file mode 100644 index 0000000..4e5e57c --- /dev/null +++ b/wagfarm-api/log/base/route.go @@ -0,0 +1,11 @@ +package base + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg, generic.DefaultCRUDController[BaseLog]()) +} diff --git a/wagfarm-api/log/cropprotection/model.go b/wagfarm-api/log/cropprotection/model.go new file mode 100644 index 0000000..926f479 --- /dev/null +++ b/wagfarm-api/log/cropprotection/model.go @@ -0,0 +1,12 @@ +package cropprotection + +import "wagfarm-api/log/base" + +type CropProtectionLog struct { + base.FieldWorkLog + PesticideID uint `gorm:"not null"` + Pesticide taxonomy.Pesticide `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` + Amount float64 `gorm:"not null"` // in units of the pesticide + PerformedByID uint `gorm:"not null"` + PerformedBy taxonomy.Worker `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` +} diff --git a/wagfarm-api/log/cropprotection/route.go b/wagfarm-api/log/cropprotection/route.go new file mode 100644 index 0000000..914e314 --- /dev/null +++ b/wagfarm-api/log/cropprotection/route.go @@ -0,0 +1,11 @@ +package cropprotection + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/cropprotection"), generic.DefaultCRUDController[CropProtectionLog]()) +} diff --git a/wagfarm-api/log/fertilizing/model.go b/wagfarm-api/log/fertilizing/model.go new file mode 100644 index 0000000..946648f --- /dev/null +++ b/wagfarm-api/log/fertilizing/model.go @@ -0,0 +1,12 @@ +package fertilizing + +import ( + "wagfarm-api/log/base" +) + +type FertilizingLog struct { + base.ExtendedLog + FertilizerID uint `gorm:"not null"` + Fertilizer asset.Fertilizer `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` + Amount float64 `gorm:"not null"` // in units of the fertilizer +} diff --git a/wagfarm-api/log/fertilizing/route.go b/wagfarm-api/log/fertilizing/route.go new file mode 100644 index 0000000..ea6256d --- /dev/null +++ b/wagfarm-api/log/fertilizing/route.go @@ -0,0 +1,11 @@ +package fertilizing + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/fertilizer"), generic.DefaultCRUDController[FertilizingLog]()) +} diff --git a/wagfarm-api/log/harvest/model.go b/wagfarm-api/log/harvest/model.go new file mode 100644 index 0000000..39c6908 --- /dev/null +++ b/wagfarm-api/log/harvest/model.go @@ -0,0 +1,9 @@ +package harvest + +import base "wagfarm-api/log/seeding" + +type HarvestLog struct { + base.FieldWorkLog + Product asset.Product `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` + Amount float64 `gorm:"not null"` // in units of the product +} diff --git a/wagfarm-api/log/harvest/route.go b/wagfarm-api/log/harvest/route.go new file mode 100644 index 0000000..ec6aaff --- /dev/null +++ b/wagfarm-api/log/harvest/route.go @@ -0,0 +1,11 @@ +package harvest + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/harvest"), generic.DefaultCRUDController[HarvestLog]()) +} diff --git a/wagfarm-api/log/seeding/model.go b/wagfarm-api/log/seeding/model.go new file mode 100644 index 0000000..31fa698 --- /dev/null +++ b/wagfarm-api/log/seeding/model.go @@ -0,0 +1,14 @@ +package seeding + +import "wagfarm-api/log/base" + +type SeedingLog struct { + base.FieldWorkLog + SeedID uint `gorm:"not null"` + Seed asset.Seed `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` + TechniqueID uint `gorm:"not null"` + Technique taxonomy.SeedingTechnique `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` + Amount float64 `gorm:"not null"` // in units/ha + ConditionsID uint `gorm:"not null"` + Conditions taxonomy.SeedingCondition `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` +} diff --git a/wagfarm-api/log/seeding/route.go b/wagfarm-api/log/seeding/route.go new file mode 100644 index 0000000..d328d1d --- /dev/null +++ b/wagfarm-api/log/seeding/route.go @@ -0,0 +1,11 @@ +package seeding + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seeding"), generic.DefaultCRUDController[SeedingLog]()) +} diff --git a/wagfarm-api/main.go b/wagfarm-api/main.go index 665cb11..e3ad232 100644 --- a/wagfarm-api/main.go +++ b/wagfarm-api/main.go @@ -4,7 +4,6 @@ import ( "log" "os" "wagfarm-api/database" - "wagfarm-api/routes" "github.com/gin-gonic/gin" ) @@ -26,6 +25,10 @@ func initLogging() { gin.DefaultWriter = f // capture Gin logs too } +func RegisterRoutes(r *gin.Engine) { + +} + func main() { initLogging() @@ -44,7 +47,7 @@ func main() { log.Println("Database migrated successfully!") r := gin.Default() - routes.RegisterRoutes(r) + RegisterRoutes(r) if err := r.Run(":8080"); err != nil { log.Fatalf("Failed to run server: %v", err) diff --git a/wagfarm-api/models/assets.go b/wagfarm-api/models/assets.go deleted file mode 100644 index c81dca5..0000000 --- a/wagfarm-api/models/assets.go +++ /dev/null @@ -1,98 +0,0 @@ -package models - -var AssetModels = []interface{}{ - &Land{}, - &Plant{}, - &Machine{}, - &Seed{}, - &Fertilizer{}, - &FertilizerIngredient{}, - &Pesticide{}, - &Product{}, -} - -type _Asset struct { - ID uint `gorm:"primaryKey` - Name string `gorm:"not null"` - Notes string -} - -type Land struct { - _Asset - FID string `gorm:"not null"` - IsWaterProtectionArea bool `gorm:"not null"` - IsRedArea bool `gorm:"not null"` - Area float64 `gorm:"not null"` -} - -type Plant struct { - _Asset - LandId uint `gorm:"not null"` - Land Land `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - CropID uint `gorm:"not null"` - Crop Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - CoverCropID uint `gorm:"not null"` - CoverCrop Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - Year uint `gorm:"not null"` - AreaPercentage float64 `gorm:"not null"` -} -type _Resource struct { - _Asset - UnitID uint `gorm:"not null"` - Unit Unit `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - Cost decimal.Decimal `gorm:"not null; type:decimal(10,2);"` // in euro/unit -} - -type Machine struct { - _Resource -} - -type _BoughtResource struct { - _Resource - BuyDate Datetime.Time `gorm:"type:date;default:CURRENT_DATE"` - BoughtFromID uint `gorm:"not null"` - BoughtFrom Seller `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} - -type _SoldResource struct { - _Resource - SaleDate Datetime.Time `gorm:"type:date;default:CURRENT_DATE"` - SoldToID uint `gorm:"not null"` - SoldTo Customer `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} - -type Seed struct { - _BoughtResource - SeedTypeID uint `gorm:"not null"` - SeedType SeedType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} - -type Fertilizer struct { - _Asset - _BoughtResource - FertilizerTypeID uint `gorm:"not null"` - FertilizerType FertilizerType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` - // Association to the ingredients. This represents the composition. - Ingredients []FertilizerIngredient `gorm:"not null; many2many:fertilizer_ingredient"` -} - -type FertilizerIngredient struct { - FertilizerAssetID uint `gorm:"primaryKey"` // foreign key to the fertilizer asset - IngredientID uint `gorm:"primaryKey"` // foreign key to the ingredient - Amount float64 `gorm:"not null"` // amount of the ingredient - - // Preload the ingredient details if needed. - Ingredient Ingredient `gorm:"not null"` -} - -type Pesticide struct { - _BoughtResource - PesticideTypeID uint `gorm:"not null"` - PesticideType PesticideType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} - -type Product struct { - _SoldResource - ProductTypeID uint `gorm:"not null"` - ProductType ProductType `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} diff --git a/wagfarm-api/models/logs.go b/wagfarm-api/models/logs.go deleted file mode 100644 index 9bb0d69..0000000 --- a/wagfarm-api/models/logs.go +++ /dev/null @@ -1,67 +0,0 @@ -package models - -var LogModels = []interface{}{ - &Log{}, - &SeedingLog{}, - &FertilizingLog{}, - &CropProtectionLog{}, - &HarvestLog{}, -} - -type Log struct { - ID uint `gorm:"primaryKey"` - Name string `gorm:"not null"` - Notes string `gorm:"not null"` - LogType string `gorm:"not null"` - Date Datetime.Time `gorm:"type:date;default:CURRENT_DATE"not null` - Duration float64 `gorm:"not null"` // in hours - VisibiltyID uint `gorm:"not null"` - Visibility Visibility `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` -} - -type _LogMetadata struct { - ID uint `gorm:"primaryKey"` - LogID uint `gorm:"not null"` - Log Log `gorm:"foreignKey:LogID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` -} - -type _FieldWorkLog struct { - _LogMetadata - WorkedAreaPercentage float64 `gorm:"not null"` - MachineID uint `gorm:"not null"` - Machine Machine `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` -} - -type SeedingLog struct { - _FieldWorkLog - SeedID uint `gorm:"not null"` - Seed Seed `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` - TechniqueID uint `gorm:"not null"` - Technique SeedingTechnique `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` - Amount float64 `gorm:"not null"` // in units/ha - ConditionsID uint `gorm:"not null"` - Conditions SeedingCondition `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` -} - -type FertilizingLog struct { - _FieldWorkLog - FertilizerID uint `gorm:"not null"` - Fertilizer Fertilizer `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` - Amount float64 `gorm:"not null"` // in units of the fertilizer -} - -type CropProtectionLog struct { - _FieldWorkLog - PesticideID uint `gorm:"not null"` - Pesticide Pesticide `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` - Amount float64 `gorm:"not null"` // in units of the pesticide - PerformedByID uint `gorm:"not null"` - PerformedBy Worker `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` -} - -type HarvestLog struct { - _FieldWorkLog - ProductID uint `gorm:"not null"` - Product Product `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;not null"` - Amount float64 `gorm:"not null"` // in units of the product -} diff --git a/wagfarm-api/models/taxonomy.go b/wagfarm-api/models/taxonomy.go deleted file mode 100644 index 9f4cf3c..0000000 --- a/wagfarm-api/models/taxonomy.go +++ /dev/null @@ -1,44 +0,0 @@ -package models - -var TaxonomyModels = []interface{}{ - &Unit{}, - &Visibility{}, - &SeedingTechnique{}, - &SeedingCondition{}, - &Worker{}, - &Crop{}, - &Seller{}, - &Customer{}, - &SeedType{}, - &Ingredient{}, - &FertilizerType{}, - &PesticideType{}, - &ProductType{}, -} - -type _Taxonomy struct { - ID uint `gorm:"primaryKey" json:"id"` - Name string `gorm:"not null;index" json:"name"` // e.g., "kg", "lb" -} - -type Unit struct{ _Taxonomy } -type Visibility struct{ _Taxonomy } -type SeedingTechnique struct{ _Taxonomy } -type SeedingCondition struct{ _Taxonomy } -type Worker struct{ _Taxonomy } -type Crop struct{ _Taxonomy } -type Seller struct{ _Taxonomy } -type Customer struct{ _Taxonomy } -type SeedType struct { - _Taxonomy - CropID uint `gorm:"not null"` - Crop Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` -} -type Ingredient struct { - _Taxonomy - UnitID uint `gorm:"not null"` - Unit Unit `gorm:"not null"` -} -type FertilizerType struct{ _Taxonomy } -type PesticideType struct{ _Taxonomy } -type ProductType struct{ _Taxonomy } diff --git a/wagfarm-api/routes/logs.go b/wagfarm-api/routes/logs.go deleted file mode 100644 index 57b4ce0..0000000 --- a/wagfarm-api/routes/logs.go +++ /dev/null @@ -1,27 +0,0 @@ -package routes - -import ( - "wagfarm-api/controllers/logs" - - "github.com/gin-gonic/gin" -) - -func RegisterLogRoutes(rg *gin.RouterGroup) { - group := rg.Group("/log") - { - RegisterLog(group, &logs.GenericLogController{}) - RegisterLog(group.Group("/seeding"), &logs.SeedingLogController{}) - } -} -} - -func RegisterLog(rg *gin.RouterGroup controller logs.LogController) { - group := rg.Group(routePrefix) - { - group.GET("/", controller.GetAll) - group.GET("/:id", controller.GetOne) - group.POST("/", controller.Create) - group.PUT("/:id", controller.Update) - group.DELETE("/:id", controller.Delete) - } -} diff --git a/wagfarm-api/routes/routes.go b/wagfarm-api/routes/routes.go deleted file mode 100644 index 57b7a54..0000000 --- a/wagfarm-api/routes/routes.go +++ /dev/null @@ -1,13 +0,0 @@ -package routes - -import ( - "github.com/gin-gonic/gin" -) - -func RegisterRoutes(r *gin.Engine) { - // Use API versioning if desired, e.g., v1 - v1 := r.Group("/v1") - { - RegisterLogRoutes(v1) - } -} diff --git a/wagfarm-api/taxonomy/base/model.go b/wagfarm-api/taxonomy/base/model.go new file mode 100644 index 0000000..6e2b8ae --- /dev/null +++ b/wagfarm-api/taxonomy/base/model.go @@ -0,0 +1,8 @@ +package base + +type Taxonomy struct { + ID uint `gorm:"primaryKey" json:"id"` + Name string `gorm:"not null;index" json:"name"` // e.g., "kg", "lb" +} + +func (t Taxonomy) GetID() uint { return t.ID } diff --git a/wagfarm-api/taxonomy/crop/model.go b/wagfarm-api/taxonomy/crop/model.go new file mode 100644 index 0000000..67199e3 --- /dev/null +++ b/wagfarm-api/taxonomy/crop/model.go @@ -0,0 +1,5 @@ +package crop + +import "wagfarm-api/taxonomy/base" + +type Crop struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/crop/route.go b/wagfarm-api/taxonomy/crop/route.go new file mode 100644 index 0000000..355fa89 --- /dev/null +++ b/wagfarm-api/taxonomy/crop/route.go @@ -0,0 +1,11 @@ +package crop + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/crop"), generic.DefaultCRUDController[Crop]()) +} diff --git a/wagfarm-api/taxonomy/customer/model.go b/wagfarm-api/taxonomy/customer/model.go new file mode 100644 index 0000000..a58f2ce --- /dev/null +++ b/wagfarm-api/taxonomy/customer/model.go @@ -0,0 +1,5 @@ +package customer + +import "wagfarm-api/taxonomy/base" + +type Customer struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/customer/route.go b/wagfarm-api/taxonomy/customer/route.go new file mode 100644 index 0000000..30d66b6 --- /dev/null +++ b/wagfarm-api/taxonomy/customer/route.go @@ -0,0 +1,11 @@ +package customer + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/customer"), generic.DefaultCRUDController[Customer]()) +} diff --git a/wagfarm-api/taxonomy/fertilizertype/model.go b/wagfarm-api/taxonomy/fertilizertype/model.go new file mode 100644 index 0000000..c4dbfb0 --- /dev/null +++ b/wagfarm-api/taxonomy/fertilizertype/model.go @@ -0,0 +1,5 @@ +package fertilizertype + +import "wagfarm-api/taxonomy/base" + +type FertilizerType struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/fertilizertype/route.go b/wagfarm-api/taxonomy/fertilizertype/route.go new file mode 100644 index 0000000..0f3cec9 --- /dev/null +++ b/wagfarm-api/taxonomy/fertilizertype/route.go @@ -0,0 +1,11 @@ +package fertilizertype + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/fertilizertype"), generic.DefaultCRUDController[FertilizerType]()) +} diff --git a/wagfarm-api/taxonomy/ingredient/model.go b/wagfarm-api/taxonomy/ingredient/model.go new file mode 100644 index 0000000..2758f3d --- /dev/null +++ b/wagfarm-api/taxonomy/ingredient/model.go @@ -0,0 +1,12 @@ +package ingredient + +import ( + "wagfarm-api/taxonomy/base" + "wagfarm-api/taxonomy/unit" +) + +type Ingredient struct { + base.Taxonomy + UnitID uint `gorm:"not null"` + Unit unit.Unit `gorm:"not null"` +} diff --git a/wagfarm-api/taxonomy/ingredient/route.go b/wagfarm-api/taxonomy/ingredient/route.go new file mode 100644 index 0000000..fe4a91f --- /dev/null +++ b/wagfarm-api/taxonomy/ingredient/route.go @@ -0,0 +1,11 @@ +package ingredient + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/ingredient"), generic.DefaultCRUDController[Ingredient]()) +} diff --git a/wagfarm-api/taxonomy/pesticidetype/model.go b/wagfarm-api/taxonomy/pesticidetype/model.go new file mode 100644 index 0000000..e834c9f --- /dev/null +++ b/wagfarm-api/taxonomy/pesticidetype/model.go @@ -0,0 +1,5 @@ +package pesticidetype + +import "wagfarm-api/taxonomy/base" + +type PesticideType struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/pesticidetype/route.go b/wagfarm-api/taxonomy/pesticidetype/route.go new file mode 100644 index 0000000..2af1dc1 --- /dev/null +++ b/wagfarm-api/taxonomy/pesticidetype/route.go @@ -0,0 +1,11 @@ +package pesticidetype + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/pesticidetype"), generic.DefaultCRUDController[PesticideType]()) +} diff --git a/wagfarm-api/taxonomy/producttype/model.go b/wagfarm-api/taxonomy/producttype/model.go new file mode 100644 index 0000000..22f5b15 --- /dev/null +++ b/wagfarm-api/taxonomy/producttype/model.go @@ -0,0 +1,5 @@ +package producttype + +import "wagfarm-api/taxonomy/base" + +type ProductType struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/producttype/route.go b/wagfarm-api/taxonomy/producttype/route.go new file mode 100644 index 0000000..d036834 --- /dev/null +++ b/wagfarm-api/taxonomy/producttype/route.go @@ -0,0 +1,11 @@ +package producttype + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/producttype"), generic.DefaultCRUDController[ProductType]()) +} diff --git a/wagfarm-api/taxonomy/seedingcondition/model.go b/wagfarm-api/taxonomy/seedingcondition/model.go new file mode 100644 index 0000000..2b3c891 --- /dev/null +++ b/wagfarm-api/taxonomy/seedingcondition/model.go @@ -0,0 +1,5 @@ +package seedingcondition + +import "wagfarm-api/taxonomy/base" + +type SeedingCondition struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/seedingcondition/route.go b/wagfarm-api/taxonomy/seedingcondition/route.go new file mode 100644 index 0000000..b6e5173 --- /dev/null +++ b/wagfarm-api/taxonomy/seedingcondition/route.go @@ -0,0 +1,11 @@ +package seedingcondition + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seedingcondition"), generic.DefaultCRUDController[SeedingCondition]()) +} diff --git a/wagfarm-api/taxonomy/seedingtechnique/model.go b/wagfarm-api/taxonomy/seedingtechnique/model.go new file mode 100644 index 0000000..2556abe --- /dev/null +++ b/wagfarm-api/taxonomy/seedingtechnique/model.go @@ -0,0 +1,5 @@ +package seedingtechnique + +import "wagfarm-api/taxonomy/base" + +type SeedingTechnique struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/seedingtechnique/route.go b/wagfarm-api/taxonomy/seedingtechnique/route.go new file mode 100644 index 0000000..fab0bb6 --- /dev/null +++ b/wagfarm-api/taxonomy/seedingtechnique/route.go @@ -0,0 +1,11 @@ +package seedingtechnique + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seedingtechnique"), generic.DefaultCRUDController[SeedingTechnique]()) +} diff --git a/wagfarm-api/taxonomy/seedtype/model.go b/wagfarm-api/taxonomy/seedtype/model.go new file mode 100644 index 0000000..324d2b5 --- /dev/null +++ b/wagfarm-api/taxonomy/seedtype/model.go @@ -0,0 +1,12 @@ +package seedtype + +import ( + "wagfarm-api/taxonomy/base" + "wagfarm-api/taxonomy/crop" +) + +type SeedType struct { + base.Taxonomy + CropID uint `gorm:"not null"` + Crop crop.Crop `gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;"` +} diff --git a/wagfarm-api/taxonomy/seedtype/route.go b/wagfarm-api/taxonomy/seedtype/route.go new file mode 100644 index 0000000..1701c74 --- /dev/null +++ b/wagfarm-api/taxonomy/seedtype/route.go @@ -0,0 +1,11 @@ +package seedtype + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seedtype"), generic.DefaultCRUDController[SeedType]()) +} diff --git a/wagfarm-api/taxonomy/seller/model.go b/wagfarm-api/taxonomy/seller/model.go new file mode 100644 index 0000000..4954dcf --- /dev/null +++ b/wagfarm-api/taxonomy/seller/model.go @@ -0,0 +1,5 @@ +package seller + +import "wagfarm-api/taxonomy/base" + +type Seller struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/seller/route.go b/wagfarm-api/taxonomy/seller/route.go new file mode 100644 index 0000000..bec615e --- /dev/null +++ b/wagfarm-api/taxonomy/seller/route.go @@ -0,0 +1,11 @@ +package seller + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/seller"), generic.DefaultCRUDController[Seller]()) +} diff --git a/wagfarm-api/taxonomy/unit/model.go b/wagfarm-api/taxonomy/unit/model.go new file mode 100644 index 0000000..3a4811b --- /dev/null +++ b/wagfarm-api/taxonomy/unit/model.go @@ -0,0 +1,5 @@ +package unit + +import "wagfarm-api/taxonomy/base" + +type Unit struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/unit/route.go b/wagfarm-api/taxonomy/unit/route.go new file mode 100644 index 0000000..70c8c09 --- /dev/null +++ b/wagfarm-api/taxonomy/unit/route.go @@ -0,0 +1,11 @@ +package unit + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/unit"), generic.DefaultCRUDController[Unit]()) +} diff --git a/wagfarm-api/taxonomy/visibility/model.go b/wagfarm-api/taxonomy/visibility/model.go new file mode 100644 index 0000000..c027db0 --- /dev/null +++ b/wagfarm-api/taxonomy/visibility/model.go @@ -0,0 +1,5 @@ +package visibility + +import "wagfarm-api/taxonomy/base" + +type Visibility struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/visibility/route.go b/wagfarm-api/taxonomy/visibility/route.go new file mode 100644 index 0000000..b44fb01 --- /dev/null +++ b/wagfarm-api/taxonomy/visibility/route.go @@ -0,0 +1,11 @@ +package visibility + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/visibility"), generic.DefaultCRUDController[Visibility]()) +} diff --git a/wagfarm-api/taxonomy/worker/model.go b/wagfarm-api/taxonomy/worker/model.go new file mode 100644 index 0000000..b7245e6 --- /dev/null +++ b/wagfarm-api/taxonomy/worker/model.go @@ -0,0 +1,5 @@ +package worker + +import "wagfarm-api/taxonomy/base" + +type Worker struct{ base.Taxonomy } diff --git a/wagfarm-api/taxonomy/worker/route.go b/wagfarm-api/taxonomy/worker/route.go new file mode 100644 index 0000000..ed2e158 --- /dev/null +++ b/wagfarm-api/taxonomy/worker/route.go @@ -0,0 +1,11 @@ +package worker + +import ( + "wagfarm-api/generic" + + "github.com/gin-gonic/gin" +) + +func RegisterRoutes(rg *gin.RouterGroup) { + generic.RegisterCRUDRoutes(rg.Group("/worker"), generic.DefaultCRUDController[Worker]()) +}