2
This commit is contained in:
albert 2024-08-20 15:50:52 +02:00
commit 76e3bdcce1
25 changed files with 2722 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
bin

33
Makefile Normal file
View File

@ -0,0 +1,33 @@
# Variables
IMAGE_NAME = registry.espin.casa/cml04-pbl018
CONTAINER_NAME = cml04-pbl018
# Check if Docker or Podman is available
DOCKER := $(shell command -v docker 2> /dev/null)
PODMAN := $(shell command -v podman 2> /dev/null)
# Determine which command to use based on availability
ifdef DOCKER
DOCKER_CMD := docker
else ifdef PODMAN
DOCKER_CMD := podman
else
$(error "Neither Docker nor Podman is installed on this system.")
endif
# Build the Docker image
build:
$(DOCKER_CMD) build -t $(IMAGE_NAME) -f docker/Dockerfile .
# Run the container
run:
@$(DOCKER_CMD) run $(IMAGE_NAME)
# Stop and remove the container
stop:
$(DOCKER_CMD) stop $(CONTAINER_NAME)
$(DOCKER_CMD) rm $(CONTAINER_NAME)
# Remove the Docker image
clean:
$(DOCKER_CMD) rmi $(IMAGE_NAME)

1
ata12.dat Normal file
View File

@ -0,0 +1 @@
94012345698

1
ata345.dat Normal file
View File

@ -0,0 +1 @@
94512345681

28
celsa2048.crt Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIJANu+mC2Jt3uTMA0GCSqGSIb3DQEBCwUAMIGhMQswCQYD
VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2Ux
FTATBgNVBAoTDFpzY2FsZXIgSW5jLjEVMBMGA1UECxMMWnNjYWxlciBJbmMuMRgw
FgYDVQQDEw9ac2NhbGVyIFJvb3QgQ0ExIjAgBgkqhkiG9w0BCQEWE3N1cHBvcnRA
enNjYWxlci5jb20wHhcNMTQxMjE5MDAyNzU1WhcNNDIwNTA2MDAyNzU1WjCBoTEL
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcTCFNhbiBK
b3NlMRUwEwYDVQQKEwxac2NhbGVyIEluYy4xFTATBgNVBAsTDFpzY2FsZXIgSW5j
LjEYMBYGA1UEAxMPWnNjYWxlciBSb290IENBMSIwIAYJKoZIhvcNAQkBFhNzdXBw
b3J0QHpzY2FsZXIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
qT7STSxZRTgEFFf6doHajSc1vk5jmzmM6BWuOo044EsaTc9eVEV/HjH/1DWzZtcr
fTj+ni205apMTlKBW3UYR+lyLHQ9FoZiDXYXK8poKSV5+Tm0Vls/5Kb8mkhVVqv7
LgYEmvEY7HPY+i1nEGZCa46ZXCOohJ0mBEtB9JVlpDIO+nN0hUMAYYdZ1KZWCMNf
5J/aTZiShsorN2A38iSOhdd+mcRM4iNL3gsLu99XhKnRqKoHeH83lVdfu1XBeoQz
z5V6gA3kbRvhDwoIlTBeMa5l4yRdJAfdpkbFzqiwSgNdhbxTHnYYorDzKfr2rEFM
dsMU0DHdeAZf711+1CunuQIDAQABo4IBCjCCAQYwHQYDVR0OBBYEFLm33UrNww4M
hp1d3+wcBGnFTpjfMIHWBgNVHSMEgc4wgcuAFLm33UrNww4Mhp1d3+wcBGnFTpjf
oYGnpIGkMIGhMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8G
A1UEBxMIU2FuIEpvc2UxFTATBgNVBAoTDFpzY2FsZXIgSW5jLjEVMBMGA1UECxMM
WnNjYWxlciBJbmMuMRgwFgYDVQQDEw9ac2NhbGVyIFJvb3QgQ0ExIjAgBgkqhkiG
9w0BCQEWE3N1cHBvcnRAenNjYWxlci5jb22CCQDbvpgtibd7kzAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAw0NdJh8w3NsJu4KHuVZUrmZgIohnTm0j+
RTmYQ9IKA/pvxAcA6K1i/LO+Bt+tCX+C0yxqB8qzuo+4vAzoY5JEBhyhBhf1uK+P
/WVWFZN/+hTgpSbZgzUEnWQG2gOVd24msex+0Sr7hyr9vn6OueH+jj+vCMiAm5+u
kd7lLvJsBu3AO3jGWVLyPkS3i6Gf+rwAp1OsRrv3WnbkYcFf9xjuaf4z0hRCrLN2
xFNjavxrHmsH8jPHVvgc1VD0Opja0l/BRVauTrUaoW6tE+wFG5rEcPGS80jjHK4S
pB5iDj2mUZH1T8lzYtuZy0ZPirxmtsk3135+CKNa2OCAhhFjE0xd
-----END CERTIFICATE-----

9
cmd/main.go Normal file
View File

@ -0,0 +1,9 @@
package main
import "git.espin.casa/albert/cml04-plb018/internal/app"
func main() {
if err := app.Run(); err != nil {
panic(err)
}
}

1
curl Normal file
View File

@ -0,0 +1 @@
curl -X POST "http://localhost:3000/api/v1/etiqueta/imprimir" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"DatosEtiqueta\": { \"CoID\": 40155678, \"Colada\": \"CE123456\", \"NrBarras\": \"12\", \"NrEtiquetas\": \"2\", \"NrMatricula\": \"9461234567\", \"Operador\": \"AER\", \"Peso\": 4512.18, \"Turno\": \"A\" }, \"ImpresoraID\": \"NONE\", \"TimeStamp\": \"string\"}"

BIN
db.sqlite Normal file

Binary file not shown.

37
docker/Dockerfile Normal file
View File

@ -0,0 +1,37 @@
# Etapa de compilación
FROM golang:1.22-bookworm AS builder
ENV TZ=Europe/Madrid
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD celsa2048.crt /usr/local/share/ca-certificates/celsa2048.crt
RUN chmod 644 /usr/local/share/ca-certificates/celsa2048.crt
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates
RUN update-ca-certificates
WORKDIR /app
COPY . .
RUN go get -d -v ./...
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -mod=mod -ldflags "-s -w" -o myapp cmd/main.go
# Etapa de producción
FROM debian:stable
ENV TZ=Europe/Madrid
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ADD celsa2048.crt /usr/local/share/ca-certificates/celsa2048.crt
RUN chmod 644 /usr/local/share/ca-certificates/celsa2048.crt
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates
RUN update-ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

24
go.mod Normal file
View File

@ -0,0 +1,24 @@
module git.espin.casa/albert/cml04-plb018
go 1.22.4
require (
git.espin.casa/albert/cml04-eventer v0.0.0-20240508172957-52ca86976f5f
git.espin.casa/albert/logger v0.0.0-20240312060442-59b35e5c6996
github.com/zc2638/swag v1.6.0
gorm.io/driver/sqlite v1.5.6
gorm.io/gorm v1.25.10
)
require (
github.com/golang/snappy v0.0.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nsqio/go-nsq v1.1.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
)

54
go.sum Normal file
View File

@ -0,0 +1,54 @@
git.espin.casa/albert/cml04-eventer v0.0.0-20240508172957-52ca86976f5f h1:ovKbIJFxABDQhMz+bfZ9eeMrPcs8KINRAIQamFHZrUI=
git.espin.casa/albert/cml04-eventer v0.0.0-20240508172957-52ca86976f5f/go.mod h1:/fj0cTIFEdeYmzL2r4WLEAN2q3N3T48ZPOT1hqusuSI=
git.espin.casa/albert/logger v0.0.0-20240312060442-59b35e5c6996 h1:gOY7u2z9gMOdp0Q1Rod9XvoM0gL84SBXR7n/VxrgvtE=
git.espin.casa/albert/logger v0.0.0-20240312060442-59b35e5c6996/go.mod h1:dacFMi82f5ysDOaJQm0QmQaJZ7mwGFiayJ2iS+JKAfQ=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE=
github.com/nsqio/go-nsq v1.1.0/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/zc2638/swag v1.6.0 h1:pQ3UE0SeqFKnoOPdBPBMPXVkW+iqODS+ALVh8ZGRyQ0=
github.com/zc2638/swag v1.6.0/go.mod h1:AjyTDUHzZZ4mctSNLEZVD5jWQHFGDJlaCR5XjDm46aE=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE=
gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4=
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=

153
internal/app/app.go Normal file
View File

