Update API
This commit is contained in:
parent
b077ef9f06
commit
40705fbf3b
@ -1,20 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
// dependencies
|
||||
}
|
||||
|
||||
func NewHandler() *Handler {
|
||||
return &Handler{}
|
||||
}
|
||||
|
||||
func (h *Handler) HealthCheck(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{
|
||||
"status": "success",
|
||||
"message": "Server is running",
|
||||
})
|
||||
}
|
||||
15
api/routes.go
Normal file
15
api/routes.go
Normal file
@ -0,0 +1,15 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/auth"
|
||||
"BE-MiniERP/modules/inventory"
|
||||
"BE-MiniERP/modules/sales"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func SetupRoutes(app *fiber.App) {
|
||||
auth.RegisterRoutes(app.Group("/auth"))
|
||||
inventory.RegisterRoutes(app.Group("/inventory"))
|
||||
sales.RegisterRoutes(app.Group("/sales"))
|
||||
}
|
||||
26
cmd/main.go
Normal file
26
cmd/main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"BE-MiniERP/api"
|
||||
"BE-MiniERP/database" // pastikan ini sesuai dengan module di go.mod
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Koneksi database
|
||||
database.Connect()
|
||||
|
||||
// Inisialisasi Fiber
|
||||
app := fiber.New()
|
||||
|
||||
// Setup semua routing dari API
|
||||
api.SetupRoutes(app)
|
||||
|
||||
// Jalankan server
|
||||
if err := app.Listen(":3000"); err != nil {
|
||||
log.Fatal("Gagal menjalankan server:", err)
|
||||
}
|
||||
}
|
||||
15
config/config.go
Normal file
15
config/config.go
Normal file
@ -0,0 +1,15 @@
|
||||
package config
|
||||
|
||||
import "os"
|
||||
|
||||
type Config struct {
|
||||
DBUrl string
|
||||
JWTSecret string
|
||||
}
|
||||
|
||||
func GetConfig() Config {
|
||||
return Config{
|
||||
DBUrl: os.Getenv("DB_URL"),
|
||||
JWTSecret: os.Getenv("JWT_SECRET"),
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,8 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@ -8,16 +10,10 @@ import (
|
||||
var DB *gorm.DB
|
||||
|
||||
func Connect() {
|
||||
dsn := "host=10.5.50.9 user=probindo password=probindo dbname=minierp port=5432 sslmode=disable TimeZone=Asia/Jakarta"
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
dsn := "host=10.5.50.9 user=probindo password=Pr08ind0 dbname=erp port=5432 sslmode=disable"
|
||||
var err error
|
||||
DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
log.Fatal("Failed to connect to DB:", err)
|
||||
}
|
||||
|
||||
DB = db
|
||||
}
|
||||
|
||||
func AutoMigrate() {
|
||||
// Tambahkan model-model di sini untuk auto migration
|
||||
// DB.AutoMigrate(&models.User{}, &models.Product{})
|
||||
}
|
||||
|
||||
3
go.mod
3
go.mod
@ -1,4 +1,4 @@
|
||||
module fiber-demo
|
||||
module BE-MiniERP
|
||||
|
||||
go 1.24.4
|
||||
|
||||
@ -6,6 +6,7 @@ require github.com/gofiber/fiber/v2 v2.52.8
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@ -3,6 +3,8 @@ github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer5
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gofiber/fiber/v2 v2.52.8 h1:xl4jJQ0BV5EJTA2aWiKw/VddRpHrKeZLF0QPUxqn0x4=
|
||||
github.com/gofiber/fiber/v2 v2.52.8/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
|
||||
50
main.go
50
main.go
@ -1,50 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fiber-demo/database"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func main() {
|
||||
database.Connect()
|
||||
database.AutoMigrate()
|
||||
// Inisialisasi aplikasi Fiber
|
||||
app := fiber.New()
|
||||
|
||||
// Route untuk halaman utama
|
||||
app.Get("/", func(c *fiber.Ctx) error {
|
||||
return c.SendString("Hello, World! 👋")
|
||||
})
|
||||
|
||||
// Route untuk GET /api/greeting
|
||||
app.Get("/api/greeting", func(c *fiber.Ctx) error {
|
||||
return c.JSON(fiber.Map{
|
||||
"message": "Hello from Fiber API!",
|
||||
"status": "success",
|
||||
})
|
||||
})
|
||||
|
||||
// Route untuk POST /api/greeting
|
||||
app.Post("/api/greeting", func(c *fiber.Ctx) error {
|
||||
type Request struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
var body Request
|
||||
if err := c.BodyParser(&body); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
||||
"error": "Cannot parse JSON",
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"message": "Hello, " + body.Name + "!",
|
||||
"status": "success",
|
||||
})
|
||||
})
|
||||
|
||||
// Menjalankan server di port 3000
|
||||
log.Fatal(app.Listen(":3000"))
|
||||
}
|
||||
30
middlewares/jwt.go
Normal file
30
middlewares/jwt.go
Normal file
@ -0,0 +1,30 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"BE-MiniERP/config"
|
||||
"strings"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
func JWTProtected() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
authHeader := c.Get("Authorization")
|
||||
if authHeader == "" {
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
}
|
||||
|
||||
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(config.GetConfig().JWTSecret), nil
|
||||
})
|
||||
|
||||
if err != nil || !token.Valid {
|
||||
return c.SendStatus(fiber.StatusUnauthorized)
|
||||
}
|
||||
|
||||
c.Locals("user", token.Claims)
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
18
middlewares/logger.go
Normal file
18
middlewares/logger.go
Normal file
@ -0,0 +1,18 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func Logger() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
start := time.Now()
|
||||
err := c.Next()
|
||||
duration := time.Since(start)
|
||||
fmt.Printf("[%s] %s %s (%v)\n", c.Method(), c.Path(), c.IP(), duration)
|
||||
return err
|
||||
}
|
||||
}
|
||||
72
modules/auth/handler/auth_handler.go
Normal file
72
modules/auth/handler/auth_handler.go
Normal file
@ -0,0 +1,72 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/auth/models"
|
||||
"BE-MiniERP/modules/auth/repository"
|
||||
"BE-MiniERP/modules/auth/service"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type AuthHandler struct {
|
||||
Repo *repository.UserRepository
|
||||
}
|
||||
|
||||
func NewAuthHandler() *AuthHandler {
|
||||
return &AuthHandler{
|
||||
Repo: repository.NewUserRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *AuthHandler) Register(c *fiber.Ctx) error {
|
||||
var input struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input"})
|
||||
}
|
||||
|
||||
hash, err := service.HashPassword(input.Password)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to hash password"})
|
||||
}
|
||||
|
||||
user := &models.User{
|
||||
Username: input.Username,
|
||||
PasswordHash: hash,
|
||||
Role: input.Role,
|
||||
}
|
||||
|
||||
if err := h.Repo.Create(user); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to create user"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"message": "user registered"})
|
||||
}
|
||||
|
||||
func (h *AuthHandler) Login(c *fiber.Ctx) error {
|
||||
var input struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "invalid input"})
|
||||
}
|
||||
|
||||
user, err := h.Repo.FindByUsername(input.Username)
|
||||
if err != nil || !service.CheckPasswordHash(input.Password, user.PasswordHash) {
|
||||
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"error": "invalid credentials"})
|
||||
}
|
||||
|
||||
token, err := service.GenerateJWT(user.ID, user.Role)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": "failed to generate token"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"token": token, "role": user.Role})
|
||||
}
|
||||
12
modules/auth/models/user.go
Normal file
12
modules/auth/models/user.go
Normal file
@ -0,0 +1,12 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type User struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"unique" json:"username"`
|
||||
PasswordHash string `json:"-"`
|
||||
Role string `json:"role"` // admin, sales, warehouse, etc
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
25
modules/auth/repository/user_repo.go
Normal file
25
modules/auth/repository/user_repo.go
Normal file
@ -0,0 +1,25 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/auth/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type UserRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewUserRepository(db *gorm.DB) *UserRepository {
|
||||
return &UserRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *UserRepository) Create(user *models.User) error {
|
||||
return r.DB.Create(user).Error
|
||||
}
|
||||
|
||||
func (r *UserRepository) FindByUsername(username string) (*models.User, error) {
|
||||
var user models.User
|
||||
result := r.DB.Where("username = ?", username).First(&user)
|
||||
return &user, result.Error
|
||||
}
|
||||
13
modules/auth/routes.go
Normal file
13
modules/auth/routes.go
Normal file
@ -0,0 +1,13 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/auth/handler"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RegisterRoutes(r fiber.Router) {
|
||||
h := handler.NewAuthHandler()
|
||||
r.Post("/register", h.Register)
|
||||
r.Post("/login", h.Login)
|
||||
}
|
||||
15
modules/auth/service/auth_logic.go
Normal file
15
modules/auth/service/auth_logic.go
Normal file
@ -0,0 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func HashPassword(password string) (string, error) {
|
||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||
return string(bytes), err
|
||||
}
|
||||
|
||||
func CheckPasswordHash(password, hash string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
27
modules/auth/service/jwt.go
Normal file
27
modules/auth/service/jwt.go
Normal file
@ -0,0 +1,27 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
var jwtKey = []byte("supersecret") // sebaiknya dari env
|
||||
|
||||
type Claims struct {
|
||||
UserID uint `json:"user_id"`
|
||||
Role string `json:"role"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func GenerateJWT(userID uint, role string) (string, error) {
|
||||
claims := &Claims{
|
||||
UserID: userID,
|
||||
Role: role,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(24 * time.Hour)),
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString(jwtKey)
|
||||
}
|
||||
59
modules/inventory/handler/collection_handler.go
Normal file
59
modules/inventory/handler/collection_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type CollectionHandler struct {
|
||||
Repo *repository.CollectionRepository
|
||||
}
|
||||
|
||||
func NewCollectionHandler() *CollectionHandler {
|
||||
return &CollectionHandler{
|
||||
Repo: repository.NewCollectionRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *CollectionHandler) GetAll(c *fiber.Ctx) error {
|
||||
collections, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch collections"})
|
||||
}
|
||||
return c.JSON(collections)
|
||||
}
|
||||
|
||||
func (h *CollectionHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Collection
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create collection"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *CollectionHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Collection
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update collection"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Collection updated"})
|
||||
}
|
||||
|
||||
func (h *CollectionHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete collection"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Collection deleted"})
|
||||
}
|
||||
59
modules/inventory/handler/colour_handler.go
Normal file
59
modules/inventory/handler/colour_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ColourHandler struct {
|
||||
Repo *repository.ColourRepository
|
||||
}
|
||||
|
||||
func NewColourHandler() *ColourHandler {
|
||||
return &ColourHandler{
|
||||
Repo: repository.NewColourRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ColourHandler) GetAll(c *fiber.Ctx) error {
|
||||
colours, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch colours"})
|
||||
}
|
||||
return c.JSON(colours)
|
||||
}
|
||||
|
||||
func (h *ColourHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Colour
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create colour"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *ColourHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Colour
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update colour"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Colour updated"})
|
||||
}
|
||||
|
||||
func (h *ColourHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete colour"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Colour deleted"})
|
||||
}
|
||||
59
modules/inventory/handler/product_category_handler.go
Normal file
59
modules/inventory/handler/product_category_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type CategoryHandler struct {
|
||||
Repo *repository.CategoryRepository
|
||||
}
|
||||
|
||||
func NewCategoryHandler() *CategoryHandler {
|
||||
return &CategoryHandler{
|
||||
Repo: repository.NewCategoryRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) GetAll(c *fiber.Ctx) error {
|
||||
categories, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch categories"})
|
||||
}
|
||||
return c.JSON(categories)
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.ProductCategory
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create category"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.ProductCategory
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update category"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Category updated"})
|
||||
}
|
||||
|
||||
func (h *CategoryHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete category"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Category deleted"})
|
||||
}
|
||||
47
modules/inventory/handler/product_component_handler.go
Normal file
47
modules/inventory/handler/product_component_handler.go
Normal file
@ -0,0 +1,47 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ProductComponentHandler struct {
|
||||
Repo *repository.ProductComponentRepository
|
||||
}
|
||||
|
||||
func NewProductComponentHandler() *ProductComponentHandler {
|
||||
return &ProductComponentHandler{
|
||||
Repo: repository.NewProductComponentRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ProductComponentHandler) GetAll(c *fiber.Ctx) error {
|
||||
result, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch components"})
|
||||
}
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
func (h *ProductComponentHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.ProductComponent
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create component entry"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *ProductComponentHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete component entry"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted successfully"})
|
||||
}
|
||||
59
modules/inventory/handler/product_handler.go
Normal file
59
modules/inventory/handler/product_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ProductHandler struct {
|
||||
Repo *repository.ProductRepository
|
||||
}
|
||||
|
||||
func NewProductHandler() *ProductHandler {
|
||||
return &ProductHandler{
|
||||
Repo: repository.NewProductRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ProductHandler) GetAll(c *fiber.Ctx) error {
|
||||
products, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch products"})
|
||||
}
|
||||
return c.JSON(products)
|
||||
}
|
||||
|
||||
func (h *ProductHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Product
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create product"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *ProductHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Product
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update product"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Product updated"})
|
||||
}
|
||||
|
||||
func (h *ProductHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete product"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Product deleted"})
|
||||
}
|
||||
59
modules/inventory/handler/production_order_handler.go
Normal file
59
modules/inventory/handler/production_order_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type ProductionOrderHandler struct {
|
||||
Repo *repository.ProductionOrderRepository
|
||||
}
|
||||
|
||||
func NewProductionOrderHandler() *ProductionOrderHandler {
|
||||
return &ProductionOrderHandler{
|
||||
Repo: repository.NewProductionOrderRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *ProductionOrderHandler) GetAll(c *fiber.Ctx) error {
|
||||
data, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch production orders"})
|
||||
}
|
||||
return c.JSON(data)
|
||||
}
|
||||
|
||||
func (h *ProductionOrderHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.ProductionOrder
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create production order"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *ProductionOrderHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.ProductionOrder
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update production order"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *ProductionOrderHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete production order"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/inventory/handler/size_handler.go
Normal file
59
modules/inventory/handler/size_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type SizeHandler struct {
|
||||
Repo *repository.SizeRepository
|
||||
}
|
||||
|
||||
func NewSizeHandler() *SizeHandler {
|
||||
return &SizeHandler{
|
||||
Repo: repository.NewSizeRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SizeHandler) GetAll(c *fiber.Ctx) error {
|
||||
sizes, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch sizes"})
|
||||
}
|
||||
return c.JSON(sizes)
|
||||
}
|
||||
|
||||
func (h *SizeHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Size
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create size"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *SizeHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Size
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update size"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Size updated"})
|
||||
}
|
||||
|
||||
func (h *SizeHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete size"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Size deleted"})
|
||||
}
|
||||
40
modules/inventory/handler/stock_movement_handler.go
Normal file
40
modules/inventory/handler/stock_movement_handler.go
Normal file
@ -0,0 +1,40 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type StockMovementHandler struct {
|
||||
Repo *repository.StockMovementRepository
|
||||
}
|
||||
|
||||
func NewStockMovementHandler() *StockMovementHandler {
|
||||
return &StockMovementHandler{
|
||||
Repo: repository.NewStockMovementRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *StockMovementHandler) GetAll(c *fiber.Ctx) error {
|
||||
data, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch stock movements"})
|
||||
}
|
||||
return c.JSON(data)
|
||||
}
|
||||
|
||||
func (h *StockMovementHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.StockMovement
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create stock movement"})
|
||||
}
|
||||
|
||||
return c.JSON(input)
|
||||
}
|
||||
59
modules/inventory/handler/warehouse_handler.go
Normal file
59
modules/inventory/handler/warehouse_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
"BE-MiniERP/modules/inventory/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type WarehouseHandler struct {
|
||||
Repo *repository.WarehouseRepository
|
||||
}
|
||||
|
||||
func NewWarehouseHandler() *WarehouseHandler {
|
||||
return &WarehouseHandler{
|
||||
Repo: repository.NewWarehouseRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *WarehouseHandler) GetAll(c *fiber.Ctx) error {
|
||||
warehouses, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch warehouses"})
|
||||
}
|
||||
return c.JSON(warehouses)
|
||||
}
|
||||
|
||||
func (h *WarehouseHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Warehouse
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create warehouse"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *WarehouseHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Warehouse
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update warehouse"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Warehouse updated"})
|
||||
}
|
||||
|
||||
func (h *WarehouseHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete warehouse"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Warehouse deleted"})
|
||||
}
|
||||
10
modules/inventory/models/collection.go
Normal file
10
modules/inventory/models/collection.go
Normal file
@ -0,0 +1,10 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Collection struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
11
modules/inventory/models/colour.go
Normal file
11
modules/inventory/models/colour.go
Normal file
@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Colour struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Code string `json:"code"` // contoh: HEX (#000000) atau RGB
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
29
modules/inventory/models/product.go
Normal file
29
modules/inventory/models/product.go
Normal file
@ -0,0 +1,29 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Product struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
CategoryID uint `json:"category_id"`
|
||||
Category ProductCategory `gorm:"foreignKey:CategoryID" json:"category"`
|
||||
|
||||
CollectionID uint `json:"collection_id"`
|
||||
Collection Collection `gorm:"foreignKey:CollectionID" json:"collection"`
|
||||
|
||||
ColourID uint `json:"colour_id"`
|
||||
Colour Colour `gorm:"foreignKey:ColourID" json:"colour"`
|
||||
|
||||
SizeID uint `json:"size_id"`
|
||||
Size Size `gorm:"foreignKey:SizeID" json:"size"`
|
||||
|
||||
SKU string `gorm:"not null;unique" json:"sku"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Description string `json:"description"`
|
||||
UnitOfMeasure string `json:"unit_of_measure"`
|
||||
|
||||
IsRawMaterial bool `json:"is_raw_material"`
|
||||
IsFinishedGood bool `json:"is_finished_good"`
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
10
modules/inventory/models/product_category.go
Normal file
10
modules/inventory/models/product_category.go
Normal file
@ -0,0 +1,10 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ProductCategory struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
18
modules/inventory/models/product_component.go
Normal file
18
modules/inventory/models/product_component.go
Normal file
@ -0,0 +1,18 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ProductComponent struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
|
||||
ProductID uint `json:"product_id"` // Produk utama
|
||||
Product Product `gorm:"foreignKey:ProductID" json:"product"`
|
||||
|
||||
ComponenID uint `json:"componen_id"` // Komponen produk
|
||||
Component Product `gorm:"foreignKey:ComponenID" json:"component"`
|
||||
|
||||
Quantity float64 `json:"quantity"`
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
21
modules/inventory/models/production_order.go
Normal file
21
modules/inventory/models/production_order.go
Normal file
@ -0,0 +1,21 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type ProductionOrder struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
|
||||
ProductID uint `json:"product_id"`
|
||||
Product Product `gorm:"foreignKey:ProductID" json:"product"`
|
||||
|
||||
ProductionID string `gorm:"not null;unique" json:"production_id"` // kode batch
|
||||
|
||||
TargetQuantity float64 `json:"target_quantity"`
|
||||
Status string `json:"status"` // contoh: "planned", "in_progress", "done"
|
||||
StartDate time.Time `json:"start_date"`
|
||||
EndDate time.Time `json:"end_date"`
|
||||
Note string `json:"note"`
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
11
modules/inventory/models/size.go
Normal file
11
modules/inventory/models/size.go
Normal file
@ -0,0 +1,11 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Size struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `gorm:"not null" json:"name"` // contoh: S, M, L, XL
|
||||
Description string `json:"description"` // opsional, seperti "Small", "Large"
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
24
modules/inventory/models/stock_movement.go
Normal file
24
modules/inventory/models/stock_movement.go
Normal file
@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type StockMovement struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
|
||||
ProductID uint `json:"product_id"`
|
||||
Product Product `gorm:"foreignKey:ProductID" json:"product"`
|
||||
|
||||
OriginWarehouseID uint `json:"origin_warehouse_id"`
|
||||
OriginWarehouse Warehouse `gorm:"foreignKey:OriginWarehouseID" json:"origin_warehouse"`
|
||||
|
||||
StockType string `json:"stock_type"` // contoh: "in", "out", "transfer"
|
||||
|
||||
DestinationWarehouseID *uint `json:"destination_warehouse_id"`
|
||||
DestinationWarehouse *Warehouse `gorm:"foreignKey:DestinationWarehouseID" json:"destination_warehouse"`
|
||||
|
||||
Date time.Time `json:"date"`
|
||||
Note string `json:"note"`
|
||||
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
15
modules/inventory/models/warehouse.go
Normal file
15
modules/inventory/models/warehouse.go
Normal file
@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Warehouse struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Kode string `gorm:"not null;unique" json:"kode"`
|
||||
Name string `gorm:"not null" json:"name"`
|
||||
Address string `json:"address"`
|
||||
Stackholder string `json:"stackholder"`
|
||||
Number string `json:"number"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
33
modules/inventory/repository/collection_repo.go
Normal file
33
modules/inventory/repository/collection_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CollectionRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewCollectionRepository(db *gorm.DB) *CollectionRepository {
|
||||
return &CollectionRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *CollectionRepository) FindAll() ([]models.Collection, error) {
|
||||
var collections []models.Collection
|
||||
err := r.DB.Find(&collections).Error
|
||||
return collections, err
|
||||
}
|
||||
|
||||
func (r *CollectionRepository) Create(col *models.Collection) error {
|
||||
return r.DB.Create(col).Error
|
||||
}
|
||||
|
||||
func (r *CollectionRepository) Update(id uint, data *models.Collection) error {
|
||||
return r.DB.Model(&models.Collection{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *CollectionRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Collection{}, id).Error
|
||||
}
|
||||
33
modules/inventory/repository/colour__repo.go
Normal file
33
modules/inventory/repository/colour__repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ColourRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewColourRepository(db *gorm.DB) *ColourRepository {
|
||||
return &ColourRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *ColourRepository) FindAll() ([]models.Colour, error) {
|
||||
var colours []models.Colour
|
||||
err := r.DB.Find(&colours).Error
|
||||
return colours, err
|
||||
}
|
||||
|
||||
func (r *ColourRepository) Create(colour *models.Colour) error {
|
||||
return r.DB.Create(colour).Error
|
||||
}
|
||||
|
||||
func (r *ColourRepository) Update(id uint, data *models.Colour) error {
|
||||
return r.DB.Model(&models.Colour{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *ColourRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Colour{}, id).Error
|
||||
}
|
||||
38
modules/inventory/repository/product__repo.go
Normal file
38
modules/inventory/repository/product__repo.go
Normal file
@ -0,0 +1,38 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ProductRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewProductRepository(db *gorm.DB) *ProductRepository {
|
||||
return &ProductRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *ProductRepository) FindAll() ([]models.Product, error) {
|
||||
var products []models.Product
|
||||
err := r.DB.
|
||||
Preload("Category").
|
||||
Preload("Collection").
|
||||
Preload("Colour").
|
||||
Preload("Size").
|
||||
Find(&products).Error
|
||||
return products, err
|
||||
}
|
||||
|
||||
func (r *ProductRepository) Create(product *models.Product) error {
|
||||
return r.DB.Create(product).Error
|
||||
}
|
||||
|
||||
func (r *ProductRepository) Update(id uint, product *models.Product) error {
|
||||
return r.DB.Model(&models.Product{}).Where("id = ?", id).Updates(product).Error
|
||||
}
|
||||
|
||||
func (r *ProductRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Product{}, id).Error
|
||||
}
|
||||
33
modules/inventory/repository/product_category_repo.go
Normal file
33
modules/inventory/repository/product_category_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CategoryRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewCategoryRepository(db *gorm.DB) *CategoryRepository {
|
||||
return &CategoryRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *CategoryRepository) FindAll() ([]models.ProductCategory, error) {
|
||||
var categories []models.ProductCategory
|
||||
err := r.DB.Find(&categories).Error
|
||||
return categories, err
|
||||
}
|
||||
|
||||
func (r *CategoryRepository) Create(cat *models.ProductCategory) error {
|
||||
return r.DB.Create(cat).Error
|
||||
}
|
||||
|
||||
func (r *CategoryRepository) Update(id uint, data *models.ProductCategory) error {
|
||||
return r.DB.Model(&models.ProductCategory{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *CategoryRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.ProductCategory{}, id).Error
|
||||
}
|
||||
32
modules/inventory/repository/product_component__repo.go
Normal file
32
modules/inventory/repository/product_component__repo.go
Normal file
@ -0,0 +1,32 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ProductComponentRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewProductComponentRepository(db *gorm.DB) *ProductComponentRepository {
|
||||
return &ProductComponentRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *ProductComponentRepository) FindAll() ([]models.ProductComponent, error) {
|
||||
var data []models.ProductComponent
|
||||
err := r.DB.
|
||||
Preload("Product").
|
||||
Preload("Component").
|
||||
Find(&data).Error
|
||||
return data, err
|
||||
}
|
||||
|
||||
func (r *ProductComponentRepository) Create(pc *models.ProductComponent) error {
|
||||
return r.DB.Create(pc).Error
|
||||
}
|
||||
|
||||
func (r *ProductComponentRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.ProductComponent{}, id).Error
|
||||
}
|
||||
33
modules/inventory/repository/production_order_repo.go
Normal file
33
modules/inventory/repository/production_order_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type ProductionOrderRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewProductionOrderRepository(db *gorm.DB) *ProductionOrderRepository {
|
||||
return &ProductionOrderRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *ProductionOrderRepository) FindAll() ([]models.ProductionOrder, error) {
|
||||
var orders []models.ProductionOrder
|
||||
err := r.DB.Preload("Product").Find(&orders).Error
|
||||
return orders, err
|
||||
}
|
||||
|
||||
func (r *ProductionOrderRepository) Create(order *models.ProductionOrder) error {
|
||||
return r.DB.Create(order).Error
|
||||
}
|
||||
|
||||
func (r *ProductionOrderRepository) Update(id uint, data *models.ProductionOrder) error {
|
||||
return r.DB.Model(&models.ProductionOrder{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *ProductionOrderRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.ProductionOrder{}, id).Error
|
||||
}
|
||||
33
modules/inventory/repository/size_repo.go
Normal file
33
modules/inventory/repository/size_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SizeRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewSizeRepository(db *gorm.DB) *SizeRepository {
|
||||
return &SizeRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *SizeRepository) FindAll() ([]models.Size, error) {
|
||||
var sizes []models.Size
|
||||
err := r.DB.Find(&sizes).Error
|
||||
return sizes, err
|
||||
}
|
||||
|
||||
func (r *SizeRepository) Create(size *models.Size) error {
|
||||
return r.DB.Create(size).Error
|
||||
}
|
||||
|
||||
func (r *SizeRepository) Update(id uint, data *models.Size) error {
|
||||
return r.DB.Model(&models.Size{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *SizeRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Size{}, id).Error
|
||||
}
|
||||
29
modules/inventory/repository/stock_movement_repo.go
Normal file
29
modules/inventory/repository/stock_movement_repo.go
Normal file
@ -0,0 +1,29 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type StockMovementRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewStockMovementRepository(db *gorm.DB) *StockMovementRepository {
|
||||
return &StockMovementRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *StockMovementRepository) FindAll() ([]models.StockMovement, error) {
|
||||
var movements []models.StockMovement
|
||||
err := r.DB.
|
||||
Preload("Product").
|
||||
Preload("OriginWarehouse").
|
||||
Preload("DestinationWarehouse").
|
||||
Find(&movements).Error
|
||||
return movements, err
|
||||
}
|
||||
|
||||
func (r *StockMovementRepository) Create(movement *models.StockMovement) error {
|
||||
return r.DB.Create(movement).Error
|
||||
}
|
||||
33
modules/inventory/repository/warehouse_repo.go
Normal file
33
modules/inventory/repository/warehouse_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type WarehouseRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewWarehouseRepository(db *gorm.DB) *WarehouseRepository {
|
||||
return &WarehouseRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *WarehouseRepository) FindAll() ([]models.Warehouse, error) {
|
||||
var warehouses []models.Warehouse
|
||||
err := r.DB.Find(&warehouses).Error
|
||||
return warehouses, err
|
||||
}
|
||||
|
||||
func (r *WarehouseRepository) Create(wh *models.Warehouse) error {
|
||||
return r.DB.Create(wh).Error
|
||||
}
|
||||
|
||||
func (r *WarehouseRepository) Update(id uint, wh *models.Warehouse) error {
|
||||
return r.DB.Model(&models.Warehouse{}).Where("id = ?", id).Updates(wh).Error
|
||||
}
|
||||
|
||||
func (r *WarehouseRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Warehouse{}, id).Error
|
||||
}
|
||||
60
modules/inventory/routes.go
Normal file
60
modules/inventory/routes.go
Normal file
@ -0,0 +1,60 @@
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/inventory/handler"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RegisterRoutes(r fiber.Router) {
|
||||
category := handler.NewCategoryHandler()
|
||||
r.Get("/categories", category.GetAll)
|
||||
r.Post("/categories", category.Create)
|
||||
r.Put("/categories/:id", category.Update)
|
||||
r.Delete("/categories/:id", category.Delete)
|
||||
|
||||
collection := handler.NewCollectionHandler()
|
||||
r.Get("/collections", collection.GetAll)
|
||||
r.Post("/collections", collection.Create)
|
||||
r.Put("/collections/:id", collection.Update)
|
||||
r.Delete("/collections/:id", collection.Delete)
|
||||
|
||||
colour := handler.NewColourHandler()
|
||||
r.Get("/colours", colour.GetAll)
|
||||
r.Post("/colours", colour.Create)
|
||||
r.Put("/colours/:id", colour.Update)
|
||||
r.Delete("/colours/:id", colour.Delete)
|
||||
|
||||
size := handler.NewSizeHandler()
|
||||
r.Get("/sizes", size.GetAll)
|
||||
r.Post("/sizes", size.Create)
|
||||
r.Put("/sizes/:id", size.Update)
|
||||
r.Delete("/sizes/:id", size.Delete)
|
||||
|
||||
product := handler.NewProductHandler()
|
||||
r.Get("/products", product.GetAll)
|
||||
r.Post("/products", product.Create)
|
||||
r.Put("/products/:id", product.Update)
|
||||
r.Delete("/products/:id", product.Delete)
|
||||
|
||||
warehouse := handler.NewWarehouseHandler()
|
||||
r.Get("/warehouses", warehouse.GetAll)
|
||||
r.Post("/warehouses", warehouse.Create)
|
||||
r.Put("/warehouses/:id", warehouse.Update)
|
||||
r.Delete("/warehouses/:id", warehouse.Delete)
|
||||
|
||||
stock := handler.NewStockMovementHandler()
|
||||
r.Get("/stock-movements", stock.GetAll)
|
||||
r.Post("/stock-movements", stock.Create)
|
||||
|
||||
component := handler.NewProductComponentHandler()
|
||||
r.Get("/product-components", component.GetAll)
|
||||
r.Post("/product-components", component.Create)
|
||||
r.Delete("/product-components/:id", component.Delete)
|
||||
|
||||
po := handler.NewProductionOrderHandler()
|
||||
r.Get("/production-orders", po.GetAll)
|
||||
r.Post("/production-orders", po.Create)
|
||||
r.Put("/production-orders/:id", po.Update)
|
||||
r.Delete("/production-orders/:id", po.Delete)
|
||||
}
|
||||
59
modules/sales/handler/customer_handler.go
Normal file
59
modules/sales/handler/customer_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type CustomerHandler struct {
|
||||
Repo *repository.CustomerRepository
|
||||
}
|
||||
|
||||
func NewCustomerHandler() *CustomerHandler {
|
||||
return &CustomerHandler{
|
||||
Repo: repository.NewCustomerRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *CustomerHandler) GetAll(c *fiber.Ctx) error {
|
||||
customers, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch customers"})
|
||||
}
|
||||
return c.JSON(customers)
|
||||
}
|
||||
|
||||
func (h *CustomerHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Customer
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create customer"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *CustomerHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Customer
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update customer"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *CustomerHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete customer"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/sales/handler/invoice_handler.go
Normal file
59
modules/sales/handler/invoice_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type InvoiceHandler struct {
|
||||
Repo *repository.InvoiceRepository
|
||||
}
|
||||
|
||||
func NewInvoiceHandler() *InvoiceHandler {
|
||||
return &InvoiceHandler{
|
||||
Repo: repository.NewInvoiceRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *InvoiceHandler) GetAll(c *fiber.Ctx) error {
|
||||
result, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch invoices"})
|
||||
}
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
func (h *InvoiceHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Invoice
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create invoice"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *InvoiceHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Invoice
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update invoice"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *InvoiceHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete invoice"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/sales/handler/invoice_line_handler.go
Normal file
59
modules/sales/handler/invoice_line_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type InvoiceLineHandler struct {
|
||||
Repo *repository.InvoiceLineRepository
|
||||
}
|
||||
|
||||
func NewInvoiceLineHandler() *InvoiceLineHandler {
|
||||
return &InvoiceLineHandler{
|
||||
Repo: repository.NewInvoiceLineRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *InvoiceLineHandler) GetAll(c *fiber.Ctx) error {
|
||||
data, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch invoice lines"})
|
||||
}
|
||||
return c.JSON(data)
|
||||
}
|
||||
|
||||
func (h *InvoiceLineHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.InvoiceLine
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create invoice line"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *InvoiceLineHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.InvoiceLine
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update invoice line"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *InvoiceLineHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete invoice line"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/sales/handler/payment_handler.go
Normal file
59
modules/sales/handler/payment_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type PaymentHandler struct {
|
||||
Repo *repository.PaymentRepository
|
||||
}
|
||||
|
||||
func NewPaymentHandler() *PaymentHandler {
|
||||
return &PaymentHandler{
|
||||
Repo: repository.NewPaymentRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *PaymentHandler) GetAll(c *fiber.Ctx) error {
|
||||
result, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch payments"})
|
||||
}
|
||||
return c.JSON(result)
|
||||
}
|
||||
|
||||
func (h *PaymentHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.Payment
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create payment"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *PaymentHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.Payment
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update payment"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *PaymentHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete payment"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/sales/handler/sales_order_handler.go
Normal file
59
modules/sales/handler/sales_order_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type SalesOrderHandler struct {
|
||||
Repo *repository.SalesOrderRepository
|
||||
}
|
||||
|
||||
func NewSalesOrderHandler() *SalesOrderHandler {
|
||||
return &SalesOrderHandler{
|
||||
Repo: repository.NewSalesOrderRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SalesOrderHandler) GetAll(c *fiber.Ctx) error {
|
||||
data, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch sales orders"})
|
||||
}
|
||||
return c.JSON(data)
|
||||
}
|
||||
|
||||
func (h *SalesOrderHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.SalesOrder
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create sales order"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *SalesOrderHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.SalesOrder
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update sales order"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *SalesOrderHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete sales order"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
59
modules/sales/handler/sales_order_item_handler.go
Normal file
59
modules/sales/handler/sales_order_item_handler.go
Normal file
@ -0,0 +1,59 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"BE-MiniERP/database"
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
"BE-MiniERP/modules/sales/repository"
|
||||
"strconv"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
type SalesOrderItemHandler struct {
|
||||
Repo *repository.SalesOrderItemRepository
|
||||
}
|
||||
|
||||
func NewSalesOrderItemHandler() *SalesOrderItemHandler {
|
||||
return &SalesOrderItemHandler{
|
||||
Repo: repository.NewSalesOrderItemRepository(database.DB),
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SalesOrderItemHandler) GetAll(c *fiber.Ctx) error {
|
||||
data, err := h.Repo.FindAll()
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to fetch items"})
|
||||
}
|
||||
return c.JSON(data)
|
||||
}
|
||||
|
||||
func (h *SalesOrderItemHandler) Create(c *fiber.Ctx) error {
|
||||
var input models.SalesOrderItem
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Create(&input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to create item"})
|
||||
}
|
||||
return c.JSON(input)
|
||||
}
|
||||
|
||||
func (h *SalesOrderItemHandler) Update(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
var input models.SalesOrderItem
|
||||
if err := c.BodyParser(&input); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid input"})
|
||||
}
|
||||
if err := h.Repo.Update(uint(id), &input); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to update item"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Updated"})
|
||||
}
|
||||
|
||||
func (h *SalesOrderItemHandler) Delete(c *fiber.Ctx) error {
|
||||
id, _ := strconv.Atoi(c.Params("id"))
|
||||
if err := h.Repo.Delete(uint(id)); err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Failed to delete item"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"message": "Deleted"})
|
||||
}
|
||||
14
modules/sales/models/customer.go
Normal file
14
modules/sales/models/customer.go
Normal file
@ -0,0 +1,14 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Customer struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Name string `json:"name"`
|
||||
Address string `json:"address"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
16
modules/sales/models/invoice.go
Normal file
16
modules/sales/models/invoice.go
Normal file
@ -0,0 +1,16 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Invoice struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
SalesOrderID uint `json:"sales_order_id"`
|
||||
InvoiceDate time.Time `json:"invoice_date"`
|
||||
DueDate time.Time `json:"due_date"`
|
||||
TotalAmount float64 `json:"total_amount"`
|
||||
Status string `json:"status"` // contoh: unpaid, partial, paid
|
||||
Note string `json:"note"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
15
modules/sales/models/invoice_line.go
Normal file
15
modules/sales/models/invoice_line.go
Normal file
@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type InvoiceLine struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
InvoiceID uint `json:"invoice_id"`
|
||||
ProductID uint `json:"product_id"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
Subtotal float64 `json:"subtotal"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
15
modules/sales/models/payment.go
Normal file
15
modules/sales/models/payment.go
Normal file
@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type Payment struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
InvoiceID uint `json:"invoice_id"`
|
||||
Amount float64 `json:"amount"`
|
||||
PaidAt time.Time `json:"paid_at"`
|
||||
Method string `json:"method"` // contoh: cash, bank transfer, credit card
|
||||
Note string `json:"note"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
19
modules/sales/models/sales_order.go
Normal file
19
modules/sales/models/sales_order.go
Normal file
@ -0,0 +1,19 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type SalesOrder struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
CustomerID uint `json:"customer_id"`
|
||||
OrderDate time.Time `json:"order_date"`
|
||||
Status string `json:"status"`
|
||||
TotalAmount float64 `json:"total_amount"`
|
||||
Note string `json:"note"`
|
||||
PaymentTerms string `json:"payment_terms"`
|
||||
DueDate time.Time `json:"due_date"`
|
||||
DPAmount float64 `json:"dp_amount"`
|
||||
DPPaid float64 `json:"dp_paid"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
15
modules/sales/models/sales_order_item.go
Normal file
15
modules/sales/models/sales_order_item.go
Normal file
@ -0,0 +1,15 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
type SalesOrderItem struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
SalesOrderID uint `json:"sales_order_id"`
|
||||
ProductID uint `json:"product_id"`
|
||||
Quantity float64 `json:"quantity"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
Subtotal float64 `json:"subtotal"`
|
||||
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
33
modules/sales/repository/customer_repo.go
Normal file
33
modules/sales/repository/customer_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CustomerRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewCustomerRepository(db *gorm.DB) *CustomerRepository {
|
||||
return &CustomerRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *CustomerRepository) FindAll() ([]models.Customer, error) {
|
||||
var customers []models.Customer
|
||||
err := r.DB.Find(&customers).Error
|
||||
return customers, err
|
||||
}
|
||||
|
||||
func (r *CustomerRepository) Create(customer *models.Customer) error {
|
||||
return r.DB.Create(customer).Error
|
||||
}
|
||||
|
||||
func (r *CustomerRepository) Update(id uint, data *models.Customer) error {
|
||||
return r.DB.Model(&models.Customer{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *CustomerRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Customer{}, id).Error
|
||||
}
|
||||
33
modules/sales/repository/invoice_line_repo.go
Normal file
33
modules/sales/repository/invoice_line_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvoiceLineRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewInvoiceLineRepository(db *gorm.DB) *InvoiceLineRepository {
|
||||
return &InvoiceLineRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *InvoiceLineRepository) FindAll() ([]models.InvoiceLine, error) {
|
||||
var result []models.InvoiceLine
|
||||
err := r.DB.Find(&result).Error
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *InvoiceLineRepository) Create(data *models.InvoiceLine) error {
|
||||
return r.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *InvoiceLineRepository) Update(id uint, data *models.InvoiceLine) error {
|
||||
return r.DB.Model(&models.InvoiceLine{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *InvoiceLineRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.InvoiceLine{}, id).Error
|
||||
}
|
||||
33
modules/sales/repository/invoice_repo.go
Normal file
33
modules/sales/repository/invoice_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type InvoiceRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewInvoiceRepository(db *gorm.DB) *InvoiceRepository {
|
||||
return &InvoiceRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *InvoiceRepository) FindAll() ([]models.Invoice, error) {
|
||||
var result []models.Invoice
|
||||
err := r.DB.Find(&result).Error
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *InvoiceRepository) Create(data *models.Invoice) error {
|
||||
return r.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *InvoiceRepository) Update(id uint, data *models.Invoice) error {
|
||||
return r.DB.Model(&models.Invoice{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *InvoiceRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Invoice{}, id).Error
|
||||
}
|
||||
33
modules/sales/repository/payment_repo.go
Normal file
33
modules/sales/repository/payment_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PaymentRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewPaymentRepository(db *gorm.DB) *PaymentRepository {
|
||||
return &PaymentRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) FindAll() ([]models.Payment, error) {
|
||||
var result []models.Payment
|
||||
err := r.DB.Find(&result).Error
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) Create(data *models.Payment) error {
|
||||
return r.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) Update(id uint, data *models.Payment) error {
|
||||
return r.DB.Model(&models.Payment{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.Payment{}, id).Error
|
||||
}
|
||||
33
modules/sales/repository/sales_order_item_repo.go
Normal file
33
modules/sales/repository/sales_order_item_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SalesOrderItemRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewSalesOrderItemRepository(db *gorm.DB) *SalesOrderItemRepository {
|
||||
return &SalesOrderItemRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *SalesOrderItemRepository) FindAll() ([]models.SalesOrderItem, error) {
|
||||
var result []models.SalesOrderItem
|
||||
err := r.DB.Find(&result).Error
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *SalesOrderItemRepository) Create(data *models.SalesOrderItem) error {
|
||||
return r.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *SalesOrderItemRepository) Update(id uint, data *models.SalesOrderItem) error {
|
||||
return r.DB.Model(&models.SalesOrderItem{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *SalesOrderItemRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.SalesOrderItem{}, id).Error
|
||||
}
|
||||
33
modules/sales/repository/sales_order_repo.go
Normal file
33
modules/sales/repository/sales_order_repo.go
Normal file
@ -0,0 +1,33 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type SalesOrderRepository struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
|
||||
func NewSalesOrderRepository(db *gorm.DB) *SalesOrderRepository {
|
||||
return &SalesOrderRepository{DB: db}
|
||||
}
|
||||
|
||||
func (r *SalesOrderRepository) FindAll() ([]models.SalesOrder, error) {
|
||||
var result []models.SalesOrder
|
||||
err := r.DB.Find(&result).Error
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (r *SalesOrderRepository) Create(data *models.SalesOrder) error {
|
||||
return r.DB.Create(data).Error
|
||||
}
|
||||
|
||||
func (r *SalesOrderRepository) Update(id uint, data *models.SalesOrder) error {
|
||||
return r.DB.Model(&models.SalesOrder{}).Where("id = ?", id).Updates(data).Error
|
||||
}
|
||||
|
||||
func (r *SalesOrderRepository) Delete(id uint) error {
|
||||
return r.DB.Delete(&models.SalesOrder{}, id).Error
|
||||
}
|
||||
46
modules/sales/routes.go
Normal file
46
modules/sales/routes.go
Normal file
@ -0,0 +1,46 @@
|
||||
package sales
|
||||
|
||||
import (
|
||||
"BE-MiniERP/modules/sales/handler"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func RegisterRoutes(router fiber.Router) {
|
||||
customer := handler.NewCustomerHandler()
|
||||
salesOrder := handler.NewSalesOrderHandler()
|
||||
salesOrderItem := handler.NewSalesOrderItemHandler()
|
||||
invoice := handler.NewInvoiceHandler()
|
||||
invoiceLine := handler.NewInvoiceLineHandler()
|
||||
payment := handler.NewPaymentHandler()
|
||||
|
||||
router.Get("/customers", customer.GetAll)
|
||||
router.Post("/customers", customer.Create)
|
||||
router.Put("/customers/:id", customer.Update)
|
||||
router.Delete("/customers/:id", customer.Delete)
|
||||
|
||||
router.Get("/sales-orders", salesOrder.GetAll)
|
||||
router.Post("/sales-orders", salesOrder.Create)
|
||||
router.Put("/sales-orders/:id", salesOrder.Update)
|
||||
router.Delete("/sales-orders/:id", salesOrder.Delete)
|
||||
|
||||
router.Get("/sales-order-items", salesOrderItem.GetAll)
|
||||
router.Post("/sales-order-items", salesOrderItem.Create)
|
||||
router.Put("/sales-order-items/:id", salesOrderItem.Update)
|
||||
router.Delete("/sales-order-items/:id", salesOrderItem.Delete)
|
||||
|
||||
router.Get("/invoices", invoice.GetAll)
|
||||
router.Post("/invoices", invoice.Create)
|
||||
router.Put("/invoices/:id", invoice.Update)
|
||||
router.Delete("/invoices/:id", invoice.Delete)
|
||||
|
||||
router.Get("/invoice-lines", invoiceLine.GetAll)
|
||||
router.Post("/invoice-lines", invoiceLine.Create)
|
||||
router.Put("/invoice-lines/:id", invoiceLine.Update)
|
||||
router.Delete("/invoice-lines/:id", invoiceLine.Delete)
|
||||
|
||||
router.Get("/payments", payment.GetAll)
|
||||
router.Post("/payments", payment.Create)
|
||||
router.Put("/payments/:id", payment.Update)
|
||||
router.Delete("/payments/:id", payment.Delete)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user