cml04-mediciones-service/internal/service/service.go
2024-08-20 09:09:31 +02:00

326 lines
9.8 KiB
Go

package service
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"regexp"
"time"
cml04eventer "git.espin.casa/albert/cml04-eventer"
"git.espin.casa/albert/cml04-mediciones-service/internal/storage"
"git.espin.casa/albert/cml04-mediciones-service/internal/types"
"golang.org/x/crypto/bcrypt"
)
type IService interface {
/* REST */
// from rest
CreateTolerance(ctx context.Context, req types.CreateToleranceReq) (res types.CreateToleranceRes, err error)
GetTolerance(ctx context.Context, req types.GetToleranciaReq) (res types.GetToleranciaRes, err error)
// production orders from SAP
GetProductionOrder(ctx context.Context, req types.GetProductionOrderReq) (res types.GetProductionOrderRes, err error)
GetProductionOrders(ctx context.Context, req types.GetProductionOrdersReq) (res types.GetProductionOrdersRes, err error)
// mediciones
GetMedicion(ctx context.Context, req types.GetMedicionReq) (types.GetMedicionRes, error)
GetMediciones(ctx context.Context, req types.GetMedicionesReq) (types.GetMedicionesRes, error)
PostMediciones(ctx context.Context, req types.PostMedicionesReq) (types.PostMedicionesRes, error)
// Ususarios
GetUsuario(ctx context.Context, req types.GetUsuarioReq) (types.GetUsuarioRes, error)
CreateUsuario(ctx context.Context, req types.CreateUsuarioReq) (types.CreateUsuarioRes, error)
ValidarUsuario(ctx context.Context, req types.ValidarUsuarioReq) (types.ValidarUsuarioRes, error)
/* NSQ */
ProcessEvent(ctx context.Context, event *cml04eventer.Event) error
CreateProductionOrder(ctx context.Context, po *types.OrdenFabricacion) error
/* Excel */
GetExcel(ctx context.Context, req types.GetExcelReq) (types.GetExcelRes, error)
}
type service struct {
storage storage.IStorage
file *os.File
}
// GetExcel implements IService.
func (s *service) GetExcel(ctx context.Context, req types.GetExcelReq) (types.GetExcelRes, error) {
// get mediciones from database
mediciones, err := s.storage.GetExcel(ctx, req.Product, req.StartTime, req.EndTime)
if err != nil {
return types.GetExcelRes{}, err
}
return types.GetExcelRes{
Mediciones: mediciones,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// ValidarUsuario implements IService.
func (s *service) ValidarUsuario(ctx context.Context, req types.ValidarUsuarioReq) (types.ValidarUsuarioRes, error) {
// get user from database
user, err := s.storage.GetUser(ctx, req.Email)
if err != nil {
return types.ValidarUsuarioRes{}, err
}
// password from request
pass := req.Pass
// hash from database
hash := user.Password
// compare hash and pass
if err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(pass)); err != nil {
return types.ValidarUsuarioRes{}, err
}
return types.ValidarUsuarioRes{
Message: "user validated success",
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
func checkEmail(email string) bool {
// regular expression for validate email
regex := `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
// compile regular expression
pattern := regexp.MustCompile(regex)
// check if string match pattern
return pattern.MatchString(email)
}
func encryptPass(pass string) (string, error) {
res, err := bcrypt.GenerateFromPassword([]byte(pass), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(res), nil
}
// CreateUsuario implements IService.
func (s *service) CreateUsuario(ctx context.Context, req types.CreateUsuarioReq) (types.CreateUsuarioRes, error) {
// user var holder
user := req.Usuario
// encrypt user pass
pass, err := encryptPass(user.Password)
if err != nil {
return types.CreateUsuarioRes{}, err
}
// assign hash based on password
user.Password = pass
// check if email is correct
if !checkEmail(user.Email) {
return types.CreateUsuarioRes{}, errors.New("email format is not correct")
}
// create user
if err := s.storage.CreateUser(ctx, user); err != nil {
return types.CreateUsuarioRes{}, err
}
// done
return types.CreateUsuarioRes{
Message: fmt.Sprintf("create user: %s success", user.Email),
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// GetUsuario implements IService.
func (s *service) GetUsuario(ctx context.Context, req types.GetUsuarioReq) (types.GetUsuarioRes, error) {
user, err := s.storage.GetUser(ctx, req.Email)
if err != nil {
return types.GetUsuarioRes{}, err
}
return types.GetUsuarioRes{
Usuario: user,
TimeStamp: time.Now().Format(time.RFC3339),
}, nil
}
// GetMedicion implements IService.
func (s *service) GetMedicion(ctx context.Context, req types.GetMedicionReq) (types.GetMedicionRes, error) {
medicion, err := s.storage.GetMedicion(ctx, req.MedicionID)
if err != nil {
return types.GetMedicionRes{}, err
}
return types.GetMedicionRes{
Medicion: medicion,
TimeStamp: time.Now().Format(time.RFC3339),
}, nil
}
// GetMediciones implements IService.
func (s *service) GetMediciones(ctx context.Context, req types.GetMedicionesReq) (types.GetMedicionesRes, error) {
mediciones, err := s.storage.GetMediciones(ctx, req.POrderNo)
if err != nil {
return types.GetMedicionesRes{}, nil
}
return types.GetMedicionesRes{
Mediciones: mediciones,
TimeStamp: time.Now().Format(time.RFC3339),
}, nil
}
// PostMediciones implements IService.
func (s *service) PostMediciones(ctx context.Context, req types.PostMedicionesReq) (types.PostMedicionesRes, error) {
if err := s.storage.PostMediciones(ctx, req.Medicion); err != nil {
return types.PostMedicionesRes{}, err
}
return types.PostMedicionesRes{
Message: "post mediciones success",
TimeStamp: time.Now().Format(time.RFC3339),
}, nil
}
// GetProductionOrders implements IService.
func (s *service) GetProductionOrders(ctx context.Context, req types.GetProductionOrdersReq) (res types.GetProductionOrdersRes, err error) {
pos, err := s.storage.GetProductionOrders(ctx, req.Limit)
if err != nil {
return types.GetProductionOrdersRes{}, err
}
return types.GetProductionOrdersRes{
OrdenFabricacion: pos,
TimeStamp: time.Now().Format(time.RFC3339),
}, nil
}
// GetProductionOrder implements IService.
func (s *service) GetProductionOrder(ctx context.Context, req types.GetProductionOrderReq) (types.GetProductionOrderRes, error) {
po, err := s.storage.GetProductionOrder(ctx, req.PoNo)
if err != nil {
return types.GetProductionOrderRes{}, err
}
return types.GetProductionOrderRes{
OrdenFabricacion: po,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// CreateTolerance implements IService.
func (s *service) CreateTolerance(ctx context.Context, req types.CreateToleranceReq) (res types.CreateToleranceRes, err error) {
// insert product tolerance into storage database
if err := s.storage.CreateTolerance(ctx, req.Tolerancia); err != nil {
return types.CreateToleranceRes{}, err
}
return types.CreateToleranceRes{
Message: "create tolerance sucess",
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// GetTolerancia implements IService.
func (s *service) GetTolerance(ctx context.Context, req types.GetToleranciaReq) (res types.GetToleranciaRes, err error) {
// request product tolerance storage database
tolerance, err := s.storage.GetProductTolerance(ctx, req.Medida)
// handle error
if err != nil {
return types.GetToleranciaRes{}, err
}
return types.GetToleranciaRes{
Tolerancia: tolerance,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// CreateProductionOrder implements IService.
func (s *service) CreateProductionOrder(ctx context.Context, po *types.OrdenFabricacion) error {
return s.storage.CreateProductionOrder(ctx, po)
}
// ProcessEvent implements IService.
func (s *service) ProcessEvent(ctx context.Context, event *cml04eventer.Event) error {
// create buffer
buffer := bytes.NewBuffer(event.EventData)
// get event message subject
subject, err := event.EventMeta.Get("subject")
// handle error
if err != nil {
return err
}
switch subject {
case "sap.in.telegramas.z_sms_10001": // Production order telegram
// holder
h := &types.T10001{}
// decode
if err := json.NewDecoder(buffer).Decode(h); err != nil {
return err
}
po := &types.OrdenFabricacion{
Inst: h.Inst,
DateTime: h.DateTime,
POrderNo: h.POrderNo,
SchedulNo: h.SchedulNo,
SeqNumber: h.SeqNumber,
PptimeWfc: h.PptimeWfc,
PptimeMsc: h.PptimeMsc,
SteelGrad: h.SteelGrad,
ITemp: h.ITemp,
IHeight: h.IHeight,
IWidth: h.IWidth,
ISection: h.ISection,
HeatingSt: h.HeatingSt,
FTarTemp: h.FTarTemp,
FSection: h.FSection,
FSectType: h.FSectType,
TotWeight: h.TotWeight,
TBeamBla: h.TBeamBla,
TCustOrd: h.TCustOrd,
TestLen: h.TestLen,
PostFlag: h.PostFlag,
ModuloX: h.ModuloX,
OvWTolU: h.OvWTolU,
OvWTolL: h.OvWTolL,
OvHTolU: h.OvHTolU,
OvHTolL: h.OvHTolL,
WeTTolU: h.WeTTolU,
WeTTolL: h.WeTTolL,
WeHTolU: h.WeHTolU,
WeHTolL: h.WeHTolL,
FlWDsU: h.FlWDsU,
FlWDsL: h.FlWDsL,
FlWOsU: h.FlWOsU,
FlWOsL: h.FlWOsL,
WeMetTU: h.WeMetTU,
WeMetTL: h.WeMetTL,
WeCenTol: h.WeCenTol,
WeSquTol: h.WeSquTol,
FlParTol: h.FlParTol,
BdRollID: h.BdRollID,
UrRollID: h.UrRollID,
EdRollID: h.EdRollID,
UfRollID: h.UfRollID,
SmRollID: h.SmRollID,
Grupo6: h.Grupo6,
StName: h.StName,
StWeighM: h.StWeighM,
StLen1: h.StLen1,
StLen2: h.StLen2,
StLen3: h.StLen3,
StLen4: h.StLen4,
StLen5: h.StLen5,
StLen6: h.StLen6,
StLen7: h.StLen7,
StLen8: h.StLen8,
StLen9: h.StLen9,
StLen10: h.StLen10,
StLen11: h.StLen11,
StLen12: h.StLen12,
Marfab: h.Marfab,
Sortb: h.Sortb,
}
// create production order
if err := s.CreateProductionOrder(ctx, po); err != nil {
return err
}
}
return nil
}
func NewService(storage storage.IStorage) IService {
f, err := os.Create("events.dat")
if err != nil {
panic(err)
}
return &service{
storage: storage,
file: f,
}
}