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