spf_tracking 0.0.20 → 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YmIxY2UwYmQ1MzJlYjg5NDEzZTMxNTQwNDk0NDQxZDk4MDBhOGJhMQ==
4
+ OWE5YTllMjBhMDhhMGY5MTA2NDYwYmIwY2U1ODBhZDkyOGQxNjZhNg==
5
5
  data.tar.gz: !binary |-
6
- YjU5YWNiMjlhZTg5YjhlYmJiZmE0Mjk1NzcxNDg1YzlkMDAxOWZlZA==
6
+ YmQ5NDI1NTVkNzIzMjlhNDM5NWZiOWJiNGU5NjZlZWUxNTJlYmFjOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MmZiZTkzMDI5YzlhMzcxZTQwNWYwMTE3MGMwNTJhY2QwMGEwYzU0ZmZmZmQ3
10
- YjE3Zjc4YzYzYzVmOWY5ZDRkNDA2ZjA3Y2U5MGVmMWQ5MTY5YjZkOGUwMmVi
11
- MzU2MDM0ZjcyZDM0YjAxMTlhZGU4ZTZhYjY4NGU2YzVmZjVmYjU=
9
+ YjY4NWVmNDljYTdmNzA5MDI4NGM1ZDNmY2MwYWJiOTEzZjE1OTg4MGQzYjE4
10
+ NWQ5NGFkN2M0ZGVmZTA2MTQ2NDA0NDZiZjRjODRhYTgxN2Y5NTI5N2U0N2Q0
11
+ NDI1MzI3OTNlN2M2MzI5ZjNkMmIwNjg5ODI0ZDVmZjhjOGJmZDM=
12
12
  data.tar.gz: !binary |-
