457 lines
14 KiB
Go
457 lines
14 KiB
Go
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)
|
|
}
|