StockInicialProcesoMigracion.cs
1 using sage.ew.db;
2 using sage.ew.ewbase;
3 using System;
4 using System.Collections.Generic;
5 using System.Data;
6 using System.Linq;
7 using System.Text;
8 
9 namespace sage.ew.serie.Clases
10 {
17  {
18  #region Variables privadas
19 
23  private bool _usarDatosHisserie = true;
24 
25  #region Tablas temporales
26 
27  private const string TEMPCOMPRAS = @"#TMPCOMPRAS";
28  private const string TEMPSTOCKINI = @"#TMPSTOCKINI";
29  private const string TEMPINICIALSER = @"#TMPINICIALSER";
30  private const string TEMPTRASP = @"#TMPTRASP";
31 
32  #endregion Tablas temporales
33 
34  #endregion Variables privadas
35 
36  #region Propiedades
37 
41  public string EjercicioAnterior
42  {
43  get { return _Anterior.Ejercicio; }
44  }
45  PeriodoItem _Anterior = null;
46 
50  public string Ejercicio
51  {
52  get { return _Actual.Ejercicio; }
53  }
54  PeriodoItem _Actual = null;
55 
59  public string Mensaje { get; private set; } = string.Empty;
60 
64  public bool Restultado { get; private set; } = false;
65 
66  #endregion Propiedades
67 
68  #region Constructores
69 
73  private StockInicialProcesoMigracion() { }
74 
79  public StockInicialProcesoMigracion(string ejercicio) : this()
80  {
81  _Actual = Periodos.Instancia.GetPeriodo(ejercicio);
82  _Anterior = Periodos.Instancia.GetPeriodoAnteriorAl(ejercicio);
83  }
84 
85  #endregion Constructores
86 
87  #region Métodos públicos
88 
92  public void Execute()
93  {
94  //Sino supera las validaciones previas acabo
95  if (!ValidacionesPrevias())
96  return;
97 
98  var query = string.Empty;
99 
100  //Obtiene el query de borrado de tablas temporales (por si acaso)
101  query += GetQuery_BorrarTablasTemporales();
102 
103  //Obtengo la instrucción de borrado de datos previos en stockini (presuntamente ha de estar vacio para articulos de series)
104  query += GetQuery_BorrarArticulosDeSeriesDeStockIni();
105 
106  //Obtengo la instrucción de borrado de datos previos en INICIALSER (presuntamente ha de estar vacio)
107  query += GetQuery_BorrarArticulosDeSeriesDeInicialser();
108 
109  //Obtengo el query que creará los orínenes de datos
110  query += GetQuery_CrearOrigenesDeDatos();
111 
112  //Obtengo el query para insertar registros
113  query += GetQuery_InsertarRegistros();
114 
115  //Obtiene el query de borrado de tablas temporales
116  query += GetQuery_BorrarTablasTemporales();
117 
118  //Ejecuto todas las operaciones
119  Restultado = DB.SQLExec(query);
120  }
121 
122  #endregion Métodos públicos
123 
124  #region Métodos privados
125 
129  private string GetQuery_BorrarTablasTemporales()
130  {
131  var query = string.Empty;
132 
133  query += $"IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..{TEMPCOMPRAS}')) BEGIN DROP TABLE {TEMPCOMPRAS} END; " + Environment.NewLine;
134  query += $"IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..{TEMPSTOCKINI}')) BEGIN DROP TABLE {TEMPSTOCKINI} END; " + Environment.NewLine;
135  query += $"IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..{TEMPINICIALSER}')) BEGIN DROP TABLE {TEMPINICIALSER} END; " + Environment.NewLine;
136  query += $"IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE ID = OBJECT_ID(N'tempdb..{TEMPTRASP}')) BEGIN DROP TABLE {TEMPTRASP} END; " + Environment.NewLine;
137 
138  return query;
139  }
140 
141  private bool ValidacionesPrevias()
142  {
143 
144  //Ha de tener ejercicio anterior
146  {
147  Restultado = true; //El resultado es true pq no implica error, simplemente el proceso es innecesario
148  Mensaje = "No existe ejercicio anterior.";
149  return false;
150  }
151 
152  //Que trabaje con series
153  if (!InstalacionConSeries())
154  {
155  Restultado = true; //El resultado es true pq no implica error, simplemente el proceso es innecesario
156  Mensaje = "La instalación no trabaja con series.";
157  return false;
158  }
159 
160  return true;
161  }
162 
163  private bool InstalacionConSeries()
164  {
165  //Lo ideal sería usar EW_GLOBAL => Convert.ToBoolean(EW_GLOBAL._GetVariable("wl_series", false)) pero no esta cargada
166  //por lo que iremos a por los valores en tablas => GESTION.CONTADOR campo SERIES. El uso de series debería ser uniforme por todas las empresas de un grupo
167  var sql = $"SELECT TOP (1) * FROM {DB.SQLDatabase(_Actual.Ejercicio, "CONTADOR")} WHERE SERIES = 8758 OR SERIES = 8578 ";
168  var datos = new DataTable();
169  if (DB.SQLExec(sql, ref datos) && datos.Rows.Count > 0)
170  {
171  return true;
172  }
173  return false;
174  }
175 
176  private string GetQuery_InsertarRegistros()
177  {
178  var query = string.Empty;
179 
180  //STOCKINI
181  query += $"INSERT INTO {DB.SQLDatabase(_Actual.Ejercicio, "STOCKINI")} (EMPRESA, ALMACEN, FECHA, ARTICULO, UNIDADES, LINIA, PMCOM, DEPCOM) " + Environment.NewLine +
182  $"(" + Environment.NewLine +
183  $" SELECT STOCKINI.EMPRESA, STOCKINI.ALMACEN, {DB.SQLString(_Actual.PeriodoIni)} as FECHA, STOCKINI.ARTICULO, STOCKINI.SERIES as UNIDADES, " + Environment.NewLine +
184  " (SELECT STR(COALESCE(MAX(NUMLINEA.LINIA) + STOCKINI.NUMLIN, STOCKINI.NUMLIN), 5) AS NUMERO " + Environment.NewLine + //Autocalcula el número de línea
185  $" FROM {DB.SQLDatabase(_Actual.Ejercicio, "STOCKINI")} NUMLINEA " + Environment.NewLine +
186  " WHERE NUMLINEA.EMPRESA = STOCKINI.EMPRESA " + Environment.NewLine +
187  " AND NUMLINEA.ALMACEN = STOCKINI.ALMACEN " + Environment.NewLine +
188  $" AND NUMLINEA.FECHA = {DB.SQLString(_Actual.PeriodoIni)} " + Environment.NewLine +
189  " ) as LINIA, STOCKINI.COSTE AS PMCOM, STOCKINI.DEPOSITO AS DEPCOM " + Environment.NewLine +
190  $" FROM {TEMPSTOCKINI} as STOCKINI" + Environment.NewLine +
191  $"); " + Environment.NewLine;
192 
193  //Ahora en stockini tenemos números de linea nuevos que hay que usar para informar INICIALSER y HISSERIE, volcamos a temporal
194  query += $"SELECT STOCKINI.EMPRESA, STOCKINI.ALMACEN, STOCKINI.FECHA, STOCKINI.LINIA as LINEA, STOCKINI.ARTICULO, COMPRAS.SERIE, " + Environment.NewLine +
195  $" COMPRAS.LINEA as NUMERO, Cast(0 as bit) as BAJA, Cast(0 as bit) as MODELO, " + Environment.NewLine +
196  $" (CASE COMPRAS.DEPOSITO WHEN 'D' THEN Cast(1 as bit) ELSE Cast(0 as bit) END) as DEPOSITO " + Environment.NewLine +
197  $"INTO {TEMPINICIALSER} " + Environment.NewLine +
198  $"FROM (" + Environment.NewLine +
199  $" SELECT STOCKINI.EMPRESA, STOCKINI.ALMACEN, STOCKINI.FECHA, STOCKINI.ARTICULO, STOCKINI.LINIA " + Environment.NewLine +
200  $" FROM {DB.SQLDatabase(_Actual.Ejercicio, "STOCKINI")} " + Environment.NewLine +
201  $" INNER JOIN({GetQuery_ArticulosDeSeries(_Anterior.Ejercicio)}) ARTICULO ON STOCKINI.ARTICULO = ARTICULO.ARTICULO " + Environment.NewLine +
202  $" ) STOCKINI " + Environment.NewLine +
203  $"LEFT JOIN( " + Environment.NewLine +
204  $" SELECT ARTICULO, ALMACEN, SERIE, DEPOSITO, ROW_NUMBER() OVER(PARTITION BY EMPRESA, ALMACEN, ARTICULO order by EMPRESA, ALMACEN, ARTICULO) as LINEA " + Environment.NewLine +
205  $" FROM {TEMPCOMPRAS} " + Environment.NewLine +
206  $" ) COMPRAS ON COMPRAS.ARTICULO = STOCKINI.ARTICULO AND COMPRAS.ALMACEN = STOCKINI.ALMACEN ; " + Environment.NewLine;
207 
208  //Insertamos en INICIALSER
209  query += $"INSERT {DB.SQLDatabase(_Actual.Ejercicio, "INICIALSER")} (EMPRESA, ALMACEN, FECHA, LINEA, ARTICULO, SERIE, NUMERO, BAJA, MODELO, DEPOSITO) " + Environment.NewLine +
210  $" (SELECT EMPRESA, ALMACEN, FECHA, LINEA, ARTICULO, SERIE, NUMERO, BAJA, MODELO, DEPOSITO FROM {TEMPINICIALSER}) ;" + Environment.NewLine;
211 
212  //Ahora hay que insertar el registro del movimiento en HISSERIE
213  query += $"INSERT INTO {DB.SQLDatabase("COMUNES", "HISSERIE")} " +
214  "(SERIE,FECHA,HORA,DOCUMENTO,NUMERO,CUENTA,MOVIMIENTO,USUARIO,COSTE,PRECIO,OBSERVA,ORDENADOR,EMPRESA,ALMACEN,MODELO, IGNORAR, FECHADOC) " + Environment.NewLine +
215  "(SELECT SERIE," +
216  DB.SQLString(DateTime.Now.ToString("d")) + ", " + //FECHA
217  DB.SQLString(DateTime.Now.ToString("T")) + ", " + //HORA
218  "'INICIAL', " + //DOCUMENTO
219  "'' , " + //NUMERO
220  "'INICIAL', " + //CUENTA
221  "'A', " + //MOVIMIENTO
222  "'ACTUALIZACION', " + //USUARIO
223  "0, " + //COSTE
224  "0, " + //PRECIO
225  "'', " + //OBSERVA
226  DB.SQLString(Environment.MachineName.Trim().ToUpper()) + ", " + //ORDENADOR
227  "EMPRESA, " + //EMPRESA
228  "ALMACEN, " + //ALMACEN
229  "'', " + //MODELO
230  " CAST(0 as BIT), " + //CCR 148577
231  DB.SQLString(_Actual.PeriodoIni) + " " +
232  $"FROM {TEMPINICIALSER} ) ;" + Environment.NewLine;
233 
234  return query;
235  }
236 
242  private string GetQuery_CrearOrigenesDeDatos()
243  {
244  #region Datos STOCKINSER
245 
246  //Obtener datos de stockinser
247  string queryOrigenDatos = GetQuery_ObtenerSeriesDeStockInSer();
248 
249  //Incorporo los costes y la marca de deposito a los datos
250  queryOrigenDatos = $@"SELECT DATOS.* " + Environment.NewLine +
251  $"INTO {TEMPCOMPRAS} " + Environment.NewLine +
252  $"FROM ({queryOrigenDatos}) AS DATOS; " + Environment.NewLine;
253 
254  #region Corrección eventuales cambios de almacen
255 
256  //Creo tabla temporal de cambios de almacen
257  queryOrigenDatos += QueryCrearTablaTemporal_TraspasosAlmacen() + "; ";
258 
259  //Actualizo los datos de la tabla temporal de compras con los datos de cambio de almacén
260  queryOrigenDatos += $"UPDATE A set A.ALMACEN = B.ALMACEN " + Environment.NewLine +
261  $"FROM {TEMPCOMPRAS} AS A," + Environment.NewLine +
262  $"(" + Environment.NewLine +
263  $" SELECT x.SERIE, x.ALMACEN FROM {TEMPTRASP} x " + Environment.NewLine +
264  $") AS B" + Environment.NewLine +
265  $"WHERE A.SERIE = B.SERIE; " + Environment.NewLine;
266 
267 
268  #endregion Corrección eventuales cambios de almacen
269 
270  #endregion Datos COMPRAS e STOCKINSER
271 
272  #region Datos para STOCKINI
273 
274  queryOrigenDatos += "SELECT EMPRESA, ALMACEN, ARTICULO, COUNT(*) AS SERIES, " + Environment.NewLine +
275  " ROUND(SUM(COSTE)/COUNT(*),2) AS COSTE, " + Environment.NewLine +
276  " SUM(CASE DEPOSITO WHEN 'D' THEN 1 ELSE 0 END) AS DEPOSITO, " + Environment.NewLine +
277  " ROW_NUMBER() OVER(PARTITION BY EMPRESA, ALMACEN order by EMPRESA, ALMACEN, ARTICULO) as NUMLIN " + Environment.NewLine +
278  $"INTO {TEMPSTOCKINI} FROM {TEMPCOMPRAS} " + Environment.NewLine +
279  "GROUP BY EMPRESA, ALMACEN, ARTICULO ; " + Environment.NewLine + Environment.NewLine;
280 
281  #endregion Datos para STOCKINI
282 
283  return queryOrigenDatos;
284  }
285 
286  private string QueryCrearTablaTemporal_TraspasosAlmacen()
287  {
288  //Movimientos entre almacenes para determinar el almacen a fecha de apertura
289 
290  var query = "SELECT DATOS.* " +
291  $"INTO {TEMPTRASP} " +
292  "FROM (" + Environment.NewLine +
293  "SELECT SERIE.SERIE, SERIE.ARTICULO, DOCUMENTO.FECHA, DOCUMENTO.ALMORIG AS ALMACEN, DOCUMENTO.ALMDEST, 'TRASPASO' as TIPOMOV, " + Environment.NewLine +
294  CamposHisserie() + ", ROW_NUMBER() OVER(PARTITION BY SERIE.SERIE ORDER BY DOCUMENTO.Fecha ASC ) AS fila" + Environment.NewLine +
295  $"FROM {DB.SQLDatabase(_Actual.Ejercicio, "TRASPSER")} SERIE " + Environment.NewLine +
296  $"INNER JOIN {DB.SQLDatabase(_Actual.Ejercicio, "C_ALBATR")} DOCUMENTO ON DOCUMENTO.EMPRESA = SERIE.EMPRESA " +
297  "AND DOCUMENTO.NUMERO = SERIE.ALBARAN " + Environment.NewLine +
298  $"INNER JOIN {DB.SQLDatabase(_Actual.Ejercicio, "D_ALBATR")} DETALLE ON DETALLE.EMPRESA = SERIE.EMPRESA " +
299  "AND DETALLE.NUMERO = SERIE.ALBARAN " +
300  "AND DETALLE.LINIA = SERIE.LINEA " +
301  "AND DETALLE.ARTICULO = SERIE.ARTICULO " + Environment.NewLine +
302  LeftJoinHisserie(documento: "TRASPASO") + " " + Environment.NewLine +
303  ") DATOS WHERE DATOS.FILA = 1 " + Environment.NewLine; //Sólo me interesa el más antiguo
304 
305  return query;
306  }
307 
308  #region Métodos comunes de HISSERIE
309 
310  private string CamposHisserie()
311  {
312  var campos = "";
313  if (_usarDatosHisserie)
314  {
315  campos = "HISSERIE.FECHAMOV, HISSERIE.MOVIMIENTO " + Environment.NewLine;
316  //HISSERIE.FECHAMOV => Es un campo construido
317  //campos = " HISSERIE.FECHA + HISSERIE.HORA as FECHAMOV, HISSERIE.MOVIMIENTO " + Environment.NewLine;
318  }
319  return campos;
320  }
321 
322  private string LeftJoinHisserie(string documento)
323  {
324  var query = "";
325  if (_usarDatosHisserie)
326  {
327  var tipoMovimiento = "(MOVIMIENTO = 'A' OR MOVIMIENTO = 'B')";
328  var joinClause = "SERIE.SERIE = HISSERIE.SERIE ";
329  switch (documento)
330  {
331  case "VENTA":
332  joinClause += " AND RTRIM(SERIE.ALBARAN) +LTRIM(RTRIM(SERIE.LETRA)) = RTRIM(HISSERIE.NUMERO) ";
333  break;
334  case "DEPOSITO":
335  joinClause += " AND RTRIM(SERIE.DEPOSITO) +LTRIM(RTRIM(SERIE.LETRA)) = RTRIM(HISSERIE.NUMERO) ";
336  break;
337 
338  case "MODELO":
339  case "REGULARI":
340  joinClause += " AND RTRIM(SERIE.DOCUMENTO) = RTRIM(HISSERIE.NUMERO) ";
341  break;
342 
343  case "PRODUC": //Consumo en producción
344  case "PRODUCCION": //Alta por producción
345  case "TRANSFORM": //Consumo en transformación
346  case "TRANSFORMA": //Alta por transformación
347  case "ALBAREGU":
348  case "DEPCOM":
349  joinClause += " AND RTRIM(SERIE.ALBARAN) = RTRIM(HISSERIE.NUMERO) ";
350  break;
351 
352  case "TRASPASO":
353  tipoMovimiento = "MOVIMIENTO = 'M' ";
354  joinClause += " AND RTRIM(SERIE.ALBARAN) = RTRIM(HISSERIE.NUMERO) ";
355  break;
356 
357  case "SERVICIO": //Entragada a técnico o entrada en un servicio
358  joinClause += " AND RTRIM(SERIE.SERVEI) = RTRIM(HISSERIE.NUMERO) ";
359  break;
360 
361  case "ORDENES": //Entragada a técnico o entrada en un servicio
362  joinClause += " AND RTRIM(SERIE.ORDRE) = RTRIM(HISSERIE.NUMERO) ";
363  break;
364 
365  case "MONTAJE": //Solo informa la baja, no informa cuenta ni modelo ni nada
366  joinClause += " AND HISSERIE.CUENTA = '' AND HISSERIE.NUMERO = '' ";
367  break;
368 
369  case "COMPRA":
370  joinClause += " AND RTRIM(SERIE.ALBARAN) = RTRIM(HISSERIE.NUMERO) AND SERIE.PROVEEDOR = HISSERIE.CUENTA ";
371  break;
372 
373  case "INICIAL":
374  joinClause += " AND RTRIM(SERIE.EMPRESA) = RTRIM(HISSERIE.DOCUMENTO) ";
375  break;
376  default:
377  //Sin clausula adicional o no contemplada
378  break;
379  }
380 
381  query = "LEFT JOIN ( " + Environment.NewLine +
382  " SELECT SERIE, MAX(FECHA +HORA) AS FECHAMOV, NUMERO, MAX(MOVIMIENTO) AS MOVIMIENTO, MAX(DOCUMENTO) AS DOCUMENTO, MAX(CUENTA) AS CUENTA " + Environment.NewLine +
383  $" FROM { DB.SQLDatabase("COMUNES", "HISSERIE")} " + Environment.NewLine +
384  $" WHERE DOCUMENTO = '{documento}' AND {tipoMovimiento} AND IGNORAR = 0 " + Environment.NewLine +
385  " GROUP BY SERIE, NUMERO, FECHA " + Environment.NewLine +
386  ") HISSERIE ON " + joinClause;
387  }
388  return query;
389  }
390 
391  #endregion Métodos comunes de HISSERIE
392 
397  private string GetQuery_ObtenerSeriesDeStockInSer()
398  {
399  return $"SELECT COMPRAS.CODEMPCOM AS EMPRESA, COMPRAS.ALMACEN, STOCKINSER.SERIE, STOCKINSER.ARTICULO, ARTICULO.NOMBRE, COMPRAS.COSTE, COMPRAS.DEPOSITO, " + Environment.NewLine +
400  $" COMPRAS.GARANTIA, COMPRAS.BAJA, COMPRAS.FECHA, COMPRAS.CODEMPCOM, COMPRAS.EMPRESA as CAMPOEMPRESA " + Environment.NewLine +
401  $"FROM ({GetQuery_StockInser(_Actual.Ejercicio)}) STOCKINSER " + Environment.NewLine +
402  $"INNER JOIN " + DB.SQLDatabase("COMUNES", "COMPRAS") + " COMPRAS on STOCKINSER.SERIE = COMPRAS.SERIE " + Environment.NewLine +
403  $"INNER JOIN ({GetQuery_ArticulosDeSeries(_Anterior.Ejercicio)}) AS ARTICULO ON ARTICULO.ARTICULO = COMPRAS.ARTICULO " + Environment.NewLine +
404  $"WHERE (COMPRAS.BAJA = '' OR (COMPRAS.BAJA = 'S' AND COMPRAS.FBAJA >= {DB.SQLString(_Actual.PeriodoIni)} )) " + Environment.NewLine; //Descarto bajas anteriores a fecha inicio
405  }
406 
412  private string GetQuery_ArticulosDeSeries(string ejercicio)
413  {
414  string lcSql = $"SELECT CODIGO AS ARTICULO, NOMBRE FROM {DB.SQLDatabase(ejercicio, "ARTICULO")} WHERE VENSERIE = 1 AND MODELO = '' ";
415  return lcSql;
416  }
417 
423  private string GetQuery_StockInser(string ejercicio)
424  {
425  string lcSql = $"SELECT ARTICULO, SERIE, ALMACEN FROM {DB.SQLDatabase(ejercicio, "STOCKINSER")} ";
426  return lcSql;
427  }
428 
433  private string GetQuery_BorrarArticulosDeSeriesDeStockIni()
434  {
435  var query = $"DELETE FROM {DB.SQLDatabase(_Actual.Ejercicio, "STOCKINI")} " +
436  $"WHERE ARTICULO IN(SELECT CODIGO AS ARTICULO FROM {DB.SQLDatabase(_Anterior.Ejercicio, "ARTICULO")} WHERE VENSERIE = 1 AND MODELO = ''); " + Environment.NewLine;
437 
438  return query;
439  }
440 
445  private string GetQuery_BorrarArticulosDeSeriesDeInicialser()
446  {
447  var query = $"DELETE FROM {DB.SQLDatabase(_Actual.Ejercicio, "INICIALSER")}; " + Environment.NewLine;
448 
449  return query;
450  }
451 
452  #endregion Métodos privados
453  }
454 }
PeriodoItem GetPeriodoAnteriorAl(string tcEjercicio)
Obtiene el período anterior del ejercicio pasado como parámetro
Definition: Periodos.cs:131
Clase período (Item)
Definition: Periodos.cs:197
Clase para mensajes
Definition: Mensaje.cs:13
PeriodoItem GetPeriodo(string tcEjercicio)
Obtiene el período correspondiente al ejercicio pasado como parámetro
Definition: Periodos.cs:109
string Ejercicio
Ejercicio
Definition: Periodos.cs:202
Clase para la generación de registros en STOCKINI e INICIALSER en procesos de migración EW => s50 Se ...
DateTime PeriodoIni
Fecha de inicio de período
Definition: Periodos.cs:206
static Periodos Instancia
Instancia SINGLETON para períodos
Definition: Periodos.cs:18
Clase SINGLETON para la gestión de períodos
Definition: Periodos.cs:12
bool ExisteEjercicioAnteriorAl(string tcEjercicio)
Método que determina si existe el ejercicio anterior al indicado
Definition: Periodos.cs:161
StockInicialProcesoMigracion(string ejercicio)
Constructor con parámetros
string Ejercicio
Ejercicio sobre el que se realiza la operación