@ -0,0 +1,153 @@
package app
import (
"bytes"
"context"
"encoding/json"
"flag"
"os"
"os/signal"
"syscall"
cml04eventer "git.espin.casa/albert/cml04-eventer"
"git.espin.casa/albert/cml04-plb018/internal/logging"
"git.espin.casa/albert/cml04-plb018/internal/server"
"git.espin.casa/albert/cml04-plb018/internal/service"
"git.espin.casa/albert/cml04-plb018/internal/storage"
"git.espin.casa/albert/cml04-plb018/internal/types"
"git.espin.casa/albert/logger"
)
func Run() error {
// flags
httpBind := flag.String("bind-addr", ":3000", "http bind address")
nsqAddr := flag.String("nsq-addr", "10.1.152.13", "nsq address")
nsqPort := flag.Int("nsq-port", 4150, "nsq port")
logLevel := flag.String("level", "debug", "Log level")
flag.Parse()
// setup logger
log := logger.New(os.Stdout, *logLevel)
// log fields
logFields := logger.LogFields{
"http_bind": *httpBind,
"nsq_addr": *nsqAddr,
"nsq_port": *nsqPort,
"log_level": *logLevel,
}
// create subscriber
sub, err := cml04eventer.NewSubscriber(&cml04eventer.SubscriberConfig{
NSQAddress: *nsqAddr,
NSQPort: *nsqPort,
Unmarshaler: cml04eventer.JSONMarshaler{},
Channel: "CML04-PLB018",
}, log)
if err != nil {
log.Error("create subscriber failed", err, logFields)
return err
}
defer sub.Close()
// create publisher
pub, err := cml04eventer.NewPublisher(&cml04eventer.PublisherImplConfig{
NSQAddress: *nsqAddr,
NSQPort: *nsqPort,
Marshaler: cml04eventer.JSONMarshaler{},
}, log)
if err != nil {
log.Error("create publisher failed", err, logFields)
}
defer pub.Close()
// create context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// subscribe events
SapChan, err := sub.SubscribeEvent(ctx, "SAP-IN")
if err != nil {
log.Error("create subscribe event failed", err, logFields)
return err
}
// create storage
storage, err := storage.NewStorage(log)
if err != nil {
log.Error("create storage event failed", err, logFields)
return err
}
// process incoming events
go func() {
for event := range SapChan {
if err := ProcessEvent(ctx, event, storage, log); err != nil {
log.Error("process event has been failed", err, logFields)
continue
}
}
}()
// create service
svc := service.NewService(storage, pub)
// create logging service
svc = logging.NewLogging(svc, log)
// create server
server := server.NewServer(*httpBind, svc)
// start server
server.Start()
// info banner
log.Info("started cml04-pbl018", logFields)
// wait signal to finish
signal := WaitSignal()
log.Info("signal received", logFields.Add(logger.LogFields{
"signal": signal.String(),
}))
return nil
}
func ProcessEvent(ctx context.Context, event *cml04eventer.Event, storage storage.Storager, log logger.LoggerAdapter) error {
subject, err := event.EventMeta.Get("subject")
if err != nil {
return err
}
switch subject.(string) {
// production order telegram
case "sap.in.telegramas.z_sms_10001":
log.Info("received production order data from SAP", logger.LogFields{})
po := &types.ProductionOrder{}
buf := bytes.NewBuffer(event.EventData)
if err := json.NewDecoder(buf).Decode(po); err != nil {
return err
}
return storage.SalvarOrdenProduccion(ctx, po)
// customer order telegram
case "sap.in.telegramas.z_sms_10002":
log.Info("received customer order data from SAP", logger.LogFields{})
co := &types.CustomerOrder{}
buf := bytes.NewBuffer(event.EventData)
if err := json.NewDecoder(buf).Decode(co); err != nil {
return err
}
return storage.SalvarOrdenCliente(ctx, co)
case "sap.in.calidades":
log.Info("received normas/calidades data from SAP", logger.LogFields{})
list := &types.NormaList{}
buf := bytes.NewBuffer(event.EventData)
if err := json.NewDecoder(buf).Decode(list); err != nil {
return err
}
return storage.SalvarNormas(ctx, list)
}
return nil
}
// WaitSignal catching exit signal
func WaitSignal() os.Signal {
ch := make(chan os.Signal, 2)
signal.Notify(
ch,
syscall.SIGINT,
syscall.SIGQUIT,
syscall.SIGTERM,
)
for {
sig := <-ch
switch sig {
case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM:
return sig
}
}
}

View File

@ -0,0 +1,89 @@
package helpers
import (
"fmt"
"os"
"strconv"
"strings"
"sync"
"git.espin.casa/albert/cml04-plb018/internal/types"
)
var (
mux = sync.RWMutex{}
contador = map[types.PEtiquetado]string{
types.Ata12: "ata12.dat",
types.Ata345: "ata345.dat",
}
)
// EsAmericano comprueba si el producto es americano y lo devuelve como boolean
func EsAmericano(producto string) bool {
if strings.HasPrefix(producto, "W") {
return true
}
return false
}
// MetrosAPies convierte una longitud en metros a pies
func MetrosAPies(m float64) float64 {
return m * 3.28084
}
// PiesAMetros convierte una longitud en pies a metros
func PiesAMetros(p float64) float64 {
return p / 3.28084
}
// NroPaqueteSiguiente incrementa el contador de paquetes para un puesto de etiquetado
// y lo devuelve como string
func NroPaqueteSiguiente(pe types.PEtiquetado) (string, error) {
mux.Lock()
defer mux.Unlock()
// Read actual value
contador, ok := contador[pe]
if !ok {
return "", fmt.Errorf("puesto de etiquetado desconocido")
}
data, err := os.ReadFile(contador)
if err != nil {
return "", err
}
nm, err := strconv.ParseUint(string(data), 10, 64)
if err != nil {
return "", err
}
// increase value
nm++
// Write new matricula value in file
newData := strconv.FormatUint(nm, 10)
// Write new matricula value in file
if err = os.WriteFile(contador, []byte(newData), 0644); err != nil {
return "", err
}
// return new value
return strconv.FormatUint(nm, 10), nil
}
// NroPaqueteActual devuelve el contador de paquetes para un puesto de etiquetado
// como string
func NroPaqueteActual(pe types.PEtiquetado) (string, error) {
mux.RLock()
defer mux.RUnlock()
// Read actual value
contador, ok := contador[pe]
if !ok {
return "", fmt.Errorf("puesto de etiquetado desconocido")
}
data, err := os.ReadFile(contador)
if err != nil {
return "", err
}
nm, err := strconv.ParseUint(string(data), 10, 64)
if err != nil {
return "", err
}
// return new value
return strconv.FormatUint(nm, 10), nil
}

291
internal/logging/logging.go Normal file
View File

