Added the README file.
[mx3r.git] / testfile1.qs.REMOTE
blob086c55fada62d107c96a64cdb0aa37a253b86785
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(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
127                 return this.ctx.oficial_regenerarAsiento(curFactura, 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 comprobarCambioSerie(cursor:FLSqlCursor):Boolean {
199                 return this.ctx.oficial_comprobarCambioSerie(cursor);
200         }
201         function consultarCtaEspecial(ctaEsp:String, codEjercicio:String):Boolean {
202                 return this.ctx.oficial_consultarCtaEspecial(ctaEsp, codEjercicio);
203         }
204         function netoVentasFacturaCli(curFactura:FLSqlCursor):Number {
205                 return this.ctx.oficial_netoVentasFacturaCli(curFactura);
206         }
207         function crearCtaEspecial(codCtaEspecial:String, tipo:String, codEjercicio:String, desCta:String):Boolean {
208                 return this.ctx.oficial_crearCtaEspecial(codCtaEspecial, tipo, codEjercicio, desCta);
209         }
211 //// OFICIAL /////////////////////////////////////////////////////
212 //////////////////////////////////////////////////////////////////
214 /** @class_declaration head */
215 /////////////////////////////////////////////////////////////////
216 //// DESARROLLO /////////////////////////////////////////////////
217 class head extends oficial {
218         function head( context ) { oficial ( context ); }
220 //// DESARROLLO /////////////////////////////////////////////////
221 /////////////////////////////////////////////////////////////////
223 /** @class_declaration ifaceCtx */
224 /////////////////////////////////////////////////////////////////
225 //// INTERFACE  /////////////////////////////////////////////////
226 class ifaceCtx extends head {
227         function ifaceCtx( context ) { head( context ); }
228         function pub_cerosIzquierda(numero:String, totalCifras:Number):String {
229                 return this.cerosIzquierda(numero, totalCifras);
230         }
231         function pub_asientoBorrable(idAsiento:Number):Boolean {
232                 return this.asientoBorrable(idAsiento);
233         }
234         function pub_regenerarAsiento(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
235                 return this.regenerarAsiento(curFactura, valoresDefecto);
236         }
237         function pub_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array {
238                 return this.datosCtaEspecial(ctaEsp, codEjercicio);
239         }
240         function pub_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number {
241                 return this.siguienteNumero(codSerie, codEjercicio, fN);
242         }
243         function pub_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String {
244                 return this.construirCodigo(codSerie, codEjercicio, numero);
245         }
246         function pub_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean {
247                 return this.agregarHueco(serie, ejercicio, numero, fN);
248         }
249         function pub_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array {
250                 return this.datosDocFacturacion(fecha, codEjercicio, tipoDoc);
251         }
252         function pub_tieneIvaDocCliente(codSerie:String, codCliente:String):Number {
253                 return this.tieneIvaDocCliente(codSerie, codCliente);
254         }
255         function pub_automataActivado():Boolean {
256                 return this.automataActivado();
257         }
258         function pub_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean {
259                 return this.generarAsientoFacturaCli(curFactura);
260         }
261         function pub_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean {
262                 return this.generarAsientoFacturaProv(curFactura);
263         }
264         function pub_mostrarTraza(codigo:String, tipo:String) {
265                 return this.mostrarTraza(codigo, tipo);
266         }
267         function pub_eliminarAsiento(idAsiento:String):Boolean {
268                 return this.eliminarAsiento(idAsiento);
269         }
270         function pub_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean {
271                 return this.validarIvaRecargoCliente(codCliente,id,tabla,identificador);
272         }
273         function pub_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean {
274                 return this.validarIvaRecargoProveedor(codProveedor,id,tabla,identificador);
275         }
278 const iface = new ifaceCtx( this );
279 //// INTERFACE  /////////////////////////////////////////////////
280 /////////////////////////////////////////////////////////////////
282 /** @class_definition interna */
283 ////////////////////////////////////////////////////////////////////////////
284 //// DEFINICION ////////////////////////////////////////////////////////////
285 ////////////////////////////////////////////////////////////////////////////
287 //////////////////////////////////////////////////////////////////
288 //// INTERNA /////////////////////////////////////////////////////
289 /** \C 
290 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
292 Se actualiza el estado del pedido.
294 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.
295 \end */
296 function interna_beforeCommit_pedidoscli(curPedido:FLSqlCursor):Boolean
298         var util:FLUtil = new FLUtil();
299         var numero:String;
300         
301         switch (curPedido.modeAccess()) {
302                 case curPedido.Insert: {
303                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
304                                 return false;
305                         if (curPedido.valueBuffer("numero") == 0) {
306                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidocli");
307                                 if (!numero)
308                                         return false;
309                                 curPedido.setValueBuffer("numero", numero);
310                                 curPedido.setValueBuffer("codigo", formpedidoscli.iface.pub_commonCalculateField("codigo", curPedido));
311                         }
312                         break;
313                 }
314                 case curPedido.Edit: {
315                         if(!this.iface.comprobarCambioSerie(curPedido))
316                                 return false;
317                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
318                                 return false;
319                         if (curPedido.valueBuffer("servido") == "Parcial") {
320                                 var estado:String = formRecordlineasalbaranescli.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
321                                 if (estado == "Sí") {
322                                         curPedido.setValueBuffer("servido", estado);
323                                         curPedido.setValueBuffer("editable", false);
324                                 }
325                         }
326                         break;
327                 }
328                 case curPedido.Del: {
329                         if (curPedido.valueBuffer("servido") == "Parcial") {
330                                 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);
331                                 return false;
332                         }
333                         break;
334                 }
335         }
336         
337         return true;
340 /** \C 
341 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
343 Se actualiza el estado del pedido.
345 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.
346 \end */
347 function interna_beforeCommit_pedidosprov(curPedido:FLSqlCursor):Boolean
349         var util:FLUtil = new FLUtil();
350         var numero:String;
351         
352         switch (curPedido.modeAccess()) {
353                 case curPedido.Insert: {
354                         if (curPedido.valueBuffer("numero") == 0) {
355                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidoprov");
356                                 if (!numero)
357                                         return false;
358                                 curPedido.setValueBuffer("numero", numero);
359                                 curPedido.setValueBuffer("codigo", formpedidosprov.iface.pub_commonCalculateField("codigo", curPedido));
360                         }
361                         break;
362                 }
363                 case curPedido.Edit: {
364                         if(!this.iface.comprobarCambioSerie(curPedido))
365                                 return false;
366                         if (curPedido.valueBuffer("servido") == "Parcial") {
367                                 var estado:String = formRecordlineasalbaranesprov.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
368                                 if (estado == "Sí") {
369                                         curPedido.setValueBuffer("servido", estado);
370                                         curPedido.setValueBuffer("editable", false);
371                                         if (sys.isLoadedModule("flcolaproc")) {
372                                                 if (!flfactppal.iface.pub_lanzarEvento(curPedido, "pedidoProvAlbaranado"))
373                                                         return false;
374                                         }
375                                 }
376                         }
377                         break;
378                 }
379                 case curPedido.Del: {
380                         if (curPedido.valueBuffer("servido") == "Parcial") {
381                                 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);
382                                 return false;
383                         }
384                         break;
385                 }
386         }
387         return true;
390 /* \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.
391 \end */
392 function interna_beforeCommit_facturascli(curFactura:FLSqlCursor):Boolean
394         var util:FLUtil = new FLUtil();
395         var numero:String;
396         
397         if (!this.iface.comprobarFacturaAbonoCli(curFactura))
398                 return false;
400         switch (curFactura.modeAccess()) {
401                 case curFactura.Insert: {
402                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
403                                 return false;
404                         if (curFactura.valueBuffer("numero") == 0) {
405                                 this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli" );
406                                 numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
407                                 if (!numero)
408                                         return false;
409                                 curFactura.setValueBuffer("numero", numero);
410                                 curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
411                         }
412                         break;
413                 }
414                 case curFactura.Edit: {
415                         if(!this.iface.comprobarCambioSerie(curFactura))
416                                 return false;
417                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
418                                 return false;
419                         break;
420                 }
421         }
423         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
424                 if (util.sqlSelect("facturascli", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
425                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
426                         if (!numero)
427                                 return false;
428                         curFactura.setValueBuffer("numero", numero);
429                         curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
430                 }
431         }
433         if (!formRecordfacturascli.iface.pub_actualizarLineasIva(curFactura))
434                 return false;
436         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
437                 if (this.iface.generarAsientoFacturaCli(curFactura) == false)
438                         return false;
439         }
440         
441         return true;
444 /* \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.
445 \end */
446 function interna_beforeCommit_facturasprov(curFactura:FLSqlCursor):Boolean
448         var util:FLUtil = new FLUtil();
449         var numero:String;
450         
451         if (curFactura.valueBuffer("deabono") == true) {
452                 if (!curFactura.valueBuffer("idfacturarect")){
453                         MessageBox.warning(util.translate("scripts", "Debe seleccionar la factura que desea abonar"),MessageBox.Ok, MessageBox.NoButton,MessageBox.NoButton);
454                         return false;
455                 }
456                 if (util.sqlSelect("facturasprov", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
457                         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);
458                         return false;
459                 }
460         }
461         
462         if (curFactura.modeAccess() == curFactura.Edit) {
463                 if(!this.iface.comprobarCambioSerie(curFactura))
464                         return false;
465         }
466         
467         if (curFactura.modeAccess() == curFactura.Insert) {
468                 if (curFactura.valueBuffer("numero") == 0) {
469                         this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov" );
470                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
471                         if (!numero)
472                                 return false;
473                         curFactura.setValueBuffer("numero", numero);
474                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
475                 }
476         }
478         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
479                 if (util.sqlSelect("facturasprov", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
480                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
481                         if (!numero)
482                                 return false;
483                         curFactura.setValueBuffer("numero", numero);
484                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
485                 }
486         }
488         if (!formRecordfacturasprov.iface.pub_actualizarLineasIva(curFactura))
489                 return false;
491         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
492                 if (this.iface.generarAsientoFacturaProv(curFactura) == false)
493                         return false;
494         }
495         return true;
499 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
500 Se recalcula el estado de los pedidos asociados al albarán
501 \end */
502 function interna_beforeCommit_albaranescli(curAlbaran:FLSqlCursor):Boolean
504         var util:FLUtil = new FLUtil();
505         var numero:String;
506         
507         switch (curAlbaran.modeAccess()) {
508                 case curAlbaran.Insert: {
509                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
510                                 return false;
511                         if (curAlbaran.valueBuffer("numero") == 0) {
512                                 numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbarancli");
513                                 if (!numero)
514                                         return false;
515                                 curAlbaran.setValueBuffer("numero", numero);
516                                 curAlbaran.setValueBuffer("codigo", formalbaranescli.iface.pub_commonCalculateField("codigo", curAlbaran));
517                         }
518                         break;
519                 }
520                 case curAlbaran.Edit: {
521                         if(!this.iface.comprobarCambioSerie(curAlbaran))
522                                 return false;
523                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
524                                 return false;
525                         break;
526                 }
527         }
528         
529         var query:FLSqlQuery = new FLSqlQuery();
530         query.setTablesList("lineasalbaranescli");
531         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
532         query.setFrom("lineasalbaranescli");
533         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
534         try { query.setForwardOnly( true ); } catch (e) {}
535         query.exec();
536         var idPedido:String = 0;
537         while (query.next()) {
538                 if (!formRecordlineasalbaranescli.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
539                         return false;
540                         
541                 if (idPedido != query.value(1)) {
542                         if (!formRecordlineasalbaranescli.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
543                                 return false;
544                 }
545                 idPedido = query.value(1)
546         }
547         return true;
550 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
552 Se recalcula el estado de los pedidos asociados al albarán
553 \end */
554 function interna_beforeCommit_albaranesprov(curAlbaran:FLSqlCursor):Boolean
556         var util:FLUtil = new FLUtil();
557         var numero:String;
558         
559         if (curAlbaran.modeAccess() == curAlbaran.Insert) {
560                 if (curAlbaran.valueBuffer("numero") == 0) {
561                         numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbaranprov");
562                         if (!numero)
563                                 return false;
564                         curAlbaran.setValueBuffer("numero", numero);
565                         curAlbaran.setValueBuffer("codigo", formalbaranesprov.iface.pub_commonCalculateField("codigo", curAlbaran));
566                 }
567         }
568         if (curAlbaran.modeAccess() == curAlbaran.Edit) {
569                 if(!this.iface.comprobarCambioSerie(curAlbaran))
570                         return false;
571         }
572         
573         var query:FLSqlQuery = new FLSqlQuery();
574         query.setTablesList("lineasalbaranesprov");
575         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
576         query.setFrom("lineasalbaranesprov");
577         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
578         try { query.setForwardOnly( true ); } catch (e) {}
579         query.exec();
580         var idPedido:String = 0;
581         while (query.next()) {
582                 if (!formRecordlineasalbaranesprov.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
583                         return false;
584                 if (idPedido != query.value(1)) {
585                         if (!formRecordlineasalbaranesprov.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
586                                 return false;
587                 }
588                 idPedido = query.value(1);
589         }
590         
591         return true;
594 /* \C Se calcula el número del presupuesto como el siguiente de la secuencia asociada a su ejercicio y serie. 
595 \end */
596 function interna_beforeCommit_presupuestoscli(curPresupuesto:FLSqlCursor):Boolean
598         var util:FLUtil = new FLUtil();
599         var numero:String;
600         
601         switch (curPresupuesto.modeAccess()) {
602                 case curPresupuesto.Insert: {
603                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
604                                 return false;
605                         if (curPresupuesto.valueBuffer("numero") == 0) {
606                                 numero = this.iface.siguienteNumero(curPresupuesto.valueBuffer("codserie"), curPresupuesto.valueBuffer("codejercicio"), "npresupuestocli");
607                                 if (!numero)
608                                         return false;
609                                 curPresupuesto.setValueBuffer("numero", numero);
610                                 curPresupuesto.setValueBuffer("codigo", formpresupuestoscli.iface.pub_commonCalculateField("codigo", curPresupuesto));
611                         }
612                         break;
613                 }
614                 case curPresupuesto.Edit: {
615                         if(!this.iface.comprobarCambioSerie(curPresupuesto))
616                                 return false;
617                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
618                                 return false;
619                         break;
620                 }
621         }
622         
623         return true;
626 /* \C En el caso de que el módulo de tesorería esté cargado, genera o modifica los recibos correspondientes a la factura.
628 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.
629 \end */
630 function interna_afterCommit_facturascli(curFactura:FLSqlCursor):Boolean
632         if (curFactura.modeAccess() == curFactura.Del) {
633                 if (!this.iface.agregarHueco(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), curFactura.valueBuffer("numero"), "nfacturacli"))
634                         return false;
635         }
636         
637         var util:FLUtil = new FLUtil();
638         
639         if (sys.isLoadedModule("flfactteso") && curFactura.valueBuffer("tpv") == false) {
640                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
641                         if (this.iface.siGenerarRecibosCli(curFactura))
642                                 if (flfactteso.iface.pub_regenerarRecibosCli(curFactura) == false)
643                                         return false;
644                 }
645                 if (curFactura.modeAccess() == curFactura.Del) {
646                         flfactteso.iface.pub_actualizarRiesgoCliente(curFactura.valueBuffer("codcliente"));
647                 }
648         }
650         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
651                 switch (curFactura.modeAccess()) {
652                         case curFactura.Del: {
653                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
654                                         return false;
655                                 break;
656                         }
657                         case curFactura.Edit: {
658                                 if (curFactura.valueBuffer("nogenerarasiento")) {
659                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
660                                         if (idAsientoAnterior && idAsientoAnterior != "") {
661                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
662                                                         return false;
663                                         }
664                                 }
665                                 break;
666                         }
667                 }
668         }
669         
670         return true;
673 /* \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.
674 \end */
675 function interna_afterCommit_facturasprov(curFactura:FLSqlCursor):Boolean
677         var util:FLUtil = new FLUtil();
678         if (sys.isLoadedModule("flfactteso")) {
679                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
680                         if (curFactura.valueBuffer("total") != curFactura.valueBufferCopy("total")
681                                 || curFactura.valueBuffer("codproveedor") != curFactura.valueBufferCopy("codproveedor")
682                                 || curFactura.valueBuffer("codpago") != curFactura.valueBufferCopy("codpago")
683                                 || curFactura.valueBuffer("fecha") != curFactura.valueBufferCopy("fecha")) {
684                                 if (flfactteso.iface.pub_regenerarRecibosProv(curFactura) == false)
685                                         return false;
686                         }
687                 }
688         }
690         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
691                 switch (curFactura.modeAccess()) {
692                         case curFactura.Del: {
693                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
694                                         return false;
695                                 break;
696                         }
697                         case curFactura.Edit: {
698                                 if (curFactura.valueBuffer("nogenerarasiento")) {
699                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
700                                         if (idAsientoAnterior && idAsientoAnterior != "") {
701                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
702                                                         return false;
703                                         }
704                                 }
705                                 break;
706                         }
707                 }
708         }
709         return true;
712 /** \C
713 Actualización del stock correspondiente al artículo seleccionado en la línea
714 \end */
715 function interna_afterCommit_lineasalbaranesprov(curLA:FLSqlCursor):Boolean
717         if (sys.isLoadedModule("flfactalma")) 
718                 if (!flfactalma.iface.pub_controlStockAlbaranesProv(curLA))
719                         return false;
720         
721         return true;
724 /** \C
725 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.
727 Actualiza también el coste medio de los artículos afectados por el cambio.
728 \end */
729 function interna_afterCommit_lineasfacturasprov(curLF:FLSqlCursor):Boolean
731         if (sys.isLoadedModule("flfactalma")) {
732                 var util:FLUtil = new FLUtil();
733                 switch(curLF.modeAccess()) {
734                         case curLF.Edit:
735                                 if (curLF.valueBuffer("referencia") != curLF.valueBufferCopy("referencia"))
736                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBufferCopy("referencia"));
737                         case curLF.Insert:
738                         case curLF.Del:
739                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBuffer("referencia"));
740                         break;
741                 }
742                 
743                 if (!flfactalma.iface.pub_controlStockFacturasProv(curLF))
744                         return false;
745         }
746         return true;
749 /** \C
750 Actualiza el stock correspondiente al artículo seleccionado en la línea si el sistema
751 está configurado para ello
752 \end */
753 function interna_afterCommit_lineaspedidoscli(curLP:FLSqlCursor):Boolean
755         if (sys.isLoadedModule("flfactalma"))
756                 if (!flfactalma.iface.pub_controlStockPedidosCli(curLP))
757                         return false;
758         
759         return true;
762 /** \C
763 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
764 \end */
765 function interna_afterCommit_lineasalbaranescli(curLA:FLSqlCursor):Boolean
767         if (sys.isLoadedModule("flfactalma")) 
768                 if (!flfactalma.iface.pub_controlStockAlbaranesCli(curLA))
769                         return false;
770         
771         return true;
774 /** \C
775 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
776 \end */
777 function interna_afterCommit_lineasfacturascli(curLF:FLSqlCursor):Boolean
779         if (sys.isLoadedModule("flfactalma")) 
780                 if (!flfactalma.iface.pub_controlStockFacturasCli(curLF))
781                         return false;
782         
783         return true;
785 //// INTERNA /////////////////////////////////////////////////////
786 /////////////////////////////////////////////////////////////////
788 /** @class_definition oficial */
789 //////////////////////////////////////////////////////////////////
790 //// OFICIAL /////////////////////////////////////////////////////
791 /** \D
792 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)
793 @param codSerie: Código de serie del documento
794 @param codEjercicio: Código de ejercicio del documento
795 @param tipo: Tipo de documento (factura a cliente, a proveedor)
796 @return Número correspondiente al primer hueco encontrado (0 si no se encuentra ninguno)
797 \end */
798 function oficial_obtenerHueco(codSerie:String, codEjercicio:String, tipo:String):Number
800         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
801         var numHueco:Number = 0;
802         cursorHuecos.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "' AND upper(tipo)='" + tipo + "' ORDER BY numero;");
803         if (cursorHuecos.next()) {
804                 numHueco = cursorHuecos.valueBuffer("numero");
805                 cursorHuecos.setActivatedCheckIntegrity(false);
806                 cursorHuecos.setModeAccess(cursorHuecos.Del);
807                 cursorHuecos.refreshBuffer();
808                 cursorHuecos.commitBuffer();
809         }
810         return numHueco;
813 function oficial_establecerNumeroSecuencia(fN:String, value:Number):Number
815         return (parseFloat(value) + 1);
818 /** \D
819 Rellena un string con ceros a la izquierda hasta completar la logitud especificada
820 @param numero: String que contiene el número
821 @param totalCifras: Longitud a completar
822 \end */
823 function oficial_cerosIzquierda(numero:String, totalCifras:Number):String
825         var ret:String = numero.toString();
826         var numCeros:Number = totalCifras - ret.length;
827         for ( ; numCeros > 0 ; --numCeros)
828                 ret = "0" + ret;
829         return ret;
832 function oficial_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String
834         return this.iface.cerosIzquierda(codEjercicio, 4) +
835                 this.iface.cerosIzquierda(codSerie, 2) +
836                 this.iface.cerosIzquierda(numero, 6);
839 /** \D
840 Obtiene el siguiente número de la secuencia de documentos
841 @param codSerie: Código de serie del documento
842 @param codEjercicio: Código de ejercicio del documento
843 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
844 @return Número correspondiente al siguiente documento en la serie o false si hay error
845 \end */
846 function oficial_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number
848         var numero:Number;
849         var util:FLUtil = new FLUtil;
850         var cursorSecuencias:FLSqlCursor = new FLSqlCursor("secuenciasejercicios");
852         cursorSecuencias.setContext(this);
853         cursorSecuencias.setActivatedCheckIntegrity(false);
854         cursorSecuencias.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "';");
855         if (cursorSecuencias.next()) {
856                 if (fN == "nfacturaprov") {
857                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FP");
858                         if (numeroHueco != 0) {
859                                 cursorSecuencias.setActivatedCheckIntegrity(true);
860                                 return numeroHueco;
861                         }
862                 }
863                 if (fN == "nfacturacli") {
864                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FC");
865                         if (numeroHueco != 0) {
866                                 cursorSecuencias.setActivatedCheckIntegrity(true);
867                                 return numeroHueco;
868                         }
869                 }
871                 /** \C
872                 Para minimizar bloqueos las secuencias se han separado en distintos registros de otra tabla
873                 llamada secuencias
874                 \end */
875                 var cursorSecs:FLSqlCursor = new FLSqlCursor( "secuencias" );
876                 cursorSecs.setContext( this );
877                 cursorSecs.setActivatedCheckIntegrity( false );
878                 /** \C
879                 Si el registro no existe lo crea inicializandolo con su antiguo valor del campo correspondiente
880                 en la tabla secuenciasejercicios.
881                 \end */
882                 var idSec:Number = cursorSecuencias.valueBuffer( "id" );
883                 cursorSecs.select( "id=" + idSec + " AND nombre='" + fN + "'" );
884                 if ( !cursorSecs.next() ) {
885                         numero = cursorSecuencias.valueBuffer(fN);
886                         cursorSecs.setModeAccess( cursorSecs.Insert );
887                         cursorSecs.refreshBuffer();
888                         cursorSecs.setValueBuffer( "id", idSec );
889                         cursorSecs.setValueBuffer( "nombre", fN );
890                         cursorSecs.setValueBuffer( "valor", this.iface.establecerNumeroSecuencia( fN, numero ) );
891                         cursorSecs.commitBuffer();
892                 } else {
893                         cursorSecs.setModeAccess( cursorSecs.Edit );
894                         cursorSecs.refreshBuffer();
895                         if ( !cursorSecs.isNull( "valorout" ) )
896                                 numero = cursorSecs.valueBuffer( "valorout" );
897                         else
898                                 numero = cursorSecs.valueBuffer( "valor" );
899                         cursorSecs.setValueBuffer( "valorout", this.iface.establecerNumeroSecuencia( fN, numero ) );            
900                         cursorSecs.commitBuffer();
901                 }
902                 cursorSecs.setActivatedCheckIntegrity( true );
903         } else {
904                 /** \C
905                 Si la serie no existe para el ejercicio actual se consultará al usuario si la quiere crear
906                 \end */
907                 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);
908                 if (res != MessageBox.Yes) {
909                         cursorSecuencias.setActivatedCheckIntegrity(true);
910                         return false;
911                 }
912                 cursorSecuencias.setModeAccess(cursorSecuencias.Insert);
913                 cursorSecuencias.refreshBuffer();
914                 cursorSecuencias.setValueBuffer("codserie", codSerie);
915                 cursorSecuencias.setValueBuffer("codejercicio", codEjercicio);
916                 numero = "1";
917                 cursorSecuencias.setValueBuffer(fN, "2");
918                 if (!cursorSecuencias.commitBuffer()) {
919                         cursorSecuencias.setActivatedCheckIntegrity(true);
920                         return false;
921                 }
922         }
923         cursorSecuencias.setActivatedCheckIntegrity(true);
924         return numero;
927 /** \D
928 Agrega un hueco a la tabla de huecos
929 @param serie: Código de serie del documento
930 @param ejercicio: Código de ejercicio del documento
931 @param numero: Número del documento
932 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
933 @return true si el hueco se inserta correctamente o false si hay error
934 \end */
935 function oficial_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean
937         return this.iface.recalcularHuecos( serie, ejercicio, fN );
940 /* \D Indica si el asiento asociado a la factura puede o no regenerarse, según pertenezca a un ejercicio abierto o cerrado
941 @param idAsiento: Identificador del asiento
942 @return True: Asiento borrable, False: Asiento no borrable
943 \end */
944 function oficial_asientoBorrable(idAsiento:Number):Boolean
946         var util:FLUtil = new FLUtil();
947         var qryEjerAsiento:FLSqlQuery = new FLSqlQuery();
948         qryEjerAsiento.setTablesList("ejercicios,co_asientos");
949         qryEjerAsiento.setSelect("e.estado");
950         qryEjerAsiento.setFrom("co_asientos a INNER JOIN ejercicios e" +
951                         " ON a.codejercicio = e.codejercicio");
952         qryEjerAsiento.setWhere("a.idasiento = " + idAsiento);
953         try { qryEjerAsiento.setForwardOnly( true ); } catch (e) {}
955         if (!qryEjerAsiento.exec())
956                 return false;
958         if (!qryEjerAsiento.next())
959                 return false;
961         if (qryEjerAsiento.value(0) != "ABIERTO") {
962                 MessageBox.critical(util.translate("scripts",
963                 "No puede realizarse la modificación porque el asiento contable correspondiente pertenece a un ejercicio cerrado"),
964                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
965                 return false;
966         }
968         return true;
971 /** \U Genera o regenera el asiento correspondiente a una factura de cliente
972 @param  curFactura: Cursor con los datos de la factura
973 @return VERDADERO si no hay error. FALSO en otro caso
974 \end */
975 function oficial_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean
977         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
978                 return true;
980         var util:FLUtil = new FLUtil;
981         if (curFactura.valueBuffer("nogenerarasiento")) {
982                 curFactura.setNull("idasiento");
983                 return true;
984         }
986         if (!this.iface.comprobarRegularizacion(curFactura))
987                 return false;
989         var datosAsiento:Array = [];
990         var valoresDefecto:Array;
991         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
992         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
994         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
995         if (datosAsiento.error == true)
996                 return false;
998         var ctaCliente = this.iface.datosCtaCliente(curFactura, valoresDefecto);
999         if (ctaCliente.error != 0)
1000                 return false;
1002         if (!this.iface.generarPartidasCliente(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
1003                 return false;
1005         if (!this.iface.generarPartidasIRPF(curFactura, datosAsiento.idasiento, valoresDefecto))
1006                 return false;
1008         if (!this.iface.generarPartidasIVACli(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
1009                 return false;
1011         if (!this.iface.generarPartidasRecFinCli(curFactura, datosAsiento.idasiento, valoresDefecto))
1012                 return false;                           
1013                         
1014         if (!this.iface.generarPartidasVenta(curFactura, datosAsiento.idasiento, valoresDefecto))
1015                 return false;
1016     
1017         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1018         
1019         if (curFactura.valueBuffer("deabono") == true)
1020                 if (!this.iface.asientoFacturaAbonoCli(curFactura, valoresDefecto))
1021                         return false;
1023         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1024                 return false;
1026         return true;
1029 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de ventas
1030 @param  curFactura: Cursor de la factura
1031 @param  idAsiento: Id del asiento asociado
1032 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1033 @return VERDADERO si no hay error, FALSO en otro caso
1034 \end */
1035 function oficial_generarPartidasVenta(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1037                 var util:FLUtil = new FLUtil();
1038                 var ctaVentas:Array = this.iface.datosCtaVentas(valoresDefecto.codejercicio, curFactura.valueBuffer("codserie"));
1039                 if (ctaVentas.error != 0) {
1040                         MessageBox.warning(util.translate("scripts", "No se ha encontrado una subcuenta de ventas para esta factura."), MessageBox.Ok, MessageBox.NoButton);
1041                         return false;
1042                 }
1043                 var haber:Number = 0;
1044                 var haberME:Number = 0;
1045                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1046                 if (monedaSistema) {
1047                                 haber = this.iface.netoVentasFacturaCli(curFactura);
1048                                 haberME = 0;
1049                 } else {
1050                                 haber = util.sqlSelect("co_partidas", "SUM(debe - haber)", "idasiento = " + idAsiento);
1051                                 haberME = curFactura.valueBuffer("neto");
1052                 }
1053                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1054                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1056                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1057                 with (curPartida) {
1058                                 setModeAccess(curPartida.Insert);
1059                                 refreshBuffer();
1060                                 setValueBuffer("idsubcuenta", ctaVentas.idsubcuenta);
1061                                 setValueBuffer("codsubcuenta", ctaVentas.codsubcuenta);
1062                                 setValueBuffer("idasiento", idAsiento);
1063                                 setValueBuffer("debe", 0);
1064                                 setValueBuffer("haber", haber);
1065                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1066                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1067                                 setValueBuffer("debeME", 0);
1068                                 setValueBuffer("haberME", haberME);
1069                 }
1070                 
1071                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1072                 
1073                 if (!curPartida.commitBuffer())
1074                                 return false;
1075                 return true;
1078 function oficial_netoVentasFacturaCli(curFactura:FLSqlCursor):Number
1080         return parseFloat(curFactura.valueBuffer("neto"));
1083 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IVA y de recargo de equivalencia, si la factura lo tiene
1084 @param  curFactura: Cursor de la factura
1085 @param  idAsiento: Id del asiento asociado
1086 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1087 @param  ctaCliente: Array con los datos de la contrapartida
1088 @return VERDADERO si no hay error, FALSO en otro caso
1089 \end */
1090 function oficial_generarPartidasIVACli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1092         var util:FLUtil = new FLUtil();
1093         var haber:Number = 0;
1094         var haberME:Number = 0;
1095         var baseImponible:Number = 0;
1096         
1097         var regimenIVA:String = util.sqlSelect("clientes","regimeniva","codcliente = '" + curFactura.valueBuffer("codcliente") + "'");
1098         
1099         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1100         var qryIva:FLSqlQuery = new FLSqlQuery();
1101         qryIva.setTablesList("lineasivafactcli");
1102         qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");
1103         qryIva.setFrom("lineasivafactcli");
1104         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1105         try { qryIva.setForwardOnly( true ); } catch (e) {}
1106         if (!qryIva.exec())
1107                 return false;
1109         while (qryIva.next()) {
1110                 if (monedaSistema) {
1111                         haber = parseFloat(qryIva.value(2));
1112                         haberME = 0;
1113                         baseImponible = parseFloat(qryIva.value(0));
1114                 } else {
1115                         haber = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1116                         haberME = parseFloat(qryIva.value(2));
1117                         baseImponible = parseFloat(qryIva.value(0))  * parseFloat(curFactura.valueBuffer("tasaconv"));
1118                 }
1119                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1120                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1121                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1123                 var ctaIvaRep:Array;
1124                 if (regimenIVA == "U.E.") {
1125                         ctaIvaRep = this.iface.datosCtaIVA("IVAEUE", valoresDefecto.codejercicio, qryIva.value(5));
1126                 } else {
1127                         ctaIvaRep = this.iface.datosCtaIVA("IVAREP", valoresDefecto.codejercicio, qryIva.value(5));
1128                 }
1129                 if (ctaIvaRep.error != 0)
1130                         return false;
1131                 
1132                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1133                 with (curPartida) {
1134                         setModeAccess(curPartida.Insert);
1135                         refreshBuffer();
1136                         setValueBuffer("idsubcuenta", ctaIvaRep.idsubcuenta);
1137                         setValueBuffer("codsubcuenta", ctaIvaRep.codsubcuenta);
1138                         setValueBuffer("idasiento", idAsiento);
1139                         setValueBuffer("debe", 0);
1140                         setValueBuffer("haber", haber);
1141                         setValueBuffer("baseimponible", baseImponible);
1142                         setValueBuffer("iva", qryIva.value(1));
1143                         setValueBuffer("recargo", qryIva.value(3));
1144                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1145                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1146                         setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1147                         setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1148                         setValueBuffer("debeME", 0);
1149                         setValueBuffer("haberME", haberME);
1150                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1151                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1152                 }
1153                 
1154                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1155                 
1156                 if (!curPartida.commitBuffer())
1157                         return false;
1159                 if (monedaSistema) {
1160                         haber = parseFloat(qryIva.value(4));
1161                         haberME = 0;
1162                 } else {
1163                         haber = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1164                         haberME = parseFloat(qryIva.value(4));
1165                 }
1166                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1167                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1169                 if (parseFloat(haber) != 0) {
1170                         var ctaRecargo = this.iface.datosCtaIVA("IVAACR", valoresDefecto.codejercicio, qryIva.value(5));
1171                         if (ctaRecargo.error != 0)
1172                                 return false;
1173                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1174                         with (curPartida) {
1175                                 setModeAccess(curPartida.Insert);
1176                                 refreshBuffer();
1177                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1178                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1179                                 setValueBuffer("idasiento", idAsiento);
1180                                 setValueBuffer("debe", 0);
1181                                 setValueBuffer("haber", haber);
1182                                 setValueBuffer("baseimponible", baseImponible);
1183                                 setValueBuffer("iva", qryIva.value(1));
1184                                 setValueBuffer("recargo", qryIva.value(3));
1185                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1186                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1187                                 setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1188                                 setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1189                                 setValueBuffer("debeME", 0);
1190                                 setValueBuffer("haberME", haberME);
1191                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1192                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1193                         }
1194                         
1195                         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1196                         
1197                         if (!curPartida.commitBuffer())
1198                                 return false;
1199                 }
1200         }
1201         return true;
1204 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF, si la factura lo tiene
1205 @param  curFactura: Cursor de la factura
1206 @param  idAsiento: Id del asiento asociado
1207 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1208 @return VERDADERO si no hay error, FALSO en otro caso
1209 \end */
1210 function oficial_generarPartidasIRPF(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1212                 var util:FLUtil = new FLUtil();
1213                 var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1214                 if (irpf == 0)
1215                                 return true;
1216                 var debe:Number = 0;
1217                 var debeME:Number = 0;
1218                 var ctaIrpf:Array = this.iface.datosCtaEspecial("IRPF", valoresDefecto.codejercicio);
1219                 if (ctaIrpf.error != 0) {
1220                         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);
1221                         return false;
1222                 }
1224                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1225                 if (monedaSistema) {
1226                                 debe = irpf;
1227                                 debeME = 0;
1228                 } else {
1229                                 debe = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1230                                 debeME = irpf;
1231                 }
1232                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1233                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1235                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1236                 with (curPartida) {
1237                                 setModeAccess(curPartida.Insert);
1238                                 refreshBuffer();
1239                                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1240                                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1241                                 setValueBuffer("idasiento", idAsiento);
1242                                 setValueBuffer("debe", debe);
1243                                 setValueBuffer("haber", 0);
1244                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1245                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1246                                 setValueBuffer("debeME", debeME);
1247                                 setValueBuffer("haberME", 0);
1248                 }
1249                 
1250                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1251                 
1252                 if (!curPartida.commitBuffer())
1253                                 return false;
1255                 return true;
1258 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para clientes, si la factura lo tiene
1259 @param  curFactura: Cursor de la factura
1260 @param  idAsiento: Id del asiento asociado
1261 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1262 @return VERDADERO si no hay error, FALSO en otro caso
1263 \end */
1264 function oficial_generarPartidasRecFinCli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1266         var util:FLUtil = new FLUtil();
1267         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
1268         if (!recFinanciero)
1269                 return true;
1270         var haber:Number = 0;
1271         var haberME:Number = 0;
1273         var ctaRecfin:Array = [];
1274         ctaRecfin = this.iface.datosCtaEspecial("INGRF", valoresDefecto.codejercicio);
1275         if (ctaRecfin.error != 0) {
1276                 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);
1277                 return false;
1278         }
1280         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1281         if (monedaSistema) {
1282                 haber = recFinanciero;
1283                 haberME = 0;
1284         } else {
1285                 haber = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
1286                 haberME = recFinanciero;
1287         }
1288         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1289         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1291         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1292         with (curPartida) {
1293                 setModeAccess(curPartida.Insert);
1294                 refreshBuffer();
1295                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
1296                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
1297                 setValueBuffer("idasiento", idAsiento);
1298                 setValueBuffer("haber", haber);
1299                 setValueBuffer("debe", 0);
1300                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1301                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1302                 setValueBuffer("haberME", haberME);
1303                 setValueBuffer("debeME", 0);
1304         }
1305         
1306         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1307         
1308         if (!curPartida.commitBuffer())
1309                         return false;
1311         return true;
1314 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF para proveedores, si la factura lo tiene
1315 @param  curFactura: Cursor de la factura
1316 @param  idAsiento: Id del asiento asociado
1317 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1318 @return VERDADERO si no hay error, FALSO en otro caso
1319 \end */
1320 function oficial_generarPartidasIRPFProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1322         var util:FLUtil = new FLUtil();
1323         var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1324         if (irpf == 0)
1325                         return true;
1326         var haber:Number = 0;
1327         var haberME:Number = 0;
1329         var ctaIrpf:Array = [];
1330         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");
1331         if (ctaIrpf.codsubcuenta) {
1332                 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");
1333                 if (hayDistintasSubcuentas) {
1334                         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);
1335                         return false;
1336                 }
1337                 ctaIrpf.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta", "codsubcuenta = '" + ctaIrpf.codsubcuenta + "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1338                 if (!ctaIrpf.idsubcuenta) {
1339                         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);
1340                         return false;
1341                 }
1342         } else {
1343                 ctaIrpf = this.iface.datosCtaEspecial("IRPFPR", valoresDefecto.codejercicio);
1344                 if (ctaIrpf.error != 0) {
1345                         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);
1346                         return false;
1347                 }
1348         }
1350         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1351         if (monedaSistema) {
1352                 haber = irpf;
1353                 haberME = 0;
1354         } else {
1355                 haber = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1356                 haberME = irpf;
1357         }
1358         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1359         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1361         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1362         with (curPartida) {
1363                 setModeAccess(curPartida.Insert);
1364                 refreshBuffer();
1365                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1366                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1367                 setValueBuffer("idasiento", idAsiento);
1368                 setValueBuffer("debe", 0);
1369                 setValueBuffer("haber", haber);
1370                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1371                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1372                 setValueBuffer("debeME", 0);
1373                 setValueBuffer("haberME", haberME);
1374         }
1375         
1376         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1377         
1378         if (!curPartida.commitBuffer())
1379                         return false;
1381         return true;
1385 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de clientes
1386 @param  curFactura: Cursor de la factura
1387 @param  idAsiento: Id del asiento asociado
1388 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1389 @param  ctaCliente: Datos de la subcuenta del cliente asociado a la factura
1390 @return VERDADERO si no hay error, FALSO en otro caso
1391 \end */
1392 function oficial_generarPartidasCliente(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1394                 var util:FLUtil = new FLUtil();
1395                 var debe:Number = 0;
1396                 var debeME:Number = 0;
1397                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1398                 if (monedaSistema) {
1399                                 debe = parseFloat(curFactura.valueBuffer("total"));
1400                                 debeME = 0;
1401                 } else {
1402                                 debe = parseFloat(curFactura.valueBuffer("total")) * parseFloat(curFactura.valueBuffer("tasaconv"));
1403                                 debeME = parseFloat(curFactura.valueBuffer("total"));
1404                 }
1405                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1406                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1407                 
1408                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1409                 with (curPartida) {
1410                                 setModeAccess(curPartida.Insert);
1411                                 refreshBuffer();
1412                                 setValueBuffer("idsubcuenta", ctaCliente.idsubcuenta);
1413                                 setValueBuffer("codsubcuenta", ctaCliente.codsubcuenta);
1414                                 setValueBuffer("idasiento", idAsiento);
1415                                 setValueBuffer("debe", debe);
1416                                 setValueBuffer("haber", 0);
1417                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1418                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1419                                 setValueBuffer("debeME", debeME);
1420                                 setValueBuffer("haberME", 0);
1421                 }
1422                 
1423                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1424                 
1425                 if (!curPartida.commitBuffer())
1426                                 return false;
1428                 return true;
1431 /** \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.
1432 @param  curFactura: Cursor posicionado en el registro de factura
1433 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1434 @return array con los siguientes datos:
1435 asiento.idasiento: Id del asiento
1436 asiento.numero: numero del asiento
1437 asiento.fecha: fecha del asiento
1438 asiento.error: indicador booleano de que ha habido un error en la función
1439 \end */
1440 function oficial_regenerarAsiento(curFactura:FLSqlCursor, valoresDefecto:Array):Array
1442         var util:FLUtil = new FLUtil;
1443         var asiento:Array = [];
1444         var idAsiento:Number = curFactura.valueBuffer("idasiento");
1445         if (curFactura.isNull("idasiento")) {
1446                 var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1447                 //var numAsiento:Number = util.sqlSelect("co_asientos", "MAX(numero)",  "codejercicio = '" + valoresDefecto.codejercicio + "'");
1448                 //numAsiento++;
1449                 with (curAsiento) {
1450                         setModeAccess(curAsiento.Insert);
1451                         refreshBuffer();
1452                         setValueBuffer("numero", 0);
1453                         setValueBuffer("fecha", curFactura.valueBuffer("fecha"));
1454                         setValueBuffer("codejercicio", valoresDefecto.codejercicio);
1455                 }
1456                 if (!curAsiento.commitBuffer()) {
1457                         asiento.error = true;
1458                         return asiento;
1459                 }
1460                 asiento.idasiento = curAsiento.valueBuffer("idasiento");
1461                 asiento.numero = curAsiento.valueBuffer("numero");
1462                 asiento.fecha = curAsiento.valueBuffer("fecha");
1463                 curAsiento.select("idasiento = " + asiento.idasiento);
1464                 curAsiento.first();
1465                 curAsiento.setUnLock("editable", false);
1466         } else {
1467                 if (!this.iface.asientoBorrable(idAsiento)) {
1468                         asiento.error = true;
1469                         return asiento;
1470                 }
1472                 if (curFactura.valueBuffer("fecha") != curFactura.valueBufferCopy("fecha")) {
1473                         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1474                         curAsiento.select("idasiento = " + idAsiento);
1475                         if (!curAsiento.first()) {
1476                                 asiento.error = true;
1477                                 return asiento;
1478                         }
1479                         curAsiento.setUnLock("editable", true);
1481                         curAsiento.select("idasiento = " + idAsiento);
1482                         if (!curAsiento.first()) {
1483                                 asiento.error = true;
1484                                 return asiento;
1485                         }
1486                         curAsiento.setModeAccess(curAsiento.Edit);
1487                         curAsiento.refreshBuffer();
1488                         curAsiento.setValueBuffer("fecha", curFactura.valueBuffer("fecha"));
1490                         if (!curAsiento.commitBuffer()) {
1491                                 asiento.error = true;
1492                                 return asiento;
1493                         }
1494                         curAsiento.select("idasiento = " + idAsiento);
1495                         if (!curAsiento.first()) {
1496                                 asiento.error = true;
1497                                 return asiento;
1498                         }
1499                         curAsiento.setUnLock("editable", false);
1500                 }
1502                 asiento = flfactppal.iface.pub_ejecutarQry("co_asientos", "idasiento,numero,fecha,codejercicio", "idasiento = '" + idAsiento + "'");
1503                 if (asiento.codejercicio != valoresDefecto.codejercicio) {
1504                         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);
1505                         asiento.error = true;
1506                         return asiento;
1507                 }
1508                 var curPartidas = new FLSqlCursor("co_partidas");
1509                 curPartidas.select("idasiento = " + idAsiento);
1510                 while (curPartidas.next()) {
1511                         curPartidas.setModeAccess(curPartidas.Del);
1512                         curPartidas.refreshBuffer();
1513                         if (!curPartidas.commitBuffer()) {
1514                                 asiento.error = true;
1515                                 return asiento;
1516                         }
1517                 }
1518         }
1520         asiento.error = false;
1521         return asiento;
1524 function oficial_eliminarAsiento(idAsiento:String):Boolean
1526         var util:FLUtil = new FLUtil;
1527         if (!idAsiento || idAsiento == "")
1528                 return true;
1530         if (!this.iface.asientoBorrable(idAsiento))
1531                 return false;
1533         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1534         curAsiento.select("idasiento = " + idAsiento);
1535         if (!curAsiento.first())
1536                 return false;
1538         curAsiento.setUnLock("editable", true);
1539         if (!util.sqlDelete("co_asientos", "idasiento = " + idAsiento)) {
1540                 curAsiento.setValueBuffer("idasiento", idAsiento);
1541                 return false;
1542         }
1543         return true;
1546 /** \U Genera o regenera el asiento correspondiente a una factura de proveedor
1547 @param  curFactura: Cursor con los datos de la factura
1548 @return VERDADERO si no hay error. FALSO en otro caso
1549 \end */
1550 /** \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.
1551 \end */
1552 function oficial_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean
1554         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
1555                 return true;
1557         var util:FLUtil = new FLUtil;
1558         if (curFactura.valueBuffer("nogenerarasiento")) {
1559                 curFactura.setNull("idasiento");
1560                 return true;
1561         }
1563         if (!this.iface.comprobarRegularizacion(curFactura))
1564                 return false;
1566         var util:FLUtil = new FLUtil();
1567         var datosAsiento:Array = [];
1568         var valoresDefecto:Array;
1569         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
1570         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
1572         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
1573         if (datosAsiento.error == true)
1574                 return false;
1576         var numProveedor:String = curFactura.valueBuffer("numproveedor");
1577         var concepto:String;
1578         if (!numProveedor || numProveedor == "")
1579                 concepto = util.translate("scripts", "Su factura ") + curFactura.valueBuffer("codigo");
1580         else
1581                 concepto = util.translate("scripts", "Su factura ") + numProveedor;
1582         concepto += " - " + curFactura.valueBuffer("nombre");
1584         var ctaProveedor:Array = this.iface.datosCtaProveedor(curFactura, valoresDefecto);
1585         if (ctaProveedor.error != 0)
1586                 return false;
1588         // Las partidas generadas dependen del régimen de IVA del proveedor
1589         var regimenIVA:String = util.sqlSelect("proveedores", "regimeniva", "codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1590         
1591         switch(regimenIVA) {
1592                 case "UE":
1593                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1594                                 return false;
1595                                 
1596                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1597                                 return false;
1598                 
1599                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1600                                 return false;                           
1601                         
1602                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1603                                 return false;
1604                 
1605                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1606                                 return false;
1607                 break;
1608                 
1609                 case "Exento":
1610                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1611                                 return false;
1612                                 
1613                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1614                                 return false;                           
1615                         
1616                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1617                                 return false;
1618                 
1619                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1620                                 return false;
1621                 break;
1622                 
1623                 default:
1624                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1625                                 return false;
1626                                 
1627                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1628                                 return false;
1629                 
1630                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1631                                 return false;                           
1632                         
1633                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1634                                 return false;
1635                 
1636                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1637                                 return false;
1638         }
1639                 
1640         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1641                 
1642         if (curFactura.valueBuffer("deabono") == true)
1643                 if (!this.iface.asientoFacturaAbonoProv(curFactura, valoresDefecto))
1644                         return false;
1646         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1647                 return false;
1649         return true;
1652 /** \D Genera la parte del asiento de factura de proveedor correspondiente a la subcuenta de compras
1653 @param  curFactura: Cursor de la factura
1654 @param  idAsiento: Id del asiento asociado
1655 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1656 @param  concepto: Concepto de la partida
1657 @return VERDADERO si no hay error, FALSO en otro caso
1658 \end */
1659 function oficial_generarPartidasCompra(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, concepto:String):Boolean
1661                 var ctaCompras:Array = [];
1662                 var util:FLUtil = new FLUtil();
1663                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1664                 var debe:Number = 0;
1665                 var debeME:Number = 0;
1666                 var idUltimaPartida:Number = 0;
1668                 /** \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
1669                 \end */
1670                 var qrySubcuentas:FLSqlQuery = new FLSqlQuery();
1671                 with (qrySubcuentas) {
1672                                 setTablesList("lineasfacturasprov");
1673                                 setSelect("codsubcuenta, SUM(pvptotal)");
1674                                 setFrom("lineasfacturasprov");
1675                                 setWhere("idfactura = " + curFactura.valueBuffer("idfactura") +
1676                                                 " GROUP BY codsubcuenta");
1677                 }
1678                 try { qrySubcuentas.setForwardOnly( true ); } catch (e) {}
1679                 
1680                 if (!qrySubcuentas.exec())
1681                                 return false;
1682                 while (qrySubcuentas.next()) {
1683                                 if (qrySubcuentas.value(0) == "" || !qrySubcuentas.value(0)) {
1684                                                 ctaCompras = this.iface.datosCtaEspecial("COMPRA", valoresDefecto.codejercicio);
1685                                                 if (ctaCompras.error != 0)
1686                                                                 return false;
1687                                 } else {
1688                                                 ctaCompras.codsubcuenta = qrySubcuentas.value(0);
1689                                                 ctaCompras.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta",
1690                                                                 "codsubcuenta = '" + qrySubcuentas.value(0) +
1691                                                                 "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1692                                                 if (!ctaCompras.idsubcuenta) {
1693                                                                 MessageBox.warning(util.translate("scripts", "No existe la subcuenta ")  + ctaCompras.codsubcuenta +
1694                                                                                 util.translate("scripts", " correspondiente al ejercicio ") + valoresDefecto.codejercicio +
1695                                                                                 util.translate("scripts", ".\nPara poder crear la factura debe crear antes esta subcuenta"),
1696                                                                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1697                                                                 return false;
1698                                                 }
1699                                 }
1701                                 if (monedaSistema) {
1702                                                 debe = parseFloat(qrySubcuentas.value(1));
1703                                                 debeME = 0;
1704                                 } else {
1705                                                 debe = parseFloat(qrySubcuentas.value(1)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1706                                                 debeME = parseFloat(qrySubcuentas.value(1));
1707                                 }
1708                                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1709                                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1710                                 
1711                                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1712                                 with (curPartida) {
1713                                                 setModeAccess(curPartida.Insert);
1714                                                 refreshBuffer();
1715                                                 setValueBuffer("idsubcuenta", ctaCompras.idsubcuenta);
1716                                                 setValueBuffer("codsubcuenta", ctaCompras.codsubcuenta);
1717                                                 setValueBuffer("idasiento", idAsiento);
1718                                                 setValueBuffer("debe", debe);
1719                                                 setValueBuffer("haber", 0);
1720                                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1721                                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1722                                                 setValueBuffer("debeME", debeME);
1723                                                 setValueBuffer("haberME", 0);
1724                                 }
1725                                 
1726                                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
1727                                 
1728                                 if (!curPartida.commitBuffer())
1729                                                 return false;
1730                                 idUltimaPartida = curPartida.valueBuffer("idpartida");
1731                 }
1733                 /** \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.
1734                 \end */
1735                 if (!monedaSistema) {
1736                         debe = parseFloat(util.sqlSelect("co_partidas", "SUM(haber - debe)", "idasiento = " + idAsiento + " AND idpartida <> " + idUltimaPartida));
1737                         if (debe && !isNaN(debe) && debe != 0) {
1738                                 debe = parseFloat(util.roundFieldValue(debe, "co_partidas", "debe"));
1739                                 if (!util.sqlUpdate("co_partidas", "debe", debe, "idpartida = " + idUltimaPartida))
1740                                                 return false;
1741                         }
1742                 }
1744                 return true;
1747 /** \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
1748 @param  curFactura: Cursor de la factura
1749 @param  idAsiento: Id del asiento asociado
1750 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1751 @param  ctaProveedor: Array con los datos de la contrapartida
1752 @param  concepto: Concepto de la partida
1753 @return VERDADERO si no hay error, FALSO en otro caso
1754 \end */
1755 function oficial_generarPartidasIVAProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String):Boolean
1757         var util:FLUtil = new FLUtil();
1758         var haber:Number = 0;
1759         var haberME:Number = 0;
1760         var baseImponible:Number = 0;
1761         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1762         
1763         var regimenIVA:String = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1764         var codCuentaEspIVA:String;
1765         
1766         var qryIva:FLSqlQuery = new FLSqlQuery();
1767         qryIva.setTablesList("lineasivafactprov");
1768         
1769         if (regimenIVA == "UE")
1770                 qryIva.setSelect("neto, iva, neto*iva/100, recargo, neto*recargo/100, codimpuesto");
1771         else
1772                 qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");    
1773         
1774         qryIva.setFrom("lineasivafactprov");
1775         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1776         try { qryIva.setForwardOnly( true ); } catch (e) {}
1777         if (!qryIva.exec())
1778                 return false;
1780                 
1781         while (qryIva.next()) {
1782                 if (monedaSistema) {
1783                         debe = parseFloat(qryIva.value(2));
1784                         debeME = 0;
1785                         baseImponible = parseFloat(qryIva.value(0));
1786                 } else {
1787                         debe = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1788                         debeME = parseFloat(qryIva.value(2));
1789                         baseImponible = parseFloat(qryIva.value(0)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1790                 }
1791                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1792                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1793                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1794                 
1795                 switch(regimenIVA) {
1796                         case "UE":
1797                                 codCuentaEspIVA = "IVASUE";
1798                                 break;
1799                         case "General":
1800                         case "Exento":
1801                         case "Exportaciones":
1802                                 codCuentaEspIVA = "IVASOP";
1803                                 break;
1804                         default:
1805                                 codCuentaEspIVA = "IVASOP";
1806                 }
1807                 
1808                 var ctaIvaSop:Array = this.iface.datosCtaIVA(codCuentaEspIVA, valoresDefecto.codejercicio, qryIva.value(5));
1809                 if (ctaIvaSop.error != 0) {
1810                         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);
1811                         return false;
1812                 }
1813                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1814                 with (curPartida) {
1815                         setModeAccess(curPartida.Insert);
1816                         refreshBuffer();
1817                         setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1818                         setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1819                         setValueBuffer("idasiento", idAsiento);
1820                         setValueBuffer("debe", debe);
1821                         setValueBuffer("haber", 0);
1822                         setValueBuffer("baseimponible", baseImponible);
1823                         setValueBuffer("iva", qryIva.value(1));
1824                         setValueBuffer("recargo", qryIva.value(3));
1825                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1826                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1827                         setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1828                         setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1829                         setValueBuffer("debeME", debeME);
1830                         setValueBuffer("haberME", 0);
1831                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1832                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1833                 }
1834                 
1835                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1836                 
1837                 if (!curPartida.commitBuffer())
1838                         return false;
1840                 
1841                 // Otra partida de haber de IVA sobre una cuenta 477 para compensar en UE
1842                 if (regimenIVA == "UE") {
1843                         
1844                         haber = debe;
1845                         haberME = debeME;
1846                         codCuentaEspIVA = "IVARUE";
1847                         var ctaIvaSop = this.iface.datosCtaIVA("IVARUE", valoresDefecto.codejercicio,qryIva.value(5));
1848 //                      var ctaIvaSop:Array = this.iface.datosCtaEspecial("IVARUE", valoresDefecto.codejercicio);
1849                         if (ctaIvaSop.error != 0) {
1850                                 return false;
1851                         }
1852                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1853                         with (curPartida) {
1854                                 setModeAccess(curPartida.Insert);
1855                                 refreshBuffer();
1856                                 setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1857                                 setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1858                                 setValueBuffer("idasiento", idAsiento);
1859                                 setValueBuffer("debe", 0);
1860                                 setValueBuffer("haber", haber);
1861                                 setValueBuffer("baseimponible", baseImponible);
1862                                 setValueBuffer("iva", qryIva.value(1));
1863                                 setValueBuffer("recargo", qryIva.value(3));
1864                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1865                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1866                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1867                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1868                                 setValueBuffer("debeME", 0);
1869                                 setValueBuffer("haberME", haberME);
1870                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1871                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1872                         }
1873                 
1874                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
1875                         
1876                         if (!curPartida.commitBuffer())
1877                                 return false;
1878                 }
1879                         
1880                 if (monedaSistema) {
1881                         debe = parseFloat(qryIva.value(4));
1882                         debeME = 0;
1883                 } else {
1884                         debe = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1885                         debeME = parseFloat(qryIva.value(4));
1886                 }
1887                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1888                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1890                 if (parseFloat(debe) != 0) {
1891                         var ctaRecargo:Array = this.iface.datosCtaIVA("IVADEU", valoresDefecto.codejercicio, qryIva.value(5));
1892                         if (ctaRecargo.error != 0)
1893                                 return false;
1894                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1895                         with (curPartida) {
1896                                 setModeAccess(curPartida.Insert);
1897                                 refreshBuffer();
1898                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1899                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1900                                 setValueBuffer("idasiento", idAsiento);
1901                                 setValueBuffer("debe", debe);
1902                                 setValueBuffer("haber", 0);
1903                                 setValueBuffer("baseimponible", baseImponible);
1904                                 setValueBuffer("iva", qryIva.value(1));
1905                                 setValueBuffer("recargo", qryIva.value(3));
1906                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1907                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1908                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1909                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1910                                 setValueBuffer("debeME", debeME);
1911                                 setValueBuffer("haberME", 0);
1912                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1913                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1914                         }
1915                 
1916                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
1917                         
1918                         if (!curPartida.commitBuffer())
1919                                 return false;
1920                 }
1921         }
1922         return true;
1925 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de proveedor
1926 @param  curFactura: Cursor de la factura
1927 @param  idAsiento: Id del asiento asociado
1928 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1929 @param  ctaCliente: Datos de la subcuenta del proveedor asociado a la factura
1930 @param  concepto: Concepto a asociar a la factura
1931 @return VERDADERO si no hay error, FALSO en otro caso
1932 \end */
1933 function oficial_generarPartidasProveedor(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String, sinIVA:Boolean):Boolean
1935                 var util:FLUtil = new FLUtil;
1936                 var haber:Number = 0;
1937                 var haberME:Number = 0;
1938                 var totalIVA:Number = 0;
1939                 
1940                 if (sinIVA)
1941                         totalIVA = parseFloat(curFactura.valueBuffer("totaliva"));
1942                 
1943                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1944                 if (monedaSistema) {
1945                                 haber = parseFloat(curFactura.valueBuffer("total"));
1946                                 haber -= totalIVA;
1947                                 haberME = 0;
1948                 } else {
1949                                 haber = (parseFloat(curFactura.valueBuffer("total")) - totalIVA) * parseFloat(curFactura.valueBuffer("tasaconv"));
1950                                 haberME = parseFloat(curFactura.valueBuffer("total"));
1951                 }
1952                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1953                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1955                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1956                 with (curPartida) {
1957                                 setModeAccess(curPartida.Insert);
1958                                 refreshBuffer();
1959                                 setValueBuffer("idsubcuenta", ctaProveedor.idsubcuenta);
1960                                 setValueBuffer("codsubcuenta", ctaProveedor.codsubcuenta);
1961                                 setValueBuffer("idasiento", idAsiento);
1962                                 setValueBuffer("debe", 0);
1963                                 setValueBuffer("haber", haber);
1964                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1965                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1966                                 setValueBuffer("debeME", 0);
1967                                 setValueBuffer("haberME", haberME);
1968                 }
1969                 
1970                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
1971                 
1972                 if (!curPartida.commitBuffer())
1973                                 return false;
1974                 return true;
1977 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para proveedores, si la factura lo tiene
1978 @param  curFactura: Cursor de la factura
1979 @param  idAsiento: Id del asiento asociado
1980 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1981 @return VERDADERO si no hay error, FALSO en otro caso
1982 \end */
1983 function oficial_generarPartidasRecFinProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1985         var util:FLUtil = new FLUtil();
1986         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
1987         if (!recFinanciero)
1988                 return true;
1989         var debe:Number = 0;
1990         var debeME:Number = 0;
1992         var ctaRecfin:Array = [];
1993         ctaRecfin = this.iface.datosCtaEspecial("GTORF", valoresDefecto.codejercicio);
1994         if (ctaRecfin.error != 0) {
1995                 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);
1996                 return false;
1997         }
1999         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
2000         if (monedaSistema) {
2001                 debe = recFinanciero;
2002                 debeME = 0;
2003         } else {
2004                 debe = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
2005                 debeME = recFinanciero;
2006         }
2007         debe = util.roundFieldValue(debe, "co_partidas", "debe");
2008         debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2010         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
2011         with (curPartida) {
2012                 setModeAccess(curPartida.Insert);
2013                 refreshBuffer();
2014                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
2015                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
2016                 setValueBuffer("idasiento", idAsiento);
2017                 setValueBuffer("debe", debe);
2018                 setValueBuffer("haber", 0);
2019                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
2020                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
2021                 setValueBuffer("debeME", debeME);
2022                 setValueBuffer("haberME", 0);
2023         }
2024                 
2025         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
2026         
2027         if (!curPartida.commitBuffer())
2028                         return false;
2030         return true;
2033 /* \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.
2034 @param ctaEsp: Tipo de cuenta especial
2035 @codEjercicio: Código de ejercicio
2036 @return Los datos componen un vector de tres valores:
2037 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2038 idsubcuenta: Identificador de la subcuenta
2039 codsubcuenta: Código de la subcuenta
2040 \end */
2041 function oficial_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array
2043         var datos:Array = [];
2044         var q:FLSqlQuery = new FLSqlQuery();
2045         
2046         with(q) {
2047                 setTablesList("co_subcuentas,co_cuentasesp");
2048                 setSelect("s.idsubcuenta, s.codsubcuenta");
2049                 setFrom("co_cuentasesp ce INNER JOIN co_subcuentas s ON ce.codsubcuenta = s.codsubcuenta");
2050                 setWhere("idcuentaesp = '" + ctaEsp + "' AND s.codejercicio = '" + codEjercicio + "'  ORDER BY s.codsubcuenta");
2051         }
2052         try { q.setForwardOnly( true ); } catch (e) {}
2053         if (!q.exec()) {
2054                 datos["error"] = 2;
2055                 return datos;
2056         }
2057         if (q.next()) {
2058                 datos["error"] = 0;
2059                 datos["idsubcuenta"] = q.value(0);
2060                 datos["codsubcuenta"] = q.value(1);
2061                 return datos;
2062         }
2063         
2064         with(q) {
2065                 setTablesList("co_cuentas,co_subcuentas,co_cuentasesp");
2066                 setSelect("s.idsubcuenta, s.codsubcuenta");
2067                 setFrom("co_cuentasesp ce INNER JOIN co_cuentas c ON ce.codcuenta = c.codcuenta INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2068                 setWhere("ce.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2069         }
2070         try { q.setForwardOnly( true ); } catch (e) {}
2071         if (!q.exec()) {
2072                 datos["error"] = 2;
2073                 return datos;
2074         }
2075         if (q.next()) {
2076                 datos["error"] = 0;
2077                 datos["idsubcuenta"] = q.value(0);
2078                 datos["codsubcuenta"] = q.value(1);
2079                 return datos;
2080         }
2082         with(q) {
2083                 setTablesList("co_cuentas,co_subcuentas");
2084                 setSelect("s.idsubcuenta, s.codsubcuenta");
2085                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2086                 setWhere("c.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2087         }
2088         try { q.setForwardOnly( true ); } catch (e) {}
2089         if (!q.exec()) {
2090                 datos["error"] = 2;
2091                 return datos;
2092         }
2093         if (!q.next()) {
2094                 if (this.iface.consultarCtaEspecial(ctaEsp, codEjercicio)) {
2095                         return this.iface.datosCtaEspecial(ctaEsp, codEjercicio);
2096                 } else {
2097                         datos["error"] = 1;
2098                         return datos;
2099                 }
2100         }
2102         datos["error"] = 0;
2103         datos["idsubcuenta"] = q.value(0);
2104         datos["codsubcuenta"] = q.value(1);
2105         return datos;
2108 function oficial_consultarCtaEspecial(ctaEsp:String, codEjercicio:String):Boolean
2110         var util:FLUtil = new FLUtil;
2111         switch (ctaEsp) {
2112                 case "IVASUE": {
2113                         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);
2114                         if (res != MessageBox.Yes)
2115                                 return false;
2116                         return this.iface.crearCtaEspecial("IVASUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA soportado en adquisiciones intracomunitarias U.E."));
2117                         break;
2118                 }
2119                 case "IVARUE": {
2120                         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);
2121                         if (res != MessageBox.Yes)
2122                                 return false;
2123                         return this.iface.crearCtaEspecial("IVARUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA repercutido en adquisiciones intracomunitarias U.E."));
2124                         break;
2125                 }
2126                 case "IVAEUE": {
2127                         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);
2128                         if (res != MessageBox.Yes)
2129                                 return false;
2130                         return this.iface.crearCtaEspecial("IVAEUE", "subcuenta", codEjercicio, util.translate("scripts", "IVA en entregas intracomunitarias U.E."));
2131                         break;
2132                 }
2133                 default: {
2134                         return false;
2135                 }
2136         }
2137         return false;
2140 /* \D Devuelve el código e id de la subcuenta correspondiente a un impuesto y ejercicio determinados
2141 @param  ctaEsp: Tipo de cuenta (IVA soportado, repercutido, Recargo de equivalencia)
2143 @param  codEjercicio: Código de ejercicio
2144 @param  codImpuesto: Código de impuesto
2145 @return Los datos componen un vector de tres valores:
2146 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2147 idsubcuenta: Identificador de la subcuenta
2148 codsubcuenta: Código de la subcuenta
2149 \end */
2150 function oficial_datosCtaIVA(tipo:String, codEjercicio:String, codImpuesto:String):Array
2152                 if (!codImpuesto || codImpuesto == "")
2153                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2155                 var util:FLUtil = new FLUtil();
2156                 var datos:Array = [];
2157                 var codSubcuenta:String;
2158                 if (tipo == "IVAREP")
2159                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentarep", "codimpuesto = '" + codImpuesto + "'");
2160                 if (tipo == "IVASOP")
2161                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentasop", "codimpuesto = '" + codImpuesto + "'");
2162                 if (tipo == "IVAACR")
2163                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaacr", "codimpuesto = '" + codImpuesto + "'");
2164                 if (tipo == "IVADEU")
2165                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentadeu", "codimpuesto = '" + codImpuesto + "'");
2166                 if (tipo == "IVARUE")
2167                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadevadue", "codimpuesto = '" + codImpuesto + "'");
2168                 if (tipo == "IVASUE")
2169                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadedadue", "codimpuesto = '" + codImpuesto + "'");
2170                 if (tipo == "IVAEUE")
2171                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadeventue", "codimpuesto = '" + codImpuesto + "'");
2173                 if (!codSubcuenta || codSubcuenta == "") {
2174                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2175                 }
2177                 var q:FLSqlQuery = new FLSqlQuery();
2178                 with(q) {
2179                                 setTablesList("co_subcuentas");
2180                                 setSelect("idsubcuenta, codsubcuenta");
2181                                 setFrom("co_subcuentas");
2182                                 setWhere("codsubcuenta = '" + codSubcuenta + "' AND codejercicio = '" + codEjercicio + "'");
2183                 }
2184                 try { q.setForwardOnly( true ); } catch (e) {}
2185                 if (!q.exec()) {
2186                                 datos["error"] = 2;
2187                                 return datos;
2188                 }
2189                 if (!q.next()) {
2190                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2191                 }
2193                 datos["error"] = 0;
2194                 datos["idsubcuenta"] = q.value(0);
2195                 datos["codsubcuenta"] = q.value(1);
2196                 return datos;
2199 /* \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
2200 @param ctaEsp: Tipo de cuenta especial
2201 @param codEjercicio: Código de ejercicio
2202 @param codSerie: Código de serie de la factura
2203 @return Los datos componen un vector de tres valores:
2204 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2205 idsubcuenta: Identificador de la subcuenta
2206 codsubcuenta: Código de la subcuenta
2207 \end */
2208 function oficial_datosCtaVentas(codEjercicio:String, codSerie:String):Array
2210                 var util:FLUtil = new FLUtil();
2211                 var datos:Array = [];
2213                 var codCuenta:String = util.sqlSelect("series", "codcuenta", "codserie = '" + codSerie + "'");
2214                 if (codCuenta.toString().isEmpty())
2215                                 return this.iface.datosCtaEspecial("VENTAS", codEjercicio);
2217                 var q:FLSqlQuery = new FLSqlQuery();
2218                 with(q) {
2219                                 setTablesList("co_cuentas,co_subcuentas");
2220                                 setSelect("idsubcuenta, codsubcuenta");
2221                                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2222                                 setWhere("c.codcuenta = '" + codCuenta + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY codsubcuenta");
2223                 }
2224                 try { q.setForwardOnly( true ); } catch (e) {}
2225                 if (!q.exec()) {
2226                                 datos["error"] = 2;
2227                                 return datos;
2228                 }
2229                 if (!q.next()) {
2230                                 datos["error"] = 1;
2231                                 return datos;
2232                 }
2234                 datos["error"] = 0;
2235                 datos["idsubcuenta"] = q.value(0);
2236                 datos["codsubcuenta"] = q.value(1);
2237                 return datos;
2240 /* \D Devuelve el código e id de la subcuenta de cliente correspondiente a una  determinada factura
2241 @param curFactura: Cursor posicionado en la factura
2242 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2243 @return Los datos componen un vector de tres valores:
2244 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2245 idsubcuenta: Identificador de la subcuenta
2246 codsubcuenta: Código de la subcuenta
2247 \end */
2248 function oficial_datosCtaCliente(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2250         return flfactppal.iface.pub_datosCtaCliente( curFactura.valueBuffer("codcliente"), valoresDefecto );
2253 /* \D Devuelve el código e id de la subcuenta de proveedor correspondiente a una  determinada factura
2254 @param curFactura: Cursor posicionado en la factura
2255 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2256 @return Los datos componen un vector de tres valores:
2257 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2258 idsubcuenta: Identificador de la subcuenta
2259 codsubcuenta: Código de la subcuenta
2260 \end */
2261 function oficial_datosCtaProveedor(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2263         return flfactppal.iface.pub_datosCtaProveedor( curFactura.valueBuffer("codproveedor"), valoresDefecto );
2266 /* \D Regenera el asiento correspondiente a una factura de abono de cliente
2267 @param  curFactura: Cursor con los datos de la factura
2268 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2269 @return VERDADERO si no hay error. FALSO en otro caso
2270 \end */
2271 function oficial_asientoFacturaAbonoCli(curFactura:FLSqlCursor, valoresDefecto:Array)
2273         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2274     var idFactura:String = curFactura.valueBuffer("idfactura");
2275         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2276         var debe:Number = 0;
2277         var haber:Number = 0;
2278         var debeME:Number = 0;
2279         var haberME:Number = 0;
2280         var aux:Number;
2281         var util:FLUtil = new FLUtil;
2282         
2283         curPartidas.select("idasiento = '" + idAsiento + "'");
2284         while (curPartidas.next()) {
2285                 curPartidas.setModeAccess(curPartidas.Edit);
2286                 curPartidas.refreshBuffer();
2287                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2288                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2289                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2290                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2291                 aux = debe;
2292                 debe = haber * -1;
2293                 haber = aux * -1;
2294                 aux = debeME;
2295                 debeME = haberME * -1;
2296                 haberME = aux * -1;
2297                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2298                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2299                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2300                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2302                 curPartidas.setValueBuffer("debe",  debe);
2303                 curPartidas.setValueBuffer("haber", haber);
2304                 curPartidas.setValueBuffer("debeme",  debeME);
2305                 curPartidas.setValueBuffer("haberme", haberME);
2307                 if (!curPartidas.commitBuffer())
2308                         return false;
2309         }
2310         
2311         var ctaDevolVentas = this.iface.datosCtaEspecial("DEVVEN", valoresDefecto.codejercicio);
2312         if (ctaDevolVentas.error == 1) {
2313                 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);
2314                 return false;
2315         }
2316         if (ctaDevolVentas.error == 2)
2317                 return false;
2318         
2319         var qryPartidasVenta:FLSqlQuery = new FLSqlQuery();
2320         qryPartidasVenta.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2321         qryPartidasVenta.setSelect("p.idsubcuenta");
2322         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 ");
2323         qryPartidasVenta.setWhere("c.idcuentaesp = 'VENTAS' AND idasiento = " + idAsiento);
2324         try { qryPartidasVenta.setForwardOnly( true ); } catch (e) {}
2326         if (!qryPartidasVenta.exec())
2327                 return false;
2329         if (!qryPartidasVenta.next())
2330                 return false;
2331         
2332         
2333         var curPartidasVenta:FLSqlCursor = new FLSqlCursor("co_partidas");
2334         curPartidasVenta.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasVenta.value(0));
2335         curPartidasVenta.first();
2336         curPartidasVenta.setModeAccess(curPartidasVenta.Edit);
2337         curPartidasVenta.refreshBuffer();
2338         curPartidasVenta.setValueBuffer("idsubcuenta",  ctaDevolVentas.idsubcuenta);
2339         curPartidasVenta.setValueBuffer("codsubcuenta",  ctaDevolVentas.codsubcuenta);
2340         if (!curPartidasVenta.commitBuffer())
2341                         return false;
2342         return true;
2346 /* \D Regenera el asiento correspondiente a una factura de abono de proveedor
2347 @param  curFactura: Cursor con los datos de la factura
2348 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2349 @return VERDADERO si no hay error. FALSO en otro caso
2350 \end */
2351 function oficial_asientoFacturaAbonoProv(curFactura:FLSqlCursor, valoresDefecto:Array)
2353         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2354     var idFactura:String = curFactura.valueBuffer("idfactura");
2355         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2356         var debe:Number = 0;
2357         var haber:Number = 0;
2358         var debeME:Number = 0;
2359         var haberME:Number = 0;
2360         var aux:Number;
2361         
2362         var util:FLUtil = new FLUtil;
2363         
2364         curPartidas.select("idasiento = '" + idAsiento + "'");
2365         while (curPartidas.next()) {
2366                 curPartidas.setModeAccess(curPartidas.Edit);
2367                 curPartidas.refreshBuffer();
2368                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2369                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2370                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2371                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2372                 aux = debe;
2373                 debe = haber * -1;
2374                 haber = aux * -1;
2375                 aux = debeME;
2376                 debeME = haberME * -1;
2377                 haberME = aux * -1;
2378                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2379                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2380                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2381                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2383                 curPartidas.setValueBuffer("debe",  debe);
2384                 curPartidas.setValueBuffer("haber", haber);
2385                 curPartidas.setValueBuffer("debeme",  debeME);
2386                 curPartidas.setValueBuffer("haberme", haberME);
2387         }
2388         
2389         var ctaDevolCompra = this.iface.datosCtaEspecial("DEVCOM", valoresDefecto.codejercicio);
2390         if (ctaDevolCompra.error == 1) {
2391                 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);
2392                 return false;
2393         }
2394         if (ctaDevolCompra.error == 2)
2395                 return false;
2396         
2397         var qryPartidasCompra:FLSqlQuery = new FLSqlQuery();
2398         qryPartidasCompra.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2399         qryPartidasCompra.setSelect("p.idsubcuenta");
2400         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 ");
2401         qryPartidasCompra.setWhere("c.idcuentaesp = 'COMPRA' AND idasiento = " + idAsiento);
2402         try { qryPartidasCompra.setForwardOnly( true ); } catch (e) {}
2404         if (!qryPartidasCompra.exec())
2405                 return false;
2407         if (!qryPartidasCompra.next())
2408                 return false;
2409         
2410         
2411         var curPartidasCompra:FLSqlCursor = new FLSqlCursor("co_partidas");
2412         curPartidasCompra.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasCompra.value(0));
2413         curPartidasCompra.first();
2414         curPartidasCompra.setModeAccess(curPartidasCompra.Edit);
2415         curPartidasCompra.refreshBuffer();
2416         curPartidasCompra.setValueBuffer("idsubcuenta",  ctaDevolCompra.idsubcuenta);
2417         curPartidasCompra.setValueBuffer("codsubcuenta",  ctaDevolCompra.codsubcuenta);
2418         if (!curPartidasCompra.commitBuffer())
2419                         return false;
2420         return true;
2423 /** \D Si la fecha no está dentro del ejercicio, propone al usuario la selección de uno nuevo
2424 @param  fecha: Fecha del documento
2425 @param  codEjercicio: Ejercicio del documento
2426 @param  tipoDoc: Tipo de documento a generar
2427 @return Devuelve un array con los siguientes datos:
2428 ok:     Indica si la función terminó correctamente (true) o con error (false)
2429 modificaciones: Indica si se ha modificado algún valor (fecha o ejercicio)
2430 fecha: Nuevo valor para la fecha modificada
2431 codEjercicio: Nuevo valor para el ejercicio modificado
2432 \end */
2433 function oficial_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array
2435         
2436         var res:Array = [];
2437         res["ok"] = true;
2438         res["modificaciones"] = false;
2439         
2440         var util:FLUtil = new FLUtil;
2441         if (util.sqlSelect("ejercicios", "codejercicio", "codejercicio = '" + codEjercicio + "' AND '" + fecha + "' BETWEEN fechainicio AND fechafin"))
2442                 return res;
2443                 
2444         var f:Object = new FLFormSearchDB("fechaejercicio");
2445         var cursor:FLSqlCursor = f.cursor();
2446         
2447         cursor.select();
2448         if (!cursor.first())
2449                 cursor.setModeAccess(cursor.Insert);
2450         else
2451                 cursor.setModeAccess(cursor.Edit);
2452         cursor.refreshBuffer();
2454         cursor.refreshBuffer();
2455         cursor.setValueBuffer("fecha", fecha);
2456         cursor.setValueBuffer("codejercicio", codEjercicio);
2457         cursor.setValueBuffer("label", tipoDoc);
2458         cursor.commitBuffer();
2459         cursor.select();
2461         if (!cursor.first()) {
2462                 res["ok"] = false;
2463                 return res;
2464         }
2466         cursor.setModeAccess(cursor.Edit);
2467         cursor.refreshBuffer();
2469         f.setMainWidget();
2470         
2471         var acpt:String = f.exec("codejercicio");
2472         if (!acpt) {
2473                 res["ok"] = false;
2474                 return res;
2475         }
2476         res["modificaciones"] = true;
2477         res["fecha"] = cursor.valueBuffer("fecha");
2478         res["codEjercicio"] = cursor.valueBuffer("codejercicio");
2479         
2480         if (res.codEjercicio != flfactppal.iface.pub_ejercicioActual()) {
2481                 if (tipoDoc != "pagosdevolcli" && tipoDoc != "pagosdevolprov") {
2482                         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);
2483                 }
2484         }
2485         
2486         return res;
2489 /** \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
2490 @param  codSerie: Serie del documento
2491 @param  codCliente: Código del cliente
2492 @return Devuelve 3 posibles valores:
2493         0: Si no debe tener ni IVA ni recargo de equivalencia,
2494         1: Si debe tener IVA pero no recargo de equivalencia,
2495         2: Si debe tener IVA y recargo de equivalencia
2496 \end */
2497 function oficial_tieneIvaDocCliente(codSerie:String, codCliente:String):Number
2499         var util:FLUtil = new FLUtil;
2500         var conIva:Boolean = true;
2501         
2502         if (util.sqlSelect("series", "siniva", "codserie = '" + codSerie + "'"))
2503                 return 0;
2504         else {
2505                 var regIva:String = util.sqlSelect("clientes", "regimeniva", "codcliente = '" + codCliente + "'");
2506                 if (regIva == "Exento")
2507                         return 0;
2508                 else
2509                         if (!util.sqlSelect("clientes", "recargo", "codcliente = '" + codCliente + "'"))
2510                                 return 1;
2511         }
2512         
2513         return 2;
2517 /** \D Indica si el módulo de autómata está instalado y activado
2518 @return true si está activado, false en caso contrario
2519 \end */
2520 function oficial_automataActivado():Boolean
2522         if (!sys.isLoadedModule("flautomata"))
2523                 return false;
2524         
2525         if (formau_automata.iface.pub_activado())
2526                 return true;
2527         
2528         return false;
2531 /** \D Comprueba que si la factura tiene IVA, no esté incluida en un período de regularización ya cerrado
2532 @param  curFactura: Cursor de la factura de cliente o proveedor
2533 @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
2534 \end */
2535 function oficial_comprobarRegularizacion(curFactura:FLSqlCursor):Boolean
2537         var util:FLUtil = new FLUtil;
2539         var fecha:String = curFactura.valueBuffer("fecha");
2540         if (util.sqlSelect("co_regiva", "idregiva", "fechainicio <= '" + fecha + "' AND fechafin >= '" + fecha + "' AND codejercicio = '" + curFactura.valueBuffer("codejercicio") + "'")) {
2541                 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);
2542                 return false;
2543         }
2544         return true;
2547 /** \D
2548 Recalcula la tabla huecos y el último valor de la secuencia de numeración.
2549 @param serie: Código de serie del documento
2550 @param ejercicio: Código de ejercicio del documento
2551 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
2552 @return true si el calculo se ralizó correctamente
2553 \end */
2554 function oficial_recalcularHuecos( serie:String, ejercicio:String, fN:String ):Boolean {
2555         var util:FLUtil = new FLUtil;
2556         var tipo:String;
2557         var tabla:String;
2559         if ( fN == "nfacturaprov" ) {
2560                 tipo = "FP";
2561                 tabla = "facturasprov"
2562         } else if (fN == "nfacturacli") {
2563                 tipo = "FC";
2564                 tabla = "facturascli";
2565         }
2567         var idSec = util.sqlSelect( "secuenciasejercicios", "id", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2569         if ( idSec ) {
2570                 var nHuecos:Number = parseInt( util.sqlSelect( "huecos", "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND tipo = '" + tipo + "'" ) );
2571                 var nFacturas:Number = parseInt( util.sqlSelect( tabla, "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" ) );
2572                 var maxFactura:Number = parseInt( util.sqlSelect( "secuencias", "valorout", "id = " + idSec + " AND nombre='" + fN + "'" ) ) - 1;
2573                 if (isNaN(maxFactura))
2574                         maxFactura = 0;
2576                 if ( maxFactura - nFacturas != nHuecos ) {
2577                         var nSec:Number = 0;
2578                         var nFac:Number = 0;
2579                         var ultFac:Number = -1;
2580                         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
2581                         var qryFac:FLSqlQuery = new FLSqlQuery();
2583                         util.createProgressDialog( util.translate( "scripts", "Calculando huecos en la numeración..." ), maxFactura );
2585                         qryFac.setTablesList( tabla );
2586                         qryFac.setSelect( "numero" );
2587                         qryFac.setFrom( tabla );
2588                         qryFac.setWhere( "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2589                         qryFac.setOrderBy( "codigo asc" );
2590                         qryFac.setForwardOnly( true );
2592                         if ( !qryFac.exec() )
2593                                 return true;
2595                         util.sqlDelete( "huecos", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND ( tipo = 'XX' OR tipo = '" + tipo + "')" );
2597                         while ( qryFac.next() ) {
2598                                 nFac = qryFac.value( 0 );
2599                                 
2600                                 // Por si hay duplicados, que no debería haberlos...
2601                                 if (ultFac == nFac)
2602                                         continue;
2603                                 ultFac = nFac;
2604                                 
2605                                 util.setProgress( ++nSec );
2606                                 while ( nSec < nFac ) {
2607                                         cursorHuecos.setModeAccess( cursorHuecos.Insert );
2608                                         cursorHuecos.refreshBuffer();
2609                                         cursorHuecos.setValueBuffer( "tipo", tipo );
2610                                         cursorHuecos.setValueBuffer( "codserie", serie );
2611                                         cursorHuecos.setValueBuffer( "codejercicio", ejercicio );
2612                                         cursorHuecos.setValueBuffer( "numero", nSec );
2613                                         cursorHuecos.commitBuffer();
2614                                         util.setProgress( ++nSec );
2615                                 }
2616                         }
2617                         
2618                         util.setProgress( ++nSec );
2619                         util.sqlUpdate( "secuencias", "valorout", nSec, "id = " + idSec + " AND nombre='" + fN + "'" );
2621                         util.setProgress( maxFactura );
2622                         util.destroyProgressDialog();
2623                 }
2624         }
2626         return true;
2629 /** \D Lanza el formulario que muestra los documentos relacionados con un determinado documento de facturación
2630 @param  codigo: Código del documento
2631 @param  tipo: Tipo del documento
2632 \end */
2633 function oficial_mostrarTraza(codigo:String, tipo:String)
2635         var util:FLUtil = new FLUtil();
2636         util.sqlDelete("trazadoc", "usuario = '" + sys.nameUser() + "'");
2638         var f:Object = new FLFormSearchDB("trazadoc");
2639         var curTraza:FLSqlCursor = f.cursor();
2640         curTraza.setModeAccess(curTraza.Insert);
2641         curTraza.refreshBuffer();
2642         curTraza.setValueBuffer("usuario", sys.nameUser());
2643         curTraza.setValueBuffer("codigo", codigo);
2644         curTraza.setValueBuffer("tipo", tipo);
2645         if (!curTraza.commitBuffer())
2646                 return false;;
2648         curTraza.select("usuario = '" + sys.nameUser() + "'");
2649         if (!curTraza.first())
2650                 return false;
2652         curTraza.setModeAccess(curTraza.Browse);
2653         f.setMainWidget();
2654         curTraza.refreshBuffer();
2655         var acpt:String = f.exec("usuario");
2658 /** \D Establece los datos opcionales de una partida de IVA decompras/ventas.
2659 Para facilitar personalizaciones en las partidas.
2660 Se ponen datos de concepto, tipo de documento, documento y factura
2661 @param  curPartida: Cursor sobre la partida
2662 @param  curFactura: Cursor sobre la factura
2663 @param  tipo: cliente / proveedor
2664 @param  concepto: Concepto, opcional
2666 function oficial_datosPartidaFactura(curPartida:FLSqlCursor, curFactura:FLSqlCursor, tipo:String, concepto:String) 
2668         var util:FLUtil = new FLUtil();
2669         
2670         if (tipo == "cliente") {
2671                 if (concepto)
2672                         curPartida.setValueBuffer("concepto", concepto);
2673                 else
2674                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Nuestra factura ") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombrecliente"));
2675                 
2676                 // Si es de IVA
2677                 if (curPartida.valueBuffer("cifnif"))
2678                         curPartida.setValueBuffer("tipodocumento", "Factura de cliente");
2679         }
2680         else {
2681                 if (concepto)
2682                         curPartida.setValueBuffer("concepto", concepto);
2683                 else
2684                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Su factura") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombre"));
2685                 
2686                 // Si es de IVA
2687                 if (curPartida.valueBuffer("cifnif"))
2688                 curPartida.setValueBuffer("tipodocumento", "Factura de proveedor");
2689         }
2690         
2691         // Si es de IVA
2692         if (curPartida.valueBuffer("cifnif")) {
2693                 curPartida.setValueBuffer("documento", curFactura.valueBuffer("codigo"));
2694                 curPartida.setValueBuffer("factura", curFactura.valueBuffer("numero"));
2695         }
2698 /** \D Comprueba si hay condiciones para regenerar los recibos de una factura
2699 cuando se edita la misma. Para sobrecargar en extensiones
2700 @param  curFactura: Cursor de la factura
2701 @param  masCampos: Array con los nombres de campos adicionales. Opcional
2702 @return VERDADERO si hay que regenerar, FALSO en otro caso
2703 \end */
2704 function oficial_siGenerarRecibosCli(curFactura:FLSqlCursor, masCampos:Array):Boolean 
2706         var camposAcomprobar = new Array("codcliente","total","codpago","fecha");
2707         
2708         for (var i:Number = 0; i < camposAcomprobar.length; i++)
2709                 if (curFactura.valueBuffer(camposAcomprobar[i]) != curFactura.valueBufferCopy(camposAcomprobar[i]))
2710                         return true;
2711         
2712         if (masCampos) {
2713                 for (i = 0; i < masCampos.length; i++)
2714                         if (curFactura.valueBuffer(masCampos[i]) != curFactura.valueBufferCopy(masCampos[i]))
2715                                 return true;
2716         }
2717         
2718         return false;
2721 function oficial_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean
2723         var util:FLUtil;
2725         if(!codCliente)
2726                 return true;
2728         var regimenIva = util.sqlSelect("clientes","regimeniva","codcliente = '" + codCliente + "'");
2729         var aplicarRecargo = util.sqlSelect("clientes","recargo","codcliente = '" + codCliente + "'");
2730         
2731         var q:FLSqlQuery = new FLSqlQuery();
2732         q.setTablesList(tabla);
2733         q.setSelect("iva,recargo");
2734         q.setFrom(tabla);
2735         q.setWhere(identificador + " = " + id);
2736         
2737         if (!q.exec())
2738                 return false;
2740         while (q.next()) {
2741                                 var iva:Number = parseFloat(q.value("iva"));
2742                 if(!iva)
2743                         iva = 0;
2744                 var recargo:Number = parseFloat(q.value("recargo"));
2745                 if(!recargo)
2746                         recargo = 0;
2748                 switch (regimenIva) {
2749                         case "General": {
2750                                 if (iva == 0) {
2751                                         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);
2752                                         if (res != MessageBox.Yes)
2753                                                 return false;
2754                                 }
2755                         }
2756                         break;
2757                         case "Exento":
2758                         case "U.E.": {
2759                                 if (iva != 0) {
2760                                         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);
2761                                         if (res != MessageBox.Yes)
2762                                                 return false;
2763                                 }
2764                         }
2765                         break;
2766                 }
2767                 if (aplicarRecargo && recargo == 0) {
2768                         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);
2769                         if (res != MessageBox.Yes)
2770                                 return false;
2771                 }
2772                 if (!aplicarRecargo && recargo != 0) {
2773                         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);
2774                         if (res != MessageBox.Yes)
2775                                 return false;
2776                 }
2777         }
2779         return true;
2782 function oficial_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean
2784         var util:FLUtil;
2786         if(!codProveedor)
2787                 return true;    
2789         var regimenIva = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + codProveedor + "'");
2790         var aplicarRecargo = util.sqlSelect("empresa","recequivalencia","1 = 1");
2791         
2792         var q:FLSqlQuery = new FLSqlQuery();
2793         q.setTablesList(tabla);
2794         q.setSelect("iva,recargo");
2795         q.setFrom(tabla);
2796         q.setWhere(identificador + " = " + id);
2797         
2798         if (!q.exec())
2799                 return false;
2801         while (q.next()) {
2802                 var iva:Number = parseFloat(q.value("iva"));
2803                 if(!iva)
2804                         iva = 0;
2805                 var recargo:Number = parseFloat(q.value("recargo"));
2806                 if(!recargo)
2807                         recargo = 0;
2809                 switch (regimenIva) {
2810                         case "General":
2811                         case "U.E.": {
2812                                 if (iva == 0) {
2813                                         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);
2814                                         if (res != MessageBox.Yes)
2815                                                 return false;
2816                                 }
2817                         }
2818                         break;
2819                         case "Exento": {
2820                                 if (iva != 0) {
2821                                         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);
2822                                         if (res != MessageBox.Yes)
2823                                                 return false;
2824                                 }
2825                         }
2826                         break;
2827                 }
2828                 if (aplicarRecargo && recargo == 0) {
2829                         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);
2830                         if (res != MessageBox.Yes)
2831                                 return false;
2832                 }
2833                 if (!aplicarRecargo && recargo != 0) {
2834                         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);
2835                         if (res != MessageBox.Yes)
2836                                 return false;
2837                 }
2838         }
2840         return true;
2843 function oficial_comprobarFacturaAbonoCli(curFactura:FLSqlCursor):Boolean
2845         var util:FLUtil = new FLUtil();
2846         if (curFactura.valueBuffer("deabono") == true) {
2847                 if (!curFactura.valueBuffer("idfacturarect")){
2848                         var res:Number = MessageBox.warning(util.translate("scripts", "No ha indicado la factura que desea abonar.\n¿Desea continuar?"), MessageBox.No, MessageBox.Yes);
2849                         if (res != MessageBox.Yes) {
2850                                 return false;
2851                         }
2852                 } else {
2853                         if (util.sqlSelect("facturascli", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
2854                                 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);
2855                                 return false;
2856                         }
2857                 }
2858         }
2859         return true;
2862 function oficial_comprobarCambioSerie(cursor:FLSqlCursor):Boolean
2864         var util:FLUtil;
2865         if(!cursor.valueBuffer("codserie") || cursor.valueBuffer("codserie") == "" || !cursor.valueBufferCopy("codserie") || cursor.valueBufferCopy("codserie") == "")
2866                 return true;
2867         if(cursor.valueBuffer("codserie") != cursor.valueBufferCopy("codserie")) {
2868                 var util:FLUtil = new FLUtil();
2869                 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);
2870                 return false;
2871         }
2872         return true;
2875 //// OFICIAL ////////////////////////////////////////////////////
2876 /////////////////////////////////////////////////////////////////
2878 /** @class_definition head */
2879 /////////////////////////////////////////////////////////////////
2880 //// DESARROLLO /////////////////////////////////////////////////
2882 //// DESARROLLO /////////////////////////////////////////////////
2883 /////////////////////////////////////////////////////////////////