product.go 14.7 KB
package service

import (
	"fmt"
	"github.com/linmadan/egglib-go/core/application"
	pgTransaction "github.com/linmadan/egglib-go/transaction/pg"
	"github.com/linmadan/egglib-go/utils/tool_funs"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/factory"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/command"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/dto"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/application/product/query"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/domainService"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/redis"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/infrastructure/utils"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-manufacture/pkg/log"
	"time"
)

// 产品服务
type ProductService struct {
}

// 创建产品服务
func (productService *ProductService) CreateProduct(createProductCommand *command.CreateProductCommand) (interface{}, error) {
	if err := createProductCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	if len(createProductCommand.ProductCode) == 0 {
		generator := redis.NewProductCodeCache(createProductCommand.CompanyId)
		code, err := redis.GenCode(generator)
		if err != nil {
			log.Logger.Error(err.Error())
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "服务器异常")
		}
		createProductCommand.ProductCode = code
	}
	var userService = domainService.NewUserService()
	var org *domain.Org
	org, err = userService.Organization(createProductCommand.OrgId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}

	newProduct := &domain.Product{
		CompanyId:       createProductCommand.CompanyId,
		OrgId:           createProductCommand.OrgId,
		ProductCode:     createProductCommand.ProductCode,
		ProductName:     createProductCommand.ProductName,
		ProductCategory: createProductCommand.ProductCategory,
		ProductSpec: &domain.UnitQuantity{
			Unit:       createProductCommand.Unit,
			UnitWeight: createProductCommand.UnitWeight,
		},
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
		Ext:       domain.NewExt(org.OrgName),
	}
	productRepository, _, _ := factory.FastPgProduct(transactionContext, 0)

	if item, err := productRepository.FindOne(map[string]interface{}{"companyId": createProductCommand.CompanyId, "productCode": createProductCommand.ProductCode}); err == nil && item != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "产品编号重复,请重新提交")
	}

	if product, err := productRepository.Save(newProduct); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return product, nil
	}
}

// 返回产品服务
func (productService *ProductService) GetProduct(getProductQuery *query.GetProductQuery) (interface{}, error) {
	if err := getProductQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var productRepository domain.ProductRepository
	if value, err := factory.CreateProductRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		productRepository = value
	}
	product, err := productRepository.FindOne(map[string]interface{}{"productId": getProductQuery.ProductId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if product == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(getProductQuery.ProductId)))
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		result := &dto.ProductDto{}
		return result.LoadDto(product, 0), nil
	}
}

// 返回产品服务列表
func (productService *ProductService) ListProduct(listProductQuery *query.ListProductQuery) (interface{}, error) {
	if err := listProductQuery.ValidateQuery(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var productRepository domain.ProductRepository
	if value, err := factory.CreateProductRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		productRepository = value
	}
	if count, products, err := productRepository.Find(tool_funs.SimpleStructToMap(listProductQuery)); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return map[string]interface{}{
			"count":    count,
			"products": products,
		}, nil
	}
}

// 移除产品服务
func (productService *ProductService) RemoveProduct(removeProductCommand *command.RemoveProductCommand) (interface{}, error) {
	if err := removeProductCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var productRepository domain.ProductRepository
	if value, err := factory.CreateProductRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		productRepository = value
	}
	product, err := productRepository.FindOne(map[string]interface{}{"productId": removeProductCommand.ProductId})
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if product == nil {
		return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeProductCommand.ProductId)))
	}
	if product, err := productRepository.Remove(product); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return product, nil
	}
}

// 移除产品服务
func (productService *ProductService) BatchRemoveProduct(cmd *command.BatchRemoveProductCommand) (interface{}, error) {
	if err := cmd.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var productRepository domain.ProductRepository
	if value, err := factory.CreateProductRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		productRepository = value
	}
	for i := range cmd.IdList {
		id := cmd.IdList[i]
		product, err := productRepository.FindOne(map[string]interface{}{"productId": id})
		if err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
		if product == nil {
			return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%d", id))
		}
		if _, err := productRepository.Remove(product); err != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
		}
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return struct {
	}{}, nil

}

// 更新产品服务
func (productService *ProductService) UpdateProduct(updateProductCommand *command.UpdateProductCommand) (interface{}, error) {
	if err := updateProductCommand.ValidateCommand(); err != nil {
		return nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	productRepository, product, err := factory.FastPgProduct(transactionContext, updateProductCommand.ProductId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if len(updateProductCommand.ProductCode) == 0 {
		generator := redis.NewProductCodeCache(product.CompanyId)
		code, err := redis.GenCode(generator)
		if err != nil {
			log.Logger.Error(err.Error())
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "服务器异常")
		}
		updateProductCommand.ProductCode = code
	}
	if updateProductCommand.ProductCode != product.ProductCode {
		if item, err := productRepository.FindOne(map[string]interface{}{"companyId": product.CompanyId, "productCode": updateProductCommand.ProductCode}); err == nil && item != nil {
			return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "产品编号重复,请重新提交")
		}
	}

	var userService = domainService.NewUserService()
	var org *domain.Org
	org, err = userService.Organization(product.OrgId)
	if err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	data := tool_funs.SimpleStructToMap(updateProductCommand)
	data["orgName"] = org.OrgName
	if err := product.Update(data); err != nil {
		return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
	}
	if product, err := productRepository.Save(product); err != nil {
		return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		if err := transactionContext.CommitTransaction(); err != nil {
			return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
		}
		return product, nil
	}
}

// 返回产品服务列表
func (productService *ProductService) SearchProduct(operateInfo *domain.OperateInfo, listProductQuery *query.SearchProductQuery) (int64, interface{}, error) {
	if err := listProductQuery.ValidateQuery(); err != nil {
		return 0, nil, application.ThrowError(application.ARG_ERROR, err.Error())
	}
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()
	var productRepository domain.ProductRepository
	if value, err := factory.CreateProductRepository(map[string]interface{}{
		"transactionContext": transactionContext,
	}); err != nil {
		return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	} else {
		productRepository = value
	}
	count, products, err := productRepository.Find(utils.ObjectToMap(listProductQuery))
	if err != nil {
		return 0, nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return 0, nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	var result = make([]*dto.ProductDto, 0)
	for i := range products {
		newItem := &dto.ProductDto{}
		result = append(result, newItem.LoadDto(products[i], operateInfo.OrgId))
	}
	return count, result, nil

}

// 创建产品服务
func (productService *ProductService) BatchAddProduct(opt *domain.OperateInfo, list []*domain.ImportProductItem) ([]interface{}, error) {
	transactionContext, err := factory.CreateTransactionContext(nil)
	if err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if err := transactionContext.StartTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	defer func() {
		transactionContext.RollbackTransaction()
	}()

	batchAddProductService, _ := domainService.NewPGBatchAddProductService(transactionContext.(*pgTransaction.TransactionContext))
	var failRows []interface{}
	if failRows, err = batchAddProductService.BatchAddProduct(opt, list, false); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	if len(failRows) != 0 {
		return failRows, nil //有错误行,回滚
	}
	if err := transactionContext.CommitTransaction(); err != nil {
		return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
	}
	return failRows, nil
}

func NewProductService(options map[string]interface{}) *ProductService {
	newProductService := &ProductService{}
	return newProductService
}