@ -0,0 +1,291 @@
package logging
import (
"context"
"time"
"git.espin.casa/albert/cml04-plb018/internal/service"
"git.espin.casa/albert/cml04-plb018/internal/types"
"git.espin.casa/albert/logger"
)
type Logging struct {
log logger.LoggerAdapter
next service.IService
}
// NroPaqueteActual implements service.IService.
func (l *Logging) NroPaqueteActual(ctx context.Context, req *types.NroPaqueteActualReq) (res *types.NroPaqueteActualRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"took": time.Since(start),
}
if err != nil {
l.log.Error("Nro paquete actual failed", err, logFields)
} else {
l.log.Info("Nro paquete actual success", logFields)
}
}(time.Now())
return l.next.NroPaqueteActual(ctx, req)
}
// NroPaqueteSiguiente implements service.IService.
func (l *Logging) NroPaqueteSiguiente(ctx context.Context, req *types.NroPaqueteSiguienteReq) (res *types.NroPaqueteSiguienteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"took": time.Since(start),
}
if err != nil {
l.log.Error("Nro paquete siguiente failed", err, logFields)
} else {
l.log.Info("Nro paquete siguiente success", logFields)
}
}(time.Now())
return l.next.NroPaqueteSiguiente(ctx, req)
}
// ImprimirPaqueteRobot implements service.IService.
func (l *Logging) ImprimirPaqueteRobot(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"nro_matricula": req.DatosEtiqueta.NroMatricula,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Imprimir paquete robot failed", err, logFields)
} else {
l.log.Info("Imprimir paquete robot success", logFields)
}
}(time.Now())
return l.next.ImprimirPaqueteRobot(ctx, req)
}
// Paquete implements service.IService.
func (l *Logging) Paquete(ctx context.Context, req *types.PaqueteReq) (res *types.PaqueteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"codigo_etiqueta": req.Codigo,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Paquete failed", err, logFields)
} else {
l.log.Info("Paquete success", logFields)
}
}(time.Now())
return l.next.Paquete(ctx, req)
}
// Paquetes implements service.IService.
func (l *Logging) Paquetes(ctx context.Context, req *types.PaquetesReq) (res *types.PaquetesRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"inicio": req.Inicio,
"final": req.Final,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Paquetes failed", err, logFields)
} else {
l.log.Info("Paquetes success", logFields)
}
}(time.Now())
return l.next.Paquetes(ctx, req)
}
// Etiqueta implements service.IService.
func (l *Logging) Etiqueta(ctx context.Context, req *types.EtiquetaReq) (res *types.EtiquetaRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"codigo_etiqueta": req.Codigo,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Etiqueta failed", err, logFields)
} else {
l.log.Info("Etiqueta success", logFields)
}
}(time.Now())
return l.next.Etiqueta(ctx, req)
}
// Etiquetas implements service.IService.
func (l *Logging) Etiquetas(ctx context.Context, req *types.EtiquetasReq) (res *types.EtiquetasRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"took": time.Since(start),
}
if err != nil {
l.log.Error("Etiquetas failed", err, logFields)
} else {
l.log.Info("Etiquetas success", logFields)
}
}(time.Now())
return l.next.Etiquetas(ctx, req)
}
// SalvarEtiqueta implements service.IService.
func (l *Logging) SalvarEtiqueta(ctx context.Context, req *types.SalvarEtiquetaReq) (res *types.SalvarEtiquetaRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"codigo_etiqueta": req.Etiqueta.Codigo,
"took": time.Since(start),
}
if err != nil {
l.log.Error("SalvarEtiqueta failed", err, logFields)
} else {
l.log.Info("SalvarEtiqueta success", logFields)
}
}(time.Now())
return l.next.SalvarEtiqueta(ctx, req)
}
// SalvarImpresora implements service.IService.
func (l *Logging) SalvarImpresora(ctx context.Context, req *types.SalvarImpresoraReq) (res *types.SalvarImpresoraRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"id_impresora": req.Impresora.ID,
"took": time.Since(start),
}
if err != nil {
l.log.Error("SalvarImpresora failed", err, logFields)
} else {
l.log.Info("SalvarImpresora success", logFields)
}
}(time.Now())
return l.next.SalvarImpresora(ctx, req)
}
// Impresora implements service.IService.
func (l *Logging) Impresora(ctx context.Context, req *types.ImpresoraReq) (res *types.ImpresoraRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"id_impresora": req.ID,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Impresora failed", err, logFields)
} else {
l.log.Info("Impresora success", logFields)
}
}(time.Now())
return l.next.Impresora(ctx, req)
}
// Impresoras implements service.IService.
func (l *Logging) Impresoras(ctx context.Context, req *types.ImpresorasReq) (res *types.ImpresorasRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"took": time.Since(start),
}
if err != nil {
l.log.Error("Impresoras failed", err, logFields)
} else {
l.log.Info("Impresoras success", logFields)
}
}(time.Now())
return l.next.Impresoras(ctx, req)
}
// OrdenesProduccion implements service.IService.
func (l *Logging) OrdenesProduccion(ctx context.Context, req *types.OrdenesProduccionReq) (res *types.OrdenesProduccionRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"limit": req.Limit,
"took": time.Since(start),
}
if err != nil {
l.log.Error("OrdenesProduccion failed", err, logFields)
} else {
l.log.Info("OrdenesProduccion success", logFields)
}
}(time.Now())
return l.next.OrdenesProduccion(ctx, req)
}
// OrdenCliente implements service.IService.
func (l *Logging) OrdenCliente(ctx context.Context, req *types.OrdenClienteReq) (res *types.OrdenClienteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"co_id": req.CoID,
"took": time.Since(start),
}
if err != nil {
l.log.Error("OrdenCliente failed", err, logFields)
} else {
l.log.Info("OrdenCliente success", logFields)
}
}(time.Now())
return l.next.OrdenCliente(ctx, req)
}
// OrdenProduccion implements service.IService.
func (l *Logging) OrdenProduccion(ctx context.Context, req *types.OrdenProduccionReq) (res *types.OrdenProduccionRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"po_id": req.PoID,
"took": time.Since(start),
}
if err != nil {
l.log.Error("OrdenProduccion failed", err, logFields)
} else {
l.log.Info("OrdenProduccion success", logFields)
}
}(time.Now())
return l.next.OrdenProduccion(ctx, req)
}
// OrdenesCliente implements service.IService.
func (l *Logging) OrdenesCliente(ctx context.Context, req *types.OrdenesClienteReq) (res *types.OrdenesClienteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"po_id": req.PoID,
"took": time.Since(start),
}
if err != nil {
l.log.Error("OrdenesCliente failed", err, logFields)
} else {
l.log.Info("OrdenesCliente success", logFields)
}
}(time.Now())
return l.next.OrdenesCliente(ctx, req)
}
// Normas implements service.IService.
func (l *Logging) Normas(ctx context.Context, req *types.NormasReq) (res *types.NormasRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"code": req.Codigo,
"took": time.Since(start),
}
if err != nil {
l.log.Error("Normas failed", err, logFields)
} else {
l.log.Info("Normas success", logFields)
}
}(time.Now())
return l.next.Normas(ctx, req)
}
// ImprimirPaquete implements service.IService.
func (l *Logging) ImprimirPaquete(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error) {
defer func(start time.Time) {
logFields := logger.LogFields{
"took": time.Since(start),
}
if err != nil {
l.log.Error("imprimir etiqueta failed", err, logFields)
} else {
l.log.Info("imprimir etiqueta success", logFields)
}
}(time.Now())
return l.next.ImprimirPaquete(ctx, req)
}
func NewLogging(svc service.IService, log logger.LoggerAdapter) service.IService {
return &Logging{
log: log,
next: svc,
}
}

682
internal/server/server.go Normal file
View File

