465 lines
15 KiB
Go
465 lines
15 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_receipt/dto"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_receipt/query"
|
|
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_receipt/repository"
|
|
productrepository "github.com/Caknoooo/go-gin-clean-starter/modules/product/repository"
|
|
uomrepository "github.com/Caknoooo/go-gin-clean-starter/modules/uom/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 InventoryReceiptService interface {
|
|
Create(ctx context.Context, req dtodomain.InventoryReceiptCreateRequest) (dtodomain.InventoryReceiptResponse, error)
|
|
GetById(ctx context.Context, id string) (dtodomain.InventoryReceiptResponse, error)
|
|
GetAll(ctx context.Context, filter query.InventoryReceiptFilter) ([]dtodomain.InventoryReceiptResponse, int64, error)
|
|
Update(ctx context.Context, req dtodomain.InventoryReceiptUpdateRequest, id string) (dtodomain.InventoryReceiptResponse, error)
|
|
Delete(ctx context.Context, id string) error
|
|
CreateLine(ctx context.Context, receiptId string, req dtodomain.InventoryReceiptLineCreateRequest) (dtodomain.InventoryReceiptLineResponse, error)
|
|
UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryReceiptLineUpdateRequest) (dtodomain.InventoryReceiptLineResponse, error)
|
|
DeleteLine(ctx context.Context, lineId string) error
|
|
}
|
|
|
|
type inventoryReceiptService struct {
|
|
db *gorm.DB
|
|
receiptRepo repository.InventoryReceiptRepository
|
|
receiptLineRepo repository.InventoryReceiptLineRepository
|
|
productRepo productrepository.ProductRepository
|
|
uomRepo uomrepository.UomRepository
|
|
}
|
|
|
|
// DeleteLine implements InventoryReceiptService.
|
|
func (s *inventoryReceiptService) DeleteLine(ctx context.Context, lineId string) error {
|
|
return s.receiptLineRepo.Delete(ctx, nil, lineId)
|
|
}
|
|
|
|
// UpdateLine implements InventoryReceiptService.
|
|
func (s *inventoryReceiptService) UpdateLine(ctx context.Context, lineId string, req dtodomain.InventoryReceiptLineUpdateRequest) (dtodomain.InventoryReceiptLineResponse, error) {
|
|
line, err := s.receiptLineRepo.GetById(ctx, nil, lineId)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
if req.Quantity != nil {
|
|
line.Quantity = *req.Quantity
|
|
}
|
|
if req.BatchNumber != nil {
|
|
line.BatchNumber = *req.BatchNumber
|
|
}
|
|
if req.RepackingSuggestion != nil {
|
|
line.RepackingSuggestion = *req.RepackingSuggestion
|
|
}
|
|
if req.RepackUomID != nil {
|
|
if *req.RepackUomID != "" {
|
|
tmp, err := uuid.Parse(*req.RepackUomID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
line.RepackUomID = &tmp
|
|
} else {
|
|
line.RepackUomID = nil
|
|
}
|
|
}
|
|
if req.ProductID != nil {
|
|
if *req.ProductID != "" {
|
|
tmp, err := uuid.Parse(*req.ProductID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
line.ProductID = tmp
|
|
} else {
|
|
line.ProductID = uuid.Nil
|
|
}
|
|
}
|
|
updated, err := s.receiptLineRepo.Update(ctx, nil, line)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
var repackUomID *string
|
|
if updated.RepackUomID != nil {
|
|
tmp := updated.RepackUomID.String()
|
|
repackUomID = &tmp
|
|
}
|
|
product := dtodomain.InventoryReceiptLineProductResponse{}
|
|
if updated.Product.ID != uuid.Nil {
|
|
product = dtodomain.InventoryReceiptLineProductResponse{
|
|
ID: updated.Product.ID.String(),
|
|
Name: updated.Product.Name,
|
|
}
|
|
}
|
|
return dtodomain.InventoryReceiptLineResponse{
|
|
ID: updated.ID.String(),
|
|
Quantity: updated.Quantity,
|
|
BatchNumber: updated.BatchNumber,
|
|
RepackingSuggestion: updated.RepackingSuggestion,
|
|
RepackUomID: repackUomID,
|
|
Product: product,
|
|
ClientID: updated.ClientID.String(),
|
|
}, nil
|
|
}
|
|
|
|
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 toInventoryReceiptResponse(e entities.TInventoryReceiptEntity) dtodomain.InventoryReceiptResponse {
|
|
client := pkgdto.IdNameResponse{}
|
|
if e.Client.ID != uuid.Nil {
|
|
client = pkgdto.IdNameResponse{
|
|
ID: e.Client.ID.String(),
|
|
Name: e.Client.Name,
|
|
}
|
|
}
|
|
|
|
lines := make([]dtodomain.InventoryReceiptLineResponse, 0)
|
|
for _, line := range e.ReceiptLines {
|
|
product := dtodomain.InventoryReceiptLineProductResponse{}
|
|
if line.Product.ID != uuid.Nil {
|
|
product = dtodomain.InventoryReceiptLineProductResponse{
|
|
ID: line.Product.ID.String(),
|
|
Name: line.Product.Name,
|
|
RefNumber: line.Product.RefNumber,
|
|
Uom: pkgdto.IdNameResponse{
|
|
ID: line.Product.Uom.ID.String(),
|
|
Name: line.Product.Uom.Name,
|
|
},
|
|
DimLength: line.Product.DimLength,
|
|
DimWidth: line.Product.DimWidth,
|
|
DimHeight: line.Product.DimHeight,
|
|
DimUom: pkgdto.IdNameResponse{
|
|
ID: line.Product.DimUom.ID.String(),
|
|
Name: line.Product.DimUom.Name,
|
|
},
|
|
}
|
|
}
|
|
|
|
var repackUomID *string
|
|
if line.RepackUomID != nil {
|
|
tmp := line.RepackUomID.String()
|
|
repackUomID = &tmp
|
|
} else {
|
|
repackUomID = nil
|
|
}
|
|
|
|
lines = append(lines, dtodomain.InventoryReceiptLineResponse{
|
|
ID: line.ID.String(),
|
|
Quantity: line.Quantity,
|
|
BatchNumber: line.BatchNumber,
|
|
RepackingSuggestion: line.RepackingSuggestion,
|
|
RepackUomID: repackUomID,
|
|
Product: product,
|
|
ClientID: line.ClientID.String(),
|
|
})
|
|
}
|
|
|
|
assignment := dtodomain.AssignmentResponse{}
|
|
if e.Assignment.ID != uuid.Nil {
|
|
assignment = toAssignmentResponse(e.Assignment)
|
|
}
|
|
|
|
return dtodomain.InventoryReceiptResponse{
|
|
ID: e.ID.String(),
|
|
ReferenceNumber: e.ReferenceNumber,
|
|
DocumentNumber: e.DocumentNumber,
|
|
Status: e.Status,
|
|
DocumentDate: utils.DateTimeToString(e.DocumentDate),
|
|
Source: e.Source,
|
|
QrCodeFile: e.QrCodeFile,
|
|
// ClientID: e.ClientID.String(),
|
|
Client: client,
|
|
LineCount: len(lines),
|
|
ReceiptLines: lines,
|
|
Assignment: assignment,
|
|
}
|
|
}
|
|
|
|
func (s *inventoryReceiptService) Create(ctx context.Context, req dtodomain.InventoryReceiptCreateRequest) (dtodomain.InventoryReceiptResponse, 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.InventoryReceiptResponse{}, err
|
|
}
|
|
docNum, err := entities.GenerateDocumentNumber(s.db, req.ClientID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
receipt := entities.TInventoryReceiptEntity{
|
|
ReferenceNumber: req.ReferenceNumber,
|
|
DocumentNumber: docNum,
|
|
DocumentDate: utils.StringToDateTime(req.DocumentDate),
|
|
Source: req.Source,
|
|
QrCodeFile: req.QrCodeFile,
|
|
ClientID: clientUUID,
|
|
Status: req.Status,
|
|
}
|
|
created, err := s.receiptRepo.Create(ctx, tx, receipt)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
// Bulk create lines
|
|
var lines []entities.TInventoryReceiptLineEntity
|
|
for _, lineReq := range req.ReceiptLines {
|
|
var productUUID uuid.UUID
|
|
if lineReq.ProductID != "" {
|
|
productUUID, err = uuid.Parse(lineReq.ProductID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
} else if lineReq.ProductCode != "" {
|
|
product, err := s.productRepo.GetByCode(ctx, tx, lineReq.ProductCode, req.ClientID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
productUUID = product.ID
|
|
} else {
|
|
productUUID = uuid.Nil
|
|
}
|
|
var repackUomUUID *uuid.UUID
|
|
if lineReq.RepackUomID != "" {
|
|
tmp, err := uuid.Parse(lineReq.RepackUomID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
repackUomUUID = &tmp
|
|
} else if lineReq.RepackUomCode != "" {
|
|
uom, err := s.uomRepo.GetByCode(ctx, tx, lineReq.RepackUomCode, req.ClientID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
repackUomUUID = &uom.ID
|
|
} else {
|
|
repackUomUUID = nil
|
|
}
|
|
clientLineUUID, err := uuid.Parse(lineReq.ClientID)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
lines = append(lines, entities.TInventoryReceiptLineEntity{
|
|
Quantity: lineReq.Quantity,
|
|
BatchNumber: lineReq.BatchNumber,
|
|
RepackingSuggestion: lineReq.RepackingSuggestion,
|
|
RepackUomID: repackUomUUID,
|
|
InvReceiptID: created.ID,
|
|
ProductID: productUUID,
|
|
ClientID: clientLineUUID,
|
|
})
|
|
}
|
|
if len(lines) > 0 {
|
|
err = s.receiptLineRepo.BulkCreate(ctx, tx, lines)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
}
|
|
tx.Commit()
|
|
result, err := s.receiptRepo.GetById(ctx, nil, created.ID.String())
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
return toInventoryReceiptResponse(result), nil
|
|
}
|
|
|
|
func (s *inventoryReceiptService) GetById(ctx context.Context, id string) (dtodomain.InventoryReceiptResponse, error) {
|
|
receipt, err := s.receiptRepo.GetById(ctx, nil, id)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
return toInventoryReceiptResponse(receipt), nil
|
|
}
|
|
|
|
func (s *inventoryReceiptService) GetAll(ctx context.Context, filter query.InventoryReceiptFilter) ([]dtodomain.InventoryReceiptResponse, int64, error) {
|
|
receipts, total, err := s.receiptRepo.GetAll(ctx, filter)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
var responses []dtodomain.InventoryReceiptResponse
|
|
for _, e := range receipts {
|
|
responses = append(responses, toInventoryReceiptResponse(e))
|
|
}
|
|
if responses == nil {
|
|
responses = make([]dtodomain.InventoryReceiptResponse, 0)
|
|
}
|
|
return responses, total, nil
|
|
}
|
|
|
|
func (s *inventoryReceiptService) Update(ctx context.Context, req dtodomain.InventoryReceiptUpdateRequest, id string) (dtodomain.InventoryReceiptResponse, error) {
|
|
tx := s.db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
receipt, err := s.receiptRepo.GetById(ctx, tx, id)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
if req.ReferenceNumber != "" {
|
|
receipt.ReferenceNumber = req.ReferenceNumber
|
|
}
|
|
receipt.DocumentDate = utils.StringToDateTime(req.DocumentDate)
|
|
receipt.Source = req.Source
|
|
receipt.QrCodeFile = req.QrCodeFile
|
|
receipt.Status = req.Status
|
|
updated, err := s.receiptRepo.Update(ctx, tx, receipt)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
tx.Commit()
|
|
result, err := s.receiptRepo.GetById(ctx, nil, updated.ID.String())
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptResponse{}, err
|
|
}
|
|
return toInventoryReceiptResponse(result), nil
|
|
}
|
|
|
|
func (s *inventoryReceiptService) Delete(ctx context.Context, id string) error {
|
|
tx := s.db.Begin()
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
if err := s.receiptRepo.Delete(ctx, tx, id); err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
tx.Commit()
|
|
return nil
|
|
}
|
|
|
|
func (s *inventoryReceiptService) CreateLine(ctx context.Context, receiptId string, req dtodomain.InventoryReceiptLineCreateRequest) (dtodomain.InventoryReceiptLineResponse, error) {
|
|
receiptUUID, err := uuid.Parse(receiptId)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
var productUUID uuid.UUID
|
|
if req.ProductID != "" {
|
|
productUUID, err = uuid.Parse(req.ProductID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
} else if req.ProductCode != "" {
|
|
product, err := s.productRepo.GetByCode(ctx, nil, req.ProductCode, req.ClientID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
productUUID = product.ID
|
|
} else {
|
|
productUUID = uuid.Nil
|
|
}
|
|
var repackUomUUID *uuid.UUID
|
|
if req.RepackUomID != "" {
|
|
tmp, err := uuid.Parse(req.RepackUomID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
repackUomUUID = &tmp
|
|
} else if req.RepackUomCode != "" {
|
|
uom, err := s.uomRepo.GetByCode(ctx, nil, req.RepackUomCode, req.ClientID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
repackUomUUID = &uom.ID
|
|
} else {
|
|
repackUomUUID = nil
|
|
}
|
|
clientLineUUID, err := uuid.Parse(req.ClientID)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
line := entities.TInventoryReceiptLineEntity{
|
|
Quantity: req.Quantity,
|
|
BatchNumber: req.BatchNumber,
|
|
RepackingSuggestion: req.RepackingSuggestion,
|
|
RepackUomID: repackUomUUID,
|
|
InvReceiptID: receiptUUID,
|
|
ProductID: productUUID,
|
|
ClientID: clientLineUUID,
|
|
}
|
|
created, err := s.receiptLineRepo.Create(ctx, nil, line)
|
|
if err != nil {
|
|
return dtodomain.InventoryReceiptLineResponse{}, err
|
|
}
|
|
var repackUomID *string
|
|
if created.RepackUomID != nil {
|
|
tmp := created.RepackUomID.String()
|
|
repackUomID = &tmp
|
|
}
|
|
|
|
product := dtodomain.InventoryReceiptLineProductResponse{}
|
|
if created.Product.ID != uuid.Nil {
|
|
product = dtodomain.InventoryReceiptLineProductResponse{
|
|
ID: created.Product.ID.String(),
|
|
Name: created.Product.Name,
|
|
}
|
|
}
|
|
|
|
return dtodomain.InventoryReceiptLineResponse{
|
|
ID: created.ID.String(),
|
|
Quantity: created.Quantity,
|
|
BatchNumber: created.BatchNumber,
|
|
RepackingSuggestion: created.RepackingSuggestion,
|
|
RepackUomID: repackUomID,
|
|
Product: product,
|
|
ClientID: created.ClientID.String(),
|
|
}, nil
|
|
}
|
|
|
|
func NewInventoryReceiptService(db *gorm.DB,
|
|
receiptRepo repository.InventoryReceiptRepository,
|
|
receiptLineRepo repository.InventoryReceiptLineRepository,
|
|
productRepo productrepository.ProductRepository,
|
|
uomRepo uomrepository.UomRepository) InventoryReceiptService {
|
|
return &inventoryReceiptService{
|
|
db: db,
|
|
receiptRepo: receiptRepo,
|
|
receiptLineRepo: receiptLineRepo,
|
|
productRepo: productRepo,
|
|
uomRepo: uomRepo,
|
|
}
|
|
}
|