Added -v flag. Some changes trying to merge a XML file.
[mx3r.git] / testfile1.qs.MERGED_kdiff3
blob8554dd7f3d33e79bf144ef1fd25fbd2c3a9a4f4f
1 /***************************************************************************
2                  flfacturac.qs  -  description
3                              -------------------
4     begin                : lun abr 26 2004
5     copyright            : (C) 2004 by InfoSiAL S.L.
6     email                : mail@infosial.com
7  ***************************************************************************/
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
18 /** @file */ 
20 /** @class_declaration interna */
21 ////////////////////////////////////////////////////////////////////////////
22 //// DECLARACION ///////////////////////////////////////////////////////////
23 ////////////////////////////////////////////////////////////////////////////
25 //////////////////////////////////////////////////////////////////
26 //// INTERNA /////////////////////////////////////////////////////
27 class interna {
28         var ctx:Object;
29         function interna( context ) { this.ctx = context; }
30         function beforeCommit_presupuestoscli(curPresupuesto:FLSqlCursor):Boolean {
31                 return this.ctx.interna_beforeCommit_presupuestoscli(curPresupuesto);
32         }
33         function beforeCommit_pedidoscli(curPedido:FLSqlCursor):Boolean {
34                 return this.ctx.interna_beforeCommit_pedidoscli(curPedido);
35         }
36         function beforeCommit_pedidosprov(curPedido:FLSqlCursor):Boolean {
37                 return this.ctx.interna_beforeCommit_pedidosprov(curPedido);
38         }
39         function beforeCommit_albaranescli(curAlbaran:FLSqlCursor):Boolean {
40                 return this.ctx.interna_beforeCommit_albaranescli(curAlbaran);
41         }
42         function beforeCommit_albaranesprov(curAlbaran:FLSqlCursor):Boolean {
43                 return this.ctx.interna_beforeCommit_albaranesprov(curAlbaran);
44         }
45         function beforeCommit_facturascli(curFactura:FLSqlCursor):Boolean {
46                 return this.ctx.interna_beforeCommit_facturascli(curFactura);
47         }
48         function beforeCommit_facturasprov(curFactura:FLSqlCursor):Boolean {
49                 return this.ctx.interna_beforeCommit_facturasprov(curFactura);
50         }
51         function afterCommit_facturascli(curFactura:FLSqlCursor):Boolean {
52                 return this.ctx.interna_afterCommit_facturascli(curFactura);
53         }
54         function afterCommit_facturasprov(curFactura:FLSqlCursor):Boolean {
55                 return this.ctx.interna_afterCommit_facturasprov(curFactura);
56         }
57         function afterCommit_lineasalbaranesprov(curLA:FLSqlCursor):Boolean {
58                 return this.ctx.interna_afterCommit_lineasalbaranesprov(curLA);
59         }
60         function afterCommit_lineasfacturasprov(curLF:FLSqlCursor):Boolean {
61                 return this.ctx.interna_afterCommit_lineasfacturasprov(curLF);
62         }
63         function afterCommit_lineaspedidoscli(curLA:FLSqlCursor):Boolean {
64                 return this.ctx.interna_afterCommit_lineaspedidoscli(curLA);
65         }
66         function afterCommit_lineasalbaranescli(curLA:FLSqlCursor):Boolean {
67                 return this.ctx.interna_afterCommit_lineasalbaranescli(curLA);
68         }
69         function afterCommit_lineasfacturascli(curLF:FLSqlCursor):Boolean {
70                 return this.ctx.interna_afterCommit_lineasfacturascli(curLF);
71         }
73 //// INTERNA /////////////////////////////////////////////////////
74 //////////////////////////////////////////////////////////////////
76 /** @class_declaration oficial */
77 //////////////////////////////////////////////////////////////////
78 //// OFICIAL /////////////////////////////////////////////////////
79 class oficial extends interna {
80         function oficial( context ) { interna( context ); }
81         function obtenerHueco(codSerie:String, codEjercicio:String, tipo:String):Number {
82                 return this.ctx.oficial_obtenerHueco(codSerie, codEjercicio, tipo);
83         }
84         function establecerNumeroSecuencia(fN:String, value:Number):Number {
85                 return this.ctx.oficial_establecerNumeroSecuencia(fN, value);
86         }
87         function cerosIzquierda(numero:String, totalCifras:Number):String {
88                 return this.ctx.oficial_cerosIzquierda(numero, totalCifras);
89         }
90         function construirCodigo(codSerie:String, codEjercicio:String, numero:String):String {
91                 return this.ctx.oficial_construirCodigo(codSerie, codEjercicio, numero);
92         }
93         function siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number {
94                 return this.ctx.oficial_siguienteNumero(codSerie, codEjercicio, fN);
95         }
96         function agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean {
97                 return this.ctx.oficial_agregarHueco(serie, ejercicio, numero, fN);
98         }
99         function asientoBorrable(idAsiento:Number):Boolean {
100                 return this.ctx.oficial_asientoBorrable(idAsiento);
101         }
102         function generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean {
103                 return this.ctx.oficial_generarAsientoFacturaCli(curFactura);
104         }
105         function generarPartidasVenta(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
106                 return this.ctx.oficial_generarPartidasVenta(curFactura, idAsiento, valoresDefecto);
107         }
108         function generarPartidasIVACli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean {
109                 return this.ctx.oficial_generarPartidasIVACli(curFactura, idAsiento, valoresDefecto, ctaCliente);
110         }
111         function generarPartidasIRPF(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
112                 return this.ctx.oficial_generarPartidasIRPF(curFactura, idAsiento, valoresDefecto);
113         }
114         function generarPartidasRecFinCli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
115                 return this.ctx.oficial_generarPartidasRecFinCli(curFactura, idAsiento, valoresDefecto);
116         }
117         function generarPartidasIRPFProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
118                 return this.ctx.oficial_generarPartidasIRPFProv(curFactura, idAsiento, valoresDefecto);
119         }
120         function generarPartidasRecFinProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
121                 return this.ctx.oficial_generarPartidasRecFinProv(curFactura, idAsiento, valoresDefecto);
122         }
123         function generarPartidasCliente(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean {
124                 return this.ctx.oficial_generarPartidasCliente(curFactura, idAsiento, valoresDefecto, ctaCliente);
125         }
126         function regenerarAsiento(cur:FLSqlCursor, valoresDefecto:Array):Array {
127                 return this.ctx.oficial_regenerarAsiento(cur, valoresDefecto);
128         }
129         function generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean {
130                 return this.ctx.oficial_generarAsientoFacturaProv(curFactura);
131         }
132         function generarPartidasCompra(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, concepto:String):Boolean {
133                 return this.ctx.oficial_generarPartidasCompra(curFactura, idAsiento, valoresDefecto, concepto);
134         }
135         function generarPartidasIVAProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String):Boolean {
136                 return this.ctx.oficial_generarPartidasIVAProv(curFactura, idAsiento, valoresDefecto, ctaProveedor, concepto);
137         }
138         function generarPartidasProveedor(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String, sinIVA:Boolean):Boolean {
139                 return this.ctx.oficial_generarPartidasProveedor(curFactura, idAsiento, valoresDefecto, ctaProveedor, concepto, sinIVA);
140         }
141         function datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array {
142                 return this.ctx.oficial_datosCtaEspecial(ctaEsp, codEjercicio);
143         }
144         function datosCtaIVA(tipo:String, codEjercicio:String, codImpuesto:String):Array {
145                 return this.ctx.oficial_datosCtaIVA(tipo, codEjercicio, codImpuesto);
146         }
147         function datosCtaVentas(codEjercicio:String, codSerie:String):Array {
148                 return this.ctx.oficial_datosCtaVentas(codEjercicio, codSerie);
149         }
150         function datosCtaCliente(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
151                 return this.ctx.oficial_datosCtaCliente(curFactura, valoresDefecto);
152         }
153         function datosCtaProveedor(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
154                 return this.ctx.oficial_datosCtaProveedor(curFactura, valoresDefecto);
155         }
156         function asientoFacturaAbonoCli(curFactura:FLSqlCursor, valoresDefecto:Array){
157                 return this.ctx.oficial_asientoFacturaAbonoCli(curFactura, valoresDefecto);
158         }
159         function asientoFacturaAbonoProv(curFactura:FLSqlCursor, valoresDefecto:Array){
160                 return this.ctx.oficial_asientoFacturaAbonoProv(curFactura, valoresDefecto);
161         }
162         function datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array {
163                 return this.ctx.oficial_datosDocFacturacion(fecha, codEjercicio, tipoDoc);
164         }
165         function tieneIvaDocCliente(codSerie:String, codCliente:String):Number {
166                 return this.ctx.oficial_tieneIvaDocCliente(codSerie, codCliente);
167         }
168         function automataActivado():Boolean {
169                 return this.ctx.oficial_automataActivado();
170         }
171         function comprobarRegularizacion(curFactura:FLSqlCursor):Boolean {
172                 return this.ctx.oficial_comprobarRegularizacion(curFactura);
173         }
174         function recalcularHuecos(serie:String, ejercicio:String, fN:String):Boolean {
175                 return this.ctx.oficial_recalcularHuecos(serie, ejercicio, fN);
176         }
177         function mostrarTraza(codigo:String, tipo:String) {
178                 return this.ctx.oficial_mostrarTraza(codigo, tipo);
179         }
180         function datosPartidaFactura(curPartida:FLSqlCursor, curFactura:FLSqlCursor, tipo:String, concepto:String) {
181                 return this.ctx.oficial_datosPartidaFactura(curPartida, curFactura, tipo, concepto);
182         }
183         function eliminarAsiento(idAsiento:String):Boolean {
184                 return this.ctx.oficial_eliminarAsiento(idAsiento);
185         }
186         function siGenerarRecibosCli(curFactura:FLSqlCursor, masCampos:Array):Boolean {
187                 return this.ctx.oficial_siGenerarRecibosCli(curFactura, masCampos);
188         }
189         function validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean {
190                 return this.ctx.oficial_validarIvaRecargoCliente(codCliente,id,tabla,identificador);
191         }
192         function validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean {
193                 return this.ctx.oficial_validarIvaRecargoProveedor(codProveedor,id,tabla,identificador);
194         }
195         function comprobarFacturaAbonoCli(curFactura:FLSqlCursor):Boolean {
196                 return this.ctx.oficial_comprobarFacturaAbonoCli(curFactura);
197         }
198         function consultarCtaEspecial(ctaEsp:String, codEjercicio:String):Boolean {
199                 return this.ctx.oficial_consultarCtaEspecial(ctaEsp, codEjercicio);
200         }
201         function crearCtaEspecial(codCtaEspecial:String, tipo:String, codEjercicio:String, desCta:String):Boolean {
202                 return this.ctx.oficial_crearCtaEspecial(codCtaEspecial, tipo, codEjercicio, desCta);
203         }
204         function comprobarCambioSerie(cursor:FLSqlCursor):Boolean {
205                 return this.ctx.oficial_comprobarCambioSerie(cursor);
206         }
207         function consultarCtaEspecial(ctaEsp:String, codEjercicio:String):Boolean {
208                 return this.ctx.oficial_consultarCtaEspecial(ctaEsp, codEjercicio);
209         }
210         function netoVentasFacturaCli(curFactura:FLSqlCursor):Number {
211                 return this.ctx.oficial_netoVentasFacturaCli(curFactura);
212         }
213         function datosConceptoAsiento(cur:FLSqlCursor):Array {
214                 return this.ctx.oficial_datosConceptoAsiento(cur);
215         }
216         function crearCtaEspecial(codCtaEspecial:String, tipo:String, codEjercicio:String, desCta:String):Boolean {
217                 return this.ctx.oficial_crearCtaEspecial(codCtaEspecial, tipo, codEjercicio, desCta);
218         }
221 //// OFICIAL /////////////////////////////////////////////////////
222 //////////////////////////////////////////////////////////////////
224 /** @class_declaration barCode */
225 /////////////////////////////////////////////////////////////////
226 //// TALLAS Y COLORES POR BARCODE ///////////////////////////////
227 class barCode extends oficial {
228     function barCode( context ) { oficial ( context ); }
229         function afterCommit_lineaspedidosprov(curLP:FLSqlCursor):Boolean {
230                 return this.ctx.barCode_afterCommit_lineaspedidosprov(curLP);
231         }
232         function validarLinea(curLinea:FLSqlCursor):Boolean {
233                 return this.ctx.barCode_validarLinea(curLinea);
234         }
236 //// TALLAS Y COLORES POR BARCODE ///////////////////////////////
237 /////////////////////////////////////////////////////////////////
239 /** @class_declaration head */
240 /////////////////////////////////////////////////////////////////
241 //// DESARROLLO /////////////////////////////////////////////////
242 class head extends barCode {
243         function head( context ) { barCode ( context ); }
245 //// DESARROLLO /////////////////////////////////////////////////
246 /////////////////////////////////////////////////////////////////
248 /** @class_declaration ifaceCtx */
249 /////////////////////////////////////////////////////////////////
250 //// INTERFACE  /////////////////////////////////////////////////
251 class ifaceCtx extends head {
252         function ifaceCtx( context ) { head( context ); }
253         function pub_cerosIzquierda(numero:String, totalCifras:Number):String {
254                 return this.cerosIzquierda(numero, totalCifras);
255         }
256         function pub_asientoBorrable(idAsiento:Number):Boolean {
257                 return this.asientoBorrable(idAsiento);
258         }
259         function pub_regenerarAsiento(cur:FLSqlCursor, valoresDefecto:Array):Array {
260                 return this.regenerarAsiento(cur, valoresDefecto);
261         }
262         function pub_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array {
263                 return this.datosCtaEspecial(ctaEsp, codEjercicio);
264         }
265         function pub_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number {
266                 return this.siguienteNumero(codSerie, codEjercicio, fN);
267         }
268         function pub_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String {
269                 return this.construirCodigo(codSerie, codEjercicio, numero);
270         }
271         function pub_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean {
272                 return this.agregarHueco(serie, ejercicio, numero, fN);
273         }
274         function pub_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array {
275                 return this.datosDocFacturacion(fecha, codEjercicio, tipoDoc);
276         }
277         function pub_tieneIvaDocCliente(codSerie:String, codCliente:String):Number {
278                 return this.tieneIvaDocCliente(codSerie, codCliente);
279         }
280         function pub_automataActivado():Boolean {
281                 return this.automataActivado();
282         }
283         function pub_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean {
284                 return this.generarAsientoFacturaCli(curFactura);
285         }
286         function pub_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean {
287                 return this.generarAsientoFacturaProv(curFactura);
288         }
289         function pub_mostrarTraza(codigo:String, tipo:String) {
290                 return this.mostrarTraza(codigo, tipo);
291         }
292         function pub_eliminarAsiento(idAsiento:String):Boolean {
293                 return this.eliminarAsiento(idAsiento);
294         }
295         function pub_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean {
296                 return this.validarIvaRecargoCliente(codCliente,id,tabla,identificador);
297         }
298         function pub_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean {
299                 return this.validarIvaRecargoProveedor(codProveedor,id,tabla,identificador);
300         }
303 const iface = new pubBarcode( this );
304 //// INTERFACE  /////////////////////////////////////////////////
305 /////////////////////////////////////////////////////////////////
307 /** @class_declaration pubBarcode */
308 /////////////////////////////////////////////////////////////////
309 //// PUB BARCODE ////////////////////////////////////////////////
310 class pubBarcode extends ifaceCtx {
311         function pubBarcode( context ) { ifaceCtx( context ); }
312         function pub_validarLinea(curLinea:FLSqlCursor):Boolean {
313                 return this.validarLinea(curLinea);
314         }
316 //// PUB BARCODE ////////////////////////////////////////////////
317 /////////////////////////////////////////////////////////////////
319 /** @class_definition interna */
320 ////////////////////////////////////////////////////////////////////////////
321 //// DEFINICION ////////////////////////////////////////////////////////////
322 ////////////////////////////////////////////////////////////////////////////
324 //////////////////////////////////////////////////////////////////
325 //// INTERNA /////////////////////////////////////////////////////
326 /** \C 
327 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
329 Se actualiza el estado del pedido.
331 Si el pedido está servido parcialmente y se quiere borrar, no se permite borrarlo o se dá la opción de cancelar lo pendiente de servir.
332 \end */
333 function interna_beforeCommit_pedidoscli(curPedido:FLSqlCursor):Boolean
335         var util:FLUtil = new FLUtil();
336         var numero:String;
337         
338         switch (curPedido.modeAccess()) {
339                 case curPedido.Insert: {
340                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
341                                 return false;
342                         if (curPedido.valueBuffer("numero") == 0) {
343                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidocli");
344                                 if (!numero)
345                                         return false;
346                                 curPedido.setValueBuffer("numero", numero);
347                                 curPedido.setValueBuffer("codigo", formpedidoscli.iface.pub_commonCalculateField("codigo", curPedido));
348                         }
349                         break;
350                 }
351                 case curPedido.Edit: {
352                         if(!this.iface.comprobarCambioSerie(curPedido))
353                                 return false;
354                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
355                                 return false;
356                         if (curPedido.valueBuffer("servido") == "Parcial") {
357                                 var estado:String = formRecordlineasalbaranescli.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
358                                 if (estado == "Sí") {
359                                         curPedido.setValueBuffer("servido", estado);
360                                         curPedido.setValueBuffer("editable", false);
361                                 }
362                         }
363                         break;
364                 }
365                 case curPedido.Del: {
366                         if (curPedido.valueBuffer("servido") == "Parcial") {
367                                 MessageBox.warning(util.translate("scripts", "No se puede eliminar un pedido servido parcialmente.\nDebe borrar antes el albarán relacionado."), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
368                                 return false;
369                         }
370                         break;
371                 }
372         }
373         
374         return true;
377 /** \C 
378 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
380 Se actualiza el estado del pedido.
382 Si el pedido está servido parcialmente y se quiere borrar, no se permite borrarlo o se dá la opción de cancelar lo pendiente de servir.
383 \end */
384 function interna_beforeCommit_pedidosprov(curPedido:FLSqlCursor):Boolean
386         var util:FLUtil = new FLUtil();
387         var numero:String;
388         
389         switch (curPedido.modeAccess()) {
390                 case curPedido.Insert: {
391                         if (curPedido.valueBuffer("numero") == 0) {
392                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidoprov");
393                                 if (!numero)
394                                         return false;
395                                 curPedido.setValueBuffer("numero", numero);
396                                 curPedido.setValueBuffer("codigo", formpedidosprov.iface.pub_commonCalculateField("codigo", curPedido));
397                         }
398                         break;
399                 }
400                 case curPedido.Edit: {
401                         if(!this.iface.comprobarCambioSerie(curPedido))
402                                 return false;
403                         if (curPedido.valueBuffer("servido") == "Parcial") {
404                                 var estado:String = formRecordlineasalbaranesprov.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
405                                 if (estado == "Sí") {
406                                         curPedido.setValueBuffer("servido", estado);
407                                         curPedido.setValueBuffer("editable", false);
408                                         if (sys.isLoadedModule("flcolaproc")) {
409                                                 if (!flfactppal.iface.pub_lanzarEvento(curPedido, "pedidoProvAlbaranado"))
410                                                         return false;
411                                         }
412                                 }
413                         }
414                         break;
415                 }
416                 case curPedido.Del: {
417                         if (curPedido.valueBuffer("servido") == "Parcial") {
418                                 MessageBox.warning(util.translate("scripts", "No se puede eliminar un pedido servido parcialmente.\nDebe borrar antes el albarán relacionado."), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
419                                 return false;
420                         }
421                         break;
422                 }
423         }
424         return true;
427 /* \C En el caso de que el módulo de contabilidad esté cargado y activado, genera o modifica el asiento contable correspondiente a la factura a cliente.
428 \end */
429 function interna_beforeCommit_facturascli(curFactura:FLSqlCursor):Boolean
431         var util:FLUtil = new FLUtil();
432         var numero:String;
433         
434         if (!this.iface.comprobarFacturaAbonoCli(curFactura))
435                 return false;
437         switch (curFactura.modeAccess()) {
438                 case curFactura.Insert: {
439                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
440                                 return false;
441                         if (curFactura.valueBuffer("numero") == 0) {
442                                 this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli" );
443                                 numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
444                                 if (!numero)
445                                         return false;
446                                 curFactura.setValueBuffer("numero", numero);
447                                 curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
448                         }
449                         break;
450                 }
451                 case curFactura.Edit: {
452                         if(!this.iface.comprobarCambioSerie(curFactura))
453                                 return false;
454                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
455                                 return false;
456                         break;
457                 }
458         }
460         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
461                 if (util.sqlSelect("facturascli", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
462                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
463                         if (!numero)
464                                 return false;
465                         curFactura.setValueBuffer("numero", numero);
466                         curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
467                 }
468         }
470         if (!formRecordfacturascli.iface.pub_actualizarLineasIva(curFactura))
471                 return false;
473         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
474                 if (this.iface.generarAsientoFacturaCli(curFactura) == false)
475                         return false;
476         }
478         return true;
481 /* \C En el caso de que el módulo de contabilidad esté cargado y activado, genera o modifica el asiento contable correspondiente a la factura a proveedor.
482 \end */
483 function interna_beforeCommit_facturasprov(curFactura:FLSqlCursor):Boolean
485         var util:FLUtil = new FLUtil();
486         var numero:String;
487         
488         if (curFactura.valueBuffer("deabono") == true) {
489                 if (!curFactura.valueBuffer("idfacturarect")){
490                         MessageBox.warning(util.translate("scripts", "Debe seleccionar la factura que desea abonar"),MessageBox.Ok, MessageBox.NoButton,MessageBox.NoButton);
491                         return false;
492                 }
493                 if (util.sqlSelect("facturasprov", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
494                         MessageBox.warning(util.translate("scripts", "La factura ") +  util.sqlSelect("facturasprov", "codigo", "idfactura = " + curFactura.valueBuffer("idFacturarect"))  + util.translate("scripts", " ya está abonada"),MessageBox.Ok, MessageBox.NoButton,MessageBox.NoButton);
495                         return false;
496                 }
497         }
498         if (curFactura.modeAccess() == curFactura.Edit) {
499                 if(!this.iface.comprobarCambioSerie(curFactura))
500                                 return false;
501         }
502         if (curFactura.modeAccess() == curFactura.Insert) {
503                 if (curFactura.valueBuffer("numero") == 0) {
504                         this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov" );
505                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
506                         if (!numero)
507                                 return false;
508                         curFactura.setValueBuffer("numero", numero);
509                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
510                 }
511         }
513         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
514                 if (util.sqlSelect("facturasprov", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
515                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
516                         if (!numero)
517                                 return false;
518                         curFactura.setValueBuffer("numero", numero);
519                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
520                 }
521         }
523         if (!formRecordfacturasprov.iface.pub_actualizarLineasIva(curFactura))
524                 return false;
526         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
527                 if (this.iface.generarAsientoFacturaProv(curFactura) == false)
528                         return false;
529         }
530         return true;
534 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
535 Se recalcula el estado de los pedidos asociados al albarán
536 \end */
537 function interna_beforeCommit_albaranescli(curAlbaran:FLSqlCursor):Boolean
539         var util:FLUtil = new FLUtil();
540         var numero:String;
541         
542         switch (curAlbaran.modeAccess()) {
543                 case curAlbaran.Insert: {
544                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
545                                 return false;
546                         if (curAlbaran.valueBuffer("numero") == 0) {
547                                 numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbarancli");
548                                 if (!numero)
549                                         return false;
550                                 curAlbaran.setValueBuffer("numero", numero);
551                                 curAlbaran.setValueBuffer("codigo", formalbaranescli.iface.pub_commonCalculateField("codigo", curAlbaran));
552                         }
553                         break;
554                 }
555                 case curAlbaran.Edit: {
556                         if(!this.iface.comprobarCambioSerie(curAlbaran))
557                                 return false;
558                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
559                                 return false;
560                         break;
561                 }
562         }
563         
564         var query:FLSqlQuery = new FLSqlQuery();
565         query.setTablesList("lineasalbaranescli");
566         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
567         query.setFrom("lineasalbaranescli");
568         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
569         try { query.setForwardOnly( true ); } catch (e) {}
570         query.exec();
571         var idPedido:String = 0;
572         while (query.next()) {
573                 if (!formRecordlineasalbaranescli.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
574                         return false;
575                         
576                 if (idPedido != query.value(1)) {
577                         if (!formRecordlineasalbaranescli.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
578                                 return false;
579                 }
580                 idPedido = query.value(1)
581         }
582         return true;
585 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
587 Se recalcula el estado de los pedidos asociados al albarán
588 \end */
589 function interna_beforeCommit_albaranesprov(curAlbaran:FLSqlCursor):Boolean
591         var util:FLUtil = new FLUtil();
592         var numero:String;
593         
594         if (curAlbaran.modeAccess() == curAlbaran.Insert) {
595                 if (curAlbaran.valueBuffer("numero") == 0) {
596                         numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbaranprov");
597                         if (!numero)
598                                 return false;
599                         curAlbaran.setValueBuffer("numero", numero);
600                         curAlbaran.setValueBuffer("codigo", formalbaranesprov.iface.pub_commonCalculateField("codigo", curAlbaran));
601                 }
602         }
603         if (curAlbaran.modeAccess() == curAlbaran.Edit) {
604                 if(!this.iface.comprobarCambioSerie(curAlbaran))
605                                 return false;
606         }
608         var query:FLSqlQuery = new FLSqlQuery();
609         query.setTablesList("lineasalbaranesprov");
610         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
611         query.setFrom("lineasalbaranesprov");
612         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
613         try { query.setForwardOnly( true ); } catch (e) {}
614         query.exec();
615         var idPedido:String = 0;
616         while (query.next()) {
617                 if (!formRecordlineasalbaranesprov.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
618                         return false;
619                 if (idPedido != query.value(1)) {
620                         if (!formRecordlineasalbaranesprov.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
621                                 return false;
622                 }
623                 idPedido = query.value(1);
624         }
625         
626         return true;
629 /* \C Se calcula el número del presupuesto como el siguiente de la secuencia asociada a su ejercicio y serie. 
630 \end */
631 function interna_beforeCommit_presupuestoscli(curPresupuesto:FLSqlCursor):Boolean
633         var util:FLUtil = new FLUtil();
634         var numero:String;
635         
636         switch (curPresupuesto.modeAccess()) {
637                 case curPresupuesto.Insert: {
638                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
639                                 return false;
640                         if (curPresupuesto.valueBuffer("numero") == 0) {
641                                 numero = this.iface.siguienteNumero(curPresupuesto.valueBuffer("codserie"), curPresupuesto.valueBuffer("codejercicio"), "npresupuestocli");
642                                 if (!numero)
643                                         return false;
644                                 curPresupuesto.setValueBuffer("numero", numero);
645                                 curPresupuesto.setValueBuffer("codigo", formpresupuestoscli.iface.pub_commonCalculateField("codigo", curPresupuesto));
646                         }
647                         break;
648                 }
649                 case curPresupuesto.Edit: {
650                         if(!this.iface.comprobarCambioSerie(curPresupuesto))
651                                 return false;
652                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
653                                 return false;
654                         break;
655                 }
656         }
657         
658         return true;
661 /* \C En el caso de que el módulo de tesorería esté cargado, genera o modifica los recibos correspondientes a la factura.
663 En el caso de que el módulo pincipal de contabilidad esté cargado y activado, y que la acción a realizar sea la de borrado de la factura, borra el asiento contable correspondiente.
664 \end */
665 function interna_afterCommit_facturascli(curFactura:FLSqlCursor):Boolean
667         if (curFactura.modeAccess() == curFactura.Del) {
668                 if (!this.iface.agregarHueco(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), curFactura.valueBuffer("numero"), "nfacturacli"))
669                         return false;
670         }
671         
672         var util:FLUtil = new FLUtil();
673         
674         if (sys.isLoadedModule("flfactteso") && curFactura.valueBuffer("tpv") == false) {
675                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
676                         if (this.iface.siGenerarRecibosCli(curFactura))
677                                 if (flfactteso.iface.pub_regenerarRecibosCli(curFactura) == false)
678                                         return false;
679                 }
680                 if (curFactura.modeAccess() == curFactura.Del) {
681                         flfactteso.iface.pub_actualizarRiesgoCliente(curFactura.valueBuffer("codcliente"));
682                 }
683         }
685         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
686                 switch (curFactura.modeAccess()) {
687                         case curFactura.Del: {
688                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
689                                         return false;
690                                 break;
691                         }
692                         case curFactura.Edit: {
693                                 if (curFactura.valueBuffer("nogenerarasiento")) {
694                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
695                                         if (idAsientoAnterior && idAsientoAnterior != "") {
696                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
697                                                         return false;
698                                         }
699                                 }
700                                 break;
701                         }
702                 }
703         }
705         return true;
708 /* \C En el caso de que el módulo pincipal de contabilidad esté cargado y activado, y que la acción a realizar sea la de borrado de la factura, borra el asiento contable correspondiente.
709 \end */
710 function interna_afterCommit_facturasprov(curFactura:FLSqlCursor):Boolean
712         var util:FLUtil = new FLUtil();
713         if (sys.isLoadedModule("flfactteso")) {
714                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
715                         if (curFactura.valueBuffer("total") != curFactura.valueBufferCopy("total")
716                                 || curFactura.valueBuffer("codproveedor") != curFactura.valueBufferCopy("codproveedor")
717                                 || curFactura.valueBuffer("codpago") != curFactura.valueBufferCopy("codpago")
718                                 || curFactura.valueBuffer("fecha") != curFactura.valueBufferCopy("fecha")) {
719                                 if (flfactteso.iface.pub_regenerarRecibosProv(curFactura) == false)
720                                         return false;
721                         }
722                 }
723         }
725         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
726                 switch (curFactura.modeAccess()) {
727                         case curFactura.Del: {
728                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
729                                         return false;
730                                 break;
731                         }
732                         case curFactura.Edit: {
733                                 if (curFactura.valueBuffer("nogenerarasiento")) {
734                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
735                                         if (idAsientoAnterior && idAsientoAnterior != "") {
736                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
737                                                         return false;
738                                         }
739                                 }
740                                 break;
741                         }
742                 }
743         }
744         return true;
747 /** \C
748 Actualización del stock correspondiente al artículo seleccionado en la línea
749 \end */
750 function interna_afterCommit_lineasalbaranesprov(curLA:FLSqlCursor):Boolean
752         if (sys.isLoadedModule("flfactalma")) 
753                 if (!flfactalma.iface.pub_controlStockAlbaranesProv(curLA))
754                         return false;
755         
756         return true;
759 /** \C
760 En el caso de que la factura no sea automática (no provenga de un albarán), realiza la actualización del stock correspondiente al artículo seleccionado en la línea.
762 Actualiza también el coste medio de los artículos afectados por el cambio.
763 \end */
764 function interna_afterCommit_lineasfacturasprov(curLF:FLSqlCursor):Boolean
766         if (sys.isLoadedModule("flfactalma")) {
767                 var util:FLUtil = new FLUtil();
768                 switch(curLF.modeAccess()) {
769                         case curLF.Edit:
770                                 if (curLF.valueBuffer("referencia") != curLF.valueBufferCopy("referencia"))
771                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBufferCopy("referencia"));
772                         case curLF.Insert:
773                         case curLF.Del:
774                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBuffer("referencia"));
775                         break;
776                 }
777                 
778                 if (!flfactalma.iface.pub_controlStockFacturasProv(curLF))
779                         return false;
780         }
781         return true;
784 /** \C
785 Actualiza el stock correspondiente al artículo seleccionado en la línea si el sistema
786 está configurado para ello
787 \end */
788 function interna_afterCommit_lineaspedidoscli(curLP:FLSqlCursor):Boolean
790         if (sys.isLoadedModule("flfactalma"))
791                 if (!flfactalma.iface.pub_controlStockPedidosCli(curLP))
792                         return false;
793         
794         return true;
797 /** \C
798 Si la línea de albarán no proviene de una línea de pedido, realiza la actualización del stock correspondiente al artículo seleccionado en la línea
799 \end */
800 function interna_afterCommit_lineasalbaranescli(curLA:FLSqlCursor):Boolean
802         if (sys.isLoadedModule("flfactalma")) 
803                 if (!flfactalma.iface.pub_controlStockAlbaranesCli(curLA))
804                         return false;
805         
806         return true;
809 /** \C
810 En el caso de que la factura no sea automática (no provenga de un albarán), realiza la actualización del stock correspondiente al artículo seleccionado en la línea
811 \end */
812 function interna_afterCommit_lineasfacturascli(curLF:FLSqlCursor):Boolean
814         if (sys.isLoadedModule("flfactalma")) 
815                 if (!flfactalma.iface.pub_controlStockFacturasCli(curLF))
816                         return false;
817         
818         return true;
820 //// INTERNA /////////////////////////////////////////////////////
821 /////////////////////////////////////////////////////////////////
823 /** @class_definition oficial */
824 //////////////////////////////////////////////////////////////////
825 //// OFICIAL /////////////////////////////////////////////////////
826 /** \D
827 Obtiene el primer hueco de la tabla de huecos (documentos de facturación que han sido borrados y han dejado su código disponible para volver a ser usado)
828 @param codSerie: Código de serie del documento
829 @param codEjercicio: Código de ejercicio del documento
830 @param tipo: Tipo de documento (factura a cliente, a proveedor)
831 @return Número correspondiente al primer hueco encontrado (0 si no se encuentra ninguno)
832 \end */
833 function oficial_obtenerHueco(codSerie:String, codEjercicio:String, tipo:String):Number
835         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
836         var numHueco:Number = 0;
837         cursorHuecos.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "' AND upper(tipo)='" + tipo + "' ORDER BY numero;");
838         if (cursorHuecos.next()) {
839                 numHueco = cursorHuecos.valueBuffer("numero");
840                 cursorHuecos.setActivatedCheckIntegrity(false);
841                 cursorHuecos.setModeAccess(cursorHuecos.Del);
842                 cursorHuecos.refreshBuffer();
843                 cursorHuecos.commitBuffer();
844         }
845         return numHueco;
848 function oficial_establecerNumeroSecuencia(fN:String, value:Number):Number
850         return (parseFloat(value) + 1);
853 /** \D
854 Rellena un string con ceros a la izquierda hasta completar la logitud especificada
855 @param numero: String que contiene el número
856 @param totalCifras: Longitud a completar
857 \end */
858 function oficial_cerosIzquierda(numero:String, totalCifras:Number):String
860         var ret:String = numero.toString();
861         var numCeros:Number = totalCifras - ret.length;
862         for ( ; numCeros > 0 ; --numCeros)
863                 ret = "0" + ret;
864         return ret;
867 function oficial_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String
869         return this.iface.cerosIzquierda(codEjercicio, 4) +
870                 this.iface.cerosIzquierda(codSerie, 2) +
871                 this.iface.cerosIzquierda(numero, 6);
874 /** \D
875 Obtiene el siguiente número de la secuencia de documentos
876 @param codSerie: Código de serie del documento
877 @param codEjercicio: Código de ejercicio del documento
878 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
879 @return Número correspondiente al siguiente documento en la serie o false si hay error
880 \end */
881 function oficial_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number
883         var numero:Number;
884         var util:FLUtil = new FLUtil;
885         var cursorSecuencias:FLSqlCursor = new FLSqlCursor("secuenciasejercicios");
887         cursorSecuencias.setContext(this);
888         cursorSecuencias.setActivatedCheckIntegrity(false);
889         cursorSecuencias.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "';");
890         if (cursorSecuencias.next()) {
891                 if (fN == "nfacturaprov") {
892                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FP");
893                         if (numeroHueco != 0) {
894                                 cursorSecuencias.setActivatedCheckIntegrity(true);
895                                 return numeroHueco;
896                         }
897                 }
898                 if (fN == "nfacturacli") {
899                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FC");
900                         if (numeroHueco != 0) {
901                                 cursorSecuencias.setActivatedCheckIntegrity(true);
902                                 return numeroHueco;
903                         }
904                 }
906                 /** \C
907                 Para minimizar bloqueos las secuencias se han separado en distintos registros de otra tabla
908                 llamada secuencias
909                 \end */
910                 var cursorSecs:FLSqlCursor = new FLSqlCursor( "secuencias" );
911                 cursorSecs.setContext( this );
912                 cursorSecs.setActivatedCheckIntegrity( false );
913                 /** \C
914                 Si el registro no existe lo crea inicializandolo con su antiguo valor del campo correspondiente
915                 en la tabla secuenciasejercicios.
916                 \end */
917                 var idSec:Number = cursorSecuencias.valueBuffer( "id" );
918                 cursorSecs.select( "id=" + idSec + " AND nombre='" + fN + "'" );
919                 if ( !cursorSecs.next() ) {
920                         numero = cursorSecuencias.valueBuffer(fN);
921                         cursorSecs.setModeAccess( cursorSecs.Insert );
922                         cursorSecs.refreshBuffer();
923                         cursorSecs.setValueBuffer( "id", idSec );
924                         cursorSecs.setValueBuffer( "nombre", fN );
925                         cursorSecs.setValueBuffer( "valor", this.iface.establecerNumeroSecuencia( fN, numero ) );
926                         cursorSecs.commitBuffer();
927                 } else {
928                         cursorSecs.setModeAccess( cursorSecs.Edit );
929                         cursorSecs.refreshBuffer();
930                         if ( !cursorSecs.isNull( "valorout" ) )
931                                 numero = cursorSecs.valueBuffer( "valorout" );
932                         else
933                                 numero = cursorSecs.valueBuffer( "valor" );
934                         cursorSecs.setValueBuffer( "valorout", this.iface.establecerNumeroSecuencia( fN, numero ) );            
935                         cursorSecs.commitBuffer();
936                 }
937                 cursorSecs.setActivatedCheckIntegrity( true );
938         } else {
939                 /** \C
940                 Si la serie no existe para el ejercicio actual se consultará al usuario si la quiere crear
941                 \end */
942                 var res:Number = MessageBox.warning(util.translate("scripts", "La serie ") + codSerie + util.translate("scripts"," no existe para el ejercicio ") + codEjercicio + util.translate("scripts",".\n¿Desea crearla?"), MessageBox.Yes,MessageBox.No);
943                 if (res != MessageBox.Yes) {
944                         cursorSecuencias.setActivatedCheckIntegrity(true);
945                         return false;
946                 }
947                 cursorSecuencias.setModeAccess(cursorSecuencias.Insert);
948                 cursorSecuencias.refreshBuffer();
949                 cursorSecuencias.setValueBuffer("codserie", codSerie);
950                 cursorSecuencias.setValueBuffer("codejercicio", codEjercicio);
951                 numero = "1";
952                 cursorSecuencias.setValueBuffer(fN, "2");
953                 if (!cursorSecuencias.commitBuffer()) {
954                         cursorSecuencias.setActivatedCheckIntegrity(true);
955                         return false;
956                 }
957         }
958         cursorSecuencias.setActivatedCheckIntegrity(true);
959         return numero;
962 /** \D
963 Agrega un hueco a la tabla de huecos
964 @param serie: Código de serie del documento
965 @param ejercicio: Código de ejercicio del documento
966 @param numero: Número del documento
967 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
968 @return true si el hueco se inserta correctamente o false si hay error
969 \end */
970 function oficial_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean
972         return this.iface.recalcularHuecos( serie, ejercicio, fN );
975 /* \D Indica si el asiento asociado a la factura puede o no regenerarse, según pertenezca a un ejercicio abierto o cerrado
976 @param idAsiento: Identificador del asiento
977 @return True: Asiento borrable, False: Asiento no borrable
978 \end */
979 function oficial_asientoBorrable(idAsiento:Number):Boolean
981         var util:FLUtil = new FLUtil();
982         var qryEjerAsiento:FLSqlQuery = new FLSqlQuery();
983         qryEjerAsiento.setTablesList("ejercicios,co_asientos");
984         qryEjerAsiento.setSelect("e.estado");
985         qryEjerAsiento.setFrom("co_asientos a INNER JOIN ejercicios e" +
986                         " ON a.codejercicio = e.codejercicio");
987         qryEjerAsiento.setWhere("a.idasiento = " + idAsiento);
988         try { qryEjerAsiento.setForwardOnly( true ); } catch (e) {}
990         if (!qryEjerAsiento.exec())
991                 return false;
993         if (!qryEjerAsiento.next())
994                 return false;
996         if (qryEjerAsiento.value(0) != "ABIERTO") {
997                 MessageBox.critical(util.translate("scripts",
998                 "No puede realizarse la modificación porque el asiento contable correspondiente pertenece a un ejercicio cerrado"),
999                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1000                 return false;
1001         }
1003         return true;
1006 /** \U Genera o regenera el asiento correspondiente a una factura de cliente
1007 @param  curFactura: Cursor con los datos de la factura
1008 @return VERDADERO si no hay error. FALSO en otro caso
1009 \end */
1010 function oficial_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean
1012         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
1013                 return true;
1015         var util:FLUtil = new FLUtil;
1016         if (curFactura.valueBuffer("nogenerarasiento")) {
1017                 curFactura.setNull("idasiento");
1018                 return true;
1019         }
1021         if (!this.iface.comprobarRegularizacion(curFactura))
1022                 return false;
1024         var datosAsiento:Array = [];
1025         var valoresDefecto:Array;
1026         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
1027         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
1029         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
1030         if (datosAsiento.error == true)
1031                 return false;
1033         var ctaCliente = this.iface.datosCtaCliente(curFactura, valoresDefecto);
1034         if (ctaCliente.error != 0)
1035                 return false;
1037         if (!this.iface.generarPartidasCliente(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
1038                 return false;
1040         if (!this.iface.generarPartidasIRPF(curFactura, datosAsiento.idasiento, valoresDefecto))
1041                 return false;
1043         if (!this.iface.generarPartidasIVACli(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
1044                 return false;
1046         if (!this.iface.generarPartidasRecFinCli(curFactura, datosAsiento.idasiento, valoresDefecto))
1047                 return false;                           
1048                         
1049         if (!this.iface.generarPartidasVenta(curFactura, datosAsiento.idasiento, valoresDefecto))
1050                 return false;
1051     
1052         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1053         
1054         if (curFactura.valueBuffer("deabono") == true)
1055                 if (!this.iface.asientoFacturaAbonoCli(curFactura, valoresDefecto))
1056                         return false;
1058         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1059                 return false;
1061         return true;
1064 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de ventas
1065 @param  curFactura: Cursor de la factura
1066 @param  idAsiento: Id del asiento asociado
1067 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1068 @return VERDADERO si no hay error, FALSO en otro caso
1069 \end */
1070 function oficial_generarPartidasVenta(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1072                 var util:FLUtil = new FLUtil();
1073                 var ctaVentas:Array = this.iface.datosCtaVentas(valoresDefecto.codejercicio, curFactura.valueBuffer("codserie"));
1074                 if (ctaVentas.error != 0) {
1075                         MessageBox.warning(util.translate("scripts", "No se ha encontrado una subcuenta de ventas para esta factura."), MessageBox.Ok, MessageBox.NoButton);
1076                         return false;
1077                 }
1078                 var haber:Number = 0;
1079                 var haberME:Number = 0;
1080                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1081                 if (monedaSistema) {
1082                                 haber = this.iface.netoVentasFacturaCli(curFactura);
1083                                 haberME = 0;
1084                 } else {
1085                                 haber = parseFloat(util.sqlSelect("co_partidas", "SUM(debe - haber)", "idasiento = " + idAsiento));
1086                                 haberME = parseFloat(curFactura.valueBuffer("neto"));
1087                 }
1088                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1089                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1091                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1092                 with (curPartida) {
1093                                 setModeAccess(curPartida.Insert);
1094                                 refreshBuffer();
1095                                 setValueBuffer("idsubcuenta", ctaVentas.idsubcuenta);
1096                                 setValueBuffer("codsubcuenta", ctaVentas.codsubcuenta);
1097                                 setValueBuffer("idasiento", idAsiento);
1098                                 setValueBuffer("debe", 0);
1099                                 setValueBuffer("haber", haber);
1100                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1101                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1102                                 setValueBuffer("debeME", 0);
1103                                 setValueBuffer("haberME", haberME);
1104                 }
1105                 
1106                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1107                 
1108                 if (!curPartida.commitBuffer())
1109                                 return false;
1110                 return true;
1113 function oficial_netoVentasFacturaCli(curFactura:FLSqlCursor):Number
1115         return parseFloat(curFactura.valueBuffer("neto"));
1118 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IVA y de recargo de equivalencia, si la factura lo tiene
1119 @param  curFactura: Cursor de la factura
1120 @param  idAsiento: Id del asiento asociado
1121 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1122 @param  ctaCliente: Array con los datos de la contrapartida
1123 @return VERDADERO si no hay error, FALSO en otro caso
1124 \end */
1125 function oficial_generarPartidasIVACli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1127         var util:FLUtil = new FLUtil();
1128         var haber:Number = 0;
1129         var haberME:Number = 0;
1130         var baseImponible:Number = 0;
1131         
1132         var regimenIVA:String = util.sqlSelect("clientes","regimeniva","codcliente = '" + curFactura.valueBuffer("codcliente") + "'");
1133         
1134         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1135         var qryIva:FLSqlQuery = new FLSqlQuery();
1136         qryIva.setTablesList("lineasivafactcli");
1137         qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");
1138         qryIva.setFrom("lineasivafactcli");
1139         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1140         try { qryIva.setForwardOnly( true ); } catch (e) {}
1141         if (!qryIva.exec())
1142                 return false;
1144         while (qryIva.next()) {
1145                 if (monedaSistema) {
1146                         haber = parseFloat(qryIva.value(2));
1147                         haberME = 0;
1148                         baseImponible = parseFloat(qryIva.value(0));
1149                 } else {
1150                         haber = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1151                         haberME = parseFloat(qryIva.value(2));
1152                         baseImponible = parseFloat(qryIva.value(0))  * parseFloat(curFactura.valueBuffer("tasaconv"));
1153                 }
1154                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1155                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1156                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1158                 var ctaIvaRep:Array;
1159                 if (regimenIVA == "U.E.") {
1160                         ctaIvaRep = this.iface.datosCtaIVA("IVAEUE", valoresDefecto.codejercicio,qryIva.value(5));
1161                 } else {
1162                         ctaIvaRep = this.iface.datosCtaIVA("IVAREP", valoresDefecto.codejercicio, qryIva.value(5));
1163                 }
1164                 if (ctaIvaRep.error != 0) {
1165                         MessageBox.information(util.translate("scripts", "La cuenta especial no tiene asignada subcuenta.\nDebe asociarla en el módulo Principal del área Financiera"), MessageBox.Ok, MessageBox.NoButton);
1166                         return false;
1167                 }
1168                 
1169                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1170                 with (curPartida) {
1171                         setModeAccess(curPartida.Insert);
1172                         refreshBuffer();
1173                         setValueBuffer("idsubcuenta", ctaIvaRep.idsubcuenta);
1174                         setValueBuffer("codsubcuenta", ctaIvaRep.codsubcuenta);
1175                         setValueBuffer("idasiento", idAsiento);
1176                         setValueBuffer("debe", 0);
1177                         setValueBuffer("haber", haber);
1178                         setValueBuffer("baseimponible", baseImponible);
1179                         setValueBuffer("iva", qryIva.value(1));
1180                         setValueBuffer("recargo", qryIva.value(3));
1181                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1182                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1183                         setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1184                         setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1185                         setValueBuffer("debeME", 0);
1186                         setValueBuffer("haberME", haberME);
1187                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1188                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1189                 }
1190                 
1191                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1192                 
1193                 if (!curPartida.commitBuffer())
1194                         return false;
1196                 if (monedaSistema) {
1197                         haber = parseFloat(qryIva.value(4));
1198                         haberME = 0;
1199                 } else {
1200                         haber = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1201                         haberME = parseFloat(qryIva.value(4));
1202                 }
1203                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1204                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1206                 if (parseFloat(haber) != 0) {
1207                         var ctaRecargo = this.iface.datosCtaIVA("IVAACR", valoresDefecto.codejercicio, qryIva.value(5));
1208                         if (ctaRecargo.error != 0)
1209                                 return false;
1210                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1211                         with (curPartida) {
1212                                 setModeAccess(curPartida.Insert);
1213                                 refreshBuffer();
1214                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1215                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1216                                 setValueBuffer("idasiento", idAsiento);
1217                                 setValueBuffer("debe", 0);
1218                                 setValueBuffer("haber", haber);
1219                                 setValueBuffer("baseimponible", baseImponible);
1220                                 setValueBuffer("iva", qryIva.value(1));
1221                                 setValueBuffer("recargo", qryIva.value(3));
1222                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1223                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1224                                 setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1225                                 setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1226                                 setValueBuffer("debeME", 0);
1227                                 setValueBuffer("haberME", haberME);
1228                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1229                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1230                         }
1231                         
1232                         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1233                         
1234                         if (!curPartida.commitBuffer())
1235                                 return false;
1236                 }
1237         }
1238         return true;
1241 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF, si la factura lo tiene
1242 @param  curFactura: Cursor de la factura
1243 @param  idAsiento: Id del asiento asociado
1244 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1245 @return VERDADERO si no hay error, FALSO en otro caso
1246 \end */
1247 function oficial_generarPartidasIRPF(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1249                 var util:FLUtil = new FLUtil();
1250                 var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1251                 if (irpf == 0)
1252                                 return true;
1253                 var debe:Number = 0;
1254                 var debeME:Number = 0;
1255                 var ctaIrpf:Array = this.iface.datosCtaEspecial("IRPF", valoresDefecto.codejercicio);
1256                 if (ctaIrpf.error != 0) {
1257                         MessageBox.warning(util.translate("scripts", "No tiene ninguna cuenta contable marcada como cuenta especial\nIRPF (IRPF para clientes).\nDebe asociar la cuenta a la cuenta especial en el módulo Principal del área Financiera"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1258                         return false;
1259                 }
1261                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1262                 if (monedaSistema) {
1263                                 debe = irpf;
1264                                 debeME = 0;
1265                 } else {
1266                                 debe = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1267                                 debeME = irpf;
1268                 }
1269                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1270                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1272                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1273                 with (curPartida) {
1274                                 setModeAccess(curPartida.Insert);
1275                                 refreshBuffer();
1276                                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1277                                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1278                                 setValueBuffer("idasiento", idAsiento);
1279                                 setValueBuffer("debe", debe);
1280                                 setValueBuffer("haber", 0);
1281                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1282                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1283                                 setValueBuffer("debeME", debeME);
1284                                 setValueBuffer("haberME", 0);
1285                 }
1286                 
1287                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1288                 
1289                 if (!curPartida.commitBuffer())
1290                                 return false;
1292                 return true;
1295 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para clientes, si la factura lo tiene
1296 @param  curFactura: Cursor de la factura
1297 @param  idAsiento: Id del asiento asociado
1298 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1299 @return VERDADERO si no hay error, FALSO en otro caso
1300 \end */
1301 function oficial_generarPartidasRecFinCli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1303         var util:FLUtil = new FLUtil();
1304         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
1305         if (!recFinanciero)
1306                 return true;
1307         var haber:Number = 0;
1308         var haberME:Number = 0;
1310         var ctaRecfin:Array = [];
1311         ctaRecfin = this.iface.datosCtaEspecial("INGRF", valoresDefecto.codejercicio);
1312         if (ctaRecfin.error != 0) {
1313                 MessageBox.warning(util.translate("scripts", "No tiene ninguna cuenta contable marcada como cuenta especial\nINGRF (recargo financiero en ingresos) \nDebe asociar una cuenta contable a esta cuenta especial en el módulo Principal del área Financiera"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1314                 return false;
1315         }
1317         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1318         if (monedaSistema) {
1319                 haber = recFinanciero;
1320                 haberME = 0;
1321         } else {
1322                 haber = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
1323                 haberME = recFinanciero;
1324         }
1325         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1326         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1328         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1329         with (curPartida) {
1330                 setModeAccess(curPartida.Insert);
1331                 refreshBuffer();
1332                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
1333                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
1334                 setValueBuffer("idasiento", idAsiento);
1335                 setValueBuffer("haber", haber);
1336                 setValueBuffer("debe", 0);
1337                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1338                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1339                 setValueBuffer("haberME", haberME);
1340                 setValueBuffer("debeME", 0);
1341         }
1342         
1343         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1344         
1345         if (!curPartida.commitBuffer())
1346                         return false;
1348         return true;
1351 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF para proveedores, si la factura lo tiene
1352 @param  curFactura: Cursor de la factura
1353 @param  idAsiento: Id del asiento asociado
1354 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1355 @return VERDADERO si no hay error, FALSO en otro caso
1356 \end */
1357 function oficial_generarPartidasIRPFProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1359         var util:FLUtil = new FLUtil();
1360         var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1361         if (irpf == 0)
1362                         return true;
1363         var haber:Number = 0;
1364         var haberME:Number = 0;
1366         var ctaIrpf:Array = [];
1367         ctaIrpf.codsubcuenta = util.sqlSelect("lineasfacturasprov lf INNER JOIN articulos a ON lf.referencia = a.referencia", "a.codsubcuentairpfcom", "lf.idfactura = " + curFactura.valueBuffer("idfactura") + " AND a.codsubcuentairpfcom IS NOT NULL", "lineasfacturasprov,articulos");
1368         if (ctaIrpf.codsubcuenta) {
1369                 var hayDistintasSubcuentas:String = util.sqlSelect("lineasfacturasprov lf INNER JOIN articulos a ON lf.referencia = a.referencia", "a.referencia", "lf.idfactura = " + curFactura.valueBuffer("idfactura") + " AND (a.codsubcuentairpfcom <> '" + ctaIrpf.codsubcuenta + "' OR a.codsubcuentairpfcom  IS NULL)", "lineasfacturasprov,articulos");
1370                 if (hayDistintasSubcuentas) {
1371                         MessageBox.warning(util.translate("scripts", "No es posible generar el asiento contable de una factura que tiene artículos asignados a distintas subcuentas de IRPF.\nDebe corregir la asociación de las subcuentas de IRPF a los artículos o bien crear distintas facturas para cada subcuenta."), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1372                         return false;
1373                 }
1374                 ctaIrpf.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta", "codsubcuenta = '" + ctaIrpf.codsubcuenta + "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1375                 if (!ctaIrpf.idsubcuenta) {
1376                         MessageBox.warning(util.translate("scripts", "No existe la subcuenta de IRPF %1 para el ejercicio %2.\nAntes de generar el asiento debe crear esta subcuenta.").arg(ctaIrpf.codsubcuenta).arg(valoresDefecto.codejercicio), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1377                         return false;
1378                 }
1379         } else {
1380                 ctaIrpf = this.iface.datosCtaEspecial("IRPFPR", valoresDefecto.codejercicio);
1381                 if (ctaIrpf.error != 0) {
1382                         MessageBox.warning(util.translate("scripts", "No tiene ninguna cuenta contable marcada como cuenta especial\nIRPFPR (IRPF para proveedores / acreedores).\nDebe asociar la cuenta a la cuenta especial en el módulo Principal del área Financiera"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1383                         return false;
1384                 }
1385         }
1387         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1388         if (monedaSistema) {
1389                 haber = irpf;
1390                 haberME = 0;
1391         } else {
1392                 haber = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1393                 haberME = irpf;
1394         }
1395         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1396         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1398         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1399         with (curPartida) {
1400                 setModeAccess(curPartida.Insert);
1401                 refreshBuffer();
1402                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1403                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1404                 setValueBuffer("idasiento", idAsiento);
1405                 setValueBuffer("debe", 0);
1406                 setValueBuffer("haber", haber);
1407                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1408                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1409                 setValueBuffer("debeME", 0);
1410                 setValueBuffer("haberME", haberME);
1411         }
1412         
1413         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1414         
1415         if (!curPartida.commitBuffer())
1416                         return false;
1418         return true;
1422 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de clientes
1423 @param  curFactura: Cursor de la factura
1424 @param  idAsiento: Id del asiento asociado
1425 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1426 @param  ctaCliente: Datos de la subcuenta del cliente asociado a la factura
1427 @return VERDADERO si no hay error, FALSO en otro caso
1428 \end */
1429 function oficial_generarPartidasCliente(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1431                 var util:FLUtil = new FLUtil();
1432                 var debe:Number = 0;
1433                 var debeME:Number = 0;
1434                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1435                 if (monedaSistema) {
1436                                 debe = parseFloat(curFactura.valueBuffer("total"));
1437                                 debeME = 0;
1438                 } else {
1439                                 debe = parseFloat(curFactura.valueBuffer("total")) * parseFloat(curFactura.valueBuffer("tasaconv"));
1440                                 debeME = parseFloat(curFactura.valueBuffer("total"));
1441                 }
1442                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1443                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1444                 
1445                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1446                 with (curPartida) {
1447                                 setModeAccess(curPartida.Insert);
1448                                 refreshBuffer();
1449                                 setValueBuffer("idsubcuenta", ctaCliente.idsubcuenta);
1450                                 setValueBuffer("codsubcuenta", ctaCliente.codsubcuenta);
1451                                 setValueBuffer("idasiento", idAsiento);
1452                                 setValueBuffer("debe", debe);
1453                                 setValueBuffer("haber", 0);
1454                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1455                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1456                                 setValueBuffer("debeME", debeME);
1457                                 setValueBuffer("haberME", 0);
1458                 }
1459                 
1460                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1461                 
1462                 if (!curPartida.commitBuffer())
1463                                 return false;
1465                 return true;
1468 /** \D Genera o regenera el registro en la tabla de asientos correspondiente a la factura. Si el asiento ya estaba creado borra sus partidas asociadas.
1469 @param  curFactura: Cursor posicionado en el registro de factura
1470 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1471 @return array con los siguientes datos:
1472 asiento.idasiento: Id del asiento
1473 asiento.numero: numero del asiento
1474 asiento.fecha: fecha del asiento
1475 asiento.error: indicador booleano de que ha habido un error en la función
1476 \end */
1477 function oficial_regenerarAsiento(cur:FLSqlCursor, valoresDefecto:Array):Array
1479         var util:FLUtil = new FLUtil;
1480         var asiento:Array = [];
1481         var idAsiento:Number = cur.valueBuffer("idasiento");
1482         if (cur.isNull("idasiento")) {
1484                 var datosAsiento:Array = this.iface.datosConceptoAsiento(cur);
1486                 var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1487                 //var numAsiento:Number = util.sqlSelect("co_asientos", "MAX(numero)",  "codejercicio = '" + valoresDefecto.codejercicio + "'");
1488                 //numAsiento++;
1489                 with (curAsiento) {
1490                         setModeAccess(curAsiento.Insert);
1491                         refreshBuffer();
1492                         setValueBuffer("numero", 0);
1493                         setValueBuffer("fecha", cur.valueBuffer("fecha"));
1494                         setValueBuffer("codejercicio", valoresDefecto.codejercicio);
1495                         setValueBuffer("concepto", datosAsiento.concepto);
1496                         setValueBuffer("tipodocumento", datosAsiento.tipoDocumento);
1497                         setValueBuffer("documento", datosAsiento.documento);
1498                 }
1500                 if (!curAsiento.commitBuffer()) {
1501                         asiento.error = true;
1502                         return asiento;
1503                 }
1504                 asiento.idasiento = curAsiento.valueBuffer("idasiento");
1505                 asiento.numero = curAsiento.valueBuffer("numero");
1506                 asiento.fecha = curAsiento.valueBuffer("fecha");
1507                 curAsiento.select("idasiento = " + asiento.idasiento);
1508                 curAsiento.first();
1509                 curAsiento.setUnLock("editable", false);
1510         } else {
1511                 if (!this.iface.asientoBorrable(idAsiento)) {
1512                         asiento.error = true;
1513                         return asiento;
1514                 }
1516                 if (cur.valueBuffer("fecha") != cur.valueBufferCopy("fecha")) {
1517                         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1518                         curAsiento.select("idasiento = " + idAsiento);
1519                         if (!curAsiento.first()) {
1520                                 asiento.error = true;
1521                                 return asiento;
1522                         }
1523                         curAsiento.setUnLock("editable", true);
1525                         curAsiento.select("idasiento = " + idAsiento);
1526                         if (!curAsiento.first()) {
1527                                 asiento.error = true;
1528                                 return asiento;
1529                         }
1530                         curAsiento.setModeAccess(curAsiento.Edit);
1531                         curAsiento.refreshBuffer();
1532                         curAsiento.setValueBuffer("fecha", cur.valueBuffer("fecha"));
1534                         if (!curAsiento.commitBuffer()) {
1535                                 asiento.error = true;
1536                                 return asiento;
1537                         }
1538                         curAsiento.select("idasiento = " + idAsiento);
1539                         if (!curAsiento.first()) {
1540                                 asiento.error = true;
1541                                 return asiento;
1542                         }
1543                         curAsiento.setUnLock("editable", false);
1544                 }
1546                 asiento = flfactppal.iface.pub_ejecutarQry("co_asientos", "idasiento,numero,fecha,codejercicio", "idasiento = '" + idAsiento + "'");
1547                 if (asiento.codejercicio != valoresDefecto.codejercicio) {
1548                         MessageBox.warning(util.translate("scripts", "Está intentando regenerar un asiento del ejercicio %1 en el ejercicio %2.\nVerifique que su ejercicio actual es correcto. Si lo es y está actualizando un pago, bórrelo y vuélvalo a crear.").arg(asiento.codejercicio).arg(valoresDefecto.codejercicio), MessageBox.Ok, MessageBox.NoButton);
1549                         asiento.error = true;
1550                         return asiento;
1551                 }
1552                 var curPartidas = new FLSqlCursor("co_partidas");
1553                 curPartidas.select("idasiento = " + idAsiento);
1554                 var idP:Number = 0;
1555                 while (curPartidas.next()) {
1556                         curPartidas.setModeAccess(curPartidas.Del);
1557                         curPartidas.refreshBuffer();
1558                         if (!curPartidas.commitBuffer()) {
1559                                 asiento.error = true;
1560                                 return asiento;
1561                         }
1562                 }
1563         }
1565         asiento.error = false;
1566         return asiento;
1569 function oficial_datosConceptoAsiento(cur:FLSqlCursor):Array
1571         var util:FLUtil = new FLUtil;
1572         var datosAsiento:Array = [];
1574         switch (cur.table()) {
1575                 case "facturascli": {
1576                         datosAsiento.concepto = "Nuestra factura " + cur.valueBuffer("codigo") + " - " + cur.valueBuffer("nombrecliente");
1577                         datosAsiento.documento = cur.valueBuffer("codigo");
1578                         datosAsiento.tipoDocumento = "Factura de cliente";
1579                         break;
1580                 }
1581                 case "facturasprov": {
1582                         datosAsiento.concepto = "Su factura " + cur.valueBuffer("codigo") + " - " + cur.valueBuffer("nombre");
1583                         datosAsiento.documento = cur.valueBuffer("codigo");
1584                         datosAsiento.tipoDocumento = "Factura de proveedor";
1585                         break;
1586                 }
1587                 case "pagosdevolcli": {
1588                         var codRecibo:String = util.sqlSelect("reciboscli", "codigo", "idrecibo = " + cur.valueBuffer("idrecibo"));
1589                         var nombreCli:String = util.sqlSelect("reciboscli", "nombrecliente", "idrecibo = " + cur.valueBuffer("idrecibo"));
1590                         
1591                         if (cur.valueBuffer("tipo") == "Pago")
1592                                 datosAsiento.concepto = "Pago recibo " + codRecibo + " - " + nombreCli;
1593                         else
1594                                 datosAsiento.concepto = "Devolución recibo " + codRecibo;
1596                         datosAsiento.tipoDocumento = "Recibo";
1597                         datosAsiento.documento = "";
1598                         break;
1599                 }
1600                 case "pagosdevolrem": {
1601                         if (cur.valueBuffer("tipo") == "Pago")
1602                                 datosAsiento.concepto = cur.valueBuffer("tipo") + " " + "remesa" + " " + cur.valueBuffer("idremesa");
1603                                 datosAsiento.tipoDocumento = "";
1604                                 datosAsiento.documento = "";
1605                         break;
1606                 }
1607                 case "co_dotaciones": {
1608                         datosAsiento.concepto = "Dotación de " + util.sqlSelect("co_amortizaciones","elemento","codamortizacion = '" + cur.valueBuffer("codamortizacion") + "'") + " - " + util.dateAMDtoDMA(cur.valueBuffer("fecha"));
1609                         datosAsiento.documento = "";
1610                         datosAsiento.tipoDocumento = "";
1611                         break;
1612                 }
1613         }
1614         return datosAsiento;
1617 function oficial_eliminarAsiento(idAsiento:String):Boolean
1619         var util:FLUtil = new FLUtil;
1620         if (!idAsiento || idAsiento == "")
1621                 return true;
1623         if (!this.iface.asientoBorrable(idAsiento))
1624                 return false;
1626         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1627         curAsiento.select("idasiento = " + idAsiento);
1628         if (!curAsiento.first())
1629                 return false;
1631         curAsiento.setUnLock("editable", true);
1632         if (!util.sqlDelete("co_asientos", "idasiento = " + idAsiento)) {
1633                 curAsiento.setValueBuffer("idasiento", idAsiento);
1634                 return false;
1635         }
1636         return true;
1639 /** \U Genera o regenera el asiento correspondiente a una factura de proveedor
1640 @param  curFactura: Cursor con los datos de la factura
1641 @return VERDADERO si no hay error. FALSO en otro caso
1642 \end */
1643 /** \C El concepto de los asientos de factura de proveedor será 'Su factura ' + número de proveedor asociado a la factura. Si el número de proveedor no se especifica, el concepto será 'Su factura ' + código de factura.
1644 \end */
1645 function oficial_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean
1647         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
1648                 return true;
1650         var util:FLUtil = new FLUtil;
1651         if (curFactura.valueBuffer("nogenerarasiento")) {
1652                 curFactura.setNull("idasiento");
1653                 return true;
1654         }
1656         if (!this.iface.comprobarRegularizacion(curFactura))
1657                 return false;
1659         var util:FLUtil = new FLUtil();
1660         var datosAsiento:Array = [];
1661         var valoresDefecto:Array;
1662         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
1663         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
1665         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
1666         if (datosAsiento.error == true)
1667                 return false;
1669         var numProveedor:String = curFactura.valueBuffer("numproveedor");
1670         var concepto:String;
1671         if (!numProveedor || numProveedor == "")
1672                 concepto = util.translate("scripts", "Su factura ") + curFactura.valueBuffer("codigo");
1673         else
1674                 concepto = util.translate("scripts", "Su factura ") + numProveedor;
1675         concepto += " - " + curFactura.valueBuffer("nombre");
1677         var ctaProveedor:Array = this.iface.datosCtaProveedor(curFactura, valoresDefecto);
1678         if (ctaProveedor.error != 0)
1679                 return false;
1681         // Las partidas generadas dependen del régimen de IVA del proveedor
1682         var regimenIVA:String = util.sqlSelect("proveedores", "regimeniva", "codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1683         
1684         switch(regimenIVA) {
1685                 case "UE":
1686                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1687                                 return false;
1688                                 
1689                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1690                                 return false;
1691                 
1692                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1693                                 return false;                           
1694                         
1695                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1696                                 return false;
1697                 
1698                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1699                                 return false;
1700                 break;
1701                 
1702                 case "Exento":
1703                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1704                                 return false;
1705                                 
1706                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1707                                 return false;                           
1708                         
1709                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1710                                 return false;
1711                 
1712                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1713                                 return false;
1714                 break;
1715                 
1716                 default:
1717                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1718                                 return false;
1719                                 
1720                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1721                                 return false;
1722                 
1723                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1724                                 return false;                           
1725                         
1726                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1727                                 return false;
1728                 
1729                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1730                                 return false;
1731         }
1732                 
1733         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1734                 
1735         if (curFactura.valueBuffer("deabono") == true)
1736                 if (!this.iface.asientoFacturaAbonoProv(curFactura, valoresDefecto))
1737                         return false;
1739         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1740                 return false;
1742         return true;
1745 /** \D Genera la parte del asiento de factura de proveedor correspondiente a la subcuenta de compras
1746 @param  curFactura: Cursor de la factura
1747 @param  idAsiento: Id del asiento asociado
1748 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1749 @param  concepto: Concepto de la partida
1750 @return VERDADERO si no hay error, FALSO en otro caso
1751 \end */
1752 function oficial_generarPartidasCompra(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, concepto:String):Boolean
1754                 var ctaCompras:Array = [];
1755                 var util:FLUtil = new FLUtil();
1756                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1757                 var debe:Number = 0;
1758                 var debeME:Number = 0;
1759                 var idUltimaPartida:Number = 0;
1761                 /** \C En el asiento correspondiente a las facturas de proveedor, se generarán tantas partidas de compra como subcuentas distintas existan en las líneas de factura
1762                 \end */
1763                 var qrySubcuentas:FLSqlQuery = new FLSqlQuery();
1764                 with (qrySubcuentas) {
1765                                 setTablesList("lineasfacturasprov");
1766                                 setSelect("codsubcuenta, SUM(pvptotal)");
1767                                 setFrom("lineasfacturasprov");
1768                                 setWhere("idfactura = " + curFactura.valueBuffer("idfactura") +
1769                                                 " GROUP BY codsubcuenta");
1770                 }
1771                 try { qrySubcuentas.setForwardOnly( true ); } catch (e) {}
1772                 
1773                 if (!qrySubcuentas.exec())
1774                                 return false;
1775                 while (qrySubcuentas.next()) {
1776                                 if (qrySubcuentas.value(0) == "" || !qrySubcuentas.value(0)) {
1777                                                 ctaCompras = this.iface.datosCtaEspecial("COMPRA", valoresDefecto.codejercicio);
1778                                                 if (ctaCompras.error != 0)
1779                                                                 return false;
1780                                 } else {
1781                                                 ctaCompras.codsubcuenta = qrySubcuentas.value(0);
1782                                                 ctaCompras.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta",
1783                                                                 "codsubcuenta = '" + qrySubcuentas.value(0) +
1784                                                                 "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1785                                                 if (!ctaCompras.idsubcuenta) {
1786                                                                 MessageBox.warning(util.translate("scripts", "No existe la subcuenta ")  + ctaCompras.codsubcuenta +
1787                                                                                 util.translate("scripts", " correspondiente al ejercicio ") + valoresDefecto.codejercicio +
1788                                                                                 util.translate("scripts", ".\nPara poder crear la factura debe crear antes esta subcuenta"),
1789                                                                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1790                                                                 return false;
1791                                                 }
1792                                 }
1794                                 if (monedaSistema) {
1795                                                 debe = parseFloat(qrySubcuentas.value(1));
1796                                                 debeME = 0;
1797                                 } else {
1798                                                 debe = parseFloat(qrySubcuentas.value(1)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1799                                                 debeME = parseFloat(qrySubcuentas.value(1));
1800                                 }
1801                                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1802                                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1803                                 
1804                                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1805                                 with (curPartida) {
1806                                                 setModeAccess(curPartida.Insert);
1807                                                 refreshBuffer();
1808                                                 setValueBuffer("idsubcuenta", ctaCompras.idsubcuenta);
1809                                                 setValueBuffer("codsubcuenta", ctaCompras.codsubcuenta);
1810                                                 setValueBuffer("idasiento", idAsiento);
1811                                                 setValueBuffer("debe", debe);
1812                                                 setValueBuffer("haber", 0);
1813                                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1814                                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1815                                                 setValueBuffer("debeME", debeME);
1816                                                 setValueBuffer("haberME", 0);
1817                                 }
1818                                 
1819                                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
1820                                 
1821                                 if (!curPartida.commitBuffer())
1822                                                 return false;
1823                                 idUltimaPartida = curPartida.valueBuffer("idpartida");
1824                 }
1826                 /** \C En los asientos de factura de proveedor, y en el caso de que se use moneda extranjera, la última partida de compras tiene un saldo tal que haga que el asiento cuadre perfectamente. Esto evita errores de redondeo de conversión de moneda entre las partidas del asiento.
1827                 \end */
1828                 if (!monedaSistema) {
1829                         debe = parseFloat(util.sqlSelect("co_partidas", "SUM(haber - debe)", "idasiento = " + idAsiento + " AND idpartida <> " + idUltimaPartida));
1830                         if (debe && !isNaN(debe) && debe != 0) {
1831                                 debe = parseFloat(util.roundFieldValue(debe, "co_partidas", "debe"));
1832                                 if (!util.sqlUpdate("co_partidas", "debe", debe, "idpartida = " + idUltimaPartida))
1833                                                 return false;
1834                         }
1835                 }
1837                 return true;
1840 /** \D Genera la parte del asiento de factura de proveedor correspondiente a la subcuenta de IVA y de recargo de equivalencia, si la factura lo tiene
1841 @param  curFactura: Cursor de la factura
1842 @param  idAsiento: Id del asiento asociado
1843 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1844 @param  ctaProveedor: Array con los datos de la contrapartida
1845 @param  concepto: Concepto de la partida
1846 @return VERDADERO si no hay error, FALSO en otro caso
1847 \end */
1848 function oficial_generarPartidasIVAProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String):Boolean
1850         var util:FLUtil = new FLUtil();
1851         var haber:Number = 0;
1852         var haberME:Number = 0;
1853         var baseImponible:Number = 0;
1854         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1855         
1856         var regimenIVA:String = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1857         var codCuentaEspIVA:String;
1858         
1859         var qryIva:FLSqlQuery = new FLSqlQuery();
1860         qryIva.setTablesList("lineasivafactprov");
1861         
1862         if (regimenIVA == "UE")
1863                 qryIva.setSelect("neto, iva, neto*iva/100, recargo, neto*recargo/100, codimpuesto");
1864         else
1865                 qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");    
1866         
1867         qryIva.setFrom("lineasivafactprov");
1868         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1869         try { qryIva.setForwardOnly( true ); } catch (e) {}
1870         if (!qryIva.exec())
1871                 return false;
1873                 
1874         while (qryIva.next()) {
1875                 if (monedaSistema) {
1876                         debe = parseFloat(qryIva.value(2));
1877                         debeME = 0;
1878                         baseImponible = parseFloat(qryIva.value(0));
1879                 } else {
1880                         debe = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1881                         debeME = parseFloat(qryIva.value(2));
1882                         baseImponible = parseFloat(qryIva.value(0)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1883                 }
1884                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1885                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1886                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1887                 
1888                 switch(regimenIVA) {
1889                         case "UE":
1890                                 codCuentaEspIVA = "IVASUE";
1891                                 break;
1892                         case "General":
1893                         case "Exento":
1894                         case "Exportaciones":
1895                                 codCuentaEspIVA = "IVASOP";
1896                                 break;
1897                         default:
1898                                 codCuentaEspIVA = "IVASOP";
1899                 }
1900                 
1901                 var ctaIvaSop:Array = this.iface.datosCtaIVA(codCuentaEspIVA, valoresDefecto.codejercicio, qryIva.value(5));
1902                 if (ctaIvaSop.error != 0) {
1903                         MessageBox.warning(util.translate("scripts", "Esta factura pertenece al régimen IVA tipo %1.\nNo existe ninguna cuenta contable marcada como tipo especial %2\n\nDebe asociar una cuenta contable a dicho tipo especial en el módulo Principal del área Financiera").arg(regimenIVA).arg(codCuentaEspIVA), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1904                         return false;
1905                 }
1906                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1907                 with (curPartida) {
1908                         setModeAccess(curPartida.Insert);
1909                         refreshBuffer();
1910                         setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1911                         setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1912                         setValueBuffer("idasiento", idAsiento);
1913                         setValueBuffer("debe", debe);
1914                         setValueBuffer("haber", 0);
1915                         setValueBuffer("baseimponible", baseImponible);
1916                         setValueBuffer("iva", qryIva.value(1));
1917                         setValueBuffer("recargo", qryIva.value(3));
1918                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1919                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1920                         setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1921                         setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1922                         setValueBuffer("debeME", debeME);
1923                         setValueBuffer("haberME", 0);
1924                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1925                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1926                 }
1927                 
1928                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1929                 
1930                 if (!curPartida.commitBuffer())
1931                         return false;
1933                 
1934                 // Otra partida de haber de IVA sobre una cuenta 477 para compensar en UE
1935                 if (regimenIVA == "UE") {
1936                         
1937                         haber = debe;
1938                         haberME = debeME;
1939                         codCuentaEspIVA = "IVARUE";
1940                         var ctaIvaSop = this.iface.datosCtaIVA("IVARUE", valoresDefecto.codejercicio,qryIva.value(5));
1941 //                      var ctaIvaSop:Array = this.iface.datosCtaEspecial("IVARUE", valoresDefecto.codejercicio);
1942                         if (ctaIvaSop.error != 0) {
1943                                 return false;
1944                         }
1945                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1946                         with (curPartida) {
1947                                 setModeAccess(curPartida.Insert);
1948                                 refreshBuffer();
1949                                 setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1950                                 setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1951                                 setValueBuffer("idasiento", idAsiento);
1952                                 setValueBuffer("debe", 0);
1953                                 setValueBuffer("haber", haber);
1954                                 setValueBuffer("baseimponible", baseImponible);
1955                                 setValueBuffer("iva", qryIva.value(1));
1956                                 setValueBuffer("recargo", qryIva.value(3));
1957                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1958                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1959                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1960                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1961                                 setValueBuffer("debeME", 0);
1962                                 setValueBuffer("haberME", haberME);
1963                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1964                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1965                         }
1966                 
1967                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
1968                         
1969                         if (!curPartida.commitBuffer())
1970                                 return false;
1971                 }
1972                         
1973                 if (monedaSistema) {
1974                         debe = parseFloat(qryIva.value(4));
1975                         debeME = 0;
1976                 } else {
1977                         debe = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1978                         debeME = parseFloat(qryIva.value(4));
1979                 }
1980                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1981                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1983                 if (parseFloat(debe) != 0) {
1984                         var ctaRecargo:Array = this.iface.datosCtaIVA("IVADEU", valoresDefecto.codejercicio, qryIva.value(5));
1985                         if (ctaRecargo.error != 0)
1986                                 return false;
1987                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1988                         with (curPartida) {
1989                                 setModeAccess(curPartida.Insert);
1990                                 refreshBuffer();
1991                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1992                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1993                                 setValueBuffer("idasiento", idAsiento);
1994                                 setValueBuffer("debe", debe);
1995                                 setValueBuffer("haber", 0);
1996                                 setValueBuffer("baseimponible", baseImponible);
1997                                 setValueBuffer("iva", qryIva.value(1));
1998                                 setValueBuffer("recargo", qryIva.value(3));
1999                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
2000                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
2001                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
2002                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
2003                                 setValueBuffer("debeME", debeME);
2004                                 setValueBuffer("haberME", 0);
2005                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
2006                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
2007                         }
2008                 
2009                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
2010                         
2011                         if (!curPartida.commitBuffer())
2012                                 return false;
2013                 }
2014         }
2015         return true;
2018 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de proveedor
2019 @param  curFactura: Cursor de la factura
2020 @param  idAsiento: Id del asiento asociado
2021 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
2022 @param  ctaCliente: Datos de la subcuenta del proveedor asociado a la factura
2023 @param  concepto: Concepto a asociar a la factura
2024 @return VERDADERO si no hay error, FALSO en otro caso
2025 \end */
2026 function oficial_generarPartidasProveedor(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String, sinIVA:Boolean):Boolean
2028                 var util:FLUtil = new FLUtil;
2029                 var haber:Number = 0;
2030                 var haberME:Number = 0;
2031                 var totalIVA:Number = 0;
2032                 
2033                 if (sinIVA)
2034                         totalIVA = parseFloat(curFactura.valueBuffer("totaliva"));
2035                 
2036                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
2037                 if (monedaSistema) {
2038                                 haber = parseFloat(curFactura.valueBuffer("total"));
2039                                 haber -= totalIVA;
2040                                 haberME = 0;
2041                 } else {
2042                                 haber = (parseFloat(curFactura.valueBuffer("total")) - totalIVA) * parseFloat(curFactura.valueBuffer("tasaconv"));
2043                                 haberME = parseFloat(curFactura.valueBuffer("total"));
2044                 }
2045                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2046                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2048                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
2049                 with (curPartida) {
2050                                 setModeAccess(curPartida.Insert);
2051                                 refreshBuffer();
2052                                 setValueBuffer("idsubcuenta", ctaProveedor.idsubcuenta);
2053                                 setValueBuffer("codsubcuenta", ctaProveedor.codsubcuenta);
2054                                 setValueBuffer("idasiento", idAsiento);
2055                                 setValueBuffer("debe", 0);
2056                                 setValueBuffer("haber", haber);
2057                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
2058                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
2059                                 setValueBuffer("debeME", 0);
2060                                 setValueBuffer("haberME", haberME);
2061                 }
2062                 
2063                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
2064                 
2065                 if (!curPartida.commitBuffer())
2066                                 return false;
2067                 return true;
2070 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para proveedores, si la factura lo tiene
2071 @param  curFactura: Cursor de la factura
2072 @param  idAsiento: Id del asiento asociado
2073 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
2074 @return VERDADERO si no hay error, FALSO en otro caso
2075 \end */
2076 function oficial_generarPartidasRecFinProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
2078         var util:FLUtil = new FLUtil();
2079         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
2080         if (!recFinanciero)
2081                 return true;
2082         var debe:Number = 0;
2083         var debeME:Number = 0;
2085         var ctaRecfin:Array = [];
2086         ctaRecfin = this.iface.datosCtaEspecial("GTORF", valoresDefecto.codejercicio);
2087         if (ctaRecfin.error != 0) {
2088                 MessageBox.warning(util.translate("scripts", "No tiene ninguna cuenta contable marcada como cuenta especial\nGTORF (recargo financiero en gastos).\nDebe asociar una cuenta contable a esta cuenta especial en el módulo Principal del área Financiera"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
2089                 return false;
2090         }
2092         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
2093         if (monedaSistema) {
2094                 debe = recFinanciero;
2095                 debeME = 0;
2096         } else {
2097                 debe = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
2098                 debeME = recFinanciero;
2099         }
2100         debe = util.roundFieldValue(debe, "co_partidas", "debe");
2101         debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2103         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
2104         with (curPartida) {
2105                 setModeAccess(curPartida.Insert);
2106                 refreshBuffer();
2107                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
2108                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
2109                 setValueBuffer("idasiento", idAsiento);
2110                 setValueBuffer("debe", debe);
2111                 setValueBuffer("haber", 0);
2112                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
2113                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
2114                 setValueBuffer("debeME", debeME);
2115                 setValueBuffer("haberME", 0);
2116         }
2117                 
2118         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
2119         
2120         if (!curPartida.commitBuffer())
2121                         return false;
2123         return true;
2126 /* \D Devuelve el código e id de la subcuenta especial correspondiente a un determinado ejercicio. Primero trata de obtener los datos a partir del campo cuenta de co_cuentasesp. Si este no existe o no produce resultados, busca los datos de la cuenta (co_cuentas) marcada con el tipo especial buscado.
2127 @param ctaEsp: Tipo de cuenta especial
2128 @codEjercicio: Código de ejercicio
2129 @return Los datos componen un vector de tres valores:
2130 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2131 idsubcuenta: Identificador de la subcuenta
2132 codsubcuenta: Código de la subcuenta
2133 \end */
2134 function oficial_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array
2136         var datos:Array = [];
2137         var q:FLSqlQuery = new FLSqlQuery();
2138         
2139         with(q) {
2140                 setTablesList("co_subcuentas,co_cuentasesp");
2141                 setSelect("s.idsubcuenta, s.codsubcuenta");
2142                 setFrom("co_cuentasesp ce INNER JOIN co_subcuentas s ON ce.codsubcuenta = s.codsubcuenta");
2143                 setWhere("idcuentaesp = '" + ctaEsp + "' AND s.codejercicio = '" + codEjercicio + "'  ORDER BY s.codsubcuenta");
2144         }
2145         try { q.setForwardOnly( true ); } catch (e) {}
2146         if (!q.exec()) {
2147                 datos["error"] = 2;
2148                 return datos;
2149         }
2150         if (q.next()) {
2151                 datos["error"] = 0;
2152                 datos["idsubcuenta"] = q.value(0);
2153                 datos["codsubcuenta"] = q.value(1);
2154                 return datos;
2155         }
2156         
2157         with(q) {
2158                 setTablesList("co_cuentas,co_subcuentas,co_cuentasesp");
2159                 setSelect("s.idsubcuenta, s.codsubcuenta");
2160                 setFrom("co_cuentasesp ce INNER JOIN co_cuentas c ON ce.codcuenta = c.codcuenta INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2161                 setWhere("ce.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2162         }
2163         try { q.setForwardOnly( true ); } catch (e) {}
2164         if (!q.exec()) {
2165                 datos["error"] = 2;
2166                 return datos;
2167         }
2168         if (q.next()) {
2169                 datos["error"] = 0;
2170                 datos["idsubcuenta"] = q.value(0);
2171                 datos["codsubcuenta"] = q.value(1);
2172                 return datos;
2173         }
2175         with(q) {
2176                 setTablesList("co_cuentas,co_subcuentas");
2177                 setSelect("s.idsubcuenta, s.codsubcuenta");
2178                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2179                 setWhere("c.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2180         }
2181         try { q.setForwardOnly( true ); } catch (e) {}
2182         if (!q.exec()) {
2183                 datos["error"] = 2;
2184                 return datos;
2185         }
2186         if (!q.next()) {
2187                 if (this.iface.consultarCtaEspecial(ctaEsp, codEjercicio)) {
2188                         return this.iface.datosCtaEspecial(ctaEsp, codEjercicio);
2189                 } else {
2190                         datos["error"] = 1;
2191                         return datos;
2192                 }
2193         }
2195         datos["error"] = 0;
2196         datos["idsubcuenta"] = q.value(0);
2197         datos["codsubcuenta"] = q.value(1);
2198         return datos;
2201 function oficial_consultarCtaEspecial(ctaEsp:String, codEjercicio:String):Boolean
2203         var util:FLUtil = new FLUtil;
2204         switch (ctaEsp) {
2205                 case "IVASUE": {
2206                         var res:Number = MessageBox.warning(util.translate("scripts", "No tiene establecida la subcuenta de IVA soportado para adquisiciones intracomunitaras (IVASUE).\nEsta subcuenta es necesaria para almacenar información útil para informes como el de facturas emitidas o el modelo 300.\n¿Desea indicar cuál es esta subcuenta ahora?"), MessageBox.Yes, MessageBox.No);
2207                         if (res != MessageBox.Yes)
2208                                 return false;
2209                         return this.iface.crearCtaEspecial("IVASUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA soportado en adquisiciones intracomunitarias U.E."));
2210                         break;
2211                 }
2212                 case "IVARUE": {
2213                         var res:Number = MessageBox.warning(util.translate("scripts", "No tiene establecida la subcuenta de IVA repercutido para adquisiciones intracomunitaras (IVARUE).\nEsta subcuenta es necesaria para almacenar información útil para informes como el de facturas emitidas o el modelo 300.\n¿Desea indicar cuál es esta subcuenta ahora?"), MessageBox.Yes, MessageBox.No);
2214                         if (res != MessageBox.Yes)
2215                                 return false;
2216                         return this.iface.crearCtaEspecial("IVARUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA repercutido en adquisiciones intracomunitarias U.E."));
2217                         break;
2218                 }
2219                 case "IVAEUE": {
2220                         var res:Number = MessageBox.warning(util.translate("scripts", "No tiene establecida la subcuenta de IVA para entregas intracomunitaras (IVAEUE).\nEsta subcuenta es necesaria para almacenar información útil para informes como el de facturas emitidas o el modelo 300.\n¿Desea indicar cuál es esta subcuenta ahora?"), MessageBox.Yes, MessageBox.No);
2221                         if (res != MessageBox.Yes)
2222                                 return false;
2223                         return this.iface.crearCtaEspecial("IVAEUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA en entregas intracomunitarias U.E."));
2224                         break;
2225                 }
2226                 default: {
2227                         return false;
2228                 }
2229         }
2230         return false;
2233 /* \D Devuelve el código e id de la subcuenta correspondiente a un impuesto y ejercicio determinados
2234 @param  ctaEsp: Tipo de cuenta (IVA soportado, repercutido, Recargo de equivalencia)
2236 @param  codEjercicio: Código de ejercicio
2237 @param  codImpuesto: Código de impuesto
2238 @return Los datos componen un vector de tres valores:
2239 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2240 idsubcuenta: Identificador de la subcuenta
2241 codsubcuenta: Código de la subcuenta
2242 \end */
2243 function oficial_datosCtaIVA(tipo:String, codEjercicio:String, codImpuesto:String):Array
2245                 if (!codImpuesto || codImpuesto == "")
2246                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2248                 var util:FLUtil = new FLUtil();
2249                 var datos:Array = [];
2250                 var codSubcuenta:String;
2251                 if (tipo == "IVAREP")
2252                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentarep", "codimpuesto = '" + codImpuesto + "'");
2253                 if (tipo == "IVASOP")
2254                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentasop", "codimpuesto = '" + codImpuesto + "'");
2255                 if (tipo == "IVAACR")
2256                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaacr", "codimpuesto = '" + codImpuesto + "'");
2257                 if (tipo == "IVADEU")
2258                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentadeu", "codimpuesto = '" + codImpuesto + "'");
2259                 if (tipo == "IVARUE")
2260                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadevadue", "codimpuesto = '" + codImpuesto + "'");
2261                 if (tipo == "IVASUE")
2262                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadedadue", "codimpuesto = '" + codImpuesto + "'");
2263                 if (tipo == "IVAEUE")
2264                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadeventue", "codimpuesto = '" + codImpuesto + "'");
2266                 if (!codSubcuenta || codSubcuenta == "") {
2267                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2268                 }
2270                 var q:FLSqlQuery = new FLSqlQuery();
2271                 with(q) {
2272                                 setTablesList("co_subcuentas");
2273                                 setSelect("idsubcuenta, codsubcuenta");
2274                                 setFrom("co_subcuentas");
2275                                 setWhere("codsubcuenta = '" + codSubcuenta + "' AND codejercicio = '" + codEjercicio + "'");
2276                 }
2277                 try { q.setForwardOnly( true ); } catch (e) {}
2278                 if (!q.exec()) {
2279                                 datos["error"] = 2;
2280                                 return datos;
2281                 }
2282                 if (!q.next()) {
2283                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2284                 }
2286                 datos["error"] = 0;
2287                 datos["idsubcuenta"] = q.value(0);
2288                 datos["codsubcuenta"] = q.value(1);
2289                 return datos;
2292 /* \D Devuelve el código e id de la subcuenta de ventas correspondiente a un determinado ejercicio. La cuenta de ventas es la asignada a la serie de facturación. En caso de no estar establecida es la correspondiente a la subcuenta especial marcada como ventas
2293 @param ctaEsp: Tipo de cuenta especial
2294 @param codEjercicio: Código de ejercicio
2295 @param codSerie: Código de serie de la factura
2296 @return Los datos componen un vector de tres valores:
2297 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2298 idsubcuenta: Identificador de la subcuenta
2299 codsubcuenta: Código de la subcuenta
2300 \end */
2301 function oficial_datosCtaVentas(codEjercicio:String, codSerie:String):Array
2303                 var util:FLUtil = new FLUtil();
2304                 var datos:Array = [];
2306                 var codCuenta:String = util.sqlSelect("series", "codcuenta", "codserie = '" + codSerie + "'");
2307                 if (codCuenta.toString().isEmpty())
2308                                 return this.iface.datosCtaEspecial("VENTAS", codEjercicio);
2310                 var q:FLSqlQuery = new FLSqlQuery();
2311                 with(q) {
2312                                 setTablesList("co_cuentas,co_subcuentas");
2313                                 setSelect("idsubcuenta, codsubcuenta");
2314                                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2315                                 setWhere("c.codcuenta = '" + codCuenta + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY codsubcuenta");
2316                 }
2317                 try { q.setForwardOnly( true ); } catch (e) {}
2318                 if (!q.exec()) {
2319                                 datos["error"] = 2;
2320                                 return datos;
2321                 }
2322                 if (!q.next()) {
2323                                 datos["error"] = 1;
2324                                 return datos;
2325                 }
2327                 datos["error"] = 0;
2328                 datos["idsubcuenta"] = q.value(0);
2329                 datos["codsubcuenta"] = q.value(1);
2330                 return datos;
2333 /* \D Devuelve el código e id de la subcuenta de cliente correspondiente a una  determinada factura
2334 @param curFactura: Cursor posicionado en la factura
2335 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2336 @return Los datos componen un vector de tres valores:
2337 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2338 idsubcuenta: Identificador de la subcuenta
2339 codsubcuenta: Código de la subcuenta
2340 \end */
2341 function oficial_datosCtaCliente(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2343         return flfactppal.iface.pub_datosCtaCliente( curFactura.valueBuffer("codcliente"), valoresDefecto );
2346 /* \D Devuelve el código e id de la subcuenta de proveedor correspondiente a una  determinada factura
2347 @param curFactura: Cursor posicionado en la factura
2348 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2349 @return Los datos componen un vector de tres valores:
2350 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2351 idsubcuenta: Identificador de la subcuenta
2352 codsubcuenta: Código de la subcuenta
2353 \end */
2354 function oficial_datosCtaProveedor(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2356         return flfactppal.iface.pub_datosCtaProveedor( curFactura.valueBuffer("codproveedor"), valoresDefecto );
2359 /* \D Regenera el asiento correspondiente a una factura de abono de cliente
2360 @param  curFactura: Cursor con los datos de la factura
2361 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2362 @return VERDADERO si no hay error. FALSO en otro caso
2363 \end */
2364 function oficial_asientoFacturaAbonoCli(curFactura:FLSqlCursor, valoresDefecto:Array)
2366         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2367     var idFactura:String = curFactura.valueBuffer("idfactura");
2368         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2369         var debe:Number = 0;
2370         var haber:Number = 0;
2371         var debeME:Number = 0;
2372         var haberME:Number = 0;
2373         var aux:Number;
2374         var util:FLUtil = new FLUtil;
2375         
2376         curPartidas.select("idasiento = '" + idAsiento + "'");
2377         while (curPartidas.next()) {
2378                 curPartidas.setModeAccess(curPartidas.Edit);
2379                 curPartidas.refreshBuffer();
2380                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2381                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2382                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2383                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2384                 aux = debe;
2385                 debe = haber * -1;
2386                 haber = aux * -1;
2387                 aux = debeME;
2388                 debeME = haberME * -1;
2389                 haberME = aux * -1;
2390                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2391                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2392                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2393                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2395                 curPartidas.setValueBuffer("debe",  debe);
2396                 curPartidas.setValueBuffer("haber", haber);
2397                 curPartidas.setValueBuffer("debeme",  debeME);
2398                 curPartidas.setValueBuffer("haberme", haberME);
2400                 if (!curPartidas.commitBuffer())
2401                         return false;
2402         }
2403         
2404         var ctaDevolVentas = this.iface.datosCtaEspecial("DEVVEN", valoresDefecto.codejercicio);
2405         if (ctaDevolVentas.error == 1) {
2406                 MessageBox.warning(util.translate("scripts", "No tiene definida una subcuenta especial de devoluciones de ventas.\nEl asiento asociado a la factura no puede ser creado"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
2407                 return false;
2408         }
2409         if (ctaDevolVentas.error == 2)
2410                 return false;
2411         
2412         var qryPartidasVenta:FLSqlQuery = new FLSqlQuery();
2413         qryPartidasVenta.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2414         qryPartidasVenta.setSelect("p.idsubcuenta");
2415         qryPartidasVenta.setFrom("co_partidas p INNER JOIN co_subcuentas s ON s.idsubcuenta = p.idsubcuenta INNER JOIN co_cuentas c ON c.idcuenta = s.idcuenta ");
2416         qryPartidasVenta.setWhere("c.idcuentaesp = 'VENTAS' AND idasiento = " + idAsiento);
2417         try { qryPartidasVenta.setForwardOnly( true ); } catch (e) {}
2419         if (!qryPartidasVenta.exec())
2420                 return false;
2422         if (!qryPartidasVenta.next())
2423                 return false;
2424         
2425         
2426         var curPartidasVenta:FLSqlCursor = new FLSqlCursor("co_partidas");
2427         curPartidasVenta.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasVenta.value(0));
2428         curPartidasVenta.first();
2429         curPartidasVenta.setModeAccess(curPartidasVenta.Edit);
2430         curPartidasVenta.refreshBuffer();
2431         curPartidasVenta.setValueBuffer("idsubcuenta",  ctaDevolVentas.idsubcuenta);
2432         curPartidasVenta.setValueBuffer("codsubcuenta",  ctaDevolVentas.codsubcuenta);
2433         if (!curPartidasVenta.commitBuffer())
2434                         return false;
2435         return true;
2439 /* \D Regenera el asiento correspondiente a una factura de abono de proveedor
2440 @param  curFactura: Cursor con los datos de la factura
2441 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2442 @return VERDADERO si no hay error. FALSO en otro caso
2443 \end */
2444 function oficial_asientoFacturaAbonoProv(curFactura:FLSqlCursor, valoresDefecto:Array)
2446         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2447     var idFactura:String = curFactura.valueBuffer("idfactura");
2448         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2449         var debe:Number = 0;
2450         var haber:Number = 0;
2451         var debeME:Number = 0;
2452         var haberME:Number = 0;
2453         var aux:Number;
2454         
2455         var util:FLUtil = new FLUtil;
2456         
2457         curPartidas.select("idasiento = '" + idAsiento + "'");
2458         while (curPartidas.next()) {
2459                 curPartidas.setModeAccess(curPartidas.Edit);
2460                 curPartidas.refreshBuffer();
2461                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2462                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2463                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2464                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2465                 aux = debe;
2466                 debe = haber * -1;
2467                 haber = aux * -1;
2468                 aux = debeME;
2469                 debeME = haberME * -1;
2470                 haberME = aux * -1;
2471                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2472                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2473                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2474                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2476                 curPartidas.setValueBuffer("debe",  debe);
2477                 curPartidas.setValueBuffer("haber", haber);
2478                 curPartidas.setValueBuffer("debeme",  debeME);
2479                 curPartidas.setValueBuffer("haberme", haberME);
2480         }
2481         
2482         var ctaDevolCompra = this.iface.datosCtaEspecial("DEVCOM", valoresDefecto.codejercicio);
2483         if (ctaDevolCompra.error == 1) {
2484                 MessageBox.warning(util.translate("scripts", "No tiene definida una subcuenta especial de devoluciones de compras.\nEl asiento asociado a la factura no puede ser creado"), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
2485                 return false;
2486         }
2487         if (ctaDevolCompra.error == 2)
2488                 return false;
2489         
2490         var qryPartidasCompra:FLSqlQuery = new FLSqlQuery();
2491         qryPartidasCompra.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2492         qryPartidasCompra.setSelect("p.idsubcuenta");
2493         qryPartidasCompra.setFrom("co_partidas p INNER JOIN co_subcuentas s ON s.idsubcuenta = p.idsubcuenta INNER JOIN co_cuentas c ON c.idcuenta = s.idcuenta ");
2494         qryPartidasCompra.setWhere("c.idcuentaesp = 'COMPRA' AND idasiento = " + idAsiento);
2495         try { qryPartidasCompra.setForwardOnly( true ); } catch (e) {}
2497         if (!qryPartidasCompra.exec())
2498                 return false;
2500         if (!qryPartidasCompra.next())
2501                 return false;
2502         
2503         
2504         var curPartidasCompra:FLSqlCursor = new FLSqlCursor("co_partidas");
2505         curPartidasCompra.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasCompra.value(0));
2506         curPartidasCompra.first();
2507         curPartidasCompra.setModeAccess(curPartidasCompra.Edit);
2508         curPartidasCompra.refreshBuffer();
2509         curPartidasCompra.setValueBuffer("idsubcuenta",  ctaDevolCompra.idsubcuenta);
2510         curPartidasCompra.setValueBuffer("codsubcuenta",  ctaDevolCompra.codsubcuenta);
2511         if (!curPartidasCompra.commitBuffer())
2512                         return false;
2513         return true;
2516 /** \D Si la fecha no está dentro del ejercicio, propone al usuario la selección de uno nuevo
2517 @param  fecha: Fecha del documento
2518 @param  codEjercicio: Ejercicio del documento
2519 @param  tipoDoc: Tipo de documento a generar
2520 @return Devuelve un array con los siguientes datos:
2521 ok:     Indica si la función terminó correctamente (true) o con error (false)
2522 modificaciones: Indica si se ha modificado algún valor (fecha o ejercicio)
2523 fecha: Nuevo valor para la fecha modificada
2524 codEjercicio: Nuevo valor para el ejercicio modificado
2525 \end */
2526 function oficial_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array
2528         
2529         var res:Array = [];
2530         res["ok"] = true;
2531         res["modificaciones"] = false;
2532         
2533         var util:FLUtil = new FLUtil;
2534         if (util.sqlSelect("ejercicios", "codejercicio", "codejercicio = '" + codEjercicio + "' AND '" + fecha + "' BETWEEN fechainicio AND fechafin"))
2535                 return res;
2536                 
2537         var f:Object = new FLFormSearchDB("fechaejercicio");
2538         var cursor:FLSqlCursor = f.cursor();
2539         
2540         cursor.select();
2541         if (!cursor.first())
2542                 cursor.setModeAccess(cursor.Insert);
2543         else
2544                 cursor.setModeAccess(cursor.Edit);
2545         cursor.refreshBuffer();
2547         cursor.refreshBuffer();
2548         cursor.setValueBuffer("fecha", fecha);
2549         cursor.setValueBuffer("codejercicio", codEjercicio);
2550         cursor.setValueBuffer("label", tipoDoc);
2551         cursor.commitBuffer();
2552         cursor.select();
2554         if (!cursor.first()) {
2555                 res["ok"] = false;
2556                 return res;
2557         }
2559         cursor.setModeAccess(cursor.Edit);
2560         cursor.refreshBuffer();
2562         f.setMainWidget();
2563         
2564         var acpt:String = f.exec("codejercicio");
2565         if (!acpt) {
2566                 res["ok"] = false;
2567                 return res;
2568         }
2569         res["modificaciones"] = true;
2570         res["fecha"] = cursor.valueBuffer("fecha");
2571         res["codEjercicio"] = cursor.valueBuffer("codejercicio");
2572         
2573         if (res.codEjercicio != flfactppal.iface.pub_ejercicioActual()) {
2574                 if (tipoDoc != "pagosdevolcli" && tipoDoc != "pagosdevolprov") {
2575                         MessageBox.information(util.translate("scripts", "Ha seleccionado un ejercicio distinto del actual.\nPara visualizar los documentos generados debe cambiar el ejercicio actual en la ventana\nde empresa y volver a abrir el formulario maestro correspondiente a los documentos generados"), MessageBox.Ok, MessageBox.NoButton);
2576                 }
2577         }
2578         
2579         return res;
2582 /** \C Establece si un documento de cliente debe tener IVA. No lo tendrá si el cliente seleccionado está exento o es UE, o la serie seleccionada sea sin IVA
2583 @param  codSerie: Serie del documento
2584 @param  codCliente: Código del cliente
2585 @return Devuelve 3 posibles valores:
2586         0: Si no debe tener ni IVA ni recargo de equivalencia,
2587         1: Si debe tener IVA pero no recargo de equivalencia,
2588         2: Si debe tener IVA y recargo de equivalencia
2589 \end */
2590 function oficial_tieneIvaDocCliente(codSerie:String, codCliente:String):Number
2592         var util:FLUtil = new FLUtil;
2593         var conIva:Boolean = true;
2594         
2595         if (util.sqlSelect("series", "siniva", "codserie = '" + codSerie + "'"))
2596                 return 0;
2597         else {
2598                 var regIva:String = util.sqlSelect("clientes", "regimeniva", "codcliente = '" + codCliente + "'");
2599                 if (regIva == "Exento")
2600                         return 0;
2601                 else
2602                         if (!util.sqlSelect("clientes", "recargo", "codcliente = '" + codCliente + "'"))
2603                                 return 1;
2604         }
2605         
2606         return 2;
2609 /** \D Indica si el módulo de autómata está instalado y activado
2610 @return true si está activado, false en caso contrario
2611 \end */
2612 function oficial_automataActivado():Boolean
2614         if (!sys.isLoadedModule("flautomata"))
2615                 return false;
2616         
2617         if (formau_automata.iface.pub_activado())
2618                 return true;
2619         
2620         return false;
2623 /** \D Comprueba que si la factura tiene IVA, no esté incluida en un período de regularización ya cerrado
2624 @param  curFactura: Cursor de la factura de cliente o proveedor
2625 @return TRUE si la factura no tiene IVA o teniéndolo su fecha no está incluida en ningún período ya cerrado. FALSE en caso contrario
2626 \end */
2627 function oficial_comprobarRegularizacion(curFactura:FLSqlCursor):Boolean
2629         var util:FLUtil = new FLUtil;
2631         var fecha:String = curFactura.valueBuffer("fecha");
2632         if (util.sqlSelect("co_regiva", "idregiva", "fechainicio <= '" + fecha + "' AND fechafin >= '" + fecha + "' AND codejercicio = '" + curFactura.valueBuffer("codejercicio") + "'")) {
2633                 MessageBox.warning(util.translate("scripts", "No puede incluirse el asiento de la factura en un período de I.V.A. ya regularizado"), MessageBox.Ok, MessageBox.NoButton);
2634                 return false;
2635         }
2636         return true;
2639 /** \D
2640 Recalcula la tabla huecos y el último valor de la secuencia de numeración.
2641 @param serie: Código de serie del documento
2642 @param ejercicio: Código de ejercicio del documento
2643 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
2644 @return true si el calculo se ralizó correctamente
2645 \end */
2646 function oficial_recalcularHuecos( serie:String, ejercicio:String, fN:String ):Boolean {
2647         var util:FLUtil = new FLUtil;
2648         var tipo:String;
2649         var tabla:String;
2651         if ( fN == "nfacturaprov" ) {
2652                 tipo = "FP";
2653                 tabla = "facturasprov"
2654         } else if (fN == "nfacturacli") {
2655                 tipo = "FC";
2656                 tabla = "facturascli";
2657         }
2659         var idSec = util.sqlSelect( "secuenciasejercicios", "id", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2661         if ( idSec ) {
2662                 var nHuecos:Number = parseInt( util.sqlSelect( "huecos", "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND tipo = '" + tipo + "'" ) );
2663                 var nFacturas:Number = parseInt( util.sqlSelect( tabla, "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" ) );
2664                 var maxFactura:Number = parseInt( util.sqlSelect( "secuencias", "valorout", "id = " + idSec + " AND nombre='" + fN + "'" ) ) - 1;
2665                 if (isNaN(maxFactura))
2666                         maxFactura = 0;
2668                 if ( maxFactura - nFacturas != nHuecos ) {
2669                         var nSec:Number = 0;
2670                         var nFac:Number = 0;
2671                         var ultFac:Number = -1;
2672                         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
2673                         var qryFac:FLSqlQuery = new FLSqlQuery();
2675                         util.createProgressDialog( util.translate( "scripts", "Calculando huecos en la numeración..." ), maxFactura );
2677                         qryFac.setTablesList( tabla );
2678                         qryFac.setSelect( "numero" );
2679                         qryFac.setFrom( tabla );
2680                         qryFac.setWhere( "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2681                         qryFac.setOrderBy( "codigo asc" );
2682                         qryFac.setForwardOnly( true );
2684                         if ( !qryFac.exec() )
2685                                 return true;
2687                         util.sqlDelete( "huecos", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND ( tipo = 'XX' OR tipo = '" + tipo + "')" );
2689                         while ( qryFac.next() ) {
2690                                 nFac = qryFac.value( 0 );
2691                                 
2692                                 // Por si hay duplicados, que no debería haberlos...
2693                                 if (ultFac == nFac)
2694                                         continue;
2695                                 ultFac = nFac;
2696                                 
2697                                 util.setProgress( ++nSec );
2698                                 while ( nSec < nFac ) {
2699                                         cursorHuecos.setModeAccess( cursorHuecos.Insert );
2700                                         cursorHuecos.refreshBuffer();
2701                                         cursorHuecos.setValueBuffer( "tipo", tipo );
2702                                         cursorHuecos.setValueBuffer( "codserie", serie );
2703                                         cursorHuecos.setValueBuffer( "codejercicio", ejercicio );
2704                                         cursorHuecos.setValueBuffer( "numero", nSec );
2705                                         cursorHuecos.commitBuffer();
2706                                         util.setProgress( ++nSec );
2707                                 }
2708                         }
2709                         
2710                         util.setProgress( ++nSec );
2711                         util.sqlUpdate( "secuencias", "valorout", nSec, "id = " + idSec + " AND nombre='" + fN + "'" );
2713                         util.setProgress( maxFactura );
2714                         util.destroyProgressDialog();
2715                 }
2716         }
2718         return true;
2721 /** \D Lanza el formulario que muestra los documentos relacionados con un determinado documento de facturación
2722 @param  codigo: Código del documento
2723 @param  tipo: Tipo del documento
2724 \end */
2725 function oficial_mostrarTraza(codigo:String, tipo:String)
2727         var util:FLUtil = new FLUtil();
2728         util.sqlDelete("trazadoc", "usuario = '" + sys.nameUser() + "'");
2730         var f:Object = new FLFormSearchDB("trazadoc");
2731         var curTraza:FLSqlCursor = f.cursor();
2732         curTraza.setModeAccess(curTraza.Insert);
2733         curTraza.refreshBuffer();
2734         curTraza.setValueBuffer("usuario", sys.nameUser());
2735         curTraza.setValueBuffer("codigo", codigo);
2736         curTraza.setValueBuffer("tipo", tipo);
2737         if (!curTraza.commitBuffer())
2738                 return false;;
2740         curTraza.select("usuario = '" + sys.nameUser() + "'");
2741         if (!curTraza.first())
2742                 return false;
2744         curTraza.setModeAccess(curTraza.Browse);
2745         f.setMainWidget();
2746         curTraza.refreshBuffer();
2747         var acpt:String = f.exec("usuario");
2750 /** \D Establece los datos opcionales de una partida de IVA decompras/ventas.
2751 Para facilitar personalizaciones en las partidas.
2752 Se ponen datos de concepto, tipo de documento, documento y factura
2753 @param  curPartida: Cursor sobre la partida
2754 @param  curFactura: Cursor sobre la factura
2755 @param  tipo: cliente / proveedor
2756 @param  concepto: Concepto, opcional
2758 function oficial_datosPartidaFactura(curPartida:FLSqlCursor, curFactura:FLSqlCursor, tipo:String, concepto:String) 
2760         var util:FLUtil = new FLUtil();
2761         
2762         if (tipo == "cliente") {
2763                 if (concepto)
2764                         curPartida.setValueBuffer("concepto", concepto);
2765                 else
2766                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Nuestra factura ") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombrecliente"));
2767                 
2768                 // Si es de IVA
2769                 if (curPartida.valueBuffer("cifnif"))
2770                         curPartida.setValueBuffer("tipodocumento", "Factura de cliente");
2771         }
2772         else {
2773                 if (concepto)
2774                         curPartida.setValueBuffer("concepto", concepto);
2775                 else
2776                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Su factura") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombre"));
2777                 
2778                 // Si es de IVA
2779                 if (curPartida.valueBuffer("cifnif"))
2780                 curPartida.setValueBuffer("tipodocumento", "Factura de proveedor");
2781         }
2782         
2783         // Si es de IVA
2784         if (curPartida.valueBuffer("cifnif")) {
2785                 curPartida.setValueBuffer("documento", curFactura.valueBuffer("codigo"));
2786                 curPartida.setValueBuffer("factura", curFactura.valueBuffer("numero"));
2787         }
2790 /** \D Comprueba si hay condiciones para regenerar los recibos de una factura
2791 cuando se edita la misma. Para sobrecargar en extensiones
2792 @param  curFactura: Cursor de la factura
2793 @param  masCampos: Array con los nombres de campos adicionales. Opcional
2794 @return VERDADERO si hay que regenerar, FALSO en otro caso
2795 \end */
2796 function oficial_siGenerarRecibosCli(curFactura:FLSqlCursor, masCampos:Array):Boolean 
2798         var camposAcomprobar = new Array("codcliente","total","codpago","fecha");
2799         
2800         for (var i:Number = 0; i < camposAcomprobar.length; i++)
2801                 if (curFactura.valueBuffer(camposAcomprobar[i]) != curFactura.valueBufferCopy(camposAcomprobar[i]))
2802                         return true;
2803         
2804         if (masCampos) {
2805                 for (i = 0; i < masCampos.length; i++)
2806                         if (curFactura.valueBuffer(masCampos[i]) != curFactura.valueBufferCopy(masCampos[i]))
2807                                 return true;
2808         }
2809         
2810         return false;
2813 function oficial_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean
2815         var util:FLUtil;
2817         if(!codCliente)
2818                 return true;
2820         var regimenIva = util.sqlSelect("clientes","regimeniva","codcliente = '" + codCliente + "'");
2821         var aplicarRecargo = util.sqlSelect("clientes","recargo","codcliente = '" + codCliente + "'");
2822         
2823         var q:FLSqlQuery = new FLSqlQuery();
2824         q.setTablesList(tabla);
2825         q.setSelect("iva,recargo");
2826         q.setFrom(tabla);
2827         q.setWhere(identificador + " = " + id);
2828         
2829         if (!q.exec())
2830                 return false;
2832         while (q.next()) {
2833                                 var iva:Number = parseFloat(q.value("iva"));
2834                 if(!iva)
2835                         iva = 0;
2836                 var recargo:Number = parseFloat(q.value("recargo"));
2837                 if(!recargo)
2838                         recargo = 0;
2840                 switch (regimenIva) {
2841                         case "General": {
2842                                 if (iva == 0) {
2843                                         var res:Number = MessageBox.warning(util.translate("scripts", "El cliente %1 tiene establecido un régimen de I.V.A. %2\ny en alguna o varias de las lineas no hay establecido un % de I.V.A.\n¿Desea continuar de todas formas?").arg(codCliente).arg(regimenIva), MessageBox.Yes,MessageBox.No);
2844                                         if (res != MessageBox.Yes)
2845                                                 return false;
2846                                 }
2847                         }
2848                         break;
2849                         case "Exento":
2850                         case "U.E.": {
2851                                 if (iva != 0) {
2852                                         var res:Number = MessageBox.warning(util.translate("scripts", "El cliente %1 tiene establecido un régimen de I.V.A. %2\ny en alguna o varias de las lineas hay establecido un % de I.V.A.\n¿Desea continuar de todas formas?").arg(codCliente).arg(regimenIva), MessageBox.Yes,MessageBox.No);
2853                                         if (res != MessageBox.Yes)
2854                                                 return false;
2855                                 }
2856                         }
2857                         break;
2858                 }
2859                 if (aplicarRecargo && recargo == 0) {
2860                         var res:Number = MessageBox.warning(util.translate("scripts", "Al cliente %1 se le debe aplicar Recargo de Equivalencia\ny en alguna o varias de las lineas no hay establecido un % de R. Equivalencia.\n¿Desea continuar de todas formas?").arg(codCliente), MessageBox.Yes,MessageBox.No);
2861                         if (res != MessageBox.Yes)
2862                                 return false;
2863                 }
2864                 if (!aplicarRecargo && recargo != 0) {
2865                         var res:Number = MessageBox.warning(util.translate("scripts", "Al cliente %1 no se le debe aplicar Recargo de Equivalencia\ny en alguna o varias de las lineas hay establecido un % de R. Equivalencia.\n¿Desea continuar de todas formas?").arg(codCliente), MessageBox.Yes,MessageBox.No);
2866                         if (res != MessageBox.Yes)
2867                                 return false;
2868                 }
2869         }
2871         return true;
2874 function oficial_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean
2876         var util:FLUtil;
2878         if(!codProveedor)
2879                 return true;    
2881         var regimenIva = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + codProveedor + "'");
2882         var aplicarRecargo = util.sqlSelect("empresa","recequivalencia","1 = 1");
2883         
2884         var q:FLSqlQuery = new FLSqlQuery();
2885         q.setTablesList(tabla);
2886         q.setSelect("iva,recargo");
2887         q.setFrom(tabla);
2888         q.setWhere(identificador + " = " + id);
2889         
2890         if (!q.exec())
2891                 return false;
2893         while (q.next()) {
2894                 var iva:Number = parseFloat(q.value("iva"));
2895                 if(!iva)
2896                         iva = 0;
2897                 var recargo:Number = parseFloat(q.value("recargo"));
2898                 if(!recargo)
2899                         recargo = 0;
2901                 switch (regimenIva) {
2902                         case "General":
2903                         case "U.E.": {
2904                                 if (iva == 0) {
2905                                         var res:Number = MessageBox.warning(util.translate("scripts", "El proveedor %1 tiene establecido un régimen de I.V.A. %2\ny en alguna o varias de las lineas no hay establecido un % de I.V.A.\n¿Desea continuar de todas formas?").arg(codProveedor).arg(regimenIva), MessageBox.Yes,MessageBox.No);
2906                                         if (res != MessageBox.Yes)
2907                                                 return false;
2908                                 }
2909                         }
2910                         break;
2911                         case "Exento": {
2912                                 if (iva != 0) {
2913                                         var res:Number = MessageBox.warning(util.translate("scripts", "El proveedor %1 tiene establecido un régimen de I.V.A. %2\ny en alguna o varias de las lineas hay establecido un % de I.V.A.\n¿Desea continuar de todas formas?").arg(codProveedor).arg(regimenIva), MessageBox.Yes,MessageBox.No);
2914                                         if (res != MessageBox.Yes)
2915                                                 return false;
2916                                 }
2917                         }
2918                         break;
2919                 }
2920                 if (aplicarRecargo && recargo == 0) {
2921                         var res:Number = MessageBox.warning(util.translate("scripts", "En los datos de empresa está activa al opción Aplicar Recargo de Equivalencia\ny en alguna o varias de las lineas no hay establecido un % de R. Equivalencia.\n¿Desea continuar de todas formas?"), MessageBox.Yes,MessageBox.No);
2922                         if (res != MessageBox.Yes)
2923                                 return false;
2924                 }
2925                 if (!aplicarRecargo && recargo != 0) {
2926                         var res:Number = MessageBox.warning(util.translate("scripts", "En los datos de empresa no está activa al opción Aplicar Recargo de Equivalencia\ny en alguna o varias de las lineas hay establecido un % de R. Equivalencia.\n¿Desea continuar de todas formas?"), MessageBox.Yes,MessageBox.No);
2927                         if (res != MessageBox.Yes)
2928                                 return false;
2929                 }
2930         }
2932         return true;
2935 function oficial_comprobarFacturaAbonoCli(curFactura:FLSqlCursor):Boolean
2937         var util:FLUtil = new FLUtil();
2938         if (curFactura.valueBuffer("deabono") == true) {
2939                 if (!curFactura.valueBuffer("idfacturarect")){
2940                         var res:Number = MessageBox.warning(util.translate("scripts", "No ha indicado la factura que desea abonar.\n¿Desea continuar?"), MessageBox.No, MessageBox.Yes);
2941                         if (res != MessageBox.Yes) {
2942                                 return false;
2943                         }
2944                 } else {
2945                         if (util.sqlSelect("facturascli", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
2946                                 MessageBox.warning(util.translate("scripts", "La factura ") +  util.sqlSelect("facturascli", "codigo", "idfactura = " + curFactura.valueBuffer("idfacturarect"))  + util.translate("scripts", " ya está abonada"),MessageBox.Ok, MessageBox.NoButton,MessageBox.NoButton);
2947                                 return false;
2948                         }
2949                 }
2950         }
2951         return true;
2954 function oficial_crearCtaEspecial(codCtaEspecial:String, tipo:String, codEjercicio:String, desCta:String):Boolean
2956         var util:FLUtil = new FLUtil();
2957         
2958         var codSubcuenta:String;
2959         if (tipo == "subcuenta") {
2960                 var f:Object = new FLFormSearchDB("co_subcuentas");
2961                 var curSubcuenta:FLSqlCursor = f.cursor();
2962                 curSubcuenta.setMainFilter("codejercicio = '" + codEjercicio + "'");
2963                 
2964                 f.setMainWidget();
2965                 codSubcuenta = f.exec("codsubcuenta");
2966                 if (!codSubcuenta)
2967                         return false;
2968         }
2969         var curCtaEspecial:FLSqlCursor = new FLSqlCursor("co_cuentasesp");
2970         curCtaEspecial.select("idcuentaesp = '" + codCtaEspecial + "'");
2971         if (curCtaEspecial.first()) {
2972                 curCtaEspecial.setModeAccess(curCtaEspecial.Edit);
2973                 curCtaEspecial.refreshBuffer();
2974         } else {
2975                 curCtaEspecial.setModeAccess(curCtaEspecial.Insert);
2976                 curCtaEspecial.refreshBuffer();
2977                 curCtaEspecial.setValueBuffer("idcuentaesp", codCtaEspecial);
2978                 curCtaEspecial.setValueBuffer("descripcion", desCta);
2979         }
2980         if (codSubcuenta && codSubcuenta != "") {
2981                 curCtaEspecial.setValueBuffer("codsubcuenta", codSubcuenta);
2982         }
2983         if (!curCtaEspecial.commitBuffer())
2984                 return false;
2986         return true;
2989 function oficial_comprobarCambioSerie(cursor:FLSqlCursor):Boolean
2991         var util:FLUtil;
2992         if(!cursor.valueBuffer("codserie") || cursor.valueBuffer("codserie") == "" || !cursor.valueBufferCopy("codserie") || cursor.valueBufferCopy("codserie") == "")
2993                 return true;
2994         if(cursor.valueBuffer("codserie") != cursor.valueBufferCopy("codserie")) {
2995                 var util:FLUtil = new FLUtil();
2996                 MessageBox.warning(util.translate("scripts", "No se puede modificar la serie.\nSerie anterior:%1 - Serie actual:%2").arg(cursor.valueBufferCopy("codserie")).arg(cursor.valueBuffer("codserie")), MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
2997                 return false;
2998         }
2999         return true;
3001 //// OFICIAL ////////////////////////////////////////////////////
3002 /////////////////////////////////////////////////////////////////
3004 /** @class_definition barCode */
3005 /////////////////////////////////////////////////////////////////
3006 //// TALLAS Y COLORES POR BARCODE ///////////////////////////////
3007 /** \C
3008 Actualiza el stock correspondiente al artículo seleccionado en la línea
3009 \end */
3010 function barCode_afterCommit_lineaspedidosprov(curLP:FLSqlCursor):Boolean
3012         if (sys.isLoadedModule("flfactalma")) 
3013                 if (!flfactalma.iface.pub_controlStockPedidosProv(curLP))
3014                         return false;
3015         
3016         return true;
3019 function barCode_validarLinea(curLinea:FLSqlCursor):Boolean
3021         var util:FLUtil = new FLUtil();
3023         var talla:String = curLinea.valueBuffer("talla");
3024         var color:String = curLinea.valueBuffer("color");
3025         var barcode:String = curLinea.valueBuffer("barcode");
3026         if (((talla && talla != "") || (color && color != "")) && (!barcode || barcode == "")) {
3027                 MessageBox.warning(util.translate("scripts", "Si establece la talla o color debe indicar el código de barras (barcode) del artículo"), MessageBox.Ok, MessageBox.NoButton);
3028                 return false;
3029         }
3030         return true;
3032 //// TALLAS Y COLORES POR BARCODE ///////////////////////////////
3033 /////////////////////////////////////////////////////////////////
3035 /** @class_definition head */
3036 /////////////////////////////////////////////////////////////////
3037 //// DESARROLLO /////////////////////////////////////////////////
3039 //// DESARROLLO /////////////////////////////////////////////////
3040 ////////////////////////////////////////////////////////////////