@ -0,0 +1,682 @@
package server
import (
"encoding/json"
"fmt"
"net/http"
"path"
"time"
"git.espin.casa/albert/cml04-plb018/internal/service"
"git.espin.casa/albert/cml04-plb018/internal/types"
"github.com/zc2638/swag"
"github.com/zc2638/swag/endpoint"
"github.com/zc2638/swag/option"
)
type Server struct {
svc service.IService
api *swag.API
url string
}
func NroMatriculaSiguienteEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/nromatricula/next",
endpoint.BodyR(types.NroPaqueteSiguienteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.NroPaqueteSiguienteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene el numero de matricula siguiente"),
endpoint.Description("Obtiene el numero de matricula siguiente"),
endpoint.Handler(NroMatriculaSiguienteHandler(svc)),
)
}
func NroMatriculaSiguienteHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.NroPaqueteSiguienteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
// call service
res, err := svc.NroPaqueteSiguiente(r.Context(), req)
if err != nil {
http.Error(w, fmt.Sprintf("PaquetesHandler failed: %s", err.Error()), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func NroMatriculaActualEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/nromatricula/get",
endpoint.BodyR(types.NroPaqueteActualReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.NroPaqueteActualReq{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene el numero de matricula actual"),
endpoint.Description("Obtiene el numero de matricula actual"),
endpoint.Handler(NroMatriculaActualHandler(svc)),
)
}
func NroMatriculaActualHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.NroPaqueteActualReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
// call service
res, err := svc.NroPaqueteActual(r.Context(), req)
if err != nil {
http.Error(w, fmt.Sprintf("PaquetesHandler failed: %s", err.Error()), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func PaquetesEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/paquete/list",
endpoint.BodyR(types.PaquetesReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.PaquetesRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene el numero de matricula actual"),
endpoint.Description("Obtiene el numero de matricula actual"),
endpoint.Handler(PaquetesHandler(svc)),
)
}
func PaquetesHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.PaquetesReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
// call service
res, err := svc.Paquetes(r.Context(), req)
if err != nil {
http.Error(w, fmt.Sprintf("PaquetesHandler failed: %s", err.Error()), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func PaqueteEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/paquete/get",
endpoint.BodyR(types.PaqueteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.PaqueteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene los datos del paquete (bulto)"),
endpoint.Description("Obtiene los datos del paquete (bulto)"),
endpoint.Handler(PaqueteHandler(svc)),
)
}
func PaqueteHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.PaqueteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
// call service
res, err := svc.Paquete(r.Context(), req)
if err != nil {
http.Error(w, fmt.Sprintf("PaqueteHandler failed: %s", err.Error()), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func EtiquetasEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/etiqueta/list",
endpoint.BodyR(types.EtiquetasReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.EtiquetasRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene los datos de las etiquetas"),
endpoint.Description("Obtiene los datos de las etiquetas"),
endpoint.Handler(EtiquetasHandler(svc)),
)
}
func EtiquetasHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.EtiquetasReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
// call service
res, err := svc.Etiquetas(r.Context(), req)
if err != nil {
http.Error(w, fmt.Sprintf("EtiquetasHandler failed: %s", err.Error()), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func EtiquetaEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/etiqueta/get",
endpoint.BodyR(types.EtiquetaReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.EtiquetaRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene los datos de la etiqueta"),
endpoint.Description("Obtiene los datos de la etiqueta"),
endpoint.Handler(EtiquetaHandler(svc)),
)
}
func EtiquetaHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.EtiquetaReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.Etiqueta(r.Context(), req)
if err != nil {
http.Error(w, "etiqueta handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func SalvarEtiquetaEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/etiqueta/create",
endpoint.BodyR(types.SalvarEtiquetaReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.SalvarEtiquetaRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Salva los datos de la etiqueta"),
endpoint.Description("Salva los datos de la etiqueta"),
endpoint.Handler(SalvarEtiquetaHandler(svc)),
)
}
func SalvarEtiquetaHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.SalvarEtiquetaReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.SalvarEtiqueta(r.Context(), req)
if err != nil {
http.Error(w, "salva datos etiqueta handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func SalvarImpresorasEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/impresora/create",
endpoint.BodyR(types.SalvarImpresoraReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.SalvarImpresoraRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Salva los datos de la impresora"),
endpoint.Description("Salva los datos de la impresora"),
endpoint.Handler(SalvarImpresoraHandler(svc)),
)
}
func SalvarImpresoraHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.SalvarImpresoraReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.SalvarImpresora(r.Context(), req)
if err != nil {
http.Error(w, "salva datos impresora handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func ImpresorasEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/impresora/list",
endpoint.BodyR(types.ImpresorasReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.ImpresorasRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene los datos de las impresoras"),
endpoint.Description("Obtiene los datos de las impresoras"),
endpoint.Handler(ImpresorasHandler(svc)),
)
}
func ImpresorasHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.ImpresorasReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.Impresoras(r.Context(), req)
if err != nil {
http.Error(w, "obtiene datos de las impresoras handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func ImpresoraEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/impresora/get",
endpoint.BodyR(types.ImpresoraReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.ImpresoraRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtiene los datos de la impresora"),
endpoint.Description("Obtiene los datos de la impresora"),
endpoint.Handler(ImpresoraHandler(svc)),
)
}
func ImpresoraHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.ImpresoraReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.Impresora(r.Context(), req)
if err != nil {
http.Error(w, "obtiene datos impresora handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func OrdenesClientesEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/co/list",
endpoint.BodyR(types.OrdenesClienteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.OrdenesClienteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtener lista de Ordenes de cliente"),
endpoint.Description("Obtener lista de Ordenes de cliente"),
endpoint.Handler(OrdenesClienteHandler(svc)),
)
}
func OrdenesClienteHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.OrdenesClienteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.OrdenesCliente(r.Context(), req)
if err != nil {
http.Error(w, "obtiene ordenes de cliente handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func OrdenClienteEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/co/get",
endpoint.BodyR(types.OrdenClienteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.OrdenClienteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtener lista de Ordenes de cliente"),
endpoint.Description("Obtener lista de Ordenes de cliente"),
endpoint.Handler(OrdenClienteHandler(svc)),
)
}
func OrdenClienteHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.OrdenClienteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.OrdenCliente(r.Context(), req)
if err != nil {
http.Error(w, "obtiene ordenes de cliente handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func OrdenesProduccionEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/po/list",
endpoint.BodyR(types.OrdenesProduccionReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.OrdenesProduccionRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtener lista de Ordenes de producción"),
endpoint.Description("Obtener lista de Ordenes de producción"),
endpoint.Handler(OrdenesProduccionHandler(svc)),
)
}
func OrdenesProduccionHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.OrdenesProduccionReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.OrdenesProduccion(r.Context(), req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func OrdenProduccionEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/po/get",
endpoint.BodyR(types.OrdenProduccionReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.OrdenProduccionRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Obtener datos de la Orden de producción basado en el identificador"),
endpoint.Description("Obtener datos de la Orden de producción basado en el identificador"),
endpoint.Handler(OrdenProduccionHandler(svc)),
)
}
func OrdenProduccionHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.OrdenProduccionReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.OrdenProduccion(r.Context(), req)
if err != nil {
http.Error(w, "obtiene orden de produccion by id datos handler failed", http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func ImprimirPaqueteRobotEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/robot/print",
endpoint.BodyR(types.ImprimirPaqueteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.ImprimirPaqueteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Imprimir paquete"),
endpoint.Description("Imprimir paquete"),
endpoint.Handler(ImprimirPaqueteRobotHandler(svc)),
)
}
func ImprimirPaqueteRobotHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.ImprimirPaqueteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.ImprimirPaqueteRobot(r.Context(), req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func ImprimirEtiquetaEndPoint(svc service.IService) *swag.Endpoint {
return endpoint.New(http.MethodPost, "/paquete/print",
endpoint.BodyR(types.ImprimirPaqueteReq{}),
endpoint.ResponseSuccess(endpoint.SchemaResponseOption(types.ImprimirPaqueteRes{})),
endpoint.Response(http.StatusInternalServerError, "process internal error", endpoint.SchemaResponseOption("")),
endpoint.Summary("Imprimir paquete"),
endpoint.Description("Imprimir paquete"),
endpoint.Handler(ImprimirEtiquetaHandler(svc)),
)
}
func ImprimirEtiquetaHandler(svc service.IService) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// request body holder
req := &types.ImprimirPaqueteReq{}
// decode json body request
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "body json decoding failed", http.StatusBadRequest)
return
}
res, err := svc.ImprimirPaquete(r.Context(), req)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// set content type header
w.Header().Set("Content-Type", "application/json")
// response
w.WriteHeader(http.StatusOK)
// write response
if err := json.NewEncoder(w).Encode(&res); err != nil {
http.Error(w, "encode response failed", http.StatusInternalServerError)
return
}
})
}
func (s *Server) Start() error {
// set api handlers
for p, endpoints := range s.api.Paths {
http.DefaultServeMux.Handle(path.Join(s.api.BasePath, p), endpoints)
}
// set swagger handlers
http.DefaultServeMux.Handle("/swagger/json", s.api.Handler())
patterns := swag.UIPatterns("/swagger/ui")
for _, pattern := range patterns {
http.DefaultServeMux.Handle(pattern, swag.UIHandler("/swagger/ui", "/swagger/json", true))
}
// Crear un servidor HTTP
server := http.Server{
Addr: s.url,
ReadTimeout: 5 * time.Second, // time limit for reading
WriteTimeout: 5 * time.Second, // time limit for writting
IdleTimeout: 5 * time.Second,
}
// start api
go func() {
if err := server.ListenAndServe(); err != nil {
panic(err)
}
}()
return nil
}
func NewServer(url string, svc service.IService) *Server {
// create new swag
api := swag.New(
option.Title("CELSA 4 Plb018 API Server"),
option.Description("This is an implementation of a REST API server for Plb18"),
option.ContactEmail("aespin@gcelsa.com"),
option.Version("1.0"),
option.BasePath("/api/v1"),
option.License("MIT", "https://opensource.org/license/mit"),
)
// add end points
api.AddEndpoint(
ImprimirEtiquetaEndPoint(svc),
ImprimirPaqueteRobotEndPoint(svc),
EtiquetaEndPoint(svc),
EtiquetasEndPoint(svc),
SalvarEtiquetaEndPoint(svc),
OrdenProduccionEndPoint(svc),
OrdenesProduccionEndPoint(svc),
OrdenClienteEndPoint(svc),
OrdenesClientesEndPoint(svc),
ImpresoraEndPoint(svc),
ImpresorasEndPoint(svc),
SalvarImpresorasEndPoint(svc),
PaqueteEndPoint(svc),
PaquetesEndPoint(svc),
NroMatriculaActualEndPoint(svc),
NroMatriculaSiguienteEndPoint(svc),
)
// return new server
return &Server{
svc: svc,
api: api,
url: url,
}
}

510
internal/service/service.go Normal file
View File

@ -0,0 +1,510 @@
package service
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"net"
"strconv"
"strings"
"sync"
"time"
cml04eventer "git.espin.casa/albert/cml04-eventer"
"git.espin.casa/albert/cml04-plb018/internal/helpers"
"git.espin.casa/albert/cml04-plb018/internal/storage"
"git.espin.casa/albert/cml04-plb018/internal/types"
"gorm.io/gorm"
)
var (
NSQTOPIC = map[types.Robot]string{
types.Robot12: "ROBOT12",
types.Robot345: "ROBOT345",
}
)
type IService interface {
// Etiquetas
Etiqueta(ctx context.Context, req *types.EtiquetaReq) (res *types.EtiquetaRes, err error)
Etiquetas(ctx context.Context, req *types.EtiquetasReq) (res *types.EtiquetasRes, err error)
SalvarEtiqueta(ctx context.Context, req *types.SalvarEtiquetaReq) (res *types.SalvarEtiquetaRes, err error)
// Normas
Normas(ctx context.Context, req *types.NormasReq) (res *types.NormasRes, err error)
// Orden Produccion
OrdenProduccion(ctx context.Context, req *types.OrdenProduccionReq) (res *types.OrdenProduccionRes, err error)
OrdenesProduccion(ctx context.Context, req *types.OrdenesProduccionReq) (res *types.OrdenesProduccionRes, err error)
// Orden Cliente
OrdenCliente(ctx context.Context, req *types.OrdenClienteReq) (res *types.OrdenClienteRes, err error)
OrdenesCliente(ctx context.Context, req *types.OrdenesClienteReq) (res *types.OrdenesClienteRes, err error)
// Impresora
Impresora(ctx context.Context, req *types.ImpresoraReq) (res *types.ImpresoraRes, err error)
Impresoras(ctx context.Context, req *types.ImpresorasReq) (res *types.ImpresorasRes, err error)
SalvarImpresora(ctx context.Context, req *types.SalvarImpresoraReq) (res *types.SalvarImpresoraRes, err error)
// Paquetes
Paquete(ctx context.Context, req *types.PaqueteReq) (res *types.PaqueteRes, err error)
Paquetes(ctx context.Context, req *types.PaquetesReq) (res *types.PaquetesRes, err error)
ImprimirPaquete(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error)
ImprimirPaqueteRobot(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error)
// Nro Paquetes
NroPaqueteActual(ctx context.Context, req *types.NroPaqueteActualReq) (res *types.NroPaqueteActualRes, err error)
NroPaqueteSiguiente(ctx context.Context, req *types.NroPaqueteSiguienteReq) (res *types.NroPaqueteSiguienteRes, err error)
}
type service struct {
pub cml04eventer.Publisher
storage storage.Storager
mux *sync.Mutex
}
// NroPaqueteActual implements IService.
func (s *service) NroPaqueteActual(ctx context.Context, req *types.NroPaqueteActualReq) (res *types.NroPaqueteActualRes, err error) {
nroMatricula, err := helpers.NroPaqueteActual(req.PEtiquetado)
if err != nil {
return nil, err
}
return &types.NroPaqueteActualRes{
NroMatricula: nroMatricula,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// NroPaqueteSiguiente implements IService.
func (s *service) NroPaqueteSiguiente(ctx context.Context, req *types.NroPaqueteSiguienteReq) (res *types.NroPaqueteSiguienteRes, err error) {
nroMatricula, err := helpers.NroPaqueteSiguiente(req.PEtiquetado)
if err != nil {
return nil, err
}
return &types.NroPaqueteSiguienteRes{
NroMatricula: nroMatricula,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// ImprimirPaqueteRobot implements IService.
func (s *service) ImprimirPaqueteRobot(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error) {
// create buffer
buff := bytes.Buffer{}
// encode request
if err := json.NewEncoder(&buff).Encode(req); err != nil {
return nil, err
}
// get nsq robot topic
topic, ok := NSQTOPIC[req.Robot]
if !ok {
return nil, fmt.Errorf("robot topic not found")
}
// create meta header event
meta := cml04eventer.NewMetaData()
// set subjet
meta.Set("subject", "pbl018.print.data")
// create event
event := cml04eventer.NewEvent("PLB018", topic, meta, buff.Bytes())
// publish event
if err := s.pub.PublishEvent(event); err != nil {
return nil, err
}
// crear paquete
paquete, err := s.CrearDatosPaquete(ctx, req)
if err != nil {
return nil, err
}
// guardar paquete
if err := s.SalvarPaquete(ctx, paquete); err != nil {
return nil, err
}
// return response
return &types.ImprimirPaqueteRes{
Respuesta: fmt.Sprintf("imprimir paquete [%s] mediante robot finalizó con éxito", req.DatosEtiqueta.NroMatricula),
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Paquete implements IService.
func (s *service) Paquete(ctx context.Context, req *types.PaqueteReq) (res *types.PaqueteRes, err error) {
paquete, err := s.storage.Paquete(ctx, req.Codigo)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.PaqueteRes{
Paquete: paquete,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Paquetes implements IService.
func (s *service) Paquetes(ctx context.Context, req *types.PaquetesReq) (res *types.PaquetesRes, err error) {
inicio, err := time.Parse("02/01/2006 15:04:05", req.Inicio)
if err != nil {
return nil, err
}
final, err := time.Parse("02/01/2006 15:04:05", req.Final)
if err != nil {
return nil, err
}
paquetes, err := s.storage.Paquetes(ctx, inicio, final)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.PaquetesRes{
Paquetes: paquetes,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Etiqueta implements IService.
func (s *service) Etiqueta(ctx context.Context, req *types.EtiquetaReq) (res *types.EtiquetaRes, err error) {
etiqueta, err := s.storage.Etiqueta(ctx, req.Codigo)
if err != nil {
return nil, err
}
return &types.EtiquetaRes{
Etiqueta: etiqueta,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Etiquetas implements IService.
func (s *service) Etiquetas(ctx context.Context, req *types.EtiquetasReq) (res *types.EtiquetasRes, err error) {
// get etiquetas
etiquetas, err := s.storage.Etiquetas(ctx)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.EtiquetasRes{
Etiquetas: etiquetas,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
func (s *service) SalvarEtiqueta(ctx context.Context, req *types.SalvarEtiquetaReq) (res *types.SalvarEtiquetaRes, err error) {
if err := s.storage.SalvarEtiqueta(ctx, req.Etiqueta); err != nil {
return nil, err
}
// return response
return &types.SalvarEtiquetaRes{
Respuesta: fmt.Sprintf("save label: %s success", req.Etiqueta.Codigo),
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// SalvarImpresora implements IService.
func (s *service) SalvarImpresora(ctx context.Context, req *types.SalvarImpresoraReq) (res *types.SalvarImpresoraRes, err error) {
if err := s.storage.SalvarImpresora(ctx, req.Impresora); err != nil {
return nil, err
}
// return response
return &types.SalvarImpresoraRes{
Message: fmt.Sprintf("save printer: %s success", req.Impresora.ID),
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Impresora implements IService.
func (s *service) Impresora(ctx context.Context, req *types.ImpresoraReq) (res *types.ImpresoraRes, err error) {
// get impresora
zebra, err := s.storage.Impresora(ctx, req.ID)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.ImpresoraRes{
Impresora: zebra,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Impresoras implements IService.
func (s *service) Impresoras(ctx context.Context, req *types.ImpresorasReq) (res *types.ImpresorasRes, err error) {
// get impresoras
zebras, err := s.storage.Impresoras(ctx)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.ImpresorasRes{
Impresoras: zebras,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, err
}
// OrdenesProduccion implements IService.
func (s *service) OrdenesProduccion(ctx context.Context, req *types.OrdenesProduccionReq) (res *types.OrdenesProduccionRes, err error) {
// get ordenes produccion
pos, err := s.storage.OrdenesProduccion(ctx, req.Limit)
// handle error
if err != nil {
return nil, err
}
// return response
return &types.OrdenesProduccionRes{
OrdenesProduccion: pos,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// OrdenesCliente implements IService.
func (s *service) OrdenesCliente(ctx context.Context, req *types.OrdenesClienteReq) (res *types.OrdenesClienteRes, err error) {
// get ordenes clientes
cos, err := s.storage.OrdenesCliente(ctx, req.PoID)
// handle error
if err != nil {
return nil, err
}
return &types.OrdenesClienteRes{OrdenesCliente: cos, TimeStamp: time.Now().UTC().Format(time.RFC3339)}, nil
}
// OrdenCliente implements IService.
func (s *service) OrdenCliente(ctx context.Context, req *types.OrdenClienteReq) (res *types.OrdenClienteRes, err error) {
// get orden cliente
co, err := s.storage.OrdenCliente(ctx, req.CoID)
// handle error
if err != nil {
return nil, err
}
return &types.OrdenClienteRes{
OrdenCliente: co,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// OrdenProduccion implements IService.
func (s *service) OrdenProduccion(ctx context.Context, req *types.OrdenProduccionReq) (res *types.OrdenProduccionRes, err error) {
// get orden produccion
po, err := s.storage.OrdenProduccion(ctx, req.PoID)
if err != nil {
return nil, err
}
return &types.OrdenProduccionRes{
OrdenProduccion: po,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
// Normas implements IService.
func (s *service) Normas(ctx context.Context, req *types.NormasReq) (res *types.NormasRes, err error) {
normas, err := s.storage.Normas(ctx, req.Codigo)
if err != nil {
return nil, err
}
return &types.NormasRes{
Normas: normas,
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
func TipoEtiqueta(producto string) types.EtiquetaTipo {
if strings.HasPrefix(producto, "W") {
return types.EtiquetaAmericana
} else if strings.HasPrefix(producto, "UB") || strings.HasPrefix(producto, "UC") || strings.HasPrefix(producto, "UPF") {
return types.EtiquetaBritanica
} else {
return types.EtiquetaEuropea
}
}
func (s *service) SalvarPaquete(ctx context.Context, paquete *types.Paquete) error {
// check if bundle already exists
_, err := s.storage.Paquete(ctx, paquete.NroPaquete)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
// doesn't exists create it!
return s.CrearPaquete(ctx, paquete)
} else {
// error
return err
}
} else {
// exists update it!
return s.storage.ActualizarPaquete(ctx, paquete)
}
}
func (s *service) CrearDatosPaquete(ctx context.Context, req *types.ImprimirPaqueteReq) (*types.Paquete, error) {
// get orden cliente
co, err := s.storage.OrdenCliente(ctx, req.DatosEtiqueta.CoID)
if err != nil {
return nil, err
}
// get material code
matnr := co.MaterCode
// get norma code
matnr = strings.Split(matnr, "-")[0]
// get normas
normas, err := s.storage.Normas(ctx, matnr)
if err != nil {
return nil, err
}
// get production order
po, err := s.storage.OrdenProduccion(ctx, co.POrderNo)
if err != nil {
return nil, err
}
// barras
barras, err := strconv.Atoi(req.DatosEtiqueta.NrBarras)
if err != nil {
return nil, err
}
// get longitud
longitud, err := strconv.ParseFloat(co.OrdLen, 64)
if err != nil {
return nil, err
}
longitud = longitud / 1000
// create bundle data
return &types.Paquete{
NroPaquete: req.DatosEtiqueta.NroMatricula,
OrdenProduccion: po.POrderNo,
OrdenCliente: co.COrderNo,
Producto: po.FSection,
Colada: req.DatosEtiqueta.Colada,
Calidad: normas.Calidad,
Matnr: co.MaterCode,
Operador: req.DatosEtiqueta.Operador,
Turno: req.DatosEtiqueta.Turno,
Longitud: longitud,
Barras: uint8(barras),
Peso: req.DatosEtiqueta.Peso,
PesoTeorico: req.DatosEtiqueta.PesoTeorico,
Normed: normas.NormaMedida,
Norpro: normas.NormaProducto,
Nortol: normas.NormaTolerancia,
DesvioPeso: req.DatosEtiqueta.DesvioPeso,
Confirmado: false,
Procesado: false,
Observaciones: "",
Reclasificado: false,
}, nil
}
// ImprimirPaquete implements IService.
func (s *service) ImprimirPaquete(ctx context.Context, req *types.ImprimirPaqueteReq) (res *types.ImprimirPaqueteRes, err error) {
// crear datos paq
paquete, err := s.CrearDatosPaquete(ctx, req)
if err != nil {
return nil, err
}
// salvar paquete
if err := s.SalvarPaquete(ctx, paquete); err != nil {
return nil, err
}
// create label zpl code
contenido, err := s.CrearEtiqueta(
ctx,
req.DatosEtiqueta.NroMatricula,
// convert longitud to string
strconv.FormatFloat(paquete.Longitud, 'f', 2, 64),
req.DatosEtiqueta.Colada,
paquete.Normed,
paquete.Norpro,
paquete.Nortol,
paquete.Calidad,
time.Now().Format("02/01/2006"),
req.DatosEtiqueta.NrBarras,
paquete.Producto,
req.DatosEtiqueta.NrEtiquetas,
TipoEtiqueta(paquete.Producto),
)
// handle error
if err != nil {
return nil, err
}
// imprimir
if err := s.Imprimir(ctx, contenido, req.ImpresoraID); err != nil {
return nil, err
}
// return response
return &types.ImprimirPaqueteRes{
Respuesta: "imprimir etiqueta success",
TimeStamp: time.Now().UTC().Format(time.RFC3339),
}, nil
}
func (s *service) CrearPaquete(ctx context.Context, paquete *types.Paquete) error {
return s.storage.SalvarPaquete(ctx, paquete)
}
func (s *service) ActualizarPaquete(ctx context.Context, paquete *types.Paquete) error {
return s.storage.ActualizarPaquete(ctx, paquete)
}
func (s *service) CrearEtiqueta(ctx context.Context, nroMatricula, longitud, colada, normaa, normab, normac, calidad, fecha, barras, producto, nroEtis string, tipo types.EtiquetaTipo) ([]byte, error) {
// get formato
formato, ok := types.TipoFormato[tipo]
if !ok {
return nil, fmt.Errorf("tipo formato etiqueta no existe")
}
// get etiqueta
etiqueta, err := s.storage.Etiqueta(ctx, formato)
if err != nil {
return nil, err
}
// si el producto es americano la longitud se convierte a pies
if helpers.EsAmericano(producto) {
// convertir longitud a pies
l, err := strconv.ParseFloat(longitud, 64)
if err != nil {
return nil, err
}
longitud = strconv.FormatFloat(l, 'f', 2, 64)
}
// replace all template with label data
contenido := etiqueta.Contenido
contenido = strings.ReplaceAll(contenido, "9999999999", nroMatricula)
contenido = strings.ReplaceAll(contenido, "{{longitud}}", longitud)
contenido = strings.ReplaceAll(contenido, "{{colada}}", colada)
contenido = strings.ReplaceAll(contenido, "{{normaA}}", normaa)
contenido = strings.ReplaceAll(contenido, "{{normaB}}", normab)
contenido = strings.ReplaceAll(contenido, "{{normaC}}", normac)
contenido = strings.ReplaceAll(contenido, "{{calidad}}", calidad)
contenido = strings.ReplaceAll(contenido, "{{fecha}}", fecha)
contenido = strings.ReplaceAll(contenido, "{{barras}}", barras)
contenido = strings.ReplaceAll(contenido, "{{producto}}", producto)
contenido = strings.ReplaceAll(contenido, "{{etiquetas}}", nroEtis)
// return
return []byte(contenido), nil
}
func (s *service) Imprimir(ctx context.Context, data []byte, ImpresoraID string) error {
if strings.ToUpper(ImpresoraID) == "NONE" {
return nil
}
s.mux.Lock()
defer s.mux.Unlock()
impresora, err := s.storage.Impresora(ctx, ImpresoraID)
if err != nil {
return err
}
// connect to printer
conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", impresora.Address, impresora.Port))
if err != nil {
return err
}
// close connection
defer conn.Close()
// send data
_, err = conn.Write(data)
if err != nil {
return err
}
return nil
}
func NewService(storage storage.Storager, pub cml04eventer.Publisher) IService {
return &service{
pub: pub,
storage: storage,
mux: &sync.Mutex{},
}
}

241
internal/storage/storage.go Normal file
View File

@ -0,0 +1,241 @@
package storage
import (
"context"
"fmt"
"sync"
"time"
"git.espin.casa/albert/cml04-plb018/internal/types"
"git.espin.casa/albert/logger"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
)
type Storager interface {
// Normas
Normas(ctx context.Context, codigo string) (*types.Normas, error)
SalvarNormas(ctx context.Context, etiqueta *types.NormaList) error
// Ordenes produccion
OrdenProduccion(ctx context.Context, po int) (*types.ProductionOrder, error)
OrdenesProduccion(ctx context.Context, limit int) ([]types.ProductionOrder, error)
SalvarOrdenProduccion(ctx context.Context, po *types.ProductionOrder) error
// Ordenes cliente
OrdenCliente(ctx context.Context, co int) (*types.CustomerOrder, error)
OrdenesCliente(ctx context.Context, po int) ([]types.CustomerOrder, error)
SalvarOrdenCliente(ctx context.Context, co *types.CustomerOrder) error
// Impresoras
Impresora(ctx context.Context, id string) (*types.Zebra, error)
Impresoras(ctx context.Context) ([]types.Zebra, error)
SalvarImpresora(ctx context.Context, zebra *types.Zebra) error
// Etiquetas
Etiqueta(ctx context.Context, id string) (*types.Label, error)
Etiquetas(ctx context.Context) ([]types.Label, error)
SalvarEtiqueta(ctx context.Context, label *types.Label) error
// Paquetes
Paquete(ctx context.Context, id string) (*types.Paquete, error)
Paquetes(ctx context.Context, inicio, final time.Time) ([]types.Paquete, error)
SalvarPaquete(ctx context.Context, paquete *types.Paquete) error
ActualizarPaquete(ctx context.Context, paquete *types.Paquete) error
}
type storage struct {
db *gorm.DB
mux *sync.RWMutex
log logger.LoggerAdapter
}
// ActualizarPaquete implements Storager.
func (s *storage) ActualizarPaquete(ctx context.Context, paquete *types.Paquete) error {
return s.db.Model(&types.Paquete{}).Where("nro_paquete = ?", paquete.NroPaquete).Updates(types.Paquete{
NroPaquete: paquete.NroPaquete,
OrdenProduccion: paquete.OrdenProduccion,
OrdenCliente: paquete.OrdenCliente,
Producto: paquete.Producto,
Colada: paquete.Colada,
Calidad: paquete.Calidad,
Matnr: paquete.Matnr,
Operador: paquete.Operador,
Turno: paquete.Turno,
Longitud: paquete.Longitud,
Barras: paquete.Barras,
Peso: paquete.Peso,
PesoTeorico: paquete.PesoTeorico,
Normed: paquete.Normed,
Norpro: paquete.Norpro,
Nortol: paquete.Nortol,
DesvioPeso: paquete.DesvioPeso,
Confirmado: true,
Procesado: false,
Observaciones: fmt.Sprintf("reclasificado por: %s en fecha: %s", paquete.Operador, time.Now().Format("02/01/2006 15:04")),
Reclasificado: true,
UpdatedAt: time.Now(),
}).Error
}
// Paquete implements Storager.
func (s *storage) Paquete(ctx context.Context, id string) (*types.Paquete, error) {
paquete := &types.Paquete{}
if err := s.db.Where("nro_paquete = ?", id).First(paquete).Error; err != nil {
return nil, err
}
return paquete, nil
}
// Paquetes implements Storager.
func (s *storage) Paquetes(ctx context.Context, inicio time.Time, final time.Time) ([]types.Paquete, error) {
paquetes := []types.Paquete{}
// get paquetes
if err := s.db.Where("created_at BETWEEN ? AND ?", inicio, final).Find(&paquetes).Error; err != nil {
return nil, err
}
return paquetes, nil
}
// SalvarPaquete implements Storager.
func (s *storage) SalvarPaquete(ctx context.Context, paquete *types.Paquete) error {
return s.db.Create(paquete).Error
}
// Etiquetas implements Storager.
func (s *storage) Etiquetas(ctx context.Context) ([]types.Label, error) {
etiquetas := []types.Label{}
if err := s.db.Order("codigo asc").Find(&etiquetas).Error; err != nil {
return nil, err
}
return etiquetas, nil
}
// Etiqueta implements Storager.
func (s *storage) Etiqueta(ctx context.Context, id string) (*types.Label, error) {
etiqueta := &types.Label{}
// get etiqueta
if err := s.db.Where("codigo = ?", id).First(etiqueta).Error; err != nil {
return nil, err
}
return etiqueta, nil
}
// SalvarEtiqueta implements Storager.
func (s *storage) SalvarEtiqueta(ctx context.Context, label *types.Label) error {
return s.db.Save(label).Error
}
// SalvarNormas implements Storager.
func (s *storage) SalvarNormas(ctx context.Context, normas *types.NormaList) error {
for _, norma := range normas.Lista {
if err := s.db.Save(&norma).Error; err != nil {
return err
}
}
return nil
}
// Impresora implements Storager.
func (s *storage) Impresora(ctx context.Context, id string) (*types.Zebra, error) {
zebra := &types.Zebra{}
if err := s.db.Where("id = ?", id).First(zebra).Error; err != nil {
return nil, err
}
return zebra, nil
}
// Impresoras implements Storager.
func (s *storage) Impresoras(ctx context.Context) ([]types.Zebra, error) {
zebras := []types.Zebra{}
if err := s.db.Order("id asc").Find(&zebras).Error; err != nil {
return nil, err
}
return zebras, nil
}
// SalvarImpresora implements Storager.
func (s *storage) SalvarImpresora(ctx context.Context, zebra *types.Zebra) error {
return s.db.Save(zebra).Error
}
// OrdenesProduccion implements Storager.
func (s *storage) OrdenesProduccion(ctx context.Context, limit int) ([]types.ProductionOrder, error) {
poos := []types.ProductionOrder{}
// get production orders
if err := s.db.Order("p_order_no desc").Limit(limit).Find(&poos).Error; err != nil {
return nil, err
}
return poos, nil
}
// Normas implements Storager.
func (s *storage) Normas(ctx context.Context, codigo string) (*types.Normas, error) {
normas := &types.Normas{}
// get normas
if err := s.db.Where("codigo = ?", codigo).First(normas).Error; err != nil {
return nil, err
}
return normas, nil
}
// OrdenCliente implements Storager.
func (s *storage) OrdenCliente(ctx context.Context, co int) (*types.CustomerOrder, error) {
coo := &types.CustomerOrder{}
// get customer order
if err := s.db.Where("c_order_no=?", co).First(coo).Error; err != nil {
return nil, err
}
return coo, nil
}
// OrdenProduccion implements Storager.
func (s *storage) OrdenProduccion(ctx context.Context, po int) (*types.ProductionOrder, error) {
pro := &types.ProductionOrder{}
// get production order
if err := s.db.Where("p_order_no=?", po).First(pro).Error; err != nil {
return nil, err
}
return pro, nil
}
// OrdenesCliente implements Storager.
func (s *storage) OrdenesCliente(ctx context.Context, po int) ([]types.CustomerOrder, error) {
cos := []types.CustomerOrder{}
if err := s.db.Where("p_order_no=?", po).Order("c_order_no asc").Find(&cos).Error; err != nil {
return nil, err
}
return cos, nil
}
// SalvarOrdenCliente implements Storager.
func (s *storage) SalvarOrdenCliente(ctx context.Context, co *types.CustomerOrder) error {
// save orden cliente
return s.db.Save(co).Error
}
// SalvarOrdenProduccion implements Storager.
func (s *storage) SalvarOrdenProduccion(ctx context.Context, po *types.ProductionOrder) error {
// save orden produccion
return s.db.Save(po).Error
}
func AutoMigrate(db *gorm.DB) error {
return db.AutoMigrate(
&types.Normas{},
&types.ProductionOrder{},
&types.CustomerOrder{},
&types.Zebra{},
&types.Paquete{},
&types.Label{},
)
}
func NewStorage(log logger.LoggerAdapter) (Storager, error) {
// create database connection
db, err := gorm.Open(sqlite.Open("db.sqlite"), &gorm.Config{})
// auto migrate database
if err := AutoMigrate(db); err != nil {
return nil, err
}
return &storage{
db: db,
mux: &sync.RWMutex{},
log: log,
}, err
}

189
internal/types/api.go Normal file
View File

@ -0,0 +1,189 @@
package types
type PEtiquetado uint8
const (
Ata12 PEtiquetado = iota + 1
Ata345
)
type Robot uint8
const (
Robot12 Robot = iota + 1
Robot345
)
type NroPaqueteActualReq struct {
PEtiquetado PEtiquetado
TimeStamp string
}
type NroPaqueteActualRes struct {
NroMatricula string
TimeStamp string
}
type NroPaqueteSiguienteReq struct {
PEtiquetado PEtiquetado
TimeStamp string
}
type NroPaqueteSiguienteRes struct {
NroMatricula string
TimeStamp string
}
type PaquetesReq struct {
Inicio string
Final string
TimeStamp string
}
type PaquetesRes struct {
Paquetes []Paquete
TimeStamp string
}
type PaqueteReq struct {
Codigo string
TimeStamp string
}
type PaqueteRes struct {
Paquete *Paquete
TimeStamp string
}
type EtiquetaReq struct {
Codigo string
TimeStamp string
}
type EtiquetaRes struct {
Etiqueta *Label
TimeStamp string
}
type EtiquetasReq struct {
TimeStamp string
}
type EtiquetasRes struct {
Etiquetas []Label
TimeStamp string
}
type SalvarEtiquetaReq struct {
Etiqueta *Label
TimeStamp string
}
type SalvarEtiquetaRes struct {
Respuesta string
TimeStamp string
}
type NormasReq struct {
Codigo string
TimeStamp string
}
type NormasRes struct {
Normas *Normas
TimeStamp string
}
type ImprimirPaqueteReq struct {
ImpresoraID string
Robot Robot
DatosEtiqueta *DatosEtiqueta
TimeStamp string
}
type ImprimirPaqueteRes struct {
Respuesta string
TimeStamp string
}
type OrdenProduccionReq struct {
PoID int
TimeStamp string
}
type OrdenProduccionRes struct {
OrdenProduccion *ProductionOrder
TimeStamp string
}
type OrdenClienteReq struct {
CoID int
TimeStamp string
}
type OrdenClienteRes struct {
OrdenCliente *CustomerOrder
TimeStamp string
}
type OrdenesClienteReq struct {
PoID int
TimeStamp string
}
type OrdenesClienteRes struct {
OrdenesCliente []CustomerOrder
TimeStamp string
}
type DatosEtiqueta struct {
CoID int
Peso float64
PesoTeorico float64
DesvioPeso float64
Turno string
Operador string
Colada string
NrBarras string
NrEtiquetas string
NroMatricula string
}
type OrdenesProduccionReq struct {
Limit int
TimeStamp string
}
type OrdenesProduccionRes struct {
OrdenesProduccion []ProductionOrder
TimeStamp string
}
type ImpresoraReq struct {
ID string
TimeStamp string
}
type ImpresoraRes struct {
Impresora *Zebra
TimeStamp string
}
type ImpresorasReq struct {
TimeStamp string
}
type ImpresorasRes struct {
Impresoras []Zebra
TimeStamp string
}
type SalvarImpresoraReq struct {
Impresora *Zebra
TimeStamp string
}
type SalvarImpresoraRes struct {
Message string
TimeStamp string
}

94
internal/types/co.go Normal file
View File

@ -0,0 +1,94 @@
package types
import (
"time"
"gorm.io/gorm"
)
type CustomerOrder struct {
Inst string `json:"INST"`
DateTime string `json:"DATE_TIME"`
COrderNo int `json:"C_ORDER_NO" gorm:"primarykey"`
POrderNo int `json:"P_ORDER_NO" gorm:"index"`
SchedulNo int `json:"SCHEDUL_NO"`
OrdWeight string `json:"ORD_WEIGHT"`
OrdLen string `json:"ORD_LEN"`
OrLenTU string `json:"OR_LEN_T_U"`
OrLenTL string `json:"OR_LEN_T_L"`
PackType int `json:"PACK_TYPE"`
SectLayer int `json:"SECT_LAYER"`
LayerPack int `json:"LAYER_PACK"`
SecLastL int `json:"SEC_LAST_L"`
TotalSect int `json:"TOTAL_SECT"`
PackWidth int `json:"PACK_WIDTH"`
PackHigh int `json:"PACK_HIGH"`
OutpTolU int `json:"OUTP_TOL_U"`
OutpTolD int `json:"OUTP_TOL_D"`
LogoCode int `json:"LOGO_CODE"`
SecondLab string `json:"SECOND_LAB"`
PaintText string `json:"PAINT_TEXT"`
AddLabel1 string `json:"ADD_LABEL1"`
AddLabel2 string `json:"ADD_LABEL2"`
AddLabel3 string `json:"ADD_LABEL3"`
MaterCode string `json:"MATER_CODE"`
ProduDate int `json:"PRODU_DATE"`
LangLabel string `json:"LANG_LABEL"`
Warehouse string `json:"WAREHOUSE"`
Location string `json:"LOCATION"`
Marking string `json:"MARKING"`
DisForwar string `json:"DIS_FORWAR"`
NumTies int `json:"NUM_TIES"`
DisTies string `json:"DIS_TIES"`
DisMachin string `json:"DIS_MACHIN"`
Vbeln string `json:"VBELN"`
Posnr string `json:"POSNR"`
CoType string `json:"CO_TYPE"`
LoadBed int `json:"LOAD_BED"`
SecNum int `json:"SEC_NUM"`
Numpal int `json:"NUMPAL"`
Numbul string `json:"NUMBUL"`
Marfab int `json:"MARFAB"`
Sortb string `json:"SORTB"`
Strol1 int `json:"STROL1"`
Strol2 string `json:"STROL2"`
Strol3 int `json:"STROL3"`
Strol4 int `json:"STROL4"`
Strol5 int `json:"STROL5"`
Strol6 int `json:"STROL6"`
Strol7 int `json:"STROL7"`
Strol8 int `json:"STROL8"`
Strol9 int `json:"STROL9"`
Strol10 int `json:"STROL10"`
Strol11 int `json:"STROL11"`
Strol12 int `json:"STROL12"`
Strol13 int `json:"STROL13"`
Strol14 int `json:"STROL14"`
Strol15 int `json:"STROL15"`
Strol16 string `json:"STROL16"`
Strol17 string `json:"STROL17"`
Strol18 string `json:"STROL18"`
Strol19 string `json:"STROL19"`
Strol20 string `json:"STROL20"`
Strol21 string `json:"STROL21"`
Strol22 string `json:"STROL22"`
Strol23 string `json:"STROL23"`
Strol24 string `json:"STROL24"`
Strol25 string `json:"STROL25"`
Strol26 string `json:"STROL26"`
Strol27 string `json:"STROL27"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (c *CustomerOrder) BeforeCreate(tx *gorm.DB) (err error) {
c.CreatedAt = time.Now()
c.UpdatedAt = time.Now()
return
}
func (c *CustomerOrder) BeforeUpdate(tx *gorm.DB) (err error) {
c.UpdatedAt = time.Now()
return
}

View File

@ -0,0 +1,43 @@
package types
import (
"time"
"gorm.io/gorm"
)
type EtiquetaTipo uint8
const (
EtiquetaEuropea EtiquetaTipo = iota + 1
EtiquetaBritanica
EtiquetaAmericana
)
var (
TipoFormato = map[EtiquetaTipo]string{
EtiquetaEuropea: "EU-200dpi",
EtiquetaAmericana: "US-200dpi",
EtiquetaBritanica: "UK-200dpi",
}
)
type Label struct {
Codigo string `json:"codigo" gorm:"primaryKey"`
Tipo EtiquetaTipo
Contenido string
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (l *Label) BeforeCreate(tx *gorm.DB) (err error) {
l.CreatedAt = time.Now()
l.UpdatedAt = time.Now()
return
}
func (l *Label) BeforeUpdate(tx *gorm.DB) (err error) {
l.UpdatedAt = time.Now()
return
}

36
internal/types/normas.go Normal file
View File

@ -0,0 +1,36 @@
package types
import (
"time"
"gorm.io/gorm"
)
type Normas struct {
Codigo string `json:"codigo" gorm:"primarykey"`
Calidad string `json:"calidad"`
CodProducto string `json:"cod_producto,omitempty"`
CodMedida string `json:"cod_medida,omitempty"`
CodTolerancia string `json:"cod_tolerancia,omitempty"`
NormaProducto string `json:"norma_producto,omitempty"`
NormaMedida string `json:"norma_medida,omitempty"`
NormaTolerancia string `json:"norma_tolerancia,omitempty"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
type NormaList struct {
Lista []Normas `json:"Etiqueta"`
}
func (n *Normas) BeforeCreate(tx *gorm.DB) (err error) {
n.CreatedAt = time.Now()
n.UpdatedAt = time.Now()
return
}
func (n *Normas) BeforeUpdate(tx *gorm.DB) (err error) {
n.UpdatedAt = time.Now()
return
}

38
internal/types/paquete.go Normal file
View File

@ -0,0 +1,38 @@
package types
import (
"time"
"gorm.io/gorm"
)
type Paquete struct {
NroPaquete string `gorm:"primarykey"`
OrdenProduccion int `gorm:"index"`
OrdenCliente int `gorm:"index"`
Producto string `gorm:"index"`
Colada string
Calidad string
Matnr string
Operador string
Turno string `gorm:"index"`
Longitud float64
Barras uint8
Peso float64
PesoTeorico float64
Normed string
Norpro string
Nortol string
DesvioPeso float64
Confirmado bool
Procesado bool
Observaciones string
Reclasificado bool
CreatedAt time.Time `gorm:"index"`
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (Paquete) TableName() string {
return "paquetes"
}

85
internal/types/po.go Normal file
View File

@ -0,0 +1,85 @@
package types
import (
"time"
"gorm.io/gorm"
)
type ProductionOrder struct {
Inst string `json:"INST"`
DateTime string `json:"DATE_TIME"`
POrderNo int `json:"P_ORDER_NO" gorm:"primarykey"`
SchedulNo int `json:"SCHEDUL_NO"`
SeqNumber int `json:"SEQ_NUMBER"`
PptimeWfc string `json:"PPTIME_WFC"`
PptimeMsc string `json:"PPTIME_MSC"`
SteelGrad string `json:"STEEL_GRAD"`
ITemp string `json:"I_TEMP"`
IHeight string `json:"I_HEIGHT"`
IWidth string `json:"I_WIDTH"`
ISection string `json:"I_SECTION"`
HeatingSt int `json:"HEATING_ST"`
FTarTemp string `json:"F_TAR_TEMP"`
FSection string `json:"F_SECTION"`
FSectType string `json:"F_SECT_TYPE"`
TotWeight string `json:"TOT_WEIGHT"`
TBeamBla int `json:"T_BEAM_BLA"`
TCustOrd int `json:"T_CUST_ORD"`
TestLen int `json:"TEST_LEN"`
PostFlag string `json:"POST_FLAG"`
ModuloX string `json:"MODULO_X"`
OvWTolU string `json:"OV_W_TOL_U"`
OvWTolL string `json:"OV_W_TOL_L"`
OvHTolU string `json:"OV_H_TOL_U"`
OvHTolL string `json:"OV_H_TOL_L"`
WeTTolU string `json:"WE_T_TOL_U"`
WeTTolL string `json:"WE_T_TOL_L"`
WeHTolU string `json:"WE_H_TOL_U"`
WeHTolL string `json:"WE_H_TOL_L"`
FlWDsU string `json:"FL_W_DS_U"`
FlWDsL string `json:"FL_W_DS_L"`
FlWOsU string `json:"FL_W_OS_U"`
FlWOsL string `json:"FL_W_OS_L"`
WeMetTU string `json:"WE_MET_T_U"`
WeMetTL string `json:"WE_MET_T_L"`
WeCenTol string `json:"WE_CEN_TOL"`
WeSquTol string `json:"WE_SQU_TOL"`
FlParTol string `json:"FL_PAR_TOL"`
BdRollID string `json:"BD_ROLL_ID"`
UrRollID string `json:"UR_ROLL_ID"`
EdRollID string `json:"ED_ROLL_ID"`
UfRollID string `json:"UF_ROLL_ID"`
SmRollID string `json:"SM_ROLL_ID"`
Grupo6 string `json:"GRUPO6"`
StName string `json:"ST_NAME"`
StWeighM string `json:"ST_WEIGH_M"`
StLen1 string `json:"ST_LEN_1"`
StLen2 string `json:"ST_LEN_2"`
StLen3 string `json:"ST_LEN_3"`
StLen4 string `json:"ST_LEN_4"`
StLen5 string `json:"ST_LEN_5"`
StLen6 string `json:"ST_LEN_6"`
StLen7 string `json:"ST_LEN_7"`
StLen8 string `json:"ST_LEN_8"`
StLen9 string `json:"ST_LEN_9"`
StLen10 string `json:"ST_LEN_10"`
StLen11 string `json:"ST_LEN_11"`
StLen12 string `json:"ST_LEN_12"`
Marfab int `json:"MARFAB"`
Sortb string `json:"SORTB"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (p *ProductionOrder) BeforeCreate(tx *gorm.DB) (err error) {
p.CreatedAt = time.Now()
p.UpdatedAt = time.Now()
return
}
func (p *ProductionOrder) BeforeUpdate(tx *gorm.DB) (err error) {
p.UpdatedAt = time.Now()
return
}

54
internal/types/ppack.go Normal file
View File

@ -0,0 +1,54 @@
package types
type Ppack struct {
Grupo6 string `json:"grupo6"`
Po int `json:"po"`
Co int `json:"co"`
Colada string `json:"colada"`
Calidad string `json:"calidad"`
Matnr string `json:"matnr"`
Dibujo int `json:"dibujo"`
Operador string `json:"operador"`
Serie int `json:"serie"`
Nromatricula string `json:"nromatricula"`
NroBulto string `json:"nro_bulto"`
EtiquetaDoble string `json:"etiqueta_doble"`
Fecha int `json:"fecha"`
Turno string `json:"turno"`
Observacion1 string `json:"observacion1"`
Observacion2 string `json:"observacion2"`
Observacion3 string `json:"observacion3"`
PaqueteLongitud float64 `json:"paquete_longitud"`
PaqueteAncho int `json:"paquete_ancho"`
PaqueteAlto float64 `json:"paquete_alto"`
PaquetePeso int `json:"paquete_peso"`
PaqueteNroSecciones int `json:"paquete_nro_secciones"`
PaqueteNroMantos int `json:"paquete_nro_mantos"`
PaqueteNroSeccManto int `json:"paquete_nro_secc_manto"`
SeccionTipo string `json:"seccion_tipo"`
SeccionLongitud int `json:"seccion_longitud"`
SeccionAncho int `json:"seccion_ancho"`
SeccionAlto int `json:"seccion_alto"`
Idioma string `json:"idioma"`
Destino int `json:"destino"`
Hora int `json:"hora"`
Horario int `json:"horario"`
Inst string `json:"inst"`
Tren int `json:"tren"`
Normed string `json:"normed"`
Norpro string `json:"norpro"`
Nortol string `json:"nortol"`
Spras string `json:"spras"`
Statu int `json:"statu"`
Crlf string `json:"crlf"`
Maquina int `json:"maquina"`
Padre string `json:"padre"`
Paqpadre string `json:"paqpadre"`
RelevantTime string `json:"relevant_time"`
Desvio int `json:"desvio"`
Pesoteorico int `json:"pesoteorico"`
PesoteoricoReal int `json:"pesoteorico_real"`
DesvioTeoricoReal int `json:"desvio_teorico_real"`
FechaImpresion string `json:"fecha_impresion"`
PesoNivel1 int `json:"peso_nivel1"`
}

28
internal/types/zebra.go Normal file
View File

@ -0,0 +1,28 @@
package types
import (
"time"
"gorm.io/gorm"
)
type Zebra struct {
ID string `gorm:"primarykey"`
Address string
Port int
Enabled bool
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
func (z *Zebra) BeforeCreate(tx *gorm.DB) (err error) {
z.CreatedAt = time.Now()
z.UpdatedAt = time.Now()
return
}
func (z *Zebra) BeforeUpdate(tx *gorm.DB) (err error) {
z.UpdatedAt = time.Now()
return
}