13
- MzBiMzFkMzhiM2I5ZGE3ODZmZGEyZmE1MzA1NTM2ODI3ODYyYjI4ZmMxZmY5
14
- YTNjMzU3MGM2MGNjNjU0YmI5YzM3YTM5MmZjYjIwOTczZmNlNzcxNDA1ZGNh
15
- MDFiNzhkNjgxMjNmMDA0Y2JmYTUzZTBlMDg5ZmI5MzM4MzNmMTQ=
13
+ Yjg0ZTY5Yjk2Njc5NTFlNWE0ODM0Y2ZmMzdiZDdiNTQxYjU5OWJmNWE2YTlm
14
+ N2Q4ZjhmOGQzOTgwNGFlZTFmOGNhNjk5YTkwNGUwOWQ1Mzc1NWQ5MDIyMDMz
15
+ NWVjMzAyNTg0NmQ2ZDUzY2EzM2ZhMDgxYWE2NTg5NGFlNmI5OWY=
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = SpfTracking
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SpfTracking'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ module Descriptivo
3
+
4
+ module DescriptivoItem
5
+ def descripcion_primer_vidrio
6
+ composicion.nil? ? "El item no tiene una compisición asignada" : composicion.primer_vidrio.elementos.map(&:descripcion).join(" ")
7
+ end
8
+ end
9
+
10
+ module DescriptivoItemMedida
11
+ def etiqueta_excel
12
+ pedido = item.pedido
13
+
14
+ e_im = self.cardinalidad.to_s.rjust(3, '0')
15
+ e_i = item.cardinalidad.to_s.rjust(3, '0')
16
+ e_p = pedido.id.to_s.rjust(6, '0')
17
+
18
+ "#{e_p}-#{e_i}-#{e_im}"
19
+ end
20
+ end
21
+
22
+ module DescriptivoTrazabilidad
23
+ def etiqueta_string
24
+ item = composicion.item
25
+ pedido = item.pedido
26
+ componente = self.componente || self.elemento.try(:componente)
27
+
28
+ pedido_string = pedido.id.to_s.rjust(7, '0')
29
+ item_string = item.cardinalidad.to_s.rjust(3, '0')
30
+ item_medida_string = self.item_medida.cardinalidad.to_s.rjust(3, '0')
31
+
32
+ if self.elemento
33
+ componente_string = componente.orden.to_s
34
+ elemento_string = self.elemento.orden.to_s.rjust(2, '0')
35
+ else
36
+ if self.componente
37
+ componente_string = self.componente.orden.to_s
38
+ elemento_string = "00"
39
+ else
40
+ componente_string = "0"
41
+ elemento_string = "00"
42
+ end
43
+ end
44
+
45
+ "#{pedido_string}-#{item_string}-#{item_medida_string}-#{componente_string}-#{elemento_string}"
46
+
47
+ end
48
+
49
+ end
50
+
51
+ module DescriptivoElemento
52
+ def descripcion
53
+ # (["Float 4"] + ["Pulido", "Termoendurecido"]).join(" ")
54
+ ([self.elemento_de_componente.descripcion] + self.procesos_de_procesos.map(&:nombre)).join(" ")
55
+ end
56
+
57
+ def descripcion_corta_tango
58
+ # (["Float 4"] + ["Pulido", "Termoendurecido"]).join(" ")
59
+ ([self.elemento_de_componente.descripcion_corta_tango] + self.procesos_de_procesos.map(&:descripcion_corta_tango)).join(" ")
60
+ end
61
+
62
+ def descripcion_tango
63
+ # (["Float 4"] + ["Pulido", "Termoendurecido"]).join(" ")
64
+ ([self.elemento_de_componente.descripcion_tango] + self.procesos_de_procesos.map(&:descripcion_corta_tango)).join(" ")
65
+ end
66
+
67
+ def descripcion_elemento
68
+ self.elemento_de_componente.descripcion
69
+ end
70
+
71
+ def descripcion_sin_procesos
72
+ self.descripcion_elemento
73
+ end
74
+ end
75
+
76
+
77
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+
3
+ # A ESTA CLASE LE LLEGAN OBJETOS Y DEVUELVE EL PRD_TRACK EN EL CUAL
4
+ # TRAZABILIDAD TIENE QUE EJECUTAR EL METODO CARGAR_ROTURA
5
+
6
+ # RECORDAR QUE ESTO ES POR EL PROBLEMA DE "LAS DOS ROTURAS, UNA REAL, OTRA
7
+ # DEL SISTEMA DE TRAZABILIDAD"
8
+
9
+ class ExpertoRoturaTrazabilidad
10
+
11
+ def initialize(item_medida, elemento, puesto_control)
12
+ @item_medida, @elemento, @puesto_control = item_medida, elemento, puesto_control
13
+ end
14
+
15
+ def get_prd_track_donde_se_rompe
16
+
17
+ prd_track_actual = RoturaAnterior.new(@item_medida, @elemento, @puesto_control).get_prd_track_actual
18
+
19
+
20
+ if prd_track_actual.trabajos_disponibles == 0
21
+ return ProximaTrazabilidadRotura.new(@item_medida, @elemento, @puesto_control).get_prd_track
22
+ else
23
+ return prd_track_actual
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,104 @@
1
+ class ExpertoTrazabilidad
2
+
3
+
4
+
5
+ def finalizar_y_pasar_a_historico(pedido)
6
+ composicions_ids = pedido.composicions_ids
7
+ # busco todas las filas en trazabilidads que tengan composicion perteneciente al pedido
8
+ trazabilidads_ids = Trazabilidad.where(composicion_id: composicions_ids).ids
9
+ ActiveRecord::Base.transaction do
10
+ # si finaliza entonces sí hago el pasaje a historico
11
+ if pedido.finalizar
12
+ # pasaje de trabajos
13
+ Trabajo.pasar_trabajos_a_historico(trazabilidads_ids)
14
+ Trabajo.borrar_trabajo(trazabilidads_ids)
15
+ # pasaje de trazabilidad
16
+ Trazabilidad.pasar_trazabilidad_a_historico(composicions_ids)
17
+ Trazabilidad.borrar_trazabilidad(composicions_ids)
18
+ # pasaje de tango a tango_historico
19
+ TangoHeader.pasar_a_historico(pedido.id)
20
+ TangoBody.pasar_a_historico(pedido.id)
21
+ TangoActivo.pasar_a_historico(pedido.id)
22
+ # borro de las tablas de tango_ los registros
23
+ TangoHeader.where(pedido_id: pedido.id).delete_all
24
+ TangoBody.where(pedido_id: pedido.id).delete_all
25
+ TangoActivo.where(pedido_id: pedido.id).delete_all
26
+ return true
27
+ end
28
+ end
29
+ end
30
+
31
+ def pasar_a_historico(pedido)
32
+ composicions_ids = pedido.composicions_ids
33
+ # busco todas las filas en trazabilidads que tengan composicion perteneciente al pedido
34
+ trazabilidads_ids = Trazabilidad.where(composicion_id: composicions_ids).ids
35
+ ActiveRecord::Base.transaction do
36
+ # si finaliza entonces sí hago el pasaje a historico
37
+ # pasaje de trabajos
38
+ Trabajo.pasar_trabajos_a_historico(trazabilidads_ids)
39
+ Trabajo.borrar_trabajo(trazabilidads_ids)
40
+ # pasaje de trazabilidad
41
+ Trazabilidad.pasar_trazabilidad_a_historico(composicions_ids)
42
+ Trazabilidad.borrar_trazabilidad(composicions_ids)
43
+ # pasaje de tango a tango_historico
44
+ TangoHeader.pasar_a_historico(pedido.id)
45
+ TangoBody.pasar_a_historico(pedido.id)
46
+ TangoActivo.pasar_a_historico(pedido.id)
47
+ # borro de las tablas de tango_ los registros
48
+ TangoHeader.where(pedido_id: pedido.id).delete_all
49
+ TangoBody.where(pedido_id: pedido.id).delete_all
50
+ TangoActivo.where(pedido_id: pedido.id).delete_all
51
+ return true
52
+ end
53
+ end
54
+
55
+
56
+ # devuelve falso solo si hay productos disponibles para terminar y estos estan en dvh, preparacion o facturacion
57
+
58
+
59
+
60
+ def descontar_remito(puesto_control, item_medida, cantidad)
61
+ if %w"Facturacion Expedicion Entregado".include?(puesto_control.nombre)
62
+ facturacion = Facturacion.where(linea_item: item_medida).max_by{|x| x.created_at}
63
+ new_cantidad = facturacion.cantidad == 0 ? 0 : facturacion.cantidad - cantidad
64
+ Rails.logger.info "Del comprobante_medida_id #{facturacion.id} se le descuenta 1 a #{facturacion.cantidad} y queda #{new_cantidad}"
65
+ facturacion.update_attribute :cantidad, new_cantidad
66
+ end
67
+ end
68
+
69
+ def terminados_de_medidas_en_puesto(item_medidas, puesto)
70
+ prd_tracks = puesto.get_prd_track.where(linea_item_type: "ItemMedida", linea_item_id: item_medidas.map(&:id))
71
+ prd_tracks.to_a.sum(&:terminado_listo)
72
+ end
73
+
74
+ def items_que_pasan_por(pedido, puesto)
75
+ pedido.items.map{|i| i if i.composicion.composicion_pasa_por?(puesto)}.compact
76
+ end
77
+
78
+ def medidas_que_pasan_por(pedido, puesto)
79
+ items_que_pasan_por(pedido, puesto).map(&:item_medidas).flatten
80
+ end
81
+
82
+
83
+
84
+ # si los terminados en dvh son mayor que los terminados en preparacion, entonces el pedido entra en el array de pedidos con dvh listos para preparar
85
+ def pedidos_con_dvh_para_preparar_old(pedidos)
86
+ pedidos.map{|p| p if (p.pedido_pasa_por_dvh? && self.terminados_de_medidas_en_puesto(self.medidas_que_pasan_por(p, PuestoControl.dvh), PuestoControl.dvh) > self.terminados_de_medidas_en_puesto(self.medidas_que_pasan_por(p, PuestoControl.dvh), PuestoControl.preparacion)) }.compact
87
+ end
88
+
89
+ def pedidos_con_dvh_para_preparar(array_pedidos_puestos)
90
+ # me quedo solamente con pedidos que tengan activo Preparacion
91
+ # para aplicarles el filtro siguiente
92
+
93
+ pedidos_prepa = []
94
+
95
+ array_pedidos_puestos.each do |pedido|
96
+ pedidos_prepa << pedido[0] if pedido[1].include?(PuestoControl.preparacion)
97
+ end
98
+
99
+ pedidos_prepa.map{|p| p if (self.terminados_de_medidas_en_puesto(self.medidas_que_pasan_por(p, PuestoControl.dvh), PuestoControl.dvh) > self.terminados_de_medidas_en_puesto(self.medidas_que_pasan_por(p, PuestoControl.dvh), PuestoControl.preparacion)) }.compact
100
+
101
+ end
102
+
103
+
104
+ end
@@ -0,0 +1,31 @@
1
+ module ProcesoDeProducto
2
+ module ProcesoDeProductoElemento
3
+ def procesos
4
+ proceso_de_elementos
5
+ end
6
+
7
+ def procesos_de_procesos
8
+ proceso_de_elementos.sort{|a,b| a.orden <=> b.orden}.map(&:proceso)
9
+ end
10
+ end
11
+
12
+ module ProcesoDeProductoComponente
13
+ def procesos
14
+ proceso_de_componentes
15
+ end
16
+
17
+ def procesos_de_procesos
18
+ proceso_de_componentes.sort{|a,b| a.orden <=> b.orden}.map(&:proceso)
19
+ end
20
+ end
21
+
22
+ module ProcesoDeProductoComposicion
23
+ def procesos
24
+ proceso_de_composicions
25
+ end
26
+
27
+ def procesos_de_procesos
28
+ proceso_de_composicions.sort{|a,b| a.orden <=> b.orden}.map(&:proceso)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ # ESTE OBJETO SIRVE PARA IMPLEMENTAR MOMENTANEAMENTE LA ROTURA POR ETIQUETA
4
+ # ACTUALMENTE ESTA EL PROBLEMA DE QUE POR LOS PUESTOS QUE PASAN A TERMINADO
5
+ # EN FORMA AUTOMATICA, POR EJEMPLO UN VIDRIO TEMPLADO DE UN PEDIDO QUE SE
6
+ # ACTIVA, YA PASA A ESTADO TEMPLADO TERMINADO Y A LA ESPERA DE PREPARACION
7
+ # AUNQUE EN FABRICA, EN LA REALIDAD, TODAVIA NI SIQUIERA FUE CORTADO
8
+
9
+ # ENTONCES SURGE LA CUESTIÓN DE QUE UN VIDRIO "SE ROMPE EN DOS PUESTOS"
10
+
11
+ # SI EL VIDRIO SE ROMPE EN LA REALIDAD EN TALLER AL MOMENTO DE SER PULIDO
12
+ # ENTONCES VOY A GUARDAR EN LA TABLA ROTURAVIDRIOS ESE DATO
13
+ # PERO... PERO
14
+ # EN EL SISTEMA DE TRAZABILIDAD NO PUEDO HACER QUE EL VIDRIO SE ROMPA AHÍ
15
+ # PORQUE NO ES CONSISTENTE, YA QUE SUPUESTAMENTE EL VIDRIO YA ESTÁ TALLER
16
+ # TERMINADO Y TEMPLADO TAMBIÉN TERMINADO -POR LA NATURALEZA DE TERMINARSE
17
+ # AUTOMÁTICAMENTE LOS PUESTOS QUE NO TIENEN AUN UNA PC EN PLANTA
18
+
19
+ # RESUMIENDO
20
+ # SI SE ROMPE ALGO EN TALLER, COMO TALLER NO ESTÁ IMPLEMENTADO EN PLANTA,
21
+ # EL VIDRIO EN LA TEORIA SE HACE ROMPER LUEGO DEL ULTIMO PUESTO COMPLETO
22
+
23
+
24
+ class ProximaTrazabilidadRotura
25
+
26
+ def initialize(item_medida, elemento, puesto_control)
27
+ @item_medida = item_medida
28
+ @elemento = elemento
29
+ @puesto_control = puesto_control
30
+ end
31
+
32
+ # REFACTORIZAR Y AGREGAR QUE TAMBIEN DEVUELVA POR COMPONENTE Y ELEMENTO
33
+ def get_prd_track
34
+ prd_track = @puesto_control.get_prd_track.find_by(linea_item: @item_medida, elemento_id: @elemento.id) || @puesto_control.get_prd_track.find_by(linea_item: @item_medida, componente_id: @elemento.componente_id) || @puesto_control.get_prd_track.find_by(linea_item: @item_medida, composicion_id: @elemento.componente.composicion.id)
35
+
36
+
37
+
38
+ while prd_track.next.trabajos_disponibles == 0 do
39
+ prd_track = prd_track.next
40
+ end
41
+
42
+ prd_track
43
+ end
44
+
45
+
46
+
47
+ end
@@ -0,0 +1,18 @@
1
+ class RoturaAnterior
2
+
3
+ def initialize(item_medida, elemento, puesto_control_actual)
4
+ @item_medida = item_medida
5
+ @elemento = elemento
6
+ @puesto_control_actual = puesto_control_actual
7
+ end
8
+
9
+ # REFACTORIZAR Y AGREGAR QUE TAMBIEN DEVUELVA POR COMPONENTE Y ELEMENTO
10
+ def get_prd_track_actual
11
+ @puesto_control_actual.get_prd_track.find_by(linea_item: @item_medida, elemento_id: @elemento.id) || @puesto_control_actual.get_prd_track.find_by(linea_item: @item_medida, componente_id: @elemento.componente_id) || @puesto_control_actual.get_prd_track.find_by(linea_item: @item_medida, composicion_id: @elemento.componente.composicion.id)
12
+ end
13
+
14
+ def get_prd_track_anterior
15
+ Trazabilidad.find_by(linea_item: @item_medida, elemento_id: @elemento.id, proximo_prd_track_id: get_prd_track_actual.try(:id)) || Trazabilidad.find_by(linea_item: @item_medida, componente_id: @elemento.componente_id, proximo_prd_track_id: get_prd_track_actual.try(:id))
16
+ end
17
+
18
+ end
@@ -0,0 +1,233 @@
1
+ module RutaSeguimiento
2
+ module RutaSeguimientoPedido
3
+ def lista_de_puestos_de_pedido
4
+ self.items.map(&:composicion).map(&:get_elementos_trackeables).flatten.map(&:lista_de_puestos_del_elemento).flatten.uniq
5
+ end
6
+
7
+ # mas general incluye adjuntos y taller(agujeros), administracion, etc
8
+ def lista_de_puestos_de_pedido_mas_general
9
+ lista = lista_de_puestos_de_pedido
10
+ lista << PuestoControl.adjunto if self.tiene_adjuntos?
11
+ lista << PuestoControl.expedicion
12
+ lista << PuestoControl.corte
13
+ lista << PuestoControl.glassware_produccion
14
+ lista << PuestoControl.glassware_administracion
15
+
16
+ lista << PuestoControl.taller if (!lista.include?(PuestoControl.taller) && self.tiene_agujeros_o_entrantes?)
17
+
18
+ lista.flatten
19
+ end
20
+
21
+ # completa desde inicio hasta entrega, sin adjunto, glassware admin, etc
22
+ def lista_de_puestos_de_pedido_completa
23
+ (self.items.map(&:composicion).map(&:get_elementos_trackeables).flatten.map(&:lista_de_puestos_del_elemento_completa) + self.items.map(&:item_complementos).flatten.map(&:lista_de_puestos_del_complemento_completa)).flatten.uniq
24
+ end
25
+ end
26
+
27
+ module RutaSeguimientoComposicion
28
+
29
+ # DVH EXP
30
+ def lista_de_racks
31
+ lista = []
32
+ lista << PuestoControl.dvh if multicomponente?
33
+ lista << procesos_de_procesos.map(&:puesto_control)
34
+ lista.flatten.uniq
35
+ end
36
+
37
+ def lista_de_puestos_de_composicion
38
+ get_elementos_trackeables.map(&:lista_de_puestos_del_elemento).flatten.uniq
39
+ end
40
+
41
+ def lista_de_puestos_de_composicion_completa
42
+ lista = []
43
+ lista = agregar_puestos_pre_composicion(lista)
44
+ lista << lista_de_puestos_de_composicion
45
+ lista = agregar_puestos_post_composicion(lista)
46
+ lista.flatten.uniq
47
+ end
48
+
49
+ def lista_de_puestos_de_composicion_track_tercer_nivel
50
+ lista = []
51
+ lista << PuestoControl.dvh if self.multicomponente?
52
+ lista << procesos_de_procesos.map(&:puesto_control)
53
+ lista = self.agregar_puestos_post_composicion(lista)
54
+ lista.flatten.uniq
55
+ end
56
+
57
+ # ver de refactorizar, este metodo se usa en un showlogic
58
+ def composicion_pasa_por?(puesto_control)
59
+ lista_de_puestos_de_composicion_track_tercer_nivel.include?(puesto_control)
60
+ end
61
+ end
62
+
63
+ module RutaSeguimientoComponente
64
+ # LAM TLL DVH
65
+ def lista_de_racks
66
+ lista = []
67
+ if !cantidad_de_pvb.zero?
68
+ lista << PuestoControl.prelaminado
69
+ lista << PuestoControl.laminado
70
+ end
71
+ lista << procesos_de_procesos.map(&:puesto_control)
72
+ lista << PuestoControl.dvh if composicion.multicomponente?
73
+ lista << composicion.procesos_de_procesos.map(&:puesto_control)
74
+ lista.flatten.uniq
75
+ end
76
+
77
+ def lista_de_puestos_del_componente_track_segundo_nivel
78
+ # devuelve como mucho [LAM, TLL]
79
+ lista = []
80
+ if !cantidad_de_pvb.zero?
81
+ lista << PuestoControl.prelaminado
82
+ lista << PuestoControl.laminado
83
+ end
84
+ lista << procesos_de_procesos.map(&:puesto_control)
85
+ return lista.flatten.uniq
86
+ end
87
+ end
88
+
89
+ module RutaSeguimientoElemento
90
+ # TLL TMP CUR LAM DVH
91
+ def lista_de_racks
92
+ lista = []
93
+ lista << procesos_de_procesos.map(&:puesto_control)
94
+ if !componente.cantidad_de_pvb.zero?
95
+ lista << PuestoControl.prelaminado
96
+ lista << PuestoControl.laminado
97
+ end
98
+ lista << componente.procesos_de_procesos.map(&:puesto_control)
99
+ lista << PuestoControl.dvh if componente.composicion.multicomponente?
100
+ lista << componente.composicion.procesos_de_procesos.map(&:puesto_control)
101
+ lista.flatten.uniq
102
+ end
103
+
104
+ def lista_de_puestos_del_elemento # excel ????????
105
+
106
+ composicion = componente.composicion
107
+
108
+ lista = []
109
+ # procesos de elementos
110
+ lista << procesos_de_procesos.map(&:puesto_control)
111
+ # pvb; laminados
112
+ if !componente.cantidad_de_pvb.zero?
113
+ lista << PuestoControl.prelaminado
114
+ lista << PuestoControl.laminado
115
+ end
116
+ # procesos de componentes
117
+ lista << componente.procesos_de_procesos.map(&:puesto_control)
118
+ # dvh
119
+ lista << PuestoControl.dvh if composicion.multicomponente?
120
+ # procesos de composicion
121
+ lista << composicion.procesos_de_procesos.map(&:puesto_control)
122
+ lista.flatten
123
+ end
124
+
125
+ def lista_de_puestos_del_elemento_completa
126
+ lista = []
127
+ agregar_puestos_pre_composicion(lista)
128
+ lista << lista_de_puestos_del_elemento
129
+ agregar_puestos_post_composicion(lista)
130
+ end
131
+
132
+ # este incluye LAMINADO (a diferencia de primer nivel)
133
+ def lista_de_puestos_del_elemento_track
134
+ composicion = componente.composicion
135
+
136
+ lista = []
137
+ agregar_puestos_pre_composicion(lista)
138
+ # procesos de elementos
139
+ lista << procesos_de_procesos.map(&:puesto_control)
140
+ # pvb; laminados
141
+ if !componente.cantidad_de_pvb.zero?
142
+ lista << PuestoControl.prelaminado
143
+ lista << PuestoControl.laminado
144
+ end
145
+ lista.flatten
146
+ end
147
+
148
+ # todos los que tienen elemento_id en tabla trazabilidad [ini... corte, templado] (LAMINADO NO)
149
+ def lista_de_puestos_del_elemento_track_primer_nivel
150
+ composicion = componente.composicion
151
+
152
+ lista = []
153
+ agregar_puestos_pre_composicion(lista)
154
+ # procesos de elementos
155
+ lista << procesos_de_procesos.map(&:puesto_control)
156
+ lista.flatten
157
+ end
158
+
159
+ end
160
+
161
+ module RutaSeguimientoItemComplemento
162
+
163
+ def lista_de_puestos_del_complemento_completa
164
+ lista = []
165
+ agregar_puestos_comunes_complemento(lista)
166
+ lista.flatten
167
+ end
168
+
169
+ end
170
+
171
+ module RutaSeguimientoGeneral
172
+
173
+ # si puesto_control_actual es corte => devuelve el primer rack
174
+ # caso contrario devuelve el proximo rack respecto al actual
175
+ def proximo_rack(puesto_control_actual)
176
+
177
+ if puesto_control_actual == PuestoControl.corte
178
+ if lista_de_racks.empty?
179
+ return PuestoControl.expedicion
180
+ else
181
+ return lista_de_racks[0]
182
+ end
183
+ end
184
+
185
+
186
+ index_puesto_actual = lista_de_racks.index(puesto_control_actual) || 0
187
+
188
+ # si lista[index_puesto_actual + 1] no existe entonces devuelve EXPEDICION
189
+
190
+ return PuestoControl.expedicion if lista_de_racks[index_puesto_actual + 1].nil?
191
+
192
+ # devuelve el proximo
193
+ lista_de_racks[index_puesto_actual + 1]
194
+ end
195
+
196
+ def agregar_puestos_post_composicion(lista)
197
+ # lista << PuestoControl.find_by_nombre("Embalaje")
198
+ lista << PuestoControl.preparacion
199
+ lista << PuestoControl.facturacion
200
+ lista << PuestoControl.expedicion
201
+ # lista << PuestoControl.find_by_nombre("Salida de camiones")
202
+ lista << PuestoControl.entregado
203
+ # lista << PuestoControl.find_by_nombre("Devolucion")
204
+ lista.flatten
205
+ end
206
+
207
+ def agregar_puestos_pre_composicion(lista)
208
+ lista << PuestoControl.inicial
209
+ lista << PuestoControl.compra
210
+ lista << PuestoControl.stock
211
+ lista << PuestoControl.sin_programar
212
+ lista << PuestoControl.borrador
213
+ lista << PuestoControl.planificado
214
+ lista << PuestoControl.corte
215
+ lista.flatten
216
+ end
217
+
218
+ def agregar_puestos_comunes_complemento(lista)
219
+ lista << PuestoControl.inicial
220
+ lista << PuestoControl.compra
221
+ lista << PuestoControl.stock
222
+ # lista << PuestoControl.find_by_nombre("Embalaje")
223
+ lista << PuestoControl.preparacion
224
+ lista << PuestoControl.facturacion
225
+ lista << PuestoControl.expedicion
226
+ # lista << PuestoControl.find_by_nombre("Salida de camiones")
227
+ lista << PuestoControl.entregado
228
+ # lista << PuestoControl.find_by_nombre("Devolucion")
229
+ lista.flatten
230
+ end
231
+ end
232
+
233
+ end
@@ -0,0 +1,54 @@
1
+ class ServiceTrack::BuscaUltimoPuestoCompleto
2
+
3
+ def initialize(opts = {})
4
+ @puesto = opts.has_key?(:item) ? ultimo_puesto_completo_item(opts[:item]) : ultimo_puesto_completo_item_medida(opts[:item_medida])
5
+ end
6
+
7
+ def verbo_terminado
8
+ @puesto ? @puesto.verbo_terminado : "Mixto"
9
+ end
10
+
11
+ private
12
+
13
+ def ultimo_puesto_completo_item_medida(item_medida)
14
+
15
+ ultimo_puesto_completo = nil
16
+ PuestoControl.trazables.order(:orden).each do |puesto|
17
+
18
+ if !%w("Inicial Compra Stock Sin\ programar Planificado Borrador Taller Templado Serigrafiado").include?(puesto.nombre)
19
+
20
+ klass_prd_track = puesto.get_prd_track
21
+ prd_tracks = klass_prd_track.where(item_medida_id: item_medida.id)
22
+
23
+ if prd_tracks.any?
24
+ puesto_todo_terminado = true
25
+ prd_tracks.each do |prd_track|
26
+ if !prd_track.esta_terminado?
27
+ puesto_todo_terminado = false
28
+ break
29
+ end
30
+ end
31
+
32
+ ultimo_puesto_completo = puesto if puesto_todo_terminado
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
39
+ ultimo_puesto_completo
40
+ end
41
+
42
+ def ultimo_puesto_completo_item(item)
43
+ puestos = []
44
+ item.item_medidas.each do |item_medida|
45
+ puestos << ultimo_puesto_completo_item_medida(item_medida)
46
+ end
47
+
48
+ puestos = puestos.uniq.compact
49
+
50
+ puestos.count == 1 ? puestos[0] : nil
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,26 @@
1
+ class ServiceTrack::CreateEntregaRapida
2
+
3
+ def initialize(opts = {})
4
+ @opts = opts
5
+ end
6
+
7
+ def save
8
+ ActiveRecord::Base.transaction do
9
+ terminar_facturacion
10
+ nuevas_expediciones # con los comprobantes generados en el paso anterior
11
+ # comprobar coherencia?
12
+ end
13
+ end
14
+
15
+ def terminar_facturacion
16
+ @comprobante_temps_generados = TerminarFacturacion.new(@opts).save
17
+ end
18
+
19
+ def nuevas_expediciones
20
+ @comprobante_temps_generados.each do |comprobante|
21
+ @opts[:comprobante_temp_id] = comprobante.id
22
+ NuevaExpedicion.new(@opts).save
23
+ end
24
+ end
25
+
26
+ end
@@ -0,0 +1,42 @@
1
+ class ServiceTrack::CreateRotura
2
+
3
+ def initialize(opts)
4
+ opts.each_pair { |k, v| instance_variable_set("@#{k}", v) }
5
+ @opts = opts
6
+
7
+ @cantidad = 1 # de momento ?
8
+ end
9
+
10
+
11
+
12
+ def save
13
+ ActiveRecord::Base.transaction do
14
+ update_roturas
15
+ update_retrabajos
16
+ domino
17
+ create_rotura_vidrios
18
+ # comprobar coherencia?
19
+ end
20
+ end
21
+
22
+ def update_roturas
23
+ @elementos_y_prd_tracks.each do |eypt|
24
+ eypt[:prd_track].cargar_rotura(@cantidad, @current_user)
25
+ end
26
+ end
27
+
28
+ def update_retrabajos
29
+ ServiceTrack::UpdateRetrabajos.new(@elementos_y_prd_tracks, @item_medida, @cantidad).start()
30
+ end
31
+
32
+ def domino
33
+ @elementos_y_prd_tracks.each do |eypt|
34
+ Tracking::PrdIniTrack.find_by(linea_item: @item_medida, elemento_id: eypt[:elemento].id).domino
35
+ end
36
+ end
37
+
38
+ def create_rotura_vidrios
39
+ ServiceTrack::NuevaRotura.new(@opts).save
40
+ end
41
+
42
+ end
@@ -0,0 +1,21 @@
1
+ class ServiceTrack::NuevaRotura
2
+
3
+ def initialize(opts)
4
+ opts.each_pair { |k, v| instance_variable_set("@#{k}", v) }
5
+
6
+ @cantidad = 1 # de momento ?
7
+ end
8
+
9
+ def save
10
+ ActiveRecord::Base.transaction do
11
+ create_roturas
12
+ end
13
+ end
14
+
15
+ def create_roturas
16
+ @elementos_y_prd_tracks.each do |eypt|
17
+ RoturaVidrio.create(item_medida_id: @item_medida.id, elemento_id: eypt[:elemento].id, observacion: @motivo_rotura, motivo_id: @motivo_id, momento_id: @momento_id, puesto_control_id: @puesto_rotura_vidrio.id, user_id: @current_user.try(:id))
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,87 @@
1
+ class ServiceTrack::UpdateRetrabajos
2
+
3
+ # cuando hay una rotura, actualiza los prd_track de los puestos anteriores hasta "puesto_control" en el parámetro
4
+ def initialize(elementos_y_prd_tracks, item_medida, cantidad)
5
+ @elementos_y_prd_tracks = elementos_y_prd_tracks
6
+ @item_medida = item_medida
7
+
8
+ @cantidad = cantidad
9
+ end
10
+
11
+ def puestos_de_primer_nivel_a_actualizar(elemento)
12
+ elemento.lista_de_puestos_del_elemento_track_primer_nivel
13
+ end
14
+
15
+ def puestos_de_segundo_nivel_a_actualizar(componente)
16
+ componente.lista_de_puestos_del_componente_track_segundo_nivel
17
+ end
18
+
19
+ def puestos_de_tercer_nivel_a_actualizar(composicion)
20
+ composicion.lista_de_puestos_de_composicion_track_tercer_nivel
21
+ end
22
+
23
+ def prd_track_de_primer_nivel_a_actualizar(lista_de_puestos, elemento)
24
+ lista_de_puestos.collect do |puesto|
25
+ puesto.get_prd_track.find_by(linea_item: @item_medida, elemento_id: elemento.id)
26
+ end
27
+ end
28
+
29
+ def prd_track_de_segundo_nivel_a_actualizar(lista_de_puestos, componente)
30
+ lista_de_puestos.collect do |puesto|
31
+ puesto.get_prd_track.find_by(linea_item: @item_medida, componente_id: componente.id)
32
+ end
33
+ end
34
+
35
+ def prd_track_de_tercer_nivel_a_actualizar(lista_de_puestos, composicion)
36
+ lista_de_puestos.collect do |puesto|
37
+ puesto.get_prd_track.find_by(linea_item: @item_medida, composicion_id: composicion.id)
38
+ end
39
+ end
40
+
41
+ # se le pasa una lista, y devuelve la misma lista hasta encontrarse con el prd_track pasado por parametro
42
+ # el 9999 es para que si el prd_track no esta dentro de la lista, devuelva toda la lista
43
+ # recordar que las listas son por niveles
44
+ # -> nivel 1 (Ini, Cmp, Crt, etc)
45
+ # -> nivel 2 (Lam, Tll)
46
+ # quiere decir que si quiero marcar retrabajos hasta DVH, en las listas de primer y segundo nivel, no va a aparecer el prd_track de DVH, por eso index = 9999
47
+ def hasta_puesto(lista, prd_track_hasta)
48
+ index_de_este_puesto_en_la_lista = lista.index(prd_track_hasta) || 9999
49
+ lista[0..index_de_este_puesto_en_la_lista]
50
+ end
51
+
52
+ def update_retrabajos(prd_tracks, cantidad)
53
+ Rails.logger.info "ENTRA AL UPDATE_RETRABAJOS"
54
+ prd_tracks.map{ |pt| pt.update_attribute :retrabajo, pt.retrabajo + cantidad }
55
+ end
56
+
57
+ def start(rotura_anterior = nil)
58
+
59
+ prd_tracks = []
60
+
61
+ @elementos_y_prd_tracks.each do |eypt|
62
+
63
+ elemento = eypt[:elemento]
64
+ prd_track_hasta = eypt[:prd_track]
65
+
66
+ componente = elemento.componente
67
+ composicion = componente.composicion
68
+
69
+ prd_tracks_parcial = []
70
+
71
+ prd_tracks_parcial << prd_track_de_primer_nivel_a_actualizar(puestos_de_primer_nivel_a_actualizar(elemento), elemento).flatten
72
+
73
+ prd_tracks_parcial << prd_track_de_segundo_nivel_a_actualizar(puestos_de_segundo_nivel_a_actualizar(componente), componente).flatten
74
+
75
+ prd_tracks_parcial << prd_track_de_tercer_nivel_a_actualizar(puestos_de_tercer_nivel_a_actualizar(composicion), composicion).flatten
76
+
77
+ prd_tracks << hasta_puesto(prd_tracks_parcial.flatten, prd_track_hasta)
78
+
79
+ end
80
+
81
+ prd_tracks.flatten!.uniq! # borro los repetidos para que no se actualicen dos veces duplicando valores de retrabajo
82
+
83
+ update_retrabajos(prd_tracks, @cantidad)
84
+
85
+ end
86
+
87
+ end
@@ -0,0 +1,2 @@
1
+ class ServiceTrack
2
+ end
@@ -0,0 +1,3 @@
1
+ module SpfTracking
2
+ VERSION = "0.0.22"
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'service_track/busca_ultimo_puesto_completo'
2
+ require 'service_track/create_entrega_rapida'
3
+ require 'service_track/create_rotura'
4
+ require 'service_track/nueva_rotura'
5
+ require 'service_track/update_retrabajos'
6
+
7
+ require 'tracking/carga_rotura'
8
+ require 'tracking/registro_trabajo'
9
+ require 'tracking/trazabilidad_elemento'
10
+ require 'tracking/routes'
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :spf_tracking do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Tracking::CargaRotura
4
+
5
+ # solo carga la rotura del puesto actual
6
+ def cargar_rotura(cant, current_user)
7
+ if validacion_carga_rotura(cant)
8
+
9
+ self.update_attribute :rotura, self.rotura + cant
10
+ self.trabajos.build(type: "Rotura", cantidad: cant, hora_fecha: Time.now, user_id: current_user.try(:id)).save!
11
+ end
12
+
13
+ end
14
+
15
+ def validacion_carga_rotura(cant)
16
+ (cant == 1) # mientras la carga de rotura sea unitaria
17
+ #(cant <= self.terminado - self.retrabajo)
18
+ end
19
+
20
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ module Tracking::RegistroTrabajo
4
+
5
+
6
+ def registrar_trabajo(cant_trabajada, opts = {})
7
+
8
+ cant_trabajada = cant_trabajada.to_i
9
+
10
+ proximo = self.next
11
+
12
+ if validaciones_actualizar_terminados(cant_trabajada)
13
+ actualizar_terminados(cant_trabajada, opts)
14
+
15
+ proximo.registrar_trabajo(cant_trabajada, opts) if proximo.try(:modo) == "auto" # si proximo no es nil (si self == PrdDevTrack, proximo es nil )
16
+ end
17
+
18
+ # REFACTORIZAR: ESTO MEPA QUE NO SE USA MAS, ERA DE LA PREFACTURACION
19
+ # post_proceso(cant_trabajada)
20
+
21
+ end
22
+
23
+
24
+ def validaciones_actualizar_terminados(cant_trabajada)
25
+ validar_disponible_anterior(cant_trabajada) && validar_limite_total_pedido(cant_trabajada)
26
+ end
27
+
28
+ # la cantidad trabajada tiene que ser menor o igual a lo que haya di
29
+ def validar_disponible_anterior(cant)
30
+ disponibles = self.disponibles_anterior || 9999
31
+ (cant.to_i <= disponibles)
32
+ end
33
+
34
+ # la cantidad trabajada más lo que ya hay terminado y listo no puede superar al total de paños pedidos
35
+ def validar_limite_total_pedido(cant)
36
+ (self.total_pedido >= cant.to_i + self.terminado_listo)
37
+ end
38
+
39
+
40
+
41
+ def disponibles_anterior
42
+ self.prev.min_by(&:terminado_listo).try(:terminado_listo)
43
+ end
44
+
45
+ # terminado listo es lo que está terminado y en existencia física
46
+ def terminado_listo
47
+ terminado - retrabajo
48
+ end
49
+
50
+
51
+
52
+
53
+ def actualizar_terminados(cant_trabajada, opts = {})
54
+ usuario_id = opts.fetch(:usuario_id, nil)
55
+ self.trabajos.build(type: "Terminado", cantidad: cant_trabajada, hora_fecha: Time.now, user_id: usuario_id).save!
56
+ self.update_attribute :terminado, self.terminado + cant_trabajada
57
+ end
58
+
59
+
60
+
61
+ end
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ # se le pasa una medida y un elemento
4
+
5
+ # ente otras cosas sabe calcular la cantidad de disponibles que hay en cada
6
+ # puesto, no solo de pustos referidos a ese elemento, sino también a su
7
+ # componente y a su composición
8
+
9
+ # EJEMPLO
10
+
11
+ # si se le pasa IM1 y E1, no solamente busca en Trazabilidad las filas con esos
12
+ # parametros, sino también los que tienen componente E1.componente y
13
+ # composición E1.componente.composicion
14
+
15
+
16
+ class Tracking::TrazabilidadElemento
17
+
18
+ def initialize(item_medida, elemento, puesto_control)
19
+ @puesto_control = puesto_control
20
+ @elemento = elemento
21
+ @componente = elemento.componente
22
+ @composicion = @componente.composicion
23
+ @trazabilidads = []
24
+ @trazabilidads += Trazabilidad.where(linea_item: item_medida, elemento: elemento)
25
+ @trazabilidads += Trazabilidad.where(linea_item: item_medida, componente: @componente)
26
+ @trazabilidads += Trazabilidad.where(linea_item: item_medida, composicion: @composicion, componente_id: nil, elemento_id: nil)
27
+ @trazabilidads = @trazabilidads.flatten.compact.uniq
28
+ end
29
+
30
+ def cantidad_terminados_listos
31
+ @trazabilidads.each do |t|
32
+ if t.puesto_control == @puesto_control
33
+ listo = t.terminado_listo
34
+ listo_siguiente = t.next.terminado_listo
35
+
36
+ return listo - listo_siguiente
37
+ end
38
+ end
39
+ raise "Error al calcular los terminados listos para Medida: #{@item_medida.ancho}x#{@item_medida.alto} ; Puesto: #{@puesto_control.nombre} ; Elemento: #{@elemento.descripcion} Id: #{@elemento.id}"
40
+ end
41
+
42
+ # Ejemplo: Float 6 Pulido Templado + cam + lam3+3
43
+ # Hoy 1/12/15 el Corte, Taller, Temp no están implementados
44
+ # Entonces
45
+ # Este método va a devovler la cantidad disponible no sólo para DVH
46
+ # Sino también para Corte, Taller, Etc
47
+ # Se usaba en el lector de roturas, selección de Puesto
48
+ def cantidad_terminados_listos_ultimo_auto
49
+ @trazabilidads.each do |t|
50
+ if t.puesto_control == @puesto_control
51
+ listo = t.terminado_listo
52
+ listo_siguiente = t.next.terminado_listo
53
+
54
+ return 1 #listo - listo_siguiente
55
+ end
56
+ end
57
+ raise "Error al calcular los terminados listos para Medida: #{@item_medida.ancho}x#{@item_medida.alto} ; Puesto: #{@puesto_control.nombre} ; Elemento: #{@elemento.descripcion} Id: #{@elemento.id}"
58
+ end
59
+
60
+ def ya_fue_laminado?
61
+ lista = @elemento.lista_de_puestos_del_elemento_completa
62
+
63
+ index_laminado = lista.index(PuestoControl.laminado) || (return false)
64
+ index_actual = lista.index(@puesto_control)
65
+
66
+ index_actual > index_laminado ? true : false
67
+ end
68
+
69
+ end
70
+
@@ -0,0 +1,40 @@
1
+ module UtilTrazabilidad
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ def estado_string
6
+ esta_terminado? ? puesto_control.verbo_terminado : trabajos_disponibles > 0 ? "Disponible" : "No disponible"
7
+ end
8
+
9
+ def esta_terminado?
10
+ terminado - retrabajo == total_pedido
11
+ end
12
+
13
+ def esta_terminado_parcial?
14
+ (!esta_terminado? && (terminado - retrabajo > 0))
15
+ end
16
+
17
+ # trabajos disponibles reales en cada sección
18
+ # terminados seccion anterior menos terminados de la actual
19
+ # REVISAR ceros y nulos
20
+ def trabajos_disponibles
21
+ if self.class == Tracking::PrdIniTrack
22
+ return total_pedido - (terminado - retrabajo)
23
+ else
24
+ minimo_de_los_terminados_anterior = prev.min_by(&:terminado_listo)
25
+ return minimo_de_los_terminados_anterior.terminado_listo - terminado_listo
26
+ end
27
+ end
28
+
29
+ def puesto_actual_y_siguiente_completos?
30
+ prd_track_actual_completo = self.try(:esta_terminado?)
31
+ prd_track_siguiente_completo = self.next.try(:esta_terminado?)
32
+ # si están completos, entonces el icono no se muestra
33
+ (prd_track_actual_completo && prd_track_siguiente_completo)
34
+ end
35
+
36
+ def cant_disponibles_siguiente
37
+ self.next.try(:trabajos_disponibles)
38
+ end
39
+
40
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spf_tracking
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.20
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Ramseyer
@@ -31,7 +31,30 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - MIT-LICENSE
35
+ - README.rdoc
36
+ - Rakefile
37
+ - lib/descriptivo.rb
38
+ - lib/experto_rotura_trazabilidad.rb
39
+ - lib/experto_trazabilidad.rb
40
+ - lib/proceso_de_producto.rb
41
+ - lib/proxima_trazabilidad_rotura.rb
42
+ - lib/rotura_anterior.rb
43
+ - lib/ruta_seguimiento.rb
44
+ - lib/service_track.rb
45
+ - lib/service_track/busca_ultimo_puesto_completo.rb
46
+ - lib/service_track/create_entrega_rapida.rb
47
+ - lib/service_track/create_rotura.rb
48
+ - lib/service_track/nueva_rotura.rb
49
+ - lib/service_track/update_retrabajos.rb
50
+ - lib/spf_tracking.rb
51
+ - lib/spf_tracking/version.rb
52
+ - lib/tasks/spf_tracking_tasks.rake
53
+ - lib/tracking/carga_rotura.rb
54
+ - lib/tracking/registro_trabajo.rb
34
55
  - lib/tracking/routes.rb
56
+ - lib/tracking/trazabilidad_elemento.rb
57
+ - lib/util_trazabilidad.rb
35
58
  - test/dummy/README.rdoc
36
59
  - test/dummy/Rakefile
37
60
  - test/dummy/app/assets/javascripts/application.js