Files
bssapp/svc/routes/orders.go
2026-04-14 16:34:25 +03:00

320 lines
8.6 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routes
import (
"bssapp-backend/auth"
"bssapp-backend/models"
"bssapp-backend/queries"
"bssapp-backend/utils"
"database/sql"
"encoding/json"
"errors"
"fmt"
"net/http"
"github.com/gorilla/mux"
)
func BulkUpdateOrderLineDueDateHandler(mssql *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
claims, ok := auth.GetClaimsFromContext(r.Context())
if !ok || claims == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
user := utils.UserFromClaims(claims)
if user == nil {
http.Error(w, "Kullanici dogrulanamadi", http.StatusUnauthorized)
return
}
orderHeaderID := mux.Vars(r)["id"]
if orderHeaderID == "" {
http.Error(w, "OrderHeaderID bulunamadi", http.StatusBadRequest)
return
}
var payload struct {
DueDate string `json:"dueDate"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "Gecersiz JSON", http.StatusBadRequest)
return
}
username := user.Username
if username == "" {
username = user.V3Username
}
updatedLines, headerUpdated, err := queries.BulkUpdateOrderLineDueDate(mssql, orderHeaderID, payload.DueDate, username)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_ = json.NewEncoder(w).Encode(map[string]any{
"code": "ORDER_BULK_DUE_DATE_UPDATE_FAILED",
"message": "Siparis satir terminleri guncellenemedi.",
"detail": err.Error(),
})
return
}
_ = json.NewEncoder(w).Encode(map[string]any{
"success": true,
"orderHeaderID": orderHeaderID,
"dueDate": payload.DueDate,
"updatedLines": updatedLines,
"headerUpdated": headerUpdated,
})
}
}
// ================================
// POST /api/order/update
// ================================
func UpdateOrderHandler(w http.ResponseWriter, r *http.Request) {
// --------------------------------------------------
// 1⃣ JWT CLAIMS (TEK KAYNAK)
// --------------------------------------------------
claims, ok := auth.GetClaimsFromContext(r.Context())
if !ok || claims == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
user := utils.UserFromClaims(claims)
if !ok || claims == nil {
http.Error(w, "Kullanıcı doğrulanamadı", http.StatusUnauthorized)
return
}
user = utils.UserFromClaims(claims)
if user == nil {
http.Error(w, "Kullanıcı doğrulanamadı", http.StatusUnauthorized)
return
}
// --------------------------------------------------
// 2⃣ REQUEST BODY
// --------------------------------------------------
var payload struct {
Header models.OrderHeader `json:"header"`
Lines []models.OrderDetail `json:"lines"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, "Geçersiz JSON", http.StatusBadRequest)
return
}
// --------------------------------------------------
// 3⃣ UPDATE
// --------------------------------------------------
results, err := queries.UpdateOrder(
payload.Header,
payload.Lines,
user, // ✅ *models.User
)
if err != nil {
// ✅ VALIDATION ERROR
var vErr *models.ValidationError
if errors.As(err, &vErr) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
_ = json.NewEncoder(w).Encode(vErr)
return
}
// ❌ SYSTEM ERROR
utils.LogError("ORDER_UPDATE", err)
w.WriteHeader(http.StatusInternalServerError)
_ = json.NewEncoder(w).Encode(map[string]any{
"code": "ORDER_UPDATE_FAILED",
"message": "Sipariş kaydedilirken beklenmeyen bir hata oluştu.",
"detail": err.Error(),
})
return
}
// --------------------------------------------------
// 4⃣ RESPONSE
// --------------------------------------------------
w.Header().Set("Content-Type", "application/json")
_ = json.NewEncoder(w).Encode(map[string]any{
"success": true,
"lines": results,
})
}
// -------------------------------------------------------------
// 🟩 CREATE — /api/order/create
// -------------------------------------------------------------
func CreateOrderHandler(pg *sql.DB, mssql *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
// --------------------------------------------------
// JWT CLAIMS (TEK KAYNAK)
// --------------------------------------------------
claims, ok := auth.GetClaimsFromContext(r.Context())
if !ok || claims == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
user := utils.UserFromClaims(claims)
if user == nil {
http.Error(w, "Kullanici dogrulanamadi", http.StatusUnauthorized)
return
}
fmt.Printf("[CREATE] hit user=%s role=%s\n", user.Username, user.RoleCode)
var payload struct {
Header models.OrderHeader `json:"header"`
Lines []models.OrderDetail `json:"lines"`
}
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
fmt.Printf("[CREATE] decode error: %v\n", err)
http.Error(w, "Gecersiz JSON", http.StatusBadRequest)
return
}
fmt.Printf(
"[CREATE] payload header_id=%s curr_acc=%s office=%s store=%s orderer_office=%s orderer_store=%s lines=%d\n",
payload.Header.OrderHeaderID,
payload.Header.CurrAccCode.String,
payload.Header.OfficeCode.String,
payload.Header.StoreCode.String,
payload.Header.OrdererOfficeCode.String,
payload.Header.OrdererStoreCode.String,
len(payload.Lines),
)
fmt.Printf(
"🧾 CREATE PAYLOAD | header_id=%s curr_acc=%s office=%s store=%s orderer_office=%s orderer_store=%s lines=%d\n",
payload.Header.OrderHeaderID,
payload.Header.CurrAccCode.String,
payload.Header.OfficeCode.String,
payload.Header.StoreCode.String,
payload.Header.OrdererOfficeCode.String,
payload.Header.OrdererStoreCode.String,
len(payload.Lines),
)
// --------------------------------------------------
// INSERT
// --------------------------------------------------
newID, lineResults, err := queries.InsertOrder(
payload.Header,
payload.Lines,
user, // *models.User
)
if err != nil {
var vErr *models.ValidationError
if errors.As(err, &vErr) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
_ = json.NewEncoder(w).Encode(vErr)
return
}
// SYSTEM ERROR
utils.LogError("ORDER_CREATE", err)
w.WriteHeader(http.StatusInternalServerError)
_ = json.NewEncoder(w).Encode(map[string]any{
"code": "ORDER_CREATE_FAILED",
"message": "Siparis kaydedilirken beklenmeyen bir hata olustu.",
"detail": err.Error(),
})
return
}
orderNo := ""
if payload.Header.OrderNumber.Valid {
orderNo = payload.Header.OrderNumber.String
}
// --------------------------------------------------
// RESPONSE
// --------------------------------------------------
_ = json.NewEncoder(w).Encode(map[string]any{
"status": "success",
"orderID": newID,
"orderNumber": orderNo,
"lineResults": lineResults,
})
}
}
// -------------------------------------------------------------
// 🟨 GET BY ID — /api/order/get/{id}
// -------------------------------------------------------------
func GetOrderByIDHandler(mssql *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
orderID := mux.Vars(r)["id"]
if orderID == "" {
http.Error(w, "Eksik parametre: id", http.StatusBadRequest)
return
}
fmt.Printf("📦 /api/order/get/%s çağrıldı\n", orderID)
header, lines, err := queries.GetOrderByID(orderID)
switch {
case errors.Is(err, sql.ErrNoRows):
http.Error(w, fmt.Sprintf("Sipariş bulunamadı: %s", orderID), http.StatusNotFound)
return
case err != nil:
http.Error(w, fmt.Sprintf("Veritabanı hatası: %v", err), http.StatusInternalServerError)
return
default:
_ = json.NewEncoder(w).Encode(map[string]any{
"header": header,
"lines": lines,
})
}
}
}
// -------------------------------------------------------------
// 🔎 ORDER EXISTS — /api/order/check/{id}
// -------------------------------------------------------------
func OrderExistsHandler(db *sql.DB) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := mux.Vars(r)["id"]
var count int
err := db.QueryRow(`
SELECT COUNT(*)
FROM trOrderHeader
WHERE OrderHeaderID = @p1
`, id).Scan(&count)
if err != nil {
http.Error(w, "db error", http.StatusInternalServerError)
return
}
_ = json.NewEncoder(w).Encode(map[string]any{
"exists": count > 0,
})
})
}