326 lines
9.8 KiB
Go
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,
|
||
|
}
|
||
|
}
|