388 lines
12 KiB
Go
388 lines
12 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_request/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/query"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository"
|
|
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
|
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
|
|
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/pkg/utils"
|
|
"github.com/google/uuid"
|
|
"github.com/sirupsen/logrus"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type InventoryRequestService interface {
|
|
Create(ctx context.Context, req dtodomain.InventoryRequestCreateRequest) (dtodomain.InventoryRequestResponse, error)
|
|
GetById(ctx context.Context, id string) (dtodomain.InventoryRequestResponse, error)
|
|
GetAll(ctx context.Context, filter query.InventoryRequestFilter) ([]dtodomain.InventoryRequestResponse, int64, error)
|
|
Update(ctx context.Context, req dtodomain.InventoryRequestUpdateRequest, id string) (dtodomain.InventoryRequestResponse, error)
|
|
Delete(ctx context.Context, id string) error
|
|
GetLinesByRequestId(ctx context.Context, requestId string) ([]dtodomain.InventoryRequestLineResponse, error)
|
|
GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryRequestLineResponse, error)
|
|
CreateLine(ctx context.Context, requestId string, req dtodomain.InventoryRequestLineCreateRequest) (dtodomain.InventoryRequestLineResponse, error)
|
|
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryRequestLineUpdateRequest) (dtodomain.InventoryRequestLineResponse, error)
|
|
DeleteLine(ctx context.Context, lineId string) error
|
|
}
|
|
|
|
type inventoryRequestService struct {
|
|
db *gorm.DB
|
|
requestRepo repository.InventoryRequestRepository
|
|
requestLineRepo repository.InventoryRequestLineRepository
|
|
sequenceService sequenceservice.SequenceService
|
|
log *logrus.Logger
|
|
}
|
|
|
|
// GetLineById implements InventoryRequestService.
|
|
func (s *inventoryRequestService) GetLineById(ctx context.Context, lineId string) (dtodomain.InventoryRequestLineResponse, error) {
|
|
line, err := s.requestLineRepo.GetById(ctx, nil, lineId)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
return dtodomain.ToInventoryRequestLineResponse(line), nil
|
|
}
|
|
|
|
// GetLinesByRequestId implements InventoryRequestService.
|
|
func (s *inventoryRequestService) GetLinesByRequestId(ctx context.Context, requestId string) ([]dtodomain.InventoryRequestLineResponse, error) {
|
|
lines, err := s.requestLineRepo.GetAllByRequestId(ctx, requestId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return dtodomain.ToInventoryRequestLineResponses(lines), nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) DeleteLine(ctx context.Context, lineId string) error {
|
|
line, err := s.requestLineRepo.GetById(ctx, nil, lineId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
|
|
_, err = s.requestLineRepo.Update(ctx, nil, line)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
result := s.requestLineRepo.Delete(ctx, nil, lineId)
|
|
if result != nil {
|
|
return result
|
|
}
|
|
|
|
s.log.WithFields(logrus.Fields{
|
|
"user_id": utils.GetUserID(ctx),
|
|
"action": constants.DELETE,
|
|
"entity": "inventory_request_line",
|
|
"entity_id": lineId,
|
|
}).Info("Inventory Request Line deleted")
|
|
return nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryRequestLineUpdateRequest) (dtodomain.InventoryRequestLineResponse, error) {
|
|
line, err := s.requestLineRepo.GetById(ctx, nil, lineId)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
before := line
|
|
|
|
line.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
|
|
|
|
if req.Quantity != nil {
|
|
line.Quantity = *req.Quantity
|
|
}
|
|
if req.ProductID != nil {
|
|
if *req.ProductID != "" {
|
|
tmp, err := uuid.Parse(*req.ProductID)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
line.ProductID = tmp
|
|
} else {
|
|
line.ProductID = uuid.Nil
|
|
}
|
|
}
|
|
updated, err := s.requestLineRepo.Update(ctx, nil, line)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
|
|
changes := utils.GetChangedFields(before, updated)
|
|
s.log.WithFields(logrus.Fields{
|
|
"user_id": utils.GetUserID(ctx),
|
|
"action": constants.UPDATE,
|
|
"entity": "inventory_request_line",
|
|
"entity_id": lineId,
|
|
"changes": changes,
|
|
}).Info("Inventory Request Line updated")
|
|
|
|
product := dtodomain.InventoryRequestLineProductResponse{}
|
|
if updated.Product.ID != uuid.Nil {
|
|
product = dtodomain.InventoryRequestLineProductResponse{
|
|
ID: updated.Product.ID.String(),
|
|
Name: updated.Product.Name,
|
|
RefNumber: updated.Product.RefNumber,
|
|
Uom: pkgdto.IdNameResponse{
|
|
ID: updated.Product.Uom.ID.String(),
|
|
Name: updated.Product.Uom.Name,
|
|
},
|
|
}
|
|
}
|
|
return dtodomain.InventoryRequestLineResponse{
|
|
ID: updated.ID.String(),
|
|
Quantity: updated.Quantity,
|
|
Product: product,
|
|
ClientID: updated.ClientID.String(),
|
|
}, nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) Create(ctx context.Context, req dtodomain.InventoryRequestCreateRequest) (dtodomain.InventoryRequestResponse, 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.InventoryRequestResponse{}, err
|
|
}
|
|
docNum, err := s.sequenceService.GenerateDocumentNumber(ctx, req.ClientID, "RQST", pkgdto.SequenceConfig{
|
|
Prefix: "RQST",
|
|
EntityType: "INV_REQUEST",
|
|
Period: "",
|
|
})
|
|
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
request := entities.TInventoryRequestEntity{
|
|
ReferenceNumber: req.ReferenceNumber,
|
|
DocumentNumber: docNum,
|
|
DueDate: utils.StringToDateTime(req.DueDate),
|
|
RequestType: req.RequestType,
|
|
Note: req.Note,
|
|
ClientID: clientUUID,
|
|
Status: req.Status,
|
|
FullAuditTrail: utils.FillAuditTrail(ctx, constants.CREATE),
|
|
}
|
|
created, err := s.requestRepo.Create(ctx, tx, request)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
var lines []entities.TInventoryRequestLineEntity
|
|
for _, lineReq := range req.RequestLines {
|
|
var productUUID uuid.UUID
|
|
if lineReq.ProductID != "" {
|
|
productUUID, err = uuid.Parse(lineReq.ProductID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
} else {
|
|
productUUID = uuid.Nil
|
|
}
|
|
clientLineUUID, err := uuid.Parse(lineReq.ClientID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
lines = append(lines, entities.TInventoryRequestLineEntity{
|
|
Quantity: lineReq.Quantity,
|
|
InvRequestID: created.ID,
|
|
ProductID: productUUID,
|
|
ClientID: clientLineUUID,
|
|
})
|
|
}
|
|
if len(lines) > 0 {
|
|
err = s.requestLineRepo.BulkCreate(ctx, tx, lines)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
}
|
|
tx.Commit()
|
|
|
|
// Log the creation of the inventory request
|
|
s.log.WithFields(logrus.Fields{
|
|
"user_id": utils.GetUserID(ctx),
|
|
"action": constants.CREATE,
|
|
"entity": "inventory_request",
|
|
"entity_id": created.ID.String(),
|
|
}).Info("Inventory Request created")
|
|
|
|
result, err := s.requestRepo.GetById(ctx, nil, created.ID.String())
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
return dtodomain.ToInventoryRequestResponse(result), nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) GetById(ctx context.Context, id string) (dtodomain.InventoryRequestResponse, error) {
|
|
request, err := s.requestRepo.GetById(ctx, nil, id)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
return dtodomain.ToInventoryRequestResponse(request), nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) GetAll(ctx context.Context, filter query.InventoryRequestFilter) ([]dtodomain.InventoryRequestResponse, int64, error) {
|
|
requests, total, err := s.requestRepo.GetAll(ctx, filter)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
var responses []dtodomain.InventoryRequestResponse
|
|
for _, e := range requests {
|
|
responses = append(responses, dtodomain.ToInventoryRequestResponse(e))
|
|
}
|
|
if responses == nil {
|
|
responses = make([]dtodomain.InventoryRequestResponse, 0)
|
|
}
|
|
return responses, total, nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) Update(ctx context.Context, req dtodomain.InventoryRequestUpdateRequest, id string) (dtodomain.InventoryRequestResponse, error) {
|
|
tx := s.db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
request, err := s.requestRepo.GetById(ctx, tx, id)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
|
|
before := request
|
|
|
|
request.FullAuditTrail = utils.FillAuditTrail(ctx, constants.UPDATE)
|
|
|
|
if req.ReferenceNumber != "" {
|
|
request.ReferenceNumber = req.ReferenceNumber
|
|
}
|
|
request.DocumentNumber = req.DocumentNumber
|
|
request.DueDate = utils.StringToDateTime(req.DueDate)
|
|
request.RequestType = req.RequestType
|
|
request.Note = req.Note
|
|
request.Status = req.Status
|
|
updated, err := s.requestRepo.Update(ctx, tx, request)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
tx.Commit()
|
|
result, err := s.requestRepo.GetById(ctx, nil, updated.ID.String())
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestResponse{}, err
|
|
}
|
|
|
|
changes := utils.GetChangedFields(before, result)
|
|
s.log.WithFields(logrus.Fields{
|
|
"user_id": utils.GetUserID(ctx),
|
|
"action": constants.UPDATE,
|
|
"entity": "inventory_request",
|
|
"entity_id": id,
|
|
"changes": changes,
|
|
}).Info("Inventory Request updated")
|
|
return dtodomain.ToInventoryRequestResponse(result), nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) Delete(ctx context.Context, id string) error {
|
|
tx := s.db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
request, err := s.requestRepo.GetById(ctx, tx, id)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
request.FullAuditTrail = utils.FillAuditTrail(ctx, constants.DELETE)
|
|
if _, err := s.requestRepo.Update(ctx, tx, request); err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
|
|
if err := s.requestRepo.Delete(ctx, tx, id); err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
tx.Commit()
|
|
|
|
s.log.WithFields(logrus.Fields{
|
|
"user_id": utils.GetUserID(ctx),
|
|
"action": constants.DELETE,
|
|
"entity": "inventory_request",
|
|
"entity_id": id,
|
|
}).Info("Inventory Request deleted")
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *inventoryRequestService) CreateLine(ctx context.Context, requestId string, req dtodomain.InventoryRequestLineCreateRequest) (dtodomain.InventoryRequestLineResponse, error) {
|
|
requestUUID, err := uuid.Parse(requestId)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
var productUUID uuid.UUID
|
|
if req.ProductID != "" {
|
|
productUUID, err = uuid.Parse(req.ProductID)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
} else {
|
|
productUUID = uuid.Nil
|
|
}
|
|
clientLineUUID, err := uuid.Parse(req.ClientID)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
line := entities.TInventoryRequestLineEntity{
|
|
Quantity: req.Quantity,
|
|
InvRequestID: requestUUID,
|
|
ProductID: productUUID,
|
|
ClientID: clientLineUUID,
|
|
}
|
|
created, err := s.requestLineRepo.Create(ctx, nil, line)
|
|
if err != nil {
|
|
return dtodomain.InventoryRequestLineResponse{}, err
|
|
}
|
|
product := dtodomain.InventoryRequestLineProductResponse{}
|
|
if created.Product.ID != uuid.Nil {
|
|
product = dtodomain.InventoryRequestLineProductResponse{
|
|
ID: created.Product.ID.String(),
|
|
Name: created.Product.Name,
|
|
RefNumber: created.Product.RefNumber,
|
|
Uom: pkgdto.IdNameResponse{
|
|
ID: created.Product.Uom.ID.String(),
|
|
Name: created.Product.Uom.Name,
|
|
},
|
|
}
|
|
}
|
|
return dtodomain.InventoryRequestLineResponse{
|
|
ID: created.ID.String(),
|
|
Quantity: created.Quantity,
|
|
Product: product,
|
|
ClientID: created.ClientID.String(),
|
|
}, nil
|
|
}
|
|
|
|
func NewInventoryRequestService(db *gorm.DB, requestRepo repository.InventoryRequestRepository, requestLineRepo repository.InventoryRequestLineRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryRequestService {
|
|
return &inventoryRequestService{
|
|
db: db,
|
|
requestRepo: requestRepo,
|
|
requestLineRepo: requestLineRepo,
|
|
sequenceService: sequenceService,
|
|
log: log,
|
|
}
|
|
}
|