feat: implement inventory issue management
- Added migration for inventory issue and issue line entities. - Created InventoryIssueController with CRUD operations for inventory issues and lines. - Developed DTOs for inventory issue requests and responses. - Implemented query filters for inventory issues. - Created repositories for inventory issue and issue line data access. - Developed service layer for inventory issue business logic. - Added routes for inventory issue management in the API. - Updated existing repositories to include assignment retrieval for inventory receipts and requests. - Registered new dependencies in the core provider for inventory issue functionality.
This commit is contained in:
parent
0543f8a1ff
commit
52dec2f37a
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/Caknoooo/go-gin-clean-starter/modules/auth"
|
"github.com/Caknoooo/go-gin-clean-starter/modules/auth"
|
||||||
"github.com/Caknoooo/go-gin-clean-starter/modules/category"
|
"github.com/Caknoooo/go-gin-clean-starter/modules/category"
|
||||||
"github.com/Caknoooo/go-gin-clean-starter/modules/client"
|
"github.com/Caknoooo/go-gin-clean-starter/modules/client"
|
||||||
|
inventoryissue "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue"
|
||||||
inventoryreceipt "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_receipt"
|
inventoryreceipt "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_receipt"
|
||||||
inventoryrequest "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request"
|
inventoryrequest "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request"
|
||||||
maintenancegroup "github.com/Caknoooo/go-gin-clean-starter/modules/maintenance_group"
|
maintenancegroup "github.com/Caknoooo/go-gin-clean-starter/modules/maintenance_group"
|
||||||
|
|
@ -167,6 +168,7 @@ func main() {
|
||||||
inventoryreceipt.RegisterRoutes(server, injector)
|
inventoryreceipt.RegisterRoutes(server, injector)
|
||||||
assignment.RegisterRoutes(server, injector)
|
assignment.RegisterRoutes(server, injector)
|
||||||
inventoryrequest.RegisterRoutes(server, injector)
|
inventoryrequest.RegisterRoutes(server, injector)
|
||||||
|
inventoryissue.RegisterRoutes(server, injector)
|
||||||
|
|
||||||
// register swagger route
|
// register swagger route
|
||||||
server.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
server.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
package entities
|
package entities
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TInventoryIssueEntity struct {
|
type TInventoryIssueEntity struct {
|
||||||
|
|
@ -11,15 +14,17 @@ type TInventoryIssueEntity struct {
|
||||||
DocumentNumber string `gorm:"type:varchar(100);" json:"document_number"`
|
DocumentNumber string `gorm:"type:varchar(100);" json:"document_number"`
|
||||||
DocumentDate time.Time `gorm:"type:timestamp;" json:"document_date"`
|
DocumentDate time.Time `gorm:"type:timestamp;" json:"document_date"`
|
||||||
DueDate time.Time `gorm:"type:timestamp;" json:"due_date"`
|
DueDate time.Time `gorm:"type:timestamp;" json:"due_date"`
|
||||||
Status string `gorm:"type:varchar(50);" json:"status"`
|
Status string `gorm:"type:varchar(50);default:'draft'" json:"status"`
|
||||||
|
|
||||||
IssuerBy uuid.UUID `gorm:"type:uuid;index;" json:"issuer_by"`
|
IssuerBy uuid.UUID `gorm:"type:uuid;index;" json:"issuer_by"`
|
||||||
InvRequestID uuid.UUID `gorm:"type:uuid;index;" json:"inv_request_id"`
|
InvRequestID uuid.UUID `gorm:"type:uuid;index;" json:"inv_request_id"`
|
||||||
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
||||||
|
|
||||||
Issuer M_User `gorm:"foreignKey:IssuerBy;references:ID"`
|
Issuer M_User `gorm:"foreignKey:IssuerBy;references:ID"`
|
||||||
InvRequest TInventoryRequestEntity `gorm:"foreignKey:InvRequestID;references:ID"`
|
InvRequest TInventoryRequestEntity `gorm:"foreignKey:InvRequestID;references:ID"`
|
||||||
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
IssueLines []TInventoryIssueLineEntity `gorm:"foreignKey:InvIssueID;references:ID"`
|
||||||
|
Assignment TAssignmentEntity `gorm:"-"`
|
||||||
|
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
||||||
|
|
||||||
FullAuditTrail
|
FullAuditTrail
|
||||||
}
|
}
|
||||||
|
|
@ -27,3 +32,44 @@ type TInventoryIssueEntity struct {
|
||||||
func (TInventoryIssueEntity) TableName() string {
|
func (TInventoryIssueEntity) TableName() string {
|
||||||
return "t_inventory_issues"
|
return "t_inventory_issues"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateDocumentNumber generates a new document number for a client
|
||||||
|
func GenerateDocumentNumberInvIssue(db *gorm.DB, clientId string) (string, error) {
|
||||||
|
prefix := "ISSUE"
|
||||||
|
|
||||||
|
// Ambil nama client berdasarkan clientId
|
||||||
|
var client struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
if err := db.Table("m_clients").Select("name").Where("id = ?", clientId).First(&client).Error; err != nil {
|
||||||
|
return "", fmt.Errorf("client not found")
|
||||||
|
}
|
||||||
|
if client.Name == "" {
|
||||||
|
return "", fmt.Errorf("client name is empty")
|
||||||
|
}
|
||||||
|
words := strings.Fields(client.Name)
|
||||||
|
initials := ""
|
||||||
|
for _, w := range words {
|
||||||
|
if len(w) > 0 {
|
||||||
|
initials += strings.ToUpper(string(w[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cari document number terakhir untuk client ini
|
||||||
|
var lastReceipt TInventoryIssueEntity
|
||||||
|
err := db.
|
||||||
|
Where("client_id = ?", clientId).
|
||||||
|
Order("document_number DESC").
|
||||||
|
First(&lastReceipt).Error
|
||||||
|
|
||||||
|
seq := 1
|
||||||
|
if err == nil && lastReceipt.DocumentNumber != "" {
|
||||||
|
parts := strings.Split(lastReceipt.DocumentNumber, "-")
|
||||||
|
if len(parts) == 3 {
|
||||||
|
fmt.Sscanf(parts[2], "%d", &seq)
|
||||||
|
seq++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
docNum := fmt.Sprintf("%s-%s-%04d", prefix, initials, seq)
|
||||||
|
return docNum, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,13 @@ type TInventoryIssueLineEntity struct {
|
||||||
IssuedQuantity float64 `gorm:"type:numeric;default:0" json:"issued_quantity"`
|
IssuedQuantity float64 `gorm:"type:numeric;default:0" json:"issued_quantity"`
|
||||||
Remarks string `gorm:"type:text;" json:"remarks"`
|
Remarks string `gorm:"type:text;" json:"remarks"`
|
||||||
|
|
||||||
IssueID uuid.UUID `gorm:"type:uuid;index;" json:"issue_id"`
|
InvIssueID uuid.UUID `gorm:"type:uuid;index;" json:"inv_issue_id"`
|
||||||
ProductID uuid.UUID `gorm:"type:uuid;index;" json:"product_id"`
|
ProductID uuid.UUID `gorm:"type:uuid;index;" json:"product_id"`
|
||||||
WarehouseID uuid.UUID `gorm:"type:uuid;index;" json:"warehouse_id"`
|
WarehouseID uuid.UUID `gorm:"type:uuid;index;" json:"warehouse_id"`
|
||||||
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
||||||
|
|
||||||
Product MProductEntity `gorm:"foreignKey:ProductID;references:ID"`
|
Product MProductEntity `gorm:"foreignKey:ProductID;references:ID"`
|
||||||
Issue TInventoryIssueEntity `gorm:"foreignKey:IssueID;references:ID"`
|
InvIssue TInventoryIssueEntity `gorm:"foreignKey:InvIssueID;references:ID"`
|
||||||
Warehouse MWarehouseEntity `gorm:"foreignKey:WarehouseID;references:ID"`
|
Warehouse MWarehouseEntity `gorm:"foreignKey:WarehouseID;references:ID"`
|
||||||
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ type TInventoryReceiptEntity struct {
|
||||||
|
|
||||||
ReceiptLines []TInventoryReceiptLineEntity `gorm:"foreignKey:InvReceiptID;references:ID"`
|
ReceiptLines []TInventoryReceiptLineEntity `gorm:"foreignKey:InvReceiptID;references:ID"`
|
||||||
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
||||||
Assignment TAssignmentEntity `gorm:"foreignKey:DocumentID;references:ID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
|
Assignment TAssignmentEntity `gorm:"-"`
|
||||||
|
|
||||||
FullAuditTrail
|
FullAuditTrail
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ type TInventoryRequestEntity struct {
|
||||||
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
ClientID uuid.UUID `gorm:"type:uuid;index;" json:"client_id"`
|
||||||
|
|
||||||
RequestLines []TInventoryRequestLineEntity `gorm:"foreignKey:InvRequestID;references:ID"`
|
RequestLines []TInventoryRequestLineEntity `gorm:"foreignKey:InvRequestID;references:ID"`
|
||||||
Assignment TAssignmentEntity `gorm:"foreignKey:DocumentID;references:ID"`
|
Assignment TAssignmentEntity `gorm:"-"`
|
||||||
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
Client M_Client `gorm:"foreignKey:ClientID;references:ID"`
|
||||||
|
|
||||||
FullAuditTrail
|
FullAuditTrail
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ func Migrate(db *gorm.DB) error {
|
||||||
&entities.TInventoryReceiptLineEntity{},
|
&entities.TInventoryReceiptLineEntity{},
|
||||||
&entities.TInventoryRequestEntity{},
|
&entities.TInventoryRequestEntity{},
|
||||||
&entities.TInventoryRequestLineEntity{},
|
&entities.TInventoryRequestLineEntity{},
|
||||||
// &entities.TInventoryIssueEntity{},
|
&entities.TInventoryIssueEntity{},
|
||||||
// &entities.TInventoryIssueLineEntity{},
|
&entities.TInventoryIssueLineEntity{},
|
||||||
// &entities.InventoryTransactionEntity{},
|
// &entities.InventoryTransactionEntity{},
|
||||||
// &entities.InventoryStorageEntity{},
|
// &entities.InventoryStorageEntity{},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
@ -68,15 +68,15 @@ func MigrateFresh(db *gorm.DB) error {
|
||||||
// &entities.MCrossReferenceEntity{},
|
// &entities.MCrossReferenceEntity{},
|
||||||
// &entities.MWarehouseEntity{},
|
// &entities.MWarehouseEntity{},
|
||||||
// &entities.MZonaEntity{},
|
// &entities.MZonaEntity{},
|
||||||
&entities.MAisleEntity{},
|
// &entities.MAisleEntity{},
|
||||||
// &entities.TAssignmentEntity{},
|
&entities.TAssignmentEntity{},
|
||||||
// &entities.TAssignmentUserEntity{},
|
&entities.TAssignmentUserEntity{},
|
||||||
// &entities.TInventoryReceiptEntity{},
|
// &entities.TInventoryReceiptEntity{},
|
||||||
// &entities.TInventoryReceiptLineEntity{},
|
// &entities.TInventoryReceiptLineEntity{},
|
||||||
&entities.TInventoryRequestEntity{},
|
// &entities.TInventoryRequestEntity{},
|
||||||
&entities.TInventoryRequestLineEntity{},
|
// &entities.TInventoryRequestLineEntity{},
|
||||||
// &entities.TInventoryIssueEntity{},
|
&entities.TInventoryIssueEntity{},
|
||||||
// &entities.TInventoryIssueLineEntity{},
|
&entities.TInventoryIssueLineEntity{},
|
||||||
// &entities.InventoryTransactionEntity{},
|
// &entities.InventoryTransactionEntity{},
|
||||||
// &entities.InventoryStorageEntity{},
|
// &entities.InventoryStorageEntity{},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,179 @@
|
||||||
|
package controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/dto"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/query"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/service"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/samber/do"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueController interface {
|
||||||
|
Create(ctx *gin.Context)
|
||||||
|
Update(ctx *gin.Context)
|
||||||
|
Delete(ctx *gin.Context)
|
||||||
|
GetById(ctx *gin.Context)
|
||||||
|
GetAll(ctx *gin.Context)
|
||||||
|
CreateLine(ctx *gin.Context)
|
||||||
|
UpdateLine(ctx *gin.Context)
|
||||||
|
DeleteLine(ctx *gin.Context)
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventoryIssueController struct {
|
||||||
|
issueService service.InventoryIssueService
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInventoryIssueController(i *do.Injector, issueService service.InventoryIssueService) InventoryIssueController {
|
||||||
|
db := do.MustInvokeNamed[*gorm.DB](i, constants.DB)
|
||||||
|
return &inventoryIssueController{
|
||||||
|
issueService: issueService,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) Create(ctx *gin.Context) {
|
||||||
|
var req dto.InventoryIssueCreateRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
created, err := c.issueService.Create(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_CREATE_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_CREATE_INVENTORY_ISSUE, created)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) Update(ctx *gin.Context) {
|
||||||
|
id := ctx.Param("id")
|
||||||
|
var req dto.InventoryIssueUpdateRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updated, err := c.issueService.Update(ctx, req, id)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_UPDATE_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_UPDATE_INVENTORY_ISSUE, updated)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) Delete(ctx *gin.Context) {
|
||||||
|
id := ctx.Param("id")
|
||||||
|
if err := c.issueService.Delete(ctx, id); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_DELETE_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE, nil)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) GetById(ctx *gin.Context) {
|
||||||
|
id := ctx.Param("id")
|
||||||
|
result, err := c.issueService.GetById(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_ISSUE, result)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) GetAll(ctx *gin.Context) {
|
||||||
|
clientId := ctx.MustGet("client_id").(string)
|
||||||
|
var filter query.InventoryIssueFilter
|
||||||
|
filter.ClientID = clientId
|
||||||
|
if err := ctx.ShouldBindQuery(&filter); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getAll := ctx.Query("get_all")
|
||||||
|
if getAll != "" {
|
||||||
|
issues, _, err := c.issueService.GetAll(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_GET_INVENTORY_ISSUE, issues)
|
||||||
|
ctx.JSON(http.StatusOK, response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
perPage := utils.ParseInt(ctx.DefaultQuery("per_page", "10"))
|
||||||
|
page := utils.ParseInt(ctx.DefaultQuery("page", "1"))
|
||||||
|
filter.PerPage = perPage
|
||||||
|
filter.Page = (page - 1) * perPage
|
||||||
|
issues, total, err := c.issueService.GetAll(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_INVENTORY_ISSUE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
paginationResponse := utils.BuildPaginationResponse(perPage, page, total)
|
||||||
|
res := utils.BuildResponseSuccessWithPagination(http.StatusOK, dto.MESSAGE_SUCCESS_GET_INVENTORY_ISSUE, issues, paginationResponse)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) CreateLine(ctx *gin.Context) {
|
||||||
|
issueId := ctx.Param("id")
|
||||||
|
var req dto.InventoryIssueLineCreateRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
created, err := c.issueService.CreateLine(ctx, issueId, req)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_CREATE_INVENTORY_ISSUE_LINE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_CREATE_INVENTORY_ISSUE_LINE, created)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) UpdateLine(ctx *gin.Context) {
|
||||||
|
id := ctx.Param("id")
|
||||||
|
var req dto.InventoryIssueLineUpdateRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusBadRequest, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updated, err := c.issueService.UpdateLine(ctx, id, req)
|
||||||
|
if err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_UPDATE_INVENTORY_ISSUE_LINE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_UPDATE_INVENTORY_ISSUE_LINE, updated)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *inventoryIssueController) DeleteLine(ctx *gin.Context) {
|
||||||
|
id := ctx.Param("id")
|
||||||
|
if err := c.issueService.DeleteLine(ctx, id); err != nil {
|
||||||
|
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_DELETE_INVENTORY_ISSUE_LINE, err.Error(), nil)
|
||||||
|
ctx.JSON(http.StatusInternalServerError, res)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE_LINE, nil)
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
import pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
||||||
|
|
||||||
|
const (
|
||||||
|
MESSAGE_FAILED_CREATE_INVENTORY_ISSUE = "failed create inventory issue"
|
||||||
|
MESSAGE_FAILED_CREATE_INVENTORY_ISSUE_LINE = "failed create inventory issue line"
|
||||||
|
MESSAGE_SUCCESS_CREATE_INVENTORY_ISSUE = "success create inventory issue"
|
||||||
|
MESSAGE_SUCCESS_CREATE_INVENTORY_ISSUE_LINE = "success create inventory issue line"
|
||||||
|
MESSAGE_FAILED_GET_INVENTORY_ISSUE = "failed get inventory issue"
|
||||||
|
MESSAGE_SUCCESS_GET_INVENTORY_ISSUE = "success get inventory issue"
|
||||||
|
MESSAGE_FAILED_UPDATE_INVENTORY_ISSUE = "failed update inventory issue"
|
||||||
|
MESSAGE_FAILED_UPDATE_INVENTORY_ISSUE_LINE = "failed update inventory issue line"
|
||||||
|
MESSAGE_SUCCESS_UPDATE_INVENTORY_ISSUE = "success update inventory issue"
|
||||||
|
MESSAGE_SUCCESS_UPDATE_INVENTORY_ISSUE_LINE = "success update inventory issue line"
|
||||||
|
MESSAGE_FAILED_DELETE_INVENTORY_ISSUE = "failed delete inventory issue"
|
||||||
|
MESSAGE_FAILED_DELETE_INVENTORY_ISSUE_LINE = "failed delete inventory issue line"
|
||||||
|
MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE = "success delete inventory issue"
|
||||||
|
MESSAGE_SUCCESS_DELETE_INVENTORY_ISSUE_LINE = "success delete inventory issue line"
|
||||||
|
MESSAGE_FAILED_GET_DATA_FROM_BODY = "failed get data from body"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueCreateRequest struct {
|
||||||
|
DocumentDate string `json:"document_date"`
|
||||||
|
DueDate string `json:"due_date"`
|
||||||
|
IssuerBy string `json:"issuer_by"`
|
||||||
|
InvRequestID string `json:"inv_request_id"`
|
||||||
|
ClientID string `json:"client_id" binding:"required"`
|
||||||
|
Status string `json:"status" binding:"required"`
|
||||||
|
IssueLines []InventoryIssueLineCreateRequest `json:"issue_lines,omitempty" binding:"dive"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueLineCreateRequest struct {
|
||||||
|
CurrentStock float64 `json:"current_stock"`
|
||||||
|
MinStock float64 `json:"min_stock"`
|
||||||
|
RequestQuantity float64 `json:"request_quantity"`
|
||||||
|
IssuedQuantity float64 `json:"issued_quantity"`
|
||||||
|
Remarks string `json:"remarks"`
|
||||||
|
ProductID string `json:"product_id"`
|
||||||
|
WarehouseID string `json:"warehouse_id"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueUpdateRequest struct {
|
||||||
|
DocumentDate string `json:"document_date"`
|
||||||
|
DueDate string `json:"due_date"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueLineUpdateRequest struct {
|
||||||
|
CurrentStock *float64 `json:"current_stock"`
|
||||||
|
MinStock *float64 `json:"min_stock"`
|
||||||
|
RequestQuantity *float64 `json:"request_quantity"`
|
||||||
|
IssuedQuantity *float64 `json:"issued_quantity"`
|
||||||
|
Remarks *string `json:"remarks"`
|
||||||
|
ProductID *string `json:"product_id"`
|
||||||
|
WarehouseID *string `json:"warehouse_id"`
|
||||||
|
ClientID *string `json:"client_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
DocumentNumber string `json:"document_number"`
|
||||||
|
DocumentDate string `json:"document_date"`
|
||||||
|
DueDate string `json:"due_date"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
IssuerBy pkgdto.IdNameResponse `json:"issuer_by"`
|
||||||
|
InvRequest pkgdto.IdNameResponse `json:"inv_request"`
|
||||||
|
Client pkgdto.IdNameResponse `json:"client"`
|
||||||
|
LineCount int `json:"line_count"`
|
||||||
|
IssueLines []InventoryIssueLineResponse `json:"issue_lines"`
|
||||||
|
Assignment AssignmentResponse `json:"assignment,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueLineResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
CurrentStock float64 `json:"current_stock"`
|
||||||
|
MinStock float64 `json:"min_stock"`
|
||||||
|
RequestQuantity float64 `json:"request_quantity"`
|
||||||
|
IssuedQuantity float64 `json:"issued_quantity"`
|
||||||
|
Remarks string `json:"remarks"`
|
||||||
|
Product InventoryIssueProductResponse `json:"product"`
|
||||||
|
Warehouse pkgdto.IdNameResponse `json:"warehouse"`
|
||||||
|
Client pkgdto.IdNameResponse `json:"client"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryIssueProductResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
RefNumber string `json:"ref_number"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssignmentResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
DocumentType string `json:"document_type"`
|
||||||
|
DocumentID string `json:"document_id"`
|
||||||
|
// Client pkgdto.IdNameResponse `json:"client"`
|
||||||
|
AssignmentUsers []AssignmentUserResponse `json:"assignment_users"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssignmentUserResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
TaskType string `json:"task_type"`
|
||||||
|
User pkgdto.IdNameResponse `json:"user"`
|
||||||
|
Role pkgdto.IdNameResponse `json:"role"`
|
||||||
|
// Client pkgdto.IdNameResponse `json:"client"`
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueFilter struct {
|
||||||
|
ClientID string `form:"client_id"`
|
||||||
|
IssuerBy string `form:"issuer_by"`
|
||||||
|
PerPage int `form:"per_page"`
|
||||||
|
Page int `form:"page"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyInventoryIssueFilters(db *gorm.DB, filter InventoryIssueFilter) *gorm.DB {
|
||||||
|
if filter.ClientID != "" {
|
||||||
|
db = db.Where("client_id = ?", filter.ClientID)
|
||||||
|
}
|
||||||
|
if filter.IssuerBy != "" {
|
||||||
|
db = db.Where("issuer_by = ?", filter.IssuerBy)
|
||||||
|
}
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueLineRepository interface {
|
||||||
|
Create(ctx context.Context, tx *gorm.DB, line entities.TInventoryIssueLineEntity) (entities.TInventoryIssueLineEntity, error)
|
||||||
|
GetById(ctx context.Context, tx *gorm.DB, id string) (entities.TInventoryIssueLineEntity, error)
|
||||||
|
GetAllByIssueId(ctx context.Context, issueId string) ([]entities.TInventoryIssueLineEntity, error)
|
||||||
|
Update(ctx context.Context, tx *gorm.DB, line entities.TInventoryIssueLineEntity) (entities.TInventoryIssueLineEntity, error)
|
||||||
|
Delete(ctx context.Context, tx *gorm.DB, id string) error
|
||||||
|
BulkCreate(ctx context.Context, tx *gorm.DB, lines []entities.TInventoryIssueLineEntity) error
|
||||||
|
DeleteByIssueId(ctx context.Context, tx *gorm.DB, issueId string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventoryIssueLineRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInventoryIssueLineRepository(db *gorm.DB) InventoryIssueLineRepository {
|
||||||
|
return &inventoryIssueLineRepository{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) Create(ctx context.Context, tx *gorm.DB, line entities.TInventoryIssueLineEntity) (entities.TInventoryIssueLineEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Create(&line).Error; err != nil {
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
return line, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) GetById(ctx context.Context, tx *gorm.DB, id string) (entities.TInventoryIssueLineEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
var line entities.TInventoryIssueLineEntity
|
||||||
|
if err := tx.WithContext(ctx).Preload("Product").Preload("Warehouse").Preload("Issue").Preload("Client").First(&line, "id = ?", id).Error; err != nil {
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
return line, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) GetAllByIssueId(ctx context.Context, issueId string) ([]entities.TInventoryIssueLineEntity, error) {
|
||||||
|
var lines []entities.TInventoryIssueLineEntity
|
||||||
|
if err := r.db.WithContext(ctx).Where("issue_id = ?", issueId).Preload("Product").Preload("Warehouse").Preload("Issue").Preload("Client").Find(&lines).Error; err != nil {
|
||||||
|
return lines, err
|
||||||
|
}
|
||||||
|
return lines, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) Update(ctx context.Context, tx *gorm.DB, line entities.TInventoryIssueLineEntity) (entities.TInventoryIssueLineEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Model(&entities.TInventoryIssueLineEntity{}).Where("id = ?", line.ID).Select("*").Updates(&line).Error; err != nil {
|
||||||
|
return line, err
|
||||||
|
}
|
||||||
|
return line, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) Delete(ctx context.Context, tx *gorm.DB, id string) error {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Delete(&entities.TInventoryIssueLineEntity{}, "id = ?", id).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) BulkCreate(ctx context.Context, tx *gorm.DB, lines []entities.TInventoryIssueLineEntity) error {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
return tx.WithContext(ctx).Create(&lines).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueLineRepository) DeleteByIssueId(ctx context.Context, tx *gorm.DB, issueId string) error {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
return tx.WithContext(ctx).Where("issue_id = ?", issueId).Delete(&entities.TInventoryIssueLineEntity{}).Error
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
package repository
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/query"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueRepository interface {
|
||||||
|
Create(ctx context.Context, tx *gorm.DB, issue entities.TInventoryIssueEntity) (entities.TInventoryIssueEntity, error)
|
||||||
|
GetById(ctx context.Context, tx *gorm.DB, id string) (entities.TInventoryIssueEntity, error)
|
||||||
|
GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]entities.TInventoryIssueEntity, int64, error)
|
||||||
|
Update(ctx context.Context, tx *gorm.DB, issue entities.TInventoryIssueEntity) (entities.TInventoryIssueEntity, error)
|
||||||
|
Delete(ctx context.Context, tx *gorm.DB, id string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventoryIssueRepository struct {
|
||||||
|
db *gorm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInventoryIssueRepository(db *gorm.DB) InventoryIssueRepository {
|
||||||
|
return &inventoryIssueRepository{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueRepository) Create(ctx context.Context, tx *gorm.DB, issue entities.TInventoryIssueEntity) (entities.TInventoryIssueEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Create(&issue).Error; err != nil {
|
||||||
|
return issue, err
|
||||||
|
}
|
||||||
|
return issue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueRepository) GetById(ctx context.Context, tx *gorm.DB, id string) (entities.TInventoryIssueEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
var issue entities.TInventoryIssueEntity
|
||||||
|
if err := tx.WithContext(ctx).
|
||||||
|
Preload("Client").
|
||||||
|
Preload("IssueLines").
|
||||||
|
Preload("IssueLines.Client").
|
||||||
|
Preload("IssueLines.Product").
|
||||||
|
Preload("IssueLines.Warehouse").
|
||||||
|
Preload("Issuer").
|
||||||
|
Preload("InvRequest").
|
||||||
|
First(&issue, "id = ?", id).Error; err != nil {
|
||||||
|
return issue, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ambil assignment manual
|
||||||
|
var assignment entities.TAssignmentEntity
|
||||||
|
if err := tx.WithContext(ctx).
|
||||||
|
Preload("AssignmentUsers").
|
||||||
|
Preload("AssignmentUsers.User").
|
||||||
|
Preload("AssignmentUsers.Role").
|
||||||
|
First(&assignment, "document_id = ? AND document_type = ?", issue.ID, "InventoryIssue").Error; err == nil {
|
||||||
|
issue.Assignment = assignment
|
||||||
|
}
|
||||||
|
return issue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueRepository) GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]entities.TInventoryIssueEntity, int64, error) {
|
||||||
|
var issues []entities.TInventoryIssueEntity
|
||||||
|
var total int64
|
||||||
|
db := query.ApplyInventoryIssueFilters(r.db, filter)
|
||||||
|
db.Preload("Client").
|
||||||
|
Preload("IssueLines").
|
||||||
|
Preload("IssueLines.Client").
|
||||||
|
Preload("IssueLines.Product").
|
||||||
|
Preload("IssueLines.Warehouse").
|
||||||
|
Preload("Issuer").
|
||||||
|
Preload("InvRequest").
|
||||||
|
Find(&issues).
|
||||||
|
Count(&total)
|
||||||
|
return issues, total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueRepository) Update(ctx context.Context, tx *gorm.DB, issue entities.TInventoryIssueEntity) (entities.TInventoryIssueEntity, error) {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Model(&entities.TInventoryIssueEntity{}).Where("id = ?", issue.ID).Select("*").Updates(&issue).Error; err != nil {
|
||||||
|
return issue, err
|
||||||
|
}
|
||||||
|
return issue, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *inventoryIssueRepository) Delete(ctx context.Context, tx *gorm.DB, id string) error {
|
||||||
|
if tx == nil {
|
||||||
|
tx = r.db
|
||||||
|
}
|
||||||
|
if err := tx.WithContext(ctx).Delete(&entities.TInventoryIssueEntity{}, "id = ?", id).Error; err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package inventoryissue
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/middlewares"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/auth/service"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/controller"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/samber/do"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
|
||||||
|
issueController := do.MustInvoke[controller.InventoryIssueController](injector)
|
||||||
|
jwtService := do.MustInvokeNamed[service.JWTService](injector, constants.JWTService)
|
||||||
|
|
||||||
|
issueRoutes := server.Group("/api/v1/inventory-issues")
|
||||||
|
{
|
||||||
|
issueRoutes.POST("", middlewares.Authenticate(jwtService), issueController.Create)
|
||||||
|
issueRoutes.GET(":id", middlewares.Authenticate(jwtService), issueController.GetById)
|
||||||
|
issueRoutes.PUT(":id", middlewares.Authenticate(jwtService), issueController.Update)
|
||||||
|
issueRoutes.DELETE(":id", middlewares.Authenticate(jwtService), issueController.Delete)
|
||||||
|
issueRoutes.GET("", middlewares.Authenticate(jwtService), issueController.GetAll)
|
||||||
|
issueRoutes.POST(":id/lines", middlewares.Authenticate(jwtService), issueController.CreateLine)
|
||||||
|
issueRoutes.PUT("lines/:id", middlewares.Authenticate(jwtService), issueController.UpdateLine)
|
||||||
|
issueRoutes.DELETE("lines/:id", middlewares.Authenticate(jwtService), issueController.DeleteLine)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,456 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/database/entities"
|
||||||
|
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/dto"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/query"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/repository"
|
||||||
|
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
||||||
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type InventoryIssueService interface {
|
||||||
|
Create(ctx context.Context, req dtodomain.InventoryIssueCreateRequest) (dtodomain.InventoryIssueResponse, error)
|
||||||
|
GetById(ctx context.Context, id string) (dtodomain.InventoryIssueResponse, error)
|
||||||
|
GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error)
|
||||||
|
Update(ctx context.Context, req dtodomain.InventoryIssueUpdateRequest, id string) (dtodomain.InventoryIssueResponse, error)
|
||||||
|
Delete(ctx context.Context, id string) error
|
||||||
|
CreateLine(ctx context.Context, issueId string, req dtodomain.InventoryIssueLineCreateRequest) (dtodomain.InventoryIssueLineResponse, error)
|
||||||
|
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryIssueLineUpdateRequest) (dtodomain.InventoryIssueLineResponse, error)
|
||||||
|
DeleteLine(ctx context.Context, lineId string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type inventoryIssueService struct {
|
||||||
|
db *gorm.DB
|
||||||
|
issueRepo repository.InventoryIssueRepository
|
||||||
|
issueLineRepo repository.InventoryIssueLineRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewInventoryIssueService(db *gorm.DB, issueRepo repository.InventoryIssueRepository, issueLineRepo repository.InventoryIssueLineRepository) InventoryIssueService {
|
||||||
|
return &inventoryIssueService{db: db, issueRepo: issueRepo, issueLineRepo: issueLineRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toInventoryIssueResponse(e entities.TInventoryIssueEntity) dtodomain.InventoryIssueResponse {
|
||||||
|
issuer := pkgdto.IdNameResponse{}
|
||||||
|
if e.Issuer.ID != uuid.Nil {
|
||||||
|
issuer = pkgdto.IdNameResponse{
|
||||||
|
ID: e.Issuer.ID.String(),
|
||||||
|
Name: e.Issuer.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invRequest := pkgdto.IdNameResponse{}
|
||||||
|
if e.InvRequest.ID != uuid.Nil {
|
||||||
|
invRequest = pkgdto.IdNameResponse{
|
||||||
|
ID: e.InvRequest.ID.String(),
|
||||||
|
Name: e.InvRequest.DocumentNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
client := pkgdto.IdNameResponse{}
|
||||||
|
if e.Client.ID != uuid.Nil {
|
||||||
|
client = pkgdto.IdNameResponse{
|
||||||
|
ID: e.Client.ID.String(),
|
||||||
|
Name: e.Client.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assignment := dtodomain.AssignmentResponse{}
|
||||||
|
if e.Assignment.ID != uuid.Nil {
|
||||||
|
assignment = toAssignmentResponse(e.Assignment)
|
||||||
|
}
|
||||||
|
lines := make([]dtodomain.InventoryIssueLineResponse, 0)
|
||||||
|
for _, line := range e.IssueLines {
|
||||||
|
product := dtodomain.InventoryIssueProductResponse{}
|
||||||
|
if line.Product.ID != uuid.Nil {
|
||||||
|
product = dtodomain.InventoryIssueProductResponse{
|
||||||
|
ID: line.Product.ID.String(),
|
||||||
|
RefNumber: line.Product.RefNumber,
|
||||||
|
Name: line.Product.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warehouse := pkgdto.IdNameResponse{}
|
||||||
|
if line.Warehouse.ID != uuid.Nil {
|
||||||
|
warehouse = pkgdto.IdNameResponse{
|
||||||
|
ID: line.Warehouse.ID.String(),
|
||||||
|
Name: line.Warehouse.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientLine := pkgdto.IdNameResponse{}
|
||||||
|
if line.Client.ID != uuid.Nil {
|
||||||
|
clientLine = pkgdto.IdNameResponse{
|
||||||
|
ID: line.Client.ID.String(),
|
||||||
|
Name: line.Client.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lines = append(lines, dtodomain.InventoryIssueLineResponse{
|
||||||
|
ID: line.ID.String(),
|
||||||
|
CurrentStock: line.CurrentStock,
|
||||||
|
MinStock: line.MinStock,
|
||||||
|
RequestQuantity: line.RequestQuantity,
|
||||||
|
IssuedQuantity: line.IssuedQuantity,
|
||||||
|
Remarks: line.Remarks,
|
||||||
|
Product: product,
|
||||||
|
Warehouse: warehouse,
|
||||||
|
Client: clientLine,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return dtodomain.InventoryIssueResponse{
|
||||||
|
ID: e.ID.String(),
|
||||||
|
DocumentNumber: e.DocumentNumber,
|
||||||
|
DocumentDate: utils.DateTimeToString(e.DocumentDate),
|
||||||
|
DueDate: utils.DateTimeToString(e.DueDate),
|
||||||
|
Status: e.Status,
|
||||||
|
IssuerBy: issuer,
|
||||||
|
InvRequest: invRequest,
|
||||||
|
Client: client,
|
||||||
|
LineCount: len(lines),
|
||||||
|
IssueLines: lines,
|
||||||
|
Assignment: assignment,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toAssignmentResponse(e entities.TAssignmentEntity) dtodomain.AssignmentResponse {
|
||||||
|
// client := pkgdto.IdNameResponse{}
|
||||||
|
// if e.Client.ID != uuid.Nil {
|
||||||
|
// client = pkgdto.IdNameResponse{
|
||||||
|
// ID: e.Client.ID.String(),
|
||||||
|
// Name: e.Client.Name,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
users := make([]dtodomain.AssignmentUserResponse, 0)
|
||||||
|
for _, user := range e.AssignmentUsers {
|
||||||
|
userResp := dtodomain.AssignmentUserResponse{
|
||||||
|
ID: user.ID.String(),
|
||||||
|
TaskType: user.TaskType,
|
||||||
|
User: pkgdto.IdNameResponse{ID: user.User.ID.String(), Name: user.User.Name},
|
||||||
|
Role: pkgdto.IdNameResponse{ID: user.Role.ID.String(), Name: user.Role.Name},
|
||||||
|
// Client: pkgdto.IdNameResponse{ID: user.Client.ID.String(), Name: user.Client.Name},
|
||||||
|
}
|
||||||
|
users = append(users, userResp)
|
||||||
|
}
|
||||||
|
return dtodomain.AssignmentResponse{
|
||||||
|
ID: e.ID.String(),
|
||||||
|
DocumentType: e.DocumentType,
|
||||||
|
DocumentID: e.DocumentID.String(),
|
||||||
|
// Client: client,
|
||||||
|
AssignmentUsers: users,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) Create(ctx context.Context, req dtodomain.InventoryIssueCreateRequest) (dtodomain.InventoryIssueResponse, error) {
|
||||||
|
tx := s.db.Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
clientUUID, err := uuid.Parse(req.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
issuerUUID, err := uuid.Parse(req.IssuerBy)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
invRequestUUID, err := uuid.Parse(req.InvRequestID)
|
||||||
|
if err != nil && req.InvRequestID != "" {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
docNum, err := entities.GenerateDocumentNumberInvIssue(s.db, req.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
issue := entities.TInventoryIssueEntity{
|
||||||
|
DocumentNumber: docNum,
|
||||||
|
DocumentDate: utils.StringToDateTime(req.DocumentDate),
|
||||||
|
DueDate: utils.StringToDateTime(req.DueDate),
|
||||||
|
IssuerBy: issuerUUID,
|
||||||
|
InvRequestID: invRequestUUID,
|
||||||
|
ClientID: clientUUID,
|
||||||
|
Status: req.Status,
|
||||||
|
}
|
||||||
|
created, err := s.issueRepo.Create(ctx, tx, issue)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
// Bulk create lines
|
||||||
|
var lines []entities.TInventoryIssueLineEntity
|
||||||
|
for _, lineReq := range req.IssueLines {
|
||||||
|
productUUID, err := uuid.Parse(lineReq.ProductID)
|
||||||
|
if err != nil && lineReq.ProductID != "" {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
warehouseUUID, err := uuid.Parse(lineReq.WarehouseID)
|
||||||
|
if err != nil && lineReq.WarehouseID != "" {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
clientLineUUID, err := uuid.Parse(lineReq.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
lines = append(lines, entities.TInventoryIssueLineEntity{
|
||||||
|
CurrentStock: lineReq.CurrentStock,
|
||||||
|
MinStock: lineReq.MinStock,
|
||||||
|
RequestQuantity: lineReq.RequestQuantity,
|
||||||
|
IssuedQuantity: lineReq.IssuedQuantity,
|
||||||
|
Remarks: lineReq.Remarks,
|
||||||
|
InvIssueID: created.ID,
|
||||||
|
ProductID: productUUID,
|
||||||
|
WarehouseID: warehouseUUID,
|
||||||
|
ClientID: clientLineUUID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if len(lines) > 0 {
|
||||||
|
err = s.issueLineRepo.BulkCreate(ctx, tx, lines)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
result, err := s.issueRepo.GetById(ctx, nil, created.ID.String())
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
return toInventoryIssueResponse(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) GetById(ctx context.Context, id string) (dtodomain.InventoryIssueResponse, error) {
|
||||||
|
issue, err := s.issueRepo.GetById(ctx, nil, id)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
return toInventoryIssueResponse(issue), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) GetAll(ctx context.Context, filter query.InventoryIssueFilter) ([]dtodomain.InventoryIssueResponse, int64, error) {
|
||||||
|
issues, total, err := s.issueRepo.GetAll(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
var responses []dtodomain.InventoryIssueResponse
|
||||||
|
for _, e := range issues {
|
||||||
|
responses = append(responses, toInventoryIssueResponse(e))
|
||||||
|
}
|
||||||
|
if responses == nil {
|
||||||
|
responses = make([]dtodomain.InventoryIssueResponse, 0)
|
||||||
|
}
|
||||||
|
return responses, total, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) Update(ctx context.Context, req dtodomain.InventoryIssueUpdateRequest, id string) (dtodomain.InventoryIssueResponse, error) {
|
||||||
|
tx := s.db.Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
issue, err := s.issueRepo.GetById(ctx, tx, id)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
issue.DocumentDate = utils.StringToDateTime(req.DocumentDate)
|
||||||
|
issue.DueDate = utils.StringToDateTime(req.DueDate)
|
||||||
|
issue.Status = req.Status
|
||||||
|
updated, err := s.issueRepo.Update(ctx, tx, issue)
|
||||||
|
if err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
result, err := s.issueRepo.GetById(ctx, nil, updated.ID.String())
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueResponse{}, err
|
||||||
|
}
|
||||||
|
return toInventoryIssueResponse(result), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) Delete(ctx context.Context, id string) error {
|
||||||
|
tx := s.db.Begin()
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if err := s.issueRepo.Delete(ctx, tx, id); err != nil {
|
||||||
|
tx.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) CreateLine(ctx context.Context, issueId string, req dtodomain.InventoryIssueLineCreateRequest) (dtodomain.InventoryIssueLineResponse, error) {
|
||||||
|
issueUUID, err := uuid.Parse(issueId)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
productUUID, err := uuid.Parse(req.ProductID)
|
||||||
|
if err != nil && req.ProductID != "" {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
warehouseUUID, err := uuid.Parse(req.WarehouseID)
|
||||||
|
if err != nil && req.WarehouseID != "" {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
clientLineUUID, err := uuid.Parse(req.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
line := entities.TInventoryIssueLineEntity{
|
||||||
|
CurrentStock: req.CurrentStock,
|
||||||
|
MinStock: req.MinStock,
|
||||||
|
RequestQuantity: req.RequestQuantity,
|
||||||
|
IssuedQuantity: req.IssuedQuantity,
|
||||||
|
Remarks: req.Remarks,
|
||||||
|
InvIssueID: issueUUID,
|
||||||
|
ProductID: productUUID,
|
||||||
|
WarehouseID: warehouseUUID,
|
||||||
|
ClientID: clientLineUUID,
|
||||||
|
}
|
||||||
|
created, err := s.issueLineRepo.Create(ctx, nil, line)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
product := dtodomain.InventoryIssueProductResponse{}
|
||||||
|
if created.Product.ID != uuid.Nil {
|
||||||
|
product = dtodomain.InventoryIssueProductResponse{
|
||||||
|
ID: created.Product.ID.String(),
|
||||||
|
RefNumber: created.Product.RefNumber,
|
||||||
|
Name: created.Product.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warehouse := pkgdto.IdNameResponse{}
|
||||||
|
if created.Warehouse.ID != uuid.Nil {
|
||||||
|
warehouse = pkgdto.IdNameResponse{
|
||||||
|
ID: created.Warehouse.ID.String(),
|
||||||
|
Name: created.Warehouse.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientLine := pkgdto.IdNameResponse{}
|
||||||
|
if created.Client.ID != uuid.Nil {
|
||||||
|
clientLine = pkgdto.IdNameResponse{
|
||||||
|
ID: created.Client.ID.String(),
|
||||||
|
Name: created.Client.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtodomain.InventoryIssueLineResponse{
|
||||||
|
ID: created.ID.String(),
|
||||||
|
CurrentStock: created.CurrentStock,
|
||||||
|
MinStock: created.MinStock,
|
||||||
|
RequestQuantity: created.RequestQuantity,
|
||||||
|
IssuedQuantity: created.IssuedQuantity,
|
||||||
|
Remarks: created.Remarks,
|
||||||
|
Product: product,
|
||||||
|
Warehouse: warehouse,
|
||||||
|
Client: clientLine,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryIssueLineUpdateRequest) (dtodomain.InventoryIssueLineResponse, error) {
|
||||||
|
line, err := s.issueLineRepo.GetById(ctx, nil, lineId)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
if req.CurrentStock != nil {
|
||||||
|
line.CurrentStock = *req.CurrentStock
|
||||||
|
}
|
||||||
|
if req.MinStock != nil {
|
||||||
|
line.MinStock = *req.MinStock
|
||||||
|
}
|
||||||
|
if req.RequestQuantity != nil {
|
||||||
|
line.RequestQuantity = *req.RequestQuantity
|
||||||
|
}
|
||||||
|
if req.IssuedQuantity != nil {
|
||||||
|
line.IssuedQuantity = *req.IssuedQuantity
|
||||||
|
}
|
||||||
|
if req.Remarks != nil {
|
||||||
|
line.Remarks = *req.Remarks
|
||||||
|
}
|
||||||
|
if req.ProductID != nil {
|
||||||
|
if *req.ProductID != "" {
|
||||||
|
tmp, err := uuid.Parse(*req.ProductID)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
line.ProductID = tmp
|
||||||
|
} else {
|
||||||
|
line.ProductID = uuid.Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.WarehouseID != nil {
|
||||||
|
if *req.WarehouseID != "" {
|
||||||
|
tmp, err := uuid.Parse(*req.WarehouseID)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
line.WarehouseID = tmp
|
||||||
|
} else {
|
||||||
|
line.WarehouseID = uuid.Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if req.ClientID != nil {
|
||||||
|
if *req.ClientID != "" {
|
||||||
|
tmp, err := uuid.Parse(*req.ClientID)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
line.ClientID = tmp
|
||||||
|
} else {
|
||||||
|
line.ClientID = uuid.Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updated, err := s.issueLineRepo.Update(ctx, nil, line)
|
||||||
|
if err != nil {
|
||||||
|
return dtodomain.InventoryIssueLineResponse{}, err
|
||||||
|
}
|
||||||
|
product := dtodomain.InventoryIssueProductResponse{}
|
||||||
|
if updated.Product.ID != uuid.Nil {
|
||||||
|
product = dtodomain.InventoryIssueProductResponse{
|
||||||
|
ID: updated.Product.ID.String(),
|
||||||
|
RefNumber: updated.Product.RefNumber,
|
||||||
|
Name: updated.Product.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warehouse := pkgdto.IdNameResponse{}
|
||||||
|
if updated.Warehouse.ID != uuid.Nil {
|
||||||
|
warehouse = pkgdto.IdNameResponse{
|
||||||
|
ID: updated.Warehouse.ID.String(),
|
||||||
|
Name: updated.Warehouse.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clientLine := pkgdto.IdNameResponse{}
|
||||||
|
if updated.Client.ID != uuid.Nil {
|
||||||
|
clientLine = pkgdto.IdNameResponse{
|
||||||
|
ID: updated.Client.ID.String(),
|
||||||
|
Name: updated.Client.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dtodomain.InventoryIssueLineResponse{
|
||||||
|
ID: updated.ID.String(),
|
||||||
|
CurrentStock: updated.CurrentStock,
|
||||||
|
MinStock: updated.MinStock,
|
||||||
|
RequestQuantity: updated.RequestQuantity,
|
||||||
|
IssuedQuantity: updated.IssuedQuantity,
|
||||||
|
Remarks: updated.Remarks,
|
||||||
|
Product: product,
|
||||||
|
Warehouse: warehouse,
|
||||||
|
Client: clientLine,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *inventoryIssueService) DeleteLine(ctx context.Context, lineId string) error {
|
||||||
|
return s.issueLineRepo.Delete(ctx, nil, lineId)
|
||||||
|
}
|
||||||
|
|
@ -45,14 +45,20 @@ func (r *inventoryReceiptRepository) GetById(ctx context.Context, tx *gorm.DB, i
|
||||||
Preload("ReceiptLines.Product").
|
Preload("ReceiptLines.Product").
|
||||||
Preload("ReceiptLines.Product.Uom").
|
Preload("ReceiptLines.Product.Uom").
|
||||||
Preload("ReceiptLines.Product.DimUom").
|
Preload("ReceiptLines.Product.DimUom").
|
||||||
Preload("Assignment").
|
|
||||||
Preload("Assignment.AssignmentUsers").
|
|
||||||
Preload("Assignment.AssignmentUsers.User").
|
|
||||||
Preload("Assignment.AssignmentUsers.Role").
|
|
||||||
First(&receipt, "id = ?", id).Error; err != nil {
|
First(&receipt, "id = ?", id).Error; err != nil {
|
||||||
return receipt, err
|
return receipt, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ambil assignment manual
|
||||||
|
var assignment entities.TAssignmentEntity
|
||||||
|
if err := tx.WithContext(ctx).
|
||||||
|
Preload("AssignmentUsers").
|
||||||
|
Preload("AssignmentUsers.User").
|
||||||
|
Preload("AssignmentUsers.Role").
|
||||||
|
First(&assignment, "document_id = ? AND document_type = ?", receipt.ID, "InventoryReceipt").Error; err == nil {
|
||||||
|
receipt.Assignment = assignment
|
||||||
|
}
|
||||||
|
|
||||||
return receipt, nil
|
return receipt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,19 @@ func (r *inventoryRequestRepository) GetById(ctx context.Context, tx *gorm.DB, i
|
||||||
Preload("Client").
|
Preload("Client").
|
||||||
Preload("RequestLines").
|
Preload("RequestLines").
|
||||||
Preload("RequestLines.Product").
|
Preload("RequestLines.Product").
|
||||||
Preload("Assignment").
|
|
||||||
Preload("Assignment.AssignmentUsers").
|
|
||||||
Preload("Assignment.AssignmentUsers.User").
|
|
||||||
Preload("Assignment.AssignmentUsers.Role").
|
|
||||||
First(&request, "id = ?", id).Error; err != nil {
|
First(&request, "id = ?", id).Error; err != nil {
|
||||||
return request, err
|
return request, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ambil assignment manual
|
||||||
|
var assignment entities.TAssignmentEntity
|
||||||
|
if err := tx.WithContext(ctx).
|
||||||
|
Preload("AssignmentUsers").
|
||||||
|
Preload("AssignmentUsers.User").
|
||||||
|
Preload("AssignmentUsers.Role").
|
||||||
|
First(&assignment, "document_id = ? AND document_type = ?", request.ID, "InventoryRequest").Error; err == nil {
|
||||||
|
request.Assignment = assignment
|
||||||
|
}
|
||||||
return request, nil
|
return request, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,11 @@ import (
|
||||||
inventoryRequestRepo "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository"
|
inventoryRequestRepo "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository"
|
||||||
inventoryRequestService "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/service"
|
inventoryRequestService "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/service"
|
||||||
|
|
||||||
|
inventoryIssueController "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/controller"
|
||||||
|
inventoryIssueLineRepo "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/repository"
|
||||||
|
inventoryIssueRepo "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/repository"
|
||||||
|
inventoryIssueService "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_issue/service"
|
||||||
|
|
||||||
"github.com/Caknoooo/go-gin-clean-starter/modules/user/controller"
|
"github.com/Caknoooo/go-gin-clean-starter/modules/user/controller"
|
||||||
"github.com/Caknoooo/go-gin-clean-starter/modules/user/repository"
|
"github.com/Caknoooo/go-gin-clean-starter/modules/user/repository"
|
||||||
userService "github.com/Caknoooo/go-gin-clean-starter/modules/user/service"
|
userService "github.com/Caknoooo/go-gin-clean-starter/modules/user/service"
|
||||||
|
|
@ -128,6 +133,8 @@ func RegisterDependencies(injector *do.Injector) {
|
||||||
assignmentUserRepository := assignmentUserRepo.NewAssignmentUserRepository(db)
|
assignmentUserRepository := assignmentUserRepo.NewAssignmentUserRepository(db)
|
||||||
inventoryRequestRepository := inventoryRequestRepo.NewInventoryRequestRepository(db)
|
inventoryRequestRepository := inventoryRequestRepo.NewInventoryRequestRepository(db)
|
||||||
inventoryRequestLineRepository := inventoryRequestLineRepo.NewInventoryRequestLineRepository(db)
|
inventoryRequestLineRepository := inventoryRequestLineRepo.NewInventoryRequestLineRepository(db)
|
||||||
|
inventoryIssueRepository := inventoryIssueRepo.NewInventoryIssueRepository(db)
|
||||||
|
inventoryIssueLineRepository := inventoryIssueLineRepo.NewInventoryIssueLineRepository(db)
|
||||||
|
|
||||||
// Service
|
// Service
|
||||||
userServ := userService.NewUserService(userRepository, refreshTokenRepository, jwtService, db)
|
userServ := userService.NewUserService(userRepository, refreshTokenRepository, jwtService, db)
|
||||||
|
|
@ -146,6 +153,7 @@ func RegisterDependencies(injector *do.Injector) {
|
||||||
inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository)
|
inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository)
|
||||||
assignmentServ := assignmentService.NewAssignmentService(db, assignmentRepository, assignmentUserRepository)
|
assignmentServ := assignmentService.NewAssignmentService(db, assignmentRepository, assignmentUserRepository)
|
||||||
inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository)
|
inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository)
|
||||||
|
inventoryIssueServ := inventoryIssueService.NewInventoryIssueService(db, inventoryIssueRepository, inventoryIssueLineRepository)
|
||||||
|
|
||||||
// Controller
|
// Controller
|
||||||
do.Provide(
|
do.Provide(
|
||||||
|
|
@ -238,4 +246,9 @@ func RegisterDependencies(injector *do.Injector) {
|
||||||
return inventoryRequestController.NewInventoryRequestController(i, inventoryRequestServ), nil
|
return inventoryRequestController.NewInventoryRequestController(i, inventoryRequestServ), nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
do.Provide(
|
||||||
|
injector, func(i *do.Injector) (inventoryIssueController.InventoryIssueController, error) {
|
||||||
|
return inventoryIssueController.NewInventoryIssueController(i, inventoryIssueServ), nil
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue