Added the README file.
[mx3r.git] / testfile1.qs.BASE
blob08f208b0385cf7a83c5b106ecd745e5d177c86f7
1 /***************************************************************************
2                  flfacturac.qs  -  description
3                              -------------------
4     begin                : lun abr 26 2004
5     copyright            : (C) 2004 by InfoSiAL S.L.
6     email                : mail@infosial.com
7  ***************************************************************************/
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
18 /** @file */ 
20 /** @class_declaration interna */
21 ////////////////////////////////////////////////////////////////////////////
22 //// DECLARACION ///////////////////////////////////////////////////////////
23 ////////////////////////////////////////////////////////////////////////////
25 //////////////////////////////////////////////////////////////////
26 //// INTERNA /////////////////////////////////////////////////////
27 class interna {
28         var ctx:Object;
29         function interna( context ) { this.ctx = context; }
30         function beforeCommit_presupuestoscli(curPresupuesto:FLSqlCursor):Boolean {
31                 return this.ctx.interna_beforeCommit_presupuestoscli(curPresupuesto);
32         }
33         function beforeCommit_pedidoscli(curPedido:FLSqlCursor):Boolean {
34                 return this.ctx.interna_beforeCommit_pedidoscli(curPedido);
35         }
36         function beforeCommit_pedidosprov(curPedido:FLSqlCursor):Boolean {
37                 return this.ctx.interna_beforeCommit_pedidosprov(curPedido);
38         }
39         function beforeCommit_albaranescli(curAlbaran:FLSqlCursor):Boolean {
40                 return this.ctx.interna_beforeCommit_albaranescli(curAlbaran);
41         }
42         function beforeCommit_albaranesprov(curAlbaran:FLSqlCursor):Boolean {
43                 return this.ctx.interna_beforeCommit_albaranesprov(curAlbaran);
44         }
45         function beforeCommit_facturascli(curFactura:FLSqlCursor):Boolean {
46                 return this.ctx.interna_beforeCommit_facturascli(curFactura);
47         }
48         function beforeCommit_facturasprov(curFactura:FLSqlCursor):Boolean {
49                 return this.ctx.interna_beforeCommit_facturasprov(curFactura);
50         }
51         function afterCommit_facturascli(curFactura:FLSqlCursor):Boolean {
52                 return this.ctx.interna_afterCommit_facturascli(curFactura);
53         }
54         function afterCommit_facturasprov(curFactura:FLSqlCursor):Boolean {
55                 return this.ctx.interna_afterCommit_facturasprov(curFactura);
56         }
57         function afterCommit_lineasalbaranesprov(curLA:FLSqlCursor):Boolean {
58                 return this.ctx.interna_afterCommit_lineasalbaranesprov(curLA);
59         }
60         function afterCommit_lineasfacturasprov(curLF:FLSqlCursor):Boolean {
61                 return this.ctx.interna_afterCommit_lineasfacturasprov(curLF);
62         }
63         function afterCommit_lineaspedidoscli(curLA:FLSqlCursor):Boolean {
64                 return this.ctx.interna_afterCommit_lineaspedidoscli(curLA);
65         }
66         function afterCommit_lineasalbaranescli(curLA:FLSqlCursor):Boolean {
67                 return this.ctx.interna_afterCommit_lineasalbaranescli(curLA);
68         }
69         function afterCommit_lineasfacturascli(curLF:FLSqlCursor):Boolean {
70                 return this.ctx.interna_afterCommit_lineasfacturascli(curLF);
71         }
73 //// INTERNA /////////////////////////////////////////////////////
74 //////////////////////////////////////////////////////////////////
76 /** @class_declaration oficial */
77 //////////////////////////////////////////////////////////////////
78 //// OFICIAL /////////////////////////////////////////////////////
79 class oficial extends interna {
80         function oficial( context ) { interna( context ); }
81         function obtenerHueco(codSerie:String, codEjercicio:String, tipo:String):Number {
82                 return this.ctx.oficial_obtenerHueco(codSerie, codEjercicio, tipo);
83         }
84         function establecerNumeroSecuencia(fN:String, value:Number):Number {
85                 return this.ctx.oficial_establecerNumeroSecuencia(fN, value);
86         }
87         function cerosIzquierda(numero:String, totalCifras:Number):String {
88                 return this.ctx.oficial_cerosIzquierda(numero, totalCifras);
89         }
90         function construirCodigo(codSerie:String, codEjercicio:String, numero:String):String {
91                 return this.ctx.oficial_construirCodigo(codSerie, codEjercicio, numero);
92         }
93         function siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number {
94                 return this.ctx.oficial_siguienteNumero(codSerie, codEjercicio, fN);
95         }
96         function agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean {
97                 return this.ctx.oficial_agregarHueco(serie, ejercicio, numero, fN);
98         }
99         function asientoBorrable(idAsiento:Number):Boolean {
100                 return this.ctx.oficial_asientoBorrable(idAsiento);
101         }
102         function generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean {
103                 return this.ctx.oficial_generarAsientoFacturaCli(curFactura);
104         }
105         function generarPartidasVenta(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
106                 return this.ctx.oficial_generarPartidasVenta(curFactura, idAsiento, valoresDefecto);
107         }
108         function generarPartidasIVACli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean {
109                 return this.ctx.oficial_generarPartidasIVACli(curFactura, idAsiento, valoresDefecto, ctaCliente);
110         }
111         function generarPartidasIRPF(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
112                 return this.ctx.oficial_generarPartidasIRPF(curFactura, idAsiento, valoresDefecto);
113         }
114         function generarPartidasRecFinCli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
115                 return this.ctx.oficial_generarPartidasRecFinCli(curFactura, idAsiento, valoresDefecto);
116         }
117         function generarPartidasIRPFProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
118                 return this.ctx.oficial_generarPartidasIRPFProv(curFactura, idAsiento, valoresDefecto);
119         }
120         function generarPartidasRecFinProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean {
121                 return this.ctx.oficial_generarPartidasRecFinProv(curFactura, idAsiento, valoresDefecto);
122         }
123         function generarPartidasCliente(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean {
124                 return this.ctx.oficial_generarPartidasCliente(curFactura, idAsiento, valoresDefecto, ctaCliente);
125         }
126         function regenerarAsiento(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
127                 return this.ctx.oficial_regenerarAsiento(curFactura, valoresDefecto);
128         }
129         function generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean {
130                 return this.ctx.oficial_generarAsientoFacturaProv(curFactura);
131         }
132         function generarPartidasCompra(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, concepto:String):Boolean {
133                 return this.ctx.oficial_generarPartidasCompra(curFactura, idAsiento, valoresDefecto, concepto);
134         }
135         function generarPartidasIVAProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String):Boolean {
136                 return this.ctx.oficial_generarPartidasIVAProv(curFactura, idAsiento, valoresDefecto, ctaProveedor, concepto);
137         }
138         function generarPartidasProveedor(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String, sinIVA:Boolean):Boolean {
139                 return this.ctx.oficial_generarPartidasProveedor(curFactura, idAsiento, valoresDefecto, ctaProveedor, concepto, sinIVA);
140         }
141         function datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array {
142                 return this.ctx.oficial_datosCtaEspecial(ctaEsp, codEjercicio);
143         }
144         function datosCtaIVA(tipo:String, codEjercicio:String, codImpuesto:String):Array {
145                 return this.ctx.oficial_datosCtaIVA(tipo, codEjercicio, codImpuesto);
146         }
147         function datosCtaVentas(codEjercicio:String, codSerie:String):Array {
148                 return this.ctx.oficial_datosCtaVentas(codEjercicio, codSerie);
149         }
150         function datosCtaCliente(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
151                 return this.ctx.oficial_datosCtaCliente(curFactura, valoresDefecto);
152         }
153         function datosCtaProveedor(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
154                 return this.ctx.oficial_datosCtaProveedor(curFactura, valoresDefecto);
155         }
156         function asientoFacturaAbonoCli(curFactura:FLSqlCursor, valoresDefecto:Array){
157                 return this.ctx.oficial_asientoFacturaAbonoCli(curFactura, valoresDefecto);
158         }
159         function asientoFacturaAbonoProv(curFactura:FLSqlCursor, valoresDefecto:Array){
160                 return this.ctx.oficial_asientoFacturaAbonoProv(curFactura, valoresDefecto);
161         }
162         function datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array {
163                 return this.ctx.oficial_datosDocFacturacion(fecha, codEjercicio, tipoDoc);
164         }
165         function tieneIvaDocCliente(codSerie:String, codCliente:String):Boolean {
166                 return this.ctx.oficial_tieneIvaDocCliente(codSerie, codCliente);
167         }
168         function automataActivado():Boolean {
169                 return this.ctx.oficial_automataActivado();
170         }
171         function comprobarRegularizacion(curFactura:FLSqlCursor):Boolean {
172                 return this.ctx.oficial_comprobarRegularizacion(curFactura);
173         }
174         function recalcularHuecos(serie:String, ejercicio:String, fN:String):Boolean {
175                 return this.ctx.oficial_recalcularHuecos(serie, ejercicio, fN);
176         }
177         function mostrarTraza(codigo:String, tipo:String) {
178                 return this.ctx.oficial_mostrarTraza(codigo, tipo);
179         }
180         function datosPartidaFactura(curPartida:FLSqlCursor, curFactura:FLSqlCursor, tipo:String, concepto:String) {
181                 return this.ctx.oficial_datosPartidaFactura(curPartida, curFactura, tipo, concepto);
182         }
183         function eliminarAsiento(idAsiento:String):Boolean {
184                 return this.ctx.oficial_eliminarAsiento(idAsiento);
185         }
186         function siGenerarRecibosCli(curFactura:FLSqlCursor, masCampos:Array):Boolean {
187                 return this.ctx.oficial_siGenerarRecibosCli(curFactura, masCampos);
188         }
189         function validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean {
190                 return this.ctx.oficial_validarIvaRecargoCliente(codCliente,id,tabla,identificador);
191         }
192         function validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean {
193                 return this.ctx.oficial_validarIvaRecargoProveedor(codProveedor,id,tabla,identificador);
194         }
195         function comprobarFacturaAbonoCli(curFactura:FLSqlCursor):Boolean {
196                 return this.ctx.oficial_comprobarFacturaAbonoCli(curFactura);
197         }
198         function comprobarCambioSerie(cursor:FLSqlCursor):Boolean {
199                 return this.ctx.oficial_comprobarCambioSerie(cursor);
200         }
201         function netoVentasFacturaCli(curFactura:FLSqlCursor):Number {
202                 return this.ctx.oficial_netoVentasFacturaCli(curFactura);
203         }
205 //// OFICIAL /////////////////////////////////////////////////////
206 //////////////////////////////////////////////////////////////////
208 /** @class_declaration head */
209 /////////////////////////////////////////////////////////////////
210 //// DESARROLLO /////////////////////////////////////////////////
211 class head extends oficial {
212         function head( context ) { oficial ( context ); }
214 //// DESARROLLO /////////////////////////////////////////////////
215 /////////////////////////////////////////////////////////////////
217 /** @class_declaration ifaceCtx */
218 /////////////////////////////////////////////////////////////////
219 //// INTERFACE  /////////////////////////////////////////////////
220 class ifaceCtx extends head {
221         function ifaceCtx( context ) { head( context ); }
222         function pub_cerosIzquierda(numero:String, totalCifras:Number):String {
223                 return this.cerosIzquierda(numero, totalCifras);
224         }
225         function pub_asientoBorrable(idAsiento:Number):Boolean {
226                 return this.asientoBorrable(idAsiento);
227         }
228         function pub_regenerarAsiento(curFactura:FLSqlCursor, valoresDefecto:Array):Array {
229                 return this.regenerarAsiento(curFactura, valoresDefecto);
230         }
231         function pub_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array {
232                 return this.datosCtaEspecial(ctaEsp, codEjercicio);
233         }
234         function pub_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number {
235                 return this.siguienteNumero(codSerie, codEjercicio, fN);
236         }
237         function pub_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String {
238                 return this.construirCodigo(codSerie, codEjercicio, numero);
239         }
240         function pub_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean {
241                 return this.agregarHueco(serie, ejercicio, numero, fN);
242         }
243         function pub_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array {
244                 return this.datosDocFacturacion(fecha, codEjercicio, tipoDoc);
245         }
246         function pub_tieneIvaDocCliente(codSerie:String, codCliente:String):Boolean {
247                 return this.tieneIvaDocCliente(codSerie, codCliente);
248         }
249         function pub_automataActivado():Boolean {
250                 return this.automataActivado();
251         }
252         function pub_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean {
253                 return this.generarAsientoFacturaCli(curFactura);
254         }
255         function pub_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean {
256                 return this.generarAsientoFacturaProv(curFactura);
257         }
258         function pub_mostrarTraza(codigo:String, tipo:String) {
259                 return this.mostrarTraza(codigo, tipo);
260         }
261         function pub_eliminarAsiento(idAsiento:String):Boolean {
262                 return this.eliminarAsiento(idAsiento);
263         }
264         function pub_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean {
265                 return this.validarIvaRecargoCliente(codCliente,id,tabla,identificador);
266         }
267         function pub_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean {
268                 return this.validarIvaRecargoProveedor(codProveedor,id,tabla,identificador);
269         }
272 const iface = new ifaceCtx( this );
273 //// INTERFACE  /////////////////////////////////////////////////
274 /////////////////////////////////////////////////////////////////
276 /** @class_definition interna */
277 ////////////////////////////////////////////////////////////////////////////
278 //// DEFINICION ////////////////////////////////////////////////////////////
279 ////////////////////////////////////////////////////////////////////////////
281 //////////////////////////////////////////////////////////////////
282 //// INTERNA /////////////////////////////////////////////////////
283 /** \C 
284 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
286 Se actualiza el estado del pedido.
288 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.
289 \end */
290 function interna_beforeCommit_pedidoscli(curPedido:FLSqlCursor):Boolean
292         var util:FLUtil = new FLUtil();
293         var numero:String;
294         
295         switch (curPedido.modeAccess()) {
296                 case curPedido.Insert: {
297                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
298                                 return false;
299                         if (curPedido.valueBuffer("numero") == 0) {
300                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidocli");
301                                 if (!numero)
302                                         return false;
303                                 curPedido.setValueBuffer("numero", numero);
304                                 curPedido.setValueBuffer("codigo", formpedidoscli.iface.pub_commonCalculateField("codigo", curPedido));
305                         }
306                         break;
307                 }
308                 case curPedido.Edit: {
309                         if(!this.iface.comprobarCambioSerie(curPedido))
310                                 return false;
311                         if (!flfactppal.iface.pub_clienteActivo(curPedido.valueBuffer("codcliente"), curPedido.valueBuffer("fecha")))
312                                 return false;
313                         if (curPedido.valueBuffer("servido") == "Parcial") {
314                                 var estado:String = formRecordlineasalbaranescli.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
315                                 if (estado == "Sí") {
316                                         curPedido.setValueBuffer("servido", estado);
317                                         curPedido.setValueBuffer("editable", false);
318                                 }
319                         }
320                         break;
321                 }
322                 case curPedido.Del: {
323                         if (curPedido.valueBuffer("servido") == "Parcial") {
324                                 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);
325                                 return false;
326                         }
327                         break;
328                 }
329         }
330         
331         return true;
334 /** \C 
335 Se calcula el número del pedido como el siguiente de la secuencia asociada a su ejercicio y serie. 
337 Se actualiza el estado del pedido.
339 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.
340 \end */
341 function interna_beforeCommit_pedidosprov(curPedido:FLSqlCursor):Boolean
343         var util:FLUtil = new FLUtil();
344         var numero:String;
345         
346         switch (curPedido.modeAccess()) {
347                 case curPedido.Insert: {
348                         if (curPedido.valueBuffer("numero") == 0) {
349                                 numero = this.iface.siguienteNumero(curPedido.valueBuffer("codserie"), curPedido.valueBuffer("codejercicio"), "npedidoprov");
350                                 if (!numero)
351                                         return false;
352                                 curPedido.setValueBuffer("numero", numero);
353                                 curPedido.setValueBuffer("codigo", formpedidosprov.iface.pub_commonCalculateField("codigo", curPedido));
354                         }
355                         break;
356                 }
357                 case curPedido.Edit: {
358                         if(!this.iface.comprobarCambioSerie(curPedido))
359                                 return false;
360                         if (curPedido.valueBuffer("servido") == "Parcial") {
361                                 var estado:String = formRecordlineasalbaranesprov.iface.pub_obtenerEstadoPedido(curPedido.valueBuffer("idpedido"));
362                                 if (estado == "Sí") {
363                                         curPedido.setValueBuffer("servido", estado);
364                                         curPedido.setValueBuffer("editable", false);
365                                         if (sys.isLoadedModule("flcolaproc")) {
366                                                 if (!flfactppal.iface.pub_lanzarEvento(curPedido, "pedidoProvAlbaranado"))
367                                                         return false;
368                                         }
369                                 }
370                         }
371                         break;
372                 }
373                 case curPedido.Del: {
374                         if (curPedido.valueBuffer("servido") == "Parcial") {
375                                 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);
376                                 return false;
377                         }
378                         break;
379                 }
380         }
381         return true;
384 /* \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.
385 \end */
386 function interna_beforeCommit_facturascli(curFactura:FLSqlCursor):Boolean
388         var util:FLUtil = new FLUtil();
389         var numero:String;
390         
391         if (!this.iface.comprobarFacturaAbonoCli(curFactura))
392                 return false;
393         
394         switch (curFactura.modeAccess()) {
395                 case curFactura.Insert: {
396                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
397                                 return false;
398                         if (curFactura.valueBuffer("numero") == 0) {
399                                 this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli" );
400                                 numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
401                                 if (!numero)
402                                         return false;
403                                 curFactura.setValueBuffer("numero", numero);
404                                 curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
405                         }
406                         break;
407                 }
408                 case curFactura.Edit: {
409                         if(!this.iface.comprobarCambioSerie(curFactura))
410                                 return false;
411                         if (!flfactppal.iface.pub_clienteActivo(curFactura.valueBuffer("codcliente"), curFactura.valueBuffer("fecha")))
412                                 return false;
413                         break;
414                 }
415         }
417         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
418                 if (util.sqlSelect("facturascli", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
419                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturacli");
420                         if (!numero)
421                                 return false;
422                         curFactura.setValueBuffer("numero", numero);
423                         curFactura.setValueBuffer("codigo", formfacturascli.iface.pub_commonCalculateField("codigo", curFactura));
424                 }
425         }
427         if (!formRecordfacturascli.iface.pub_actualizarLineasIva(curFactura))
428                 return false;
430         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
431                 if (this.iface.generarAsientoFacturaCli(curFactura) == false)
432                         return false;
433         }
434         
435         return true;
438 /* \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.
439 \end */
440 function interna_beforeCommit_facturasprov(curFactura:FLSqlCursor):Boolean
442         var util:FLUtil = new FLUtil();
443         var numero:String;
444         
445         if (curFactura.valueBuffer("deabono") == true) {
446                 if (!curFactura.valueBuffer("idfacturarect")){
447                         MessageBox.warning(util.translate("scripts", "Debe seleccionar la factura que desea abonar"),MessageBox.Ok, MessageBox.NoButton,MessageBox.NoButton);
448                         return false;
449                 }
450                 if (util.sqlSelect("facturasprov", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
451                         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);
452                         return false;
453                 }
454         }
455         
456         if (curFactura.modeAccess() == curFactura.Edit) {
457                 if(!this.iface.comprobarCambioSerie(curFactura))
458                         return false;
459         }
460         
461         if (curFactura.modeAccess() == curFactura.Insert) {
462                 if (curFactura.valueBuffer("numero") == 0) {
463                         this.iface.recalcularHuecos( curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov" );
464                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
465                         if (!numero)
466                                 return false;
467                         curFactura.setValueBuffer("numero", numero);
468                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
469                 }
470         }
472         if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
473                 if (util.sqlSelect("facturasprov", "idfactura", "codejercicio = '" + curFactura.valueBuffer("codejercicio") + "' AND codserie = '" + curFactura.valueBuffer("codserie") + "' AND numero = '" + curFactura.valueBuffer("numero") + "' AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
474                         numero = this.iface.siguienteNumero(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), "nfacturaprov");
475                         if (!numero)
476                                 return false;
477                         curFactura.setValueBuffer("numero", numero);
478                         curFactura.setValueBuffer("codigo", formfacturasprov.iface.pub_commonCalculateField("codigo", curFactura));
479                 }
480         }
482         if (!formRecordfacturasprov.iface.pub_actualizarLineasIva(curFactura))
483                 return false;
485         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
486                 if (this.iface.generarAsientoFacturaProv(curFactura) == false)
487                         return false;
488         }
489         return true;
493 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
494 Se recalcula el estado de los pedidos asociados al albarán
495 \end */
496 function interna_beforeCommit_albaranescli(curAlbaran:FLSqlCursor):Boolean
498         var util:FLUtil = new FLUtil();
499         var numero:String;
500         
501         switch (curAlbaran.modeAccess()) {
502                 case curAlbaran.Insert: {
503                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
504                                 return false;
505                         if (curAlbaran.valueBuffer("numero") == 0) {
506                                 numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbarancli");
507                                 if (!numero)
508                                         return false;
509                                 curAlbaran.setValueBuffer("numero", numero);
510                                 curAlbaran.setValueBuffer("codigo", formalbaranescli.iface.pub_commonCalculateField("codigo", curAlbaran));
511                         }
512                         break;
513                 }
514                 case curAlbaran.Edit: {
515                         if(!this.iface.comprobarCambioSerie(curAlbaran))
516                                 return false;
517                         if (!flfactppal.iface.pub_clienteActivo(curAlbaran.valueBuffer("codcliente"), curAlbaran.valueBuffer("fecha")))
518                                 return false;
519                         break;
520                 }
521         }
522         
523         var query:FLSqlQuery = new FLSqlQuery();
524         query.setTablesList("lineasalbaranescli");
525         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
526         query.setFrom("lineasalbaranescli");
527         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
528         try { query.setForwardOnly( true ); } catch (e) {}
529         query.exec();
530         var idPedido:String = 0;
531         while (query.next()) {
532                 if (!formRecordlineasalbaranescli.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
533                         return false;
534                         
535                 if (idPedido != query.value(1)) {
536                         if (!formRecordlineasalbaranescli.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
537                                 return false;
538                 }
539                 idPedido = query.value(1)
540         }
541         return true;
544 /* \C Se calcula el número del albarán como el siguiente de la secuencia asociada a su ejercicio y serie. 
546 Se recalcula el estado de los pedidos asociados al albarán
547 \end */
548 function interna_beforeCommit_albaranesprov(curAlbaran:FLSqlCursor):Boolean
550         var util:FLUtil = new FLUtil();
551         var numero:String;
552         
553         if (curAlbaran.modeAccess() == curAlbaran.Insert) {
554                 if (curAlbaran.valueBuffer("numero") == 0) {
555                         numero = this.iface.siguienteNumero(curAlbaran.valueBuffer("codserie"), curAlbaran.valueBuffer("codejercicio"), "nalbaranprov");
556                         if (!numero)
557                                 return false;
558                         curAlbaran.setValueBuffer("numero", numero);
559                         curAlbaran.setValueBuffer("codigo", formalbaranesprov.iface.pub_commonCalculateField("codigo", curAlbaran));
560                 }
561         }
562         if (curAlbaran.modeAccess() == curAlbaran.Edit) {
563                 if(!this.iface.comprobarCambioSerie(curAlbaran))
564                         return false;
565         }
566         
567         var query:FLSqlQuery = new FLSqlQuery();
568         query.setTablesList("lineasalbaranesprov");
569         query.setSelect("idlineapedido, idpedido, referencia, idalbaran, cantidad");
570         query.setFrom("lineasalbaranesprov");
571         query.setWhere("idalbaran = " + curAlbaran.valueBuffer("idalbaran") + " AND idlineapedido <> 0 ORDER BY idpedido");
572         try { query.setForwardOnly( true ); } catch (e) {}
573         query.exec();
574         var idPedido:String = 0;
575         while (query.next()) {
576                 if (!formRecordlineasalbaranesprov.iface.pub_actualizarLineaPedido(query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
577                         return false;
578                 if (idPedido != query.value(1)) {
579                         if (!formRecordlineasalbaranesprov.iface.pub_actualizarEstadoPedido(query.value(1), curAlbaran))
580                                 return false;
581                 }
582                 idPedido = query.value(1);
583         }
584         
585         return true;
588 /* \C Se calcula el número del presupuesto como el siguiente de la secuencia asociada a su ejercicio y serie. 
589 \end */
590 function interna_beforeCommit_presupuestoscli(curPresupuesto:FLSqlCursor):Boolean
592         var util:FLUtil = new FLUtil();
593         var numero:String;
594         
595         switch (curPresupuesto.modeAccess()) {
596                 case curPresupuesto.Insert: {
597                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
598                                 return false;
599                         if (curPresupuesto.valueBuffer("numero") == 0) {
600                                 numero = this.iface.siguienteNumero(curPresupuesto.valueBuffer("codserie"), curPresupuesto.valueBuffer("codejercicio"), "npresupuestocli");
601                                 if (!numero)
602                                         return false;
603                                 curPresupuesto.setValueBuffer("numero", numero);
604                                 curPresupuesto.setValueBuffer("codigo", formpresupuestoscli.iface.pub_commonCalculateField("codigo", curPresupuesto));
605                         }
606                         break;
607                 }
608                 case curPresupuesto.Edit: {
609                         if(!this.iface.comprobarCambioSerie(curPresupuesto))
610                                 return false;
611                         if (!flfactppal.iface.pub_clienteActivo(curPresupuesto.valueBuffer("codcliente"), curPresupuesto.valueBuffer("fecha")))
612                                 return false;
613                         break;
614                 }
615         }
616         
617         return true;
620 /* \C En el caso de que el módulo de tesorería esté cargado, genera o modifica los recibos correspondientes a la factura.
622 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.
623 \end */
624 function interna_afterCommit_facturascli(curFactura:FLSqlCursor):Boolean
626         if (curFactura.modeAccess() == curFactura.Del) {
627                 if (!this.iface.agregarHueco(curFactura.valueBuffer("codserie"), curFactura.valueBuffer("codejercicio"), curFactura.valueBuffer("numero"), "nfacturacli"))
628                         return false;
629         }
630         
631         var util:FLUtil = new FLUtil();
632         if (sys.isLoadedModule("flfactteso") && curFactura.valueBuffer("tpv") == false) {
633                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
634                         if (this.iface.siGenerarRecibosCli(curFactura))
635                                 if (flfactteso.iface.pub_regenerarRecibosCli(curFactura) == false)
636                                         return false;
637                 }
638                 if (curFactura.modeAccess() == curFactura.Del) {
639                         flfactteso.iface.pub_actualizarRiesgoCliente(curFactura.valueBuffer("codcliente"));
640                 }
641         }
643         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
644                 switch (curFactura.modeAccess()) {
645                         case curFactura.Del: {
646                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
647                                         return false;
648                                 break;
649                         }
650                         case curFactura.Edit: {
651                                 if (curFactura.valueBuffer("nogenerarasiento")) {
652                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
653                                         if (idAsientoAnterior && idAsientoAnterior != "") {
654                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
655                                                         return false;
656                                         }
657                                 }
658                                 break;
659                         }
660                 }
661         }
662         
663         return true;
666 /* \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.
667 \end */
668 function interna_afterCommit_facturasprov(curFactura:FLSqlCursor):Boolean
670         var util:FLUtil = new FLUtil();
671         if (sys.isLoadedModule("flfactteso")) {
672                 if (curFactura.modeAccess() == curFactura.Insert || curFactura.modeAccess() == curFactura.Edit) {
673                         if (curFactura.valueBuffer("total") != curFactura.valueBufferCopy("total")
674                                 || curFactura.valueBuffer("codproveedor") != curFactura.valueBufferCopy("codproveedor")
675                                 || curFactura.valueBuffer("codpago") != curFactura.valueBufferCopy("codpago")
676                                 || curFactura.valueBuffer("fecha") != curFactura.valueBufferCopy("fecha")) {
677                                 if (flfactteso.iface.pub_regenerarRecibosProv(curFactura) == false)
678                                         return false;
679                         }
680                 }
681         }
683         if (sys.isLoadedModule("flcontppal") && flfactppal.iface.pub_valorDefectoEmpresa("contintegrada")) {
684                 switch (curFactura.modeAccess()) {
685                         case curFactura.Del: {
686                                 if (!this.iface.eliminarAsiento(curFactura.valueBuffer("idasiento")))
687                                         return false;
688                                 break;
689                         }
690                         case curFactura.Edit: {
691                                 if (curFactura.valueBuffer("nogenerarasiento")) {
692                                         var idAsientoAnterior:String = curFactura.valueBufferCopy("idasiento");
693                                         if (idAsientoAnterior && idAsientoAnterior != "") {
694                                                 if (!this.iface.eliminarAsiento(idAsientoAnterior))
695                                                         return false;
696                                         }
697                                 }
698                                 break;
699                         }
700                 }
701         }
702         return true;
705 /** \C
706 Actualización del stock correspondiente al artículo seleccionado en la línea
707 \end */
708 function interna_afterCommit_lineasalbaranesprov(curLA:FLSqlCursor):Boolean
710         if (sys.isLoadedModule("flfactalma")) 
711                 if (!flfactalma.iface.pub_controlStockAlbaranesProv(curLA))
712                         return false;
713         
714         return true;
717 /** \C
718 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.
720 Actualiza también el coste medio de los artículos afectados por el cambio.
721 \end */
722 function interna_afterCommit_lineasfacturasprov(curLF:FLSqlCursor):Boolean
724         if (sys.isLoadedModule("flfactalma")) {
725                 var util:FLUtil = new FLUtil();
726                 switch(curLF.modeAccess()) {
727                         case curLF.Edit:
728                                 if (curLF.valueBuffer("referencia") != curLF.valueBufferCopy("referencia"))
729                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBufferCopy("referencia"));
730                         case curLF.Insert:
731                         case curLF.Del:
732                                         flfactalma.iface.pub_cambiarCosteMedio(curLF.valueBuffer("referencia"));
733                         break;
734                 }
735                 
736                 if (!flfactalma.iface.pub_controlStockFacturasProv(curLF))
737                         return false;
738         }
739         return true;
742 /** \C
743 Actualiza el stock correspondiente al artículo seleccionado en la línea si el sistema
744 está configurado para ello
745 \end */
746 function interna_afterCommit_lineaspedidoscli(curLP:FLSqlCursor):Boolean
748         if (sys.isLoadedModule("flfactalma"))
749                 if (!flfactalma.iface.pub_controlStockPedidosCli(curLP))
750                         return false;
751         
752         return true;
755 /** \C
756 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
757 \end */
758 function interna_afterCommit_lineasalbaranescli(curLA:FLSqlCursor):Boolean
760         if (sys.isLoadedModule("flfactalma")) 
761                 if (!flfactalma.iface.pub_controlStockAlbaranesCli(curLA))
762                         return false;
763         
764         return true;
767 /** \C
768 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
769 \end */
770 function interna_afterCommit_lineasfacturascli(curLF:FLSqlCursor):Boolean
772         if (sys.isLoadedModule("flfactalma")) 
773                 if (!flfactalma.iface.pub_controlStockFacturasCli(curLF))
774                         return false;
775         
776         return true;
778 //// INTERNA /////////////////////////////////////////////////////
779 /////////////////////////////////////////////////////////////////
781 /** @class_definition oficial */
782 //////////////////////////////////////////////////////////////////
783 //// OFICIAL /////////////////////////////////////////////////////
784 /** \D
785 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)
786 @param codSerie: Código de serie del documento
787 @param codEjercicio: Código de ejercicio del documento
788 @param tipo: Tipo de documento (factura a cliente, a proveedor)
789 @return Número correspondiente al primer hueco encontrado (0 si no se encuentra ninguno)
790 \end */
791 function oficial_obtenerHueco(codSerie:String, codEjercicio:String, tipo:String):Number
793         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
794         var numHueco:Number = 0;
795         cursorHuecos.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "' AND upper(tipo)='" + tipo + "' ORDER BY numero;");
796         if (cursorHuecos.next()) {
797                 numHueco = cursorHuecos.valueBuffer("numero");
798                 cursorHuecos.setActivatedCheckIntegrity(false);
799                 cursorHuecos.setModeAccess(cursorHuecos.Del);
800                 cursorHuecos.refreshBuffer();
801                 cursorHuecos.commitBuffer();
802         }
803         return numHueco;
806 function oficial_establecerNumeroSecuencia(fN:String, value:Number):Number
808         return (parseFloat(value) + 1);
811 /** \D
812 Rellena un string con ceros a la izquierda hasta completar la logitud especificada
813 @param numero: String que contiene el número
814 @param totalCifras: Longitud a completar
815 \end */
816 function oficial_cerosIzquierda(numero:String, totalCifras:Number):String
818         var ret:String = numero.toString();
819         var numCeros:Number = totalCifras - ret.length;
820         for ( ; numCeros > 0 ; --numCeros)
821                 ret = "0" + ret;
822         return ret;
825 function oficial_construirCodigo(codSerie:String, codEjercicio:String, numero:String):String
827         return this.iface.cerosIzquierda(codEjercicio, 4) +
828                 this.iface.cerosIzquierda(codSerie, 2) +
829                 this.iface.cerosIzquierda(numero, 6);
832 /** \D
833 Obtiene el siguiente número de la secuencia de documentos
834 @param codSerie: Código de serie del documento
835 @param codEjercicio: Código de ejercicio del documento
836 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
837 @return Número correspondiente al siguiente documento en la serie o false si hay error
838 \end */
839 function oficial_siguienteNumero(codSerie:String, codEjercicio:String, fN:String):Number
841         var numero:Number;
842         var util:FLUtil = new FLUtil;
843         var cursorSecuencias:FLSqlCursor = new FLSqlCursor("secuenciasejercicios");
845         cursorSecuencias.setContext(this);
846         cursorSecuencias.setActivatedCheckIntegrity(false);
847         cursorSecuencias.select("upper(codserie)='" + codSerie + "' AND upper(codejercicio)='" + codEjercicio + "';");
848         if (cursorSecuencias.next()) {
849                 if (fN == "nfacturaprov") {
850                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FP");
851                         if (numeroHueco != 0) {
852                                 cursorSecuencias.setActivatedCheckIntegrity(true);
853                                 return numeroHueco;
854                         }
855                 }
856                 if (fN == "nfacturacli") {
857                         var numeroHueco:Number = this.iface.obtenerHueco(codSerie, codEjercicio, "FC");
858                         if (numeroHueco != 0) {
859                                 cursorSecuencias.setActivatedCheckIntegrity(true);
860                                 return numeroHueco;
861                         }
862                 }
864                 /** \C
865                 Para minimizar bloqueos las secuencias se han separado en distintos registros de otra tabla
866                 llamada secuencias
867                 \end */
868                 var cursorSecs:FLSqlCursor = new FLSqlCursor( "secuencias" );
869                 cursorSecs.setContext( this );
870                 cursorSecs.setActivatedCheckIntegrity( false );
871                 /** \C
872                 Si el registro no existe lo crea inicializandolo con su antiguo valor del campo correspondiente
873                 en la tabla secuenciasejercicios.
874                 \end */
875                 var idSec:Number = cursorSecuencias.valueBuffer( "id" );
876                 cursorSecs.select( "id=" + idSec + " AND nombre='" + fN + "'" );
877                 if ( !cursorSecs.next() ) {
878                         numero = cursorSecuencias.valueBuffer(fN);
879                         cursorSecs.setModeAccess( cursorSecs.Insert );
880                         cursorSecs.refreshBuffer();
881                         cursorSecs.setValueBuffer( "id", idSec );
882                         cursorSecs.setValueBuffer( "nombre", fN );
883                         cursorSecs.setValueBuffer( "valor", this.iface.establecerNumeroSecuencia( fN, numero ) );
884                         cursorSecs.commitBuffer();
885                 } else {
886                         cursorSecs.setModeAccess( cursorSecs.Edit );
887                         cursorSecs.refreshBuffer();
888                         if ( !cursorSecs.isNull( "valorout" ) )
889                                 numero = cursorSecs.valueBuffer( "valorout" );
890                         else
891                                 numero = cursorSecs.valueBuffer( "valor" );
892                         cursorSecs.setValueBuffer( "valorout", this.iface.establecerNumeroSecuencia( fN, numero ) );            
893                         cursorSecs.commitBuffer();
894                 }
895                 cursorSecs.setActivatedCheckIntegrity( true );
896         } else {
897                 /** \C
898                 Si la serie no existe para el ejercicio actual se consultará al usuario si la quiere crear
899                 \end */
900                 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);
901                 if (res != MessageBox.Yes) {
902                         cursorSecuencias.setActivatedCheckIntegrity(true);
903                         return false;
904                 }
905                 cursorSecuencias.setModeAccess(cursorSecuencias.Insert);
906                 cursorSecuencias.refreshBuffer();
907                 cursorSecuencias.setValueBuffer("codserie", codSerie);
908                 cursorSecuencias.setValueBuffer("codejercicio", codEjercicio);
909                 numero = "1";
910                 cursorSecuencias.setValueBuffer(fN, "2");
911                 if (!cursorSecuencias.commitBuffer()) {
912                         cursorSecuencias.setActivatedCheckIntegrity(true);
913                         return false;
914                 }
915         }
916         cursorSecuencias.setActivatedCheckIntegrity(true);
917         return numero;
920 /** \D
921 Agrega un hueco a la tabla de huecos
922 @param serie: Código de serie del documento
923 @param ejercicio: Código de ejercicio del documento
924 @param numero: Número del documento
925 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
926 @return true si el hueco se inserta correctamente o false si hay error
927 \end */
928 function oficial_agregarHueco(serie:String, ejercicio:String, numero:Number, fN:String):Boolean
930         return this.iface.recalcularHuecos( serie, ejercicio, fN );
933 /* \D Indica si el asiento asociado a la factura puede o no regenerarse, según pertenezca a un ejercicio abierto o cerrado
934 @param idAsiento: Identificador del asiento
935 @return True: Asiento borrable, False: Asiento no borrable
936 \end */
937 function oficial_asientoBorrable(idAsiento:Number):Boolean
939         var util:FLUtil = new FLUtil();
940         var qryEjerAsiento:FLSqlQuery = new FLSqlQuery();
941         qryEjerAsiento.setTablesList("ejercicios,co_asientos");
942         qryEjerAsiento.setSelect("e.estado");
943         qryEjerAsiento.setFrom("co_asientos a INNER JOIN ejercicios e" +
944                         " ON a.codejercicio = e.codejercicio");
945         qryEjerAsiento.setWhere("a.idasiento = " + idAsiento);
946         try { qryEjerAsiento.setForwardOnly( true ); } catch (e) {}
948         if (!qryEjerAsiento.exec())
949                 return false;
951         if (!qryEjerAsiento.next())
952                 return false;
954         if (qryEjerAsiento.value(0) != "ABIERTO") {
955                 MessageBox.critical(util.translate("scripts",
956                 "No puede realizarse la modificación porque el asiento contable correspondiente pertenece a un ejercicio cerrado"),
957                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
958                 return false;
959         }
961         return true;
964 /** \U Genera o regenera el asiento correspondiente a una factura de cliente
965 @param  curFactura: Cursor con los datos de la factura
966 @return VERDADERO si no hay error. FALSO en otro caso
967 \end */
968 function oficial_generarAsientoFacturaCli(curFactura:FLSqlCursor):Boolean
970         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
971                 return true;
973         var util:FLUtil = new FLUtil;
974         if (curFactura.valueBuffer("nogenerarasiento")) {
975                 curFactura.setNull("idasiento");
976                 return true;
977         }
979         if (!this.iface.comprobarRegularizacion(curFactura))
980                 return false;
982         var datosAsiento:Array = [];
983         var valoresDefecto:Array;
984         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
985         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
987         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
988         if (datosAsiento.error == true)
989                 return false;
991         var ctaCliente = this.iface.datosCtaCliente(curFactura, valoresDefecto);
992         if (ctaCliente.error != 0)
993                 return false;
995         if (!this.iface.generarPartidasCliente(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
996                 return false;
998         if (!this.iface.generarPartidasIRPF(curFactura, datosAsiento.idasiento, valoresDefecto))
999                 return false;
1001         if (!this.iface.generarPartidasIVACli(curFactura, datosAsiento.idasiento, valoresDefecto, ctaCliente))
1002                 return false;
1004         if (!this.iface.generarPartidasRecFinCli(curFactura, datosAsiento.idasiento, valoresDefecto))
1005                 return false;                           
1006                         
1007         if (!this.iface.generarPartidasVenta(curFactura, datosAsiento.idasiento, valoresDefecto))
1008                 return false;
1009     
1010         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1011         
1012         if (curFactura.valueBuffer("deabono") == true)
1013                 if (!this.iface.asientoFacturaAbonoCli(curFactura, valoresDefecto))
1014                         return false;
1016         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1017                 return false;
1019         return true;
1022 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de ventas
1023 @param  curFactura: Cursor de la factura
1024 @param  idAsiento: Id del asiento asociado
1025 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1026 @return VERDADERO si no hay error, FALSO en otro caso
1027 \end */
1028 function oficial_generarPartidasVenta(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1030                 var util:FLUtil = new FLUtil();
1031                 var ctaVentas:Array = this.iface.datosCtaVentas(valoresDefecto.codejercicio, curFactura.valueBuffer("codserie"));
1032                 if (ctaVentas.error != 0) {
1033                         MessageBox.warning(util.translate("scripts", "No se ha encontrado una subcuenta de ventas para esta factura."), MessageBox.Ok, MessageBox.NoButton);
1034                         return false;
1035                 }
1036                 var haber:Number = 0;
1037                 var haberME:Number = 0;
1038                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1039                 if (monedaSistema) {
1040                                 haber = this.iface.netoVentasFacturaCli(curFactura);
1041                                 haberME = 0;
1042                 } else {
1043                                 haber = util.sqlSelect("co_partidas", "SUM(debe - haber)", "idasiento = " + idAsiento);
1044                                 haberME = curFactura.valueBuffer("neto");
1045                 }
1046                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1047                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1049                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1050                 with (curPartida) {
1051                                 setModeAccess(curPartida.Insert);
1052                                 refreshBuffer();
1053                                 setValueBuffer("idsubcuenta", ctaVentas.idsubcuenta);
1054                                 setValueBuffer("codsubcuenta", ctaVentas.codsubcuenta);
1055                                 setValueBuffer("idasiento", idAsiento);
1056                                 setValueBuffer("debe", 0);
1057                                 setValueBuffer("haber", haber);
1058                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1059                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1060                                 setValueBuffer("debeME", 0);
1061                                 setValueBuffer("haberME", haberME);
1062                 }
1063                 
1064                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1065                 
1066                 if (!curPartida.commitBuffer())
1067                                 return false;
1068                 return true;
1071 function oficial_netoVentasFacturaCli(curFactura:FLSqlCursor):Number
1073         return parseFloat(curFactura.valueBuffer("neto"));
1076 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IVA y de recargo de equivalencia, si la factura lo tiene
1077 @param  curFactura: Cursor de la factura
1078 @param  idAsiento: Id del asiento asociado
1079 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1080 @param  ctaCliente: Array con los datos de la contrapartida
1081 @return VERDADERO si no hay error, FALSO en otro caso
1082 \end */
1083 function oficial_generarPartidasIVACli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1085         var util:FLUtil = new FLUtil();
1086         var haber:Number = 0;
1087         var haberME:Number = 0;
1088         var baseImponible:Number = 0;
1089         
1090         var regimenIVA:String = util.sqlSelect("clientes","regimeniva","codcliente = '" + curFactura.valueBuffer("codcliente") + "'");
1091         
1092         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1093         var qryIva:FLSqlQuery = new FLSqlQuery();
1094         qryIva.setTablesList("lineasivafactcli");
1095         qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");
1096         qryIva.setFrom("lineasivafactcli");
1097         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1098         try { qryIva.setForwardOnly( true ); } catch (e) {}
1099         if (!qryIva.exec())
1100                 return false;
1102         while (qryIva.next()) {
1103                 if (monedaSistema) {
1104                         haber = parseFloat(qryIva.value(2));
1105                         haberME = 0;
1106                         baseImponible = parseFloat(qryIva.value(0));
1107                 } else {
1108                         haber = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1109                         haberME = parseFloat(qryIva.value(2));
1110                         baseImponible = parseFloat(qryIva.value(0))  * parseFloat(curFactura.valueBuffer("tasaconv"));
1111                 }
1112                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1113                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1114                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1116                 var ctaIvaRep:Array;
1117                 if (regimenIVA == "U.E.") {
1118                         ctaIvaRep = this.iface.datosCtaIVA("IVAEUE", valoresDefecto.codejercicio, qryIva.value(5));
1119                 } else {
1120                         ctaIvaRep = this.iface.datosCtaIVA("IVAREP", valoresDefecto.codejercicio, qryIva.value(5));
1121                 }
1122                 if (ctaIvaRep.error != 0)
1123                         return false;
1124                 
1125                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1126                 with (curPartida) {
1127                         setModeAccess(curPartida.Insert);
1128                         refreshBuffer();
1129                         setValueBuffer("idsubcuenta", ctaIvaRep.idsubcuenta);
1130                         setValueBuffer("codsubcuenta", ctaIvaRep.codsubcuenta);
1131                         setValueBuffer("idasiento", idAsiento);
1132                         setValueBuffer("debe", 0);
1133                         setValueBuffer("haber", haber);
1134                         setValueBuffer("baseimponible", baseImponible);
1135                         setValueBuffer("iva", qryIva.value(1));
1136                         setValueBuffer("recargo", qryIva.value(3));
1137                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1138                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1139                         setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1140                         setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1141                         setValueBuffer("debeME", 0);
1142                         setValueBuffer("haberME", haberME);
1143                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1144                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1145                 }
1146                 
1147                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1148                 
1149                 if (!curPartida.commitBuffer())
1150                         return false;
1152                 if (monedaSistema) {
1153                         haber = parseFloat(qryIva.value(4));
1154                         haberME = 0;
1155                 } else {
1156                         haber = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1157                         haberME = parseFloat(qryIva.value(4));
1158                 }
1159                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1160                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1162                 if (parseFloat(haber) != 0) {
1163                         var ctaRecargo = this.iface.datosCtaIVA("IVAACR", valoresDefecto.codejercicio, qryIva.value(5));
1164                         if (ctaRecargo.error != 0)
1165                                 return false;
1166                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1167                         with (curPartida) {
1168                                 setModeAccess(curPartida.Insert);
1169                                 refreshBuffer();
1170                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1171                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1172                                 setValueBuffer("idasiento", idAsiento);
1173                                 setValueBuffer("debe", 0);
1174                                 setValueBuffer("haber", haber);
1175                                 setValueBuffer("baseimponible", baseImponible);
1176                                 setValueBuffer("iva", qryIva.value(1));
1177                                 setValueBuffer("recargo", qryIva.value(3));
1178                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1179                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1180                                 setValueBuffer("idcontrapartida", ctaCliente.idsubcuenta);
1181                                 setValueBuffer("codcontrapartida", ctaCliente.codsubcuenta);
1182                                 setValueBuffer("debeME", 0);
1183                                 setValueBuffer("haberME", haberME);
1184                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1185                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1186                         }
1187                         
1188                         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1189                         
1190                         if (!curPartida.commitBuffer())
1191                                 return false;
1192                 }
1193         }
1194         return true;
1197 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF, si la factura lo tiene
1198 @param  curFactura: Cursor de la factura
1199 @param  idAsiento: Id del asiento asociado
1200 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1201 @return VERDADERO si no hay error, FALSO en otro caso
1202 \end */
1203 function oficial_generarPartidasIRPF(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1205                 var util:FLUtil = new FLUtil();
1206                 var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1207                 if (irpf == 0)
1208                                 return true;
1209                 var debe:Number = 0;
1210                 var debeME:Number = 0;
1211                 var ctaIrpf:Array = this.iface.datosCtaEspecial("IRPF", valoresDefecto.codejercicio);
1212                 if (ctaIrpf.error != 0) {
1213                         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);
1214                         return false;
1215                 }
1217                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1218                 if (monedaSistema) {
1219                                 debe = irpf;
1220                                 debeME = 0;
1221                 } else {
1222                                 debe = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1223                                 debeME = irpf;
1224                 }
1225                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1226                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1228                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1229                 with (curPartida) {
1230                                 setModeAccess(curPartida.Insert);
1231                                 refreshBuffer();
1232                                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1233                                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1234                                 setValueBuffer("idasiento", idAsiento);
1235                                 setValueBuffer("debe", debe);
1236                                 setValueBuffer("haber", 0);
1237                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1238                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1239                                 setValueBuffer("debeME", debeME);
1240                                 setValueBuffer("haberME", 0);
1241                 }
1242                 
1243                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1244                 
1245                 if (!curPartida.commitBuffer())
1246                                 return false;
1248                 return true;
1251 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para clientes, si la factura lo tiene
1252 @param  curFactura: Cursor de la factura
1253 @param  idAsiento: Id del asiento asociado
1254 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1255 @return VERDADERO si no hay error, FALSO en otro caso
1256 \end */
1257 function oficial_generarPartidasRecFinCli(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1259         var util:FLUtil = new FLUtil();
1260         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
1261         if (!recFinanciero)
1262                 return true;
1263         var haber:Number = 0;
1264         var haberME:Number = 0;
1266         var ctaRecfin:Array = [];
1267         ctaRecfin = this.iface.datosCtaEspecial("INGRF", valoresDefecto.codejercicio);
1268         if (ctaRecfin.error != 0) {
1269                 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);
1270                 return false;
1271         }
1273         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1274         if (monedaSistema) {
1275                 haber = recFinanciero;
1276                 haberME = 0;
1277         } else {
1278                 haber = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
1279                 haberME = recFinanciero;
1280         }
1281         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1282         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1284         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1285         with (curPartida) {
1286                 setModeAccess(curPartida.Insert);
1287                 refreshBuffer();
1288                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
1289                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
1290                 setValueBuffer("idasiento", idAsiento);
1291                 setValueBuffer("haber", haber);
1292                 setValueBuffer("debe", 0);
1293                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1294                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1295                 setValueBuffer("haberME", haberME);
1296                 setValueBuffer("debeME", 0);
1297         }
1298         
1299         this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1300         
1301         if (!curPartida.commitBuffer())
1302                         return false;
1304         return true;
1307 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de IRPF para proveedores, si la factura lo tiene
1308 @param  curFactura: Cursor de la factura
1309 @param  idAsiento: Id del asiento asociado
1310 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1311 @return VERDADERO si no hay error, FALSO en otro caso
1312 \end */
1313 function oficial_generarPartidasIRPFProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1315         var util:FLUtil = new FLUtil();
1316         var irpf:Number = parseFloat(curFactura.valueBuffer("totalirpf"));
1317         if (irpf == 0)
1318                         return true;
1319         var haber:Number = 0;
1320         var haberME:Number = 0;
1322         var ctaIrpf:Array = [];
1323         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");
1324         if (ctaIrpf.codsubcuenta) {
1325                 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");
1326                 if (hayDistintasSubcuentas) {
1327                         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);
1328                         return false;
1329                 }
1330                 ctaIrpf.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta", "codsubcuenta = '" + ctaIrpf.codsubcuenta + "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1331                 if (!ctaIrpf.idsubcuenta) {
1332                         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);
1333                         return false;
1334                 }
1335         } else {
1336                 ctaIrpf = this.iface.datosCtaEspecial("IRPFPR", valoresDefecto.codejercicio);
1337                 if (ctaIrpf.error != 0) {
1338                         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);
1339                         return false;
1340                 }
1341         }
1343         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1344         if (monedaSistema) {
1345                 haber = irpf;
1346                 haberME = 0;
1347         } else {
1348                 haber = irpf * parseFloat(curFactura.valueBuffer("tasaconv"));
1349                 haberME = irpf;
1350         }
1351         haber = util.roundFieldValue(haber, "co_partidas", "haber");
1352         haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1354         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1355         with (curPartida) {
1356                 setModeAccess(curPartida.Insert);
1357                 refreshBuffer();
1358                 setValueBuffer("idsubcuenta", ctaIrpf.idsubcuenta);
1359                 setValueBuffer("codsubcuenta", ctaIrpf.codsubcuenta);
1360                 setValueBuffer("idasiento", idAsiento);
1361                 setValueBuffer("debe", 0);
1362                 setValueBuffer("haber", haber);
1363                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1364                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1365                 setValueBuffer("debeME", 0);
1366                 setValueBuffer("haberME", haberME);
1367         }
1368         
1369         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1370         
1371         if (!curPartida.commitBuffer())
1372                         return false;
1374         return true;
1378 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de clientes
1379 @param  curFactura: Cursor de la factura
1380 @param  idAsiento: Id del asiento asociado
1381 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1382 @param  ctaCliente: Datos de la subcuenta del cliente asociado a la factura
1383 @return VERDADERO si no hay error, FALSO en otro caso
1384 \end */
1385 function oficial_generarPartidasCliente(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaCliente:Array):Boolean
1387                 var util:FLUtil = new FLUtil();
1388                 var debe:Number = 0;
1389                 var debeME:Number = 0;
1390                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1391                 if (monedaSistema) {
1392                                 debe = curFactura.valueBuffer("total");
1393                                 debeME = 0;
1394                 } else {
1395                                 debe = parseFloat(curFactura.valueBuffer("total")) * parseFloat(curFactura.valueBuffer("tasaconv"));
1396                                 debeME = curFactura.valueBuffer("total");
1397                 }
1398                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1399                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1400                 
1401                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1402                 with (curPartida) {
1403                                 setModeAccess(curPartida.Insert);
1404                                 refreshBuffer();
1405                                 setValueBuffer("idsubcuenta", ctaCliente.idsubcuenta);
1406                                 setValueBuffer("codsubcuenta", ctaCliente.codsubcuenta);
1407                                 setValueBuffer("idasiento", idAsiento);
1408                                 setValueBuffer("debe", debe);
1409                                 setValueBuffer("haber", 0);
1410                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1411                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1412                                 setValueBuffer("debeME", debeME);
1413                                 setValueBuffer("haberME", 0);
1414                 }
1415                 
1416                 this.iface.datosPartidaFactura(curPartida, curFactura, "cliente")
1417                 
1418                 if (!curPartida.commitBuffer())
1419                                 return false;
1421                 return true;
1424 /** \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.
1425 @param  curFactura: Cursor posicionado en el registro de factura
1426 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1427 @return array con los siguientes datos:
1428 asiento.idasiento: Id del asiento
1429 asiento.numero: numero del asiento
1430 asiento.fecha: fecha del asiento
1431 asiento.error: indicador booleano de que ha habido un error en la función
1432 \end */
1433 function oficial_regenerarAsiento(curFactura:FLSqlCursor, valoresDefecto:Array):Array
1435         var util:FLUtil = new FLUtil;
1436         var asiento:Array = [];
1437         var idAsiento:Number = curFactura.valueBuffer("idasiento");
1438         if (curFactura.isNull("idasiento")) {
1439                 var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1440                 //var numAsiento:Number = util.sqlSelect("co_asientos", "MAX(numero)",  "codejercicio = '" + valoresDefecto.codejercicio + "'");
1441                 //numAsiento++;
1442                 with (curAsiento) {
1443                         setModeAccess(curAsiento.Insert);
1444                         refreshBuffer();
1445                         setValueBuffer("numero", 0);
1446                         setValueBuffer("fecha", curFactura.valueBuffer("fecha"));
1447                         setValueBuffer("codejercicio", valoresDefecto.codejercicio);
1448                 }
1449                 if (!curAsiento.commitBuffer()) {
1450                         asiento.error = true;
1451                         return asiento;
1452                 }
1453                 asiento.idasiento = curAsiento.valueBuffer("idasiento");
1454                 asiento.numero = curAsiento.valueBuffer("numero");
1455                 asiento.fecha = curAsiento.valueBuffer("fecha");
1456                 curAsiento.select("idasiento = " + asiento.idasiento);
1457                 curAsiento.first();
1458                 curAsiento.setUnLock("editable", false);
1459         } else {
1460                 if (!this.iface.asientoBorrable(idAsiento)) {
1461                         asiento.error = true;
1462                         return asiento;
1463                 }
1465                 if (curFactura.valueBuffer("fecha") != curFactura.valueBufferCopy("fecha")) {
1466                         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1467                         curAsiento.select("idasiento = " + idAsiento);
1468                         if (!curAsiento.first()) {
1469                                 asiento.error = true;
1470                                 return asiento;
1471                         }
1472                         curAsiento.setUnLock("editable", true);
1474                         curAsiento.select("idasiento = " + idAsiento);
1475                         if (!curAsiento.first()) {
1476                                 asiento.error = true;
1477                                 return asiento;
1478                         }
1479                         curAsiento.setModeAccess(curAsiento.Edit);
1480                         curAsiento.refreshBuffer();
1481                         curAsiento.setValueBuffer("fecha", curFactura.valueBuffer("fecha"));
1483                         if (!curAsiento.commitBuffer()) {
1484                                 asiento.error = true;
1485                                 return asiento;
1486                         }
1487                         curAsiento.select("idasiento = " + idAsiento);
1488                         if (!curAsiento.first()) {
1489                                 asiento.error = true;
1490                                 return asiento;
1491                         }
1492                         curAsiento.setUnLock("editable", false);
1493                 }
1495                 asiento = flfactppal.iface.pub_ejecutarQry("co_asientos", "idasiento,numero,fecha,codejercicio", "idasiento = '" + idAsiento + "'");
1496                 if (asiento.codejercicio != valoresDefecto.codejercicio) {
1497                         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);
1498                         asiento.error = true;
1499                         return asiento;
1500                 }
1501                 var curPartidas = new FLSqlCursor("co_partidas");
1502                 curPartidas.select("idasiento = " + idAsiento);
1503                 while (curPartidas.next()) {
1504                         curPartidas.setModeAccess(curPartidas.Del);
1505                         curPartidas.refreshBuffer();
1506                         if (!curPartidas.commitBuffer()) {
1507                                 asiento.error = true;
1508                                 return asiento;
1509                         }
1510                 }
1511         }
1513         asiento.error = false;
1514         return asiento;
1517 function oficial_eliminarAsiento(idAsiento:String):Boolean
1519         var util:FLUtil = new FLUtil;
1520         if (!idAsiento || idAsiento == "")
1521                 return true;
1523         if (!this.iface.asientoBorrable(idAsiento))
1524                 return false;
1526         var curAsiento:FLSqlCursor = new FLSqlCursor("co_asientos");
1527         curAsiento.select("idasiento = " + idAsiento);
1528         if (!curAsiento.first())
1529                 return false;
1531         curAsiento.setUnLock("editable", true);
1532         if (!util.sqlDelete("co_asientos", "idasiento = " + idAsiento)) {
1533                 curAsiento.setValueBuffer("idasiento", idAsiento);
1534                 return false;
1535         }
1536         return true;
1539 /** \U Genera o regenera el asiento correspondiente a una factura de proveedor
1540 @param  curFactura: Cursor con los datos de la factura
1541 @return VERDADERO si no hay error. FALSO en otro caso
1542 \end */
1543 /** \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.
1544 \end */
1545 function oficial_generarAsientoFacturaProv(curFactura:FLSqlCursor):Boolean
1547         if (curFactura.modeAccess() != curFactura.Insert && curFactura.modeAccess() != curFactura.Edit)
1548                 return true;
1550         var util:FLUtil = new FLUtil;
1551         if (curFactura.valueBuffer("nogenerarasiento")) {
1552                 curFactura.setNull("idasiento");
1553                 return true;
1554         }
1556         if (!this.iface.comprobarRegularizacion(curFactura))
1557                 return false;
1559         var util:FLUtil = new FLUtil();
1560         var datosAsiento:Array = [];
1561         var valoresDefecto:Array;
1562         valoresDefecto["codejercicio"] = curFactura.valueBuffer("codejercicio");
1563         valoresDefecto["coddivisa"] = flfactppal.iface.pub_valorDefectoEmpresa("coddivisa");
1565         datosAsiento = this.iface.regenerarAsiento(curFactura, valoresDefecto);
1566         if (datosAsiento.error == true)
1567                 return false;
1569         var numProveedor:String = curFactura.valueBuffer("numproveedor");
1570         var concepto:String;
1571         if (!numProveedor || numProveedor == "")
1572                 concepto = util.translate("scripts", "Su factura ") + curFactura.valueBuffer("codigo");
1573         else
1574                 concepto = util.translate("scripts", "Su factura ") + numProveedor;
1575         concepto += " - " + curFactura.valueBuffer("nombre");
1577         var ctaProveedor:Array = this.iface.datosCtaProveedor(curFactura, valoresDefecto);
1578         if (ctaProveedor.error != 0)
1579                 return false;
1581         // Las partidas generadas dependen del régimen de IVA del proveedor
1582         var regimenIVA:String = util.sqlSelect("proveedores", "regimeniva", "codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1583         
1584         switch(regimenIVA) {
1585                 case "UE":
1586                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1587                                 return false;
1588                                 
1589                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1590                                 return false;
1591                 
1592                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1593                                 return false;                           
1594                         
1595                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1596                                 return false;
1597                 
1598                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1599                                 return false;
1600                 break;
1601                 
1602                 case "Exento":
1603                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto, true))
1604                                 return false;
1605                                 
1606                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1607                                 return false;                           
1608                         
1609                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1610                                 return false;
1611                 
1612                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1613                                 return false;
1614                 break;
1615                 
1616                 default:
1617                         if (!this.iface.generarPartidasProveedor(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1618                                 return false;
1619                                 
1620                         if (!this.iface.generarPartidasIRPFProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1621                                 return false;
1622                 
1623                         if (!this.iface.generarPartidasRecFinProv(curFactura, datosAsiento.idasiento, valoresDefecto))
1624                                 return false;                           
1625                         
1626                         if (!this.iface.generarPartidasIVAProv(curFactura, datosAsiento.idasiento, valoresDefecto, ctaProveedor, concepto))
1627                                 return false;
1628                 
1629                         if (!this.iface.generarPartidasCompra(curFactura, datosAsiento.idasiento, valoresDefecto, concepto))
1630                                 return false;
1631         }
1632                 
1633         curFactura.setValueBuffer("idasiento", datosAsiento.idasiento);
1634                 
1635         if (curFactura.valueBuffer("deabono") == true)
1636                 if (!this.iface.asientoFacturaAbonoProv(curFactura, valoresDefecto))
1637                         return false;
1639         if (!flcontppal.iface.pub_comprobarAsiento(datosAsiento.idasiento))
1640                 return false;
1642         return true;
1645 /** \D Genera la parte del asiento de factura de proveedor correspondiente a la subcuenta de compras
1646 @param  curFactura: Cursor de la factura
1647 @param  idAsiento: Id del asiento asociado
1648 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1649 @param  concepto: Concepto de la partida
1650 @return VERDADERO si no hay error, FALSO en otro caso
1651 \end */
1652 function oficial_generarPartidasCompra(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, concepto:String):Boolean
1654                 var ctaCompras:Array = [];
1655                 var util:FLUtil = new FLUtil();
1656                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1657                 var debe:Number = 0;
1658                 var debeME:Number = 0;
1659                 var idUltimaPartida:Number = 0;
1661                 /** \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
1662                 \end */
1663                 var qrySubcuentas:FLSqlQuery = new FLSqlQuery();
1664                 with (qrySubcuentas) {
1665                                 setTablesList("lineasfacturasprov");
1666                                 setSelect("codsubcuenta, SUM(pvptotal)");
1667                                 setFrom("lineasfacturasprov");
1668                                 setWhere("idfactura = " + curFactura.valueBuffer("idfactura") +
1669                                                 " GROUP BY codsubcuenta");
1670                 }
1671                 try { qrySubcuentas.setForwardOnly( true ); } catch (e) {}
1672                 
1673                 if (!qrySubcuentas.exec())
1674                                 return false;
1675                 while (qrySubcuentas.next()) {
1676                                 if (qrySubcuentas.value(0) == "" || !qrySubcuentas.value(0)) {
1677                                                 ctaCompras = this.iface.datosCtaEspecial("COMPRA", valoresDefecto.codejercicio);
1678                                                 if (ctaCompras.error != 0)
1679                                                                 return false;
1680                                 } else {
1681                                                 ctaCompras.codsubcuenta = qrySubcuentas.value(0);
1682                                                 ctaCompras.idsubcuenta = util.sqlSelect("co_subcuentas", "idsubcuenta",
1683                                                                 "codsubcuenta = '" + qrySubcuentas.value(0) +
1684                                                                 "' AND codejercicio = '" + valoresDefecto.codejercicio + "'");
1685                                                 if (!ctaCompras.idsubcuenta) {
1686                                                                 MessageBox.warning(util.translate("scripts", "No existe la subcuenta ")  + ctaCompras.codsubcuenta +
1687                                                                                 util.translate("scripts", " correspondiente al ejercicio ") + valoresDefecto.codejercicio +
1688                                                                                 util.translate("scripts", ".\nPara poder crear la factura debe crear antes esta subcuenta"),
1689                                                                                 MessageBox.Ok, MessageBox.NoButton, MessageBox.NoButton);
1690                                                                 return false;
1691                                                 }
1692                                 }
1694                                 if (monedaSistema) {
1695                                                 debe = parseFloat(qrySubcuentas.value(1));
1696                                                 debeME = 0;
1697                                 } else {
1698                                                 debe = parseFloat(qrySubcuentas.value(1)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1699                                                 debeME = parseFloat(qrySubcuentas.value(1));
1700                                 }
1701                                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1702                                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1703                                 
1704                                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1705                                 with (curPartida) {
1706                                                 setModeAccess(curPartida.Insert);
1707                                                 refreshBuffer();
1708                                                 setValueBuffer("idsubcuenta", ctaCompras.idsubcuenta);
1709                                                 setValueBuffer("codsubcuenta", ctaCompras.codsubcuenta);
1710                                                 setValueBuffer("idasiento", idAsiento);
1711                                                 setValueBuffer("debe", debe);
1712                                                 setValueBuffer("haber", 0);
1713                                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1714                                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1715                                                 setValueBuffer("debeME", debeME);
1716                                                 setValueBuffer("haberME", 0);
1717                                 }
1718                                 
1719                                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
1720                                 
1721                                 if (!curPartida.commitBuffer())
1722                                                 return false;
1723                                 idUltimaPartida = curPartida.valueBuffer("idpartida");
1724                 }
1726                 /** \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.
1727                 \end */
1728                 if (!monedaSistema) {
1729                         debe = util.sqlSelect("co_partidas", "SUM(haber - debe)", "idasiento = " + idAsiento + " AND idpartida <> " + idUltimaPartida);
1730                         if (debe && !isNaN(debe) && debe != 0) {
1731                                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1732                                 if (!util.sqlUpdate("co_partidas", "debe", debe, "idpartida = " + idUltimaPartida))
1733                                                 return false;
1734                         }
1735                 }
1737                 return true;
1740 /** \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
1741 @param  curFactura: Cursor de la factura
1742 @param  idAsiento: Id del asiento asociado
1743 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1744 @param  ctaProveedor: Array con los datos de la contrapartida
1745 @param  concepto: Concepto de la partida
1746 @return VERDADERO si no hay error, FALSO en otro caso
1747 \end */
1748 function oficial_generarPartidasIVAProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String):Boolean
1750         var util:FLUtil = new FLUtil();
1751         var haber:Number = 0;
1752         var haberME:Number = 0;
1753         var baseImponible:Number = 0;
1754         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1755         
1756         var regimenIVA:String = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + curFactura.valueBuffer("codproveedor") + "'");
1757         var codCuentaEspIVA:String;
1758         
1759         var qryIva:FLSqlQuery = new FLSqlQuery();
1760         qryIva.setTablesList("lineasivafactprov");
1761         
1762         if (regimenIVA == "UE")
1763                 qryIva.setSelect("neto, iva, neto*iva/100, recargo, neto*recargo/100, codimpuesto");
1764         else
1765                 qryIva.setSelect("neto, iva, totaliva, recargo, totalrecargo, codimpuesto");    
1766         
1767         qryIva.setFrom("lineasivafactprov");
1768         qryIva.setWhere("idfactura = " + curFactura.valueBuffer("idfactura"));
1769         try { qryIva.setForwardOnly( true ); } catch (e) {}
1770         if (!qryIva.exec())
1771                 return false;
1773                 
1774         while (qryIva.next()) {
1775                 if (monedaSistema) {
1776                         debe = qryIva.value(2);
1777                         debeME = 0;
1778                         baseImponible = qryIva.value(0);
1779                 } else {
1780                         debe = parseFloat(qryIva.value(2)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1781                         debeME = qryIva.value(2);
1782                         baseImponible = parseFloat(qryIva.value(0)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1783                 }
1784                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1785                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1786                 baseImponible = util.roundFieldValue(baseImponible, "co_partidas", "baseimponible");
1787                 
1788                 switch(regimenIVA) {
1789                         case "UE":
1790                                 codCuentaEspIVA = "IVASUE";
1791                                 break;
1792                         case "General":
1793                         case "Exento":
1794                         case "Exportaciones":
1795                                 codCuentaEspIVA = "IVASOP";
1796                                 break;
1797                         default:
1798                                 codCuentaEspIVA = "IVASOP";
1799                 }
1800                 
1801                 var ctaIvaSop:Array = this.iface.datosCtaIVA(codCuentaEspIVA, valoresDefecto.codejercicio, qryIva.value(5));
1802                 if (ctaIvaSop.error != 0) {
1803                         MessageBox.warning(util.translate("scripts", "Esta factura pertenece al régimen IVA tipo %1.\nNo existe ninguna cuenta contable marcada como tipo especial %1\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);
1804                         return false;
1805                 }                       
1806                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1807                 with (curPartida) {
1808                         setModeAccess(curPartida.Insert);
1809                         refreshBuffer();
1810                         setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1811                         setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1812                         setValueBuffer("idasiento", idAsiento);
1813                         setValueBuffer("debe", debe);
1814                         setValueBuffer("haber", 0);
1815                         setValueBuffer("baseimponible", baseImponible);
1816                         setValueBuffer("iva", qryIva.value(1));
1817                         setValueBuffer("recargo", qryIva.value(3));
1818                         setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1819                         setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1820                         setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1821                         setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1822                         setValueBuffer("debeME", debeME);
1823                         setValueBuffer("haberME", 0);
1824                         setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1825                         setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1826                 }
1827                 
1828                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor")
1829                 
1830                 if (!curPartida.commitBuffer())
1831                         return false;
1833                 
1834                 // Otra partida de haber de IVA sobre una cuenta 477 para compensar en UE
1835                 if (regimenIVA == "UE") {
1836                         
1837                         haber = debe;
1838                         haberME = debeME;
1839                         codCuentaEspIVA = "IVARUE";
1840                         var ctaIvaSop = this.iface.datosCtaIVA("IVARUE", valoresDefecto.codejercicio,qryIva.value(5));
1841 //                      var ctaIvaSop:Array = this.iface.datosCtaEspecial("IVARUE", valoresDefecto.codejercicio);
1842                         if (ctaIvaSop.error != 0) {
1843                                 return false;
1844                         }
1845                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1846                         with (curPartida) {
1847                                 setModeAccess(curPartida.Insert);
1848                                 refreshBuffer();
1849                                 setValueBuffer("idsubcuenta", ctaIvaSop.idsubcuenta);
1850                                 setValueBuffer("codsubcuenta", ctaIvaSop.codsubcuenta);
1851                                 setValueBuffer("idasiento", idAsiento);
1852                                 setValueBuffer("debe", 0);
1853                                 setValueBuffer("haber", haber);
1854                                 setValueBuffer("baseimponible", baseImponible);
1855                                 setValueBuffer("iva", qryIva.value(1));
1856                                 setValueBuffer("recargo", qryIva.value(3));
1857                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1858                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1859                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1860                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1861                                 setValueBuffer("debeME", 0);
1862                                 setValueBuffer("haberME", haberME);
1863                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1864                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1865                         }
1866                 
1867                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
1868                         
1869                         if (!curPartida.commitBuffer())
1870                                 return false;
1871                 }
1872                         
1873                 if (monedaSistema) {
1874                         debe = qryIva.value(4);
1875                         debeME = 0;
1876                 } else {
1877                         debe = parseFloat(qryIva.value(4)) * parseFloat(curFactura.valueBuffer("tasaconv"));
1878                         debeME = qryIva.value(4);
1879                 }
1880                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
1881                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
1883                 if (parseFloat(debe) != 0) {
1884                         var ctaRecargo:Array = this.iface.datosCtaIVA("IVADEU", valoresDefecto.codejercicio, qryIva.value(5));
1885                         if (ctaRecargo.error != 0)
1886                                 return false;
1887                         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1888                         with (curPartida) {
1889                                 setModeAccess(curPartida.Insert);
1890                                 refreshBuffer();
1891                                 setValueBuffer("idsubcuenta", ctaRecargo.idsubcuenta);
1892                                 setValueBuffer("codsubcuenta", ctaRecargo.codsubcuenta);
1893                                 setValueBuffer("idasiento", idAsiento);
1894                                 setValueBuffer("debe", debe);
1895                                 setValueBuffer("haber", 0);
1896                                 setValueBuffer("baseimponible", baseImponible);
1897                                 setValueBuffer("iva", qryIva.value(1));
1898                                 setValueBuffer("recargo", qryIva.value(3));
1899                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1900                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1901                                 setValueBuffer("idcontrapartida", ctaProveedor.idsubcuenta);
1902                                 setValueBuffer("codcontrapartida", ctaProveedor.codsubcuenta);
1903                                 setValueBuffer("debeME", debeME);
1904                                 setValueBuffer("haberME", 0);
1905                                 setValueBuffer("codserie", curFactura.valueBuffer("codserie"));
1906                                 setValueBuffer("cifnif", curFactura.valueBuffer("cifnif"));
1907                         }
1908                 
1909                         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto)
1910                         
1911                         if (!curPartida.commitBuffer())
1912                                 return false;
1913                 }
1914         }
1915         return true;
1918 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de proveedor
1919 @param  curFactura: Cursor de la factura
1920 @param  idAsiento: Id del asiento asociado
1921 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1922 @param  ctaCliente: Datos de la subcuenta del proveedor asociado a la factura
1923 @param  concepto: Concepto a asociar a la factura
1924 @return VERDADERO si no hay error, FALSO en otro caso
1925 \end */
1926 function oficial_generarPartidasProveedor(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array, ctaProveedor:Array, concepto:String, sinIVA:Boolean):Boolean
1928                 var util:FLUtil = new FLUtil;
1929                 var haber:Number = 0;
1930                 var haberME:Number = 0;
1931                 var totalIVA:Number = 0;
1932                 
1933                 if (sinIVA)
1934                         totalIVA = parseFloat(curFactura.valueBuffer("totaliva"));
1935                 
1936                 var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1937                 if (monedaSistema) {
1938                                 haber = curFactura.valueBuffer("total");
1939                                 haber -= totalIVA;
1940                                 haberME = 0;
1941                 } else {
1942                                 haber = (parseFloat(curFactura.valueBuffer("total")) - totalIVA) * parseFloat(curFactura.valueBuffer("tasaconv"));
1943                                 haberME = curFactura.valueBuffer("total");
1944                 }
1945                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
1946                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
1948                 var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
1949                 with (curPartida) {
1950                                 setModeAccess(curPartida.Insert);
1951                                 refreshBuffer();
1952                                 setValueBuffer("idsubcuenta", ctaProveedor.idsubcuenta);
1953                                 setValueBuffer("codsubcuenta", ctaProveedor.codsubcuenta);
1954                                 setValueBuffer("idasiento", idAsiento);
1955                                 setValueBuffer("debe", 0);
1956                                 setValueBuffer("haber", haber);
1957                                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
1958                                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
1959                                 setValueBuffer("debeME", 0);
1960                                 setValueBuffer("haberME", haberME);
1961                 }
1962                 
1963                 this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
1964                 
1965                 if (!curPartida.commitBuffer())
1966                                 return false;
1967                 return true;
1970 /** \D Genera la parte del asiento de factura correspondiente a la subcuenta de recargo financiero para proveedores, si la factura lo tiene
1971 @param  curFactura: Cursor de la factura
1972 @param  idAsiento: Id del asiento asociado
1973 @param  valoresDefecto: Array con los valores por defecto de ejercicio y divisa
1974 @return VERDADERO si no hay error, FALSO en otro caso
1975 \end */
1976 function oficial_generarPartidasRecFinProv(curFactura:FLSqlCursor, idAsiento:Number, valoresDefecto:Array):Boolean
1978         var util:FLUtil = new FLUtil();
1979         var recFinanciero:Number = parseFloat(curFactura.valueBuffer("recfinanciero") * curFactura.valueBuffer("neto") / 100);
1980         if (!recFinanciero)
1981                 return true;
1982         var debe:Number = 0;
1983         var debeME:Number = 0;
1985         var ctaRecfin:Array = [];
1986         ctaRecfin = this.iface.datosCtaEspecial("GTORF", valoresDefecto.codejercicio);
1987         if (ctaRecfin.error != 0) {
1988                 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);
1989                 return false;
1990         }
1992         var monedaSistema:Boolean = (valoresDefecto.coddivisa == curFactura.valueBuffer("coddivisa"));
1993         if (monedaSistema) {
1994                 debe = recFinanciero;
1995                 debeME = 0;
1996         } else {
1997                 debe = recFinanciero * parseFloat(curFactura.valueBuffer("tasaconv"));
1998                 debeME = recFinanciero;
1999         }
2000         debe = util.roundFieldValue(debe, "co_partidas", "debe");
2001         debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2003         var curPartida:FLSqlCursor = new FLSqlCursor("co_partidas");
2004         with (curPartida) {
2005                 setModeAccess(curPartida.Insert);
2006                 refreshBuffer();
2007                 setValueBuffer("idsubcuenta", ctaRecfin.idsubcuenta);
2008                 setValueBuffer("codsubcuenta", ctaRecfin.codsubcuenta);
2009                 setValueBuffer("idasiento", idAsiento);
2010                 setValueBuffer("debe", debe);
2011                 setValueBuffer("haber", 0);
2012                 setValueBuffer("coddivisa", curFactura.valueBuffer("coddivisa"));
2013                 setValueBuffer("tasaconv", curFactura.valueBuffer("tasaconv"));
2014                 setValueBuffer("debeME", debeME);
2015                 setValueBuffer("haberME", 0);
2016         }
2017                 
2018         this.iface.datosPartidaFactura(curPartida, curFactura, "proveedor", concepto);
2019         
2020         if (!curPartida.commitBuffer())
2021                         return false;
2023         return true;
2026 /* \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.
2027 @param ctaEsp: Tipo de cuenta especial
2028 @codEjercicio: Código de ejercicio
2029 @return Los datos componen un vector de tres valores:
2030 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2031 idsubcuenta: Identificador de la subcuenta
2032 codsubcuenta: Código de la subcuenta
2033 \end */
2034 function oficial_datosCtaEspecial(ctaEsp:String, codEjercicio:String):Array
2036         var datos:Array = [];
2037         var q:FLSqlQuery = new FLSqlQuery();
2038         
2039         with(q) {
2040                 setTablesList("co_subcuentas,co_cuentasesp");
2041                 setSelect("s.idsubcuenta, s.codsubcuenta");
2042                 setFrom("co_cuentasesp ce INNER JOIN co_subcuentas s ON ce.codsubcuenta = s.codsubcuenta");
2043                 setWhere("idcuentaesp = '" + ctaEsp + "' AND s.codejercicio = '" + codEjercicio + "'  ORDER BY s.codsubcuenta");
2044         }
2045         try { q.setForwardOnly( true ); } catch (e) {}
2046         if (!q.exec()) {
2047                 datos["error"] = 2;
2048                 return datos;
2049         }
2050         if (q.next()) {
2051                 datos["error"] = 0;
2052                 datos["idsubcuenta"] = q.value(0);
2053                 datos["codsubcuenta"] = q.value(1);
2054                 return datos;
2055         }
2056         
2057         with(q) {
2058                 setTablesList("co_cuentas,co_subcuentas,co_cuentasesp");
2059                 setSelect("s.idsubcuenta, s.codsubcuenta");
2060                 setFrom("co_cuentasesp ce INNER JOIN co_cuentas c ON ce.codcuenta = c.codcuenta INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2061                 setWhere("ce.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2062         }
2063         try { q.setForwardOnly( true ); } catch (e) {}
2064         if (!q.exec()) {
2065                 datos["error"] = 2;
2066                 return datos;
2067         }
2068         if (q.next()) {
2069                 datos["error"] = 0;
2070                 datos["idsubcuenta"] = q.value(0);
2071                 datos["codsubcuenta"] = q.value(1);
2072                 return datos;
2073         }
2075         with(q) {
2076                 setTablesList("co_cuentas,co_subcuentas");
2077                 setSelect("s.idsubcuenta, s.codsubcuenta");
2078                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2079                 setWhere("c.idcuentaesp = '" + ctaEsp + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY s.codsubcuenta");
2080         }
2081         try { q.setForwardOnly( true ); } catch (e) {}
2082         if (!q.exec()) {
2083                 datos["error"] = 2;
2084                 return datos;
2085         }
2086         if (!q.next()) {
2087                 datos["error"] = 1;
2088                 return datos;
2089         }
2091         datos["error"] = 0;
2092         datos["idsubcuenta"] = q.value(0);
2093         datos["codsubcuenta"] = q.value(1);
2094         return datos;
2097 /* \D Devuelve el código e id de la subcuenta correspondiente a un impuesto y ejercicio determinados
2098 @param  ctaEsp: Tipo de cuenta (IVA soportado, repercutido, Recargo de equivalencia)
2100 @param  codEjercicio: Código de ejercicio
2101 @param  codImpuesto: Código de impuesto
2102 @return Los datos componen un vector de tres valores:
2103 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2104 idsubcuenta: Identificador de la subcuenta
2105 codsubcuenta: Código de la subcuenta
2106 \end */
2107 function oficial_datosCtaIVA(tipo:String, codEjercicio:String, codImpuesto:String):Array
2109                 if (!codImpuesto || codImpuesto == "")
2110                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2112                 var util:FLUtil = new FLUtil();
2113                 var datos:Array = [];
2114                 var codSubcuenta:String;
2115                 if (tipo == "IVAREP")
2116                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentarep", "codimpuesto = '" + codImpuesto + "'");
2117                 if (tipo == "IVASOP")
2118                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentasop", "codimpuesto = '" + codImpuesto + "'");
2119                 if (tipo == "IVAACR")
2120                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaacr", "codimpuesto = '" + codImpuesto + "'");
2121                 if (tipo == "IVADEU")
2122                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentadeu", "codimpuesto = '" + codImpuesto + "'");
2123                 if (tipo == "IVARUE")
2124                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadevadue", "codimpuesto = '" + codImpuesto + "'");
2125                 if (tipo == "IVASUE")
2126                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadedadue", "codimpuesto = '" + codImpuesto + "'");
2127                 if (tipo == "IVAEUE")
2128                                 codSubcuenta = util.sqlSelect("impuestos", "codsubcuentaivadeventue", "codimpuesto = '" + codImpuesto + "'");
2130                 if (!codSubcuenta || codSubcuenta == "") {
2131                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2132                 }
2134                 var q:FLSqlQuery = new FLSqlQuery();
2135                 with(q) {
2136                                 setTablesList("co_subcuentas");
2137                                 setSelect("idsubcuenta, codsubcuenta");
2138                                 setFrom("co_subcuentas");
2139                                 setWhere("codsubcuenta = '" + codSubcuenta + "' AND codejercicio = '" + codEjercicio + "'");
2140                 }
2141                 try { q.setForwardOnly( true ); } catch (e) {}
2142                 if (!q.exec()) {
2143                                 datos["error"] = 2;
2144                                 return datos;
2145                 }
2146                 if (!q.next()) {
2147                                 return this.iface.datosCtaEspecial(tipo, codEjercicio);
2148                 }
2150                 datos["error"] = 0;
2151                 datos["idsubcuenta"] = q.value(0);
2152                 datos["codsubcuenta"] = q.value(1);
2153                 return datos;
2156 /* \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
2157 @param ctaEsp: Tipo de cuenta especial
2158 @param codEjercicio: Código de ejercicio
2159 @param codSerie: Código de serie de la factura
2160 @return Los datos componen un vector de tres valores:
2161 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2162 idsubcuenta: Identificador de la subcuenta
2163 codsubcuenta: Código de la subcuenta
2164 \end */
2165 function oficial_datosCtaVentas(codEjercicio:String, codSerie:String):Array
2167                 var util:FLUtil = new FLUtil();
2168                 var datos:Array = [];
2170                 var codCuenta:String = util.sqlSelect("series", "codcuenta", "codserie = '" + codSerie + "'");
2171                 if (codCuenta.toString().isEmpty())
2172                                 return this.iface.datosCtaEspecial("VENTAS", codEjercicio);
2174                 var q:FLSqlQuery = new FLSqlQuery();
2175                 with(q) {
2176                                 setTablesList("co_cuentas,co_subcuentas");
2177                                 setSelect("idsubcuenta, codsubcuenta");
2178                                 setFrom("co_cuentas c INNER JOIN co_subcuentas s ON c.idcuenta = s.idcuenta");
2179                                 setWhere("c.codcuenta = '" + codCuenta + "' AND c.codejercicio = '" + codEjercicio + "' ORDER BY codsubcuenta");
2180                 }
2181                 try { q.setForwardOnly( true ); } catch (e) {}
2182                 if (!q.exec()) {
2183                                 datos["error"] = 2;
2184                                 return datos;
2185                 }
2186                 if (!q.next()) {
2187                                 datos["error"] = 1;
2188                                 return datos;
2189                 }
2191                 datos["error"] = 0;
2192                 datos["idsubcuenta"] = q.value(0);
2193                 datos["codsubcuenta"] = q.value(1);
2194                 return datos;
2197 /* \D Devuelve el código e id de la subcuenta de cliente correspondiente a una  determinada factura
2198 @param curFactura: Cursor posicionado en la factura
2199 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2200 @return Los datos componen un vector de tres valores:
2201 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2202 idsubcuenta: Identificador de la subcuenta
2203 codsubcuenta: Código de la subcuenta
2204 \end */
2205 function oficial_datosCtaCliente(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2207         return flfactppal.iface.pub_datosCtaCliente( curFactura.valueBuffer("codcliente"), valoresDefecto );
2210 /* \D Devuelve el código e id de la subcuenta de proveedor correspondiente a una  determinada factura
2211 @param curFactura: Cursor posicionado en la factura
2212 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2213 @return Los datos componen un vector de tres valores:
2214 error: 0.Sin error 1.Datos no encontrados 2.Error al ejecutar la query
2215 idsubcuenta: Identificador de la subcuenta
2216 codsubcuenta: Código de la subcuenta
2217 \end */
2218 function oficial_datosCtaProveedor(curFactura:FLSqlCursor, valoresDefecto:Array):Array
2220         return flfactppal.iface.pub_datosCtaProveedor( curFactura.valueBuffer("codproveedor"), valoresDefecto );
2223 /* \D Regenera el asiento correspondiente a una factura de abono de cliente
2224 @param  curFactura: Cursor con los datos de la factura
2225 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2226 @return VERDADERO si no hay error. FALSO en otro caso
2227 \end */
2228 function oficial_asientoFacturaAbonoCli(curFactura:FLSqlCursor, valoresDefecto:Array)
2230         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2231     var idFactura:String = curFactura.valueBuffer("idfactura");
2232         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2233         var debe:Number = 0;
2234         var haber:Number = 0;
2235         var debeME:Number = 0;
2236         var haberME:Number = 0;
2237         var aux:Number;
2238         var util:FLUtil = new FLUtil;
2239         
2240         curPartidas.select("idasiento = '" + idAsiento + "'");
2241         while (curPartidas.next()) {
2242                 curPartidas.setModeAccess(curPartidas.Edit);
2243                 curPartidas.refreshBuffer();
2244                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2245                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2246                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2247                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2248                 aux = debe;
2249                 debe = haber * -1;
2250                 haber = aux * -1;
2251                 aux = debeME;
2252                 debeME = haberME * -1;
2253                 haberME = aux * -1;
2254                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2255                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2256                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2257                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2259                 curPartidas.setValueBuffer("debe",  debe);
2260                 curPartidas.setValueBuffer("haber", haber);
2261                 curPartidas.setValueBuffer("debeme",  debeME);
2262                 curPartidas.setValueBuffer("haberme", haberME);
2264                 if (!curPartidas.commitBuffer())
2265                         return false;
2266         }
2267         
2268         var ctaDevolVentas = this.iface.datosCtaEspecial("DEVVEN", valoresDefecto.codejercicio);
2269         if (ctaDevolVentas.error == 1) {
2270                 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);
2271                 return false;
2272         }
2273         if (ctaDevolVentas.error == 2)
2274                 return false;
2275         
2276         var qryPartidasVenta:FLSqlQuery = new FLSqlQuery();
2277         qryPartidasVenta.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2278         qryPartidasVenta.setSelect("p.idsubcuenta");
2279         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 ");
2280         qryPartidasVenta.setWhere("c.idcuentaesp = 'VENTAS' AND idasiento = " + idAsiento);
2281         try { qryPartidasVenta.setForwardOnly( true ); } catch (e) {}
2283         if (!qryPartidasVenta.exec())
2284                 return false;
2286         if (!qryPartidasVenta.next())
2287                 return false;
2288         
2289         
2290         var curPartidasVenta:FLSqlCursor = new FLSqlCursor("co_partidas");
2291         curPartidasVenta.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasVenta.value(0));
2292         curPartidasVenta.first();
2293         curPartidasVenta.setModeAccess(curPartidasVenta.Edit);
2294         curPartidasVenta.refreshBuffer();
2295         curPartidasVenta.setValueBuffer("idsubcuenta",  ctaDevolVentas.idsubcuenta);
2296         curPartidasVenta.setValueBuffer("codsubcuenta",  ctaDevolVentas.codsubcuenta);
2297         if (!curPartidasVenta.commitBuffer())
2298                         return false;
2299         return true;
2303 /* \D Regenera el asiento correspondiente a una factura de abono de proveedor
2304 @param  curFactura: Cursor con los datos de la factura
2305 @param valoresDefecto: Array con los datos de ejercicio y divisa actuales
2306 @return VERDADERO si no hay error. FALSO en otro caso
2307 \end */
2308 function oficial_asientoFacturaAbonoProv(curFactura:FLSqlCursor, valoresDefecto:Array)
2310         var idAsiento:String  = curFactura.valueBuffer("idasiento").toString();
2311     var idFactura:String = curFactura.valueBuffer("idfactura");
2312         var curPartidas:FLSqlCursor = new FLSqlCursor("co_partidas");
2313         var debe:Number = 0;
2314         var haber:Number = 0;
2315         var debeME:Number = 0;
2316         var haberME:Number = 0;
2317         var aux:Number;
2318         
2319         var util:FLUtil = new FLUtil;
2320         
2321         curPartidas.select("idasiento = '" + idAsiento + "'");
2322         while (curPartidas.next()) {
2323                 curPartidas.setModeAccess(curPartidas.Edit);
2324                 curPartidas.refreshBuffer();
2325                 debe = parseFloat(curPartidas.valueBuffer("debe"));
2326                 haber = parseFloat(curPartidas.valueBuffer("haber"));
2327                 debeME = parseFloat(curPartidas.valueBuffer("debeme"));
2328                 haberME = parseFloat(curPartidas.valueBuffer("haberme"));
2329                 aux = debe;
2330                 debe = haber * -1;
2331                 haber = aux * -1;
2332                 aux = debeME;
2333                 debeME = haberME * -1;
2334                 haberME = aux * -1;
2335                 debe = util.roundFieldValue(debe, "co_partidas", "debe");
2336                 haber = util.roundFieldValue(haber, "co_partidas", "haber");
2337                 debeME = util.roundFieldValue(debeME, "co_partidas", "debeme");
2338                 haberME = util.roundFieldValue(haberME, "co_partidas", "haberme");
2340                 curPartidas.setValueBuffer("debe",  debe);
2341                 curPartidas.setValueBuffer("haber", haber);
2342                 curPartidas.setValueBuffer("debeme",  debeME);
2343                 curPartidas.setValueBuffer("haberme", haberME);
2344         }
2345         
2346         var ctaDevolCompra = this.iface.datosCtaEspecial("DEVCOM", valoresDefecto.codejercicio);
2347         if (ctaDevolCompra.error == 1) {
2348                 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);
2349                 return false;
2350         }
2351         if (ctaDevolCompra.error == 2)
2352                 return false;
2353         
2354         var qryPartidasCompra:FLSqlQuery = new FLSqlQuery();
2355         qryPartidasCompra.setTablesList("co_partidas,co_subcuentas,co_cuentas");
2356         qryPartidasCompra.setSelect("p.idsubcuenta");
2357         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 ");
2358         qryPartidasCompra.setWhere("c.idcuentaesp = 'COMPRA' AND idasiento = " + idAsiento);
2359         try { qryPartidasCompra.setForwardOnly( true ); } catch (e) {}
2361         if (!qryPartidasCompra.exec())
2362                 return false;
2364         if (!qryPartidasCompra.next())
2365                 return false;
2366         
2367         
2368         var curPartidasCompra:FLSqlCursor = new FLSqlCursor("co_partidas");
2369         curPartidasCompra.select("idasiento = " + idAsiento + " AND idsubcuenta = " + qryPartidasCompra.value(0));
2370         curPartidasCompra.first();
2371         curPartidasCompra.setModeAccess(curPartidasCompra.Edit);
2372         curPartidasCompra.refreshBuffer();
2373         curPartidasCompra.setValueBuffer("idsubcuenta",  ctaDevolCompra.idsubcuenta);
2374         curPartidasCompra.setValueBuffer("codsubcuenta",  ctaDevolCompra.codsubcuenta);
2375         if (!curPartidasCompra.commitBuffer())
2376                         return false;
2377         return true;
2380 /** \D Si la fecha no está dentro del ejercicio, propone al usuario la selección de uno nuevo
2381 @param  fecha: Fecha del documento
2382 @param  codEjercicio: Ejercicio del documento
2383 @param  tipoDoc: Tipo de documento a generar
2384 @return Devuelve un array con los siguientes datos:
2385 ok:     Indica si la función terminó correctamente (true) o con error (false)
2386 modificaciones: Indica si se ha modificado algún valor (fecha o ejercicio)
2387 fecha: Nuevo valor para la fecha modificada
2388 codEjercicio: Nuevo valor para el ejercicio modificado
2389 \end */
2390 function oficial_datosDocFacturacion(fecha:String, codEjercicio:String, tipoDoc:String):Array
2392         
2393         var res:Array = [];
2394         res["ok"] = true;
2395         res["modificaciones"] = false;
2396         
2397         var util:FLUtil = new FLUtil;
2398         if (util.sqlSelect("ejercicios", "codejercicio", "codejercicio = '" + codEjercicio + "' AND '" + fecha + "' BETWEEN fechainicio AND fechafin"))
2399                 return res;
2400                 
2401         var f:Object = new FLFormSearchDB("fechaejercicio");
2402         var cursor:FLSqlCursor = f.cursor();
2403         
2404         cursor.select();
2405         if (!cursor.first())
2406                 cursor.setModeAccess(cursor.Insert);
2407         else
2408                 cursor.setModeAccess(cursor.Edit);
2409         cursor.refreshBuffer();
2411         cursor.refreshBuffer();
2412         cursor.setValueBuffer("fecha", fecha);
2413         cursor.setValueBuffer("codejercicio", codEjercicio);
2414         cursor.setValueBuffer("label", tipoDoc);
2415         cursor.commitBuffer();
2416         cursor.select();
2418         if (!cursor.first()) {
2419                 res["ok"] = false;
2420                 return res;
2421         }
2423         cursor.setModeAccess(cursor.Edit);
2424         cursor.refreshBuffer();
2426         f.setMainWidget();
2427         
2428         var acpt:String = f.exec("codejercicio");
2429         if (!acpt) {
2430                 res["ok"] = false;
2431                 return res;
2432         }
2433         res["modificaciones"] = true;
2434         res["fecha"] = cursor.valueBuffer("fecha");
2435         res["codEjercicio"] = cursor.valueBuffer("codejercicio");
2436         
2437         if (res.codEjercicio != flfactppal.iface.pub_ejercicioActual()) {
2438                 if (tipoDoc != "pagosdevolcli" && tipoDoc != "pagosdevolprov") {
2439                         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);
2440                 }
2441         }
2442         
2443         return res;
2446 /** \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
2447 @param  codSerie: Serie del documento
2448 @param  codCliente: Código del cliente
2449 @return true si el documento debe llevar IVA, false en caso contrario
2450 \end */
2451 function oficial_tieneIvaDocCliente(codSerie:String, codCliente:String):Number
2453         var util:FLUtil = new FLUtil;
2454         var conIva:Boolean = true;
2455         
2456         if (util.sqlSelect("series", "siniva", "codserie = '" + codSerie + "'"))
2457                 return 0;
2458         else {
2459                 var regIva:String = util.sqlSelect("clientes", "regimeniva", "codcliente = '" + codCliente + "'");
2460                 if (regIva == "Exento")
2461                         return 0;
2462                 else
2463                         if (!util.sqlSelect("clientes", "recargo", "codcliente = '" + codCliente + "'"))
2464                                 return 1;
2465         }
2466         
2467         return 2;
2471 /** \D Indica si el módulo de autómata está instalado y activado
2472 @return true si está activado, false en caso contrario
2473 \end */
2474 function oficial_automataActivado():Boolean
2476         if (!sys.isLoadedModule("flautomata"))
2477                 return false;
2478         
2479         if (formau_automata.iface.pub_activado())
2480                 return true;
2481         
2482         return false;
2485 /** \D Comprueba que si la factura tiene IVA, no esté incluida en un período de regularización ya cerrado
2486 @param  curFactura: Cursor de la factura de cliente o proveedor
2487 @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
2488 \end */
2489 function oficial_comprobarRegularizacion(curFactura:FLSqlCursor):Boolean
2491         var util:FLUtil = new FLUtil;
2493         var fecha:String = curFactura.valueBuffer("fecha");
2494         if (util.sqlSelect("co_regiva", "idregiva", "fechainicio <= '" + fecha + "' AND fechafin >= '" + fecha + "' AND codejercicio = '" + curFactura.valueBuffer("codejercicio") + "'")) {
2495                 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);
2496                 return false;
2497         }
2498         return true;
2501 /** \D
2502 Recalcula la tabla huecos y el último valor de la secuencia de numeración.
2503 @param serie: Código de serie del documento
2504 @param ejercicio: Código de ejercicio del documento
2505 @param fN: Tipo de documento (factura a cliente, a proveedor, albarán, etc.)
2506 @return true si el calculo se ralizó correctamente
2507 \end */
2508 function oficial_recalcularHuecos( serie:String, ejercicio:String, fN:String ):Boolean {
2509         var util:FLUtil = new FLUtil;
2510         var tipo:String;
2511         var tabla:String;
2513         if ( fN == "nfacturaprov" ) {
2514                 tipo = "FP";
2515                 tabla = "facturasprov"
2516         } else if (fN == "nfacturacli") {
2517                 tipo = "FC";
2518                 tabla = "facturascli";
2519         }
2521         var idSec = util.sqlSelect( "secuenciasejercicios", "id", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2523         if ( idSec ) {
2524                 var nHuecos:Number = parseInt( util.sqlSelect( "huecos", "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND tipo = '" + tipo + "'" ) );
2525                 var nFacturas:Number = parseInt( util.sqlSelect( tabla, "count(*)", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" ) );
2526                 var maxFactura:Number = parseInt( util.sqlSelect( "secuencias", "valorout", "id = " + idSec + " AND nombre='" + fN + "'" ) ) - 1;
2527                 if (isNaN(maxFactura))
2528                         maxFactura = 0;
2530                 if ( maxFactura - nFacturas != nHuecos ) {
2531                         var nSec:Number = 0;
2532                         var nFac:Number = 0;
2533                         var ultFac:Number = -1;
2534                         var cursorHuecos:FLSqlCursor = new FLSqlCursor("huecos");
2535                         var qryFac:FLSqlQuery = new FLSqlQuery();
2537                         util.createProgressDialog( util.translate( "scripts", "Calculando huecos en la numeración..." ), maxFactura );
2539                         qryFac.setTablesList( tabla );
2540                         qryFac.setSelect( "numero" );
2541                         qryFac.setFrom( tabla );
2542                         qryFac.setWhere( "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "'" );
2543                         qryFac.setOrderBy( "codigo asc" );
2544                         qryFac.setForwardOnly( true );
2546                         if ( !qryFac.exec() )
2547                                 return true;
2549                         util.sqlDelete( "huecos", "codserie = '" + serie + "' AND codejercicio = '" + ejercicio + "' AND ( tipo = 'XX' OR tipo = '" + tipo + "')" );
2551                         while ( qryFac.next() ) {
2552                                 nFac = qryFac.value( 0 );
2553                                 
2554                                 // Por si hay duplicados, que no debería haberlos...
2555                                 if (ultFac == nFac)
2556                                         continue;
2557                                 ultFac = nFac;
2558                                 
2559                                 util.setProgress( ++nSec );
2560                                 while ( nSec < nFac ) {
2561                                         cursorHuecos.setModeAccess( cursorHuecos.Insert );
2562                                         cursorHuecos.refreshBuffer();
2563                                         cursorHuecos.setValueBuffer( "tipo", tipo );
2564                                         cursorHuecos.setValueBuffer( "codserie", serie );
2565                                         cursorHuecos.setValueBuffer( "codejercicio", ejercicio );
2566                                         cursorHuecos.setValueBuffer( "numero", nSec );
2567                                         cursorHuecos.commitBuffer();
2568                                         util.setProgress( ++nSec );
2569                                 }
2570                         }
2571                         
2572                         util.setProgress( ++nSec );
2573                         util.sqlUpdate( "secuencias", "valorout", nSec, "id = " + idSec + " AND nombre='" + fN + "'" );
2575                         util.setProgress( maxFactura );
2576                         util.destroyProgressDialog();
2577                 }
2578         }
2580         return true;
2583 /** \D Lanza el formulario que muestra los documentos relacionados con un determinado documento de facturación
2584 @param  codigo: Código del documento
2585 @param  tipo: Tipo del documento
2586 \end */
2587 function oficial_mostrarTraza(codigo:String, tipo:String)
2589         var util:FLUtil = new FLUtil();
2590         util.sqlDelete("trazadoc", "usuario = '" + sys.nameUser() + "'");
2592         var f:Object = new FLFormSearchDB("trazadoc");
2593         var curTraza:FLSqlCursor = f.cursor();
2594         curTraza.setModeAccess(curTraza.Insert);
2595         curTraza.refreshBuffer();
2596         curTraza.setValueBuffer("usuario", sys.nameUser());
2597         curTraza.setValueBuffer("codigo", codigo);
2598         curTraza.setValueBuffer("tipo", tipo);
2599         if (!curTraza.commitBuffer())
2600                 return false;;
2602         curTraza.select("usuario = '" + sys.nameUser() + "'");
2603         if (!curTraza.first())
2604                 return false;
2606         curTraza.setModeAccess(curTraza.Browse);
2607         f.setMainWidget();
2608         curTraza.refreshBuffer();
2609         var acpt:String = f.exec("usuario");
2612 /** \D Establece los datos opcionales de una partida de IVA decompras/ventas.
2613 Para facilitar personalizaciones en las partidas.
2614 Se ponen datos de concepto, tipo de documento, documento y factura
2615 @param  curPartida: Cursor sobre la partida
2616 @param  curFactura: Cursor sobre la factura
2617 @param  tipo: cliente / proveedor
2618 @param  concepto: Concepto, opcional
2620 function oficial_datosPartidaFactura(curPartida:FLSqlCursor, curFactura:FLSqlCursor, tipo:String, concepto:String) 
2622         var util:FLUtil = new FLUtil();
2623         
2624         if (tipo == "cliente") {
2625                 if (concepto)
2626                         curPartida.setValueBuffer("concepto", concepto);
2627                 else
2628                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Nuestra factura ") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombrecliente"));
2629                 
2630                 // Si es de IVA
2631                 if (curPartida.valueBuffer("cifnif"))
2632                         curPartida.setValueBuffer("tipodocumento", "Factura de cliente");
2633         }
2634         else {
2635                 if (concepto)
2636                         curPartida.setValueBuffer("concepto", concepto);
2637                 else
2638                         curPartida.setValueBuffer("concepto", util.translate("scripts", "Su factura") + curFactura.valueBuffer("codigo") + " - " + curFactura.valueBuffer("nombre"));
2639                 
2640                 // Si es de IVA
2641                 if (curPartida.valueBuffer("cifnif"))
2642                 curPartida.setValueBuffer("tipodocumento", "Factura de proveedor");
2643         }
2644         
2645         // Si es de IVA
2646         if (curPartida.valueBuffer("cifnif")) {
2647                 curPartida.setValueBuffer("documento", curFactura.valueBuffer("codigo"));
2648                 curPartida.setValueBuffer("factura", curFactura.valueBuffer("numero"));
2649         }
2652 /** \D Comprueba si hay condiciones para regenerar los recibos de una factura
2653 cuando se edita la misma. Para sobrecargar en extensiones
2654 @param  curFactura: Cursor de la factura
2655 @param  masCampos: Array con los nombres de campos adicionales. Opcional
2656 @return VERDADERO si hay que regenerar, FALSO en otro caso
2657 \end */
2658 function oficial_siGenerarRecibosCli(curFactura:FLSqlCursor, masCampos:Array):Boolean 
2660         var camposAcomprobar = new Array("codcliente","total","codpago","fecha");
2661         
2662         for (var i:Number = 0; i < camposAcomprobar.length; i++)
2663                 if (curFactura.valueBuffer(camposAcomprobar[i]) != curFactura.valueBufferCopy(camposAcomprobar[i]))
2664                         return true;
2665         
2666         if (masCampos) {
2667                 for (i = 0; i < masCampos.length; i++)
2668                         if (curFactura.valueBuffer(masCampos[i]) != curFactura.valueBufferCopy(masCampos[i]))
2669                                 return true;
2670         }
2671         
2672         return false;
2675 function oficial_validarIvaRecargoCliente(codCliente:String,id:Number,tabla:String,identificador:String):Boolean
2677         var util:FLUtil;
2679         if(!codCliente)
2680                 return true;    
2682         var regimenIva = util.sqlSelect("clientes","regimeniva","codcliente = '" + codCliente + "'");
2683         var aplicarRecargo = util.sqlSelect("clientes","recargo","codcliente = '" + codCliente + "'");
2684         
2685         var q:FLSqlQuery = new FLSqlQuery();
2686         q.setTablesList(tabla);
2687         q.setSelect("iva,recargo");
2688         q.setFrom(tabla);
2689         q.setWhere(identificador + " = " + id);
2690         
2691         if (!q.exec())
2692                 return false;
2694         while (q.next()) {
2695                                 var iva:Number = parseFloat(q.value("iva"));
2696                 if(!iva)
2697                         iva = 0;
2698                 var recargo:Number = parseFloat(q.value("recargo"));
2699                 if(!recargo)
2700                         recargo = 0;
2702                 switch (regimenIva) {
2703                         case "General":
2704                         case "U.E.": {
2705                                 if (iva <= 0) {
2706                                         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);
2707                                         if (res != MessageBox.Yes)
2708                                                 return false;
2709                                 }
2710                         }
2711                         break;
2712                         case "Exento": {
2713                                 if (iva != 0) {
2714                                         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);
2715                                         if (res != MessageBox.Yes)
2716                                                 return false;
2717                                 }
2718                         }
2719                         break;
2720                 }
2721                 if (aplicarRecargo && recargo <= 0) {
2722                         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);
2723                                 if (res != MessageBox.Yes)
2724                                         return false;
2725                 }
2726                 if (!aplicarRecargo && recargo != 0) {
2727                         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);
2728                                 if (res != MessageBox.Yes)
2729                                         return false;
2730                 }
2731         }
2733         return true;
2736 function oficial_validarIvaRecargoProveedor(codProveedor:String,id:Number,tabla:String,identificador:String):Boolean
2738         var util:FLUtil;
2740         if(!codProveedor)
2741                 return true;    
2743         var regimenIva = util.sqlSelect("proveedores","regimeniva","codproveedor = '" + codProveedor + "'");
2744         var aplicarRecargo = util.sqlSelect("empresa","recequivalencia","1 = 1");
2745         
2746         var q:FLSqlQuery = new FLSqlQuery();
2747         q.setTablesList(tabla);
2748         q.setSelect("iva,recargo");
2749         q.setFrom(tabla);
2750         q.setWhere(identificador + " = " + id);
2751         
2752         if (!q.exec())
2753                 return false;
2755         while (q.next()) {
2756                 var iva:Number = parseFloat(q.value("iva"));
2757                 if(!iva)
2758                         iva = 0;
2759                 var recargo:Number = parseFloat(q.value("recargo"));
2760                 if(!recargo)
2761                         recargo = 0;
2763                 switch (regimenIva) {
2764                         case "General":
2765                         case "U.E.": {
2766                                 if (q.value("iva") <= 0) {
2767                                         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);
2768                                         if (res != MessageBox.Yes)
2769                                                 return false;
2770                                 }
2771                         }
2772                         break;
2773                         case "Exento": {
2774                                 if (q.value("iva") != 0) {
2775                                         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);
2776                                         if (res != MessageBox.Yes)
2777                                                 return false;
2778                                 }
2779                         }
2780                         break;
2781                 }
2782                 if (aplicarRecargo && q.value("recargo") <= 0) {
2783                         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);
2784                                 if (res != MessageBox.Yes)
2785                                         return false;
2786                 }
2787                 if (!aplicarRecargo && q.value("recargo") != 0) {
2788                         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);
2789                                 if (res != MessageBox.Yes)
2790                                         return false;
2791                 }
2792         }
2794         return true;
2797 function oficial_comprobarFacturaAbonoCli(curFactura:FLSqlCursor):Boolean
2799         var util:FLUtil = new FLUtil();
2800         if (curFactura.valueBuffer("deabono") == true) {
2801                 if (!curFactura.valueBuffer("idfacturarect")){
2802                         var res:Number = MessageBox.warning(util.translate("scripts", "No ha indicado la factura que desea abonar.\n¿Desea continuar?"), MessageBox.No, MessageBox.Yes);
2803                         if (res != MessageBox.Yes) {
2804                                 return false;
2805                         }
2806                 } else {
2807                         if (util.sqlSelect("facturascli", "idfacturarect", "idfacturarect = " + curFactura.valueBuffer("idfacturarect") + " AND idfactura <> " + curFactura.valueBuffer("idfactura"))) {
2808                                 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);
2809                                 return false;
2810                         }
2811                 }
2812         }
2813         return true;
2816 function oficial_comprobarCambioSerie(cursor:FLSqlCursor):Boolean
2818         var util:FLUtil;
2819         if(!cursor.valueBuffer("codserie") || cursor.valueBuffer("codserie") == "" || !cursor.valueBufferCopy("codserie") || cursor.valueBufferCopy("codserie") == "")
2820                 return true;
2821         if(cursor.valueBuffer("codserie") != cursor.valueBufferCopy("codserie")) {
2822                 var util:FLUtil = new FLUtil();
2823                 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);
2824                 return false;
2825         }
2826         return true;
2829 //// OFICIAL ////////////////////////////////////////////////////
2830 /////////////////////////////////////////////////////////////////
2832 /** @class_definition head */
2833 /////////////////////////////////////////////////////////////////
2834 //// DESARROLLO /////////////////////////////////////////////////
2836 //// DESARROLLO /////////////////////////////////////////////////
2837 /////////////////////////////////////////////////////////////////