443 lines
9.5 KiB
Go
443 lines
9.5 KiB
Go
package handler
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/wmms/wmms/internal/model"
|
|
"github.com/wmms/wmms/internal/service"
|
|
"github.com/wmms/wmms/pkg/response"
|
|
)
|
|
|
|
func organizationID(c *gin.Context) (int64, bool) {
|
|
value := c.GetHeader("X-Organization-ID")
|
|
if value == "" {
|
|
return 1, true
|
|
}
|
|
id, err := strconv.ParseInt(value, 10, 64)
|
|
if err != nil || id <= 0 {
|
|
response.BadRequest(c, "invalid X-Organization-ID")
|
|
return 0, false
|
|
}
|
|
return id, true
|
|
}
|
|
|
|
func pathID(c *gin.Context) (int64, bool) {
|
|
id, err := strconv.ParseInt(c.Param("id"), 10, 64)
|
|
if err != nil || id <= 0 {
|
|
response.BadRequest(c, "invalid id")
|
|
return 0, false
|
|
}
|
|
return id, true
|
|
}
|
|
|
|
func bind(c *gin.Context, value interface{}) bool {
|
|
if err := c.ShouldBindJSON(value); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (h *Handler) ListOrganizations(c *gin.Context) {
|
|
items, err := h.organizationSvc.List()
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) ListRoles(c *gin.Context) {
|
|
items, err := h.organizationSvc.ListRoles()
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) ListPermissions(c *gin.Context) {
|
|
items, err := h.organizationSvc.ListPermissions()
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) UpdateRole(c *gin.Context) {
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req model.UpdateRoleRequest
|
|
if !bind(c, &req) {
|
|
return
|
|
}
|
|
if err := h.organizationSvc.UpdateRole(id, &req); err != nil {
|
|
if errors.Is(err, service.ErrProtectedRole) {
|
|
response.Error(c, 409, err.Error())
|
|
return
|
|
}
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.SuccessWithMessage(c, "Role updated successfully", nil)
|
|
}
|
|
func (h *Handler) CreateOrganization(c *gin.Context) {
|
|
var item model.Organization
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
if err := h.organizationSvc.Create(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Organization created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateOrganization(c *gin.Context) {
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.Organization
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID = id
|
|
if err := h.organizationSvc.Update(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListMaterialCategories(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, err := h.masterDataSvc.ListCategories(orgID)
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) CreateMaterialCategory(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.MaterialCategory
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.OrganizationID = orgID
|
|
if err := h.masterDataSvc.CreateCategory(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Material category created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateMaterialCategory(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.MaterialCategory
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.OrganizationID = id, orgID
|
|
if err := h.masterDataSvc.UpdateCategory(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListUnits(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, err := h.masterDataSvc.ListUnits(orgID)
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) CreateUnit(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.Unit
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.OrganizationID = orgID
|
|
if err := h.masterDataSvc.CreateUnit(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Unit created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateUnit(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.Unit
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.OrganizationID = id, orgID
|
|
if err := h.masterDataSvc.UpdateUnit(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListCodeRules(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, err := h.masterDataSvc.ListCodeRules(orgID)
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
|
|
// GetNextMaterialCode 预览按小类规则自动生成的物料编码。新增物料的人要用它
|
|
// 填表,所以只要求登录,不要求管理员。
|
|
func (h *Handler) GetNextMaterialCode(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
categoryID, err := strconv.ParseInt(c.Query("category_id"), 10, 64)
|
|
if err != nil || categoryID <= 0 {
|
|
response.BadRequest(c, "invalid category_id")
|
|
return
|
|
}
|
|
next, err := h.masterDataSvc.NextMaterialCode(orgID, categoryID)
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, next)
|
|
}
|
|
func (h *Handler) CreateCodeRule(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.CodeRule
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.OrganizationID = orgID
|
|
if err := h.masterDataSvc.CreateCodeRule(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Code rule created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateCodeRule(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.CodeRule
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.OrganizationID = id, orgID
|
|
if err := h.masterDataSvc.UpdateCodeRule(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListPartners(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
// 分页参数的默认值与上限跟物料等列表接口保持一致,前端不必记两套规则
|
|
limit := 20
|
|
offset := 0
|
|
if l := c.Query("limit"); l != "" {
|
|
if parsed, err := strconv.Atoi(l); err == nil && parsed > 0 {
|
|
limit = parsed
|
|
if limit > 100 {
|
|
limit = 100
|
|
}
|
|
}
|
|
}
|
|
if o := c.Query("offset"); o != "" {
|
|
if parsed, err := strconv.Atoi(o); err == nil && parsed >= 0 {
|
|
offset = parsed
|
|
}
|
|
}
|
|
|
|
items, total, err := h.partnerSvc.List(orgID, c.Query("role"), limit, offset, c.Query("category"))
|
|
if err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
if items == nil {
|
|
items = []model.BusinessPartner{}
|
|
}
|
|
response.PaginatedSuccess(c, items, limit, offset, total)
|
|
}
|
|
func (h *Handler) CreatePartner(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.BusinessPartner
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.OrganizationID = orgID
|
|
if err := h.partnerSvc.Create(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Partner created successfully", item)
|
|
}
|
|
func (h *Handler) UpdatePartner(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.BusinessPartner
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.OrganizationID = id, orgID
|
|
if err := h.partnerSvc.Update(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
|
|
func (h *Handler) ListWarehouses(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
items, err := h.warehouseSvc.List(orgID)
|
|
if err != nil {
|
|
response.InternalError(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, items)
|
|
}
|
|
func (h *Handler) CreateWarehouse(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.Warehouse
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.OrganizationID = orgID
|
|
if err := h.warehouseSvc.Create(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Warehouse created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateWarehouse(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
id, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.Warehouse
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.OrganizationID = id, orgID
|
|
if err := h.warehouseSvc.Update(&item); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|
|
func (h *Handler) CreateWarehouseLocation(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
warehouseID, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var item model.WarehouseLocation
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.WarehouseID = warehouseID
|
|
if err := h.warehouseSvc.CreateLocation(&item, orgID); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Created(c, "Location created successfully", item)
|
|
}
|
|
func (h *Handler) UpdateWarehouseLocation(c *gin.Context) {
|
|
orgID, ok := organizationID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
warehouseID, ok := pathID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
locationID, err := strconv.ParseInt(c.Param("locationId"), 10, 64)
|
|
if err != nil || locationID <= 0 {
|
|
response.BadRequest(c, "invalid location id")
|
|
return
|
|
}
|
|
var item model.WarehouseLocation
|
|
if !bind(c, &item) {
|
|
return
|
|
}
|
|
item.ID, item.WarehouseID = locationID, warehouseID
|
|
if err := h.warehouseSvc.UpdateLocation(&item, orgID); err != nil {
|
|
response.BadRequest(c, err.Error())
|
|
return
|
|
}
|
|
response.Success(c, item)
|
|
}
|